From 8a81511a7c55b6c1aa1d66e4d4d1b56fcbf7ba67 Mon Sep 17 00:00:00 2001 From: Manuel Zapf Date: Tue, 14 May 2019 11:03:44 +0200 Subject: [PATCH 1/2] load email sending account from config and use it --- aws/resource_aws_cognito_user_pool.go | 27 ++++++++++++++++-- aws/resource_aws_cognito_user_pool_test.go | 33 ++++++++++++++-------- aws/structure.go | 4 +++ website/docs/r/cognito_user_pool.markdown | 1 + 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/aws/resource_aws_cognito_user_pool.go b/aws/resource_aws_cognito_user_pool.go index 6b7548140da..a3190206e80 100644 --- a/aws/resource_aws_cognito_user_pool.go +++ b/aws/resource_aws_cognito_user_pool.go @@ -131,6 +131,7 @@ func resourceAwsCognitoUserPool() *schema.Resource { Type: schema.TypeList, Optional: true, MaxItems: 1, + Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "reply_to_email_address": { @@ -143,6 +144,15 @@ func resourceAwsCognitoUserPool() *schema.Resource { Optional: true, ValidateFunc: validateArn, }, + "email_sending_account": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + cognitoidentityprovider.EmailSendingAccountTypeCognitoDefault, + cognitoidentityprovider.EmailSendingAccountTypeDeveloper, + }, false), + }, }, }, }, @@ -529,6 +539,10 @@ func resourceAwsCognitoUserPoolCreate(d *schema.ResourceData, meta interface{}) emailConfigurationType.SourceArn = aws.String(v.(string)) } + if v, ok := config["email_sending_account"]; ok && v.(string) != "" { + emailConfigurationType.EmailSendingAccount = aws.String(v.(string)) + } + params.EmailConfiguration = emailConfigurationType } } @@ -723,8 +737,10 @@ func resourceAwsCognitoUserPoolRead(d *schema.ResourceData, meta interface{}) er return fmt.Errorf("Failed setting device_configuration: %s", err) } - if err := d.Set("email_configuration", flattenCognitoUserPoolEmailConfiguration(resp.UserPool.EmailConfiguration)); err != nil { - return fmt.Errorf("Failed setting email_configuration: %s", err) + if resp.UserPool.EmailConfiguration != nil { + if err := d.Set("email_configuration", flattenCognitoUserPoolEmailConfiguration(resp.UserPool.EmailConfiguration)); err != nil { + return fmt.Errorf("Failed setting email_configuration: %s", err) + } } if resp.UserPool.Policies != nil && resp.UserPool.Policies.PasswordPolicy != nil { @@ -795,10 +811,13 @@ func resourceAwsCognitoUserPoolUpdate(d *schema.ResourceData, meta interface{}) } if v, ok := d.GetOk("email_configuration"); ok { + configs := v.([]interface{}) config, ok := configs[0].(map[string]interface{}) + if ok && config != nil { + log.Printf("[DEBUG] Set Values to update from configs") emailConfigurationType := &cognitoidentityprovider.EmailConfigurationType{} if v, ok := config["reply_to_email_address"]; ok && v.(string) != "" { @@ -809,6 +828,10 @@ func resourceAwsCognitoUserPoolUpdate(d *schema.ResourceData, meta interface{}) emailConfigurationType.SourceArn = aws.String(v.(string)) } + if v, ok := config["email_sending_account"]; ok && v.(string) != "" { + emailConfigurationType.EmailSendingAccount = aws.String(v.(string)) + } + params.EmailConfiguration = emailConfigurationType } } diff --git a/aws/resource_aws_cognito_user_pool_test.go b/aws/resource_aws_cognito_user_pool_test.go index aee5238545d..6a06b7c4a53 100644 --- a/aws/resource_aws_cognito_user_pool_test.go +++ b/aws/resource_aws_cognito_user_pool_test.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "log" + "os" "regexp" "testing" @@ -270,6 +271,12 @@ func TestAccAWSCognitoUserPool_withSmsVerificationMessage(t *testing.T) { func TestAccAWSCognitoUserPool_withEmailConfiguration(t *testing.T) { name := acctest.RandString(5) + replyTo := fmt.Sprintf("tf-acc-reply-%s@terraformtesting.com", name) + + sourceARN, ok := os.LookupEnv("TEST_AWS_SES_VERIFIED_EMAIL_ARN") + if !ok { + t.Skip("'TEST_AWS_SES_VERIFIED_EMAIL_ARN' not set, skipping test.") + } resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSCognitoIdentityProvider(t) }, @@ -283,10 +290,12 @@ func TestAccAWSCognitoUserPool_withEmailConfiguration(t *testing.T) { ), }, { - Config: testAccAWSCognitoUserPoolConfig_withEmailConfiguration(name), + Config: testAccAWSCognitoUserPoolConfig_withEmailConfiguration(name, replyTo, sourceARN, "DEVELOPER"), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr("aws_cognito_user_pool.pool", "email_configuration.#", "1"), - resource.TestCheckResourceAttr("aws_cognito_user_pool.pool", "email_configuration.0.reply_to_email_address", "foo.bar@baz"), + resource.TestCheckResourceAttr("aws_cognito_user_pool.pool", "email_configuration.0.reply_to_email_address", replyTo), + resource.TestCheckResourceAttr("aws_cognito_user_pool.pool", "email_configuration.0.email_sending_account", "DEVELOPER"), + resource.TestCheckResourceAttr("aws_cognito_user_pool.pool", "email_configuration.0.source_arn", sourceARN), ), }, }, @@ -857,16 +866,18 @@ resource "aws_cognito_user_pool" "pool" { `, name) } -func testAccAWSCognitoUserPoolConfig_withEmailConfiguration(name string) string { +func testAccAWSCognitoUserPoolConfig_withEmailConfiguration(name, email, arn, account string) string { return fmt.Sprintf(` -resource "aws_cognito_user_pool" "pool" { - name = "terraform-test-pool-%s" - - email_configuration { - reply_to_email_address = "foo.bar@baz" - } -} -`, name) +resource "aws_cognito_user_pool" "pool" { + name = "terraform-test-pool-%[1]s" + + + email_configuration { + reply_to_email_address = %[2]q + source_arn = %[3]q + email_sending_account = %[4]q + } + }`, name, email, arn, account) } func testAccAWSCognitoUserPoolConfig_withSmsConfiguration(name string) string { diff --git a/aws/structure.go b/aws/structure.go index 159c077eeac..1a5aaa5d10e 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -2464,6 +2464,10 @@ func flattenCognitoUserPoolEmailConfiguration(s *cognitoidentityprovider.EmailCo m["source_arn"] = *s.SourceArn } + if s.EmailSendingAccount != nil { + m["email_sending_account"] = *s.EmailSendingAccount + } + if len(m) > 0 { return []map[string]interface{}{m} } diff --git a/website/docs/r/cognito_user_pool.markdown b/website/docs/r/cognito_user_pool.markdown index 8d4f90fe309..e0c2866ecb0 100644 --- a/website/docs/r/cognito_user_pool.markdown +++ b/website/docs/r/cognito_user_pool.markdown @@ -65,6 +65,7 @@ The following arguments are supported: * `reply_to_email_address` (Optional) - The REPLY-TO email address. * `source_arn` (Optional) - The ARN of the email source. + * `email_sending_account` (Optional) - Instruct Cognito to either use its built-in functional or Amazon SES to send out emails. #### Lambda Configuration From b8d2892143e09afc6f2125e6550a6c72745ac40a Mon Sep 17 00:00:00 2001 From: nywilken Date: Fri, 7 Jun 2019 13:21:50 -0400 Subject: [PATCH 2/2] resource/aws_cognito_user_pool: Fix email_configuration validation * Update validation for reply_to_address to allow for empty strings to fix issues around drift detection. * Replace email validation with an inline validation func within the resource. * Update email_configuration tests to test both Cognito Email constant types. Acceptance tests after change ``` --- PASS: TestAccAWSCognitoUserPool_basic (17.29s) --- PASS: TestAccAWSCognitoUserPool_importBasic (19.75s) --- PASS: TestAccAWSCognitoUserPool_withVerificationMessageTemplate (28.54s) --- PASS: TestAccAWSCognitoUserPool_withEmailConfiguration (29.14s) --- PASS: TestAccAWSCognitoUserPool_withAdminCreateUserConfiguration (29.14s) --- PASS: TestAccAWSCognitoUserPool_withTags (29.93s) --- PASS: TestAccAWSCognitoUserPool_withPasswordPolicy (29.96s) --- PASS: TestAccAWSCognitoUserPool_withDeviceConfiguration (30.86s) --- PASS: TestAccAWSCognitoUserPool_withEmailVerificationMessage (30.90s) --- PASS: TestAccAWSCognitoUserPool_withAliasAttributes (30.98s) --- PASS: TestAccAWSCognitoUserPool_withSchemaAttributes (32.96s) --- PASS: TestAccAWSCognitoUserPool_withSmsConfiguration (35.26s) --- PASS: TestAccAWSCognitoUserPool_withSmsVerificationMessage (35.92s) --- PASS: TestAccAWSCognitoUserPool_withAdvancedSecurityMode (41.35s) --- PASS: TestAccAWSCognitoUserPool_withSmsConfigurationUpdated (46.93s) --- PASS: TestAccAWSCognitoUserPool_withLambdaConfig (53.77s) --- PASS: TestAccAWSCognitoUserPool_update (58.74s) ``` --- aws/resource_aws_cognito_user_pool.go | 22 ++++++++++-------- aws/resource_aws_cognito_user_pool_test.go | 24 +++++++++++--------- aws/validators.go | 10 --------- aws/validators_test.go | 26 ---------------------- 4 files changed, 26 insertions(+), 56 deletions(-) diff --git a/aws/resource_aws_cognito_user_pool.go b/aws/resource_aws_cognito_user_pool.go index a3190206e80..6b31bbee3b2 100644 --- a/aws/resource_aws_cognito_user_pool.go +++ b/aws/resource_aws_cognito_user_pool.go @@ -3,6 +3,7 @@ package aws import ( "fmt" "log" + "regexp" "time" "github.com/aws/aws-sdk-go/aws" @@ -128,16 +129,20 @@ func resourceAwsCognitoUserPool() *schema.Resource { }, "email_configuration": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Computed: true, + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + DiffSuppressFunc: suppressMissingOptionalConfigurationBlock, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "reply_to_email_address": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validateCognitoUserPoolReplyEmailAddress, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.Any( + validation.StringInSlice([]string{""}, false), + validation.StringMatch(regexp.MustCompile(`[\p{L}\p{M}\p{S}\p{N}\p{P}]+@[\p{L}\p{M}\p{S}\p{N}\p{P}]+`), + `must satisfy regular expression pattern: [\p{L}\p{M}\p{S}\p{N}\p{P}]+@[\p{L}\p{M}\p{S}\p{N}\p{P}]+`), + ), }, "source_arn": { Type: schema.TypeString, @@ -147,7 +152,7 @@ func resourceAwsCognitoUserPool() *schema.Resource { "email_sending_account": { Type: schema.TypeString, Optional: true, - Computed: true, + Default: cognitoidentityprovider.EmailSendingAccountTypeCognitoDefault, ValidateFunc: validation.StringInSlice([]string{ cognitoidentityprovider.EmailSendingAccountTypeCognitoDefault, cognitoidentityprovider.EmailSendingAccountTypeDeveloper, @@ -815,7 +820,6 @@ func resourceAwsCognitoUserPoolUpdate(d *schema.ResourceData, meta interface{}) configs := v.([]interface{}) config, ok := configs[0].(map[string]interface{}) - if ok && config != nil { log.Printf("[DEBUG] Set Values to update from configs") emailConfigurationType := &cognitoidentityprovider.EmailConfigurationType{} diff --git a/aws/resource_aws_cognito_user_pool_test.go b/aws/resource_aws_cognito_user_pool_test.go index 6a06b7c4a53..e3861f3d621 100644 --- a/aws/resource_aws_cognito_user_pool_test.go +++ b/aws/resource_aws_cognito_user_pool_test.go @@ -284,9 +284,11 @@ func TestAccAWSCognitoUserPool_withEmailConfiguration(t *testing.T) { CheckDestroy: testAccCheckAWSCognitoUserPoolDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSCognitoUserPoolConfig_basic(name), + Config: testAccAWSCognitoUserPoolConfig_withEmailConfiguration(name, "", "", "COGNITO_DEFAULT"), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSCognitoUserPoolExists("aws_cognito_user_pool.pool"), + resource.TestCheckResourceAttr("aws_cognito_user_pool.pool", "email_configuration.#", "1"), + resource.TestCheckResourceAttr("aws_cognito_user_pool.pool", "email_configuration.0.reply_to_email_address", ""), + resource.TestCheckResourceAttr("aws_cognito_user_pool.pool", "email_configuration.0.email_sending_account", "COGNITO_DEFAULT"), ), }, { @@ -868,15 +870,15 @@ resource "aws_cognito_user_pool" "pool" { func testAccAWSCognitoUserPoolConfig_withEmailConfiguration(name, email, arn, account string) string { return fmt.Sprintf(` -resource "aws_cognito_user_pool" "pool" { - name = "terraform-test-pool-%[1]s" - - - email_configuration { - reply_to_email_address = %[2]q - source_arn = %[3]q - email_sending_account = %[4]q - } +resource "aws_cognito_user_pool" "pool" { + name = "terraform-test-pool-%[1]s" + + + email_configuration { + reply_to_email_address = %[2]q + source_arn = %[3]q + email_sending_account = %[4]q + } }`, name, email, arn, account) } diff --git a/aws/validators.go b/aws/validators.go index dab1c72f66c..81295f77d9f 100644 --- a/aws/validators.go +++ b/aws/validators.go @@ -1705,16 +1705,6 @@ func validateCognitoUserPoolInviteTemplateSmsMessage(v interface{}, k string) (w return } -func validateCognitoUserPoolReplyEmailAddress(v interface{}, k string) (ws []string, errors []error) { - value := v.(string) - - if !regexp.MustCompile(`[\p{L}\p{M}\p{S}\p{N}\p{P}]+@[\p{L}\p{M}\p{S}\p{N}\p{P}]+`).MatchString(value) { - errors = append(errors, fmt.Errorf( - `%q must satisfy regular expression pattern: [\p{L}\p{M}\p{S}\p{N}\p{P}]+@[\p{L}\p{M}\p{S}\p{N}\p{P}]+`, k)) - } - return -} - func validateCognitoUserPoolSchemaName(v interface{}, k string) (ws []string, es []error) { value := v.(string) if len(value) < 1 { diff --git a/aws/validators_test.go b/aws/validators_test.go index 083b5f47fc1..cbaf8a317a5 100644 --- a/aws/validators_test.go +++ b/aws/validators_test.go @@ -2465,32 +2465,6 @@ func TestValidateKmsKey(t *testing.T) { } } -func TestValidateCognitoUserPoolReplyEmailAddress(t *testing.T) { - validTypes := []string{ - "foo@gmail.com", - "foo@bar", - "foo bar@gmail.com", - "foo+bar.baz@gmail.com", - } - for _, v := range validTypes { - _, errors := validateCognitoUserPoolReplyEmailAddress(v, "name") - if len(errors) != 0 { - t.Fatalf("%q should be a valid Cognito User Pool Reply Email Address: %q", v, errors) - } - } - - invalidTypes := []string{ - "foo", - "@bar.baz", - } - for _, v := range invalidTypes { - _, errors := validateCognitoUserPoolReplyEmailAddress(v, "name") - if len(errors) == 0 { - t.Fatalf("%q should be an invalid Cognito User Pool Reply Email Address", v) - } - } -} - func TestResourceAWSElastiCacheReplicationGroupAuthTokenValidation(t *testing.T) { cases := []struct { Value string