Split db_instance_supplier

main
William Beuil 2021-07-07 17:08:17 +02:00
parent af253a173e
commit 58c9c88811
No known key found for this signature in database
GPG Key ID: BED2072C5C2BF537
16 changed files with 173 additions and 200 deletions

View File

@ -1,59 +0,0 @@
package aws
import (
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/cloudskiff/driftctl/pkg/resource"
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
"github.com/cloudskiff/driftctl/pkg/terraform"
"github.com/sirupsen/logrus"
"github.com/zclconf/go-cty/cty"
)
type DBInstanceSupplier struct {
reader terraform.ResourceReader
deserializer *resource.Deserializer
repository repository.RDSRepository
runner *terraform.ParallelResourceReader
}
func NewDBInstanceSupplier(provider *AWSTerraformProvider, deserializer *resource.Deserializer, repository repository.RDSRepository) *DBInstanceSupplier {
return &DBInstanceSupplier{
provider,
deserializer,
repository,
terraform.NewParallelResourceReader(provider.Runner().SubRunner()),
}
}
func (s *DBInstanceSupplier) Resources() ([]resource.Resource, error) {
resourceList, err := s.repository.ListAllDBInstances()
if err != nil {
return nil, remoteerror.NewResourceEnumerationError(err, resourceaws.AwsDbInstanceResourceType)
}
for _, res := range resourceList {
id := *res.DBInstanceIdentifier
s.runner.Run(func() (cty.Value, error) {
completeResource, err := s.reader.ReadResource(terraform.ReadResourceArgs{
Ty: resourceaws.AwsDbInstanceResourceType,
ID: id,
})
if err != nil {
logrus.Warnf("Error reading %s[%s]: %+v", id, resourceaws.AwsDbInstanceResourceType, err)
return cty.NilVal, err
}
return *completeResource, nil
})
}
results, err := s.runner.Wait()
if err != nil {
return nil, err
}
return s.deserializer.Deserialize(resourceaws.AwsDbInstanceResourceType, results)
}

View File

@ -1,136 +0,0 @@
package aws
import (
"context"
"testing"
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
"github.com/cloudskiff/driftctl/pkg/remote/cache"
testresource "github.com/cloudskiff/driftctl/test/resource"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
"github.com/stretchr/testify/assert"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/cloudskiff/driftctl/pkg/parallel"
"github.com/cloudskiff/driftctl/test/goldenfile"
"github.com/cloudskiff/driftctl/pkg/resource"
"github.com/cloudskiff/driftctl/pkg/terraform"
"github.com/cloudskiff/driftctl/test"
"github.com/cloudskiff/driftctl/test/mocks"
awssdk "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/rds"
)
func TestDBInstanceSupplier_Resources(t *testing.T) {
tests := []struct {
test string
dirName string
mocks func(client *repository.MockRDSRepository)
err error
}{
{
test: "no dbs",
dirName: "db_instance_empty",
mocks: func(client *repository.MockRDSRepository) {
client.On("ListAllDBInstances").Return([]*rds.DBInstance{}, nil)
},
err: nil,
},
{
test: "single db",
dirName: "db_instance_single",
mocks: func(client *repository.MockRDSRepository) {
client.On("ListAllDBInstances").Return([]*rds.DBInstance{
{
DBInstanceIdentifier: awssdk.String("terraform-20201015115018309600000001"),
},
}, nil)
},
err: nil,
},
{
test: "multiples mixed db",
dirName: "db_instance_multiple",
mocks: func(client *repository.MockRDSRepository) {
client.On("ListAllDBInstances").Return([]*rds.DBInstance{
{
DBInstanceIdentifier: awssdk.String("terraform-20201015115018309600000001"),
},
{
DBInstanceIdentifier: awssdk.String("database-1"),
},
}, nil)
},
err: nil,
},
{
test: "multiples mixed db",
dirName: "db_instance_multiple",
mocks: func(client *repository.MockRDSRepository) {
client.On("ListAllDBInstances").Return([]*rds.DBInstance{
{
DBInstanceIdentifier: awssdk.String("terraform-20201015115018309600000001"),
},
{
DBInstanceIdentifier: awssdk.String("database-1"),
},
}, nil)
},
err: nil,
},
{
test: "Cannot list db instances",
dirName: "db_instance_empty",
mocks: func(client *repository.MockRDSRepository) {
client.On("ListAllDBInstances").Return([]*rds.DBInstance{}, awserr.NewRequestFailure(nil, 403, ""))
},
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsDbInstanceResourceType),
},
}
for _, tt := range tests {
shouldUpdate := tt.dirName == *goldenfile.Update
providerLibrary := terraform.NewProviderLibrary()
supplierLibrary := resource.NewSupplierLibrary()
repo := testresource.InitFakeSchemaRepository("aws", "3.19.0")
resourceaws.InitResourcesMetadata(repo)
factory := terraform.NewTerraformResourceFactory(repo)
deserializer := resource.NewDeserializer(factory)
if shouldUpdate {
provider, err := InitTestAwsProvider(providerLibrary)
if err != nil {
t.Fatal(err)
}
supplierLibrary.AddSupplier(NewDBInstanceSupplier(provider, deserializer, repository.NewRDSRepository(provider.session, cache.New(0))))
}
t.Run(tt.test, func(t *testing.T) {
provider := mocks.NewMockedGoldenTFProvider(tt.dirName, providerLibrary.Provider(terraform.AWS), shouldUpdate)
client := &repository.MockRDSRepository{}
tt.mocks(client)
s := &DBInstanceSupplier{
provider,
deserializer,
client,
terraform.NewParallelResourceReader(parallel.NewParallelRunner(context.TODO(), 10)),
}
got, err := s.Resources()
assert.Equal(t, tt.err, err)
test.CtyTestDiff(got, tt.dirName, provider, deserializer, shouldUpdate, t)
})
}
}

View File

@ -86,7 +86,7 @@ func TestDBSubnetGroupSupplier_Resources(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
supplierLibrary.AddSupplier(NewDBInstanceSupplier(provider, deserializer, repository.NewRDSRepository(provider.session, cache.New(0)))) supplierLibrary.AddSupplier(NewDBSubnetGroupSupplier(provider, deserializer, repository.NewRDSRepository(provider.session, cache.New(0))))
} }
t.Run(tt.test, func(t *testing.T) { t.Run(tt.test, func(t *testing.T) {

View File

@ -119,6 +119,9 @@ func Init(version string, alerter *alerter.Alerter,
remoteLibrary.AddEnumerator(NewCloudfrontDistributionEnumerator(cloudfrontRepository, factory)) remoteLibrary.AddEnumerator(NewCloudfrontDistributionEnumerator(cloudfrontRepository, factory))
remoteLibrary.AddDetailsFetcher(aws.AwsCloudfrontDistributionResourceType, common.NewGenericDetailsFetcher(aws.AwsCloudfrontDistributionResourceType, provider, deserializer)) remoteLibrary.AddDetailsFetcher(aws.AwsCloudfrontDistributionResourceType, common.NewGenericDetailsFetcher(aws.AwsCloudfrontDistributionResourceType, provider, deserializer))
remoteLibrary.AddEnumerator(NewRDSDBInstanceEnumerator(rdsRepository, factory))
remoteLibrary.AddDetailsFetcher(aws.AwsDbInstanceResourceType, common.NewGenericDetailsFetcher(aws.AwsDbInstanceResourceType, provider, deserializer))
remoteLibrary.AddEnumerator(NewSQSQueueEnumerator(sqsRepository, factory)) remoteLibrary.AddEnumerator(NewSQSQueueEnumerator(sqsRepository, factory))
remoteLibrary.AddDetailsFetcher(aws.AwsSqsQueueResourceType, common.NewGenericDetailsFetcher(aws.AwsSqsQueueResourceType, provider, deserializer)) remoteLibrary.AddDetailsFetcher(aws.AwsSqsQueueResourceType, common.NewGenericDetailsFetcher(aws.AwsSqsQueueResourceType, provider, deserializer))
remoteLibrary.AddEnumerator(NewSQSQueuePolicyEnumerator(sqsRepository, factory)) remoteLibrary.AddEnumerator(NewSQSQueuePolicyEnumerator(sqsRepository, factory))
@ -137,7 +140,6 @@ func Init(version string, alerter *alerter.Alerter,
supplierLibrary.AddSupplier(NewS3BucketAnalyticSupplier(provider, s3Repository, deserializer)) supplierLibrary.AddSupplier(NewS3BucketAnalyticSupplier(provider, s3Repository, deserializer))
supplierLibrary.AddSupplier(NewLambdaFunctionSupplier(provider, deserializer, lambdaRepository)) supplierLibrary.AddSupplier(NewLambdaFunctionSupplier(provider, deserializer, lambdaRepository))
supplierLibrary.AddSupplier(NewDBSubnetGroupSupplier(provider, deserializer, rdsRepository)) supplierLibrary.AddSupplier(NewDBSubnetGroupSupplier(provider, deserializer, rdsRepository))
supplierLibrary.AddSupplier(NewDBInstanceSupplier(provider, deserializer, rdsRepository))
supplierLibrary.AddSupplier(NewIamUserSupplier(provider, deserializer, iamRepository)) supplierLibrary.AddSupplier(NewIamUserSupplier(provider, deserializer, iamRepository))
supplierLibrary.AddSupplier(NewIamUserPolicySupplier(provider, deserializer, iamRepository)) supplierLibrary.AddSupplier(NewIamUserPolicySupplier(provider, deserializer, iamRepository))
supplierLibrary.AddSupplier(NewIamUserPolicyAttachmentSupplier(provider, deserializer, iamRepository)) supplierLibrary.AddSupplier(NewIamUserPolicyAttachmentSupplier(provider, deserializer, iamRepository))

View File

@ -0,0 +1,46 @@
package aws
import (
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/cloudskiff/driftctl/pkg/resource"
"github.com/cloudskiff/driftctl/pkg/resource/aws"
)
type RDSDBInstanceEnumerator struct {
repository repository.RDSRepository
factory resource.ResourceFactory
}
func NewRDSDBInstanceEnumerator(repo repository.RDSRepository, factory resource.ResourceFactory) *RDSDBInstanceEnumerator {
return &RDSDBInstanceEnumerator{
repository: repo,
factory: factory,
}
}
func (e *RDSDBInstanceEnumerator) SupportedType() resource.ResourceType {
return aws.AwsDbInstanceResourceType
}
func (e *RDSDBInstanceEnumerator) Enumerate() ([]resource.Resource, error) {
instances, err := e.repository.ListAllDBInstances()
if err != nil {
return nil, remoteerror.NewResourceEnumerationError(err, string(e.SupportedType()))
}
results := make([]resource.Resource, len(instances))
for _, instance := range instances {
results = append(
results,
e.factory.CreateAbstractResource(
string(e.SupportedType()),
*instance.DBInstanceIdentifier,
map[string]interface{}{},
),
)
}
return results, err
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,122 @@
package remote
import (
"testing"
awssdk "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/rds"
"github.com/cloudskiff/driftctl/mocks"
"github.com/cloudskiff/driftctl/pkg/remote/aws"
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
"github.com/cloudskiff/driftctl/pkg/remote/cache"
"github.com/cloudskiff/driftctl/pkg/remote/common"
"github.com/cloudskiff/driftctl/pkg/resource"
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
"github.com/cloudskiff/driftctl/pkg/terraform"
"github.com/cloudskiff/driftctl/test"
"github.com/cloudskiff/driftctl/test/goldenfile"
testresource "github.com/cloudskiff/driftctl/test/resource"
terraform2 "github.com/cloudskiff/driftctl/test/terraform"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
func TestRDSDBInstance(t *testing.T) {
tests := []struct {
test string
dirName string
mocks func(repository *repository.MockRDSRepository)
wantErr error
}{
{
test: "no db instances",
dirName: "aws_rds_db_instance_empty",
mocks: func(repository *repository.MockRDSRepository) {
repository.On("ListAllDBInstances").Return([]*rds.DBInstance{}, nil)
},
},
{
test: "single db instance",
dirName: "aws_rds_db_instance_single",
mocks: func(repository *repository.MockRDSRepository) {
repository.On("ListAllDBInstances").Return([]*rds.DBInstance{
{DBInstanceIdentifier: awssdk.String("terraform-20201015115018309600000001")},
}, nil)
},
},
{
test: "multiple mixed db instances",
dirName: "aws_rds_db_instance_multiple",
mocks: func(repository *repository.MockRDSRepository) {
repository.On("ListAllDBInstances").Return([]*rds.DBInstance{
{DBInstanceIdentifier: awssdk.String("terraform-20201015115018309600000001")},
{DBInstanceIdentifier: awssdk.String("database-1")},
}, nil)
},
},
{
test: "cannot list db instances",
dirName: "aws_rds_db_instance_list",
mocks: func(repository *repository.MockRDSRepository) {
repository.On("ListAllDBInstances").Return(nil, awserr.NewRequestFailure(nil, 403, ""))
},
wantErr: nil,
},
}
schemaRepository := testresource.InitFakeSchemaRepository("aws", "3.19.0")
resourceaws.InitResourcesMetadata(schemaRepository)
factory := terraform.NewTerraformResourceFactory(schemaRepository)
deserializer := resource.NewDeserializer(factory)
for _, c := range tests {
t.Run(c.test, func(tt *testing.T) {
shouldUpdate := c.dirName == *goldenfile.Update
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
scanOptions := ScannerOptions{Deep: true}
providerLibrary := terraform.NewProviderLibrary()
remoteLibrary := common.NewRemoteLibrary()
// Initialize mocks
alerter := &mocks.AlerterInterface{}
alerter.On("SendAlert", mock.Anything, mock.Anything).Maybe().Return()
fakeRepo := &repository.MockRDSRepository{}
c.mocks(fakeRepo)
var repo repository.RDSRepository = fakeRepo
providerVersion := "3.19.0"
realProvider, err := terraform2.InitTestAwsProvider(providerLibrary, providerVersion)
if err != nil {
t.Fatal(err)
}
provider := terraform2.NewFakeTerraformProvider(realProvider)
provider.WithResponse(c.dirName)
// Replace mock by real resources if we are in update mode
if shouldUpdate {
err := realProvider.Init()
if err != nil {
t.Fatal(err)
}
provider.ShouldUpdate()
repo = repository.NewRDSRepository(sess, cache.New(0))
}
remoteLibrary.AddEnumerator(aws.NewRDSDBInstanceEnumerator(repo, factory))
remoteLibrary.AddDetailsFetcher(resourceaws.AwsDbInstanceResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsDbInstanceResourceType, provider, deserializer))
s := NewScanner(nil, remoteLibrary, alerter, scanOptions)
got, err := s.Resources()
assert.Equal(tt, err, c.wantErr)
if err != nil {
return
}
test.TestAgainstGoldenFile(got, resourceaws.AwsDbInstanceResourceType, c.dirName, provider, deserializer, shouldUpdate, tt)
})
}
}

View File

@ -0,0 +1 @@
[]