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

Fix aws dx gateway association proposal #19741

Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2e09495
don't report diff when proposal is gone
dkujawski May 18, 2021
8c198a1
Populate proposal state using found association
dkujawski May 18, 2021
7f5ae58
WIP activate debug code path for testing
dkujawski May 24, 2021
19b4043
collect state information from associated gateway to determine if pro…
dkujawski May 24, 2021
363a762
when associated gateway is not found or errors, assume we need the pr…
dkujawski May 24, 2021
76c016d
provide some commentary for clarity
dkujawski Jun 9, 2021
1f41003
add test to cover proposal end of life
dkujawski Jun 9, 2021
69feb2f
reset debug mode default
dkujawski Jun 9, 2021
69767a4
allow import dx gateway assoc poroposal after EOL
dkujawski Jun 21, 2021
925c9df
defer existance checks to Read function
dkujawski Jun 22, 2021
2710bca
remove test function no longer needed
dkujawski Jun 22, 2021
f7501be
include allowed_prefixes when atrificially populating proposal
dkujawski Jun 23, 2021
e8b8e03
include tgw for acc tests
dkujawski Jun 23, 2021
10830b0
Add DirectConnect internal finder and waiter packages.
ewbankkit Jul 7, 2021
c281882
Use finder package in aws_dx_gateway_association & aws_dx_gateway_ass…
ewbankkit Jul 7, 2021
9a5b53c
Add DirectConnect internal lister package and use in (some) test swee…
ewbankkit Jul 7, 2021
5d7606d
r/aws_dx_gateway_association_proposal: Document alternate resource im…
ewbankkit Jul 7, 2021
cc09452
r/aws_dx_gateway_association_proposal: Ensure that any pseudo-proposa…
ewbankkit Jul 8, 2021
5091041
Tweak acceptance test configurations.
ewbankkit Jul 8, 2021
847d868
Fix 'errcheck' linter errors.
ewbankkit Jul 8, 2021
1a884d2
r/aws_dx_gateway_association: Use internal waiter package.
ewbankkit Jul 8, 2021
ccddd60
r/aws_dx_gateway_association: Use internal finder and waiter packages.
ewbankkit Jul 8, 2021
9a5d4db
r/aws_dx_gateway: Use internal finder and waiter packages.
ewbankkit Jul 8, 2021
7d84773
Add CHANGELOG entry.
ewbankkit Jul 8, 2021
8cb22b4
Taint Proposal to test Gateway Association ForceNew.
ewbankkit Jul 8, 2021
e75ba1b
Configuration changes for 'TestAccAwsDxGatewayAssociation_recreatePro…
ewbankkit Jul 9, 2021
f97a52e
Fix 'terrafmt' errors.
ewbankkit Jul 12, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/19741.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:note
resource/aws_dx_gateway_association_proposal: If an accepted Proposal reaches end-of-life and is removed by AWS do not recreate the resource, instead refreshing Terraform state from the resource's Direct Connect Gateway ID and Associated Gateway ID.
```
142 changes: 142 additions & 0 deletions aws/internal/service/directconnect/finder/finder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package finder

import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/directconnect"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func GatewayByID(conn *directconnect.DirectConnect, id string) (*directconnect.Gateway, error) {
input := &directconnect.DescribeDirectConnectGatewaysInput{
DirectConnectGatewayId: aws.String(id),
}

output, err := conn.DescribeDirectConnectGateways(input)

if err != nil {
return nil, err
}

if output == nil || len(output.DirectConnectGateways) == 0 || output.DirectConnectGateways[0] == nil {
return nil, &resource.NotFoundError{
Message: "Empty result",
LastRequest: input,
}
}

// TODO Check for multiple results.
// TODO https://github.com/hashicorp/terraform-provider-aws/pull/17613.

gateway := output.DirectConnectGateways[0]

if state := aws.StringValue(gateway.DirectConnectGatewayState); state == directconnect.GatewayStateDeleted {
return nil, &resource.NotFoundError{
Message: state,
LastRequest: input,
}
}

return gateway, nil
}

func GatewayAssociationByID(conn *directconnect.DirectConnect, id string) (*directconnect.GatewayAssociation, error) {
input := &directconnect.DescribeDirectConnectGatewayAssociationsInput{
AssociationId: aws.String(id),
}

return GatewayAssociation(conn, input)
}

func GatewayAssociationByDirectConnectGatewayIDAndAssociatedGatewayID(conn *directconnect.DirectConnect, directConnectGatewayID, associatedGatewayID string) (*directconnect.GatewayAssociation, error) {
input := &directconnect.DescribeDirectConnectGatewayAssociationsInput{
AssociatedGatewayId: aws.String(associatedGatewayID),
DirectConnectGatewayId: aws.String(directConnectGatewayID),
}

return GatewayAssociation(conn, input)
}

func GatewayAssociationByDirectConnectGatewayIDAndVirtualGatewayID(conn *directconnect.DirectConnect, directConnectGatewayID, virtualGatewayID string) (*directconnect.GatewayAssociation, error) {
input := &directconnect.DescribeDirectConnectGatewayAssociationsInput{
DirectConnectGatewayId: aws.String(directConnectGatewayID),
VirtualGatewayId: aws.String(virtualGatewayID),
}

return GatewayAssociation(conn, input)
}

func GatewayAssociation(conn *directconnect.DirectConnect, input *directconnect.DescribeDirectConnectGatewayAssociationsInput) (*directconnect.GatewayAssociation, error) {
output, err := conn.DescribeDirectConnectGatewayAssociations(input)

if err != nil {
return nil, err
}

if output == nil || len(output.DirectConnectGatewayAssociations) == 0 || output.DirectConnectGatewayAssociations[0] == nil {
return nil, &resource.NotFoundError{
Message: "Empty result",
LastRequest: input,
}
}

// TODO Check for multiple results.
// TODO https://github.com/hashicorp/terraform-provider-aws/pull/17613.

association := output.DirectConnectGatewayAssociations[0]

if state := aws.StringValue(association.AssociationState); state == directconnect.GatewayAssociationStateDisassociated {
return nil, &resource.NotFoundError{
Message: state,
LastRequest: input,
}
}

if association.AssociatedGateway == nil {
return nil, &resource.NotFoundError{
Message: "Empty AssociatedGateway",
LastRequest: input,
}
}

return association, nil
}

func GatewayAssociationProposalByID(conn *directconnect.DirectConnect, id string) (*directconnect.GatewayAssociationProposal, error) {
input := &directconnect.DescribeDirectConnectGatewayAssociationProposalsInput{
ProposalId: aws.String(id),
}

output, err := conn.DescribeDirectConnectGatewayAssociationProposals(input)

if err != nil {
return nil, err
}

if output == nil || len(output.DirectConnectGatewayAssociationProposals) == 0 || output.DirectConnectGatewayAssociationProposals[0] == nil {
return nil, &resource.NotFoundError{
Message: "Empty result",
LastRequest: input,
}
}

// TODO Check for multiple results.
// TODO https://github.com/hashicorp/terraform-provider-aws/pull/17613.

proposal := output.DirectConnectGatewayAssociationProposals[0]

if state := aws.StringValue(proposal.ProposalState); state == directconnect.GatewayAssociationProposalStateDeleted {
return nil, &resource.NotFoundError{
Message: state,
LastRequest: input,
}
}

if proposal.AssociatedGateway == nil {
return nil, &resource.NotFoundError{
Message: "Empty AssociatedGateway",
LastRequest: input,
}
}

return proposal, nil
}
9 changes: 9 additions & 0 deletions aws/internal/service/directconnect/id.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package directconnect

import (
"fmt"
)

func GatewayAssociationCreateResourceID(directConnectGatewayID, associatedGatewayID string) string {
return fmt.Sprintf("ga-%s%s", directConnectGatewayID, associatedGatewayID)
}
3 changes: 3 additions & 0 deletions aws/internal/service/directconnect/lister/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//go:generate go run ../../../generators/listpages/main.go -function=DescribeDirectConnectGateways,DescribeDirectConnectGatewayAssociations,DescribeDirectConnectGatewayAssociationProposals -paginator=NextToken github.com/aws/aws-sdk-go/service/directconnect

package lister
73 changes: 73 additions & 0 deletions aws/internal/service/directconnect/lister/list_pages_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions aws/internal/service/directconnect/waiter/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package waiter

import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/directconnect"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/directconnect/finder"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource"
)

func GatewayState(conn *directconnect.DirectConnect, id string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
output, err := finder.GatewayByID(conn, id)

if tfresource.NotFound(err) {
return nil, "", nil
}

if err != nil {
return nil, "", err
}

return output, aws.StringValue(output.DirectConnectGatewayState), nil
}
}

func GatewayAssociationState(conn *directconnect.DirectConnect, id string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
output, err := finder.GatewayAssociationByID(conn, id)

if tfresource.NotFound(err) {
return nil, "", nil
}

if err != nil {
return nil, "", err
}

return output, aws.StringValue(output.AssociationState), nil
}
}
106 changes: 106 additions & 0 deletions aws/internal/service/directconnect/waiter/waiter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package waiter

import (
"errors"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/directconnect"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource"
)

func GatewayCreated(conn *directconnect.DirectConnect, id string, timeout time.Duration) (*directconnect.Gateway, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{directconnect.GatewayStatePending},
Target: []string{directconnect.GatewayStateAvailable},
Refresh: GatewayState(conn, id),
Timeout: timeout,
}

outputRaw, err := stateConf.WaitForState()

if output, ok := outputRaw.(*directconnect.Gateway); ok {
tfresource.SetLastError(err, errors.New(aws.StringValue(output.StateChangeError)))

return output, err
}

return nil, err
}

func GatewayDeleted(conn *directconnect.DirectConnect, id string, timeout time.Duration) (*directconnect.Gateway, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{directconnect.GatewayStatePending, directconnect.GatewayStateAvailable, directconnect.GatewayStateDeleting},
Target: []string{},
Refresh: GatewayState(conn, id),
Timeout: timeout,
}

outputRaw, err := stateConf.WaitForState()

if output, ok := outputRaw.(*directconnect.Gateway); ok {
tfresource.SetLastError(err, errors.New(aws.StringValue(output.StateChangeError)))

return output, err
}

return nil, err
}

func GatewayAssociationCreated(conn *directconnect.DirectConnect, id string, timeout time.Duration) (*directconnect.GatewayAssociation, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{directconnect.GatewayAssociationStateAssociating},
Target: []string{directconnect.GatewayAssociationStateAssociated},
Refresh: GatewayAssociationState(conn, id),
Timeout: timeout,
}

outputRaw, err := stateConf.WaitForState()

if output, ok := outputRaw.(*directconnect.GatewayAssociation); ok {
tfresource.SetLastError(err, errors.New(aws.StringValue(output.StateChangeError)))

return output, err
}

return nil, err
}

func GatewayAssociationUpdated(conn *directconnect.DirectConnect, id string, timeout time.Duration) (*directconnect.GatewayAssociation, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{directconnect.GatewayAssociationStateUpdating},
Target: []string{directconnect.GatewayAssociationStateAssociated},
Refresh: GatewayAssociationState(conn, id),
Timeout: timeout,
}

outputRaw, err := stateConf.WaitForState()

if output, ok := outputRaw.(*directconnect.GatewayAssociation); ok {
tfresource.SetLastError(err, errors.New(aws.StringValue(output.StateChangeError)))

return output, err
}

return nil, err
}

func GatewayAssociationDeleted(conn *directconnect.DirectConnect, id string, timeout time.Duration) (*directconnect.GatewayAssociation, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{directconnect.GatewayAssociationStateDisassociating},
Target: []string{},
Refresh: GatewayAssociationState(conn, id),
Timeout: timeout,
}

outputRaw, err := stateConf.WaitForState()

if output, ok := outputRaw.(*directconnect.GatewayAssociation); ok {
tfresource.SetLastError(err, errors.New(aws.StringValue(output.StateChangeError)))

return output, err
}

return nil, err
}
Loading