Skip to content

Commit

Permalink
Add additional properties for google resource storage bucket object. R…
Browse files Browse the repository at this point in the history
…esolves hashicorp#13616.
  • Loading branch information
emilymye committed May 5, 2017
1 parent 076a67f commit abd6d23
Show file tree
Hide file tree
Showing 3 changed files with 243 additions and 13 deletions.
74 changes: 66 additions & 8 deletions builtin/providers/google/resource_storage_bucket_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,36 @@ 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,
Computed: true,
},

"content": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -62,6 +92,12 @@ func resourceStorageBucketObject() *schema.Resource {
ForceNew: true,
ConflictsWith: []string{"content"},
},

"storage_class": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},
},
}
}
Expand Down Expand Up @@ -92,6 +128,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)
Expand Down Expand Up @@ -133,6 +193,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))

Expand All @@ -151,14 +217,6 @@ func resourceStorageBucketObjectDelete(d *schema.ResourceData, meta interface{})
err := DeleteCall.Do()

if err != nil {
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
log.Printf("[WARN] Removing Bucket Object %q because it's gone", name)
// The resource doesn't exist anymore
d.SetId("")

return nil
}

return fmt.Errorf("Error deleting contents of object %s: %s", name, err)
}

Expand Down
158 changes: 157 additions & 1 deletion builtin/providers/google/resource_storage_bucket_object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 TestAccGoogleStorageObjectContent_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: testGoogleStorageBucketsObjectContent_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 TestAccGoogleStorageObjectContent_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: testGoogleStorageBucketsObjectContent_cacheControl(bucketName, cacheControl),
Check: resource.ComposeTestCheckFunc(
testAccCheckGoogleStorageObject(bucketName, objectName, data_md5),
resource.TestCheckResourceAttr(
"google_storage_bucket_object.object", "cache_control", cacheControl),
),
},
},
})
}

func TestAccGoogleStorageObjectContent_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),
),
},
},
})
Expand Down Expand Up @@ -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" {
Expand All @@ -143,3 +250,52 @@ resource "google_storage_bucket_object" "object" {
}
`, bucketName, objectName, tf.Name())
}

func testGoogleStorageBucketsObjectContent_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 testGoogleStorageBucketsObjectContent_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)
}
Original file line number Diff line number Diff line change
Expand Up @@ -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]() 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

Expand Down

0 comments on commit abd6d23

Please sign in to comment.