From c98d3e13c1808e5352e96f55a4c8f4ac4f1fd557 Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Tue, 3 Dec 2019 23:29:31 +0000 Subject: [PATCH] Add support for cloud run service IAM. Use base paths via replaceVars Signed-off-by: Modular Magician --- google/config.go | 2 +- google/iam_binary_authorization_attestor.go | 19 +- google/iam_cloud_functions_cloud_function.go | 19 +- google/iam_cloud_run_service.go | 202 +++++++++++++++ google/iam_compute_instance.go | 19 +- google/iam_compute_subnetwork.go | 19 +- google/iam_iap_app_engine_service.go | 19 +- google/iam_iap_app_engine_version.go | 19 +- google/iam_iap_web.go | 19 +- google/iam_iap_web_backend_service.go | 19 +- google/iam_iap_web_type_app_engine.go | 19 +- google/iam_iap_web_type_compute.go | 19 +- google/iam_pubsub_topic.go | 19 +- google/iam_runtime_config_config.go | 19 +- google/iam_source_repo_repository.go | 19 +- google/provider.go | 7 +- google/resource_cloud_run_domain_mapping.go | 8 +- ...cloud_run_domain_mapping_generated_test.go | 2 +- google/resource_cloud_run_service.go | 12 +- ...source_cloud_run_service_generated_test.go | 101 -------- google/resource_cloud_run_service_iam_test.go | 240 ++++++++++++++++++ google/resource_sql_database_instance_test.go | 1 - .../docs/r/cloud_run_service.html.markdown | 5 - .../r/cloud_run_service_iam.html.markdown | 148 +++++++++++ 24 files changed, 802 insertions(+), 173 deletions(-) create mode 100644 google/iam_cloud_run_service.go delete mode 100644 google/resource_cloud_run_service_generated_test.go create mode 100644 google/resource_cloud_run_service_iam_test.go create mode 100644 website/docs/r/cloud_run_service_iam.html.markdown diff --git a/google/config.go b/google/config.go index da68cc37ec0..df975c6d084 100644 --- a/google/config.go +++ b/google/config.go @@ -207,7 +207,7 @@ var BigtableDefaultBasePath = "https://bigtableadmin.googleapis.com/v2/" var BinaryAuthorizationDefaultBasePath = "https://binaryauthorization.googleapis.com/v1/" var CloudBuildDefaultBasePath = "https://cloudbuild.googleapis.com/v1/" var CloudFunctionsDefaultBasePath = "https://cloudfunctions.googleapis.com/v1/" -var CloudRunDefaultBasePath = "https://{{location}}-run.googleapis.com/apis/" +var CloudRunDefaultBasePath = "https://{{location}}-run.googleapis.com/" var CloudSchedulerDefaultBasePath = "https://cloudscheduler.googleapis.com/v1/" var CloudTasksDefaultBasePath = "https://cloudtasks.googleapis.com/v2/" var ComputeDefaultBasePath = "https://www.googleapis.com/compute/v1/" diff --git a/google/iam_binary_authorization_attestor.go b/google/iam_binary_authorization_attestor.go index 56be5118ed1..d2c582b0dda 100644 --- a/google/iam_binary_authorization_attestor.go +++ b/google/iam_binary_authorization_attestor.go @@ -108,7 +108,10 @@ func BinaryAuthorizationAttestorIdParseFunc(d *schema.ResourceData, config *Conf } func (u *BinaryAuthorizationAttestorIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { - url := u.qualifyAttestorUrl("getIamPolicy") + url, err := u.qualifyAttestorUrl("getIamPolicy") + if err != nil { + return nil, err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -139,7 +142,10 @@ func (u *BinaryAuthorizationAttestorIamUpdater) SetResourceIamPolicy(policy *clo obj := make(map[string]interface{}) obj["policy"] = json - url := u.qualifyAttestorUrl("setIamPolicy") + url, err := u.qualifyAttestorUrl("setIamPolicy") + if err != nil { + return err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -154,8 +160,13 @@ func (u *BinaryAuthorizationAttestorIamUpdater) SetResourceIamPolicy(policy *clo return nil } -func (u *BinaryAuthorizationAttestorIamUpdater) qualifyAttestorUrl(methodIdentifier string) string { - return fmt.Sprintf("https://binaryauthorization.googleapis.com/v1/%s:%s", fmt.Sprintf("projects/%s/attestors/%s", u.project, u.attestor), methodIdentifier) +func (u *BinaryAuthorizationAttestorIamUpdater) qualifyAttestorUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{BinaryAuthorizationBasePath}}%s:%s", fmt.Sprintf("projects/%s/attestors/%s", u.project, u.attestor), methodIdentifier) + url, err := replaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil } func (u *BinaryAuthorizationAttestorIamUpdater) GetResourceId() string { diff --git a/google/iam_cloud_functions_cloud_function.go b/google/iam_cloud_functions_cloud_function.go index 17782fadd72..991b405f08f 100644 --- a/google/iam_cloud_functions_cloud_function.go +++ b/google/iam_cloud_functions_cloud_function.go @@ -128,7 +128,10 @@ func CloudFunctionsCloudFunctionIdParseFunc(d *schema.ResourceData, config *Conf } func (u *CloudFunctionsCloudFunctionIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { - url := u.qualifyCloudFunctionUrl("getIamPolicy") + url, err := u.qualifyCloudFunctionUrl("getIamPolicy") + if err != nil { + return nil, err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -159,7 +162,10 @@ func (u *CloudFunctionsCloudFunctionIamUpdater) SetResourceIamPolicy(policy *clo obj := make(map[string]interface{}) obj["policy"] = json - url := u.qualifyCloudFunctionUrl("setIamPolicy") + url, err := u.qualifyCloudFunctionUrl("setIamPolicy") + if err != nil { + return err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -174,8 +180,13 @@ func (u *CloudFunctionsCloudFunctionIamUpdater) SetResourceIamPolicy(policy *clo return nil } -func (u *CloudFunctionsCloudFunctionIamUpdater) qualifyCloudFunctionUrl(methodIdentifier string) string { - return fmt.Sprintf("https://cloudfunctions.googleapis.com/v1/%s:%s", fmt.Sprintf("projects/%s/locations/%s/functions/%s", u.project, u.region, u.cloudFunction), methodIdentifier) +func (u *CloudFunctionsCloudFunctionIamUpdater) qualifyCloudFunctionUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{CloudFunctionsBasePath}}%s:%s", fmt.Sprintf("projects/%s/locations/%s/functions/%s", u.project, u.region, u.cloudFunction), methodIdentifier) + url, err := replaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil } func (u *CloudFunctionsCloudFunctionIamUpdater) GetResourceId() string { diff --git a/google/iam_cloud_run_service.go b/google/iam_cloud_run_service.go new file mode 100644 index 00000000000..cc3ece339be --- /dev/null +++ b/google/iam_cloud_run_service.go @@ -0,0 +1,202 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- +package google + +import ( + "fmt" + + "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "google.golang.org/api/cloudresourcemanager/v1" +) + +var CloudRunServiceIamSchema = map[string]*schema.Schema{ + "project": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + }, + "location": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + }, + "service": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + }, +} + +type CloudRunServiceIamUpdater struct { + project string + location string + service string + d *schema.ResourceData + Config *Config +} + +func CloudRunServiceIamUpdaterProducer(d *schema.ResourceData, config *Config) (ResourceIamUpdater, error) { + values := make(map[string]string) + + project, err := getProject(d, config) + if err != nil { + return nil, err + } + values["project"] = project + location, err := getLocation(d, config) + if err != nil { + return nil, err + } + values["location"] = location + if v, ok := d.GetOk("service"); ok { + values["service"] = v.(string) + } + + // We may have gotten either a long or short name, so attempt to parse long name if possible + m, err := getImportIdQualifiers([]string{"projects/(?P[^/]+)/locations/(?P[^/]+)/services/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Get("service").(string)) + if err != nil { + return nil, err + } + + for k, v := range m { + values[k] = v + } + + u := &CloudRunServiceIamUpdater{ + project: values["project"], + location: values["location"], + service: values["service"], + d: d, + Config: config, + } + + d.Set("project", u.project) + d.Set("location", u.location) + d.Set("service", u.GetResourceId()) + + return u, nil +} + +func CloudRunServiceIdParseFunc(d *schema.ResourceData, config *Config) error { + values := make(map[string]string) + + project, err := getProject(d, config) + if err != nil { + return err + } + values["project"] = project + location, err := getLocation(d, config) + if err != nil { + return err + } + values["location"] = location + + m, err := getImportIdQualifiers([]string{"projects/(?P[^/]+)/locations/(?P[^/]+)/services/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Id()) + if err != nil { + return err + } + + for k, v := range m { + values[k] = v + } + + u := &CloudRunServiceIamUpdater{ + project: values["project"], + location: values["location"], + service: values["service"], + d: d, + Config: config, + } + d.Set("service", u.GetResourceId()) + d.SetId(u.GetResourceId()) + return nil +} + +func (u *CloudRunServiceIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { + url, err := u.qualifyServiceUrl("getIamPolicy") + if err != nil { + return nil, err + } + + project, err := getProject(u.d, u.Config) + if err != nil { + return nil, err + } + var obj map[string]interface{} + + policy, err := sendRequest(u.Config, "GET", project, url, obj) + if err != nil { + return nil, errwrap.Wrapf(fmt.Sprintf("Error retrieving IAM policy for %s: {{err}}", u.DescribeResource()), err) + } + + out := &cloudresourcemanager.Policy{} + err = 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 *CloudRunServiceIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanager.Policy) error { + json, err := ConvertToMap(policy) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + obj["policy"] = json + + url, err := u.qualifyServiceUrl("setIamPolicy") + if err != nil { + return err + } + + project, err := getProject(u.d, u.Config) + if err != nil { + return err + } + + _, err = sendRequestWithTimeout(u.Config, "POST", project, url, obj, 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 *CloudRunServiceIamUpdater) qualifyServiceUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{CloudRunBasePath}}%s:%s", fmt.Sprintf("v1/projects/%s/locations/%s/services/%s", u.project, u.location, u.service), methodIdentifier) + url, err := replaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil +} + +func (u *CloudRunServiceIamUpdater) GetResourceId() string { + return fmt.Sprintf("v1/projects/%s/locations/%s/services/%s", u.project, u.location, u.service) +} + +func (u *CloudRunServiceIamUpdater) GetMutexKey() string { + return fmt.Sprintf("iam-cloudrun-service-%s", u.GetResourceId()) +} + +func (u *CloudRunServiceIamUpdater) DescribeResource() string { + return fmt.Sprintf("cloudrun service %q", u.GetResourceId()) +} diff --git a/google/iam_compute_instance.go b/google/iam_compute_instance.go index 82c51ded917..cdd6419033c 100644 --- a/google/iam_compute_instance.go +++ b/google/iam_compute_instance.go @@ -128,7 +128,10 @@ func ComputeInstanceIdParseFunc(d *schema.ResourceData, config *Config) error { } func (u *ComputeInstanceIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { - url := u.qualifyInstanceUrl("getIamPolicy") + url, err := u.qualifyInstanceUrl("getIamPolicy") + if err != nil { + return nil, err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -159,7 +162,10 @@ func (u *ComputeInstanceIamUpdater) SetResourceIamPolicy(policy *cloudresourcema obj := make(map[string]interface{}) obj["policy"] = json - url := u.qualifyInstanceUrl("setIamPolicy") + url, err := u.qualifyInstanceUrl("setIamPolicy") + if err != nil { + return err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -174,8 +180,13 @@ func (u *ComputeInstanceIamUpdater) SetResourceIamPolicy(policy *cloudresourcema return nil } -func (u *ComputeInstanceIamUpdater) qualifyInstanceUrl(methodIdentifier string) string { - return fmt.Sprintf("https://www.googleapis.com/compute/v1/%s/%s", fmt.Sprintf("projects/%s/zones/%s/instances/%s", u.project, u.zone, u.instanceName), methodIdentifier) +func (u *ComputeInstanceIamUpdater) qualifyInstanceUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{ComputeBasePath}}%s/%s", fmt.Sprintf("projects/%s/zones/%s/instances/%s", u.project, u.zone, u.instanceName), methodIdentifier) + url, err := replaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil } func (u *ComputeInstanceIamUpdater) GetResourceId() string { diff --git a/google/iam_compute_subnetwork.go b/google/iam_compute_subnetwork.go index cbd70a11a74..7f4e8498b0d 100644 --- a/google/iam_compute_subnetwork.go +++ b/google/iam_compute_subnetwork.go @@ -128,7 +128,10 @@ func ComputeSubnetworkIdParseFunc(d *schema.ResourceData, config *Config) error } func (u *ComputeSubnetworkIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { - url := u.qualifySubnetworkUrl("getIamPolicy") + url, err := u.qualifySubnetworkUrl("getIamPolicy") + if err != nil { + return nil, err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -159,7 +162,10 @@ func (u *ComputeSubnetworkIamUpdater) SetResourceIamPolicy(policy *cloudresource obj := make(map[string]interface{}) obj["policy"] = json - url := u.qualifySubnetworkUrl("setIamPolicy") + url, err := u.qualifySubnetworkUrl("setIamPolicy") + if err != nil { + return err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -174,8 +180,13 @@ func (u *ComputeSubnetworkIamUpdater) SetResourceIamPolicy(policy *cloudresource return nil } -func (u *ComputeSubnetworkIamUpdater) qualifySubnetworkUrl(methodIdentifier string) string { - return fmt.Sprintf("https://www.googleapis.com/compute/v1/%s/%s", fmt.Sprintf("projects/%s/regions/%s/subnetworks/%s", u.project, u.region, u.subnetwork), methodIdentifier) +func (u *ComputeSubnetworkIamUpdater) qualifySubnetworkUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{ComputeBasePath}}%s/%s", fmt.Sprintf("projects/%s/regions/%s/subnetworks/%s", u.project, u.region, u.subnetwork), methodIdentifier) + url, err := replaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil } func (u *ComputeSubnetworkIamUpdater) GetResourceId() string { diff --git a/google/iam_iap_app_engine_service.go b/google/iam_iap_app_engine_service.go index 575020d21d4..2f6f06767b7 100644 --- a/google/iam_iap_app_engine_service.go +++ b/google/iam_iap_app_engine_service.go @@ -121,7 +121,10 @@ func IapAppEngineServiceIdParseFunc(d *schema.ResourceData, config *Config) erro } func (u *IapAppEngineServiceIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { - url := u.qualifyAppEngineServiceUrl("getIamPolicy") + url, err := u.qualifyAppEngineServiceUrl("getIamPolicy") + if err != nil { + return nil, err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -152,7 +155,10 @@ func (u *IapAppEngineServiceIamUpdater) SetResourceIamPolicy(policy *cloudresour obj := make(map[string]interface{}) obj["policy"] = json - url := u.qualifyAppEngineServiceUrl("setIamPolicy") + url, err := u.qualifyAppEngineServiceUrl("setIamPolicy") + if err != nil { + return err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -167,8 +173,13 @@ func (u *IapAppEngineServiceIamUpdater) SetResourceIamPolicy(policy *cloudresour return nil } -func (u *IapAppEngineServiceIamUpdater) qualifyAppEngineServiceUrl(methodIdentifier string) string { - return fmt.Sprintf("https://iap.googleapis.com/v1/%s:%s", fmt.Sprintf("projects/%s/iap_web/appengine-%s/services/%s", u.project, u.appId, u.service), methodIdentifier) +func (u *IapAppEngineServiceIamUpdater) qualifyAppEngineServiceUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{IapBasePath}}%s:%s", fmt.Sprintf("projects/%s/iap_web/appengine-%s/services/%s", u.project, u.appId, u.service), methodIdentifier) + url, err := replaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil } func (u *IapAppEngineServiceIamUpdater) GetResourceId() string { diff --git a/google/iam_iap_app_engine_version.go b/google/iam_iap_app_engine_version.go index d4da9e912bb..87bc07d075a 100644 --- a/google/iam_iap_app_engine_version.go +++ b/google/iam_iap_app_engine_version.go @@ -134,7 +134,10 @@ func IapAppEngineVersionIdParseFunc(d *schema.ResourceData, config *Config) erro } func (u *IapAppEngineVersionIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { - url := u.qualifyAppEngineVersionUrl("getIamPolicy") + url, err := u.qualifyAppEngineVersionUrl("getIamPolicy") + if err != nil { + return nil, err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -165,7 +168,10 @@ func (u *IapAppEngineVersionIamUpdater) SetResourceIamPolicy(policy *cloudresour obj := make(map[string]interface{}) obj["policy"] = json - url := u.qualifyAppEngineVersionUrl("setIamPolicy") + url, err := u.qualifyAppEngineVersionUrl("setIamPolicy") + if err != nil { + return err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -180,8 +186,13 @@ func (u *IapAppEngineVersionIamUpdater) SetResourceIamPolicy(policy *cloudresour return nil } -func (u *IapAppEngineVersionIamUpdater) qualifyAppEngineVersionUrl(methodIdentifier string) string { - return fmt.Sprintf("https://iap.googleapis.com/v1/%s:%s", fmt.Sprintf("projects/%s/iap_web/appengine-%s/services/%s/versions/%s", u.project, u.appId, u.service, u.versionId), methodIdentifier) +func (u *IapAppEngineVersionIamUpdater) qualifyAppEngineVersionUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{IapBasePath}}%s:%s", fmt.Sprintf("projects/%s/iap_web/appengine-%s/services/%s/versions/%s", u.project, u.appId, u.service, u.versionId), methodIdentifier) + url, err := replaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil } func (u *IapAppEngineVersionIamUpdater) GetResourceId() string { diff --git a/google/iam_iap_web.go b/google/iam_iap_web.go index bf600c4f287..ba81e4e8d73 100644 --- a/google/iam_iap_web.go +++ b/google/iam_iap_web.go @@ -96,7 +96,10 @@ func IapWebIdParseFunc(d *schema.ResourceData, config *Config) error { } func (u *IapWebIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { - url := u.qualifyWebUrl("getIamPolicy") + url, err := u.qualifyWebUrl("getIamPolicy") + if err != nil { + return nil, err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -127,7 +130,10 @@ func (u *IapWebIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanager.Pol obj := make(map[string]interface{}) obj["policy"] = json - url := u.qualifyWebUrl("setIamPolicy") + url, err := u.qualifyWebUrl("setIamPolicy") + if err != nil { + return err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -142,8 +148,13 @@ func (u *IapWebIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanager.Pol return nil } -func (u *IapWebIamUpdater) qualifyWebUrl(methodIdentifier string) string { - return fmt.Sprintf("https://iap.googleapis.com/v1/%s:%s", fmt.Sprintf("projects/%s/iap_web", u.project), methodIdentifier) +func (u *IapWebIamUpdater) qualifyWebUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{IapBasePath}}%s:%s", fmt.Sprintf("projects/%s/iap_web", u.project), methodIdentifier) + url, err := replaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil } func (u *IapWebIamUpdater) GetResourceId() string { diff --git a/google/iam_iap_web_backend_service.go b/google/iam_iap_web_backend_service.go index 6599748f63d..6d4335460ed 100644 --- a/google/iam_iap_web_backend_service.go +++ b/google/iam_iap_web_backend_service.go @@ -108,7 +108,10 @@ func IapWebBackendServiceIdParseFunc(d *schema.ResourceData, config *Config) err } func (u *IapWebBackendServiceIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { - url := u.qualifyWebBackendServiceUrl("getIamPolicy") + url, err := u.qualifyWebBackendServiceUrl("getIamPolicy") + if err != nil { + return nil, err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -139,7 +142,10 @@ func (u *IapWebBackendServiceIamUpdater) SetResourceIamPolicy(policy *cloudresou obj := make(map[string]interface{}) obj["policy"] = json - url := u.qualifyWebBackendServiceUrl("setIamPolicy") + url, err := u.qualifyWebBackendServiceUrl("setIamPolicy") + if err != nil { + return err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -154,8 +160,13 @@ func (u *IapWebBackendServiceIamUpdater) SetResourceIamPolicy(policy *cloudresou return nil } -func (u *IapWebBackendServiceIamUpdater) qualifyWebBackendServiceUrl(methodIdentifier string) string { - return fmt.Sprintf("https://iap.googleapis.com/v1/%s:%s", fmt.Sprintf("projects/%s/iap_web/compute/services/%s", u.project, u.webBackendService), methodIdentifier) +func (u *IapWebBackendServiceIamUpdater) qualifyWebBackendServiceUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{IapBasePath}}%s:%s", fmt.Sprintf("projects/%s/iap_web/compute/services/%s", u.project, u.webBackendService), methodIdentifier) + url, err := replaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil } func (u *IapWebBackendServiceIamUpdater) GetResourceId() string { diff --git a/google/iam_iap_web_type_app_engine.go b/google/iam_iap_web_type_app_engine.go index bc540398ab9..f54a9e67084 100644 --- a/google/iam_iap_web_type_app_engine.go +++ b/google/iam_iap_web_type_app_engine.go @@ -122,7 +122,10 @@ func IapWebTypeAppEngineIdParseFunc(d *schema.ResourceData, config *Config) erro } func (u *IapWebTypeAppEngineIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { - url := u.qualifyWebTypeAppEngineUrl("getIamPolicy") + url, err := u.qualifyWebTypeAppEngineUrl("getIamPolicy") + if err != nil { + return nil, err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -153,7 +156,10 @@ func (u *IapWebTypeAppEngineIamUpdater) SetResourceIamPolicy(policy *cloudresour obj := make(map[string]interface{}) obj["policy"] = json - url := u.qualifyWebTypeAppEngineUrl("setIamPolicy") + url, err := u.qualifyWebTypeAppEngineUrl("setIamPolicy") + if err != nil { + return err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -168,8 +174,13 @@ func (u *IapWebTypeAppEngineIamUpdater) SetResourceIamPolicy(policy *cloudresour return nil } -func (u *IapWebTypeAppEngineIamUpdater) qualifyWebTypeAppEngineUrl(methodIdentifier string) string { - return fmt.Sprintf("https://iap.googleapis.com/v1/%s:%s", fmt.Sprintf("projects/%s/iap_web/appengine-%s", u.project, u.appId), methodIdentifier) +func (u *IapWebTypeAppEngineIamUpdater) qualifyWebTypeAppEngineUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{IapBasePath}}%s:%s", fmt.Sprintf("projects/%s/iap_web/appengine-%s", u.project, u.appId), methodIdentifier) + url, err := replaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil } func (u *IapWebTypeAppEngineIamUpdater) GetResourceId() string { diff --git a/google/iam_iap_web_type_compute.go b/google/iam_iap_web_type_compute.go index 03735e51162..9b5c667d178 100644 --- a/google/iam_iap_web_type_compute.go +++ b/google/iam_iap_web_type_compute.go @@ -96,7 +96,10 @@ func IapWebTypeComputeIdParseFunc(d *schema.ResourceData, config *Config) error } func (u *IapWebTypeComputeIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { - url := u.qualifyWebTypeComputeUrl("getIamPolicy") + url, err := u.qualifyWebTypeComputeUrl("getIamPolicy") + if err != nil { + return nil, err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -127,7 +130,10 @@ func (u *IapWebTypeComputeIamUpdater) SetResourceIamPolicy(policy *cloudresource obj := make(map[string]interface{}) obj["policy"] = json - url := u.qualifyWebTypeComputeUrl("setIamPolicy") + url, err := u.qualifyWebTypeComputeUrl("setIamPolicy") + if err != nil { + return err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -142,8 +148,13 @@ func (u *IapWebTypeComputeIamUpdater) SetResourceIamPolicy(policy *cloudresource return nil } -func (u *IapWebTypeComputeIamUpdater) qualifyWebTypeComputeUrl(methodIdentifier string) string { - return fmt.Sprintf("https://iap.googleapis.com/v1/%s:%s", fmt.Sprintf("projects/%s/iap_web/compute", u.project), methodIdentifier) +func (u *IapWebTypeComputeIamUpdater) qualifyWebTypeComputeUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{IapBasePath}}%s:%s", fmt.Sprintf("projects/%s/iap_web/compute", u.project), methodIdentifier) + url, err := replaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil } func (u *IapWebTypeComputeIamUpdater) GetResourceId() string { diff --git a/google/iam_pubsub_topic.go b/google/iam_pubsub_topic.go index 7ea1e8816a3..c50de29addb 100644 --- a/google/iam_pubsub_topic.go +++ b/google/iam_pubsub_topic.go @@ -108,7 +108,10 @@ func PubsubTopicIdParseFunc(d *schema.ResourceData, config *Config) error { } func (u *PubsubTopicIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { - url := u.qualifyTopicUrl("getIamPolicy") + url, err := u.qualifyTopicUrl("getIamPolicy") + if err != nil { + return nil, err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -139,7 +142,10 @@ func (u *PubsubTopicIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanage obj := make(map[string]interface{}) obj["policy"] = json - url := u.qualifyTopicUrl("setIamPolicy") + url, err := u.qualifyTopicUrl("setIamPolicy") + if err != nil { + return err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -154,8 +160,13 @@ func (u *PubsubTopicIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanage return nil } -func (u *PubsubTopicIamUpdater) qualifyTopicUrl(methodIdentifier string) string { - return fmt.Sprintf("https://pubsub.googleapis.com/v1/%s:%s", fmt.Sprintf("projects/%s/topics/%s", u.project, u.topic), methodIdentifier) +func (u *PubsubTopicIamUpdater) qualifyTopicUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{PubsubBasePath}}%s:%s", fmt.Sprintf("projects/%s/topics/%s", u.project, u.topic), methodIdentifier) + url, err := replaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil } func (u *PubsubTopicIamUpdater) GetResourceId() string { diff --git a/google/iam_runtime_config_config.go b/google/iam_runtime_config_config.go index e3197f72e92..fa3b326fcd5 100644 --- a/google/iam_runtime_config_config.go +++ b/google/iam_runtime_config_config.go @@ -108,7 +108,10 @@ func RuntimeConfigConfigIdParseFunc(d *schema.ResourceData, config *Config) erro } func (u *RuntimeConfigConfigIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { - url := u.qualifyConfigUrl("getIamPolicy") + url, err := u.qualifyConfigUrl("getIamPolicy") + if err != nil { + return nil, err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -139,7 +142,10 @@ func (u *RuntimeConfigConfigIamUpdater) SetResourceIamPolicy(policy *cloudresour obj := make(map[string]interface{}) obj["policy"] = json - url := u.qualifyConfigUrl("setIamPolicy") + url, err := u.qualifyConfigUrl("setIamPolicy") + if err != nil { + return err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -154,8 +160,13 @@ func (u *RuntimeConfigConfigIamUpdater) SetResourceIamPolicy(policy *cloudresour return nil } -func (u *RuntimeConfigConfigIamUpdater) qualifyConfigUrl(methodIdentifier string) string { - return fmt.Sprintf("https://runtimeconfig.googleapis.com/v1beta1/%s:%s", fmt.Sprintf("projects/%s/configs/%s", u.project, u.config), methodIdentifier) +func (u *RuntimeConfigConfigIamUpdater) qualifyConfigUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{RuntimeConfigBasePath}}%s:%s", fmt.Sprintf("projects/%s/configs/%s", u.project, u.config), methodIdentifier) + url, err := replaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil } func (u *RuntimeConfigConfigIamUpdater) GetResourceId() string { diff --git a/google/iam_source_repo_repository.go b/google/iam_source_repo_repository.go index d62ae4c4889..ade79acbc8f 100644 --- a/google/iam_source_repo_repository.go +++ b/google/iam_source_repo_repository.go @@ -108,7 +108,10 @@ func SourceRepoRepositoryIdParseFunc(d *schema.ResourceData, config *Config) err } func (u *SourceRepoRepositoryIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { - url := u.qualifyRepositoryUrl("getIamPolicy") + url, err := u.qualifyRepositoryUrl("getIamPolicy") + if err != nil { + return nil, err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -139,7 +142,10 @@ func (u *SourceRepoRepositoryIamUpdater) SetResourceIamPolicy(policy *cloudresou obj := make(map[string]interface{}) obj["policy"] = json - url := u.qualifyRepositoryUrl("setIamPolicy") + url, err := u.qualifyRepositoryUrl("setIamPolicy") + if err != nil { + return err + } project, err := getProject(u.d, u.Config) if err != nil { @@ -154,8 +160,13 @@ func (u *SourceRepoRepositoryIamUpdater) SetResourceIamPolicy(policy *cloudresou return nil } -func (u *SourceRepoRepositoryIamUpdater) qualifyRepositoryUrl(methodIdentifier string) string { - return fmt.Sprintf("https://sourcerepo.googleapis.com/v1/%s:%s", fmt.Sprintf("projects/%s/repos/%s", u.project, u.repository), methodIdentifier) +func (u *SourceRepoRepositoryIamUpdater) qualifyRepositoryUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{SourceRepoBasePath}}%s:%s", fmt.Sprintf("projects/%s/repos/%s", u.project, u.repository), methodIdentifier) + url, err := replaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil } func (u *SourceRepoRepositoryIamUpdater) GetResourceId() string { diff --git a/google/provider.go b/google/provider.go index 9b03266c96b..7a4a881b1e3 100644 --- a/google/provider.go +++ b/google/provider.go @@ -454,8 +454,8 @@ func Provider() terraform.ResourceProvider { } // Generated resources: 86 -// Generated IAM resources: 39 -// Total generated resources: 125 +// Generated IAM resources: 42 +// Total generated resources: 128 func ResourceMap() map[string]*schema.Resource { resourceMap, _ := ResourceMapWithErrors() return resourceMap @@ -485,6 +485,9 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) { "google_cloudfunctions_function_iam_policy": ResourceIamPolicy(CloudFunctionsCloudFunctionIamSchema, CloudFunctionsCloudFunctionIamUpdaterProducer, CloudFunctionsCloudFunctionIdParseFunc), "google_cloud_run_domain_mapping": resourceCloudRunDomainMapping(), "google_cloud_run_service": resourceCloudRunService(), + "google_cloud_run_service_iam_binding": ResourceIamBinding(CloudRunServiceIamSchema, CloudRunServiceIamUpdaterProducer, CloudRunServiceIdParseFunc), + "google_cloud_run_service_iam_member": ResourceIamMember(CloudRunServiceIamSchema, CloudRunServiceIamUpdaterProducer, CloudRunServiceIdParseFunc), + "google_cloud_run_service_iam_policy": ResourceIamPolicy(CloudRunServiceIamSchema, CloudRunServiceIamUpdaterProducer, CloudRunServiceIdParseFunc), "google_cloud_scheduler_job": resourceCloudSchedulerJob(), "google_cloud_tasks_queue": resourceCloudTasksQueue(), "google_compute_address": resourceComputeAddress(), diff --git a/google/resource_cloud_run_domain_mapping.go b/google/resource_cloud_run_domain_mapping.go index 0e207a98fe3..3730f6a7f9d 100644 --- a/google/resource_cloud_run_domain_mapping.go +++ b/google/resource_cloud_run_domain_mapping.go @@ -263,7 +263,7 @@ func resourceCloudRunDomainMappingCreate(d *schema.ResourceData, meta interface{ return err } - url, err := replaceVars(d, config, "{{CloudRunBasePath}}domains.cloudrun.com/v1/namespaces/{{project}}/domainmappings") + url, err := replaceVars(d, config, "{{CloudRunBasePath}}apis/domains.cloudrun.com/v1/namespaces/{{project}}/domainmappings") if err != nil { return err } @@ -293,7 +293,7 @@ func resourceCloudRunDomainMappingCreate(d *schema.ResourceData, meta interface{ func resourceCloudRunDomainMappingRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - url, err := replaceVars(d, config, "{{CloudRunBasePath}}domains.cloudrun.com/v1/namespaces/{{project}}/domainmappings/{{name}}") + url, err := replaceVars(d, config, "{{CloudRunBasePath}}apis/domains.cloudrun.com/v1/namespaces/{{project}}/domainmappings/{{name}}") if err != nil { return err } @@ -363,7 +363,7 @@ func resourceCloudRunDomainMappingUpdate(d *schema.ResourceData, meta interface{ return err } - url, err := replaceVars(d, config, "{{CloudRunBasePath}}domains.cloudrun.com/v1/namespaces/{{project}}/domainmappings/{{name}}") + url, err := replaceVars(d, config, "{{CloudRunBasePath}}apis/domains.cloudrun.com/v1/namespaces/{{project}}/domainmappings/{{name}}") if err != nil { return err } @@ -386,7 +386,7 @@ func resourceCloudRunDomainMappingDelete(d *schema.ResourceData, meta interface{ return err } - url, err := replaceVars(d, config, "{{CloudRunBasePath}}domains.cloudrun.com/v1/namespaces/{{project}}/domainmappings/{{name}}") + url, err := replaceVars(d, config, "{{CloudRunBasePath}}apis/domains.cloudrun.com/v1/namespaces/{{project}}/domainmappings/{{name}}") if err != nil { return err } diff --git a/google/resource_cloud_run_domain_mapping_generated_test.go b/google/resource_cloud_run_domain_mapping_generated_test.go index be989ec1446..1b2475e9751 100644 --- a/google/resource_cloud_run_domain_mapping_generated_test.go +++ b/google/resource_cloud_run_domain_mapping_generated_test.go @@ -96,7 +96,7 @@ func testAccCheckCloudRunDomainMappingDestroy(s *terraform.State) error { config := testAccProvider.Meta().(*Config) - url, err := replaceVarsForTest(config, rs, "{{CloudRunBasePath}}domains.cloudrun.com/v1/namespaces/{{project}}/domainmappings/{{name}}") + url, err := replaceVarsForTest(config, rs, "{{CloudRunBasePath}}apis/domains.cloudrun.com/v1/namespaces/{{project}}/domainmappings/{{name}}") if err != nil { return err } diff --git a/google/resource_cloud_run_service.go b/google/resource_cloud_run_service.go index b6336614621..5767ab9cb74 100644 --- a/google/resource_cloud_run_service.go +++ b/google/resource_cloud_run_service.go @@ -592,7 +592,7 @@ func resourceCloudRunServiceCreate(d *schema.ResourceData, meta interface{}) err return err } - url, err := replaceVars(d, config, "{{CloudRunBasePath}}serving.knative.dev/v1/namespaces/{{project}}/services") + url, err := replaceVars(d, config, "{{CloudRunBasePath}}apis/serving.knative.dev/v1/namespaces/{{project}}/services") if err != nil { return err } @@ -614,7 +614,7 @@ func resourceCloudRunServiceCreate(d *schema.ResourceData, meta interface{}) err } d.SetId(id) - waitURL, err := replaceVars(d, config, "{{CloudRunBasePath}}serving.knative.dev/v1/namespaces/{{project}}/services/{{name}}") + waitURL, err := replaceVars(d, config, "{{CloudRunBasePath}}apis/serving.knative.dev/v1/namespaces/{{project}}/services/{{name}}") if err != nil { return err } @@ -635,7 +635,7 @@ func resourceCloudRunServiceCreate(d *schema.ResourceData, meta interface{}) err func resourceCloudRunServiceRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - url, err := replaceVars(d, config, "{{CloudRunBasePath}}serving.knative.dev/v1/namespaces/{{project}}/services/{{name}}") + url, err := replaceVars(d, config, "{{CloudRunBasePath}}apis/serving.knative.dev/v1/namespaces/{{project}}/services/{{name}}") if err != nil { return err } @@ -712,7 +712,7 @@ func resourceCloudRunServiceUpdate(d *schema.ResourceData, meta interface{}) err return err } - url, err := replaceVars(d, config, "{{CloudRunBasePath}}serving.knative.dev/v1/namespaces/{{project}}/services/{{name}}") + url, err := replaceVars(d, config, "{{CloudRunBasePath}}apis/serving.knative.dev/v1/namespaces/{{project}}/services/{{name}}") if err != nil { return err } @@ -724,7 +724,7 @@ func resourceCloudRunServiceUpdate(d *schema.ResourceData, meta interface{}) err return fmt.Errorf("Error updating Service %q: %s", d.Id(), err) } - waitURL, err := replaceVars(d, config, "{{CloudRunBasePath}}serving.knative.dev/v1/namespaces/{{project}}/services/{{name}}") + waitURL, err := replaceVars(d, config, "{{CloudRunBasePath}}apis/serving.knative.dev/v1/namespaces/{{project}}/services/{{name}}") if err != nil { return err } @@ -748,7 +748,7 @@ func resourceCloudRunServiceDelete(d *schema.ResourceData, meta interface{}) err return err } - url, err := replaceVars(d, config, "{{CloudRunBasePath}}serving.knative.dev/v1/namespaces/{{project}}/services/{{name}}") + url, err := replaceVars(d, config, "{{CloudRunBasePath}}apis/serving.knative.dev/v1/namespaces/{{project}}/services/{{name}}") if err != nil { return err } diff --git a/google/resource_cloud_run_service_generated_test.go b/google/resource_cloud_run_service_generated_test.go deleted file mode 100644 index 1e8eb3dd1d2..00000000000 --- a/google/resource_cloud_run_service_generated_test.go +++ /dev/null @@ -1,101 +0,0 @@ -// ---------------------------------------------------------------------------- -// -// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** -// -// ---------------------------------------------------------------------------- -// -// This file is automatically generated by Magic Modules and manual -// changes will be clobbered when the file is regenerated. -// -// Please read more about how to change this file in -// .github/CONTRIBUTING.md. -// -// ---------------------------------------------------------------------------- - -package google - -import ( - "fmt" - "strings" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" -) - -func TestAccCloudRunService_cloudRunServiceBasicExample(t *testing.T) { - t.Parallel() - - context := map[string]interface{}{ - "namespace": getTestProjectFromEnv(), - "random_suffix": acctest.RandString(10), - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckCloudRunServiceDestroy, - Steps: []resource.TestStep{ - { - Config: testAccCloudRunService_cloudRunServiceBasicExample(context), - }, - { - ResourceName: "google_cloud_run_service.default", - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func testAccCloudRunService_cloudRunServiceBasicExample(context map[string]interface{}) string { - return Nprintf(` -resource "google_cloud_run_service" "default" { - name = "tftest-cloudrun%{random_suffix}" - location = "us-central1" - - metadata { - namespace = "%{namespace}" - } - - template { - spec { - containers { - image = "gcr.io/cloudrun/hello" - } - } - } - - traffic { - percent = 100 - latest_revision = true - } -} -`, context) -} - -func testAccCheckCloudRunServiceDestroy(s *terraform.State) error { - for name, rs := range s.RootModule().Resources { - if rs.Type != "google_cloud_run_service" { - continue - } - if strings.HasPrefix(name, "data.") { - continue - } - - config := testAccProvider.Meta().(*Config) - - url, err := replaceVarsForTest(config, rs, "{{CloudRunBasePath}}serving.knative.dev/v1/namespaces/{{project}}/services/{{name}}") - if err != nil { - return err - } - - _, err = sendRequest(config, "GET", "", url, nil) - if err == nil { - return fmt.Errorf("CloudRunService still exists at %s", url) - } - } - - return nil -} diff --git a/google/resource_cloud_run_service_iam_test.go b/google/resource_cloud_run_service_iam_test.go new file mode 100644 index 00000000000..dcb787455f9 --- /dev/null +++ b/google/resource_cloud_run_service_iam_test.go @@ -0,0 +1,240 @@ +package google + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccCloudRunServiceIamBinding(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/viewer", + "namespace": getTestProjectFromEnv(), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCloudRunServiceIamBinding_basic(context), + }, + { + ResourceName: "google_cloud_run_service_iam_binding.foo", + ImportStateId: fmt.Sprintf("projects/%s/locations/%s/services/%s roles/viewer", getTestProjectFromEnv(), getTestRegionFromEnv(), fmt.Sprintf("tftest-cloudrun%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + { + // Test Iam Binding update + Config: testAccCloudRunServiceIamBinding_update(context), + }, + { + ResourceName: "google_cloud_run_service_iam_binding.foo", + ImportStateId: fmt.Sprintf("projects/%s/locations/%s/services/%s roles/viewer", getTestProjectFromEnv(), getTestRegionFromEnv(), fmt.Sprintf("tftest-cloudrun%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccCloudRunServiceIamMember(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/viewer", + "namespace": getTestProjectFromEnv(), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + // Test Iam Member creation (no update for member, no need to test) + Config: testAccCloudRunServiceIamMember_basic(context), + }, + { + ResourceName: "google_cloud_run_service_iam_member.foo", + ImportStateId: fmt.Sprintf("projects/%s/locations/%s/services/%s roles/viewer user:admin@hashicorptest.com", getTestProjectFromEnv(), getTestRegionFromEnv(), fmt.Sprintf("tftest-cloudrun%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccCloudRunServiceIamPolicy(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/viewer", + "namespace": getTestProjectFromEnv(), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCloudRunServiceIamPolicy_basic(context), + }, + { + ResourceName: "google_cloud_run_service_iam_policy.foo", + ImportStateId: fmt.Sprintf("projects/%s/locations/%s/services/%s", getTestProjectFromEnv(), getTestRegionFromEnv(), fmt.Sprintf("tftest-cloudrun%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCloudRunServiceIamMember_basic(context map[string]interface{}) string { + return Nprintf(` +resource "google_cloud_run_service" "default" { + name = "tftest-cloudrun%{random_suffix}" + location = "us-central1" + + metadata { + namespace = "%{namespace}" + } + + template { + spec { + containers { + image = "gcr.io/cloudrun/hello" + } + } + } + + traffic { + percent = 100 + latest_revision = true + } +} + +resource "google_cloud_run_service_iam_member" "foo" { + location = "${google_cloud_run_service.default.location}" + project = "${google_cloud_run_service.default.project}" + service = "${google_cloud_run_service.default.name}" + role = "%{role}" + member = "user:admin@hashicorptest.com" +} +`, context) +} + +func testAccCloudRunServiceIamPolicy_basic(context map[string]interface{}) string { + return Nprintf(` +resource "google_cloud_run_service" "default" { + name = "tftest-cloudrun%{random_suffix}" + location = "us-central1" + + metadata { + namespace = "%{namespace}" + } + + template { + spec { + containers { + image = "gcr.io/cloudrun/hello" + } + } + } + + traffic { + percent = 100 + latest_revision = true + } +} + +data "google_iam_policy" "foo" { + binding { + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + } +} + +resource "google_cloud_run_service_iam_policy" "foo" { + location = "${google_cloud_run_service.default.location}" + project = "${google_cloud_run_service.default.project}" + service = "${google_cloud_run_service.default.name}" + policy_data = "${data.google_iam_policy.foo.policy_data}" +} +`, context) +} + +func testAccCloudRunServiceIamBinding_basic(context map[string]interface{}) string { + return Nprintf(` +resource "google_cloud_run_service" "default" { + name = "tftest-cloudrun%{random_suffix}" + location = "us-central1" + + metadata { + namespace = "%{namespace}" + } + + template { + spec { + containers { + image = "gcr.io/cloudrun/hello" + } + } + } + + traffic { + percent = 100 + latest_revision = true + } +} + +resource "google_cloud_run_service_iam_binding" "foo" { + location = "${google_cloud_run_service.default.location}" + project = "${google_cloud_run_service.default.project}" + service = "${google_cloud_run_service.default.name}" + role = "%{role}" + members = ["user:admin@hashicorptest.com"] +} +`, context) +} + +func testAccCloudRunServiceIamBinding_update(context map[string]interface{}) string { + return Nprintf(` +resource "google_cloud_run_service" "default" { + name = "tftest-cloudrun%{random_suffix}" + location = "us-central1" + + metadata { + namespace = "%{namespace}" + } + + template { + spec { + containers { + image = "gcr.io/cloudrun/hello" + } + } + } + + traffic { + percent = 100 + latest_revision = true + } +} + +resource "google_cloud_run_service_iam_binding" "foo" { + location = "${google_cloud_run_service.default.location}" + project = "${google_cloud_run_service.default.project}" + service = "${google_cloud_run_service.default.name}" + role = "%{role}" + members = ["user:admin@hashicorptest.com", "user:paddy@hashicorp.com"] +} +`, context) +} diff --git a/google/resource_sql_database_instance_test.go b/google/resource_sql_database_instance_test.go index 402fe1699bc..4c96a3d03b9 100644 --- a/google/resource_sql_database_instance_test.go +++ b/google/resource_sql_database_instance_test.go @@ -9,7 +9,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" - sqladmin "google.golang.org/api/sqladmin/v1beta4" ) diff --git a/website/docs/r/cloud_run_service.html.markdown b/website/docs/r/cloud_run_service.html.markdown index 9163e794515..05a5d728757 100644 --- a/website/docs/r/cloud_run_service.html.markdown +++ b/website/docs/r/cloud_run_service.html.markdown @@ -44,11 +44,6 @@ To get more information about Service, see: * How-to Guides * [Official Documentation](https://cloud.google.com/run/docs/) - ## Example Usage - Cloud Run Service Basic diff --git a/website/docs/r/cloud_run_service_iam.html.markdown b/website/docs/r/cloud_run_service_iam.html.markdown new file mode 100644 index 00000000000..4ebd2e6c9d5 --- /dev/null +++ b/website/docs/r/cloud_run_service_iam.html.markdown @@ -0,0 +1,148 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Cloud Run" +layout: "google" +page_title: "Google: google_cloud_run_service_iam" +sidebar_current: "docs-google-cloud-run-service-iam" +description: |- + Collection of resources to manage IAM policy for CloudRunService +--- + +# IAM policy for CloudRunService +Three different resources help you manage your IAM policy for CloudRun Service. Each of these resources serves a different use case: + +* `google_cloud_run_service_iam_policy`: Authoritative. Sets the IAM policy for the service and replaces any existing policy already attached. +* `google_cloud_run_service_iam_binding`: Authoritative for a given role. Updates the IAM policy to grant a role to a list of members. Other roles within the IAM policy for the service are preserved. +* `google_cloud_run_service_iam_member`: Non-authoritative. Updates the IAM policy to grant a role to a new member. Other members for the role for the service are preserved. + +~> **Note:** `google_cloud_run_service_iam_policy` **cannot** be used in conjunction with `google_cloud_run_service_iam_binding` and `google_cloud_run_service_iam_member` or they will fight over what your policy should be. + +~> **Note:** `google_cloud_run_service_iam_binding` resources **can be** used in conjunction with `google_cloud_run_service_iam_member` resources **only if** they do not grant privilege to the same role. + + + +## google\_cloud\_run\_service\_iam\_policy + +```hcl +data "google_iam_policy" "admin" { + binding { + role = "roles/viewer" + members = [ + "user:jane@example.com", + ] + } +} + +resource "google_cloud_run_service_iam_policy" "editor" { + location = "${google_cloud_run_service.default.location}" + project = "${google_cloud_run_service.default.project}" + service = "${google_cloud_run_service.default.name}" + policy_data = "${data.google_iam_policy.admin.policy_data}" +} +``` + +## google\_cloud\_run\_service\_iam\_binding + +```hcl +resource "google_cloud_run_service_iam_binding" "editor" { + location = "${google_cloud_run_service.default.location}" + project = "${google_cloud_run_service.default.project}" + service = "${google_cloud_run_service.default.name}" + role = "roles/viewer" + members = [ + "user:jane@example.com", + ] +} +``` + +## google\_cloud\_run\_service\_iam\_member + +```hcl +resource "google_cloud_run_service_iam_member" "editor" { + location = "${google_cloud_run_service.default.location}" + project = "${google_cloud_run_service.default.project}" + service = "${google_cloud_run_service.default.name}" + role = "roles/viewer" + member = "user:jane@example.com" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `service` - (Required) Used to find the parent resource to bind the IAM policy to +* `location` - (Required) The location of the cloud run instance. eg us-central1 Used to find the parent resource to bind the IAM policy to + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the project will be parsed from the identifier of the parent resource. If no project is provided in the parent identifier and no project is specified, the provider project is used. + +* `member/members` - (Required) Identities that will be granted the privilege in `role`. + Each entry can have one of the following values: + * **allUsers**: A special identifier that represents anyone who is on the internet; with or without a Google account. + * **allAuthenticatedUsers**: A special identifier that represents anyone who is authenticated with a Google account or a service account. + * **user:{emailid}**: An email address that represents a specific Google account. For example, alice@gmail.com or joe@example.com. + * **serviceAccount:{emailid}**: An email address that represents a service account. For example, my-other-app@appspot.gserviceaccount.com. + * **group:{emailid}**: An email address that represents a Google group. For example, admins@example.com. + * **domain:{domain}**: A G Suite domain (primary, instead of alias) name that represents all the users of that domain. For example, google.com or example.com. + +* `role` - (Required) The role that should be applied. Only one + `google_cloud_run_service_iam_binding` can be used per role. Note that custom roles must be of the format + `[projects|organizations]/{parent-name}/roles/{role-name}`. + +* `policy_data` - (Required only by `google_cloud_run_service_iam_policy`) The policy data generated by + a `google_iam_policy` data source. + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are +exported: + +* `etag` - (Computed) The etag of the IAM policy. + +## Import + +For all import syntaxes, the "resource in question" can take any of the following forms: + +* projects/{{project}}/locations/{{location}}/services/{{service}} +* {{project}}/{{location}}/{{service}} +* {{location}}/{{service}} +* {{service}} + +Any variables not passed in the import command will be taken from the provider configuration. + +CloudRun service IAM resources can be imported using the resource identifiers, role, and member. + +IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g. +``` +$ terraform import google_cloud_run_service_iam_member.editor "locations/{{location}}/namespaces/{{project}}/services/{{service}} roles/viewer jane@example.com" +``` + +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. +``` +$ terraform import google_cloud_run_service_iam_binding.editor "locations/{{location}}/namespaces/{{project}}/services/{{service}} roles/viewer" +``` + +IAM policy imports use the identifier of the resource in question, e.g. +``` +$ terraform import google_cloud_run_service_iam_policy.editor locations/{{location}}/namespaces/{{project}}/services/{{service}} +``` + +-> If you're importing a resource with beta features, make sure to include `-provider=google-beta` +as an argument so that Terraform uses the correct provider to import your resource. + +## User Project Overrides + +This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override).