Skip to content

Commit

Permalink
Merge pull request #16963 from ewbankkit/d-aws_route-wavelength
Browse files Browse the repository at this point in the history
d/aws_route: AWS Wavelength support
  • Loading branch information
YakDriver authored Mar 26, 2021
2 parents 18cac7d + c679cff commit d76c0dc
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 135 deletions.
3 changes: 3 additions & 0 deletions .changelog/16963.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-notes:enhancement
data-source/aws_route: Add `carrier_gateway_id` attribute
```
184 changes: 77 additions & 107 deletions aws/data_source_aws_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package aws

import (
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
tfec2 "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2/finder"
)

func dataSourceAwsRoute() *schema.Resource {
Expand All @@ -19,6 +19,10 @@ func dataSourceAwsRoute() *schema.Resource {
Type: schema.TypeString,
Required: true,
},

///
// Destinations.
///
"destination_cidr_block": {
Type: schema.TypeString,
Optional: true,
Expand All @@ -29,6 +33,15 @@ func dataSourceAwsRoute() *schema.Resource {
Optional: true,
Computed: true,
},

//
// Targets.
//
"carrier_gateway_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"egress_only_gateway_id": {
Type: schema.TypeString,
Optional: true,
Expand All @@ -44,27 +57,27 @@ func dataSourceAwsRoute() *schema.Resource {
Optional: true,
Computed: true,
},
"nat_gateway_id": {
"local_gateway_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"local_gateway_id": {
"nat_gateway_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"transit_gateway_id": {
"network_interface_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"vpc_peering_connection_id": {
"transit_gateway_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"network_interface_id": {
"vpc_peering_connection_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Expand All @@ -75,63 +88,19 @@ func dataSourceAwsRoute() *schema.Resource {

func dataSourceAwsRouteRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ec2conn
req := &ec2.DescribeRouteTablesInput{}
rtbId := d.Get("route_table_id")
cidr := d.Get("destination_cidr_block")
ipv6Cidr := d.Get("destination_ipv6_cidr_block")

req.Filters = buildEC2AttributeFilterList(
map[string]string{
"route-table-id": rtbId.(string),
"route.destination-cidr-block": cidr.(string),
"route.destination-ipv6-cidr-block": ipv6Cidr.(string),
},
)

log.Printf("[DEBUG] Reading Route Table: %s", req)
resp, err := conn.DescribeRouteTables(req)
if err != nil {
return err
}
if resp == nil || len(resp.RouteTables) == 0 {
return fmt.Errorf("Your query returned no results. Please change your search criteria and try again.")
}
if len(resp.RouteTables) > 1 {
return fmt.Errorf("Your query returned more than one route table. Please change your search criteria and try again.")
}
routeTableID := d.Get("route_table_id").(string)

results := getRoutes(resp.RouteTables[0], d)
routeTable, err := finder.RouteTableByID(conn, routeTableID)

if len(results) == 0 {
return fmt.Errorf("No routes matching supplied arguments found in table(s)")
}
if len(results) > 1 {
return fmt.Errorf("Multiple routes matched; use additional constraints to reduce matches to a single route")
if err != nil {
return fmt.Errorf("error reading Route Table (%s): %w", routeTableID, err)
}
route := results[0]

d.SetId(resourceAwsRouteID(d, route)) // using function from "resource_aws_route.go"
d.Set("destination_cidr_block", route.DestinationCidrBlock)
d.Set("destination_ipv6_cidr_block", route.DestinationIpv6CidrBlock)
d.Set("egress_only_gateway_id", route.EgressOnlyInternetGatewayId)
d.Set("gateway_id", route.GatewayId)
d.Set("instance_id", route.InstanceId)
d.Set("nat_gateway_id", route.NatGatewayId)
d.Set("local_gateway_id", route.LocalGatewayId)
d.Set("transit_gateway_id", route.TransitGatewayId)
d.Set("vpc_peering_connection_id", route.VpcPeeringConnectionId)
d.Set("network_interface_id", route.NetworkInterfaceId)

return nil
}

func getRoutes(table *ec2.RouteTable, d *schema.ResourceData) []*ec2.Route {
ec2Routes := table.Routes
routes := make([]*ec2.Route, 0, len(ec2Routes))
// Loop through the routes and add them to the set
for _, r := range ec2Routes {
routes := []*ec2.Route{}

if r.Origin != nil && *r.Origin == "EnableVgwRoutePropagation" {
for _, r := range routeTable.Routes {
if aws.StringValue(r.Origin) == ec2.RouteOriginEnableVgwRoutePropagation {
continue
}

Expand All @@ -141,79 +110,80 @@ func getRoutes(table *ec2.RouteTable, d *schema.ResourceData) []*ec2.Route {
continue
}

if v, ok := d.GetOk("destination_cidr_block"); ok {
if r.DestinationCidrBlock == nil || *r.DestinationCidrBlock != v.(string) {
continue
}
if v, ok := d.GetOk("destination_cidr_block"); ok && aws.StringValue(r.DestinationCidrBlock) != v.(string) {
continue
}

if v, ok := d.GetOk("destination_ipv6_cidr_block"); ok {
if r.DestinationIpv6CidrBlock == nil || *r.DestinationIpv6CidrBlock != v.(string) {
continue
}
if v, ok := d.GetOk("destination_ipv6_cidr_block"); ok && aws.StringValue(r.DestinationIpv6CidrBlock) != v.(string) {
continue
}

if v, ok := d.GetOk("egress_only_gateway_id"); ok {
if r.EgressOnlyInternetGatewayId == nil || *r.EgressOnlyInternetGatewayId != v.(string) {
continue
}
if v, ok := d.GetOk("carrier_gateway_id"); ok && aws.StringValue(r.CarrierGatewayId) != v.(string) {
continue
}

if v, ok := d.GetOk("egress_only_gateway_id"); ok && aws.StringValue(r.EgressOnlyInternetGatewayId) != v.(string) {
continue
}

if v, ok := d.GetOk("gateway_id"); ok {
if r.GatewayId == nil || *r.GatewayId != v.(string) {
continue
}
if v, ok := d.GetOk("gateway_id"); ok && aws.StringValue(r.GatewayId) != v.(string) {
continue
}

if v, ok := d.GetOk("instance_id"); ok {
if r.InstanceId == nil || *r.InstanceId != v.(string) {
continue
}
if v, ok := d.GetOk("instance_id"); ok && aws.StringValue(r.InstanceId) != v.(string) {
continue
}

if v, ok := d.GetOk("nat_gateway_id"); ok {
if r.NatGatewayId == nil || *r.NatGatewayId != v.(string) {
continue
}
if v, ok := d.GetOk("local_gateway_id"); ok && aws.StringValue(r.LocalGatewayId) != v.(string) {
continue
}

if v, ok := d.GetOk("local_gateway_id"); ok {
if r.LocalGatewayId == nil || *r.LocalGatewayId != v.(string) {
continue
}
if v, ok := d.GetOk("nat_gateway_id"); ok && aws.StringValue(r.NatGatewayId) != v.(string) {
continue
}

if v, ok := d.GetOk("transit_gateway_id"); ok {
if r.TransitGatewayId == nil || *r.TransitGatewayId != v.(string) {
continue
}
if v, ok := d.GetOk("network_interface_id"); ok && aws.StringValue(r.NetworkInterfaceId) != v.(string) {
continue
}

if v, ok := d.GetOk("vpc_peering_connection_id"); ok {
if r.VpcPeeringConnectionId == nil || *r.VpcPeeringConnectionId != v.(string) {
continue
}
if v, ok := d.GetOk("transit_gateway_id"); ok && aws.StringValue(r.TransitGatewayId) != v.(string) {
continue
}

if v, ok := d.GetOk("network_interface_id"); ok {
if r.NetworkInterfaceId == nil || *r.NetworkInterfaceId != v.(string) {
continue
}
if v, ok := d.GetOk("vpc_peering_connection_id"); ok && aws.StringValue(r.VpcPeeringConnectionId) != v.(string) {
continue
}

routes = append(routes, r)
}
return routes
}

// Helper: Create an ID for a route
func resourceAwsRouteID(d *schema.ResourceData, r *ec2.Route) string {
routeTableID := d.Get("route_table_id").(string)
if len(routes) == 0 {
return fmt.Errorf("No routes matching supplied arguments found in Route Table (%s)", routeTableID)
}

if len(routes) > 1 {
return fmt.Errorf("%d routes matched in Route Table (%s); use additional constraints to reduce matches to a single route", len(routes), routeTableID)
}

route := routes[0]

if destination := aws.StringValue(r.DestinationCidrBlock); destination != "" {
return tfec2.RouteCreateID(routeTableID, destination)
} else if destination := aws.StringValue(r.DestinationIpv6CidrBlock); destination != "" {
return tfec2.RouteCreateID(routeTableID, destination)
if destination := aws.StringValue(route.DestinationCidrBlock); destination != "" {
d.SetId(tfec2.RouteCreateID(routeTableID, destination))
} else if destination := aws.StringValue(route.DestinationIpv6CidrBlock); destination != "" {
d.SetId(tfec2.RouteCreateID(routeTableID, destination))
}

return ""
d.Set("carrier_gateway_id", route.CarrierGatewayId)
d.Set("destination_cidr_block", route.DestinationCidrBlock)
d.Set("destination_ipv6_cidr_block", route.DestinationIpv6CidrBlock)
d.Set("egress_only_gateway_id", route.EgressOnlyInternetGatewayId)
d.Set("gateway_id", route.GatewayId)
d.Set("instance_id", route.InstanceId)
d.Set("local_gateway_id", route.LocalGatewayId)
d.Set("nat_gateway_id", route.NatGatewayId)
d.Set("network_interface_id", route.NetworkInterfaceId)
d.Set("transit_gateway_id", route.TransitGatewayId)
d.Set("vpc_peering_connection_id", route.VpcPeeringConnectionId)

return nil
}
62 changes: 62 additions & 0 deletions aws/data_source_aws_route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,29 @@ func TestAccAWSRouteDataSource_LocalGatewayID(t *testing.T) {
})
}

func TestAccAWSRouteDataSource_CarrierGatewayID(t *testing.T) {
dataSourceName := "data.aws_route.test"
resourceName := "aws_route.test"
rName := acctest.RandomWithPrefix("tf-acc-test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSWavelengthZoneAvailable(t) },
ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID),
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSRouteDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSRouteDataSourceConfigIpv4CarrierGateway(rName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair(resourceName, "destination_cidr_block", dataSourceName, "destination_cidr_block"),
resource.TestCheckResourceAttrPair(resourceName, "route_table_id", dataSourceName, "route_table_id"),
resource.TestCheckResourceAttrPair(resourceName, "carrier_gateway_id", dataSourceName, "carrier_gateway_id"),
),
},
},
})
}

func testAccDataSourceAwsRouteConfigBasic(rName string) string {
return composeConfig(
testAccLatestAmazonLinuxHvmEbsAmiConfig(),
Expand Down Expand Up @@ -352,3 +375,42 @@ data "aws_route" "by_local_gateway_id" {
}
`, rName)
}

func testAccAWSRouteDataSourceConfigIpv4CarrierGateway(rName string) string {
return fmt.Sprintf(`
resource "aws_vpc" "test" {
cidr_block = "10.0.0.0/16"
tags = {
Name = %[1]q
}
}
resource "aws_ec2_carrier_gateway" "test" {
vpc_id = aws_vpc.test.id
tags = {
Name = %[1]q
}
}
resource "aws_route_table" "test" {
vpc_id = aws_vpc.test.id
tags = {
Name = %[1]q
}
}
resource "aws_route" "test" {
destination_cidr_block = "0.0.0.0/0"
route_table_id = aws_route_table.test.id
carrier_gateway_id = aws_ec2_carrier_gateway.test.id
}
data "aws_route" "test" {
route_table_id = aws_route.test.route_table_id
carrier_gateway_id = aws_route.test.carrier_gateway_id
}
`, rName)
}
Loading

0 comments on commit d76c0dc

Please sign in to comment.