fix: fix broken tests

Those tests were broken due to removal of SetResolveReadAttributesFunc.
Sometimes in those methods we were casting field from different types to string.
If we loose that case it causes some issues since in the detail fetcher we only take into account
strings attributes. To fix that I added some cast directly in the detail fetcher.
That should not cause any issues to retrieve details if we send additional (useless) fields to the
ReadResource call.
main
Elie CHARRA 2022-07-27 15:30:56 +02:00 committed by Elie
parent e7750bc00c
commit 6c5e6787b0
No known key found for this signature in database
GPG Key ID: 399AF69092C727B6
14 changed files with 57 additions and 34 deletions

View File

@ -1,9 +1,11 @@
package aws package aws
import ( import (
"fmt"
"strconv" "strconv"
"github.com/aws/aws-sdk-go/service/cloudformation" "github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/hashicorp/terraform/flatmap"
"github.com/snyk/driftctl/enumeration/remote/aws/repository" "github.com/snyk/driftctl/enumeration/remote/aws/repository"
remoteerror "github.com/snyk/driftctl/enumeration/remote/error" remoteerror "github.com/snyk/driftctl/enumeration/remote/error"
"github.com/snyk/driftctl/enumeration/resource" "github.com/snyk/driftctl/enumeration/resource"
@ -38,7 +40,9 @@ func (e *CloudformationStackEnumerator) Enumerate() ([]*resource.Resource, error
attrs := map[string]interface{}{} attrs := map[string]interface{}{}
if stack.Parameters != nil && len(stack.Parameters) > 0 { if stack.Parameters != nil && len(stack.Parameters) > 0 {
attrs["parameters.%"] = strconv.FormatInt(int64(len(stack.Parameters)), 10) attrs["parameters.%"] = strconv.FormatInt(int64(len(stack.Parameters)), 10)
attrs["parameters"] = flattenParameters(stack.Parameters) for k, v := range flattenParameters(stack.Parameters) {
attrs[fmt.Sprintf("parameters.%s", k)] = v
}
} }
results = append( results = append(
@ -54,10 +58,10 @@ func (e *CloudformationStackEnumerator) Enumerate() ([]*resource.Resource, error
return results, err return results, err
} }
func flattenParameters(parameters []*cloudformation.Parameter) interface{} { func flattenParameters(parameters []*cloudformation.Parameter) flatmap.Map {
params := make(map[string]interface{}, len(parameters)) params := make(map[string]interface{}, len(parameters))
for _, p := range parameters { for _, p := range parameters {
params[*p.ParameterKey] = *p.ParameterValue params[*p.ParameterKey] = *p.ParameterValue
} }
return params return flatmap.Flatten(params)
} }

View File

@ -1,6 +1,8 @@
package common package common
import ( import (
"strconv"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
remoteerror "github.com/snyk/driftctl/enumeration/remote/error" remoteerror "github.com/snyk/driftctl/enumeration/remote/error"
"github.com/snyk/driftctl/enumeration/resource" "github.com/snyk/driftctl/enumeration/resource"
@ -29,6 +31,12 @@ func (f *GenericDetailsFetcher) ReadDetails(res *resource.Resource) (*resource.R
attributes := map[string]string{} attributes := map[string]string{}
if res.Attributes() != nil { if res.Attributes() != nil {
for k, v := range *res.Attributes() { for k, v := range *res.Attributes() {
if b, ok := v.(bool); ok {
attributes[k] = strconv.FormatBool(b)
}
if i64, ok := v.(int64); ok {
attributes[k] = strconv.FormatInt(i64, 10)
}
if str, ok := v.(string); ok { if str, ok := v.(string); ok {
attributes[k] = str attributes[k] = str
} }

View File

@ -188,6 +188,9 @@ func (a *Attributes) GetBool(path string) *bool {
} }
func (a *Attributes) GetInt(path string) *int { func (a *Attributes) GetInt(path string) *int {
// This is a nonsense, if we want to retrieve an int this is gonna fail
// We were doing that because all numbers fields from cty are float64 but sometimes we want to retrieve an int
// TODO Change this to be compatible with both int and float64 underlying type
val := a.GetFloat64(path) val := a.GetFloat64(path)
if val == nil { if val == nil {
return nil return nil

View File

@ -62,9 +62,10 @@ func (m AwsDefaultNetworkACLRule) Execute(remoteResources, resourcesFromState *[
func (m *AwsDefaultNetworkACLRule) isDefaultACLRule(res *resource.Resource) bool { func (m *AwsDefaultNetworkACLRule) isDefaultACLRule(res *resource.Resource) bool {
isIPv4 := res.Attrs.GetString("cidr_block") != nil isIPv4 := res.Attrs.GetString("cidr_block") != nil
ruleNumber, ruleNumberOk := (*res.Attrs)["rule_number"].(int64)
if isIPv4 { if isIPv4 {
if number := res.Attrs.GetFloat64("rule_number"); number != nil && int(*number) != 32767 { if ruleNumberOk && ruleNumber != 32767 {
return false return false
} }
if cidr := res.Attrs.GetString("cidr_block"); cidr != nil && *cidr != "0.0.0.0/0" { if cidr := res.Attrs.GetString("cidr_block"); cidr != nil && *cidr != "0.0.0.0/0" {
@ -73,7 +74,7 @@ func (m *AwsDefaultNetworkACLRule) isDefaultACLRule(res *resource.Resource) bool
} }
if !isIPv4 { if !isIPv4 {
if number := res.Attrs.GetFloat64("rule_number"); number != nil && int(*number) != 32768 { if ruleNumberOk && ruleNumber != 32768 {
return false return false
} }
if cidr := res.Attrs.GetString("ipv6_cidr_block"); cidr != nil && *cidr != "::/0" { if cidr := res.Attrs.GetString("ipv6_cidr_block"); cidr != nil && *cidr != "::/0" {

View File

@ -27,7 +27,7 @@ func TestAwsDefaultNetworkACLRule_Execute(t *testing.T) {
Id: "default-acl-rule", Id: "default-acl-rule",
Type: aws.AwsNetworkACLRuleResourceType, Type: aws.AwsNetworkACLRuleResourceType,
Attrs: &resource.Attributes{ Attrs: &resource.Attributes{
"rule_number": float64(32767), "rule_number": int64(32767),
"rule_action": "deny", "rule_action": "deny",
"cidr_block": "0.0.0.0/0", "cidr_block": "0.0.0.0/0",
"protocol": "-1", "protocol": "-1",
@ -37,14 +37,14 @@ func TestAwsDefaultNetworkACLRule_Execute(t *testing.T) {
Id: "non-default-acl", Id: "non-default-acl",
Type: aws.AwsNetworkACLRuleResourceType, Type: aws.AwsNetworkACLRuleResourceType,
Attrs: &resource.Attributes{ Attrs: &resource.Attributes{
"rule_number": float64(100), "rule_number": int64(100),
}, },
}, },
{ {
Id: "non-default-acl-2", Id: "non-default-acl-2",
Type: aws.AwsNetworkACLRuleResourceType, Type: aws.AwsNetworkACLRuleResourceType,
Attrs: &resource.Attributes{ Attrs: &resource.Attributes{
"rule_number": float64(32767), "rule_number": int64(32767),
"rule_action": "allow", "rule_action": "allow",
}, },
}, },
@ -52,7 +52,7 @@ func TestAwsDefaultNetworkACLRule_Execute(t *testing.T) {
Id: "non-default-acl-3", Id: "non-default-acl-3",
Type: aws.AwsNetworkACLRuleResourceType, Type: aws.AwsNetworkACLRuleResourceType,
Attrs: &resource.Attributes{ Attrs: &resource.Attributes{
"rule_number": float64(32767), "rule_number": int64(32767),
"rule_action": "deny", "rule_action": "deny",
"cidr_block": "1.2.3.0/0", "cidr_block": "1.2.3.0/0",
}, },
@ -61,7 +61,7 @@ func TestAwsDefaultNetworkACLRule_Execute(t *testing.T) {
Id: "non-default-acl-4", Id: "non-default-acl-4",
Type: aws.AwsNetworkACLRuleResourceType, Type: aws.AwsNetworkACLRuleResourceType,
Attrs: &resource.Attributes{ Attrs: &resource.Attributes{
"rule_number": float64(32767), "rule_number": int64(32767),
"rule_action": "deny", "rule_action": "deny",
"cidr_block": "0.0.0.0/0", "cidr_block": "0.0.0.0/0",
"protocol": "6", "protocol": "6",
@ -82,7 +82,7 @@ func TestAwsDefaultNetworkACLRule_Execute(t *testing.T) {
Id: "default-acl-rule", Id: "default-acl-rule",
Type: aws.AwsNetworkACLRuleResourceType, Type: aws.AwsNetworkACLRuleResourceType,
Attrs: &resource.Attributes{ Attrs: &resource.Attributes{
"rule_number": float64(32767), "rule_number": int64(32767),
"rule_action": "deny", "rule_action": "deny",
"cidr_block": "0.0.0.0/0", "cidr_block": "0.0.0.0/0",
"protocol": "-1", "protocol": "-1",
@ -92,14 +92,14 @@ func TestAwsDefaultNetworkACLRule_Execute(t *testing.T) {
Id: "non-default-acl", Id: "non-default-acl",
Type: aws.AwsNetworkACLRuleResourceType, Type: aws.AwsNetworkACLRuleResourceType,
Attrs: &resource.Attributes{ Attrs: &resource.Attributes{
"rule_number": float64(100), "rule_number": int64(100),
}, },
}, },
{ {
Id: "non-default-acl-2", Id: "non-default-acl-2",
Type: aws.AwsNetworkACLRuleResourceType, Type: aws.AwsNetworkACLRuleResourceType,
Attrs: &resource.Attributes{ Attrs: &resource.Attributes{
"rule_number": float64(32767), "rule_number": int64(32767),
"rule_action": "allow", "rule_action": "allow",
}, },
}, },
@ -107,7 +107,7 @@ func TestAwsDefaultNetworkACLRule_Execute(t *testing.T) {
Id: "non-default-acl-3", Id: "non-default-acl-3",
Type: aws.AwsNetworkACLRuleResourceType, Type: aws.AwsNetworkACLRuleResourceType,
Attrs: &resource.Attributes{ Attrs: &resource.Attributes{
"rule_number": float64(32767), "rule_number": int64(32767),
"rule_action": "deny", "rule_action": "deny",
"cidr_block": "1.2.3.0/0", "cidr_block": "1.2.3.0/0",
}, },
@ -116,7 +116,7 @@ func TestAwsDefaultNetworkACLRule_Execute(t *testing.T) {
Id: "non-default-acl-4", Id: "non-default-acl-4",
Type: aws.AwsNetworkACLRuleResourceType, Type: aws.AwsNetworkACLRuleResourceType,
Attrs: &resource.Attributes{ Attrs: &resource.Attributes{
"rule_number": float64(32767), "rule_number": int64(32767),
"rule_action": "deny", "rule_action": "deny",
"cidr_block": "0.0.0.0/0", "cidr_block": "0.0.0.0/0",
"protocol": "6", "protocol": "6",
@ -135,7 +135,7 @@ func TestAwsDefaultNetworkACLRule_Execute(t *testing.T) {
Type: aws.AwsNetworkACLRuleResourceType, Type: aws.AwsNetworkACLRuleResourceType,
Attrs: &resource.Attributes{ Attrs: &resource.Attributes{
"network_acl_id": "my-network", "network_acl_id": "my-network",
"rule_number": float64(32767), "rule_number": int64(32767),
"rule_action": "deny", "rule_action": "deny",
"cidr_block": "0.0.0.0/0", "cidr_block": "0.0.0.0/0",
"protocol": "-1", "protocol": "-1",
@ -146,7 +146,7 @@ func TestAwsDefaultNetworkACLRule_Execute(t *testing.T) {
Type: aws.AwsNetworkACLRuleResourceType, Type: aws.AwsNetworkACLRuleResourceType,
Attrs: &resource.Attributes{ Attrs: &resource.Attributes{
"network_acl_id": "my-network", "network_acl_id": "my-network",
"rule_number": float64(32768), "rule_number": int64(32768),
"rule_action": "deny", "rule_action": "deny",
"ipv6_cidr_block": "::/0", "ipv6_cidr_block": "::/0",
"protocol": "-1", "protocol": "-1",
@ -156,7 +156,7 @@ func TestAwsDefaultNetworkACLRule_Execute(t *testing.T) {
Id: "non-default-acl", Id: "non-default-acl",
Type: aws.AwsNetworkACLRuleResourceType, Type: aws.AwsNetworkACLRuleResourceType,
Attrs: &resource.Attributes{ Attrs: &resource.Attributes{
"rule_number": float64(32767), "rule_number": int64(32767),
"rule_action": "deny", "rule_action": "deny",
"cidr_block": "0.0.0.0/0", "cidr_block": "0.0.0.0/0",
"protocol": "6", "protocol": "6",
@ -172,7 +172,7 @@ func TestAwsDefaultNetworkACLRule_Execute(t *testing.T) {
Id: "non-default-acl", Id: "non-default-acl",
Type: aws.AwsNetworkACLRuleResourceType, Type: aws.AwsNetworkACLRuleResourceType,
Attrs: &resource.Attributes{ Attrs: &resource.Attributes{
"rule_number": float64(32767), "rule_number": int64(32767),
"rule_action": "deny", "rule_action": "deny",
"cidr_block": "0.0.0.0/0", "cidr_block": "0.0.0.0/0",
"protocol": "6", "protocol": "6",

View File

@ -72,7 +72,7 @@ func (e *AwsNetworkACLExpander) expandBlock(resourcesFromState *[]*resource.Reso
for _, rule := range ruleBlock { for _, rule := range ruleBlock {
attrs := rule.(map[string]interface{}) attrs := rule.(map[string]interface{})
attrs["rule_number"] = attrs["rule_no"] attrs["rule_number"] = int64(attrs["rule_no"].(float64))
delete(attrs, "rule_no") delete(attrs, "rule_no")
attrs["egress"] = egress attrs["egress"] = egress
@ -86,7 +86,7 @@ func (e *AwsNetworkACLExpander) expandBlock(resourcesFromState *[]*resource.Reso
aws.AwsNetworkACLRuleResourceType, aws.AwsNetworkACLRuleResourceType,
aws.CreateNetworkACLRuleID( aws.CreateNetworkACLRuleID(
networkAclId, networkAclId,
int64(attrs["rule_number"].(int)), attrs["rule_number"].(int64),
egress, egress,
attrs["protocol"].(string), attrs["protocol"].(string),
), ),

View File

@ -7,8 +7,8 @@ import (
"github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/aws/awsutil"
"github.com/r3labs/diff/v2" "github.com/r3labs/diff/v2"
"github.com/snyk/driftctl/enumeration/resource" "github.com/snyk/driftctl/enumeration/resource"
"github.com/snyk/driftctl/enumeration/resource/aws"
dctlresource "github.com/snyk/driftctl/pkg/resource" dctlresource "github.com/snyk/driftctl/pkg/resource"
"github.com/snyk/driftctl/pkg/resource/aws"
) )
func TestAwsNetworkACLExpander_Execute(t *testing.T) { func TestAwsNetworkACLExpander_Execute(t *testing.T) {
@ -87,7 +87,7 @@ func TestAwsNetworkACLExpander_Execute(t *testing.T) {
"icmp_type": 0, "icmp_type": 0,
"ipv6_cidr_block": "", "ipv6_cidr_block": "",
"protocol": "17", "protocol": "17",
"rule_number": 100, "rule_number": int64(100),
"to_port": 80, "to_port": 80,
}, },
).Once().Return(&resource.Resource{ ).Once().Return(&resource.Resource{
@ -114,7 +114,7 @@ func TestAwsNetworkACLExpander_Execute(t *testing.T) {
"icmp_type": 0, "icmp_type": 0,
"ipv6_cidr_block": "", "ipv6_cidr_block": "",
"protocol": "6", "protocol": "6",
"rule_number": 101, "rule_number": int64(101),
"to_port": 80, "to_port": 80,
}, },
).Once().Return(&resource.Resource{ ).Once().Return(&resource.Resource{
@ -141,7 +141,7 @@ func TestAwsNetworkACLExpander_Execute(t *testing.T) {
"icmp_type": 0, "icmp_type": 0,
"ipv6_cidr_block": "", "ipv6_cidr_block": "",
"protocol": "6", "protocol": "6",
"rule_number": 103, "rule_number": int64(103),
"to_port": 80, "to_port": 80,
}, },
).Once().Return(&resource.Resource{ ).Once().Return(&resource.Resource{
@ -168,7 +168,7 @@ func TestAwsNetworkACLExpander_Execute(t *testing.T) {
"icmp_type": 0, "icmp_type": 0,
"ipv6_cidr_block": "", "ipv6_cidr_block": "",
"protocol": "17", "protocol": "17",
"rule_number": 100, "rule_number": int64(100),
"to_port": 80, "to_port": 80,
}, },
).Once().Return(&resource.Resource{ ).Once().Return(&resource.Resource{
@ -190,7 +190,7 @@ func TestAwsNetworkACLExpander_Execute(t *testing.T) {
"icmp_type": 0, "icmp_type": 0,
"ipv6_cidr_block": "", "ipv6_cidr_block": "",
"protocol": "17", "protocol": "17",
"rule_no": 100, "rule_no": 100.0,
"to_port": 80, "to_port": 80,
}, },
}, },
@ -203,7 +203,7 @@ func TestAwsNetworkACLExpander_Execute(t *testing.T) {
"icmp_type": 0, "icmp_type": 0,
"ipv6_cidr_block": "", "ipv6_cidr_block": "",
"protocol": "6", "protocol": "6",
"rule_no": 101, "rule_no": 101.0,
"to_port": 80, "to_port": 80,
}, },
// This one exist in state, test that we do not duplicate it // This one exist in state, test that we do not duplicate it
@ -216,7 +216,7 @@ func TestAwsNetworkACLExpander_Execute(t *testing.T) {
"icmp_type": 0, "icmp_type": 0,
"ipv6_cidr_block": "", "ipv6_cidr_block": "",
"protocol": "6", "protocol": "6",
"rule_no": 103, "rule_no": 103.0,
"to_port": 80, "to_port": 80,
}, },
}, },
@ -235,7 +235,7 @@ func TestAwsNetworkACLExpander_Execute(t *testing.T) {
"icmp_type": 0, "icmp_type": 0,
"ipv6_cidr_block": "", "ipv6_cidr_block": "",
"protocol": "17", "protocol": "17",
"rule_no": 100, "rule_no": 100.0,
"to_port": 80, "to_port": 80,
}, },
}, },

View File

@ -3,12 +3,11 @@ package aws
import ( import (
"bytes" "bytes"
"fmt" "fmt"
dctlresource "github.com/snyk/driftctl/pkg/resource"
"strconv" "strconv"
"github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/hashcode"
"github.com/snyk/driftctl/enumeration/resource" "github.com/snyk/driftctl/enumeration/resource"
dctlresource "github.com/snyk/driftctl/pkg/resource"
) )
const AwsNetworkACLRuleResourceType = "aws_network_acl_rule" const AwsNetworkACLRuleResourceType = "aws_network_acl_rule"
@ -178,6 +177,14 @@ func initAwsNetworkACLRuleMetaData(resourceSchemaRepository dctlresource.SchemaR
_ = res.Attrs.SafeSet([]string{"protocol"}, strconv.Itoa(number)) _ = res.Attrs.SafeSet([]string{"protocol"}, strconv.Itoa(number))
} }
// For some reason, when deserialising the state, this field is deserialized as a float
// We need to make this homogeneous between remote and IaC so we cast this to an int64
// The real type returned by AWS SDK is int64
ruleNumber := (*res.Attrs)["rule_number"]
if v, isFloat := ruleNumber.(float64); isFloat {
_ = res.Attrs.SafeSet([]string{"rule_number"}, int64(v))
}
// ID can be different even if the resource is the same. // ID can be different even if the resource is the same.
// protocol is taken into account while creating the ID, if you set protocol="tcp" you'll end with // protocol is taken into account while creating the ID, if you set protocol="tcp" you'll end with
// a resource with a different ID than if you set protocol="6" which is the same // a resource with a different ID than if you set protocol="6" which is the same
@ -188,7 +195,7 @@ func initAwsNetworkACLRuleMetaData(resourceSchemaRepository dctlresource.SchemaR
// This workaround is mandatory to harmonize resources ID // This workaround is mandatory to harmonize resources ID
res.Id = CreateNetworkACLRuleID( res.Id = CreateNetworkACLRuleID(
*res.Attrs.GetString("network_acl_id"), *res.Attrs.GetString("network_acl_id"),
int64(*res.Attrs.GetInt("rule_number")), (*res.Attrs)["rule_number"].(int64),
*res.Attrs.GetBool("egress"), *res.Attrs.GetBool("egress"),
*res.Attrs.GetString("protocol"), *res.Attrs.GetString("protocol"),
) )
@ -200,7 +207,7 @@ func initAwsNetworkACLRuleMetaData(resourceSchemaRepository dctlresource.SchemaR
resourceSchemaRepository.SetFlags(AwsNetworkACLRuleResourceType, resource.FlagDeepMode) resourceSchemaRepository.SetFlags(AwsNetworkACLRuleResourceType, resource.FlagDeepMode)
resourceSchemaRepository.SetHumanReadableAttributesFunc(AwsNetworkACLRuleResourceType, func(res *resource.Resource) map[string]string { resourceSchemaRepository.SetHumanReadableAttributesFunc(AwsNetworkACLRuleResourceType, func(res *resource.Resource) map[string]string {
ruleNumber := strconv.FormatInt(int64(*res.Attrs.GetInt("rule_number")), 10) ruleNumber := strconv.FormatInt((*res.Attrs)["rule_number"].(int64), 10)
if ruleNumber == "32767" { if ruleNumber == "32767" {
ruleNumber = "*" ruleNumber = "*"
} }