Merge branch 'main' into fix/records
commit
7d6b6a86f8
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
name: 📝 Documentation
|
||||
about: documentation lacks and improvements
|
||||
label: kind/documentation
|
||||
labels: kind/documentation
|
||||
|
||||
---
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
name: 🚀 Feature
|
||||
about: RFC and ideas for new features and improvements
|
||||
label: kind/feature
|
||||
labels: kind/enhancement
|
||||
|
||||
---
|
||||
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
package state
|
||||
|
||||
import (
|
||||
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
|
||||
"github.com/hashicorp/terraform/addrs"
|
||||
|
||||
"github.com/cloudskiff/driftctl/pkg/iac"
|
||||
"github.com/cloudskiff/driftctl/pkg/iac/config"
|
||||
"github.com/cloudskiff/driftctl/pkg/iac/terraform/state/backend"
|
||||
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
|
||||
"github.com/cloudskiff/driftctl/pkg/resource"
|
||||
"github.com/cloudskiff/driftctl/pkg/terraform"
|
||||
|
||||
"github.com/hashicorp/terraform/states/statefile"
|
||||
|
||||
"github.com/hashicorp/terraform/addrs"
|
||||
"github.com/hashicorp/terraform/states"
|
||||
"github.com/hashicorp/terraform/states/statefile"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
ctyconvert "github.com/zclconf/go-cty/cty/convert"
|
||||
ctyjson "github.com/zclconf/go-cty/cty/json"
|
||||
)
|
||||
|
||||
const TerraformStateReaderSupplier = "tfstate"
|
||||
|
@ -54,11 +53,13 @@ func (r *TerraformStateReader) retrieve() (map[string][]cty.Value, error) {
|
|||
stateResources := state.RootModule().Resources
|
||||
resMap := make(map[string][]cty.Value)
|
||||
for _, stateRes := range stateResources {
|
||||
resName := stateRes.Addr.Resource.Name
|
||||
resType := stateRes.Addr.Resource.Type
|
||||
if stateRes.Addr.Resource.Mode != addrs.ManagedResourceMode {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"mode": stateRes.Addr.Resource.Mode,
|
||||
"name": stateRes.Addr.Resource.Name,
|
||||
"type": stateRes.Addr.Resource.Type,
|
||||
"name": resName,
|
||||
"type": resType,
|
||||
}).Debug("Skipping state entry as it is not a managed resource")
|
||||
continue
|
||||
}
|
||||
|
@ -74,8 +75,28 @@ func (r *TerraformStateReader) retrieve() (map[string][]cty.Value, error) {
|
|||
for _, instance := range stateRes.Instances {
|
||||
decodedVal, err := instance.Current.Decode(schema.Block.ImpliedType())
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
continue
|
||||
// Try to do a manual type conversion if we got a path error
|
||||
// It will allow driftctl to read state generated with a superior version of provider
|
||||
// than the actually supported one
|
||||
// by ignoring new fields
|
||||
_, isPathError := err.(cty.PathError)
|
||||
if isPathError {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"name": resName,
|
||||
"type": resType,
|
||||
"err": err.Error(),
|
||||
}).Debug("Got a cty path error when deserializing state")
|
||||
|
||||
decodedVal, err = r.convertInstance(instance.Current, schema.Block.ImpliedType())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"name": resName,
|
||||
"type": resType,
|
||||
}).Error("Unable to decode resource from state")
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
_, exists := resMap[stateRes.Addr.Resource.Type]
|
||||
if !exists {
|
||||
|
@ -91,6 +112,34 @@ func (r *TerraformStateReader) retrieve() (map[string][]cty.Value, error) {
|
|||
return resMap, nil
|
||||
}
|
||||
|
||||
func (r *TerraformStateReader) convertInstance(instance *states.ResourceInstanceObjectSrc, ty cty.Type) (*states.ResourceInstanceObject, error) {
|
||||
inputType, err := ctyjson.ImpliedType(instance.AttrsJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
input, err := ctyjson.Unmarshal(instance.AttrsJSON, inputType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
convertedVal, err := ctyconvert.Convert(input, ty)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
instanceObj := &states.ResourceInstanceObject{
|
||||
Value: convertedVal,
|
||||
Status: instance.Status,
|
||||
Dependencies: instance.Dependencies,
|
||||
Private: instance.Private,
|
||||
CreateBeforeDestroy: instance.CreateBeforeDestroy,
|
||||
}
|
||||
|
||||
logrus.Debug("Successfully converted resource")
|
||||
|
||||
return instanceObj, nil
|
||||
}
|
||||
|
||||
func (r *TerraformStateReader) decode(values map[string][]cty.Value) ([]resource.Resource, error) {
|
||||
results := make([]resource.Resource, 0)
|
||||
for _, deserializer := range r.deserializers {
|
||||
|
|
|
@ -7,13 +7,12 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/cloudskiff/driftctl/test/goldenfile"
|
||||
|
||||
"github.com/cloudskiff/driftctl/pkg/iac"
|
||||
"github.com/cloudskiff/driftctl/pkg/iac/terraform/state/backend"
|
||||
"github.com/cloudskiff/driftctl/pkg/remote/aws"
|
||||
"github.com/cloudskiff/driftctl/pkg/resource"
|
||||
"github.com/cloudskiff/driftctl/pkg/terraform"
|
||||
"github.com/cloudskiff/driftctl/test/goldenfile"
|
||||
"github.com/cloudskiff/driftctl/test/mocks"
|
||||
|
||||
"github.com/r3labs/diff/v2"
|
||||
|
@ -50,6 +49,7 @@ func TestTerraformStateReader_Resources(t *testing.T) {
|
|||
{name: "RDS DB instance", dirName: "db_instance", wantErr: false},
|
||||
{name: "RDS DB Subnet group", dirName: "db_subnet_group", wantErr: false},
|
||||
{name: "Lambda function", dirName: "lambda_function", wantErr: false},
|
||||
{name: "unsupported attribute", dirName: "unsupported_attribute", wantErr: false},
|
||||
{name: "Unsupported provider", dirName: "unsupported_provider", wantErr: false},
|
||||
{name: "EC2 instance", dirName: "ec2_instance", wantErr: false},
|
||||
{name: "EC2 key pair", dirName: "ec2_key_pair", wantErr: false},
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
[
|
||||
{
|
||||
"Ami": "ami-0f8e5edde3a79f541",
|
||||
"Arn": "arn:aws:ec2:eu-west-3:929327065333:instance/i-002c7d44410fee60e",
|
||||
"AssociatePublicIpAddress": true,
|
||||
"AvailabilityZone": "eu-west-3a",
|
||||
"CpuCoreCount": 1,
|
||||
"CpuThreadsPerCore": 2,
|
||||
"DisableApiTermination": false,
|
||||
"EbsOptimized": false,
|
||||
"GetPasswordData": false,
|
||||
"Hibernation": false,
|
||||
"HostId": null,
|
||||
"IamInstanceProfile": "",
|
||||
"Id": "i-002c7d44410fee60e",
|
||||
"InstanceInitiatedShutdownBehavior": null,
|
||||
"InstanceState": "running",
|
||||
"InstanceType": "t3.micro",
|
||||
"Ipv6AddressCount": 0,
|
||||
"Ipv6Addresses": [],
|
||||
"KeyName": "",
|
||||
"Monitoring": false,
|
||||
"OutpostArn": "",
|
||||
"PasswordData": "",
|
||||
"PlacementGroup": "",
|
||||
"PrimaryNetworkInterfaceId": "eni-004ddff1c7a130f8b",
|
||||
"PrivateDns": "ip-172-31-11-192.eu-west-3.compute.internal",
|
||||
"PrivateIp": "172.31.11.192",
|
||||
"PublicDns": "ec2-15-188-23-233.eu-west-3.compute.amazonaws.com",
|
||||
"PublicIp": "15.188.23.233",
|
||||
"SecondaryPrivateIps": [],
|
||||
"SecurityGroups": [
|
||||
"default"
|
||||
],
|
||||
"SourceDestCheck": true,
|
||||
"SubnetId": "subnet-63c5f90a",
|
||||
"Tags": {
|
||||
"Name": "HelloWorld"
|
||||
},
|
||||
"Tenancy": "default",
|
||||
"UserData": null,
|
||||
"UserDataBase64": null,
|
||||
"VolumeTags": {},
|
||||
"VpcSecurityGroupIds": [
|
||||
"sg-a74815c8"
|
||||
],
|
||||
"CreditSpecification": [
|
||||
{
|
||||
"CpuCredits": "unlimited"
|
||||
}
|
||||
],
|
||||
"EbsBlockDevice": null,
|
||||
"EphemeralBlockDevice": [],
|
||||
"MetadataOptions": [
|
||||
{
|
||||
"HttpEndpoint": "enabled",
|
||||
"HttpPutResponseHopLimit": 1,
|
||||
"HttpTokens": "optional"
|
||||
}
|
||||
],
|
||||
"NetworkInterface": [],
|
||||
"RootBlockDevice": [
|
||||
{
|
||||
"DeleteOnTermination": true,
|
||||
"DeviceName": "/dev/sda1",
|
||||
"Encrypted": false,
|
||||
"Iops": 100,
|
||||
"KmsKeyId": "",
|
||||
"VolumeId": "vol-08b1deab4881e2b00",
|
||||
"VolumeSize": 8,
|
||||
"VolumeType": "gp2"
|
||||
}
|
||||
],
|
||||
"Timeouts": null
|
||||
}
|
||||
]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,195 @@
|
|||
{
|
||||
"version": 4,
|
||||
"terraform_version": "0.14.2",
|
||||
"serial": 17,
|
||||
"lineage": "3f0e3848-13be-8734-9b0a-54239733c408",
|
||||
"outputs": {},
|
||||
"resources": [
|
||||
{
|
||||
"mode": "data",
|
||||
"type": "aws_ami",
|
||||
"name": "ubuntu",
|
||||
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
|
||||
"instances": [
|
||||
{
|
||||
"schema_version": 0,
|
||||
"attributes": {
|
||||
"architecture": "x86_64",
|
||||
"arn": "arn:aws:ec2:eu-west-3::image/ami-0f8e5edde3a79f541",
|
||||
"block_device_mappings": [
|
||||
{
|
||||
"device_name": "/dev/sda1",
|
||||
"ebs": {
|
||||
"delete_on_termination": "true",
|
||||
"encrypted": "false",
|
||||
"iops": "0",
|
||||
"snapshot_id": "snap-0185f1217f4670aa2",
|
||||
"volume_size": "8",
|
||||
"volume_type": "gp2"
|
||||
},
|
||||
"no_device": "",
|
||||
"virtual_name": ""
|
||||
},
|
||||
{
|
||||
"device_name": "/dev/sdb",
|
||||
"ebs": {},
|
||||
"no_device": "",
|
||||
"virtual_name": "ephemeral0"
|
||||
},
|
||||
{
|
||||
"device_name": "/dev/sdc",
|
||||
"ebs": {},
|
||||
"no_device": "",
|
||||
"virtual_name": "ephemeral1"
|
||||
}
|
||||
],
|
||||
"creation_date": "2021-01-06T01:26:13.000Z",
|
||||
"description": "Canonical, Ubuntu, 20.04 LTS, amd64 focal image build on 2021-01-05",
|
||||
"executable_users": null,
|
||||
"filter": [
|
||||
{
|
||||
"name": "name",
|
||||
"values": [
|
||||
"ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "virtualization-type",
|
||||
"values": [
|
||||
"hvm"
|
||||
]
|
||||
}
|
||||
],
|
||||
"hypervisor": "xen",
|
||||
"id": "ami-0f8e5edde3a79f541",
|
||||
"image_id": "ami-0f8e5edde3a79f541",
|
||||
"image_location": "099720109477/ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20210105",
|
||||
"image_owner_alias": null,
|
||||
"image_type": "machine",
|
||||
"kernel_id": null,
|
||||
"most_recent": true,
|
||||
"name": "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20210105",
|
||||
"name_regex": null,
|
||||
"owner_id": "099720109477",
|
||||
"owners": [
|
||||
"099720109477"
|
||||
],
|
||||
"platform": null,
|
||||
"product_codes": [],
|
||||
"public": true,
|
||||
"ramdisk_id": null,
|
||||
"root_device_name": "/dev/sda1",
|
||||
"root_device_type": "ebs",
|
||||
"root_snapshot_id": "snap-0185f1217f4670aa2",
|
||||
"sriov_net_support": "simple",
|
||||
"state": "available",
|
||||
"state_reason": {
|
||||
"code": "UNSET",
|
||||
"message": "UNSET"
|
||||
},
|
||||
"tags": {},
|
||||
"virtualization_type": "hvm"
|
||||
},
|
||||
"sensitive_attributes": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"mode": "managed",
|
||||
"type": "aws_instance",
|
||||
"name": "web",
|
||||
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
|
||||
"instances": [
|
||||
{
|
||||
"schema_version": 1,
|
||||
"attributes": {
|
||||
"unsupported_attribute": "foobar",
|
||||
"ami": "ami-0f8e5edde3a79f541",
|
||||
"arn": "arn:aws:ec2:eu-west-3:929327065333:instance/i-002c7d44410fee60e",
|
||||
"associate_public_ip_address": true,
|
||||
"availability_zone": "eu-west-3a",
|
||||
"cpu_core_count": 1,
|
||||
"cpu_threads_per_core": 2,
|
||||
"credit_specification": [
|
||||
{
|
||||
"cpu_credits": "unlimited"
|
||||
}
|
||||
],
|
||||
"disable_api_termination": false,
|
||||
"ebs_block_device": [],
|
||||
"ebs_optimized": false,
|
||||
"enclave_options": [
|
||||
{
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"ephemeral_block_device": [],
|
||||
"get_password_data": false,
|
||||
"hibernation": false,
|
||||
"host_id": null,
|
||||
"iam_instance_profile": "",
|
||||
"id": "i-002c7d44410fee60e",
|
||||
"instance_initiated_shutdown_behavior": null,
|
||||
"instance_state": "running",
|
||||
"instance_type": "t3.micro",
|
||||
"ipv6_address_count": 0,
|
||||
"ipv6_addresses": [],
|
||||
"key_name": "",
|
||||
"metadata_options": [
|
||||
{
|
||||
"http_endpoint": "enabled",
|
||||
"http_put_response_hop_limit": 1,
|
||||
"http_tokens": "optional"
|
||||
}
|
||||
],
|
||||
"monitoring": false,
|
||||
"network_interface": [],
|
||||
"outpost_arn": "",
|
||||
"password_data": "",
|
||||
"placement_group": "",
|
||||
"primary_network_interface_id": "eni-004ddff1c7a130f8b",
|
||||
"private_dns": "ip-172-31-11-192.eu-west-3.compute.internal",
|
||||
"private_ip": "172.31.11.192",
|
||||
"public_dns": "ec2-15-188-23-233.eu-west-3.compute.amazonaws.com",
|
||||
"public_ip": "15.188.23.233",
|
||||
"root_block_device": [
|
||||
{
|
||||
"delete_on_termination": true,
|
||||
"device_name": "/dev/sda1",
|
||||
"encrypted": false,
|
||||
"iops": 100,
|
||||
"kms_key_id": "",
|
||||
"throughput": 0,
|
||||
"volume_id": "vol-08b1deab4881e2b00",
|
||||
"volume_size": 8,
|
||||
"volume_type": "gp2"
|
||||
}
|
||||
],
|
||||
"secondary_private_ips": [],
|
||||
"security_groups": [
|
||||
"default"
|
||||
],
|
||||
"source_dest_check": true,
|
||||
"subnet_id": "subnet-63c5f90a",
|
||||
"tags": {
|
||||
"Name": "HelloWorld"
|
||||
},
|
||||
"tenancy": "default",
|
||||
"timeouts": null,
|
||||
"user_data": null,
|
||||
"user_data_base64": null,
|
||||
"volume_tags": {},
|
||||
"vpc_security_group_ids": [
|
||||
"sg-a74815c8"
|
||||
]
|
||||
},
|
||||
"sensitive_attributes": [],
|
||||
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6MTIwMDAwMDAwMDAwMCwidXBkYXRlIjo2MDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjEifQ==",
|
||||
"dependencies": [
|
||||
"data.aws_ami.ubuntu"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue