1351 lines
47 KiB
Go
1351 lines
47 KiB
Go
package pkg_test
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
|
|
awssdk "github.com/aws/aws-sdk-go/aws"
|
|
"github.com/r3labs/diff/v2"
|
|
"github.com/stretchr/testify/mock"
|
|
"github.com/zclconf/go-cty/cty"
|
|
|
|
"github.com/cloudskiff/driftctl/pkg"
|
|
"github.com/cloudskiff/driftctl/pkg/alerter"
|
|
"github.com/cloudskiff/driftctl/pkg/analyser"
|
|
"github.com/cloudskiff/driftctl/pkg/filter"
|
|
"github.com/cloudskiff/driftctl/pkg/resource"
|
|
"github.com/cloudskiff/driftctl/pkg/resource/aws"
|
|
"github.com/cloudskiff/driftctl/pkg/resource/github"
|
|
"github.com/cloudskiff/driftctl/pkg/terraform"
|
|
"github.com/cloudskiff/driftctl/test"
|
|
testresource "github.com/cloudskiff/driftctl/test/resource"
|
|
)
|
|
|
|
type TestProvider struct {
|
|
Name string
|
|
Version string
|
|
}
|
|
|
|
type TestCase struct {
|
|
name string
|
|
provider *TestProvider
|
|
stateResources []resource.Resource
|
|
remoteResources []resource.Resource
|
|
mocks func(factory resource.ResourceFactory)
|
|
assert func(result *test.ScanResult, err error)
|
|
options *pkg.ScanOptions
|
|
}
|
|
|
|
type TestCases []TestCase
|
|
|
|
func runTest(t *testing.T, cases TestCases) {
|
|
for _, c := range cases {
|
|
if c.provider == nil {
|
|
c.provider = &TestProvider{
|
|
Name: "aws",
|
|
Version: "3.19.0",
|
|
}
|
|
}
|
|
repo := testresource.InitFakeSchemaRepository(c.provider.Name, c.provider.Version)
|
|
aws.InitResourcesMetadata(repo)
|
|
github.InitMetadatas(repo)
|
|
t.Run(c.name, func(t *testing.T) {
|
|
testAlerter := alerter.NewAlerter()
|
|
|
|
if c.stateResources == nil {
|
|
c.stateResources = []resource.Resource{}
|
|
}
|
|
|
|
stateSupplier := &resource.MockSupplier{}
|
|
stateSupplier.On("Resources").Return(c.stateResources, nil)
|
|
|
|
if c.remoteResources == nil {
|
|
c.remoteResources = []resource.Resource{}
|
|
}
|
|
|
|
remoteSupplier := &resource.MockSupplier{}
|
|
remoteSupplier.On("Resources").Return(c.remoteResources, nil)
|
|
|
|
resourceFactory := &terraform.MockResourceFactory{}
|
|
|
|
if c.mocks != nil {
|
|
c.mocks(resourceFactory)
|
|
}
|
|
|
|
driftctl := pkg.NewDriftCTL(remoteSupplier, stateSupplier, testAlerter, resourceFactory, c.options, repo)
|
|
|
|
analysis, err := driftctl.Run()
|
|
|
|
c.assert(test.NewScanResult(t, analysis), err)
|
|
})
|
|
}
|
|
}
|
|
|
|
func matchByAttributes(input, attrs map[string]interface{}) bool {
|
|
for k, v := range attrs {
|
|
if value, ok := input[k]; !ok || !reflect.DeepEqual(value, v) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func TestDriftctlRun_BasicBehavior(t *testing.T) {
|
|
|
|
cases := TestCases{
|
|
{
|
|
name: "infrastructure should be in sync",
|
|
stateResources: []resource.Resource{
|
|
&testresource.FakeResource{},
|
|
},
|
|
remoteResources: []resource.Resource{
|
|
&testresource.FakeResource{},
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertInfrastructureIsInSync()
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
return &pkg.ScanOptions{}
|
|
}(t),
|
|
},
|
|
{
|
|
name: "we should have deleted resource",
|
|
stateResources: []resource.Resource{
|
|
&testresource.FakeResource{},
|
|
},
|
|
remoteResources: []resource.Resource{},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertDeletedCount(1)
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
return &pkg.ScanOptions{}
|
|
}(t),
|
|
},
|
|
{
|
|
name: "we should have unmanaged resource",
|
|
stateResources: []resource.Resource{},
|
|
remoteResources: []resource.Resource{
|
|
&testresource.FakeResource{},
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertUnmanagedCount(1)
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
return &pkg.ScanOptions{}
|
|
}(t),
|
|
},
|
|
{
|
|
name: "we should have changes of field update",
|
|
stateResources: []resource.Resource{
|
|
&testresource.FakeResource{
|
|
Id: "fake",
|
|
FooBar: "barfoo",
|
|
},
|
|
},
|
|
remoteResources: []resource.Resource{
|
|
&testresource.FakeResource{
|
|
Id: "fake",
|
|
FooBar: "foobar",
|
|
},
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertManagedCount(1)
|
|
result.AssertResourceHasDrift("fake", "FakeResource", analyser.Change{
|
|
Change: diff.Change{
|
|
Type: diff.UPDATE,
|
|
Path: []string{"FooBar"},
|
|
From: "barfoo",
|
|
To: "foobar",
|
|
},
|
|
Computed: false,
|
|
})
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
return &pkg.ScanOptions{}
|
|
}(t),
|
|
},
|
|
{
|
|
name: "we should have changes on computed field",
|
|
stateResources: []resource.Resource{
|
|
&testresource.FakeResource{
|
|
Id: "fake",
|
|
BarFoo: "barfoo",
|
|
},
|
|
},
|
|
remoteResources: []resource.Resource{
|
|
&testresource.FakeResource{
|
|
Id: "fake",
|
|
BarFoo: "foobar",
|
|
},
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertManagedCount(1)
|
|
result.AssertResourceHasDrift("fake", "FakeResource", analyser.Change{
|
|
Change: diff.Change{
|
|
Type: diff.UPDATE,
|
|
Path: []string{"BarFoo"},
|
|
From: "barfoo",
|
|
To: "foobar",
|
|
},
|
|
Computed: true,
|
|
})
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
return &pkg.ScanOptions{}
|
|
}(t),
|
|
},
|
|
{
|
|
name: "we should have changes of deleted field",
|
|
stateResources: []resource.Resource{
|
|
&testresource.FakeResource{
|
|
Id: "fake",
|
|
Tags: map[string]string{
|
|
"tag1": "deleted",
|
|
},
|
|
},
|
|
},
|
|
remoteResources: []resource.Resource{
|
|
&testresource.FakeResource{
|
|
Id: "fake",
|
|
},
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertManagedCount(1)
|
|
result.AssertResourceHasDrift("fake", "FakeResource", analyser.Change{
|
|
Change: diff.Change{
|
|
Type: diff.DELETE,
|
|
Path: []string{"Tags", "tag1"},
|
|
From: "deleted",
|
|
To: nil,
|
|
},
|
|
Computed: false,
|
|
})
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
return &pkg.ScanOptions{}
|
|
}(t),
|
|
},
|
|
{
|
|
name: "we should have changes of added field",
|
|
stateResources: []resource.Resource{
|
|
&testresource.FakeResource{
|
|
Id: "fake",
|
|
},
|
|
},
|
|
remoteResources: []resource.Resource{
|
|
&testresource.FakeResource{
|
|
Id: "fake",
|
|
Tags: map[string]string{
|
|
"tag1": "added",
|
|
},
|
|
},
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertManagedCount(1)
|
|
result.AssertResourceHasDrift("fake", "FakeResource", analyser.Change{
|
|
Change: diff.Change{
|
|
Type: diff.CREATE,
|
|
Path: []string{"Tags", "tag1"},
|
|
From: nil,
|
|
To: "added",
|
|
},
|
|
Computed: false,
|
|
})
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
return &pkg.ScanOptions{}
|
|
}(t),
|
|
},
|
|
{
|
|
name: "we should ignore default AWS IAM role when strict mode is disabled",
|
|
stateResources: []resource.Resource{
|
|
testresource.FakeResource{
|
|
Id: "fake",
|
|
},
|
|
&aws.AwsIamPolicy{
|
|
Id: "role-policy-test-1",
|
|
Arn: func(p string) *string { return &p }("policy-test-1"),
|
|
},
|
|
},
|
|
remoteResources: []resource.Resource{
|
|
testresource.FakeResource{
|
|
Id: "fake",
|
|
},
|
|
&aws.AwsIamRole{
|
|
Id: "role-test-1",
|
|
Path: func(p string) *string { return &p }("/aws-service-role/test"),
|
|
},
|
|
&aws.AwsIamRolePolicy{
|
|
Id: "role-policy-test-1",
|
|
Role: func(p string) *string { return &p }("role-test-1"),
|
|
},
|
|
&aws.AwsIamPolicy{
|
|
Id: "role-policy-test-1",
|
|
Arn: func(p string) *string { return &p }("policy-test-1"),
|
|
},
|
|
&aws.AwsIamPolicyAttachment{
|
|
Id: "policy-attachment-test-1",
|
|
PolicyArn: func(p string) *string { return &p }("policy-test-1"),
|
|
Users: func(p []string) *[]string { return &p }([]string{}),
|
|
Roles: func(p []string) *[]string { return &p }([]string{"role-test-1"}),
|
|
},
|
|
&aws.AwsIamRole{
|
|
Id: "role-test-2",
|
|
Path: func(p string) *string { return &p }("/not-aws-service-role/test"),
|
|
},
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertManagedCount(2)
|
|
result.AssertUnmanagedCount(1)
|
|
result.AssertDeletedCount(0)
|
|
result.AssertDriftCountTotal(0)
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
return &pkg.ScanOptions{
|
|
StrictMode: false,
|
|
}
|
|
}(t),
|
|
},
|
|
{
|
|
name: "we should not ignore default AWS IAM role when strict mode is enabled",
|
|
stateResources: []resource.Resource{
|
|
testresource.FakeResource{
|
|
Id: "fake",
|
|
},
|
|
&aws.AwsIamPolicy{
|
|
Id: "policy-test-1",
|
|
Arn: func(p string) *string { return &p }("policy-test-1"),
|
|
},
|
|
},
|
|
remoteResources: []resource.Resource{
|
|
testresource.FakeResource{
|
|
Id: "fake",
|
|
},
|
|
&aws.AwsIamRole{
|
|
Id: "role-test-1",
|
|
Path: func(p string) *string { return &p }("/aws-service-role/test"),
|
|
},
|
|
&aws.AwsIamRolePolicy{
|
|
Id: "role-policy-test-1",
|
|
Role: func(p string) *string { return &p }("role-test-1"),
|
|
},
|
|
&aws.AwsIamPolicy{
|
|
Id: "policy-test-1",
|
|
Arn: func(p string) *string { return &p }("policy-test-1"),
|
|
},
|
|
&aws.AwsIamPolicyAttachment{
|
|
Id: "policy-attachment-test-1",
|
|
PolicyArn: func(p string) *string { return &p }("policy-test-1"),
|
|
Users: func(p []string) *[]string { return &p }([]string{}),
|
|
Roles: func(p []string) *[]string { return &p }([]string{"role-test-1"}),
|
|
},
|
|
&aws.AwsIamRole{
|
|
Id: "role-test-2",
|
|
Path: func(p string) *string { return &p }("/not-aws-service-role/test"),
|
|
},
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertManagedCount(2)
|
|
result.AssertUnmanagedCount(4)
|
|
result.AssertDeletedCount(0)
|
|
result.AssertDriftCountTotal(0)
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
return &pkg.ScanOptions{
|
|
StrictMode: true,
|
|
}
|
|
}(t),
|
|
},
|
|
{
|
|
name: "we should not ignore default AWS IAM role when strict mode is enabled and a filter is specified",
|
|
stateResources: []resource.Resource{
|
|
testresource.FakeResource{
|
|
Id: "fake",
|
|
},
|
|
&aws.AwsIamPolicy{
|
|
Id: "policy-test-1",
|
|
Arn: func(p string) *string { return &p }("policy-test-1"),
|
|
},
|
|
},
|
|
remoteResources: []resource.Resource{
|
|
testresource.FakeResource{
|
|
Id: "fake",
|
|
},
|
|
&aws.AwsIamRole{
|
|
Id: "role-test-1",
|
|
Path: func(p string) *string { return &p }("/aws-service-role/test"),
|
|
},
|
|
&aws.AwsIamRolePolicy{
|
|
Id: "role-policy-test-1",
|
|
Role: func(p string) *string { return &p }("role-test-1"),
|
|
},
|
|
&aws.AwsIamPolicy{
|
|
Id: "policy-test-1",
|
|
Arn: func(p string) *string { return &p }("policy-test-1"),
|
|
},
|
|
&aws.AwsIamPolicyAttachment{
|
|
Id: "policy-attachment-test-1",
|
|
PolicyArn: func(p string) *string { return &p }("policy-test-1"),
|
|
Users: func(p []string) *[]string { return &p }([]string{}),
|
|
Roles: func(p []string) *[]string { return &p }([]string{"role-test-1"}),
|
|
},
|
|
&aws.AwsIamRole{
|
|
Id: "role-test-2",
|
|
Path: func(p string) *string { return &p }("/not-aws-service-role/test"),
|
|
},
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertCoverage(0)
|
|
result.AssertInfrastructureIsNotSync()
|
|
result.AssertManagedCount(0)
|
|
result.AssertUnmanagedCount(1)
|
|
result.AssertDeletedCount(0)
|
|
result.AssertDriftCountTotal(0)
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
filterStr := "Id=='role-test-1'"
|
|
f, err := filter.BuildExpression(filterStr)
|
|
if err != nil {
|
|
t.Fatalf("Unable to build filter expression: %s\n%s", filterStr, err)
|
|
}
|
|
|
|
return &pkg.ScanOptions{
|
|
Filter: f,
|
|
StrictMode: true,
|
|
}
|
|
}(t),
|
|
},
|
|
}
|
|
|
|
runTest(t, cases)
|
|
}
|
|
|
|
func TestDriftctlRun_BasicFilter(t *testing.T) {
|
|
cases := TestCases{
|
|
{
|
|
name: "test filtering on Type",
|
|
stateResources: []resource.Resource{},
|
|
remoteResources: []resource.Resource{
|
|
testresource.FakeResource{
|
|
Id: "res1",
|
|
Type: "not-filtered",
|
|
},
|
|
testresource.FakeResource{
|
|
Id: "res2",
|
|
Type: "filtered",
|
|
},
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertUnmanagedCount(1)
|
|
result.AssertResourceUnmanaged("res2", "filtered")
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
filterStr := "Type=='filtered'"
|
|
f, err := filter.BuildExpression(filterStr)
|
|
if err != nil {
|
|
t.Fatalf("Unable to build filter expression: %s\n%s", filterStr, err)
|
|
}
|
|
|
|
return &pkg.ScanOptions{Filter: f}
|
|
}(t),
|
|
},
|
|
{
|
|
name: "test filtering on Id",
|
|
stateResources: []resource.Resource{},
|
|
remoteResources: []resource.Resource{
|
|
testresource.FakeResource{
|
|
Id: "res1",
|
|
Type: "not-filtered",
|
|
},
|
|
testresource.FakeResource{
|
|
Id: "res2",
|
|
Type: "filtered",
|
|
},
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertUnmanagedCount(1)
|
|
result.AssertResourceUnmanaged("res2", "filtered")
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
filterStr := "Id=='res2'"
|
|
f, err := filter.BuildExpression(filterStr)
|
|
if err != nil {
|
|
t.Fatalf("Unable to build filter expression: %s\n%s", filterStr, err)
|
|
}
|
|
|
|
return &pkg.ScanOptions{Filter: f}
|
|
}(t),
|
|
},
|
|
{
|
|
name: "test filtering on attribute",
|
|
stateResources: []resource.Resource{},
|
|
remoteResources: []resource.Resource{
|
|
testresource.FakeResource{
|
|
Id: "res1",
|
|
Type: "filtered",
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"test_field": cty.StringVal("value to filter on"),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
testresource.FakeResource{
|
|
Id: "res2",
|
|
Type: "not-filtered",
|
|
},
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertUnmanagedCount(1)
|
|
result.AssertResourceUnmanaged("res1", "filtered")
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
filterStr := "Attr.test_field=='value to filter on'"
|
|
f, err := filter.BuildExpression(filterStr)
|
|
if err != nil {
|
|
t.Fatalf("Unable to build filter expression: %s\n%s", filterStr, err)
|
|
}
|
|
|
|
return &pkg.ScanOptions{Filter: f}
|
|
}(t),
|
|
},
|
|
}
|
|
|
|
runTest(t, cases)
|
|
}
|
|
|
|
func TestDriftctlRun_Middlewares(t *testing.T) {
|
|
cases := TestCases{
|
|
{
|
|
name: "test bucket policy expander middleware",
|
|
stateResources: []resource.Resource{
|
|
&aws.AwsS3Bucket{
|
|
Id: "foo",
|
|
Bucket: awssdk.String("foo"),
|
|
Policy: awssdk.String("{\"Id\":\"foo\"}"),
|
|
},
|
|
},
|
|
remoteResources: []resource.Resource{
|
|
&aws.AwsS3BucketPolicy{
|
|
Id: "foo",
|
|
Bucket: awssdk.String("foo"),
|
|
Policy: awssdk.String("{\"Id\":\"bar\"}"),
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("foo"),
|
|
"bucket": cty.StringVal("foo"),
|
|
"policy": cty.StringVal("{\"Id\":\"bar\"}"),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
},
|
|
mocks: func(factory resource.ResourceFactory) {
|
|
foo := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("foo"),
|
|
"bucket": cty.StringVal("foo"),
|
|
"policy": cty.StringVal("{\"Id\":\"foo\"}"),
|
|
})
|
|
factory.(*terraform.MockResourceFactory).On("CreateResource", mock.MatchedBy(func(input map[string]interface{}) bool {
|
|
return matchByAttributes(input, map[string]interface{}{
|
|
"id": "foo",
|
|
"bucket": awssdk.String("foo"),
|
|
"policy": awssdk.String("{\"Id\":\"foo\"}"),
|
|
})
|
|
}), "aws_s3_bucket_policy").Times(1).Return(&foo, nil)
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertManagedCount(1)
|
|
result.AssertResourceHasDrift("foo", "aws_s3_bucket_policy", analyser.Change{
|
|
Change: diff.Change{
|
|
Type: diff.UPDATE,
|
|
Path: []string{"Policy"},
|
|
From: "{\"Id\":\"foo\"}",
|
|
To: "{\"Id\":\"bar\"}",
|
|
},
|
|
Computed: false,
|
|
})
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
filterStr := "Type=='aws_s3_bucket_policy' && Attr.bucket=='foo'"
|
|
f, err := filter.BuildExpression(filterStr)
|
|
if err != nil {
|
|
t.Fatalf("Unable to build filter expression: %s\n%s", filterStr, err)
|
|
}
|
|
|
|
return &pkg.ScanOptions{Filter: f}
|
|
}(t),
|
|
},
|
|
{
|
|
name: "test instance block device middleware",
|
|
stateResources: []resource.Resource{
|
|
&aws.AwsInstance{
|
|
Id: "dummy-instance",
|
|
AvailabilityZone: awssdk.String("us-east-1"),
|
|
EbsBlockDevice: &[]struct {
|
|
DeleteOnTermination *bool `cty:"delete_on_termination"`
|
|
DeviceName *string `cty:"device_name"`
|
|
Encrypted *bool `cty:"encrypted" computed:"true"`
|
|
Iops *int `cty:"iops" computed:"true"`
|
|
KmsKeyId *string `cty:"kms_key_id" computed:"true"`
|
|
SnapshotId *string `cty:"snapshot_id" computed:"true"`
|
|
VolumeId *string `cty:"volume_id" computed:"true"`
|
|
VolumeSize *int `cty:"volume_size" computed:"true"`
|
|
VolumeType *string `cty:"volume_type" computed:"true"`
|
|
}{
|
|
{
|
|
VolumeId: awssdk.String("vol-018c5ae89895aca4c"),
|
|
Encrypted: awssdk.Bool(true),
|
|
},
|
|
},
|
|
RootBlockDevice: &[]struct {
|
|
DeleteOnTermination *bool `cty:"delete_on_termination"`
|
|
DeviceName *string `cty:"device_name" computed:"true"`
|
|
Encrypted *bool `cty:"encrypted" computed:"true"`
|
|
Iops *int `cty:"iops" computed:"true"`
|
|
KmsKeyId *string `cty:"kms_key_id" computed:"true"`
|
|
VolumeId *string `cty:"volume_id" computed:"true"`
|
|
VolumeSize *int `cty:"volume_size" computed:"true"`
|
|
VolumeType *string `cty:"volume_type" computed:"true"`
|
|
}{
|
|
{
|
|
VolumeId: awssdk.String("vol-02862d9b39045a3a4"),
|
|
VolumeType: awssdk.String("gp2"),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
remoteResources: []resource.Resource{
|
|
&aws.AwsEbsVolume{
|
|
Id: "vol-018c5ae89895aca4c",
|
|
Encrypted: awssdk.Bool(false),
|
|
MultiAttachEnabled: awssdk.Bool(false),
|
|
AvailabilityZone: awssdk.String("us-east-1"),
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("vol-018c5ae89895aca4c"),
|
|
"availability_zone": cty.StringVal("us-east-1"),
|
|
"encrypted": cty.BoolVal(false),
|
|
"multi_attach_enabled": cty.BoolVal(false),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
&aws.AwsEbsVolume{
|
|
Id: "vol-02862d9b39045a3a4",
|
|
Type: awssdk.String("gp3"),
|
|
MultiAttachEnabled: awssdk.Bool(false),
|
|
AvailabilityZone: awssdk.String("us-east-1"),
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("vol-02862d9b39045a3a4"),
|
|
"availability_zone": cty.StringVal("us-east-1"),
|
|
"type": cty.StringVal("gp3"),
|
|
"multi_attach_enabled": cty.BoolVal(false),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
},
|
|
mocks: func(factory resource.ResourceFactory) {
|
|
foo := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("vol-018c5ae89895aca4c"),
|
|
"availability_zone": cty.StringVal("us-east-1"),
|
|
"encrypted": cty.BoolVal(true),
|
|
"multi_attach_enabled": cty.BoolVal(false),
|
|
})
|
|
factory.(*terraform.MockResourceFactory).On("CreateResource", mock.MatchedBy(func(input map[string]interface{}) bool {
|
|
return matchByAttributes(input, map[string]interface{}{
|
|
"id": "vol-018c5ae89895aca4c",
|
|
"availability_zone": awssdk.String("us-east-1"),
|
|
"encrypted": awssdk.Bool(true),
|
|
"multi_attach_enabled": false,
|
|
})
|
|
}), "aws_ebs_volume").Times(1).Return(&foo, nil)
|
|
|
|
bar := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("vol-02862d9b39045a3a4"),
|
|
"availability_zone": cty.StringVal("us-east-1"),
|
|
"type": cty.StringVal("gp2"),
|
|
"multi_attach_enabled": cty.BoolVal(false),
|
|
})
|
|
factory.(*terraform.MockResourceFactory).On("CreateResource", mock.MatchedBy(func(input map[string]interface{}) bool {
|
|
return matchByAttributes(input, map[string]interface{}{
|
|
"id": "vol-02862d9b39045a3a4",
|
|
"availability_zone": awssdk.String("us-east-1"),
|
|
"type": awssdk.String("gp2"),
|
|
"multi_attach_enabled": false,
|
|
})
|
|
}), "aws_ebs_volume").Times(1).Return(&bar, nil)
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertManagedCount(2)
|
|
result.AssertResourceHasDrift("vol-02862d9b39045a3a4", "aws_ebs_volume", analyser.Change{
|
|
Change: diff.Change{
|
|
Type: diff.UPDATE,
|
|
Path: []string{"Type"},
|
|
From: "gp2",
|
|
To: "gp3",
|
|
},
|
|
Computed: true,
|
|
})
|
|
result.AssertResourceHasDrift("vol-018c5ae89895aca4c", "aws_ebs_volume", analyser.Change{
|
|
Change: diff.Change{
|
|
Type: diff.UPDATE,
|
|
Path: []string{"Encrypted"},
|
|
From: true,
|
|
To: false,
|
|
},
|
|
Computed: true,
|
|
})
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
filterStr := "Type=='aws_ebs_volume' && Attr.availability_zone=='us-east-1'"
|
|
f, err := filter.BuildExpression(filterStr)
|
|
if err != nil {
|
|
t.Fatalf("Unable to build filter expression: %s\n%s", filterStr, err)
|
|
}
|
|
|
|
return &pkg.ScanOptions{Filter: f}
|
|
}(t),
|
|
},
|
|
{
|
|
name: "test route table expander middleware",
|
|
stateResources: []resource.Resource{
|
|
&aws.AwsRouteTable{
|
|
Id: "table",
|
|
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"),
|
|
CidrBlock: awssdk.String("0.0.0.0/0"),
|
|
},
|
|
{
|
|
GatewayId: awssdk.String("igw-07b7844a8fd17a638"),
|
|
Ipv6CidrBlock: awssdk.String("::/0"),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
remoteResources: []resource.Resource{
|
|
&aws.AwsRoute{
|
|
Id: "r-table1080289494",
|
|
RouteTableId: awssdk.String("table"),
|
|
DestinationCidrBlock: awssdk.String("0.0.0.0/0"),
|
|
GatewayId: awssdk.String("igw-07b7844a8fd17a638"),
|
|
Origin: awssdk.String("CreateRoute"),
|
|
State: awssdk.String("active"),
|
|
DestinationPrefixListId: awssdk.String(""),
|
|
InstanceOwnerId: awssdk.String(""),
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("r-table1080289494"),
|
|
"route_table_id": cty.StringVal("table"),
|
|
"destination_cidr_block": cty.StringVal("0.0.0.0/0"),
|
|
"gateway_id": cty.StringVal("igw-07b7844a8fd17a638"),
|
|
"origin": cty.StringVal("CreateRoute"),
|
|
"state": cty.StringVal("active"),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
&aws.AwsRoute{
|
|
Id: "r-table2750132062",
|
|
RouteTableId: awssdk.String("table"),
|
|
DestinationIpv6CidrBlock: awssdk.String("::/0"),
|
|
GatewayId: awssdk.String("igw-07b7844a8fd17a638"),
|
|
Origin: awssdk.String("CreateRoute"),
|
|
State: awssdk.String("active"),
|
|
DestinationPrefixListId: awssdk.String(""),
|
|
InstanceOwnerId: awssdk.String(""),
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("r-table2750132062"),
|
|
"route_table_id": cty.StringVal("table"),
|
|
"destination_ipv6_cidr_block": cty.StringVal("::/0"),
|
|
"gateway_id": cty.StringVal("igw-07b7844a8fd17a638"),
|
|
"origin": cty.StringVal("CreateRoute"),
|
|
"state": cty.StringVal("active"),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
},
|
|
mocks: func(factory resource.ResourceFactory) {
|
|
foo := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("r-table1080289494"),
|
|
"route_table_id": cty.StringVal("table"),
|
|
"destination_cidr_block": cty.StringVal("0.0.0.0/0"),
|
|
"gateway_id": cty.StringVal("igw-07b7844a8fd17a638"),
|
|
"origin": cty.StringVal("CreateRoute"),
|
|
"state": cty.StringVal("active"),
|
|
})
|
|
factory.(*terraform.MockResourceFactory).On("CreateResource", mock.MatchedBy(func(input map[string]interface{}) bool {
|
|
return matchByAttributes(input, map[string]interface{}{
|
|
"id": "r-table1080289494",
|
|
"destination_cidr_block": awssdk.String("0.0.0.0/0"),
|
|
"gateway_id": awssdk.String("igw-07b7844a8fd17a638"),
|
|
"origin": "CreateRoute",
|
|
"route_table_id": "table",
|
|
"state": "active",
|
|
})
|
|
}), "aws_route").Times(1).Return(&foo, nil)
|
|
|
|
bar := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("r-table2750132062"),
|
|
"route_table_id": cty.StringVal("table"),
|
|
"destination_ipv6_cidr_block": cty.StringVal("::/0"),
|
|
"gateway_id": cty.StringVal("igw-07b7844a8fd17a638"),
|
|
"origin": cty.StringVal("CreateRoute"),
|
|
"state": cty.StringVal("active"),
|
|
})
|
|
factory.(*terraform.MockResourceFactory).On("CreateResource", mock.MatchedBy(func(input map[string]interface{}) bool {
|
|
return matchByAttributes(input, map[string]interface{}{
|
|
"id": "r-table2750132062",
|
|
"destination_ipv6_cidr_block": awssdk.String("::/0"),
|
|
"gateway_id": awssdk.String("igw-07b7844a8fd17a638"),
|
|
"origin": "CreateRoute",
|
|
"route_table_id": "table",
|
|
"state": "active",
|
|
})
|
|
}), "aws_route").Times(1).Return(&bar, nil)
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertManagedCount(2)
|
|
result.AssertInfrastructureIsInSync()
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
filterStr := "Type=='aws_route' && Attr.gateway_id=='igw-07b7844a8fd17a638'"
|
|
f, err := filter.BuildExpression(filterStr)
|
|
if err != nil {
|
|
t.Fatalf("Unable to build filter expression: %s\n%s", filterStr, err)
|
|
}
|
|
|
|
return &pkg.ScanOptions{Filter: f}
|
|
}(t),
|
|
},
|
|
{
|
|
name: "test sns topic policy expander middleware",
|
|
stateResources: []resource.Resource{
|
|
&aws.AwsSnsTopic{
|
|
Id: "foo",
|
|
Arn: awssdk.String("arn"),
|
|
Policy: awssdk.String("{\"policy\":\"bar\"}"),
|
|
},
|
|
},
|
|
remoteResources: []resource.Resource{
|
|
&aws.AwsSnsTopicPolicy{
|
|
Id: "foo",
|
|
Arn: awssdk.String("arn"),
|
|
Policy: awssdk.String("{\"policy\":\"baz\"}"),
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("foo"),
|
|
"arn": cty.StringVal("arn"),
|
|
"policy": cty.StringVal("{\"policy\":\"baz\"}"),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
},
|
|
mocks: func(factory resource.ResourceFactory) {
|
|
foo := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("foo"),
|
|
"arn": cty.StringVal("arn"),
|
|
"policy": cty.StringVal("{\"policy\":\"bar\"}"),
|
|
})
|
|
factory.(*terraform.MockResourceFactory).On("CreateResource", mock.MatchedBy(func(input map[string]interface{}) bool {
|
|
return matchByAttributes(input, map[string]interface{}{
|
|
"id": "foo",
|
|
"arn": awssdk.String("arn"),
|
|
"policy": awssdk.String("{\"policy\":\"bar\"}"),
|
|
})
|
|
}), "aws_sns_topic_policy").Times(1).Return(&foo, nil)
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertManagedCount(1)
|
|
result.AssertResourceHasDrift("foo", "aws_sns_topic_policy", analyser.Change{
|
|
Change: diff.Change{
|
|
Type: diff.UPDATE,
|
|
Path: []string{"Policy"},
|
|
From: "{\"policy\":\"bar\"}",
|
|
To: "{\"policy\":\"baz\"}",
|
|
},
|
|
Computed: false,
|
|
})
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
filterStr := "Type=='aws_sns_topic_policy' && Attr.arn=='arn'"
|
|
f, err := filter.BuildExpression(filterStr)
|
|
if err != nil {
|
|
t.Fatalf("Unable to build filter expression: %s\n%s", filterStr, err)
|
|
}
|
|
|
|
return &pkg.ScanOptions{Filter: f}
|
|
}(t),
|
|
},
|
|
{
|
|
name: "test sqs queue policy expander middleware",
|
|
stateResources: []resource.Resource{
|
|
&aws.AwsSqsQueue{
|
|
Id: "foo",
|
|
Policy: awssdk.String("{\"policy\":\"bar\"}"),
|
|
},
|
|
},
|
|
remoteResources: []resource.Resource{
|
|
&aws.AwsSqsQueuePolicy{
|
|
Id: "foo",
|
|
QueueUrl: awssdk.String("foo"),
|
|
Policy: awssdk.String("{\"policy\":\"baz\"}"),
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("foo"),
|
|
"queue_url": cty.StringVal("foo"),
|
|
"policy": cty.StringVal("{\"policy\":\"baz\"}"),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
},
|
|
mocks: func(factory resource.ResourceFactory) {
|
|
foo := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("foo"),
|
|
"queue_url": cty.StringVal("foo"),
|
|
"policy": cty.StringVal("{\"policy\":\"bar\"}"),
|
|
})
|
|
factory.(*terraform.MockResourceFactory).On("CreateResource", mock.MatchedBy(func(input map[string]interface{}) bool {
|
|
return matchByAttributes(input, map[string]interface{}{
|
|
"id": "foo",
|
|
"queue_url": "foo",
|
|
"policy": awssdk.String("{\"policy\":\"bar\"}"),
|
|
})
|
|
}), "aws_sqs_queue_policy").Times(1).Return(&foo, nil)
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertManagedCount(1)
|
|
result.AssertResourceHasDrift("foo", "aws_sqs_queue_policy", analyser.Change{
|
|
Change: diff.Change{
|
|
Type: diff.UPDATE,
|
|
Path: []string{"Policy"},
|
|
From: "{\"policy\":\"bar\"}",
|
|
To: "{\"policy\":\"baz\"}",
|
|
},
|
|
Computed: false,
|
|
})
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
filterStr := "Type=='aws_sqs_queue_policy' && Attr.queue_url=='foo'"
|
|
f, err := filter.BuildExpression(filterStr)
|
|
if err != nil {
|
|
t.Fatalf("Unable to build filter expression: %s\n%s", filterStr, err)
|
|
}
|
|
|
|
return &pkg.ScanOptions{Filter: f}
|
|
}(t),
|
|
},
|
|
{
|
|
name: "test security group rule sanitizer middleware",
|
|
stateResources: []resource.Resource{
|
|
&aws.AwsSecurityGroupRule{
|
|
Id: "sgrule-3970541193",
|
|
Type: awssdk.String("ingress"),
|
|
SecurityGroupId: awssdk.String("sg-0254c038e32f25530"),
|
|
Protocol: awssdk.String("tcp"),
|
|
FromPort: awssdk.Int(0),
|
|
ToPort: awssdk.Int(65535),
|
|
Self: awssdk.Bool(true),
|
|
SourceSecurityGroupId: awssdk.String("sg-0254c038e32f25530"),
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("sgrule-3970541193"),
|
|
"type": cty.StringVal("ingress"),
|
|
"security_group_id": cty.StringVal("sg-0254c038e32f25530"),
|
|
"protocol": cty.StringVal("tcp"),
|
|
"from_port": cty.NumberIntVal(0),
|
|
"to_port": cty.NumberIntVal(65535),
|
|
"self": cty.BoolVal(true),
|
|
"source_security_group_id": cty.StringVal("sg-0254c038e32f25530"),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
&aws.AwsSecurityGroupRule{
|
|
Id: "sgrule-845917806",
|
|
Type: awssdk.String("egress"),
|
|
SecurityGroupId: awssdk.String("sg-0254c038e32f25530"),
|
|
Protocol: awssdk.String("-1"),
|
|
FromPort: awssdk.Int(0),
|
|
ToPort: awssdk.Int(0),
|
|
CidrBlocks: &[]string{"0.0.0.0/0"},
|
|
Ipv6CidrBlocks: &[]string{"::/0"},
|
|
},
|
|
&aws.AwsSecurityGroupRule{
|
|
Id: "sgrule-294318973",
|
|
Type: awssdk.String("ingress"),
|
|
SecurityGroupId: awssdk.String("sg-0254c038e32f25530"),
|
|
Protocol: awssdk.String("-1"),
|
|
FromPort: awssdk.Int(0),
|
|
ToPort: awssdk.Int(0),
|
|
CidrBlocks: &[]string{"1.2.0.0/16", "5.6.7.0/24"},
|
|
},
|
|
&aws.AwsSecurityGroupRule{
|
|
Id: "sgrule-2471889226",
|
|
Type: awssdk.String("ingress"),
|
|
SecurityGroupId: awssdk.String("sg-0254c038e32f25530"),
|
|
Protocol: awssdk.String("tcp"),
|
|
FromPort: awssdk.Int(0),
|
|
ToPort: awssdk.Int(0),
|
|
PrefixListIds: &[]string{"pl-abb451c2"},
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("sgrule-2471889226"),
|
|
"type": cty.StringVal("ingress"),
|
|
"security_group_id": cty.StringVal("sg-0254c038e32f25530"),
|
|
"protocol": cty.StringVal("tcp"),
|
|
"from_port": cty.NumberIntVal(0),
|
|
"to_port": cty.NumberIntVal(0),
|
|
"prefix_list_ids": cty.SetVal([]cty.Value{
|
|
cty.StringVal("pl-abb451c2"),
|
|
}),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
&aws.AwsSecurityGroupRule{
|
|
Id: "sgrule-3587309474",
|
|
Type: awssdk.String("ingress"),
|
|
SecurityGroupId: awssdk.String("sg-0254c038e32f25530"),
|
|
Protocol: awssdk.String("tcp"),
|
|
FromPort: awssdk.Int(0),
|
|
ToPort: awssdk.Int(65535),
|
|
SourceSecurityGroupId: awssdk.String("sg-9e0204ff"),
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("sgrule-3587309474"),
|
|
"type": cty.StringVal("ingress"),
|
|
"security_group_id": cty.StringVal("sg-0254c038e32f25530"),
|
|
"protocol": cty.StringVal("tcp"),
|
|
"from_port": cty.NumberIntVal(0),
|
|
"to_port": cty.NumberIntVal(65535),
|
|
"source_security_group_id": cty.StringVal("sg-9e0204ff"),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
},
|
|
remoteResources: []resource.Resource{
|
|
&aws.AwsSecurityGroupRule{
|
|
Id: "sgrule-3970541193",
|
|
Type: awssdk.String("ingress"),
|
|
SecurityGroupId: awssdk.String("sg-0254c038e32f25530"),
|
|
Protocol: awssdk.String("tcp"),
|
|
FromPort: awssdk.Int(0),
|
|
ToPort: awssdk.Int(65535),
|
|
Self: awssdk.Bool(true),
|
|
SourceSecurityGroupId: awssdk.String("sg-0254c038e32f25530"),
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("sgrule-3970541193"),
|
|
"type": cty.StringVal("ingress"),
|
|
"security_group_id": cty.StringVal("sg-0254c038e32f25530"),
|
|
"protocol": cty.StringVal("tcp"),
|
|
"from_port": cty.NumberIntVal(0),
|
|
"to_port": cty.NumberIntVal(65535),
|
|
"self": cty.BoolVal(true),
|
|
"source_security_group_id": cty.StringVal("sg-0254c038e32f25530"),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
&aws.AwsSecurityGroupRule{
|
|
Id: "sgrule-1707973622",
|
|
Type: awssdk.String("egress"),
|
|
SecurityGroupId: awssdk.String("sg-0254c038e32f25530"),
|
|
Protocol: awssdk.String("-1"),
|
|
FromPort: awssdk.Int(0),
|
|
ToPort: awssdk.Int(0),
|
|
CidrBlocks: &[]string{"0.0.0.0/0"},
|
|
Ipv6CidrBlocks: &[]string{},
|
|
PrefixListIds: &[]string{},
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("sgrule-1707973622"),
|
|
"type": cty.StringVal("egress"),
|
|
"security_group_id": cty.StringVal("sg-0254c038e32f25530"),
|
|
"protocol": cty.StringVal("-1"),
|
|
"from_port": cty.NumberIntVal(0),
|
|
"to_port": cty.NumberIntVal(0),
|
|
"cidr_blocks": cty.SetVal([]cty.Value{
|
|
cty.StringVal("0.0.0.0/0"),
|
|
}),
|
|
"ipv6_cidr_blocks": cty.SetValEmpty(cty.String),
|
|
"prefix_list_ids": cty.SetValEmpty(cty.String),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
&aws.AwsSecurityGroupRule{
|
|
Id: "sgrule-2821752134",
|
|
Type: awssdk.String("egress"),
|
|
SecurityGroupId: awssdk.String("sg-0254c038e32f25530"),
|
|
Protocol: awssdk.String("-1"),
|
|
FromPort: awssdk.Int(0),
|
|
ToPort: awssdk.Int(0),
|
|
CidrBlocks: &[]string{},
|
|
Ipv6CidrBlocks: &[]string{"::/0"},
|
|
PrefixListIds: &[]string{},
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("sgrule-2821752134"),
|
|
"type": cty.StringVal("egress"),
|
|
"security_group_id": cty.StringVal("sg-0254c038e32f25530"),
|
|
"protocol": cty.StringVal("-1"),
|
|
"from_port": cty.NumberIntVal(0),
|
|
"to_port": cty.NumberIntVal(0),
|
|
"cidr_blocks": cty.SetValEmpty(cty.String),
|
|
"ipv6_cidr_blocks": cty.SetVal([]cty.Value{
|
|
cty.StringVal("::/0"),
|
|
}),
|
|
"prefix_list_ids": cty.SetValEmpty(cty.String),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
&aws.AwsSecurityGroupRule{
|
|
Id: "sgrule-2165103420",
|
|
Type: awssdk.String("ingress"),
|
|
SecurityGroupId: awssdk.String("sg-0254c038e32f25530"),
|
|
Protocol: awssdk.String("-1"),
|
|
FromPort: awssdk.Int(0),
|
|
ToPort: awssdk.Int(0),
|
|
CidrBlocks: &[]string{"5.6.7.0/24"},
|
|
Ipv6CidrBlocks: &[]string{},
|
|
PrefixListIds: &[]string{},
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("sgrule-2165103420"),
|
|
"type": cty.StringVal("ingress"),
|
|
"security_group_id": cty.StringVal("sg-0254c038e32f25530"),
|
|
"protocol": cty.StringVal("-1"),
|
|
"from_port": cty.NumberIntVal(0),
|
|
"to_port": cty.NumberIntVal(0),
|
|
"cidr_blocks": cty.SetVal([]cty.Value{
|
|
cty.StringVal("5.6.7.0/24"),
|
|
}),
|
|
"ipv6_cidr_blocks": cty.SetValEmpty(cty.String),
|
|
"prefix_list_ids": cty.SetValEmpty(cty.String),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
&aws.AwsSecurityGroupRule{
|
|
Id: "sgrule-2582518759",
|
|
Type: awssdk.String("ingress"),
|
|
SecurityGroupId: awssdk.String("sg-0254c038e32f25530"),
|
|
Protocol: awssdk.String("-1"),
|
|
FromPort: awssdk.Int(0),
|
|
ToPort: awssdk.Int(0),
|
|
CidrBlocks: &[]string{"1.2.0.0/16"},
|
|
Ipv6CidrBlocks: &[]string{},
|
|
PrefixListIds: &[]string{},
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("sgrule-2582518759"),
|
|
"type": cty.StringVal("ingress"),
|
|
"security_group_id": cty.StringVal("sg-0254c038e32f25530"),
|
|
"protocol": cty.StringVal("-1"),
|
|
"from_port": cty.NumberIntVal(0),
|
|
"to_port": cty.NumberIntVal(0),
|
|
"cidr_blocks": cty.SetVal([]cty.Value{
|
|
cty.StringVal("1.2.0.0/16"),
|
|
}),
|
|
"ipv6_cidr_blocks": cty.SetValEmpty(cty.String),
|
|
"prefix_list_ids": cty.SetValEmpty(cty.String),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
&aws.AwsSecurityGroupRule{
|
|
Id: "sgrule-2471889226",
|
|
Type: awssdk.String("ingress"),
|
|
SecurityGroupId: awssdk.String("sg-0254c038e32f25530"),
|
|
Protocol: awssdk.String("tcp"),
|
|
FromPort: awssdk.Int(0),
|
|
ToPort: awssdk.Int(0),
|
|
PrefixListIds: &[]string{"pl-abb451c2"},
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("sgrule-2471889226"),
|
|
"type": cty.StringVal("ingress"),
|
|
"security_group_id": cty.StringVal("sg-0254c038e32f25530"),
|
|
"protocol": cty.StringVal("tcp"),
|
|
"from_port": cty.NumberIntVal(0),
|
|
"to_port": cty.NumberIntVal(0),
|
|
"prefix_list_ids": cty.SetVal([]cty.Value{
|
|
cty.StringVal("pl-abb451c2"),
|
|
}),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
&aws.AwsSecurityGroupRule{
|
|
Id: "sgrule-3587309474",
|
|
Type: awssdk.String("ingress"),
|
|
SecurityGroupId: awssdk.String("sg-0254c038e32f25530"),
|
|
Protocol: awssdk.String("tcp"),
|
|
FromPort: awssdk.Int(0),
|
|
ToPort: awssdk.Int(65535),
|
|
SourceSecurityGroupId: awssdk.String("sg-9e0204ff"),
|
|
CtyVal: func() *cty.Value {
|
|
v := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("sgrule-3587309474"),
|
|
"type": cty.StringVal("ingress"),
|
|
"security_group_id": cty.StringVal("sg-0254c038e32f25530"),
|
|
"protocol": cty.StringVal("tcp"),
|
|
"from_port": cty.NumberIntVal(0),
|
|
"to_port": cty.NumberIntVal(65535),
|
|
"source_security_group_id": cty.StringVal("sg-9e0204ff"),
|
|
})
|
|
return &v
|
|
}(),
|
|
},
|
|
},
|
|
mocks: func(factory resource.ResourceFactory) {
|
|
rule1 := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("sgrule-1707973622"),
|
|
"type": cty.StringVal("egress"),
|
|
"security_group_id": cty.StringVal("sg-0254c038e32f25530"),
|
|
"protocol": cty.StringVal("-1"),
|
|
"from_port": cty.NumberIntVal(0),
|
|
"to_port": cty.NumberIntVal(0),
|
|
"cidr_blocks": cty.SetVal([]cty.Value{
|
|
cty.StringVal("0.0.0.0/0"),
|
|
}),
|
|
"ipv6_cidr_blocks": cty.SetValEmpty(cty.String),
|
|
"prefix_list_ids": cty.SetValEmpty(cty.String),
|
|
})
|
|
factory.(*terraform.MockResourceFactory).On("CreateResource", mock.MatchedBy(func(input map[string]interface{}) bool {
|
|
return matchByAttributes(input, map[string]interface{}{
|
|
"id": "sgrule-1707973622",
|
|
"type": awssdk.String("egress"),
|
|
"security_group_id": awssdk.String("sg-0254c038e32f25530"),
|
|
"protocol": awssdk.String("-1"),
|
|
"from_port": awssdk.Int(0),
|
|
"to_port": awssdk.Int(0),
|
|
"cidr_blocks": &[]string{"0.0.0.0/0"},
|
|
"ipv6_cidr_blocks": &[]string{},
|
|
"prefix_list_ids": &[]string{},
|
|
})
|
|
}), "aws_security_group_rule").Times(1).Return(&rule1, nil)
|
|
|
|
rule2 := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("sgrule-2821752134"),
|
|
"type": cty.StringVal("egress"),
|
|
"security_group_id": cty.StringVal("sg-0254c038e32f25530"),
|
|
"protocol": cty.StringVal("-1"),
|
|
"from_port": cty.NumberIntVal(0),
|
|
"to_port": cty.NumberIntVal(0),
|
|
"cidr_blocks": cty.SetValEmpty(cty.String),
|
|
"ipv6_cidr_blocks": cty.SetVal([]cty.Value{
|
|
cty.StringVal("::/0"),
|
|
}),
|
|
"prefix_list_ids": cty.SetValEmpty(cty.String),
|
|
})
|
|
factory.(*terraform.MockResourceFactory).On("CreateResource", mock.MatchedBy(func(input map[string]interface{}) bool {
|
|
return matchByAttributes(input, map[string]interface{}{
|
|
"id": "sgrule-2821752134",
|
|
"type": awssdk.String("egress"),
|
|
"security_group_id": awssdk.String("sg-0254c038e32f25530"),
|
|
"protocol": awssdk.String("-1"),
|
|
"from_port": awssdk.Int(0),
|
|
"to_port": awssdk.Int(0),
|
|
"cidr_blocks": &[]string{},
|
|
"ipv6_cidr_blocks": &[]string{"::/0"},
|
|
"prefix_list_ids": &[]string{},
|
|
})
|
|
}), "aws_security_group_rule").Times(1).Return(&rule2, nil)
|
|
|
|
rule3 := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("sgrule-2165103420"),
|
|
"type": cty.StringVal("ingress"),
|
|
"security_group_id": cty.StringVal("sg-0254c038e32f25530"),
|
|
"protocol": cty.StringVal("-1"),
|
|
"from_port": cty.NumberIntVal(0),
|
|
"to_port": cty.NumberIntVal(0),
|
|
"cidr_blocks": cty.SetVal([]cty.Value{
|
|
cty.StringVal("5.6.7.0/24"),
|
|
}),
|
|
"ipv6_cidr_blocks": cty.SetValEmpty(cty.String),
|
|
"prefix_list_ids": cty.SetValEmpty(cty.String),
|
|
})
|
|
factory.(*terraform.MockResourceFactory).On("CreateResource", mock.MatchedBy(func(input map[string]interface{}) bool {
|
|
return matchByAttributes(input, map[string]interface{}{
|
|
"id": "sgrule-2165103420",
|
|
"type": awssdk.String("ingress"),
|
|
"security_group_id": awssdk.String("sg-0254c038e32f25530"),
|
|
"protocol": awssdk.String("-1"),
|
|
"from_port": awssdk.Int(0),
|
|
"to_port": awssdk.Int(0),
|
|
"cidr_blocks": &[]string{"5.6.7.0/24"},
|
|
"ipv6_cidr_blocks": &[]string{},
|
|
"prefix_list_ids": &[]string{},
|
|
})
|
|
}), "aws_security_group_rule").Times(1).Return(&rule3, nil)
|
|
|
|
rule4 := cty.ObjectVal(map[string]cty.Value{
|
|
"id": cty.StringVal("sgrule-2582518759"),
|
|
"type": cty.StringVal("ingress"),
|
|
"security_group_id": cty.StringVal("sg-0254c038e32f25530"),
|
|
"protocol": cty.StringVal("-1"),
|
|
"from_port": cty.NumberIntVal(0),
|
|
"to_port": cty.NumberIntVal(0),
|
|
"cidr_blocks": cty.SetVal([]cty.Value{
|
|
cty.StringVal("1.2.0.0/16"),
|
|
}),
|
|
"ipv6_cidr_blocks": cty.SetValEmpty(cty.String),
|
|
"prefix_list_ids": cty.SetValEmpty(cty.String),
|
|
})
|
|
factory.(*terraform.MockResourceFactory).On("CreateResource", mock.MatchedBy(func(input map[string]interface{}) bool {
|
|
return matchByAttributes(input, map[string]interface{}{
|
|
"id": "sgrule-2582518759",
|
|
"type": awssdk.String("ingress"),
|
|
"security_group_id": awssdk.String("sg-0254c038e32f25530"),
|
|
"protocol": awssdk.String("-1"),
|
|
"from_port": awssdk.Int(0),
|
|
"to_port": awssdk.Int(0),
|
|
"cidr_blocks": &[]string{"1.2.0.0/16"},
|
|
"ipv6_cidr_blocks": &[]string{},
|
|
"prefix_list_ids": &[]string{},
|
|
})
|
|
}), "aws_security_group_rule").Times(1).Return(&rule4, nil)
|
|
},
|
|
assert: func(result *test.ScanResult, err error) {
|
|
result.AssertManagedCount(7)
|
|
result.AssertInfrastructureIsInSync()
|
|
},
|
|
options: func(t *testing.T) *pkg.ScanOptions {
|
|
filterStr := "Type=='aws_security_group_rule' && Attr.security_group_id=='sg-0254c038e32f25530'"
|
|
f, err := filter.BuildExpression(filterStr)
|
|
if err != nil {
|
|
t.Fatalf("Unable to build filter expression: %s\n%s", filterStr, err)
|
|
}
|
|
|
|
return &pkg.ScanOptions{Filter: f}
|
|
}(t),
|
|
},
|
|
}
|
|
|
|
runTest(t, cases)
|
|
}
|