Skip to content

Commit

Permalink
Add support for GCS managed folders (#10786) (#18555)
Browse files Browse the repository at this point in the history
[upstream:0836fbe77e64a07242c695326680a72bfe3861af]

Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
modular-magician authored Jun 26, 2024
1 parent c87f997 commit e7f0725
Show file tree
Hide file tree
Showing 8 changed files with 1,588 additions and 2 deletions.
6 changes: 6 additions & 0 deletions .changelog/10786.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
```release-note:new-resource
`google_storage_managed_folder`
```
```release-note:new-resource
`google_storage_managed_folder_iam`
```
9 changes: 7 additions & 2 deletions google/provider/provider_mmv1_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ var handwrittenIAMDatasources = map[string]*schema.Resource{
"google_kms_crypto_key_iam_policy": tpgiamresource.DataSourceIamPolicy(kms.IamKmsCryptoKeySchema, kms.NewKmsCryptoKeyIamUpdater),
"google_spanner_instance_iam_policy": tpgiamresource.DataSourceIamPolicy(spanner.IamSpannerInstanceSchema, spanner.NewSpannerInstanceIamUpdater),
"google_spanner_database_iam_policy": tpgiamresource.DataSourceIamPolicy(spanner.IamSpannerDatabaseSchema, spanner.NewSpannerDatabaseIamUpdater),
"google_storage_managed_folder_iam_policy": tpgiamresource.DataSourceIamPolicy(storage.StorageManagedFolderIamSchema, storage.StorageManagedFolderIamUpdaterProducer),
"google_organization_iam_policy": tpgiamresource.DataSourceIamPolicy(resourcemanager.IamOrganizationSchema, resourcemanager.NewOrganizationIamUpdater),
"google_project_iam_policy": tpgiamresource.DataSourceIamPolicy(resourcemanager.IamProjectSchema, resourcemanager.NewProjectIamUpdater),
"google_pubsub_subscription_iam_policy": tpgiamresource.DataSourceIamPolicy(pubsub.IamPubsubSubscriptionSchema, pubsub.NewPubsubSubscriptionIamUpdater),
Expand All @@ -414,9 +415,9 @@ var handwrittenIAMDatasources = map[string]*schema.Resource{
}

// Resources
// Generated resources: 427
// Generated resources: 428
// Generated IAM resources: 249
// Total generated resources: 676
// Total generated resources: 677
var generatedResources = map[string]*schema.Resource{
"google_folder_access_approval_settings": accessapproval.ResourceAccessApprovalFolderSettings(),
"google_organization_access_approval_settings": accessapproval.ResourceAccessApprovalOrganizationSettings(),
Expand Down Expand Up @@ -1033,6 +1034,7 @@ var generatedResources = map[string]*schema.Resource{
"google_storage_bucket_access_control": storage.ResourceStorageBucketAccessControl(),
"google_storage_default_object_access_control": storage.ResourceStorageDefaultObjectAccessControl(),
"google_storage_hmac_key": storage.ResourceStorageHmacKey(),
"google_storage_managed_folder": storage.ResourceStorageManagedFolder(),
"google_storage_object_access_control": storage.ResourceStorageObjectAccessControl(),
"google_storage_insights_report_config": storageinsights.ResourceStorageInsightsReportConfig(),
"google_storage_transfer_agent_pool": storagetransfer.ResourceStorageTransferAgentPool(),
Expand Down Expand Up @@ -1209,6 +1211,9 @@ var handwrittenIAMResources = map[string]*schema.Resource{
"google_spanner_database_iam_binding": tpgiamresource.ResourceIamBinding(spanner.IamSpannerDatabaseSchema, spanner.NewSpannerDatabaseIamUpdater, spanner.SpannerDatabaseIdParseFunc),
"google_spanner_database_iam_member": tpgiamresource.ResourceIamMember(spanner.IamSpannerDatabaseSchema, spanner.NewSpannerDatabaseIamUpdater, spanner.SpannerDatabaseIdParseFunc),
"google_spanner_database_iam_policy": tpgiamresource.ResourceIamPolicy(spanner.IamSpannerDatabaseSchema, spanner.NewSpannerDatabaseIamUpdater, spanner.SpannerDatabaseIdParseFunc),
"google_storage_managed_folder_iam_binding": tpgiamresource.ResourceIamBinding(storage.StorageManagedFolderIamSchema, storage.StorageManagedFolderIamUpdaterProducer, storage.StorageManagedFolderIdParseFunc),
"google_storage_managed_folder_iam_member": tpgiamresource.ResourceIamMember(storage.StorageManagedFolderIamSchema, storage.StorageManagedFolderIamUpdaterProducer, storage.StorageManagedFolderIdParseFunc),
"google_storage_managed_folder_iam_policy": tpgiamresource.ResourceIamPolicy(storage.StorageManagedFolderIamSchema, storage.StorageManagedFolderIamUpdaterProducer, storage.StorageManagedFolderIdParseFunc),
"google_organization_iam_binding": tpgiamresource.ResourceIamBinding(resourcemanager.IamOrganizationSchema, resourcemanager.NewOrganizationIamUpdater, resourcemanager.OrgIdParseFunc),
"google_organization_iam_member": tpgiamresource.ResourceIamMember(resourcemanager.IamOrganizationSchema, resourcemanager.NewOrganizationIamUpdater, resourcemanager.OrgIdParseFunc),
"google_organization_iam_policy": tpgiamresource.ResourceIamPolicy(resourcemanager.IamOrganizationSchema, resourcemanager.NewOrganizationIamUpdater, resourcemanager.OrgIdParseFunc),
Expand Down
186 changes: 186 additions & 0 deletions google/services/storage/iam_storage_managed_folder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package storage

import (
"fmt"
"net/url"

"github.com/hashicorp/errwrap"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"google.golang.org/api/cloudresourcemanager/v1"

"github.com/hashicorp/terraform-provider-google/google/tpgiamresource"
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
"github.com/hashicorp/terraform-provider-google/google/verify"
)

var StorageManagedFolderIamSchema = map[string]*schema.Schema{
"bucket": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"managed_folder": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
DiffSuppressFunc: tpgresource.CompareSelfLinkOrResourceName,
ValidateFunc: verify.ValidateRegexp(`/$`),
},
}

type StorageManagedFolderIamUpdater struct {
bucket string
managedFolder string
d tpgresource.TerraformResourceData
Config *transport_tpg.Config
}

func StorageManagedFolderIamUpdaterProducer(d tpgresource.TerraformResourceData, config *transport_tpg.Config) (tpgiamresource.ResourceIamUpdater, error) {
values := make(map[string]string)

if v, ok := d.GetOk("bucket"); ok {
values["bucket"] = v.(string)
}

if v, ok := d.GetOk("managed_folder"); ok {
values["managed_folder"] = v.(string)
}

u := &StorageManagedFolderIamUpdater{
bucket: values["bucket"],
managedFolder: values["managed_folder"],
d: d,
Config: config,
}

if err := d.Set("bucket", u.bucket); err != nil {
return nil, fmt.Errorf("Error setting bucket: %s", err)
}
if err := d.Set("managed_folder", u.managedFolder); err != nil {
return nil, fmt.Errorf("Error setting managed_folder: %s", err)
}

return u, nil
}

func StorageManagedFolderIdParseFunc(d *schema.ResourceData, config *transport_tpg.Config) error {
values := make(map[string]string)

m, err := tpgresource.GetImportIdQualifiers([]string{"(?P<bucket>[^/]+)/managedFolders/(?P<managed_folder>.+)", "(?P<bucket>[^/]+)/(?P<managed_folder>.+)"}, d, config, d.Id())
if err != nil {
return err
}

for k, v := range m {
values[k] = v
}

u := &StorageManagedFolderIamUpdater{
bucket: values["bucket"],
managedFolder: values["managed_folder"],
d: d,
Config: config,
}
if err := d.Set("bucket", u.bucket); err != nil {
return fmt.Errorf("Error setting bucket: %s", err)
}
if err := d.Set("managed_folder", u.managedFolder); err != nil {
return fmt.Errorf("Error setting managed_folder: %s", err)
}
d.SetId(u.GetResourceId())
return nil
}

func (u *StorageManagedFolderIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) {
url, err := u.qualifyManagedFolderUrl("iam")
if err != nil {
return nil, err
}

var obj map[string]interface{}
url, err = transport_tpg.AddQueryParams(url, map[string]string{"optionsRequestedPolicyVersion": fmt.Sprintf("%d", tpgiamresource.IamPolicyVersion)})
if err != nil {
return nil, err
}

userAgent, err := tpgresource.GenerateUserAgentString(u.d, u.Config.UserAgent)
if err != nil {
return nil, err
}

policy, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: u.Config,
Method: "GET",
RawURL: url,
UserAgent: userAgent,
Body: obj,
})
if err != nil {
return nil, errwrap.Wrapf(fmt.Sprintf("Error retrieving IAM policy for %s: {{err}}", u.DescribeResource()), err)
}

out := &cloudresourcemanager.Policy{}
err = tpgresource.Convert(policy, out)
if err != nil {
return nil, errwrap.Wrapf("Cannot convert a policy to a resource manager policy: {{err}}", err)
}

return out, nil
}

func (u *StorageManagedFolderIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanager.Policy) error {
json, err := tpgresource.ConvertToMap(policy)
if err != nil {
return err
}

obj := json

url, err := u.qualifyManagedFolderUrl("iam")
if err != nil {
return err
}

userAgent, err := tpgresource.GenerateUserAgentString(u.d, u.Config.UserAgent)
if err != nil {
return err
}

_, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: u.Config,
Method: "PUT",
RawURL: url,
UserAgent: userAgent,
Body: obj,
Timeout: u.d.Timeout(schema.TimeoutCreate),
})
if err != nil {
return errwrap.Wrapf(fmt.Sprintf("Error setting IAM policy for %s: {{err}}", u.DescribeResource()), err)
}

return nil
}

func (u *StorageManagedFolderIamUpdater) qualifyManagedFolderUrl(methodIdentifier string) (string, error) {
urlTemplate := fmt.Sprintf("{{StorageBasePath}}b/%s/managedFolders/%s/%s", u.bucket, url.PathEscape(u.managedFolder), methodIdentifier)
url, err := tpgresource.ReplaceVars(u.d, u.Config, urlTemplate)
if err != nil {
return "", err
}
return url, nil
}

func (u *StorageManagedFolderIamUpdater) GetResourceId() string {
return fmt.Sprintf("b/%s/managedFolders/%s", u.bucket, u.managedFolder)
}

func (u *StorageManagedFolderIamUpdater) GetMutexKey() string {
return fmt.Sprintf("iam-storage-managedfolder-%s", u.GetResourceId())
}

func (u *StorageManagedFolderIamUpdater) DescribeResource() string {
return fmt.Sprintf("storage managedfolder %q", u.GetResourceId())
}
Loading

0 comments on commit e7f0725

Please sign in to comment.