diff --git a/pkg/remote/cloudfront_scanner_test.go b/pkg/remote/cloudfront_scanner_test.go index 0749c25e..f0728857 100644 --- a/pkg/remote/cloudfront_scanner_test.go +++ b/pkg/remote/cloudfront_scanner_test.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/cloudfront" "github.com/cloudskiff/driftctl/mocks" "github.com/cloudskiff/driftctl/pkg/filter" + "github.com/cloudskiff/driftctl/pkg/remote/alerts" "github.com/cloudskiff/driftctl/pkg/remote/aws" "github.com/cloudskiff/driftctl/pkg/remote/aws/repository" "github.com/cloudskiff/driftctl/pkg/remote/cache" @@ -28,20 +29,20 @@ func TestCloudfrontDistribution(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockCloudfrontRepository) + mocks func(*repository.MockCloudfrontRepository, *mocks.AlerterInterface) wantErr error }{ { test: "no cloudfront distributions", dirName: "aws_cloudfront_distribution_empty", - mocks: func(repository *repository.MockCloudfrontRepository) { + mocks: func(repository *repository.MockCloudfrontRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllDistributions").Return([]*cloudfront.DistributionSummary{}, nil) }, }, { test: "single cloudfront distribution", dirName: "aws_cloudfront_distribution_single", - mocks: func(repository *repository.MockCloudfrontRepository) { + mocks: func(repository *repository.MockCloudfrontRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllDistributions").Return([]*cloudfront.DistributionSummary{ {Id: awssdk.String("E1M9CNS0XSHI19")}, }, nil) @@ -50,8 +51,10 @@ func TestCloudfrontDistribution(t *testing.T) { { test: "cannot list cloudfront distributions", dirName: "aws_cloudfront_distribution_list", - mocks: func(repository *repository.MockCloudfrontRepository) { + mocks: func(repository *repository.MockCloudfrontRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllDistributions").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsCloudfrontDistributionResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsCloudfrontDistributionResourceType, resourceaws.AwsCloudfrontDistributionResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -76,9 +79,9 @@ func TestCloudfrontDistribution(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockCloudfrontRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.CloudfrontRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -111,6 +114,8 @@ func TestCloudfrontDistribution(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsCloudfrontDistributionResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } diff --git a/pkg/remote/dynamodb_scanner_test.go b/pkg/remote/dynamodb_scanner_test.go index cbbfe28b..a9eb16a7 100644 --- a/pkg/remote/dynamodb_scanner_test.go +++ b/pkg/remote/dynamodb_scanner_test.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/cloudskiff/driftctl/mocks" "github.com/cloudskiff/driftctl/pkg/filter" + "github.com/cloudskiff/driftctl/pkg/remote/alerts" "github.com/cloudskiff/driftctl/pkg/remote/aws" "github.com/cloudskiff/driftctl/pkg/remote/aws/repository" "github.com/cloudskiff/driftctl/pkg/remote/cache" @@ -28,13 +29,13 @@ func TestDynamoDBTable(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockDynamoDBRepository) + mocks func(*repository.MockDynamoDBRepository, *mocks.AlerterInterface) wantErr error }{ { test: "no DynamoDB Table", dirName: "dynamodb_table_empty", - mocks: func(client *repository.MockDynamoDBRepository) { + mocks: func(client *repository.MockDynamoDBRepository, alerter *mocks.AlerterInterface) { client.On("ListAllTables").Return([]*string{}, nil) }, wantErr: nil, @@ -42,7 +43,7 @@ func TestDynamoDBTable(t *testing.T) { { test: "Multiple DynamoDB Table", dirName: "dynamodb_table_multiple", - mocks: func(client *repository.MockDynamoDBRepository) { + mocks: func(client *repository.MockDynamoDBRepository, alerter *mocks.AlerterInterface) { client.On("ListAllTables").Return([]*string{ awssdk.String("GameScores"), awssdk.String("example"), @@ -53,8 +54,10 @@ func TestDynamoDBTable(t *testing.T) { { test: "cannot list DynamoDB Table", dirName: "dynamodb_table_list", - mocks: func(client *repository.MockDynamoDBRepository) { + mocks: func(client *repository.MockDynamoDBRepository, alerter *mocks.AlerterInterface) { client.On("ListAllTables").Return(nil, awserr.NewRequestFailure(awserr.New("AccessDeniedException", "", errors.New("")), 400, "")) + + alerter.On("SendAlert", resourceaws.AwsDynamodbTableResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsDynamodbTableResourceType, resourceaws.AwsDynamodbTableResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -79,9 +82,9 @@ func TestDynamoDBTable(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockDynamoDBRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.DynamoDBRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -114,6 +117,8 @@ func TestDynamoDBTable(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsDynamodbTableResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } diff --git a/pkg/remote/ec2_scanner_test.go b/pkg/remote/ec2_scanner_test.go index 7183c814..97506bf6 100644 --- a/pkg/remote/ec2_scanner_test.go +++ b/pkg/remote/ec2_scanner_test.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" "github.com/cloudskiff/driftctl/mocks" "github.com/cloudskiff/driftctl/pkg/filter" + "github.com/cloudskiff/driftctl/pkg/remote/alerts" "github.com/cloudskiff/driftctl/pkg/remote/aws" "github.com/cloudskiff/driftctl/pkg/remote/aws/repository" "github.com/cloudskiff/driftctl/pkg/remote/cache" @@ -28,20 +29,20 @@ func TestEC2EbsVolume(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no volumes", dirName: "aws_ec2_ebs_volume_empty", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllVolumes").Return([]*ec2.Volume{}, nil) }, }, { test: "multiple volumes", dirName: "aws_ec2_ebs_volume_multiple", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllVolumes").Return([]*ec2.Volume{ {VolumeId: awssdk.String("vol-081c7272a57a09db1")}, {VolumeId: awssdk.String("vol-01ddc91d3d9d1318b")}, @@ -51,8 +52,10 @@ func TestEC2EbsVolume(t *testing.T) { { test: "cannot list volumes", dirName: "aws_ec2_ebs_volume_list", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllVolumes").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsEbsVolumeResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsEbsVolumeResourceType, resourceaws.AwsEbsVolumeResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -77,9 +80,9 @@ func TestEC2EbsVolume(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -112,6 +115,8 @@ func TestEC2EbsVolume(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsEbsVolumeResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -120,20 +125,20 @@ func TestEC2EbsSnapshot(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no snapshots", dirName: "aws_ec2_ebs_snapshot_empty", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllSnapshots").Return([]*ec2.Snapshot{}, nil) }, }, { test: "multiple snapshots", dirName: "aws_ec2_ebs_snapshot_multiple", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllSnapshots").Return([]*ec2.Snapshot{ {SnapshotId: awssdk.String("snap-0c509a2a880d95a39")}, {SnapshotId: awssdk.String("snap-00672558cecd93a61")}, @@ -143,8 +148,10 @@ func TestEC2EbsSnapshot(t *testing.T) { { test: "cannot list snapshots", dirName: "aws_ec2_ebs_snapshot_list", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllSnapshots").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsEbsSnapshotResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsEbsSnapshotResourceType, resourceaws.AwsEbsSnapshotResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -169,9 +176,9 @@ func TestEC2EbsSnapshot(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -204,6 +211,8 @@ func TestEC2EbsSnapshot(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsEbsSnapshotResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -212,20 +221,20 @@ func TestEC2Eip(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no eips", dirName: "aws_ec2_eip_empty", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllAddresses").Return([]*ec2.Address{}, nil) }, }, { test: "multiple eips", dirName: "aws_ec2_eip_multiple", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllAddresses").Return([]*ec2.Address{ {AllocationId: awssdk.String("eipalloc-017d5267e4dda73f1")}, {AllocationId: awssdk.String("eipalloc-0cf714dc097c992cc")}, @@ -235,8 +244,10 @@ func TestEC2Eip(t *testing.T) { { test: "cannot list eips", dirName: "aws_ec2_eip_list", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllAddresses").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsEipResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsEipResourceType, resourceaws.AwsEipResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -261,9 +272,9 @@ func TestEC2Eip(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -296,6 +307,8 @@ func TestEC2Eip(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsEipResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -304,20 +317,20 @@ func TestEC2Ami(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no amis", dirName: "aws_ec2_ami_empty", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllImages").Return([]*ec2.Image{}, nil) }, }, { test: "multiple amis", dirName: "aws_ec2_ami_multiple", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllImages").Return([]*ec2.Image{ {ImageId: awssdk.String("ami-03a578b46f4c3081b")}, {ImageId: awssdk.String("ami-025962fd8b456731f")}, @@ -327,8 +340,10 @@ func TestEC2Ami(t *testing.T) { { test: "cannot list ami", dirName: "aws_ec2_ami_list", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllImages").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsAmiResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsAmiResourceType, resourceaws.AwsAmiResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -353,9 +368,9 @@ func TestEC2Ami(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -388,6 +403,8 @@ func TestEC2Ami(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsAmiResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -396,20 +413,20 @@ func TestEC2KeyPair(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no key pairs", dirName: "aws_ec2_key_pair_empty", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllKeyPairs").Return([]*ec2.KeyPairInfo{}, nil) }, }, { test: "multiple key pairs", dirName: "aws_ec2_key_pair_multiple", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllKeyPairs").Return([]*ec2.KeyPairInfo{ {KeyName: awssdk.String("test")}, {KeyName: awssdk.String("bar")}, @@ -419,8 +436,10 @@ func TestEC2KeyPair(t *testing.T) { { test: "cannot list key pairs", dirName: "aws_ec2_key_pair_list", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllKeyPairs").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsKeyPairResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsKeyPairResourceType, resourceaws.AwsKeyPairResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -445,9 +464,9 @@ func TestEC2KeyPair(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -480,6 +499,8 @@ func TestEC2KeyPair(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsKeyPairResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -488,20 +509,20 @@ func TestEC2EipAssociation(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no eip associations", dirName: "aws_ec2_eip_association_empty", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllAddressesAssociation").Return([]*ec2.Address{}, nil) }, }, { test: "single eip association", dirName: "aws_ec2_eip_association_single", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllAddressesAssociation").Return([]*ec2.Address{ { AssociationId: awssdk.String("eipassoc-0e9a7356e30f0c3d1"), @@ -513,8 +534,10 @@ func TestEC2EipAssociation(t *testing.T) { { test: "cannot list eip associations", dirName: "aws_ec2_eip_association_list", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllAddressesAssociation").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsEipAssociationResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsEipAssociationResourceType, resourceaws.AwsEipAssociationResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -539,9 +562,9 @@ func TestEC2EipAssociation(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -574,6 +597,8 @@ func TestEC2EipAssociation(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsEipAssociationResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -582,20 +607,20 @@ func TestEC2Instance(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no instances", dirName: "aws_ec2_instance_empty", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllInstances").Return([]*ec2.Instance{}, nil) }, }, { test: "multiple instances", dirName: "aws_ec2_instance_multiple", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllInstances").Return([]*ec2.Instance{ {InstanceId: awssdk.String("i-0d3650a23f4e45dc0")}, {InstanceId: awssdk.String("i-010376047a71419f1")}, @@ -605,7 +630,7 @@ func TestEC2Instance(t *testing.T) { { test: "terminated instances", dirName: "aws_ec2_instance_terminated", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllInstances").Return([]*ec2.Instance{ {InstanceId: awssdk.String("i-0e1543baf4f2cd990")}, {InstanceId: awssdk.String("i-0a3a7ed51ae2b4fa0")}, // Nil @@ -615,8 +640,10 @@ func TestEC2Instance(t *testing.T) { { test: "cannot list instances", dirName: "aws_ec2_instance_list", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllInstances").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsInstanceResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsInstanceResourceType, resourceaws.AwsInstanceResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -641,9 +668,9 @@ func TestEC2Instance(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -676,6 +703,8 @@ func TestEC2Instance(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsInstanceResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -684,20 +713,20 @@ func TestEC2InternetGateway(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no internet gateways", dirName: "aws_ec2_internet_gateway_empty", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllInternetGateways").Return([]*ec2.InternetGateway{}, nil) }, }, { test: "multiple internet gateways", dirName: "aws_ec2_internet_gateway_multiple", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllInternetGateways").Return([]*ec2.InternetGateway{ {InternetGatewayId: awssdk.String("igw-0184eb41aadc62d1c")}, {InternetGatewayId: awssdk.String("igw-047b487f5c60fca99")}, @@ -707,8 +736,10 @@ func TestEC2InternetGateway(t *testing.T) { { test: "cannot list internet gateways", dirName: "aws_ec2_internet_gateway_list", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllInternetGateways").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsInternetGatewayResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsInternetGatewayResourceType, resourceaws.AwsInternetGatewayResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -733,9 +764,9 @@ func TestEC2InternetGateway(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -768,6 +799,8 @@ func TestEC2InternetGateway(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsInternetGatewayResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -777,13 +810,13 @@ func TestVPC(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no VPC", dirName: "vpc_empty", - mocks: func(client *repository.MockEC2Repository) { + mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllVPCs").Once().Return([]*ec2.Vpc{}, []*ec2.Vpc{}, nil) }, wantErr: nil, @@ -791,7 +824,7 @@ func TestVPC(t *testing.T) { { test: "VPC results", dirName: "vpc", - mocks: func(client *repository.MockEC2Repository) { + mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllVPCs").Once().Return([]*ec2.Vpc{ { VpcId: awssdk.String("vpc-0768e1fd0029e3fc3"), @@ -816,8 +849,10 @@ func TestVPC(t *testing.T) { { test: "cannot list VPC", dirName: "vpc_empty", - mocks: func(client *repository.MockEC2Repository) { + mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllVPCs").Once().Return(nil, nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsVpcResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsVpcResourceType, resourceaws.AwsVpcResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -842,9 +877,9 @@ func TestVPC(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -877,6 +912,8 @@ func TestVPC(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsVpcResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -886,13 +923,13 @@ func TestDefaultVPC(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no VPC", dirName: "vpc_empty", - mocks: func(client *repository.MockEC2Repository) { + mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllVPCs").Once().Return([]*ec2.Vpc{}, []*ec2.Vpc{}, nil) }, wantErr: nil, @@ -900,7 +937,7 @@ func TestDefaultVPC(t *testing.T) { { test: "default VPC results", dirName: "default_vpc", - mocks: func(client *repository.MockEC2Repository) { + mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllVPCs").Once().Return([]*ec2.Vpc{ { VpcId: awssdk.String("vpc-0768e1fd0029e3fc3"), @@ -922,8 +959,10 @@ func TestDefaultVPC(t *testing.T) { { test: "cannot list VPC", dirName: "vpc_empty", - mocks: func(client *repository.MockEC2Repository) { + mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllVPCs").Once().Return(nil, nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsDefaultVpcResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsDefaultVpcResourceType, resourceaws.AwsDefaultVpcResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -948,9 +987,9 @@ func TestDefaultVPC(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -983,6 +1022,8 @@ func TestDefaultVPC(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsDefaultVpcResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -991,13 +1032,13 @@ func TestEC2RouteTableAssociation(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no route table associations (test for nil values)", dirName: "aws_ec2_route_table_association_empty", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllRouteTables").Return([]*ec2.RouteTable{ { RouteTableId: awssdk.String("assoc_with_nil"), @@ -1019,7 +1060,7 @@ func TestEC2RouteTableAssociation(t *testing.T) { { test: "multiple route table associations (mixed subnet and gateway associations)", dirName: "aws_ec2_route_table_association_multiple", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllRouteTables").Return([]*ec2.RouteTable{ { RouteTableId: awssdk.String("rtb-05aa6c5673311a17b"), // route @@ -1083,8 +1124,10 @@ func TestEC2RouteTableAssociation(t *testing.T) { { test: "cannot list route table associations", dirName: "aws_ec2_route_table_association_list", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllRouteTables").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsRouteTableAssociationResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsRouteTableAssociationResourceType, resourceaws.AwsRouteTableResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -1109,9 +1152,9 @@ func TestEC2RouteTableAssociation(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -1144,6 +1187,8 @@ func TestEC2RouteTableAssociation(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsRouteTableAssociationResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -1152,20 +1197,20 @@ func TestEC2Subnet(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no subnets", dirName: "aws_ec2_subnet_empty", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllSubnets").Return([]*ec2.Subnet{}, []*ec2.Subnet{}, nil) }, }, { test: "multiple subnets", dirName: "aws_ec2_subnet_multiple", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllSubnets").Return([]*ec2.Subnet{ { SubnetId: awssdk.String("subnet-05810d3f933925f6d"), // subnet1 @@ -1198,8 +1243,10 @@ func TestEC2Subnet(t *testing.T) { { test: "cannot list subnets", dirName: "aws_ec2_subnet_list", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllSubnets").Return(nil, nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsSubnetResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsSubnetResourceType, resourceaws.AwsSubnetResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -1224,9 +1271,9 @@ func TestEC2Subnet(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -1259,6 +1306,8 @@ func TestEC2Subnet(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsSubnetResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -1267,20 +1316,20 @@ func TestEC2DefaultSubnet(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no default subnets", dirName: "aws_ec2_default_subnet_empty", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllSubnets").Return([]*ec2.Subnet{}, []*ec2.Subnet{}, nil) }, }, { test: "multiple default subnets", dirName: "aws_ec2_default_subnet_multiple", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllSubnets").Return([]*ec2.Subnet{ { SubnetId: awssdk.String("subnet-05810d3f933925f6d"), // subnet1 @@ -1313,8 +1362,10 @@ func TestEC2DefaultSubnet(t *testing.T) { { test: "cannot list default subnets", dirName: "aws_ec2_default_subnet_list", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllSubnets").Return(nil, nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsDefaultSubnetResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsDefaultSubnetResourceType, resourceaws.AwsDefaultSubnetResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -1339,9 +1390,9 @@ func TestEC2DefaultSubnet(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -1374,6 +1425,8 @@ func TestEC2DefaultSubnet(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsDefaultSubnetResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -1382,20 +1435,20 @@ func TestEC2RouteTable(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no route tables", dirName: "aws_ec2_route_table_empty", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllRouteTables").Return([]*ec2.RouteTable{}, nil) }, }, { test: "multiple route tables", dirName: "aws_ec2_route_table_multiple", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllRouteTables").Return([]*ec2.RouteTable{ {RouteTableId: awssdk.String("rtb-08b7b71af15e183ce")}, // table1 {RouteTableId: awssdk.String("rtb-0002ac731f6fdea55")}, // table2 @@ -1415,8 +1468,10 @@ func TestEC2RouteTable(t *testing.T) { { test: "cannot list route tables", dirName: "aws_ec2_route_table_list", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllRouteTables").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsRouteTableResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsRouteTableResourceType, resourceaws.AwsRouteTableResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -1441,9 +1496,9 @@ func TestEC2RouteTable(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -1476,6 +1531,8 @@ func TestEC2RouteTable(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsRouteTableResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -1484,20 +1541,20 @@ func TestEC2DefaultRouteTable(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no default route tables", dirName: "aws_ec2_default_route_table_empty", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllRouteTables").Return([]*ec2.RouteTable{}, nil) }, }, { test: "multiple default route tables", dirName: "aws_ec2_default_route_table_single", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllRouteTables").Return([]*ec2.RouteTable{ {RouteTableId: awssdk.String("rtb-08b7b71af15e183ce")}, // table1 {RouteTableId: awssdk.String("rtb-0002ac731f6fdea55")}, // table2 @@ -1517,8 +1574,10 @@ func TestEC2DefaultRouteTable(t *testing.T) { { test: "cannot list default route tables", dirName: "aws_ec2_default_route_table_list", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllRouteTables").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsDefaultRouteTableResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsDefaultRouteTableResourceType, resourceaws.AwsDefaultRouteTableResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -1543,9 +1602,9 @@ func TestEC2DefaultRouteTable(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -1578,6 +1637,8 @@ func TestEC2DefaultRouteTable(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsDefaultRouteTableResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -1587,13 +1648,13 @@ func TestVpcSecurityGroup(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no security groups", dirName: "vpc_security_group_empty", - mocks: func(client *repository.MockEC2Repository) { + mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllSecurityGroups").Once().Return([]*ec2.SecurityGroup{}, []*ec2.SecurityGroup{}, nil) }, wantErr: nil, @@ -1601,7 +1662,7 @@ func TestVpcSecurityGroup(t *testing.T) { { test: "with security groups", dirName: "vpc_security_group_multiple", - mocks: func(client *repository.MockEC2Repository) { + mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllSecurityGroups").Once().Return([]*ec2.SecurityGroup{ { GroupId: awssdk.String("sg-0254c038e32f25530"), @@ -1619,8 +1680,10 @@ func TestVpcSecurityGroup(t *testing.T) { { test: "cannot list security groups", dirName: "vpc_security_group_empty", - mocks: func(client *repository.MockEC2Repository) { + mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllSecurityGroups").Return(nil, nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsSecurityGroupResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsSecurityGroupResourceType, resourceaws.AwsSecurityGroupResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -1645,9 +1708,9 @@ func TestVpcSecurityGroup(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -1680,6 +1743,8 @@ func TestVpcSecurityGroup(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsSecurityGroupResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -1689,13 +1754,13 @@ func TestVpcDefaultSecurityGroup(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no security groups", dirName: "vpc_default_security_group_empty", - mocks: func(client *repository.MockEC2Repository) { + mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllSecurityGroups").Once().Return([]*ec2.SecurityGroup{}, []*ec2.SecurityGroup{}, nil) }, wantErr: nil, @@ -1703,7 +1768,7 @@ func TestVpcDefaultSecurityGroup(t *testing.T) { { test: "with security groups", dirName: "vpc_default_security_group_multiple", - mocks: func(client *repository.MockEC2Repository) { + mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllSecurityGroups").Once().Return([]*ec2.SecurityGroup{ { GroupId: awssdk.String("sg-0254c038e32f25530"), @@ -1721,8 +1786,10 @@ func TestVpcDefaultSecurityGroup(t *testing.T) { { test: "cannot list security groups", dirName: "vpc_default_security_group_empty", - mocks: func(client *repository.MockEC2Repository) { + mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllSecurityGroups").Return(nil, nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsDefaultSecurityGroupResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsDefaultSecurityGroupResourceType, resourceaws.AwsDefaultSecurityGroupResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -1747,9 +1814,9 @@ func TestVpcDefaultSecurityGroup(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -1782,6 +1849,8 @@ func TestVpcDefaultSecurityGroup(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsDefaultSecurityGroupResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -1790,20 +1859,20 @@ func TestEC2NatGateway(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no nat gateways", dirName: "aws_ec2_nat_gateway_empty", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllNatGateways").Return([]*ec2.NatGateway{}, nil) }, }, { test: "single nat gateway", dirName: "aws_ec2_nat_gateway_single", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllNatGateways").Return([]*ec2.NatGateway{ {NatGatewayId: awssdk.String("nat-0a5408508b19ef490")}, }, nil) @@ -1812,8 +1881,10 @@ func TestEC2NatGateway(t *testing.T) { { test: "cannot list nat gateways", dirName: "aws_ec2_nat_gateway_list", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllNatGateways").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsNatGatewayResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsNatGatewayResourceType, resourceaws.AwsNatGatewayResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -1838,9 +1909,9 @@ func TestEC2NatGateway(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -1873,6 +1944,8 @@ func TestEC2NatGateway(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsNatGatewayResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -1881,7 +1954,7 @@ func TestEC2Route(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { @@ -1889,14 +1962,14 @@ func TestEC2Route(t *testing.T) { // as a default route will always be present in each route table test: "no routes", dirName: "aws_ec2_route_empty", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllRouteTables").Return([]*ec2.RouteTable{}, nil) }, }, { test: "multiple routes (mixed default_route_table and route_table)", dirName: "aws_ec2_route_multiple", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllRouteTables").Return([]*ec2.RouteTable{ { RouteTableId: awssdk.String("rtb-096bdfb69309c54c3"), // table1 @@ -1976,8 +2049,10 @@ func TestEC2Route(t *testing.T) { { test: "cannot list routes", dirName: "aws_ec2_route_list", - mocks: func(repository *repository.MockEC2Repository) { + mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllRouteTables").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsRouteResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsRouteResourceType, resourceaws.AwsRouteTableResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -2002,9 +2077,9 @@ func TestEC2Route(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -2037,6 +2112,8 @@ func TestEC2Route(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsRouteResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -2046,13 +2123,13 @@ func TestVpcSecurityGroupRule(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockEC2Repository) + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) wantErr error }{ { test: "no security group rules", dirName: "vpc_security_group_rule_empty", - mocks: func(client *repository.MockEC2Repository) { + mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllSecurityGroups").Once().Return([]*ec2.SecurityGroup{ { GroupId: awssdk.String("sg-0254c038e32f25530"), @@ -2066,7 +2143,7 @@ func TestVpcSecurityGroupRule(t *testing.T) { { test: "with security group rules", dirName: "vpc_security_group_rule_multiple", - mocks: func(client *repository.MockEC2Repository) { + mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllSecurityGroups").Once().Return([]*ec2.SecurityGroup{ { GroupId: awssdk.String("sg-0254c038e32f25530"), @@ -2162,8 +2239,10 @@ func TestVpcSecurityGroupRule(t *testing.T) { { test: "cannot list security group rules", dirName: "vpc_security_group_rule_empty", - mocks: func(client *repository.MockEC2Repository) { + mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllSecurityGroups").Once().Return(nil, nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsSecurityGroupRuleResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsSecurityGroupRuleResourceType, resourceaws.AwsSecurityGroupResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -2178,7 +2257,7 @@ func TestVpcSecurityGroupRule(t *testing.T) { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - session := session.Must(session.NewSessionWithOptions(session.Options{ + sess := session.Must(session.NewSessionWithOptions(session.Options{ SharedConfigState: session.SharedConfigEnable, })) @@ -2188,9 +2267,9 @@ func TestVpcSecurityGroupRule(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockEC2Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.EC2Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -2207,7 +2286,7 @@ func TestVpcSecurityGroupRule(t *testing.T) { t.Fatal(err) } provider.ShouldUpdate() - repo = repository.NewEC2Repository(session, cache.New(0)) + repo = repository.NewEC2Repository(sess, cache.New(0)) } remoteLibrary.AddEnumerator(aws.NewVPCSecurityGroupRuleEnumerator(repo, factory)) @@ -2223,6 +2302,8 @@ func TestVpcSecurityGroupRule(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsSecurityGroupRuleResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } diff --git a/pkg/remote/ecr_scanner_test.go b/pkg/remote/ecr_scanner_test.go index 39e0176e..e34a0eb1 100644 --- a/pkg/remote/ecr_scanner_test.go +++ b/pkg/remote/ecr_scanner_test.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/ecr" "github.com/cloudskiff/driftctl/mocks" "github.com/cloudskiff/driftctl/pkg/filter" + "github.com/cloudskiff/driftctl/pkg/remote/alerts" "github.com/cloudskiff/driftctl/pkg/remote/aws" "github.com/cloudskiff/driftctl/pkg/remote/aws/repository" "github.com/cloudskiff/driftctl/pkg/remote/cache" @@ -28,13 +29,13 @@ func TestECRRepository(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockECRRepository) + mocks func(*repository.MockECRRepository, *mocks.AlerterInterface) err error }{ { test: "no repository", dirName: "aws_ecr_repository_empty", - mocks: func(client *repository.MockECRRepository) { + mocks: func(client *repository.MockECRRepository, alerter *mocks.AlerterInterface) { client.On("ListAllRepositories").Return([]*ecr.Repository{}, nil) }, err: nil, @@ -42,7 +43,7 @@ func TestECRRepository(t *testing.T) { { test: "multiple repositories", dirName: "aws_ecr_repository_multiple", - mocks: func(client *repository.MockECRRepository) { + mocks: func(client *repository.MockECRRepository, alerter *mocks.AlerterInterface) { client.On("ListAllRepositories").Return([]*ecr.Repository{ {RepositoryName: awssdk.String("test_ecr")}, {RepositoryName: awssdk.String("bar")}, @@ -53,8 +54,10 @@ func TestECRRepository(t *testing.T) { { test: "cannot list repository", dirName: "aws_ecr_repository_empty", - mocks: func(client *repository.MockECRRepository) { + mocks: func(client *repository.MockECRRepository, alerter *mocks.AlerterInterface) { client.On("ListAllRepositories").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsEcrRepositoryResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsEcrRepositoryResourceType, resourceaws.AwsEcrRepositoryResourceType, alerts.EnumerationPhase)).Return() }, err: nil, }, @@ -79,9 +82,9 @@ func TestECRRepository(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockECRRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.ECRRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -114,6 +117,8 @@ func TestECRRepository(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsEcrRepositoryResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } diff --git a/pkg/remote/github_branch_protection_scanner_test.go b/pkg/remote/github_branch_protection_scanner_test.go index fe2eede8..0a6f7830 100644 --- a/pkg/remote/github_branch_protection_scanner_test.go +++ b/pkg/remote/github_branch_protection_scanner_test.go @@ -5,6 +5,7 @@ import ( "github.com/cloudskiff/driftctl/mocks" "github.com/cloudskiff/driftctl/pkg/filter" + "github.com/cloudskiff/driftctl/pkg/remote/alerts" "github.com/cloudskiff/driftctl/pkg/remote/cache" "github.com/cloudskiff/driftctl/pkg/remote/common" "github.com/cloudskiff/driftctl/pkg/remote/github" @@ -12,6 +13,7 @@ import ( "github.com/cloudskiff/driftctl/pkg/terraform" testresource "github.com/cloudskiff/driftctl/test/resource" tftest "github.com/cloudskiff/driftctl/test/terraform" + "github.com/pkg/errors" "github.com/stretchr/testify/mock" "github.com/cloudskiff/driftctl/pkg/resource" @@ -25,13 +27,13 @@ func TestScanGithubBranchProtection(t *testing.T) { cases := []struct { test string dirName string - mocks func(client *github.MockGithubRepository) + mocks func(*github.MockGithubRepository, *mocks.AlerterInterface) err error }{ { test: "no branch protection", dirName: "github_branch_protection_empty", - mocks: func(client *github.MockGithubRepository) { + mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { client.On("ListBranchProtection").Return([]string{}, nil) }, err: nil, @@ -39,7 +41,7 @@ func TestScanGithubBranchProtection(t *testing.T) { { test: "Multiple branch protections", dirName: "github_branch_protection_multiples", - mocks: func(client *github.MockGithubRepository) { + mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { client.On("ListBranchProtection").Return([]string{ "MDIwOkJyYW5jaFByb3RlY3Rpb25SdWxlMTk1NDg0NzI=", //"repo0:main" "MDIwOkJyYW5jaFByb3RlY3Rpb25SdWxlMTk1NDg0Nzg=", //"repo0:toto" @@ -51,13 +53,22 @@ func TestScanGithubBranchProtection(t *testing.T) { }, err: nil, }, + { + test: "cannot list branch protections", + dirName: "github_branch_protection_empty", + mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { + client.On("ListBranchProtection").Return(nil, errors.New("Your token has not been granted the required scopes to execute this query.")) + + alerter.On("SendAlert", githubres.GithubBranchProtectionResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteGithubTerraform, githubres.GithubBranchProtectionResourceType, githubres.GithubBranchProtectionResourceType, alerts.EnumerationPhase)).Return() + }, + err: nil, + }, } schemaRepository := testresource.InitFakeSchemaRepository("github", "4.4.0") githubres.InitResourcesMetadata(schemaRepository) factory := terraform.NewTerraformResourceFactory(schemaRepository) deserializer := resource.NewDeserializer(factory) - alerter := &mocks.AlerterInterface{} for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -68,8 +79,11 @@ func TestScanGithubBranchProtection(t *testing.T) { providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() + // Initialize mocks + alerter := &mocks.AlerterInterface{} mockedRepo := github.MockGithubRepository{} - c.mocks(&mockedRepo) + c.mocks(&mockedRepo, alerter) + var repo github.GithubRepository = &mockedRepo realProvider, err := tftest.InitTestGithubProvider(providerLibrary, "4.4.0") @@ -101,6 +115,8 @@ func TestScanGithubBranchProtection(t *testing.T) { return } test.TestAgainstGoldenFile(got, githubres.GithubBranchProtectionResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + mockedRepo.AssertExpectations(tt) + alerter.AssertExpectations(tt) }) } } diff --git a/pkg/remote/github_membership_scanner_test.go b/pkg/remote/github_membership_scanner_test.go index ad159e9c..9a40bf7f 100644 --- a/pkg/remote/github_membership_scanner_test.go +++ b/pkg/remote/github_membership_scanner_test.go @@ -1,10 +1,12 @@ package remote import ( + "errors" "testing" "github.com/cloudskiff/driftctl/mocks" "github.com/cloudskiff/driftctl/pkg/filter" + "github.com/cloudskiff/driftctl/pkg/remote/alerts" "github.com/cloudskiff/driftctl/pkg/remote/cache" "github.com/cloudskiff/driftctl/pkg/remote/common" "github.com/cloudskiff/driftctl/pkg/remote/github" @@ -25,13 +27,13 @@ func TestScanGithubMembership(t *testing.T) { cases := []struct { test string dirName string - mocks func(client *github.MockGithubRepository) + mocks func(*github.MockGithubRepository, *mocks.AlerterInterface) err error }{ { test: "no members", dirName: "github_membership_empty", - mocks: func(client *github.MockGithubRepository) { + mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { client.On("ListMembership").Return([]string{}, nil) }, err: nil, @@ -39,7 +41,7 @@ func TestScanGithubMembership(t *testing.T) { { test: "Multiple membership with admin and member roles", dirName: "github_membership_multiple", - mocks: func(client *github.MockGithubRepository) { + mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { client.On("ListMembership").Return([]string{ "driftctl-test:driftctl-acceptance-tester", "driftctl-test:eliecharra", @@ -47,13 +49,22 @@ func TestScanGithubMembership(t *testing.T) { }, err: nil, }, + { + test: "cannot list membership", + dirName: "github_membership_empty", + mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { + client.On("ListMembership").Return(nil, errors.New("Your token has not been granted the required scopes to execute this query.")) + + alerter.On("SendAlert", githubres.GithubMembershipResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteGithubTerraform, githubres.GithubMembershipResourceType, githubres.GithubMembershipResourceType, alerts.EnumerationPhase)).Return() + }, + err: nil, + }, } schemaRepository := testresource.InitFakeSchemaRepository("github", "4.4.0") githubres.InitResourcesMetadata(schemaRepository) factory := terraform.NewTerraformResourceFactory(schemaRepository) deserializer := resource.NewDeserializer(factory) - alerter := &mocks.AlerterInterface{} for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -64,8 +75,11 @@ func TestScanGithubMembership(t *testing.T) { providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() + // Initialize mocks + alerter := &mocks.AlerterInterface{} mockedRepo := github.MockGithubRepository{} - c.mocks(&mockedRepo) + c.mocks(&mockedRepo, alerter) + var repo github.GithubRepository = &mockedRepo realProvider, err := tftest.InitTestGithubProvider(providerLibrary, "4.4.0") @@ -97,6 +111,8 @@ func TestScanGithubMembership(t *testing.T) { return } test.TestAgainstGoldenFile(got, githubres.GithubMembershipResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + mockedRepo.AssertExpectations(tt) + alerter.AssertExpectations(tt) }) } } diff --git a/pkg/remote/github_repository_scanner_test.go b/pkg/remote/github_repository_scanner_test.go index 54b7565e..0c213703 100644 --- a/pkg/remote/github_repository_scanner_test.go +++ b/pkg/remote/github_repository_scanner_test.go @@ -1,10 +1,12 @@ package remote import ( + "errors" "testing" "github.com/cloudskiff/driftctl/mocks" "github.com/cloudskiff/driftctl/pkg/filter" + "github.com/cloudskiff/driftctl/pkg/remote/alerts" "github.com/cloudskiff/driftctl/pkg/remote/cache" "github.com/cloudskiff/driftctl/pkg/remote/common" "github.com/cloudskiff/driftctl/pkg/remote/github" @@ -25,13 +27,13 @@ func TestScanGithubRepository(t *testing.T) { tests := []struct { test string dirName string - mocks func(client *github.MockGithubRepository) + mocks func(*github.MockGithubRepository, *mocks.AlerterInterface) err error }{ { test: "no github repos", dirName: "github_repository_empty", - mocks: func(client *github.MockGithubRepository) { + mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { client.On("ListRepositories").Return([]string{}, nil) }, err: nil, @@ -39,7 +41,7 @@ func TestScanGithubRepository(t *testing.T) { { test: "Multiple github repos Table", dirName: "github_repository_multiple", - mocks: func(client *github.MockGithubRepository) { + mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { client.On("ListRepositories").Return([]string{ "driftctl", "driftctl-demos", @@ -47,13 +49,22 @@ func TestScanGithubRepository(t *testing.T) { }, err: nil, }, + { + test: "cannot list repositories", + dirName: "github_repository_empty", + mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { + client.On("ListRepositories").Return(nil, errors.New("Your token has not been granted the required scopes to execute this query.")) + + alerter.On("SendAlert", githubres.GithubRepositoryResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteGithubTerraform, githubres.GithubRepositoryResourceType, githubres.GithubRepositoryResourceType, alerts.EnumerationPhase)).Return() + }, + err: nil, + }, } schemaRepository := testresource.InitFakeSchemaRepository("github", "4.4.0") githubres.InitResourcesMetadata(schemaRepository) factory := terraform.NewTerraformResourceFactory(schemaRepository) deserializer := resource.NewDeserializer(factory) - alerter := &mocks.AlerterInterface{} for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -64,8 +75,11 @@ func TestScanGithubRepository(t *testing.T) { providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() + // Initialize mocks + alerter := &mocks.AlerterInterface{} mockedRepo := github.MockGithubRepository{} - c.mocks(&mockedRepo) + c.mocks(&mockedRepo, alerter) + var repo github.GithubRepository = &mockedRepo realProvider, err := tftest.InitTestGithubProvider(providerLibrary, "4.4.0") @@ -97,6 +111,8 @@ func TestScanGithubRepository(t *testing.T) { return } test.TestAgainstGoldenFile(got, githubres.GithubRepositoryResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + mockedRepo.AssertExpectations(tt) + alerter.AssertExpectations(tt) }) } } diff --git a/pkg/remote/github_team_membership_scanner_test.go b/pkg/remote/github_team_membership_scanner_test.go index 588a7852..0c9ea800 100644 --- a/pkg/remote/github_team_membership_scanner_test.go +++ b/pkg/remote/github_team_membership_scanner_test.go @@ -1,10 +1,12 @@ package remote import ( + "errors" "testing" "github.com/cloudskiff/driftctl/mocks" "github.com/cloudskiff/driftctl/pkg/filter" + "github.com/cloudskiff/driftctl/pkg/remote/alerts" "github.com/cloudskiff/driftctl/pkg/remote/cache" "github.com/cloudskiff/driftctl/pkg/remote/common" "github.com/cloudskiff/driftctl/pkg/remote/github" @@ -25,13 +27,13 @@ func TestScanGithubTeamMembership(t *testing.T) { cases := []struct { test string dirName string - mocks func(client *github.MockGithubRepository) + mocks func(*github.MockGithubRepository, *mocks.AlerterInterface) err error }{ { test: "no github team memberships", dirName: "github_team_membership_empty", - mocks: func(client *github.MockGithubRepository) { + mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { client.On("ListTeamMemberships").Return([]string{}, nil) }, err: nil, @@ -39,7 +41,7 @@ func TestScanGithubTeamMembership(t *testing.T) { { test: "multiple github team memberships", dirName: "github_team_membership_multiple", - mocks: func(client *github.MockGithubRepository) { + mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { client.On("ListTeamMemberships").Return([]string{ "4570529:driftctl-acceptance-tester", "4570529:wbeuil", @@ -47,13 +49,22 @@ func TestScanGithubTeamMembership(t *testing.T) { }, err: nil, }, + { + test: "cannot list team membership", + dirName: "github_team_membership_empty", + mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { + client.On("ListTeamMemberships").Return(nil, errors.New("Your token has not been granted the required scopes to execute this query.")) + + alerter.On("SendAlert", githubres.GithubTeamMembershipResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteGithubTerraform, githubres.GithubTeamMembershipResourceType, githubres.GithubTeamMembershipResourceType, alerts.EnumerationPhase)).Return() + }, + err: nil, + }, } schemaRepository := testresource.InitFakeSchemaRepository("github", "4.4.0") githubres.InitResourcesMetadata(schemaRepository) factory := terraform.NewTerraformResourceFactory(schemaRepository) deserializer := resource.NewDeserializer(factory) - alerter := &mocks.AlerterInterface{} for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -64,8 +75,11 @@ func TestScanGithubTeamMembership(t *testing.T) { providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() + // Initialize mocks + alerter := &mocks.AlerterInterface{} mockedRepo := github.MockGithubRepository{} - c.mocks(&mockedRepo) + c.mocks(&mockedRepo, alerter) + var repo github.GithubRepository = &mockedRepo realProvider, err := tftest.InitTestGithubProvider(providerLibrary, "4.4.0") @@ -97,6 +111,8 @@ func TestScanGithubTeamMembership(t *testing.T) { return } test.TestAgainstGoldenFile(got, githubres.GithubTeamMembershipResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + mockedRepo.AssertExpectations(tt) + alerter.AssertExpectations(tt) }) } } diff --git a/pkg/remote/github_team_scanner_test.go b/pkg/remote/github_team_scanner_test.go index e83167b6..99867ef5 100644 --- a/pkg/remote/github_team_scanner_test.go +++ b/pkg/remote/github_team_scanner_test.go @@ -1,10 +1,12 @@ package remote import ( + "errors" "testing" "github.com/cloudskiff/driftctl/mocks" "github.com/cloudskiff/driftctl/pkg/filter" + "github.com/cloudskiff/driftctl/pkg/remote/alerts" "github.com/cloudskiff/driftctl/pkg/remote/cache" "github.com/cloudskiff/driftctl/pkg/remote/common" "github.com/cloudskiff/driftctl/pkg/remote/github" @@ -25,13 +27,13 @@ func TestScanGithubTeam(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *github.MockGithubRepository) + mocks func(*github.MockGithubRepository, *mocks.AlerterInterface) err error }{ { test: "no github teams", dirName: "github_teams_empty", - mocks: func(client *github.MockGithubRepository) { + mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { client.On("ListTeams").Return([]github.Team{}, nil) }, err: nil, @@ -39,7 +41,7 @@ func TestScanGithubTeam(t *testing.T) { { test: "Multiple github teams with parent", dirName: "github_teams_multiple", - mocks: func(client *github.MockGithubRepository) { + mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { client.On("ListTeams").Return([]github.Team{ {DatabaseId: 4556811}, // github_team.team1 {DatabaseId: 4556812}, // github_team.team2 @@ -48,13 +50,22 @@ func TestScanGithubTeam(t *testing.T) { }, err: nil, }, + { + test: "cannot list teams", + dirName: "github_teams_empty", + mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { + client.On("ListTeams").Return(nil, errors.New("Your token has not been granted the required scopes to execute this query.")) + + alerter.On("SendAlert", githubres.GithubTeamResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteGithubTerraform, githubres.GithubTeamResourceType, githubres.GithubTeamResourceType, alerts.EnumerationPhase)).Return() + }, + err: nil, + }, } schemaRepository := testresource.InitFakeSchemaRepository("github", "4.4.0") githubres.InitResourcesMetadata(schemaRepository) factory := terraform.NewTerraformResourceFactory(schemaRepository) deserializer := resource.NewDeserializer(factory) - alerter := &mocks.AlerterInterface{} for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -65,8 +76,11 @@ func TestScanGithubTeam(t *testing.T) { providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() + // Initialize mocks + alerter := &mocks.AlerterInterface{} mockedRepo := github.MockGithubRepository{} - c.mocks(&mockedRepo) + c.mocks(&mockedRepo, alerter) + var repo github.GithubRepository = &mockedRepo realProvider, err := tftest.InitTestGithubProvider(providerLibrary, "4.4.0") @@ -98,6 +112,8 @@ func TestScanGithubTeam(t *testing.T) { return } test.TestAgainstGoldenFile(got, githubres.GithubTeamResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + mockedRepo.AssertExpectations(tt) + alerter.AssertExpectations(tt) }) } } diff --git a/pkg/remote/iam_scanner_test.go b/pkg/remote/iam_scanner_test.go index ccd6a1ba..de3bb106 100644 --- a/pkg/remote/iam_scanner_test.go +++ b/pkg/remote/iam_scanner_test.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/iam" "github.com/cloudskiff/driftctl/mocks" "github.com/cloudskiff/driftctl/pkg/filter" + "github.com/cloudskiff/driftctl/pkg/remote/alerts" remoteaws "github.com/cloudskiff/driftctl/pkg/remote/aws" "github.com/cloudskiff/driftctl/pkg/remote/aws/repository" "github.com/cloudskiff/driftctl/pkg/remote/cache" @@ -29,13 +30,13 @@ func TestIamUser(t *testing.T) { cases := []struct { test string dirName string - mocks func(repo *repository.MockIAMRepository) + mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) wantErr error }{ { test: "no iam user", dirName: "iam_user_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllUsers").Return([]*iam.User{}, nil) }, wantErr: nil, @@ -43,7 +44,7 @@ func TestIamUser(t *testing.T) { { test: "iam multiples users", dirName: "iam_user_multiple", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllUsers").Return([]*iam.User{ { UserName: aws.String("test-driftctl-0"), @@ -61,8 +62,10 @@ func TestIamUser(t *testing.T) { { test: "cannot list iam user", dirName: "iam_user_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllUsers").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsIamUserResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsIamUserResourceType, resourceaws.AwsIamUserResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -86,9 +89,9 @@ func TestIamUser(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockIAMRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.IAMRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -121,6 +124,8 @@ func TestIamUser(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsIamUserResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -130,13 +135,13 @@ func TestIamUserPolicy(t *testing.T) { cases := []struct { test string dirName string - mocks func(repo *repository.MockIAMRepository) + mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) wantErr error }{ { test: "no iam user policy", dirName: "iam_user_policy_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { users := []*iam.User{ { UserName: aws.String("loadbalancer"), @@ -150,7 +155,7 @@ func TestIamUserPolicy(t *testing.T) { { test: "iam multiples users multiple policies", dirName: "iam_user_policy_multiple", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { users := []*iam.User{ { UserName: aws.String("loadbalancer"), @@ -183,17 +188,21 @@ func TestIamUserPolicy(t *testing.T) { { test: "cannot list user", dirName: "iam_user_policy_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllUsers").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsIamUserPolicyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsIamUserPolicyResourceType, resourceaws.AwsIamUserResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, { test: "cannot list user policy", dirName: "iam_user_policy_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllUsers").Once().Return([]*iam.User{}, nil) repo.On("ListAllUserPolicies", mock.Anything).Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsIamUserPolicyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsIamUserPolicyResourceType, resourceaws.AwsIamUserPolicyResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -217,9 +226,9 @@ func TestIamUserPolicy(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockIAMRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.IAMRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -252,6 +261,8 @@ func TestIamUserPolicy(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsIamUserPolicyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -261,13 +272,13 @@ func TestIamPolicy(t *testing.T) { cases := []struct { test string dirName string - mocks func(repo *repository.MockIAMRepository) + mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) wantErr error }{ { test: "no iam custom policies", dirName: "iam_policy_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllPolicies").Once().Return([]*iam.Policy{}, nil) }, wantErr: nil, @@ -275,7 +286,7 @@ func TestIamPolicy(t *testing.T) { { test: "iam multiples custom policies", dirName: "iam_policy_multiple", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllPolicies").Once().Return([]*iam.Policy{ { Arn: aws.String("arn:aws:iam::929327065333:policy/policy-0"), @@ -293,8 +304,10 @@ func TestIamPolicy(t *testing.T) { { test: "cannot list iam custom policies", dirName: "iam_policy_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllPolicies").Once().Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsIamPolicyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsIamPolicyResourceType, resourceaws.AwsIamPolicyResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -319,9 +332,9 @@ func TestIamPolicy(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockIAMRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.IAMRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -354,6 +367,8 @@ func TestIamPolicy(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsIamPolicyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -363,13 +378,13 @@ func TestIamRole(t *testing.T) { cases := []struct { test string dirName string - mocks func(repo *repository.MockIAMRepository) + mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) wantErr error }{ { test: "no iam roles", dirName: "iam_role_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllRoles").Return([]*iam.Role{}, nil) }, wantErr: nil, @@ -377,7 +392,7 @@ func TestIamRole(t *testing.T) { { test: "iam multiples roles", dirName: "iam_role_multiple", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllRoles").Return([]*iam.Role{ { RoleName: aws.String("test_role_0"), @@ -398,7 +413,7 @@ func TestIamRole(t *testing.T) { { test: "iam roles ignore services roles", dirName: "iam_role_ignore_services_roles", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllRoles").Return([]*iam.Role{ { RoleName: aws.String("AWSServiceRoleForOrganizations"), @@ -437,9 +452,9 @@ func TestIamRole(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockIAMRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.IAMRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -472,6 +487,8 @@ func TestIamRole(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsIamRoleResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -481,13 +498,13 @@ func TestIamRolePolicyAttachment(t *testing.T) { cases := []struct { test string dirName string - mocks func(repo *repository.MockIAMRepository) + mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) err error }{ { test: "no iam role policy", dirName: "aws_iam_role_policy_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { roles := []*iam.Role{ { RoleName: aws.String("test-role"), @@ -501,7 +518,7 @@ func TestIamRolePolicyAttachment(t *testing.T) { { test: "iam multiples roles multiple policies", dirName: "aws_iam_role_policy_attachment_multiple", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { roles := []*iam.Role{ { RoleName: aws.String("test-role"), @@ -561,7 +578,7 @@ func TestIamRolePolicyAttachment(t *testing.T) { { test: "iam multiples roles for ignored roles", dirName: "aws_iam_role_policy_attachment_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { roles := []*iam.Role{ { RoleName: aws.String("AWSServiceRoleForSupport"), @@ -579,16 +596,20 @@ func TestIamRolePolicyAttachment(t *testing.T) { { test: "Cannot list roles", dirName: "aws_iam_role_policy_attachment_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllRoles").Once().Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsIamRolePolicyAttachmentResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsIamRolePolicyAttachmentResourceType, resourceaws.AwsIamRoleResourceType, alerts.EnumerationPhase)).Return() }, }, { test: "Cannot list roles policy attachment", dirName: "aws_iam_role_policy_attachment_empty", - mocks: func(repo *repository.MockIAMRepository) { - repo.On("ListAllRoles").Once().Return([]*iam.Role{}, nil) + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { + repo.On("ListAllRoles").Once().Return([]*iam.Role{{RoleName: aws.String("test")}}, nil) repo.On("ListAllRolePolicyAttachments", mock.Anything).Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsIamRolePolicyAttachmentResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsIamRolePolicyAttachmentResourceType, resourceaws.AwsIamRolePolicyAttachmentResourceType, alerts.EnumerationPhase)).Return() }, }, } @@ -612,9 +633,9 @@ func TestIamRolePolicyAttachment(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockIAMRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.IAMRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -647,6 +668,8 @@ func TestIamRolePolicyAttachment(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsIamRolePolicyAttachmentResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -656,13 +679,13 @@ func TestIamAccessKey(t *testing.T) { cases := []struct { test string dirName string - mocks func(repo *repository.MockIAMRepository) + mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) wantErr error }{ { test: "no iam access_key", dirName: "iam_access_key_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { users := []*iam.User{ { UserName: aws.String("test-driftctl"), @@ -676,7 +699,7 @@ func TestIamAccessKey(t *testing.T) { { test: "iam multiples keys for multiples users", dirName: "iam_access_key_multiple", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { users := []*iam.User{ { UserName: aws.String("test-driftctl"), @@ -707,17 +730,21 @@ func TestIamAccessKey(t *testing.T) { { test: "Cannot list iam user", dirName: "iam_access_key_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllUsers").Once().Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsIamAccessKeyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsIamAccessKeyResourceType, resourceaws.AwsIamUserResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, { test: "Cannot list iam access_key", dirName: "iam_access_key_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllUsers").Once().Return([]*iam.User{}, nil) repo.On("ListAllAccessKeys", mock.Anything).Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsIamAccessKeyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsIamAccessKeyResourceType, resourceaws.AwsIamAccessKeyResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -742,9 +769,9 @@ func TestIamAccessKey(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockIAMRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.IAMRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -777,6 +804,8 @@ func TestIamAccessKey(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsIamAccessKeyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -786,13 +815,13 @@ func TestIamUserPolicyAttachment(t *testing.T) { cases := []struct { test string dirName string - mocks func(repo *repository.MockIAMRepository) + mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) wantErr error }{ { test: "no iam user policy", dirName: "iam_user_policy_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { users := []*iam.User{ { UserName: aws.String("loadbalancer"), @@ -806,7 +835,7 @@ func TestIamUserPolicyAttachment(t *testing.T) { { test: "iam multiples users multiple policies", dirName: "iam_user_policy_attachment_multiple", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { users := []*iam.User{ { UserName: aws.String("loadbalancer"), @@ -912,17 +941,21 @@ func TestIamUserPolicyAttachment(t *testing.T) { { test: "cannot list user", dirName: "iam_user_policy_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllUsers").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsIamUserPolicyAttachmentResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsIamUserPolicyAttachmentResourceType, resourceaws.AwsIamUserResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, { test: "cannot list user policies attachment", dirName: "iam_user_policy_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllUsers").Once().Return([]*iam.User{}, nil) repo.On("ListAllUserPolicyAttachments", mock.Anything).Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsIamUserPolicyAttachmentResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsIamUserPolicyAttachmentResourceType, resourceaws.AwsIamUserPolicyAttachmentResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -947,9 +980,9 @@ func TestIamUserPolicyAttachment(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockIAMRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.IAMRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -982,6 +1015,8 @@ func TestIamUserPolicyAttachment(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsIamUserPolicyAttachmentResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -991,13 +1026,13 @@ func TestIamRolePolicy(t *testing.T) { cases := []struct { test string dirName string - mocks func(repo *repository.MockIAMRepository) + mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) wantErr error }{ { test: "no iam role policy", dirName: "iam_role_policy_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { roles := []*iam.Role{ { RoleName: aws.String("test_role"), @@ -1011,7 +1046,7 @@ func TestIamRolePolicy(t *testing.T) { { test: "multiples roles with inline policies", dirName: "iam_role_policy_multiple", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { roles := []*iam.Role{ { RoleName: aws.String("test_role_0"), @@ -1035,17 +1070,21 @@ func TestIamRolePolicy(t *testing.T) { { test: "Cannot list roles", dirName: "iam_role_policy_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllRoles").Once().Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsIamRolePolicyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsIamRolePolicyResourceType, resourceaws.AwsIamRoleResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, { test: "cannot list role policy", dirName: "iam_role_policy_empty", - mocks: func(repo *repository.MockIAMRepository) { + mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllRoles").Once().Return([]*iam.Role{}, nil) repo.On("ListAllRolePolicies", mock.Anything).Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsIamRolePolicyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsIamRolePolicyResourceType, resourceaws.AwsIamRolePolicyResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -1070,9 +1109,9 @@ func TestIamRolePolicy(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockIAMRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.IAMRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -1105,6 +1144,8 @@ func TestIamRolePolicy(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsIamRolePolicyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } diff --git a/pkg/remote/kms_scanner_test.go b/pkg/remote/kms_scanner_test.go index 3f30df59..c60a7d6b 100644 --- a/pkg/remote/kms_scanner_test.go +++ b/pkg/remote/kms_scanner_test.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/kms" "github.com/cloudskiff/driftctl/mocks" "github.com/cloudskiff/driftctl/pkg/filter" + "github.com/cloudskiff/driftctl/pkg/remote/alerts" "github.com/cloudskiff/driftctl/pkg/remote/aws" "github.com/cloudskiff/driftctl/pkg/remote/aws/repository" "github.com/cloudskiff/driftctl/pkg/remote/cache" @@ -28,20 +29,20 @@ func TestKMSKey(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockKMSRepository) + mocks func(*repository.MockKMSRepository, *mocks.AlerterInterface) wantErr error }{ { test: "no keys", dirName: "aws_kms_key_empty", - mocks: func(repository *repository.MockKMSRepository) { + mocks: func(repository *repository.MockKMSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllKeys").Return([]*kms.KeyListEntry{}, nil) }, }, { test: "multiple keys", dirName: "aws_kms_key_multiple", - mocks: func(repository *repository.MockKMSRepository) { + mocks: func(repository *repository.MockKMSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllKeys").Return([]*kms.KeyListEntry{ {KeyId: awssdk.String("8ee21d91-c000-428c-8032-235aac55da36")}, {KeyId: awssdk.String("5d765f32-bfdc-4610-b6ab-f82db5d0601b")}, @@ -52,8 +53,10 @@ func TestKMSKey(t *testing.T) { { test: "cannot list keys", dirName: "aws_kms_key_list", - mocks: func(repository *repository.MockKMSRepository) { + mocks: func(repository *repository.MockKMSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllKeys").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsKmsKeyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsKmsKeyResourceType, resourceaws.AwsKmsKeyResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -78,9 +81,9 @@ func TestKMSKey(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockKMSRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.KMSRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -113,6 +116,8 @@ func TestKMSKey(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsKmsKeyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -121,20 +126,20 @@ func TestKMSAlias(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockKMSRepository) + mocks func(*repository.MockKMSRepository, *mocks.AlerterInterface) wantErr error }{ { test: "no aliases", dirName: "aws_kms_alias_empty", - mocks: func(repository *repository.MockKMSRepository) { + mocks: func(repository *repository.MockKMSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllAliases").Return([]*kms.AliasListEntry{}, nil) }, }, { test: "multiple aliases", dirName: "aws_kms_alias_multiple", - mocks: func(repository *repository.MockKMSRepository) { + mocks: func(repository *repository.MockKMSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllAliases").Return([]*kms.AliasListEntry{ {AliasName: awssdk.String("alias/foo")}, {AliasName: awssdk.String("alias/bar")}, @@ -145,8 +150,10 @@ func TestKMSAlias(t *testing.T) { { test: "cannot list aliases", dirName: "aws_kms_alias_list", - mocks: func(repository *repository.MockKMSRepository) { + mocks: func(repository *repository.MockKMSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllAliases").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsKmsAliasResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsKmsAliasResourceType, resourceaws.AwsKmsAliasResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -171,9 +178,9 @@ func TestKMSAlias(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockKMSRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.KMSRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -206,6 +213,8 @@ func TestKMSAlias(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsKmsAliasResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } diff --git a/pkg/remote/lambda_scanner_test.go b/pkg/remote/lambda_scanner_test.go index 04a4e523..8aada2bd 100644 --- a/pkg/remote/lambda_scanner_test.go +++ b/pkg/remote/lambda_scanner_test.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/lambda" "github.com/cloudskiff/driftctl/mocks" "github.com/cloudskiff/driftctl/pkg/filter" + "github.com/cloudskiff/driftctl/pkg/remote/alerts" "github.com/cloudskiff/driftctl/pkg/remote/aws" "github.com/cloudskiff/driftctl/pkg/remote/cache" "github.com/cloudskiff/driftctl/pkg/remote/common" @@ -31,13 +32,13 @@ func TestScanLambdaFunction(t *testing.T) { tests := []struct { test string dirName string - mocks func(repo *repository.MockLambdaRepository) + mocks func(*repository.MockLambdaRepository, *mocks.AlerterInterface) err error }{ { test: "no lambda functions", dirName: "lambda_function_empty", - mocks: func(repo *repository.MockLambdaRepository) { + mocks: func(repo *repository.MockLambdaRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllLambdaFunctions").Return([]*lambda.FunctionConfiguration{}, nil) }, err: nil, @@ -45,7 +46,7 @@ func TestScanLambdaFunction(t *testing.T) { { test: "with lambda functions", dirName: "lambda_function_multiple", - mocks: func(repo *repository.MockLambdaRepository) { + mocks: func(repo *repository.MockLambdaRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllLambdaFunctions").Return([]*lambda.FunctionConfiguration{ { FunctionName: awssdk.String("foo"), @@ -60,7 +61,7 @@ func TestScanLambdaFunction(t *testing.T) { { test: "One lambda with signing", dirName: "lambda_function_signed", - mocks: func(repo *repository.MockLambdaRepository) { + mocks: func(repo *repository.MockLambdaRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllLambdaFunctions").Return([]*lambda.FunctionConfiguration{ { FunctionName: awssdk.String("foo"), @@ -72,8 +73,10 @@ func TestScanLambdaFunction(t *testing.T) { { test: "cannot list lambda functions", dirName: "lambda_function_empty", - mocks: func(repo *repository.MockLambdaRepository) { + mocks: func(repo *repository.MockLambdaRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllLambdaFunctions").Return([]*lambda.FunctionConfiguration{}, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsLambdaFunctionResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsLambdaFunctionResourceType, resourceaws.AwsLambdaFunctionResourceType, alerts.EnumerationPhase)).Return() }, err: nil, }, @@ -92,16 +95,15 @@ func TestScanLambdaFunction(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() // Initialize mocks + alerter := &mocks.AlerterInterface{} fakeRepo := &repository.MockLambdaRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.LambdaRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -134,6 +136,8 @@ func TestScanLambdaFunction(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsLambdaFunctionResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -143,13 +147,13 @@ func TestScanLambdaEventSourceMapping(t *testing.T) { tests := []struct { test string dirName string - mocks func(repo *repository.MockLambdaRepository) + mocks func(*repository.MockLambdaRepository, *mocks.AlerterInterface) err error }{ { test: "no EventSourceMapping", dirName: "lambda_source_mapping_empty", - mocks: func(repo *repository.MockLambdaRepository) { + mocks: func(repo *repository.MockLambdaRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllLambdaEventSourceMappings").Return([]*lambda.EventSourceMappingConfiguration{}, nil) }, err: nil, @@ -157,7 +161,7 @@ func TestScanLambdaEventSourceMapping(t *testing.T) { { test: "with 2 sqs EventSourceMapping", dirName: "lambda_source_mapping_sqs_multiple", - mocks: func(repo *repository.MockLambdaRepository) { + mocks: func(repo *repository.MockLambdaRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllLambdaEventSourceMappings").Return([]*lambda.EventSourceMappingConfiguration{ { UUID: awssdk.String("13ff66f8-37eb-4ad6-a0a8-594fea72df4f"), @@ -172,7 +176,7 @@ func TestScanLambdaEventSourceMapping(t *testing.T) { { test: "with dynamo EventSourceMapping", dirName: "lambda_source_mapping_dynamo_multiple", - mocks: func(repo *repository.MockLambdaRepository) { + mocks: func(repo *repository.MockLambdaRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllLambdaEventSourceMappings").Return([]*lambda.EventSourceMappingConfiguration{ { UUID: awssdk.String("1aa9c4a0-060b-41c1-a9ae-dc304ebcdb00"), @@ -184,8 +188,10 @@ func TestScanLambdaEventSourceMapping(t *testing.T) { { test: "cannot list lambda functions", dirName: "lambda_function_empty", - mocks: func(repo *repository.MockLambdaRepository) { + mocks: func(repo *repository.MockLambdaRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllLambdaEventSourceMappings").Return([]*lambda.EventSourceMappingConfiguration{}, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsLambdaEventSourceMappingResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsLambdaEventSourceMappingResourceType, resourceaws.AwsLambdaEventSourceMappingResourceType, alerts.EnumerationPhase)).Return() }, err: nil, }, @@ -204,16 +210,15 @@ func TestScanLambdaEventSourceMapping(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() // Initialize mocks + alerter := &mocks.AlerterInterface{} fakeRepo := &repository.MockLambdaRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.LambdaRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -246,6 +251,8 @@ func TestScanLambdaEventSourceMapping(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsLambdaEventSourceMappingResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } diff --git a/pkg/remote/rds_scanner_test.go b/pkg/remote/rds_scanner_test.go index 24ef89bb..98c7cc3f 100644 --- a/pkg/remote/rds_scanner_test.go +++ b/pkg/remote/rds_scanner_test.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/rds" "github.com/cloudskiff/driftctl/mocks" "github.com/cloudskiff/driftctl/pkg/filter" + "github.com/cloudskiff/driftctl/pkg/remote/alerts" "github.com/cloudskiff/driftctl/pkg/remote/aws" "github.com/cloudskiff/driftctl/pkg/remote/aws/repository" "github.com/cloudskiff/driftctl/pkg/remote/cache" @@ -28,20 +29,20 @@ func TestRDSDBInstance(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockRDSRepository) + mocks func(*repository.MockRDSRepository, *mocks.AlerterInterface) wantErr error }{ { test: "no db instances", dirName: "aws_rds_db_instance_empty", - mocks: func(repository *repository.MockRDSRepository) { + mocks: func(repository *repository.MockRDSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllDBInstances").Return([]*rds.DBInstance{}, nil) }, }, { test: "single db instance", dirName: "aws_rds_db_instance_single", - mocks: func(repository *repository.MockRDSRepository) { + mocks: func(repository *repository.MockRDSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllDBInstances").Return([]*rds.DBInstance{ {DBInstanceIdentifier: awssdk.String("terraform-20201015115018309600000001")}, }, nil) @@ -50,7 +51,7 @@ func TestRDSDBInstance(t *testing.T) { { test: "multiple mixed db instances", dirName: "aws_rds_db_instance_multiple", - mocks: func(repository *repository.MockRDSRepository) { + mocks: func(repository *repository.MockRDSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllDBInstances").Return([]*rds.DBInstance{ {DBInstanceIdentifier: awssdk.String("terraform-20201015115018309600000001")}, {DBInstanceIdentifier: awssdk.String("database-1")}, @@ -60,8 +61,10 @@ func TestRDSDBInstance(t *testing.T) { { test: "cannot list db instances", dirName: "aws_rds_db_instance_list", - mocks: func(repository *repository.MockRDSRepository) { + mocks: func(repository *repository.MockRDSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllDBInstances").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsDbInstanceResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsDbInstanceResourceType, resourceaws.AwsDbInstanceResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -86,9 +89,9 @@ func TestRDSDBInstance(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockRDSRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.RDSRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -121,6 +124,8 @@ func TestRDSDBInstance(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsDbInstanceResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -129,20 +134,20 @@ func TestRDSDBSubnetGroup(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockRDSRepository) + mocks func(*repository.MockRDSRepository, *mocks.AlerterInterface) wantErr error }{ { test: "no db subnet groups", dirName: "aws_rds_db_subnet_group_empty", - mocks: func(repository *repository.MockRDSRepository) { + mocks: func(repository *repository.MockRDSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllDBSubnetGroups").Return([]*rds.DBSubnetGroup{}, nil) }, }, { test: "multiple db subnet groups", dirName: "aws_rds_db_subnet_group_multiple", - mocks: func(repository *repository.MockRDSRepository) { + mocks: func(repository *repository.MockRDSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllDBSubnetGroups").Return([]*rds.DBSubnetGroup{ {DBSubnetGroupName: awssdk.String("foo")}, {DBSubnetGroupName: awssdk.String("bar")}, @@ -152,8 +157,10 @@ func TestRDSDBSubnetGroup(t *testing.T) { { test: "cannot list db subnet groups", dirName: "aws_rds_db_subnet_group_list", - mocks: func(repository *repository.MockRDSRepository) { + mocks: func(repository *repository.MockRDSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllDBSubnetGroups").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsDbSubnetGroupResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsDbSubnetGroupResourceType, resourceaws.AwsDbSubnetGroupResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -178,9 +185,9 @@ func TestRDSDBSubnetGroup(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockRDSRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.RDSRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -213,6 +220,8 @@ func TestRDSDBSubnetGroup(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsDbSubnetGroupResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } diff --git a/pkg/remote/route53_scanner_test.go b/pkg/remote/route53_scanner_test.go index 89478ea1..6d1f78d7 100644 --- a/pkg/remote/route53_scanner_test.go +++ b/pkg/remote/route53_scanner_test.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/route53" "github.com/cloudskiff/driftctl/mocks" "github.com/cloudskiff/driftctl/pkg/filter" + "github.com/cloudskiff/driftctl/pkg/remote/alerts" "github.com/cloudskiff/driftctl/pkg/remote/aws" "github.com/cloudskiff/driftctl/pkg/remote/cache" "github.com/cloudskiff/driftctl/pkg/remote/common" @@ -31,13 +32,13 @@ func TestRoute53_HealthCheck(t *testing.T) { tests := []struct { test string dirName string - mocks func(*repository.MockRoute53Repository) + mocks func(*repository.MockRoute53Repository, *mocks.AlerterInterface) err error }{ { test: "no health check", dirName: "route53_health_check_empty", - mocks: func(client *repository.MockRoute53Repository) { + mocks: func(client *repository.MockRoute53Repository, alerter *mocks.AlerterInterface) { client.On("ListAllHealthChecks").Return([]*route53.HealthCheck{}, nil) }, err: nil, @@ -45,7 +46,7 @@ func TestRoute53_HealthCheck(t *testing.T) { { test: "Multiple health check", dirName: "route53_health_check_multiple", - mocks: func(client *repository.MockRoute53Repository) { + mocks: func(client *repository.MockRoute53Repository, alerter *mocks.AlerterInterface) { client.On("ListAllHealthChecks").Return([]*route53.HealthCheck{ {Id: awssdk.String("7001a9df-ded4-4802-9909-668eb80b972b")}, {Id: awssdk.String("84fc318a-2e0d-41d6-b638-280e2f0f4e26")}, @@ -56,8 +57,10 @@ func TestRoute53_HealthCheck(t *testing.T) { { test: "cannot list health check", dirName: "route53_health_check_empty", - mocks: func(client *repository.MockRoute53Repository) { + mocks: func(client *repository.MockRoute53Repository, alerter *mocks.AlerterInterface) { client.On("ListAllHealthChecks").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsRoute53HealthCheckResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsRoute53HealthCheckResourceType, resourceaws.AwsRoute53HealthCheckResourceType, alerts.EnumerationPhase)).Return() }, err: nil, }, @@ -82,9 +85,9 @@ func TestRoute53_HealthCheck(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockRoute53Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.Route53Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -117,6 +120,8 @@ func TestRoute53_HealthCheck(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsRoute53HealthCheckResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -126,13 +131,13 @@ func TestRoute53_Zone(t *testing.T) { tests := []struct { test string dirName string - mocks func(*repository.MockRoute53Repository) + mocks func(*repository.MockRoute53Repository, *mocks.AlerterInterface) err error }{ { test: "no zones", dirName: "route53_zone_empty", - mocks: func(client *repository.MockRoute53Repository) { + mocks: func(client *repository.MockRoute53Repository, alerter *mocks.AlerterInterface) { client.On("ListAllZones").Return( []*route53.HostedZone{}, nil, @@ -143,7 +148,7 @@ func TestRoute53_Zone(t *testing.T) { { test: "single zone", dirName: "route53_zone_single", - mocks: func(client *repository.MockRoute53Repository) { + mocks: func(client *repository.MockRoute53Repository, alerter *mocks.AlerterInterface) { client.On("ListAllZones").Return( []*route53.HostedZone{ { @@ -159,7 +164,7 @@ func TestRoute53_Zone(t *testing.T) { { test: "multiples zone (test pagination)", dirName: "route53_zone_multiples", - mocks: func(client *repository.MockRoute53Repository) { + mocks: func(client *repository.MockRoute53Repository, alerter *mocks.AlerterInterface) { client.On("ListAllZones").Return( []*route53.HostedZone{ { @@ -183,11 +188,13 @@ func TestRoute53_Zone(t *testing.T) { { test: "cannot list zones", dirName: "route53_zone_empty", - mocks: func(client *repository.MockRoute53Repository) { + mocks: func(client *repository.MockRoute53Repository, alerter *mocks.AlerterInterface) { client.On("ListAllZones").Return( []*route53.HostedZone{}, awserr.NewRequestFailure(nil, 403, ""), ) + + alerter.On("SendAlert", resourceaws.AwsRoute53ZoneResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsRoute53ZoneResourceType, resourceaws.AwsRoute53ZoneResourceType, alerts.EnumerationPhase)).Return() }, err: nil, }, @@ -212,9 +219,9 @@ func TestRoute53_Zone(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockRoute53Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.Route53Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -247,6 +254,8 @@ func TestRoute53_Zone(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsRoute53ZoneResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -256,13 +265,13 @@ func TestRoute53_Record(t *testing.T) { tests := []struct { test string dirName string - mocks func(*repository.MockRoute53Repository) + mocks func(*repository.MockRoute53Repository, *mocks.AlerterInterface) err error }{ { test: "no records", dirName: "route53_zone_with_no_record", - mocks: func(client *repository.MockRoute53Repository) { + mocks: func(client *repository.MockRoute53Repository, alerter *mocks.AlerterInterface) { client.On("ListAllZones").Return( []*route53.HostedZone{ { @@ -279,7 +288,7 @@ func TestRoute53_Record(t *testing.T) { { test: "multiples records in multiples zones", dirName: "route53_record_multiples", - mocks: func(client *repository.MockRoute53Repository) { + mocks: func(client *repository.MockRoute53Repository, alerter *mocks.AlerterInterface) { client.On("ListAllZones").Return( []*route53.HostedZone{ { @@ -327,7 +336,7 @@ func TestRoute53_Record(t *testing.T) { { test: "explicit subdomain records", dirName: "route53_record_explicit_subdomain", - mocks: func(client *repository.MockRoute53Repository) { + mocks: func(client *repository.MockRoute53Repository, alerter *mocks.AlerterInterface) { client.On("ListAllZones").Return( []*route53.HostedZone{ { @@ -369,17 +378,19 @@ func TestRoute53_Record(t *testing.T) { { test: "cannot list zones", dirName: "route53_zone_with_no_record", - mocks: func(client *repository.MockRoute53Repository) { + mocks: func(client *repository.MockRoute53Repository, alerter *mocks.AlerterInterface) { client.On("ListAllZones").Return( []*route53.HostedZone{}, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsRoute53RecordResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsRoute53RecordResourceType, resourceaws.AwsRoute53ZoneResourceType, alerts.EnumerationPhase)).Return() }, err: nil, }, { test: "cannot list records", dirName: "route53_zone_with_no_record", - mocks: func(client *repository.MockRoute53Repository) { + mocks: func(client *repository.MockRoute53Repository, alerter *mocks.AlerterInterface) { client.On("ListAllZones").Return( []*route53.HostedZone{ { @@ -392,6 +403,7 @@ func TestRoute53_Record(t *testing.T) { []*route53.ResourceRecordSet{}, awserr.NewRequestFailure(nil, 403, "")) + alerter.On("SendAlert", resourceaws.AwsRoute53RecordResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsRoute53RecordResourceType, resourceaws.AwsRoute53RecordResourceType, alerts.EnumerationPhase)).Return() }, err: nil, }, @@ -416,9 +428,9 @@ func TestRoute53_Record(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockRoute53Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.Route53Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -451,6 +463,8 @@ func TestRoute53_Record(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsRoute53RecordResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } diff --git a/pkg/remote/s3_scanner_test.go b/pkg/remote/s3_scanner_test.go index 501cf69f..787a8e9f 100644 --- a/pkg/remote/s3_scanner_test.go +++ b/pkg/remote/s3_scanner_test.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/s3" "github.com/cloudskiff/driftctl/mocks" "github.com/cloudskiff/driftctl/pkg/filter" + "github.com/cloudskiff/driftctl/pkg/remote/alerts" "github.com/cloudskiff/driftctl/pkg/remote/aws" "github.com/cloudskiff/driftctl/pkg/remote/cache" "github.com/cloudskiff/driftctl/pkg/remote/common" @@ -33,12 +34,12 @@ func TestS3Bucket(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockS3Repository) + mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) wantErr error }{ { test: "multiple bucket", dirName: "aws_s3_bucket_multiple", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On( "ListAllBuckets", ).Return([]*s3.Bucket{ @@ -74,8 +75,10 @@ func TestS3Bucket(t *testing.T) { }, { test: "cannot list bucket", dirName: "s3_bucket_list", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllBuckets").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsS3BucketResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsS3BucketResourceType, resourceaws.AwsS3BucketResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -100,9 +103,8 @@ func TestS3Bucket(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockS3Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) var repo repository.S3Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -138,6 +140,8 @@ func TestS3Bucket(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsS3BucketResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -147,12 +151,12 @@ func TestS3BucketInventory(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockS3Repository) + mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) wantErr error }{ { test: "multiple bucket with multiple inventories", dirName: "s3_bucket_inventories_multiple", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On( "ListAllBuckets", ).Return([]*s3.Bucket{ @@ -200,14 +204,16 @@ func TestS3BucketInventory(t *testing.T) { }, { test: "cannot list bucket", dirName: "s3_bucket_inventories_list_bucket", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllBuckets").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsS3BucketInventoryResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsS3BucketInventoryResourceType, resourceaws.AwsS3BucketResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, { test: "cannot list bucket inventories", dirName: "s3_bucket_inventories_list_inventories", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllBuckets").Return( []*s3.Bucket{ {Name: awssdk.String("bucket-martin-test-drift")}, @@ -229,6 +235,8 @@ func TestS3BucketInventory(t *testing.T) { nil, awserr.NewRequestFailure(nil, 403, ""), ) + + alerter.On("SendAlert", resourceaws.AwsS3BucketInventoryResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsS3BucketInventoryResourceType, resourceaws.AwsS3BucketInventoryResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -253,9 +261,8 @@ func TestS3BucketInventory(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockS3Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) var repo repository.S3Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -291,6 +298,8 @@ func TestS3BucketInventory(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsS3BucketInventoryResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -300,13 +309,13 @@ func TestS3BucketNotification(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockS3Repository) + mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) wantErr error }{ { test: "single bucket without notifications", dirName: "s3_bucket_notifications_no_notif", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On( "ListAllBuckets", ).Return([]*s3.Bucket{ @@ -333,7 +342,7 @@ func TestS3BucketNotification(t *testing.T) { }, { test: "multiple bucket with notifications", dirName: "s3_bucket_notifications_multiple", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On( "ListAllBuckets", ).Return([]*s3.Bucket{ @@ -387,7 +396,7 @@ func TestS3BucketNotification(t *testing.T) { }, { test: "Cannot get bucket notification", dirName: "s3_bucket_notifications_list_bucket", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On( "ListAllBuckets", ).Return([]*s3.Bucket{ @@ -401,13 +410,17 @@ func TestS3BucketNotification(t *testing.T) { nil, ) repository.On("GetBucketNotification", "dritftctl-test-notifications-error", "eu-west-3").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", "aws_s3_bucket_notification.dritftctl-test-notifications-error", alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, "aws_s3_bucket_notification.dritftctl-test-notifications-error", resourceaws.AwsS3BucketNotificationResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, { test: "Cannot list bucket", dirName: "s3_bucket_notifications_list_bucket", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllBuckets").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsS3BucketNotificationResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsS3BucketNotificationResourceType, resourceaws.AwsS3BucketResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -432,9 +445,8 @@ func TestS3BucketNotification(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockS3Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) var repo repository.S3Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -470,6 +482,8 @@ func TestS3BucketNotification(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsS3BucketNotificationResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -479,12 +493,12 @@ func TestS3BucketMetrics(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockS3Repository) + mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) wantErr error }{ { test: "multiple bucket with multiple metrics", dirName: "s3_bucket_metrics_multiple", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On( "ListAllBuckets", ).Return([]*s3.Bucket{ @@ -532,14 +546,16 @@ func TestS3BucketMetrics(t *testing.T) { }, { test: "cannot list bucket", dirName: "s3_bucket_metrics_list_bucket", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllBuckets").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsS3BucketMetricResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsS3BucketMetricResourceType, resourceaws.AwsS3BucketResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, { test: "cannot list metrics", dirName: "s3_bucket_metrics_list_metrics", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllBuckets").Return( []*s3.Bucket{ {Name: awssdk.String("bucket-martin-test-drift")}, @@ -563,6 +579,7 @@ func TestS3BucketMetrics(t *testing.T) { awserr.NewRequestFailure(nil, 403, ""), ) + alerter.On("SendAlert", resourceaws.AwsS3BucketMetricResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsS3BucketMetricResourceType, resourceaws.AwsS3BucketMetricResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -587,9 +604,8 @@ func TestS3BucketMetrics(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockS3Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) var repo repository.S3Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -625,6 +641,8 @@ func TestS3BucketMetrics(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsS3BucketMetricResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -634,13 +652,13 @@ func TestS3BucketPolicy(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockS3Repository) + mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) wantErr error }{ { test: "single bucket without policy", dirName: "s3_bucket_policy_no_policy", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On( "ListAllBuckets", ).Return([]*s3.Bucket{ @@ -667,7 +685,7 @@ func TestS3BucketPolicy(t *testing.T) { }, { test: "multiple bucket with policies", dirName: "s3_bucket_policies_multiple", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On( "ListAllBuckets", ).Return([]*s3.Bucket{ @@ -715,8 +733,10 @@ func TestS3BucketPolicy(t *testing.T) { }, { test: "cannot list bucket", dirName: "s3_bucket_policies_list_bucket", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllBuckets").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsS3BucketPolicyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsS3BucketPolicyResourceType, resourceaws.AwsS3BucketResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -741,9 +761,8 @@ func TestS3BucketPolicy(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockS3Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) var repo repository.S3Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -779,6 +798,8 @@ func TestS3BucketPolicy(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsS3BucketPolicyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -788,13 +809,13 @@ func TestS3BucketAnalytic(t *testing.T) { tests := []struct { test string dirName string - mocks func(repository *repository.MockS3Repository) + mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) wantErr error }{ { test: "multiple bucket with multiple analytics", dirName: "aws_s3_bucket_analytics_multiple", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On( "ListAllBuckets", ).Return([]*s3.Bucket{ @@ -840,17 +861,18 @@ func TestS3BucketAnalytic(t *testing.T) { ) }, }, - { test: "cannot list bucket", dirName: "aws_s3_bucket_analytics_list_bucket", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllBuckets").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsS3BucketAnalyticsConfigurationResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsS3BucketAnalyticsConfigurationResourceType, resourceaws.AwsS3BucketResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, { test: "cannot list Analytics", dirName: "aws_s3_bucket_analytics_list_analytics", - mocks: func(repository *repository.MockS3Repository) { + mocks: func(repository *repository.MockS3Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllBuckets").Return( []*s3.Bucket{ {Name: awssdk.String("bucket-martin-test-drift")}, @@ -874,6 +896,7 @@ func TestS3BucketAnalytic(t *testing.T) { awserr.NewRequestFailure(nil, 403, ""), ) + alerter.On("SendAlert", resourceaws.AwsS3BucketAnalyticsConfigurationResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsS3BucketAnalyticsConfigurationResourceType, resourceaws.AwsS3BucketAnalyticsConfigurationResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -898,9 +921,8 @@ func TestS3BucketAnalytic(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockS3Repository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) var repo repository.S3Repository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -936,6 +958,8 @@ func TestS3BucketAnalytic(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsS3BucketAnalyticsConfigurationResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } diff --git a/pkg/remote/sns_scanner_test.go b/pkg/remote/sns_scanner_test.go index 62bedbbd..ae3836be 100644 --- a/pkg/remote/sns_scanner_test.go +++ b/pkg/remote/sns_scanner_test.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/sns" "github.com/cloudskiff/driftctl/mocks" - "github.com/cloudskiff/driftctl/pkg/alerter" "github.com/cloudskiff/driftctl/pkg/filter" "github.com/cloudskiff/driftctl/pkg/remote/alerts" "github.com/cloudskiff/driftctl/pkg/remote/aws" @@ -33,13 +32,13 @@ func TestScanSNSTopic(t *testing.T) { cases := []struct { test string dirName string - mocks func(client *repository.MockSNSRepository) + mocks func(*repository.MockSNSRepository, *mocks.AlerterInterface) err error }{ { test: "no SNS Topic", dirName: "sns_topic_empty", - mocks: func(client *repository.MockSNSRepository) { + mocks: func(client *repository.MockSNSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllTopics").Return([]*sns.Topic{}, nil) }, err: nil, @@ -47,7 +46,7 @@ func TestScanSNSTopic(t *testing.T) { { test: "Multiple SNSTopic", dirName: "sns_topic_multiple", - mocks: func(client *repository.MockSNSRepository) { + mocks: func(client *repository.MockSNSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllTopics").Return([]*sns.Topic{ {TopicArn: awssdk.String("arn:aws:sns:eu-west-3:526954929923:user-updates-topic")}, {TopicArn: awssdk.String("arn:aws:sns:eu-west-3:526954929923:user-updates-topic2")}, @@ -59,8 +58,10 @@ func TestScanSNSTopic(t *testing.T) { { test: "cannot list SNSTopic", dirName: "sns_topic_empty", - mocks: func(client *repository.MockSNSRepository) { + mocks: func(client *repository.MockSNSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllTopics").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsSnsTopicResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsSnsTopicResourceType, resourceaws.AwsSnsTopicResourceType, alerts.EnumerationPhase)).Return() }, err: nil, }, @@ -75,20 +76,19 @@ func TestScanSNSTopic(t *testing.T) { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - session := session.Must(session.NewSessionWithOptions(session.Options{ + sess := session.Must(session.NewSessionWithOptions(session.Options{ SharedConfigState: session.SharedConfigEnable, })) - alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() // Initialize mocks + alerter := &mocks.AlerterInterface{} fakeRepo := &repository.MockSNSRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.SNSRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -105,7 +105,7 @@ func TestScanSNSTopic(t *testing.T) { t.Fatal(err) } provider.ShouldUpdate() - repo = repository.NewSNSRepository(session, cache.New(0)) + repo = repository.NewSNSRepository(sess, cache.New(0)) } remoteLibrary.AddEnumerator(aws.NewSNSTopicEnumerator(repo, factory)) @@ -121,6 +121,8 @@ func TestScanSNSTopic(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsSnsTopicResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -130,13 +132,13 @@ func TestSNSTopicPolicyScan(t *testing.T) { cases := []struct { test string dirName string - mocks func(client *repository.MockSNSRepository) + mocks func(*repository.MockSNSRepository, *mocks.AlerterInterface) err error }{ { test: "no SNS Topic policy", dirName: "sns_topic_policy_empty", - mocks: func(client *repository.MockSNSRepository) { + mocks: func(client *repository.MockSNSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllTopics").Return([]*sns.Topic{}, nil) }, err: nil, @@ -144,7 +146,7 @@ func TestSNSTopicPolicyScan(t *testing.T) { { test: "Multiple SNSTopicPolicy", dirName: "sns_topic_policy_multiple", - mocks: func(client *repository.MockSNSRepository) { + mocks: func(client *repository.MockSNSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllTopics").Return([]*sns.Topic{ {TopicArn: awssdk.String("arn:aws:sns:us-east-1:526954929923:my-topic-with-policy")}, {TopicArn: awssdk.String("arn:aws:sns:us-east-1:526954929923:my-topic-with-policy2")}, @@ -155,8 +157,10 @@ func TestSNSTopicPolicyScan(t *testing.T) { { test: "cannot list SNSTopic", dirName: "sns_topic_policy_topic_list", - mocks: func(client *repository.MockSNSRepository) { + mocks: func(client *repository.MockSNSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllTopics").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsSnsTopicPolicyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsSnsTopicPolicyResourceType, resourceaws.AwsSnsTopicResourceType, alerts.EnumerationPhase)).Return() }, err: nil, }, @@ -171,20 +175,19 @@ func TestSNSTopicPolicyScan(t *testing.T) { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - session := session.Must(session.NewSessionWithOptions(session.Options{ + sess := session.Must(session.NewSessionWithOptions(session.Options{ SharedConfigState: session.SharedConfigEnable, })) - alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() // Initialize mocks + alerter := &mocks.AlerterInterface{} fakeRepo := &repository.MockSNSRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.SNSRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -201,7 +204,7 @@ func TestSNSTopicPolicyScan(t *testing.T) { t.Fatal(err) } provider.ShouldUpdate() - repo = repository.NewSNSRepository(session, cache.New(0)) + repo = repository.NewSNSRepository(sess, cache.New(0)) } remoteLibrary.AddEnumerator(aws.NewSNSTopicPolicyEnumerator(repo, factory)) @@ -217,6 +220,8 @@ func TestSNSTopicPolicyScan(t *testing.T) { return } test.TestAgainstGoldenFile(got, resourceaws.AwsSnsTopicPolicyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } @@ -226,62 +231,52 @@ func TestSNSTopicSubscriptionScan(t *testing.T) { cases := []struct { test string dirName string - mocks func(client *repository.MockSNSRepository) - alerts alerter.Alerts + mocks func(*repository.MockSNSRepository, *mocks.AlerterInterface) err error }{ { test: "no SNS Topic Subscription", dirName: "sns_topic_subscription_empty", - mocks: func(client *repository.MockSNSRepository) { + mocks: func(client *repository.MockSNSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllSubscriptions").Return([]*sns.Subscription{}, nil) }, - alerts: map[string][]alerter.Alert{}, - err: nil, + err: nil, }, { test: "Multiple SNSTopic Subscription", dirName: "sns_topic_subscription_multiple", - mocks: func(client *repository.MockSNSRepository) { + mocks: func(client *repository.MockSNSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllSubscriptions").Return([]*sns.Subscription{ {SubscriptionArn: awssdk.String("arn:aws:sns:us-east-1:526954929923:user-updates-topic2:c0f794c5-a009-4db4-9147-4c55959787fa")}, {SubscriptionArn: awssdk.String("arn:aws:sns:us-east-1:526954929923:user-updates-topic:b6e66147-2b31-4486-8d4b-2a2272264c8e")}, }, nil) }, - alerts: map[string][]alerter.Alert{}, - err: nil, + err: nil, }, { test: "Multiple SNSTopic Subscription with one pending and one incorrect", dirName: "sns_topic_subscription_multiple", - mocks: func(client *repository.MockSNSRepository) { + mocks: func(client *repository.MockSNSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllSubscriptions").Return([]*sns.Subscription{ {SubscriptionArn: awssdk.String("PendingConfirmation"), Endpoint: awssdk.String("TEST")}, {SubscriptionArn: awssdk.String("Incorrect"), Endpoint: awssdk.String("INCORRECT")}, {SubscriptionArn: awssdk.String("arn:aws:sns:us-east-1:526954929923:user-updates-topic2:c0f794c5-a009-4db4-9147-4c55959787fa")}, {SubscriptionArn: awssdk.String("arn:aws:sns:us-east-1:526954929923:user-updates-topic:b6e66147-2b31-4486-8d4b-2a2272264c8e")}, }, nil) - }, - alerts: map[string][]alerter.Alert{ - "aws_sns_topic_subscription.PendingConfirmation": []alerter.Alert{ - aws.NewWrongArnTopicAlert("PendingConfirmation", awssdk.String("TEST")), - }, - "aws_sns_topic_subscription.Incorrect": []alerter.Alert{ - aws.NewWrongArnTopicAlert("Incorrect", awssdk.String("INCORRECT")), - }, + + alerter.On("SendAlert", "aws_sns_topic_subscription.PendingConfirmation", aws.NewWrongArnTopicAlert("PendingConfirmation", awssdk.String("TEST"))).Return() + + alerter.On("SendAlert", "aws_sns_topic_subscription.Incorrect", aws.NewWrongArnTopicAlert("Incorrect", awssdk.String("INCORRECT"))).Return() }, err: nil, }, { test: "cannot list SNSTopic subscription", dirName: "sns_topic_subscription_list", - mocks: func(client *repository.MockSNSRepository) { + mocks: func(client *repository.MockSNSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllSubscriptions").Return(nil, awserr.NewRequestFailure(nil, 403, "")) - }, - alerts: map[string][]alerter.Alert{ - resourceaws.AwsSnsTopicSubscriptionResourceType: { - alerts.NewRemoteAccessDeniedAlert("aws+tf", resourceaws.AwsSnsTopicSubscriptionResourceType, resourceaws.AwsSnsTopicSubscriptionResourceType, alerts.EnumerationPhase), - }, + + alerter.On("SendAlert", resourceaws.AwsSnsTopicSubscriptionResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsSnsTopicSubscriptionResourceType, resourceaws.AwsSnsTopicSubscriptionResourceType, alerts.EnumerationPhase)).Return() }, err: nil, }, @@ -296,7 +291,7 @@ func TestSNSTopicSubscriptionScan(t *testing.T) { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - session := session.Must(session.NewSessionWithOptions(session.Options{ + sess := session.Must(session.NewSessionWithOptions(session.Options{ SharedConfigState: session.SharedConfigEnable, })) @@ -305,9 +300,10 @@ func TestSNSTopicSubscriptionScan(t *testing.T) { remoteLibrary := common.NewRemoteLibrary() // Initialize mocks - alerter := alerter.NewAlerter() + alerter := &mocks.AlerterInterface{} fakeRepo := &repository.MockSNSRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) + var repo repository.SNSRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -324,7 +320,7 @@ func TestSNSTopicSubscriptionScan(t *testing.T) { t.Fatal(err) } provider.ShouldUpdate() - repo = repository.NewSNSRepository(session, cache.New(0)) + repo = repository.NewSNSRepository(sess, cache.New(0)) } remoteLibrary.AddEnumerator(aws.NewSNSTopicSubscriptionEnumerator(repo, factory, alerter)) @@ -339,8 +335,9 @@ func TestSNSTopicSubscriptionScan(t *testing.T) { if err != nil { return } - assert.Equal(tt, c.alerts, alerter.Retrieve()) test.TestAgainstGoldenFile(got, resourceaws.AwsSnsTopicSubscriptionResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + alerter.AssertExpectations(tt) + fakeRepo.AssertExpectations(tt) }) } } diff --git a/pkg/remote/sqs_scanner_test.go b/pkg/remote/sqs_scanner_test.go index 34a25f4c..fa90a362 100644 --- a/pkg/remote/sqs_scanner_test.go +++ b/pkg/remote/sqs_scanner_test.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/sqs" "github.com/cloudskiff/driftctl/mocks" "github.com/cloudskiff/driftctl/pkg/filter" + "github.com/cloudskiff/driftctl/pkg/remote/alerts" "github.com/cloudskiff/driftctl/pkg/remote/aws" "github.com/cloudskiff/driftctl/pkg/remote/aws/repository" "github.com/cloudskiff/driftctl/pkg/remote/cache" @@ -28,13 +29,13 @@ func TestSQSQueue(t *testing.T) { cases := []struct { test string dirName string - mocks func(client *repository.MockSQSRepository) + mocks func(*repository.MockSQSRepository, *mocks.AlerterInterface) wantErr error }{ { test: "no sqs queues", dirName: "sqs_queue_empty", - mocks: func(client *repository.MockSQSRepository) { + mocks: func(client *repository.MockSQSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllQueues").Return([]*string{}, nil) }, wantErr: nil, @@ -42,7 +43,7 @@ func TestSQSQueue(t *testing.T) { { test: "multiple sqs queues", dirName: "sqs_queue_multiple", - mocks: func(client *repository.MockSQSRepository) { + mocks: func(client *repository.MockSQSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllQueues").Return([]*string{ awssdk.String("https://sqs.eu-west-3.amazonaws.com/047081014315/bar.fifo"), awssdk.String("https://sqs.eu-west-3.amazonaws.com/047081014315/foo"), @@ -53,8 +54,10 @@ func TestSQSQueue(t *testing.T) { { test: "cannot list sqs queues", dirName: "sqs_queue_empty", - mocks: func(client *repository.MockSQSRepository) { + mocks: func(client *repository.MockSQSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllQueues").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsSqsQueueResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsSqsQueueResourceType, resourceaws.AwsSqsQueueResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -79,9 +82,8 @@ func TestSQSQueue(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockSQSRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) var repo repository.SQSRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion) @@ -122,7 +124,7 @@ func TestSQSQueuePolicy(t *testing.T) { cases := []struct { test string dirName string - mocks func(client *repository.MockSQSRepository) + mocks func(*repository.MockSQSRepository, *mocks.AlerterInterface) wantErr error }{ { @@ -130,7 +132,7 @@ func TestSQSQueuePolicy(t *testing.T) { // as a default SQSDefaultPolicy (e.g. policy="") will always be present in each queue test: "no sqs queue policies", dirName: "sqs_queue_policy_empty", - mocks: func(client *repository.MockSQSRepository) { + mocks: func(client *repository.MockSQSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllQueues").Return([]*string{}, nil) }, wantErr: nil, @@ -138,7 +140,7 @@ func TestSQSQueuePolicy(t *testing.T) { { test: "multiple sqs queue policies (default or not)", dirName: "sqs_queue_policy_multiple", - mocks: func(client *repository.MockSQSRepository) { + mocks: func(client *repository.MockSQSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllQueues").Return([]*string{ awssdk.String("https://sqs.eu-west-3.amazonaws.com/047081014315/bar.fifo"), awssdk.String("https://sqs.eu-west-3.amazonaws.com/047081014315/foo"), @@ -159,7 +161,7 @@ func TestSQSQueuePolicy(t *testing.T) { { test: "multiple sqs queue policies (with nil attributes)", dirName: "sqs_queue_policy_multiple", - mocks: func(client *repository.MockSQSRepository) { + mocks: func(client *repository.MockSQSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllQueues").Return([]*string{ awssdk.String("https://sqs.eu-west-3.amazonaws.com/047081014315/bar.fifo"), awssdk.String("https://sqs.eu-west-3.amazonaws.com/047081014315/foo"), @@ -176,8 +178,10 @@ func TestSQSQueuePolicy(t *testing.T) { { test: "cannot list sqs queues, thus sqs queue policies", dirName: "sqs_queue_policy_empty", - mocks: func(client *repository.MockSQSRepository) { + mocks: func(client *repository.MockSQSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllQueues").Return(nil, awserr.NewRequestFailure(nil, 403, "")) + + alerter.On("SendAlert", resourceaws.AwsSqsQueuePolicyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, resourceaws.AwsSqsQueuePolicyResourceType, resourceaws.AwsSqsQueueResourceType, alerts.EnumerationPhase)).Return() }, wantErr: nil, }, @@ -202,9 +206,8 @@ func TestSQSQueuePolicy(t *testing.T) { // Initialize mocks alerter := &mocks.AlerterInterface{} - alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return() fakeRepo := &repository.MockSQSRepository{} - c.mocks(fakeRepo) + c.mocks(fakeRepo, alerter) var repo repository.SQSRepository = fakeRepo providerVersion := "3.19.0" realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion)