diff --git a/aws/resource_aws_transfer_user.go b/aws/resource_aws_transfer_user.go index bff0e39b125e..2142c52d73cf 100644 --- a/aws/resource_aws_transfer_user.go +++ b/aws/resource_aws_transfer_user.go @@ -37,6 +37,32 @@ func resourceAwsTransferUser() *schema.Resource { ValidateFunc: validation.StringLenBetween(0, 1024), }, + "home_directory_mappings": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "entry": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(0, 1024), + }, + "target": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(0, 1024), + }, + }, + }, + }, + + "home_directory_type": { + Type: schema.TypeString, + Optional: true, + Default: transfer.HomeDirectoryTypePath, + ValidateFunc: validation.StringInSlice([]string{transfer.HomeDirectoryTypePath, transfer.HomeDirectoryTypeLogical}, false), + }, + "policy": { Type: schema.TypeString, Optional: true, @@ -84,6 +110,14 @@ func resourceAwsTransferUserCreate(d *schema.ResourceData, meta interface{}) err createOpts.HomeDirectory = aws.String(attr.(string)) } + if attr, ok := d.GetOk("home_directory_type"); ok { + createOpts.HomeDirectoryType = aws.String(attr.(string)) + } + + if attr, ok := d.GetOk("home_directory_mappings"); ok { + createOpts.HomeDirectoryMappings = expandAwsTransferHomeDirectoryMappings(attr.([]interface{})) + } + if attr, ok := d.GetOk("policy"); ok { createOpts.Policy = aws.String(attr.(string)) } @@ -134,9 +168,14 @@ func resourceAwsTransferUserRead(d *schema.ResourceData, meta interface{}) error d.Set("user_name", resp.User.UserName) d.Set("arn", resp.User.Arn) d.Set("home_directory", resp.User.HomeDirectory) + d.Set("home_directory_type", resp.User.HomeDirectoryType) d.Set("policy", resp.User.Policy) d.Set("role", resp.User.Role) + if err := d.Set("home_directory_mappings", flattenAwsTransferHomeDirectoryMappings(resp.User.HomeDirectoryMappings)); err != nil { + return fmt.Errorf("Error setting home_directory_mappings: %s", err) + } + if err := d.Set("tags", keyvaluetags.TransferKeyValueTags(resp.User.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { return fmt.Errorf("Error setting tags: %s", err) } @@ -161,6 +200,16 @@ func resourceAwsTransferUserUpdate(d *schema.ResourceData, meta interface{}) err updateFlag = true } + if d.HasChange("home_directory_mappings") { + updateOpts.HomeDirectoryMappings = expandAwsTransferHomeDirectoryMappings(d.Get("home_directory_mappings").([]interface{})) + updateFlag = true + } + + if d.HasChange("home_directory_type") { + updateOpts.HomeDirectoryType = aws.String(d.Get("home_directory_type").(string)) + updateFlag = true + } + if d.HasChange("policy") { updateOpts.Policy = aws.String(d.Get("policy").(string)) updateFlag = true @@ -261,3 +310,31 @@ func waitForTransferUserDeletion(conn *transfer.Transfer, serverID, userName str } return nil } + +func expandAwsTransferHomeDirectoryMappings(in []interface{}) []*transfer.HomeDirectoryMapEntry { + mappings := make([]*transfer.HomeDirectoryMapEntry, 0) + + for _, tConfig := range in { + config := tConfig.(map[string]interface{}) + + m := &transfer.HomeDirectoryMapEntry{ + Entry: aws.String(config["entry"].(string)), + Target: aws.String(config["target"].(string)), + } + + mappings = append(mappings, m) + } + + return mappings +} + +func flattenAwsTransferHomeDirectoryMappings(mappings []*transfer.HomeDirectoryMapEntry) []interface{} { + l := make([]interface{}, len(mappings)) + for i, m := range mappings { + l[i] = map[string]interface{}{ + "entry": aws.StringValue(m.Entry), + "target": aws.StringValue(m.Target), + } + } + return l +} diff --git a/aws/resource_aws_transfer_user_test.go b/aws/resource_aws_transfer_user_test.go index 4cb4d35ad976..74a153e82718 100644 --- a/aws/resource_aws_transfer_user_test.go +++ b/aws/resource_aws_transfer_user_test.go @@ -156,6 +156,40 @@ func TestAccAWSTransferUser_UserName_Validation(t *testing.T) { }) } +func TestAccAWSTransferUser_homeDirectoryMappings(t *testing.T) { + var conf transfer.DescribedUser + rName := acctest.RandString(10) + resourceName := "aws_transfer_user.foo" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSTransfer(t) }, + IDRefreshName: resourceName, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSTransferUserDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSTransferUserConfig_homeDirectoryMappings(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSTransferUserExists(resourceName, &conf), + resource.TestCheckResourceAttr(resourceName, "home_directory_mappings.#", "1"), + ), + }, + { + Config: testAccAWSTransferUserConfig_homeDirectoryMappingsUpdate(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSTransferUserExists(resourceName, &conf), + resource.TestCheckResourceAttr(resourceName, "home_directory_mappings.#", "2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccCheckAWSTransferUserExists(n string, res *transfer.DescribedUser) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -233,8 +267,7 @@ func testAccCheckAWSTransferUserDestroy(s *terraform.State) error { return nil } -func testAccAWSTransferUserConfig_basic(rName string) string { - return fmt.Sprintf(` +const testAccAWSTransferUserConfig_base = ` resource "aws_transfer_server" "foo" { identity_provider_type = "SERVICE_MANAGED" @@ -242,6 +275,10 @@ resource "aws_transfer_server" "foo" { NAME = "tf-acc-test-transfer-server" } } +` + +func testAccAWSTransferUserConfig_basic(rName string) string { + return testAccAWSTransferUserConfig_base + fmt.Sprintf(` resource "aws_iam_role" "foo" { name = "tf-test-transfer-user-iam-role-%s" @@ -292,14 +329,7 @@ resource "aws_transfer_user" "foo" { } func testAccAWSTransferUserName_validation(rName string) string { - return fmt.Sprintf(` -resource "aws_transfer_server" "foo" { - identity_provider_type = "SERVICE_MANAGED" - - tags = { - NAME = "tf-acc-test-transfer-server" - } -} + return testAccAWSTransferUserConfig_base + fmt.Sprintf(` resource "aws_transfer_user" "foo" { server_id = "${aws_transfer_server.foo.id}" @@ -329,14 +359,7 @@ EOF } func testAccAWSTransferUserConfig_options(rName string) string { - return fmt.Sprintf(` -resource "aws_transfer_server" "foo" { - identity_provider_type = "SERVICE_MANAGED" - - tags = { - NAME = "tf-acc-test-transfer-server" - } -} + return testAccAWSTransferUserConfig_base + fmt.Sprintf(` resource "aws_iam_role" "foo" { name = "tf-test-transfer-user-iam-role-%s" @@ -438,14 +461,7 @@ resource "aws_transfer_user" "foo" { } func testAccAWSTransferUserConfig_modify(rName string) string { - return fmt.Sprintf(` -resource "aws_transfer_server" "foo" { - identity_provider_type = "SERVICE_MANAGED" - - tags = { - NAME = "tf-acc-test-transfer-server" - } -} + return testAccAWSTransferUserConfig_base + fmt.Sprintf(` resource "aws_iam_role" "foo" { name = "tf-test-transfer-user-iam-role-%s" @@ -544,14 +560,7 @@ resource "aws_transfer_user" "foo" { } func testAccAWSTransferUserConfig_forceNew(rName string) string { - return fmt.Sprintf(` -resource "aws_transfer_server" "foo" { - identity_provider_type = "SERVICE_MANAGED" - - tags = { - NAME = "tf-acc-test-transfer-server" - } -} + return testAccAWSTransferUserConfig_base + fmt.Sprintf(` resource "aws_iam_role" "foo" { name = "tf-test-transfer-user-iam-role-%s" @@ -650,3 +659,122 @@ resource "aws_transfer_user" "foo" { } `, rName, rName) } + +func testAccAWSTransferUserConfig_homeDirectoryMappings(rName string) string { + return testAccAWSTransferUserConfig_base + fmt.Sprintf(` + +resource "aws_iam_role" "foo" { + name = "tf-test-transfer-user-iam-role-%s" + + assume_role_policy = <