From 64c2e68de92cf8634f33fe41d4ca06b9af719df0 Mon Sep 17 00:00:00 2001 From: emily Date: Mon, 8 May 2017 16:35:47 -0700 Subject: [PATCH] Add additional properties for google resource storage bucket object. (#14259) --- .../google/resource_storage_bucket_object.go | 68 ++++++++ .../resource_storage_bucket_object_test.go | 158 +++++++++++++++++- .../r/storage_bucket_object.html.markdown | 26 ++- 3 files changed, 246 insertions(+), 6 deletions(-) diff --git a/builtin/providers/google/resource_storage_bucket_object.go b/builtin/providers/google/resource_storage_bucket_object.go index 5b1f37e25..14db8d21c 100644 --- a/builtin/providers/google/resource_storage_bucket_object.go +++ b/builtin/providers/google/resource_storage_bucket_object.go @@ -32,6 +32,37 @@ func resourceStorageBucketObject() *schema.Resource { ForceNew: true, }, + "cache_control": &schema.Schema{ + Type: schema.TypeString, + ForceNew: true, + Optional: true, + }, + + "content_disposition": &schema.Schema{ + Type: schema.TypeString, + ForceNew: true, + Optional: true, + }, + + "content_encoding": &schema.Schema{ + Type: schema.TypeString, + ForceNew: true, + Optional: true, + }, + + "content_language": &schema.Schema{ + Type: schema.TypeString, + ForceNew: true, + Optional: true, + }, + + "content_type": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + }, + "content": &schema.Schema{ Type: schema.TypeString, Optional: true, @@ -62,6 +93,13 @@ func resourceStorageBucketObject() *schema.Resource { ForceNew: true, ConflictsWith: []string{"content"}, }, + + "storage_class": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + }, }, } } @@ -92,6 +130,30 @@ func resourceStorageBucketObjectCreate(d *schema.ResourceData, meta interface{}) objectsService := storage.NewObjectsService(config.clientStorage) object := &storage.Object{Bucket: bucket} + if v, ok := d.GetOk("cache_control"); ok { + object.CacheControl = v.(string) + } + + if v, ok := d.GetOk("content_disposition"); ok { + object.ContentDisposition = v.(string) + } + + if v, ok := d.GetOk("content_encoding"); ok { + object.ContentEncoding = v.(string) + } + + if v, ok := d.GetOk("content_language"); ok { + object.ContentLanguage = v.(string) + } + + if v, ok := d.GetOk("content_type"); ok { + object.ContentType = v.(string) + } + + if v, ok := d.GetOk("storage_class"); ok { + object.StorageClass = v.(string) + } + insertCall := objectsService.Insert(bucket, object) insertCall.Name(name) insertCall.Media(media) @@ -133,6 +195,12 @@ func resourceStorageBucketObjectRead(d *schema.ResourceData, meta interface{}) e d.Set("md5hash", res.Md5Hash) d.Set("crc32c", res.Crc32c) + d.Set("cache_control", res.CacheControl) + d.Set("content_disposition", res.ContentDisposition) + d.Set("content_encoding", res.ContentEncoding) + d.Set("content_language", res.ContentLanguage) + d.Set("content_type", res.ContentType) + d.Set("storage_class", res.StorageClass) d.SetId(objectGetId(res)) diff --git a/builtin/providers/google/resource_storage_bucket_object_test.go b/builtin/providers/google/resource_storage_bucket_object_test.go index 9ee0981e3..d3eff46db 100644 --- a/builtin/providers/google/resource_storage_bucket_object_test.go +++ b/builtin/providers/google/resource_storage_bucket_object_test.go @@ -64,7 +64,113 @@ func TestAccGoogleStorageObject_content(t *testing.T) { Steps: []resource.TestStep{ resource.TestStep{ Config: testGoogleStorageBucketsObjectContent(bucketName), - Check: testAccCheckGoogleStorageObject(bucketName, objectName, data_md5), + Check: resource.ComposeTestCheckFunc( + testAccCheckGoogleStorageObject(bucketName, objectName, data_md5), + resource.TestCheckResourceAttr( + "google_storage_bucket_object.object", "content_type", "text/plain; charset=utf-8"), + resource.TestCheckResourceAttr( + "google_storage_bucket_object.object", "storage_class", "STANDARD"), + ), + }, + }, + }) +} + +func TestAccGoogleStorageObject_withContentCharacteristics(t *testing.T) { + bucketName := testBucketName() + data := []byte(content) + h := md5.New() + h.Write(data) + data_md5 := base64.StdEncoding.EncodeToString(h.Sum(nil)) + ioutil.WriteFile(tf.Name(), data, 0644) + + disposition, encoding, language, content_type := "inline", "compress", "en", "binary/octet-stream" + resource.Test(t, resource.TestCase{ + PreCheck: func() { + if err != nil { + panic(err) + } + testAccPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccGoogleStorageObjectDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testGoogleStorageBucketsObject_optionalContentFields( + bucketName, disposition, encoding, language, content_type), + Check: resource.ComposeTestCheckFunc( + testAccCheckGoogleStorageObject(bucketName, objectName, data_md5), + resource.TestCheckResourceAttr( + "google_storage_bucket_object.object", "content_disposition", disposition), + resource.TestCheckResourceAttr( + "google_storage_bucket_object.object", "content_encoding", encoding), + resource.TestCheckResourceAttr( + "google_storage_bucket_object.object", "content_language", language), + resource.TestCheckResourceAttr( + "google_storage_bucket_object.object", "content_type", content_type), + ), + }, + }, + }) +} + +func TestAccGoogleStorageObject_cacheControl(t *testing.T) { + bucketName := testBucketName() + data := []byte(content) + h := md5.New() + h.Write(data) + data_md5 := base64.StdEncoding.EncodeToString(h.Sum(nil)) + ioutil.WriteFile(tf.Name(), data, 0644) + + cacheControl := "private" + resource.Test(t, resource.TestCase{ + PreCheck: func() { + if err != nil { + panic(err) + } + testAccPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccGoogleStorageObjectDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testGoogleStorageBucketsObject_cacheControl(bucketName, cacheControl), + Check: resource.ComposeTestCheckFunc( + testAccCheckGoogleStorageObject(bucketName, objectName, data_md5), + resource.TestCheckResourceAttr( + "google_storage_bucket_object.object", "cache_control", cacheControl), + ), + }, + }, + }) +} + +func TestAccGoogleStorageObject_storageClass(t *testing.T) { + bucketName := testBucketName() + data := []byte(content) + h := md5.New() + h.Write(data) + data_md5 := base64.StdEncoding.EncodeToString(h.Sum(nil)) + ioutil.WriteFile(tf.Name(), data, 0644) + + storageClass := "MULTI_REGIONAL" + resource.Test(t, resource.TestCase{ + PreCheck: func() { + if err != nil { + panic(err) + } + testAccPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccGoogleStorageObjectDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testGoogleStorageBucketsObject_storageClass(bucketName, storageClass), + Check: resource.ComposeTestCheckFunc( + testAccCheckGoogleStorageObject(bucketName, objectName, data_md5), + resource.TestCheckResourceAttr( + "google_storage_bucket_object.object", "storage_class", storageClass), + ), }, }, }) @@ -129,6 +235,7 @@ resource "google_storage_bucket_object" "object" { } `, bucketName, objectName, content) } + func testGoogleStorageBucketsObjectBasic(bucketName string) string { return fmt.Sprintf(` resource "google_storage_bucket" "bucket" { @@ -143,3 +250,52 @@ resource "google_storage_bucket_object" "object" { } `, bucketName, objectName, tf.Name()) } + +func testGoogleStorageBucketsObject_optionalContentFields( + bucketName, disposition, encoding, language, content_type string) string { + return fmt.Sprintf(` +resource "google_storage_bucket" "bucket" { + name = "%s" +} + +resource "google_storage_bucket_object" "object" { + name = "%s" + bucket = "${google_storage_bucket.bucket.name}" + content = "%s" + content_disposition = "%s" + content_encoding = "%s" + content_language = "%s" + content_type = "%s" +} +`, bucketName, objectName, content, disposition, encoding, language, content_type) +} + +func testGoogleStorageBucketsObject_cacheControl(bucketName, cacheControl string) string { + return fmt.Sprintf(` +resource "google_storage_bucket" "bucket" { + name = "%s" +} + +resource "google_storage_bucket_object" "object" { + name = "%s" + bucket = "${google_storage_bucket.bucket.name}" + source = "%s" + cache_control = "%s" +} +`, bucketName, objectName, tf.Name(), cacheControl) +} + +func testGoogleStorageBucketsObject_storageClass(bucketName string, storageClass string) string { + return fmt.Sprintf(` +resource "google_storage_bucket" "bucket" { + name = "%s" +} + +resource "google_storage_bucket_object" "object" { + name = "%s" + bucket = "${google_storage_bucket.bucket.name}" + content = "%s" + storage_class = "%s" +} +`, bucketName, objectName, content, storageClass) +} diff --git a/website/source/docs/providers/google/r/storage_bucket_object.html.markdown b/website/source/docs/providers/google/r/storage_bucket_object.html.markdown index 49f7e24e0..38a18c00c 100644 --- a/website/source/docs/providers/google/r/storage_bucket_object.html.markdown +++ b/website/source/docs/providers/google/r/storage_bucket_object.html.markdown @@ -8,7 +8,7 @@ description: |- # google\_storage\_bucket\_object -Creates a new object inside an exisiting bucket in Google cloud storage service (GCS). Currently, it does not support creating custom ACLs. For more information see [the official documentation](https://cloud.google.com/storage/docs/overview) and [API](https://cloud.google.com/storage/docs/json_api). +Creates a new object inside an existing bucket in Google cloud storage service (GCS). Currently, it does not support creating custom ACLs. For more information see [the official documentation](https://cloud.google.com/storage/docs/overview) and [API](https://cloud.google.com/storage/docs/json_api). ## Example Usage @@ -31,17 +31,33 @@ The following arguments are supported: * `name` - (Required) The name of the object. -- - - +One of the following is required: * `content` - (Optional) Data as `string` to be uploaded. Must be defined if `source` is not. +* `source` - (Optional) A path to the data you want to upload. Must be defined + if `content` is not. + +- - - + +* `cache_control` - (Optional) [Cache-Control](https://tools.ietf.org/html/rfc7234#section-5.2) + directive to specify caching behavior of object data. If omitted and object is accessible to all anonymous users, the default will be public, max-age=3600 + +* `content_disposition` - (Optional) [Content-Disposition](https://tools.ietf.org/html/rfc6266) of the object data. + +* `content_encoding` - (Optional) [Content-Encoding](https://tools.ietf.org/html/rfc7231#section-3.1.2.2) of the object data. + +* `content_language` - (Optional) [Content-Language](https://tools.ietf.org/html/rfc7231#section-3.1.3.2) of the object data. + +* `content_type` - (Optional) [Content-Type](https://tools.ietf.org/html/rfc7231#section-3.1.1.5) of the object data. Defaults to "application/octet-stream" or "text/plain; charset=utf-8". + * `predefined_acl` - (Optional, Deprecated) The [canned GCS ACL](https://cloud.google.com/storage/docs/access-control#predefined-acl) apply. Please switch to `google_storage_object_acl.predefined_acl`. - -* `source` - (Optional) A path to the data you want to upload. Must be defined - if `content` is not. +* `storage_class` - (Optional) The [StorageClass](https://cloud.google.com/storage/docs/storage-classes) of the new bucket object. + Supported values include: `MULTI_REGIONAL`, `REGIONAL`, `NEARLINE`, `COLDLINE`. If not provided, this defaults to the bucket's default + storage class or to a [standard](https://cloud.google.com/storage/docs/storage-classes#standard) class. ## Attributes Reference