From c5b1e7af1924a2304fe70ad19d9bfa0e9d8eb5c9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Sep 2020 14:36:20 -0400 Subject: [PATCH] resource/aws_route53_resolver_rule: Correct handling for single period (`.`) value in `domain_name` argument (#15015) Output from acceptance testing: ``` --- PASS: TestAccAwsRoute53ResolverRule_basic (51.50s) --- PASS: TestAccAwsRoute53ResolverRule_forward (302.02s) --- PASS: TestAccAwsRoute53ResolverRule_forwardEndpointRecreate (468.20s) --- PASS: TestAccAwsRoute53ResolverRule_justDotDomainName (53.81s) --- PASS: TestAccAwsRoute53ResolverRule_tags (79.55s) --- PASS: TestAccAwsRoute53ResolverRule_trailingDotDomainName (53.97s) --- PASS: TestAccAwsRoute53ResolverRule_updateName (76.52s) --- PASS: TestAccAwsRoute53ResolverRuleAssociation_basic (200.65s) --- PASS: TestAccAWSRoute53Zone_basic (73.79s) --- PASS: TestAccAWSRoute53Zone_Comment (88.35s) --- PASS: TestAccAWSRoute53Zone_DelegationSetID (75.67s) --- PASS: TestAccAWSRoute53Zone_disappears (67.61s) --- PASS: TestAccAWSRoute53Zone_ForceDestroy (238.61s) --- PASS: TestAccAWSRoute53Zone_ForceDestroy_TrailingPeriod (237.20s) --- PASS: TestAccAWSRoute53Zone_multiple (78.13s) --- PASS: TestAccAWSRoute53Zone_Tags (80.90s) --- PASS: TestAccAWSRoute53Zone_VPC_Multiple (168.51s) --- PASS: TestAccAWSRoute53Zone_VPC_Single (99.75s) --- PASS: TestAccAWSRoute53Zone_VPC_Updates (262.79s) --- PASS: TestAccAWSRoute53ZoneAssociation_basic (201.40s) --- PASS: TestAccAWSRoute53ZoneAssociation_CrossRegion (205.99s) --- PASS: TestAccAWSRoute53ZoneAssociation_disappears (205.47s) --- PASS: TestAccAWSRoute53ZoneAssociation_disappears_VPC (191.07s) --- PASS: TestAccAWSRoute53ZoneAssociation_disappears_Zone (192.61s) ``` --- ...resource_aws_route53_resolver_rule_test.go | 67 +++++++++++++++++++ aws/resource_aws_route53_zone.go | 10 ++- aws/resource_aws_route53_zone_test.go | 10 ++- 3 files changed, 84 insertions(+), 3 deletions(-) diff --git a/aws/resource_aws_route53_resolver_rule_test.go b/aws/resource_aws_route53_resolver_rule_test.go index 64fcef77bb5..5278e20482c 100644 --- a/aws/resource_aws_route53_resolver_rule_test.go +++ b/aws/resource_aws_route53_resolver_rule_test.go @@ -111,6 +111,64 @@ func TestAccAwsRoute53ResolverRule_basic(t *testing.T) { }) } +func TestAccAwsRoute53ResolverRule_justDotDomainName(t *testing.T) { + var rule route53resolver.ResolverRule + resourceName := "aws_route53_resolver_rule.example" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSRoute53Resolver(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckRoute53ResolverRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccRoute53ResolverRuleConfig("."), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverRuleExists(resourceName, &rule), + resource.TestCheckResourceAttr(resourceName, "domain_name", "."), + resource.TestCheckResourceAttr(resourceName, "rule_type", "SYSTEM"), + resource.TestCheckResourceAttr(resourceName, "share_status", "NOT_SHARED"), + testAccCheckResourceAttrAccountID(resourceName, "owner_id"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAwsRoute53ResolverRule_trailingDotDomainName(t *testing.T) { + var rule route53resolver.ResolverRule + resourceName := "aws_route53_resolver_rule.example" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSRoute53Resolver(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckRoute53ResolverRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccRoute53ResolverRuleConfig("example.com."), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverRuleExists(resourceName, &rule), + resource.TestCheckResourceAttr(resourceName, "domain_name", "example.com"), + resource.TestCheckResourceAttr(resourceName, "rule_type", "SYSTEM"), + resource.TestCheckResourceAttr(resourceName, "share_status", "NOT_SHARED"), + testAccCheckResourceAttrAccountID(resourceName, "owner_id"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAwsRoute53ResolverRule_tags(t *testing.T) { var rule route53resolver.ResolverRule resourceName := "aws_route53_resolver_rule.example" @@ -389,6 +447,15 @@ func testAccCheckRoute53ResolverRuleExists(n string, rule *route53resolver.Resol } } +func testAccRoute53ResolverRuleConfig(domainName string) string { + return fmt.Sprintf(` +resource "aws_route53_resolver_rule" "example" { + domain_name = %[1]q + rule_type = "SYSTEM" +} +`, domainName) +} + const testAccRoute53ResolverRuleConfig_basicNoTags = ` resource "aws_route53_resolver_rule" "example" { domain_name = "example.com" diff --git a/aws/resource_aws_route53_zone.go b/aws/resource_aws_route53_zone.go index cb7ff868f62..9b5b28bd1dd 100644 --- a/aws/resource_aws_route53_zone.go +++ b/aws/resource_aws_route53_zone.go @@ -397,17 +397,23 @@ func cleanZoneID(ID string) string { // trimTrailingPeriod is used to remove the trailing period // of "name" or "domain name" attributes often returned from -// the Route53 API or provided as user input +// the Route53 API or provided as user input. +// The single dot (".") domain name is returned as-is. func trimTrailingPeriod(v interface{}) string { var str string switch value := v.(type) { case *string: - str = *value + str = aws.StringValue(value) case string: str = value default: return "" } + + if str == "." { + return str + } + return strings.TrimSuffix(str, ".") } diff --git a/aws/resource_aws_route53_zone_test.go b/aws/resource_aws_route53_zone_test.go index 29dbef7fa39..347f9f90aad 100644 --- a/aws/resource_aws_route53_zone_test.go +++ b/aws/resource_aws_route53_zone_test.go @@ -50,11 +50,19 @@ func TestCleanChangeID(t *testing.T) { func TestTrimTrailingPeriod(t *testing.T) { cases := []struct { - Input, Output string + Input interface{} + Output string }{ {"example.com", "example.com"}, {"example.com.", "example.com"}, {"www.example.com.", "www.example.com"}, + {"", ""}, + {".", "."}, + {aws.String("example.com"), "example.com"}, + {aws.String("example.com."), "example.com"}, + {(*string)(nil), ""}, + {42, ""}, + {nil, ""}, } for _, tc := range cases {