From dcc0130237674e5f9d165ecade54ec17613cb405 Mon Sep 17 00:00:00 2001 From: sundowndev Date: Wed, 13 Oct 2021 17:37:27 +0200 Subject: [PATCH 1/2] feat: add google_compute_instance_group --- ...oogle_compute_instance_group_enumerator.go | 58 +++++++++ pkg/remote/google/init.go | 3 + pkg/remote/google/repository/asset.go | 19 ++- .../google/repository/mock_AssetRepository.go | 23 ++++ pkg/remote/google_compute_scanner_test.go | 123 ++++++++++++++++++ .../results.golden.json | 1 + .../terraform.tf | 12 ++ .../google/google_compute_instance_group.go | 22 ++++ pkg/resource/google/metadatas.go | 1 + pkg/resource/resource_types.go | 3 +- 10 files changed, 258 insertions(+), 7 deletions(-) create mode 100644 pkg/remote/google/google_compute_instance_group_enumerator.go create mode 100755 pkg/remote/test/google_compute_instance_group/results.golden.json create mode 100644 pkg/remote/test/google_compute_instance_group/terraform.tf create mode 100644 pkg/resource/google/google_compute_instance_group.go diff --git a/pkg/remote/google/google_compute_instance_group_enumerator.go b/pkg/remote/google/google_compute_instance_group_enumerator.go new file mode 100644 index 00000000..11beb6fb --- /dev/null +++ b/pkg/remote/google/google_compute_instance_group_enumerator.go @@ -0,0 +1,58 @@ +package google + +import ( + "strings" + + remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error" + "github.com/cloudskiff/driftctl/pkg/remote/google/repository" + "github.com/cloudskiff/driftctl/pkg/resource" + "github.com/cloudskiff/driftctl/pkg/resource/google" + "github.com/sirupsen/logrus" +) + +type GoogleComputeInstanceGroupEnumerator struct { + repository repository.AssetRepository + factory resource.ResourceFactory +} + +func NewGoogleComputeInstanceGroupEnumerator(repo repository.AssetRepository, factory resource.ResourceFactory) *GoogleComputeInstanceGroupEnumerator { + return &GoogleComputeInstanceGroupEnumerator{ + repository: repo, + factory: factory, + } +} + +func (e *GoogleComputeInstanceGroupEnumerator) SupportedType() resource.ResourceType { + return google.GoogleComputeInstanceGroupResourceType +} + +func (e *GoogleComputeInstanceGroupEnumerator) Enumerate() ([]*resource.Resource, error) { + groups, err := e.repository.SearchAllInstanceGroups() + if err != nil { + return nil, remoteerror.NewResourceListingError(err, string(e.SupportedType())) + } + + results := make([]*resource.Resource, 0, len(groups)) + for _, res := range groups { + splittedName := strings.Split(res.GetName(), "/") + if len(splittedName) != 9 { + logrus.WithField("name", res.GetName()).Error("Unable to decode project from instance group name") + continue + } + project := splittedName[4] + results = append( + results, + e.factory.CreateAbstractResource( + string(e.SupportedType()), + trimResourceName(res.GetName()), + map[string]interface{}{ + "display_name": res.GetDisplayName(), + "project": project, + "location": res.GetLocation(), + }, + ), + ) + } + + return results, err +} diff --git a/pkg/remote/google/init.go b/pkg/remote/google/init.go index c09ed9fe..b4100c50 100644 --- a/pkg/remote/google/init.go +++ b/pkg/remote/google/init.go @@ -69,6 +69,9 @@ func Init(version string, alerter *alerter.Alerter, remoteLibrary.AddEnumerator(NewGoogleDNSManagedZoneEnumerator(assetRepository, factory)) + remoteLibrary.AddEnumerator(NewGoogleComputeInstanceGroupEnumerator(assetRepository, factory)) + remoteLibrary.AddDetailsFetcher(google.GoogleComputeInstanceGroupResourceType, common.NewGenericDetailsFetcher(google.GoogleComputeInstanceGroupResourceType, provider, deserializer)) + err = resourceSchemaRepository.Init(terraform.GOOGLE, provider.Version(), provider.Schema()) if err != nil { return err diff --git a/pkg/remote/google/repository/asset.go b/pkg/remote/google/repository/asset.go index 6428ff1a..76f3cbe1 100644 --- a/pkg/remote/google/repository/asset.go +++ b/pkg/remote/google/repository/asset.go @@ -13,12 +13,13 @@ import ( // https://cloud.google.com/asset-inventory/docs/supported-asset-types#supported_resource_types const ( - storageBucketAssetType = "storage.googleapis.com/Bucket" - computeFirewallAssetType = "compute.googleapis.com/Firewall" - computeRouterAssetType = "compute.googleapis.com/Router" - computeInstanceAssetType = "compute.googleapis.com/Instance" - computeNetworkAssetType = "compute.googleapis.com/Network" - dnsManagedZoneAssetType = "dns.googleapis.com/ManagedZone" + storageBucketAssetType = "storage.googleapis.com/Bucket" + computeFirewallAssetType = "compute.googleapis.com/Firewall" + computeRouterAssetType = "compute.googleapis.com/Router" + computeInstanceAssetType = "compute.googleapis.com/Instance" + computeNetworkAssetType = "compute.googleapis.com/Network" + dnsManagedZoneAssetType = "dns.googleapis.com/ManagedZone" + computeInstanceGroupAssetType = "compute.googleapis.com/InstanceGroup" ) type AssetRepository interface { @@ -28,6 +29,7 @@ type AssetRepository interface { SearchAllInstances() ([]*assetpb.ResourceSearchResult, error) SearchAllNetworks() ([]*assetpb.ResourceSearchResult, error) SearchAllDNSManagedZones() ([]*assetpb.ResourceSearchResult, error) + SearchAllInstanceGroups() ([]*assetpb.ResourceSearchResult, error) } type assetRepository struct { @@ -54,6 +56,7 @@ func (s assetRepository) searchAllResources(ty string) ([]*assetpb.ResourceSearc computeInstanceAssetType, computeNetworkAssetType, dnsManagedZoneAssetType, + computeInstanceGroupAssetType, }, } var results []*assetpb.ResourceSearchResult @@ -113,3 +116,7 @@ func (s assetRepository) SearchAllNetworks() ([]*assetpb.ResourceSearchResult, e func (s assetRepository) SearchAllDNSManagedZones() ([]*assetpb.ResourceSearchResult, error) { return s.searchAllResources(dnsManagedZoneAssetType) } + +func (s assetRepository) SearchAllInstanceGroups() ([]*assetpb.ResourceSearchResult, error) { + return s.searchAllResources(computeInstanceGroupAssetType) +} diff --git a/pkg/remote/google/repository/mock_AssetRepository.go b/pkg/remote/google/repository/mock_AssetRepository.go index 8cda5e57..ae62d5f5 100644 --- a/pkg/remote/google/repository/mock_AssetRepository.go +++ b/pkg/remote/google/repository/mock_AssetRepository.go @@ -81,6 +81,29 @@ func (_m *MockAssetRepository) SearchAllFirewalls() ([]*asset.ResourceSearchResu return r0, r1 } +// SearchAllInstanceGroups provides a mock function with given fields: +func (_m *MockAssetRepository) SearchAllInstanceGroups() ([]*asset.ResourceSearchResult, error) { + ret := _m.Called() + + var r0 []*asset.ResourceSearchResult + if rf, ok := ret.Get(0).(func() []*asset.ResourceSearchResult); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*asset.ResourceSearchResult) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // SearchAllInstances provides a mock function with given fields: func (_m *MockAssetRepository) SearchAllInstances() ([]*asset.ResourceSearchResult, error) { ret := _m.Called() diff --git a/pkg/remote/google_compute_scanner_test.go b/pkg/remote/google_compute_scanner_test.go index 482ac216..cc084435 100644 --- a/pkg/remote/google_compute_scanner_test.go +++ b/pkg/remote/google_compute_scanner_test.go @@ -499,3 +499,126 @@ func TestGoogleComputeNetwork(t *testing.T) { }) } } + +func TestGoogleComputeInstanceGroup(t *testing.T) { + + cases := []struct { + test string + dirName string + response []*assetpb.ResourceSearchResult + responseErr error + setupAlerterMock func(alerter *mocks.AlerterInterface) + wantErr error + }{ + { + test: "no instance group", + dirName: "google_compute_instance_group_empty", + response: []*assetpb.ResourceSearchResult{}, + wantErr: nil, + }, + { + test: "multiple instance groups", + dirName: "google_compute_instance_group", + response: []*assetpb.ResourceSearchResult{ + { + AssetType: "compute.googleapis.com/InstanceGroup", + DisplayName: "driftctl-unittest-1", + Name: "//compute.googleapis.com/projects/driftctl-qa-1/zones/us-central1-a/instanceGroups/driftctl-unittest-1", + }, + { + AssetType: "compute.googleapis.com/InstanceGroup", + DisplayName: "driftctl-unittest-2", + Name: "//compute.googleapis.com/projects/driftctl-qa-1/zones/us-central1-a/instanceGroups/driftctl-unittest-2", + }, + { + AssetType: "compute.googleapis.com/InstanceGroup", + DisplayName: "driftctl-unittest-3", + Name: "//compute.googleapis.com/projects/driftctl-qa-1/zones/us-central1-a/instanceGroups/driftctl-unittest-3", + }, + }, + wantErr: nil, + }, + { + test: "cannot list instance groups", + dirName: "google_compute_instance_group_empty", + responseErr: status.Error(codes.PermissionDenied, "The caller does not have permission"), + setupAlerterMock: func(alerter *mocks.AlerterInterface) { + alerter.On( + "SendAlert", + "google_compute_instance_group", + alerts.NewRemoteAccessDeniedAlert( + common.RemoteGoogleTerraform, + remoteerr.NewResourceListingError( + status.Error(codes.PermissionDenied, "The caller does not have permission"), + "google_compute_instance_group", + ), + alerts.EnumerationPhase, + ), + ).Once() + }, + wantErr: nil, + }, + } + + providerVersion := "3.78.0" + resType := resource.ResourceType(googleresource.GoogleComputeInstanceGroupResourceType) + schemaRepository := testresource.InitFakeSchemaRepository("google", providerVersion) + googleresource.InitResourcesMetadata(schemaRepository) + factory := terraform.NewTerraformResourceFactory(schemaRepository) + 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() + + // Initialize mocks + alerter := &mocks.AlerterInterface{} + if c.setupAlerterMock != nil { + c.setupAlerterMock(alerter) + } + + assetClient, err := testgoogle.NewFakeAssetServer(c.response, c.responseErr) + if err != nil { + tt.Fatal(err) + } + + realProvider, err := terraform2.InitTestGoogleProvider(providerLibrary, providerVersion) + if err != nil { + tt.Fatal(err) + } + provider := terraform2.NewFakeTerraformProvider(realProvider) + provider.WithResponse(c.dirName) + + // Replace mock by real resources if we are in update mode + if shouldUpdate { + err = realProvider.Init() + if err != nil { + tt.Fatal(err) + } + provider.ShouldUpdate() + } + + 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 := &filter.MockFilter{} + testFilter.On("IsTypeIgnored", mock.Anything).Return(false) + + s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) + got, err := s.Resources() + assert.Equal(tt, err, c.wantErr) + if err != nil { + return + } + alerter.AssertExpectations(tt) + testFilter.AssertExpectations(tt) + test.TestAgainstGoldenFile(got, resType.String(), c.dirName, provider, deserializer, shouldUpdate, tt) + }) + } +} diff --git a/pkg/remote/test/google_compute_instance_group/results.golden.json b/pkg/remote/test/google_compute_instance_group/results.golden.json new file mode 100755 index 00000000..0637a088 --- /dev/null +++ b/pkg/remote/test/google_compute_instance_group/results.golden.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/pkg/remote/test/google_compute_instance_group/terraform.tf b/pkg/remote/test/google_compute_instance_group/terraform.tf new file mode 100644 index 00000000..4ee4da43 --- /dev/null +++ b/pkg/remote/test/google_compute_instance_group/terraform.tf @@ -0,0 +1,12 @@ +provider "google" {} + +resource "google_compute_network" "default" { + name = "test-network" +} + +resource "google_compute_instance_group" "test" { + name = "terraform-test" + description = "Terraform test instance group" + zone = "us-central1-a" + network = google_compute_network.default.id +} diff --git a/pkg/resource/google/google_compute_instance_group.go b/pkg/resource/google/google_compute_instance_group.go new file mode 100644 index 00000000..a4b29886 --- /dev/null +++ b/pkg/resource/google/google_compute_instance_group.go @@ -0,0 +1,22 @@ +package google + +import "github.com/cloudskiff/driftctl/pkg/resource" + +const GoogleComputeInstanceGroupResourceType = "google_compute_instance_group" + +func initGoogleComputeInstanceGroupMetadata(resourceSchemaRepository resource.SchemaRepositoryInterface) { + resourceSchemaRepository.SetResolveReadAttributesFunc(GoogleComputeInstanceGroupResourceType, func(res *resource.Resource) map[string]string { + return map[string]string{ + "name": *res.Attributes().GetString("display_name"), + "project": *res.Attributes().GetString("project"), + "zone": *res.Attributes().GetString("location"), + } + }) + resourceSchemaRepository.SetHumanReadableAttributesFunc(GoogleComputeInstanceGroupResourceType, func(res *resource.Resource) map[string]string { + attrs := make(map[string]string) + if v := res.Attributes().GetString("display_name"); v != nil && *v != "" { + attrs["Name"] = *v + } + return attrs + }) +} diff --git a/pkg/resource/google/metadatas.go b/pkg/resource/google/metadatas.go index f91fc5ed..c06bf728 100644 --- a/pkg/resource/google/metadatas.go +++ b/pkg/resource/google/metadatas.go @@ -8,4 +8,5 @@ func InitResourcesMetadata(resourceSchemaRepository resource.SchemaRepositoryInt initGoogleComputeRouterMetadata(resourceSchemaRepository) initGoogleComputeNetworkMetadata(resourceSchemaRepository) initGoogleStorageBucketIamBMemberMetadata(resourceSchemaRepository) + initGoogleComputeInstanceGroupMetadata(resourceSchemaRepository) } diff --git a/pkg/resource/resource_types.go b/pkg/resource/resource_types.go index a3df3373..525c9bd1 100644 --- a/pkg/resource/resource_types.go +++ b/pkg/resource/resource_types.go @@ -140,7 +140,8 @@ var supportedTypes = map[string]ResourceTypeMeta{ "google_storage_bucket_iam_policy": {children: []ResourceType{ "google_storage_bucket_iam_member", }}, - "google_dns_managed_zone": {}, + "google_dns_managed_zone": {}, + "google_compute_instance_group": {}, "azurerm_storage_account": {}, "azurerm_storage_container": {}, From c59c36a86c090ab240255ec2276a7bcc8abb90f1 Mon Sep 17 00:00:00 2001 From: sundowndev Date: Fri, 15 Oct 2021 15:54:30 +0200 Subject: [PATCH 2/2] test: google_compute_instance_group state reader tests --- pkg/remote/google_compute_scanner_test.go | 20 ++++++------- ...-dev-raphael-us-central1-a.res.golden.json | 5 ++++ ...-dev-raphael-us-central1-a.res.golden.json | 5 ++++ .../results.golden.json | 29 ++++++++++++++++++- .../terraform.tf | 19 ++++++++---- .../google/google_compute_instance_group.go | 3 ++ 6 files changed, 64 insertions(+), 17 deletions(-) create mode 100755 pkg/remote/test/google_compute_instance_group/google_compute_instance_group-projects_cloudskiff-dev-raphael_zones_us-central1-a_instanceGroups_driftctl-test-1-driftctl-test-1-cloudskiff-dev-raphael-us-central1-a.res.golden.json create mode 100755 pkg/remote/test/google_compute_instance_group/google_compute_instance_group-projects_cloudskiff-dev-raphael_zones_us-central1-a_instanceGroups_driftctl-test-2-driftctl-test-2-cloudskiff-dev-raphael-us-central1-a.res.golden.json diff --git a/pkg/remote/google_compute_scanner_test.go b/pkg/remote/google_compute_scanner_test.go index cc084435..52203271 100644 --- a/pkg/remote/google_compute_scanner_test.go +++ b/pkg/remote/google_compute_scanner_test.go @@ -522,18 +522,17 @@ func TestGoogleComputeInstanceGroup(t *testing.T) { response: []*assetpb.ResourceSearchResult{ { AssetType: "compute.googleapis.com/InstanceGroup", - DisplayName: "driftctl-unittest-1", - Name: "//compute.googleapis.com/projects/driftctl-qa-1/zones/us-central1-a/instanceGroups/driftctl-unittest-1", + DisplayName: "driftctl-test-1", + Name: "//compute.googleapis.com/projects/cloudskiff-dev-raphael/zones/us-central1-a/instanceGroups/driftctl-test-1", + Project: "cloudskiff-dev-raphael", + Location: "us-central1-a", }, { AssetType: "compute.googleapis.com/InstanceGroup", - DisplayName: "driftctl-unittest-2", - Name: "//compute.googleapis.com/projects/driftctl-qa-1/zones/us-central1-a/instanceGroups/driftctl-unittest-2", - }, - { - AssetType: "compute.googleapis.com/InstanceGroup", - DisplayName: "driftctl-unittest-3", - Name: "//compute.googleapis.com/projects/driftctl-qa-1/zones/us-central1-a/instanceGroups/driftctl-unittest-3", + DisplayName: "driftctl-test-2", + Name: "//compute.googleapis.com/projects/cloudskiff-dev-raphael/zones/us-central1-a/instanceGroups/driftctl-test-2", + Project: "cloudskiff-dev-raphael", + Location: "us-central1-a", }, }, wantErr: nil, @@ -612,10 +611,11 @@ func TestGoogleComputeInstanceGroup(t *testing.T) { s := NewScanner(remoteLibrary, alerter, scanOptions, testFilter) got, err := s.Resources() - assert.Equal(tt, err, c.wantErr) + assert.Equal(tt, c.wantErr, err) if err != nil { return } + alerter.AssertExpectations(tt) testFilter.AssertExpectations(tt) test.TestAgainstGoldenFile(got, resType.String(), c.dirName, provider, deserializer, shouldUpdate, tt) diff --git a/pkg/remote/test/google_compute_instance_group/google_compute_instance_group-projects_cloudskiff-dev-raphael_zones_us-central1-a_instanceGroups_driftctl-test-1-driftctl-test-1-cloudskiff-dev-raphael-us-central1-a.res.golden.json b/pkg/remote/test/google_compute_instance_group/google_compute_instance_group-projects_cloudskiff-dev-raphael_zones_us-central1-a_instanceGroups_driftctl-test-1-driftctl-test-1-cloudskiff-dev-raphael-us-central1-a.res.golden.json new file mode 100755 index 00000000..8e00315a --- /dev/null +++ b/pkg/remote/test/google_compute_instance_group/google_compute_instance_group-projects_cloudskiff-dev-raphael_zones_us-central1-a_instanceGroups_driftctl-test-1-driftctl-test-1-cloudskiff-dev-raphael-us-central1-a.res.golden.json @@ -0,0 +1,5 @@ +{ + "Typ": "WyJvYmplY3QiLHsiZGVzY3JpcHRpb24iOiJzdHJpbmciLCJpZCI6InN0cmluZyIsImluc3RhbmNlcyI6WyJzZXQiLCJzdHJpbmciXSwibmFtZSI6InN0cmluZyIsIm5hbWVkX3BvcnQiOlsibGlzdCIsWyJvYmplY3QiLHsibmFtZSI6InN0cmluZyIsInBvcnQiOiJudW1iZXIifV1dLCJuZXR3b3JrIjoic3RyaW5nIiwicHJvamVjdCI6InN0cmluZyIsInNlbGZfbGluayI6InN0cmluZyIsInNpemUiOiJudW1iZXIiLCJ0aW1lb3V0cyI6WyJvYmplY3QiLHsiY3JlYXRlIjoic3RyaW5nIiwiZGVsZXRlIjoic3RyaW5nIiwidXBkYXRlIjoic3RyaW5nIn1dLCJ6b25lIjoic3RyaW5nIn1d", + "Val": "eyJkZXNjcmlwdGlvbiI6IlRlcnJhZm9ybSB0ZXN0IGluc3RhbmNlIGdyb3VwIiwiaWQiOiJwcm9qZWN0cy9jbG91ZHNraWZmLWRldi1yYXBoYWVsL3pvbmVzL3VzLWNlbnRyYWwxLWEvaW5zdGFuY2VHcm91cHMvZHJpZnRjdGwtdGVzdC0xIiwiaW5zdGFuY2VzIjpbXSwibmFtZSI6ImRyaWZ0Y3RsLXRlc3QtMSIsIm5hbWVkX3BvcnQiOltdLCJuZXR3b3JrIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vY29tcHV0ZS92MS9wcm9qZWN0cy9jbG91ZHNraWZmLWRldi1yYXBoYWVsL2dsb2JhbC9uZXR3b3Jrcy90ZXN0LW5ldHdvcmsiLCJwcm9qZWN0IjoiY2xvdWRza2lmZi1kZXYtcmFwaGFlbCIsInNlbGZfbGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2NvbXB1dGUvdjEvcHJvamVjdHMvY2xvdWRza2lmZi1kZXYtcmFwaGFlbC96b25lcy91cy1jZW50cmFsMS1hL2luc3RhbmNlR3JvdXBzL2RyaWZ0Y3RsLXRlc3QtMSIsInNpemUiOjAsInRpbWVvdXRzIjp7ImNyZWF0ZSI6bnVsbCwiZGVsZXRlIjpudWxsLCJ1cGRhdGUiOm51bGx9LCJ6b25lIjoidXMtY2VudHJhbDEtYSJ9", + "Err": null +} \ No newline at end of file diff --git a/pkg/remote/test/google_compute_instance_group/google_compute_instance_group-projects_cloudskiff-dev-raphael_zones_us-central1-a_instanceGroups_driftctl-test-2-driftctl-test-2-cloudskiff-dev-raphael-us-central1-a.res.golden.json b/pkg/remote/test/google_compute_instance_group/google_compute_instance_group-projects_cloudskiff-dev-raphael_zones_us-central1-a_instanceGroups_driftctl-test-2-driftctl-test-2-cloudskiff-dev-raphael-us-central1-a.res.golden.json new file mode 100755 index 00000000..99bf7813 --- /dev/null +++ b/pkg/remote/test/google_compute_instance_group/google_compute_instance_group-projects_cloudskiff-dev-raphael_zones_us-central1-a_instanceGroups_driftctl-test-2-driftctl-test-2-cloudskiff-dev-raphael-us-central1-a.res.golden.json @@ -0,0 +1,5 @@ +{ + "Typ": "WyJvYmplY3QiLHsiZGVzY3JpcHRpb24iOiJzdHJpbmciLCJpZCI6InN0cmluZyIsImluc3RhbmNlcyI6WyJzZXQiLCJzdHJpbmciXSwibmFtZSI6InN0cmluZyIsIm5hbWVkX3BvcnQiOlsibGlzdCIsWyJvYmplY3QiLHsibmFtZSI6InN0cmluZyIsInBvcnQiOiJudW1iZXIifV1dLCJuZXR3b3JrIjoic3RyaW5nIiwicHJvamVjdCI6InN0cmluZyIsInNlbGZfbGluayI6InN0cmluZyIsInNpemUiOiJudW1iZXIiLCJ0aW1lb3V0cyI6WyJvYmplY3QiLHsiY3JlYXRlIjoic3RyaW5nIiwiZGVsZXRlIjoic3RyaW5nIiwidXBkYXRlIjoic3RyaW5nIn1dLCJ6b25lIjoic3RyaW5nIn1d", + "Val": "eyJkZXNjcmlwdGlvbiI6IlRlcnJhZm9ybSB0ZXN0IGluc3RhbmNlIGdyb3VwIiwiaWQiOiJwcm9qZWN0cy9jbG91ZHNraWZmLWRldi1yYXBoYWVsL3pvbmVzL3VzLWNlbnRyYWwxLWEvaW5zdGFuY2VHcm91cHMvZHJpZnRjdGwtdGVzdC0yIiwiaW5zdGFuY2VzIjpbXSwibmFtZSI6ImRyaWZ0Y3RsLXRlc3QtMiIsIm5hbWVkX3BvcnQiOltdLCJuZXR3b3JrIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vY29tcHV0ZS92MS9wcm9qZWN0cy9jbG91ZHNraWZmLWRldi1yYXBoYWVsL2dsb2JhbC9uZXR3b3Jrcy90ZXN0LW5ldHdvcmsiLCJwcm9qZWN0IjoiY2xvdWRza2lmZi1kZXYtcmFwaGFlbCIsInNlbGZfbGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2NvbXB1dGUvdjEvcHJvamVjdHMvY2xvdWRza2lmZi1kZXYtcmFwaGFlbC96b25lcy91cy1jZW50cmFsMS1hL2luc3RhbmNlR3JvdXBzL2RyaWZ0Y3RsLXRlc3QtMiIsInNpemUiOjAsInRpbWVvdXRzIjp7ImNyZWF0ZSI6bnVsbCwiZGVsZXRlIjpudWxsLCJ1cGRhdGUiOm51bGx9LCJ6b25lIjoidXMtY2VudHJhbDEtYSJ9", + "Err": null +} \ No newline at end of file diff --git a/pkg/remote/test/google_compute_instance_group/results.golden.json b/pkg/remote/test/google_compute_instance_group/results.golden.json index 0637a088..cc28d15f 100755 --- a/pkg/remote/test/google_compute_instance_group/results.golden.json +++ b/pkg/remote/test/google_compute_instance_group/results.golden.json @@ -1 +1,28 @@ -[] \ No newline at end of file +[ + { + "description": "Terraform test instance group", + "id": "projects/cloudskiff-dev-raphael/zones/us-central1-a/instanceGroups/driftctl-test-2", + "instances": null, + "name": "driftctl-test-2", + "named_port": null, + "network": "https://www.googleapis.com/compute/v1/projects/cloudskiff-dev-raphael/global/networks/test-network", + "project": "cloudskiff-dev-raphael", + "self_link": "https://www.googleapis.com/compute/v1/projects/cloudskiff-dev-raphael/zones/us-central1-a/instanceGroups/driftctl-test-2", + "size": 0, + "timeouts": null, + "zone": "us-central1-a" + }, + { + "description": "Terraform test instance group", + "id": "projects/cloudskiff-dev-raphael/zones/us-central1-a/instanceGroups/driftctl-test-1", + "instances": null, + "name": "driftctl-test-1", + "named_port": null, + "network": "https://www.googleapis.com/compute/v1/projects/cloudskiff-dev-raphael/global/networks/test-network", + "project": "cloudskiff-dev-raphael", + "self_link": "https://www.googleapis.com/compute/v1/projects/cloudskiff-dev-raphael/zones/us-central1-a/instanceGroups/driftctl-test-1", + "size": 0, + "timeouts": null, + "zone": "us-central1-a" + } +] \ No newline at end of file diff --git a/pkg/remote/test/google_compute_instance_group/terraform.tf b/pkg/remote/test/google_compute_instance_group/terraform.tf index 4ee4da43..832e5c97 100644 --- a/pkg/remote/test/google_compute_instance_group/terraform.tf +++ b/pkg/remote/test/google_compute_instance_group/terraform.tf @@ -1,12 +1,19 @@ provider "google" {} resource "google_compute_network" "default" { - name = "test-network" + name = "test-network" } -resource "google_compute_instance_group" "test" { - name = "terraform-test" - description = "Terraform test instance group" - zone = "us-central1-a" - network = google_compute_network.default.id +resource "google_compute_instance_group" "test-1" { + name = "driftctl-test-1" + description = "Terraform test instance group" + zone = "us-central1-a" + network = google_compute_network.default.id +} + +resource "google_compute_instance_group" "test-2" { + name = "driftctl-test-2" + description = "Terraform test instance group" + zone = "us-central1-a" + network = google_compute_network.default.id } diff --git a/pkg/resource/google/google_compute_instance_group.go b/pkg/resource/google/google_compute_instance_group.go index a4b29886..bb4ce1bb 100644 --- a/pkg/resource/google/google_compute_instance_group.go +++ b/pkg/resource/google/google_compute_instance_group.go @@ -5,6 +5,9 @@ import "github.com/cloudskiff/driftctl/pkg/resource" const GoogleComputeInstanceGroupResourceType = "google_compute_instance_group" func initGoogleComputeInstanceGroupMetadata(resourceSchemaRepository resource.SchemaRepositoryInterface) { + resourceSchemaRepository.SetNormalizeFunc(GoogleComputeInstanceGroupResourceType, func(res *resource.Resource) { + res.Attributes().SafeDelete([]string{"timeouts"}) + }) resourceSchemaRepository.SetResolveReadAttributesFunc(GoogleComputeInstanceGroupResourceType, func(res *resource.Resource) map[string]string { return map[string]string{ "name": *res.Attributes().GetString("display_name"),