diff --git a/.gitleaksignore b/.gitleaksignore index 03a88e99d..228409f9b 100644 --- a/.gitleaksignore +++ b/.gitleaksignore @@ -281,3 +281,13 @@ ff72de8e77f908fba61df50bc0938744270d1b51:pkg/remote/aws/test/iam_role_multiple/r ff72de8e77f908fba61df50bc0938744270d1b51:pkg/remote/aws/test/iam_user_multiple/results.golden.json:aws-access-token:12 ff72de8e77f908fba61df50bc0938744270d1b51:pkg/remote/aws/test/iam_user_multiple/results.golden.json:aws-access-token:24 ff72de8e77f908fba61df50bc0938744270d1b51:pkg/remote/aws/test/iam_user_multiple/results.golden.json:aws-access-token:36 +20e6356a49e6dd18f00cd6c36b735ef1a850ac55:enumeration/remote/aws_iam_scanner_test.go:aws-access-token:823 +20e6356a49e6dd18f00cd6c36b735ef1a850ac55:enumeration/remote/aws_iam_scanner_test.go:aws-access-token:826 +651ab697db3ff60ba195c22dc0570d1204a97f7e:enumeration/remote/aws_iam_scanner_test.go:aws-access-token:823 +651ab697db3ff60ba195c22dc0570d1204a97f7e:enumeration/remote/aws_iam_scanner_test.go:aws-access-token:826 +6cf09f996d8637c30ad06884a450ff66920d9798:enumeration/remote/aws_iam_scanner_test.go:aws-access-token:823 +6cf09f996d8637c30ad06884a450ff66920d9798:enumeration/remote/aws_iam_scanner_test.go:aws-access-token:826 +6d204a7f446251a3c1519bfc4b80599529eec279:enumeration/remote/aws_iam_scanner_test.go:aws-access-token:823 +6d204a7f446251a3c1519bfc4b80599529eec279:enumeration/remote/aws_iam_scanner_test.go:aws-access-token:826 +40f68d61a91d8c10c09e43263cbd36b380cca90a:enumeration/remote/aws_iam_scanner_test.go:aws-access-token:823 +40f68d61a91d8c10c09e43263cbd36b380cca90a:enumeration/remote/aws_iam_scanner_test.go:aws-access-token:826 diff --git a/.snyk b/.snyk index f67397add..24f946749 100644 --- a/.snyk +++ b/.snyk @@ -85,4 +85,9 @@ ignore: - '*': reason: This license is addressed by including acknowledgments in each release created: 2022-09-09T14:25:05.042Z + SNYK-GOLANG-GOLANGORGXNETHTTP2-5953327: + - '*': + reason: Not affected because CLI + expires: 2024-04-15T15:15:28.330Z + created: 2023-10-16T15:15:28.356Z patch: {} diff --git a/docs/README.md b/docs/README.md index e8e1c792a..8e005751a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -17,4 +17,3 @@ Resource listing is done using cloud providers SDK. Resource details retrieval i - `Remote` is a representation of a cloud provider - `Resource` is an abstract representation of a cloud provider resource (e.g. S3 bucket, EC2 instance, etc ...) - `Enumerator` is used to list resources of a given type from a given remote and return a resource list, it should exist only one Enumerator per resource -- `DetailsFetcher` is used to retrieve resource's details of a given type, this is an optional layer and is used only in deep mode. diff --git a/docs/media/generalflow.png b/docs/media/generalflow.png index 147d96971..55b243dfd 100644 Binary files a/docs/media/generalflow.png and b/docs/media/generalflow.png differ diff --git a/docs/media/resource.png b/docs/media/resource.png index 74651c646..c1fddf046 100644 Binary files a/docs/media/resource.png and b/docs/media/resource.png differ diff --git a/docs/media/resource.puml b/docs/media/resource.puml index 1079e4f08..441ce0eb5 100644 --- a/docs/media/resource.puml +++ b/docs/media/resource.puml @@ -12,16 +12,5 @@ RemoteSDK --> Enumerator: Attrs end Enumerator --> Scanner: []Resource with limited attributes end -alt if deep mode enabled -hnote across: Details fetching phase -loop for each enumerated resource -Scanner -> DetailsFetcher: ReadDetails(res) -DetailsFetcher -> TerraformProvider: ReadResource() -TerraformProvider --> DetailsFetcher: CTYValue -DetailsFetcher -> Deserializer: Deserialize() -Deserializer -> DetailsFetcher: Resource -DetailsFetcher -> Scanner: Resource with\nfull attributes -end -end Scanner --> driftctl: []Resource -@enduml +@enduml \ No newline at end of file diff --git a/docs/new-resource.md b/docs/new-resource.md index 66816db76..4a93bdb79 100644 --- a/docs/new-resource.md +++ b/docs/new-resource.md @@ -13,22 +13,12 @@ Then, you'll find below a more detailed flow of how we handle the enumeration an First step would be to add a file called `pkg/resource//.go`. This file will define a string constant that will be the resource type identifier in driftctl. -Optionally, if your resource is to be supported by driftctl experimental deep mode, you can add a function that will be applied to this resource at creation. -This allows to prevent useless diffs to be displayed. -You can also add metadata to fields so that they are compared or displayed differently. - For example this defines the `aws_iam_role` resource: ```go const AwsIamRoleResourceType = "aws_iam_role" func initAwsIAMRoleMetaData(resourceSchemaRepository resource.SchemaRepositoryInterface) { - // assume_role_policy drifts will be displayed as json - resourceSchemaRepository.UpdateSchema(AwsIamRoleResourceType, map[string]func(attributeSchema *resource.AttributeSchema){ - "assume_role_policy": func(attributeSchema *resource.AttributeSchema) { - attributeSchema.JsonString = true - }, - }) // force_detach_policies should not be compared so it will be removed before the comparison resourceSchemaRepository.SetNormalizeFunc(AwsIamRoleResourceType, func(res *resource.Resource) { val := res.Attrs @@ -57,17 +47,12 @@ var supportedTypes = map[string]struct{}{ All resources inside driftctl are `resource.Resource` structs. All the other attributes are represented inside a `map[string]interface` -## Repository, Enumerator and DetailsFetcher +## Repository, Enumerator -Then you will have to implement two interfaces: +Then you will have to implement one interface: - Repositories are the way we decided to hide direct calls to SDK and pagination logic. It's a common abstraction pattern for data retrieval. - `remote.common.Enumerator` is used to enumerate resources. It will call the cloud provider SDK to get the list of resources. - For some resource it could make other call to enrich the resource with additional attributes when driftctl is used in deep mode -- `remote.common.DetailsFetcher` is used to retrieve resource's details. It makes a call to Terraform provider `ReadResource`. - This implementation is optional and is only needed if your resource type is to be supported by experimental deep mode. - Please also note that it exists a generic implementation called `remote.common.GenericDetailsFetcher` that can be used with most resource types. - ### Repository @@ -126,7 +111,6 @@ Most of the resource returned by enumerator have empty attributes: they only rep **There are exceptions to this**: - Sometimes, you will need more information about resources for them to be fetched in the `DetailsFetcher`. For those cases, you will add specific attributes to the map of data. -- For complex cases (e.g. middlewares) where you would need driftctl to run as expected in deep and non-deep mode, you would need to enumerate resources as well as to fetch manually specific attributes, using the remote SDK, before adding them to the map of data. You can use an already implemented Enumerator as example. @@ -192,26 +176,3 @@ Once the enumerator is written you have to add it to the remote initialization l ```go remoteLibrary.AddEnumerator(NewEC2InstanceEnumerator(s3Repository, factory)) ``` - -### DetailsFetcher - -DetailsFetchers are only used by driftctl experimental deep mode. - -This is the component that call Terraform provider to retrieve all attributes for each resource. -We do not want to reimplement what has already been done in each Terraform provider. Thus, you should not call the remote SDK there. - -If `common.GenericDetailsFetcher` satisfies your needs you should always prefer using it instead of implementing a custom `DetailsFetcher` in a new struct. - -The `DetailsFetcher` should also be added to `pkg/remote//init.go` even if you use the generic version: - -```go - remoteLibrary.AddDetailsFetcher(aws.AwsEbsVolumeResourceType, common.NewGenericDetailsFetcher(aws.AwsEbsVolumeResourceType, provider, deserializer)) -``` - -***Don't forget to add unit tests after adding a new resource.*** - -You can find example of **functional tests** in `pkg/remote/_scanner_test.go`. - -You should also add **acceptance tests** if you think it makes sense. They are located next to the resource definition described in the first step. - -More information about adding tests can be found in [testing documentation](testing.md) diff --git a/enumeration/enumerator/cloud_enumerator.go b/enumeration/enumerator/cloud_enumerator.go deleted file mode 100644 index 3c8aaed13..000000000 --- a/enumeration/enumerator/cloud_enumerator.go +++ /dev/null @@ -1,300 +0,0 @@ -package enumerator - -import ( - "context" - "fmt" - "os" - "sync" - - "github.com/sirupsen/logrus" - "github.com/snyk/driftctl/enumeration" - "github.com/snyk/driftctl/enumeration/alerter" - "github.com/snyk/driftctl/enumeration/diagnostic" - "github.com/snyk/driftctl/enumeration/parallel" - "github.com/snyk/driftctl/enumeration/remote" - "github.com/snyk/driftctl/enumeration/remote/common" - "github.com/snyk/driftctl/enumeration/resource" - "github.com/snyk/driftctl/enumeration/terraform" -) - -type CloudEnumerator struct { - alerter *sliceAlerter - progress enumeration.ProgressCounter - remoteLibrary *common.RemoteLibrary - providerLibrary *terraform.ProviderLibrary - enumeratorRunner *parallel.ParallelRunner - detailsFetcherRunner *parallel.ParallelRunner - to string -} - -type ListOutput struct { - Resources []*resource.Resource - Diagnostics diagnostic.Diagnostics -} - -type cloudEnumeratorBuilder struct { - cloud string - providerVersion string - configDirectory string -} - -// WithCloud Choose which cloud to use for enumeration and refresh -// TODO could be inferred with types listed -func (b *cloudEnumeratorBuilder) WithCloud(cloud string) *cloudEnumeratorBuilder { - b.cloud = cloud - return b -} - -// WithProviderVersion optionally choose the provider version used for refresh -func (b *cloudEnumeratorBuilder) WithProviderVersion(providerVersion string) *cloudEnumeratorBuilder { - b.providerVersion = providerVersion - return b -} - -// WithConfigDirectory optionally choose the directory used to download terraform provider used for refresh -func (b *cloudEnumeratorBuilder) WithConfigDirectory(configDir string) *cloudEnumeratorBuilder { - b.configDirectory = configDir - return b -} - -func (b *cloudEnumeratorBuilder) Build() (*CloudEnumerator, error) { - enumerator := &CloudEnumerator{ - enumeratorRunner: parallel.NewParallelRunner(context.TODO(), 10), - detailsFetcherRunner: parallel.NewParallelRunner(context.TODO(), 10), - providerLibrary: terraform.NewProviderLibrary(), - remoteLibrary: common.NewRemoteLibrary(), - alerter: newSliceAlerter(), - progress: &dummyCounter{}, - } - - if b.configDirectory == "" { - tempDir, err := os.MkdirTemp("", "enumerator") - if err != nil { - return nil, err - } - b.configDirectory = tempDir - } - - err := enumerator.init(fmt.Sprintf("%s+tf", b.cloud), b.providerVersion, b.configDirectory) - - return enumerator, err -} - -func NewCloudEnumerator() *cloudEnumeratorBuilder { - return &cloudEnumeratorBuilder{} -} - -func (e *CloudEnumerator) init(to, providerVersion, configDirectory string) error { - e.to = to - - resFactory := terraform.NewTerraformResourceFactory() - - err := remote.Activate(to, providerVersion, e.alerter, e.providerLibrary, e.remoteLibrary, e.progress, resFactory, configDirectory) - if err != nil { - return err - } - return nil -} - -func (e *CloudEnumerator) Enumerate(input *enumeration.EnumerateInput) (*enumeration.EnumerateOutput, error) { - - e.alerter.alerts = alerter.Alerts{} - - enumerators := e.remoteLibrary.Enumerators() - - types := map[string]struct{}{} - for _, resourceType := range input.ResourceTypes { - if !resource.IsResourceTypeSupported(resourceType) { - e.alerter.SendAlert(resourceType, alerter.NewUnsupportedResourcetypeAlert(resourceType)) - } - types[resourceType] = struct{}{} - } - filter := typeFilter{types: types} - - for _, enumerator := range enumerators { - if filter.IsTypeIgnored(enumerator.SupportedType()) { - logrus.WithFields(logrus.Fields{ - "type": enumerator.SupportedType(), - }).Debug("Ignored enumeration of resources since it is ignored in filter") - continue - } - enumerator := enumerator - e.enumeratorRunner.Run(func() (interface{}, error) { - resources, err := enumerator.Enumerate() - if err != nil { - err := remote.HandleResourceEnumerationError(err, e.alerter) - if err == nil { - return []*resource.Resource{}, nil - } - return nil, err - } - for _, res := range resources { - if res == nil { - continue - } - logrus.WithFields(logrus.Fields{ - "id": res.ResourceId(), - "type": res.ResourceType(), - }).Debug("Found cloud resource") - } - return resources, nil - }) - } - - results, err := e.retrieveRunnerResults(e.enumeratorRunner) - if err != nil { - return nil, err - } - - mapRes := mapByType(results) - - diagnostics := diagnostic.FromAlerts(e.alerter.Alerts()) - - return &enumeration.EnumerateOutput{ - Resources: mapRes, - Timings: nil, - Diagnostics: diagnostics, - }, nil -} - -func (e *CloudEnumerator) Refresh(input *enumeration.RefreshInput) (*enumeration.RefreshOutput, error) { - - e.alerter.alerts = alerter.Alerts{} - - for _, resByType := range input.Resources { - for _, res := range resByType { - res := res - e.detailsFetcherRunner.Run(func() (interface{}, error) { - fetcher := e.remoteLibrary.GetDetailsFetcher(resource.ResourceType(res.ResourceType())) - if fetcher == nil { - return []*resource.Resource{res}, nil - } - - resourceWithDetails, err := fetcher.ReadDetails(res) - if err != nil { - if err := remote.HandleResourceDetailsFetchingError(err, e.alerter); err != nil { - return nil, err - } - return []*resource.Resource{}, nil - } - return []*resource.Resource{resourceWithDetails}, nil - }) - } - } - - results, err := e.retrieveRunnerResults(e.detailsFetcherRunner) - if err != nil { - return nil, err - } - - mapRes := mapByType(results) - diagnostics := diagnostic.FromAlerts(e.alerter.Alerts()) - - return &enumeration.RefreshOutput{ - Resources: mapRes, - Diagnostics: diagnostics, - }, nil -} - -func (e *CloudEnumerator) GetSchema() (*enumeration.GetSchemasOutput, error) { - panic("GetSchema is not implemented..") -} - -func (e *CloudEnumerator) retrieveRunnerResults(runner *parallel.ParallelRunner) ([]*resource.Resource, error) { - results := make([]*resource.Resource, 0) -loop: - for { - select { - case resources, ok := <-runner.Read(): - if !ok || resources == nil { - break loop - } - - for _, res := range resources.([]*resource.Resource) { - if res != nil { - results = append(results, res) - } - } - case <-runner.DoneChan(): - break loop - } - } - return results, runner.Err() -} - -func (e *CloudEnumerator) List(typ string) (*ListOutput, error) { - - diagnostics := diagnostic.Diagnostics{} - - enumInput := &enumeration.EnumerateInput{ResourceTypes: []string{typ}} - enumerate, err := e.Enumerate(enumInput) - if err != nil { - return nil, err - } - diagnostics = append(diagnostics, enumerate.Diagnostics...) - - refreshInput := &enumeration.RefreshInput{Resources: enumerate.Resources} - refresh, err := e.Refresh(refreshInput) - if err != nil { - return nil, err - } - diagnostics = append(diagnostics, refresh.Diagnostics...) - - return &ListOutput{ - Resources: refresh.Resources[typ], - Diagnostics: diagnostics, - }, nil -} - -type sliceAlerter struct { - lock sync.Mutex - alerts alerter.Alerts -} - -func newSliceAlerter() *sliceAlerter { - return &sliceAlerter{ - alerts: alerter.Alerts{}, - } -} - -func (d *sliceAlerter) Alerts() alerter.Alerts { - return d.alerts -} - -func (d *sliceAlerter) SendAlert(key string, alert alerter.Alert) { - d.lock.Lock() - defer d.lock.Unlock() - d.alerts[key] = append(d.alerts[key], alert) -} - -type typeFilter struct { - types map[string]struct{} -} - -func (u *typeFilter) IsTypeIgnored(ty resource.ResourceType) bool { - _, ok := u.types[ty.String()] - return !ok -} - -func (u *typeFilter) IsResourceIgnored(res *resource.Resource) bool { - _, ok := u.types[res.Type] - return !ok -} - -func (u *typeFilter) IsFieldIgnored(res *resource.Resource, path []string) bool { - return false -} - -type dummyCounter struct { -} - -func (d *dummyCounter) Inc() { -} - -func mapByType(results []*resource.Resource) map[string][]*resource.Resource { - mapRes := map[string][]*resource.Resource{} - for _, result := range results { - mapRes[result.Type] = append(mapRes[result.Type], result) - } - return mapRes -} diff --git a/enumeration/filter.go b/enumeration/filter.go index 7c8ef215b..f3baf101b 100644 --- a/enumeration/filter.go +++ b/enumeration/filter.go @@ -5,5 +5,4 @@ import "github.com/snyk/driftctl/enumeration/resource" type Filter interface { IsTypeIgnored(ty resource.ResourceType) bool IsResourceIgnored(res *resource.Resource) bool - IsFieldIgnored(res *resource.Resource, path []string) bool } diff --git a/enumeration/mock_Filter.go b/enumeration/mock_Filter.go index 0b1b546d3..24c48f27e 100644 --- a/enumeration/mock_Filter.go +++ b/enumeration/mock_Filter.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.28.1. DO NOT EDIT. +// Code generated by mockery v2.35.4. DO NOT EDIT. package enumeration @@ -12,20 +12,6 @@ type MockFilter struct { mock.Mock } -// IsFieldIgnored provides a mock function with given fields: res, path -func (_m *MockFilter) IsFieldIgnored(res *resource.Resource, path []string) bool { - ret := _m.Called(res, path) - - var r0 bool - if rf, ok := ret.Get(0).(func(*resource.Resource, []string) bool); ok { - r0 = rf(res, path) - } else { - r0 = ret.Get(0).(bool) - } - - return r0 -} - // IsResourceIgnored provides a mock function with given fields: res func (_m *MockFilter) IsResourceIgnored(res *resource.Resource) bool { ret := _m.Called(res) @@ -54,13 +40,12 @@ func (_m *MockFilter) IsTypeIgnored(ty resource.ResourceType) bool { return r0 } -type mockConstructorTestingTNewMockFilter interface { +// NewMockFilter creates a new instance of MockFilter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockFilter(t interface { mock.TestingT Cleanup(func()) -} - -// NewMockFilter creates a new instance of MockFilter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewMockFilter(t mockConstructorTestingTNewMockFilter) *MockFilter { +}) *MockFilter { mock := &MockFilter{} mock.Mock.Test(t) diff --git a/enumeration/remote/aws/init.go b/enumeration/remote/aws/init.go index 693759446..4ad81bdf6 100644 --- a/enumeration/remote/aws/init.go +++ b/enumeration/remote/aws/init.go @@ -8,7 +8,6 @@ import ( "github.com/snyk/driftctl/enumeration/remote/cache" "github.com/snyk/driftctl/enumeration/remote/common" "github.com/snyk/driftctl/enumeration/resource" - "github.com/snyk/driftctl/enumeration/resource/aws" "github.com/snyk/driftctl/enumeration/terraform" ) @@ -57,147 +56,88 @@ func Init(version string, alerter alerter.AlerterInterface, providerLibrary *ter elbRepository := repository.NewELBRepository(provider.session, repositoryCache) elasticacheRepository := repository.NewElastiCacheRepository(provider.session, repositoryCache) - deserializer := resource.NewDeserializer(factory) providerLibrary.AddProvider(terraform.AWS, provider) remoteLibrary.AddEnumerator(NewS3BucketEnumerator(s3Repository, factory, provider.Config, alerter)) - remoteLibrary.AddDetailsFetcher(aws.AwsS3BucketResourceType, common.NewGenericDetailsFetcher(aws.AwsS3BucketResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewS3BucketInventoryEnumerator(s3Repository, factory, provider.Config, alerter)) - remoteLibrary.AddDetailsFetcher(aws.AwsS3BucketInventoryResourceType, common.NewGenericDetailsFetcher(aws.AwsS3BucketInventoryResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewS3BucketNotificationEnumerator(s3Repository, factory, provider.Config, alerter)) - remoteLibrary.AddDetailsFetcher(aws.AwsS3BucketNotificationResourceType, common.NewGenericDetailsFetcher(aws.AwsS3BucketNotificationResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewS3BucketMetricsEnumerator(s3Repository, factory, provider.Config, alerter)) - remoteLibrary.AddDetailsFetcher(aws.AwsS3BucketMetricResourceType, common.NewGenericDetailsFetcher(aws.AwsS3BucketMetricResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewS3BucketPolicyEnumerator(s3Repository, factory, provider.Config, alerter)) - remoteLibrary.AddDetailsFetcher(aws.AwsS3BucketPolicyResourceType, common.NewGenericDetailsFetcher(aws.AwsS3BucketPolicyResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewS3BucketAnalyticEnumerator(s3Repository, factory, provider.Config, alerter)) - remoteLibrary.AddDetailsFetcher(aws.AwsS3BucketAnalyticsConfigurationResourceType, common.NewGenericDetailsFetcher(aws.AwsS3BucketAnalyticsConfigurationResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewS3BucketPublicAccessBlockEnumerator(s3Repository, factory, provider.Config, alerter)) remoteLibrary.AddEnumerator(NewS3AccountPublicAccessBlockEnumerator(s3ControlRepository, factory, provider.accountId, alerter)) remoteLibrary.AddEnumerator(NewEC2EbsVolumeEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsEbsVolumeResourceType, common.NewGenericDetailsFetcher(aws.AwsEbsVolumeResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2EbsSnapshotEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsEbsSnapshotResourceType, common.NewGenericDetailsFetcher(aws.AwsEbsSnapshotResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2EipEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsEipResourceType, common.NewGenericDetailsFetcher(aws.AwsEipResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2AmiEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsAmiResourceType, common.NewGenericDetailsFetcher(aws.AwsAmiResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2KeyPairEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsKeyPairResourceType, common.NewGenericDetailsFetcher(aws.AwsKeyPairResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2EipAssociationEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsEipAssociationResourceType, common.NewGenericDetailsFetcher(aws.AwsEipAssociationResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2InstanceEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsInstanceResourceType, common.NewGenericDetailsFetcher(aws.AwsInstanceResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2InternetGatewayEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsInternetGatewayResourceType, common.NewGenericDetailsFetcher(aws.AwsInternetGatewayResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewVPCEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsVpcResourceType, common.NewGenericDetailsFetcher(aws.AwsVpcResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewDefaultVPCEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsDefaultVpcResourceType, common.NewGenericDetailsFetcher(aws.AwsDefaultVpcResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2RouteTableEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsRouteTableResourceType, common.NewGenericDetailsFetcher(aws.AwsRouteTableResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2DefaultRouteTableEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsDefaultRouteTableResourceType, common.NewGenericDetailsFetcher(aws.AwsDefaultRouteTableResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2RouteTableAssociationEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsRouteTableAssociationResourceType, common.NewGenericDetailsFetcher(aws.AwsRouteTableAssociationResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2SubnetEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsSubnetResourceType, common.NewGenericDetailsFetcher(aws.AwsSubnetResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2DefaultSubnetEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsDefaultSubnetResourceType, common.NewGenericDetailsFetcher(aws.AwsDefaultSubnetResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewVPCSecurityGroupEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsSecurityGroupResourceType, common.NewGenericDetailsFetcher(aws.AwsSecurityGroupResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewVPCDefaultSecurityGroupEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsDefaultSecurityGroupResourceType, common.NewGenericDetailsFetcher(aws.AwsDefaultSecurityGroupResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2NatGatewayEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsNatGatewayResourceType, common.NewGenericDetailsFetcher(aws.AwsNatGatewayResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2NetworkACLEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsNetworkACLResourceType, common.NewGenericDetailsFetcher(aws.AwsNetworkACLResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2NetworkACLRuleEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsNetworkACLRuleResourceType, common.NewGenericDetailsFetcher(aws.AwsNetworkACLRuleResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2DefaultNetworkACLEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsDefaultNetworkACLResourceType, common.NewGenericDetailsFetcher(aws.AwsDefaultNetworkACLResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2RouteEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsRouteResourceType, common.NewGenericDetailsFetcher(aws.AwsRouteResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewVPCSecurityGroupRuleEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsSecurityGroupRuleResourceType, common.NewGenericDetailsFetcher(aws.AwsSecurityGroupRuleResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewLaunchTemplateEnumerator(ec2repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsLaunchTemplateResourceType, common.NewGenericDetailsFetcher(aws.AwsLaunchTemplateResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewEC2EbsEncryptionByDefaultEnumerator(ec2repository, factory)) remoteLibrary.AddEnumerator(NewKMSKeyEnumerator(kmsRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsKmsKeyResourceType, common.NewGenericDetailsFetcher(aws.AwsKmsKeyResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewKMSAliasEnumerator(kmsRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsKmsAliasResourceType, common.NewGenericDetailsFetcher(aws.AwsKmsAliasResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewRoute53HealthCheckEnumerator(route53repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsRoute53HealthCheckResourceType, common.NewGenericDetailsFetcher(aws.AwsRoute53HealthCheckResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewRoute53ZoneEnumerator(route53repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsRoute53ZoneResourceType, common.NewGenericDetailsFetcher(aws.AwsRoute53ZoneResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewRoute53RecordEnumerator(route53repository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsRoute53RecordResourceType, common.NewGenericDetailsFetcher(aws.AwsRoute53RecordResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewCloudfrontDistributionEnumerator(cloudfrontRepository, factory)) - 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(NewRDSDBSubnetGroupEnumerator(rdsRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsDbSubnetGroupResourceType, common.NewGenericDetailsFetcher(aws.AwsDbSubnetGroupResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewSQSQueueEnumerator(sqsRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsSqsQueueResourceType, NewSQSQueueDetailsFetcher(provider, deserializer)) remoteLibrary.AddEnumerator(NewSQSQueuePolicyEnumerator(sqsRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsSqsQueuePolicyResourceType, common.NewGenericDetailsFetcher(aws.AwsSqsQueuePolicyResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewSNSTopicEnumerator(snsRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsSnsTopicResourceType, common.NewGenericDetailsFetcher(aws.AwsSnsTopicResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewSNSTopicPolicyEnumerator(snsRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsSnsTopicPolicyResourceType, common.NewGenericDetailsFetcher(aws.AwsSnsTopicPolicyResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewSNSTopicSubscriptionEnumerator(snsRepository, factory, alerter)) - remoteLibrary.AddDetailsFetcher(aws.AwsSnsTopicSubscriptionResourceType, common.NewGenericDetailsFetcher(aws.AwsSnsTopicSubscriptionResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewDynamoDBTableEnumerator(dynamoDBRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsDynamodbTableResourceType, common.NewGenericDetailsFetcher(aws.AwsDynamodbTableResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewIamPolicyEnumerator(iamRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsIamPolicyResourceType, common.NewGenericDetailsFetcher(aws.AwsIamPolicyResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewLambdaFunctionEnumerator(lambdaRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsLambdaFunctionResourceType, common.NewGenericDetailsFetcher(aws.AwsLambdaFunctionResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewLambdaEventSourceMappingEnumerator(lambdaRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsLambdaEventSourceMappingResourceType, common.NewGenericDetailsFetcher(aws.AwsLambdaEventSourceMappingResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewIamUserEnumerator(iamRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsIamUserResourceType, common.NewGenericDetailsFetcher(aws.AwsIamUserResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewIamUserPolicyEnumerator(iamRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsIamUserPolicyResourceType, common.NewGenericDetailsFetcher(aws.AwsIamUserPolicyResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewIamRoleEnumerator(iamRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsIamRoleResourceType, common.NewGenericDetailsFetcher(aws.AwsIamRoleResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewIamAccessKeyEnumerator(iamRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsIamAccessKeyResourceType, common.NewGenericDetailsFetcher(aws.AwsIamAccessKeyResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewIamRolePolicyAttachmentEnumerator(iamRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsIamRolePolicyAttachmentResourceType, common.NewGenericDetailsFetcher(aws.AwsIamRolePolicyAttachmentResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewIamRolePolicyEnumerator(iamRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsIamRolePolicyResourceType, common.NewGenericDetailsFetcher(aws.AwsIamRolePolicyResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewIamUserPolicyAttachmentEnumerator(iamRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsIamUserPolicyAttachmentResourceType, common.NewGenericDetailsFetcher(aws.AwsIamUserPolicyAttachmentResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewIamGroupPolicyEnumerator(iamRepository, factory)) remoteLibrary.AddEnumerator(NewIamGroupEnumerator(iamRepository, factory)) remoteLibrary.AddEnumerator(NewIamGroupPolicyAttachmentEnumerator(iamRepository, factory)) remoteLibrary.AddEnumerator(NewECRRepositoryEnumerator(ecrRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsEcrRepositoryResourceType, common.NewGenericDetailsFetcher(aws.AwsEcrRepositoryResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewECRRepositoryPolicyEnumerator(ecrRepository, factory)) remoteLibrary.AddEnumerator(NewRDSClusterEnumerator(rdsRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsRDSClusterResourceType, common.NewGenericDetailsFetcher(aws.AwsRDSClusterResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewCloudformationStackEnumerator(cloudformationRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsCloudformationStackResourceType, common.NewGenericDetailsFetcher(aws.AwsCloudformationStackResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewCloudtrailEnumerator(cloudtrailRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsCloudtrailResourceType, common.NewGenericDetailsFetcher(aws.AwsCloudtrailResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewApiGatewayRestApiEnumerator(apigatewayRepository, factory)) remoteLibrary.AddEnumerator(NewApiGatewayAccountEnumerator(apigatewayRepository, factory)) @@ -232,10 +172,8 @@ func Init(version string, alerter alerter.AlerterInterface, providerLibrary *ter remoteLibrary.AddEnumerator(NewApiGatewayV2IntegrationResponseEnumerator(apigatewayv2Repository, factory)) remoteLibrary.AddEnumerator(NewAppAutoscalingTargetEnumerator(appAutoScalingRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsAppAutoscalingTargetResourceType, common.NewGenericDetailsFetcher(aws.AwsAppAutoscalingTargetResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewAppAutoscalingPolicyEnumerator(appAutoScalingRepository, factory)) - remoteLibrary.AddDetailsFetcher(aws.AwsAppAutoscalingPolicyResourceType, common.NewGenericDetailsFetcher(aws.AwsAppAutoscalingPolicyResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewAppAutoscalingScheduledActionEnumerator(appAutoScalingRepository, factory)) diff --git a/enumeration/remote/aws/sqs_queue_details_fetcher.go b/enumeration/remote/aws/sqs_queue_details_fetcher.go deleted file mode 100644 index 7aba9327e..000000000 --- a/enumeration/remote/aws/sqs_queue_details_fetcher.go +++ /dev/null @@ -1,47 +0,0 @@ -package aws - -import ( - remoteerror "github.com/snyk/driftctl/enumeration/remote/error" - "github.com/snyk/driftctl/enumeration/terraform" - "strings" - - "github.com/sirupsen/logrus" - "github.com/snyk/driftctl/enumeration/resource" - "github.com/snyk/driftctl/enumeration/resource/aws" -) - -type SQSQueueDetailsFetcher struct { - reader terraform.ResourceReader - deserializer *resource.Deserializer -} - -func NewSQSQueueDetailsFetcher(provider terraform.ResourceReader, deserializer *resource.Deserializer) *SQSQueueDetailsFetcher { - return &SQSQueueDetailsFetcher{ - reader: provider, - deserializer: deserializer, - } -} - -func (r *SQSQueueDetailsFetcher) ReadDetails(res *resource.Resource) (*resource.Resource, error) { - ctyVal, err := r.reader.ReadResource(terraform.ReadResourceArgs{ - ID: res.ResourceId(), - Ty: aws.AwsSqsQueueResourceType, - }) - if err != nil { - if strings.Contains(err.Error(), "NonExistentQueue") { - logrus.WithFields(logrus.Fields{ - "id": res.ResourceId(), - "type": aws.AwsSqsQueueResourceType, - }).Debugf("Ignoring queue that seems to be already deleted: %+v", err) - return nil, nil - } - logrus.Error(err) - return nil, remoteerror.NewResourceScanningError(err, res.ResourceType(), res.ResourceId()) - } - deserializedRes, err := r.deserializer.DeserializeOne(aws.AwsSqsQueueResourceType, *ctyVal) - if err != nil { - return nil, err - } - - return deserializedRes, nil -} diff --git a/enumeration/remote/aws_api_gateway_scanner_test.go b/enumeration/remote/aws_api_gateway_scanner_test.go index 9f0d7f2f9..14ff45f13 100644 --- a/enumeration/remote/aws_api_gateway_scanner_test.go +++ b/enumeration/remote/aws_api_gateway_scanner_test.go @@ -72,7 +72,6 @@ func TestApiGatewayRestApi(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -87,7 +86,7 @@ func TestApiGatewayRestApi(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -146,7 +145,6 @@ func TestApiGatewayAccount(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -161,7 +159,7 @@ func TestApiGatewayAccount(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -226,7 +224,6 @@ func TestApiGatewayApiKey(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -241,7 +238,7 @@ func TestApiGatewayApiKey(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -324,7 +321,6 @@ func TestApiGatewayAuthorizer(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -339,7 +335,7 @@ func TestApiGatewayAuthorizer(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -418,7 +414,6 @@ func TestApiGatewayStage(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -433,7 +428,7 @@ func TestApiGatewayStage(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -512,7 +507,6 @@ func TestApiGatewayResource(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -527,7 +521,7 @@ func TestApiGatewayResource(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -588,7 +582,6 @@ func TestApiGatewayDomainName(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -603,7 +596,7 @@ func TestApiGatewayDomainName(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -664,7 +657,6 @@ func TestApiGatewayVpcLink(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -679,7 +671,7 @@ func TestApiGatewayVpcLink(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -758,7 +750,6 @@ func TestApiGatewayRequestValidator(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -773,7 +764,7 @@ func TestApiGatewayRequestValidator(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -841,7 +832,6 @@ func TestApiGatewayRestApiPolicy(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -856,7 +846,7 @@ func TestApiGatewayRestApiPolicy(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -935,7 +925,6 @@ func TestApiGatewayBasePathMapping(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -950,7 +939,7 @@ func TestApiGatewayBasePathMapping(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1037,7 +1026,6 @@ func TestApiGatewayMethod(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -1052,7 +1040,7 @@ func TestApiGatewayMethod(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := remote.NewSortableScanner(NewScanner(remoteLibrary, alerter, scanOptions, testFilter)) + s := remote.NewSortableScanner(NewScanner(remoteLibrary, alerter, testFilter)) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1131,7 +1119,6 @@ func TestApiGatewayModel(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -1146,7 +1133,7 @@ func TestApiGatewayModel(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1237,7 +1224,6 @@ func TestApiGatewayMethodResponse(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -1252,7 +1238,7 @@ func TestApiGatewayMethodResponse(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := remote.NewSortableScanner(NewScanner(remoteLibrary, alerter, scanOptions, testFilter)) + s := remote.NewSortableScanner(NewScanner(remoteLibrary, alerter, testFilter)) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1331,7 +1317,6 @@ func TestApiGatewayGatewayResponse(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -1346,7 +1331,7 @@ func TestApiGatewayGatewayResponse(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1433,7 +1418,6 @@ func TestApiGatewayMethodSettings(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -1448,7 +1432,7 @@ func TestApiGatewayMethodSettings(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := remote.NewSortableScanner(NewScanner(remoteLibrary, alerter, scanOptions, testFilter)) + s := remote.NewSortableScanner(NewScanner(remoteLibrary, alerter, testFilter)) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1535,7 +1519,6 @@ func TestApiGatewayIntegration(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -1550,7 +1533,7 @@ func TestApiGatewayIntegration(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := remote.NewSortableScanner(NewScanner(remoteLibrary, alerter, scanOptions, testFilter)) + s := remote.NewSortableScanner(NewScanner(remoteLibrary, alerter, testFilter)) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1641,7 +1624,6 @@ func TestApiGatewayIntegrationResponse(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -1656,7 +1638,7 @@ func TestApiGatewayIntegrationResponse(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := remote.NewSortableScanner(NewScanner(remoteLibrary, alerter, scanOptions, testFilter)) + s := remote.NewSortableScanner(NewScanner(remoteLibrary, alerter, testFilter)) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { diff --git a/enumeration/remote/aws_apigatewayv2_scanner_test.go b/enumeration/remote/aws_apigatewayv2_scanner_test.go index 5b6570fa6..6c93a82a8 100644 --- a/enumeration/remote/aws_apigatewayv2_scanner_test.go +++ b/enumeration/remote/aws_apigatewayv2_scanner_test.go @@ -69,7 +69,6 @@ func TestApiGatewayV2Api(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -84,7 +83,7 @@ func TestApiGatewayV2Api(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -155,7 +154,6 @@ func TestApiGatewayV2Route(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -170,7 +168,7 @@ func TestApiGatewayV2Route(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -261,7 +259,6 @@ func TestApiGatewayV2Deployment(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -276,7 +273,7 @@ func TestApiGatewayV2Deployment(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -337,7 +334,6 @@ func TestApiGatewayV2VpcLink(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -352,7 +348,7 @@ func TestApiGatewayV2VpcLink(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -436,7 +432,6 @@ func TestApiGatewayV2Authorizer(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -451,7 +446,7 @@ func TestApiGatewayV2Authorizer(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -541,7 +536,6 @@ func TestApiGatewayV2Integration(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -556,7 +550,7 @@ func TestApiGatewayV2Integration(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -649,7 +643,6 @@ func TestApiGatewayV2Model(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -664,7 +657,7 @@ func TestApiGatewayV2Model(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -729,7 +722,6 @@ func TestApiGatewayV2Stage(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -744,7 +736,7 @@ func TestApiGatewayV2Stage(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -847,7 +839,6 @@ func TestApiGatewayV2RouteResponse(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -862,7 +853,7 @@ func TestApiGatewayV2RouteResponse(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -969,7 +960,6 @@ func TestApiGatewayV2Mapping(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -983,7 +973,7 @@ func TestApiGatewayV2Mapping(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1045,7 +1035,6 @@ func TestApiGatewayV2DomainName(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -1060,7 +1049,7 @@ func TestApiGatewayV2DomainName(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1163,7 +1152,6 @@ func TestApiGatewayV2IntegrationResponse(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -1178,7 +1166,7 @@ func TestApiGatewayV2IntegrationResponse(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { diff --git a/enumeration/remote/aws_applicationautoscaling_scanner_test.go b/enumeration/remote/aws_applicationautoscaling_scanner_test.go index 57e325c36..e6ba0612d 100644 --- a/enumeration/remote/aws_applicationautoscaling_scanner_test.go +++ b/enumeration/remote/aws_applicationautoscaling_scanner_test.go @@ -19,7 +19,6 @@ import ( resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" "github.com/snyk/driftctl/mocks" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" @@ -28,10 +27,11 @@ import ( func TestAppAutoScalingTarget(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockAppAutoScalingRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockAppAutoScalingRepository, *mocks.AlerterInterface) + assertExpected func(t *testing.T, got []*resource.Resource) + wantErr error }{ { test: "should return one target", @@ -52,6 +52,12 @@ func TestAppAutoScalingTarget(t *testing.T) { client.On("DescribeScalableTargets", mock.AnythingOfType("string")).Return([]*applicationautoscaling.ScalableTarget{}, nil).Times(len(applicationautoscaling.ServiceNamespace_Values()) - 1) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, got[0].ResourceId(), "table/GameScores") + assert.Equal(t, got[0].ResourceType(), resourceaws.AwsAppAutoscalingTargetResourceType) + }, wantErr: nil, }, { @@ -67,7 +73,6 @@ func TestAppAutoScalingTarget(t *testing.T) { } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -77,7 +82,6 @@ func TestAppAutoScalingTarget(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -106,12 +110,11 @@ func TestAppAutoScalingTarget(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewAppAutoscalingTargetEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsAppAutoscalingTargetResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsAppAutoscalingTargetResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() if err != nil { assert.EqualError(tt, c.wantErr, err.Error()) @@ -122,7 +125,7 @@ func TestAppAutoScalingTarget(t *testing.T) { if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsAppAutoscalingTargetResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -131,10 +134,11 @@ func TestAppAutoScalingTarget(t *testing.T) { func TestAppAutoScalingPolicy(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockAppAutoScalingRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockAppAutoScalingRepository, *mocks.AlerterInterface) + assertExpected func(t *testing.T, got []*resource.Resource) + wantErr error }{ { test: "should return one policy", @@ -153,6 +157,12 @@ func TestAppAutoScalingPolicy(t *testing.T) { client.On("DescribeScalingPolicies", mock.AnythingOfType("string")).Return([]*applicationautoscaling.ScalingPolicy{}, nil).Times(len(applicationautoscaling.ServiceNamespace_Values()) - 1) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, got[0].ResourceId(), "DynamoDBReadCapacityUtilization:table/GameScores") + assert.Equal(t, got[0].ResourceType(), resourceaws.AwsAppAutoscalingPolicyResourceType) + }, wantErr: nil, }, { @@ -168,7 +178,6 @@ func TestAppAutoScalingPolicy(t *testing.T) { } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -178,7 +187,6 @@ func TestAppAutoScalingPolicy(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -207,12 +215,11 @@ func TestAppAutoScalingPolicy(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewAppAutoscalingPolicyEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsAppAutoscalingPolicyResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsAppAutoscalingPolicyResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() if err != nil { assert.EqualError(tt, c.wantErr, err.Error()) @@ -223,7 +230,8 @@ func TestAppAutoScalingPolicy(t *testing.T) { if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsAppAutoscalingPolicyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -289,7 +297,6 @@ func TestAppAutoScalingScheduledAction(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -304,7 +311,7 @@ func TestAppAutoScalingScheduledAction(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { diff --git a/enumeration/remote/aws_autoscaling_scanner_test.go b/enumeration/remote/aws_autoscaling_scanner_test.go index 7e7f3cded..cd2897972 100644 --- a/enumeration/remote/aws_autoscaling_scanner_test.go +++ b/enumeration/remote/aws_autoscaling_scanner_test.go @@ -76,8 +76,6 @@ func TestAutoscaling_LaunchConfiguration(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -92,7 +90,7 @@ func TestAutoscaling_LaunchConfiguration(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { diff --git a/enumeration/remote/aws_cloudformation_scanner_test.go b/enumeration/remote/aws_cloudformation_scanner_test.go index 7aa504b85..452b3e956 100644 --- a/enumeration/remote/aws_cloudformation_scanner_test.go +++ b/enumeration/remote/aws_cloudformation_scanner_test.go @@ -1,9 +1,9 @@ package remote import ( - "errors" "testing" + "github.com/pkg/errors" "github.com/snyk/driftctl/enumeration" "github.com/snyk/driftctl/enumeration/remote/alerts" "github.com/snyk/driftctl/enumeration/remote/aws" @@ -11,6 +11,7 @@ import ( "github.com/snyk/driftctl/enumeration/remote/cache" "github.com/snyk/driftctl/enumeration/remote/common" remoteerr "github.com/snyk/driftctl/enumeration/remote/error" + resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" "github.com/snyk/driftctl/enumeration/terraform" awssdk "github.com/aws/aws-sdk-go/aws" @@ -18,10 +19,8 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/cloudformation" "github.com/snyk/driftctl/enumeration/resource" - resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" "github.com/snyk/driftctl/mocks" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" @@ -29,11 +28,13 @@ import ( ) func TestCloudformationStack(t *testing.T) { + awsError := awserr.NewRequestFailure(awserr.New("AccessDeniedException", "", errors.New("")), 400, "") tests := []struct { - test string - dirName string - mocks func(*repository.MockCloudformationRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockCloudformationRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no cloudformation stacks", @@ -41,6 +42,9 @@ func TestCloudformationStack(t *testing.T) { mocks: func(repository *repository.MockCloudformationRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllStacks").Return([]*cloudformation.Stack{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple cloudformation stacks", @@ -51,22 +55,32 @@ func TestCloudformationStack(t *testing.T) { {StackId: awssdk.String("arn:aws:cloudformation:us-east-1:047081014315:stack/foo-stack/c7aa0ab0-0f21-11ec-ba25-129d8c0b3757")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "arn:aws:cloudformation:us-east-1:047081014315:stack/bar-stack/c7a96e70-0f21-11ec-bd2a-0a2d95c2b2ab", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsCloudformationStackResourceType, got[0].ResourceType()) + + assert.Equal(t, "arn:aws:cloudformation:us-east-1:047081014315:stack/foo-stack/c7aa0ab0-0f21-11ec-ba25-129d8c0b3757", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsCloudformationStackResourceType, got[1].ResourceType()) + }, }, { test: "cannot list cloudformation stacks", dirName: "aws_cloudformation_stack_list", mocks: func(repository *repository.MockCloudformationRepository, alerter *mocks.AlerterInterface) { - awsError := awserr.NewRequestFailure(awserr.New("AccessDeniedException", "", errors.New("")), 400, "") repository.On("ListAllStacks").Return(nil, awsError) alerter.On("SendAlert", resourceaws.AwsCloudformationStackResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsCloudformationStackResourceType, resourceaws.AwsCloudformationStackResourceType), alerts.EnumerationPhase)).Return() }, wantErr: nil, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -76,7 +90,6 @@ func TestCloudformationStack(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -105,18 +118,18 @@ func TestCloudformationStack(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewCloudformationStackEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsCloudformationStackResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsCloudformationStackResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsCloudformationStackResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) testFilter.AssertExpectations(tt) diff --git a/enumeration/remote/aws_cloudfront_scanner_test.go b/enumeration/remote/aws_cloudfront_scanner_test.go index e708d3c7c..0a7dcd14a 100644 --- a/enumeration/remote/aws_cloudfront_scanner_test.go +++ b/enumeration/remote/aws_cloudfront_scanner_test.go @@ -3,6 +3,7 @@ package remote import ( "testing" + "github.com/pkg/errors" "github.com/snyk/driftctl/enumeration" "github.com/snyk/driftctl/enumeration/remote/alerts" "github.com/snyk/driftctl/enumeration/remote/aws" @@ -10,18 +11,16 @@ import ( "github.com/snyk/driftctl/enumeration/remote/cache" "github.com/snyk/driftctl/enumeration/remote/common" remoteerr "github.com/snyk/driftctl/enumeration/remote/error" + resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" "github.com/snyk/driftctl/enumeration/terraform" 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/cloudfront" - "github.com/pkg/errors" "github.com/snyk/driftctl/enumeration/resource" - resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" "github.com/snyk/driftctl/mocks" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" @@ -30,10 +29,11 @@ import ( func TestCloudfrontDistribution(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockCloudfrontRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockCloudfrontRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no cloudfront distributions", @@ -41,6 +41,9 @@ func TestCloudfrontDistribution(t *testing.T) { mocks: func(repository *repository.MockCloudfrontRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllDistributions").Return([]*cloudfront.DistributionSummary{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "single cloudfront distribution", @@ -50,6 +53,12 @@ func TestCloudfrontDistribution(t *testing.T) { {Id: awssdk.String("E1M9CNS0XSHI19")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, "E1M9CNS0XSHI19", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsCloudfrontDistributionResourceType, got[0].ResourceType()) + }, }, { test: "cannot list cloudfront distributions", @@ -61,11 +70,13 @@ func TestCloudfrontDistribution(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsCloudfrontDistributionResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsCloudfrontDistributionResourceType, resourceaws.AwsCloudfrontDistributionResourceType), alerts.EnumerationPhase)).Return() }, wantErr: nil, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -75,7 +86,6 @@ func TestCloudfrontDistribution(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -104,18 +114,18 @@ func TestCloudfrontDistribution(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewCloudfrontDistributionEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsCloudfrontDistributionResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsCloudfrontDistributionResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsCloudfrontDistributionResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) diff --git a/enumeration/remote/aws_dynamodb_scanner_test.go b/enumeration/remote/aws_dynamodb_scanner_test.go index 7858d57e2..e8ea52e4f 100644 --- a/enumeration/remote/aws_dynamodb_scanner_test.go +++ b/enumeration/remote/aws_dynamodb_scanner_test.go @@ -1,9 +1,9 @@ package remote import ( - "errors" "testing" + "github.com/pkg/errors" "github.com/snyk/driftctl/enumeration" "github.com/snyk/driftctl/enumeration/remote/alerts" "github.com/snyk/driftctl/enumeration/remote/aws" @@ -11,16 +11,15 @@ import ( "github.com/snyk/driftctl/enumeration/remote/cache" "github.com/snyk/driftctl/enumeration/remote/common" remoteerr "github.com/snyk/driftctl/enumeration/remote/error" + resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" "github.com/snyk/driftctl/enumeration/terraform" 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/snyk/driftctl/enumeration/resource" - resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" "github.com/snyk/driftctl/mocks" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" @@ -29,10 +28,11 @@ import ( func TestDynamoDBTable(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockDynamoDBRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockDynamoDBRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no DynamoDB Table", @@ -40,6 +40,9 @@ func TestDynamoDBTable(t *testing.T) { mocks: func(client *repository.MockDynamoDBRepository, alerter *mocks.AlerterInterface) { client.On("ListAllTables").Return([]*string{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -51,6 +54,15 @@ func TestDynamoDBTable(t *testing.T) { awssdk.String("example"), }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "GameScores", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsDynamodbTableResourceType, got[0].ResourceType()) + + assert.Equal(t, "example", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsDynamodbTableResourceType, got[1].ResourceType()) + }, wantErr: nil, }, { @@ -62,12 +74,14 @@ func TestDynamoDBTable(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsDynamodbTableResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsDynamodbTableResourceType, resourceaws.AwsDynamodbTableResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -77,7 +91,6 @@ func TestDynamoDBTable(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -106,18 +119,18 @@ func TestDynamoDBTable(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewDynamoDBTableEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsDynamodbTableResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsDynamodbTableResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsDynamodbTableResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) diff --git a/enumeration/remote/aws_ec2_scanner_test.go b/enumeration/remote/aws_ec2_scanner_test.go index ba530babe..bca0eb395 100644 --- a/enumeration/remote/aws_ec2_scanner_test.go +++ b/enumeration/remote/aws_ec2_scanner_test.go @@ -21,7 +21,6 @@ import ( resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" "github.com/snyk/driftctl/mocks" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" @@ -30,10 +29,11 @@ import ( func TestEC2EbsVolume(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no volumes", @@ -41,6 +41,9 @@ func TestEC2EbsVolume(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllVolumes").Return([]*ec2.Volume{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple volumes", @@ -51,6 +54,15 @@ func TestEC2EbsVolume(t *testing.T) { {VolumeId: awssdk.String("vol-01ddc91d3d9d1318b")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "vol-081c7272a57a09db1", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsEbsVolumeResourceType, got[0].ResourceType()) + + assert.Equal(t, "vol-01ddc91d3d9d1318b", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsEbsVolumeResourceType, got[1].ResourceType()) + }, }, { test: "cannot list volumes", @@ -61,12 +73,14 @@ func TestEC2EbsVolume(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsEbsVolumeResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsEbsVolumeResourceType, resourceaws.AwsEbsVolumeResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -76,7 +90,6 @@ func TestEC2EbsVolume(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -105,18 +118,18 @@ func TestEC2EbsVolume(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2EbsVolumeEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsEbsVolumeResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsEbsVolumeResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsEbsVolumeResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -125,10 +138,11 @@ func TestEC2EbsVolume(t *testing.T) { func TestEC2EbsSnapshot(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no snapshots", @@ -136,6 +150,9 @@ func TestEC2EbsSnapshot(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllSnapshots").Return([]*ec2.Snapshot{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple snapshots", @@ -146,6 +163,15 @@ func TestEC2EbsSnapshot(t *testing.T) { {SnapshotId: awssdk.String("snap-00672558cecd93a61")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "snap-0c509a2a880d95a39", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsEbsSnapshotResourceType, got[0].ResourceType()) + + assert.Equal(t, "snap-00672558cecd93a61", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsEbsSnapshotResourceType, got[1].ResourceType()) + }, }, { test: "cannot list snapshots", @@ -156,12 +182,14 @@ func TestEC2EbsSnapshot(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsEbsSnapshotResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsEbsSnapshotResourceType, resourceaws.AwsEbsSnapshotResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -171,7 +199,6 @@ func TestEC2EbsSnapshot(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -200,18 +227,18 @@ func TestEC2EbsSnapshot(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2EbsSnapshotEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsEbsSnapshotResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsEbsSnapshotResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsEbsSnapshotResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -220,10 +247,11 @@ func TestEC2EbsSnapshot(t *testing.T) { func TestEC2Eip(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no eips", @@ -233,6 +261,9 @@ func TestEC2Eip(t *testing.T) { {}, // Test Eip without AllocationId because it can happen (seen in sentry) }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple eips", @@ -243,6 +274,15 @@ func TestEC2Eip(t *testing.T) { {AllocationId: awssdk.String("eipalloc-0cf714dc097c992cc")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "eipalloc-017d5267e4dda73f1", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsEipResourceType, got[0].ResourceType()) + + assert.Equal(t, "eipalloc-0cf714dc097c992cc", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsEipResourceType, got[1].ResourceType()) + }, }, { test: "cannot list eips", @@ -253,12 +293,14 @@ func TestEC2Eip(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsEipResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsEipResourceType, resourceaws.AwsEipResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -268,7 +310,6 @@ func TestEC2Eip(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -297,18 +338,18 @@ func TestEC2Eip(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2EipEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsEipResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsEipResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFileNoCty(got, resourceaws.AwsEipResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -317,10 +358,11 @@ func TestEC2Eip(t *testing.T) { func TestEC2Ami(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no amis", @@ -328,6 +370,9 @@ func TestEC2Ami(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllImages").Return([]*ec2.Image{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple amis", @@ -338,6 +383,15 @@ func TestEC2Ami(t *testing.T) { {ImageId: awssdk.String("ami-025962fd8b456731f")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "ami-03a578b46f4c3081b", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsAmiResourceType, got[0].ResourceType()) + + assert.Equal(t, "ami-025962fd8b456731f", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsAmiResourceType, got[1].ResourceType()) + }, }, { test: "cannot list ami", @@ -348,12 +402,14 @@ func TestEC2Ami(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsAmiResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsAmiResourceType, resourceaws.AwsAmiResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -363,7 +419,6 @@ func TestEC2Ami(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -392,18 +447,18 @@ func TestEC2Ami(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2AmiEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsAmiResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsAmiResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsAmiResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -412,10 +467,11 @@ func TestEC2Ami(t *testing.T) { func TestEC2KeyPair(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no key pairs", @@ -423,6 +479,9 @@ func TestEC2KeyPair(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllKeyPairs").Return([]*ec2.KeyPairInfo{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple key pairs", @@ -433,6 +492,15 @@ func TestEC2KeyPair(t *testing.T) { {KeyName: awssdk.String("bar")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "test", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsKeyPairResourceType, got[0].ResourceType()) + + assert.Equal(t, "bar", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsKeyPairResourceType, got[1].ResourceType()) + }, }, { test: "cannot list key pairs", @@ -443,12 +511,14 @@ func TestEC2KeyPair(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsKeyPairResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsKeyPairResourceType, resourceaws.AwsKeyPairResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -458,7 +528,6 @@ func TestEC2KeyPair(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -487,18 +556,18 @@ func TestEC2KeyPair(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2KeyPairEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsKeyPairResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsKeyPairResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsKeyPairResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -507,10 +576,11 @@ func TestEC2KeyPair(t *testing.T) { func TestEC2EipAssociation(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no eip associations", @@ -518,6 +588,9 @@ func TestEC2EipAssociation(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllAddressesAssociation").Return([]*ec2.Address{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "single eip association", @@ -530,6 +603,12 @@ func TestEC2EipAssociation(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, "eipassoc-0e9a7356e30f0c3d1", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsEipAssociationResourceType, got[0].ResourceType()) + }, }, { test: "cannot list eip associations", @@ -540,12 +619,14 @@ func TestEC2EipAssociation(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsEipAssociationResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsEipAssociationResourceType, resourceaws.AwsEipAssociationResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -555,7 +636,6 @@ func TestEC2EipAssociation(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -584,18 +664,18 @@ func TestEC2EipAssociation(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2EipAssociationEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsEipAssociationResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsEipAssociationResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsEipAssociationResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -604,10 +684,11 @@ func TestEC2EipAssociation(t *testing.T) { func TestEC2Instance(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no instances", @@ -615,6 +696,9 @@ func TestEC2Instance(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllInstances").Return([]*ec2.Instance{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple instances", @@ -625,6 +709,15 @@ func TestEC2Instance(t *testing.T) { {InstanceId: awssdk.String("i-010376047a71419f1")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "i-0d3650a23f4e45dc0", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsInstanceResourceType, got[0].ResourceType()) + + assert.Equal(t, "i-010376047a71419f1", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsInstanceResourceType, got[1].ResourceType()) + }, }, { test: "terminated instances", @@ -635,6 +728,15 @@ func TestEC2Instance(t *testing.T) { {InstanceId: awssdk.String("i-0a3a7ed51ae2b4fa0")}, // Nil }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "i-0e1543baf4f2cd990", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsInstanceResourceType, got[0].ResourceType()) + + assert.Equal(t, "i-0a3a7ed51ae2b4fa0", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsInstanceResourceType, got[1].ResourceType()) + }, }, { test: "cannot list instances", @@ -645,12 +747,14 @@ func TestEC2Instance(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsInstanceResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsInstanceResourceType, resourceaws.AwsInstanceResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -660,7 +764,6 @@ func TestEC2Instance(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -689,18 +792,18 @@ func TestEC2Instance(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2InstanceEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsInstanceResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsInstanceResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsInstanceResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -709,10 +812,11 @@ func TestEC2Instance(t *testing.T) { func TestEC2InternetGateway(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no internet gateways", @@ -720,6 +824,9 @@ func TestEC2InternetGateway(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllInternetGateways").Return([]*ec2.InternetGateway{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple internet gateways", @@ -730,6 +837,15 @@ func TestEC2InternetGateway(t *testing.T) { {InternetGatewayId: awssdk.String("igw-047b487f5c60fca99")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "igw-0184eb41aadc62d1c", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsInternetGatewayResourceType, got[0].ResourceType()) + + assert.Equal(t, "igw-047b487f5c60fca99", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsInternetGatewayResourceType, got[1].ResourceType()) + }, }, { test: "cannot list internet gateways", @@ -740,12 +856,14 @@ func TestEC2InternetGateway(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsInternetGatewayResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsInternetGatewayResourceType, resourceaws.AwsInternetGatewayResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -755,7 +873,6 @@ func TestEC2InternetGateway(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -784,18 +901,18 @@ func TestEC2InternetGateway(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2InternetGatewayEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsInternetGatewayResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsInternetGatewayResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsInternetGatewayResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -805,10 +922,11 @@ func TestEC2InternetGateway(t *testing.T) { func TestVPC(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no VPC", @@ -816,6 +934,9 @@ func TestVPC(t *testing.T) { mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllVPCs").Once().Return([]*ec2.Vpc{}, []*ec2.Vpc{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -841,6 +962,18 @@ func TestVPC(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "vpc-0768e1fd0029e3fc3", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsVpcResourceType, got[0].ResourceType()) + + assert.Equal(t, "vpc-020b072316a95b97f", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsVpcResourceType, got[1].ResourceType()) + + assert.Equal(t, "vpc-02c50896b59598761", got[2].ResourceId()) + assert.Equal(t, resourceaws.AwsVpcResourceType, got[2].ResourceType()) + }, wantErr: nil, }, { @@ -852,12 +985,14 @@ func TestVPC(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsVpcResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsVpcResourceType, resourceaws.AwsVpcResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -867,7 +1002,6 @@ func TestVPC(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -896,18 +1030,18 @@ func TestVPC(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewVPCEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsVpcResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsVpcResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsVpcResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -917,10 +1051,11 @@ func TestVPC(t *testing.T) { func TestDefaultVPC(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no VPC", @@ -928,6 +1063,9 @@ func TestDefaultVPC(t *testing.T) { mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllVPCs").Once().Return([]*ec2.Vpc{}, []*ec2.Vpc{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -950,6 +1088,12 @@ func TestDefaultVPC(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, "vpc-a8c5d4c1", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsDefaultVpcResourceType, got[0].ResourceType()) + }, wantErr: nil, }, { @@ -961,12 +1105,14 @@ func TestDefaultVPC(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsDefaultVpcResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsDefaultVpcResourceType, resourceaws.AwsDefaultVpcResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -976,7 +1122,6 @@ func TestDefaultVPC(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1005,18 +1150,18 @@ func TestDefaultVPC(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewDefaultVPCEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsDefaultVpcResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsDefaultVpcResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsDefaultVpcResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -1025,10 +1170,11 @@ func TestDefaultVPC(t *testing.T) { func TestEC2RouteTableAssociation(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no route table associations (test for nil values)", @@ -1051,6 +1197,9 @@ func TestEC2RouteTableAssociation(t *testing.T) { {RouteTableId: awssdk.String("nil_assoc")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple route table associations (mixed subnet and gateway associations)", @@ -1115,6 +1264,21 @@ func TestEC2RouteTableAssociation(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 4) + + assert.Equal(t, "rtbassoc-0809598f92dbec03b", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsRouteTableAssociationResourceType, got[0].ResourceType()) + + assert.Equal(t, "rtbassoc-01957791b2cfe6ea4", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsRouteTableAssociationResourceType, got[1].ResourceType()) + + assert.Equal(t, "rtbassoc-0b4f97ea57490e213", got[2].ResourceId()) + assert.Equal(t, resourceaws.AwsRouteTableAssociationResourceType, got[2].ResourceType()) + + assert.Equal(t, "rtbassoc-0a79ccacfceb4944b", got[3].ResourceId()) + assert.Equal(t, resourceaws.AwsRouteTableAssociationResourceType, got[3].ResourceType()) + }, }, { test: "cannot list route table associations", @@ -1125,12 +1289,14 @@ func TestEC2RouteTableAssociation(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsRouteTableAssociationResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsRouteTableAssociationResourceType, resourceaws.AwsRouteTableResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -1140,7 +1306,6 @@ func TestEC2RouteTableAssociation(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1169,18 +1334,18 @@ func TestEC2RouteTableAssociation(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2RouteTableAssociationEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsRouteTableAssociationResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsRouteTableAssociationResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsRouteTableAssociationResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -1189,10 +1354,11 @@ func TestEC2RouteTableAssociation(t *testing.T) { func TestEC2Subnet(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no subnets", @@ -1200,6 +1366,9 @@ func TestEC2Subnet(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllSubnets").Return([]*ec2.Subnet{}, []*ec2.Subnet{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple subnets", @@ -1233,6 +1402,18 @@ func TestEC2Subnet(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "subnet-05810d3f933925f6d", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsSubnetResourceType, got[0].ResourceType()) + + assert.Equal(t, "subnet-0b13f1e0eacf67424", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsSubnetResourceType, got[1].ResourceType()) + + assert.Equal(t, "subnet-0c9b78001fe186e22", got[2].ResourceId()) + assert.Equal(t, resourceaws.AwsSubnetResourceType, got[2].ResourceType()) + }, }, { test: "cannot list subnets", @@ -1243,12 +1424,14 @@ func TestEC2Subnet(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsSubnetResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsSubnetResourceType, resourceaws.AwsSubnetResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -1258,7 +1441,6 @@ func TestEC2Subnet(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1287,18 +1469,18 @@ func TestEC2Subnet(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2SubnetEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsSubnetResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsSubnetResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsSubnetResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -1307,10 +1489,11 @@ func TestEC2Subnet(t *testing.T) { func TestEC2DefaultSubnet(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no default subnets", @@ -1318,6 +1501,9 @@ func TestEC2DefaultSubnet(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllSubnets").Return([]*ec2.Subnet{}, []*ec2.Subnet{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple default subnets", @@ -1351,6 +1537,18 @@ func TestEC2DefaultSubnet(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "subnet-44fe0c65", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsDefaultSubnetResourceType, got[0].ResourceType()) + + assert.Equal(t, "subnet-65e16628", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsDefaultSubnetResourceType, got[1].ResourceType()) + + assert.Equal(t, "subnet-afa656f0", got[2].ResourceId()) + assert.Equal(t, resourceaws.AwsDefaultSubnetResourceType, got[2].ResourceType()) + }, }, { test: "cannot list default subnets", @@ -1361,12 +1559,14 @@ func TestEC2DefaultSubnet(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsDefaultSubnetResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsDefaultSubnetResourceType, resourceaws.AwsDefaultSubnetResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -1376,7 +1576,6 @@ func TestEC2DefaultSubnet(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1405,18 +1604,18 @@ func TestEC2DefaultSubnet(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2DefaultSubnetEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsDefaultSubnetResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsDefaultSubnetResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsDefaultSubnetResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -1425,10 +1624,11 @@ func TestEC2DefaultSubnet(t *testing.T) { func TestEC2RouteTable(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no route tables", @@ -1436,6 +1636,9 @@ func TestEC2RouteTable(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllRouteTables").Return([]*ec2.RouteTable{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple route tables", @@ -1456,6 +1659,18 @@ func TestEC2RouteTable(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "rtb-08b7b71af15e183ce", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsRouteTableResourceType, got[0].ResourceType()) + + assert.Equal(t, "rtb-0002ac731f6fdea55", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsRouteTableResourceType, got[1].ResourceType()) + + assert.Equal(t, "rtb-0c55d55593f33fbac", got[2].ResourceId()) + assert.Equal(t, resourceaws.AwsRouteTableResourceType, got[2].ResourceType()) + }, }, { test: "cannot list route tables", @@ -1466,12 +1681,14 @@ func TestEC2RouteTable(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsRouteTableResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsRouteTableResourceType, resourceaws.AwsRouteTableResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -1481,7 +1698,6 @@ func TestEC2RouteTable(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1510,18 +1726,18 @@ func TestEC2RouteTable(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2RouteTableEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsRouteTableResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsRouteTableResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsRouteTableResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -1530,10 +1746,11 @@ func TestEC2RouteTable(t *testing.T) { func TestEC2DefaultRouteTable(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no default route tables", @@ -1541,6 +1758,9 @@ func TestEC2DefaultRouteTable(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllRouteTables").Return([]*ec2.RouteTable{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple default route tables", @@ -1561,6 +1781,12 @@ func TestEC2DefaultRouteTable(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, "rtb-0eabf071c709c0976", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsDefaultRouteTableResourceType, got[0].ResourceType()) + }, }, { test: "cannot list default route tables", @@ -1571,12 +1797,14 @@ func TestEC2DefaultRouteTable(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsDefaultRouteTableResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsDefaultRouteTableResourceType, resourceaws.AwsDefaultRouteTableResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -1586,7 +1814,6 @@ func TestEC2DefaultRouteTable(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1615,18 +1842,18 @@ func TestEC2DefaultRouteTable(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2DefaultRouteTableEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsDefaultRouteTableResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsDefaultRouteTableResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsDefaultRouteTableResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -1636,10 +1863,11 @@ func TestEC2DefaultRouteTable(t *testing.T) { func TestVpcSecurityGroup(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no security groups", @@ -1647,6 +1875,9 @@ func TestVpcSecurityGroup(t *testing.T) { mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllSecurityGroups").Once().Return([]*ec2.SecurityGroup{}, []*ec2.SecurityGroup{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -1665,6 +1896,12 @@ func TestVpcSecurityGroup(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, "sg-0254c038e32f25530", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsSecurityGroupResourceType, got[0].ResourceType()) + }, wantErr: nil, }, { @@ -1676,12 +1913,14 @@ func TestVpcSecurityGroup(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsSecurityGroupResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsSecurityGroupResourceType, resourceaws.AwsSecurityGroupResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -1691,7 +1930,6 @@ func TestVpcSecurityGroup(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1720,18 +1958,18 @@ func TestVpcSecurityGroup(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewVPCSecurityGroupEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsSecurityGroupResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsSecurityGroupResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsSecurityGroupResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -1741,10 +1979,11 @@ func TestVpcSecurityGroup(t *testing.T) { func TestVpcDefaultSecurityGroup(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no security groups", @@ -1752,6 +1991,9 @@ func TestVpcDefaultSecurityGroup(t *testing.T) { mocks: func(client *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { client.On("ListAllSecurityGroups").Once().Return([]*ec2.SecurityGroup{}, []*ec2.SecurityGroup{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -1770,6 +2012,12 @@ func TestVpcDefaultSecurityGroup(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, "sg-9e0204ff", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsDefaultSecurityGroupResourceType, got[0].ResourceType()) + }, wantErr: nil, }, { @@ -1781,12 +2029,14 @@ func TestVpcDefaultSecurityGroup(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsDefaultSecurityGroupResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsDefaultSecurityGroupResourceType, resourceaws.AwsDefaultSecurityGroupResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -1796,7 +2046,6 @@ func TestVpcDefaultSecurityGroup(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1825,18 +2074,18 @@ func TestVpcDefaultSecurityGroup(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewVPCDefaultSecurityGroupEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsDefaultSecurityGroupResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsDefaultSecurityGroupResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsDefaultSecurityGroupResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -1845,10 +2094,11 @@ func TestVpcDefaultSecurityGroup(t *testing.T) { func TestEC2NatGateway(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no nat gateways", @@ -1856,6 +2106,9 @@ func TestEC2NatGateway(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllNatGateways").Return([]*ec2.NatGateway{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "single nat gateway", @@ -1865,6 +2118,12 @@ func TestEC2NatGateway(t *testing.T) { {NatGatewayId: awssdk.String("nat-0a5408508b19ef490")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, "nat-0a5408508b19ef490", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsNatGatewayResourceType, got[0].ResourceType()) + }, }, { test: "cannot list nat gateways", @@ -1875,12 +2134,14 @@ func TestEC2NatGateway(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsNatGatewayResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsNatGatewayResourceType, resourceaws.AwsNatGatewayResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -1890,7 +2151,6 @@ func TestEC2NatGateway(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1919,18 +2179,18 @@ func TestEC2NatGateway(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2NatGatewayEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsNatGatewayResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsNatGatewayResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsNatGatewayResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -1939,10 +2199,11 @@ func TestEC2NatGateway(t *testing.T) { func TestEC2NetworkACL(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no network ACL", @@ -1950,6 +2211,9 @@ func TestEC2NetworkACL(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllNetworkACLs").Return([]*ec2.NetworkAcl{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "network acl", @@ -1970,6 +2234,15 @@ func TestEC2NetworkACL(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "acl-043880b4682d2366b", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsNetworkACLResourceType, got[0].ResourceType()) + + assert.Equal(t, "acl-07a565dbe518c0713", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsNetworkACLResourceType, got[1].ResourceType()) + }, }, { test: "cannot list network acl", @@ -1991,12 +2264,14 @@ func TestEC2NetworkACL(t *testing.T) { ), ).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -2006,7 +2281,6 @@ func TestEC2NetworkACL(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -2035,18 +2309,18 @@ func TestEC2NetworkACL(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2NetworkACLEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsNetworkACLResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsNetworkACLResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsNetworkACLResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -2055,10 +2329,11 @@ func TestEC2NetworkACL(t *testing.T) { func TestEC2NetworkACLRule(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no network ACL", @@ -2066,6 +2341,9 @@ func TestEC2NetworkACLRule(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllNetworkACLs").Return([]*ec2.NetworkAcl{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "network acl rules", @@ -2121,6 +2399,15 @@ func TestEC2NetworkACLRule(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 5) + + assert.Equal(t, "nacl-4293207588", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsNetworkACLRuleResourceType, got[0].ResourceType()) + + assert.Equal(t, "nacl-4268384215", got[4].ResourceId()) + assert.Equal(t, resourceaws.AwsNetworkACLRuleResourceType, got[4].ResourceType()) + }, }, { test: "cannot list network acl", @@ -2142,18 +2429,19 @@ func TestEC2NetworkACLRule(t *testing.T) { ), ).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -2180,18 +2468,18 @@ func TestEC2NetworkACLRule(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2NetworkACLRuleEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsNetworkACLRuleResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsNetworkACLRuleResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsNetworkACLRuleResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -2200,10 +2488,11 @@ func TestEC2NetworkACLRule(t *testing.T) { func TestEC2DefaultNetworkACL(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no network ACL", @@ -2211,6 +2500,9 @@ func TestEC2DefaultNetworkACL(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllNetworkACLs").Return([]*ec2.NetworkAcl{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "default network acl", @@ -2231,6 +2523,12 @@ func TestEC2DefaultNetworkACL(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, "acl-e88ee595", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsDefaultNetworkACLResourceType, got[0].ResourceType()) + }, }, { test: "cannot list default network acl", @@ -2252,12 +2550,14 @@ func TestEC2DefaultNetworkACL(t *testing.T) { ), ).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -2267,7 +2567,6 @@ func TestEC2DefaultNetworkACL(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -2296,18 +2595,18 @@ func TestEC2DefaultNetworkACL(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2DefaultNetworkACLEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsDefaultNetworkACLResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsDefaultNetworkACLResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsDefaultNetworkACLResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -2316,10 +2615,11 @@ func TestEC2DefaultNetworkACL(t *testing.T) { func TestEC2Route(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { // route table with no routes case is not possible @@ -2329,6 +2629,9 @@ func TestEC2Route(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("ListAllRouteTables").Return([]*ec2.RouteTable{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple routes (mixed default_route_table and route_table)", @@ -2409,6 +2712,15 @@ func TestEC2Route(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 10) + + assert.Equal(t, "r-rtb-096bdfb69309c54c3179966490", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsRouteResourceType, got[0].ResourceType()) + + assert.Equal(t, "r-179966490", got[9].ResourceId()) + assert.Equal(t, resourceaws.AwsRouteResourceType, got[9].ResourceType()) + }, }, { test: "cannot list routes", @@ -2419,12 +2731,14 @@ func TestEC2Route(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsRouteResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsRouteResourceType, resourceaws.AwsRouteTableResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -2434,7 +2748,6 @@ func TestEC2Route(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -2463,18 +2776,18 @@ func TestEC2Route(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2RouteEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsRouteResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsRouteResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsRouteResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -2484,10 +2797,11 @@ func TestEC2Route(t *testing.T) { func TestVpcSecurityGroupRule(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no security group rules", @@ -2501,6 +2815,9 @@ func TestVpcSecurityGroupRule(t *testing.T) { }, }, nil, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -2597,6 +2914,15 @@ func TestVpcSecurityGroupRule(t *testing.T) { }, }, nil, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 11) + + assert.Equal(t, "sgrule-3970541193", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsSecurityGroupRuleResourceType, got[0].ResourceType()) + + assert.Equal(t, "sgrule-850043874", got[10].ResourceId()) + assert.Equal(t, resourceaws.AwsSecurityGroupRuleResourceType, got[10].ResourceType()) + }, wantErr: nil, }, { @@ -2608,12 +2934,14 @@ func TestVpcSecurityGroupRule(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsSecurityGroupRuleResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsSecurityGroupRuleResourceType, resourceaws.AwsSecurityGroupResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -2623,7 +2951,6 @@ func TestVpcSecurityGroupRule(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -2652,18 +2979,18 @@ func TestVpcSecurityGroupRule(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewVPCSecurityGroupRuleEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsSecurityGroupRuleResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsSecurityGroupRuleResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsSecurityGroupRuleResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -2672,10 +2999,11 @@ func TestVpcSecurityGroupRule(t *testing.T) { func TestEC2LaunchTemplate(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no launch template", @@ -2683,6 +3011,9 @@ func TestEC2LaunchTemplate(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("DescribeLaunchTemplates").Return([]*ec2.LaunchTemplate{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple launch templates", @@ -2695,6 +3026,15 @@ func TestEC2LaunchTemplate(t *testing.T) { repository.On("DescribeLaunchTemplates").Return(launchTemplates, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "lt-0ed993d09ce6afc67", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsLaunchTemplateResourceType, got[0].ResourceType()) + + assert.Equal(t, "lt-00b2d18c6cee7fe23", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsLaunchTemplateResourceType, got[1].ResourceType()) + }, }, { test: "cannot list launch templates", @@ -2705,12 +3045,14 @@ func TestEC2LaunchTemplate(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsLaunchTemplateResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsLaunchTemplateResourceType, resourceaws.AwsLaunchTemplateResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -2720,7 +3062,6 @@ func TestEC2LaunchTemplate(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -2749,18 +3090,18 @@ func TestEC2LaunchTemplate(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewLaunchTemplateEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsLaunchTemplateResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsLaunchTemplateResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsLaunchTemplateResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) testFilter.AssertExpectations(tt) @@ -2770,10 +3111,11 @@ func TestEC2LaunchTemplate(t *testing.T) { func TestEC2EbsEncryptionByDefault(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockEC2Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no encryption by default resource", @@ -2781,6 +3123,12 @@ func TestEC2EbsEncryptionByDefault(t *testing.T) { mocks: func(repository *repository.MockEC2Repository, alerter *mocks.AlerterInterface) { repository.On("IsEbsEncryptionEnabledByDefault").Return(false, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, "ebs_encryption_default", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsEbsEncryptionByDefaultResourceType, got[0].ResourceType()) + }, }, { test: "cannot list encryption by default resources", @@ -2791,12 +3139,14 @@ func TestEC2EbsEncryptionByDefault(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsEbsEncryptionByDefaultResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsEbsEncryptionByDefaultResourceType, resourceaws.AwsEbsEncryptionByDefaultResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -2806,7 +3156,6 @@ func TestEC2EbsEncryptionByDefault(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -2835,18 +3184,18 @@ func TestEC2EbsEncryptionByDefault(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewEC2EbsEncryptionByDefaultEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsEbsEncryptionByDefaultResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsEbsEncryptionByDefaultResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsEbsEncryptionByDefaultResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) diff --git a/enumeration/remote/aws_ecr_scanner_test.go b/enumeration/remote/aws_ecr_scanner_test.go index 810c92f92..f4c668f00 100644 --- a/enumeration/remote/aws_ecr_scanner_test.go +++ b/enumeration/remote/aws_ecr_scanner_test.go @@ -21,7 +21,6 @@ import ( resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" "github.com/snyk/driftctl/mocks" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" @@ -30,10 +29,11 @@ import ( func TestECRRepository(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockECRRepository, *mocks.AlerterInterface) - err error + test string + dirName string + mocks func(*repository.MockECRRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + err error }{ { test: "no repository", @@ -41,6 +41,9 @@ func TestECRRepository(t *testing.T) { mocks: func(client *repository.MockECRRepository, alerter *mocks.AlerterInterface) { client.On("ListAllRepositories").Return([]*ecr.Repository{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, { @@ -52,6 +55,15 @@ func TestECRRepository(t *testing.T) { {RepositoryName: awssdk.String("bar")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "test_ecr", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsEcrRepositoryResourceType, got[0].ResourceType()) + + assert.Equal(t, "bar", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsEcrRepositoryResourceType, got[1].ResourceType()) + }, err: nil, }, { @@ -63,12 +75,14 @@ func TestECRRepository(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsEcrRepositoryResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsEcrRepositoryResourceType, resourceaws.AwsEcrRepositoryResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -78,7 +92,6 @@ func TestECRRepository(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -107,18 +120,18 @@ func TestECRRepository(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewECRRepositoryEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsEcrRepositoryResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsEcrRepositoryResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsEcrRepositoryResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -162,7 +175,6 @@ func TestECRRepositoryPolicy(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -177,7 +189,7 @@ func TestECRRepositoryPolicy(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.err) if err != nil { diff --git a/enumeration/remote/aws_elasticache_scanner_test.go b/enumeration/remote/aws_elasticache_scanner_test.go index 4bd44bf30..f7e47b79e 100644 --- a/enumeration/remote/aws_elasticache_scanner_test.go +++ b/enumeration/remote/aws_elasticache_scanner_test.go @@ -81,7 +81,6 @@ func TestElastiCacheCluster(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -96,7 +95,7 @@ func TestElastiCacheCluster(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) c.assertExpected(tt, got) diff --git a/enumeration/remote/aws_elb_scanner_test.go b/enumeration/remote/aws_elb_scanner_test.go index 299a6fbe0..f3e78d2a1 100644 --- a/enumeration/remote/aws_elb_scanner_test.go +++ b/enumeration/remote/aws_elb_scanner_test.go @@ -84,8 +84,6 @@ func TestELB_LoadBalancer(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -100,7 +98,7 @@ func TestELB_LoadBalancer(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { diff --git a/enumeration/remote/aws_elbv2_scanner_test.go b/enumeration/remote/aws_elbv2_scanner_test.go index 79424ccd7..d85759d3a 100644 --- a/enumeration/remote/aws_elbv2_scanner_test.go +++ b/enumeration/remote/aws_elbv2_scanner_test.go @@ -85,8 +85,6 @@ func TestELBV2_LoadBalancer(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -101,7 +99,7 @@ func TestELBV2_LoadBalancer(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -211,8 +209,6 @@ func TestELBV2_LoadBalancerListener(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -227,7 +223,7 @@ func TestELBV2_LoadBalancerListener(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { diff --git a/enumeration/remote/aws_iam_scanner_test.go b/enumeration/remote/aws_iam_scanner_test.go index 35a3ea9a8..6db6acb0e 100644 --- a/enumeration/remote/aws_iam_scanner_test.go +++ b/enumeration/remote/aws_iam_scanner_test.go @@ -21,7 +21,6 @@ import ( resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" "github.com/snyk/driftctl/mocks" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" @@ -31,10 +30,11 @@ import ( func TestIamUser(t *testing.T) { cases := []struct { - test string - dirName string - mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no iam user", @@ -42,6 +42,9 @@ func TestIamUser(t *testing.T) { mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllUsers").Return([]*iam.User{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -60,6 +63,18 @@ func TestIamUser(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "test-driftctl-0", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsIamUserResourceType, got[0].ResourceType()) + + assert.Equal(t, "test-driftctl-1", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsIamUserResourceType, got[1].ResourceType()) + + assert.Equal(t, "test-driftctl-2", got[2].ResourceId()) + assert.Equal(t, resourceaws.AwsIamUserResourceType, got[2].ResourceType()) + }, wantErr: nil, }, { @@ -71,12 +86,14 @@ func TestIamUser(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsIamUserResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsIamUserResourceType, resourceaws.AwsIamUserResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -86,7 +103,6 @@ func TestIamUser(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -115,18 +131,18 @@ func TestIamUser(t *testing.T) { } remoteLibrary.AddEnumerator(aws2.NewIamUserEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsIamUserResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsIamUserResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsIamUserResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -136,10 +152,11 @@ func TestIamUser(t *testing.T) { func TestIamUserPolicy(t *testing.T) { cases := []struct { - test string - dirName string - mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no iam user policy", @@ -153,6 +170,9 @@ func TestIamUserPolicy(t *testing.T) { repo.On("ListAllUsers").Return(users, nil) repo.On("ListAllUserPolicies", users).Return([]string{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -186,6 +206,15 @@ func TestIamUserPolicy(t *testing.T) { *aws.String("loadbalancer3:test34"), }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 12) + + assert.Equal(t, "loadbalancer:test", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsIamUserPolicyResourceType, got[0].ResourceType()) + + assert.Equal(t, "loadbalancer3:test34", got[11].ResourceId()) + assert.Equal(t, resourceaws.AwsIamUserPolicyResourceType, got[11].ResourceType()) + }, wantErr: nil, }, { @@ -197,6 +226,9 @@ func TestIamUserPolicy(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsIamUserPolicyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsIamUserPolicyResourceType, resourceaws.AwsIamUserResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -209,12 +241,14 @@ func TestIamUserPolicy(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsIamUserPolicyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsIamUserPolicyResourceType, resourceaws.AwsIamUserPolicyResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -224,7 +258,6 @@ func TestIamUserPolicy(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -253,18 +286,18 @@ func TestIamUserPolicy(t *testing.T) { } remoteLibrary.AddEnumerator(aws2.NewIamUserPolicyEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsIamUserPolicyResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsIamUserPolicyResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsIamUserPolicyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -274,10 +307,11 @@ func TestIamUserPolicy(t *testing.T) { func TestIamPolicy(t *testing.T) { cases := []struct { - test string - dirName string - mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no iam custom policies", @@ -285,6 +319,9 @@ func TestIamPolicy(t *testing.T) { mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllPolicies").Once().Return([]*iam.Policy{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -303,6 +340,18 @@ func TestIamPolicy(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "arn:aws:iam::929327065333:policy/policy-0", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsIamPolicyResourceType, got[0].ResourceType()) + + assert.Equal(t, "arn:aws:iam::929327065333:policy/policy-1", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsIamPolicyResourceType, got[1].ResourceType()) + + assert.Equal(t, "arn:aws:iam::929327065333:policy/policy-2", got[2].ResourceId()) + assert.Equal(t, resourceaws.AwsIamPolicyResourceType, got[2].ResourceType()) + }, wantErr: nil, }, { @@ -314,12 +363,14 @@ func TestIamPolicy(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsIamPolicyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsIamPolicyResourceType, resourceaws.AwsIamPolicyResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -329,7 +380,6 @@ func TestIamPolicy(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -358,18 +408,18 @@ func TestIamPolicy(t *testing.T) { } remoteLibrary.AddEnumerator(aws2.NewIamPolicyEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsIamPolicyResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsIamPolicyResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsIamPolicyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -379,10 +429,11 @@ func TestIamPolicy(t *testing.T) { func TestIamRole(t *testing.T) { cases := []struct { - test string - dirName string - mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no iam roles", @@ -390,6 +441,9 @@ func TestIamRole(t *testing.T) { mocks: func(repo *repository.MockIAMRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllRoles").Return([]*iam.Role{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -411,6 +465,18 @@ func TestIamRole(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "test_role_0", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsIamRoleResourceType, got[0].ResourceType()) + + assert.Equal(t, "test_role_1", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsIamRoleResourceType, got[1].ResourceType()) + + assert.Equal(t, "test_role_2", got[2].ResourceId()) + assert.Equal(t, resourceaws.AwsIamRoleResourceType, got[2].ResourceType()) + }, wantErr: nil, }, { @@ -432,12 +498,14 @@ func TestIamRole(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -447,7 +515,6 @@ func TestIamRole(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -476,18 +543,18 @@ func TestIamRole(t *testing.T) { } remoteLibrary.AddEnumerator(aws2.NewIamRoleEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsIamRoleResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsIamRoleResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsIamRoleResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -497,10 +564,11 @@ func TestIamRole(t *testing.T) { func TestIamRolePolicyAttachment(t *testing.T) { cases := []struct { - test string - dirName string - mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) - err error + test string + dirName string + mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + err error }{ { test: "no iam role policy", @@ -514,6 +582,9 @@ func TestIamRolePolicyAttachment(t *testing.T) { repo.On("ListAllRoles").Return(roles, nil) repo.On("ListAllRolePolicyAttachments", roles).Return([]*repository.AttachedRolePolicy{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, { @@ -574,6 +645,15 @@ func TestIamRolePolicyAttachment(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 6) + + assert.Equal(t, "test-policy-test-role", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsIamRolePolicyAttachmentResourceType, got[0].ResourceType()) + + assert.Equal(t, "test-policy3-test-role2", got[5].ResourceId()) + assert.Equal(t, resourceaws.AwsIamRolePolicyAttachmentResourceType, got[5].ResourceType()) + }, err: nil, }, { @@ -593,6 +673,9 @@ func TestIamRolePolicyAttachment(t *testing.T) { } repo.On("ListAllRoles").Return(roles, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "Cannot list roles", @@ -603,6 +686,9 @@ func TestIamRolePolicyAttachment(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsIamRolePolicyAttachmentResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsIamRolePolicyAttachmentResourceType, resourceaws.AwsIamRoleResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "Cannot list roles policy attachment", @@ -614,11 +700,13 @@ func TestIamRolePolicyAttachment(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsIamRolePolicyAttachmentResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsIamRolePolicyAttachmentResourceType, resourceaws.AwsIamRolePolicyAttachmentResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -628,7 +716,6 @@ func TestIamRolePolicyAttachment(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -657,18 +744,18 @@ func TestIamRolePolicyAttachment(t *testing.T) { } remoteLibrary.AddEnumerator(aws2.NewIamRolePolicyAttachmentEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsIamRolePolicyAttachmentResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsIamRolePolicyAttachmentResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.err, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsIamRolePolicyAttachmentResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -678,10 +765,11 @@ func TestIamRolePolicyAttachment(t *testing.T) { func TestIamAccessKey(t *testing.T) { cases := []struct { - test string - dirName string - mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no iam access_key", @@ -695,6 +783,9 @@ func TestIamAccessKey(t *testing.T) { repo.On("ListAllUsers").Return(users, nil) repo.On("ListAllAccessKeys", users).Return([]*iam.AccessKeyMetadata{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -726,6 +817,15 @@ func TestIamAccessKey(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 4) + + assert.Equal(t, "AKIA5QYBVVD223VWU32A", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsIamAccessKeyResourceType, got[0].ResourceType()) + + assert.Equal(t, "AKIA5QYBVVD2SWDFVVMG", got[3].ResourceId()) + assert.Equal(t, resourceaws.AwsIamAccessKeyResourceType, got[3].ResourceType()) + }, wantErr: nil, }, { @@ -737,6 +837,9 @@ func TestIamAccessKey(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsIamAccessKeyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsIamAccessKeyResourceType, resourceaws.AwsIamUserResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -749,12 +852,14 @@ func TestIamAccessKey(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsIamAccessKeyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsIamAccessKeyResourceType, resourceaws.AwsIamAccessKeyResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -764,7 +869,6 @@ func TestIamAccessKey(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -793,18 +897,18 @@ func TestIamAccessKey(t *testing.T) { } remoteLibrary.AddEnumerator(aws2.NewIamAccessKeyEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsIamAccessKeyResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsIamAccessKeyResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsIamAccessKeyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -814,10 +918,11 @@ func TestIamAccessKey(t *testing.T) { func TestIamUserPolicyAttachment(t *testing.T) { cases := []struct { - test string - dirName string - mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no iam user policy", @@ -831,6 +936,9 @@ func TestIamUserPolicyAttachment(t *testing.T) { repo.On("ListAllUsers").Return(users, nil) repo.On("ListAllUserPolicyAttachments", users).Return([]*repository.AttachedUserPolicy{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -937,6 +1045,15 @@ func TestIamUserPolicyAttachment(t *testing.T) { }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 12) + + assert.Equal(t, "test-loadbalancer", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsIamUserPolicyAttachmentResourceType, got[0].ResourceType()) + + assert.Equal(t, "test4-loadbalancer3", got[11].ResourceId()) + assert.Equal(t, resourceaws.AwsIamUserPolicyAttachmentResourceType, got[11].ResourceType()) + }, wantErr: nil, }, { @@ -948,6 +1065,9 @@ func TestIamUserPolicyAttachment(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsIamUserPolicyAttachmentResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsIamUserPolicyAttachmentResourceType, resourceaws.AwsIamUserResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -960,12 +1080,14 @@ func TestIamUserPolicyAttachment(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsIamUserPolicyAttachmentResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsIamUserPolicyAttachmentResourceType, resourceaws.AwsIamUserPolicyAttachmentResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -975,7 +1097,6 @@ func TestIamUserPolicyAttachment(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1004,18 +1125,18 @@ func TestIamUserPolicyAttachment(t *testing.T) { } remoteLibrary.AddEnumerator(aws2.NewIamUserPolicyAttachmentEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsIamUserPolicyAttachmentResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsIamUserPolicyAttachmentResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsIamUserPolicyAttachmentResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -1025,10 +1146,11 @@ func TestIamUserPolicyAttachment(t *testing.T) { func TestIamRolePolicy(t *testing.T) { cases := []struct { - test string - dirName string - mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockIAMRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no iam role policy", @@ -1042,6 +1164,9 @@ func TestIamRolePolicy(t *testing.T) { repo.On("ListAllRoles").Return(roles, nil) repo.On("ListAllRolePolicies", roles).Return([]repository.RolePolicy{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -1066,6 +1191,15 @@ func TestIamRolePolicy(t *testing.T) { {Policy: "policy-role1-2", RoleName: "test_role_1"}, }, nil).Once() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 6) + + assert.Equal(t, "test_role_0:policy-role0-0", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsIamRolePolicyResourceType, got[0].ResourceType()) + + assert.Equal(t, "test_role_1:policy-role1-2", got[5].ResourceId()) + assert.Equal(t, resourceaws.AwsIamRolePolicyResourceType, got[5].ResourceType()) + }, wantErr: nil, }, { @@ -1077,6 +1211,9 @@ func TestIamRolePolicy(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsIamRolePolicyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsIamRolePolicyResourceType, resourceaws.AwsIamRoleResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -1089,12 +1226,14 @@ func TestIamRolePolicy(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsIamRolePolicyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsIamRolePolicyResourceType, resourceaws.AwsIamRolePolicyResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -1104,7 +1243,6 @@ func TestIamRolePolicy(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1133,18 +1271,18 @@ func TestIamRolePolicy(t *testing.T) { } remoteLibrary.AddEnumerator(aws2.NewIamRolePolicyEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsIamRolePolicyResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsIamRolePolicyResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsIamRolePolicyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -1196,7 +1334,6 @@ func TestIamGroupPolicy(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -1213,7 +1350,7 @@ func TestIamGroupPolicy(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -1270,7 +1407,6 @@ func TestIamGroup(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -1287,7 +1423,7 @@ func TestIamGroup(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { diff --git a/enumeration/remote/aws_kms_scanner_test.go b/enumeration/remote/aws_kms_scanner_test.go index 8a00d19fe..c67ee958d 100644 --- a/enumeration/remote/aws_kms_scanner_test.go +++ b/enumeration/remote/aws_kms_scanner_test.go @@ -21,7 +21,6 @@ import ( resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" "github.com/snyk/driftctl/mocks" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" @@ -30,10 +29,11 @@ import ( func TestKMSKey(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockKMSRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockKMSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no keys", @@ -41,6 +41,9 @@ func TestKMSKey(t *testing.T) { mocks: func(repository *repository.MockKMSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllKeys").Return([]*kms.KeyListEntry{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple keys", @@ -52,6 +55,18 @@ func TestKMSKey(t *testing.T) { {KeyId: awssdk.String("89d2c023-ea53-40a5-b20a-d84905c622d7")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "8ee21d91-c000-428c-8032-235aac55da36", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsKmsKeyResourceType, got[0].ResourceType()) + + assert.Equal(t, "5d765f32-bfdc-4610-b6ab-f82db5d0601b", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsKmsKeyResourceType, got[1].ResourceType()) + + assert.Equal(t, "89d2c023-ea53-40a5-b20a-d84905c622d7", got[2].ResourceId()) + assert.Equal(t, resourceaws.AwsKmsKeyResourceType, got[2].ResourceType()) + }, }, { test: "cannot list keys", @@ -62,12 +77,14 @@ func TestKMSKey(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsKmsKeyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsKmsKeyResourceType, resourceaws.AwsKmsKeyResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -77,7 +94,6 @@ func TestKMSKey(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -106,18 +122,18 @@ func TestKMSKey(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewKMSKeyEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsKmsKeyResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsKmsKeyResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsKmsKeyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -126,10 +142,11 @@ func TestKMSKey(t *testing.T) { func TestKMSAlias(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockKMSRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockKMSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no aliases", @@ -137,6 +154,9 @@ func TestKMSAlias(t *testing.T) { mocks: func(repository *repository.MockKMSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllAliases").Return([]*kms.AliasListEntry{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple aliases", @@ -148,6 +168,18 @@ func TestKMSAlias(t *testing.T) { {AliasName: awssdk.String("alias/baz20210225124429210500000001")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "alias/foo", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsKmsAliasResourceType, got[0].ResourceType()) + + assert.Equal(t, "alias/bar", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsKmsAliasResourceType, got[1].ResourceType()) + + assert.Equal(t, "alias/baz20210225124429210500000001", got[2].ResourceId()) + assert.Equal(t, resourceaws.AwsKmsAliasResourceType, got[2].ResourceType()) + }, }, { test: "cannot list aliases", @@ -158,12 +190,14 @@ func TestKMSAlias(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsKmsAliasResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsKmsAliasResourceType, resourceaws.AwsKmsAliasResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -173,7 +207,6 @@ func TestKMSAlias(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -202,18 +235,18 @@ func TestKMSAlias(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewKMSAliasEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsKmsAliasResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsKmsAliasResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsKmsAliasResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) diff --git a/enumeration/remote/aws_lambda_scanner_test.go b/enumeration/remote/aws_lambda_scanner_test.go index 808d0fa23..68411a9c2 100644 --- a/enumeration/remote/aws_lambda_scanner_test.go +++ b/enumeration/remote/aws_lambda_scanner_test.go @@ -25,18 +25,17 @@ import ( "github.com/snyk/driftctl/enumeration/resource" resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" "github.com/stretchr/testify/assert" ) func TestScanLambdaFunction(t *testing.T) { - tests := []struct { - test string - dirName string - mocks func(*repository.MockLambdaRepository, *mocks.AlerterInterface) - err error + test string + dirName string + mocks func(*repository.MockLambdaRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + err error }{ { test: "no lambda functions", @@ -44,6 +43,9 @@ func TestScanLambdaFunction(t *testing.T) { mocks: func(repo *repository.MockLambdaRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllLambdaFunctions").Return([]*lambda.FunctionConfiguration{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, { @@ -59,6 +61,15 @@ func TestScanLambdaFunction(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "foo", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsLambdaFunctionResourceType, got[0].ResourceType()) + + assert.Equal(t, "bar", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsLambdaFunctionResourceType, got[1].ResourceType()) + }, err: nil, }, { @@ -71,6 +82,12 @@ func TestScanLambdaFunction(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, "foo", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsLambdaFunctionResourceType, got[0].ResourceType()) + }, err: nil, }, { @@ -82,12 +99,14 @@ func TestScanLambdaFunction(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsLambdaFunctionResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsLambdaFunctionResourceType, resourceaws.AwsLambdaFunctionResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -97,7 +116,6 @@ func TestScanLambdaFunction(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -126,18 +144,18 @@ func TestScanLambdaFunction(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewLambdaFunctionEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsLambdaFunctionResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsLambdaFunctionResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.err, err) if err != nil { return } - test.TestAgainstGoldenFileNoCty(got, resourceaws.AwsLambdaFunctionResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -145,12 +163,12 @@ func TestScanLambdaFunction(t *testing.T) { } func TestScanLambdaEventSourceMapping(t *testing.T) { - tests := []struct { - test string - dirName string - mocks func(*repository.MockLambdaRepository, *mocks.AlerterInterface) - err error + test string + dirName string + mocks func(*repository.MockLambdaRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + err error }{ { test: "no EventSourceMapping", @@ -158,6 +176,9 @@ func TestScanLambdaEventSourceMapping(t *testing.T) { mocks: func(repo *repository.MockLambdaRepository, alerter *mocks.AlerterInterface) { repo.On("ListAllLambdaEventSourceMappings").Return([]*lambda.EventSourceMappingConfiguration{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, { @@ -173,6 +194,15 @@ func TestScanLambdaEventSourceMapping(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "13ff66f8-37eb-4ad6-a0a8-594fea72df4f", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsLambdaEventSourceMappingResourceType, got[0].ResourceType()) + + assert.Equal(t, "4ad7e2b3-79e9-4713-9d9d-5af2c01d9058", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsLambdaEventSourceMappingResourceType, got[1].ResourceType()) + }, err: nil, }, { @@ -185,6 +215,12 @@ func TestScanLambdaEventSourceMapping(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, "1aa9c4a0-060b-41c1-a9ae-dc304ebcdb00", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsLambdaEventSourceMappingResourceType, got[0].ResourceType()) + }, err: nil, }, { @@ -196,12 +232,14 @@ func TestScanLambdaEventSourceMapping(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsLambdaEventSourceMappingResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsLambdaEventSourceMappingResourceType, resourceaws.AwsLambdaEventSourceMappingResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -211,7 +249,6 @@ func TestScanLambdaEventSourceMapping(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -240,18 +277,18 @@ func TestScanLambdaEventSourceMapping(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewLambdaEventSourceMappingEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsLambdaEventSourceMappingResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsLambdaEventSourceMappingResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.err, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsLambdaEventSourceMappingResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) diff --git a/enumeration/remote/aws_rds_scanner_test.go b/enumeration/remote/aws_rds_scanner_test.go index e8c9c528a..8471c2926 100644 --- a/enumeration/remote/aws_rds_scanner_test.go +++ b/enumeration/remote/aws_rds_scanner_test.go @@ -21,7 +21,6 @@ import ( resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" "github.com/snyk/driftctl/mocks" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" @@ -30,10 +29,11 @@ import ( func TestRDSDBInstance(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockRDSRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockRDSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no db instances", @@ -41,6 +41,9 @@ func TestRDSDBInstance(t *testing.T) { mocks: func(repository *repository.MockRDSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllDBInstances").Return([]*rds.DBInstance{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "single db instance", @@ -50,6 +53,12 @@ func TestRDSDBInstance(t *testing.T) { {DBInstanceIdentifier: awssdk.String("terraform-20201015115018309600000001")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, "terraform-20201015115018309600000001", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsDbInstanceResourceType, got[0].ResourceType()) + }, }, { test: "multiple mixed db instances", @@ -60,6 +69,15 @@ func TestRDSDBInstance(t *testing.T) { {DBInstanceIdentifier: awssdk.String("database-1")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "terraform-20201015115018309600000001", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsDbInstanceResourceType, got[0].ResourceType()) + + assert.Equal(t, "database-1", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsDbInstanceResourceType, got[1].ResourceType()) + }, }, { test: "cannot list db instances", @@ -70,12 +88,14 @@ func TestRDSDBInstance(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsDbInstanceResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsDbInstanceResourceType, resourceaws.AwsDbInstanceResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -85,7 +105,6 @@ func TestRDSDBInstance(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -114,18 +133,18 @@ func TestRDSDBInstance(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewRDSDBInstanceEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsDbInstanceResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsDbInstanceResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFileNoCty(got, resourceaws.AwsDbInstanceResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -134,10 +153,11 @@ func TestRDSDBInstance(t *testing.T) { func TestRDSDBSubnetGroup(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockRDSRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockRDSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no db subnet groups", @@ -145,6 +165,9 @@ func TestRDSDBSubnetGroup(t *testing.T) { mocks: func(repository *repository.MockRDSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllDBSubnetGroups").Return([]*rds.DBSubnetGroup{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple db subnet groups", @@ -155,6 +178,15 @@ func TestRDSDBSubnetGroup(t *testing.T) { {DBSubnetGroupName: awssdk.String("bar")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "foo", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsDbSubnetGroupResourceType, got[0].ResourceType()) + + assert.Equal(t, "bar", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsDbSubnetGroupResourceType, got[1].ResourceType()) + }, }, { test: "cannot list db subnet groups", @@ -165,12 +197,14 @@ func TestRDSDBSubnetGroup(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsDbSubnetGroupResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsDbSubnetGroupResourceType, resourceaws.AwsDbSubnetGroupResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -180,7 +214,6 @@ func TestRDSDBSubnetGroup(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -209,18 +242,18 @@ func TestRDSDBSubnetGroup(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewRDSDBSubnetGroupEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsDbSubnetGroupResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsDbSubnetGroupResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsDbSubnetGroupResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -229,10 +262,11 @@ func TestRDSDBSubnetGroup(t *testing.T) { func TestRDSCluster(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockRDSRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockRDSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no cluster", @@ -240,9 +274,12 @@ func TestRDSCluster(t *testing.T) { mocks: func(repository *repository.MockRDSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllDBClusters").Return([]*rds.DBCluster{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { - test: "should return one result", + test: "should return results", dirName: "aws_rds_clusters_results", mocks: func(repository *repository.MockRDSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllDBClusters").Return([]*rds.DBCluster{ @@ -255,6 +292,15 @@ func TestRDSCluster(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "aurora-cluster-demo", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsRDSClusterResourceType, got[0].ResourceType()) + + assert.Equal(t, "aurora-cluster-demo-2", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsRDSClusterResourceType, got[1].ResourceType()) + }, }, { test: "cannot list clusters", @@ -265,12 +311,14 @@ func TestRDSCluster(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsRDSClusterResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsRDSClusterResourceType, resourceaws.AwsRDSClusterResourceType), alerts.EnumerationPhase)).Return().Once() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -280,7 +328,6 @@ func TestRDSCluster(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -309,18 +356,18 @@ func TestRDSCluster(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewRDSClusterEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsRDSClusterResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsRDSClusterResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsRDSClusterResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) diff --git a/enumeration/remote/aws_route53_scanner_test.go b/enumeration/remote/aws_route53_scanner_test.go index af405cecc..88f595417 100644 --- a/enumeration/remote/aws_route53_scanner_test.go +++ b/enumeration/remote/aws_route53_scanner_test.go @@ -1,6 +1,8 @@ package remote import ( + "testing" + "github.com/snyk/driftctl/enumeration" "github.com/snyk/driftctl/enumeration/remote/alerts" "github.com/snyk/driftctl/enumeration/remote/aws" @@ -9,7 +11,6 @@ import ( "github.com/snyk/driftctl/enumeration/remote/common" remoteerr "github.com/snyk/driftctl/enumeration/remote/error" "github.com/snyk/driftctl/enumeration/terraform" - "testing" awssdk "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" @@ -24,7 +25,6 @@ import ( "github.com/snyk/driftctl/enumeration/resource" resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" "github.com/stretchr/testify/assert" ) @@ -32,10 +32,11 @@ import ( func TestRoute53_HealthCheck(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockRoute53Repository, *mocks.AlerterInterface) - err error + test string + dirName string + mocks func(*repository.MockRoute53Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + err error }{ { test: "no health check", @@ -43,6 +44,9 @@ func TestRoute53_HealthCheck(t *testing.T) { mocks: func(client *repository.MockRoute53Repository, alerter *mocks.AlerterInterface) { client.On("ListAllHealthChecks").Return([]*route53.HealthCheck{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, { @@ -54,6 +58,15 @@ func TestRoute53_HealthCheck(t *testing.T) { {Id: awssdk.String("84fc318a-2e0d-41d6-b638-280e2f0f4e26")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "7001a9df-ded4-4802-9909-668eb80b972b", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsRoute53HealthCheckResourceType, got[0].ResourceType()) + + assert.Equal(t, "84fc318a-2e0d-41d6-b638-280e2f0f4e26", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsRoute53HealthCheckResourceType, got[1].ResourceType()) + }, err: nil, }, { @@ -65,12 +78,14 @@ func TestRoute53_HealthCheck(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsRoute53HealthCheckResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsRoute53HealthCheckResourceType, resourceaws.AwsRoute53HealthCheckResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -80,7 +95,6 @@ func TestRoute53_HealthCheck(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -109,18 +123,18 @@ func TestRoute53_HealthCheck(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewRoute53HealthCheckEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsRoute53HealthCheckResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsRoute53HealthCheckResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.err, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsRoute53HealthCheckResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -130,10 +144,11 @@ func TestRoute53_HealthCheck(t *testing.T) { func TestRoute53_Zone(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockRoute53Repository, *mocks.AlerterInterface) - err error + test string + dirName string + mocks func(*repository.MockRoute53Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + err error }{ { test: "no zones", @@ -144,6 +159,9 @@ func TestRoute53_Zone(t *testing.T) { nil, ) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, { @@ -160,6 +178,12 @@ func TestRoute53_Zone(t *testing.T) { nil, ) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, "Z08068311RGDXPHF8KE62", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsRoute53ZoneResourceType, got[0].ResourceType()) + }, err: nil, }, { @@ -184,6 +208,18 @@ func TestRoute53_Zone(t *testing.T) { nil, ) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "Z01809283VH9BBALZHO7B", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsRoute53ZoneResourceType, got[0].ResourceType()) + + assert.Equal(t, "Z01804312AV8PHE3C43AD", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsRoute53ZoneResourceType, got[1].ResourceType()) + + assert.Equal(t, "Z01874941AR1TCGV5K65C", got[2].ResourceId()) + assert.Equal(t, resourceaws.AwsRoute53ZoneResourceType, got[2].ResourceType()) + }, err: nil, }, { @@ -198,12 +234,14 @@ func TestRoute53_Zone(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsRoute53ZoneResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsRoute53ZoneResourceType, resourceaws.AwsRoute53ZoneResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -213,7 +251,6 @@ func TestRoute53_Zone(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -242,18 +279,18 @@ func TestRoute53_Zone(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewRoute53ZoneEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsRoute53ZoneResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsRoute53ZoneResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.err, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsRoute53ZoneResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -263,10 +300,11 @@ func TestRoute53_Zone(t *testing.T) { func TestRoute53_Record(t *testing.T) { tests := []struct { - test string - dirName string - mocks func(*repository.MockRoute53Repository, *mocks.AlerterInterface) - err error + test string + dirName string + mocks func(*repository.MockRoute53Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + err error }{ { test: "no records", @@ -283,6 +321,9 @@ func TestRoute53_Record(t *testing.T) { ) client.On("ListRecordsForZone", "Z1035360GLIB82T1EH2G").Return([]*route53.ResourceRecordSet{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, { @@ -331,6 +372,15 @@ func TestRoute53_Record(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 6) + + assert.Equal(t, "Z1035360GLIB82T1EH2G_foo-0.com_NS", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsRoute53RecordResourceType, got[0].ResourceType()) + + assert.Equal(t, "Z10347383HV75H96J919W_test2_A", got[5].ResourceId()) + assert.Equal(t, resourceaws.AwsRoute53RecordResourceType, got[5].ResourceType()) + }, err: nil, }, { @@ -373,6 +423,15 @@ func TestRoute53_Record(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 6) + + assert.Equal(t, "Z06486383UC8WYSBZTWFM_test0_TXT", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsRoute53RecordResourceType, got[0].ResourceType()) + + assert.Equal(t, "Z06486383UC8WYSBZTWFM__test2.foo-2.com_A", got[5].ResourceId()) + assert.Equal(t, resourceaws.AwsRoute53RecordResourceType, got[5].ResourceType()) + }, err: nil, }, { @@ -386,6 +445,9 @@ func TestRoute53_Record(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsRoute53RecordResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsRoute53RecordResourceType, resourceaws.AwsRoute53ZoneResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, { @@ -406,12 +468,14 @@ func TestRoute53_Record(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsRoute53RecordResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsRoute53RecordResourceType, resourceaws.AwsRoute53RecordResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -421,7 +485,6 @@ func TestRoute53_Record(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -450,18 +513,18 @@ func TestRoute53_Record(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewRoute53RecordEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsRoute53RecordResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsRoute53RecordResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.err, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsRoute53RecordResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) diff --git a/enumeration/remote/aws_s3_scanner_test.go b/enumeration/remote/aws_s3_scanner_test.go index cf28d3250..e3adca90b 100644 --- a/enumeration/remote/aws_s3_scanner_test.go +++ b/enumeration/remote/aws_s3_scanner_test.go @@ -28,18 +28,17 @@ import ( "github.com/snyk/driftctl/enumeration/resource" resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" "github.com/stretchr/testify/assert" ) func TestS3Bucket(t *testing.T) { - tests := []struct { - test string - dirName string - mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "multiple bucket", dirName: "aws_s3_bucket_multiple", @@ -76,6 +75,12 @@ func TestS3Bucket(t *testing.T) { nil, ) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, "bucket-martin-test-drift2", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsS3BucketResourceType, got[0].ResourceType()) + }, }, { test: "cannot list bucket", dirName: "aws_s3_bucket_list", @@ -85,12 +90,14 @@ func TestS3Bucket(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsS3BucketResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsS3BucketResourceType, resourceaws.AwsS3BucketResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -100,7 +107,6 @@ func TestS3Bucket(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -131,18 +137,18 @@ func TestS3Bucket(t *testing.T) { Name: "test", DefaultAlias: "eu-west-3", }, alerter)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsS3BucketResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsS3BucketResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsS3BucketResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -150,12 +156,12 @@ func TestS3Bucket(t *testing.T) { } func TestS3BucketInventory(t *testing.T) { - tests := []struct { - test string - dirName string - mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "multiple bucket with multiple inventories", dirName: "aws_s3_bucket_inventories_multiple", @@ -204,6 +210,15 @@ func TestS3BucketInventory(t *testing.T) { nil, ) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "bucket-martin-test-drift2:Inventory_Bucket2", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsS3BucketInventoryResourceType, got[0].ResourceType()) + + assert.Equal(t, "bucket-martin-test-drift2:Inventory2_Bucket2", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsS3BucketInventoryResourceType, got[1].ResourceType()) + }, }, { test: "cannot list bucket", dirName: "aws_s3_bucket_inventories_list_bucket", @@ -213,6 +228,9 @@ func TestS3BucketInventory(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsS3BucketInventoryResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsS3BucketInventoryResourceType, resourceaws.AwsS3BucketResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -243,12 +261,14 @@ func TestS3BucketInventory(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsS3BucketInventoryResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsS3BucketInventoryResourceType, resourceaws.AwsS3BucketInventoryResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -258,7 +278,6 @@ func TestS3BucketInventory(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -289,18 +308,18 @@ func TestS3BucketInventory(t *testing.T) { Name: "test", DefaultAlias: "eu-west-3", }, alerter)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsS3BucketInventoryResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsS3BucketInventoryResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsS3BucketInventoryResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -308,12 +327,12 @@ func TestS3BucketInventory(t *testing.T) { } func TestS3BucketNotification(t *testing.T) { - tests := []struct { - test string - dirName string - mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "single bucket without notifications", @@ -342,6 +361,9 @@ func TestS3BucketNotification(t *testing.T) { nil, ) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple bucket with notifications", dirName: "aws_s3_bucket_notifications_multiple", @@ -396,6 +418,12 @@ func TestS3BucketNotification(t *testing.T) { nil, ) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, "bucket-martin-test-drift2", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsS3BucketNotificationResourceType, got[0].ResourceType()) + }, }, { test: "Cannot get bucket notification", dirName: "aws_s3_bucket_notifications_list_bucket", @@ -417,6 +445,9 @@ func TestS3BucketNotification(t *testing.T) { alerter.On("SendAlert", "aws_s3_bucket_notification.dritftctl-test-notifications-error", alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, "aws_s3_bucket_notification.dritftctl-test-notifications-error", resourceaws.AwsS3BucketNotificationResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -427,12 +458,14 @@ func TestS3BucketNotification(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsS3BucketNotificationResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsS3BucketNotificationResourceType, resourceaws.AwsS3BucketResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -442,7 +475,6 @@ func TestS3BucketNotification(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -473,18 +505,18 @@ func TestS3BucketNotification(t *testing.T) { Name: "test", DefaultAlias: "eu-west-3", }, alerter)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsS3BucketNotificationResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsS3BucketNotificationResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsS3BucketNotificationResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -492,12 +524,12 @@ func TestS3BucketNotification(t *testing.T) { } func TestS3BucketMetrics(t *testing.T) { - tests := []struct { - test string - dirName string - mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "multiple bucket with multiple metrics", dirName: "aws_s3_bucket_metrics_multiple", @@ -546,6 +578,15 @@ func TestS3BucketMetrics(t *testing.T) { nil, ) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "bucket-martin-test-drift2:Metrics_Bucket2", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsS3BucketMetricResourceType, got[0].ResourceType()) + + assert.Equal(t, "bucket-martin-test-drift2:Metrics2_Bucket2", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsS3BucketMetricResourceType, got[1].ResourceType()) + }, }, { test: "cannot list bucket", dirName: "aws_s3_bucket_metrics_list_bucket", @@ -555,6 +596,9 @@ func TestS3BucketMetrics(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsS3BucketMetricResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsS3BucketMetricResourceType, resourceaws.AwsS3BucketResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -586,12 +630,14 @@ func TestS3BucketMetrics(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsS3BucketMetricResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsS3BucketMetricResourceType, resourceaws.AwsS3BucketMetricResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -601,7 +647,6 @@ func TestS3BucketMetrics(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -632,18 +677,18 @@ func TestS3BucketMetrics(t *testing.T) { Name: "test", DefaultAlias: "eu-west-3", }, alerter)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsS3BucketMetricResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsS3BucketMetricResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsS3BucketMetricResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -651,12 +696,12 @@ func TestS3BucketMetrics(t *testing.T) { } func TestS3BucketPolicy(t *testing.T) { - tests := []struct { - test string - dirName string - mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "single bucket without policy", @@ -685,6 +730,9 @@ func TestS3BucketPolicy(t *testing.T) { nil, ) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "multiple bucket with policies", dirName: "aws_s3_bucket_policies_multiple", @@ -733,6 +781,12 @@ func TestS3BucketPolicy(t *testing.T) { ) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 1) + + assert.Equal(t, "bucket-martin-test-drift2", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsS3BucketPolicyResourceType, got[0].ResourceType()) + }, }, { test: "cannot list bucket", dirName: "aws_s3_bucket_policies_list_bucket", @@ -742,12 +796,14 @@ func TestS3BucketPolicy(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsS3BucketPolicyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsS3BucketPolicyResourceType, resourceaws.AwsS3BucketResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -757,7 +813,6 @@ func TestS3BucketPolicy(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -788,18 +843,18 @@ func TestS3BucketPolicy(t *testing.T) { Name: "test", DefaultAlias: "eu-west-3", }, alerter)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsS3BucketPolicyResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsS3BucketPolicyResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsS3BucketPolicyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -874,7 +929,6 @@ func TestS3BucketPublicAccessBlock(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -893,7 +947,7 @@ func TestS3BucketPublicAccessBlock(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -909,12 +963,12 @@ func TestS3BucketPublicAccessBlock(t *testing.T) { } func TestS3BucketAnalytic(t *testing.T) { - tests := []struct { - test string - dirName string - mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockS3Repository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "multiple bucket with multiple analytics", @@ -964,6 +1018,15 @@ func TestS3BucketAnalytic(t *testing.T) { nil, ) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "bucket-martin-test-drift2:Analytics_Bucket2", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsS3BucketAnalyticsConfigurationResourceType, got[0].ResourceType()) + + assert.Equal(t, "bucket-martin-test-drift2:Analytics2_Bucket2", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsS3BucketAnalyticsConfigurationResourceType, got[1].ResourceType()) + }, }, { test: "cannot list bucket", dirName: "aws_s3_bucket_analytics_list_bucket", @@ -973,6 +1036,9 @@ func TestS3BucketAnalytic(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsS3BucketAnalyticsConfigurationResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsS3BucketAnalyticsConfigurationResourceType, resourceaws.AwsS3BucketResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -1004,12 +1070,14 @@ func TestS3BucketAnalytic(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsS3BucketAnalyticsConfigurationResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsS3BucketAnalyticsConfigurationResourceType, resourceaws.AwsS3BucketAnalyticsConfigurationResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { @@ -1019,7 +1087,6 @@ func TestS3BucketAnalytic(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1050,18 +1117,18 @@ func TestS3BucketAnalytic(t *testing.T) { Name: "test", DefaultAlias: "eu-west-3", }, alerter)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsS3BucketAnalyticsConfigurationResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsS3BucketAnalyticsConfigurationResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsS3BucketAnalyticsConfigurationResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -1113,7 +1180,6 @@ func TestS3AccountPublicAccessBlock(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -1132,7 +1198,7 @@ func TestS3AccountPublicAccessBlock(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { diff --git a/enumeration/remote/aws_sns_scanner_test.go b/enumeration/remote/aws_sns_scanner_test.go index 5943eec5a..8cd1c4d04 100644 --- a/enumeration/remote/aws_sns_scanner_test.go +++ b/enumeration/remote/aws_sns_scanner_test.go @@ -25,18 +25,17 @@ import ( "github.com/snyk/driftctl/enumeration/resource" resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" "github.com/stretchr/testify/assert" ) func TestScanSNSTopic(t *testing.T) { - cases := []struct { - test string - dirName string - mocks func(*repository.MockSNSRepository, *mocks.AlerterInterface) - err error + test string + dirName string + mocks func(*repository.MockSNSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + err error }{ { test: "no SNS Topic", @@ -44,6 +43,9 @@ func TestScanSNSTopic(t *testing.T) { mocks: func(client *repository.MockSNSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllTopics").Return([]*sns.Topic{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, { @@ -56,6 +58,18 @@ func TestScanSNSTopic(t *testing.T) { {TopicArn: awssdk.String("arn:aws:sns:eu-west-3:526954929923:user-updates-topic3")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "arn:aws:sns:eu-west-3:526954929923:user-updates-topic", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsSnsTopicResourceType, got[0].ResourceType()) + + assert.Equal(t, "arn:aws:sns:eu-west-3:526954929923:user-updates-topic2", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsSnsTopicResourceType, got[1].ResourceType()) + + assert.Equal(t, "arn:aws:sns:eu-west-3:526954929923:user-updates-topic3", got[2].ResourceId()) + assert.Equal(t, resourceaws.AwsSnsTopicResourceType, got[2].ResourceType()) + }, err: nil, }, { @@ -67,12 +81,14 @@ func TestScanSNSTopic(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsSnsTopicResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsSnsTopicResourceType, resourceaws.AwsSnsTopicResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -82,7 +98,6 @@ func TestScanSNSTopic(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -111,18 +126,18 @@ func TestScanSNSTopic(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewSNSTopicEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsSnsTopicResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsSnsTopicResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.err, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsSnsTopicResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -130,12 +145,12 @@ func TestScanSNSTopic(t *testing.T) { } func TestSNSTopicPolicyScan(t *testing.T) { - cases := []struct { - test string - dirName string - mocks func(*repository.MockSNSRepository, *mocks.AlerterInterface) - err error + test string + dirName string + mocks func(*repository.MockSNSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + err error }{ { test: "no SNS Topic policy", @@ -143,6 +158,9 @@ func TestSNSTopicPolicyScan(t *testing.T) { mocks: func(client *repository.MockSNSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllTopics").Return([]*sns.Topic{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, { @@ -154,6 +172,15 @@ func TestSNSTopicPolicyScan(t *testing.T) { {TopicArn: awssdk.String("arn:aws:sns:us-east-1:526954929923:my-topic-with-policy2")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "arn:aws:sns:us-east-1:526954929923:my-topic-with-policy", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsSnsTopicPolicyResourceType, got[0].ResourceType()) + + assert.Equal(t, "arn:aws:sns:us-east-1:526954929923:my-topic-with-policy2", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsSnsTopicPolicyResourceType, got[1].ResourceType()) + }, err: nil, }, { @@ -165,12 +192,14 @@ func TestSNSTopicPolicyScan(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsSnsTopicPolicyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsSnsTopicPolicyResourceType, resourceaws.AwsSnsTopicResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -180,7 +209,6 @@ func TestSNSTopicPolicyScan(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -209,18 +237,18 @@ func TestSNSTopicPolicyScan(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewSNSTopicPolicyEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsSnsTopicPolicyResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsSnsTopicPolicyResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.err, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsSnsTopicPolicyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -228,12 +256,12 @@ func TestSNSTopicPolicyScan(t *testing.T) { } func TestSNSTopicSubscriptionScan(t *testing.T) { - cases := []struct { - test string - dirName string - mocks func(*repository.MockSNSRepository, *mocks.AlerterInterface) - err error + test string + dirName string + mocks func(*repository.MockSNSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + err error }{ { test: "no SNS Topic Subscription", @@ -241,6 +269,9 @@ func TestSNSTopicSubscriptionScan(t *testing.T) { mocks: func(client *repository.MockSNSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllSubscriptions").Return([]*sns.Subscription{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, { @@ -252,6 +283,15 @@ func TestSNSTopicSubscriptionScan(t *testing.T) { {SubscriptionArn: awssdk.String("arn:aws:sns:us-east-1:526954929923:user-updates-topic:b6e66147-2b31-4486-8d4b-2a2272264c8e")}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "arn:aws:sns:us-east-1:526954929923:user-updates-topic2:c0f794c5-a009-4db4-9147-4c55959787fa", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsSnsTopicSubscriptionResourceType, got[0].ResourceType()) + + assert.Equal(t, "arn:aws:sns:us-east-1:526954929923:user-updates-topic:b6e66147-2b31-4486-8d4b-2a2272264c8e", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsSnsTopicSubscriptionResourceType, got[1].ResourceType()) + }, err: nil, }, { @@ -269,6 +309,15 @@ func TestSNSTopicSubscriptionScan(t *testing.T) { alerter.On("SendAlert", "aws_sns_topic_subscription.Incorrect", aws.NewWrongArnTopicAlert("Incorrect", awssdk.String("INCORRECT"))).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "arn:aws:sns:us-east-1:526954929923:user-updates-topic2:c0f794c5-a009-4db4-9147-4c55959787fa", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsSnsTopicSubscriptionResourceType, got[0].ResourceType()) + + assert.Equal(t, "arn:aws:sns:us-east-1:526954929923:user-updates-topic:b6e66147-2b31-4486-8d4b-2a2272264c8e", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsSnsTopicSubscriptionResourceType, got[1].ResourceType()) + }, err: nil, }, { @@ -280,12 +329,14 @@ func TestSNSTopicSubscriptionScan(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsSnsTopicSubscriptionResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsSnsTopicSubscriptionResourceType, resourceaws.AwsSnsTopicSubscriptionResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -295,7 +346,6 @@ func TestSNSTopicSubscriptionScan(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -324,18 +374,18 @@ func TestSNSTopicSubscriptionScan(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewSNSTopicSubscriptionEnumerator(repo, factory, alerter)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsSnsTopicSubscriptionResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsSnsTopicSubscriptionResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsSnsTopicSubscriptionResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) diff --git a/enumeration/remote/aws_sqs_scanner_test.go b/enumeration/remote/aws_sqs_scanner_test.go index 3d9cda288..bb91e4519 100644 --- a/enumeration/remote/aws_sqs_scanner_test.go +++ b/enumeration/remote/aws_sqs_scanner_test.go @@ -21,7 +21,6 @@ import ( resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" "github.com/snyk/driftctl/mocks" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" @@ -30,10 +29,11 @@ import ( func TestSQSQueue(t *testing.T) { cases := []struct { - test string - dirName string - mocks func(*repository.MockSQSRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockSQSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no sqs queues", @@ -41,6 +41,9 @@ func TestSQSQueue(t *testing.T) { mocks: func(client *repository.MockSQSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllQueues").Return([]*string{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -52,6 +55,15 @@ func TestSQSQueue(t *testing.T) { awssdk.String("https://sqs.eu-west-3.amazonaws.com/047081014315/foo"), }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "https://sqs.eu-west-3.amazonaws.com/047081014315/bar.fifo", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsSqsQueueResourceType, got[0].ResourceType()) + + assert.Equal(t, "https://sqs.eu-west-3.amazonaws.com/047081014315/foo", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsSqsQueueResourceType, got[1].ResourceType()) + }, wantErr: nil, }, { @@ -63,12 +75,14 @@ func TestSQSQueue(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsSqsQueueResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsSqsQueueResourceType, resourceaws.AwsSqsQueueResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -78,7 +92,6 @@ func TestSQSQueue(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -106,18 +119,18 @@ func TestSQSQueue(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewSQSQueueEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsSqsQueueResourceType, aws.NewSQSQueueDetailsFetcher(provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsSqsQueueResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) fakeRepo.AssertExpectations(tt) alerter.AssertExpectations(tt) }) @@ -126,10 +139,11 @@ func TestSQSQueue(t *testing.T) { func TestSQSQueuePolicy(t *testing.T) { cases := []struct { - test string - dirName string - mocks func(*repository.MockSQSRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockSQSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { // sqs queue with no policy case is not possible @@ -139,6 +153,9 @@ func TestSQSQueuePolicy(t *testing.T) { mocks: func(client *repository.MockSQSRepository, alerter *mocks.AlerterInterface) { client.On("ListAllQueues").Return([]*string{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -160,6 +177,18 @@ func TestSQSQueuePolicy(t *testing.T) { nil, ) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "https://sqs.eu-west-3.amazonaws.com/047081014315/bar.fifo", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsSqsQueuePolicyResourceType, got[0].ResourceType()) + + assert.Equal(t, "https://sqs.eu-west-3.amazonaws.com/047081014315/foo", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsSqsQueuePolicyResourceType, got[1].ResourceType()) + + assert.Equal(t, "https://sqs.eu-west-3.amazonaws.com/047081014315/baz", got[2].ResourceId()) + assert.Equal(t, resourceaws.AwsSqsQueuePolicyResourceType, got[2].ResourceType()) + }, wantErr: nil, }, { @@ -177,6 +206,18 @@ func TestSQSQueuePolicy(t *testing.T) { nil, ) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "https://sqs.eu-west-3.amazonaws.com/047081014315/bar.fifo", got[0].ResourceId()) + assert.Equal(t, resourceaws.AwsSqsQueuePolicyResourceType, got[0].ResourceType()) + + assert.Equal(t, "https://sqs.eu-west-3.amazonaws.com/047081014315/foo", got[1].ResourceId()) + assert.Equal(t, resourceaws.AwsSqsQueuePolicyResourceType, got[1].ResourceType()) + + assert.Equal(t, "https://sqs.eu-west-3.amazonaws.com/047081014315/baz", got[2].ResourceId()) + assert.Equal(t, resourceaws.AwsSqsQueuePolicyResourceType, got[2].ResourceType()) + }, wantErr: nil, }, { @@ -188,12 +229,14 @@ func TestSQSQueuePolicy(t *testing.T) { alerter.On("SendAlert", resourceaws.AwsSqsQueuePolicyResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awsError, resourceaws.AwsSqsQueuePolicyResourceType, resourceaws.AwsSqsQueueResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -203,7 +246,6 @@ func TestSQSQueuePolicy(t *testing.T) { SharedConfigState: session.SharedConfigEnable, })) - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -231,18 +273,18 @@ func TestSQSQueuePolicy(t *testing.T) { } remoteLibrary.AddEnumerator(aws.NewSQSQueuePolicyEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceaws.AwsSqsQueuePolicyResourceType, common.NewGenericDetailsFetcher(resourceaws.AwsSqsQueuePolicyResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceaws.AwsSqsQueuePolicyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) fakeRepo.AssertExpectations(tt) alerter.AssertExpectations(tt) }) diff --git a/enumeration/remote/azurerm/init.go b/enumeration/remote/azurerm/init.go index 64a1acd3b..8be9823d4 100644 --- a/enumeration/remote/azurerm/init.go +++ b/enumeration/remote/azurerm/init.go @@ -9,7 +9,6 @@ import ( "github.com/snyk/driftctl/enumeration/remote/cache" "github.com/snyk/driftctl/enumeration/remote/common" "github.com/snyk/driftctl/enumeration/resource" - "github.com/snyk/driftctl/enumeration/resource/azurerm" "github.com/snyk/driftctl/enumeration/terraform" ) @@ -46,7 +45,6 @@ func Init(version string, alerter alerter.AlerterInterface, providerLibrary *ter computeRepo := repository.NewComputeRepository(cred, clientOptions, providerConfig, c) providerLibrary.AddProvider(terraform.AZURE, provider) - deserializer := resource.NewDeserializer(factory) remoteLibrary.AddEnumerator(NewAzurermStorageAccountEnumerator(storageAccountRepo, factory)) remoteLibrary.AddEnumerator(NewAzurermStorageContainerEnumerator(storageAccountRepo, factory)) @@ -61,31 +59,20 @@ func Init(version string, alerter alerter.AlerterInterface, providerLibrary *ter remoteLibrary.AddEnumerator(NewAzurermPublicIPEnumerator(networkRepo, factory)) remoteLibrary.AddEnumerator(NewAzurermPostgresqlDatabaseEnumerator(postgresqlRepo, factory)) remoteLibrary.AddEnumerator(NewAzurermNetworkSecurityGroupEnumerator(networkRepo, factory)) - remoteLibrary.AddDetailsFetcher(azurerm.AzureNetworkSecurityGroupResourceType, common.NewGenericDetailsFetcher(azurerm.AzureNetworkSecurityGroupResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewAzurermLoadBalancerEnumerator(networkRepo, factory)) remoteLibrary.AddEnumerator(NewAzurermLoadBalancerRuleEnumerator(networkRepo, factory)) - remoteLibrary.AddDetailsFetcher(azurerm.AzureLoadBalancerRuleResourceType, common.NewGenericDetailsFetcher(azurerm.AzureLoadBalancerRuleResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewAzurermPrivateDNSZoneEnumerator(privateDNSRepo, factory)) - remoteLibrary.AddDetailsFetcher(azurerm.AzurePrivateDNSZoneResourceType, common.NewGenericDetailsFetcher(azurerm.AzurePrivateDNSZoneResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewAzurermPrivateDNSARecordEnumerator(privateDNSRepo, factory)) - remoteLibrary.AddDetailsFetcher(azurerm.AzurePrivateDNSARecordResourceType, common.NewGenericDetailsFetcher(azurerm.AzurePrivateDNSARecordResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewAzurermPrivateDNSAAAARecordEnumerator(privateDNSRepo, factory)) - remoteLibrary.AddDetailsFetcher(azurerm.AzurePrivateDNSAAAARecordResourceType, common.NewGenericDetailsFetcher(azurerm.AzurePrivateDNSAAAARecordResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewAzurermPrivateDNSMXRecordEnumerator(privateDNSRepo, factory)) - remoteLibrary.AddDetailsFetcher(azurerm.AzurePrivateDNSMXRecordResourceType, common.NewGenericDetailsFetcher(azurerm.AzurePrivateDNSMXRecordResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewAzurermPrivateDNSCNameRecordEnumerator(privateDNSRepo, factory)) - remoteLibrary.AddDetailsFetcher(azurerm.AzurePrivateDNSCNameRecordResourceType, common.NewGenericDetailsFetcher(azurerm.AzurePrivateDNSCNameRecordResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewAzurermPrivateDNSPTRRecordEnumerator(privateDNSRepo, factory)) - remoteLibrary.AddDetailsFetcher(azurerm.AzurePrivateDNSPTRRecordResourceType, common.NewGenericDetailsFetcher(azurerm.AzurePrivateDNSPTRRecordResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewAzurermPrivateDNSSRVRecordEnumerator(privateDNSRepo, factory)) - remoteLibrary.AddDetailsFetcher(azurerm.AzurePrivateDNSSRVRecordResourceType, common.NewGenericDetailsFetcher(azurerm.AzurePrivateDNSSRVRecordResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewAzurermPrivateDNSTXTRecordEnumerator(privateDNSRepo, factory)) - remoteLibrary.AddDetailsFetcher(azurerm.AzurePrivateDNSTXTRecordResourceType, common.NewGenericDetailsFetcher(azurerm.AzurePrivateDNSTXTRecordResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewAzurermImageEnumerator(computeRepo, factory)) remoteLibrary.AddEnumerator(NewAzurermSSHPublicKeyEnumerator(computeRepo, factory)) - remoteLibrary.AddDetailsFetcher(azurerm.AzureSSHPublicKeyResourceType, common.NewGenericDetailsFetcher(azurerm.AzureSSHPublicKeyResourceType, provider, deserializer)) return nil } diff --git a/enumeration/remote/azurerm_compute_scanner_test.go b/enumeration/remote/azurerm_compute_scanner_test.go index 4e37a9e3b..b51ec0e44 100644 --- a/enumeration/remote/azurerm_compute_scanner_test.go +++ b/enumeration/remote/azurerm_compute_scanner_test.go @@ -20,7 +20,6 @@ import ( resourceazure "github.com/snyk/driftctl/enumeration/resource/azurerm" "github.com/snyk/driftctl/mocks" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" @@ -28,7 +27,6 @@ import ( ) func TestAzurermCompute_Image(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { @@ -93,7 +91,6 @@ func TestAzurermCompute_Image(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -106,7 +103,7 @@ func TestAzurermCompute_Image(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -121,14 +118,14 @@ func TestAzurermCompute_Image(t *testing.T) { } func TestAzurermCompute_SSHPublicKey(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { - test string - dirName string - mocks func(*repository.MockComputeRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockComputeRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no public key", @@ -136,6 +133,9 @@ func TestAzurermCompute_SSHPublicKey(t *testing.T) { mocks: func(repository *repository.MockComputeRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllSSHPublicKeys").Return([]*armcompute.SSHPublicKeyResource{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "error listing public keys", @@ -143,6 +143,9 @@ func TestAzurermCompute_SSHPublicKey(t *testing.T) { mocks: func(repository *repository.MockComputeRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllSSHPublicKeys").Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: remoteerr.NewResourceListingError(dummyError, resourceazure.AzureSSHPublicKeyResourceType), }, { @@ -164,17 +167,24 @@ func TestAzurermCompute_SSHPublicKey(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "/subscriptions/7bfb2c5c-7308-46ed-8ae4-fffa356eb406/resourceGroups/TESTRESGROUP/providers/Microsoft.Compute/sshPublicKeys/example-key", got[0].ResourceId()) + assert.Equal(t, resourceazure.AzureSSHPublicKeyResourceType, got[0].ResourceType()) + + assert.Equal(t, "/subscriptions/7bfb2c5c-7308-46ed-8ae4-fffa356eb406/resourceGroups/TESTRESGROUP/providers/Microsoft.Compute/sshPublicKeys/example-key2", got[1].ResourceId()) + assert.Equal(t, resourceazure.AzureSSHPublicKeyResourceType, got[1].ResourceType()) + }, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -208,19 +218,19 @@ func TestAzurermCompute_SSHPublicKey(t *testing.T) { } remoteLibrary.AddEnumerator(azurerm.NewAzurermSSHPublicKeyEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceazure.AzureSSHPublicKeyResourceType, common.NewGenericDetailsFetcher(resourceazure.AzureSSHPublicKeyResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceazure.AzureSSHPublicKeyResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) diff --git a/enumeration/remote/azurerm_containerregistry_scanner_test.go b/enumeration/remote/azurerm_containerregistry_scanner_test.go index b62f2f9d7..16dc76fd7 100644 --- a/enumeration/remote/azurerm_containerregistry_scanner_test.go +++ b/enumeration/remote/azurerm_containerregistry_scanner_test.go @@ -79,8 +79,6 @@ func TestAzurermContainerRegistry(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -95,7 +93,7 @@ func TestAzurermContainerRegistry(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { diff --git a/enumeration/remote/azurerm_network_scanner_test.go b/enumeration/remote/azurerm_network_scanner_test.go index 24240746d..255ce5a16 100644 --- a/enumeration/remote/azurerm_network_scanner_test.go +++ b/enumeration/remote/azurerm_network_scanner_test.go @@ -20,7 +20,6 @@ import ( resourceazure "github.com/snyk/driftctl/enumeration/resource/azurerm" "github.com/snyk/driftctl/mocks" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" @@ -28,7 +27,6 @@ import ( ) func TestAzurermVirtualNetwork(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { @@ -87,8 +85,6 @@ func TestAzurermVirtualNetwork(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -103,7 +99,7 @@ func TestAzurermVirtualNetwork(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -118,7 +114,6 @@ func TestAzurermVirtualNetwork(t *testing.T) { } func TestAzurermRouteTables(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { @@ -177,8 +172,6 @@ func TestAzurermRouteTables(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -193,7 +186,7 @@ func TestAzurermRouteTables(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -208,7 +201,6 @@ func TestAzurermRouteTables(t *testing.T) { } func TestAzurermRoutes(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { @@ -323,8 +315,6 @@ func TestAzurermRoutes(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -339,7 +329,7 @@ func TestAzurermRoutes(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -354,7 +344,6 @@ func TestAzurermRoutes(t *testing.T) { } func TestAzurermSubnets(t *testing.T) { - dummyError := errors.New("this is an error") networks := []*armnetwork.VirtualNetwork{ @@ -453,8 +442,6 @@ func TestAzurermSubnets(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -469,7 +456,7 @@ func TestAzurermSubnets(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -484,7 +471,6 @@ func TestAzurermSubnets(t *testing.T) { } func TestAzurermFirewalls(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { @@ -543,8 +529,6 @@ func TestAzurermFirewalls(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -559,7 +543,7 @@ func TestAzurermFirewalls(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -574,7 +558,6 @@ func TestAzurermFirewalls(t *testing.T) { } func TestAzurermPublicIP(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { @@ -633,8 +616,6 @@ func TestAzurermPublicIP(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -649,7 +630,7 @@ func TestAzurermPublicIP(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -664,14 +645,14 @@ func TestAzurermPublicIP(t *testing.T) { } func TestAzurermSecurityGroups(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { - test string - dirName string - mocks func(*repository.MockNetworkRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockNetworkRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no security group", @@ -679,6 +660,9 @@ func TestAzurermSecurityGroups(t *testing.T) { mocks: func(repository *repository.MockNetworkRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllSecurityGroups").Return([]*armnetwork.NetworkSecurityGroup{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "error listing security groups", @@ -686,6 +670,9 @@ func TestAzurermSecurityGroups(t *testing.T) { mocks: func(repository *repository.MockNetworkRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllSecurityGroups").Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: error2.NewResourceListingError(dummyError, resourceazure.AzureNetworkSecurityGroupResourceType), }, { @@ -707,17 +694,23 @@ func TestAzurermSecurityGroups(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "/subscriptions/7bfb2c5c-7308-46ed-8ae4-fffa356eb406/resourceGroups/example-resources/providers/Microsoft.Network/networkSecurityGroups/acceptanceTestSecurityGroup1", got[0].ResourceId()) + assert.Equal(t, resourceazure.AzureNetworkSecurityGroupResourceType, got[0].ResourceType()) + + assert.Equal(t, "/subscriptions/7bfb2c5c-7308-46ed-8ae4-fffa356eb406/resourceGroups/example-resources/providers/Microsoft.Network/networkSecurityGroups/acceptanceTestSecurityGroup2", got[1].ResourceId()) + assert.Equal(t, resourceazure.AzureNetworkSecurityGroupResourceType, got[1].ResourceType()) + }, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -751,19 +744,19 @@ func TestAzurermSecurityGroups(t *testing.T) { } remoteLibrary.AddEnumerator(azurerm.NewAzurermNetworkSecurityGroupEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceazure.AzureNetworkSecurityGroupResourceType, common.NewGenericDetailsFetcher(resourceazure.AzureNetworkSecurityGroupResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceazure.AzureNetworkSecurityGroupResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -771,7 +764,6 @@ func TestAzurermSecurityGroups(t *testing.T) { } func TestAzurermLoadBalancers(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { @@ -830,8 +822,6 @@ func TestAzurermLoadBalancers(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -846,7 +836,7 @@ func TestAzurermLoadBalancers(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -861,14 +851,14 @@ func TestAzurermLoadBalancers(t *testing.T) { } func TestAzurermLoadBalancerRules(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { - test string - dirName string - mocks func(*repository.MockNetworkRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockNetworkRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no load balancer rule", @@ -885,6 +875,9 @@ func TestAzurermLoadBalancerRules(t *testing.T) { repository.On("ListLoadBalancerRules", loadbalancer).Return([]*armnetwork.LoadBalancingRule{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "error listing load balancer rules", @@ -892,6 +885,9 @@ func TestAzurermLoadBalancerRules(t *testing.T) { mocks: func(repository *repository.MockNetworkRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllLoadBalancers").Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: error2.NewResourceListingErrorWithType(dummyError, resourceazure.AzureLoadBalancerRuleResourceType, resourceazure.AzureLoadBalancerResourceType), }, { @@ -922,17 +918,23 @@ func TestAzurermLoadBalancerRules(t *testing.T) { }, }, nil).Once() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "/subscriptions/8cb43347-a79f-4bb2-a8b4-c838b41fa5a5/resourceGroups/raphael-dev/providers/Microsoft.Network/loadBalancers/TestLoadBalancer/loadBalancingRules/LBRule", got[0].ResourceId()) + assert.Equal(t, resourceazure.AzureLoadBalancerRuleResourceType, got[0].ResourceType()) + + assert.Equal(t, "/subscriptions/8cb43347-a79f-4bb2-a8b4-c838b41fa5a5/resourceGroups/raphael-dev/providers/Microsoft.Network/loadBalancers/TestLoadBalancer/loadBalancingRules/LBRule2", got[1].ResourceId()) + assert.Equal(t, resourceazure.AzureLoadBalancerRuleResourceType, got[1].ResourceType()) + }, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -966,19 +968,19 @@ func TestAzurermLoadBalancerRules(t *testing.T) { } remoteLibrary.AddEnumerator(azurerm.NewAzurermLoadBalancerRuleEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceazure.AzureLoadBalancerRuleResourceType, common.NewGenericDetailsFetcher(resourceazure.AzureLoadBalancerRuleResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceazure.AzureLoadBalancerRuleResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) diff --git a/enumeration/remote/azurerm_postgresql_scanner_test.go b/enumeration/remote/azurerm_postgresql_scanner_test.go index ed54f6d95..87651a5a9 100644 --- a/enumeration/remote/azurerm_postgresql_scanner_test.go +++ b/enumeration/remote/azurerm_postgresql_scanner_test.go @@ -85,8 +85,6 @@ func TestAzurermPostgresqlServer(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -101,7 +99,7 @@ func TestAzurermPostgresqlServer(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -208,8 +206,6 @@ func TestAzurermPostgresqlDatabase(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -224,7 +220,7 @@ func TestAzurermPostgresqlDatabase(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { diff --git a/enumeration/remote/azurerm_privatedns_scanner_test.go b/enumeration/remote/azurerm_privatedns_scanner_test.go index a88da35cd..88c4057e4 100644 --- a/enumeration/remote/azurerm_privatedns_scanner_test.go +++ b/enumeration/remote/azurerm_privatedns_scanner_test.go @@ -20,7 +20,6 @@ import ( resourceazure "github.com/snyk/driftctl/enumeration/resource/azurerm" "github.com/snyk/driftctl/mocks" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" terraformtest "github.com/snyk/driftctl/test/terraform" @@ -29,14 +28,14 @@ import ( ) func TestAzurermPrivateDNSZone(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { - test string - dirName string - mocks func(*repository.MockPrivateDNSRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockPrivateDNSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no private zone", @@ -44,6 +43,9 @@ func TestAzurermPrivateDNSZone(t *testing.T) { mocks: func(repository *repository.MockPrivateDNSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllPrivateZones").Return([]*armprivatedns.PrivateZone{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "error listing private zones", @@ -51,6 +53,9 @@ func TestAzurermPrivateDNSZone(t *testing.T) { mocks: func(repository *repository.MockPrivateDNSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllPrivateZones").Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: remoteerr.NewResourceListingError(dummyError, resourceazure.AzurePrivateDNSZoneResourceType), }, { @@ -84,17 +89,27 @@ func TestAzurermPrivateDNSZone(t *testing.T) { }, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "/subscriptions/7bfb2c5c-7308-46ed-8ae4-fffa356eb406/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/thisisatestusingtf.com", got[0].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSZoneResourceType, got[0].ResourceType()) + + assert.Equal(t, "/subscriptions/7bfb2c5c-7308-46ed-8ae4-fffa356eb406/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/thisisatestusingtf2.com", got[1].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSZoneResourceType, got[1].ResourceType()) + + assert.Equal(t, "/subscriptions/7bfb2c5c-7308-46ed-8ae4-fffa356eb406/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/testmartin.com", got[2].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSZoneResourceType, got[2].ResourceType()) + }, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -128,19 +143,19 @@ func TestAzurermPrivateDNSZone(t *testing.T) { } remoteLibrary.AddEnumerator(azurerm.NewAzurermPrivateDNSZoneEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceazure.AzurePrivateDNSZoneResourceType, common.NewGenericDetailsFetcher(resourceazure.AzurePrivateDNSZoneResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceazure.AzurePrivateDNSZoneResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -148,14 +163,14 @@ func TestAzurermPrivateDNSZone(t *testing.T) { } func TestAzurermPrivateDNSARecord(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { - test string - dirName string - mocks func(*repository.MockPrivateDNSRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockPrivateDNSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no private a record", @@ -163,6 +178,9 @@ func TestAzurermPrivateDNSARecord(t *testing.T) { mocks: func(repository *repository.MockPrivateDNSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllPrivateZones").Return([]*armprivatedns.PrivateZone{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "error listing private zone", @@ -170,6 +188,9 @@ func TestAzurermPrivateDNSARecord(t *testing.T) { mocks: func(repository *repository.MockPrivateDNSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllPrivateZones").Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: remoteerr.NewResourceListingErrorWithType(dummyError, resourceazure.AzurePrivateDNSARecordResourceType, resourceazure.AzurePrivateDNSZoneResourceType), }, { @@ -188,6 +209,9 @@ func TestAzurermPrivateDNSARecord(t *testing.T) { }, nil) repository.On("ListAllARecords", mock.Anything).Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: remoteerr.NewResourceListingError(dummyError, resourceazure.AzurePrivateDNSARecordResourceType), }, { @@ -235,17 +259,24 @@ func TestAzurermPrivateDNSARecord(t *testing.T) { }, }, nil).Once() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "/subscriptions/7bfb2c5c-7308-46ed-8ae4-fffa356eb406/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/thisisatestusingtf.com/A/test", got[0].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSARecordResourceType, got[0].ResourceType()) + + assert.Equal(t, "/subscriptions/7bfb2c5c-7308-46ed-8ae4-fffa356eb406/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/thisisatestusingtf.com/A/othertest", got[1].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSARecordResourceType, got[1].ResourceType()) + }, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -279,19 +310,19 @@ func TestAzurermPrivateDNSARecord(t *testing.T) { } remoteLibrary.AddEnumerator(azurerm.NewAzurermPrivateDNSARecordEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceazure.AzurePrivateDNSARecordResourceType, common.NewGenericDetailsFetcher(resourceazure.AzurePrivateDNSARecordResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceazure.AzurePrivateDNSARecordResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -299,14 +330,14 @@ func TestAzurermPrivateDNSARecord(t *testing.T) { } func TestAzurermPrivateDNSAAAARecord(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { - test string - dirName string - mocks func(*repository.MockPrivateDNSRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockPrivateDNSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no private aaaa record", @@ -314,6 +345,9 @@ func TestAzurermPrivateDNSAAAARecord(t *testing.T) { mocks: func(repository *repository.MockPrivateDNSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllPrivateZones").Return([]*armprivatedns.PrivateZone{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "error listing private zone", @@ -321,6 +355,9 @@ func TestAzurermPrivateDNSAAAARecord(t *testing.T) { mocks: func(repository *repository.MockPrivateDNSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllPrivateZones").Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: remoteerr.NewResourceListingErrorWithType(dummyError, resourceazure.AzurePrivateDNSAAAARecordResourceType, resourceazure.AzurePrivateDNSZoneResourceType), }, { @@ -339,6 +376,9 @@ func TestAzurermPrivateDNSAAAARecord(t *testing.T) { }, nil) repository.On("ListAllAAAARecords", mock.Anything).Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: remoteerr.NewResourceListingError(dummyError, resourceazure.AzurePrivateDNSAAAARecordResourceType), }, { @@ -387,17 +427,24 @@ func TestAzurermPrivateDNSAAAARecord(t *testing.T) { }, }, nil).Once() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "/subscriptions/7bfb2c5c-7308-46ed-8ae4-fffa356eb406/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/thisisatestusingtf.com/AAAA/test", got[0].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSAAAARecordResourceType, got[0].ResourceType()) + + assert.Equal(t, "/subscriptions/7bfb2c5c-7308-46ed-8ae4-fffa356eb406/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/thisisatestusingtf.com/AAAA/othertest", got[1].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSAAAARecordResourceType, got[1].ResourceType()) + }, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -431,19 +478,19 @@ func TestAzurermPrivateDNSAAAARecord(t *testing.T) { } remoteLibrary.AddEnumerator(azurerm.NewAzurermPrivateDNSAAAARecordEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceazure.AzurePrivateDNSAAAARecordResourceType, common.NewGenericDetailsFetcher(resourceazure.AzurePrivateDNSAAAARecordResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceazure.AzurePrivateDNSAAAARecordResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -451,14 +498,14 @@ func TestAzurermPrivateDNSAAAARecord(t *testing.T) { } func TestAzurermPrivateDNSCNAMERecord(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { - test string - dirName string - mocks func(*repository.MockPrivateDNSRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockPrivateDNSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no private cname record", @@ -466,6 +513,9 @@ func TestAzurermPrivateDNSCNAMERecord(t *testing.T) { mocks: func(repository *repository.MockPrivateDNSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllPrivateZones").Return([]*armprivatedns.PrivateZone{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "error listing private zone", @@ -473,6 +523,9 @@ func TestAzurermPrivateDNSCNAMERecord(t *testing.T) { mocks: func(repository *repository.MockPrivateDNSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllPrivateZones").Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: remoteerr.NewResourceListingErrorWithType(dummyError, resourceazure.AzurePrivateDNSCNameRecordResourceType, resourceazure.AzurePrivateDNSZoneResourceType), }, { @@ -491,6 +544,9 @@ func TestAzurermPrivateDNSCNAMERecord(t *testing.T) { }, nil) repository.On("ListAllCNAMERecords", mock.Anything).Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: remoteerr.NewResourceListingError(dummyError, resourceazure.AzurePrivateDNSCNameRecordResourceType), }, { @@ -527,17 +583,24 @@ func TestAzurermPrivateDNSCNAMERecord(t *testing.T) { }, }, nil).Once() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "/subscriptions/7bfb2c5c-7308-46ed-8ae4-fffa356eb406/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/thisisatestusingtf.com/CNAME/test", got[0].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSCNameRecordResourceType, got[0].ResourceType()) + + assert.Equal(t, "/subscriptions/7bfb2c5c-7308-46ed-8ae4-fffa356eb406/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/thisisatestusingtf.com/CNAME/othertest", got[1].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSCNameRecordResourceType, got[1].ResourceType()) + }, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -571,19 +634,19 @@ func TestAzurermPrivateDNSCNAMERecord(t *testing.T) { } remoteLibrary.AddEnumerator(azurerm.NewAzurermPrivateDNSCNameRecordEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceazure.AzurePrivateDNSCNameRecordResourceType, common.NewGenericDetailsFetcher(resourceazure.AzurePrivateDNSCNameRecordResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceazure.AzurePrivateDNSCNameRecordResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -591,14 +654,14 @@ func TestAzurermPrivateDNSCNAMERecord(t *testing.T) { } func TestAzurermPrivateDNSPTRRecord(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { - test string - dirName string - mocks func(*repository.MockPrivateDNSRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockPrivateDNSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no private ptr record", @@ -606,6 +669,9 @@ func TestAzurermPrivateDNSPTRRecord(t *testing.T) { mocks: func(repository *repository.MockPrivateDNSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllPrivateZones").Return([]*armprivatedns.PrivateZone{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "error listing private zone", @@ -613,6 +679,9 @@ func TestAzurermPrivateDNSPTRRecord(t *testing.T) { mocks: func(repository *repository.MockPrivateDNSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllPrivateZones").Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: remoteerr.NewResourceListingErrorWithType(dummyError, resourceazure.AzurePrivateDNSPTRRecordResourceType, resourceazure.AzurePrivateDNSZoneResourceType), }, { @@ -631,6 +700,9 @@ func TestAzurermPrivateDNSPTRRecord(t *testing.T) { }, nil) repository.On("ListAllPTRRecords", mock.Anything).Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: remoteerr.NewResourceListingError(dummyError, resourceazure.AzurePrivateDNSPTRRecordResourceType), }, { @@ -678,17 +750,24 @@ func TestAzurermPrivateDNSPTRRecord(t *testing.T) { }, }, nil).Once() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "/subscriptions/8cb43347-a79f-4bb2-a8b4-c838b41fa5a5/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/thisisatestusingtf.com/PTR/othertestptr", got[0].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSPTRRecordResourceType, got[0].ResourceType()) + + assert.Equal(t, "/subscriptions/8cb43347-a79f-4bb2-a8b4-c838b41fa5a5/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/thisisatestusingtf.com/PTR/testptr", got[1].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSPTRRecordResourceType, got[1].ResourceType()) + }, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -722,19 +801,19 @@ func TestAzurermPrivateDNSPTRRecord(t *testing.T) { } remoteLibrary.AddEnumerator(azurerm.NewAzurermPrivateDNSPTRRecordEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceazure.AzurePrivateDNSPTRRecordResourceType, common.NewGenericDetailsFetcher(resourceazure.AzurePrivateDNSPTRRecordResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceazure.AzurePrivateDNSPTRRecordResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -742,14 +821,14 @@ func TestAzurermPrivateDNSPTRRecord(t *testing.T) { } func TestAzurermPrivateDNSMXRecord(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { - test string - dirName string - mocks func(*repository.MockPrivateDNSRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockPrivateDNSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no private mx record", @@ -757,6 +836,9 @@ func TestAzurermPrivateDNSMXRecord(t *testing.T) { mocks: func(repository *repository.MockPrivateDNSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllPrivateZones").Return([]*armprivatedns.PrivateZone{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "error listing private zone", @@ -764,6 +846,9 @@ func TestAzurermPrivateDNSMXRecord(t *testing.T) { mocks: func(repository *repository.MockPrivateDNSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllPrivateZones").Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: remoteerr.NewResourceListingErrorWithType(dummyError, resourceazure.AzurePrivateDNSMXRecordResourceType, resourceazure.AzurePrivateDNSZoneResourceType), }, { @@ -782,6 +867,9 @@ func TestAzurermPrivateDNSMXRecord(t *testing.T) { }, nil) repository.On("ListAllMXRecords", mock.Anything).Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: remoteerr.NewResourceListingError(dummyError, resourceazure.AzurePrivateDNSMXRecordResourceType), }, { @@ -830,17 +918,24 @@ func TestAzurermPrivateDNSMXRecord(t *testing.T) { }, }, nil).Once() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "/subscriptions/8cb43347-a79f-4bb2-a8b4-c838b41fa5a5/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/thisisatestusingtf.com/MX/othertestmx", got[0].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSMXRecordResourceType, got[0].ResourceType()) + + assert.Equal(t, "/subscriptions/8cb43347-a79f-4bb2-a8b4-c838b41fa5a5/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/thisisatestusingtf.com/MX/testmx", got[1].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSMXRecordResourceType, got[1].ResourceType()) + }, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -874,19 +969,19 @@ func TestAzurermPrivateDNSMXRecord(t *testing.T) { } remoteLibrary.AddEnumerator(azurerm.NewAzurermPrivateDNSMXRecordEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceazure.AzurePrivateDNSMXRecordResourceType, common.NewGenericDetailsFetcher(resourceazure.AzurePrivateDNSMXRecordResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceazure.AzurePrivateDNSMXRecordResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -894,14 +989,14 @@ func TestAzurermPrivateDNSMXRecord(t *testing.T) { } func TestAzurermPrivateDNSSRVRecord(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { - test string - dirName string - mocks func(*repository.MockPrivateDNSRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockPrivateDNSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no private srv record", @@ -909,6 +1004,9 @@ func TestAzurermPrivateDNSSRVRecord(t *testing.T) { mocks: func(repository *repository.MockPrivateDNSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllPrivateZones").Return([]*armprivatedns.PrivateZone{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "error listing private zone", @@ -916,6 +1014,9 @@ func TestAzurermPrivateDNSSRVRecord(t *testing.T) { mocks: func(repository *repository.MockPrivateDNSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllPrivateZones").Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: remoteerr.NewResourceListingErrorWithType(dummyError, resourceazure.AzurePrivateDNSSRVRecordResourceType, resourceazure.AzurePrivateDNSZoneResourceType), }, { @@ -934,6 +1035,9 @@ func TestAzurermPrivateDNSSRVRecord(t *testing.T) { }, nil) repository.On("ListAllSRVRecords", mock.Anything).Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: remoteerr.NewResourceListingError(dummyError, resourceazure.AzurePrivateDNSSRVRecordResourceType), }, { @@ -981,17 +1085,24 @@ func TestAzurermPrivateDNSSRVRecord(t *testing.T) { }, }, nil).Once() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "/subscriptions/8cb43347-a79f-4bb2-a8b4-c838b41fa5a5/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/thisisatestusingtf.com/SRV/othertestptr", got[0].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSSRVRecordResourceType, got[0].ResourceType()) + + assert.Equal(t, "/subscriptions/8cb43347-a79f-4bb2-a8b4-c838b41fa5a5/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/thisisatestusingtf.com/SRV/testptr", got[1].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSSRVRecordResourceType, got[1].ResourceType()) + }, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1025,19 +1136,19 @@ func TestAzurermPrivateDNSSRVRecord(t *testing.T) { } remoteLibrary.AddEnumerator(azurerm.NewAzurermPrivateDNSSRVRecordEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceazure.AzurePrivateDNSSRVRecordResourceType, common.NewGenericDetailsFetcher(resourceazure.AzurePrivateDNSSRVRecordResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceazure.AzurePrivateDNSSRVRecordResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) @@ -1045,14 +1156,14 @@ func TestAzurermPrivateDNSSRVRecord(t *testing.T) { } func TestAzurermPrivateDNSTXTRecord(t *testing.T) { - dummyError := errors.New("this is an error") tests := []struct { - test string - dirName string - mocks func(*repository.MockPrivateDNSRepository, *mocks.AlerterInterface) - wantErr error + test string + dirName string + mocks func(*repository.MockPrivateDNSRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + wantErr error }{ { test: "no private txt record", @@ -1060,6 +1171,9 @@ func TestAzurermPrivateDNSTXTRecord(t *testing.T) { mocks: func(repository *repository.MockPrivateDNSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllPrivateZones").Return([]*armprivatedns.PrivateZone{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, }, { test: "error listing private zone", @@ -1067,6 +1181,9 @@ func TestAzurermPrivateDNSTXTRecord(t *testing.T) { mocks: func(repository *repository.MockPrivateDNSRepository, alerter *mocks.AlerterInterface) { repository.On("ListAllPrivateZones").Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: remoteerr.NewResourceListingErrorWithType(dummyError, resourceazure.AzurePrivateDNSTXTRecordResourceType, resourceazure.AzurePrivateDNSZoneResourceType), }, { @@ -1085,6 +1202,9 @@ func TestAzurermPrivateDNSTXTRecord(t *testing.T) { }, nil) repository.On("ListAllTXTRecords", mock.Anything).Return(nil, dummyError) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: remoteerr.NewResourceListingError(dummyError, resourceazure.AzurePrivateDNSTXTRecordResourceType), }, { @@ -1132,17 +1252,24 @@ func TestAzurermPrivateDNSTXTRecord(t *testing.T) { }, }, nil).Once() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "/subscriptions/8cb43347-a79f-4bb2-a8b4-c838b41fa5a5/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/thisisatestusingtf.com/TXT/othertesttxt", got[0].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSTXTRecordResourceType, got[0].ResourceType()) + + assert.Equal(t, "/subscriptions/8cb43347-a79f-4bb2-a8b4-c838b41fa5a5/resourceGroups/martin-dev/providers/Microsoft.Network/privateDnsZones/thisisatestusingtf.com/TXT/testtxt", got[1].ResourceId()) + assert.Equal(t, resourceazure.AzurePrivateDNSTXTRecordResourceType, got[1].ResourceType()) + }, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1176,19 +1303,19 @@ func TestAzurermPrivateDNSTXTRecord(t *testing.T) { } remoteLibrary.AddEnumerator(azurerm.NewAzurermPrivateDNSTXTRecordEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resourceazure.AzurePrivateDNSTXTRecordResourceType, common.NewGenericDetailsFetcher(resourceazure.AzurePrivateDNSTXTRecordResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { return } - test.TestAgainstGoldenFile(got, resourceazure.AzurePrivateDNSTXTRecordResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) alerter.AssertExpectations(tt) fakeRepo.AssertExpectations(tt) }) diff --git a/enumeration/remote/azurerm_resources_scanner_test.go b/enumeration/remote/azurerm_resources_scanner_test.go index eeddbcf15..f395449c2 100644 --- a/enumeration/remote/azurerm_resources_scanner_test.go +++ b/enumeration/remote/azurerm_resources_scanner_test.go @@ -77,8 +77,6 @@ func TestAzurermResourceGroups(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -93,7 +91,7 @@ func TestAzurermResourceGroups(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { diff --git a/enumeration/remote/azurerm_storage_scanner_test.go b/enumeration/remote/azurerm_storage_scanner_test.go index a4da45e58..707108b31 100644 --- a/enumeration/remote/azurerm_storage_scanner_test.go +++ b/enumeration/remote/azurerm_storage_scanner_test.go @@ -82,8 +82,6 @@ func TestAzurermStorageAccount(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -98,7 +96,7 @@ func TestAzurermStorageAccount(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -224,8 +222,6 @@ func TestAzurermStorageContainer(t *testing.T) { for _, c := range tests { t.Run(c.test, func(tt *testing.T) { - - scanOptions := ScannerOptions{} remoteLibrary := common.NewRemoteLibrary() // Initialize mocks @@ -240,7 +236,7 @@ func TestAzurermStorageContainer(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { diff --git a/enumeration/remote/common/details_fetcher.go b/enumeration/remote/common/details_fetcher.go deleted file mode 100644 index 312a25855..000000000 --- a/enumeration/remote/common/details_fetcher.go +++ /dev/null @@ -1,76 +0,0 @@ -package common - -import ( - "strconv" - - "github.com/hashicorp/terraform/flatmap" - "github.com/sirupsen/logrus" - remoteerror "github.com/snyk/driftctl/enumeration/remote/error" - "github.com/snyk/driftctl/enumeration/resource" - "github.com/snyk/driftctl/enumeration/terraform" -) - -type DetailsFetcher interface { - ReadDetails(*resource.Resource) (*resource.Resource, error) -} - -type GenericDetailsFetcher struct { - resType resource.ResourceType - reader terraform.ResourceReader - deserializer *resource.Deserializer -} - -func NewGenericDetailsFetcher(resType resource.ResourceType, provider terraform.ResourceReader, deserializer *resource.Deserializer) *GenericDetailsFetcher { - return &GenericDetailsFetcher{ - resType: resType, - reader: provider, - deserializer: deserializer, - } -} - -func (f *GenericDetailsFetcher) ReadDetails(res *resource.Resource) (*resource.Resource, error) { - attributes := map[string]string{} - if res.Attributes() != nil { - for k, v := range *res.Attributes() { - if b, ok := v.(bool); ok { - attributes[k] = strconv.FormatBool(b) - } - if i, ok := v.(int); ok { - attributes[k] = strconv.Itoa(i) - } - if i64, ok := v.(int64); ok { - attributes[k] = strconv.FormatInt(i64, 10) - } - if str, ok := v.(string); ok { - attributes[k] = str - } - if sliceOfInterface, ok := v.([]interface{}); ok { - m := flatmap.Flatten(map[string]interface{}{k: sliceOfInterface}) - for k2, v2 := range m { - attributes[k2] = v2 - } - } - } - } - ctyVal, err := f.reader.ReadResource(terraform.ReadResourceArgs{ - Ty: f.resType, - ID: res.ResourceId(), - Attributes: attributes, - }) - if err != nil { - return nil, remoteerror.NewResourceScanningError(err, res.ResourceType(), res.ResourceId()) - } - if ctyVal.IsNull() { - logrus.WithFields(logrus.Fields{ - "type": f.resType, - "id": res.ResourceId(), - }).Debug("Got null while reading resource details") - return nil, nil - } - deserializedRes, err := f.deserializer.DeserializeOne(string(f.resType), *ctyVal) - if err != nil { - return nil, err - } - - return deserializedRes, nil -} diff --git a/enumeration/remote/common/library.go b/enumeration/remote/common/library.go index 4b0459ba4..5f13a291d 100644 --- a/enumeration/remote/common/library.go +++ b/enumeration/remote/common/library.go @@ -10,14 +10,12 @@ type Enumerator interface { } type RemoteLibrary struct { - enumerators []Enumerator - detailsFetchers map[resource.ResourceType]DetailsFetcher + enumerators []Enumerator } func NewRemoteLibrary() *RemoteLibrary { return &RemoteLibrary{ make([]Enumerator, 0), - make(map[resource.ResourceType]DetailsFetcher), } } @@ -28,11 +26,3 @@ func (r *RemoteLibrary) AddEnumerator(enumerator Enumerator) { func (r *RemoteLibrary) Enumerators() []Enumerator { return r.enumerators } - -func (r *RemoteLibrary) AddDetailsFetcher(ty resource.ResourceType, detailsFetcher DetailsFetcher) { - r.detailsFetchers[ty] = detailsFetcher -} - -func (r *RemoteLibrary) GetDetailsFetcher(ty resource.ResourceType) DetailsFetcher { - return r.detailsFetchers[ty] -} diff --git a/enumeration/remote/github/init.go b/enumeration/remote/github/init.go index edf6d7f9a..f233f2fb7 100644 --- a/enumeration/remote/github/init.go +++ b/enumeration/remote/github/init.go @@ -6,7 +6,6 @@ import ( "github.com/snyk/driftctl/enumeration/remote/cache" "github.com/snyk/driftctl/enumeration/remote/common" "github.com/snyk/driftctl/enumeration/resource" - "github.com/snyk/driftctl/enumeration/resource/github" "github.com/snyk/driftctl/enumeration/terraform" ) @@ -29,23 +28,17 @@ func Init(version string, alerter alerter.AlerterInterface, providerLibrary *ter repositoryCache := cache.New(100) repository := NewGithubRepository(provider.GetConfig(), repositoryCache) - deserializer := resource.NewDeserializer(factory) providerLibrary.AddProvider(terraform.GITHUB, provider) remoteLibrary.AddEnumerator(NewGithubTeamEnumerator(repository, factory)) - remoteLibrary.AddDetailsFetcher(github.GithubTeamResourceType, common.NewGenericDetailsFetcher(github.GithubTeamResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewGithubRepositoryEnumerator(repository, factory)) - remoteLibrary.AddDetailsFetcher(github.GithubRepositoryResourceType, common.NewGenericDetailsFetcher(github.GithubRepositoryResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewGithubMembershipEnumerator(repository, factory)) - remoteLibrary.AddDetailsFetcher(github.GithubMembershipResourceType, common.NewGenericDetailsFetcher(github.GithubMembershipResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewGithubTeamMembershipEnumerator(repository, factory)) - remoteLibrary.AddDetailsFetcher(github.GithubTeamMembershipResourceType, common.NewGenericDetailsFetcher(github.GithubTeamMembershipResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewGithubBranchProtectionEnumerator(repository, factory)) - remoteLibrary.AddDetailsFetcher(github.GithubBranchProtectionResourceType, common.NewGenericDetailsFetcher(github.GithubBranchProtectionResourceType, provider, deserializer)) return nil } diff --git a/enumeration/remote/github_branch_protection_scanner_test.go b/enumeration/remote/github_branch_protection_scanner_test.go index 3242865d7..fe0dda194 100644 --- a/enumeration/remote/github_branch_protection_scanner_test.go +++ b/enumeration/remote/github_branch_protection_scanner_test.go @@ -19,18 +19,17 @@ import ( "github.com/stretchr/testify/mock" "github.com/snyk/driftctl/enumeration/resource" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" "github.com/stretchr/testify/assert" ) func TestScanGithubBranchProtection(t *testing.T) { - cases := []struct { - test string - dirName string - mocks func(*github.MockGithubRepository, *mocks.AlerterInterface) - err error + test string + dirName string + mocks func(*github.MockGithubRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + err error }{ { test: "no branch protection", @@ -38,6 +37,9 @@ func TestScanGithubBranchProtection(t *testing.T) { mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { client.On("ListBranchProtection").Return([]string{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, { @@ -53,6 +55,15 @@ func TestScanGithubBranchProtection(t *testing.T) { "MDIwOkJyYW5jaFByb3RlY3Rpb25SdWxlMTk1NDg0Nzc=", // "repo2:toto" }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 6) + + assert.Equal(t, "MDIwOkJyYW5jaFByb3RlY3Rpb25SdWxlMTk1NDg0NzI=", got[0].ResourceId()) + assert.Equal(t, githubres.GithubBranchProtectionResourceType, got[0].ResourceType()) + + assert.Equal(t, "MDIwOkJyYW5jaFByb3RlY3Rpb25SdWxlMTk1NDg0Nzc=", got[5].ResourceId()) + assert.Equal(t, githubres.GithubBranchProtectionResourceType, got[5].ResourceType()) + }, err: nil, }, { @@ -63,19 +74,19 @@ func TestScanGithubBranchProtection(t *testing.T) { alerter.On("SendAlert", githubres.GithubBranchProtectionResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteGithubTerraform, remoteerr.NewResourceListingErrorWithType(errors.New("Your token has not been granted the required scopes to execute this query."), githubres.GithubBranchProtectionResourceType, githubres.GithubBranchProtectionResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} - providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -103,18 +114,18 @@ func TestScanGithubBranchProtection(t *testing.T) { } remoteLibrary.AddEnumerator(github.NewGithubBranchProtectionEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(githubres.GithubBranchProtectionResourceType, common.NewGenericDetailsFetcher(githubres.GithubBranchProtectionResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.err) if err != nil { return } - test.TestAgainstGoldenFile(got, githubres.GithubBranchProtectionResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) mockedRepo.AssertExpectations(tt) alerter.AssertExpectations(tt) }) diff --git a/enumeration/remote/github_membership_scanner_test.go b/enumeration/remote/github_membership_scanner_test.go index 9a4d28433..ec322bb13 100644 --- a/enumeration/remote/github_membership_scanner_test.go +++ b/enumeration/remote/github_membership_scanner_test.go @@ -19,18 +19,17 @@ import ( "github.com/stretchr/testify/mock" "github.com/snyk/driftctl/enumeration/resource" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" "github.com/stretchr/testify/assert" ) func TestScanGithubMembership(t *testing.T) { - cases := []struct { - test string - dirName string - mocks func(*github.MockGithubRepository, *mocks.AlerterInterface) - err error + test string + dirName string + mocks func(*github.MockGithubRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + err error }{ { test: "no members", @@ -38,6 +37,9 @@ func TestScanGithubMembership(t *testing.T) { mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { client.On("ListMembership").Return([]string{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, { @@ -49,6 +51,15 @@ func TestScanGithubMembership(t *testing.T) { "driftctl-test:eliecharra", }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "driftctl-test:driftctl-acceptance-tester", got[0].ResourceId()) + assert.Equal(t, githubres.GithubMembershipResourceType, got[0].ResourceType()) + + assert.Equal(t, "driftctl-test:eliecharra", got[1].ResourceId()) + assert.Equal(t, githubres.GithubMembershipResourceType, got[1].ResourceType()) + }, err: nil, }, { @@ -59,19 +70,19 @@ func TestScanGithubMembership(t *testing.T) { alerter.On("SendAlert", githubres.GithubMembershipResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteGithubTerraform, remoteerr.NewResourceListingErrorWithType(errors.New("Your token has not been granted the required scopes to execute this query."), githubres.GithubMembershipResourceType, githubres.GithubMembershipResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} - providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -99,18 +110,18 @@ func TestScanGithubMembership(t *testing.T) { } remoteLibrary.AddEnumerator(github.NewGithubMembershipEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(githubres.GithubMembershipResourceType, common.NewGenericDetailsFetcher(githubres.GithubMembershipResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.err) if err != nil { return } - test.TestAgainstGoldenFile(got, githubres.GithubMembershipResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) mockedRepo.AssertExpectations(tt) alerter.AssertExpectations(tt) }) diff --git a/enumeration/remote/github_repository_scanner_test.go b/enumeration/remote/github_repository_scanner_test.go index 76e5aea4e..9cb86a950 100644 --- a/enumeration/remote/github_repository_scanner_test.go +++ b/enumeration/remote/github_repository_scanner_test.go @@ -19,18 +19,17 @@ import ( "github.com/stretchr/testify/mock" "github.com/snyk/driftctl/enumeration/resource" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" "github.com/stretchr/testify/assert" ) func TestScanGithubRepository(t *testing.T) { - tests := []struct { - test string - dirName string - mocks func(*github.MockGithubRepository, *mocks.AlerterInterface) - err error + test string + dirName string + mocks func(*github.MockGithubRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + err error }{ { test: "no github repos", @@ -38,6 +37,9 @@ func TestScanGithubRepository(t *testing.T) { mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { client.On("ListRepositories").Return([]string{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, { @@ -49,6 +51,15 @@ func TestScanGithubRepository(t *testing.T) { "driftctl-demos", }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "driftctl", got[0].ResourceId()) + assert.Equal(t, githubres.GithubRepositoryResourceType, got[0].ResourceType()) + + assert.Equal(t, "driftctl-demos", got[1].ResourceId()) + assert.Equal(t, githubres.GithubRepositoryResourceType, got[1].ResourceType()) + }, err: nil, }, { @@ -59,19 +70,19 @@ func TestScanGithubRepository(t *testing.T) { alerter.On("SendAlert", githubres.GithubRepositoryResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteGithubTerraform, remoteerr.NewResourceListingErrorWithType(errors.New("Your token has not been granted the required scopes to execute this query."), githubres.GithubRepositoryResourceType, githubres.GithubRepositoryResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} - providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -99,18 +110,18 @@ func TestScanGithubRepository(t *testing.T) { } remoteLibrary.AddEnumerator(github.NewGithubRepositoryEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(githubres.GithubRepositoryResourceType, common.NewGenericDetailsFetcher(githubres.GithubRepositoryResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.err) if err != nil { return } - test.TestAgainstGoldenFile(got, githubres.GithubRepositoryResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) mockedRepo.AssertExpectations(tt) alerter.AssertExpectations(tt) }) diff --git a/enumeration/remote/github_team_membership_scanner_test.go b/enumeration/remote/github_team_membership_scanner_test.go index 37de03c24..af11f168d 100644 --- a/enumeration/remote/github_team_membership_scanner_test.go +++ b/enumeration/remote/github_team_membership_scanner_test.go @@ -19,18 +19,17 @@ import ( "github.com/stretchr/testify/mock" "github.com/snyk/driftctl/enumeration/resource" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" "github.com/stretchr/testify/assert" ) func TestScanGithubTeamMembership(t *testing.T) { - cases := []struct { - test string - dirName string - mocks func(*github.MockGithubRepository, *mocks.AlerterInterface) - err error + test string + dirName string + mocks func(*github.MockGithubRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + err error }{ { test: "no github team memberships", @@ -38,6 +37,9 @@ func TestScanGithubTeamMembership(t *testing.T) { mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { client.On("ListTeamMemberships").Return([]string{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, { @@ -49,6 +51,15 @@ func TestScanGithubTeamMembership(t *testing.T) { "4570529:wbeuil", }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "4570529:driftctl-acceptance-tester", got[0].ResourceId()) + assert.Equal(t, githubres.GithubTeamMembershipResourceType, got[0].ResourceType()) + + assert.Equal(t, "4570529:wbeuil", got[1].ResourceId()) + assert.Equal(t, githubres.GithubTeamMembershipResourceType, got[1].ResourceType()) + }, err: nil, }, { @@ -59,19 +70,19 @@ func TestScanGithubTeamMembership(t *testing.T) { alerter.On("SendAlert", githubres.GithubTeamMembershipResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteGithubTerraform, remoteerr.NewResourceListingErrorWithType(errors.New("Your token has not been granted the required scopes to execute this query."), githubres.GithubTeamMembershipResourceType, githubres.GithubTeamMembershipResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} - providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -99,18 +110,18 @@ func TestScanGithubTeamMembership(t *testing.T) { } remoteLibrary.AddEnumerator(github.NewGithubTeamMembershipEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(githubres.GithubTeamMembershipResourceType, common.NewGenericDetailsFetcher(githubres.GithubTeamMembershipResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.err) if err != nil { return } - test.TestAgainstGoldenFile(got, githubres.GithubTeamMembershipResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) mockedRepo.AssertExpectations(tt) alerter.AssertExpectations(tt) }) diff --git a/enumeration/remote/github_team_scanner_test.go b/enumeration/remote/github_team_scanner_test.go index 249722b88..214729265 100644 --- a/enumeration/remote/github_team_scanner_test.go +++ b/enumeration/remote/github_team_scanner_test.go @@ -19,18 +19,17 @@ import ( "github.com/stretchr/testify/mock" "github.com/snyk/driftctl/enumeration/resource" - "github.com/snyk/driftctl/test" "github.com/snyk/driftctl/test/goldenfile" "github.com/stretchr/testify/assert" ) func TestScanGithubTeam(t *testing.T) { - tests := []struct { - test string - dirName string - mocks func(*github.MockGithubRepository, *mocks.AlerterInterface) - err error + test string + dirName string + mocks func(*github.MockGithubRepository, *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) + err error }{ { test: "no github teams", @@ -38,6 +37,9 @@ func TestScanGithubTeam(t *testing.T) { mocks: func(client *github.MockGithubRepository, alerter *mocks.AlerterInterface) { client.On("ListTeams").Return([]github.Team{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, { @@ -50,6 +52,18 @@ func TestScanGithubTeam(t *testing.T) { {DatabaseId: 4556814}, // github_team.with_parent }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "4556811", got[0].ResourceId()) + assert.Equal(t, githubres.GithubTeamResourceType, got[0].ResourceType()) + + assert.Equal(t, "4556812", got[1].ResourceId()) + assert.Equal(t, githubres.GithubTeamResourceType, got[1].ResourceType()) + + assert.Equal(t, "4556814", got[2].ResourceId()) + assert.Equal(t, githubres.GithubTeamResourceType, got[2].ResourceType()) + }, err: nil, }, { @@ -60,19 +74,19 @@ func TestScanGithubTeam(t *testing.T) { alerter.On("SendAlert", githubres.GithubTeamResourceType, alerts.NewRemoteAccessDeniedAlert(common.RemoteGithubTerraform, remoteerr.NewResourceListingErrorWithType(errors.New("Your token has not been granted the required scopes to execute this query."), githubres.GithubTeamResourceType, githubres.GithubTeamResourceType), alerts.EnumerationPhase)).Return() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, err: nil, }, } factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range tests { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} - providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -100,18 +114,18 @@ func TestScanGithubTeam(t *testing.T) { } remoteLibrary.AddEnumerator(github.NewGithubTeamEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(githubres.GithubTeamResourceType, common.NewGenericDetailsFetcher(githubres.GithubTeamResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.err) if err != nil { return } - test.TestAgainstGoldenFile(got, githubres.GithubTeamResourceType, c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) mockedRepo.AssertExpectations(tt) alerter.AssertExpectations(tt) }) diff --git a/enumeration/remote/google/init.go b/enumeration/remote/google/init.go index 3c81fa4fd..30fb0c223 100644 --- a/enumeration/remote/google/init.go +++ b/enumeration/remote/google/init.go @@ -14,7 +14,6 @@ import ( asset "cloud.google.com/go/asset/apiv1" "cloud.google.com/go/storage" "github.com/snyk/driftctl/enumeration/resource" - "github.com/snyk/driftctl/enumeration/resource/google" "google.golang.org/api/cloudresourcemanager/v1" ) @@ -58,34 +57,26 @@ func Init(version string, alerter alerter.AlerterInterface, providerLibrary *ter iamRepository := repository.NewCloudResourceManagerRepository(crmService, provider.GetConfig(), repositoryCache) providerLibrary.AddProvider(terraform.GOOGLE, provider) - deserializer := resource.NewDeserializer(factory) remoteLibrary.AddEnumerator(NewGoogleStorageBucketEnumerator(assetRepository, factory)) - remoteLibrary.AddDetailsFetcher(google.GoogleStorageBucketResourceType, common.NewGenericDetailsFetcher(google.GoogleStorageBucketResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewGoogleComputeFirewallEnumerator(assetRepository, factory)) - remoteLibrary.AddDetailsFetcher(google.GoogleComputeFirewallResourceType, common.NewGenericDetailsFetcher(google.GoogleComputeFirewallResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewGoogleComputeRouterEnumerator(assetRepository, factory)) remoteLibrary.AddEnumerator(NewGoogleComputeInstanceEnumerator(assetRepository, factory)) remoteLibrary.AddEnumerator(NewGoogleProjectIamMemberEnumerator(iamRepository, factory)) - remoteLibrary.AddDetailsFetcher(google.GoogleProjectIamMemberResourceType, common.NewGenericDetailsFetcher(google.GoogleProjectIamMemberResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewGoogleStorageBucketIamMemberEnumerator(assetRepository, storageRepository, factory)) - remoteLibrary.AddDetailsFetcher(google.GoogleStorageBucketIamMemberResourceType, common.NewGenericDetailsFetcher(google.GoogleStorageBucketIamMemberResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewGoogleComputeNetworkEnumerator(assetRepository, factory)) - remoteLibrary.AddDetailsFetcher(google.GoogleComputeNetworkResourceType, common.NewGenericDetailsFetcher(google.GoogleComputeNetworkResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewGoogleComputeSubnetworkEnumerator(assetRepository, factory)) - remoteLibrary.AddDetailsFetcher(google.GoogleComputeSubnetworkResourceType, common.NewGenericDetailsFetcher(google.GoogleComputeSubnetworkResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewGoogleDNSManagedZoneEnumerator(assetRepository, factory)) remoteLibrary.AddEnumerator(NewGoogleComputeInstanceGroupEnumerator(assetRepository, factory)) - remoteLibrary.AddDetailsFetcher(google.GoogleComputeInstanceGroupResourceType, common.NewGenericDetailsFetcher(google.GoogleComputeInstanceGroupResourceType, provider, deserializer)) remoteLibrary.AddEnumerator(NewGoogleBigqueryDatasetEnumerator(assetRepository, factory)) remoteLibrary.AddEnumerator(NewGoogleBigqueryTableEnumerator(assetRepository, factory)) diff --git a/enumeration/remote/google/repository/asset.go b/enumeration/remote/google/repository/asset.go index 0357f9f07..59d93f1cf 100644 --- a/enumeration/remote/google/repository/asset.go +++ b/enumeration/remote/google/repository/asset.go @@ -5,10 +5,10 @@ import ( "fmt" asset "cloud.google.com/go/asset/apiv1" + assetpb "cloud.google.com/go/asset/apiv1/assetpb" "github.com/snyk/driftctl/enumeration/remote/cache" "github.com/snyk/driftctl/enumeration/remote/google/config" "google.golang.org/api/iterator" - assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1" ) // https://cloud.google.com/asset-inventory/docs/supported-asset-types#supported_resource_types diff --git a/enumeration/remote/google/repository/asset_test.go b/enumeration/remote/google/repository/asset_test.go index 8c5ec92dd..65d3bda4c 100644 --- a/enumeration/remote/google/repository/asset_test.go +++ b/enumeration/remote/google/repository/asset_test.go @@ -3,12 +3,12 @@ package repository import ( "testing" + assetpb "cloud.google.com/go/asset/apiv1/assetpb" "github.com/snyk/driftctl/enumeration/remote/cache" "github.com/snyk/driftctl/enumeration/remote/google/config" "github.com/snyk/driftctl/test/google" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1" ) func Test_assetRepository_searchAllResources_CacheHit(t *testing.T) { diff --git a/enumeration/remote/google_bigquery_scanner_test.go b/enumeration/remote/google_bigquery_scanner_test.go index 1cc44d3c1..6fa82154d 100644 --- a/enumeration/remote/google_bigquery_scanner_test.go +++ b/enumeration/remote/google_bigquery_scanner_test.go @@ -17,10 +17,10 @@ import ( testgoogle "github.com/snyk/driftctl/test/google" + assetpb "cloud.google.com/go/asset/apiv1/assetpb" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -83,7 +83,6 @@ func TestGoogleBigqueryDataset(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -110,7 +109,7 @@ func TestGoogleBigqueryDataset(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -119,7 +118,7 @@ func TestGoogleBigqueryDataset(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } @@ -183,7 +182,6 @@ func TestGoogleBigqueryTable(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -210,7 +208,7 @@ func TestGoogleBigqueryTable(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -219,7 +217,7 @@ func TestGoogleBigqueryTable(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } diff --git a/enumeration/remote/google_bigtable_scanner_test.go b/enumeration/remote/google_bigtable_scanner_test.go index ebbd84c7e..0d6e74016 100644 --- a/enumeration/remote/google_bigtable_scanner_test.go +++ b/enumeration/remote/google_bigtable_scanner_test.go @@ -17,10 +17,10 @@ import ( testgoogle "github.com/snyk/driftctl/test/google" + assetpb "cloud.google.com/go/asset/apiv1/assetpb" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/structpb" @@ -120,7 +120,6 @@ func TestGoogleBigtableInstance(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -147,7 +146,7 @@ func TestGoogleBigtableInstance(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -156,7 +155,7 @@ func TestGoogleBigtableInstance(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } @@ -243,7 +242,6 @@ func TestGoogleBigtableTable(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -270,7 +268,7 @@ func TestGoogleBigtableTable(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -279,7 +277,7 @@ func TestGoogleBigtableTable(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } diff --git a/enumeration/remote/google_cloudfunctions_scanner_test.go b/enumeration/remote/google_cloudfunctions_scanner_test.go index 0dd531457..c6923243c 100644 --- a/enumeration/remote/google_cloudfunctions_scanner_test.go +++ b/enumeration/remote/google_cloudfunctions_scanner_test.go @@ -17,10 +17,10 @@ import ( testgoogle "github.com/snyk/driftctl/test/google" + assetpb "cloud.google.com/go/asset/apiv1/assetpb" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/structpb" @@ -107,7 +107,6 @@ func TestGoogleCloudFunctionsFunction(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -134,7 +133,7 @@ func TestGoogleCloudFunctionsFunction(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -143,7 +142,7 @@ func TestGoogleCloudFunctionsFunction(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } diff --git a/enumeration/remote/google_cloudrun_scanner_test.go b/enumeration/remote/google_cloudrun_scanner_test.go index 37726a807..212e03689 100644 --- a/enumeration/remote/google_cloudrun_scanner_test.go +++ b/enumeration/remote/google_cloudrun_scanner_test.go @@ -18,10 +18,10 @@ import ( testgoogle "github.com/snyk/driftctl/test/google" + assetpb "cloud.google.com/go/asset/apiv1/assetpb" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -103,7 +103,6 @@ func TestGoogleCloudRunService(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -130,7 +129,7 @@ func TestGoogleCloudRunService(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -140,7 +139,7 @@ func TestGoogleCloudRunService(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } diff --git a/enumeration/remote/google_compute_scanner_test.go b/enumeration/remote/google_compute_scanner_test.go index 58bfe1d74..015af20a7 100644 --- a/enumeration/remote/google_compute_scanner_test.go +++ b/enumeration/remote/google_compute_scanner_test.go @@ -3,8 +3,6 @@ package remote import ( "testing" - resource2 "github.com/snyk/driftctl/pkg/resource" - "github.com/snyk/driftctl/enumeration" "github.com/snyk/driftctl/enumeration/remote/alerts" "github.com/snyk/driftctl/enumeration/remote/cache" @@ -18,33 +16,35 @@ import ( googleresource "github.com/snyk/driftctl/enumeration/resource/google" "github.com/snyk/driftctl/mocks" - "github.com/snyk/driftctl/test" + assetpb "cloud.google.com/go/asset/apiv1/assetpb" "github.com/snyk/driftctl/test/goldenfile" testgoogle "github.com/snyk/driftctl/test/google" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/structpb" ) func TestGoogleComputeFirewall(t *testing.T) { - cases := []struct { test string dirName string response []*assetpb.ResourceSearchResult responseErr error setupAlerterMock func(alerter *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) wantErr error }{ { test: "no compute firewall", dirName: "google_compute_firewall_empty", response: []*assetpb.ResourceSearchResult{}, - wantErr: nil, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, + wantErr: nil, }, { test: "multiples compute firewall", @@ -66,6 +66,18 @@ func TestGoogleComputeFirewall(t *testing.T) { Name: "//compute.googleapis.com/projects/cloudskiff-dev-elie/global/firewalls/test-firewall-2", }, }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "projects/cloudskiff-dev-elie/global/firewalls/test-firewall-0", got[0].ResourceId()) + assert.Equal(t, googleresource.GoogleComputeFirewallResourceType, got[0].ResourceType()) + + assert.Equal(t, "projects/cloudskiff-dev-elie/global/firewalls/test-firewall-1", got[1].ResourceId()) + assert.Equal(t, googleresource.GoogleComputeFirewallResourceType, got[1].ResourceType()) + + assert.Equal(t, "projects/cloudskiff-dev-elie/global/firewalls/test-firewall-2", got[2].ResourceId()) + assert.Equal(t, googleresource.GoogleComputeFirewallResourceType, got[2].ResourceType()) + }, wantErr: nil, }, { @@ -86,19 +98,19 @@ func TestGoogleComputeFirewall(t *testing.T) { ), ).Once() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } - resType := resource.ResourceType(googleresource.GoogleComputeFirewallResourceType) factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -132,12 +144,11 @@ func TestGoogleComputeFirewall(t *testing.T) { repo := repository.NewAssetRepository(assetClient, realProvider.GetConfig(), cache.New(0)) remoteLibrary.AddEnumerator(google.NewGoogleComputeFirewallEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resType, common.NewGenericDetailsFetcher(resType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -145,13 +156,12 @@ func TestGoogleComputeFirewall(t *testing.T) { } alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) - test.TestAgainstGoldenFile(got, resType.String(), c.dirName, provider, deserializer, shouldUpdate, tt) + c.assertExpected(tt, got) }) } } func TestGoogleComputeRouter(t *testing.T) { - cases := []struct { test string response []*assetpb.ResourceSearchResult @@ -229,7 +239,6 @@ func TestGoogleComputeRouter(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -256,7 +265,7 @@ func TestGoogleComputeRouter(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -266,14 +275,13 @@ func TestGoogleComputeRouter(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } } func TestGoogleComputeInstance(t *testing.T) { - cases := []struct { test string assertExpected func(t *testing.T, got []*resource.Resource) @@ -330,7 +338,6 @@ func TestGoogleComputeInstance(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -357,7 +364,7 @@ func TestGoogleComputeInstance(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -366,27 +373,30 @@ func TestGoogleComputeInstance(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } } func TestGoogleComputeNetwork(t *testing.T) { - cases := []struct { test string dirName string response []*assetpb.ResourceSearchResult responseErr error setupAlerterMock func(alerter *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) wantErr error }{ { test: "no network", dirName: "google_compute_network_empty", response: []*assetpb.ResourceSearchResult{}, - wantErr: nil, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, + wantErr: nil, }, { test: "multiple networks", @@ -408,6 +418,18 @@ func TestGoogleComputeNetwork(t *testing.T) { Name: "//compute.googleapis.com/projects/driftctl-qa-1/global/networks/driftctl-unittest-3", }, }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "projects/driftctl-qa-1/global/networks/driftctl-unittest-1", got[0].ResourceId()) + assert.Equal(t, googleresource.GoogleComputeNetworkResourceType, got[0].ResourceType()) + + assert.Equal(t, "projects/driftctl-qa-1/global/networks/driftctl-unittest-2", got[1].ResourceId()) + assert.Equal(t, googleresource.GoogleComputeNetworkResourceType, got[1].ResourceType()) + + assert.Equal(t, "projects/driftctl-qa-1/global/networks/driftctl-unittest-3", got[2].ResourceId()) + assert.Equal(t, googleresource.GoogleComputeNetworkResourceType, got[2].ResourceType()) + }, wantErr: nil, }, { @@ -428,19 +450,19 @@ func TestGoogleComputeNetwork(t *testing.T) { ), ).Once() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } - resType := resource.ResourceType(googleresource.GoogleComputeNetworkResourceType) factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -474,12 +496,11 @@ func TestGoogleComputeNetwork(t *testing.T) { repo := repository.NewAssetRepository(assetClient, realProvider.GetConfig(), cache.New(0)) remoteLibrary.AddEnumerator(google.NewGoogleComputeNetworkEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resType, common.NewGenericDetailsFetcher(resType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -487,26 +508,30 @@ func TestGoogleComputeNetwork(t *testing.T) { } alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) - test.TestAgainstGoldenFile(got, resType.String(), c.dirName, provider, deserializer, shouldUpdate, tt) + + c.assertExpected(tt, got) }) } } func TestGoogleComputeInstanceGroup(t *testing.T) { - cases := []struct { test string dirName string response []*assetpb.ResourceSearchResult responseErr error setupAlerterMock func(alerter *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) wantErr error }{ { test: "no instance group", dirName: "google_compute_instance_group_empty", response: []*assetpb.ResourceSearchResult{}, - wantErr: nil, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, + wantErr: nil, }, { test: "multiple instance groups", @@ -527,6 +552,15 @@ func TestGoogleComputeInstanceGroup(t *testing.T) { Location: "us-central1-a", }, }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + + assert.Equal(t, "projects/cloudskiff-dev-raphael/zones/us-central1-a/instanceGroups/driftctl-test-1", got[0].ResourceId()) + assert.Equal(t, googleresource.GoogleComputeInstanceGroupResourceType, got[0].ResourceType()) + + assert.Equal(t, "projects/cloudskiff-dev-raphael/zones/us-central1-a/instanceGroups/driftctl-test-2", got[1].ResourceId()) + assert.Equal(t, googleresource.GoogleComputeInstanceGroupResourceType, got[1].ResourceType()) + }, wantErr: nil, }, { @@ -547,19 +581,19 @@ func TestGoogleComputeInstanceGroup(t *testing.T) { ), ).Once() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } - resType := resource2.ResourceType(googleresource.GoogleComputeInstanceGroupResourceType) factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -593,12 +627,11 @@ func TestGoogleComputeInstanceGroup(t *testing.T) { repo := repository.NewAssetRepository(assetClient, realProvider.GetConfig(), cache.New(0)) remoteLibrary.AddEnumerator(google.NewGoogleComputeInstanceGroupEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(googleresource.GoogleComputeInstanceGroupResourceType, common.NewGenericDetailsFetcher(googleresource.GoogleComputeInstanceGroupResourceType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -607,13 +640,12 @@ func TestGoogleComputeInstanceGroup(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) - test.TestAgainstGoldenFile(got, resType.String(), c.dirName, provider, deserializer, shouldUpdate, tt) + c.assertExpected(tt, got) }) } } func TestGoogleComputeAddress(t *testing.T) { - cases := []struct { test string assertExpected func(t *testing.T, got []*resource.Resource) @@ -688,7 +720,6 @@ func TestGoogleComputeAddress(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -715,7 +746,7 @@ func TestGoogleComputeAddress(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -724,14 +755,13 @@ func TestGoogleComputeAddress(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } } func TestGoogleComputeGlobalAddress(t *testing.T) { - cases := []struct { test string assertExpected func(t *testing.T, got []*resource.Resource) @@ -811,7 +841,6 @@ func TestGoogleComputeGlobalAddress(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -838,7 +867,7 @@ func TestGoogleComputeGlobalAddress(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -847,27 +876,30 @@ func TestGoogleComputeGlobalAddress(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } } func TestGoogleComputeSubnetwork(t *testing.T) { - cases := []struct { test string dirName string response []*assetpb.ResourceSearchResult responseErr error setupAlerterMock func(alerter *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) wantErr error }{ { test: "no subnetwork", dirName: "google_compute_subnetwork_empty", response: []*assetpb.ResourceSearchResult{}, - wantErr: nil, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, + wantErr: nil, }, { test: "multiple subnetworks", @@ -889,6 +921,18 @@ func TestGoogleComputeSubnetwork(t *testing.T) { Name: "//compute.googleapis.com/projects/cloudskiff-dev-raphael/regions/us-central1/subnetworks/driftctl-unittest-3", }, }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "projects/cloudskiff-dev-raphael/regions/us-central1/subnetworks/driftctl-unittest-1", got[0].ResourceId()) + assert.Equal(t, googleresource.GoogleComputeSubnetworkResourceType, got[0].ResourceType()) + + assert.Equal(t, "projects/cloudskiff-dev-raphael/regions/us-central1/subnetworks/driftctl-unittest-2", got[1].ResourceId()) + assert.Equal(t, googleresource.GoogleComputeSubnetworkResourceType, got[1].ResourceType()) + + assert.Equal(t, "projects/cloudskiff-dev-raphael/regions/us-central1/subnetworks/driftctl-unittest-3", got[2].ResourceId()) + assert.Equal(t, googleresource.GoogleComputeSubnetworkResourceType, got[2].ResourceType()) + }, wantErr: nil, }, { @@ -909,19 +953,19 @@ func TestGoogleComputeSubnetwork(t *testing.T) { ), ).Once() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } - resType := resource.ResourceType(googleresource.GoogleComputeSubnetworkResourceType) factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -955,12 +999,11 @@ func TestGoogleComputeSubnetwork(t *testing.T) { repo := repository.NewAssetRepository(assetClient, realProvider.GetConfig(), cache.New(0)) remoteLibrary.AddEnumerator(google.NewGoogleComputeSubnetworkEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resType, common.NewGenericDetailsFetcher(resType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -968,13 +1011,12 @@ func TestGoogleComputeSubnetwork(t *testing.T) { } alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) - test.TestAgainstGoldenFile(got, resType.String(), c.dirName, provider, deserializer, shouldUpdate, tt) + c.assertExpected(tt, got) }) } } func TestGoogleComputeDisk(t *testing.T) { - cases := []struct { test string assertExpected func(t *testing.T, got []*resource.Resource) @@ -1038,7 +1080,6 @@ func TestGoogleComputeDisk(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1065,7 +1106,7 @@ func TestGoogleComputeDisk(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1074,14 +1115,13 @@ func TestGoogleComputeDisk(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } } func TestGoogleComputeImage(t *testing.T) { - cases := []struct { test string assertExpected func(t *testing.T, got []*resource.Resource) @@ -1145,7 +1185,6 @@ func TestGoogleComputeImage(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1172,7 +1211,7 @@ func TestGoogleComputeImage(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1181,14 +1220,13 @@ func TestGoogleComputeImage(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } } func TestGoogleComputeHealthCheck(t *testing.T) { - cases := []struct { test string assertExpected func(t *testing.T, got []*resource.Resource) @@ -1252,7 +1290,6 @@ func TestGoogleComputeHealthCheck(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1279,7 +1316,7 @@ func TestGoogleComputeHealthCheck(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1288,14 +1325,13 @@ func TestGoogleComputeHealthCheck(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } } func TestGoogleComputeNodeGroup(t *testing.T) { - cases := []struct { test string assertExpected func(t *testing.T, got []*resource.Resource) @@ -1359,7 +1395,6 @@ func TestGoogleComputeNodeGroup(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1386,7 +1421,7 @@ func TestGoogleComputeNodeGroup(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1395,7 +1430,7 @@ func TestGoogleComputeNodeGroup(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } @@ -1465,7 +1500,6 @@ func TestGoogleComputeForwardingRule(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1492,7 +1526,7 @@ func TestGoogleComputeForwardingRule(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1501,7 +1535,7 @@ func TestGoogleComputeForwardingRule(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } @@ -1571,7 +1605,6 @@ func TestGoogleComputeSslCertificate(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1598,7 +1631,7 @@ func TestGoogleComputeSslCertificate(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1607,14 +1640,13 @@ func TestGoogleComputeSslCertificate(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } } func TestGoogleComputeInstanceGroupManager(t *testing.T) { - cases := []struct { test string assertExpected func(t *testing.T, got []*resource.Resource) @@ -1678,7 +1710,6 @@ func TestGoogleComputeInstanceGroupManager(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1705,7 +1736,7 @@ func TestGoogleComputeInstanceGroupManager(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1714,7 +1745,7 @@ func TestGoogleComputeInstanceGroupManager(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } @@ -1784,7 +1815,6 @@ func TestGoogleComputeGlobalForwardingRule(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -1811,7 +1841,7 @@ func TestGoogleComputeGlobalForwardingRule(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -1820,7 +1850,7 @@ func TestGoogleComputeGlobalForwardingRule(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } diff --git a/enumeration/remote/google_network_scanner_test.go b/enumeration/remote/google_network_scanner_test.go index a6798a830..f50e6ff96 100644 --- a/enumeration/remote/google_network_scanner_test.go +++ b/enumeration/remote/google_network_scanner_test.go @@ -18,10 +18,10 @@ import ( testgoogle "github.com/snyk/driftctl/test/google" + assetpb "cloud.google.com/go/asset/apiv1/assetpb" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -109,7 +109,6 @@ func TestGoogleDNSNanagedZone(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -136,7 +135,7 @@ func TestGoogleDNSNanagedZone(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -146,7 +145,7 @@ func TestGoogleDNSNanagedZone(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } diff --git a/enumeration/remote/google_project_scanner_test.go b/enumeration/remote/google_project_scanner_test.go index 8880300fc..29f1aedbe 100644 --- a/enumeration/remote/google_project_scanner_test.go +++ b/enumeration/remote/google_project_scanner_test.go @@ -95,7 +95,6 @@ func TestGoogleProjectIAMMember(t *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -122,7 +121,7 @@ func TestGoogleProjectIAMMember(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { diff --git a/enumeration/remote/google_sql_scanner_test.go b/enumeration/remote/google_sql_scanner_test.go index 2b61ac4e0..0b427b623 100644 --- a/enumeration/remote/google_sql_scanner_test.go +++ b/enumeration/remote/google_sql_scanner_test.go @@ -17,10 +17,10 @@ import ( testgoogle "github.com/snyk/driftctl/test/google" + assetpb "cloud.google.com/go/asset/apiv1/assetpb" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/structpb" @@ -105,7 +105,6 @@ func TestGoogleSQLDatabaseInstance(t *testing.T) { for _, c := range cases { t.Run(c.test, func(tt *testing.T) { - scanOptions := ScannerOptions{} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -132,7 +131,7 @@ func TestGoogleSQLDatabaseInstance(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -141,7 +140,7 @@ func TestGoogleSQLDatabaseInstance(t *testing.T) { alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) if c.assertExpected != nil { - c.assertExpected(t, got) + c.assertExpected(tt, got) } }) } diff --git a/enumeration/remote/google_storage_scanner_test.go b/enumeration/remote/google_storage_scanner_test.go index e2e174fcd..1335937cd 100644 --- a/enumeration/remote/google_storage_scanner_test.go +++ b/enumeration/remote/google_storage_scanner_test.go @@ -11,41 +11,43 @@ import ( remoteerr "github.com/snyk/driftctl/enumeration/remote/error" "github.com/snyk/driftctl/enumeration/remote/google" "github.com/snyk/driftctl/enumeration/remote/google/repository" + googleresource "github.com/snyk/driftctl/enumeration/resource/google" "github.com/snyk/driftctl/enumeration/terraform" asset "cloud.google.com/go/asset/apiv1" "cloud.google.com/go/storage" "github.com/pkg/errors" "github.com/snyk/driftctl/enumeration/resource" - googleresource "github.com/snyk/driftctl/enumeration/resource/google" "github.com/snyk/driftctl/mocks" - "github.com/snyk/driftctl/test" + assetpb "cloud.google.com/go/asset/apiv1/assetpb" "github.com/snyk/driftctl/test/goldenfile" testgoogle "github.com/snyk/driftctl/test/google" terraform2 "github.com/snyk/driftctl/test/terraform" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestGoogleStorageBucket(t *testing.T) { - cases := []struct { test string dirName string response []*assetpb.ResourceSearchResult responseErr error setupAlerterMock func(alerter *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) wantErr error }{ { test: "no storage buckets", dirName: "google_storage_bucket_empty", response: []*assetpb.ResourceSearchResult{}, - wantErr: nil, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, + wantErr: nil, }, { test: "multiples storage buckets", @@ -64,6 +66,18 @@ func TestGoogleStorageBucket(t *testing.T) { DisplayName: "driftctl-unittest-3", }, }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 3) + + assert.Equal(t, "driftctl-unittest-1", got[0].ResourceId()) + assert.Equal(t, googleresource.GoogleStorageBucketResourceType, got[0].ResourceType()) + + assert.Equal(t, "driftctl-unittest-2", got[1].ResourceId()) + assert.Equal(t, googleresource.GoogleStorageBucketResourceType, got[1].ResourceType()) + + assert.Equal(t, "driftctl-unittest-3", got[2].ResourceId()) + assert.Equal(t, googleresource.GoogleStorageBucketResourceType, got[2].ResourceType()) + }, wantErr: nil, }, { @@ -84,19 +98,19 @@ func TestGoogleStorageBucket(t *testing.T) { ), ).Once() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, } - resType := resource.ResourceType(googleresource.GoogleStorageBucketResourceType) factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -139,12 +153,11 @@ func TestGoogleStorageBucket(t *testing.T) { repo := repository.NewAssetRepository(assetClient, realProvider.GetConfig(), cache.New(0)) remoteLibrary.AddEnumerator(google.NewGoogleStorageBucketEnumerator(repo, factory)) - remoteLibrary.AddDetailsFetcher(resType, common.NewGenericDetailsFetcher(resType, provider, deserializer)) testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, err, c.wantErr) if err != nil { @@ -152,13 +165,12 @@ func TestGoogleStorageBucket(t *testing.T) { } alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) - test.TestAgainstGoldenFile(got, resType.String(), c.dirName, provider, deserializer, shouldUpdate, tt) + c.assertExpected(tt, got) }) } } func TestGoogleStorageBucketIAMMember(t *testing.T) { - cases := []struct { test string dirName string @@ -166,6 +178,7 @@ func TestGoogleStorageBucketIAMMember(t *testing.T) { storageRepositoryMock func(storageRepository *repository.MockStorageRepository) responseErr error setupAlerterMock func(alerter *mocks.AlerterInterface) + assertExpected func(*testing.T, []*resource.Resource) wantErr error }{ { @@ -174,6 +187,9 @@ func TestGoogleStorageBucketIAMMember(t *testing.T) { assetRepositoryMock: func(assetRepository *repository.MockAssetRepository) { assetRepository.On("SearchAllBuckets").Return([]*assetpb.ResourceSearchResult{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -195,6 +211,9 @@ func TestGoogleStorageBucketIAMMember(t *testing.T) { storageRepository.On("ListAllBindings", "dctlgstoragebucketiambinding-1").Return(map[string][]string{}, nil) storageRepository.On("ListAllBindings", "dctlgstoragebucketiambinding-2").Return(map[string][]string{}, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -227,6 +246,9 @@ func TestGoogleStorageBucketIAMMember(t *testing.T) { ), ).Once() }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, wantErr: nil, }, { @@ -255,13 +277,25 @@ func TestGoogleStorageBucketIAMMember(t *testing.T) { "roles/storage.objectViewer": {"user:elie.charra@cloudskiff.com"}, }, nil) }, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 4) + + var resourceIds []string + for _, res := range got { + assert.Equal(t, googleresource.GoogleStorageBucketIamMemberResourceType, res.ResourceType()) + resourceIds = append(resourceIds, res.ResourceId()) + } + + assert.Contains(t, resourceIds, "b/dctlgstoragebucketiambinding-1/roles/storage.admin/user:elie.charra@cloudskiff.com") + assert.Contains(t, resourceIds, "b/dctlgstoragebucketiambinding-1/roles/storage.objectViewer/user:william.beuil@cloudskiff.com") + assert.Contains(t, resourceIds, "b/dctlgstoragebucketiambinding-2/roles/storage.admin/user:william.beuil@cloudskiff.com") + assert.Contains(t, resourceIds, "b/dctlgstoragebucketiambinding-2/roles/storage.admin/user:william.beuil@cloudskiff.com") + }, wantErr: nil, }, } - resType := resource.ResourceType(googleresource.GoogleStorageBucketIamMemberResourceType) factory := terraform.NewTerraformResourceFactory() - deserializer := resource.NewDeserializer(factory) for _, c := range cases { t.Run(c.test, func(tt *testing.T) { @@ -269,7 +303,6 @@ func TestGoogleStorageBucketIAMMember(t *testing.T) { shouldUpdate := c.dirName == *goldenfile.Update - scanOptions := ScannerOptions{Deep: true} providerLibrary := terraform.NewProviderLibrary() remoteLibrary := common.NewRemoteLibrary() @@ -310,7 +343,7 @@ func TestGoogleStorageBucketIAMMember(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", mock.Anything).Return(false) - s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) got, err := s.Resources() assert.Equal(tt, c.wantErr, err) if err != nil { @@ -318,7 +351,7 @@ func TestGoogleStorageBucketIAMMember(t *testing.T) { } alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) - test.TestAgainstGoldenFileNoCty(got, resType.String(), c.dirName, provider, deserializer, shouldUpdate, tt) + c.assertExpected(tt, got) }) } } diff --git a/enumeration/remote/resource_enumeration_error_handler.go b/enumeration/remote/resource_enumeration_error_handler.go index c2d09274a..8146398b0 100644 --- a/enumeration/remote/resource_enumeration_error_handler.go +++ b/enumeration/remote/resource_enumeration_error_handler.go @@ -58,31 +58,6 @@ func HandleResourceEnumerationError(err error, alerter alerter.AlerterInterface) return err } -func HandleResourceDetailsFetchingError(err error, alerter alerter.AlerterInterface) error { - listError, ok := err.(*remoteerror.ResourceScanningError) - if !ok { - return err - } - - rootCause := listError.RootCause() - - if shouldHandleGoogleForbiddenError(listError) { - alerts.SendDetailsFetchingAlert(common.RemoteGoogleTerraform, alerter, listError) - return nil - } - - // This handles access denied errors like the following: - // iam_role_policy: error reading IAM Role Policy (): AccessDenied: User: ... - if strings.HasPrefix(rootCause.Error(), "AccessDeniedException") || - strings.Contains(rootCause.Error(), "AccessDenied") || - strings.Contains(rootCause.Error(), "AuthorizationError") { - alerts.SendDetailsFetchingAlert(common.RemoteAWSTerraform, alerter, listError) - return nil - } - - return err -} - func handleAWSError(alerter alerter.AlerterInterface, listError *remoteerror.ResourceScanningError, reqerr awserr.RequestFailure) error { if reqerr.StatusCode() == 403 || (reqerr.StatusCode() == 400 && strings.Contains(reqerr.Code(), "AccessDenied")) { alerts.SendEnumerationAlert(common.RemoteAWSTerraform, alerter, listError) diff --git a/enumeration/remote/resource_enumeration_error_handler_test.go b/enumeration/remote/resource_enumeration_error_handler_test.go index b84101e15..6a0f42cff 100644 --- a/enumeration/remote/resource_enumeration_error_handler_test.go +++ b/enumeration/remote/resource_enumeration_error_handler_test.go @@ -162,114 +162,6 @@ func TestHandleGoogleEnumerationErrors(t *testing.T) { } } -func TestHandleAwsDetailsFetchingErrors(t *testing.T) { - - tests := []struct { - name string - err error - wantAlerts alerter.Alerts - wantErr bool - }{ - { - name: "Handle AccessDeniedException error", - err: remoteerr.NewResourceListingError(awserr.NewRequestFailure(awserr.New("AccessDeniedException", "test", errors.New("")), 403, ""), resourceaws.AwsVpcResourceType), - wantAlerts: alerter.Alerts{"aws_vpc": []alerter.Alert{alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awserr.NewRequestFailure(awserr.New("AccessDeniedException", "test", errors.New("")), 403, ""), "aws_vpc", "aws_vpc"), alerts.DetailsFetchingPhase)}}, - wantErr: false, - }, - { - name: "Handle AccessDenied error", - err: remoteerr.NewResourceListingError(awserr.NewRequestFailure(awserr.New("test", "error: AccessDenied", errors.New("")), 403, ""), resourceaws.AwsVpcResourceType), - wantAlerts: alerter.Alerts{"aws_vpc": []alerter.Alert{alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awserr.NewRequestFailure(awserr.New("test", "error: AccessDenied", errors.New("")), 403, ""), "aws_vpc", "aws_vpc"), alerts.DetailsFetchingPhase)}}, - wantErr: false, - }, - { - name: "Handle AuthorizationError error", - err: remoteerr.NewResourceListingError(awserr.NewRequestFailure(awserr.New("test", "error: AuthorizationError", errors.New("")), 403, ""), resourceaws.AwsVpcResourceType), - wantAlerts: alerter.Alerts{"aws_vpc": []alerter.Alert{alerts.NewRemoteAccessDeniedAlert(common.RemoteAWSTerraform, remoteerr.NewResourceListingErrorWithType(awserr.NewRequestFailure(awserr.New("test", "error: AuthorizationError", errors.New("")), 403, ""), "aws_vpc", "aws_vpc"), alerts.DetailsFetchingPhase)}}, - wantErr: false, - }, - { - name: "Unhandled error", - err: remoteerr.NewResourceListingError(awserr.NewRequestFailure(awserr.New("test", "error: dummy error", errors.New("")), 403, ""), resourceaws.AwsVpcResourceType), - wantAlerts: alerter.Alerts{}, - wantErr: true, - }, - { - name: "Not Handled error type", - err: errors.New("error"), - wantAlerts: map[string][]alerter.Alert{}, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - alertr := alerter.NewAlerter() - gotErr := HandleResourceDetailsFetchingError(tt.err, alertr) - assert.Equal(t, tt.wantErr, gotErr != nil) - - retrieve := alertr.Retrieve() - assert.Equal(t, tt.wantAlerts, retrieve) - - }) - } -} - -func TestHandleGoogleDetailsFetchingErrors(t *testing.T) { - - tests := []struct { - name string - err error - wantAlerts alerter.Alerts - wantErr bool - }{ - { - name: "Handle 403 error", - err: remoteerr.NewResourceScanningError( - errors.New("Error when reading or editing Storage Bucket \"driftctl-unittest-1\": googleapi: Error 403: driftctl@elie-dev.iam.gserviceaccount.com does not have storage.buckets.get access to the Google Cloud Storage bucket., forbidden"), - "google_type", - "resource_id", - ), - wantAlerts: alerter.Alerts{"google_type.resource_id": []alerter.Alert{alerts.NewRemoteAccessDeniedAlert(common.RemoteGoogleTerraform, remoteerr.NewResourceListingErrorWithType(errors.New("Error when reading or editing Storage Bucket \"driftctl-unittest-1\": googleapi: Error 403: driftctl@elie-dev.iam.gserviceaccount.com does not have storage.buckets.get access to the Google Cloud Storage bucket., forbidden"), "google_type.resource_id", "google_type"), alerts.DetailsFetchingPhase)}}, - wantErr: false, - }, - { - name: "do not handle google unrelated error", - err: remoteerr.NewResourceScanningError( - errors.New("this string does not contains g o o g l e a p i string and thus should not be matched"), - "google_type", - "resource_id", - ), wantAlerts: alerter.Alerts{}, - wantErr: true, - }, - { - name: "do not handle google error other than 403", - err: remoteerr.NewResourceScanningError( - errors.New("Error when reading or editing Storage Bucket \"driftctl-unittest-1\": googleapi: Error 404: not found"), - "google_type", - "resource_id", - ), wantAlerts: alerter.Alerts{}, - wantErr: true, - }, - { - name: "Not Handled error type", - err: errors.New("error"), - wantAlerts: map[string][]alerter.Alert{}, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - alertr := alerter.NewAlerter() - gotErr := HandleResourceDetailsFetchingError(tt.err, alertr) - assert.Equal(t, tt.wantErr, gotErr != nil) - - retrieve := alertr.Retrieve() - assert.Equal(t, tt.wantAlerts, retrieve) - - }) - } -} - func TestEnumerationAccessDeniedAlert_GetProviderMessage(t *testing.T) { tests := []struct { name string diff --git a/enumeration/remote/scanner.go b/enumeration/remote/scanner.go index 5d52a9138..7c8beb887 100644 --- a/enumeration/remote/scanner.go +++ b/enumeration/remote/scanner.go @@ -13,27 +13,19 @@ import ( "github.com/sirupsen/logrus" ) -type ScannerOptions struct { - Deep bool -} - type Scanner struct { - enumeratorRunner *parallel.ParallelRunner - detailsFetcherRunner *parallel.ParallelRunner - remoteLibrary *common.RemoteLibrary - alerter alerter.AlerterInterface - options ScannerOptions - filter enumeration.Filter + enumeratorRunner *parallel.ParallelRunner + remoteLibrary *common.RemoteLibrary + alerter alerter.AlerterInterface + filter enumeration.Filter } -func NewScanner(remoteLibrary *common.RemoteLibrary, alerter alerter.AlerterInterface, options ScannerOptions, filter enumeration.Filter) *Scanner { +func NewScanner(remoteLibrary *common.RemoteLibrary, alerter alerter.AlerterInterface, filter enumeration.Filter) *Scanner { return &Scanner{ - enumeratorRunner: parallel.NewParallelRunner(context.TODO(), 10), - detailsFetcherRunner: parallel.NewParallelRunner(context.TODO(), 10), - remoteLibrary: remoteLibrary, - alerter: alerter, - options: options, - filter: filter, + enumeratorRunner: parallel.NewParallelRunner(context.TODO(), 10), + remoteLibrary: remoteLibrary, + alerter: alerter, + filter: filter, } } @@ -95,30 +87,7 @@ func (s *Scanner) scan() ([]*resource.Resource, error) { return nil, err } - if !s.options.Deep { - return enumerationResult, nil - } - - for _, res := range enumerationResult { - res := res - s.detailsFetcherRunner.Run(func() (interface{}, error) { - fetcher := s.remoteLibrary.GetDetailsFetcher(resource.ResourceType(res.ResourceType())) - if fetcher == nil { - return []*resource.Resource{res}, nil - } - - resourceWithDetails, err := fetcher.ReadDetails(res) - if err != nil { - if err := HandleResourceDetailsFetchingError(err, s.alerter); err != nil { - return nil, err - } - return []*resource.Resource{}, nil - } - return []*resource.Resource{resourceWithDetails}, nil - }) - } - - return s.retrieveRunnerResults(s.detailsFetcherRunner) + return enumerationResult, nil } func (s *Scanner) Resources() ([]*resource.Resource, error) { @@ -132,5 +101,4 @@ func (s *Scanner) Resources() ([]*resource.Resource, error) { func (s *Scanner) Stop() { logrus.Debug("Stopping scanner") s.enumeratorRunner.Stop(errors.New("interrupted")) - s.detailsFetcherRunner.Stop(errors.New("interrupted")) } diff --git a/enumeration/remote/scanner_test.go b/enumeration/remote/scanner_test.go index b99657ea7..84f7cb200 100644 --- a/enumeration/remote/scanner_test.go +++ b/enumeration/remote/scanner_test.go @@ -26,7 +26,7 @@ func TestScannerShouldIgnoreType(t *testing.T) { testFilter := &enumeration.MockFilter{} testFilter.On("IsTypeIgnored", resource.ResourceType("FakeType")).Return(true) - s := NewScanner(remoteLibrary, alerter, ScannerOptions{}, testFilter) + s := NewScanner(remoteLibrary, alerter, testFilter) _, err := s.Resources() assert.Nil(t, err) fakeEnumerator.AssertExpectations(t) diff --git a/enumeration/resource/schemas.go b/enumeration/resource/schemas.go index 01d5c0390..ef5735e34 100644 --- a/enumeration/resource/schemas.go +++ b/enumeration/resource/schemas.go @@ -14,10 +14,6 @@ type AttributeSchema struct { type Flags uint32 -const ( - FlagDeepMode Flags = 1 << iota -) - func (f Flags) HasFlag(flag Flags) bool { return f&flag != 0 } diff --git a/go.mod b/go.mod index abb37a5a7..2e7f5f898 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/snyk/driftctl go 1.17 require ( - cloud.google.com/go/asset v1.8.0 - cloud.google.com/go/storage v1.27.0 + cloud.google.com/go/asset v1.13.0 + cloud.google.com/go/storage v1.29.0 github.com/Azure/azure-sdk-for-go/sdk/azcore v0.20.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.12.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute v0.2.0 @@ -35,7 +35,6 @@ require ( github.com/jarcoal/httpmock v1.0.6 github.com/jmespath/go-jmespath v0.4.0 github.com/joho/godotenv v1.3.0 - github.com/mattn/go-isatty v0.0.12 github.com/mitchellh/go-homedir v1.1.0 github.com/pkg/errors v0.9.1 github.com/r3labs/diff/v2 v2.6.0 @@ -44,22 +43,26 @@ require ( github.com/spf13/cobra v1.0.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.7.1 - github.com/stretchr/testify v1.7.0 - github.com/yudai/gojsondiff v1.0.0 + github.com/stretchr/testify v1.8.3 github.com/zclconf/go-cty v1.8.4 go.uber.org/atomic v1.4.0 - golang.org/x/oauth2 v0.1.0 + golang.org/x/oauth2 v0.7.0 golang.org/x/sync v0.1.0 - google.golang.org/api v0.100.0 - google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71 - google.golang.org/grpc v1.50.1 - google.golang.org/protobuf v1.28.1 + google.golang.org/api v0.114.0 + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 + google.golang.org/grpc v1.56.3 + google.golang.org/protobuf v1.30.0 ) require ( - cloud.google.com/go v0.104.0 // indirect - cloud.google.com/go/compute v1.10.0 // indirect - cloud.google.com/go/iam v0.5.0 // indirect + cloud.google.com/go v0.110.0 // indirect + cloud.google.com/go/accesscontextmanager v1.7.0 // indirect + cloud.google.com/go/compute v1.19.1 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/iam v0.13.0 // indirect + cloud.google.com/go/longrunning v0.4.1 // indirect + cloud.google.com/go/orgpolicy v1.10.0 // indirect + cloud.google.com/go/osconfig v1.11.0 // indirect github.com/Azure/azure-sdk-for-go v59.0.0+incompatible // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.1 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect @@ -84,12 +87,12 @@ require ( github.com/go-openapi/swag v0.19.5 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect - github.com/googleapis/gax-go/v2 v2.6.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect + github.com/googleapis/gax-go/v2 v2.7.1 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -107,9 +110,11 @@ require ( github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/klauspost/compress v1.15.11 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect + github.com/kr/pretty v0.3.0 // indirect github.com/magiconair/properties v1.8.1 // indirect github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e // indirect github.com/mattn/go-colorable v0.1.7 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect @@ -119,25 +124,24 @@ require ( github.com/pelletier/go-toml v1.2.0 // indirect github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/sergi/go-diff v1.2.0 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect - github.com/spf13/afero v1.2.2 // indirect + github.com/spf13/afero v1.9.2 // indirect github.com/spf13/cast v1.3.0 // indirect github.com/spf13/jwalterweatherman v1.0.0 // indirect - github.com/stretchr/objx v0.1.1 // indirect + github.com/stretchr/objx v0.5.0 // indirect github.com/subosito/gotenv v1.2.0 // indirect github.com/ulikunitz/xz v0.5.10 // indirect github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect - github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect github.com/zclconf/go-cty-yaml v1.0.2 // indirect - go.opencensus.io v0.23.0 // indirect - golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect - golang.org/x/mod v0.8.0 // indirect - golang.org/x/net v0.8.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/text v0.8.0 // indirect - golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect + go.opencensus.io v0.24.0 // indirect + golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa // indirect + golang.org/x/mod v0.9.0 // indirect + golang.org/x/net v0.9.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect + golang.org/x/time v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect gopkg.in/ini.v1 v1.51.1 // indirect diff --git a/go.sum b/go.sum index 56a4f97b6..62c30a9a7 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,7 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= @@ -15,6 +16,7 @@ cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOY cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= @@ -26,28 +28,93 @@ cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+Y cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= -cloud.google.com/go v0.104.0 h1:gSmWO7DY1vOm0MVU6DNXM11BWHHsTUmsC5cv1fuW5X8= cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= +cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= +cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= +cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= +cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= +cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= +cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= +cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= +cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= +cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= +cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM= +cloud.google.com/go/accesscontextmanager v1.7.0 h1:MG60JgnEoawHJrbWw0jGdv6HLNSf6gQvYRiXpuzqgEA= +cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= +cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ= +cloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k= +cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M= +cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE= +cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= +cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= +cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= +cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= +cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= +cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= +cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= +cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= +cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM= +cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= +cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= +cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI= +cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= +cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= +cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= +cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84= +cloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A= +cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY= +cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= +cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= +cloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1nOucMH0pwXN1rOBZFI= +cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ= +cloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI= +cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= -cloud.google.com/go/asset v1.8.0 h1:qzYOcI6u4CD+0R1E8rWbrqs04fISCcg2YYxW8yBAqFM= cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= +cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= +cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo= +cloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg= +cloud.google.com/go/asset v1.13.0 h1:YAsssO08BqZ6mncbb6FPlj9h6ACS7bJQUOlzciSfbNk= +cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= +cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= +cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= +cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= +cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= +cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= +cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= +cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= +cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= +cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= +cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= +cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= +cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= +cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= +cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM= +cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -55,132 +122,490 @@ cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUM cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= +cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= +cloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/ZurWFIxmF9I/E= +cloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac= +cloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q= +cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= +cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= +cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss= +cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= +cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= +cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= +cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= +cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= +cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= +cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= +cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= +cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE= +cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= +cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= +cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= +cloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M= +cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg= +cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= +cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= +cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= +cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= +cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= +cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y= +cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= -cloud.google.com/go/compute v1.10.0 h1:aoLIYaA1fX3ywihqpBk2APQKOo20nXsp1GEZQbx5Jk4= cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= +cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= +cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= +cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY= +cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= +cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= +cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= +cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= +cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= +cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= +cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4= +cloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM= +cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI= +cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= +cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= +cloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M= +cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0= +cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= +cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA= +cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= +cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= +cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= +cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= +cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= +cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= +cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ= +cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= +cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= +cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= +cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= +cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= +cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= +cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs= +cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= +cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= +cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= +cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI= +cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= +cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= +cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= +cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4= +cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= +cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= +cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= +cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= +cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= +cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM= +cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc= +cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= +cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= +cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= +cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= +cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= +cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= +cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= +cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw= +cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= +cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= +cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= +cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= +cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= +cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= +cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw= +cloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA= +cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= +cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= +cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= +cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= +cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= +cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E= +cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= +cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= +cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= +cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= +cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= +cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= +cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= -cloud.google.com/go/iam v0.5.0 h1:fz9X5zyTWBmamZsqvqZqD7khbifcZF/q+Z1J8pfhIUg= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= +cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= +cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= +cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= +cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k= +cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= +cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= +cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= +cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= +cloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo= +cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= +cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= +cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= +cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= +cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= +cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= +cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o= +cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= +cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= +cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= +cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= +cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4jMAg= +cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= +cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24= +cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= +cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= +cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= +cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= +cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= +cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= +cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= +cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM= +cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= +cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= +cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= +cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= +cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= +cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw= +cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= +cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= +cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= +cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= +cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= +cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= +cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= +cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w= +cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= +cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= +cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E= +cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= +cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= +cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= +cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k= +cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= +cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= +cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE= +cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= +cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= +cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= +cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= +cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= +cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= +cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= +cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= +cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= +cloud.google.com/go/orgpolicy v1.10.0 h1:XDriMWug7sd0kYT1QKofRpRHzjad0bK8Q8uA9q+XrU4= +cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= +cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= +cloud.google.com/go/osconfig v1.11.0 h1:PkSQx4OHit5xz2bNyr11KGcaFccL5oqglFPdTboyqwQ= +cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= +cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= +cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= +cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= +cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= +cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw= +cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= +cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg= +cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= +cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= +cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8= +cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= +cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= +cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= +cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= +cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= +cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA= +cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= +cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= +cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= +cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= +cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= +cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= +cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= +cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots= +cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo= +cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= +cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= +cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= +cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= +cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= +cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= +cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= +cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= +cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM= +cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg= cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= +cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= +cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc= +cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= +cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= +cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= +cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= +cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8= +cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= +cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= +cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0= +cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= +cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= +cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= +cloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA= +cloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc= +cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk= cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= +cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= +cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY= +cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= +cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= +cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= +cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc= +cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4= +cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= +cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= +cloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec= +cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA= +cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= +cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= +cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= +cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= +cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk= +cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M= cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= +cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= +cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0= +cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= -cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ= cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= +cloud.google.com/go/storage v1.29.0 h1:6weCgzRvMg7lzuUurI4697AqIRPU1SvzHhynwpW31jI= +cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= +cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= +cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= +cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= +cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= +cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= +cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= +cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= +cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= +cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= +cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= +cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= +cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= +cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= +cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= +cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA= +cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= +cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= +cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= +cloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0= +cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= +cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= +cloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg= +cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk= +cloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= +cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= +cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= +cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= +cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY= +cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= +cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= +cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= +cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc= +cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= +cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= +cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8= +cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= +cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= +cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= +cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= +cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= +cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= +cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= +cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= +cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= +cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= +cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= +git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/azure-sdk-for-go v45.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v59.0.0+incompatible h1:I1ULJqny1qQhUBFy11yDXHhW3pLvbhwV0PTn7mjp9V0= @@ -236,6 +661,7 @@ github.com/ChrisTrenkamp/goxpath v0.0.0-20170922090931-c385f95c6022/go.mod h1:nu github.com/ChrisTrenkamp/goxpath v0.0.0-20190607011252-c5096ec8773d/go.mod h1:nuWgzSkT5PnyOd+272uUmV0dnAnAn42Mk7PiQC5VzN4= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= @@ -258,16 +684,24 @@ github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= +github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190329064014-6e358769c32a/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA= github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190103054945-8205d1f41e70/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/aliyun/aliyun-tablestore-go-sdk v4.1.2+incompatible/go.mod h1:LDQHRZylxvcg8H7wBIDfvO5g/cy4/sz1iucBlc2l3Jw= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/crlf v0.0.0-20171020200849-670099aa064f/go.mod h1:k8feO4+kXDxro6ErPXBRTJ/ro2mf0SsFG8s7doP9kJE= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antchfx/xpath v0.0.0-20190129040759-c8489ed3251e/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk= github.com/antchfx/xquery v0.0.0-20180515051857-ad5b8c7a47b0/go.mod h1:LzD22aAzDP8/dyiCKFp31He4m2GPjl0AFyzDtZzUu9M= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= +github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= +github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU= github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= @@ -306,9 +740,14 @@ github.com/bmatcuk/doublestar v1.1.5/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9 github.com/bmatcuk/doublestar/v4 v4.0.1 h1:v5DFrvGpNnIKPlG7gcF4TlceHwBTvHdmjgDEkbDk9t8= github.com/bmatcuk/doublestar/v4 v4.0.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -318,11 +757,15 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/coreos/bbolt v1.3.0/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -351,6 +794,7 @@ github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/ github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dylanmei/iso8601 v0.1.0/go.mod h1:w9KhXSgIyROl1DefbMYIE7UVSIvELTbMrCfx+QkYnoQ= github.com/dylanmei/winrmtest v0.0.0-20190225150635-99b7fe2fddf1/go.mod h1:lcy9/2gH1jn/VCLouHA6tOEwLoNVd4GW6zhuKLmHC2Y= @@ -370,7 +814,12 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= +github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= +github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= +github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -380,6 +829,8 @@ github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= @@ -396,6 +847,11 @@ github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aev github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= +github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= +github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= @@ -408,6 +864,8 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= +github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= @@ -420,6 +878,8 @@ github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nA github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= +github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= @@ -428,13 +888,17 @@ github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3a github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -470,12 +934,15 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -502,8 +969,9 @@ github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPg github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -513,6 +981,7 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= @@ -526,8 +995,10 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -536,10 +1007,13 @@ github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/Oth github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= -github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89qN2ZU= github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A= +github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gophercloud/gophercloud v0.6.1-0.20191122030953-d8ac278c1c9d/go.mod h1:ozGNgr9KYOVATV5jsgHl/ceCDXGuguqOZAzoQ/2vcNM= github.com/gophercloud/gophercloud v0.10.1-0.20200424014253-c3bfe50899e5/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU808e/4mzjjDA76+Ss= github.com/gophercloud/utils v0.0.0-20200423144003-7c72efc7435d/go.mod h1:ehWUbLQJPqS0Ep+CxeD559hsm9pthPXadJNKwZkp43w= @@ -554,6 +1028,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/hashicorp/aws-sdk-go-base v0.6.0/go.mod h1:2fRjWDv3jJBeN6mVWFHV6hFTNeFBx2gpDLQaZNxUVAY= github.com/hashicorp/consul v0.0.0-20171026175957-610f3c86a089/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= @@ -637,9 +1113,9 @@ github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734/go.mod github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -682,6 +1158,8 @@ github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVY github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= @@ -689,24 +1167,30 @@ github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYb github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -725,6 +1209,9 @@ github.com/likexian/simplejson-go v0.0.0-20190409170913-40473a74d76d/go.mod h1:T github.com/likexian/simplejson-go v0.0.0-20190419151922-c1f9f0b4f084/go.mod h1:U4O1vIJvIKwbMZKUJ62lppfdvkCdVd2nfMimHK81eec= github.com/likexian/simplejson-go v0.0.0-20190502021454-d8787b4bfa0b/go.mod h1:3BWwtmKP9cXWwYCr5bkoVDEfLywacOv0s06OBEDpyt8= github.com/lusis/go-artifactory v0.0.0-20160115162124-7e4ce345df82/go.mod h1:y54tfGmO3NKssKveTEFFzH8C/akrSOy/iW9qEAUDV84= +github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -750,16 +1237,20 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-shellwords v1.0.4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.8/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= +github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= @@ -813,25 +1304,30 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3 h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/packer-community/winrmcp v0.0.0-20180921211025-c76d91c1e7db/go.mod h1:f6Izs6JvFTdnRbziASagjZ2vmf55NSIkC/weStxCHqk= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= +github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -844,6 +1340,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -853,11 +1351,17 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/r3labs/diff/v2 v2.6.0 h1:9zmqWRY+/FIHqqgQOcb0re810DH7S1IFdiSYiWHqc9s= github.com/r3labs/diff/v2 v2.6.0/go.mod h1:m/37LMp7X15uXY9IFa+rdGr48V6R/8ShK3/+y6yJHkE= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= +github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= @@ -885,8 +1389,11 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= +github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= @@ -905,16 +1412,22 @@ github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/y github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/svanharmelen/jsonapi v0.0.0-20180618144545-0c0828c3f16d/go.mod h1:BSTlc8jOjh0niykqEGVXOLXdi9o0r0kR8tCYiMvjFgw= @@ -953,17 +1466,15 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q github.com/xlab/treeprint v0.0.0-20161029104018-1d6e34225557/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI= github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= @@ -975,6 +1486,8 @@ github.com/zclconf/go-cty v1.8.4/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUA github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= github.com/zclconf/go-cty-yaml v1.0.2 h1:dNyg4QLTrv2IfJpm7Wtxi55ed5gLGOlPrZ6kMd51hY0= github.com/zclconf/go-cty-yaml v1.0.2/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0= +github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -982,9 +1495,12 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1001,6 +1517,7 @@ golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191202143827-86a70503ff7e/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -1009,20 +1526,37 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa h1:idItI2DDfCokpg0N51B2VtiLdJ4vAuXC9fnCb2gACo4= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1046,9 +1580,13 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1096,6 +1634,7 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= @@ -1104,6 +1643,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -1114,11 +1655,17 @@ golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1142,9 +1689,14 @@ golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7Lm golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= +golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= +golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1158,6 +1710,7 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1213,12 +1766,15 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1227,8 +1783,11 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1245,16 +1804,26 @@ golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1266,20 +1835,29 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1294,6 +1872,7 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1325,17 +1904,22 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201028111035-eafbe7b904eb/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1345,6 +1929,14 @@ golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNq golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= +gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= +gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= +gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1393,8 +1985,17 @@ google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaE google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.100.0 h1:LGUYIrbW9pzYQQ8NWXlaIVkgnfubVBZbMFb9P8TK374= +google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= +google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= +google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= +google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= +google.golang.org/api v0.114.0 h1:1xQPji6cO2E2vLiI+C/XiFAnsn1WV3mjaEwGLhi3grE= +google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1439,7 +2040,9 @@ google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1472,6 +2075,7 @@ google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2 google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= @@ -1504,8 +2108,37 @@ google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53B google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71 h1:GEgb2jF5zxsFJpJfg9RoDDWm7tiwc/DDSTE2BtLUkXU= +google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= +google.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= +google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= +google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -1534,6 +2167,7 @@ google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= @@ -1542,8 +2176,13 @@ google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1559,8 +2198,10 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1570,7 +2211,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= @@ -1581,7 +2221,6 @@ gopkg.in/ini.v1 v1.51.1 h1:GyboHr4UqMiLUybYjd22ZjQIKEJEpgtLXtuGbR21Oho= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= @@ -1607,6 +2246,7 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= k8s.io/api v0.0.0-20190620084959-7cf5895f2711/go.mod h1:TBhBqb1AWbBQbW3XRusr7n7E4v2+5ZY8r8sAMnyFC5A= k8s.io/apimachinery v0.0.0-20190612205821-1799e75a0719/go.mod h1:I4A+glKBHiTgiEjQiCCQfCAIcIMFGt291SmsvcrFzJA= k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655/go.mod h1:nL6pwRT8NgfF8TT68DBI8uEePRt89cSvoXUVqbkWHq4= @@ -1619,7 +2259,42 @@ k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/utils v0.0.0-20200411171748-3d5a2fe318e4/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= +modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= +modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= +modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= +modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= +modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= +modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= +modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= +modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= +modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= +modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= +modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= +modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= +modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= +modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= diff --git a/pkg/analyser/analysis.go b/pkg/analyser/analysis.go index 9de62ef32..008a02da2 100644 --- a/pkg/analyser/analysis.go +++ b/pkg/analyser/analysis.go @@ -3,32 +3,16 @@ package analyser import ( "encoding/json" "fmt" - "sort" "strings" "time" "github.com/snyk/driftctl/enumeration/alerter" - "github.com/r3labs/diff/v2" "github.com/snyk/driftctl/enumeration/resource" ) -type Change struct { - diff.Change - Computed bool `json:"computed"` - JsonString bool `json:"-"` -} - -type Changelog []Change - -type Difference struct { - Res *resource.Resource - Changelog Changelog -} - type Summary struct { TotalResources int `json:"total_resources"` - TotalDrifted int `json:"total_changed"` TotalUnmanaged int `json:"total_unmanaged"` TotalDeleted int `json:"total_missing"` TotalManaged int `json:"total_managed"` @@ -39,8 +23,6 @@ type Analysis struct { unmanaged []*resource.Resource managed []*resource.Resource deleted []*resource.Resource - differences []Difference - options AnalyzerOptions summary Summary alerts alerter.Alerts Duration time.Duration @@ -49,18 +31,11 @@ type Analysis struct { ProviderVersion string } -type serializableDifference struct { - Res resource.SerializableResource `json:"res"` - Changelog Changelog `json:"changelog"` -} - type serializableAnalysis struct { - Options AnalyzerOptions `json:"options"` Summary Summary `json:"summary"` Managed []resource.SerializableResource `json:"managed"` Unmanaged []resource.SerializableResource `json:"unmanaged"` Deleted []resource.SerializableResource `json:"missing"` - Differences []serializableDifference `json:"differences"` Coverage int `json:"coverage"` Alerts map[string][]alerter.SerializableAlert `json:"alerts"` ProviderName string `json:"provider_name"` @@ -77,8 +52,8 @@ type GenDriftIgnoreOptions struct { OutputPath string } -func NewAnalysis(options AnalyzerOptions) *Analysis { - return &Analysis{options: options} +func NewAnalysis() *Analysis { + return &Analysis{} } func (a Analysis) MarshalJSON() ([]byte, error) { @@ -92,12 +67,6 @@ func (a Analysis) MarshalJSON() ([]byte, error) { for _, d := range a.deleted { bla.Deleted = append(bla.Deleted, *resource.NewSerializableResource(d)) } - for _, di := range a.differences { - bla.Differences = append(bla.Differences, serializableDifference{ - Res: *resource.NewSerializableResource(di.Res), - Changelog: di.Changelog, - }) - } if len(a.alerts) > 0 { bla.Alerts = make(map[string][]alerter.SerializableAlert) for k, v := range a.alerts { @@ -111,7 +80,6 @@ func (a Analysis) MarshalJSON() ([]byte, error) { bla.ProviderName = a.ProviderName bla.ProviderVersion = a.ProviderVersion bla.ScanDuration = uint(a.Duration.Seconds()) - bla.Options = a.Options() bla.Date = a.Date return json.Marshal(bla) @@ -152,15 +120,6 @@ func (a *Analysis) UnmarshalJSON(bytes []byte) error { } a.AddManaged(res) } - for _, di := range bla.Differences { - a.AddDifference(Difference{ - Res: &resource.Resource{ - Id: di.Res.Id, - Type: di.Res.Type, - }, - Changelog: di.Changelog, - }) - } if len(bla.Alerts) > 0 { a.alerts = make(alerter.Alerts) for k, v := range bla.Alerts { @@ -175,17 +134,12 @@ func (a *Analysis) UnmarshalJSON(bytes []byte) error { a.ProviderVersion = bla.ProviderVersion a.SetIaCSourceCount(bla.Summary.TotalIaCSourceCount) a.Duration = time.Duration(bla.ScanDuration) * time.Second - a.options = bla.Options a.Date = bla.Date return nil } func (a *Analysis) IsSync() bool { - return a.summary.TotalDrifted == 0 && a.summary.TotalUnmanaged == 0 && a.summary.TotalDeleted == 0 -} - -func (a *Analysis) Options() AnalyzerOptions { - return a.options + return a.summary.TotalUnmanaged == 0 && a.summary.TotalDeleted == 0 } func (a *Analysis) AddDeleted(resources ...*resource.Resource) { @@ -206,19 +160,10 @@ func (a *Analysis) AddManaged(resources ...*resource.Resource) { a.summary.TotalManaged += len(resources) } -func (a *Analysis) AddDifference(diffs ...Difference) { - a.differences = append(a.differences, diffs...) - a.summary.TotalDrifted += len(diffs) -} - func (a *Analysis) SetAlerts(alerts alerter.Alerts) { a.alerts = alerts } -func (a *Analysis) SetOptions(options AnalyzerOptions) { - a.options = options -} - func (a *Analysis) SetIaCSourceCount(i uint) { a.summary.TotalIaCSourceCount = i } @@ -242,10 +187,6 @@ func (a *Analysis) Deleted() []*resource.Resource { return a.deleted } -func (a *Analysis) Differences() []Difference { - return a.differences -} - func (a *Analysis) Summary() Summary { return a.summary } @@ -257,7 +198,6 @@ func (a *Analysis) Alerts() alerter.Alerts { func (a *Analysis) SortResources() { a.unmanaged = resource.Sort(a.unmanaged) a.deleted = resource.Sort(a.deleted) - a.differences = SortDifferences(a.differences) } func (a *Analysis) DriftIgnoreList(opts GenDriftIgnoreOptions) (int, string) { @@ -271,12 +211,6 @@ func (a *Analysis) DriftIgnoreList(opts GenDriftIgnoreOptions) (int, string) { } resourceCount += len(res) } - addDifferences := func(diff ...Difference) { - for _, d := range diff { - addResources(d.Res) - } - resourceCount += len(diff) - } if !opts.ExcludeUnmanaged && a.Summary().TotalUnmanaged > 0 { list = append(list, "# Resources not covered by IaC") @@ -286,36 +220,10 @@ func (a *Analysis) DriftIgnoreList(opts GenDriftIgnoreOptions) (int, string) { list = append(list, "# Missing resources") addResources(a.Deleted()...) } - if !opts.ExcludeDrifted && a.Summary().TotalDrifted > 0 { - list = append(list, "# Changed resources") - addDifferences(a.Differences()...) - } return resourceCount, strings.Join(list, "\n") } -func SortDifferences(diffs []Difference) []Difference { - sort.SliceStable(diffs, func(i, j int) bool { - if diffs[i].Res.ResourceType() != diffs[j].Res.ResourceType() { - return diffs[i].Res.ResourceType() < diffs[j].Res.ResourceType() - } - return diffs[i].Res.ResourceId() < diffs[j].Res.ResourceId() - }) - - for _, d := range diffs { - SortChanges(d.Changelog) - } - - return diffs -} - -func SortChanges(changes []Change) []Change { - sort.SliceStable(changes, func(i, j int) bool { - return strings.Join(changes[i].Path, ".") < strings.Join(changes[j].Path, ".") - }) - return changes -} - func escapeKey(line string) string { line = strings.ReplaceAll(line, `\`, `\\`) line = strings.ReplaceAll(line, `.`, `\.`) diff --git a/pkg/analyser/analyzer.go b/pkg/analyser/analyzer.go index fae7a2615..9fd5ba35a 100644 --- a/pkg/analyser/analyzer.go +++ b/pkg/analyser/analyzer.go @@ -1,7 +1,6 @@ package analyser import ( - "github.com/r3labs/diff/v2" "github.com/snyk/driftctl/enumeration/alerter" resourceaws "github.com/snyk/driftctl/enumeration/resource/aws" "github.com/snyk/driftctl/pkg/filter" @@ -45,24 +44,17 @@ func (c *ComputedDiffAlert) Resource() *resource.Resource { return nil } -type AnalyzerOptions struct { - Deep bool `json:"deep"` - OnlyManaged bool `json:"only_managed"` - OnlyUnmanaged bool `json:"only_unmanaged"` -} - type Analyzer struct { alerter *alerter.Alerter - options AnalyzerOptions filter filter.Filter } -func NewAnalyzer(alerter *alerter.Alerter, options AnalyzerOptions, filter filter.Filter) *Analyzer { - return &Analyzer{alerter, options, filter} +func NewAnalyzer(alerter *alerter.Alerter, filter filter.Filter) *Analyzer { + return &Analyzer{alerter, filter} } func (a Analyzer) Analyze(remoteResources, resourcesFromState []*resource.Resource) (Analysis, error) { - analysis := Analysis{options: a.options} + analysis := Analysis{} // Iterate on remote resources and filter ignored resources filteredRemoteResource := make([]*resource.Resource, 0, len(remoteResources)) @@ -75,62 +67,20 @@ func (a Analyzer) Analyze(remoteResources, resourcesFromState []*resource.Resour haveComputedDiff := false for _, stateRes := range resourcesFromState { - i, remoteRes, found := findCorrespondingRes(filteredRemoteResource, stateRes) + i, _, found := findCorrespondingRes(filteredRemoteResource, stateRes) if a.filter.IsResourceIgnored(stateRes) || a.alerter.IsResourceIgnored(stateRes) { continue } if !found { - if !analysis.Options().OnlyUnmanaged { - analysis.AddDeleted(stateRes) - } + analysis.AddDeleted(stateRes) continue } // Remove managed resources, so it will remain only unmanaged ones filteredRemoteResource = removeResourceByIndex(i, filteredRemoteResource) analysis.AddManaged(stateRes) - - // Stop there if we are not in deep mode, we do not want to compute diffs - if !a.options.Deep { - continue - } - - // Stop if the resource is not compatible with deep mode - if stateRes.Schema() != nil && !stateRes.Schema().Flags.HasFlag(resource.FlagDeepMode) { - continue - } - - var delta diff.Changelog - delta, _ = diff.Diff(stateRes.Attributes(), remoteRes.Attributes()) - - if len(delta) == 0 { - continue - } - - changelog := make([]Change, 0, len(delta)) - for _, change := range delta { - if a.filter.IsFieldIgnored(stateRes, change.Path) { - continue - } - c := Change{Change: change} - resSchema := stateRes.Schema() - if resSchema != nil { - c.Computed = resSchema.IsComputedField(c.Path) - c.JsonString = resSchema.IsJsonStringField(c.Path) - } - if c.Computed { - haveComputedDiff = true - } - changelog = append(changelog, c) - } - if len(changelog) > 0 { - analysis.AddDifference(Difference{ - Res: stateRes, - Changelog: changelog, - }) - } } if a.hasUnmanagedSecurityGroupRules(filteredRemoteResource) { @@ -142,9 +92,7 @@ func (a Analyzer) Analyze(remoteResources, resourcesFromState []*resource.Resour } // Add remaining unmanaged resources - if !analysis.Options().OnlyManaged { - analysis.AddUnmanaged(filteredRemoteResource...) - } + analysis.AddUnmanaged(filteredRemoteResource...) // Sort resources by Terraform Id // The purpose is to have a predictable output diff --git a/pkg/analyser/analyzer_test.go b/pkg/analyser/analyzer_test.go index d2026df70..838c41cab 100644 --- a/pkg/analyser/analyzer_test.go +++ b/pkg/analyser/analyzer_test.go @@ -38,7 +38,6 @@ func TestAnalyze(t *testing.T) { alerts alerter2.Alerts expected Analysis hasDrifted bool - options *AnalyzerOptions }{ { name: "TestNilValues", // Cover division by zero case @@ -174,634 +173,6 @@ func TestAnalyze(t *testing.T) { }, hasDrifted: true, }, - { - name: "TestDiff", - iac: []*resource.Resource{ - { - Id: "foobar", - Type: aws.AwsAmiResourceType, - Attrs: &resource.Attributes{ - "architecture": "foobar", - "arn": "barfoo", - "ebs_block_device": []map[string]interface{}{ - { - "volume_type": "bar", - "volume_size": 0, - }, - }, - }, - }, - }, - cloud: []*resource.Resource{ - { - Id: "foobar", - Type: aws.AwsAmiResourceType, - Attrs: &resource.Attributes{ - "architecture": "barfoo", - "arn": "foobar", - "ebs_block_device": []map[string]interface{}{ - { - "volume_type": "baz", - "volume_size": 1, - }, - }, - }, - }, - }, - expected: Analysis{ - managed: []*resource.Resource{ - { - Id: "foobar", - Type: aws.AwsAmiResourceType, - Attrs: &resource.Attributes{ - "architecture": "foobar", - "arn": "barfoo", - "ebs_block_device": []map[string]interface{}{ - { - "volume_type": "bar", - "volume_size": 0, - }, - }, - }, - }, - }, - summary: Summary{ - TotalResources: 1, - TotalDrifted: 1, - TotalManaged: 1, - }, - differences: []Difference{ - { - Res: &resource.Resource{ - Id: "foobar", - Type: aws.AwsAmiResourceType, - Attrs: &resource.Attributes{ - "architecture": "foobar", - "arn": "barfoo", - "ebs_block_device": []map[string]interface{}{ - { - "volume_type": "bar", - "volume_size": 0, - }, - }, - }, - }, - Changelog: Changelog{ - { - Change: diff.Change{ - Type: "update", - From: "foobar", - To: "barfoo", - Path: []string{ - "architecture", - }, - }, - }, - { - Change: diff.Change{ - Type: "update", - From: "barfoo", - To: "foobar", - Path: []string{ - "arn", - }, - }, - Computed: true, - }, - { - Change: diff.Change{ - Type: "update", - From: 0, - To: 1, - Path: []string{ - "ebs_block_device", - "0", - "volume_size", - }, - }, - }, - { - Change: diff.Change{ - Type: "update", - From: "bar", - To: "baz", - Path: []string{ - "ebs_block_device", - "0", - "volume_type", - }, - }, - }, - }, - }, - }, - alerts: alerter2.Alerts{ - "": { - NewComputedDiffAlert(), - }, - }, - }, - hasDrifted: true, - }, - { - name: "TestDiff with partial ignore", - iac: []*resource.Resource{ - { - Id: "foobar", - Type: aws.AwsAmiResourceType, - Attrs: &resource.Attributes{ - "architecture": "foobar", - "arn": "barfoo", - }, - }, - }, - cloud: []*resource.Resource{ - { - Id: "foobar", - Type: aws.AwsAmiResourceType, - Attrs: &resource.Attributes{ - "architecture": "barfoo", - "arn": "foobar", - }, - }, - }, - ignoredDrift: []struct { - res *resource.Resource - path []string - }{ - { - res: &resource.Resource{ - Id: "foobar", - Type: aws.AwsAmiResourceType, - Attrs: &resource.Attributes{ - "architecture": "foobar", - "arn": "barfoo", - }, - }, - path: []string{"architecture"}, - }, - }, - expected: Analysis{ - managed: []*resource.Resource{ - { - Id: "foobar", - Type: aws.AwsAmiResourceType, - Attrs: &resource.Attributes{ - "architecture": "foobar", - "arn": "barfoo", - }, - }, - }, - summary: Summary{ - TotalResources: 1, - TotalDrifted: 1, - TotalManaged: 1, - }, - differences: []Difference{ - { - Res: &resource.Resource{ - Id: "foobar", - Type: aws.AwsAmiResourceType, - Attrs: &resource.Attributes{ - "architecture": "foobar", - "arn": "barfoo", - }, - }, - Changelog: Changelog{ - { - Change: diff.Change{ - Type: "update", - From: "barfoo", - To: "foobar", - Path: []string{ - "arn", - }, - }, - Computed: true, - }, - }, - }, - }, - alerts: alerter2.Alerts{ - "": { - NewComputedDiffAlert(), - }, - }, - }, - hasDrifted: true, - }, - { - name: "TestDiff with full ignore", - iac: []*resource.Resource{ - { - Id: "foobar", - Attrs: &resource.Attributes{ - "foobar": "foobar", - "barfoo": "barfoo", - }, - }, - }, - ignoredRes: []*resource.Resource{ - { - Id: "should_be_ignored", - Attrs: &resource.Attributes{}, - }, - }, - cloud: []*resource.Resource{ - { - Id: "foobar", - Attrs: &resource.Attributes{ - "foobar": "barfoo", - "barfoo": "foobar", - }, - }, - { - Id: "should_be_ignored", - Attrs: &resource.Attributes{}, - }, - }, - ignoredDrift: []struct { - res *resource.Resource - path []string - }{ - { - res: &resource.Resource{ - Id: "foobar", - Attrs: &resource.Attributes{ - "foobar": "foobar", - "barfoo": "barfoo", - }, - }, - path: []string{"foobar"}, - }, - { - res: &resource.Resource{ - Id: "foobar", - Attrs: &resource.Attributes{ - "foobar": "foobar", - "barfoo": "barfoo", - }, - }, - path: []string{"barfoo"}, - }, - }, - expected: Analysis{ - managed: []*resource.Resource{ - { - Id: "foobar", - Attrs: &resource.Attributes{ - "foobar": "foobar", - "barfoo": "barfoo", - }, - }, - }, - summary: Summary{ - TotalResources: 1, - TotalDrifted: 0, - TotalManaged: 1, - }, - }, - hasDrifted: false, - }, - { - name: "TestDiffWithAlertFiltering", - iac: []*resource.Resource{ - { - Id: "foobar", - Type: "fakeres", - Attrs: &resource.Attributes{ - "foobar": "foobar", - "barfoo": "barfoo", - "struct": map[string]interface{}{ - "baz": "baz", - "bar": "bar", - }, - }, - }, - { - Id: "barfoo", - Type: "fakeres", - Attrs: &resource.Attributes{ - "foobar": "foobar", - "barfoo": "barfoo", - "struct": map[string]interface{}{ - "baz": "baz", - "bar": "bar", - }, - }, - }, - { - Id: "foobaz", - Type: "other", - Attrs: &resource.Attributes{ - "foobar": "foobar", - "barfoo": "barfoo", - "struct": map[string]interface{}{ - "baz": "baz", - "bar": "bar", - }, - }, - }, - { - Id: "resource", - Type: "other", - Attrs: &resource.Attributes{ - "foobar": "foobar", - "barfoo": "barfoo", - "struct": map[string]interface{}{ - "baz": "baz", - "bar": "bar", - }, - "structslice": []map[string]interface{}{ - { - "string": "one", - "array": []string{"foo"}, - }, - }, - }, - }, - }, - cloud: []*resource.Resource{ - { - Id: "foobar", - Type: "fakeres", - Attrs: &resource.Attributes{ - "foobar": "barfoo", - "barfoo": "foobar", - "struct": map[string]interface{}{ - "baz": "bar", - "bar": "baz", - }, - }, - }, - { - Id: "barfoo", - Type: "fakeres", - Attrs: &resource.Attributes{ - "foobar": "barfoo", - "barfoo": "foobar", - "struct": map[string]interface{}{ - "baz": "bar", - "bar": "baz", - }, - }, - }, - { - Id: "foobaz", - Type: "other", - Attrs: &resource.Attributes{ - "foobar": "barfoo", - "barfoo": "foobar", - "struct": map[string]interface{}{ - "baz": "bar", - "bar": "baz", - }, - }, - }, - { - Id: "resource", - Type: "other", - Attrs: &resource.Attributes{ - "foobar": "barfoo", - "barfoo": "foobar", - "struct": map[string]interface{}{ - "baz": "bar", - "bar": "baz", - }, - "structslice": []map[string]interface{}{ - { - "string": "two", - "array": []string{"oof"}, - }, - }, - }, - }, - }, - alerts: alerter2.Alerts{ - "fakeres": { - &alerter2.FakeAlert{Msg: "Should be ignored", IgnoreResource: true}, - }, - "other.foobaz": { - &alerter2.FakeAlert{Msg: "Should be ignored", IgnoreResource: true}, - }, - "other.resource": { - &alerter2.FakeAlert{Msg: "Should not be ignored"}, - }, - }, - expected: Analysis{ - managed: []*resource.Resource{ - { - Id: "resource", - Type: "other", - Attrs: &resource.Attributes{ - "foobar": "foobar", - "barfoo": "barfoo", - "struct": map[string]interface{}{ - "baz": "baz", - "bar": "bar", - }, - "structslice": []map[string]interface{}{ - { - "string": "one", - "array": []string{"foo"}, - }, - }, - }, - }, - }, - summary: Summary{ - TotalResources: 1, - TotalDrifted: 1, - TotalManaged: 1, - }, - differences: []Difference{ - { - Res: &resource.Resource{ - Id: "resource", - Type: "other", - Attrs: &resource.Attributes{ - "foobar": "foobar", - "barfoo": "barfoo", - "struct": map[string]interface{}{ - "baz": "baz", - "bar": "bar", - }, - "structslice": []map[string]interface{}{ - { - "string": "one", - "array": []string{"foo"}, - }, - }, - }, - }, - Changelog: Changelog{ - { - Change: diff.Change{ - Type: "update", - From: "barfoo", - To: "foobar", - Path: []string{ - "barfoo", - }, - }, - }, - { - Change: diff.Change{ - Type: "update", - From: "foobar", - To: "barfoo", - Path: []string{ - "foobar", - }, - }, - }, - { - Change: diff.Change{ - Type: "update", - From: "bar", - To: "baz", - Path: []string{ - "struct", - "bar", - }, - }, - }, - { - Change: diff.Change{ - Type: "update", - From: "baz", - To: "bar", - Path: []string{ - "struct", - "baz", - }, - }, - }, - { - Change: diff.Change{ - Type: "update", - From: "foo", - To: "oof", - Path: []string{ - "structslice", - "0", - "array", - "0", - }, - }, - }, - { - Change: diff.Change{ - Type: "update", - From: "one", - To: "two", - Path: []string{ - "structslice", - "0", - "string", - }, - }, - }, - }, - }, - }, - alerts: alerter2.Alerts{ - "fakeres": { - &alerter2.FakeAlert{Msg: "Should be ignored", IgnoreResource: true}, - }, - "other.foobaz": { - &alerter2.FakeAlert{Msg: "Should be ignored", IgnoreResource: true}, - }, - "other.resource": { - &alerter2.FakeAlert{Msg: "Should not be ignored"}, - }, - }, - }, - hasDrifted: true, - }, - { - name: "TestDiff with computed field send 1 alert", - iac: []*resource.Resource{ - { - Id: "ID", - Type: aws.AwsAmiResourceType, - Attrs: &resource.Attributes{ - "id": "ID", - "arn": "ARN", - }, - }, - }, - cloud: []*resource.Resource{ - { - Id: "ID", - Type: aws.AwsAmiResourceType, - Attrs: &resource.Attributes{ - "id": "IDCHANGED", - "arn": "ARNCHANGED", - }, - }, - }, - alerts: alerter2.Alerts{}, - expected: Analysis{ - managed: []*resource.Resource{ - { - Id: "ID", - Type: aws.AwsAmiResourceType, - Attrs: &resource.Attributes{ - "id": "ID", - "arn": "ARN", - }, - }, - }, - summary: Summary{ - TotalResources: 1, - TotalDrifted: 1, - TotalManaged: 1, - }, - differences: []Difference{ - { - Res: &resource.Resource{ - Id: "ID", - Type: aws.AwsAmiResourceType, - Attrs: &resource.Attributes{ - "id": "ID", - "arn": "ARN", - }, - }, - Changelog: Changelog{ - { - Change: diff.Change{ - Type: "update", - From: "ARN", - To: "ARNCHANGED", - Path: []string{ - "arn", - }, - }, - Computed: true, - }, - { - Change: diff.Change{ - Type: "update", - From: "ID", - To: "IDCHANGED", - Path: []string{ - "id", - }, - }, - Computed: true, - }, - }, - }, - }, - alerts: alerter2.Alerts{ - "": { - NewComputedDiffAlert(), - }, - }, - }, - hasDrifted: true, - }, { name: "Test alert on unmanaged security group rules", iac: []*resource.Resource{ @@ -985,162 +356,6 @@ func TestAnalyze(t *testing.T) { }, }, }, - { - name: "Test --only-managed flag", - iac: []*resource.Resource{ - { - Id: "foo", - Type: aws.AwsInstanceResourceType, - Attrs: &resource.Attributes{ - "instance_type": "test2", - }, - }, - { - Id: "baz", - Type: aws.AwsInstanceResourceType, - Attrs: &resource.Attributes{ - "instance_type": "test3", - }, - }, - }, - cloud: []*resource.Resource{ - { - Id: "foo", - Type: aws.AwsInstanceResourceType, - Attrs: &resource.Attributes{ - "instance_type": "test1", - }, - }, - { - Id: "bar", - Type: aws.AwsInstanceResourceType, - Attrs: &resource.Attributes{ - "instance_type": "test2", - }, - }, - }, - hasDrifted: true, - expected: Analysis{ - managed: []*resource.Resource{ - { - Id: "foo", - Type: aws.AwsInstanceResourceType, - Attrs: &resource.Attributes{ - "instance_type": "test2", - }, - }, - }, - deleted: []*resource.Resource{ - { - Id: "baz", - Type: aws.AwsInstanceResourceType, - Attrs: &resource.Attributes{ - "instance_type": "test3", - }, - }, - }, - differences: []Difference{ - { - Res: &resource.Resource{ - Id: "foo", - Type: aws.AwsInstanceResourceType, - Attrs: &resource.Attributes{ - "instance_type": "test2", - }, - }, - Changelog: Changelog{ - { - Change: diff.Change{ - Type: "update", - From: "test2", - To: "test1", - Path: []string{ - "instance_type", - }, - }, - }, - }, - }, - }, - summary: Summary{ - TotalResources: 2, - TotalManaged: 1, - TotalUnmanaged: 0, - TotalDeleted: 1, - TotalDrifted: 1, - }, - }, - options: &AnalyzerOptions{ - OnlyManaged: true, - Deep: true, - }, - }, - { - name: "Test --only-unmanaged flag", - iac: []*resource.Resource{ - { - Id: "foo", - Type: aws.AwsInstanceResourceType, - Attrs: &resource.Attributes{ - "instance_type": "test2", - }, - }, - { - Id: "baz", - Type: aws.AwsInstanceResourceType, - Attrs: &resource.Attributes{ - "instance_type": "test3", - }, - }, - }, - cloud: []*resource.Resource{ - { - Id: "foo", - Type: aws.AwsInstanceResourceType, - Attrs: &resource.Attributes{ - "instance_type": "test1", - }, - }, - { - Id: "bar", - Type: aws.AwsInstanceResourceType, - Attrs: &resource.Attributes{ - "instance_type": "test2", - }, - }, - }, - hasDrifted: true, - expected: Analysis{ - managed: []*resource.Resource{ - { - Id: "foo", - Type: aws.AwsInstanceResourceType, - Attrs: &resource.Attributes{ - "instance_type": "test2", - }, - }, - }, - unmanaged: []*resource.Resource{ - { - Id: "bar", - Type: aws.AwsInstanceResourceType, - Attrs: &resource.Attributes{ - "instance_type": "test2", - }, - }, - }, - summary: Summary{ - TotalResources: 2, - TotalManaged: 1, - TotalUnmanaged: 1, - TotalDeleted: 0, - TotalDrifted: 0, - }, - }, - options: &AnalyzerOptions{ - OnlyUnmanaged: true, - }, - }, } differ, err := diff.NewDiffer(diff.SliceOrdering(true)) @@ -1156,11 +371,6 @@ func TestAnalyze(t *testing.T) { } testFilter.On("IsResourceIgnored", mock.Anything).Return(false) - for _, s := range c.ignoredDrift { - testFilter.On("IsFieldIgnored", s.res, s.path).Return(true) - } - testFilter.On("IsFieldIgnored", mock.Anything, mock.Anything).Return(false) - al := alerter2.NewAlerter() if c.alerts != nil { al.SetAlerts(c.alerts) @@ -1169,12 +379,7 @@ func TestAnalyze(t *testing.T) { repo := testresource.InitFakeSchemaRepository("aws", "3.19.0") aws.InitResourcesMetadata(repo) - options := AnalyzerOptions{Deep: true} - if c.options != nil { - options = *c.options - } - - analyzer := NewAnalyzer(al, options, testFilter) + analyzer := NewAnalyzer(al, testFilter) for _, res := range c.cloud { addSchemaToRes(res, repo) @@ -1233,16 +438,6 @@ func TestAnalyze(t *testing.T) { } } - diffChanges, err := differ.Diff(result.Differences(), c.expected.Differences()) - if err != nil { - t.Fatalf("Unable to compare %+v", err) - } - if len(diffChanges) > 0 { - for _, change := range diffChanges { - t.Errorf("%+v", change) - } - } - summaryChanges, err := differ.Diff(c.expected.Summary(), result.Summary()) if err != nil { t.Fatalf("Unable to compare %+v", err) @@ -1309,27 +504,6 @@ func TestAnalysis_MarshalJSON(t *testing.T) { Type: "aws_iam_access_key", }, ) - analysis.AddDifference(Difference{ - Res: &resource.Resource{ - Id: "AKIA5QYBVVD25KFXJHYJ", - Type: "aws_iam_access_key", - Source: &resource.TerraformStateSource{ - State: "tfstate://terraform.tfstate", - Module: "module", - Name: "my_name", - }, - }, - Changelog: []Change{ - { - Change: diff.Change{ - Type: "update", - Path: []string{"status"}, - From: "Active", - To: "Inactive", - }, - }, - }, - }) analysis.SetAlerts(alerter2.Alerts{ "aws_iam_access_key": { &alerter2.FakeAlert{Msg: "This is an alert"}, @@ -1357,12 +531,8 @@ func TestAnalysis_MarshalJSON(t *testing.T) { func TestAnalysis_UnmarshalJSON(t *testing.T) { expected := Analysis{ - options: AnalyzerOptions{ - Deep: true, - }, summary: Summary{ TotalResources: 6, - TotalDrifted: 1, TotalUnmanaged: 2, TotalDeleted: 2, TotalManaged: 2, @@ -1398,24 +568,6 @@ func TestAnalysis_UnmarshalJSON(t *testing.T) { Type: "aws_iam_access_key", }, }, - differences: []Difference{ - { - Res: &resource.Resource{ - Id: "AKIA5QYBVVD25KFXJHYJ", - Type: "aws_iam_access_key", - }, - Changelog: []Change{ - { - Change: diff.Change{ - Type: "update", - Path: []string{"status"}, - From: "Active", - To: "Inactive", - }, - }, - }, - }, - }, alerts: alerter2.Alerts{ "aws_iam_access_key": { &alerter2.SerializedAlert{ @@ -1438,13 +590,11 @@ func TestAnalysis_UnmarshalJSON(t *testing.T) { t.Fatal(err) } assert.Equal(t, expected, got) - assert.True(t, got.Options().Deep) assert.Equal(t, 33, got.Coverage()) assert.Equal(t, 2, got.Summary().TotalUnmanaged) assert.Equal(t, 2, got.Summary().TotalManaged) assert.Equal(t, 2, got.Summary().TotalDeleted) assert.Equal(t, 6, got.Summary().TotalResources) - assert.Equal(t, 1, got.Summary().TotalDrifted) assert.Equal(t, uint(3), got.Summary().TotalIaCSourceCount) assert.Len(t, got.alerts, 1) assert.Equal(t, got.alerts["aws_iam_access_key"][0].Message(), "This is an alert") diff --git a/pkg/analyser/testdata/input.json b/pkg/analyser/testdata/input.json index 0ad426cc8..542630c74 100644 --- a/pkg/analyser/testdata/input.json +++ b/pkg/analyser/testdata/input.json @@ -1,12 +1,6 @@ { - "options": { - "deep": true, - "only_managed": false, - "only_unmanaged": false - }, "summary": { "total_resources": 6, - "total_changed": 1, "total_unmanaged": 2, "total_missing": 2, "total_managed": 2, @@ -42,25 +36,6 @@ "type": "aws_iam_access_key" } ], - "differences": [ - { - "res": { - "id": "AKIA5QYBVVD25KFXJHYJ", - "type": "aws_iam_access_key" - }, - "changelog": [ - { - "type": "update", - "path": [ - "status" - ], - "from": "Active", - "to": "Inactive", - "computed": false - } - ] - } - ], "coverage": 33, "alerts": { "aws_iam_access_key": [ diff --git a/pkg/analyser/testdata/output.json b/pkg/analyser/testdata/output.json index 484f31728..b576665d9 100644 --- a/pkg/analyser/testdata/output.json +++ b/pkg/analyser/testdata/output.json @@ -1,12 +1,6 @@ { - "options": { - "deep": false, - "only_managed": false, - "only_unmanaged": false - }, "summary": { "total_resources": 6, - "total_changed": 1, "total_unmanaged": 2, "total_missing": 2, "total_managed": 2, @@ -42,30 +36,6 @@ "type": "aws_iam_access_key" } ], - "differences": [ - { - "res": { - "id": "AKIA5QYBVVD25KFXJHYJ", - "type": "aws_iam_access_key", - "source": { - "source": "tfstate://terraform.tfstate", - "namespace": "module", - "internal_name": "my_name" - } - }, - "changelog": [ - { - "type": "update", - "path": [ - "status" - ], - "from": "Active", - "to": "Inactive", - "computed": false - } - ] - } - ], "coverage": 33, "alerts": { "aws_iam_access_key": [ diff --git a/pkg/cmd/fmt.go b/pkg/cmd/fmt.go index f14a0e277..9e67c816c 100644 --- a/pkg/cmd/fmt.go +++ b/pkg/cmd/fmt.go @@ -58,7 +58,7 @@ func runFmt(opts *pkg.FmtOptions, reader io.Reader) error { analysisText = append(analysisText, scanner.Bytes()...) } - analysis := analyser.NewAnalysis(analyser.AnalyzerOptions{}) + analysis := analyser.NewAnalysis() err := json.Unmarshal(analysisText, analysis) if err != nil { return err diff --git a/pkg/cmd/gen_driftignore.go b/pkg/cmd/gen_driftignore.go index 3cd688c48..1f2421504 100644 --- a/pkg/cmd/gen_driftignore.go +++ b/pkg/cmd/gen_driftignore.go @@ -46,7 +46,6 @@ func NewGenDriftIgnoreCmd() *cobra.Command { fl.BoolVar(&opts.ExcludeUnmanaged, "exclude-unmanaged", false, "Exclude resources not managed by IaC") fl.BoolVar(&opts.ExcludeDeleted, "exclude-missing", false, "Exclude missing resources") - fl.BoolVar(&opts.ExcludeDrifted, "exclude-changed", false, "Exclude resources that changed on cloud provider") fl.StringVarP(&opts.InputPath, "input", "i", "-", "Input where the JSON should be parsed from. Defaults to stdin.") fl.StringVarP(&opts.OutputPath, "output", "o", ".driftignore", "Output file path to write the driftignore to.") diff --git a/pkg/cmd/gen_driftignore_test.go b/pkg/cmd/gen_driftignore_test.go index c7b53cca5..c50a3571b 100644 --- a/pkg/cmd/gen_driftignore_test.go +++ b/pkg/cmd/gen_driftignore_test.go @@ -37,15 +37,9 @@ func TestGenDriftIgnoreCmd_Input(t *testing.T) { output: "./testdata/output_stdin_valid.txt", err: nil, }, - { - name: "test driftignore content with valid input and filter missing & changed only", - args: []string{"-i", "./testdata/input_stdin_valid.json", "--exclude-unmanaged"}, - output: "./testdata/output_stdin_valid_filter.txt", - err: nil, - }, { name: "test driftignore content with valid input and filter unmanaged only", - args: []string{"-i", "./testdata/input_stdin_valid.json", "--exclude-missing", "--exclude-changed"}, + args: []string{"-i", "./testdata/input_stdin_valid.json", "--exclude-missing"}, output: "./testdata/output_stdin_valid_filter2.txt", err: nil, }, @@ -103,8 +97,7 @@ func TestGenDriftIgnoreCmd_ValidFlags(t *testing.T) { {args: []string{"gen-driftignore"}}, {args: []string{"gen-driftignore", "--exclude-unmanaged"}}, {args: []string{"gen-driftignore", "--exclude-missing"}}, - {args: []string{"gen-driftignore", "--exclude-changed"}}, - {args: []string{"gen-driftignore", "--exclude-changed=false", "--exclude-missing=false", "--exclude-unmanaged=true"}}, + {args: []string{"gen-driftignore", "--exclude-missing=false", "--exclude-unmanaged=true"}}, {args: []string{"gen-driftignore", "--input", "-"}}, {args: []string{"gen-driftignore", "-i", "/dev/stdout"}}, } diff --git a/pkg/cmd/scan.go b/pkg/cmd/scan.go index 50e300397..ca4efaa88 100644 --- a/pkg/cmd/scan.go +++ b/pkg/cmd/scan.go @@ -115,10 +115,6 @@ func NewScanCmd(opts *pkg.ScanOptions) *cobra.Command { opts.ConfigDir, _ = cmd.Flags().GetString("config-dir") - if onlyManaged, _ := cmd.Flags().GetBool("only-managed"); onlyManaged { - opts.Deep = true - } - return nil }, RunE: func(cmd *cobra.Command, args []string) error { @@ -205,12 +201,6 @@ func NewScanCmd(opts *pkg.ScanOptions) *cobra.Command { false, "Includes cloud provider service-linked roles (disabled by default)", ) - fl.BoolVar(&opts.Deep, - "deep", - false, - fmt.Sprintf("%s Enable deep mode\n", warn("EXPERIMENTAL:"))+ - "You should check the documentation for more details: https://docs.driftctl.com/deep-mode\n", - ) fl.StringVar(&opts.DriftignorePath, "driftignore", ".driftignore", @@ -238,15 +228,11 @@ func NewScanCmd(opts *pkg.ScanOptions) *cobra.Command { configDir, "Directory path that driftctl uses for configuration.\n", ) - fl.BoolVar(&opts.OnlyManaged, - "only-managed", - false, - "Report only what's managed by your IaC\n", - ) - fl.BoolVar(&opts.OnlyUnmanaged, + var deprecatedOnlyUnmanaged bool + fl.BoolVar(&deprecatedOnlyUnmanaged, "only-unmanaged", false, - "Report only what's not managed by your IaC\n", + fmt.Sprintf("%s Report only what's not managed by your IaC.\nThis option is a no-op as unmanaged is the only supported mode.\n", warn("DEPRECATED:")), ) return cmd @@ -320,7 +306,7 @@ func scanRun(opts *pkg.ScanOptions) error { driftIgnore := filter.NewDriftIgnore(opts.DriftignorePath, opts.Driftignores...) // TODO use enum library interface here - scanner := remote.NewScanner(remoteLibrary, alerter, remote.ScannerOptions{Deep: opts.Deep}, driftIgnore) + scanner := remote.NewScanner(remoteLibrary, alerter, driftIgnore) iacSupplier, err := supplier.GetIACSupplier(opts.From, providerLibrary, opts.BackendOptions, iacProgress, alerter, resFactory, driftIgnore) if err != nil { @@ -331,7 +317,7 @@ func scanRun(opts *pkg.ScanOptions) error { scanner, iacSupplier, alerter, - analyser.NewAnalyzer(alerter, analyser.AnalyzerOptions{Deep: opts.Deep, OnlyManaged: opts.OnlyManaged, OnlyUnmanaged: opts.OnlyUnmanaged}, driftIgnore), + analyser.NewAnalyzer(alerter, driftIgnore), resFactory, opts, scanProgress, diff --git a/pkg/cmd/scan/output/assets/index.tmpl b/pkg/cmd/scan/output/assets/index.tmpl index 44ab2112a..b7e12a796 100644 --- a/pkg/cmd/scan/output/assets/index.tmpl +++ b/pkg/cmd/scan/output/assets/index.tmpl @@ -77,12 +77,6 @@ Unmanaged Resources ({{len .Unmanaged}}) {{end}} - {{if (gt (len .Differences) 0)}} - - {{end}} {{if (gt (len .Deleted) 0)}}