Merge branch 'main' into allow_prefix_usage_in_iac_source_for_s3

main
Elie 2021-02-25 10:05:59 +01:00 committed by GitHub
commit 1c7778477c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 37544 additions and 491 deletions

View File

@ -27,7 +27,8 @@ jobs:
- checkout
- go/install:
version: "1.16"
cache-key: "1.16"
# Disable cache at it seem to broke go 1.16 installation
cache: false
- run:
name: install dependencies
command: |

1
.gitignore vendored
View File

@ -16,6 +16,7 @@
/unit-tests.xml
/unit-tests-acc.xml
/cover.out
/cover.out.tmp
/cover-acc.out
### coverage folder inside pkg ###

View File

@ -28,7 +28,8 @@ release:
.PHONY: test
test: deps
$(GOTEST) --format testname --junitfile unit-tests.xml -- -coverprofile=cover.out -coverpkg=.,./pkg/... ./...
$(GOTEST) --format testname --junitfile unit-tests.xml -- -coverprofile=cover.out.tmp -coverpkg=.,./pkg/... ./...
cat cover.out.tmp | grep -v "mock_" > cover.out
.PHONY: coverage
coverage: test

View File

@ -1,6 +1,7 @@
package aws
import (
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
@ -10,8 +11,6 @@ import (
"github.com/cloudskiff/driftctl/pkg/terraform"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/sirupsen/logrus"
"github.com/zclconf/go-cty/cty"
)
@ -19,7 +18,7 @@ import (
type EC2AmiSupplier struct {
reader terraform.ResourceReader
deserializer deserializer.CTYDeserializer
client ec2iface.EC2API
client repository.EC2Repository
runner *terraform.ParallelResourceReader
}
@ -27,24 +26,19 @@ func NewEC2AmiSupplier(provider *AWSTerraformProvider) *EC2AmiSupplier {
return &EC2AmiSupplier{
provider,
awsdeserializer.NewEC2AmiDeserializer(),
ec2.New(provider.session),
repository.NewEC2Repository(provider.session),
terraform.NewParallelResourceReader(provider.Runner().SubRunner()),
}
}
func (s EC2AmiSupplier) Resources() ([]resource.Resource, error) {
input := &ec2.DescribeImagesInput{
Owners: []*string{
aws.String("self"),
},
}
response, err := s.client.DescribeImages(input)
images, err := s.client.ListAllImages()
if err != nil {
return nil, remoteerror.NewResourceEnumerationError(err, resourceaws.AwsAmiResourceType)
}
results := make([]cty.Value, 0)
if len(response.Images) > 0 {
for _, image := range response.Images {
if len(images) > 0 {
for _, image := range images {
id := aws.StringValue(image.ImageId)
s.runner.Run(func() (cty.Value, error) {
return s.readAMI(id)

View File

@ -4,6 +4,11 @@ import (
"context"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
@ -23,29 +28,37 @@ import (
func TestEC2AmiSupplier_Resources(t *testing.T) {
tests := []struct {
test string
dirName string
amiIDs []string
listError error
err error
test string
dirName string
mock func(mock *repository.MockEC2Repository)
err error
}{
{
test: "no amis",
dirName: "ec2_ami_empty",
amiIDs: []string{},
err: nil,
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllImages").Return([]*ec2.Image{}, nil)
},
err: nil,
},
{
test: "with amis",
dirName: "ec2_ami_multiple",
amiIDs: []string{"ami-03a578b46f4c3081b", "ami-025962fd8b456731f"},
err: nil,
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllImages").Return([]*ec2.Image{
{ImageId: aws.String("ami-03a578b46f4c3081b")},
{ImageId: aws.String("ami-025962fd8b456731f")},
}, nil)
},
err: nil,
},
{
test: "cannot list amis",
dirName: "ec2_ami_empty",
listError: awserr.NewRequestFailure(nil, 403, ""),
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsAmiResourceType),
test: "cannot list amis",
dirName: "ec2_ami_empty",
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllImages").Return([]*ec2.Image{}, awserr.NewRequestFailure(nil, 403, ""))
},
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsAmiResourceType),
},
}
for _, tt := range tests {
@ -65,10 +78,8 @@ func TestEC2AmiSupplier_Resources(t *testing.T) {
t.Run(tt.test, func(t *testing.T) {
provider := mocks.NewMockedGoldenTFProvider(tt.dirName, providerLibrary.Provider(terraform.AWS), shouldUpdate)
deserializer := awsdeserializer.NewEC2AmiDeserializer()
client := mocks.NewMockAWSEC2AmiClient(tt.amiIDs)
if tt.listError != nil {
client = mocks.NewMockAWSEC2ErrorClient(tt.listError)
}
client := &repository.MockEC2Repository{}
tt.mock(client)
s := &EC2AmiSupplier{
provider,
deserializer,

View File

@ -1,6 +1,7 @@
package aws
import (
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
@ -11,7 +12,6 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/sirupsen/logrus"
"github.com/zclconf/go-cty/cty"
)
@ -19,7 +19,7 @@ import (
type EC2EbsSnapshotSupplier struct {
reader terraform.ResourceReader
deserializer deserializer.CTYDeserializer
client ec2iface.EC2API
client repository.EC2Repository
runner *terraform.ParallelResourceReader
}
@ -27,13 +27,13 @@ func NewEC2EbsSnapshotSupplier(provider *AWSTerraformProvider) *EC2EbsSnapshotSu
return &EC2EbsSnapshotSupplier{
provider,
awsdeserializer.NewEC2EbsSnapshotDeserializer(),
ec2.New(provider.session),
repository.NewEC2Repository(provider.session),
terraform.NewParallelResourceReader(provider.Runner().SubRunner()),
}
}
func (s EC2EbsSnapshotSupplier) Resources() ([]resource.Resource, error) {
snapshots, err := listSnapshots(s.client)
snapshots, err := s.client.ListAllSnapshots()
if err != nil {
return nil, remoteerror.NewResourceEnumerationError(err, resourceaws.AwsEbsSnapshotResourceType)
}
@ -65,20 +65,3 @@ func (s EC2EbsSnapshotSupplier) readEbsSnapshot(snapshot ec2.Snapshot) (cty.Valu
}
return *resSnapshot, nil
}
func listSnapshots(client ec2iface.EC2API) ([]*ec2.Snapshot, error) {
var snapshots []*ec2.Snapshot
input := &ec2.DescribeSnapshotsInput{
OwnerIds: []*string{
aws.String("self"),
},
}
err := client.DescribeSnapshotsPages(input, func(res *ec2.DescribeSnapshotsOutput, lastPage bool) bool {
snapshots = append(snapshots, res.Snapshots...)
return !lastPage
})
if err != nil {
return nil, err
}
return snapshots, err
}

View File

@ -4,6 +4,8 @@ import (
"context"
"testing"
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
@ -27,55 +29,41 @@ import (
func TestEC2EbsSnapshotSupplier_Resources(t *testing.T) {
tests := []struct {
test string
dirName string
snapshotsPages mocks.DescribeSnapshotsPagesOutput
snapshotsPagesError error
err error
test string
dirName string
mock func(mock *repository.MockEC2Repository)
err error
}{
{
test: "no snapshots",
dirName: "ec2_ebs_snapshot_empty",
snapshotsPages: mocks.DescribeSnapshotsPagesOutput{
{
true,
&ec2.DescribeSnapshotsOutput{},
},
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllSnapshots").Return([]*ec2.Snapshot{}, nil)
},
err: nil,
},
{
test: "with snapshots",
dirName: "ec2_ebs_snapshot_multiple",
snapshotsPages: mocks.DescribeSnapshotsPagesOutput{
{
false,
&ec2.DescribeSnapshotsOutput{
Snapshots: []*ec2.Snapshot{
{
SnapshotId: aws.String("snap-0c509a2a880d95a39"),
},
},
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllSnapshots").Return([]*ec2.Snapshot{
{
SnapshotId: aws.String("snap-0c509a2a880d95a39"),
},
},
{
true,
&ec2.DescribeSnapshotsOutput{
Snapshots: []*ec2.Snapshot{
{
SnapshotId: aws.String("snap-00672558cecd93a61"),
},
},
{
SnapshotId: aws.String("snap-00672558cecd93a61"),
},
},
}, nil)
},
err: nil,
},
{
test: "cannot list snapshots",
dirName: "ec2_ebs_snapshot_empty",
snapshotsPagesError: awserr.NewRequestFailure(nil, 403, ""),
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsEbsSnapshotResourceType),
test: "cannot list snapshots",
dirName: "ec2_ebs_snapshot_empty",
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllSnapshots").Return([]*ec2.Snapshot{}, awserr.NewRequestFailure(nil, 403, ""))
},
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsEbsSnapshotResourceType),
},
}
for _, tt := range tests {
@ -96,10 +84,8 @@ func TestEC2EbsSnapshotSupplier_Resources(t *testing.T) {
t.Run(tt.test, func(t *testing.T) {
provider := mocks.NewMockedGoldenTFProvider(tt.dirName, providerLibrary.Provider(terraform.AWS), shouldUpdate)
deserializer := awsdeserializer.NewEC2EbsSnapshotDeserializer()
client := mocks.NewMockAWSEC2EbsSnapshotClient(tt.snapshotsPages)
if tt.snapshotsPagesError != nil {
client = mocks.NewMockAWSEC2ErrorClient(tt.snapshotsPagesError)
}
client := &repository.MockEC2Repository{}
tt.mock(client)
s := &EC2EbsSnapshotSupplier{
provider,
deserializer,

View File

@ -1,6 +1,7 @@
package aws
import (
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
@ -11,7 +12,6 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/sirupsen/logrus"
"github.com/zclconf/go-cty/cty"
)
@ -19,7 +19,7 @@ import (
type EC2EbsVolumeSupplier struct {
reader terraform.ResourceReader
deserializer deserializer.CTYDeserializer
client ec2iface.EC2API
client repository.EC2Repository
runner *terraform.ParallelResourceReader
}
@ -27,13 +27,13 @@ func NewEC2EbsVolumeSupplier(provider *AWSTerraformProvider) *EC2EbsVolumeSuppli
return &EC2EbsVolumeSupplier{
provider,
awsdeserializer.NewEC2EbsVolumeDeserializer(),
ec2.New(provider.session),
repository.NewEC2Repository(provider.session),
terraform.NewParallelResourceReader(provider.Runner().SubRunner()),
}
}
func (s EC2EbsVolumeSupplier) Resources() ([]resource.Resource, error) {
volumes, err := listVolumes(s.client)
volumes, err := s.client.ListAllVolumes()
if err != nil {
return nil, remoteerror.NewResourceEnumerationError(err, resourceaws.AwsEbsVolumeResourceType)
}
@ -65,16 +65,3 @@ func (s EC2EbsVolumeSupplier) readEbsVolume(volume ec2.Volume) (cty.Value, error
}
return *resVolume, nil
}
func listVolumes(client ec2iface.EC2API) ([]*ec2.Volume, error) {
var volumes []*ec2.Volume
input := &ec2.DescribeVolumesInput{}
err := client.DescribeVolumesPages(input, func(res *ec2.DescribeVolumesOutput, lastPage bool) bool {
volumes = append(volumes, res.Volumes...)
return !lastPage
})
if err != nil {
return nil, err
}
return volumes, nil
}

View File

@ -4,6 +4,8 @@ import (
"context"
"testing"
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
@ -27,55 +29,41 @@ import (
func TestEC2EbsVolumeSupplier_Resources(t *testing.T) {
tests := []struct {
test string
dirName string
volumesPages mocks.DescribeVolumesPagesOutput
volumesPagesError error
err error
test string
dirName string
mock func(mock *repository.MockEC2Repository)
err error
}{
{
test: "no volumes",
dirName: "ec2_ebs_volume_empty",
volumesPages: mocks.DescribeVolumesPagesOutput{
{
true,
&ec2.DescribeVolumesOutput{},
},
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllVolumes").Return([]*ec2.Volume{}, nil)
},
err: nil,
},
{
test: "with volumes",
dirName: "ec2_ebs_volume_multiple",
volumesPages: mocks.DescribeVolumesPagesOutput{
{
false,
&ec2.DescribeVolumesOutput{
Volumes: []*ec2.Volume{
{
VolumeId: aws.String("vol-081c7272a57a09db1"),
},
},
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllVolumes").Return([]*ec2.Volume{
{
VolumeId: aws.String("vol-081c7272a57a09db1"),
},
},
{
true,
&ec2.DescribeVolumesOutput{
Volumes: []*ec2.Volume{
{
VolumeId: aws.String("vol-01ddc91d3d9d1318b"),
},
},
{
VolumeId: aws.String("vol-01ddc91d3d9d1318b"),
},
},
}, nil)
},
err: nil,
},
{
test: "cannot list volumes",
dirName: "ec2_ebs_volume_empty",
volumesPagesError: awserr.NewRequestFailure(nil, 403, ""),
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsEbsVolumeResourceType),
test: "cannot list volumes",
dirName: "ec2_ebs_volume_empty",
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllVolumes").Return([]*ec2.Volume{}, awserr.NewRequestFailure(nil, 403, ""))
},
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsEbsVolumeResourceType),
},
}
for _, tt := range tests {
@ -96,10 +84,8 @@ func TestEC2EbsVolumeSupplier_Resources(t *testing.T) {
t.Run(tt.test, func(t *testing.T) {
provider := mocks.NewMockedGoldenTFProvider(tt.dirName, providerLibrary.Provider(terraform.AWS), shouldUpdate)
deserializer := awsdeserializer.NewEC2EbsVolumeDeserializer()
client := mocks.NewMockAWSEC2EbsVolumeClient(tt.volumesPages)
if tt.volumesPagesError != nil {
client = mocks.NewMockAWSEC2ErrorClient(tt.volumesPagesError)
}
client := &repository.MockEC2Repository{}
tt.mock(client)
s := &EC2EbsVolumeSupplier{
provider,
deserializer,

View File

@ -1,17 +1,15 @@
package aws
import (
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
"github.com/cloudskiff/driftctl/pkg/resource"
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
awsdeserializer "github.com/cloudskiff/driftctl/pkg/resource/aws/deserializer"
"github.com/cloudskiff/driftctl/pkg/terraform"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/sirupsen/logrus"
"github.com/zclconf/go-cty/cty"
)
@ -19,7 +17,7 @@ import (
type EC2EipAssociationSupplier struct {
reader terraform.ResourceReader
deserializer deserializer.CTYDeserializer
client ec2iface.EC2API
client repository.EC2Repository
runner *terraform.ParallelResourceReader
}
@ -27,12 +25,12 @@ func NewEC2EipAssociationSupplier(provider *AWSTerraformProvider) *EC2EipAssocia
return &EC2EipAssociationSupplier{
provider,
awsdeserializer.NewEC2EipAssociationDeserializer(),
ec2.New(provider.session),
repository.NewEC2Repository(provider.session),
terraform.NewParallelResourceReader(provider.Runner().SubRunner())}
}
func (s EC2EipAssociationSupplier) Resources() ([]resource.Resource, error) {
associationIds, err := listAddressesAssociationIds(s.client)
associationIds, err := s.client.ListAllAddressesAssociation()
if err != nil {
return nil, remoteerror.NewResourceEnumerationError(err, resourceaws.AwsEipAssociationResourceType)
}
@ -63,17 +61,3 @@ func (s EC2EipAssociationSupplier) readEIPAssociation(assocId string) (cty.Value
}
return *resAssoc, nil
}
func listAddressesAssociationIds(client ec2iface.EC2API) ([]string, error) {
results := make([]string, 0)
addresses, err := listAddresses(client)
if err != nil {
return nil, err
}
for _, address := range addresses {
if address.AssociationId != nil {
results = append(results, aws.StringValue(address.AssociationId))
}
}
return results, nil
}

View File

@ -4,6 +4,8 @@ import (
"context"
"testing"
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
@ -21,40 +23,40 @@ import (
"github.com/cloudskiff/driftctl/pkg/terraform"
"github.com/cloudskiff/driftctl/test"
"github.com/cloudskiff/driftctl/test/mocks"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
)
func TestEC2EipAssociationSupplier_Resources(t *testing.T) {
tests := []struct {
test string
dirName string
addresses []*ec2.Address
listError error
err error
test string
dirName string
mock func(mock *repository.MockEC2Repository)
err error
}{
{
test: "no eip associations",
dirName: "ec2_eip_association_empty",
addresses: []*ec2.Address{},
err: nil,
},
{
test: "with eip associations",
dirName: "ec2_eip_association_single",
addresses: []*ec2.Address{
{
AssociationId: aws.String("eipassoc-0e9a7356e30f0c3d1"),
},
test: "no eip associations",
dirName: "ec2_eip_association_empty",
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllAddressesAssociation").Return([]string{}, nil)
},
err: nil,
},
{
test: "Cannot list eip associations",
dirName: "ec2_eip_association_empty",
listError: awserr.NewRequestFailure(nil, 403, ""),
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsEipAssociationResourceType),
test: "with eip associations",
dirName: "ec2_eip_association_single",
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllAddressesAssociation").Return([]string{
"eipassoc-0e9a7356e30f0c3d1",
}, nil)
},
err: nil,
},
{
test: "Cannot list eip associations",
dirName: "ec2_eip_association_empty",
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllAddressesAssociation").Return([]string{}, awserr.NewRequestFailure(nil, 403, ""))
},
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsEipAssociationResourceType),
},
}
for _, tt := range tests {
@ -74,10 +76,8 @@ func TestEC2EipAssociationSupplier_Resources(t *testing.T) {
t.Run(tt.test, func(t *testing.T) {
provider := mocks.NewMockedGoldenTFProvider(tt.dirName, providerLibrary.Provider(terraform.AWS), shouldUpdate)
deserializer := awsdeserializer.NewEC2EipAssociationDeserializer()
client := mocks.NewMockAWSEC2EipClient(tt.addresses)
if tt.listError != nil {
client = mocks.NewMockAWSEC2ErrorClient(tt.listError)
}
client := &repository.MockEC2Repository{}
tt.mock(client)
s := &EC2EipAssociationSupplier{
provider,
deserializer,

View File

@ -1,6 +1,7 @@
package aws
import (
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
@ -11,7 +12,6 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/sirupsen/logrus"
"github.com/zclconf/go-cty/cty"
)
@ -19,7 +19,7 @@ import (
type EC2EipSupplier struct {
reader terraform.ResourceReader
deserializer deserializer.CTYDeserializer
client ec2iface.EC2API
client repository.EC2Repository
runner *terraform.ParallelResourceReader
}
@ -27,13 +27,13 @@ func NewEC2EipSupplier(provider *AWSTerraformProvider) *EC2EipSupplier {
return &EC2EipSupplier{
provider,
awsdeserializer.NewEC2EipDeserializer(),
ec2.New(provider.session),
repository.NewEC2Repository(provider.session),
terraform.NewParallelResourceReader(provider.Runner().SubRunner()),
}
}
func (s EC2EipSupplier) Resources() ([]resource.Resource, error) {
addresses, err := listAddresses(s.client)
addresses, err := s.client.ListAllAddresses()
if err != nil {
return nil, remoteerror.NewResourceEnumerationError(err, resourceaws.AwsEipResourceType)
}
@ -65,12 +65,3 @@ func (s EC2EipSupplier) readEIP(address ec2.Address) (cty.Value, error) {
}
return *resAddress, nil
}
func listAddresses(client ec2iface.EC2API) ([]*ec2.Address, error) {
input := &ec2.DescribeAddressesInput{}
response, err := client.DescribeAddresses(input)
if err != nil {
return nil, err
}
return response.Addresses, nil
}

View File

@ -4,6 +4,8 @@ import (
"context"
"testing"
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
@ -28,36 +30,41 @@ import (
func TestEC2EipSupplier_Resources(t *testing.T) {
tests := []struct {
test string
dirName string
addresses []*ec2.Address
listError error
err error
test string
dirName string
mock func(mock *repository.MockEC2Repository)
err error
}{
{
test: "no eips",
dirName: "ec2_eip_empty",
addresses: []*ec2.Address{},
err: nil,
},
{
test: "with eips",
dirName: "ec2_eip_multiple",
addresses: []*ec2.Address{
{
AllocationId: aws.String("eipalloc-017d5267e4dda73f1"),
},
{
AllocationId: aws.String("eipalloc-0cf714dc097c992cc"),
},
test: "no eips",
dirName: "ec2_eip_empty",
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllAddresses").Return([]*ec2.Address{}, nil)
},
err: nil,
},
{
test: "Cannot list eips",
dirName: "ec2_eip_empty",
listError: awserr.NewRequestFailure(nil, 403, ""),
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsEipResourceType),
test: "with eips",
dirName: "ec2_eip_multiple",
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllAddresses").Return([]*ec2.Address{
{
AllocationId: aws.String("eipalloc-017d5267e4dda73f1"),
},
{
AllocationId: aws.String("eipalloc-0cf714dc097c992cc"),
},
}, nil)
},
err: nil,
},
{
test: "Cannot list eips",
dirName: "ec2_eip_empty",
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllAddresses").Return([]*ec2.Address{}, awserr.NewRequestFailure(nil, 403, ""))
},
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsEipResourceType),
},
}
for _, tt := range tests {
@ -77,10 +84,8 @@ func TestEC2EipSupplier_Resources(t *testing.T) {
t.Run(tt.test, func(t *testing.T) {
provider := mocks.NewMockedGoldenTFProvider(tt.dirName, providerLibrary.Provider(terraform.AWS), shouldUpdate)
deserializer := awsdeserializer.NewEC2EipDeserializer()
client := mocks.NewMockAWSEC2EipClient(tt.addresses)
if tt.listError != nil {
client = mocks.NewMockAWSEC2ErrorClient(tt.listError)
}
client := &repository.MockEC2Repository{}
tt.mock(client)
s := &EC2EipSupplier{
provider,
deserializer,

View File

@ -1,6 +1,7 @@
package aws
import (
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
@ -10,8 +11,6 @@ import (
"github.com/cloudskiff/driftctl/pkg/terraform"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/sirupsen/logrus"
"github.com/zclconf/go-cty/cty"
)
@ -19,7 +18,7 @@ import (
type EC2InstanceSupplier struct {
reader terraform.ResourceReader
deserializer deserializer.CTYDeserializer
client ec2iface.EC2API
client repository.EC2Repository
runner *terraform.ParallelResourceReader
}
@ -27,13 +26,13 @@ func NewEC2InstanceSupplier(provider *AWSTerraformProvider) *EC2InstanceSupplier
return &EC2InstanceSupplier{
provider,
awsdeserializer.NewEC2InstanceDeserializer(),
ec2.New(provider.session),
repository.NewEC2Repository(provider.session),
terraform.NewParallelResourceReader(provider.Runner().SubRunner()),
}
}
func (s EC2InstanceSupplier) Resources() ([]resource.Resource, error) {
instances, err := listInstances(s.client)
instances, err := s.client.ListAllInstances()
if err != nil {
return nil, remoteerror.NewResourceEnumerationError(err, resourceaws.AwsInstanceResourceType)
}
@ -70,18 +69,3 @@ func (s EC2InstanceSupplier) readInstance(id string) (cty.Value, error) {
}
return *resInstance, nil
}
func listInstances(client ec2iface.EC2API) ([]*ec2.Instance, error) {
var instances []*ec2.Instance
input := &ec2.DescribeInstancesInput{}
err := client.DescribeInstancesPages(input, func(res *ec2.DescribeInstancesOutput, lastPage bool) bool {
for _, reservation := range res.Reservations {
instances = append(instances, reservation.Instances...)
}
return !lastPage
})
if err != nil {
return nil, err
}
return instances, nil
}

View File

@ -4,6 +4,8 @@ import (
"context"
"testing"
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
@ -28,87 +30,56 @@ import (
func TestEC2InstanceSupplier_Resources(t *testing.T) {
tests := []struct {
test string
dirName string
instancesPages mocks.DescribeInstancesPagesOutput
listError error
err error
test string
dirName string
mock func(mock *repository.MockEC2Repository)
err error
}{
{
test: "no instances",
dirName: "ec2_instance_empty",
instancesPages: mocks.DescribeInstancesPagesOutput{
{
true,
&ec2.DescribeInstancesOutput{},
},
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllInstances").Return([]*ec2.Instance{}, nil)
},
err: nil,
},
{
test: "with instances",
dirName: "ec2_instance_multiple",
instancesPages: mocks.DescribeInstancesPagesOutput{
{
false,
&ec2.DescribeInstancesOutput{
Reservations: []*ec2.Reservation{
{
Instances: []*ec2.Instance{
{
InstanceId: aws.String("i-0d3650a23f4e45dc0"),
},
},
},
},
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllInstances").Return([]*ec2.Instance{
{
InstanceId: aws.String("i-0d3650a23f4e45dc0"),
},
},
{
true,
&ec2.DescribeInstancesOutput{
Reservations: []*ec2.Reservation{
{
Instances: []*ec2.Instance{
{
InstanceId: aws.String("i-010376047a71419f1"),
},
},
},
},
{
InstanceId: aws.String("i-010376047a71419f1"),
},
},
}, nil)
},
err: nil,
},
{
test: "with terminated instances",
dirName: "ec2_instance_terminated",
instancesPages: mocks.DescribeInstancesPagesOutput{
{
true,
&ec2.DescribeInstancesOutput{
Reservations: []*ec2.Reservation{
{
Instances: []*ec2.Instance{
{
InstanceId: aws.String("i-0e1543baf4f2cd990"),
},
{
InstanceId: aws.String("i-0a3a7ed51ae2b4fa0"), // Nil
},
},
},
},
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllInstances").Return([]*ec2.Instance{
{
InstanceId: aws.String("i-0e1543baf4f2cd990"),
},
},
{
InstanceId: aws.String("i-0a3a7ed51ae2b4fa0"), // Nil
},
}, nil)
},
err: nil,
},
{
test: "Cannot list instances",
dirName: "ec2_instance_empty",
listError: awserr.NewRequestFailure(nil, 403, ""),
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsInstanceResourceType),
test: "Cannot list instances",
dirName: "ec2_instance_empty",
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllInstances").Return([]*ec2.Instance{}, awserr.NewRequestFailure(nil, 403, ""))
},
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsInstanceResourceType),
},
}
for _, tt := range tests {
@ -128,10 +99,8 @@ func TestEC2InstanceSupplier_Resources(t *testing.T) {
t.Run(tt.test, func(t *testing.T) {
provider := mocks.NewMockedGoldenTFProvider(tt.dirName, providerLibrary.Provider(terraform.AWS), shouldUpdate)
deserializer := awsdeserializer.NewEC2InstanceDeserializer()
client := mocks.NewMockAWSEC2InstanceClient(tt.instancesPages)
if tt.listError != nil {
client = mocks.NewMockAWSEC2ErrorClient(tt.listError)
}
client := &repository.MockEC2Repository{}
tt.mock(client)
s := &EC2InstanceSupplier{
provider,
deserializer,

View File

@ -1,6 +1,7 @@
package aws
import (
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
@ -10,8 +11,6 @@ import (
"github.com/cloudskiff/driftctl/pkg/terraform"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/sirupsen/logrus"
"github.com/zclconf/go-cty/cty"
)
@ -19,7 +18,7 @@ import (
type EC2KeyPairSupplier struct {
reader terraform.ResourceReader
deserializer deserializer.CTYDeserializer
client ec2iface.EC2API
client repository.EC2Repository
runner *terraform.ParallelResourceReader
}
@ -27,20 +26,19 @@ func NewEC2KeyPairSupplier(provider *AWSTerraformProvider) *EC2KeyPairSupplier {
return &EC2KeyPairSupplier{
provider,
awsdeserializer.NewEC2KeyPairDeserializer(),
ec2.New(provider.session),
repository.NewEC2Repository(provider.session),
terraform.NewParallelResourceReader(provider.Runner().SubRunner()),
}
}
func (s EC2KeyPairSupplier) Resources() ([]resource.Resource, error) {
input := &ec2.DescribeKeyPairsInput{}
response, err := s.client.DescribeKeyPairs(input)
keyPairs, err := s.client.ListAllKeyPairs()
if err != nil {
return nil, remoteerror.NewResourceEnumerationError(err, resourceaws.AwsKeyPairResourceType)
}
results := make([]cty.Value, 0)
if len(response.KeyPairs) > 0 {
for _, kp := range response.KeyPairs {
if len(keyPairs) > 0 {
for _, kp := range keyPairs {
name := aws.StringValue(kp.KeyName)
s.runner.Run(func() (cty.Value, error) {
return s.readKeyPair(name)

View File

@ -4,6 +4,9 @@ import (
"context"
"testing"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/aws/aws-sdk-go/aws/awserr"
@ -28,30 +31,41 @@ import (
func TestEC2KeyPairSupplier_Resources(t *testing.T) {
tests := []struct {
test string
dirName string
kpNames []string
listError error
err error
test string
dirName string
mock func(mock *repository.MockEC2Repository)
err error
}{
{
test: "no key pairs",
dirName: "ec2_key_pair_empty",
kpNames: []string{},
err: nil,
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllKeyPairs").Return([]*ec2.KeyPairInfo{}, nil)
},
err: nil,
},
{
test: "with key pairs",
dirName: "ec2_key_pair_multiple",
kpNames: []string{"test", "bar"},
err: nil,
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllKeyPairs").Return([]*ec2.KeyPairInfo{
{
KeyName: aws.String("test"),
},
{
KeyName: aws.String("bar"),
},
}, nil)
},
err: nil,
},
{
test: "cannot list key pairs",
dirName: "ec2_key_pair_empty",
kpNames: []string{},
listError: awserr.NewRequestFailure(nil, 403, ""),
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsKeyPairResourceType),
test: "cannot list key pairs",
dirName: "ec2_key_pair_empty",
mock: func(mock *repository.MockEC2Repository) {
mock.On("ListAllKeyPairs").Return([]*ec2.KeyPairInfo{}, awserr.NewRequestFailure(nil, 403, ""))
},
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsKeyPairResourceType),
},
}
for _, tt := range tests {
@ -71,10 +85,8 @@ func TestEC2KeyPairSupplier_Resources(t *testing.T) {
t.Run(tt.test, func(t *testing.T) {
provider := mocks.NewMockedGoldenTFProvider(tt.dirName, providerLibrary.Provider(terraform.AWS), shouldUpdate)
deserializer := awsdeserializer.NewEC2KeyPairDeserializer()
client := mocks.NewMockAWSEC2KeyPairClient(tt.kpNames)
if tt.listError != nil {
client = mocks.NewMockAWSEC2ErrorClient(tt.listError)
}
client := &repository.MockEC2Repository{}
tt.mock(client)
s := &EC2KeyPairSupplier{
provider,
deserializer,

View File

@ -0,0 +1,122 @@
package repository
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
)
type EC2Repository interface {
ListAllImages() ([]*ec2.Image, error)
ListAllSnapshots() ([]*ec2.Snapshot, error)
ListAllVolumes() ([]*ec2.Volume, error)
ListAllAddresses() ([]*ec2.Address, error)
ListAllAddressesAssociation() ([]string, error)
ListAllInstances() ([]*ec2.Instance, error)
ListAllKeyPairs() ([]*ec2.KeyPairInfo, error)
}
type EC2Client interface {
ec2iface.EC2API
}
type ec2Repository struct {
client ec2iface.EC2API
}
func NewEC2Repository(session *session.Session) *ec2Repository {
return &ec2Repository{
ec2.New(session),
}
}
func (r *ec2Repository) ListAllImages() ([]*ec2.Image, error) {
input := &ec2.DescribeImagesInput{
Owners: []*string{
aws.String("self"),
},
}
images, err := r.client.DescribeImages(input)
if err != nil {
return nil, err
}
return images.Images, err
}
func (r *ec2Repository) ListAllSnapshots() ([]*ec2.Snapshot, error) {
var snapshots []*ec2.Snapshot
input := &ec2.DescribeSnapshotsInput{
OwnerIds: []*string{
aws.String("self"),
},
}
err := r.client.DescribeSnapshotsPages(input, func(res *ec2.DescribeSnapshotsOutput, lastPage bool) bool {
snapshots = append(snapshots, res.Snapshots...)
return !lastPage
})
if err != nil {
return nil, err
}
return snapshots, err
}
func (r *ec2Repository) ListAllVolumes() ([]*ec2.Volume, error) {
var volumes []*ec2.Volume
input := &ec2.DescribeVolumesInput{}
err := r.client.DescribeVolumesPages(input, func(res *ec2.DescribeVolumesOutput, lastPage bool) bool {
volumes = append(volumes, res.Volumes...)
return !lastPage
})
if err != nil {
return nil, err
}
return volumes, nil
}
func (r *ec2Repository) ListAllAddresses() ([]*ec2.Address, error) {
input := &ec2.DescribeAddressesInput{}
response, err := r.client.DescribeAddresses(input)
if err != nil {
return nil, err
}
return response.Addresses, nil
}
func (r *ec2Repository) ListAllAddressesAssociation() ([]string, error) {
results := make([]string, 0)
addresses, err := r.ListAllAddresses()
if err != nil {
return nil, err
}
for _, address := range addresses {
if address.AssociationId != nil {
results = append(results, aws.StringValue(address.AssociationId))
}
}
return results, nil
}
func (r *ec2Repository) ListAllInstances() ([]*ec2.Instance, error) {
var instances []*ec2.Instance
input := &ec2.DescribeInstancesInput{}
err := r.client.DescribeInstancesPages(input, func(res *ec2.DescribeInstancesOutput, lastPage bool) bool {
for _, reservation := range res.Reservations {
instances = append(instances, reservation.Instances...)
}
return !lastPage
})
if err != nil {
return nil, err
}
return instances, nil
}
func (r *ec2Repository) ListAllKeyPairs() ([]*ec2.KeyPairInfo, error) {
input := &ec2.DescribeKeyPairsInput{}
pairs, err := r.client.DescribeKeyPairs(input)
if err != nil {
return nil, err
}
return pairs.KeyPairs, err
}

View File

@ -0,0 +1,436 @@
package repository
import (
"strings"
"testing"
"github.com/stretchr/testify/mock"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/aws"
"github.com/r3labs/diff/v2"
"github.com/stretchr/testify/assert"
)
func Test_ec2Repository_ListAllImages(t *testing.T) {
tests := []struct {
name string
mocks func(client *MockEC2Client)
want []*ec2.Image
wantErr error
}{
{
name: "List all images",
mocks: func(client *MockEC2Client) {
client.On("DescribeImages",
&ec2.DescribeImagesInput{
Owners: []*string{
aws.String("self"),
},
}).Return(&ec2.DescribeImagesOutput{
Images: []*ec2.Image{
{ImageId: aws.String("1")},
{ImageId: aws.String("2")},
{ImageId: aws.String("3")},
{ImageId: aws.String("4")},
},
}, nil)
},
want: []*ec2.Image{
{ImageId: aws.String("1")},
{ImageId: aws.String("2")},
{ImageId: aws.String("3")},
{ImageId: aws.String("4")},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &MockEC2Client{}
tt.mocks(client)
r := &ec2Repository{
client: client,
}
got, err := r.ListAllImages()
assert.Equal(t, tt.wantErr, err)
changelog, err := diff.Diff(got, tt.want)
assert.Nil(t, err)
if len(changelog) > 0 {
for _, change := range changelog {
t.Errorf("%s: %s -> %s", strings.Join(change.Path, "."), change.From, change.To)
}
t.Fail()
}
})
}
}
func Test_ec2Repository_ListAllSnapshots(t *testing.T) {
tests := []struct {
name string
mocks func(client *MockEC2Client)
want []*ec2.Snapshot
wantErr error
}{
{name: "List with 2 pages",
mocks: func(client *MockEC2Client) {
client.On("DescribeSnapshotsPages",
&ec2.DescribeSnapshotsInput{
OwnerIds: []*string{
aws.String("self"),
},
},
mock.MatchedBy(func(callback func(res *ec2.DescribeSnapshotsOutput, lastPage bool) bool) bool {
callback(&ec2.DescribeSnapshotsOutput{
Snapshots: []*ec2.Snapshot{
{VolumeId: aws.String("1")},
{VolumeId: aws.String("2")},
{VolumeId: aws.String("3")},
{VolumeId: aws.String("4")},
},
}, false)
callback(&ec2.DescribeSnapshotsOutput{
Snapshots: []*ec2.Snapshot{
{VolumeId: aws.String("5")},
{VolumeId: aws.String("6")},
{VolumeId: aws.String("7")},
{VolumeId: aws.String("8")},
},
}, true)
return true
})).Return(nil)
},
want: []*ec2.Snapshot{
{VolumeId: aws.String("1")},
{VolumeId: aws.String("2")},
{VolumeId: aws.String("3")},
{VolumeId: aws.String("4")},
{VolumeId: aws.String("5")},
{VolumeId: aws.String("6")},
{VolumeId: aws.String("7")},
{VolumeId: aws.String("8")},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &MockEC2Client{}
tt.mocks(client)
r := &ec2Repository{
client: client,
}
got, err := r.ListAllSnapshots()
assert.Equal(t, tt.wantErr, err)
changelog, err := diff.Diff(got, tt.want)
assert.Nil(t, err)
if len(changelog) > 0 {
for _, change := range changelog {
t.Errorf("%s: %s -> %s", strings.Join(change.Path, "."), change.From, change.To)
}
t.Fail()
}
})
}
}
func Test_ec2Repository_ListAllVolumes(t *testing.T) {
tests := []struct {
name string
mocks func(client *MockEC2Client)
want []*ec2.Volume
wantErr error
}{
{name: "List with 2 pages",
mocks: func(client *MockEC2Client) {
client.On("DescribeVolumesPages",
&ec2.DescribeVolumesInput{},
mock.MatchedBy(func(callback func(res *ec2.DescribeVolumesOutput, lastPage bool) bool) bool {
callback(&ec2.DescribeVolumesOutput{
Volumes: []*ec2.Volume{
{VolumeId: aws.String("1")},
{VolumeId: aws.String("2")},
{VolumeId: aws.String("3")},
{VolumeId: aws.String("4")},
},
}, false)
callback(&ec2.DescribeVolumesOutput{
Volumes: []*ec2.Volume{
{VolumeId: aws.String("5")},
{VolumeId: aws.String("6")},
{VolumeId: aws.String("7")},
{VolumeId: aws.String("8")},
},
}, true)
return true
})).Return(nil)
},
want: []*ec2.Volume{
{VolumeId: aws.String("1")},
{VolumeId: aws.String("2")},
{VolumeId: aws.String("3")},
{VolumeId: aws.String("4")},
{VolumeId: aws.String("5")},
{VolumeId: aws.String("6")},
{VolumeId: aws.String("7")},
{VolumeId: aws.String("8")},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &MockEC2Client{}
tt.mocks(client)
r := &ec2Repository{
client: client,
}
got, err := r.ListAllVolumes()
assert.Equal(t, tt.wantErr, err)
changelog, err := diff.Diff(got, tt.want)
assert.Nil(t, err)
if len(changelog) > 0 {
for _, change := range changelog {
t.Errorf("%s: %s -> %s", strings.Join(change.Path, "."), change.From, change.To)
}
t.Fail()
}
})
}
}
func Test_ec2Repository_ListAllAddresses(t *testing.T) {
tests := []struct {
name string
mocks func(client *MockEC2Client)
want []*ec2.Address
wantErr error
}{
{
name: "List address",
mocks: func(client *MockEC2Client) {
client.On("DescribeAddresses", &ec2.DescribeAddressesInput{}).
Return(&ec2.DescribeAddressesOutput{
Addresses: []*ec2.Address{
{AssociationId: aws.String("1")},
{AssociationId: aws.String("2")},
{AssociationId: aws.String("3")},
{AssociationId: aws.String("4")},
},
}, nil)
},
want: []*ec2.Address{
{AssociationId: aws.String("1")},
{AssociationId: aws.String("2")},
{AssociationId: aws.String("3")},
{AssociationId: aws.String("4")},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &MockEC2Client{}
tt.mocks(client)
r := &ec2Repository{
client: client,
}
got, err := r.ListAllAddresses()
assert.Equal(t, tt.wantErr, err)
changelog, err := diff.Diff(got, tt.want)
assert.Nil(t, err)
if len(changelog) > 0 {
for _, change := range changelog {
t.Errorf("%s: %s -> %s", strings.Join(change.Path, "."), change.From, change.To)
}
t.Fail()
}
})
}
}
func Test_ec2Repository_ListAllAddressesAssociation(t *testing.T) {
tests := []struct {
name string
mocks func(client *MockEC2Client)
want []string
wantErr error
}{
{
name: "List address",
mocks: func(client *MockEC2Client) {
client.On("DescribeAddresses", &ec2.DescribeAddressesInput{}).
Return(&ec2.DescribeAddressesOutput{
Addresses: []*ec2.Address{
{AssociationId: aws.String("1")},
{AssociationId: aws.String("2")},
{AssociationId: aws.String("3")},
{AssociationId: aws.String("4")},
},
}, nil)
},
want: []string{
"1",
"2",
"3",
"4",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &MockEC2Client{}
tt.mocks(client)
r := &ec2Repository{
client: client,
}
got, err := r.ListAllAddressesAssociation()
assert.Equal(t, tt.wantErr, err)
changelog, err := diff.Diff(got, tt.want)
assert.Nil(t, err)
if len(changelog) > 0 {
for _, change := range changelog {
t.Errorf("%s: %s -> %s", strings.Join(change.Path, "."), change.From, change.To)
}
t.Fail()
}
})
}
}
func Test_ec2Repository_ListAllInstances(t *testing.T) {
tests := []struct {
name string
mocks func(client *MockEC2Client)
want []*ec2.Instance
wantErr error
}{
{name: "List with 2 pages",
mocks: func(client *MockEC2Client) {
client.On("DescribeInstancesPages",
&ec2.DescribeInstancesInput{},
mock.MatchedBy(func(callback func(res *ec2.DescribeInstancesOutput, lastPage bool) bool) bool {
callback(&ec2.DescribeInstancesOutput{
Reservations: []*ec2.Reservation{
{
Instances: []*ec2.Instance{
{ImageId: aws.String("1")},
{ImageId: aws.String("2")},
{ImageId: aws.String("3")},
},
},
{
Instances: []*ec2.Instance{
{ImageId: aws.String("4")},
{ImageId: aws.String("5")},
{ImageId: aws.String("6")},
},
},
},
}, false)
callback(&ec2.DescribeInstancesOutput{
Reservations: []*ec2.Reservation{
{
Instances: []*ec2.Instance{
{ImageId: aws.String("7")},
{ImageId: aws.String("8")},
{ImageId: aws.String("9")},
},
},
{
Instances: []*ec2.Instance{
{ImageId: aws.String("10")},
{ImageId: aws.String("11")},
{ImageId: aws.String("12")},
},
},
},
}, true)
return true
})).Return(nil)
},
want: []*ec2.Instance{
{ImageId: aws.String("1")},
{ImageId: aws.String("2")},
{ImageId: aws.String("3")},
{ImageId: aws.String("4")},
{ImageId: aws.String("5")},
{ImageId: aws.String("6")},
{ImageId: aws.String("7")},
{ImageId: aws.String("8")},
{ImageId: aws.String("9")},
{ImageId: aws.String("10")},
{ImageId: aws.String("11")},
{ImageId: aws.String("12")},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &MockEC2Client{}
tt.mocks(client)
r := &ec2Repository{
client: client,
}
got, err := r.ListAllInstances()
assert.Equal(t, tt.wantErr, err)
changelog, err := diff.Diff(got, tt.want)
assert.Nil(t, err)
if len(changelog) > 0 {
for _, change := range changelog {
t.Errorf("%s: %s -> %s", strings.Join(change.Path, "."), change.From, change.To)
}
t.Fail()
}
})
}
}
func Test_ec2Repository_ListAllKeyPairs(t *testing.T) {
tests := []struct {
name string
mocks func(client *MockEC2Client)
want []*ec2.KeyPairInfo
wantErr error
}{
{
name: "List address",
mocks: func(client *MockEC2Client) {
client.On("DescribeKeyPairs", &ec2.DescribeKeyPairsInput{}).
Return(&ec2.DescribeKeyPairsOutput{
KeyPairs: []*ec2.KeyPairInfo{
{KeyPairId: aws.String("1")},
{KeyPairId: aws.String("2")},
{KeyPairId: aws.String("3")},
{KeyPairId: aws.String("4")},
},
}, nil)
},
want: []*ec2.KeyPairInfo{
{KeyPairId: aws.String("1")},
{KeyPairId: aws.String("2")},
{KeyPairId: aws.String("3")},
{KeyPairId: aws.String("4")},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &MockEC2Client{}
tt.mocks(client)
r := &ec2Repository{
client: client,
}
got, err := r.ListAllKeyPairs()
assert.Equal(t, tt.wantErr, err)
changelog, err := diff.Diff(got, tt.want)
assert.Nil(t, err)
if len(changelog) > 0 {
for _, change := range changelog {
t.Errorf("%s: %s -> %s", strings.Join(change.Path, "."), change.From, change.To)
}
t.Fail()
}
})
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,174 @@
// Code generated by mockery v0.0.0-dev. DO NOT EDIT.
package repository
import (
ec2 "github.com/aws/aws-sdk-go/service/ec2"
mock "github.com/stretchr/testify/mock"
)
// MockEC2Repository is an autogenerated mock type for the EC2Repository type
type MockEC2Repository struct {
mock.Mock
}
// ListAllAddresses provides a mock function with given fields:
func (_m *MockEC2Repository) ListAllAddresses() ([]*ec2.Address, error) {
ret := _m.Called()
var r0 []*ec2.Address
if rf, ok := ret.Get(0).(func() []*ec2.Address); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*ec2.Address)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ListAllAddressesAssociation provides a mock function with given fields:
func (_m *MockEC2Repository) ListAllAddressesAssociation() ([]string, error) {
ret := _m.Called()
var r0 []string
if rf, ok := ret.Get(0).(func() []string); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]string)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ListAllImages provides a mock function with given fields:
func (_m *MockEC2Repository) ListAllImages() ([]*ec2.Image, error) {
ret := _m.Called()
var r0 []*ec2.Image
if rf, ok := ret.Get(0).(func() []*ec2.Image); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*ec2.Image)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ListAllInstances provides a mock function with given fields:
func (_m *MockEC2Repository) ListAllInstances() ([]*ec2.Instance, error) {
ret := _m.Called()
var r0 []*ec2.Instance
if rf, ok := ret.Get(0).(func() []*ec2.Instance); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*ec2.Instance)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ListAllKeyPairs provides a mock function with given fields:
func (_m *MockEC2Repository) ListAllKeyPairs() ([]*ec2.KeyPairInfo, error) {
ret := _m.Called()
var r0 []*ec2.KeyPairInfo
if rf, ok := ret.Get(0).(func() []*ec2.KeyPairInfo); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*ec2.KeyPairInfo)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ListAllSnapshots provides a mock function with given fields:
func (_m *MockEC2Repository) ListAllSnapshots() ([]*ec2.Snapshot, error) {
ret := _m.Called()
var r0 []*ec2.Snapshot
if rf, ok := ret.Get(0).(func() []*ec2.Snapshot); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*ec2.Snapshot)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ListAllVolumes provides a mock function with given fields:
func (_m *MockEC2Repository) ListAllVolumes() ([]*ec2.Volume, error) {
ret := _m.Called()
var r0 []*ec2.Volume
if rf, ok := ret.Get(0).(func() []*ec2.Volume); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*ec2.Volume)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}

View File

@ -1,151 +0,0 @@
package mocks
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
)
type DescribeInstancesPagesOutput []struct {
LastPage bool
Response *ec2.DescribeInstancesOutput
}
type DescribeSnapshotsPagesOutput []struct {
LastPage bool
Response *ec2.DescribeSnapshotsOutput
}
type DescribeVolumesPagesOutput []struct {
LastPage bool
Response *ec2.DescribeVolumesOutput
}
type DescribeSecurityGroupsPagesOutput []struct {
LastPage bool
Response *ec2.DescribeSecurityGroupsOutput
}
type MockAWSEC2Client struct {
ec2iface.EC2API
instancesPages DescribeInstancesPagesOutput
kpNames []string
amiIDs []string
volumesPages DescribeVolumesPagesOutput
snapshotsPages DescribeSnapshotsPagesOutput
addresses []*ec2.Address
securityGroupsPages DescribeSecurityGroupsPagesOutput
err error
}
func NewMockAWSEC2ErrorClient(err error) *MockAWSEC2Client {
return &MockAWSEC2Client{err: err}
}
func NewMockAWSEC2InstanceClient(instancesPages DescribeInstancesPagesOutput) *MockAWSEC2Client {
return &MockAWSEC2Client{instancesPages: instancesPages}
}
func NewMockAWSEC2KeyPairClient(kpNames []string) *MockAWSEC2Client {
return &MockAWSEC2Client{kpNames: kpNames}
}
func NewMockAWSEC2AmiClient(amiIDs []string) *MockAWSEC2Client {
return &MockAWSEC2Client{amiIDs: amiIDs}
}
func NewMockAWSEC2EbsVolumeClient(volumesPages DescribeVolumesPagesOutput) *MockAWSEC2Client {
return &MockAWSEC2Client{volumesPages: volumesPages}
}
func NewMockAWSEC2EbsSnapshotClient(snapshotsPages DescribeSnapshotsPagesOutput) *MockAWSEC2Client {
return &MockAWSEC2Client{snapshotsPages: snapshotsPages}
}
func NewMockAWSEC2EipClient(addresses []*ec2.Address) *MockAWSEC2Client {
return &MockAWSEC2Client{addresses: addresses}
}
func NewMockAWSVPCSecurityGroupClient(securityGroupsPages DescribeSecurityGroupsPagesOutput) *MockAWSEC2Client {
return &MockAWSEC2Client{securityGroupsPages: securityGroupsPages}
}
func (m *MockAWSEC2Client) DescribeInstancesPages(_ *ec2.DescribeInstancesInput, cb func(*ec2.DescribeInstancesOutput, bool) bool) error {
if m.err != nil {
return m.err
}
for _, instancesPage := range m.instancesPages {
cb(instancesPage.Response, instancesPage.LastPage)
}
return nil
}
func (m *MockAWSEC2Client) DescribeKeyPairs(*ec2.DescribeKeyPairsInput) (*ec2.DescribeKeyPairsOutput, error) {
if m.err != nil {
return nil, m.err
}
var kps []*ec2.KeyPairInfo
for _, name := range m.kpNames {
kps = append(kps, &ec2.KeyPairInfo{
KeyName: aws.String(name),
})
}
return &ec2.DescribeKeyPairsOutput{
KeyPairs: kps,
}, nil
}
func (m *MockAWSEC2Client) DescribeImages(*ec2.DescribeImagesInput) (*ec2.DescribeImagesOutput, error) {
if m.err != nil {
return nil, m.err
}
var images []*ec2.Image
for _, id := range m.amiIDs {
images = append(images, &ec2.Image{
ImageId: aws.String(id),
})
}
return &ec2.DescribeImagesOutput{
Images: images,
}, nil
}
func (m *MockAWSEC2Client) DescribeVolumesPages(_ *ec2.DescribeVolumesInput, cb func(*ec2.DescribeVolumesOutput, bool) bool) error {
if m.err != nil {
return m.err
}
for _, volumesPage := range m.volumesPages {
cb(volumesPage.Response, volumesPage.LastPage)
}
return nil
}
func (m *MockAWSEC2Client) DescribeSnapshotsPages(_ *ec2.DescribeSnapshotsInput, cb func(*ec2.DescribeSnapshotsOutput, bool) bool) error {
if m.err != nil {
return m.err
}
for _, snapshotsPage := range m.snapshotsPages {
cb(snapshotsPage.Response, snapshotsPage.LastPage)
}
return nil
}
func (m *MockAWSEC2Client) DescribeAddresses(*ec2.DescribeAddressesInput) (*ec2.DescribeAddressesOutput, error) {
if m.err != nil {
return nil, m.err
}
addresses := m.addresses
return &ec2.DescribeAddressesOutput{
Addresses: addresses,
}, nil
}
func (m *MockAWSEC2Client) DescribeSecurityGroupsPages(_ *ec2.DescribeSecurityGroupsInput, cb func(*ec2.DescribeSecurityGroupsOutput, bool) bool) error {
if m.err != nil {
return m.err
}
for _, securityGroupsPage := range m.securityGroupsPages {
cb(securityGroupsPage.Response, securityGroupsPage.LastPage)
}
return nil
}