2021-01-14 17:11:02 +00:00
|
|
|
package middlewares
|
|
|
|
|
|
|
|
import (
|
2021-03-29 16:10:50 +00:00
|
|
|
"github.com/sirupsen/logrus"
|
2022-06-28 07:23:29 +00:00
|
|
|
"github.com/snyk/driftctl/enumeration/alerter"
|
2021-03-29 16:10:50 +00:00
|
|
|
|
2022-06-28 07:23:29 +00:00
|
|
|
"github.com/snyk/driftctl/enumeration/resource"
|
2022-07-21 08:37:03 +00:00
|
|
|
"github.com/snyk/driftctl/pkg/resource/aws"
|
2021-01-14 17:11:02 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Explodes routes found in aws_default_route_table.route and aws_route_table.route to dedicated resources
|
2021-02-03 15:24:55 +00:00
|
|
|
type AwsRouteTableExpander struct {
|
2021-03-29 16:10:50 +00:00
|
|
|
alerter alerter.AlerterInterface
|
|
|
|
resourceFactory resource.ResourceFactory
|
2021-02-03 15:24:55 +00:00
|
|
|
}
|
2021-01-14 17:11:02 +00:00
|
|
|
|
2021-03-29 16:10:50 +00:00
|
|
|
func NewAwsRouteTableExpander(alerter alerter.AlerterInterface, resourceFactory resource.ResourceFactory) AwsRouteTableExpander {
|
2021-02-03 15:24:55 +00:00
|
|
|
return AwsRouteTableExpander{
|
|
|
|
alerter,
|
2021-03-29 16:10:50 +00:00
|
|
|
resourceFactory,
|
2021-02-03 15:24:55 +00:00
|
|
|
}
|
2021-01-14 17:11:02 +00:00
|
|
|
}
|
|
|
|
|
2021-08-09 14:03:04 +00:00
|
|
|
func (m AwsRouteTableExpander) Execute(remoteResources, resourcesFromState *[]*resource.Resource) error {
|
2021-01-14 17:11:02 +00:00
|
|
|
|
2021-08-09 14:03:04 +00:00
|
|
|
newList := make([]*resource.Resource, 0, len(*resourcesFromState))
|
2021-01-14 17:11:02 +00:00
|
|
|
for _, res := range *resourcesFromState {
|
|
|
|
|
|
|
|
// Ignore all resources other than (default) routes tables
|
2021-08-18 13:58:28 +00:00
|
|
|
if res.ResourceType() != aws.AwsRouteTableResourceType &&
|
|
|
|
res.ResourceType() != aws.AwsDefaultRouteTableResourceType {
|
2021-01-14 17:11:02 +00:00
|
|
|
newList = append(newList, res)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
newList = append(newList, res)
|
|
|
|
|
|
|
|
var err error
|
2021-08-18 13:58:28 +00:00
|
|
|
if res.ResourceType() == aws.AwsDefaultRouteTableResourceType {
|
2021-08-09 14:03:04 +00:00
|
|
|
err = m.handleDefaultTable(res, &newList, *resourcesFromState)
|
2021-01-14 17:11:02 +00:00
|
|
|
} else {
|
2021-08-09 14:03:04 +00:00
|
|
|
err = m.handleTable(res, &newList, *resourcesFromState)
|
2021-01-14 17:11:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2021-05-07 18:55:49 +00:00
|
|
|
|
2021-08-09 14:03:04 +00:00
|
|
|
newRemoteResources := make([]*resource.Resource, 0)
|
2021-05-07 18:55:49 +00:00
|
|
|
for _, remoteRes := range *remoteResources {
|
2021-08-18 13:58:28 +00:00
|
|
|
if remoteRes.ResourceType() != aws.AwsRouteTableResourceType &&
|
|
|
|
remoteRes.ResourceType() != aws.AwsDefaultRouteTableResourceType {
|
2021-05-07 18:55:49 +00:00
|
|
|
newRemoteResources = append(newRemoteResources, remoteRes)
|
|
|
|
continue
|
|
|
|
}
|
2021-08-09 14:03:04 +00:00
|
|
|
remoteRes.Attrs.SafeDelete([]string{"route"})
|
|
|
|
newRemoteResources = append(newRemoteResources, remoteRes)
|
2021-05-07 18:55:49 +00:00
|
|
|
}
|
|
|
|
|
2021-01-14 17:11:02 +00:00
|
|
|
*resourcesFromState = newList
|
2021-05-07 18:55:49 +00:00
|
|
|
*remoteResources = newRemoteResources
|
2021-01-14 17:11:02 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-08-09 14:03:04 +00:00
|
|
|
func (m *AwsRouteTableExpander) handleTable(table *resource.Resource, results *[]*resource.Resource, resourcesFromState []*resource.Resource) error {
|
2021-05-07 18:55:49 +00:00
|
|
|
routes, exist := table.Attrs.Get("route")
|
|
|
|
if !exist || routes == nil {
|
2021-01-14 17:11:02 +00:00
|
|
|
return nil
|
|
|
|
}
|
2021-05-07 18:55:49 +00:00
|
|
|
for _, route := range routes.([]interface{}) {
|
|
|
|
route := route.(map[string]interface{})
|
2021-05-10 14:50:49 +00:00
|
|
|
cidrBlock := ""
|
|
|
|
if route["cidr_block"] != nil {
|
|
|
|
cidrBlock = route["cidr_block"].(string)
|
|
|
|
}
|
|
|
|
ipv6CidrBlock := ""
|
|
|
|
if route["ipv6_cidr_block"] != nil {
|
|
|
|
ipv6CidrBlock = route["ipv6_cidr_block"].(string)
|
|
|
|
}
|
2021-07-26 15:02:03 +00:00
|
|
|
prefixListId := ""
|
|
|
|
if route["destination_prefix_list_id"] != nil {
|
|
|
|
prefixListId = route["destination_prefix_list_id"].(string)
|
2021-02-03 15:24:55 +00:00
|
|
|
}
|
2021-07-26 15:02:03 +00:00
|
|
|
routeId := aws.CalculateRouteID(&table.Id, &cidrBlock, &ipv6CidrBlock, &prefixListId)
|
2021-04-06 13:16:12 +00:00
|
|
|
|
2021-03-29 16:10:50 +00:00
|
|
|
data := map[string]interface{}{
|
2021-05-07 18:55:49 +00:00
|
|
|
"destination_cidr_block": route["cidr_block"],
|
|
|
|
"destination_ipv6_cidr_block": route["ipv6_cidr_block"],
|
2021-07-26 15:02:03 +00:00
|
|
|
"destination_prefix_list_id": route["destination_prefix_list_id"],
|
2021-05-07 18:55:49 +00:00
|
|
|
"egress_only_gateway_id": route["egress_only_gateway_id"],
|
|
|
|
"gateway_id": route["gateway_id"],
|
2021-03-29 16:10:50 +00:00
|
|
|
"id": routeId,
|
2021-05-07 18:55:49 +00:00
|
|
|
"instance_id": route["instance_id"],
|
2021-03-29 16:10:50 +00:00
|
|
|
"instance_owner_id": "",
|
2021-05-07 18:55:49 +00:00
|
|
|
"local_gateway_id": route["local_gateway_id"],
|
|
|
|
"nat_gateway_id": route["nat_gateway_id"],
|
|
|
|
"network_interface_id": route["network_interface_id"],
|
2021-03-29 16:10:50 +00:00
|
|
|
"origin": "CreateRoute",
|
|
|
|
"route_table_id": table.Id,
|
|
|
|
"state": "active",
|
2021-05-07 18:55:49 +00:00
|
|
|
"transit_gateway_id": route["transit_gateway_id"],
|
|
|
|
"vpc_endpoint_id": route["vpc_endpoint_id"],
|
|
|
|
"vpc_peering_connection_id": route["vpc_peering_connection_id"],
|
2021-03-29 16:10:50 +00:00
|
|
|
}
|
2021-04-06 16:19:10 +00:00
|
|
|
// Don't expand if the route already exists as a dedicated resource
|
|
|
|
if m.routeExists(routeId, resourcesFromState) {
|
|
|
|
continue
|
|
|
|
}
|
2021-05-07 18:55:49 +00:00
|
|
|
newRes := m.resourceFactory.CreateAbstractResource(aws.AwsRouteResourceType, routeId, data)
|
|
|
|
*results = append(*results, newRes)
|
2021-01-14 17:11:02 +00:00
|
|
|
logrus.WithFields(logrus.Fields{
|
2021-05-07 18:55:49 +00:00
|
|
|
"route": routeId,
|
2021-01-14 17:11:02 +00:00
|
|
|
}).Debug("Created new route from route table")
|
|
|
|
}
|
2021-05-07 18:55:49 +00:00
|
|
|
table.Attrs.SafeDelete([]string{"route"})
|
2021-01-14 17:11:02 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-08-09 14:03:04 +00:00
|
|
|
func (m *AwsRouteTableExpander) handleDefaultTable(table *resource.Resource, results *[]*resource.Resource, resourcesFromState []*resource.Resource) error {
|
2021-05-07 18:55:49 +00:00
|
|
|
routes, exist := table.Attrs.Get("route")
|
|
|
|
if !exist || routes == nil {
|
2021-01-14 17:11:02 +00:00
|
|
|
return nil
|
|
|
|
}
|
2021-05-07 18:55:49 +00:00
|
|
|
for _, route := range routes.([]interface{}) {
|
|
|
|
route := route.(map[string]interface{})
|
2021-05-10 14:50:49 +00:00
|
|
|
cidrBlock := ""
|
|
|
|
if route["cidr_block"] != nil {
|
|
|
|
cidrBlock = route["cidr_block"].(string)
|
|
|
|
}
|
|
|
|
ipv6CidrBlock := ""
|
|
|
|
if route["ipv6_cidr_block"] != nil {
|
|
|
|
ipv6CidrBlock = route["ipv6_cidr_block"].(string)
|
|
|
|
}
|
2021-07-26 15:02:03 +00:00
|
|
|
prefixListId := ""
|
|
|
|
if route["destination_prefix_list_id"] != nil {
|
|
|
|
prefixListId = route["destination_prefix_list_id"].(string)
|
2021-02-03 15:24:55 +00:00
|
|
|
}
|
2021-07-26 15:02:03 +00:00
|
|
|
routeId := aws.CalculateRouteID(&table.Id, &cidrBlock, &ipv6CidrBlock, &prefixListId)
|
2021-04-06 13:16:12 +00:00
|
|
|
|
2021-03-29 16:10:50 +00:00
|
|
|
data := map[string]interface{}{
|
2021-05-07 18:55:49 +00:00
|
|
|
"destination_cidr_block": route["cidr_block"],
|
|
|
|
"destination_ipv6_cidr_block": route["ipv6_cidr_block"],
|
2021-07-26 15:02:03 +00:00
|
|
|
"destination_prefix_list_id": route["destination_prefix_list_id"],
|
2021-05-07 18:55:49 +00:00
|
|
|
"egress_only_gateway_id": route["egress_only_gateway_id"],
|
|
|
|
"gateway_id": route["gateway_id"],
|
2021-03-29 16:10:50 +00:00
|
|
|
"id": routeId,
|
2021-05-07 18:55:49 +00:00
|
|
|
"instance_id": route["instance_id"],
|
|
|
|
"nat_gateway_id": route["nat_gateway_id"],
|
|
|
|
"network_interface_id": route["network_interface_id"],
|
2021-03-29 16:10:50 +00:00
|
|
|
"origin": "CreateRoute",
|
|
|
|
"route_table_id": table.Id,
|
|
|
|
"state": "active",
|
2021-05-07 18:55:49 +00:00
|
|
|
"transit_gateway_id": route["transit_gateway_id"],
|
|
|
|
"vpc_endpoint_id": route["vpc_endpoint_id"],
|
|
|
|
"vpc_peering_connection_id": route["vpc_peering_connection_id"],
|
2021-03-29 16:10:50 +00:00
|
|
|
}
|
2021-04-06 16:19:10 +00:00
|
|
|
// Don't expand if the route already exists as a dedicated resource
|
|
|
|
if m.routeExists(routeId, resourcesFromState) {
|
|
|
|
continue
|
|
|
|
}
|
2021-05-07 18:55:49 +00:00
|
|
|
newRes := m.resourceFactory.CreateAbstractResource(aws.AwsRouteResourceType, routeId, data)
|
|
|
|
*results = append(*results, newRes)
|
2021-01-14 17:11:02 +00:00
|
|
|
logrus.WithFields(logrus.Fields{
|
2021-05-07 18:55:49 +00:00
|
|
|
"route": routeId,
|
2021-01-14 17:11:02 +00:00
|
|
|
}).Debug("Created new route from default route table")
|
|
|
|
}
|
2021-05-07 18:55:49 +00:00
|
|
|
table.Attrs.SafeDelete([]string{"route"})
|
2021-01-14 17:11:02 +00:00
|
|
|
return nil
|
|
|
|
}
|
2021-04-06 16:19:10 +00:00
|
|
|
|
2021-08-09 14:03:04 +00:00
|
|
|
func (m *AwsRouteTableExpander) routeExists(routeId string, resourcesFromState []*resource.Resource) bool {
|
2021-04-06 16:19:10 +00:00
|
|
|
for _, res := range resourcesFromState {
|
2021-08-18 13:58:28 +00:00
|
|
|
if res.ResourceType() == aws.AwsRouteResourceType && res.ResourceId() == routeId {
|
2021-04-07 09:10:56 +00:00
|
|
|
return true
|
2021-04-06 16:19:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|