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

r/aws_route: Correctly handle update of route target #14531

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
34c8326
r/aws_route: Tidy up 'testAccAWSRouteConfigBasic()'.
ewbankkit Jun 25, 2020
ae3877d
r/aws_route: Rename 'TestAccAWSRoute_ipv6Support' to 'TestAccAWSRoute…
ewbankkit Jun 25, 2020
898d88f
Remove 'TestAccAWSRoute_noopdiff'. Test steps implicitly test this fu…
ewbankkit Jun 25, 2020
21a7be4
r/aws_route: Tidy up 'TestAccAWSRoute_doesNotCrashWithVPCEndpoint'.
ewbankkit Jun 25, 2020
14619ce
r/aws_route: Tidy up 'TestAccAWSRoute_ipv6ToInternetGateway'.
ewbankkit Jun 26, 2020
e614a3f
r/aws_route: Tidy up 'TestAccAWSRoute_ipv6ToInstance'.
ewbankkit Jun 26, 2020
d169975
r/aws_route: Tidy up 'TestAccAWSRoute_ipv6ToNetworkInterface'.
ewbankkit Jun 26, 2020
23d7915
r/aws_route: Tidy up 'TestAccAWSRoute_ipv6ToVpcPeeringConnection'.
ewbankkit Jun 26, 2020
ce80327
r/aws_route: Tidy up 'TestAccAWSRoute_TransitGatewayID_DestinationCid…
ewbankkit Jun 26, 2020
8c6dc6c
r/aws_route: Add 'TestAccAWSRoute_IPv4_To_Instance'.
ewbankkit Jun 26, 2020
c02f9a8
r/aws_route: Add 'TestAccAWSRoute_IPv4_To_NetworkInterface'.
ewbankkit Jun 26, 2020
5dc50de
r/aws_route: Add 'TestAccAWSRoute_IPv4_To_VpcPeeringConnection'.
ewbankkit Jun 26, 2020
84cd688
r/aws_route: Add 'TestAccAWSRoute_IPv4_To_NatGateway'.
ewbankkit Jun 26, 2020
81d4e6d
r/aws_route: Comment out failing target update test.
ewbankkit Jun 26, 2020
f8a9f6e
r/aws_route: Add 'TestAccAWSRoute_IPv4_To_VpnGateway'.
ewbankkit Jun 27, 2020
ffa6926
r/aws_route: Add 'TestAccAWSRoute_IPv6_To_VpnGateway'.
ewbankkit Jun 27, 2020
23c67d9
r/aws_route: Test computed attributes.
ewbankkit Jun 27, 2020
a493e56
r/aws_route: Changes for #13766, #13771.
ewbankkit Jun 27, 2020
36c2963
r/aws_route: 'testAccCheckAWSRouteNumberOfRoutes' -> 'testAccCheckAWS…
ewbankkit Jun 29, 2020
63097db
r/aws_route: Add 'TestAccAWSRoute_routeTableDisappears'.
ewbankkit Jun 29, 2020
c0bf646
r/aws_route: Rework 'TestAccAWSRoute_ConditionalCidrBlock'.
ewbankkit Jul 1, 2020
176993f
r/aws_route: Add 'TestAccAWSRoute_IPv4_To_NetworkInterface_Attached' …
ewbankkit Jul 4, 2020
c2b78d0
r/aws_route: Add 'TestAccAWSRoute_IPv4_To_NetworkInterface_TwoAttachm…
ewbankkit Jul 4, 2020
42bd9bc
r/aws_route: Comment out failing 'TestAccAWSRoute_IPv4_To_NetworkInte…
ewbankkit Jul 4, 2020
fd956d8
r/aws_route: Use 'available' as the name of the 'aws_availability_zon…
ewbankkit Jul 6, 2020
141714e
r/aws_route: Use Amazon NAT instance AMI for instance tests.
ewbankkit Jul 15, 2020
36faae1
Use 'testAccAvailableAZsNoOptInDefaultExcludeConfig'.
ewbankkit Aug 9, 2020
ba1983d
r/aws_route: Add 'TestAccAWSRoute_IPv4_Update_Target'. Currently fails.
ewbankkit Jun 27, 2020
9d40178
r/aws_route: Add 'TestAccAWSRoute_IPv6_Update_Target'. Currently fails.
ewbankkit Jun 28, 2020
3c1ccbe
r/aws_route: Better validation.
ewbankkit Jul 1, 2020
b35843d
r/aws_route: Correctly handle route target updates.
ewbankkit Jul 3, 2020
80d2c45
r/aws_route: Uncommented 'TestAccAWSRoute_IPv4_To_NetworkInterface_Tw…
ewbankkit Jul 4, 2020
35b1175
Acceptance test output:
ewbankkit Jul 4, 2020
5df1429
r/aws_route: Use 'available' as the name of the 'aws_availability_zon…
ewbankkit Jul 6, 2020
6b27b98
r/aws_route: Add 'TestAccAWSRoute_LocalRoute' to test ability to impo…
ewbankkit Jul 8, 2020
d780df4
r/aws_route: Add error constants to 'aws/internal/service/ec2'. Tweak…
ewbankkit Jul 10, 2020
96a8b5f
r/aw3s_route: Move route finders to 'aws/internal/service/ec2/finder'…
ewbankkit Jul 10, 2020
ca1bec0
r/aws_route: Add 'createRoute' function.
ewbankkit Jul 10, 2020
20d086a
Use 'testAccAvailableAZsNoOptInDefaultExcludeConfig'.
ewbankkit Aug 10, 2020
193e047
Use 'RouteCreateID' in 'internal/service/ec2' package.
ewbankkit Aug 10, 2020
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
15 changes: 15 additions & 0 deletions aws/data_source_aws_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"fmt"
"log"

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

func dataSourceAwsRoute() *schema.Resource {
Expand Down Expand Up @@ -190,3 +192,16 @@ func getRoutes(table *ec2.RouteTable, d *schema.ResourceData) []*ec2.Route {
}
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 destination := aws.StringValue(r.DestinationCidrBlock); destination != "" {
return tfec2.RouteCreateID(routeTableID, destination)
} else if destination := aws.StringValue(r.DestinationIpv6CidrBlock); destination != "" {
return tfec2.RouteCreateID(routeTableID, destination)
}

return ""
}
23 changes: 23 additions & 0 deletions aws/internal/net/cidr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package net

import (
"net"
)

// CIDRBlocksEqual returns whether or not two CIDR blocks are equal:
// - Both CIDR blocks parse to an IP address and network
// - The string representation of the IP addresses are equal
// - The string representation of the networks are equal
// This function is especially useful for IPv6 CIDR blocks which have multiple valid representations.
func CIDRBlocksEqual(cidr1, cidr2 string) bool {
ip1, ipnet1, err := net.ParseCIDR(cidr1)
if err != nil {
return false
}
ip2, ipnet2, err := net.ParseCIDR(cidr2)
if err != nil {
return false
}

return ip2.String() == ip1.String() && ipnet2.String() == ipnet1.String()
}
26 changes: 26 additions & 0 deletions aws/internal/net/cidr_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package net

import (
"testing"
)

func Test_CIDRBlocksEqual(t *testing.T) {
for _, ts := range []struct {
cidr1 string
cidr2 string
equal bool
}{
{"10.2.2.0/24", "10.2.2.0/24", true},
{"10.2.2.0/1234", "10.2.2.0/24", false},
{"10.2.2.0/24", "10.2.2.0/1234", false},
{"2001::/15", "2001::/15", true},
{"::/0", "2001::/15", false},
{"::/0", "::0/0", true},
{"", "", false},
} {
equal := CIDRBlocksEqual(ts.cidr1, ts.cidr2)
if ts.equal != equal {
t.Fatalf("CIDRBlocksEqual(%q, %q) should be: %t", ts.cidr1, ts.cidr2, ts.equal)
}
}
}
10 changes: 10 additions & 0 deletions aws/internal/service/ec2/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,13 @@ const ErrCodeClientVpnAuthorizationRuleNotFound = "InvalidClientVpnEndpointAutho
const ErrCodeClientVpnAssociationIdNotFound = "InvalidClientVpnAssociationId.NotFound"

const ErrCodeClientVpnRouteNotFound = "InvalidClientVpnRouteNotFound"

const ErrCodeInvalidParameterException = "InvalidParameterException"

const ErrCodeInvalidParameterValue = "InvalidParameterValue"

const ErrCodeRouteNotFound = "InvalidRoute.NotFound"

const ErrCodeRouteTableNotFound = "InvalidRouteTableID.NotFound"

const ErrCodeTransitGatewayNotFound = "InvalidTransitGatewayID.NotFound"
56 changes: 56 additions & 0 deletions aws/internal/service/ec2/finder/finder.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package finder
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
tfnet "github.com/terraform-providers/terraform-provider-aws/aws/internal/net"
tfec2 "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2"
)

Expand Down Expand Up @@ -54,3 +55,58 @@ func ClientVpnRouteByID(conn *ec2.EC2, routeID string) (*ec2.DescribeClientVpnRo

return ClientVpnRoute(conn, endpointID, targetSubnetID, destinationCidr)
}

// RouteTableByID returns the route table corresponding to the specified identifier.
// Returns nil if no route table is found.
func RouteTableByID(conn *ec2.EC2, routeTableID string) (*ec2.RouteTable, error) {
input := &ec2.DescribeRouteTablesInput{
RouteTableIds: aws.StringSlice([]string{routeTableID}),
}

output, err := conn.DescribeRouteTables(input)
if err != nil {
return nil, err
}

if output == nil || len(output.RouteTables) == 0 || output.RouteTables[0] == nil {
return nil, nil
}

return output.RouteTables[0], nil
}

type RouteFinder func(*ec2.EC2, string, string) (*ec2.Route, error)

// RouteByIpv4Destination returns the route corresponding to the specified IPv4 destination.
// Returns nil if no route is found.
func RouteByIpv4Destination(conn *ec2.EC2, routeTableID, destinationCidr string) (*ec2.Route, error) {
routeTable, err := RouteTableByID(conn, routeTableID)
if err != nil {
return nil, err
}

for _, route := range routeTable.Routes {
if aws.StringValue(route.DestinationCidrBlock) == destinationCidr {
return route, nil
}
}

return nil, nil
}

// RouteByIpv6Destination returns the route corresponding to the specified IPv6 destination.
// Returns nil if no route is found.
func RouteByIpv6Destination(conn *ec2.EC2, routeTableID, destinationIpv6Cidr string) (*ec2.Route, error) {
routeTable, err := RouteTableByID(conn, routeTableID)
if err != nil {
return nil, err
}

for _, route := range routeTable.Routes {
if tfnet.CIDRBlocksEqual(aws.StringValue(route.DestinationIpv6CidrBlock), destinationIpv6Cidr) {
return route, nil
}
}

return nil, nil
}
7 changes: 7 additions & 0 deletions aws/internal/service/ec2/id.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package ec2
import (
"fmt"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/helper/hashcode"
)

const clientVpnAuthorizationRuleIDSeparator = ","
Expand Down Expand Up @@ -49,3 +51,8 @@ func ClientVpnRouteParseID(id string) (string, string, string, error) {
fmt.Errorf("unexpected format for ID (%q), expected endpoint-id"+clientVpnRouteIDSeparator+
"target-subnet-id"+clientVpnRouteIDSeparator+"destination-cidr-block", id)
}

// RouteCreateID returns a route resource ID.
func RouteCreateID(routeTableID, destination string) string {
return fmt.Sprintf("r-%s%d", routeTableID, hashcode.String(destination))
}
Loading