From d952370550381d88514f527cfcf463b8be4f9011 Mon Sep 17 00:00:00 2001 From: Ryn Daniels Date: Fri, 7 Jun 2019 17:16:10 +0200 Subject: [PATCH 1/2] Retry for deleting default DHCP options, plus pagination plus a test sweeper --- aws/resource_aws_default_vpc_dhcp_options.go | 20 ++++- ...ource_aws_default_vpc_dhcp_options_test.go | 4 - aws/resource_aws_vpc_dhcp_options.go | 9 ++- aws/resource_aws_vpc_dhcp_options_test.go | 77 +++++++++++++++++++ 4 files changed, 101 insertions(+), 9 deletions(-) diff --git a/aws/resource_aws_default_vpc_dhcp_options.go b/aws/resource_aws_default_vpc_dhcp_options.go index ecc0bd87ca6..b007d316fd2 100644 --- a/aws/resource_aws_default_vpc_dhcp_options.go +++ b/aws/resource_aws_default_vpc_dhcp_options.go @@ -65,16 +65,28 @@ func resourceAwsDefaultVpcDhcpOptionsCreate(d *schema.ResourceData, meta interfa }, } - resp, err := conn.DescribeDhcpOptions(req) + var dhcpOptions []*ec2.DhcpOptions + err := conn.DescribeDhcpOptionsPages(req, func(page *ec2.DescribeDhcpOptionsOutput, lastPage bool) bool { + dhcpOptions = append(dhcpOptions, page.DhcpOptions...) + return !lastPage + }) + if err != nil { - return err + return fmt.Errorf("Error describing DHCP options: %s", err) } - if len(resp.DhcpOptions) != 1 || resp.DhcpOptions[0] == nil { + if len(dhcpOptions) == 0 { return fmt.Errorf("Default DHCP Options Set not found") } - d.SetId(aws.StringValue(resp.DhcpOptions[0].DhcpOptionsId)) + if len(dhcpOptions) > 1 { + return fmt.Errorf("Multiple default DHCP Options Sets found") + } + + if dhcpOptions[0] == nil { + return fmt.Errorf("Default DHCP Options Set is empty") + } + d.SetId(aws.StringValue(dhcpOptions[0].DhcpOptionsId)) return resourceAwsVpcDhcpOptionsUpdate(d, meta) } diff --git a/aws/resource_aws_default_vpc_dhcp_options_test.go b/aws/resource_aws_default_vpc_dhcp_options_test.go index 20a6dd211db..c96372b83d4 100644 --- a/aws/resource_aws_default_vpc_dhcp_options_test.go +++ b/aws/resource_aws_default_vpc_dhcp_options_test.go @@ -41,10 +41,6 @@ func testAccCheckAWSDefaultVpcDhcpOptionsDestroy(s *terraform.State) error { } const testAccAWSDefaultVpcDhcpOptionsConfigBasic = ` -provider "aws" { - region = "us-west-2" -} - resource "aws_default_vpc_dhcp_options" "foo" { tags = { Name = "Default DHCP Option Set" diff --git a/aws/resource_aws_vpc_dhcp_options.go b/aws/resource_aws_vpc_dhcp_options.go index c4baa040644..8a81ecccdfc 100644 --- a/aws/resource_aws_vpc_dhcp_options.go +++ b/aws/resource_aws_vpc_dhcp_options.go @@ -196,7 +196,7 @@ func resourceAwsVpcDhcpOptionsUpdate(d *schema.ResourceData, meta interface{}) e func resourceAwsVpcDhcpOptionsDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn - return resource.Retry(3*time.Minute, func() *resource.RetryError { + err := resource.Retry(3*time.Minute, func() *resource.RetryError { log.Printf("[INFO] Deleting DHCP Options ID %s...", d.Id()) _, err := conn.DeleteDhcpOptions(&ec2.DeleteDhcpOptionsInput{ DhcpOptionsId: aws.String(d.Id()), @@ -239,6 +239,13 @@ func resourceAwsVpcDhcpOptionsDelete(d *schema.ResourceData, meta interface{}) e return resource.NonRetryableError(err) } }) + + if isResourceTimeoutError(err) { + _, err = conn.DeleteDhcpOptions(&ec2.DeleteDhcpOptionsInput{ + DhcpOptionsId: aws.String(d.Id()), + }) + } + return err } func findVPCsByDHCPOptionsID(conn *ec2.EC2, id string) ([]*ec2.Vpc, error) { diff --git a/aws/resource_aws_vpc_dhcp_options_test.go b/aws/resource_aws_vpc_dhcp_options_test.go index de3bac3ca80..862c6c67cbc 100644 --- a/aws/resource_aws_vpc_dhcp_options_test.go +++ b/aws/resource_aws_vpc_dhcp_options_test.go @@ -2,6 +2,7 @@ package aws import ( "fmt" + "log" "testing" "github.com/aws/aws-sdk-go/aws" @@ -11,6 +12,82 @@ import ( "github.com/hashicorp/terraform/terraform" ) +func init() { + resource.AddTestSweepers("aws_vpc_dhcp_options", &resource.Sweeper{ + Name: "aws_vpc_dhcp_options", + F: testSweepVpcDhcpOptions, + }) +} + +func testSweepVpcDhcpOptions(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*AWSClient).ec2conn + + input := &ec2.DescribeDhcpOptionsInput{} + + err = conn.DescribeDhcpOptionsPages(input, func(page *ec2.DescribeDhcpOptionsOutput, lastPage bool) bool { + for _, dhcpOption := range page.DhcpOptions { + var domainName string + var defaultDomainNameFound, defaultDomainNameServersFound bool + + if region == "us-east-1" { + domainName = "ec2.internal" + } else { + domainName = region + ".compute.internal" + } + + for _, dhcpConfiguration := range dhcpOption.DhcpConfigurations { + if aws.StringValue(dhcpConfiguration.Key) == "domain-name" { + if len(dhcpConfiguration.Values) == 0 || len(dhcpConfiguration.Values) > 1 { + continue + } + + if dhcpConfiguration.Values[0] != nil && aws.StringValue(dhcpConfiguration.Values[0].Value) == domainName { + defaultDomainNameFound = true + } + } else if aws.StringValue(dhcpConfiguration.Key) == "domain-name-servers" { + if len(dhcpConfiguration.Values) == 0 || len(dhcpConfiguration.Values) > 1 { + continue + } + + if dhcpConfiguration.Values[0] != nil && aws.StringValue(dhcpConfiguration.Values[0].Value) == "AmazonProvidedDNS" { + defaultDomainNameServersFound = true + } + } + } + + if defaultDomainNameFound && defaultDomainNameServersFound { + continue + } + + input := &ec2.DeleteDhcpOptionsInput{ + DhcpOptionsId: dhcpOption.DhcpOptionsId, + } + + _, err := conn.DeleteDhcpOptions(input) + + if err != nil { + log.Printf("[ERROR] Error deleting EC2 DHCP Option (%s): %s", aws.StringValue(dhcpOption.DhcpOptionsId), err) + } + } + return !lastPage + }) + + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping EC2 DHCP Option sweep for %s: %s", region, err) + return nil + } + + if err != nil { + return fmt.Errorf("error describing DHCP Options: %s", err) + } + + return nil +} + func TestAccAWSDHCPOptions_importBasic(t *testing.T) { resourceName := "aws_vpc_dhcp_options.foo" From e054daf8813f8d03ba1f4e5d9c26884190509574 Mon Sep 17 00:00:00 2001 From: Ryn Daniels Date: Wed, 12 Jun 2019 18:22:28 +0200 Subject: [PATCH 2/2] Nits being picked --- aws/resource_aws_vpc_dhcp_options_test.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/aws/resource_aws_vpc_dhcp_options_test.go b/aws/resource_aws_vpc_dhcp_options_test.go index 862c6c67cbc..5ce44a8fb27 100644 --- a/aws/resource_aws_vpc_dhcp_options_test.go +++ b/aws/resource_aws_vpc_dhcp_options_test.go @@ -30,30 +30,29 @@ func testSweepVpcDhcpOptions(region string) error { err = conn.DescribeDhcpOptionsPages(input, func(page *ec2.DescribeDhcpOptionsOutput, lastPage bool) bool { for _, dhcpOption := range page.DhcpOptions { - var domainName string var defaultDomainNameFound, defaultDomainNameServersFound bool + domainName := region + ".compute.internal" if region == "us-east-1" { domainName = "ec2.internal" - } else { - domainName = region + ".compute.internal" } + // This skips the default dhcp configurations so they don't get deleted for _, dhcpConfiguration := range dhcpOption.DhcpConfigurations { if aws.StringValue(dhcpConfiguration.Key) == "domain-name" { - if len(dhcpConfiguration.Values) == 0 || len(dhcpConfiguration.Values) > 1 { + if len(dhcpConfiguration.Values) != 1 || dhcpConfiguration.Values[0] == nil { continue } - if dhcpConfiguration.Values[0] != nil && aws.StringValue(dhcpConfiguration.Values[0].Value) == domainName { + if aws.StringValue(dhcpConfiguration.Values[0].Value) == domainName { defaultDomainNameFound = true } } else if aws.StringValue(dhcpConfiguration.Key) == "domain-name-servers" { - if len(dhcpConfiguration.Values) == 0 || len(dhcpConfiguration.Values) > 1 { + if len(dhcpConfiguration.Values) != 1 || dhcpConfiguration.Values[0] == nil { continue } - if dhcpConfiguration.Values[0] != nil && aws.StringValue(dhcpConfiguration.Values[0].Value) == "AmazonProvidedDNS" { + if aws.StringValue(dhcpConfiguration.Values[0].Value) == "AmazonProvidedDNS" { defaultDomainNameServersFound = true } }