Handle invalid route crash in middlewares
parent
44e9ba3d31
commit
a8f0300405
|
@ -0,0 +1,18 @@
|
|||
// Code generated by mockery v2.3.0. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
alerter "github.com/cloudskiff/driftctl/pkg/alerter"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// AlerterInterface is an autogenerated mock type for the AlerterInterface type
|
||||
type AlerterInterface struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// SendAlert provides a mock function with given fields: key, alert
|
||||
func (_m *AlerterInterface) SendAlert(key string, alert alerter.Alert) {
|
||||
_m.Called(key, alert)
|
||||
}
|
|
@ -6,6 +6,10 @@ import (
|
|||
"github.com/cloudskiff/driftctl/pkg/resource"
|
||||
)
|
||||
|
||||
type AlerterInterface interface {
|
||||
SendAlert(key string, alert Alert)
|
||||
}
|
||||
|
||||
type Alerter struct {
|
||||
alerts Alerts
|
||||
alertsCh chan Alerts
|
||||
|
|
|
@ -15,12 +15,13 @@ import (
|
|||
type DriftCTL struct {
|
||||
remoteSupplier resource.Supplier
|
||||
iacSupplier resource.Supplier
|
||||
alerter *alerter.Alerter
|
||||
analyzer analyser.Analyzer
|
||||
filter *jmespath.JMESPath
|
||||
}
|
||||
|
||||
func NewDriftCTL(remoteSupplier resource.Supplier, iacSupplier resource.Supplier, filter *jmespath.JMESPath, alerter *alerter.Alerter) *DriftCTL {
|
||||
return &DriftCTL{remoteSupplier, iacSupplier, analyser.NewAnalyzer(alerter), filter}
|
||||
return &DriftCTL{remoteSupplier, iacSupplier, alerter, analyser.NewAnalyzer(alerter), filter}
|
||||
}
|
||||
|
||||
func (d DriftCTL) Run() *analyser.Analysis {
|
||||
|
@ -42,7 +43,7 @@ func (d DriftCTL) Run() *analyser.Analysis {
|
|||
middlewares.NewAwsDefaultInternetGateway(),
|
||||
middlewares.NewAwsDefaultVPC(),
|
||||
middlewares.NewAwsDefaultSubnet(),
|
||||
middlewares.NewAwsRouteTableExpander(),
|
||||
middlewares.NewAwsRouteTableExpander(d.alerter),
|
||||
middlewares.NewAwsDefaultRouteTable(),
|
||||
middlewares.NewAwsDefaultRoute(),
|
||||
middlewares.NewAwsNatGatewayEipAssoc(),
|
||||
|
|
|
@ -1,17 +1,24 @@
|
|||
package middlewares
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
awssdk "github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/cloudskiff/driftctl/pkg/alerter"
|
||||
"github.com/cloudskiff/driftctl/pkg/resource"
|
||||
"github.com/cloudskiff/driftctl/pkg/resource/aws"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Explodes routes found in aws_default_route_table.route and aws_route_table.route to dedicated resources
|
||||
type AwsRouteTableExpander struct{}
|
||||
type AwsRouteTableExpander struct {
|
||||
alerter alerter.AlerterInterface
|
||||
}
|
||||
|
||||
func NewAwsRouteTableExpander() AwsRouteTableExpander {
|
||||
return AwsRouteTableExpander{}
|
||||
func NewAwsRouteTableExpander(alerter alerter.AlerterInterface) AwsRouteTableExpander {
|
||||
return AwsRouteTableExpander{
|
||||
alerter,
|
||||
}
|
||||
}
|
||||
|
||||
func (m AwsRouteTableExpander) Execute(remoteResources, resourcesFromState *[]resource.Resource) error {
|
||||
|
@ -51,13 +58,20 @@ func (m *AwsRouteTableExpander) handleTable(table *aws.AwsRouteTable, results *[
|
|||
return nil
|
||||
}
|
||||
for _, route := range *table.Route {
|
||||
routeId, err := aws.CalculateRouteID(&table.Id, route.CidrBlock, route.Ipv6CidrBlock)
|
||||
if err != nil {
|
||||
m.alerter.SendAlert(aws.AwsRouteTableResourceType, alerter.Alert{
|
||||
Message: fmt.Sprintf("Skipped invalid route found in state for %s.%s", aws.AwsRouteTableResourceType, table.Id),
|
||||
})
|
||||
continue
|
||||
}
|
||||
newRouteFromTable := &aws.AwsRoute{
|
||||
DestinationCidrBlock: route.CidrBlock,
|
||||
DestinationIpv6CidrBlock: route.Ipv6CidrBlock,
|
||||
DestinationPrefixListId: awssdk.String(""),
|
||||
EgressOnlyGatewayId: route.EgressOnlyGatewayId,
|
||||
GatewayId: route.GatewayId,
|
||||
Id: aws.CalculateRouteID(&table.Id, route.CidrBlock, route.Ipv6CidrBlock),
|
||||
Id: routeId,
|
||||
InstanceId: route.InstanceId,
|
||||
InstanceOwnerId: awssdk.String(""),
|
||||
LocalGatewayId: route.LocalGatewayId,
|
||||
|
@ -91,13 +105,20 @@ func (m *AwsRouteTableExpander) handleDefaultTable(table *aws.AwsDefaultRouteTab
|
|||
return nil
|
||||
}
|
||||
for _, route := range *table.Route {
|
||||
routeId, err := aws.CalculateRouteID(&table.Id, route.CidrBlock, route.Ipv6CidrBlock)
|
||||
if err != nil {
|
||||
m.alerter.SendAlert(aws.AwsDefaultRouteTableResourceType, alerter.Alert{
|
||||
Message: fmt.Sprintf("Skipped invalid route found in state for %s.%s", aws.AwsDefaultRouteTableResourceType, table.Id),
|
||||
})
|
||||
continue
|
||||
}
|
||||
newRouteFromTable := &aws.AwsRoute{
|
||||
DestinationCidrBlock: route.CidrBlock,
|
||||
DestinationIpv6CidrBlock: route.Ipv6CidrBlock,
|
||||
DestinationPrefixListId: awssdk.String(""),
|
||||
EgressOnlyGatewayId: route.EgressOnlyGatewayId,
|
||||
GatewayId: route.GatewayId,
|
||||
Id: aws.CalculateRouteID(&table.Id, route.CidrBlock, route.Ipv6CidrBlock),
|
||||
Id: routeId,
|
||||
InstanceId: route.InstanceId,
|
||||
InstanceOwnerId: awssdk.String(""),
|
||||
NatGatewayId: route.NatGatewayId,
|
||||
|
|
|
@ -6,6 +6,8 @@ import (
|
|||
|
||||
awssdk "github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
"github.com/cloudskiff/driftctl/mocks"
|
||||
"github.com/cloudskiff/driftctl/pkg/alerter"
|
||||
"github.com/cloudskiff/driftctl/pkg/resource"
|
||||
"github.com/cloudskiff/driftctl/pkg/resource/aws"
|
||||
resource2 "github.com/cloudskiff/driftctl/test/resource"
|
||||
|
@ -189,7 +191,8 @@ func TestAwsRouteTableExpander_Execute(t *testing.T) {
|
|||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := NewAwsRouteTableExpander()
|
||||
mockedAlerter := &mocks.AlerterInterface{}
|
||||
m := NewAwsRouteTableExpander(mockedAlerter)
|
||||
err := m.Execute(nil, &tt.input)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -208,3 +211,85 @@ func TestAwsRouteTableExpander_Execute(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAwsRouteTableExpander_ExecuteWithInvalidRoutes(t *testing.T) {
|
||||
|
||||
mockedAlerter := &mocks.AlerterInterface{}
|
||||
mockedAlerter.On("SendAlert", aws.AwsRouteTableResourceType, alerter.Alert{
|
||||
Message: "Skipped invalid route found in state for aws_route_table.table_from_state",
|
||||
})
|
||||
mockedAlerter.On("SendAlert", aws.AwsDefaultRouteTableResourceType, alerter.Alert{
|
||||
Message: "Skipped invalid route found in state for aws_default_route_table.default_table_from_state",
|
||||
})
|
||||
|
||||
input := []resource.Resource{
|
||||
&aws.AwsRouteTable{
|
||||
Id: "table_from_state",
|
||||
Route: &[]struct {
|
||||
CidrBlock *string `cty:"cidr_block"`
|
||||
EgressOnlyGatewayId *string `cty:"egress_only_gateway_id"`
|
||||
GatewayId *string `cty:"gateway_id"`
|
||||
InstanceId *string `cty:"instance_id"`
|
||||
Ipv6CidrBlock *string `cty:"ipv6_cidr_block"`
|
||||
LocalGatewayId *string `cty:"local_gateway_id"`
|
||||
NatGatewayId *string `cty:"nat_gateway_id"`
|
||||
NetworkInterfaceId *string `cty:"network_interface_id"`
|
||||
TransitGatewayId *string `cty:"transit_gateway_id"`
|
||||
VpcEndpointId *string `cty:"vpc_endpoint_id"`
|
||||
VpcPeeringConnectionId *string `cty:"vpc_peering_connection_id"`
|
||||
}{
|
||||
{
|
||||
GatewayId: awssdk.String("igw-07b7844a8fd17a638"),
|
||||
},
|
||||
},
|
||||
},
|
||||
&aws.AwsDefaultRouteTable{
|
||||
Id: "default_table_from_state",
|
||||
Route: &[]struct {
|
||||
CidrBlock *string `cty:"cidr_block"`
|
||||
EgressOnlyGatewayId *string `cty:"egress_only_gateway_id"`
|
||||
GatewayId *string `cty:"gateway_id"`
|
||||
InstanceId *string `cty:"instance_id"`
|
||||
Ipv6CidrBlock *string `cty:"ipv6_cidr_block"`
|
||||
NatGatewayId *string `cty:"nat_gateway_id"`
|
||||
NetworkInterfaceId *string `cty:"network_interface_id"`
|
||||
TransitGatewayId *string `cty:"transit_gateway_id"`
|
||||
VpcEndpointId *string `cty:"vpc_endpoint_id"`
|
||||
VpcPeeringConnectionId *string `cty:"vpc_peering_connection_id"`
|
||||
}{
|
||||
{
|
||||
GatewayId: awssdk.String("igw-07b7844a8fd17a638"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
expected := []resource.Resource{
|
||||
&aws.AwsRouteTable{
|
||||
Id: "table_from_state",
|
||||
Route: nil,
|
||||
},
|
||||
&aws.AwsDefaultRouteTable{
|
||||
Id: "default_table_from_state",
|
||||
Route: nil,
|
||||
},
|
||||
}
|
||||
|
||||
m := NewAwsRouteTableExpander(mockedAlerter)
|
||||
err := m.Execute(nil, &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)
|
||||
}
|
||||
|
|
|
@ -73,8 +73,10 @@ func (s RouteSupplier) readRoute(tableId string, route ec2.Route) (cty.Value, er
|
|||
attributes["destination_ipv6_cidr_block"] = *route.DestinationIpv6CidrBlock
|
||||
}
|
||||
|
||||
// We can ignore error there as remote will always return us a valid route
|
||||
routeId, _ := aws.CalculateRouteID(&tableId, route.DestinationCidrBlock, route.DestinationIpv6CidrBlock)
|
||||
val, err := s.reader.ReadResource(terraform.ReadResourceArgs{
|
||||
ID: aws.CalculateRouteID(&tableId, route.DestinationCidrBlock, route.DestinationIpv6CidrBlock),
|
||||
ID: routeId,
|
||||
Ty: Ty,
|
||||
Attributes: flatmap.Flatten(attributes),
|
||||
})
|
||||
|
|
|
@ -19,16 +19,16 @@ func (r *AwsRoute) String() string {
|
|||
return output
|
||||
}
|
||||
|
||||
func CalculateRouteID(tableId, CidrBlock, Ipv6CidrBlock *string) string {
|
||||
func CalculateRouteID(tableId, CidrBlock, Ipv6CidrBlock *string) (string, error) {
|
||||
if CidrBlock != nil && *CidrBlock != "" {
|
||||
return fmt.Sprintf("r-%s%d", *tableId, hashcode.String(*CidrBlock))
|
||||
return fmt.Sprintf("r-%s%d", *tableId, hashcode.String(*CidrBlock)), nil
|
||||
}
|
||||
|
||||
if Ipv6CidrBlock != nil && *Ipv6CidrBlock != "" {
|
||||
return fmt.Sprintf("r-%s%d", *tableId, hashcode.String(*Ipv6CidrBlock))
|
||||
return fmt.Sprintf("r-%s%d", *tableId, hashcode.String(*Ipv6CidrBlock)), nil
|
||||
}
|
||||
|
||||
panic("unable to build route ID")
|
||||
return "", fmt.Errorf("invalid route detected for table %s", *tableId)
|
||||
}
|
||||
|
||||
func (r *AwsRoute) NormalizeForState() (resource.Resource, error) {
|
||||
|
|
Loading…
Reference in New Issue