diff --git a/google-beta/config.go b/google-beta/config.go index c10f810d8b..2e68340006 100644 --- a/google-beta/config.go +++ b/google-beta/config.go @@ -88,6 +88,7 @@ type Config struct { FilestoreBasePath string FirestoreBasePath string HealthcareBasePath string + IapBasePath string KMSBasePath string LoggingBasePath string MLEngineBasePath string @@ -223,6 +224,7 @@ var DNSDefaultBasePath = "https://www.googleapis.com/dns/v1beta2/" var FilestoreDefaultBasePath = "https://file.googleapis.com/v1/" var FirestoreDefaultBasePath = "https://firestore.googleapis.com/v1/" var HealthcareDefaultBasePath = "https://healthcare.googleapis.com/v1beta1/" +var IapDefaultBasePath = "https://iap.googleapis.com/v1/" var KMSDefaultBasePath = "https://cloudkms.googleapis.com/v1/" var LoggingDefaultBasePath = "https://logging.googleapis.com/v2/" var MLEngineDefaultBasePath = "https://ml.googleapis.com/v1/" @@ -708,6 +710,7 @@ func ConfigureBasePaths(c *Config) { c.FilestoreBasePath = FilestoreDefaultBasePath c.FirestoreBasePath = FirestoreDefaultBasePath c.HealthcareBasePath = HealthcareDefaultBasePath + c.IapBasePath = IapDefaultBasePath c.KMSBasePath = KMSDefaultBasePath c.LoggingBasePath = LoggingDefaultBasePath c.MLEngineBasePath = MLEngineDefaultBasePath diff --git a/google-beta/iam.go b/google-beta/iam.go index 9684ad1047..b65688c150 100644 --- a/google-beta/iam.go +++ b/google-beta/iam.go @@ -6,6 +6,7 @@ import ( "fmt" "log" "reflect" + "regexp" "strings" "time" @@ -347,3 +348,79 @@ func compareAuditConfigs(a, b []*cloudresourcemanager.AuditConfig) bool { bMap := createIamAuditConfigsMap(b) return reflect.DeepEqual(aMap, bMap) } + +// Parse an import id extracting field values using the given list of regexes. +// They are applied in order. The first in the list is tried first. +// This does not mutate any of the parameters, returning a map of matches +// Similar to parseImportId in import.go, but less import specific +// +// e.g: +// - projects/(?P[^/]+)/regions/(?P[^/]+)/subnetworks/(?P[^/]+) (applied first) +// - (?P[^/]+)/(?P[^/]+)/(?P[^/]+), +// - (?P[^/]+) (applied last) +func getImportIdQualifiers(idRegexes []string, d TerraformResourceData, config *Config, id string) (map[string]string, error) { + for _, idFormat := range idRegexes { + re, err := regexp.Compile(idFormat) + + if err != nil { + log.Printf("[DEBUG] Could not compile %s.", idFormat) + return nil, fmt.Errorf("Import is not supported. Invalid regex formats.") + } + + if fieldValues := re.FindStringSubmatch(id); fieldValues != nil { + var result map[string]string + result = make(map[string]string) + log.Printf("[DEBUG] matching ID %s to regex %s.", id, idFormat) + // Starting at index 1, the first match is the full string. + for i := 1; i < len(fieldValues); i++ { + fieldName := re.SubexpNames()[i] + fieldValue := fieldValues[i] + result[fieldName] = fieldValue + } + + defaults, err := getDefaultValues(idRegexes[0], d, config) + if err != nil { + return nil, err + } + + for k, v := range defaults { + if _, ok := result[k]; !ok { + // Set any fields that are defaultable and not specified in import ID + result[k] = v + } + } + + return result, nil + } + } + return nil, fmt.Errorf("Import id %q doesn't match any of the accepted formats: %v", d.Id(), idRegexes) +} + +// Returns a set of default values that are contained in a regular expression +// This does not mutate any parameters, instead returning a map of defaults +func getDefaultValues(idRegex string, d TerraformResourceData, config *Config) (map[string]string, error) { + var result map[string]string + result = make(map[string]string) + if _, ok := d.GetOk("project"); !ok && strings.Contains(idRegex, "?P") { + project, err := getProject(d, config) + if err != nil { + return nil, err + } + result["project"] = project + } + if _, ok := d.GetOk("region"); !ok && strings.Contains(idRegex, "?P") { + region, err := getRegion(d, config) + if err != nil { + return nil, err + } + result["region"] = region + } + if _, ok := d.GetOk("zone"); !ok && strings.Contains(idRegex, "?P") { + zone, err := getZone(d, config) + if err != nil { + return nil, err + } + result["zone"] = zone + } + return result, nil +} diff --git a/google-beta/iam_iap_web.go b/google-beta/iam_iap_web.go new file mode 100644 index 0000000000..5c15c6abdf --- /dev/null +++ b/google-beta/iam_iap_web.go @@ -0,0 +1,165 @@ +// ---------------------------------------------------------------------------- +// +// *** 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/helper/schema" + "google.golang.org/api/cloudresourcemanager/v1" +) + +var IapWebIamSchema = map[string]*schema.Schema{ + "project": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + }, +} + +type IapWebIamUpdater struct { + project string + d *schema.ResourceData + Config *Config +} + +func IapWebIamUpdaterProducer(d *schema.ResourceData, config *Config) (ResourceIamUpdater, error) { + values := make(map[string]string) + + project, err := getProject(d, config) + if err != nil { + return nil, err + } + + // While this may be overridden by the "project" value from getImportIdQualifiers below, + // setting project here ensures the value is set even if the value set in config is the short + // name or otherwise doesn't include the project. + values["project"] = project + + // We may have gotten either a long or short name, so attempt to parse long name if possible + m, err := getImportIdQualifiers([]string{"projects/(?P[^/]+)/iap_web", "(?P[^/]+)"}, d, config, d.Get("project").(string)) + if err != nil { + return nil, err + } + + for k, v := range m { + values[k] = v + } + + u := &IapWebIamUpdater{ + project: values["project"], + d: d, + Config: config, + } + + d.Set("project", u.project) + + d.SetId(u.GetResourceId()) + + return u, nil +} + +func IapWebIdParseFunc(d *schema.ResourceData, config *Config) error { + values := make(map[string]string) + + project, err := getProject(d, config) + if err != nil { + return err + } + + values["project"] = project + + m, err := getImportIdQualifiers([]string{"projects/(?P[^/]+)/iap_web", "(?P[^/]+)"}, d, config, d.Id()) + if err != nil { + return err + } + + for k, v := range m { + values[k] = v + } + + u := &IapWebIamUpdater{ + project: values["project"], + d: d, + Config: config, + } + d.Set("project", u.project) + d.SetId(u.GetResourceId()) + return nil +} + +func (u *IapWebIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { + url := u.qualifyWebUrl("getIamPolicy") + + project, err := getProject(u.d, u.Config) + if err != nil { + return nil, err + } + + policy, err := sendRequest(u.Config, "POST", project, url, nil) + 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 *IapWebIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanager.Policy) error { + json, err := ConvertToMap(policy) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + obj["policy"] = json + + url := u.qualifyWebUrl("setIamPolicy") + + 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 *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) GetResourceId() string { + return fmt.Sprintf("projects/%s/iap_web", u.project) +} + +func (u *IapWebIamUpdater) GetMutexKey() string { + return fmt.Sprintf("iam-iap-web-%s", u.GetResourceId()) +} + +func (u *IapWebIamUpdater) DescribeResource() string { + return fmt.Sprintf("iap web %q", u.GetResourceId()) +} diff --git a/google-beta/iam_iap_web_backend_service.go b/google-beta/iam_iap_web_backend_service.go new file mode 100644 index 0000000000..d24eb7d7b8 --- /dev/null +++ b/google-beta/iam_iap_web_backend_service.go @@ -0,0 +1,174 @@ +// ---------------------------------------------------------------------------- +// +// *** 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/helper/schema" + "google.golang.org/api/cloudresourcemanager/v1" +) + +var IapWebBackendServiceIamSchema = map[string]*schema.Schema{ + "project": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + }, + "backend_service_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + }, +} + +type IapWebBackendServiceIamUpdater struct { + project string + backendServiceName string + d *schema.ResourceData + Config *Config +} + +func IapWebBackendServiceIamUpdaterProducer(d *schema.ResourceData, config *Config) (ResourceIamUpdater, error) { + values := make(map[string]string) + + project, err := getProject(d, config) + if err != nil { + return nil, err + } + + // While this may be overridden by the "project" value from getImportIdQualifiers below, + // setting project here ensures the value is set even if the value set in config is the short + // name or otherwise doesn't include the project. + values["project"] = project + + // We may have gotten either a long or short name, so attempt to parse long name if possible + m, err := getImportIdQualifiers([]string{"projects/(?P[^/]+)/iap_web/compute/services/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Get("backend_service_name").(string)) + if err != nil { + return nil, err + } + + for k, v := range m { + values[k] = v + } + + u := &IapWebBackendServiceIamUpdater{ + project: values["project"], + backendServiceName: values["backendServiceName"], + d: d, + Config: config, + } + + d.Set("project", u.project) + d.Set("backend_service_name", u.GetResourceId()) + + d.SetId(u.GetResourceId()) + + return u, nil +} + +func IapWebBackendServiceIdParseFunc(d *schema.ResourceData, config *Config) error { + values := make(map[string]string) + + project, err := getProject(d, config) + if err != nil { + return err + } + + values["project"] = project + + m, err := getImportIdQualifiers([]string{"projects/(?P[^/]+)/iap_web/compute/services/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Id()) + if err != nil { + return err + } + + for k, v := range m { + values[k] = v + } + + u := &IapWebBackendServiceIamUpdater{ + project: values["project"], + backendServiceName: values["backendServiceName"], + d: d, + Config: config, + } + d.Set("backend_service_name", u.GetResourceId()) + d.SetId(u.GetResourceId()) + return nil +} + +func (u *IapWebBackendServiceIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { + url := u.qualifyWebBackendServiceUrl("getIamPolicy") + + project, err := getProject(u.d, u.Config) + if err != nil { + return nil, err + } + + policy, err := sendRequest(u.Config, "POST", project, url, nil) + 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 *IapWebBackendServiceIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanager.Policy) error { + json, err := ConvertToMap(policy) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + obj["policy"] = json + + url := u.qualifyWebBackendServiceUrl("setIamPolicy") + + 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 *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.backendServiceName), methodIdentifier) +} + +func (u *IapWebBackendServiceIamUpdater) GetResourceId() string { + return fmt.Sprintf("projects/%s/iap_web/compute/services/%s", u.project, u.backendServiceName) +} + +func (u *IapWebBackendServiceIamUpdater) GetMutexKey() string { + return fmt.Sprintf("iam-iap-webbackendservice-%s", u.GetResourceId()) +} + +func (u *IapWebBackendServiceIamUpdater) DescribeResource() string { + return fmt.Sprintf("iap webbackendservice %q", u.GetResourceId()) +} diff --git a/google-beta/iam_iap_web_backend_service_generated_test.go b/google-beta/iam_iap_web_backend_service_generated_test.go new file mode 100644 index 0000000000..d5409afb24 --- /dev/null +++ b/google-beta/iam_iap_web_backend_service_generated_test.go @@ -0,0 +1,207 @@ +// ---------------------------------------------------------------------------- +// +// *** 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" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccIapWebBackendServiceIamBindingGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/iap.httpsResourceAccessor", + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccIapWebBackendServiceIamBinding_basicGenerated(context), + }, + { + ResourceName: "google_iap_web_backend_service_iam_binding.foo", + ImportStateId: fmt.Sprintf("projects/%s/iap_web/compute/services/%s roles/iap.httpsResourceAccessor", getTestProjectFromEnv(), fmt.Sprintf("backend-service%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + { + // Test Iam Binding update + Config: testAccIapWebBackendServiceIamBinding_updateGenerated(context), + }, + { + ResourceName: "google_iap_web_backend_service_iam_binding.foo", + ImportStateId: fmt.Sprintf("projects/%s/iap_web/compute/services/%s roles/iap.httpsResourceAccessor", getTestProjectFromEnv(), fmt.Sprintf("backend-service%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccIapWebBackendServiceIamMemberGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/iap.httpsResourceAccessor", + } + + 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: testAccIapWebBackendServiceIamMember_basicGenerated(context), + }, + { + ResourceName: "google_iap_web_backend_service_iam_member.foo", + ImportStateId: fmt.Sprintf("projects/%s/iap_web/compute/services/%s roles/iap.httpsResourceAccessor user:admin@hashicorptest.com", getTestProjectFromEnv(), fmt.Sprintf("backend-service%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccIapWebBackendServiceIamPolicyGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/iap.httpsResourceAccessor", + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccIapWebBackendServiceIamPolicy_basicGenerated(context), + }, + { + ResourceName: "google_iap_web_backend_service_iam_policy.foo", + ImportStateId: fmt.Sprintf("projects/%s/iap_web/compute/services/%s", getTestProjectFromEnv(), fmt.Sprintf("backend-service%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccIapWebBackendServiceIamMember_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_backend_service" "default" { + name = "backend-service%{random_suffix}" + health_checks = ["${google_compute_http_health_check.default.self_link}"] +} + +resource "google_compute_http_health_check" "default" { + name = "health-check%{random_suffix}" + request_path = "/" + check_interval_sec = 1 + timeout_sec = 1 +} + +resource "google_iap_web_backend_service_iam_member" "foo" { + project = "${google_compute_backend_service.default.project}" + backend_service_name = "${google_compute_backend_service.default.name}" + role = "%{role}" + member = "user:admin@hashicorptest.com" +} +`, context) +} + +func testAccIapWebBackendServiceIamPolicy_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_backend_service" "default" { + name = "backend-service%{random_suffix}" + health_checks = ["${google_compute_http_health_check.default.self_link}"] +} + +resource "google_compute_http_health_check" "default" { + name = "health-check%{random_suffix}" + request_path = "/" + check_interval_sec = 1 + timeout_sec = 1 +} + +data "google_iam_policy" "foo" { + binding { + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + } +} + +resource "google_iap_web_backend_service_iam_policy" "foo" { + project = "${google_compute_backend_service.default.project}" + backend_service_name = "${google_compute_backend_service.default.name}" + policy_data = "${data.google_iam_policy.foo.policy_data}" +} +`, context) +} + +func testAccIapWebBackendServiceIamBinding_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_backend_service" "default" { + name = "backend-service%{random_suffix}" + health_checks = ["${google_compute_http_health_check.default.self_link}"] +} + +resource "google_compute_http_health_check" "default" { + name = "health-check%{random_suffix}" + request_path = "/" + check_interval_sec = 1 + timeout_sec = 1 +} + +resource "google_iap_web_backend_service_iam_binding" "foo" { + project = "${google_compute_backend_service.default.project}" + backend_service_name = "${google_compute_backend_service.default.name}" + role = "%{role}" + members = ["user:admin@hashicorptest.com"] +} +`, context) +} + +func testAccIapWebBackendServiceIamBinding_updateGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_backend_service" "default" { + name = "backend-service%{random_suffix}" + health_checks = ["${google_compute_http_health_check.default.self_link}"] +} + +resource "google_compute_http_health_check" "default" { + name = "health-check%{random_suffix}" + request_path = "/" + check_interval_sec = 1 + timeout_sec = 1 +} + +resource "google_iap_web_backend_service_iam_binding" "foo" { + project = "${google_compute_backend_service.default.project}" + backend_service_name = "${google_compute_backend_service.default.name}" + role = "%{role}" + members = ["user:admin@hashicorptest.com", "user:paddy@hashicorp.com"] +} +`, context) +} diff --git a/google-beta/iam_iap_web_generated_test.go b/google-beta/iam_iap_web_generated_test.go new file mode 100644 index 0000000000..61efc9c027 --- /dev/null +++ b/google-beta/iam_iap_web_generated_test.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" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccIapWebIamBindingGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/iap.httpsResourceAccessor", + "org_id": getTestOrgFromEnv(t), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccIapWebIamBinding_basicGenerated(context), + }, + { + ResourceName: "google_iap_web_iam_binding.foo", + ImportStateId: fmt.Sprintf("projects/%s/iap_web roles/iap.httpsResourceAccessor", fmt.Sprintf("tf-test%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + { + // Test Iam Binding update + Config: testAccIapWebIamBinding_updateGenerated(context), + }, + { + ResourceName: "google_iap_web_iam_binding.foo", + ImportStateId: fmt.Sprintf("projects/%s/iap_web roles/iap.httpsResourceAccessor", fmt.Sprintf("tf-test%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccIapWebIamMemberGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/iap.httpsResourceAccessor", + "org_id": getTestOrgFromEnv(t), + } + + 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: testAccIapWebIamMember_basicGenerated(context), + }, + { + ResourceName: "google_iap_web_iam_member.foo", + ImportStateId: fmt.Sprintf("projects/%s/iap_web roles/iap.httpsResourceAccessor user:admin@hashicorptest.com", fmt.Sprintf("tf-test%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccIapWebIamPolicyGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/iap.httpsResourceAccessor", + "org_id": getTestOrgFromEnv(t), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccIapWebIamPolicy_basicGenerated(context), + }, + { + ResourceName: "google_iap_web_iam_policy.foo", + ImportStateId: fmt.Sprintf("projects/%s/iap_web", fmt.Sprintf("tf-test%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccIapWebIamMember_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" +} + +resource "google_project_service" "project_service" { + project = "${google_project.project.id}" + service = "iap.googleapis.com" +} + +resource "google_iap_web_iam_member" "foo" { + project = "${google_project_service.project_service.project}" + role = "%{role}" + member = "user:admin@hashicorptest.com" +} +`, context) +} + +func testAccIapWebIamPolicy_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" +} + +resource "google_project_service" "project_service" { + project = "${google_project.project.id}" + service = "iap.googleapis.com" +} + +data "google_iam_policy" "foo" { + binding { + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + } +} + +resource "google_iap_web_iam_policy" "foo" { + project = "${google_project_service.project_service.project}" + policy_data = "${data.google_iam_policy.foo.policy_data}" +} +`, context) +} + +func testAccIapWebIamBinding_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" +} + +resource "google_project_service" "project_service" { + project = "${google_project.project.id}" + service = "iap.googleapis.com" +} + +resource "google_iap_web_iam_binding" "foo" { + project = "${google_project_service.project_service.project}" + role = "%{role}" + members = ["user:admin@hashicorptest.com"] +} +`, context) +} + +func testAccIapWebIamBinding_updateGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" +} + +resource "google_project_service" "project_service" { + project = "${google_project.project.id}" + service = "iap.googleapis.com" +} + +resource "google_iap_web_iam_binding" "foo" { + project = "${google_project_service.project_service.project}" + role = "%{role}" + members = ["user:admin@hashicorptest.com", "user:paddy@hashicorp.com"] +} +`, context) +} diff --git a/google-beta/iam_iap_web_type_app_engine.go b/google-beta/iam_iap_web_type_app_engine.go new file mode 100644 index 0000000000..431b82a102 --- /dev/null +++ b/google-beta/iam_iap_web_type_app_engine.go @@ -0,0 +1,188 @@ +// ---------------------------------------------------------------------------- +// +// *** 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" + + "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform/helper/schema" + "google.golang.org/api/cloudresourcemanager/v1" +) + +var IapWebTypeAppEngineIamSchema = map[string]*schema.Schema{ + "project": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + }, + "app_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: IapWebTypeAppEngineDiffSuppress, + }, +} + +func IapWebTypeAppEngineDiffSuppress(_, old, new string, _ *schema.ResourceData) bool { + newParts := strings.Split(new, "appengine-") + + if len(newParts) == 1 { + // `new` is only the app engine id + // `old` is always a long name + if strings.HasSuffix(old, fmt.Sprintf("appengine-%s", new)) { + return true + } + } + return old == new +} + +type IapWebTypeAppEngineIamUpdater struct { + project string + appId string + d *schema.ResourceData + Config *Config +} + +func IapWebTypeAppEngineIamUpdaterProducer(d *schema.ResourceData, config *Config) (ResourceIamUpdater, error) { + values := make(map[string]string) + + project, err := getProject(d, config) + if err != nil { + return nil, err + } + + // While this may be overridden by the "project" value from getImportIdQualifiers below, + // setting project here ensures the value is set even if the value set in config is the short + // name or otherwise doesn't include the project. + values["project"] = project + + // We may have gotten either a long or short name, so attempt to parse long name if possible + m, err := getImportIdQualifiers([]string{"projects/(?P[^/]+)/iap_web/appengine-(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Get("app_id").(string)) + if err != nil { + return nil, err + } + + for k, v := range m { + values[k] = v + } + + u := &IapWebTypeAppEngineIamUpdater{ + project: values["project"], + appId: values["appId"], + d: d, + Config: config, + } + + d.Set("project", u.project) + d.Set("app_id", u.GetResourceId()) + + d.SetId(u.GetResourceId()) + + return u, nil +} + +func IapWebTypeAppEngineIdParseFunc(d *schema.ResourceData, config *Config) error { + values := make(map[string]string) + + project, err := getProject(d, config) + if err != nil { + return err + } + + values["project"] = project + + m, err := getImportIdQualifiers([]string{"projects/(?P[^/]+)/iap_web/appengine-(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Id()) + if err != nil { + return err + } + + for k, v := range m { + values[k] = v + } + + u := &IapWebTypeAppEngineIamUpdater{ + project: values["project"], + appId: values["appId"], + d: d, + Config: config, + } + d.Set("app_id", u.GetResourceId()) + d.SetId(u.GetResourceId()) + return nil +} + +func (u *IapWebTypeAppEngineIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { + url := u.qualifyWebTypeAppEngineUrl("getIamPolicy") + + project, err := getProject(u.d, u.Config) + if err != nil { + return nil, err + } + + policy, err := sendRequest(u.Config, "POST", project, url, nil) + 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 *IapWebTypeAppEngineIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanager.Policy) error { + json, err := ConvertToMap(policy) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + obj["policy"] = json + + url := u.qualifyWebTypeAppEngineUrl("setIamPolicy") + + 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 *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) GetResourceId() string { + return fmt.Sprintf("projects/%s/iap_web/appengine-%s", u.project, u.appId) +} + +func (u *IapWebTypeAppEngineIamUpdater) GetMutexKey() string { + return fmt.Sprintf("iam-iap-webtypeappengine-%s", u.GetResourceId()) +} + +func (u *IapWebTypeAppEngineIamUpdater) DescribeResource() string { + return fmt.Sprintf("iap webtypeappengine %q", u.GetResourceId()) +} diff --git a/google-beta/iam_iap_web_type_app_engine_generated_test.go b/google-beta/iam_iap_web_type_app_engine_generated_test.go new file mode 100644 index 0000000000..e29af8bca6 --- /dev/null +++ b/google-beta/iam_iap_web_type_app_engine_generated_test.go @@ -0,0 +1,229 @@ +// ---------------------------------------------------------------------------- +// +// *** 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" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccIapWebTypeAppEngineIamBindingGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/iap.httpsResourceAccessor", + "project_id": fmt.Sprintf("tf-test%s", acctest.RandString(10)), + "org_id": getTestOrgFromEnv(t), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccIapWebTypeAppEngineIamBinding_basicGenerated(context), + }, + { + ResourceName: "google_iap_web_type_app_engine_iam_binding.foo", + ImportStateId: fmt.Sprintf("projects/%s/iap_web/appengine-%s roles/iap.httpsResourceAccessor", context["project_id"], context["project_id"]), + ImportState: true, + ImportStateVerify: true, + }, + { + // Test Iam Binding update + Config: testAccIapWebTypeAppEngineIamBinding_updateGenerated(context), + }, + { + ResourceName: "google_iap_web_type_app_engine_iam_binding.foo", + ImportStateId: fmt.Sprintf("projects/%s/iap_web/appengine-%s roles/iap.httpsResourceAccessor", context["project_id"], context["project_id"]), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccIapWebTypeAppEngineIamMemberGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/iap.httpsResourceAccessor", + "project_id": fmt.Sprintf("tf-test%s", acctest.RandString(10)), + "org_id": getTestOrgFromEnv(t), + } + + 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: testAccIapWebTypeAppEngineIamMember_basicGenerated(context), + }, + { + ResourceName: "google_iap_web_type_app_engine_iam_member.foo", + ImportStateId: fmt.Sprintf("projects/%s/iap_web/appengine-%s roles/iap.httpsResourceAccessor user:admin@hashicorptest.com", context["project_id"], context["project_id"]), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccIapWebTypeAppEngineIamPolicyGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/iap.httpsResourceAccessor", + "project_id": fmt.Sprintf("tf-test%s", acctest.RandString(10)), + "org_id": getTestOrgFromEnv(t), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccIapWebTypeAppEngineIamPolicy_basicGenerated(context), + }, + { + ResourceName: "google_iap_web_type_app_engine_iam_policy.foo", + ImportStateId: fmt.Sprintf("projects/%s/iap_web/appengine-%s", context["project_id"], context["project_id"]), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccIapWebTypeAppEngineIamMember_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "my_project" { + name = "%{project_id}" + project_id = "%{project_id}" + org_id = "%{org_id}" +} + +resource "google_project_service" "project_service" { + project = "${google_project.my_project.id}" + service = "iap.googleapis.com" +} + +resource "google_app_engine_application" "app" { + project = "${google_project_service.project_service.project}" + location_id = "us-central" +} + +resource "google_iap_web_type_app_engine_iam_member" "foo" { + project = "${google_app_engine_application.app.project}" + app_id = "${google_app_engine_application.app.app_id}" + role = "%{role}" + member = "user:admin@hashicorptest.com" +} +`, context) +} + +func testAccIapWebTypeAppEngineIamPolicy_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "my_project" { + name = "%{project_id}" + project_id = "%{project_id}" + org_id = "%{org_id}" +} + +resource "google_project_service" "project_service" { + project = "${google_project.my_project.id}" + service = "iap.googleapis.com" +} + +resource "google_app_engine_application" "app" { + project = "${google_project_service.project_service.project}" + location_id = "us-central" +} + +data "google_iam_policy" "foo" { + binding { + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + } +} + +resource "google_iap_web_type_app_engine_iam_policy" "foo" { + project = "${google_app_engine_application.app.project}" + app_id = "${google_app_engine_application.app.app_id}" + policy_data = "${data.google_iam_policy.foo.policy_data}" +} +`, context) +} + +func testAccIapWebTypeAppEngineIamBinding_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "my_project" { + name = "%{project_id}" + project_id = "%{project_id}" + org_id = "%{org_id}" +} + +resource "google_project_service" "project_service" { + project = "${google_project.my_project.id}" + service = "iap.googleapis.com" +} + +resource "google_app_engine_application" "app" { + project = "${google_project_service.project_service.project}" + location_id = "us-central" +} + +resource "google_iap_web_type_app_engine_iam_binding" "foo" { + project = "${google_app_engine_application.app.project}" + app_id = "${google_app_engine_application.app.app_id}" + role = "%{role}" + members = ["user:admin@hashicorptest.com"] +} +`, context) +} + +func testAccIapWebTypeAppEngineIamBinding_updateGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "my_project" { + name = "%{project_id}" + project_id = "%{project_id}" + org_id = "%{org_id}" +} + +resource "google_project_service" "project_service" { + project = "${google_project.my_project.id}" + service = "iap.googleapis.com" +} + +resource "google_app_engine_application" "app" { + project = "${google_project_service.project_service.project}" + location_id = "us-central" +} + +resource "google_iap_web_type_app_engine_iam_binding" "foo" { + project = "${google_app_engine_application.app.project}" + app_id = "${google_app_engine_application.app.app_id}" + role = "%{role}" + members = ["user:admin@hashicorptest.com", "user:paddy@hashicorp.com"] +} +`, context) +} diff --git a/google-beta/iam_iap_web_type_compute.go b/google-beta/iam_iap_web_type_compute.go new file mode 100644 index 0000000000..e1a88d4c5d --- /dev/null +++ b/google-beta/iam_iap_web_type_compute.go @@ -0,0 +1,165 @@ +// ---------------------------------------------------------------------------- +// +// *** 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/helper/schema" + "google.golang.org/api/cloudresourcemanager/v1" +) + +var IapWebTypeComputeIamSchema = map[string]*schema.Schema{ + "project": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + }, +} + +type IapWebTypeComputeIamUpdater struct { + project string + d *schema.ResourceData + Config *Config +} + +func IapWebTypeComputeIamUpdaterProducer(d *schema.ResourceData, config *Config) (ResourceIamUpdater, error) { + values := make(map[string]string) + + project, err := getProject(d, config) + if err != nil { + return nil, err + } + + // While this may be overridden by the "project" value from getImportIdQualifiers below, + // setting project here ensures the value is set even if the value set in config is the short + // name or otherwise doesn't include the project. + values["project"] = project + + // We may have gotten either a long or short name, so attempt to parse long name if possible + m, err := getImportIdQualifiers([]string{"projects/(?P[^/]+)/iap_web/compute", "(?P[^/]+)"}, d, config, d.Get("project").(string)) + if err != nil { + return nil, err + } + + for k, v := range m { + values[k] = v + } + + u := &IapWebTypeComputeIamUpdater{ + project: values["project"], + d: d, + Config: config, + } + + d.Set("project", u.project) + + d.SetId(u.GetResourceId()) + + return u, nil +} + +func IapWebTypeComputeIdParseFunc(d *schema.ResourceData, config *Config) error { + values := make(map[string]string) + + project, err := getProject(d, config) + if err != nil { + return err + } + + values["project"] = project + + m, err := getImportIdQualifiers([]string{"projects/(?P[^/]+)/iap_web/compute", "(?P[^/]+)"}, d, config, d.Id()) + if err != nil { + return err + } + + for k, v := range m { + values[k] = v + } + + u := &IapWebTypeComputeIamUpdater{ + project: values["project"], + d: d, + Config: config, + } + d.Set("project", u.project) + d.SetId(u.GetResourceId()) + return nil +} + +func (u *IapWebTypeComputeIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { + url := u.qualifyWebTypeComputeUrl("getIamPolicy") + + project, err := getProject(u.d, u.Config) + if err != nil { + return nil, err + } + + policy, err := sendRequest(u.Config, "POST", project, url, nil) + 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 *IapWebTypeComputeIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanager.Policy) error { + json, err := ConvertToMap(policy) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + obj["policy"] = json + + url := u.qualifyWebTypeComputeUrl("setIamPolicy") + + 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 *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) GetResourceId() string { + return fmt.Sprintf("projects/%s/iap_web/compute", u.project) +} + +func (u *IapWebTypeComputeIamUpdater) GetMutexKey() string { + return fmt.Sprintf("iam-iap-webtypecompute-%s", u.GetResourceId()) +} + +func (u *IapWebTypeComputeIamUpdater) DescribeResource() string { + return fmt.Sprintf("iap webtypecompute %q", u.GetResourceId()) +} diff --git a/google-beta/iam_iap_web_type_compute_generated_test.go b/google-beta/iam_iap_web_type_compute_generated_test.go new file mode 100644 index 0000000000..e7d3deb378 --- /dev/null +++ b/google-beta/iam_iap_web_type_compute_generated_test.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" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccIapWebTypeComputeIamBindingGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/iap.httpsResourceAccessor", + "org_id": getTestOrgFromEnv(t), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccIapWebTypeComputeIamBinding_basicGenerated(context), + }, + { + ResourceName: "google_iap_web_type_compute_iam_binding.foo", + ImportStateId: fmt.Sprintf("projects/%s/iap_web/compute roles/iap.httpsResourceAccessor", fmt.Sprintf("tf-test%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + { + // Test Iam Binding update + Config: testAccIapWebTypeComputeIamBinding_updateGenerated(context), + }, + { + ResourceName: "google_iap_web_type_compute_iam_binding.foo", + ImportStateId: fmt.Sprintf("projects/%s/iap_web/compute roles/iap.httpsResourceAccessor", fmt.Sprintf("tf-test%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccIapWebTypeComputeIamMemberGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/iap.httpsResourceAccessor", + "org_id": getTestOrgFromEnv(t), + } + + 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: testAccIapWebTypeComputeIamMember_basicGenerated(context), + }, + { + ResourceName: "google_iap_web_type_compute_iam_member.foo", + ImportStateId: fmt.Sprintf("projects/%s/iap_web/compute roles/iap.httpsResourceAccessor user:admin@hashicorptest.com", fmt.Sprintf("tf-test%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccIapWebTypeComputeIamPolicyGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + "role": "roles/iap.httpsResourceAccessor", + "org_id": getTestOrgFromEnv(t), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccIapWebTypeComputeIamPolicy_basicGenerated(context), + }, + { + ResourceName: "google_iap_web_type_compute_iam_policy.foo", + ImportStateId: fmt.Sprintf("projects/%s/iap_web/compute", fmt.Sprintf("tf-test%s", context["random_suffix"])), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccIapWebTypeComputeIamMember_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" +} + +resource "google_project_service" "project_service" { + project = "${google_project.project.id}" + service = "iap.googleapis.com" +} + +resource "google_iap_web_type_compute_iam_member" "foo" { + project = "${google_project_service.project_service.project}" + role = "%{role}" + member = "user:admin@hashicorptest.com" +} +`, context) +} + +func testAccIapWebTypeComputeIamPolicy_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" +} + +resource "google_project_service" "project_service" { + project = "${google_project.project.id}" + service = "iap.googleapis.com" +} + +data "google_iam_policy" "foo" { + binding { + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + } +} + +resource "google_iap_web_type_compute_iam_policy" "foo" { + project = "${google_project_service.project_service.project}" + policy_data = "${data.google_iam_policy.foo.policy_data}" +} +`, context) +} + +func testAccIapWebTypeComputeIamBinding_basicGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" +} + +resource "google_project_service" "project_service" { + project = "${google_project.project.id}" + service = "iap.googleapis.com" +} + +resource "google_iap_web_type_compute_iam_binding" "foo" { + project = "${google_project_service.project_service.project}" + role = "%{role}" + members = ["user:admin@hashicorptest.com"] +} +`, context) +} + +func testAccIapWebTypeComputeIamBinding_updateGenerated(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" +} + +resource "google_project_service" "project_service" { + project = "${google_project.project.id}" + service = "iap.googleapis.com" +} + +resource "google_iap_web_type_compute_iam_binding" "foo" { + project = "${google_project_service.project_service.project}" + role = "%{role}" + members = ["user:admin@hashicorptest.com", "user:paddy@hashicorp.com"] +} +`, context) +} diff --git a/google-beta/iam_pubsub_topic.go b/google-beta/iam_pubsub_topic.go index 3243e6f572..56f5ab01dc 100644 --- a/google-beta/iam_pubsub_topic.go +++ b/google-beta/iam_pubsub_topic.go @@ -56,6 +56,7 @@ func PubsubTopicIamUpdaterProducer(d *schema.ResourceData, config *Config) (Reso // name or otherwise doesn't include the project. values["project"] = project + // We may have gotten either a long or short name, so attempt to parse long name if possible m, err := getImportIdQualifiers([]string{"projects/(?P[^/]+)/topics/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Get("topic").(string)) if err != nil { return nil, err @@ -71,6 +72,10 @@ func PubsubTopicIamUpdaterProducer(d *schema.ResourceData, config *Config) (Reso d: d, Config: config, } + + d.Set("project", u.project) + d.Set("topic", u.GetResourceId()) + d.SetId(u.GetResourceId()) return u, nil diff --git a/google-beta/iam_pubsub_topic_generated_test.go b/google-beta/iam_pubsub_topic_generated_test.go index 38d4d1f0ac..999df0520a 100644 --- a/google-beta/iam_pubsub_topic_generated_test.go +++ b/google-beta/iam_pubsub_topic_generated_test.go @@ -27,20 +27,19 @@ func TestAccPubsubTopicIamBindingGenerated(t *testing.T) { context := map[string]interface{}{ "random_suffix": acctest.RandString(10), - "role": "roles/editor", + "role": "roles/viewer", } resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckPubsubTopicDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, Steps: []resource.TestStep{ { Config: testAccPubsubTopicIamBinding_basicGenerated(context), }, { ResourceName: "google_pubsub_topic_iam_binding.foo", - ImportStateId: fmt.Sprintf("projects/%s/topics/%s roles/editor", getTestProjectFromEnv(), fmt.Sprintf("example-topic%s", context["random_suffix"])), + ImportStateId: fmt.Sprintf("projects/%s/topics/%s roles/viewer", getTestProjectFromEnv(), fmt.Sprintf("example-topic%s", context["random_suffix"])), ImportState: true, ImportStateVerify: true, }, @@ -50,7 +49,7 @@ func TestAccPubsubTopicIamBindingGenerated(t *testing.T) { }, { ResourceName: "google_pubsub_topic_iam_binding.foo", - ImportStateId: fmt.Sprintf("projects/%s/topics/%s roles/editor", getTestProjectFromEnv(), fmt.Sprintf("example-topic%s", context["random_suffix"])), + ImportStateId: fmt.Sprintf("projects/%s/topics/%s roles/viewer", getTestProjectFromEnv(), fmt.Sprintf("example-topic%s", context["random_suffix"])), ImportState: true, ImportStateVerify: true, }, @@ -63,13 +62,12 @@ func TestAccPubsubTopicIamMemberGenerated(t *testing.T) { context := map[string]interface{}{ "random_suffix": acctest.RandString(10), - "role": "roles/editor", + "role": "roles/viewer", } resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckPubsubTopicDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, Steps: []resource.TestStep{ { // Test Iam Member creation (no update for member, no need to test) @@ -77,7 +75,7 @@ func TestAccPubsubTopicIamMemberGenerated(t *testing.T) { }, { ResourceName: "google_pubsub_topic_iam_member.foo", - ImportStateId: fmt.Sprintf("projects/%s/topics/%s roles/editor user:admin@hashicorptest.com", getTestProjectFromEnv(), fmt.Sprintf("example-topic%s", context["random_suffix"])), + ImportStateId: fmt.Sprintf("projects/%s/topics/%s roles/viewer user:admin@hashicorptest.com", getTestProjectFromEnv(), fmt.Sprintf("example-topic%s", context["random_suffix"])), ImportState: true, ImportStateVerify: true, }, @@ -90,13 +88,12 @@ func TestAccPubsubTopicIamPolicyGenerated(t *testing.T) { context := map[string]interface{}{ "random_suffix": acctest.RandString(10), - "role": "roles/editor", + "role": "roles/viewer", } resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckPubsubTopicDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, Steps: []resource.TestStep{ { Config: testAccPubsubTopicIamPolicy_basicGenerated(context), @@ -122,9 +119,10 @@ resource "google_pubsub_topic" "example" { } resource "google_pubsub_topic_iam_member" "foo" { + project = "${google_pubsub_topic.example.project}" topic = "${google_pubsub_topic.example.id}" - role = "%{role}" - member = "user:admin@hashicorptest.com" + role = "%{role}" + member = "user:admin@hashicorptest.com" } `, context) } @@ -141,14 +139,15 @@ resource "google_pubsub_topic" "example" { data "google_iam_policy" "foo" { binding { - role = "%{role}" + role = "%{role}" members = ["user:admin@hashicorptest.com"] } } resource "google_pubsub_topic_iam_policy" "foo" { + project = "${google_pubsub_topic.example.project}" topic = "${google_pubsub_topic.example.id}" - policy_data = "${data.google_iam_policy.foo.policy_data}" + policy_data = "${data.google_iam_policy.foo.policy_data}" } `, context) } @@ -164,9 +163,10 @@ resource "google_pubsub_topic" "example" { } resource "google_pubsub_topic_iam_binding" "foo" { + project = "${google_pubsub_topic.example.project}" topic = "${google_pubsub_topic.example.id}" - role = "%{role}" - members = ["user:admin@hashicorptest.com"] + role = "%{role}" + members = ["user:admin@hashicorptest.com"] } `, context) } @@ -182,9 +182,10 @@ resource "google_pubsub_topic" "example" { } resource "google_pubsub_topic_iam_binding" "foo" { + project = "${google_pubsub_topic.example.project}" topic = "${google_pubsub_topic.example.id}" - role = "%{role}" - members = ["user:admin@hashicorptest.com", "user:paddy@hashicorp.com"] + role = "%{role}" + members = ["user:admin@hashicorptest.com", "user:paddy@hashicorp.com"] } `, context) } diff --git a/google-beta/iam_source_repo_repository.go b/google-beta/iam_source_repo_repository.go index 44b233d3bf..a21b034510 100644 --- a/google-beta/iam_source_repo_repository.go +++ b/google-beta/iam_source_repo_repository.go @@ -56,6 +56,7 @@ func SourceRepoRepositoryIamUpdaterProducer(d *schema.ResourceData, config *Conf // name or otherwise doesn't include the project. values["project"] = project + // We may have gotten either a long or short name, so attempt to parse long name if possible m, err := getImportIdQualifiers([]string{"projects/(?P[^/]+)/repos/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Get("repository").(string)) if err != nil { return nil, err @@ -71,6 +72,10 @@ func SourceRepoRepositoryIamUpdaterProducer(d *schema.ResourceData, config *Conf d: d, Config: config, } + + d.Set("project", u.project) + d.Set("repository", u.GetResourceId()) + d.SetId(u.GetResourceId()) return u, nil diff --git a/google-beta/iam_source_repo_repository_generated_test.go b/google-beta/iam_source_repo_repository_generated_test.go index 8e15ecaf4f..cdb6f23452 100644 --- a/google-beta/iam_source_repo_repository_generated_test.go +++ b/google-beta/iam_source_repo_repository_generated_test.go @@ -27,20 +27,19 @@ func TestAccSourceRepoRepositoryIamBindingGenerated(t *testing.T) { context := map[string]interface{}{ "random_suffix": acctest.RandString(10), - "role": "roles/editor", + "role": "roles/viewer", } resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckSourceRepoRepositoryDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, Steps: []resource.TestStep{ { Config: testAccSourceRepoRepositoryIamBinding_basicGenerated(context), }, { ResourceName: "google_sourcerepo_repository_iam_binding.foo", - ImportStateId: fmt.Sprintf("projects/%s/repos/%s roles/editor", getTestProjectFromEnv(), fmt.Sprintf("my-repository%s", context["random_suffix"])), + ImportStateId: fmt.Sprintf("projects/%s/repos/%s roles/viewer", getTestProjectFromEnv(), fmt.Sprintf("my-repository%s", context["random_suffix"])), ImportState: true, ImportStateVerify: true, }, @@ -50,7 +49,7 @@ func TestAccSourceRepoRepositoryIamBindingGenerated(t *testing.T) { }, { ResourceName: "google_sourcerepo_repository_iam_binding.foo", - ImportStateId: fmt.Sprintf("projects/%s/repos/%s roles/editor", getTestProjectFromEnv(), fmt.Sprintf("my-repository%s", context["random_suffix"])), + ImportStateId: fmt.Sprintf("projects/%s/repos/%s roles/viewer", getTestProjectFromEnv(), fmt.Sprintf("my-repository%s", context["random_suffix"])), ImportState: true, ImportStateVerify: true, }, @@ -63,13 +62,12 @@ func TestAccSourceRepoRepositoryIamMemberGenerated(t *testing.T) { context := map[string]interface{}{ "random_suffix": acctest.RandString(10), - "role": "roles/editor", + "role": "roles/viewer", } resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckSourceRepoRepositoryDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, Steps: []resource.TestStep{ { // Test Iam Member creation (no update for member, no need to test) @@ -77,7 +75,7 @@ func TestAccSourceRepoRepositoryIamMemberGenerated(t *testing.T) { }, { ResourceName: "google_sourcerepo_repository_iam_member.foo", - ImportStateId: fmt.Sprintf("projects/%s/repos/%s roles/editor user:admin@hashicorptest.com", getTestProjectFromEnv(), fmt.Sprintf("my-repository%s", context["random_suffix"])), + ImportStateId: fmt.Sprintf("projects/%s/repos/%s roles/viewer user:admin@hashicorptest.com", getTestProjectFromEnv(), fmt.Sprintf("my-repository%s", context["random_suffix"])), ImportState: true, ImportStateVerify: true, }, @@ -90,13 +88,12 @@ func TestAccSourceRepoRepositoryIamPolicyGenerated(t *testing.T) { context := map[string]interface{}{ "random_suffix": acctest.RandString(10), - "role": "roles/editor", + "role": "roles/viewer", } resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckSourceRepoRepositoryDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, Steps: []resource.TestStep{ { Config: testAccSourceRepoRepositoryIamPolicy_basicGenerated(context), @@ -118,9 +115,10 @@ resource "google_sourcerepo_repository" "my-repo" { } resource "google_sourcerepo_repository_iam_member" "foo" { + project = "${google_sourcerepo_repository.my-repo.project}" repository = "${google_sourcerepo_repository.my-repo.id}" - role = "%{role}" - member = "user:admin@hashicorptest.com" + role = "%{role}" + member = "user:admin@hashicorptest.com" } `, context) } @@ -133,14 +131,15 @@ resource "google_sourcerepo_repository" "my-repo" { data "google_iam_policy" "foo" { binding { - role = "%{role}" + role = "%{role}" members = ["user:admin@hashicorptest.com"] } } resource "google_sourcerepo_repository_iam_policy" "foo" { + project = "${google_sourcerepo_repository.my-repo.project}" repository = "${google_sourcerepo_repository.my-repo.id}" - policy_data = "${data.google_iam_policy.foo.policy_data}" + policy_data = "${data.google_iam_policy.foo.policy_data}" } `, context) } @@ -152,9 +151,10 @@ resource "google_sourcerepo_repository" "my-repo" { } resource "google_sourcerepo_repository_iam_binding" "foo" { + project = "${google_sourcerepo_repository.my-repo.project}" repository = "${google_sourcerepo_repository.my-repo.id}" - role = "%{role}" - members = ["user:admin@hashicorptest.com"] + role = "%{role}" + members = ["user:admin@hashicorptest.com"] } `, context) } @@ -166,9 +166,10 @@ resource "google_sourcerepo_repository" "my-repo" { } resource "google_sourcerepo_repository_iam_binding" "foo" { + project = "${google_sourcerepo_repository.my-repo.project}" repository = "${google_sourcerepo_repository.my-repo.id}" - role = "%{role}" - members = ["user:admin@hashicorptest.com", "user:paddy@hashicorp.com"] + role = "%{role}" + members = ["user:admin@hashicorptest.com", "user:paddy@hashicorp.com"] } `, context) } diff --git a/google-beta/import.go b/google-beta/import.go index 999d2330bb..27b5370705 100644 --- a/google-beta/import.go +++ b/google-beta/import.go @@ -97,76 +97,3 @@ func setDefaultValues(idRegex string, d TerraformResourceData, config *Config) e } return nil } - -// Parse an import id extracting field values using the given list of regexes. -// They are applied in order. The first in the list is tried first. -// This does not mutate any of the parameters, returning a map of matches -// -// e.g: -// - projects/(?P[^/]+)/regions/(?P[^/]+)/subnetworks/(?P[^/]+) (applied first) -// - (?P[^/]+)/(?P[^/]+)/(?P[^/]+), -// - (?P[^/]+) (applied last) -func getImportIdQualifiers(idRegexes []string, d TerraformResourceData, config *Config, id string) (map[string]string, error) { - for _, idFormat := range idRegexes { - re, err := regexp.Compile(idFormat) - - if err != nil { - log.Printf("[DEBUG] Could not compile %s.", idFormat) - return nil, fmt.Errorf("Import is not supported. Invalid regex formats.") - } - - if fieldValues := re.FindStringSubmatch(id); fieldValues != nil { - var result map[string]string - result = make(map[string]string) - log.Printf("[DEBUG] matching ID %s to regex %s.", id, idFormat) - // Starting at index 1, the first match is the full string. - for i := 1; i < len(fieldValues); i++ { - fieldName := re.SubexpNames()[i] - fieldValue := fieldValues[i] - result[fieldName] = fieldValue - } - - // The first id format is applied first and contains all the fields. - defaults, err := getDefaultValues(idRegexes[0], d, config) - if err != nil { - return nil, err - } - - for k, v := range defaults { - result[k] = v - } - - return result, nil - } - } - return nil, fmt.Errorf("Resource id %q doesn't match any of the accepted formats: %v", id, idRegexes) -} - -// Returns a set of default values that are contained in a regular expression -// This does not mutate any parameters, instead returning a map of defaults -func getDefaultValues(idRegex string, d TerraformResourceData, config *Config) (map[string]string, error) { - var result map[string]string - result = make(map[string]string) - if _, ok := d.GetOk("project"); !ok && strings.Contains(idRegex, "?P") { - project, err := getProject(d, config) - if err != nil { - return nil, err - } - result["project"] = project - } - if _, ok := d.GetOk("region"); !ok && strings.Contains(idRegex, "?P") { - region, err := getRegion(d, config) - if err != nil { - return nil, err - } - result["region"] = region - } - if _, ok := d.GetOk("zone"); !ok && strings.Contains(idRegex, "?P") { - zone, err := getZone(d, config) - if err != nil { - return nil, err - } - result["zone"] = zone - } - return result, nil -} diff --git a/google-beta/provider.go b/google-beta/provider.go index 6cecce4708..88de450d53 100644 --- a/google-beta/provider.go +++ b/google-beta/provider.go @@ -231,6 +231,14 @@ func Provider() terraform.ResourceProvider { "GOOGLE_HEALTHCARE_CUSTOM_ENDPOINT", }, HealthcareDefaultBasePath), }, + "iap_custom_endpoint": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateCustomEndpoint, + DefaultFunc: schema.MultiEnvDefaultFunc([]string{ + "GOOGLE_IAP_CUSTOM_ENDPOINT", + }, IapDefaultBasePath), + }, "kms_custom_endpoint": { Type: schema.TypeString, Optional: true, @@ -449,9 +457,9 @@ func Provider() terraform.ResourceProvider { return provider } -// Generated resources: 88 -// Generated IAM resources: 6 -// Total generated resources: 94 +// Generated resources: 92 +// Generated IAM resources: 18 +// Total generated resources: 110 func ResourceMap() map[string]*schema.Resource { resourceMap, _ := ResourceMapWithErrors() return resourceMap @@ -526,6 +534,18 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) { "google_healthcare_dicom_store": resourceHealthcareDicomStore(), "google_healthcare_fhir_store": resourceHealthcareFhirStore(), "google_healthcare_hl7_v2_store": resourceHealthcareHl7V2Store(), + "google_iap_web_iam_binding": ResourceIamBinding(IapWebIamSchema, IapWebIamUpdaterProducer, IapWebIdParseFunc), + "google_iap_web_iam_member": ResourceIamMember(IapWebIamSchema, IapWebIamUpdaterProducer, IapWebIdParseFunc), + "google_iap_web_iam_policy": ResourceIamPolicy(IapWebIamSchema, IapWebIamUpdaterProducer, IapWebIdParseFunc), + "google_iap_web_type_compute_iam_binding": ResourceIamBinding(IapWebTypeComputeIamSchema, IapWebTypeComputeIamUpdaterProducer, IapWebTypeComputeIdParseFunc), + "google_iap_web_type_compute_iam_member": ResourceIamMember(IapWebTypeComputeIamSchema, IapWebTypeComputeIamUpdaterProducer, IapWebTypeComputeIdParseFunc), + "google_iap_web_type_compute_iam_policy": ResourceIamPolicy(IapWebTypeComputeIamSchema, IapWebTypeComputeIamUpdaterProducer, IapWebTypeComputeIdParseFunc), + "google_iap_web_type_app_engine_iam_binding": ResourceIamBinding(IapWebTypeAppEngineIamSchema, IapWebTypeAppEngineIamUpdaterProducer, IapWebTypeAppEngineIdParseFunc), + "google_iap_web_type_app_engine_iam_member": ResourceIamMember(IapWebTypeAppEngineIamSchema, IapWebTypeAppEngineIamUpdaterProducer, IapWebTypeAppEngineIdParseFunc), + "google_iap_web_type_app_engine_iam_policy": ResourceIamPolicy(IapWebTypeAppEngineIamSchema, IapWebTypeAppEngineIamUpdaterProducer, IapWebTypeAppEngineIdParseFunc), + "google_iap_web_backend_service_iam_binding": ResourceIamBinding(IapWebBackendServiceIamSchema, IapWebBackendServiceIamUpdaterProducer, IapWebBackendServiceIdParseFunc), + "google_iap_web_backend_service_iam_member": ResourceIamMember(IapWebBackendServiceIamSchema, IapWebBackendServiceIamUpdaterProducer, IapWebBackendServiceIdParseFunc), + "google_iap_web_backend_service_iam_policy": ResourceIamPolicy(IapWebBackendServiceIamSchema, IapWebBackendServiceIamUpdaterProducer, IapWebBackendServiceIdParseFunc), "google_kms_key_ring": resourceKMSKeyRing(), "google_kms_crypto_key": resourceKMSCryptoKey(), "google_logging_metric": resourceLoggingMetric(), @@ -738,6 +758,7 @@ func providerConfigure(d *schema.ResourceData, terraformVersion string) (interfa config.FilestoreBasePath = d.Get("filestore_custom_endpoint").(string) config.FirestoreBasePath = d.Get("firestore_custom_endpoint").(string) config.HealthcareBasePath = d.Get("healthcare_custom_endpoint").(string) + config.IapBasePath = d.Get("iap_custom_endpoint").(string) config.KMSBasePath = d.Get("kms_custom_endpoint").(string) config.LoggingBasePath = d.Get("logging_custom_endpoint").(string) config.MLEngineBasePath = d.Get("ml_engine_custom_endpoint").(string) diff --git a/google-beta/resource_app_engine_application.go b/google-beta/resource_app_engine_application.go index 96901c772a..455cc4f710 100644 --- a/google-beta/resource_app_engine_application.go +++ b/google-beta/resource_app_engine_application.go @@ -64,6 +64,10 @@ func resourceAppEngineApplication() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "app_id": { + Type: schema.TypeString, + Computed: true, + }, "url_dispatch_rule": { Type: schema.TypeList, Computed: true, @@ -171,6 +175,7 @@ func resourceAppEngineApplicationRead(d *schema.ResourceData, meta interface{}) d.Set("default_hostname", app.DefaultHostname) d.Set("location_id", app.LocationId) d.Set("name", app.Name) + d.Set("app_id", app.Id) d.Set("serving_status", app.ServingStatus) d.Set("gcr_domain", app.GcrDomain) d.Set("project", pid) diff --git a/google-beta/resource_compute_vpn_gateway.go b/google-beta/resource_compute_vpn_gateway.go index 5ad2e3badd..80cec9685d 100644 --- a/google-beta/resource_compute_vpn_gateway.go +++ b/google-beta/resource_compute_vpn_gateway.go @@ -188,7 +188,7 @@ func resourceComputeVpnGatewayRead(d *schema.ResourceData, meta interface{}) err if err := d.Set("name", flattenComputeVpnGatewayName(res["name"], d)); err != nil { return fmt.Errorf("Error reading VpnGateway: %s", err) } - if err := d.Set("gateway_id", flattenComputeVpnGatewayGateway_id(res["id"], d)); err != nil { + if err := d.Set("gateway_id", flattenComputeVpnGatewayGatewayId(res["id"], d)); err != nil { return fmt.Errorf("Error reading VpnGateway: %s", err) } if err := d.Set("network", flattenComputeVpnGatewayNetwork(res["network"], d)); err != nil { @@ -276,7 +276,7 @@ func flattenComputeVpnGatewayName(v interface{}, d *schema.ResourceData) interfa return v } -func flattenComputeVpnGatewayGateway_id(v interface{}, d *schema.ResourceData) interface{} { +func flattenComputeVpnGatewayGatewayId(v interface{}, d *schema.ResourceData) interface{} { // Handles the string fixed64 format if strVal, ok := v.(string); ok { if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil { diff --git a/google-beta/resource_compute_vpn_tunnel.go b/google-beta/resource_compute_vpn_tunnel.go index 2591e64750..04da3b3567 100644 --- a/google-beta/resource_compute_vpn_tunnel.go +++ b/google-beta/resource_compute_vpn_tunnel.go @@ -499,7 +499,7 @@ func resourceComputeVpnTunnelRead(d *schema.ResourceData, meta interface{}) erro return fmt.Errorf("Error reading VpnTunnel: %s", err) } - if err := d.Set("tunnel_id", flattenComputeVpnTunnelTunnel_id(res["id"], d)); err != nil { + if err := d.Set("tunnel_id", flattenComputeVpnTunnelTunnelId(res["id"], d)); err != nil { return fmt.Errorf("Error reading VpnTunnel: %s", err) } if err := d.Set("creation_timestamp", flattenComputeVpnTunnelCreationTimestamp(res["creationTimestamp"], d)); err != nil { @@ -683,7 +683,7 @@ func resourceComputeVpnTunnelImport(d *schema.ResourceData, meta interface{}) ([ return []*schema.ResourceData{d}, nil } -func flattenComputeVpnTunnelTunnel_id(v interface{}, d *schema.ResourceData) interface{} { +func flattenComputeVpnTunnelTunnelId(v interface{}, d *schema.ResourceData) interface{} { return v } diff --git a/google-beta/resource_pubsub_topic_iam_test.go b/google-beta/resource_pubsub_topic_iam_test.go new file mode 100644 index 0000000000..8a1d61652b --- /dev/null +++ b/google-beta/resource_pubsub_topic_iam_test.go @@ -0,0 +1,276 @@ +package google + +import ( + "fmt" + "reflect" + "sort" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccPubsubTopicIamBinding(t *testing.T) { + t.Parallel() + + topic := "test-topic-iam-" + acctest.RandString(10) + account := "test-topic-iam-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + // Test IAM Binding creation + Config: testAccPubsubTopicIamBinding_basic(topic, account), + Check: testAccCheckPubsubTopicIam(topic, "roles/pubsub.publisher", []string{ + fmt.Sprintf("serviceAccount:%s-1@%s.iam.gserviceaccount.com", account, getTestProjectFromEnv()), + }), + }, + { + ResourceName: "google_pubsub_topic_iam_binding.foo", + ImportStateId: fmt.Sprintf("%s roles/pubsub.publisher", getComputedTopicName(getTestProjectFromEnv(), topic)), + ImportState: true, + ImportStateVerify: true, + }, + { + // Test IAM Binding update + Config: testAccPubsubTopicIamBinding_update(topic, account), + Check: testAccCheckPubsubTopicIam(topic, "roles/pubsub.publisher", []string{ + fmt.Sprintf("serviceAccount:%s-1@%s.iam.gserviceaccount.com", account, getTestProjectFromEnv()), + fmt.Sprintf("serviceAccount:%s-2@%s.iam.gserviceaccount.com", account, getTestProjectFromEnv()), + }), + }, + { + ResourceName: "google_pubsub_topic_iam_binding.foo", + ImportStateId: fmt.Sprintf("%s roles/pubsub.publisher", getComputedTopicName(getTestProjectFromEnv(), topic)), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccPubsubTopicIamBinding_topicName(t *testing.T) { + t.Parallel() + + topic := "test-topic-iam-" + acctest.RandString(10) + account := "test-topic-iam-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + // Test IAM Binding creation + Config: testAccPubsubTopicIamBinding_topicName(topic, account), + Check: testAccCheckPubsubTopicIam(topic, "roles/pubsub.publisher", []string{ + fmt.Sprintf("serviceAccount:%s-1@%s.iam.gserviceaccount.com", account, getTestProjectFromEnv()), + }), + }, + // No import step- imports want the resource to be defined using the full id as the topic + }, + }) +} + +func TestAccPubsubTopicIamMember(t *testing.T) { + t.Parallel() + + topic := "test-topic-iam-" + acctest.RandString(10) + account := "test-topic-iam-" + acctest.RandString(10) + accountEmail := fmt.Sprintf("%s@%s.iam.gserviceaccount.com", account, 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: testAccPubsubTopicIamMember_basic(topic, account), + Check: testAccCheckPubsubTopicIam(topic, "roles/pubsub.publisher", []string{ + fmt.Sprintf("serviceAccount:%s", accountEmail), + }), + }, + { + ResourceName: "google_pubsub_topic_iam_member.foo", + ImportStateId: fmt.Sprintf("%s roles/pubsub.publisher serviceAccount:%s", getComputedTopicName(getTestProjectFromEnv(), topic), accountEmail), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccPubsubTopicIamPolicy(t *testing.T) { + t.Parallel() + + topic := "test-topic-iam-" + acctest.RandString(10) + account := "test-topic-iam-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccPubsubTopicIamPolicy_basic(topic, account, "roles/pubsub.publisher"), + Check: testAccCheckPubsubTopicIam(topic, "roles/pubsub.publisher", []string{ + fmt.Sprintf("serviceAccount:%s@%s.iam.gserviceaccount.com", account, getTestProjectFromEnv()), + }), + }, + { + Config: testAccPubsubTopicIamPolicy_basic(topic, account, "roles/pubsub.subscriber"), + Check: testAccCheckPubsubTopicIam(topic, "roles/pubsub.subscriber", []string{ + fmt.Sprintf("serviceAccount:%s@%s.iam.gserviceaccount.com", account, getTestProjectFromEnv()), + }), + }, + { + ResourceName: "google_pubsub_topic_iam_policy.foo", + ImportStateId: getComputedTopicName(getTestProjectFromEnv(), topic), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckPubsubTopicIam(topic, role string, members []string) resource.TestCheckFunc { + return func(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + p, err := config.clientPubsub.Projects.Topics.GetIamPolicy(getComputedTopicName(getTestProjectFromEnv(), topic)).Do() + if err != nil { + return err + } + + for _, binding := range p.Bindings { + if binding.Role == role { + sort.Strings(members) + sort.Strings(binding.Members) + + if reflect.DeepEqual(members, binding.Members) { + return nil + } + + return fmt.Errorf("Binding found but expected members is %v, got %v", members, binding.Members) + } + } + + return fmt.Errorf("No binding for role %q", role) + } +} + +func testAccPubsubTopicIamBinding_topicName(topic, account string) string { + return fmt.Sprintf(` +resource "google_pubsub_topic" "topic" { + name = "%s" +} + +resource "google_service_account" "test-account-1" { + account_id = "%s-1" + display_name = "Iam Testing Account" +} + +resource "google_pubsub_topic_iam_binding" "foo" { + project = "%s" + topic = "${google_pubsub_topic.topic.name}" + role = "roles/pubsub.publisher" + members = [ + "serviceAccount:${google_service_account.test-account-1.email}", + ] +} +`, topic, account, getTestProjectFromEnv()) +} + +func testAccPubsubTopicIamBinding_basic(topic, account string) string { + return fmt.Sprintf(` +resource "google_pubsub_topic" "topic" { + name = "%s" +} + +resource "google_service_account" "test-account-1" { + account_id = "%s-1" + display_name = "Iam Testing Account" +} + +resource "google_pubsub_topic_iam_binding" "foo" { + # use the id instead of the name because it's more compatible with import + topic = "${google_pubsub_topic.topic.id}" + role = "roles/pubsub.publisher" + members = [ + "serviceAccount:${google_service_account.test-account-1.email}", + ] +} +`, topic, account) +} + +func testAccPubsubTopicIamBinding_update(topic, account string) string { + return fmt.Sprintf(` +resource "google_pubsub_topic" "topic" { + name = "%s" +} + +resource "google_service_account" "test-account-1" { + account_id = "%s-1" + display_name = "Iam Testing Account" +} + +resource "google_service_account" "test-account-2" { + account_id = "%s-2" + display_name = "Iam Testing Account" +} + +resource "google_pubsub_topic_iam_binding" "foo" { + # use the id instead of the name because it's more compatible with import + topic = "${google_pubsub_topic.topic.id}" + role = "roles/pubsub.publisher" + members = [ + "serviceAccount:${google_service_account.test-account-1.email}", + "serviceAccount:${google_service_account.test-account-2.email}", + ] +} +`, topic, account, account) +} + +func testAccPubsubTopicIamMember_basic(topic, account string) string { + return fmt.Sprintf(` +resource "google_pubsub_topic" "topic" { + name = "%s" +} + +resource "google_service_account" "test-account" { + account_id = "%s" + display_name = "Iam Testing Account" +} + +resource "google_pubsub_topic_iam_member" "foo" { + topic = "${google_pubsub_topic.topic.id}" + role = "roles/pubsub.publisher" + member = "serviceAccount:${google_service_account.test-account.email}" +} +`, topic, account) +} + +func testAccPubsubTopicIamPolicy_basic(topic, account, role string) string { + return fmt.Sprintf(` +resource "google_pubsub_topic" "topic" { + name = "%s" +} + +resource "google_service_account" "test-account" { + account_id = "%s" + display_name = "Iam Testing Account" +} + +data "google_iam_policy" "foo" { + binding { + role = "%s" + members = ["serviceAccount:${google_service_account.test-account.email}"] + } +} + +resource "google_pubsub_topic_iam_policy" "foo" { + topic = "${google_pubsub_topic.topic.id}" + policy_data = "${data.google_iam_policy.foo.policy_data}" +} +`, topic, account, role) +} diff --git a/website/docs/r/app_engine_application.html.markdown b/website/docs/r/app_engine_application.html.markdown index deed82a938..43a8434227 100755 --- a/website/docs/r/app_engine_application.html.markdown +++ b/website/docs/r/app_engine_application.html.markdown @@ -57,6 +57,8 @@ exported: * `name` - Unique name of the app, usually `apps/{PROJECT_ID}` +* `app_id` - Identifier of the app, usually `{PROJECT_ID}` + * `url_dispatch_rule` - A list of dispatch rule blocks. Each block has a `domain`, `path`, and `service` field. * `code_bucket` - The GCS bucket code is being stored in for this app. diff --git a/website/docs/r/iap_web_backend_service_iam.html.markdown b/website/docs/r/iap_web_backend_service_iam.html.markdown new file mode 100644 index 0000000000..0e31d0412f --- /dev/null +++ b/website/docs/r/iap_web_backend_service_iam.html.markdown @@ -0,0 +1,127 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** 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. +# +# ---------------------------------------------------------------------------- +layout: "google" +page_title: "Google: google_iap_web_backend_service_iam" +sidebar_current: "docs-google-iap-web-backend-service-iam" +description: |- + Collection of resources to manage IAM policy for IapWebBackendService +--- + +# IAM policy for IapWebBackendService +Three different resources help you manage your IAM policy for Iap WebBackendService. Each of these resources serves a different use case: + +* `google_iap_web_backend_service_iam_policy`: Authoritative. Sets the IAM policy for the webbackendservice and replaces any existing policy already attached. +* `google_iap_web_backend_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 webbackendservice are preserved. +* `google_iap_web_backend_service_iam_member`: Non-authoritative. Updates the IAM policy to grant a role to a new member. Other members for the role for the webbackendservice are preserved. + +~> **Note:** `google_iap_web_backend_service_iam_policy` **cannot** be used in conjunction with `google_iap_web_backend_service_iam_binding` and `google_iap_web_backend_service_iam_member` or they will fight over what your policy should be. + +~> **Note:** `google_iap_web_backend_service_iam_binding` resources **can be** used in conjunction with `google_iap_web_backend_service_iam_member` resources **only if** they do not grant privilege to the same role. + + + +## google\_iap\_web\_backend\_service\_iam\_policy + +```hcl +data "google_iam_policy" "admin" { + binding { + role = "roles/iap.httpsResourceAccessor" + members = [ + "user:jane@example.com", + ] + } +} + +resource "google_iap_web_backend_service_iam_policy" "editor" { + project = "${google_compute_backend_service.default.project}" + backend_service_name = "${google_compute_backend_service.default.name}" + policy_data = "${data.google_iam_policy.admin.policy_data}" +} +``` + +## google\_iap\_web\_backend\_service\_iam\_binding + +```hcl +resource "google_iap_web_backend_service_iam_binding" "editor" { + project = "${google_compute_backend_service.default.project}" + backend_service_name = "${google_compute_backend_service.default.name}" + role = "roles/iap.httpsResourceAccessor" + members = [ + "user:jane@example.com", + ] +} +``` + +## google\_iap\_web\_backend\_service\_iam\_member + +```hcl +resource "google_iap_web_backend_service_iam_member" "editor" { + project = "${google_compute_backend_service.default.project}" + backend_service_name = "${google_compute_backend_service.default.name}" + role = "roles/iap.httpsResourceAccessor" + member = "user:jane@example.com" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `backend_service_name` - (Required) Name or self link of a backend service. 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_iap_web_backend_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_iap_web_backend_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 + +Iap webbackendservice IAM resources can be imported using the project, resource identifiers, role and member. + +``` +$ terraform import google_iap_web_backend_service_iam_policy.editor projects/{{project}}/iap_web/compute/services/{{backendServiceName}} + +$ terraform import google_iap_web_backend_service_iam_binding.editor "projects/{{project}}/iap_web/compute/services/{{backendServiceName}} roles/iap.httpsResourceAccessor" + +$ terraform import google_iap_web_backend_service_iam_member.editor "projects/{{project}}/iap_web/compute/services/{{backendServiceName}} roles/iap.httpsResourceAccessor jane@example.com" +``` + +-> 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/provider_reference.html#user_project_override). diff --git a/website/docs/r/iap_web_iam.html.markdown b/website/docs/r/iap_web_iam.html.markdown new file mode 100644 index 0000000000..cf854b1e5e --- /dev/null +++ b/website/docs/r/iap_web_iam.html.markdown @@ -0,0 +1,123 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** 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. +# +# ---------------------------------------------------------------------------- +layout: "google" +page_title: "Google: google_iap_web_iam" +sidebar_current: "docs-google-iap-web-iam" +description: |- + Collection of resources to manage IAM policy for IapWeb +--- + +# IAM policy for IapWeb +Three different resources help you manage your IAM policy for Iap Web. Each of these resources serves a different use case: + +* `google_iap_web_iam_policy`: Authoritative. Sets the IAM policy for the web and replaces any existing policy already attached. +* `google_iap_web_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 web are preserved. +* `google_iap_web_iam_member`: Non-authoritative. Updates the IAM policy to grant a role to a new member. Other members for the role for the web are preserved. + +~> **Note:** `google_iap_web_iam_policy` **cannot** be used in conjunction with `google_iap_web_iam_binding` and `google_iap_web_iam_member` or they will fight over what your policy should be. + +~> **Note:** `google_iap_web_iam_binding` resources **can be** used in conjunction with `google_iap_web_iam_member` resources **only if** they do not grant privilege to the same role. + + + +## google\_iap\_web\_iam\_policy + +```hcl +data "google_iam_policy" "admin" { + binding { + role = "roles/iap.httpsResourceAccessor" + members = [ + "user:jane@example.com", + ] + } +} + +resource "google_iap_web_iam_policy" "editor" { + project = "${google_project_service.project_service.project}" + policy_data = "${data.google_iam_policy.admin.policy_data}" +} +``` + +## google\_iap\_web\_iam\_binding + +```hcl +resource "google_iap_web_iam_binding" "editor" { + project = "${google_project_service.project_service.project}" + role = "roles/iap.httpsResourceAccessor" + members = [ + "user:jane@example.com", + ] +} +``` + +## google\_iap\_web\_iam\_member + +```hcl +resource "google_iap_web_iam_member" "editor" { + project = "${google_project_service.project_service.project}" + role = "roles/iap.httpsResourceAccessor" + member = "user:jane@example.com" +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `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_iap_web_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_iap_web_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 + +Iap web IAM resources can be imported using the project, resource identifiers, role and member. + +``` +$ terraform import google_iap_web_iam_policy.editor projects/{{project}}/iap_web + +$ terraform import google_iap_web_iam_binding.editor "projects/{{project}}/iap_web roles/iap.httpsResourceAccessor" + +$ terraform import google_iap_web_iam_member.editor "projects/{{project}}/iap_web roles/iap.httpsResourceAccessor jane@example.com" +``` + +-> 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/provider_reference.html#user_project_override). diff --git a/website/docs/r/iap_web_type_app_engine_iam.html.markdown b/website/docs/r/iap_web_type_app_engine_iam.html.markdown new file mode 100644 index 0000000000..5cb3ff7e6a --- /dev/null +++ b/website/docs/r/iap_web_type_app_engine_iam.html.markdown @@ -0,0 +1,127 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** 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. +# +# ---------------------------------------------------------------------------- +layout: "google" +page_title: "Google: google_iap_web_type_app_engine_iam" +sidebar_current: "docs-google-iap-web-type-app-engine-iam" +description: |- + Collection of resources to manage IAM policy for IapWebTypeAppEngine +--- + +# IAM policy for IapWebTypeAppEngine +Three different resources help you manage your IAM policy for Iap WebTypeAppEngine. Each of these resources serves a different use case: + +* `google_iap_web_type_app_engine_iam_policy`: Authoritative. Sets the IAM policy for the webtypeappengine and replaces any existing policy already attached. +* `google_iap_web_type_app_engine_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 webtypeappengine are preserved. +* `google_iap_web_type_app_engine_iam_member`: Non-authoritative. Updates the IAM policy to grant a role to a new member. Other members for the role for the webtypeappengine are preserved. + +~> **Note:** `google_iap_web_type_app_engine_iam_policy` **cannot** be used in conjunction with `google_iap_web_type_app_engine_iam_binding` and `google_iap_web_type_app_engine_iam_member` or they will fight over what your policy should be. + +~> **Note:** `google_iap_web_type_app_engine_iam_binding` resources **can be** used in conjunction with `google_iap_web_type_app_engine_iam_member` resources **only if** they do not grant privilege to the same role. + + + +## google\_iap\_web\_type\_app\_engine\_iam\_policy + +```hcl +data "google_iam_policy" "admin" { + binding { + role = "roles/iap.httpsResourceAccessor" + members = [ + "user:jane@example.com", + ] + } +} + +resource "google_iap_web_type_app_engine_iam_policy" "editor" { + project = "${google_app_engine_application.app.project}" + app_id = "${google_app_engine_application.app.app_id}" + policy_data = "${data.google_iam_policy.admin.policy_data}" +} +``` + +## google\_iap\_web\_type\_app\_engine\_iam\_binding + +```hcl +resource "google_iap_web_type_app_engine_iam_binding" "editor" { + project = "${google_app_engine_application.app.project}" + app_id = "${google_app_engine_application.app.app_id}" + role = "roles/iap.httpsResourceAccessor" + members = [ + "user:jane@example.com", + ] +} +``` + +## google\_iap\_web\_type\_app\_engine\_iam\_member + +```hcl +resource "google_iap_web_type_app_engine_iam_member" "editor" { + project = "${google_app_engine_application.app.project}" + app_id = "${google_app_engine_application.app.app_id}" + role = "roles/iap.httpsResourceAccessor" + member = "user:jane@example.com" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `app_id` - (Required) Id of the App Engine application. 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_iap_web_type_app_engine_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_iap_web_type_app_engine_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 + +Iap webtypeappengine IAM resources can be imported using the project, resource identifiers, role and member. + +``` +$ terraform import google_iap_web_type_app_engine_iam_policy.editor projects/{{project}}/iap_web/appengine-{{appId}} + +$ terraform import google_iap_web_type_app_engine_iam_binding.editor "projects/{{project}}/iap_web/appengine-{{appId}} roles/iap.httpsResourceAccessor" + +$ terraform import google_iap_web_type_app_engine_iam_member.editor "projects/{{project}}/iap_web/appengine-{{appId}} roles/iap.httpsResourceAccessor jane@example.com" +``` + +-> 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/provider_reference.html#user_project_override). diff --git a/website/docs/r/iap_web_type_compute_iam.html.markdown b/website/docs/r/iap_web_type_compute_iam.html.markdown new file mode 100644 index 0000000000..eb40aca7e3 --- /dev/null +++ b/website/docs/r/iap_web_type_compute_iam.html.markdown @@ -0,0 +1,123 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** 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. +# +# ---------------------------------------------------------------------------- +layout: "google" +page_title: "Google: google_iap_web_type_compute_iam" +sidebar_current: "docs-google-iap-web-type-compute-iam" +description: |- + Collection of resources to manage IAM policy for IapWebTypeCompute +--- + +# IAM policy for IapWebTypeCompute +Three different resources help you manage your IAM policy for Iap WebTypeCompute. Each of these resources serves a different use case: + +* `google_iap_web_type_compute_iam_policy`: Authoritative. Sets the IAM policy for the webtypecompute and replaces any existing policy already attached. +* `google_iap_web_type_compute_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 webtypecompute are preserved. +* `google_iap_web_type_compute_iam_member`: Non-authoritative. Updates the IAM policy to grant a role to a new member. Other members for the role for the webtypecompute are preserved. + +~> **Note:** `google_iap_web_type_compute_iam_policy` **cannot** be used in conjunction with `google_iap_web_type_compute_iam_binding` and `google_iap_web_type_compute_iam_member` or they will fight over what your policy should be. + +~> **Note:** `google_iap_web_type_compute_iam_binding` resources **can be** used in conjunction with `google_iap_web_type_compute_iam_member` resources **only if** they do not grant privilege to the same role. + + + +## google\_iap\_web\_type\_compute\_iam\_policy + +```hcl +data "google_iam_policy" "admin" { + binding { + role = "roles/iap.httpsResourceAccessor" + members = [ + "user:jane@example.com", + ] + } +} + +resource "google_iap_web_type_compute_iam_policy" "editor" { + project = "${google_project_service.project_service.project}" + policy_data = "${data.google_iam_policy.admin.policy_data}" +} +``` + +## google\_iap\_web\_type\_compute\_iam\_binding + +```hcl +resource "google_iap_web_type_compute_iam_binding" "editor" { + project = "${google_project_service.project_service.project}" + role = "roles/iap.httpsResourceAccessor" + members = [ + "user:jane@example.com", + ] +} +``` + +## google\_iap\_web\_type\_compute\_iam\_member + +```hcl +resource "google_iap_web_type_compute_iam_member" "editor" { + project = "${google_project_service.project_service.project}" + role = "roles/iap.httpsResourceAccessor" + member = "user:jane@example.com" +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `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_iap_web_type_compute_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_iap_web_type_compute_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 + +Iap webtypecompute IAM resources can be imported using the project, resource identifiers, role and member. + +``` +$ terraform import google_iap_web_type_compute_iam_policy.editor projects/{{project}}/iap_web/compute + +$ terraform import google_iap_web_type_compute_iam_binding.editor "projects/{{project}}/iap_web/compute roles/iap.httpsResourceAccessor" + +$ terraform import google_iap_web_type_compute_iam_member.editor "projects/{{project}}/iap_web/compute roles/iap.httpsResourceAccessor jane@example.com" +``` + +-> 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/provider_reference.html#user_project_override). diff --git a/website/docs/r/pubsub_topic_iam.html.markdown b/website/docs/r/pubsub_topic_iam.html.markdown index f5fdef77ed..69460fe9b0 100644 --- a/website/docs/r/pubsub_topic_iam.html.markdown +++ b/website/docs/r/pubsub_topic_iam.html.markdown @@ -36,17 +36,18 @@ Three different resources help you manage your IAM policy for Pubsub Topic. Each ```hcl data "google_iam_policy" "admin" { - binding { - role = "roles/editor" - members = [ - "user:jane@example.com", - ] - } + binding { + role = "roles/viewer" + members = [ + "user:jane@example.com", + ] + } } resource "google_pubsub_topic_iam_policy" "editor" { - topic = "projects/{{project}}/topics/{{topic}}" - policy_data = "${data.google_iam_policy.admin.policy_data}" + project = "${google_pubsub_topic_iam.example.project}" + name = "${google_pubsub_topic_iam.example.id}" + policy_data = "${data.google_iam_policy.admin.policy_data}" } ``` @@ -54,12 +55,12 @@ resource "google_pubsub_topic_iam_policy" "editor" { ```hcl resource "google_pubsub_topic_iam_binding" "editor" { - topic = "projects/{{project}}/topics/{{topic}}" - - role = "roles/editor" - members = [ - "user:jane@example.com", - ] + project = "${google_pubsub_topic_iam.example.project}" + name = "${google_pubsub_topic_iam.example.id}" + role = "roles/viewer" + members = [ + "user:jane@example.com", + ] } ``` @@ -67,10 +68,10 @@ resource "google_pubsub_topic_iam_binding" "editor" { ```hcl resource "google_pubsub_topic_iam_member" "editor" { - topic = "projects/{{project}}/topics/{{topic}}" - - role = "roles/editor" - member = "user:jane@example.com" + project = "${google_pubsub_topic_iam.example.project}" + name = "${google_pubsub_topic_iam.example.id}" + role = "roles/viewer" + member = "user:jane@example.com" } ``` @@ -78,10 +79,10 @@ resource "google_pubsub_topic_iam_member" "editor" { The following arguments are supported: -* `topic` - (Required) The topic name or id to bind to attach IAM policy to. +* `topic` - (Required) Used to find the parent resource to bind the IAM policy to -* `project` - (Optional) The project in which the resource belongs. If it - is not provided, the provider project is used. +* `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: @@ -104,17 +105,18 @@ The following arguments are supported: In addition to the arguments listed above, the following computed attributes are exported: -* `etag` - (Computed) The etag of the topic's IAM policy. +* `etag` - (Computed) The etag of the IAM policy. ## Import -Pubsub topic IAM resources can be imported using the project, topic name, role and member. +Pubsub topic IAM resources can be imported using the project, resource identifiers, role and member. ``` $ terraform import google_pubsub_topic_iam_policy.editor projects/{{project}}/topics/{{topic}} -$ terraform import google_pubsub_topic_iam_binding.editor "projects/{{project}}/topics/{{topic}} roles/editor" -$ terraform import google_pubsub_topic_iam_member.editor "projects/{{project}}/topics/{{topic}} roles/editor jane@example.com" +$ terraform import google_pubsub_topic_iam_binding.editor "projects/{{project}}/topics/{{topic}} roles/viewer" + +$ terraform import google_pubsub_topic_iam_member.editor "projects/{{project}}/topics/{{topic}} roles/viewer jane@example.com" ``` -> If you're importing a resource with beta features, make sure to include `-provider=google-beta` diff --git a/website/docs/r/sourcerepo_repository_iam.html.markdown b/website/docs/r/sourcerepo_repository_iam.html.markdown index 9fddd88aca..e632104469 100644 --- a/website/docs/r/sourcerepo_repository_iam.html.markdown +++ b/website/docs/r/sourcerepo_repository_iam.html.markdown @@ -36,17 +36,18 @@ Three different resources help you manage your IAM policy for SourceRepo Reposit ```hcl data "google_iam_policy" "admin" { - binding { - role = "roles/editor" - members = [ - "user:jane@example.com", - ] - } + binding { + role = "roles/viewer" + members = [ + "user:jane@example.com", + ] + } } resource "google_sourcerepo_repository_iam_policy" "editor" { - repository = "{{project}}/{{repository}}" - policy_data = "${data.google_iam_policy.admin.policy_data}" + project = "${google_sourcerepo_repository_iam.my-repo.project}" + name = "${google_sourcerepo_repository_iam.my-repo.id}" + policy_data = "${data.google_iam_policy.admin.policy_data}" } ``` @@ -54,12 +55,12 @@ resource "google_sourcerepo_repository_iam_policy" "editor" { ```hcl resource "google_sourcerepo_repository_iam_binding" "editor" { - repository = "{{project}}/{{repository}}" - - role = "roles/editor" - members = [ - "user:jane@example.com", - ] + project = "${google_sourcerepo_repository_iam.my-repo.project}" + name = "${google_sourcerepo_repository_iam.my-repo.id}" + role = "roles/viewer" + members = [ + "user:jane@example.com", + ] } ``` @@ -67,10 +68,10 @@ resource "google_sourcerepo_repository_iam_binding" "editor" { ```hcl resource "google_sourcerepo_repository_iam_member" "editor" { - repository = "{{project}}/{{repository}}" - - role = "roles/editor" - member = "user:jane@example.com" + project = "${google_sourcerepo_repository_iam.my-repo.project}" + name = "${google_sourcerepo_repository_iam.my-repo.id}" + role = "roles/viewer" + member = "user:jane@example.com" } ``` @@ -78,10 +79,10 @@ resource "google_sourcerepo_repository_iam_member" "editor" { The following arguments are supported: -* `repository` - (Required) The repository name or id to bind to attach IAM policy to. +* `repository` - (Required) Used to find the parent resource to bind the IAM policy to -* `project` - (Optional) The project in which the resource belongs. If it - is not provided, the provider project is used. +* `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: @@ -104,17 +105,18 @@ The following arguments are supported: In addition to the arguments listed above, the following computed attributes are exported: -* `etag` - (Computed) The etag of the repository's IAM policy. +* `etag` - (Computed) The etag of the IAM policy. ## Import -SourceRepo repository IAM resources can be imported using the project, repository name, role and member. +SourceRepo repository IAM resources can be imported using the project, resource identifiers, role and member. ``` $ terraform import google_sourcerepo_repository_iam_policy.editor {{project}}/{{repository}} -$ terraform import google_sourcerepo_repository_iam_binding.editor "{{project}}/{{repository}} roles/editor" -$ terraform import google_sourcerepo_repository_iam_member.editor "{{project}}/{{repository}} roles/editor jane@example.com" +$ terraform import google_sourcerepo_repository_iam_binding.editor "{{project}}/{{repository}} roles/viewer" + +$ terraform import google_sourcerepo_repository_iam_member.editor "{{project}}/{{repository}} roles/viewer jane@example.com" ``` -> If you're importing a resource with beta features, make sure to include `-provider=google-beta` diff --git a/website/google.erb b/website/google.erb index 7b840ed393..3dfec75535 100644 --- a/website/google.erb +++ b/website/google.erb @@ -902,7 +902,6 @@ - > Google IAP Resources + > Google ML Engine Resources