driftctl/pkg/middlewares/aws_instance_block_device.go

127 lines
4.8 KiB
Go
Raw Normal View History

package middlewares
import (
2021-03-29 16:10:50 +00:00
"github.com/sirupsen/logrus"
2021-12-06 13:29:39 +00:00
"github.com/snyk/driftctl/pkg/resource"
"github.com/snyk/driftctl/pkg/resource/aws"
)
// Remove root_block_device from aws_instance resources and create dedicated aws_ebs_volume resources
2021-03-29 16:10:50 +00:00
type AwsInstanceBlockDeviceResourceMapper struct {
2021-04-29 15:17:55 +00:00
resourceFactory resource.ResourceFactory
2021-03-29 16:10:50 +00:00
}
2021-04-29 15:17:55 +00:00
func NewAwsInstanceBlockDeviceResourceMapper(resourceFactory resource.ResourceFactory) AwsInstanceBlockDeviceResourceMapper {
2021-04-29 10:32:02 +00:00
return AwsInstanceBlockDeviceResourceMapper{
2021-04-29 15:17:55 +00:00
resourceFactory: resourceFactory,
2021-04-29 10:32:02 +00:00
}
}
2021-08-09 14:03:04 +00:00
func (a AwsInstanceBlockDeviceResourceMapper) Execute(remoteResources, resourcesFromState *[]*resource.Resource) error {
2021-08-09 14:03:04 +00:00
newStateResources := make([]*resource.Resource, 0)
for _, stateRes := range *resourcesFromState {
// Ignore all resources other than aws_instance
if stateRes.ResourceType() != aws.AwsInstanceResourceType {
newStateResources = append(newStateResources, stateRes)
continue
}
2021-08-09 14:03:04 +00:00
if rootBlockDevice, exist := stateRes.Attrs.Get("root_block_device"); exist {
2021-05-06 10:55:19 +00:00
for _, rootBlock := range rootBlockDevice.([]interface{}) {
rootBlock := rootBlock.(map[string]interface{})
logrus.WithFields(logrus.Fields{
2021-04-29 15:17:55 +00:00
"volume": rootBlock["volume_id"],
"instance": stateRes.ResourceId(),
}).Debug("Creating aws_ebs_volume from aws_instance.root_block_device")
2021-03-29 16:10:50 +00:00
data := map[string]interface{}{
2021-08-09 14:03:04 +00:00
"availability_zone": (*stateRes.Attrs)["availability_zone"],
2021-04-29 15:17:55 +00:00
"encrypted": rootBlock["encrypted"],
"id": rootBlock["volume_id"],
"iops": rootBlock["iops"],
"kms_key_id": rootBlock["kms_key_id"],
"size": rootBlock["volume_size"],
"type": rootBlock["volume_type"],
2021-03-29 16:10:50 +00:00
"multi_attach_enabled": false,
2021-08-09 14:03:04 +00:00
"tags": a.volumeTags(stateRes, rootBlock),
}
if throughput, exist := rootBlock["throughput"]; exist {
data["throughput"] = throughput
}
2021-05-04 13:03:17 +00:00
newRes := a.resourceFactory.CreateAbstractResource("aws_ebs_volume", rootBlock["volume_id"].(string), data)
newStateResources = append(newStateResources, newRes)
}
2021-08-09 14:03:04 +00:00
stateRes.Attrs.SafeDelete([]string{"root_block_device"})
stateRes.Attrs.SafeDelete([]string{"volume_tags"})
}
2021-04-29 15:17:55 +00:00
2021-08-09 14:03:04 +00:00
if ebsBlockDevice, exist := stateRes.Attrs.Get("ebs_block_device"); exist {
2021-05-06 10:55:19 +00:00
for _, blockDevice := range ebsBlockDevice.([]interface{}) {
blockDevice := blockDevice.(map[string]interface{})
2021-06-22 13:40:33 +00:00
if a.hasBlockDevice(blockDevice, resourcesFromState) {
continue
}
logrus.WithFields(logrus.Fields{
2021-04-29 15:17:55 +00:00
"volume": blockDevice["volume_id"],
"instance": stateRes.ResourceId(),
}).Debug("Creating aws_ebs_volume from aws_instance.ebs_block_device")
2021-03-29 16:10:50 +00:00
data := map[string]interface{}{
2021-08-09 14:03:04 +00:00
"availability_zone": (*stateRes.Attrs)["availability_zone"],
2021-04-29 15:17:55 +00:00
"encrypted": blockDevice["encrypted"],
"id": blockDevice["volume_id"],
"iops": blockDevice["iops"],
"kms_key_id": blockDevice["kms_key_id"],
"size": blockDevice["volume_size"],
"type": blockDevice["volume_type"],
2021-03-29 16:10:50 +00:00
"multi_attach_enabled": false,
2021-08-09 14:03:04 +00:00
"tags": a.volumeTags(stateRes, blockDevice),
2021-03-29 16:10:50 +00:00
}
if throughput, exist := blockDevice["throughput"]; exist {
data["throughput"] = throughput
}
2021-05-04 13:03:17 +00:00
newRes := a.resourceFactory.CreateAbstractResource("aws_ebs_volume", blockDevice["volume_id"].(string), data)
newStateResources = append(newStateResources, newRes)
}
2021-08-09 14:03:04 +00:00
stateRes.Attrs.SafeDelete([]string{"ebs_block_device"})
stateRes.Attrs.SafeDelete([]string{"volume_tags"})
}
2021-08-09 14:03:04 +00:00
newStateResources = append(newStateResources, stateRes)
}
2021-08-09 14:03:04 +00:00
newRemoteResources := make([]*resource.Resource, 0)
2021-04-29 15:17:55 +00:00
for _, remoteRes := range *remoteResources {
if remoteRes.ResourceType() != aws.AwsInstanceResourceType {
2021-04-29 15:17:55 +00:00
newRemoteResources = append(newRemoteResources, remoteRes)
continue
2021-04-29 10:32:02 +00:00
}
2021-08-09 14:03:04 +00:00
remoteRes.Attrs.SafeDelete([]string{"root_block_device"})
remoteRes.Attrs.SafeDelete([]string{"ebs_block_device"})
remoteRes.Attrs.SafeDelete([]string{"volume_tags"})
newRemoteResources = append(newRemoteResources, remoteRes)
2021-04-29 10:32:02 +00:00
}
*resourcesFromState = newStateResources
2021-04-29 15:17:55 +00:00
*remoteResources = newRemoteResources
return nil
}
2021-06-22 09:26:39 +00:00
2021-08-09 14:03:04 +00:00
func (a AwsInstanceBlockDeviceResourceMapper) volumeTags(instance *resource.Resource, blockDevice map[string]interface{}) interface{} {
2021-06-22 09:26:39 +00:00
if tags, exist := instance.Attrs.Get("volume_tags"); exist {
return tags
}
return blockDevice["tags"]
}
2021-06-22 13:40:33 +00:00
2021-08-09 14:03:04 +00:00
func (a AwsInstanceBlockDeviceResourceMapper) hasBlockDevice(blockDevice map[string]interface{}, resourcesFromState *[]*resource.Resource) bool {
2021-06-22 13:40:33 +00:00
for _, stateRes := range *resourcesFromState {
if stateRes.ResourceType() == aws.AwsEbsVolumeResourceType &&
stateRes.ResourceId() == blockDevice["volume_id"] {
2021-06-22 13:40:33 +00:00
return true
}
}
return false
}