From 2b7a13b6091bb5b8499f9c441ba92b7f23d2b90d Mon Sep 17 00:00:00 2001 From: stack72 Date: Thu, 17 Sep 2015 20:10:35 +0100 Subject: [PATCH 1/5] Adding some other simple S3 Bucket Object (Optional) Inputs --- .../aws/resource_aws_s3_bucket_object.go | 47 +++++++++++++++++-- .../aws/resource_aws_s3_bucket_object_test.go | 41 ++++++++++++++++ .../aws/r/s3_bucket_object.html.markdown | 5 ++ 3 files changed, 90 insertions(+), 3 deletions(-) diff --git a/builtin/providers/aws/resource_aws_s3_bucket_object.go b/builtin/providers/aws/resource_aws_s3_bucket_object.go index 9d46952d0..537ed3297 100644 --- a/builtin/providers/aws/resource_aws_s3_bucket_object.go +++ b/builtin/providers/aws/resource_aws_s3_bucket_object.go @@ -26,6 +26,31 @@ func resourceAwsS3BucketObject() *schema.Resource { ForceNew: true, }, + "cache_control": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + + "content_disposition": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + + "content_encoding": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + + "content_language": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + + "content_type": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "key": &schema.Schema{ Type: schema.TypeString, Required: true, @@ -52,6 +77,11 @@ func resourceAwsS3BucketObjectPut(d *schema.ResourceData, meta interface{}) erro bucket := d.Get("bucket").(string) key := d.Get("key").(string) source := d.Get("source").(string) + encoding := d.Get("content_encoding").(string) + contentType := d.Get("content_type").(string) + cacheControl := d.Get("cache_control").(string) + contentLanguage := d.Get("content_language").(string) + contentDisposition := d.Get("content_disposition").(string) file, err := os.Open(source) @@ -61,9 +91,14 @@ func resourceAwsS3BucketObjectPut(d *schema.ResourceData, meta interface{}) erro resp, err := s3conn.PutObject( &s3.PutObjectInput{ - Bucket: aws.String(bucket), - Key: aws.String(key), - Body: file, + Bucket: aws.String(bucket), + Key: aws.String(key), + Body: file, + CacheControl: aws.String(cacheControl), + ContentDisposition: aws.String(contentDisposition), + ContentEncoding: aws.String(encoding), + ContentLanguage: aws.String(contentLanguage), + ContentType: aws.String(contentType), }) if err != nil { @@ -99,6 +134,12 @@ func resourceAwsS3BucketObjectRead(d *schema.ResourceData, meta interface{}) err return err } + d.Set("cache_control", resp.CacheControl) + d.Set("content_disposition", resp.ContentDisposition) + d.Set("content_encoding", resp.ContentEncoding) + d.Set("content_language", resp.ContentLanguage) + d.Set("content_type", resp.ContentType) + log.Printf("[DEBUG] Reading S3 Bucket Object meta: %s", resp) return nil } diff --git a/builtin/providers/aws/resource_aws_s3_bucket_object_test.go b/builtin/providers/aws/resource_aws_s3_bucket_object_test.go index 4f947736a..5e1480be2 100644 --- a/builtin/providers/aws/resource_aws_s3_bucket_object_test.go +++ b/builtin/providers/aws/resource_aws_s3_bucket_object_test.go @@ -36,6 +36,31 @@ func TestAccAWSS3BucketObject_basic(t *testing.T) { }) } +func TestAccAWSS3BucketObject_withContentCharacteristics(t *testing.T) { + // first write some data to the tempfile just so it's not 0 bytes. + ioutil.WriteFile(tf.Name(), []byte("{anything will do }"), 0644) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + if err != nil { + panic(err) + } + testAccPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSS3BucketObjectDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSS3BucketObjectConfig_withContentCharacteristics, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object"), + resource.TestCheckResourceAttr( + "aws_s3_bucket_object.object", "content_type", "binary/octet-stream"), + ), + }, + }, + }) +} + func testAccCheckAWSS3BucketObjectDestroy(s *terraform.State) error { s3conn := testAccProvider.Meta().(*AWSClient).s3conn @@ -95,5 +120,21 @@ resource "aws_s3_bucket_object" "object" { bucket = "${aws_s3_bucket.object_bucket.bucket}" key = "test-key" source = "%s" + content_type = "binary/octet-stream" +} +`, randomBucket, tf.Name()) + +var testAccAWSS3BucketObjectConfig_withContentCharacteristics = fmt.Sprintf(` +resource "aws_s3_bucket" "object_bucket_2" { + bucket = "tf-object-test-bucket-%d" +} + +resource "aws_s3_bucket_object" "object" { + bucket = "${aws_s3_bucket.object_bucket_2.bucket}" + key = "test-key" + source = "%s" + content_language = "en" + content_type = "binary/octet-stream" + } `, randomBucket, tf.Name()) diff --git a/website/source/docs/providers/aws/r/s3_bucket_object.html.markdown b/website/source/docs/providers/aws/r/s3_bucket_object.html.markdown index 63d201b82..649130f80 100644 --- a/website/source/docs/providers/aws/r/s3_bucket_object.html.markdown +++ b/website/source/docs/providers/aws/r/s3_bucket_object.html.markdown @@ -29,6 +29,11 @@ The following arguments are supported: * `bucket` - (Required) The name of the bucket to put the file in. * `key` - (Required) The name of the object once it is in the bucket. * `source` - (Required) The path to the source file being uploaded to the bucket. +* `cache_control` - (Optional) Specifies caching behavior along the request/reply chain. +* `content_disposition` - (Optional) Specifies presentational information for the object. +* `content_encoding` - (Optional) Specifies what content encodings have been applied to the object and thus what decoding mechanisms must be applied to obtain the media-type referenced by the Content-Type header field. +* `content_language` - (Optional) The language the content is in. +* `content_type` - (Optional) A standard MIME type describing the format of the object data. ## Attributes Reference From 0a5387db903e1906ab625c46cd0c741687466d1b Mon Sep 17 00:00:00 2001 From: stack72 Date: Thu, 8 Oct 2015 17:24:33 +0100 Subject: [PATCH 2/5] Adding some examples of the S3 bucket object parameters as well as checking for an empty string in the new S3 bucket object params --- .../aws/resource_aws_s3_bucket_object.go | 44 ++++++++++++------- .../aws/r/s3_bucket_object.html.markdown | 10 ++--- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/builtin/providers/aws/resource_aws_s3_bucket_object.go b/builtin/providers/aws/resource_aws_s3_bucket_object.go index 537ed3297..9f2e45960 100644 --- a/builtin/providers/aws/resource_aws_s3_bucket_object.go +++ b/builtin/providers/aws/resource_aws_s3_bucket_object.go @@ -76,30 +76,40 @@ func resourceAwsS3BucketObjectPut(d *schema.ResourceData, meta interface{}) erro bucket := d.Get("bucket").(string) key := d.Get("key").(string) - source := d.Get("source").(string) - encoding := d.Get("content_encoding").(string) - contentType := d.Get("content_type").(string) - cacheControl := d.Get("cache_control").(string) - contentLanguage := d.Get("content_language").(string) - contentDisposition := d.Get("content_disposition").(string) + source := d.Get("source").(string) file, err := os.Open(source) if err != nil { return fmt.Errorf("Error opening S3 bucket object source (%s): %s", source, err) } + putInput := &s3.PutObjectInput{ + Bucket: aws.String(bucket), + Key: aws.String(key), + Body: file, + } - resp, err := s3conn.PutObject( - &s3.PutObjectInput{ - Bucket: aws.String(bucket), - Key: aws.String(key), - Body: file, - CacheControl: aws.String(cacheControl), - ContentDisposition: aws.String(contentDisposition), - ContentEncoding: aws.String(encoding), - ContentLanguage: aws.String(contentLanguage), - ContentType: aws.String(contentType), - }) + if v, ok := d.GetOk("cache_control"); ok { + putInput.CacheControl = aws.String(v.(string)) + } + + if v, ok := d.GetOk("content_type"); ok { + putInput.ContentType = aws.String(v.(string)) + } + + if v, ok := d.GetOk("content_encoding"); ok { + putInput.ContentEncoding = aws.String(v.(string)) + } + + if v, ok := d.GetOk("content_language"); ok { + putInput.ContentLanguage = aws.String(v.(string)) + } + + if v, ok := d.GetOk("content_disposition"); ok { + putInput.ContentDisposition = aws.String(v.(string)) + } + + resp, err := s3conn.PutObject(putInput) if err != nil { return fmt.Errorf("Error putting object in S3 bucket (%s): %s", bucket, err) diff --git a/website/source/docs/providers/aws/r/s3_bucket_object.html.markdown b/website/source/docs/providers/aws/r/s3_bucket_object.html.markdown index 649130f80..99c24f38c 100644 --- a/website/source/docs/providers/aws/r/s3_bucket_object.html.markdown +++ b/website/source/docs/providers/aws/r/s3_bucket_object.html.markdown @@ -29,11 +29,11 @@ The following arguments are supported: * `bucket` - (Required) The name of the bucket to put the file in. * `key` - (Required) The name of the object once it is in the bucket. * `source` - (Required) The path to the source file being uploaded to the bucket. -* `cache_control` - (Optional) Specifies caching behavior along the request/reply chain. -* `content_disposition` - (Optional) Specifies presentational information for the object. -* `content_encoding` - (Optional) Specifies what content encodings have been applied to the object and thus what decoding mechanisms must be applied to obtain the media-type referenced by the Content-Type header field. -* `content_language` - (Optional) The language the content is in. -* `content_type` - (Optional) A standard MIME type describing the format of the object data. +* `cache_control` - (Optional) Specifies caching behavior along the request/reply chain Read [w3c cache_control](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) for futher details. +* `content_disposition` - (Optional) Specifies presentational information for the object. Read [wc3 content_disposition](http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1) for further information. +* `content_encoding` - (Optional) Specifies what content encodings have been applied to the object and thus what decoding mechanisms must be applied to obtain the media-type referenced by the Content-Type header field. Read [w3c content encoding](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11) for further information. +* `content_language` - (Optional) The language the content is in e.g. en-US or en-GB. +* `content_type` - (Optional) A standard MIME type describing the format of the object data, e.g. application/octet-stream. All Valid MIME Types are valid for this input. ## Attributes Reference From 8e2163c963b1a141f61c2986ef490522aff25fd7 Mon Sep 17 00:00:00 2001 From: stack72 Date: Thu, 8 Oct 2015 18:44:59 +0100 Subject: [PATCH 3/5] Removing the S3 Bucket Object Update method. This was removed in master but seems to be broken in my branch --- builtin/providers/aws/resource_aws_s3_bucket_object.go | 1 - 1 file changed, 1 deletion(-) diff --git a/builtin/providers/aws/resource_aws_s3_bucket_object.go b/builtin/providers/aws/resource_aws_s3_bucket_object.go index 9f2e45960..3f072ebd2 100644 --- a/builtin/providers/aws/resource_aws_s3_bucket_object.go +++ b/builtin/providers/aws/resource_aws_s3_bucket_object.go @@ -16,7 +16,6 @@ func resourceAwsS3BucketObject() *schema.Resource { return &schema.Resource{ Create: resourceAwsS3BucketObjectPut, Read: resourceAwsS3BucketObjectRead, - Update: resourceAwsS3BucketObjectPut, Delete: resourceAwsS3BucketObjectDelete, Schema: map[string]*schema.Schema{ From b3010e1412a3e2b8b8193a39c55b2e58a6883747 Mon Sep 17 00:00:00 2001 From: stack72 Date: Thu, 8 Oct 2015 18:50:30 +0100 Subject: [PATCH 4/5] Because of the lack of Update, S3 Bucket Object needs to force new when changing the params --- builtin/providers/aws/resource_aws_s3_bucket_object.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/builtin/providers/aws/resource_aws_s3_bucket_object.go b/builtin/providers/aws/resource_aws_s3_bucket_object.go index 3f072ebd2..a01ab760e 100644 --- a/builtin/providers/aws/resource_aws_s3_bucket_object.go +++ b/builtin/providers/aws/resource_aws_s3_bucket_object.go @@ -28,26 +28,31 @@ func resourceAwsS3BucketObject() *schema.Resource { "cache_control": &schema.Schema{ Type: schema.TypeString, Optional: true, + ForceNew: true, }, "content_disposition": &schema.Schema{ Type: schema.TypeString, Optional: true, + ForceNew: true, }, "content_encoding": &schema.Schema{ Type: schema.TypeString, Optional: true, + ForceNew: true, }, "content_language": &schema.Schema{ Type: schema.TypeString, Optional: true, + ForceNew: true, }, "content_type": &schema.Schema{ Type: schema.TypeString, Optional: true, + ForceNew: true, }, "key": &schema.Schema{ From 080e08fb735c0793b22671d35a16045292d65c09 Mon Sep 17 00:00:00 2001 From: stack72 Date: Thu, 8 Oct 2015 23:14:34 +0100 Subject: [PATCH 5/5] Adding Computed to the Content-Type of S3 Bucket Object. Regardless of whether you set a content-type, AWS will always set a content-type --- builtin/providers/aws/resource_aws_s3_bucket_object.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builtin/providers/aws/resource_aws_s3_bucket_object.go b/builtin/providers/aws/resource_aws_s3_bucket_object.go index a01ab760e..938780d2e 100644 --- a/builtin/providers/aws/resource_aws_s3_bucket_object.go +++ b/builtin/providers/aws/resource_aws_s3_bucket_object.go @@ -53,6 +53,7 @@ func resourceAwsS3BucketObject() *schema.Resource { Type: schema.TypeString, Optional: true, ForceNew: true, + Computed: true, }, "key": &schema.Schema{