From 56dca631f704827c420e502acedaef6a44087c5b Mon Sep 17 00:00:00 2001 From: Ilia Lazebnik Date: Thu, 20 Aug 2020 22:39:37 +0300 Subject: [PATCH] resource/aws_storagegatway_smb_file_share: Add audit_destination_arn and smb_acl_enabled arguments (#13572) Output from acceptance testing: ``` --- PASS: TestAccAWSStorageGatewaySmbFileShare_KMSEncrypted (236.89s) --- PASS: TestAccAWSStorageGatewaySmbFileShare_Authentication_GuestAccess (242.87s) --- PASS: TestAccAWSStorageGatewaySmbFileShare_Tags (361.66s) --- PASS: TestAccAWSStorageGatewaySmbFileShare_audit (370.31s) --- PASS: TestAccAWSStorageGatewaySmbFileShare_ReadOnly (375.13s) --- PASS: TestAccAWSStorageGatewaySmbFileShare_RequesterPays (400.47s) --- PASS: TestAccAWSStorageGatewaySmbFileShare_ObjectACL (401.00s) --- PASS: TestAccAWSStorageGatewaySmbFileShare_KMSKeyArn (408.98s) --- PASS: TestAccAWSStorageGatewaySmbFileShare_DefaultStorageClass (409.85s) --- PASS: TestAccAWSStorageGatewaySmbFileShare_GuessMIMETypeEnabled (419.67s) --- PASS: TestAccAWSStorageGatewaySmbFileShare_Authentication_ActiveDirectory (828.73s) --- PASS: TestAccAWSStorageGatewaySmbFileShare_InvalidUserList (872.04s) --- PASS: TestAccAWSStorageGatewaySmbFileShare_smb_acl (898.73s) --- PASS: TestAccAWSStorageGatewaySmbFileShare_ValidUserList (912.84s) ``` --- ...ource_aws_storagegateway_smb_file_share.go | 98 ++++++++------ ..._aws_storagegateway_smb_file_share_test.go | 125 ++++++++++++++++++ ...toragegateway_smb_file_share.html.markdown | 2 + 3 files changed, 188 insertions(+), 37 deletions(-) diff --git a/aws/resource_aws_storagegateway_smb_file_share.go b/aws/resource_aws_storagegateway_smb_file_share.go index 1a50e9170e6..64cbe15219f 100644 --- a/aws/resource_aws_storagegateway_smb_file_share.go +++ b/aws/resource_aws_storagegateway_smb_file_share.go @@ -43,6 +43,11 @@ func resourceAwsStorageGatewaySmbFileShare() *schema.Resource { "GuestAccess", }, false), }, + "audit_destination_arn": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateArn, + }, "default_storage_class": { Type: schema.TypeString, Optional: true, @@ -123,6 +128,10 @@ func resourceAwsStorageGatewaySmbFileShare() *schema.Resource { ForceNew: true, ValidateFunc: validateArn, }, + "smb_acl_enabled": { + Type: schema.TypeBool, + Optional: true, + }, "valid_user_list": { Type: schema.TypeSet, Optional: true, @@ -157,6 +166,14 @@ func resourceAwsStorageGatewaySmbFileShareCreate(d *schema.ResourceData, meta in input.KMSKey = aws.String(v.(string)) } + if v, ok := d.GetOk("audit_destination_arn"); ok && v.(string) != "" { + input.AuditDestinationARN = aws.String(v.(string)) + } + + if v, ok := d.GetOk("smb_acl_enabled"); ok { + input.SMBACLEnabled = aws.Bool(v.(bool)) + } + log.Printf("[DEBUG] Creating Storage Gateway SMB File Share: %s", input) output, err := conn.CreateSMBFileShare(input) if err != nil { @@ -216,7 +233,7 @@ func resourceAwsStorageGatewaySmbFileShareRead(d *schema.ResourceData, meta inte d.Set("gateway_arn", fileshare.GatewayARN) d.Set("guess_mime_type_enabled", fileshare.GuessMIMETypeEnabled) - if err := d.Set("invalid_user_list", schema.NewSet(schema.HashString, flattenStringList(fileshare.InvalidUserList))); err != nil { + if err := d.Set("invalid_user_list", flattenStringSet(fileshare.InvalidUserList)); err != nil { return fmt.Errorf("error setting invalid_user_list: %s", err) } @@ -228,16 +245,14 @@ func resourceAwsStorageGatewaySmbFileShareRead(d *schema.ResourceData, meta inte d.Set("read_only", fileshare.ReadOnly) d.Set("requester_pays", fileshare.RequesterPays) d.Set("role_arn", fileshare.Role) + d.Set("audit_destination_arn", fileshare.AuditDestinationARN) + d.Set("smb_acl_enabled", fileshare.SMBACLEnabled) - if err := d.Set("valid_user_list", schema.NewSet(schema.HashString, flattenStringList(fileshare.ValidUserList))); err != nil { + if err := d.Set("valid_user_list", flattenStringSet(fileshare.ValidUserList)); err != nil { return fmt.Errorf("error setting valid_user_list: %s", err) } - tags, err := keyvaluetags.StoragegatewayListTags(conn, *arn) - if err != nil { - return fmt.Errorf("error listing tags for resource (%s): %s", *arn, err) - } - if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + if err := d.Set("tags", keyvaluetags.StoragegatewayKeyValueTags(fileshare.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { return fmt.Errorf("error setting tags: %s", err) } @@ -254,39 +269,48 @@ func resourceAwsStorageGatewaySmbFileShareUpdate(d *schema.ResourceData, meta in } } - input := &storagegateway.UpdateSMBFileShareInput{ - DefaultStorageClass: aws.String(d.Get("default_storage_class").(string)), - FileShareARN: aws.String(d.Id()), - GuessMIMETypeEnabled: aws.Bool(d.Get("guess_mime_type_enabled").(bool)), - InvalidUserList: expandStringSet(d.Get("invalid_user_list").(*schema.Set)), - KMSEncrypted: aws.Bool(d.Get("kms_encrypted").(bool)), - ObjectACL: aws.String(d.Get("object_acl").(string)), - ReadOnly: aws.Bool(d.Get("read_only").(bool)), - RequesterPays: aws.Bool(d.Get("requester_pays").(bool)), - ValidUserList: expandStringSet(d.Get("valid_user_list").(*schema.Set)), - } + if d.HasChanges("default_storage_class", "guess_mime_type_enabled", "invalid_user_list", + "kms_encrypted", "object_acl", "read_only", "requester_pays", "requester_pays", + "valid_user_list", "kms_key_arn", "audit_destination_arn", "smb_acl_enabled") { + input := &storagegateway.UpdateSMBFileShareInput{ + DefaultStorageClass: aws.String(d.Get("default_storage_class").(string)), + FileShareARN: aws.String(d.Id()), + GuessMIMETypeEnabled: aws.Bool(d.Get("guess_mime_type_enabled").(bool)), + InvalidUserList: expandStringSet(d.Get("invalid_user_list").(*schema.Set)), + KMSEncrypted: aws.Bool(d.Get("kms_encrypted").(bool)), + ObjectACL: aws.String(d.Get("object_acl").(string)), + ReadOnly: aws.Bool(d.Get("read_only").(bool)), + RequesterPays: aws.Bool(d.Get("requester_pays").(bool)), + ValidUserList: expandStringSet(d.Get("valid_user_list").(*schema.Set)), + SMBACLEnabled: aws.Bool(d.Get("smb_acl_enabled").(bool)), + } - if v, ok := d.GetOk("kms_key_arn"); ok && v.(string) != "" { - input.KMSKey = aws.String(v.(string)) - } + if v, ok := d.GetOk("kms_key_arn"); ok && v.(string) != "" { + input.KMSKey = aws.String(v.(string)) + } - log.Printf("[DEBUG] Updating Storage Gateway SMB File Share: %s", input) - _, err := conn.UpdateSMBFileShare(input) - if err != nil { - return fmt.Errorf("error updating Storage Gateway SMB File Share: %s", err) - } + if v, ok := d.GetOk("audit_destination_arn"); ok && v.(string) != "" { + input.AuditDestinationARN = aws.String(v.(string)) + } - stateConf := &resource.StateChangeConf{ - Pending: []string{"UPDATING"}, - Target: []string{"AVAILABLE"}, - Refresh: storageGatewaySmbFileShareRefreshFunc(d.Id(), conn), - Timeout: d.Timeout(schema.TimeoutUpdate), - Delay: 5 * time.Second, - MinTimeout: 5 * time.Second, - } - _, err = stateConf.WaitForState() - if err != nil { - return fmt.Errorf("error waiting for Storage Gateway SMB File Share update: %s", err) + log.Printf("[DEBUG] Updating Storage Gateway SMB File Share: %s", input) + _, err := conn.UpdateSMBFileShare(input) + if err != nil { + return fmt.Errorf("error updating Storage Gateway SMB File Share: %s", err) + } + + stateConf := &resource.StateChangeConf{ + Pending: []string{"UPDATING"}, + Target: []string{"AVAILABLE"}, + Refresh: storageGatewaySmbFileShareRefreshFunc(d.Id(), conn), + Timeout: d.Timeout(schema.TimeoutUpdate), + Delay: 5 * time.Second, + MinTimeout: 5 * time.Second, + } + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf("error waiting for Storage Gateway SMB File Share update: %s", err) + } } return resourceAwsStorageGatewaySmbFileShareRead(d, meta) diff --git a/aws/resource_aws_storagegateway_smb_file_share_test.go b/aws/resource_aws_storagegateway_smb_file_share_test.go index 394a5c9cae6..21f7529a6e1 100644 --- a/aws/resource_aws_storagegateway_smb_file_share_test.go +++ b/aws/resource_aws_storagegateway_smb_file_share_test.go @@ -462,6 +462,81 @@ func TestAccAWSStorageGatewaySmbFileShare_ValidUserList(t *testing.T) { }) } +func TestAccAWSStorageGatewaySmbFileShare_smb_acl(t *testing.T) { + var smbFileShare storagegateway.SMBFileShareInfo + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_storagegateway_smb_file_share.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSStorageGatewaySmbFileShareDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSStorageGatewaySmbFileShareSMBACLConfig(rName, true), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSStorageGatewaySmbFileShareExists(resourceName, &smbFileShare), + resource.TestCheckResourceAttr(resourceName, "smb_acl_enabled", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSStorageGatewaySmbFileShareSMBACLConfig(rName, false), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSStorageGatewaySmbFileShareExists(resourceName, &smbFileShare), + resource.TestCheckResourceAttr(resourceName, "smb_acl_enabled", "false"), + ), + }, + { + Config: testAccAWSStorageGatewaySmbFileShareSMBACLConfig(rName, true), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSStorageGatewaySmbFileShareExists(resourceName, &smbFileShare), + resource.TestCheckResourceAttr(resourceName, "smb_acl_enabled", "true"), + ), + }, + }, + }) +} + +func TestAccAWSStorageGatewaySmbFileShare_audit(t *testing.T) { + var smbFileShare storagegateway.SMBFileShareInfo + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_storagegateway_smb_file_share.test" + logResourceName := "aws_cloudwatch_log_group.test" + logResourceNameSecond := "aws_cloudwatch_log_group.test2" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSStorageGatewaySmbFileShareDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSStorageGatewaySmbFileShareAuditDestinationConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSStorageGatewaySmbFileShareExists(resourceName, &smbFileShare), + resource.TestCheckResourceAttrPair(resourceName, "audit_destination_arn", logResourceName, "arn"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSStorageGatewaySmbFileShareAuditDestinationUpdatedConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSStorageGatewaySmbFileShareExists(resourceName, &smbFileShare), + resource.TestCheckResourceAttrPair(resourceName, "audit_destination_arn", logResourceNameSecond, "arn"), + ), + }, + }, + }) +} + func testAccCheckAWSStorageGatewaySmbFileShareDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).storagegatewayconn @@ -852,3 +927,53 @@ resource "aws_storagegateway_smb_file_share" "test" { } `, tagKey1, tagValue1, tagKey2, tagValue2) } + +func testAccAWSStorageGatewaySmbFileShareSMBACLConfig(rName string, enabled bool) string { + return testAccAWSStorageGateway_SmbFileShare_ActiveDirectoryBase(rName) + fmt.Sprintf(` +resource "aws_storagegateway_smb_file_share" "test" { + authentication = "ActiveDirectory" + gateway_arn = "${aws_storagegateway_gateway.test.arn}" + location_arn = "${aws_s3_bucket.test.arn}" + role_arn = "${aws_iam_role.test.arn}" + smb_acl_enabled = %[1]t +} +`, enabled) +} + +func testAccAWSStorageGatewaySmbFileShareAuditDestinationConfig(rName string) string { + return testAccAWSStorageGateway_SmbFileShare_GuestAccessBase(rName) + fmt.Sprintf(` +resource "aws_cloudwatch_log_group" "test" { + name = %[1]q +} + +resource "aws_storagegateway_smb_file_share" "test" { + # Use GuestAccess to simplify testing + authentication = "GuestAccess" + gateway_arn = "${aws_storagegateway_gateway.test.arn}" + location_arn = "${aws_s3_bucket.test.arn}" + role_arn = "${aws_iam_role.test.arn}" + audit_destination_arn = "${aws_cloudwatch_log_group.test.arn}" +} +`, rName) +} + +func testAccAWSStorageGatewaySmbFileShareAuditDestinationUpdatedConfig(rName string) string { + return testAccAWSStorageGateway_SmbFileShare_GuestAccessBase(rName) + fmt.Sprintf(` +resource "aws_cloudwatch_log_group" "test" { + name = %[1]q +} + +resource "aws_cloudwatch_log_group" "test2" { + name = "%[1]s-updated" +} + +resource "aws_storagegateway_smb_file_share" "test" { + # Use GuestAccess to simplify testing + authentication = "GuestAccess" + gateway_arn = "${aws_storagegateway_gateway.test.arn}" + location_arn = "${aws_s3_bucket.test.arn}" + role_arn = "${aws_iam_role.test.arn}" + audit_destination_arn = "${aws_cloudwatch_log_group.test2.arn}" +} +`, rName) +} diff --git a/website/docs/r/storagegateway_smb_file_share.html.markdown b/website/docs/r/storagegateway_smb_file_share.html.markdown index 60dd01fef55..7e63be65997 100644 --- a/website/docs/r/storagegateway_smb_file_share.html.markdown +++ b/website/docs/r/storagegateway_smb_file_share.html.markdown @@ -46,6 +46,7 @@ The following arguments are supported: * `location_arn` - (Required) The ARN of the backed storage used for storing file data. * `role_arn` - (Required) The ARN of the AWS Identity and Access Management (IAM) role that a file gateway assumes when it accesses the underlying storage. * `authentication` - (Optional) The authentication method that users use to access the file share. Defaults to `ActiveDirectory`. Valid values: `ActiveDirectory`, `GuestAccess`. +* `audit_destination_arn` - (Optional) The Amazon Resource Name (ARN) of the CloudWatch Log Group used for the audit logs. * `default_storage_class` - (Optional) The default storage class for objects put into an Amazon S3 bucket by the file gateway. Defaults to `S3_STANDARD`. Valid values: `S3_STANDARD`, `S3_STANDARD_IA`, `S3_ONEZONE_IA`. * `guess_mime_type_enabled` - (Optional) Boolean value that enables guessing of the MIME type for uploaded objects based on file extensions. Defaults to `true`. * `invalid_user_list` - (Optional) A list of users in the Active Directory that are not allowed to access the file share. Only valid if `authentication` is set to `ActiveDirectory`. @@ -55,6 +56,7 @@ The following arguments are supported: * `object_acl` - (Optional) Access Control List permission for S3 bucket objects. Defaults to `private`. * `read_only` - (Optional) Boolean to indicate write status of file share. File share does not accept writes if `true`. Defaults to `false`. * `requester_pays` - (Optional) Boolean who pays the cost of the request and the data download from the Amazon S3 bucket. Set this value to `true` if you want the requester to pay instead of the bucket owner. Defaults to `false`. +* `smb_acl_enabled` - (Optional) Set this value to `true` to enable ACL (access control list) on the SMB fileshare. Set it to `false` to map file and directory permissions to the POSIX permissions. This setting applies only to `ActiveDirectory` authentication type. * `valid_user_list` - (Optional) A list of users in the Active Directory that are allowed to access the file share. Only valid if `authentication` is set to `ActiveDirectory`. * `tags` - (Optional) Key-value map of resource tags