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: Remove extraneous Exists function #13048

Merged
merged 1 commit into from
Apr 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 16 additions & 0 deletions aws/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,22 @@ func testAccAwsRegionProviderFunc(region string, providers *[]*schema.Provider)
}
}

func testAccCheckResourceDisappears(provider *schema.Provider, resource *schema.Resource, resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
resourceState, ok := s.RootModule().Resources[resourceName]

if !ok {
return fmt.Errorf("resource not found: %s", resourceName)
}

if resourceState.Primary.ID == "" {
return fmt.Errorf("resource ID missing: %s", resourceName)
}

return resource.Delete(resource.Data(resourceState.Primary), provider.Meta())
}
}

func testAccCheckWithProviders(f func(*terraform.State, *schema.Provider) error, providers *[]*schema.Provider) resource.TestCheckFunc {
return func(s *terraform.State) error {
numberOfProviders := len(*providers)
Expand Down
107 changes: 43 additions & 64 deletions aws/resource_aws_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ func resourceAwsRoute() *schema.Resource {
Read: resourceAwsRouteRead,
Update: resourceAwsRouteUpdate,
Delete: resourceAwsRouteDelete,
Exists: resourceAwsRouteExists,
Importer: &schema.ResourceImporter{
State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
idParts := strings.Split(d.Id(), "_")
Expand Down Expand Up @@ -286,6 +285,10 @@ func resourceAwsRouteCreate(d *schema.ResourceData, meta interface{}) error {
if v, ok := d.GetOk("destination_cidr_block"); ok {
err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
route, err = resourceAwsRouteFindRoute(conn, d.Get("route_table_id").(string), v.(string), "")
if err == nil && route != nil {
return nil
}

return resource.RetryableError(err)
})
if isResourceTimeoutError(err) {
Expand All @@ -294,11 +297,18 @@ func resourceAwsRouteCreate(d *schema.ResourceData, meta interface{}) error {
if err != nil {
return fmt.Errorf("Error finding route after creating it: %s", err)
}
if route == nil {
return fmt.Errorf("Unable to find matching route for Route Table (%s) and destination CIDR block (%s).", d.Get("route_table_id").(string), v)
}
}

if v, ok := d.GetOk("destination_ipv6_cidr_block"); ok {
err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
route, err = resourceAwsRouteFindRoute(conn, d.Get("route_table_id").(string), "", v.(string))
if err == nil && route != nil {
return nil
}

return resource.RetryableError(err)
})
if isResourceTimeoutError(err) {
Expand All @@ -307,10 +317,14 @@ func resourceAwsRouteCreate(d *schema.ResourceData, meta interface{}) error {
if err != nil {
return fmt.Errorf("Error finding route after creating it: %s", err)
}
if route == nil {
return fmt.Errorf("Unable to find matching route for Route Table (%s) and destination IPv6 CIDR block (%s).", d.Get("route_table_id").(string), v)
}
}

d.SetId(resourceAwsRouteID(d, route))
resourceAwsRouteSetResourceData(d, route)

return nil
}

Expand All @@ -322,16 +336,23 @@ func resourceAwsRouteRead(d *schema.ResourceData, meta interface{}) error {
destinationIpv6CidrBlock := d.Get("destination_ipv6_cidr_block").(string)

route, err := resourceAwsRouteFindRoute(conn, routeTableId, destinationCidrBlock, destinationIpv6CidrBlock)
if isAWSErr(err, "InvalidRouteTableID.NotFound", "") {
log.Printf("[WARN] Route Table (%s) not found, removing from state", routeTableId)
d.SetId("")
return nil
}
if err != nil {
if isAWSErr(err, "InvalidRouteTableID.NotFound", "") {
log.Printf("[WARN] Route Table %q could not be found. Removing Route from state.",
routeTableId)
d.SetId("")
return nil
}
return err
}

if route == nil {
log.Printf("[WARN] Matching route not found, removing from state")
d.SetId("")
return nil
}

resourceAwsRouteSetResourceData(d, route)

return nil
}

Expand Down Expand Up @@ -454,74 +475,36 @@ func resourceAwsRouteDelete(d *schema.ResourceData, meta interface{}) error {
}
log.Printf("[DEBUG] Route delete opts: %s", deleteOpts)

var resp *ec2.DeleteRouteOutput
err := resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError {
log.Printf("[DEBUG] Trying to delete route with opts %s", deleteOpts)
var err error
resp, err = conn.DeleteRoute(deleteOpts)
log.Printf("[DEBUG] Route delete result: %s", resp)

_, err = conn.DeleteRoute(deleteOpts)
if err == nil {
return nil
}

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

if isAWSErr(err, "InvalidParameterException", "") {
return resource.RetryableError(err)
}

return resource.NonRetryableError(err)
})
if isResourceTimeoutError(err) {
resp, err = conn.DeleteRoute(deleteOpts)
_, err = conn.DeleteRoute(deleteOpts)
}
if isAWSErr(err, "InvalidRoute.NotFound", "") {
return nil
}
if err != nil {
return fmt.Errorf("Error deleting route: %s", err)
}
return nil
}

func resourceAwsRouteExists(d *schema.ResourceData, meta interface{}) (bool, error) {
conn := meta.(*AWSClient).ec2conn
routeTableId := d.Get("route_table_id").(string)

findOpts := &ec2.DescribeRouteTablesInput{
RouteTableIds: []*string{&routeTableId},
}

res, err := conn.DescribeRouteTables(findOpts)
if err != nil {
if isAWSErr(err, "InvalidRouteTableID.NotFound", "") {
log.Printf("[WARN] Route Table %q could not be found.", routeTableId)
return false, nil
}
return false, fmt.Errorf("Error while checking if route exists: %s", err)
}

if len(res.RouteTables) < 1 || res.RouteTables[0] == nil {
log.Printf("[WARN] Route Table %q is gone, or route does not exist.",
routeTableId)
return false, nil
}

if v, ok := d.GetOk("destination_cidr_block"); ok {
for _, route := range (*res.RouteTables[0]).Routes {
if route.DestinationCidrBlock != nil && *route.DestinationCidrBlock == v.(string) {
return true, nil
}
}
}

if v, ok := d.GetOk("destination_ipv6_cidr_block"); ok {
for _, route := range (*res.RouteTables[0]).Routes {
if route.DestinationIpv6CidrBlock != nil && *route.DestinationIpv6CidrBlock == v.(string) {
return true, nil
}
}
}

return false, nil
}

// Helper: Create an ID for a route
func resourceAwsRouteID(d *schema.ResourceData, r *ec2.Route) string {

Expand All @@ -532,7 +515,8 @@ func resourceAwsRouteID(d *schema.ResourceData, r *ec2.Route) string {
return fmt.Sprintf("r-%s%d", d.Get("route_table_id").(string), hashcode.String(*r.DestinationCidrBlock))
}

// Helper: retrieve a route
// resourceAwsRouteFindRoute returns any route whose destination is the specified IPv4 or IPv6 CIDR block.
// Returns nil if the route table exists but no matching destination is found.
func resourceAwsRouteFindRoute(conn *ec2.EC2, rtbid string, cidr string, ipv6cidr string) (*ec2.Route, error) {
routeTableID := rtbid

Expand All @@ -546,8 +530,7 @@ func resourceAwsRouteFindRoute(conn *ec2.EC2, rtbid string, cidr string, ipv6cid
}

if len(resp.RouteTables) < 1 || resp.RouteTables[0] == nil {
return nil, fmt.Errorf("Route Table %q is gone, or route does not exist.",
routeTableID)
return nil, nil
}

if cidr != "" {
Expand All @@ -557,8 +540,7 @@ func resourceAwsRouteFindRoute(conn *ec2.EC2, rtbid string, cidr string, ipv6cid
}
}

return nil, fmt.Errorf("Unable to find matching route for Route Table (%s) "+
"and destination CIDR block (%s).", rtbid, cidr)
return nil, nil
}

if ipv6cidr != "" {
Expand All @@ -568,11 +550,8 @@ func resourceAwsRouteFindRoute(conn *ec2.EC2, rtbid string, cidr string, ipv6cid
}
}

return nil, fmt.Errorf("Unable to find matching route for Route Table (%s) "+
"and destination IPv6 CIDR block (%s).", rtbid, ipv6cidr)
return nil, nil
}

return nil, fmt.Errorf("When trying to find a matching route for Route Table %q "+
"you need to specify a CIDR block of IPv6 CIDR Block", rtbid)

return nil, nil
}
22 changes: 22 additions & 0 deletions aws/resource_aws_route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,28 @@ func TestAccAWSRoute_basic(t *testing.T) {
})
}

func TestAccAWSRoute_disappears(t *testing.T) {
var route ec2.Route

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSRouteDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSRouteBasicConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSRouteExists("aws_route.bar", &route),
testAccCheckResourceDisappears(testAccProvider, resourceAwsRoute(), "aws_route.bar"),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func TestAccAWSRoute_ipv6Support(t *testing.T) {
var route ec2.Route

Expand Down