Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new feature for resoure acmpca_certificate_authority #7366

Merged
merged 1 commit into from
Apr 2, 2019

Conversation

vnguyen7
Copy link
Contributor

Related #4994

Changes proposed in this pull request:

Add new feature permanent_deletion_time_in_days for resource acmpca_certificate_authority

@ghost ghost added size/S Managed by automation to categorize the size of a PR. documentation Introduces or discusses updates to documentation. service/acmpca Issues and PRs that pertain to the acmpca service. tests PRs: expanded test coverage. Issues: expanded coverage, enhancements to test infrastructure. labels Jan 28, 2019
@bflad bflad added the enhancement Requests to existing resources that expand the functionality or scope. label Feb 5, 2019
Copy link
Contributor

@bflad bflad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @vnguyen7 👋 Thanks for this contribution. Apologies we don't currently have time to spend review cycles working on this pull request together to be accepted as we have an immediate need to get this functionality in, but I left some hopefully detailed notes during work on the followup commit (3f862bc) that should help for your next submission. Thanks again.

Output from acceptance testing after code updates:

--- PASS: TestAccAwsAcmpcaCertificateAuthority_Basic (24.05s)
--- PASS: TestAccAwsAcmpcaCertificateAuthority_Tags (53.09s)
--- PASS: TestAccAwsAcmpcaCertificateAuthority_RevocationConfiguration_CrlConfiguration_ExpirationInDays (70.87s)
--- PASS: TestAccAwsAcmpcaCertificateAuthority_RevocationConfiguration_CrlConfiguration_Enabled (81.25s)
--- PASS: TestAccAwsAcmpcaCertificateAuthority_RevocationConfiguration_CrlConfiguration_CustomCname (100.37s)

@@ -239,6 +239,11 @@ func resourceAwsAcmpcaCertificateAuthority() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"permanent_deletion_time_in_days ": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few things here:

  • The attribute name includes an extra space at the end
  • The attribute should include Default: 30, to match the API default
  • Since there is no ability to call d.Set() of the attribute properly during the Read function, the attribute needs to have d.Set() called during the import process, otherwise Terraform will report a plan difference immediately after import like "" => "30"

To support the new attribute with a default, the resource should include a Terraform state migration to correctly set the new default in the state (since it cannot be added to the Read function with d.Set()), e.g.

In the resource schema:

MigrateState:  resourceAwsAcmpcaCertificateAuthorityMigrateState,
SchemaVersion: 1,

In a new aws/resource_aws_acmpca_certificate_authority_migrate.go file:

package aws

import (
	"fmt"
	"log"

	"github.com/hashicorp/terraform/terraform"
)

func resourceAwsAcmpcaCertificateAuthorityMigrateState(v int, is *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) {
	switch v {
	case 0:
		log.Println("[INFO] Found ACMPCA Certificate Authority state v0; migrating to v1")
		return migrateAcmpcaCertificateAuthorityStateV0toV1(is)
	default:
		return is, fmt.Errorf("Unexpected schema version: %d", v)
	}
}

func migrateAcmpcaCertificateAuthorityStateV0toV1(is *terraform.InstanceState) (*terraform.InstanceState, error) {
	if is.Empty() || is.Attributes == nil {
		log.Println("[DEBUG] Empty ACMPCA Certificate Authority state; nothing to migrate.")
		return is, nil
	}

	log.Printf("[DEBUG] Attributes before migration: %#v", is.Attributes)

	// Add permanent_deletion_time_in_days virtual attribute with Default
	is.Attributes["permanent_deletion_time_in_days"] = "30"

	log.Printf("[DEBUG] Attributes after migration: %#v", is.Attributes)

	return is, nil
}

And unit tested in a new file named aws/resource_aws_acmpca_certificate_authority_migrate_test.go:

package aws

import (
	"testing"

	"github.com/hashicorp/terraform/terraform"
)

func TestAwsAcmpcaCertificateAuthorityMigrateState(t *testing.T) {
	testCases := map[string]struct {
		StateVersion int
		Attributes   map[string]string
		Expected     map[string]string
		Meta         interface{}
	}{
		"v0_to_v1": {
			StateVersion: 0,
			Attributes: map[string]string{
				"permanent_deletion_time_in_days": "",
			},
			Expected: map[string]string{
				"permanent_deletion_time_in_days": "30",
			},
		},
	}

	for testName, testCase := range testCases {
		instanceState := &terraform.InstanceState{
			ID:         "some_id",
			Attributes: testCase.Attributes,
		}

		tfResource := resourceAwsAcmpcaCertificateAuthority()

		if tfResource.MigrateState == nil {
			t.Fatalf("bad: %s, err: missing MigrateState function in resource", testName)
		}

		instanceState, err := tfResource.MigrateState(testCase.StateVersion, instanceState, testCase.Meta)
		if err != nil {
			t.Fatalf("bad: %s, err: %#v", testName, err)
		}

		for key, expectedValue := range testCase.Expected {
			if instanceState.Attributes[key] != expectedValue {
				t.Fatalf(
					"bad: %s\n\n expected: %#v -> %#v\n got: %#v -> %#v\n in: %#v",
					testName, key, expectedValue, key, instanceState.Attributes[key], instanceState.Attributes)
			}
		}
	}
}

To fix the import portion, it can be handled by switching from schema.ImportStatePassthrough to a custom import function, e.g.

Importer: &schema.ResourceImporter{
	State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
		d.Set("permanent_deletion_time_in_days", 30)

		return []*schema.ResourceData{d}, nil
	},
},

@@ -487,6 +492,9 @@ func resourceAwsAcmpcaCertificateAuthorityDelete(d *schema.ResourceData, meta in
}

log.Printf("[DEBUG] Deleting ACMPCA Certificate Authority: %s", input)
if v, exists := d.GetOk("permanent_deletion_time_in_days "); exists {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The attribute includes an extra space in the name here as well, but more importantly this logic should be moved above the log line so operators and code maintainers can more easily debug this new parameter to the API call.

@@ -43,11 +43,13 @@ func testSweepAcmpcaCertificateAuthorities(region string) error {
for _, certificateAuthority := range certificateAuthorities {
arn := aws.StringValue(certificateAuthority.Arn)
log.Printf("[INFO] Deleting ACMPCA Certificate Authority: %s", arn)
input := &acmpca.DeleteCertificateAuthorityInput{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if there was a reason behind removing the input variable here, but we prefer that coding style and the PermanentDeletionTimeInDays: aws.Int64(int64(7)), line could have just been added to the struct. In the updated code below it is missing the required CertificateAuthorityArn: aws.String(arn),.

input := &acmpca.DeleteCertificateAuthorityInput{
	CertificateAuthorityArn:     aws.String(arn),
	PermanentDeletionTimeInDays: aws.Int64(int64(7)),
}

subject {
common_name = "terraformtesting.com"
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Looks like spaces were switched to tabs here and below.

@@ -94,6 +95,7 @@ The following arguments are supported:
* `revocation_configuration` - (Optional) Nested argument containing revocation configuration. Defined below.
* `tags` - (Optional) Specifies a key-value map of user-defined tags that are attached to the certificate authority.
* `type` - (Optional) The type of the certificate authority. Currently, this must be `SUBORDINATE`.
*`permanent_deletion_time_in_days` - (Optional) The number of days to make a CA restorable after it has been deleted, must be between 7 to 30 days, with default to 30 days.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Missing space before backtick which is breaking formatting:

Suggested change
*`permanent_deletion_time_in_days` - (Optional) The number of days to make a CA restorable after it has been deleted, must be between 7 to 30 days, with default to 30 days.
* `permanent_deletion_time_in_days` - (Optional) The number of days to make a CA restorable after it has been deleted, must be between 7 to 30 days, with default to 30 days.

@@ -496,7 +499,8 @@ resource "aws_acmpca_certificate_authority" "test" {
subject {
common_name = "terraformtesting.com"
}
}
}
permanent_deletion_time_in_days = 7
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these test configurations include the new permanent_deletion_time_in_days argument inside other configuration blocks, which prevents the tests from running.

@bflad bflad added this to the v2.5.0 milestone Apr 2, 2019
@bflad bflad merged commit a397362 into hashicorp:master Apr 2, 2019
bflad added a commit that referenced this pull request Apr 2, 2019
…and fix acceptance testing issues

Reference: #7366

Previously, the resource could have race conditions due to a missing `IdempotencyToken` in the `CreateCertificateAuthority` request. The `InvalidStateException` handling during `GetCertificateAuthorityCertificate` was also missing from `GetCertificateAuthorityCsr`.

Output from acceptance testing:

```
--- PASS: TestAccAwsAcmpcaCertificateAuthority_Basic (24.05s)
--- PASS: TestAccAwsAcmpcaCertificateAuthority_Tags (53.09s)
--- PASS: TestAccAwsAcmpcaCertificateAuthority_RevocationConfiguration_CrlConfiguration_ExpirationInDays (70.87s)
--- PASS: TestAccAwsAcmpcaCertificateAuthority_RevocationConfiguration_CrlConfiguration_Enabled (81.25s)
--- PASS: TestAccAwsAcmpcaCertificateAuthority_RevocationConfiguration_CrlConfiguration_CustomCname (100.37s)
```
bflad added a commit that referenced this pull request Apr 2, 2019
…_deletion_time_in_days = 7 argument to test resources and handle additional error for non-existent testing

At a certain point, ACM-PCA started returning a `AccessDeniedException` instead of a `ResourceNotFoundException` when referencing a non-existing certificate authority, likely since the testing uses a fake ARN that is "another" AWS account. We cover both errors in case the error ever changes back.

Previous acceptance testing output:

```
--- FAIL: TestAccDataSourceAwsAcmpcaCertificateAuthority_Basic (3.45s)
    testing.go:531: Step 0, expected error:

        Error refreshing: 1 error occurred:
        	* data.aws_acmpca_certificate_authority.test: 1 error occurred:
        	* data.aws_acmpca_certificate_authority.test: data.aws_acmpca_certificate_authority.test: error reading ACMPCA Certificate Authority: AccessDeniedException: User: arn:aws:iam::123456789012:user/teamcity is not authorized to perform: acm-pca:DescribeCertificateAuthority on resource: arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/tf-acc-test-does-not-exist
```

ACM-PCA defaults to 30 day deletion window, which is unnecessary in our acceptance testing. Add the new `permanent_deletion_time_in_days` argument from (#7366) to help prevent `LimitExceededException` in our testing account. This is a virtual attribute so it is not valid to add to the `Check` functions.

Output from acceptance testing:

```
--- PASS: TestAccDataSourceAwsAcmpcaCertificateAuthority_Basic (19.09s)
```
@bflad
Copy link
Contributor

bflad commented Apr 5, 2019

This has been released in version 2.5.0 of the Terraform AWS provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.

@ghost
Copy link

ghost commented Mar 30, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

@ghost ghost locked and limited conversation to collaborators Mar 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
documentation Introduces or discusses updates to documentation. enhancement Requests to existing resources that expand the functionality or scope. service/acmpca Issues and PRs that pertain to the acmpca service. size/S Managed by automation to categorize the size of a PR. tests PRs: expanded test coverage. Issues: expanded coverage, enhancements to test infrastructure.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants