Skip to content

Commit

Permalink
Merge pull request #884 from cloudskiff/handle_prefix_list_id_in_route
Browse files Browse the repository at this point in the history
Handle `destination_prefix_list_id` in `aws_route`
  • Loading branch information
eliecharra committed Jul 26, 2021
2 parents d4a0194 + 4b7c874 commit 7b62202
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 106 deletions.
37 changes: 10 additions & 27 deletions pkg/middlewares/aws_route_table_expander.go
@@ -1,32 +1,13 @@
package middlewares

import (
"fmt"

"github.com/sirupsen/logrus"

"github.com/cloudskiff/driftctl/pkg/alerter"
"github.com/cloudskiff/driftctl/pkg/resource"
"github.com/cloudskiff/driftctl/pkg/resource/aws"
)

type invalidRouteAlert struct {
message string
}

func newInvalidRouteAlert(awsRouteTableResourceType, tableId string) *invalidRouteAlert {
message := fmt.Sprintf("Skipped invalid route found in state for %s.%s", awsRouteTableResourceType, tableId)
return &invalidRouteAlert{message}
}

func (i *invalidRouteAlert) Message() string {
return i.message
}

func (i *invalidRouteAlert) ShouldIgnoreResource() bool {
return false
}

// Explodes routes found in aws_default_route_table.route and aws_route_table.route to dedicated resources
type AwsRouteTableExpander struct {
alerter alerter.AlerterInterface
Expand Down Expand Up @@ -99,15 +80,16 @@ func (m *AwsRouteTableExpander) handleTable(table *resource.AbstractResource, re
if route["ipv6_cidr_block"] != nil {
ipv6CidrBlock = route["ipv6_cidr_block"].(string)
}
routeId, err := aws.CalculateRouteID(&table.Id, &cidrBlock, &ipv6CidrBlock)
if err != nil {
m.alerter.SendAlert(aws.AwsRouteTableResourceType, newInvalidRouteAlert(aws.AwsRouteTableResourceType, table.Id))
continue
prefixListId := ""
if route["destination_prefix_list_id"] != nil {
prefixListId = route["destination_prefix_list_id"].(string)
}
routeId := aws.CalculateRouteID(&table.Id, &cidrBlock, &ipv6CidrBlock, &prefixListId)

data := map[string]interface{}{
"destination_cidr_block": route["cidr_block"],
"destination_ipv6_cidr_block": route["ipv6_cidr_block"],
"destination_prefix_list_id": route["destination_prefix_list_id"],
"egress_only_gateway_id": route["egress_only_gateway_id"],
"gateway_id": route["gateway_id"],
"id": routeId,
Expand Down Expand Up @@ -152,15 +134,16 @@ func (m *AwsRouteTableExpander) handleDefaultTable(table *resource.AbstractResou
if route["ipv6_cidr_block"] != nil {
ipv6CidrBlock = route["ipv6_cidr_block"].(string)
}
routeId, err := aws.CalculateRouteID(&table.Id, &cidrBlock, &ipv6CidrBlock)
if err != nil {
m.alerter.SendAlert(aws.AwsDefaultRouteTableResourceType, newInvalidRouteAlert(aws.AwsDefaultRouteTableResourceType, table.Id))
continue
prefixListId := ""
if route["destination_prefix_list_id"] != nil {
prefixListId = route["destination_prefix_list_id"].(string)
}
routeId := aws.CalculateRouteID(&table.Id, &cidrBlock, &ipv6CidrBlock, &prefixListId)

data := map[string]interface{}{
"destination_cidr_block": route["cidr_block"],
"destination_ipv6_cidr_block": route["ipv6_cidr_block"],
"destination_prefix_list_id": route["destination_prefix_list_id"],
"egress_only_gateway_id": route["egress_only_gateway_id"],
"gateway_id": route["gateway_id"],
"id": routeId,
Expand Down
103 changes: 30 additions & 73 deletions pkg/middlewares/aws_route_table_expander_test.go
Expand Up @@ -84,6 +84,10 @@ func TestAwsRouteTableExpander_Execute(t *testing.T) {
"cidr_block": "",
"ipv6_cidr_block": "::/0",
},
map[string]interface{}{
"gateway_id": "igw-07b7844a8fd17a638",
"destination_prefix_list_id": "pl-63a5400a",
},
},
},
},
Expand Down Expand Up @@ -123,6 +127,18 @@ func TestAwsRouteTableExpander_Execute(t *testing.T) {
"instance_owner_id": "",
},
},
&resource.AbstractResource{
Id: "r-table_from_state3813769586",
Type: aws.AwsRouteResourceType,
Attrs: &resource.Attributes{
"route_table_id": "table_from_state",
"origin": "CreateRoute",
"gateway_id": "igw-07b7844a8fd17a638",
"state": "active",
"destination_prefix_list_id": "pl-63a5400a",
"instance_owner_id": "",
},
},
},
mock: func(factory *terraform.MockResourceFactory) {
factory.On("CreateAbstractResource", "aws_route", mock.Anything, mock.MatchedBy(func(input map[string]interface{}) bool {
Expand Down Expand Up @@ -155,6 +171,20 @@ func TestAwsRouteTableExpander_Execute(t *testing.T) {
"instance_owner_id": "",
},
}, nil)
factory.On("CreateAbstractResource", "aws_route", mock.Anything, mock.MatchedBy(func(input map[string]interface{}) bool {
return input["id"] == "r-table_from_state3813769586"
})).Times(1).Return(&resource.AbstractResource{
Id: "r-table_from_state3813769586",
Type: aws.AwsRouteResourceType,
Attrs: &resource.Attributes{
"route_table_id": "table_from_state",
"origin": "CreateRoute",
"gateway_id": "igw-07b7844a8fd17a638",
"state": "active",
"destination_prefix_list_id": "pl-63a5400a",
"instance_owner_id": "",
},
}, nil)
},
},
{
Expand Down Expand Up @@ -467,76 +497,3 @@ func TestAwsRouteTableExpander_Execute(t *testing.T) {
})
}
}

func TestAwsRouteTableExpander_ExecuteWithInvalidRoutes(t *testing.T) {

mockedAlerter := &mocks.AlerterInterface{}
mockedAlerter.On("SendAlert", aws.AwsRouteTableResourceType, newInvalidRouteAlert(
"aws_route_table", "table_from_state",
))
mockedAlerter.On("SendAlert", aws.AwsDefaultRouteTableResourceType, newInvalidRouteAlert(
"aws_default_route_table", "default_table_from_state",
))

input := []resource.Resource{
&resource.AbstractResource{
Id: "table_from_state",
Type: aws.AwsRouteTableResourceType,
Attrs: &resource.Attributes{
"route": []interface{}{
map[string]interface{}{
"gateway_id": "igw-07b7844a8fd17a638",
"cidr_block": "",
"ipv6_cidr_block": "",
},
},
},
},
&resource.AbstractResource{
Id: "default_table_from_state",
Type: aws.AwsDefaultRouteTableResourceType,
Attrs: &resource.Attributes{
"route": []interface{}{
map[string]interface{}{
"gateway_id": "igw-07b7844a8fd17a638",
"cidr_block": "",
"ipv6_cidr_block": "",
},
},
},
},
}

expected := []resource.Resource{
&resource.AbstractResource{
Id: "table_from_state",
Type: aws.AwsRouteTableResourceType,
Attrs: &resource.Attributes{},
},
&resource.AbstractResource{
Id: "default_table_from_state",
Type: aws.AwsDefaultRouteTableResourceType,
Attrs: &resource.Attributes{},
},
}

factory := &terraform.MockResourceFactory{}

m := NewAwsRouteTableExpander(mockedAlerter, factory)
err := m.Execute(&[]resource.Resource{}, &input)
if err != nil {
t.Fatal(err)
}

changelog, err := diff.Diff(expected, input)
if err != nil {
t.Fatal(err)
}
if len(changelog) > 0 {
for _, change := range changelog {
t.Errorf("%s got = %v, want %v", strings.Join(change.Path, "."), awsutil.Prettify(change.From), awsutil.Prettify(change.To))
}
}

mockedAlerter.AssertExpectations(t)
}
5 changes: 4 additions & 1 deletion pkg/remote/aws/ec2_route_enumerator.go
Expand Up @@ -33,7 +33,7 @@ func (e *EC2RouteEnumerator) Enumerate() ([]resource.Resource, error) {

for _, routeTable := range routeTables {
for _, route := range routeTable.Routes {
routeId, _ := aws.CalculateRouteID(routeTable.RouteTableId, route.DestinationCidrBlock, route.DestinationIpv6CidrBlock)
routeId := aws.CalculateRouteID(routeTable.RouteTableId, route.DestinationCidrBlock, route.DestinationIpv6CidrBlock, route.DestinationPrefixListId)
data := map[string]interface{}{
"route_table_id": *routeTable.RouteTableId,
"origin": *route.Origin,
Expand All @@ -44,6 +44,9 @@ func (e *EC2RouteEnumerator) Enumerate() ([]resource.Resource, error) {
if route.DestinationIpv6CidrBlock != nil && *route.DestinationIpv6CidrBlock != "" {
data["destination_ipv6_cidr_block"] = *route.DestinationIpv6CidrBlock
}
if route.DestinationPrefixListId != nil && *route.DestinationPrefixListId != "" {
data["destination_prefix_list_id"] = *route.DestinationPrefixListId
}
if route.GatewayId != nil && *route.GatewayId != "" {
data["gateway_id"] = *route.GatewayId
}
Expand Down
16 changes: 11 additions & 5 deletions pkg/resource/aws/aws_route.go
Expand Up @@ -5,7 +5,6 @@ import (

"github.com/cloudskiff/driftctl/pkg/resource"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/pkg/errors"
)

const AwsRouteResourceType = "aws_route"
Expand Down Expand Up @@ -41,18 +40,25 @@ func initAwsRouteMetaData(resourceSchemaRepository resource.SchemaRepositoryInte
if ipv6 := val.GetString("destination_ipv6_cidr_block"); ipv6 != nil && *ipv6 != "" {
attrs["Destination"] = *ipv6
}
if prefix := val.GetString("destination_prefix_list_id"); prefix != nil && *prefix != "" {
attrs["Destination"] = *prefix
}
return attrs
})
}

func CalculateRouteID(tableId, CidrBlock, Ipv6CidrBlock *string) (string, error) {
func CalculateRouteID(tableId, CidrBlock, Ipv6CidrBlock, PrefixListId *string) string {
if CidrBlock != nil && *CidrBlock != "" {
return fmt.Sprintf("r-%s%d", *tableId, hashcode.String(*CidrBlock)), nil
return fmt.Sprintf("r-%s%d", *tableId, hashcode.String(*CidrBlock))
}

if Ipv6CidrBlock != nil && *Ipv6CidrBlock != "" {
return fmt.Sprintf("r-%s%d", *tableId, hashcode.String(*Ipv6CidrBlock)), nil
return fmt.Sprintf("r-%s%d", *tableId, hashcode.String(*Ipv6CidrBlock))
}

if PrefixListId != nil && *PrefixListId != "" {
return fmt.Sprintf("r-%s%d", *tableId, hashcode.String(*PrefixListId))
}

return "", errors.Errorf("invalid route detected for table %s", *tableId)
return ""
}

0 comments on commit 7b62202

Please sign in to comment.