Skip to content

Commit

Permalink
New Resource: aws_ec2_transit_gateway_prefix_list_reference
Browse files Browse the repository at this point in the history
Reference: #16572

Output from acceptance testing in AWS Commercial:

```
--- PASS: TestAccAwsEc2TransitGatewayPrefixListReference_disappears (214.31s)
--- PASS: TestAccAwsEc2TransitGatewayPrefixListReference_basic (217.12s)
--- PASS: TestAccAwsEc2TransitGatewayPrefixListReference_disappears_TransitGateway (219.77s)
--- PASS: TestAccAwsEc2TransitGatewayPrefixListReference_TransitGatewayAttachmentId (397.05s)
```
  • Loading branch information
bflad authored and YakDriver committed Feb 4, 2021
1 parent d6389c1 commit 9c45ddd
Show file tree
Hide file tree
Showing 9 changed files with 645 additions and 0 deletions.
4 changes: 4 additions & 0 deletions aws/internal/service/ec2/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ const (
ErrCodeInvalidPrefixListIDNotFound = "InvalidPrefixListID.NotFound"
)

const (
ErrCodeInvalidRouteTableIDNotFound = "InvalidRouteTableID.NotFound"
)

const (
ErrCodeClientVpnEndpointIdNotFound = "InvalidClientVpnEndpointId.NotFound"
ErrCodeClientVpnAuthorizationRuleNotFound = "InvalidClientVpnEndpointAuthorizationRuleNotFound"
Expand Down
46 changes: 46 additions & 0 deletions aws/internal/service/ec2/finder/finder.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package finder

import (
"fmt"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
tfec2 "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2"
Expand Down Expand Up @@ -110,6 +112,50 @@ func SubnetByID(conn *ec2.EC2, id string) (*ec2.Subnet, error) {
return output.Subnets[0], nil
}

func TransitGatewayPrefixListReference(conn *ec2.EC2, transitGatewayRouteTableID string, prefixListID string) (*ec2.TransitGatewayPrefixListReference, error) {
filters := map[string]string{
"prefix-list-id": prefixListID,
}

input := &ec2.GetTransitGatewayPrefixListReferencesInput{
TransitGatewayRouteTableId: aws.String(transitGatewayRouteTableID),
Filters: tfec2.BuildAttributeFilterList(filters),
}

var result *ec2.TransitGatewayPrefixListReference

err := conn.GetTransitGatewayPrefixListReferencesPages(input, func(page *ec2.GetTransitGatewayPrefixListReferencesOutput, lastPage bool) bool {
if page == nil {
return !lastPage
}

for _, transitGatewayPrefixListReference := range page.TransitGatewayPrefixListReferences {
if transitGatewayPrefixListReference == nil {
continue
}

if aws.StringValue(transitGatewayPrefixListReference.PrefixListId) == prefixListID {
result = transitGatewayPrefixListReference
return false
}
}

return !lastPage
})

return result, err
}

func TransitGatewayPrefixListReferenceByID(conn *ec2.EC2, resourceID string) (*ec2.TransitGatewayPrefixListReference, error) {
transitGatewayRouteTableID, prefixListID, err := tfec2.TransitGatewayPrefixListReferenceParseID(resourceID)

if err != nil {
return nil, fmt.Errorf("error parsing EC2 Transit Gateway Prefix List Reference (%s) identifier: %w", resourceID, err)
}

return TransitGatewayPrefixListReference(conn, transitGatewayRouteTableID, prefixListID)
}

// VpcPeeringConnectionByID returns the VPC peering connection corresponding to the specified identifier.
// Returns nil and potentially an error if no VPC peering connection is found.
func VpcPeeringConnectionByID(conn *ec2.EC2, id string) (*ec2.VpcPeeringConnection, error) {
Expand Down
19 changes: 19 additions & 0 deletions aws/internal/service/ec2/id.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,25 @@ func ClientVpnRouteParseID(id string) (string, string, string, error) {
"target-subnet-id"+clientVpnRouteIDSeparator+"destination-cidr-block", id)
}

const transitGatewayPrefixListReferenceSeparator = "_"

func TransitGatewayPrefixListReferenceCreateID(transitGatewayRouteTableID string, prefixListID string) string {
parts := []string{transitGatewayRouteTableID, prefixListID}
id := strings.Join(parts, transitGatewayPrefixListReferenceSeparator)

return id
}

func TransitGatewayPrefixListReferenceParseID(id string) (string, string, error) {
parts := strings.Split(id, transitGatewayPrefixListReferenceSeparator)

if len(parts) == 2 && parts[0] != "" && parts[1] != "" {
return parts[0], parts[1], nil
}

return "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected transit-gateway-route-table-id%[2]sprefix-list-id", id, transitGatewayPrefixListReferenceSeparator)
}

func VpnGatewayVpcAttachmentCreateID(vpnGatewayID, vpcID string) string {
return fmt.Sprintf("vpn-attachment-%x", hashcode.String(fmt.Sprintf("%s-%s", vpcID, vpnGatewayID)))
}
16 changes: 16 additions & 0 deletions aws/internal/service/ec2/waiter/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,22 @@ func SubnetMapPublicIpOnLaunch(conn *ec2.EC2, id string) resource.StateRefreshFu
}
}

func TransitGatewayPrefixListReferenceState(conn *ec2.EC2, transitGatewayRouteTableID string, prefixListID string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
transitGatewayPrefixListReference, err := finder.TransitGatewayPrefixListReference(conn, transitGatewayRouteTableID, prefixListID)

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

if transitGatewayPrefixListReference == nil {
return nil, "", nil
}

return transitGatewayPrefixListReference, aws.StringValue(transitGatewayPrefixListReference.State), nil
}
}

const (
vpcPeeringConnectionStatusNotFound = "NotFound"
vpcPeeringConnectionStatusUnknown = "Unknown"
Expand Down
60 changes: 60 additions & 0 deletions aws/internal/service/ec2/waiter/waiter.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
tfec2 "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2"
)

const (
Expand Down Expand Up @@ -290,6 +291,65 @@ func SubnetMapPublicIpOnLaunchUpdated(conn *ec2.EC2, subnetID string, expectedVa
return nil, err
}

const (
TransitGatewayPrefixListReferenceTimeout = 5 * time.Minute
)

func TransitGatewayPrefixListReferenceStateCreated(conn *ec2.EC2, transitGatewayRouteTableID string, prefixListID string) (*ec2.TransitGatewayPrefixListReference, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{ec2.TransitGatewayPrefixListReferenceStatePending},
Target: []string{ec2.TransitGatewayPrefixListReferenceStateAvailable},
Timeout: TransitGatewayPrefixListReferenceTimeout,
Refresh: TransitGatewayPrefixListReferenceState(conn, transitGatewayRouteTableID, prefixListID),
}

outputRaw, err := stateConf.WaitForState()

if output, ok := outputRaw.(*ec2.TransitGatewayPrefixListReference); ok {
return output, err
}

return nil, err
}

func TransitGatewayPrefixListReferenceStateDeleted(conn *ec2.EC2, transitGatewayRouteTableID string, prefixListID string) (*ec2.TransitGatewayPrefixListReference, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{ec2.TransitGatewayPrefixListReferenceStateDeleting},
Target: []string{},
Timeout: TransitGatewayPrefixListReferenceTimeout,
Refresh: TransitGatewayPrefixListReferenceState(conn, transitGatewayRouteTableID, prefixListID),
}

outputRaw, err := stateConf.WaitForState()

if tfawserr.ErrCodeEquals(err, tfec2.ErrCodeInvalidRouteTableIDNotFound) {
return nil, nil
}

if output, ok := outputRaw.(*ec2.TransitGatewayPrefixListReference); ok {
return output, err
}

return nil, err
}

func TransitGatewayPrefixListReferenceStateUpdated(conn *ec2.EC2, transitGatewayRouteTableID string, prefixListID string) (*ec2.TransitGatewayPrefixListReference, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{ec2.TransitGatewayPrefixListReferenceStateModifying},
Target: []string{ec2.TransitGatewayPrefixListReferenceStateAvailable},
Timeout: TransitGatewayPrefixListReferenceTimeout,
Refresh: TransitGatewayPrefixListReferenceState(conn, transitGatewayRouteTableID, prefixListID),
}

outputRaw, err := stateConf.WaitForState()

if output, ok := outputRaw.(*ec2.TransitGatewayPrefixListReference); ok {
return output, err
}

return nil, err
}

const (
VpnGatewayVpcAttachmentAttachedTimeout = 15 * time.Minute

Expand Down
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ func Provider() *schema.Provider {
"aws_ec2_transit_gateway": resourceAwsEc2TransitGateway(),
"aws_ec2_transit_gateway_peering_attachment": resourceAwsEc2TransitGatewayPeeringAttachment(),
"aws_ec2_transit_gateway_peering_attachment_accepter": resourceAwsEc2TransitGatewayPeeringAttachmentAccepter(),
"aws_ec2_transit_gateway_prefix_list_reference": resourceAwsEc2TransitGatewayPrefixListReference(),
"aws_ec2_transit_gateway_route": resourceAwsEc2TransitGatewayRoute(),
"aws_ec2_transit_gateway_route_table": resourceAwsEc2TransitGatewayRouteTable(),
"aws_ec2_transit_gateway_route_table_association": resourceAwsEc2TransitGatewayRouteTableAssociation(),
Expand Down
Loading

0 comments on commit 9c45ddd

Please sign in to comment.