Merge pull request #1136 from cloudskiff/feat/add_google_compute_instance_group
Add google_compute_instance_groupmain
commit
6932d8b346
|
@ -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
|
||||||
|
}
|
|
@ -69,6 +69,9 @@ func Init(version string, alerter *alerter.Alerter,
|
||||||
|
|
||||||
remoteLibrary.AddEnumerator(NewGoogleDNSManagedZoneEnumerator(assetRepository, factory))
|
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())
|
err = resourceSchemaRepository.Init(terraform.GOOGLE, provider.Version(), provider.Schema())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -13,12 +13,13 @@ import (
|
||||||
|
|
||||||
// https://cloud.google.com/asset-inventory/docs/supported-asset-types#supported_resource_types
|
// https://cloud.google.com/asset-inventory/docs/supported-asset-types#supported_resource_types
|
||||||
const (
|
const (
|
||||||
storageBucketAssetType = "storage.googleapis.com/Bucket"
|
storageBucketAssetType = "storage.googleapis.com/Bucket"
|
||||||
computeFirewallAssetType = "compute.googleapis.com/Firewall"
|
computeFirewallAssetType = "compute.googleapis.com/Firewall"
|
||||||
computeRouterAssetType = "compute.googleapis.com/Router"
|
computeRouterAssetType = "compute.googleapis.com/Router"
|
||||||
computeInstanceAssetType = "compute.googleapis.com/Instance"
|
computeInstanceAssetType = "compute.googleapis.com/Instance"
|
||||||
computeNetworkAssetType = "compute.googleapis.com/Network"
|
computeNetworkAssetType = "compute.googleapis.com/Network"
|
||||||
dnsManagedZoneAssetType = "dns.googleapis.com/ManagedZone"
|
dnsManagedZoneAssetType = "dns.googleapis.com/ManagedZone"
|
||||||
|
computeInstanceGroupAssetType = "compute.googleapis.com/InstanceGroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AssetRepository interface {
|
type AssetRepository interface {
|
||||||
|
@ -28,6 +29,7 @@ type AssetRepository interface {
|
||||||
SearchAllInstances() ([]*assetpb.ResourceSearchResult, error)
|
SearchAllInstances() ([]*assetpb.ResourceSearchResult, error)
|
||||||
SearchAllNetworks() ([]*assetpb.ResourceSearchResult, error)
|
SearchAllNetworks() ([]*assetpb.ResourceSearchResult, error)
|
||||||
SearchAllDNSManagedZones() ([]*assetpb.ResourceSearchResult, error)
|
SearchAllDNSManagedZones() ([]*assetpb.ResourceSearchResult, error)
|
||||||
|
SearchAllInstanceGroups() ([]*assetpb.ResourceSearchResult, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type assetRepository struct {
|
type assetRepository struct {
|
||||||
|
@ -54,6 +56,7 @@ func (s assetRepository) searchAllResources(ty string) ([]*assetpb.ResourceSearc
|
||||||
computeInstanceAssetType,
|
computeInstanceAssetType,
|
||||||
computeNetworkAssetType,
|
computeNetworkAssetType,
|
||||||
dnsManagedZoneAssetType,
|
dnsManagedZoneAssetType,
|
||||||
|
computeInstanceGroupAssetType,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
var results []*assetpb.ResourceSearchResult
|
var results []*assetpb.ResourceSearchResult
|
||||||
|
@ -113,3 +116,7 @@ func (s assetRepository) SearchAllNetworks() ([]*assetpb.ResourceSearchResult, e
|
||||||
func (s assetRepository) SearchAllDNSManagedZones() ([]*assetpb.ResourceSearchResult, error) {
|
func (s assetRepository) SearchAllDNSManagedZones() ([]*assetpb.ResourceSearchResult, error) {
|
||||||
return s.searchAllResources(dnsManagedZoneAssetType)
|
return s.searchAllResources(dnsManagedZoneAssetType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s assetRepository) SearchAllInstanceGroups() ([]*assetpb.ResourceSearchResult, error) {
|
||||||
|
return s.searchAllResources(computeInstanceGroupAssetType)
|
||||||
|
}
|
||||||
|
|
|
@ -81,6 +81,29 @@ func (_m *MockAssetRepository) SearchAllFirewalls() ([]*asset.ResourceSearchResu
|
||||||
return r0, r1
|
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:
|
// SearchAllInstances provides a mock function with given fields:
|
||||||
func (_m *MockAssetRepository) SearchAllInstances() ([]*asset.ResourceSearchResult, error) {
|
func (_m *MockAssetRepository) SearchAllInstances() ([]*asset.ResourceSearchResult, error) {
|
||||||
ret := _m.Called()
|
ret := _m.Called()
|
||||||
|
|
|
@ -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-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-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,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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, c.wantErr, err)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
alerter.AssertExpectations(tt)
|
||||||
|
testFilter.AssertExpectations(tt)
|
||||||
|
test.TestAgainstGoldenFile(got, resType.String(), c.dirName, provider, deserializer, shouldUpdate, tt)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"Typ": "WyJvYmplY3QiLHsiZGVzY3JpcHRpb24iOiJzdHJpbmciLCJpZCI6InN0cmluZyIsImluc3RhbmNlcyI6WyJzZXQiLCJzdHJpbmciXSwibmFtZSI6InN0cmluZyIsIm5hbWVkX3BvcnQiOlsibGlzdCIsWyJvYmplY3QiLHsibmFtZSI6InN0cmluZyIsInBvcnQiOiJudW1iZXIifV1dLCJuZXR3b3JrIjoic3RyaW5nIiwicHJvamVjdCI6InN0cmluZyIsInNlbGZfbGluayI6InN0cmluZyIsInNpemUiOiJudW1iZXIiLCJ0aW1lb3V0cyI6WyJvYmplY3QiLHsiY3JlYXRlIjoic3RyaW5nIiwiZGVsZXRlIjoic3RyaW5nIiwidXBkYXRlIjoic3RyaW5nIn1dLCJ6b25lIjoic3RyaW5nIn1d",
|
||||||
|
"Val": "eyJkZXNjcmlwdGlvbiI6IlRlcnJhZm9ybSB0ZXN0IGluc3RhbmNlIGdyb3VwIiwiaWQiOiJwcm9qZWN0cy9jbG91ZHNraWZmLWRldi1yYXBoYWVsL3pvbmVzL3VzLWNlbnRyYWwxLWEvaW5zdGFuY2VHcm91cHMvZHJpZnRjdGwtdGVzdC0xIiwiaW5zdGFuY2VzIjpbXSwibmFtZSI6ImRyaWZ0Y3RsLXRlc3QtMSIsIm5hbWVkX3BvcnQiOltdLCJuZXR3b3JrIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vY29tcHV0ZS92MS9wcm9qZWN0cy9jbG91ZHNraWZmLWRldi1yYXBoYWVsL2dsb2JhbC9uZXR3b3Jrcy90ZXN0LW5ldHdvcmsiLCJwcm9qZWN0IjoiY2xvdWRza2lmZi1kZXYtcmFwaGFlbCIsInNlbGZfbGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2NvbXB1dGUvdjEvcHJvamVjdHMvY2xvdWRza2lmZi1kZXYtcmFwaGFlbC96b25lcy91cy1jZW50cmFsMS1hL2luc3RhbmNlR3JvdXBzL2RyaWZ0Y3RsLXRlc3QtMSIsInNpemUiOjAsInRpbWVvdXRzIjp7ImNyZWF0ZSI6bnVsbCwiZGVsZXRlIjpudWxsLCJ1cGRhdGUiOm51bGx9LCJ6b25lIjoidXMtY2VudHJhbDEtYSJ9",
|
||||||
|
"Err": null
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"Typ": "WyJvYmplY3QiLHsiZGVzY3JpcHRpb24iOiJzdHJpbmciLCJpZCI6InN0cmluZyIsImluc3RhbmNlcyI6WyJzZXQiLCJzdHJpbmciXSwibmFtZSI6InN0cmluZyIsIm5hbWVkX3BvcnQiOlsibGlzdCIsWyJvYmplY3QiLHsibmFtZSI6InN0cmluZyIsInBvcnQiOiJudW1iZXIifV1dLCJuZXR3b3JrIjoic3RyaW5nIiwicHJvamVjdCI6InN0cmluZyIsInNlbGZfbGluayI6InN0cmluZyIsInNpemUiOiJudW1iZXIiLCJ0aW1lb3V0cyI6WyJvYmplY3QiLHsiY3JlYXRlIjoic3RyaW5nIiwiZGVsZXRlIjoic3RyaW5nIiwidXBkYXRlIjoic3RyaW5nIn1dLCJ6b25lIjoic3RyaW5nIn1d",
|
||||||
|
"Val": "eyJkZXNjcmlwdGlvbiI6IlRlcnJhZm9ybSB0ZXN0IGluc3RhbmNlIGdyb3VwIiwiaWQiOiJwcm9qZWN0cy9jbG91ZHNraWZmLWRldi1yYXBoYWVsL3pvbmVzL3VzLWNlbnRyYWwxLWEvaW5zdGFuY2VHcm91cHMvZHJpZnRjdGwtdGVzdC0yIiwiaW5zdGFuY2VzIjpbXSwibmFtZSI6ImRyaWZ0Y3RsLXRlc3QtMiIsIm5hbWVkX3BvcnQiOltdLCJuZXR3b3JrIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vY29tcHV0ZS92MS9wcm9qZWN0cy9jbG91ZHNraWZmLWRldi1yYXBoYWVsL2dsb2JhbC9uZXR3b3Jrcy90ZXN0LW5ldHdvcmsiLCJwcm9qZWN0IjoiY2xvdWRza2lmZi1kZXYtcmFwaGFlbCIsInNlbGZfbGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2NvbXB1dGUvdjEvcHJvamVjdHMvY2xvdWRza2lmZi1kZXYtcmFwaGFlbC96b25lcy91cy1jZW50cmFsMS1hL2luc3RhbmNlR3JvdXBzL2RyaWZ0Y3RsLXRlc3QtMiIsInNpemUiOjAsInRpbWVvdXRzIjp7ImNyZWF0ZSI6bnVsbCwiZGVsZXRlIjpudWxsLCJ1cGRhdGUiOm51bGx9LCJ6b25lIjoidXMtY2VudHJhbDEtYSJ9",
|
||||||
|
"Err": null
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,19 @@
|
||||||
|
provider "google" {}
|
||||||
|
|
||||||
|
resource "google_compute_network" "default" {
|
||||||
|
name = "test-network"
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package google
|
||||||
|
|
||||||
|
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"),
|
||||||
|
"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
|
||||||
|
})
|
||||||
|
}
|
|
@ -8,4 +8,5 @@ func InitResourcesMetadata(resourceSchemaRepository resource.SchemaRepositoryInt
|
||||||
initGoogleComputeRouterMetadata(resourceSchemaRepository)
|
initGoogleComputeRouterMetadata(resourceSchemaRepository)
|
||||||
initGoogleComputeNetworkMetadata(resourceSchemaRepository)
|
initGoogleComputeNetworkMetadata(resourceSchemaRepository)
|
||||||
initGoogleStorageBucketIamBMemberMetadata(resourceSchemaRepository)
|
initGoogleStorageBucketIamBMemberMetadata(resourceSchemaRepository)
|
||||||
|
initGoogleComputeInstanceGroupMetadata(resourceSchemaRepository)
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,8 @@ var supportedTypes = map[string]ResourceTypeMeta{
|
||||||
"google_storage_bucket_iam_policy": {children: []ResourceType{
|
"google_storage_bucket_iam_policy": {children: []ResourceType{
|
||||||
"google_storage_bucket_iam_member",
|
"google_storage_bucket_iam_member",
|
||||||
}},
|
}},
|
||||||
"google_dns_managed_zone": {},
|
"google_dns_managed_zone": {},
|
||||||
|
"google_compute_instance_group": {},
|
||||||
|
|
||||||
"azurerm_storage_account": {},
|
"azurerm_storage_account": {},
|
||||||
"azurerm_storage_container": {},
|
"azurerm_storage_container": {},
|
||||||
|
|
Loading…
Reference in New Issue