Skip to content

Commit

Permalink
Allow to force s3 object content type to be able to retreive the body… (
Browse files Browse the repository at this point in the history
hashicorp#2)

* Allow to force s3 object content type to be able to retreive the body for known object content

* renamed force to forced

* Do not change the effective content type, just the interpretation of the content type to force it to be considered as text
Added the required documentation

* put the forced_content_type on data instead of resource

* fix source bucket key name
  • Loading branch information
lpbedard authored and jocgir committed Sep 5, 2017
1 parent c2c01d2 commit 734cc86
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
13 changes: 11 additions & 2 deletions aws/data_source_aws_s3_bucket_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ func dataSourceAwsS3BucketObject() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"forced_content_type": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"key": &schema.Schema{
Type: schema.TypeString,
Required: true,
Expand Down Expand Up @@ -99,7 +103,6 @@ func dataSourceAwsS3BucketObject() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},

"tags": tagsSchemaComputed(),
},
}
Expand All @@ -110,6 +113,7 @@ func dataSourceAwsS3BucketObjectRead(d *schema.ResourceData, meta interface{}) e

bucket := d.Get("bucket").(string)
key := d.Get("key").(string)
forcedContentType := d.Get("forced_content_type").(string)

input := s3.HeadObjectInput{
Bucket: aws.String(bucket),
Expand Down Expand Up @@ -139,6 +143,11 @@ func dataSourceAwsS3BucketObjectRead(d *schema.ResourceData, meta interface{}) e
bucket+key, versionText)
}

contentType := *out.ContentType
if forcedContentType == "" {
forcedContentType = contentType
}

log.Printf("[DEBUG] Received S3 object: %s", out)

d.SetId(uniqueId)
Expand Down Expand Up @@ -167,7 +176,7 @@ func dataSourceAwsS3BucketObjectRead(d *schema.ResourceData, meta interface{}) e
d.Set("storage_class", out.StorageClass)
}

if isContentTypeAllowed(out.ContentType) {
if isContentTypeAllowed(&forcedContentType) {
input := s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
Expand Down
57 changes: 57 additions & 0 deletions aws/data_source_aws_s3_bucket_object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,40 @@ func TestAccDataSourceAWSS3BucketObject_readableBody(t *testing.T) {
})
}

func TestAccDataSourceAWSS3BucketObject_forcedContentType_readableBody(t *testing.T) {
rInt := acctest.RandInt()
resourceOnlyConf, conf := testAccAWSDataSourceS3ObjectConfig_forcedContentType_readableBody(rInt)

var rObj s3.GetObjectOutput
var dsObj s3.GetObjectOutput

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
PreventPostDestroyRefresh: true,
Steps: []resource.TestStep{
resource.TestStep{
Config: resourceOnlyConf,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &rObj),
),
},
resource.TestStep{
Config: conf,
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsS3ObjectDataSourceExists("data.aws_s3_bucket_object.obj", &dsObj),
resource.TestCheckResourceAttr("data.aws_s3_bucket_object.obj", "content_length", "120"),
resource.TestCheckResourceAttr("data.aws_s3_bucket_object.obj", "content_type", "application/x-x509-ca-cert"),
resource.TestCheckResourceAttr("data.aws_s3_bucket_object.obj", "etag", "877716107971cdd406981bbbe85c97f4"),
resource.TestMatchResourceAttr("data.aws_s3_bucket_object.obj", "last_modified",
regexp.MustCompile("^[a-zA-Z]{3}, [0-9]+ [a-zA-Z]+ [0-9]{4} [0-9:]+ [A-Z]+$")),
resource.TestCheckResourceAttr("data.aws_s3_bucket_object.obj", "body", "-----BEGIN CERTIFICATE-----\nbWFpbiBDb250cm9sIFZhbGlkYXRXDDEdMBsGA1UECxMUUG9zaXRpdmVTU0wgV2ls==\n-----END CERTIFICATE-----"),
),
},
},
})
}

func TestAccDataSourceAWSS3BucketObject_kmsEncrypted(t *testing.T) {
rInt := acctest.RandInt()
resourceOnlyConf, conf := testAccAWSDataSourceS3ObjectConfig_kmsEncrypted(rInt)
Expand Down Expand Up @@ -238,6 +272,29 @@ data "aws_s3_bucket_object" "obj" {
return resources, both
}

func testAccAWSDataSourceS3ObjectConfig_forcedContentType_readableBody(randInt int) (string, string) {
resources := fmt.Sprintf(`
resource "aws_s3_bucket" "object_bucket" {
bucket = "tf-object-test-bucket-%d"
}
resource "aws_s3_bucket_object" "object" {
bucket = "${aws_s3_bucket.object_bucket.bucket}"
key = "tf-testing-obj-%d-forced-readable"
content = "-----BEGIN CERTIFICATE-----\nbWFpbiBDb250cm9sIFZhbGlkYXRXDDEdMBsGA1UECxMUUG9zaXRpdmVTU0wgV2ls==\n-----END CERTIFICATE-----"
content_type = "application/x-x509-ca-cert"
}
`, randInt, randInt)

both := fmt.Sprintf(`%s
data "aws_s3_bucket_object" "obj" {
bucket = "tf-object-test-bucket-%d"
key = "tf-testing-obj-%d-forced-readable"
forced_content_type = "text/text"
}`, resources, randInt, randInt)

return resources, both
}

func testAccAWSDataSourceS3ObjectConfig_kmsEncrypted(randInt int) (string, string) {
resources := fmt.Sprintf(`
resource "aws_s3_bucket" "object_bucket" {
Expand Down
1 change: 1 addition & 0 deletions website/docs/d/s3_bucket_object.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ The following arguments are supported:
* `bucket` - (Required) The name of the bucket to read the object from
* `key` - (Required) The full path to the object inside the bucket
* `version_id` - (Optional) Specific version ID of the object returned (defaults to latest version)
* `forced_content_type` - (Optional) Force interpretation of the resource to be of a different content type (useful to get the body of non-binary resource that are not considered as text even if they are, i.e. certificates)

## Attributes Reference

Expand Down

0 comments on commit 734cc86

Please sign in to comment.