diff --git a/google-beta/provider/provider_mmv1_resources.go b/google-beta/provider/provider_mmv1_resources.go index 773ac57a62..308a3ced0f 100644 --- a/google-beta/provider/provider_mmv1_resources.go +++ b/google-beta/provider/provider_mmv1_resources.go @@ -403,6 +403,7 @@ var generatedIAMDatasources = map[string]*schema.Resource{ "google_iap_web_region_backend_service_iam_policy": tpgiamresource.DataSourceIamPolicy(iap.IapWebRegionBackendServiceIamSchema, iap.IapWebRegionBackendServiceIamUpdaterProducer), "google_iap_web_type_app_engine_iam_policy": tpgiamresource.DataSourceIamPolicy(iap.IapWebTypeAppEngineIamSchema, iap.IapWebTypeAppEngineIamUpdaterProducer), "google_iap_web_type_compute_iam_policy": tpgiamresource.DataSourceIamPolicy(iap.IapWebTypeComputeIamSchema, iap.IapWebTypeComputeIamUpdaterProducer), + "google_logging_log_view_iam_policy": tpgiamresource.DataSourceIamPolicy(logging.LoggingLogViewIamSchema, logging.LoggingLogViewIamUpdaterProducer), "google_network_security_address_group_iam_policy": tpgiamresource.DataSourceIamPolicy(networksecurity.NetworkSecurityProjectAddressGroupIamSchema, networksecurity.NetworkSecurityProjectAddressGroupIamUpdaterProducer), "google_notebooks_instance_iam_policy": tpgiamresource.DataSourceIamPolicy(notebooks.NotebooksInstanceIamSchema, notebooks.NotebooksInstanceIamUpdaterProducer), "google_notebooks_runtime_iam_policy": tpgiamresource.DataSourceIamPolicy(notebooks.NotebooksRuntimeIamSchema, notebooks.NotebooksRuntimeIamUpdaterProducer), @@ -457,8 +458,8 @@ var handwrittenIAMDatasources = map[string]*schema.Resource{ // Resources // Generated resources: 473 -// Generated IAM resources: 276 -// Total generated resources: 749 +// Generated IAM resources: 279 +// Total generated resources: 752 var generatedResources = map[string]*schema.Resource{ "google_folder_access_approval_settings": accessapproval.ResourceAccessApprovalFolderSettings(), "google_organization_access_approval_settings": accessapproval.ResourceAccessApprovalOrganizationSettings(), @@ -995,6 +996,9 @@ var generatedResources = map[string]*schema.Resource{ "google_logging_folder_settings": logging.ResourceLoggingFolderSettings(), "google_logging_linked_dataset": logging.ResourceLoggingLinkedDataset(), "google_logging_log_view": logging.ResourceLoggingLogView(), + "google_logging_log_view_iam_binding": tpgiamresource.ResourceIamBinding(logging.LoggingLogViewIamSchema, logging.LoggingLogViewIamUpdaterProducer, logging.LoggingLogViewIdParseFunc), + "google_logging_log_view_iam_member": tpgiamresource.ResourceIamMember(logging.LoggingLogViewIamSchema, logging.LoggingLogViewIamUpdaterProducer, logging.LoggingLogViewIdParseFunc), + "google_logging_log_view_iam_policy": tpgiamresource.ResourceIamPolicy(logging.LoggingLogViewIamSchema, logging.LoggingLogViewIamUpdaterProducer, logging.LoggingLogViewIdParseFunc), "google_logging_metric": logging.ResourceLoggingMetric(), "google_logging_organization_settings": logging.ResourceLoggingOrganizationSettings(), "google_looker_instance": looker.ResourceLookerInstance(), diff --git a/google-beta/services/logging/iam_logging_log_view.go b/google-beta/services/logging/iam_logging_log_view.go new file mode 100644 index 0000000000..937df41bbe --- /dev/null +++ b/google-beta/services/logging/iam_logging_log_view.go @@ -0,0 +1,246 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// 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 logging + +import ( + "fmt" + + "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "google.golang.org/api/cloudresourcemanager/v1" + + "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgiamresource" + "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport" +) + +var LoggingLogViewIamSchema = map[string]*schema.Schema{ + "parent": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "location": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + }, + "bucket": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: tpgresource.CompareSelfLinkOrResourceName, + }, +} + +type LoggingLogViewIamUpdater struct { + parent string + location string + bucket string + name string + d tpgresource.TerraformResourceData + Config *transport_tpg.Config +} + +func LoggingLogViewIamUpdaterProducer(d tpgresource.TerraformResourceData, config *transport_tpg.Config) (tpgiamresource.ResourceIamUpdater, error) { + values := make(map[string]string) + + if v, ok := d.GetOk("parent"); ok { + values["parent"] = v.(string) + } + + location, _ := tpgresource.GetLocation(d, config) + if location != "" { + if err := d.Set("location", location); err != nil { + return nil, fmt.Errorf("Error setting location: %s", err) + } + } + values["location"] = location + if v, ok := d.GetOk("bucket"); ok { + values["bucket"] = v.(string) + } + + if v, ok := d.GetOk("name"); ok { + values["name"] = v.(string) + } + + // We may have gotten either a long or short name, so attempt to parse long name if possible + m, err := tpgresource.GetImportIdQualifiers([]string{"(?P.+)/locations/(?P[^/]+)/buckets/(?P[^/]+)/views/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Get("name").(string)) + if err != nil { + return nil, err + } + + for k, v := range m { + values[k] = v + } + + u := &LoggingLogViewIamUpdater{ + parent: values["parent"], + location: values["location"], + bucket: values["bucket"], + name: values["name"], + d: d, + Config: config, + } + + if err := d.Set("parent", u.parent); err != nil { + return nil, fmt.Errorf("Error setting parent: %s", err) + } + if err := d.Set("location", u.location); err != nil { + return nil, fmt.Errorf("Error setting location: %s", err) + } + if err := d.Set("bucket", u.bucket); err != nil { + return nil, fmt.Errorf("Error setting bucket: %s", err) + } + if err := d.Set("name", u.GetResourceId()); err != nil { + return nil, fmt.Errorf("Error setting name: %s", err) + } + + return u, nil +} + +func LoggingLogViewIdParseFunc(d *schema.ResourceData, config *transport_tpg.Config) error { + values := make(map[string]string) + + location, _ := tpgresource.GetLocation(d, config) + if location != "" { + values["location"] = location + } + + m, err := tpgresource.GetImportIdQualifiers([]string{"(?P.+)/locations/(?P[^/]+)/buckets/(?P[^/]+)/views/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Id()) + if err != nil { + return err + } + + for k, v := range m { + values[k] = v + } + + u := &LoggingLogViewIamUpdater{ + parent: values["parent"], + location: values["location"], + bucket: values["bucket"], + name: values["name"], + d: d, + Config: config, + } + if err := d.Set("name", u.GetResourceId()); err != nil { + return fmt.Errorf("Error setting name: %s", err) + } + d.SetId(u.GetResourceId()) + return nil +} + +func (u *LoggingLogViewIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { + url, err := u.qualifyLogViewUrl("getIamPolicy") + if err != nil { + return nil, err + } + + var obj map[string]interface{} + obj = map[string]interface{}{ + "options": map[string]interface{}{ + "requestedPolicyVersion": tpgiamresource.IamPolicyVersion, + }, + } + + userAgent, err := tpgresource.GenerateUserAgentString(u.d, u.Config.UserAgent) + if err != nil { + return nil, err + } + + policy, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: u.Config, + Method: "POST", + RawURL: url, + UserAgent: userAgent, + Body: obj, + }) + if err != nil { + return nil, errwrap.Wrapf(fmt.Sprintf("Error retrieving IAM policy for %s: {{err}}", u.DescribeResource()), err) + } + + out := &cloudresourcemanager.Policy{} + err = tpgresource.Convert(policy, out) + if err != nil { + return nil, errwrap.Wrapf("Cannot convert a policy to a resource manager policy: {{err}}", err) + } + + return out, nil +} + +func (u *LoggingLogViewIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanager.Policy) error { + json, err := tpgresource.ConvertToMap(policy) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + obj["policy"] = json + + url, err := u.qualifyLogViewUrl("setIamPolicy") + if err != nil { + return err + } + + userAgent, err := tpgresource.GenerateUserAgentString(u.d, u.Config.UserAgent) + if err != nil { + return err + } + + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: u.Config, + Method: "POST", + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: u.d.Timeout(schema.TimeoutCreate), + }) + if err != nil { + return errwrap.Wrapf(fmt.Sprintf("Error setting IAM policy for %s: {{err}}", u.DescribeResource()), err) + } + + return nil +} + +func (u *LoggingLogViewIamUpdater) qualifyLogViewUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{LoggingBasePath}}%s:%s", fmt.Sprintf("%s/locations/%s/buckets/%s/views/%s", u.parent, u.location, u.bucket, u.name), methodIdentifier) + url, err := tpgresource.ReplaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil +} + +func (u *LoggingLogViewIamUpdater) GetResourceId() string { + return fmt.Sprintf("%s/locations/%s/buckets/%s/views/%s", u.parent, u.location, u.bucket, u.name) +} + +func (u *LoggingLogViewIamUpdater) GetMutexKey() string { + return fmt.Sprintf("iam-logging-logview-%s", u.GetResourceId()) +} + +func (u *LoggingLogViewIamUpdater) DescribeResource() string { + return fmt.Sprintf("logging logview %q", u.GetResourceId()) +} diff --git a/google-beta/services/logging/iam_logging_log_view_generated_test.go b/google-beta/services/logging/iam_logging_log_view_generated_test.go new file mode 100644 index 0000000000..bfd544689f --- /dev/null +++ b/google-beta/services/logging/iam_logging_log_view_generated_test.go @@ -0,0 +1,637 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// 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 logging_test + +import ( + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/hashicorp/terraform-provider-google-beta/google-beta/acctest" + "github.com/hashicorp/terraform-provider-google-beta/google-beta/envvar" + "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource" +) + +func TestAccLoggingLogViewIamBindingGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + "role": "roles/logging.admin", + "project": envvar.GetTestProjectFromEnv(), + + "condition_title": "expires_after_2019_12_31", + "condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + "condition_desc": "Expiring at midnight of 2019-12-31", + "condition_title_no_desc": "expires_after_2019_12_31-no-description", + "condition_expr_no_desc": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccLoggingLogViewIamBinding_basicGenerated(context), + }, + { + // Test Iam Binding update + Config: testAccLoggingLogViewIamBinding_updateGenerated(context), + }, + }, + }) +} + +func TestAccLoggingLogViewIamMemberGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + "role": "roles/logging.admin", + "project": envvar.GetTestProjectFromEnv(), + + "condition_title": "expires_after_2019_12_31", + "condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + "condition_desc": "Expiring at midnight of 2019-12-31", + "condition_title_no_desc": "expires_after_2019_12_31-no-description", + "condition_expr_no_desc": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + // Test Iam Member creation (no update for member, no need to test) + Config: testAccLoggingLogViewIamMember_basicGenerated(context), + }, + }, + }) +} + +func TestAccLoggingLogViewIamPolicyGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + "role": "roles/logging.admin", + "project": envvar.GetTestProjectFromEnv(), + + "condition_title": "expires_after_2019_12_31", + "condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + "condition_desc": "Expiring at midnight of 2019-12-31", + "condition_title_no_desc": "expires_after_2019_12_31-no-description", + "condition_expr_no_desc": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccLoggingLogViewIamPolicy_basicGenerated(context), + Check: resource.TestCheckResourceAttrSet("data.google_logging_log_view_iam_policy.foo", "policy_data"), + }, + { + Config: testAccLoggingLogViewIamPolicy_emptyBinding(context), + }, + }, + }) +} + +func TestAccLoggingLogViewIamBindingGenerated_withCondition(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + "role": "roles/logging.admin", + "project": envvar.GetTestProjectFromEnv(), + + "condition_title": "expires_after_2019_12_31", + "condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + "condition_desc": "Expiring at midnight of 2019-12-31", + "condition_title_no_desc": "expires_after_2019_12_31-no-description", + "condition_expr_no_desc": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccLoggingLogViewIamBinding_withConditionGenerated(context), + }, + }, + }) +} + +func TestAccLoggingLogViewIamBindingGenerated_withAndWithoutCondition(t *testing.T) { + // Multiple fine-grained resources + acctest.SkipIfVcr(t) + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + "role": "roles/logging.admin", + "project": envvar.GetTestProjectFromEnv(), + + "condition_title": "expires_after_2019_12_31", + "condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + "condition_desc": "Expiring at midnight of 2019-12-31", + "condition_title_no_desc": "expires_after_2019_12_31-no-description", + "condition_expr_no_desc": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccLoggingLogViewIamBinding_withAndWithoutConditionGenerated(context), + }, + }, + }) +} + +func TestAccLoggingLogViewIamMemberGenerated_withCondition(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + "role": "roles/logging.admin", + "project": envvar.GetTestProjectFromEnv(), + + "condition_title": "expires_after_2019_12_31", + "condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + "condition_desc": "Expiring at midnight of 2019-12-31", + "condition_title_no_desc": "expires_after_2019_12_31-no-description", + "condition_expr_no_desc": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccLoggingLogViewIamMember_withConditionGenerated(context), + }, + }, + }) +} + +func TestAccLoggingLogViewIamMemberGenerated_withAndWithoutCondition(t *testing.T) { + // Multiple fine-grained resources + acctest.SkipIfVcr(t) + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + "role": "roles/logging.admin", + "project": envvar.GetTestProjectFromEnv(), + + "condition_title": "expires_after_2019_12_31", + "condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + "condition_desc": "Expiring at midnight of 2019-12-31", + "condition_title_no_desc": "expires_after_2019_12_31-no-description", + "condition_expr_no_desc": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccLoggingLogViewIamMember_withAndWithoutConditionGenerated(context), + }, + }, + }) +} + +func TestAccLoggingLogViewIamPolicyGenerated_withCondition(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + "role": "roles/logging.admin", + "project": envvar.GetTestProjectFromEnv(), + + "condition_title": "expires_after_2019_12_31", + "condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + "condition_desc": "Expiring at midnight of 2019-12-31", + "condition_title_no_desc": "expires_after_2019_12_31-no-description", + "condition_expr_no_desc": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`, + } + + // Test should have 2 bindings: one with a description and one without. Any < chars are converted to a unicode character by the API. + expectedPolicyData := acctest.Nprintf(`{"bindings":[{"condition":{"description":"%{condition_desc}","expression":"%{condition_expr}","title":"%{condition_title}"},"members":["user:admin@hashicorptest.com"],"role":"%{role}"},{"condition":{"expression":"%{condition_expr}","title":"%{condition_title}-no-description"},"members":["user:admin@hashicorptest.com"],"role":"%{role}"}]}`, context) + expectedPolicyData = strings.Replace(expectedPolicyData, "<", "\\u003c", -1) + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccLoggingLogViewIamPolicy_withConditionGenerated(context), + Check: resource.ComposeAggregateTestCheckFunc( + // TODO(SarahFrench) - uncomment once https://github.com/GoogleCloudPlatform/magic-modules/pull/6466 merged + // resource.TestCheckResourceAttr("data.google_iam_policy.foo", "policy_data", expectedPolicyData), + resource.TestCheckResourceAttr("google_logging_log_view_iam_policy.foo", "policy_data", expectedPolicyData), + resource.TestCheckResourceAttrWith("data.google_iam_policy.foo", "policy_data", tpgresource.CheckGoogleIamPolicy), + ), + }, + }, + }) +} + +func testAccLoggingLogViewIamMember_basicGenerated(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_logging_project_bucket_config" "logging_log_view" { + project = "%{project}" + location = "global" + retention_days = 30 + bucket_id = "_Default" +} + +resource "google_logging_log_view" "logging_log_view" { + name = "tf-test-my-view%{random_suffix}" + bucket = google_logging_project_bucket_config.logging_log_view.id + description = "A logging view configured with Terraform" + filter = "SOURCE(\"projects/myproject\") AND resource.type = \"gce_instance\" AND LOG_ID(\"stdout\")" +} + +resource "google_logging_log_view_iam_member" "foo" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + role = "%{role}" + member = "user:admin@hashicorptest.com" +} +`, context) +} + +func testAccLoggingLogViewIamPolicy_basicGenerated(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_logging_project_bucket_config" "logging_log_view" { + project = "%{project}" + location = "global" + retention_days = 30 + bucket_id = "_Default" +} + +resource "google_logging_log_view" "logging_log_view" { + name = "tf-test-my-view%{random_suffix}" + bucket = google_logging_project_bucket_config.logging_log_view.id + description = "A logging view configured with Terraform" + filter = "SOURCE(\"projects/myproject\") AND resource.type = \"gce_instance\" AND LOG_ID(\"stdout\")" +} + +data "google_iam_policy" "foo" { + binding { + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + } +} + +resource "google_logging_log_view_iam_policy" "foo" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + policy_data = data.google_iam_policy.foo.policy_data +} + +data "google_logging_log_view_iam_policy" "foo" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + depends_on = [ + google_logging_log_view_iam_policy.foo + ] +} +`, context) +} + +func testAccLoggingLogViewIamPolicy_emptyBinding(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_logging_project_bucket_config" "logging_log_view" { + project = "%{project}" + location = "global" + retention_days = 30 + bucket_id = "_Default" +} + +resource "google_logging_log_view" "logging_log_view" { + name = "tf-test-my-view%{random_suffix}" + bucket = google_logging_project_bucket_config.logging_log_view.id + description = "A logging view configured with Terraform" + filter = "SOURCE(\"projects/myproject\") AND resource.type = \"gce_instance\" AND LOG_ID(\"stdout\")" +} + +data "google_iam_policy" "foo" { +} + +resource "google_logging_log_view_iam_policy" "foo" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + policy_data = data.google_iam_policy.foo.policy_data +} +`, context) +} + +func testAccLoggingLogViewIamBinding_basicGenerated(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_logging_project_bucket_config" "logging_log_view" { + project = "%{project}" + location = "global" + retention_days = 30 + bucket_id = "_Default" +} + +resource "google_logging_log_view" "logging_log_view" { + name = "tf-test-my-view%{random_suffix}" + bucket = google_logging_project_bucket_config.logging_log_view.id + description = "A logging view configured with Terraform" + filter = "SOURCE(\"projects/myproject\") AND resource.type = \"gce_instance\" AND LOG_ID(\"stdout\")" +} + +resource "google_logging_log_view_iam_binding" "foo" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + role = "%{role}" + members = ["user:admin@hashicorptest.com"] +} +`, context) +} + +func testAccLoggingLogViewIamBinding_updateGenerated(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_logging_project_bucket_config" "logging_log_view" { + project = "%{project}" + location = "global" + retention_days = 30 + bucket_id = "_Default" +} + +resource "google_logging_log_view" "logging_log_view" { + name = "tf-test-my-view%{random_suffix}" + bucket = google_logging_project_bucket_config.logging_log_view.id + description = "A logging view configured with Terraform" + filter = "SOURCE(\"projects/myproject\") AND resource.type = \"gce_instance\" AND LOG_ID(\"stdout\")" +} + +resource "google_logging_log_view_iam_binding" "foo" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + role = "%{role}" + members = ["user:admin@hashicorptest.com", "user:gterraformtest1@gmail.com"] +} +`, context) +} + +func testAccLoggingLogViewIamBinding_withConditionGenerated(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_logging_project_bucket_config" "logging_log_view" { + project = "%{project}" + location = "global" + retention_days = 30 + bucket_id = "_Default" +} + +resource "google_logging_log_view" "logging_log_view" { + name = "tf-test-my-view%{random_suffix}" + bucket = google_logging_project_bucket_config.logging_log_view.id + description = "A logging view configured with Terraform" + filter = "SOURCE(\"projects/myproject\") AND resource.type = \"gce_instance\" AND LOG_ID(\"stdout\")" +} + +resource "google_logging_log_view_iam_binding" "foo" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + condition { + title = "%{condition_title}" + description = "%{condition_desc}" + expression = "%{condition_expr}" + } +} +`, context) +} + +func testAccLoggingLogViewIamBinding_withAndWithoutConditionGenerated(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_logging_project_bucket_config" "logging_log_view" { + project = "%{project}" + location = "global" + retention_days = 30 + bucket_id = "_Default" +} + +resource "google_logging_log_view" "logging_log_view" { + name = "tf-test-my-view%{random_suffix}" + bucket = google_logging_project_bucket_config.logging_log_view.id + description = "A logging view configured with Terraform" + filter = "SOURCE(\"projects/myproject\") AND resource.type = \"gce_instance\" AND LOG_ID(\"stdout\")" +} + +resource "google_logging_log_view_iam_binding" "foo" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + role = "%{role}" + members = ["user:admin@hashicorptest.com"] +} + +resource "google_logging_log_view_iam_binding" "foo2" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + condition { + title = "%{condition_title}" + description = "%{condition_desc}" + expression = "%{condition_expr}" + } +} + +resource "google_logging_log_view_iam_binding" "foo3" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + condition { + # Check that lack of description doesn't cause any issues + # Relates to issue : https://github.com/hashicorp/terraform-provider-google/issues/8701 + title = "%{condition_title_no_desc}" + expression = "%{condition_expr_no_desc}" + } +} +`, context) +} + +func testAccLoggingLogViewIamMember_withConditionGenerated(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_logging_project_bucket_config" "logging_log_view" { + project = "%{project}" + location = "global" + retention_days = 30 + bucket_id = "_Default" +} + +resource "google_logging_log_view" "logging_log_view" { + name = "tf-test-my-view%{random_suffix}" + bucket = google_logging_project_bucket_config.logging_log_view.id + description = "A logging view configured with Terraform" + filter = "SOURCE(\"projects/myproject\") AND resource.type = \"gce_instance\" AND LOG_ID(\"stdout\")" +} + +resource "google_logging_log_view_iam_member" "foo" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + role = "%{role}" + member = "user:admin@hashicorptest.com" + condition { + title = "%{condition_title}" + description = "%{condition_desc}" + expression = "%{condition_expr}" + } +} +`, context) +} + +func testAccLoggingLogViewIamMember_withAndWithoutConditionGenerated(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_logging_project_bucket_config" "logging_log_view" { + project = "%{project}" + location = "global" + retention_days = 30 + bucket_id = "_Default" +} + +resource "google_logging_log_view" "logging_log_view" { + name = "tf-test-my-view%{random_suffix}" + bucket = google_logging_project_bucket_config.logging_log_view.id + description = "A logging view configured with Terraform" + filter = "SOURCE(\"projects/myproject\") AND resource.type = \"gce_instance\" AND LOG_ID(\"stdout\")" +} + +resource "google_logging_log_view_iam_member" "foo" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + role = "%{role}" + member = "user:admin@hashicorptest.com" +} + +resource "google_logging_log_view_iam_member" "foo2" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + role = "%{role}" + member = "user:admin@hashicorptest.com" + condition { + title = "%{condition_title}" + description = "%{condition_desc}" + expression = "%{condition_expr}" + } +} + +resource "google_logging_log_view_iam_member" "foo3" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + role = "%{role}" + member = "user:admin@hashicorptest.com" + condition { + # Check that lack of description doesn't cause any issues + # Relates to issue : https://github.com/hashicorp/terraform-provider-google/issues/8701 + title = "%{condition_title_no_desc}" + expression = "%{condition_expr_no_desc}" + } +} +`, context) +} + +func testAccLoggingLogViewIamPolicy_withConditionGenerated(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_logging_project_bucket_config" "logging_log_view" { + project = "%{project}" + location = "global" + retention_days = 30 + bucket_id = "_Default" +} + +resource "google_logging_log_view" "logging_log_view" { + name = "tf-test-my-view%{random_suffix}" + bucket = google_logging_project_bucket_config.logging_log_view.id + description = "A logging view configured with Terraform" + filter = "SOURCE(\"projects/myproject\") AND resource.type = \"gce_instance\" AND LOG_ID(\"stdout\")" +} + +data "google_iam_policy" "foo" { + binding { + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + condition { + # Check that lack of description doesn't cause any issues + # Relates to issue : https://github.com/hashicorp/terraform-provider-google/issues/8701 + title = "%{condition_title_no_desc}" + expression = "%{condition_expr_no_desc}" + } + } + binding { + role = "%{role}" + members = ["user:admin@hashicorptest.com"] + condition { + title = "%{condition_title}" + description = "%{condition_desc}" + expression = "%{condition_expr}" + } + } +} + +resource "google_logging_log_view_iam_policy" "foo" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + policy_data = data.google_iam_policy.foo.policy_data +} +`, context) +} diff --git a/website/docs/d/logging_log_view_iam_policy.html.markdown b/website/docs/d/logging_log_view_iam_policy.html.markdown new file mode 100644 index 0000000000..bb915fc852 --- /dev/null +++ b/website/docs/d/logging_log_view_iam_policy.html.markdown @@ -0,0 +1,56 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Cloud (Stackdriver) Logging" +description: |- + A datasource to retrieve the IAM policy state for Cloud (Stackdriver) Logging LogView +--- + + +# `google_logging_log_view_iam_policy` +Retrieves the current IAM policy data for logview +~> **Warning:** This datasource is in beta, and should be used with the terraform-provider-google-beta provider. +See [Provider Versions](https://terraform.io/docs/providers/google/guides/provider_versions.html) for more details on beta resources. + + +## example + +```hcl +data "google_logging_log_view_iam_policy" "policy" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Used to find the parent resource to bind the IAM policy to +* `parent` - (Required) The parent of the resource. Used to find the parent resource to bind the IAM policy to +* `location` - (Optional) The location of the resource. The supported locations are: global, us-central1, us-east1, us-west1, asia-east1, europe-west1. Used to find the parent resource to bind the IAM policy to. If not specified, + the value will be parsed from the identifier of the parent resource. If no location is provided in the parent identifier and no + location is specified, it is taken from the provider configuration. +* `bucket` - (Required) The bucket of the resource Used to find the parent resource to bind the IAM policy to + +## Attributes Reference + +The attributes are exported: + +* `etag` - (Computed) The etag of the IAM policy. + +* `policy_data` - (Required only by `google_logging_log_view_iam_policy`) The policy data generated by + a `google_iam_policy` data source. diff --git a/website/docs/r/logging_log_view_iam.html.markdown b/website/docs/r/logging_log_view_iam.html.markdown new file mode 100644 index 0000000000..947bcbc1d3 --- /dev/null +++ b/website/docs/r/logging_log_view_iam.html.markdown @@ -0,0 +1,234 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Cloud (Stackdriver) Logging" +description: |- + Collection of resources to manage IAM policy for Cloud (Stackdriver) Logging LogView +--- + +# IAM policy for Cloud (Stackdriver) Logging LogView +Three different resources help you manage your IAM policy for Cloud (Stackdriver) Logging LogView. Each of these resources serves a different use case: + +* `google_logging_log_view_iam_policy`: Authoritative. Sets the IAM policy for the logview and replaces any existing policy already attached. +* `google_logging_log_view_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 logview are preserved. +* `google_logging_log_view_iam_member`: Non-authoritative. Updates the IAM policy to grant a role to a new member. Other members for the role for the logview are preserved. + +A data source can be used to retrieve policy data in advent you do not need creation + +* `google_logging_log_view_iam_policy`: Retrieves the IAM policy for the logview + +~> **Note:** `google_logging_log_view_iam_policy` **cannot** be used in conjunction with `google_logging_log_view_iam_binding` and `google_logging_log_view_iam_member` or they will fight over what your policy should be. + +~> **Note:** `google_logging_log_view_iam_binding` resources **can be** used in conjunction with `google_logging_log_view_iam_member` resources **only if** they do not grant privilege to the same role. + +~> **Note:** This resource supports IAM Conditions but they have some known limitations which can be found [here](https://cloud.google.com/iam/docs/conditions-overview#limitations). Please review this article if you are having issues with IAM Conditions. + +~> **Warning:** This resource is in beta, and should be used with the terraform-provider-google-beta provider. +See [Provider Versions](https://terraform.io/docs/providers/google/guides/provider_versions.html) for more details on beta resources. + +## google_logging_log_view_iam_policy + +```hcl +data "google_iam_policy" "admin" { + binding { + role = "roles/logging.admin" + members = [ + "user:jane@example.com", + ] + } +} + +resource "google_logging_log_view_iam_policy" "policy" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + policy_data = data.google_iam_policy.admin.policy_data +} +``` + +With IAM Conditions: + +```hcl +data "google_iam_policy" "admin" { + binding { + role = "roles/logging.admin" + members = [ + "user:jane@example.com", + ] + + condition { + title = "expires_after_2019_12_31" + description = "Expiring at midnight of 2019-12-31" + expression = "request.time < timestamp(\"2020-01-01T00:00:00Z\")" + } + } +} + +resource "google_logging_log_view_iam_policy" "policy" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + policy_data = data.google_iam_policy.admin.policy_data +} +``` +## google_logging_log_view_iam_binding + +```hcl +resource "google_logging_log_view_iam_binding" "binding" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + role = "roles/logging.admin" + members = [ + "user:jane@example.com", + ] +} +``` + +With IAM Conditions: + +```hcl +resource "google_logging_log_view_iam_binding" "binding" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + role = "roles/logging.admin" + members = [ + "user:jane@example.com", + ] + + condition { + title = "expires_after_2019_12_31" + description = "Expiring at midnight of 2019-12-31" + expression = "request.time < timestamp(\"2020-01-01T00:00:00Z\")" + } +} +``` +## google_logging_log_view_iam_member + +```hcl +resource "google_logging_log_view_iam_member" "member" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + role = "roles/logging.admin" + member = "user:jane@example.com" +} +``` + +With IAM Conditions: + +```hcl +resource "google_logging_log_view_iam_member" "member" { + parent = google_logging_log_view.logging_log_view.parent + location = google_logging_log_view.logging_log_view.location + bucket = google_logging_log_view.logging_log_view.bucket + name = google_logging_log_view.logging_log_view.name + role = "roles/logging.admin" + member = "user:jane@example.com" + + condition { + title = "expires_after_2019_12_31" + description = "Expiring at midnight of 2019-12-31" + expression = "request.time < timestamp(\"2020-01-01T00:00:00Z\")" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Used to find the parent resource to bind the IAM policy to +* `parent` - (Required) The parent of the resource. Used to find the parent resource to bind the IAM policy to +* `location` - (Optional) The location of the resource. The supported locations are: global, us-central1, us-east1, us-west1, asia-east1, europe-west1. Used to find the parent resource to bind the IAM policy to. If not specified, + the value will be parsed from the identifier of the parent resource. If no location is provided in the parent identifier and no + location is specified, it is taken from the provider configuration. +* `bucket` - (Required) The bucket of the resource Used to find the parent resource to bind the IAM policy to + +* `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. + * **projectOwner:projectid**: Owners of the given project. For example, "projectOwner:my-example-project" + * **projectEditor:projectid**: Editors of the given project. For example, "projectEditor:my-example-project" + * **projectViewer:projectid**: Viewers of the given project. For example, "projectViewer:my-example-project" + +* `role` - (Required) The role that should be applied. Only one + `google_logging_log_view_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_logging_log_view_iam_policy`) The policy data generated by + a `google_iam_policy` data source. + +* `condition` - (Optional) An [IAM Condition](https://cloud.google.com/iam/docs/conditions-overview) for a given binding. + Structure is documented below. + +--- + +The `condition` block supports: + +* `expression` - (Required) Textual representation of an expression in Common Expression Language syntax. + +* `title` - (Required) A title for the expression, i.e. a short string describing its purpose. + +* `description` - (Optional) An optional description of the expression. This is a longer text which describes the expression, e.g. when hovered over it in a UI. + +~> **Warning:** Terraform considers the `role` and condition contents (`title`+`description`+`expression`) as the + identifier for the binding. This means that if any part of the condition is changed out-of-band, Terraform will + consider it to be an entirely different resource and will treat it as such. +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are +exported: + +* `etag` - (Computed) The etag of the IAM policy. + +## Import + +For all import syntaxes, the "resource in question" can take any of the following forms: + +* {{parent}}/locations/{{location}}/buckets/{{bucket}}/views/{{name}} +* {{name}} + +Any variables not passed in the import command will be taken from the provider configuration. + +Cloud (Stackdriver) Logging logview IAM resources can be imported using the resource identifiers, role, and member. + +IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g. +``` +$ terraform import google_logging_log_view_iam_member.editor "{{parent}}/locations/{{location}}/buckets/{{bucket}}/views/{{log_view}} roles/logging.admin user:jane@example.com" +``` + +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. +``` +$ terraform import google_logging_log_view_iam_binding.editor "{{parent}}/locations/{{location}}/buckets/{{bucket}}/views/{{log_view}} roles/logging.admin" +``` + +IAM policy imports use the identifier of the resource in question, e.g. +``` +$ terraform import google_logging_log_view_iam_policy.editor {{parent}}/locations/{{location}}/buckets/{{bucket}}/views/{{log_view}} +``` + +-> **Custom Roles**: If you're importing a IAM resource with a custom role, make sure to use the + full name of the custom role, e.g. `[projects/my-project|organizations/my-org]/roles/my-custom-role`.