From 2be6f70989c2a51f6f5dba7267a600bc09ad5ec4 Mon Sep 17 00:00:00 2001 From: Scott Winkler Date: Sat, 21 Apr 2018 00:58:32 -0700 Subject: [PATCH] tests passing --- aws/resource_aws_acm_certificate.go | 108 ++++++++++++++++------- aws/resource_aws_acm_certificate_test.go | 38 +++++--- 2 files changed, 102 insertions(+), 44 deletions(-) diff --git a/aws/resource_aws_acm_certificate.go b/aws/resource_aws_acm_certificate.go index a2e9adec197..69b9b221729 100644 --- a/aws/resource_aws_acm_certificate.go +++ b/aws/resource_aws_acm_certificate.go @@ -138,11 +138,11 @@ func resourceAwsAcmCertificateCreate(d *schema.ResourceData, meta interface{}) e params.SubjectAlternativeNames = expandStringList(sanStrings) } - domainValidationOptionsInput, ok := d.GetOk("domain_validation_options") + value, ok := d.GetOk("domain_validation_options") if ok { var domainValidationOptions []*acm.DomainValidationOption - for _, o := range domainValidationOptionsInput.([]interface{}) { + for _, o := range value.([]interface{}) { x := o.(map[string]interface{}) dn := x["domain_name"].(string) vd := x["validation_domain"].(string) @@ -196,8 +196,13 @@ func resourceAwsAcmCertificateRead(d *schema.ResourceData, meta interface{}) err return resource.NonRetryableError(fmt.Errorf("Error describing certificate: %s", err)) } - d.Set("domain_name", resp.Certificate.DomainName) - d.Set("arn", resp.Certificate.CertificateArn) + if err := d.Set("domain_name", resp.Certificate.DomainName); err != nil { + return resource.NonRetryableError(err) + } + + if err := d.Set("arn", resp.Certificate.CertificateArn); err != nil { + return resource.NonRetryableError(err) + } if err := d.Set("subject_alternative_names", cleanUpSubjectAlternativeNames(resp.Certificate)); err != nil { return resource.NonRetryableError(err) @@ -205,14 +210,14 @@ func resourceAwsAcmCertificateRead(d *schema.ResourceData, meta interface{}) err certificateDetails, err := convertCertificateDetails(resp.Certificate) - if len(certificateDetails) < 1 { - return resource.NonRetryableError(fmt.Errorf("Error getting certificate details")) - } - if err != nil { return resource.RetryableError(err) } + if len(certificateDetails) < 1 { + return resource.NonRetryableError(fmt.Errorf("Error getting certificate details")) + } + if err := d.Set("certificate_details", certificateDetails); err != nil { return resource.NonRetryableError(err) } @@ -228,6 +233,34 @@ func resourceAwsAcmCertificateRead(d *schema.ResourceData, meta interface{}) err return resource.NonRetryableError(err) } + //support for deprecated attributes + d.Set("validation_emails", certificateDetails[0]["validation_emails"]) + + value, ok := d.GetOk("domain_validation_options") + var domainValidationOptionsInput []interface{} + if ok { + domainValidationOptionsInput = value.([]interface{}) + //pad until it is the same size as certificate details + for len(domainValidationOptionsInput) < len(certificateDetails) { + domainValidationOptionsInput = append(domainValidationOptionsInput, make(map[string]interface{}, 1)) + } + } else { + for i := 0; i < len(certificateDetails); i++ { + domainValidationOptionsInput = append(domainValidationOptionsInput, make(map[string]interface{}, 1)) + } + } + for i, v := range domainValidationOptionsInput { + validationOption := v.(map[string]interface{}) + validationOption["domain_name"] = certificateDetails[i]["domain_name"] + validationOption["resource_record_name"] = certificateDetails[i]["resource_record_name"] + validationOption["resource_record_type"] = certificateDetails[i]["resource_record_type"] + validationOption["resource_record_value"] = certificateDetails[i]["resource_record_value"] + } + + if err := d.Set("domain_validation_options", domainValidationOptionsInput); err != nil { + return resource.NonRetryableError(err) + } + return nil }) } @@ -260,31 +293,32 @@ func convertCertificateDetails(certificate *acm.CertificateDetail) ([]map[string if *certificate.Type == acm.CertificateTypeAmazonIssued { for _, o := range certificate.DomainValidationOptions { - var resourceRecordName interface{} - var resourceRecordType interface{} - var resourceRecordValue interface{} - var validationMethod interface{} + var validationOption map[string]interface{} if o.ResourceRecord != nil { - resourceRecordName = *o.ResourceRecord.Name - resourceRecordType = *o.ResourceRecord.Type - resourceRecordValue = *o.ResourceRecord.Value - } - if o.ValidationMethod != nil { - validationMethod = *o.ValidationMethod + validationOption = map[string]interface{}{ + "domain_name": *o.DomainName, + "resource_record_name": *o.ResourceRecord.Name, + "resource_record_type": *o.ResourceRecord.Type, + "resource_record_value": *o.ResourceRecord.Value, + "validation_method": *o.ValidationMethod, + } + + } else if o.ValidationEmails != nil && len(o.ValidationEmails) > 0 { + var validationEmails []string + for _, email := range o.ValidationEmails { + validationEmails = append(validationEmails, *email) + } + validationOption = map[string]interface{}{ + "domain_name": *o.DomainName, + "validation_emails": validationEmails, + "validation_method": "EMAIL", + } + } else { + return nil, fmt.Errorf("Validation options not yet updated. Need to retry: %#v", o) } - var validationEmails []string - for _, email := range o.ValidationEmails { - validationEmails = append(validationEmails, *email) - } - validationOption := map[string]interface{}{ - "domain_name": *o.DomainName, - "validation_domain": *o.ValidationDomain, - "resource_record_name": resourceRecordName, - "resource_record_type": resourceRecordType, - "resource_record_value": resourceRecordValue, - "validation_emails": validationEmails, - "validation_method": validationMethod, + if o.ValidationDomain != nil { + validationOption["validation_domain"] = *o.ValidationDomain } certificateDetails = append(certificateDetails, validationOption) } @@ -295,11 +329,23 @@ func convertCertificateDetails(certificate *acm.CertificateDetail) ([]map[string func resourceAwsAcmCertificateDelete(d *schema.ResourceData, meta interface{}) error { acmconn := meta.(*AWSClient).acmconn + log.Printf("[INFO] Deleting ACM Certificate: %s", d.Id()) + params := &acm.DeleteCertificateInput{ CertificateArn: aws.String(d.Id()), } - _, err := acmconn.DeleteCertificate(params) + err := resource.Retry(10*time.Minute, func() *resource.RetryError { + _, err := acmconn.DeleteCertificate(params) + if err != nil { + if isAWSErr(err, acm.ErrCodeResourceInUseException, "") { + log.Printf("[WARN] Conflict deleting certificate in use: %s, retrying", err.Error()) + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) if err != nil && !isAWSErr(err, acm.ErrCodeResourceNotFoundException, "") { return fmt.Errorf("Error deleting certificate: %s", err) diff --git a/aws/resource_aws_acm_certificate_test.go b/aws/resource_aws_acm_certificate_test.go index 24f7b956441..0347b592d5b 100644 --- a/aws/resource_aws_acm_certificate_test.go +++ b/aws/resource_aws_acm_certificate_test.go @@ -44,11 +44,12 @@ func TestAccAWSAcmCertificate_emailValidation(t *testing.T) { CheckDestroy: testAccCheckAcmCertificateDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccAcmCertificateConfig(domain, acm.ValidationMethodEmail), + Config: testAccAcmCertificateConfig(domain, acm.ValidationMethodEmail), + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestMatchResourceAttr("aws_acm_certificate.cert", "arn", certificateArnRegex), resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_name", domain), - resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_validation_options.#", "0"), + resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_validation_options.#", "1"), resource.TestCheckResourceAttr("aws_acm_certificate.cert", "subject_alternative_names.#", "0"), resource.TestMatchResourceAttr("aws_acm_certificate.cert", "validation_emails.0", regexp.MustCompile(`^[^@]+@.+$`)), resource.TestCheckResourceAttr("aws_acm_certificate.cert", "validation_method", acm.ValidationMethodEmail), @@ -77,7 +78,8 @@ func TestAccAWSAcmCertificate_dnsValidation(t *testing.T) { CheckDestroy: testAccCheckAcmCertificateDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccAcmCertificateConfig(domain, acm.ValidationMethodDns), + Config: testAccAcmCertificateConfig(domain, acm.ValidationMethodDns), + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestMatchResourceAttr("aws_acm_certificate.cert", "arn", certificateArnRegex), resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_name", domain), @@ -109,7 +111,8 @@ func TestAccAWSAcmCertificate_root(t *testing.T) { CheckDestroy: testAccCheckAcmCertificateDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccAcmCertificateConfig(rootDomain, acm.ValidationMethodDns), + Config: testAccAcmCertificateConfig(rootDomain, acm.ValidationMethodDns), + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestMatchResourceAttr("aws_acm_certificate.cert", "arn", certificateArnRegex), resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_name", rootDomain), @@ -142,7 +145,8 @@ func TestAccAWSAcmCertificate_rootAndWildcardSan(t *testing.T) { CheckDestroy: testAccCheckAcmCertificateDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccAcmCertificateConfig_subjectAlternativeNames(rootDomain, strconv.Quote(wildcardDomain), acm.ValidationMethodDns), + Config: testAccAcmCertificateConfig_subjectAlternativeNames(rootDomain, strconv.Quote(wildcardDomain), acm.ValidationMethodDns), + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestMatchResourceAttr("aws_acm_certificate.cert", "arn", certificateArnRegex), resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_name", rootDomain), @@ -184,7 +188,8 @@ func TestAccAWSAcmCertificate_san_single(t *testing.T) { CheckDestroy: testAccCheckAcmCertificateDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccAcmCertificateConfig_subjectAlternativeNames(domain, strconv.Quote(sanDomain), acm.ValidationMethodDns), + Config: testAccAcmCertificateConfig_subjectAlternativeNames(domain, strconv.Quote(sanDomain), acm.ValidationMethodDns), + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestMatchResourceAttr("aws_acm_certificate.cert", "arn", certificateArnRegex), resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_name", domain), @@ -227,7 +232,8 @@ func TestAccAWSAcmCertificate_san_multiple(t *testing.T) { CheckDestroy: testAccCheckAcmCertificateDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccAcmCertificateConfig_subjectAlternativeNames(domain, fmt.Sprintf("%q, %q", sanDomain1, sanDomain2), acm.ValidationMethodDns), + Config: testAccAcmCertificateConfig_subjectAlternativeNames(domain, fmt.Sprintf("%q, %q", sanDomain1, sanDomain2), acm.ValidationMethodDns), + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestMatchResourceAttr("aws_acm_certificate.cert", "arn", certificateArnRegex), resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_name", domain), @@ -270,7 +276,8 @@ func TestAccAWSAcmCertificate_wildcard(t *testing.T) { CheckDestroy: testAccCheckAcmCertificateDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccAcmCertificateConfig(wildcardDomain, acm.ValidationMethodDns), + Config: testAccAcmCertificateConfig(wildcardDomain, acm.ValidationMethodDns), + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestMatchResourceAttr("aws_acm_certificate.cert", "arn", certificateArnRegex), resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_name", wildcardDomain), @@ -303,7 +310,8 @@ func TestAccAWSAcmCertificate_wildcardAndRootSan(t *testing.T) { CheckDestroy: testAccCheckAcmCertificateDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccAcmCertificateConfig_subjectAlternativeNames(wildcardDomain, strconv.Quote(rootDomain), acm.ValidationMethodDns), + Config: testAccAcmCertificateConfig_subjectAlternativeNames(wildcardDomain, strconv.Quote(rootDomain), acm.ValidationMethodDns), + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestMatchResourceAttr("aws_acm_certificate.cert", "arn", certificateArnRegex), resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_name", wildcardDomain), @@ -344,13 +352,15 @@ func TestAccAWSAcmCertificate_tags(t *testing.T) { CheckDestroy: testAccCheckAcmCertificateDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccAcmCertificateConfig(domain, acm.ValidationMethodDns), + Config: testAccAcmCertificateConfig(domain, acm.ValidationMethodDns), + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.%", "0"), ), }, resource.TestStep{ - Config: testAccAcmCertificateConfig_twoTags(domain, acm.ValidationMethodDns, "Hello", "World", "Foo", "Bar"), + Config: testAccAcmCertificateConfig_twoTags(domain, acm.ValidationMethodDns, "Hello", "World", "Foo", "Bar"), + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.%", "2"), resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.Hello", "World"), @@ -358,7 +368,8 @@ func TestAccAWSAcmCertificate_tags(t *testing.T) { ), }, resource.TestStep{ - Config: testAccAcmCertificateConfig_twoTags(domain, acm.ValidationMethodDns, "Hello", "World", "Foo", "Baz"), + Config: testAccAcmCertificateConfig_twoTags(domain, acm.ValidationMethodDns, "Hello", "World", "Foo", "Baz"), + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.%", "2"), resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.Hello", "World"), @@ -366,7 +377,8 @@ func TestAccAWSAcmCertificate_tags(t *testing.T) { ), }, resource.TestStep{ - Config: testAccAcmCertificateConfig_oneTag(domain, acm.ValidationMethodDns, "Environment", "Test"), + Config: testAccAcmCertificateConfig_oneTag(domain, acm.ValidationMethodDns, "Environment", "Test"), + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.%", "1"), resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.Environment", "Test"),