add support for google_storage_bucket_iam_binding

main
Martin Guibert 2021-09-14 22:07:09 +02:00
parent d4de6a01c0
commit bab96aa5c9
7 changed files with 143 additions and 5 deletions

1
go.mod
View File

@ -8,6 +8,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0
github.com/Azure/azure-sdk-for-go/sdk/network/armnetwork v0.3.0
github.com/Azure/azure-sdk-for-go/sdk/storage/armstorage v0.2.0
cloud.google.com/go/storage v1.10.0
github.com/Azure/go-autorest/autorest v0.11.3
github.com/aws/aws-sdk-go v1.38.68
github.com/bmatcuk/doublestar/v4 v4.0.1

View File

@ -0,0 +1,59 @@
package google
import (
"fmt"
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"
)
type GoogleStorageBucketIamBindingEnumerator struct {
repository repository.AssetRepository
storageRepository repository.StorageRepository
factory resource.ResourceFactory
}
func NewGoogleStorageBucketIamBindingEnumerator(repo repository.AssetRepository, storageRepo repository.StorageRepository, factory resource.ResourceFactory) *GoogleStorageBucketIamBindingEnumerator {
return &GoogleStorageBucketIamBindingEnumerator{
repository: repo,
storageRepository: storageRepo,
factory: factory,
}
}
func (e *GoogleStorageBucketIamBindingEnumerator) SupportedType() resource.ResourceType {
return google.GoogleStorageBucketIamBindingResourceType
}
func (e *GoogleStorageBucketIamBindingEnumerator) Enumerate() ([]*resource.Resource, error) {
resources, err := e.repository.SearchAllBuckets()
if err != nil {
return nil, remoteerror.NewResourceListingError(err, string(e.SupportedType()))
}
results := make([]*resource.Resource, len(resources))
for _, bucket := range resources {
for roleName, members := range e.storageRepository.ListAllBindings(bucket.DisplayName) {
id := fmt.Sprintf("b/%s/%s", bucket.DisplayName, roleName)
results = append(
results,
e.factory.CreateAbstractResource(
string(e.SupportedType()),
id,
map[string]interface{}{
"id": id,
"bucket": fmt.Sprintf("b/%s", bucket.DisplayName),
"role": roleName,
"members": members,
},
),
)
}
}
return results, err
}

View File

@ -40,6 +40,8 @@ func Init(version string, alerter *alerter.Alerter,
}
assetRepository := repository.NewAssetRepository(assetClient, provider.GetConfig(), repositoryCache)
storageRepository := repository.NewStorageRepository(repositoryCache)
providerLibrary.AddProvider(terraform.GOOGLE, provider)
deserializer := resource.NewDeserializer(factory)
@ -52,6 +54,7 @@ func Init(version string, alerter *alerter.Alerter,
remoteLibrary.AddEnumerator(NewGoogleComputeRouterEnumerator(assetRepository, factory))
remoteLibrary.AddEnumerator(NewGoogleComputeInstanceEnumerator(assetRepository, factory))
remoteLibrary.AddEnumerator(NewGoogleStorageBucketIamBindingEnumerator(assetRepository, storageRepository, factory))
remoteLibrary.AddEnumerator(NewGoogleComputeNetworkEnumerator(assetRepository, factory))
remoteLibrary.AddDetailsFetcher(google.GoogleComputeNetworkResourceType, common.NewGenericDetailsFetcher(google.GoogleComputeNetworkResourceType, provider, deserializer))

View File

@ -0,0 +1,56 @@
package repository
import (
"context"
"sync"
"cloud.google.com/go/storage"
"github.com/cloudskiff/driftctl/pkg/remote/cache"
)
type StorageRepository interface {
ListAllBindings(bucketName string) map[string][]string
}
type storageRepository struct {
client *storage.Client
cache cache.Cache
lock sync.Locker
}
func NewStorageRepository(cache cache.Cache) *storageRepository {
client, err := storage.NewClient(context.Background())
if err != nil {
panic(err)
}
return &storageRepository{
client: client,
cache: cache,
lock: &sync.Mutex{},
}
}
func (s storageRepository) ListAllBindings(bucketName string) map[string][]string {
s.lock.Lock()
defer s.lock.Unlock()
if cachedResults := s.cache.Get("ListAllBindings"); cachedResults != nil {
return cachedResults.(map[string][]string)
}
bucket := s.client.Bucket(bucketName)
policy, err := bucket.IAM().Policy(context.Background())
if err != nil {
panic(err)
}
bindings := make(map[string][]string)
for _, name := range policy.Roles() {
members := policy.Members(name)
bindings[string(name)] = members
}
s.cache.Put("ListAllBindings", bindings)
return bindings
}

View File

@ -0,0 +1,17 @@
package google
import "github.com/cloudskiff/driftctl/pkg/resource"
const GoogleStorageBucketIamBindingResourceType = "google_storage_bucket_iam_binding"
func initGoogleStorageBucketIamBindingMetadata(resourceSchemaRepository resource.SchemaRepositoryInterface) {
resourceSchemaRepository.SetNormalizeFunc(GoogleStorageBucketIamBindingResourceType, func(res *resource.Resource) {
res.Attributes().SafeDelete([]string{"force_destroy"})
res.Attributes().SafeDelete([]string{"etag"})
})
resourceSchemaRepository.SetResolveReadAttributesFunc(GoogleStorageBucketIamBindingResourceType, func(res *resource.Resource) map[string]string {
return map[string]string{
"bucket": *res.Attrs.GetString("bucket"),
}
})
}

View File

@ -7,4 +7,5 @@ func InitResourcesMetadata(resourceSchemaRepository resource.SchemaRepositoryInt
initGoogleComputeFirewallMetadata(resourceSchemaRepository)
initGoogleComputeRouterMetadata(resourceSchemaRepository)
initGoogleComputeNetworkMetadata(resourceSchemaRepository)
initGoogleStorageBucketIamBindingMetadata(resourceSchemaRepository)
}

View File

@ -75,6 +75,7 @@ var supportedTypes = map[string]struct{}{
"google_compute_router": {},
"google_compute_instance": {},
"google_compute_network": {},
"google_storage_bucket_iam_binding": {},
"azurerm_storage_account": {},
"azurerm_storage_container": {},