github.com/mponton/terratest@v0.44.0/modules/gcp/storage.go (about) 1 package gcp 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 8 "cloud.google.com/go/storage" 9 "github.com/mponton/terratest/modules/logger" 10 "github.com/mponton/terratest/modules/testing" 11 "google.golang.org/api/iterator" 12 ) 13 14 // CreateStorageBucket creates a Google Cloud bucket with the given BucketAttrs. Note that Google Storage bucket names must be globally unique. 15 func CreateStorageBucket(t testing.TestingT, projectID string, name string, attr *storage.BucketAttrs) { 16 err := CreateStorageBucketE(t, projectID, name, attr) 17 if err != nil { 18 t.Fatal(err) 19 } 20 } 21 22 // CreateStorageBucketE creates a Google Cloud bucket with the given BucketAttrs. Note that Google Storage bucket names must be globally unique. 23 func CreateStorageBucketE(t testing.TestingT, projectID string, name string, attr *storage.BucketAttrs) error { 24 logger.Logf(t, "Creating bucket %s", name) 25 26 ctx := context.Background() 27 28 // Creates a client. 29 client, err := storage.NewClient(ctx) 30 if err != nil { 31 return err 32 } 33 34 // Creates a Bucket instance. 35 bucket := client.Bucket(name) 36 37 // Creates the new bucket. 38 return bucket.Create(ctx, projectID, attr) 39 } 40 41 // DeleteStorageBucket destroys the Google Storage bucket. 42 func DeleteStorageBucket(t testing.TestingT, name string) { 43 err := DeleteStorageBucketE(t, name) 44 if err != nil { 45 t.Fatal(err) 46 } 47 } 48 49 // DeleteStorageBucketE destroys the S3 bucket in the given region with the given name. 50 func DeleteStorageBucketE(t testing.TestingT, name string) error { 51 logger.Logf(t, "Deleting bucket %s", name) 52 53 ctx := context.Background() 54 55 client, err := storage.NewClient(ctx) 56 if err != nil { 57 return err 58 } 59 60 return client.Bucket(name).Delete(ctx) 61 } 62 63 // ReadBucketObject reads an object from the given Storage Bucket and returns its contents. 64 func ReadBucketObject(t testing.TestingT, bucketName string, filePath string) io.Reader { 65 out, err := ReadBucketObjectE(t, bucketName, filePath) 66 if err != nil { 67 t.Fatal(err) 68 } 69 return out 70 } 71 72 // ReadBucketObjectE reads an object from the given Storage Bucket and returns its contents. 73 func ReadBucketObjectE(t testing.TestingT, bucketName string, filePath string) (io.Reader, error) { 74 logger.Logf(t, "Reading object from bucket %s using path %s", bucketName, filePath) 75 76 ctx := context.Background() 77 78 client, err := storage.NewClient(ctx) 79 if err != nil { 80 return nil, err 81 } 82 83 bucket := client.Bucket(bucketName) 84 r, err := bucket.Object(filePath).NewReader(ctx) 85 if err != nil { 86 return nil, err 87 } 88 89 return r, nil 90 } 91 92 // WriteBucketObject writes an object to the given Storage Bucket and returns its URL. 93 func WriteBucketObject(t testing.TestingT, bucketName string, filePath string, body io.Reader, contentType string) string { 94 out, err := WriteBucketObjectE(t, bucketName, filePath, body, contentType) 95 if err != nil { 96 t.Fatal(err) 97 } 98 return out 99 } 100 101 // WriteBucketObjectE writes an object to the given Storage Bucket and returns its URL. 102 func WriteBucketObjectE(t testing.TestingT, bucketName string, filePath string, body io.Reader, contentType string) (string, error) { 103 // set a default content type 104 if contentType == "" { 105 contentType = "application/octet-stream" 106 } 107 108 logger.Logf(t, "Writing object to bucket %s using path %s and content type %s", bucketName, filePath, contentType) 109 110 ctx := context.Background() 111 112 client, err := storage.NewClient(ctx) 113 if err != nil { 114 return "", err 115 } 116 117 w := client.Bucket(bucketName).Object(filePath).NewWriter(ctx) 118 w.ContentType = contentType 119 120 // Don't set any ACL or cache control properties for now 121 //w.ACL = []storage.ACLRule{{Entity: storage.AllAuthenticatedUsers, Role: storage.RoleReader}} 122 // set a default cache control (1 day) 123 //w.CacheControl = "public, max-age=86400" 124 125 if _, err := io.Copy(w, body); err != nil { 126 return "", err 127 } 128 if err := w.Close(); err != nil { 129 return "", err 130 } 131 132 const publicURL = "https://storage.googleapis.com/%s/%s" 133 return fmt.Sprintf(publicURL, bucketName, filePath), nil 134 } 135 136 // EmptyStorageBucket removes the contents of a storage bucket with the given name. 137 func EmptyStorageBucket(t testing.TestingT, name string) { 138 err := EmptyStorageBucketE(t, name) 139 if err != nil { 140 t.Fatal(err) 141 } 142 } 143 144 // EmptyStorageBucketE removes the contents of a storage bucket with the given name. 145 func EmptyStorageBucketE(t testing.TestingT, name string) error { 146 logger.Logf(t, "Emptying storage bucket %s", name) 147 148 ctx := context.Background() 149 150 client, err := storage.NewClient(ctx) 151 if err != nil { 152 return err 153 } 154 155 // List all objects in the bucket 156 // 157 // TODO - we should really do a bulk delete call here, but I couldn't find 158 // anything in the SDK. 159 bucket := client.Bucket(name) 160 it := bucket.Objects(ctx, nil) 161 for { 162 objectAttrs, err := it.Next() 163 164 if err == iterator.Done { 165 break 166 } 167 168 if err != nil { 169 return err 170 } 171 172 // purge the object 173 logger.Logf(t, "Deleting storage bucket object %s", objectAttrs.Name) 174 bucket.Object(objectAttrs.Name).Delete(ctx) 175 } 176 177 return nil 178 } 179 180 // AssertStorageBucketExists checks if the given storage bucket exists and fails the test if it does not. 181 func AssertStorageBucketExists(t testing.TestingT, name string) { 182 err := AssertStorageBucketExistsE(t, name) 183 if err != nil { 184 t.Fatal(err) 185 } 186 } 187 188 // AssertStorageBucketExistsE checks if the given storage bucket exists and returns an error if it does not. 189 func AssertStorageBucketExistsE(t testing.TestingT, name string) error { 190 logger.Logf(t, "Finding bucket %s", name) 191 192 ctx := context.Background() 193 194 // Creates a client. 195 client, err := storage.NewClient(ctx) 196 if err != nil { 197 return err 198 } 199 200 // Creates a Bucket instance. 201 bucket := client.Bucket(name) 202 203 // TODO - the code below attempts to determine whether the storage bucket 204 // exists by making a making a number of API calls, then attemping to 205 // list the contents of the bucket. It was adapted from Google's own integration 206 // tests and should be improved once the appropriate API call is added. 207 // For more info see: https://github.com/GoogleCloudPlatform/google-cloud-go/blob/de879f7be552d57556875b8aaa383bce9396cc8c/storage/integration_test.go#L1231 208 if _, err := bucket.Attrs(ctx); err != nil { 209 // ErrBucketNotExist 210 return err 211 } 212 213 it := bucket.Objects(ctx, nil) 214 if _, err := it.Next(); err == storage.ErrBucketNotExist { 215 return err 216 } 217 218 return nil 219 }