From d74e855c35139c1ee04eaf1cc8b7468654f7f603 Mon Sep 17 00:00:00 2001 From: William Beuil Date: Wed, 16 Mar 2022 17:48:48 +0100 Subject: [PATCH] feat: add google_compute_forwarding_rule resource --- .../state/terraform_state_reader_test.go | 1 + .../results.golden.json | 29 +++++ .../terraform.tfstate | 52 +++++++++ ...ogle_compute_forwarding_rule_enumerator.go | 45 ++++++++ pkg/remote/google/init.go | 1 + pkg/remote/google/repository/asset.go | 49 ++++---- .../google/repository/mock_AssetRepository.go | 25 +++- pkg/remote/google_compute_scanner_test.go | 109 ++++++++++++++++++ .../google/google_compute_forwarding_rule.go | 3 + .../google_compute_forwarding_rule_test.go | 30 +++++ pkg/resource/google/metadata_test.go | 1 + .../.driftignore | 2 + .../.terraform.lock.hcl | 21 ++++ .../terraform.tf | 22 ++++ pkg/resource/resource_types.go | 1 + 15 files changed, 369 insertions(+), 22 deletions(-) create mode 100755 pkg/iac/terraform/state/test/google_compute_forwarding_rule/results.golden.json create mode 100644 pkg/iac/terraform/state/test/google_compute_forwarding_rule/terraform.tfstate create mode 100644 pkg/remote/google/google_compute_forwarding_rule_enumerator.go create mode 100644 pkg/resource/google/google_compute_forwarding_rule.go create mode 100644 pkg/resource/google/google_compute_forwarding_rule_test.go create mode 100644 pkg/resource/google/testdata/acc/google_compute_forwarding_rule/.driftignore create mode 100644 pkg/resource/google/testdata/acc/google_compute_forwarding_rule/.terraform.lock.hcl create mode 100644 pkg/resource/google/testdata/acc/google_compute_forwarding_rule/terraform.tf diff --git a/pkg/iac/terraform/state/terraform_state_reader_test.go b/pkg/iac/terraform/state/terraform_state_reader_test.go index d5658f4b..004cf802 100644 --- a/pkg/iac/terraform/state/terraform_state_reader_test.go +++ b/pkg/iac/terraform/state/terraform_state_reader_test.go @@ -377,6 +377,7 @@ func TestTerraformStateReader_Google_Resources(t *testing.T) { {name: "health check", dirName: "google_compute_health_check", wantErr: false}, {name: "cloudrun service", dirName: "google_cloudrun_service", wantErr: false}, {name: "compute node group", dirName: "google_compute_node_group", wantErr: false}, + {name: "compute forwarding rule", dirName: "google_compute_forwarding_rule", wantErr: false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/iac/terraform/state/test/google_compute_forwarding_rule/results.golden.json b/pkg/iac/terraform/state/test/google_compute_forwarding_rule/results.golden.json new file mode 100755 index 00000000..7dc4d5d9 --- /dev/null +++ b/pkg/iac/terraform/state/test/google_compute_forwarding_rule/results.golden.json @@ -0,0 +1,29 @@ +[ + { + "Id": "projects/cloudskiff-dev-william/regions/us-east1/forwardingRules/website-forwarding-rule", + "Type": "google_compute_forwarding_rule", + "Attrs": { + "all_ports": false, + "allow_global_access": false, + "backend_service": "", + "creation_timestamp": "2022-03-16T08:39:19.861-07:00", + "description": "", + "id": "projects/cloudskiff-dev-william/regions/us-east1/forwardingRules/website-forwarding-rule", + "ip_address": "35.231.108.206", + "ip_protocol": "TCP", + "is_mirroring_collector": false, + "load_balancing_scheme": "EXTERNAL", + "name": "website-forwarding-rule", + "network": "", + "network_tier": "PREMIUM", + "port_range": "80", + "project": "cloudskiff-dev-william", + "region": "us-east1", + "self_link": "https://www.googleapis.com/compute/v1/projects/cloudskiff-dev-william/regions/us-east1/forwardingRules/website-forwarding-rule", + "service_label": "", + "service_name": "", + "subnetwork": "", + "target": "projects/cloudskiff-dev-william/regions/us-east1/targetPools/website-target-pool" + } + } +] \ No newline at end of file diff --git a/pkg/iac/terraform/state/test/google_compute_forwarding_rule/terraform.tfstate b/pkg/iac/terraform/state/test/google_compute_forwarding_rule/terraform.tfstate new file mode 100644 index 00000000..c6c6703d --- /dev/null +++ b/pkg/iac/terraform/state/test/google_compute_forwarding_rule/terraform.tfstate @@ -0,0 +1,52 @@ +{ + "version": 4, + "terraform_version": "1.1.6", + "serial": 3, + "lineage": "6916ae73-3f18-ff08-09f4-2f925afcfc7f", + "outputs": {}, + "resources": [ + { + "mode": "managed", + "type": "google_compute_forwarding_rule", + "name": "default", + "provider": "provider[\"registry.terraform.io/hashicorp/google\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "all_ports": false, + "allow_global_access": false, + "backend_service": "", + "creation_timestamp": "2022-03-16T08:39:19.861-07:00", + "description": "", + "id": "projects/cloudskiff-dev-william/regions/us-east1/forwardingRules/website-forwarding-rule", + "ip_address": "35.231.108.206", + "ip_protocol": "TCP", + "is_mirroring_collector": false, + "label_fingerprint": "42WmSpB8rSM=", + "labels": null, + "load_balancing_scheme": "EXTERNAL", + "name": "website-forwarding-rule", + "network": "", + "network_tier": "PREMIUM", + "port_range": "80", + "ports": null, + "project": "cloudskiff-dev-william", + "region": "us-east1", + "self_link": "https://www.googleapis.com/compute/v1/projects/cloudskiff-dev-william/regions/us-east1/forwardingRules/website-forwarding-rule", + "service_label": "", + "service_name": "", + "subnetwork": "", + "target": "projects/cloudskiff-dev-william/regions/us-east1/targetPools/website-target-pool", + "timeouts": null + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjEyMDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19", + "dependencies": [ + "google_compute_target_pool.default" + ] + } + ] + } + ] +} diff --git a/pkg/remote/google/google_compute_forwarding_rule_enumerator.go b/pkg/remote/google/google_compute_forwarding_rule_enumerator.go new file mode 100644 index 00000000..99561491 --- /dev/null +++ b/pkg/remote/google/google_compute_forwarding_rule_enumerator.go @@ -0,0 +1,45 @@ +package google + +import ( + remoteerror "github.com/snyk/driftctl/pkg/remote/error" + "github.com/snyk/driftctl/pkg/remote/google/repository" + "github.com/snyk/driftctl/pkg/resource" + "github.com/snyk/driftctl/pkg/resource/google" +) + +type GoogleComputeForwardingRuleEnumerator struct { + repository repository.AssetRepository + factory resource.ResourceFactory +} + +func NewGoogleComputeForwardingRuleEnumerator(repo repository.AssetRepository, factory resource.ResourceFactory) *GoogleComputeForwardingRuleEnumerator { + return &GoogleComputeForwardingRuleEnumerator{ + repository: repo, + factory: factory, + } +} + +func (e *GoogleComputeForwardingRuleEnumerator) SupportedType() resource.ResourceType { + return google.GoogleComputeForwardingRuleResourceType +} + +func (e *GoogleComputeForwardingRuleEnumerator) Enumerate() ([]*resource.Resource, error) { + forwardingRules, err := e.repository.SearchAllForwardingRules() + if err != nil { + return nil, remoteerror.NewResourceListingError(err, string(e.SupportedType())) + } + + results := make([]*resource.Resource, 0, len(forwardingRules)) + for _, res := range forwardingRules { + results = append( + results, + e.factory.CreateAbstractResource( + string(e.SupportedType()), + trimResourceName(res.GetName()), + map[string]interface{}{}, + ), + ) + } + + return results, err +} diff --git a/pkg/remote/google/init.go b/pkg/remote/google/init.go index 6e7646a4..a7df696c 100644 --- a/pkg/remote/google/init.go +++ b/pkg/remote/google/init.go @@ -99,6 +99,7 @@ func Init(version string, alerter *alerter.Alerter, remoteLibrary.AddEnumerator(NewGoogleComputeHealthCheckEnumerator(assetRepository, factory)) remoteLibrary.AddEnumerator(NewGoogleCloudRunServiceEnumerator(assetRepository, factory)) remoteLibrary.AddEnumerator(NewGoogleComputeNodeGroupEnumerator(assetRepository, factory)) + remoteLibrary.AddEnumerator(NewGoogleComputeForwardingRuleEnumerator(assetRepository, factory)) err = resourceSchemaRepository.Init(terraform.GOOGLE, provider.Version(), provider.Schema()) if err != nil { diff --git a/pkg/remote/google/repository/asset.go b/pkg/remote/google/repository/asset.go index ff3b96a2..cbb8cd72 100644 --- a/pkg/remote/google/repository/asset.go +++ b/pkg/remote/google/repository/asset.go @@ -13,27 +13,28 @@ 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" - computeSubnetworkAssetType = "compute.googleapis.com/Subnetwork" - computeDiskAssetType = "compute.googleapis.com/Disk" - computeImageAssetType = "compute.googleapis.com/Image" - dnsManagedZoneAssetType = "dns.googleapis.com/ManagedZone" - computeInstanceGroupAssetType = "compute.googleapis.com/InstanceGroup" - bigqueryDatasetAssetType = "bigquery.googleapis.com/Dataset" - bigqueryTableAssetType = "bigquery.googleapis.com/Table" - computeAddressAssetType = "compute.googleapis.com/Address" - computeGlobalAddressAssetType = "compute.googleapis.com/GlobalAddress" - cloudFunctionsFunction = "cloudfunctions.googleapis.com/CloudFunction" - bigtableInstanceAssetType = "bigtableadmin.googleapis.com/Instance" - bigtableTableAssetType = "bigtableadmin.googleapis.com/Table" - sqlDatabaseInstanceAssetType = "sqladmin.googleapis.com/Instance" - healthCheckAssetType = "compute.googleapis.com/HealthCheck" - cloudRunServiceAssetType = "run.googleapis.com/Service" - nodeGroupAssetType = "compute.googleapis.com/NodeGroup" + 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" + computeSubnetworkAssetType = "compute.googleapis.com/Subnetwork" + computeDiskAssetType = "compute.googleapis.com/Disk" + computeImageAssetType = "compute.googleapis.com/Image" + dnsManagedZoneAssetType = "dns.googleapis.com/ManagedZone" + computeInstanceGroupAssetType = "compute.googleapis.com/InstanceGroup" + bigqueryDatasetAssetType = "bigquery.googleapis.com/Dataset" + bigqueryTableAssetType = "bigquery.googleapis.com/Table" + computeAddressAssetType = "compute.googleapis.com/Address" + computeGlobalAddressAssetType = "compute.googleapis.com/GlobalAddress" + cloudFunctionsFunction = "cloudfunctions.googleapis.com/CloudFunction" + bigtableInstanceAssetType = "bigtableadmin.googleapis.com/Instance" + bigtableTableAssetType = "bigtableadmin.googleapis.com/Table" + sqlDatabaseInstanceAssetType = "sqladmin.googleapis.com/Instance" + healthCheckAssetType = "compute.googleapis.com/HealthCheck" + cloudRunServiceAssetType = "run.googleapis.com/Service" + nodeGroupAssetType = "compute.googleapis.com/NodeGroup" + computeForwardingRuleAssetType = "compute.googleapis.com/ForwardingRule" ) type AssetRepository interface { @@ -58,6 +59,7 @@ type AssetRepository interface { SearchAllHealthChecks() ([]*assetpb.ResourceSearchResult, error) SearchAllCloudRunServices() ([]*assetpb.ResourceSearchResult, error) SearchAllNodeGroups() ([]*assetpb.Asset, error) + SearchAllForwardingRules() ([]*assetpb.Asset, error) } type assetRepository struct { @@ -85,6 +87,7 @@ func (s assetRepository) listAllResources(ty string) ([]*assetpb.Asset, error) { sqlDatabaseInstanceAssetType, computeGlobalAddressAssetType, nodeGroupAssetType, + computeForwardingRuleAssetType, }, } var results []*assetpb.Asset @@ -259,3 +262,7 @@ func (s assetRepository) SearchAllCloudRunServices() ([]*assetpb.ResourceSearchR func (s assetRepository) SearchAllNodeGroups() ([]*assetpb.Asset, error) { return s.listAllResources(nodeGroupAssetType) } + +func (s assetRepository) SearchAllForwardingRules() ([]*assetpb.Asset, error) { + return s.listAllResources(computeForwardingRuleAssetType) +} diff --git a/pkg/remote/google/repository/mock_AssetRepository.go b/pkg/remote/google/repository/mock_AssetRepository.go index db6f347d..4076a84e 100644 --- a/pkg/remote/google/repository/mock_AssetRepository.go +++ b/pkg/remote/google/repository/mock_AssetRepository.go @@ -1,4 +1,4 @@ -// Code generated by mockery v0.0.0-dev. DO NOT EDIT. +// Code generated by mockery v2.9.4. DO NOT EDIT. package repository @@ -219,6 +219,29 @@ func (_m *MockAssetRepository) SearchAllFirewalls() ([]*asset.ResourceSearchResu return r0, r1 } +// SearchAllForwardingRules provides a mock function with given fields: +func (_m *MockAssetRepository) SearchAllForwardingRules() ([]*asset.Asset, error) { + ret := _m.Called() + + var r0 []*asset.Asset + if rf, ok := ret.Get(0).(func() []*asset.Asset); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*asset.Asset) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // SearchAllFunctions provides a mock function with given fields: func (_m *MockAssetRepository) SearchAllFunctions() ([]*asset.Asset, error) { ret := _m.Called() diff --git a/pkg/remote/google_compute_scanner_test.go b/pkg/remote/google_compute_scanner_test.go index c0b35bbe..10daefab 100644 --- a/pkg/remote/google_compute_scanner_test.go +++ b/pkg/remote/google_compute_scanner_test.go @@ -1433,3 +1433,112 @@ func TestGoogleComputeNodeGroup(t *testing.T) { }) } } + +func TestGoogleComputeForwardingRule(t *testing.T) { + cases := []struct { + test string + assertExpected func(t *testing.T, got []*resource.Resource) + response []*assetpb.Asset + responseErr error + setupAlerterMock func(alerter *mocks.AlerterInterface) + wantErr error + }{ + { + test: "no compute forwarding rules", + response: []*assetpb.Asset{}, + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, + }, + { + test: "multiple compute forwarding rules", + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 2) + assert.Equal(t, "projects/cloudskiff-dev-william/regions/us-east1/forwardingRules/foo", got[0].ResourceId()) + assert.Equal(t, "google_compute_forwarding_rule", got[0].ResourceType()) + + assert.Equal(t, "projects/cloudskiff-dev-william/regions/us-east1/forwardingRules/bar", got[1].ResourceId()) + assert.Equal(t, "google_compute_forwarding_rule", got[1].ResourceType()) + }, + response: []*assetpb.Asset{ + { + AssetType: "compute.googleapis.com/ForwardingRule", + Name: "//compute.googleapis.com/projects/cloudskiff-dev-william/regions/us-east1/forwardingRules/foo", + }, + { + AssetType: "compute.googleapis.com/ForwardingRule", + Name: "//compute.googleapis.com/projects/cloudskiff-dev-william/regions/us-east1/forwardingRules/bar", + }, + }, + }, + { + test: "cannot list compute forwarding rules", + assertExpected: func(t *testing.T, got []*resource.Resource) { + assert.Len(t, got, 0) + }, + responseErr: status.Error(codes.PermissionDenied, "The caller does not have permission"), + setupAlerterMock: func(alerter *mocks.AlerterInterface) { + alerter.On( + "SendAlert", + "google_compute_forwarding_rule", + alerts.NewRemoteAccessDeniedAlert( + common.RemoteGoogleTerraform, + remoteerr.NewResourceListingError( + status.Error(codes.PermissionDenied, "The caller does not have permission"), + "google_compute_forwarding_rule", + ), + alerts.EnumerationPhase, + ), + ).Once() + }, + }, + } + + providerVersion := "3.78.0" + schemaRepository := testresource.InitFakeSchemaRepository(terraform.GOOGLE, providerVersion) + googleresource.InitResourcesMetadata(schemaRepository) + factory := terraform.NewTerraformResourceFactory(schemaRepository) + + for _, c := range cases { + t.Run(c.test, func(tt *testing.T) { + scanOptions := ScannerOptions{} + providerLibrary := terraform.NewProviderLibrary() + remoteLibrary := common.NewRemoteLibrary() + + // Initialize mocks + alerter := &mocks.AlerterInterface{} + if c.setupAlerterMock != nil { + c.setupAlerterMock(alerter) + } + + assetClient, err := testgoogle.NewFakeAssertServerWithList(c.response, c.responseErr) + if err != nil { + tt.Fatal(err) + } + + realProvider, err := terraform2.InitTestGoogleProvider(providerLibrary, providerVersion) + if err != nil { + tt.Fatal(err) + } + + repo := repository.NewAssetRepository(assetClient, realProvider.GetConfig(), cache.New(0)) + + remoteLibrary.AddEnumerator(google.NewGoogleComputeForwardingRuleEnumerator(repo, factory)) + + 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) + if c.assertExpected != nil { + c.assertExpected(t, got) + } + }) + } +} diff --git a/pkg/resource/google/google_compute_forwarding_rule.go b/pkg/resource/google/google_compute_forwarding_rule.go new file mode 100644 index 00000000..f02afb53 --- /dev/null +++ b/pkg/resource/google/google_compute_forwarding_rule.go @@ -0,0 +1,3 @@ +package google + +const GoogleComputeForwardingRuleResourceType = "google_compute_forwarding_rule" diff --git a/pkg/resource/google/google_compute_forwarding_rule_test.go b/pkg/resource/google/google_compute_forwarding_rule_test.go new file mode 100644 index 00000000..fc2638e0 --- /dev/null +++ b/pkg/resource/google/google_compute_forwarding_rule_test.go @@ -0,0 +1,30 @@ +package google_test + +import ( + "testing" + + "github.com/snyk/driftctl/test" + "github.com/snyk/driftctl/test/acceptance" +) + +func TestAcc_Google_ComputeForwardingRule(t *testing.T) { + acceptance.Run(t, acceptance.AccTestCase{ + TerraformVersion: "0.15.5", + Paths: []string{"./testdata/acc/google_compute_forwarding_rule"}, + Args: []string{ + "scan", + "--to", "gcp+tf", + }, + Checks: []acceptance.AccCheck{ + { + Check: func(result *test.ScanResult, stdout string, err error) { + if err != nil { + t.Fatal(err) + } + result.AssertInfrastructureIsInSync() + result.AssertManagedCount(1) + }, + }, + }, + }) +} diff --git a/pkg/resource/google/metadata_test.go b/pkg/resource/google/metadata_test.go index 41c32973..88fd4174 100644 --- a/pkg/resource/google/metadata_test.go +++ b/pkg/resource/google/metadata_test.go @@ -31,6 +31,7 @@ func TestGoogle_Metadata_Flags(t *testing.T) { GoogleComputeGlobalAddressResourceType: {}, GoogleCloudRunServiceResourceType: {}, GoogleComputeNodeGroupResourceType: {}, + GoogleComputeForwardingRuleResourceType: {}, } schemaRepository := testresource.InitFakeSchemaRepository(tf.GOOGLE, "3.78.0") diff --git a/pkg/resource/google/testdata/acc/google_compute_forwarding_rule/.driftignore b/pkg/resource/google/testdata/acc/google_compute_forwarding_rule/.driftignore new file mode 100644 index 00000000..f17dc5bd --- /dev/null +++ b/pkg/resource/google/testdata/acc/google_compute_forwarding_rule/.driftignore @@ -0,0 +1,2 @@ +* +!google_compute_forwarding_rule diff --git a/pkg/resource/google/testdata/acc/google_compute_forwarding_rule/.terraform.lock.hcl b/pkg/resource/google/testdata/acc/google_compute_forwarding_rule/.terraform.lock.hcl new file mode 100644 index 00000000..fe112068 --- /dev/null +++ b/pkg/resource/google/testdata/acc/google_compute_forwarding_rule/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "3.78.0" + constraints = "3.78.0" + hashes = [ + "h1:Seut9gKb/KzzUMxa9Qo59LRWcgURfBWMarqNTRjxnXE=", + "zh:027971c4689b6130619827fe57ce260aaca060db3446817d3a92869dba7cc07f", + "zh:0876dbecc0d441bf2479edd17fe9141d77274b5071ea5f68ac26a2994bff66f3", + "zh:2a5363ed6b1b880f5284e604567cfdabecca809584c30bbe7f19ff568d1ea4cd", + "zh:2f5af69b70654bda91199f6393253e3e479107deebfeddc3fe5850b3a1e83dfb", + "zh:52e6816ef11f5f799a6626dfff384e2153b37450d8320f1ef1eee8f71a2a87b2", + "zh:59ae534607db13db35c0015c06d1ae6d4886f01f7e8fd4e07bc120236a01c494", + "zh:65ab2ed1746ea02d0b1bbd8a22ff3a95d09dc8bdb3841fbc17e45e9feccfb327", + "zh:877a71d24ff65ede3f0c5973168acfeaea0f2fea3757cab5600efcddfd3171d5", + "zh:8b10c9643a4a53148f6758bfd60804b33c2b838482f2c39ed210b729e6b1e2e8", + "zh:ba682648d9f6c11a6d04a250ac79eec39271f615f3ff60c5ae73ebfcc2cdb450", + "zh:e946561921e0279450e9b9f705de9354ce35562ed4cc0d4cd3512aa9eb1f6486", + ] +} diff --git a/pkg/resource/google/testdata/acc/google_compute_forwarding_rule/terraform.tf b/pkg/resource/google/testdata/acc/google_compute_forwarding_rule/terraform.tf new file mode 100644 index 00000000..e202df04 --- /dev/null +++ b/pkg/resource/google/testdata/acc/google_compute_forwarding_rule/terraform.tf @@ -0,0 +1,22 @@ +provider "google" { + region = "us-east1" +} + +terraform { + required_version = "~> 0.15.0" + required_providers { + google = { + version = "3.78.0" + } + } +} + +resource "google_compute_forwarding_rule" "default" { + name = "foo-forwarding-rule" + target = google_compute_target_pool.default.id + port_range = "80" +} + +resource "google_compute_target_pool" "default" { + name = "foo-target-pool" +} diff --git a/pkg/resource/resource_types.go b/pkg/resource/resource_types.go index e3a7fca1..1d7ed721 100644 --- a/pkg/resource/resource_types.go +++ b/pkg/resource/resource_types.go @@ -198,6 +198,7 @@ var supportedTypes = map[string]ResourceTypeMeta{ "google_compute_global_address": {}, "google_compute_node_group": {}, "google_cloud_run_service": {}, + "google_compute_forwarding_rule": {}, "azurerm_storage_account": {}, "azurerm_storage_container": {},