From 1113ed5fc705bf1f13b08cdc3c0a87af2cc531f0 Mon Sep 17 00:00:00 2001 From: Paul Stack Date: Mon, 12 Dec 2016 22:34:03 +0000 Subject: [PATCH] provider/aws: Support MFA delete for s3 bucket versioning (#10020) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #7902 ``` % make testacc TEST=./builtin/providers/aws % TESTARGS='-run=TestAccAWSS3Bucket_' % ✹ ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2016/12/12 12:11:45 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSS3Bucket_ -timeout 120m === RUN TestAccAWSS3Bucket_importBasic --- PASS: TestAccAWSS3Bucket_importBasic (55.74s) === RUN TestAccAWSS3Bucket_importWithPolicy --- PASS: TestAccAWSS3Bucket_importWithPolicy (63.34s) === RUN TestAccAWSS3Bucket_Notification --- PASS: TestAccAWSS3Bucket_Notification (165.15s) === RUN TestAccAWSS3Bucket_NotificationWithoutFilter --- PASS: TestAccAWSS3Bucket_NotificationWithoutFilter (63.22s) === RUN TestAccAWSS3Bucket_basic --- PASS: TestAccAWSS3Bucket_basic (47.82s) === RUN TestAccAWSS3Bucket_region --- PASS: TestAccAWSS3Bucket_region (18.88s) === RUN TestAccAWSS3Bucket_acceleration --- PASS: TestAccAWSS3Bucket_acceleration (34.56s) === RUN TestAccAWSS3Bucket_RequestPayer --- PASS: TestAccAWSS3Bucket_RequestPayer (90.26s) === RUN TestAccAWSS3Bucket_Policy --- PASS: TestAccAWSS3Bucket_Policy (120.25s) === RUN TestAccAWSS3Bucket_UpdateAcl --- PASS: TestAccAWSS3Bucket_UpdateAcl (87.51s) === RUN TestAccAWSS3Bucket_Website_Simple --- PASS: TestAccAWSS3Bucket_Website_Simple (138.38s) === RUN TestAccAWSS3Bucket_WebsiteRedirect --- PASS: TestAccAWSS3Bucket_WebsiteRedirect (139.44s) === RUN TestAccAWSS3Bucket_WebsiteRoutingRules --- PASS: TestAccAWSS3Bucket_WebsiteRoutingRules (97.82s) === RUN TestAccAWSS3Bucket_shouldFailNotFound --- PASS: TestAccAWSS3Bucket_shouldFailNotFound (26.84s) === RUN TestAccAWSS3Bucket_Versioning --- PASS: TestAccAWSS3Bucket_Versioning (131.89s) === RUN TestAccAWSS3Bucket_Cors --- PASS: TestAccAWSS3Bucket_Cors (92.71s) === RUN TestAccAWSS3Bucket_Logging --- PASS: TestAccAWSS3Bucket_Logging (86.46s) === RUN TestAccAWSS3Bucket_Lifecycle --- PASS: TestAccAWSS3Bucket_Lifecycle (132.70s) === RUN TestAccAWSS3Bucket_Replication --- PASS: TestAccAWSS3Bucket_Replication (122.70s) === RUN TestAccAWSS3Bucket_ReplicationExpectVersioningValidationError --- PASS: TestAccAWSS3Bucket_ReplicationExpectVersioningValidationError (39.04s) ``` --- .../providers/aws/resource_aws_s3_bucket.go | 37 +++++++++++++------ .../providers/aws/r/s3_bucket.html.markdown | 1 + 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/builtin/providers/aws/resource_aws_s3_bucket.go b/builtin/providers/aws/resource_aws_s3_bucket.go index 214878530b..9eb321bf85 100644 --- a/builtin/providers/aws/resource_aws_s3_bucket.go +++ b/builtin/providers/aws/resource_aws_s3_bucket.go @@ -147,8 +147,10 @@ func resourceAwsS3Bucket() *schema.Resource { }, "versioning": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, + Computed: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "enabled": { @@ -156,15 +158,13 @@ func resourceAwsS3Bucket() *schema.Resource { Optional: true, Default: false, }, + "mfa_delete": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, }, }, - Set: func(v interface{}) int { - var buf bytes.Buffer - m := v.(map[string]interface{}) - buf.WriteString(fmt.Sprintf("%t-", m["enabled"].(bool))) - - return hashcode.String(buf.String()) - }, }, "logging": { @@ -647,14 +647,20 @@ func resourceAwsS3BucketRead(d *schema.ResourceData, meta interface{}) error { return err } log.Printf("[DEBUG] S3 Bucket: %s, versioning: %v", d.Id(), versioning) - if versioning.Status != nil && *versioning.Status == s3.BucketVersioningStatusEnabled { + if versioning != nil { vcl := make([]map[string]interface{}, 0, 1) vc := make(map[string]interface{}) - if *versioning.Status == s3.BucketVersioningStatusEnabled { + if versioning.Status != nil && *versioning.Status == s3.BucketVersioningStatusEnabled { vc["enabled"] = true } else { vc["enabled"] = false } + + if versioning.MFADelete != nil && *versioning.MFADelete == s3.MFADeleteEnabled { + vc["mfa_delete"] = true + } else { + vc["mfa_delete"] = false + } vcl = append(vcl, vc) if err := d.Set("versioning", vcl); err != nil { return err @@ -1250,7 +1256,7 @@ func resourceAwsS3BucketAclUpdate(s3conn *s3.S3, d *schema.ResourceData) error { } func resourceAwsS3BucketVersioningUpdate(s3conn *s3.S3, d *schema.ResourceData) error { - v := d.Get("versioning").(*schema.Set).List() + v := d.Get("versioning").([]interface{}) bucket := d.Get("bucket").(string) vc := &s3.VersioningConfiguration{} @@ -1262,6 +1268,13 @@ func resourceAwsS3BucketVersioningUpdate(s3conn *s3.S3, d *schema.ResourceData) } else { vc.Status = aws.String(s3.BucketVersioningStatusSuspended) } + + if c["mfa_delete"].(bool) { + vc.MFADelete = aws.String(s3.MFADeleteEnabled) + } else { + vc.MFADelete = aws.String(s3.MFADeleteDisabled) + } + } else { vc.Status = aws.String(s3.BucketVersioningStatusSuspended) } @@ -1377,7 +1390,7 @@ func resourceAwsS3BucketReplicationConfigurationUpdate(s3conn *s3.S3, d *schema. hasVersioning := false // Validate that bucket versioning is enabled if versioning, ok := d.GetOk("versioning"); ok { - v := versioning.(*schema.Set).List() + v := versioning.([]interface{}) if v[0].(map[string]interface{})["enabled"].(bool) { hasVersioning = true diff --git a/website/source/docs/providers/aws/r/s3_bucket.html.markdown b/website/source/docs/providers/aws/r/s3_bucket.html.markdown index fce4e282fd..85e97a1246 100644 --- a/website/source/docs/providers/aws/r/s3_bucket.html.markdown +++ b/website/source/docs/providers/aws/r/s3_bucket.html.markdown @@ -316,6 +316,7 @@ The `CORS` object supports the following: The `versioning` object supports the following: * `enabled` - (Optional) Enable versioning. Once you version-enable a bucket, it can never return to an unversioned state. You can, however, suspend versioning on that bucket. +* `mfa_delete` - (Optional) Enable MFA delete for either `Change the versioning state of your bucket` or `Permanently delete an object version`. Default is `false`. The `logging` object supports the following: