From dbd77c9c75e2dcc8caab526977ffc72f9435a143 Mon Sep 17 00:00:00 2001 From: Modular Magician Date: Tue, 21 May 2024 14:54:56 +0000 Subject: [PATCH] adding support for Dataplex Aspect Type resource. (#10751) [upstream:ee80c09765ddd57b3dda8bf6f5cf02395c9d9dd6] Signed-off-by: Modular Magician --- google/provider/provider_mmv1_resources.go | 11 +- .../dataplex/iam_dataplex_aspect_type.go | 245 +++++++ ...iam_dataplex_aspect_type_generated_test.go | 338 ++++++++++ .../dataplex/resource_dataplex_aspect_type.go | 605 ++++++++++++++++++ ...rce_dataplex_aspect_type_generated_test.go | 304 +++++++++ .../resource_dataplex_aspect_type_sweeper.go | 143 +++++ .../resource_dataplex_aspect_type_test.go | 124 ++++ ...aplex_aspect_type_iam_policy.html.markdown | 52 ++ .../docs/r/dataplex_aspect_type.html.markdown | 316 +++++++++ .../r/dataplex_aspect_type_iam.html.markdown | 153 +++++ 10 files changed, 2288 insertions(+), 3 deletions(-) create mode 100644 google/services/dataplex/iam_dataplex_aspect_type.go create mode 100644 google/services/dataplex/iam_dataplex_aspect_type_generated_test.go create mode 100644 google/services/dataplex/resource_dataplex_aspect_type.go create mode 100644 google/services/dataplex/resource_dataplex_aspect_type_generated_test.go create mode 100644 google/services/dataplex/resource_dataplex_aspect_type_sweeper.go create mode 100644 google/services/dataplex/resource_dataplex_aspect_type_test.go create mode 100644 website/docs/d/dataplex_aspect_type_iam_policy.html.markdown create mode 100644 website/docs/r/dataplex_aspect_type.html.markdown create mode 100644 website/docs/r/dataplex_aspect_type_iam.html.markdown diff --git a/google/provider/provider_mmv1_resources.go b/google/provider/provider_mmv1_resources.go index 01b58f5d070..841cdbb35bd 100644 --- a/google/provider/provider_mmv1_resources.go +++ b/google/provider/provider_mmv1_resources.go @@ -338,6 +338,7 @@ var generatedIAMDatasources = map[string]*schema.Resource{ "google_data_catalog_tag_template_iam_policy": tpgiamresource.DataSourceIamPolicy(datacatalog.DataCatalogTagTemplateIamSchema, datacatalog.DataCatalogTagTemplateIamUpdaterProducer), "google_data_catalog_taxonomy_iam_policy": tpgiamresource.DataSourceIamPolicy(datacatalog.DataCatalogTaxonomyIamSchema, datacatalog.DataCatalogTaxonomyIamUpdaterProducer), "google_data_fusion_instance_iam_policy": tpgiamresource.DataSourceIamPolicy(datafusion.DataFusionInstanceIamSchema, datafusion.DataFusionInstanceIamUpdaterProducer), + "google_dataplex_aspect_type_iam_policy": tpgiamresource.DataSourceIamPolicy(dataplex.DataplexAspectTypeIamSchema, dataplex.DataplexAspectTypeIamUpdaterProducer), "google_dataplex_asset_iam_policy": tpgiamresource.DataSourceIamPolicy(dataplex.DataplexAssetIamSchema, dataplex.DataplexAssetIamUpdaterProducer), "google_dataplex_datascan_iam_policy": tpgiamresource.DataSourceIamPolicy(dataplex.DataplexDatascanIamSchema, dataplex.DataplexDatascanIamUpdaterProducer), "google_dataplex_entry_group_iam_policy": tpgiamresource.DataSourceIamPolicy(dataplex.DataplexEntryGroupIamSchema, dataplex.DataplexEntryGroupIamUpdaterProducer), @@ -409,9 +410,9 @@ var handwrittenIAMDatasources = map[string]*schema.Resource{ } // Resources -// Generated resources: 415 -// Generated IAM resources: 240 -// Total generated resources: 655 +// Generated resources: 416 +// Generated IAM resources: 243 +// Total generated resources: 659 var generatedResources = map[string]*schema.Resource{ "google_folder_access_approval_settings": accessapproval.ResourceAccessApprovalFolderSettings(), "google_organization_access_approval_settings": accessapproval.ResourceAccessApprovalOrganizationSettings(), @@ -698,6 +699,10 @@ var generatedResources = map[string]*schema.Resource{ "google_data_loss_prevention_job_trigger": datalossprevention.ResourceDataLossPreventionJobTrigger(), "google_data_loss_prevention_stored_info_type": datalossprevention.ResourceDataLossPreventionStoredInfoType(), "google_data_pipeline_pipeline": datapipeline.ResourceDataPipelinePipeline(), + "google_dataplex_aspect_type": dataplex.ResourceDataplexAspectType(), + "google_dataplex_aspect_type_iam_binding": tpgiamresource.ResourceIamBinding(dataplex.DataplexAspectTypeIamSchema, dataplex.DataplexAspectTypeIamUpdaterProducer, dataplex.DataplexAspectTypeIdParseFunc), + "google_dataplex_aspect_type_iam_member": tpgiamresource.ResourceIamMember(dataplex.DataplexAspectTypeIamSchema, dataplex.DataplexAspectTypeIamUpdaterProducer, dataplex.DataplexAspectTypeIdParseFunc), + "google_dataplex_aspect_type_iam_policy": tpgiamresource.ResourceIamPolicy(dataplex.DataplexAspectTypeIamSchema, dataplex.DataplexAspectTypeIamUpdaterProducer, dataplex.DataplexAspectTypeIdParseFunc), "google_dataplex_asset_iam_binding": tpgiamresource.ResourceIamBinding(dataplex.DataplexAssetIamSchema, dataplex.DataplexAssetIamUpdaterProducer, dataplex.DataplexAssetIdParseFunc), "google_dataplex_asset_iam_member": tpgiamresource.ResourceIamMember(dataplex.DataplexAssetIamSchema, dataplex.DataplexAssetIamUpdaterProducer, dataplex.DataplexAssetIdParseFunc), "google_dataplex_asset_iam_policy": tpgiamresource.ResourceIamPolicy(dataplex.DataplexAssetIamSchema, dataplex.DataplexAssetIamUpdaterProducer, dataplex.DataplexAssetIdParseFunc), diff --git a/google/services/dataplex/iam_dataplex_aspect_type.go b/google/services/dataplex/iam_dataplex_aspect_type.go new file mode 100644 index 00000000000..d2c2fa59997 --- /dev/null +++ b/google/services/dataplex/iam_dataplex_aspect_type.go @@ -0,0 +1,245 @@ +// 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 dataplex + +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/google/tpgiamresource" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +var DataplexAspectTypeIamSchema = map[string]*schema.Schema{ + "project": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + }, + "location": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + }, + "aspect_type_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: tpgresource.CompareSelfLinkOrResourceName, + }, +} + +type DataplexAspectTypeIamUpdater struct { + project string + location string + aspectTypeId string + d tpgresource.TerraformResourceData + Config *transport_tpg.Config +} + +func DataplexAspectTypeIamUpdaterProducer(d tpgresource.TerraformResourceData, config *transport_tpg.Config) (tpgiamresource.ResourceIamUpdater, error) { + values := make(map[string]string) + + project, _ := tpgresource.GetProject(d, config) + if project != "" { + if err := d.Set("project", project); err != nil { + return nil, fmt.Errorf("Error setting project: %s", err) + } + } + values["project"] = project + 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("aspect_type_id"); ok { + values["aspect_type_id"] = 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{"projects/(?P[^/]+)/locations/(?P[^/]+)/aspectTypes/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Get("aspect_type_id").(string)) + if err != nil { + return nil, err + } + + for k, v := range m { + values[k] = v + } + + u := &DataplexAspectTypeIamUpdater{ + project: values["project"], + location: values["location"], + aspectTypeId: values["aspect_type_id"], + d: d, + Config: config, + } + + if err := d.Set("project", u.project); err != nil { + return nil, fmt.Errorf("Error setting project: %s", err) + } + if err := d.Set("location", u.location); err != nil { + return nil, fmt.Errorf("Error setting location: %s", err) + } + if err := d.Set("aspect_type_id", u.GetResourceId()); err != nil { + return nil, fmt.Errorf("Error setting aspect_type_id: %s", err) + } + + return u, nil +} + +func DataplexAspectTypeIdParseFunc(d *schema.ResourceData, config *transport_tpg.Config) error { + values := make(map[string]string) + + project, _ := tpgresource.GetProject(d, config) + if project != "" { + values["project"] = project + } + + location, _ := tpgresource.GetLocation(d, config) + if location != "" { + values["location"] = location + } + + m, err := tpgresource.GetImportIdQualifiers([]string{"projects/(?P[^/]+)/locations/(?P[^/]+)/aspectTypes/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config, d.Id()) + if err != nil { + return err + } + + for k, v := range m { + values[k] = v + } + + u := &DataplexAspectTypeIamUpdater{ + project: values["project"], + location: values["location"], + aspectTypeId: values["aspect_type_id"], + d: d, + Config: config, + } + if err := d.Set("aspect_type_id", u.GetResourceId()); err != nil { + return fmt.Errorf("Error setting aspect_type_id: %s", err) + } + d.SetId(u.GetResourceId()) + return nil +} + +func (u *DataplexAspectTypeIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { + url, err := u.qualifyAspectTypeUrl("getIamPolicy") + if err != nil { + return nil, err + } + + project, err := tpgresource.GetProject(u.d, u.Config) + if err != nil { + return nil, err + } + var obj map[string]interface{} + + userAgent, err := tpgresource.GenerateUserAgentString(u.d, u.Config.UserAgent) + if err != nil { + return nil, err + } + + policy, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: u.Config, + Method: "GET", + Project: project, + 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 *DataplexAspectTypeIamUpdater) 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.qualifyAspectTypeUrl("setIamPolicy") + if err != nil { + return err + } + project, err := tpgresource.GetProject(u.d, u.Config) + 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", + Project: project, + 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 *DataplexAspectTypeIamUpdater) qualifyAspectTypeUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{DataplexBasePath}}%s:%s", fmt.Sprintf("projects/%s/locations/%s/aspectTypes/%s", u.project, u.location, u.aspectTypeId), methodIdentifier) + url, err := tpgresource.ReplaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil +} + +func (u *DataplexAspectTypeIamUpdater) GetResourceId() string { + return fmt.Sprintf("projects/%s/locations/%s/aspectTypes/%s", u.project, u.location, u.aspectTypeId) +} + +func (u *DataplexAspectTypeIamUpdater) GetMutexKey() string { + return fmt.Sprintf("iam-dataplex-aspecttype-%s", u.GetResourceId()) +} + +func (u *DataplexAspectTypeIamUpdater) DescribeResource() string { + return fmt.Sprintf("dataplex aspecttype %q", u.GetResourceId()) +} diff --git a/google/services/dataplex/iam_dataplex_aspect_type_generated_test.go b/google/services/dataplex/iam_dataplex_aspect_type_generated_test.go new file mode 100644 index 00000000000..7ddab28821e --- /dev/null +++ b/google/services/dataplex/iam_dataplex_aspect_type_generated_test.go @@ -0,0 +1,338 @@ +// 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 dataplex_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/envvar" +) + +func TestAccDataplexAspectTypeIamBindingGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + "role": "roles/viewer", + "project_name": envvar.GetTestProjectFromEnv(), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccDataplexAspectTypeIamBinding_basicGenerated(context), + }, + { + // Test Iam Binding update + Config: testAccDataplexAspectTypeIamBinding_updateGenerated(context), + }, + }, + }) +} + +func TestAccDataplexAspectTypeIamMemberGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + "role": "roles/viewer", + "project_name": envvar.GetTestProjectFromEnv(), + } + + 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: testAccDataplexAspectTypeIamMember_basicGenerated(context), + }, + }, + }) +} + +func TestAccDataplexAspectTypeIamPolicyGenerated(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + "role": "roles/viewer", + "project_name": envvar.GetTestProjectFromEnv(), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccDataplexAspectTypeIamPolicy_basicGenerated(context), + Check: resource.TestCheckResourceAttrSet("data.google_dataplex_aspect_type_iam_policy.foo", "policy_data"), + }, + { + Config: testAccDataplexAspectTypeIamPolicy_emptyBinding(context), + }, + }, + }) +} + +func testAccDataplexAspectTypeIamMember_basicGenerated(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_dataplex_aspect_type" "test_aspect_type_basic" { + aspect_type_id = "tf-test-aspect-type-basic%{random_suffix}" + project = "%{project_name}" + location = "us-central1" + + metadata_template = < 0 { + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "PATCH", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutUpdate), + Headers: headers, + }) + + if err != nil { + return fmt.Errorf("Error updating AspectType %q: %s", d.Id(), err) + } else { + log.Printf("[DEBUG] Finished updating AspectType %q: %#v", d.Id(), res) + } + + err = DataplexOperationWaitTime( + config, res, project, "Updating AspectType", userAgent, + d.Timeout(schema.TimeoutUpdate)) + + if err != nil { + return err + } + } + + return resourceDataplexAspectTypeRead(d, meta) +} + +func resourceDataplexAspectTypeDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for AspectType: %s", err) + } + billingProject = project + + url, err := tpgresource.ReplaceVars(d, config, "{{DataplexBasePath}}projects/{{project}}/locations/{{location}}/aspectTypes/{{aspect_type_id}}") + if err != nil { + return err + } + + var obj map[string]interface{} + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + headers := make(http.Header) + + log.Printf("[DEBUG] Deleting AspectType %q", d.Id()) + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "DELETE", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutDelete), + Headers: headers, + }) + if err != nil { + return transport_tpg.HandleNotFoundError(err, d, "AspectType") + } + + err = DataplexOperationWaitTime( + config, res, project, "Deleting AspectType", userAgent, + d.Timeout(schema.TimeoutDelete)) + + if err != nil { + return err + } + + log.Printf("[DEBUG] Finished deleting AspectType %q: %#v", d.Id(), res) + return nil +} + +func resourceDataplexAspectTypeImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*transport_tpg.Config) + if err := tpgresource.ParseImportId([]string{ + "^projects/(?P[^/]+)/locations/(?P[^/]+)/aspectTypes/(?P[^/]+)$", + "^(?P[^/]+)/(?P[^/]+)/(?P[^/]+)$", + "^(?P[^/]+)/(?P[^/]+)$", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/aspectTypes/{{aspect_type_id}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenDataplexAspectTypeName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenDataplexAspectTypeUid(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenDataplexAspectTypeCreateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenDataplexAspectTypeUpdateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenDataplexAspectTypeDescription(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenDataplexAspectTypeDisplayName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenDataplexAspectTypeLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + + transformed := make(map[string]interface{}) + if l, ok := d.GetOkExists("labels"); ok { + for k := range l.(map[string]interface{}) { + transformed[k] = v.(map[string]interface{})[k] + } + } + + return transformed +} + +func flattenDataplexAspectTypeMetadataTemplate(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + b, err := json.Marshal(v) + if err != nil { + // TODO: return error once https://github.com/GoogleCloudPlatform/magic-modules/issues/3257 is fixed. + log.Printf("[ERROR] failed to marshal schema to JSON: %v", err) + } + return string(b) +} + +func flattenDataplexAspectTypeTransferStatus(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenDataplexAspectTypeTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + + transformed := make(map[string]interface{}) + if l, ok := d.GetOkExists("terraform_labels"); ok { + for k := range l.(map[string]interface{}) { + transformed[k] = v.(map[string]interface{})[k] + } + } + + return transformed +} + +func flattenDataplexAspectTypeEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func expandDataplexAspectTypeDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandDataplexAspectTypeDisplayName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandDataplexAspectTypeMetadataTemplate(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + b := []byte(v.(string)) + if len(b) == 0 { + return nil, nil + } + m := make(map[string]interface{}) + if err := json.Unmarshal(b, &m); err != nil { + return nil, err + } + return m, nil +} + +func expandDataplexAspectTypeEffectiveLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} diff --git a/google/services/dataplex/resource_dataplex_aspect_type_generated_test.go b/google/services/dataplex/resource_dataplex_aspect_type_generated_test.go new file mode 100644 index 00000000000..3b6397d8af0 --- /dev/null +++ b/google/services/dataplex/resource_dataplex_aspect_type_generated_test.go @@ -0,0 +1,304 @@ +// 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 dataplex_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/envvar" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func TestAccDataplexAspectType_dataplexAspectTypeBasicExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "project_name": envvar.GetTestProjectFromEnv(), + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckDataplexAspectTypeDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccDataplexAspectType_dataplexAspectTypeBasicExample(context), + }, + { + ResourceName: "google_dataplex_aspect_type.test_aspect_type_basic", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"aspect_type_id", "labels", "location", "terraform_labels"}, + }, + }, + }) +} + +func testAccDataplexAspectType_dataplexAspectTypeBasicExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_dataplex_aspect_type" "test_aspect_type_basic" { + aspect_type_id = "tf-test-aspect-type-basic%{random_suffix}" + project = "%{project_name}" + location = "us-central1" + + metadata_template = < 0 { + log.Printf("[INFO][SWEEPER_LOG] %d items were non-sweepable and skipped.", nonPrefixCount) + } + + return nil +} diff --git a/google/services/dataplex/resource_dataplex_aspect_type_test.go b/google/services/dataplex/resource_dataplex_aspect_type_test.go new file mode 100644 index 00000000000..ff5137fe61d --- /dev/null +++ b/google/services/dataplex/resource_dataplex_aspect_type_test.go @@ -0,0 +1,124 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 +package dataplex_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/envvar" +) + +func TestAccDataplexAspectType_update(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "project_name": envvar.GetTestProjectFromEnv(), + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckDataplexAspectTypeDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccDataplexAspectType_full(context), + }, + { + ResourceName: "google_dataplex_aspect_type.test_aspect_type", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"aspect_type_id", "labels", "location", "terraform_labels"}, + }, + { + Config: testAccDataplexAspectType_update(context), + }, + { + ResourceName: "google_dataplex_aspect_type.test_aspect_type", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"aspect_type_id", "labels", "location", "terraform_labels"}, + }, + }, + }) +} + +func testAccDataplexAspectType_full(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_dataplex_aspect_type" "test_aspect_type" { + aspect_type_id = "tf-test-aspect-type%{random_suffix}" + project = "%{project_name}" + location = "us-central1" + + metadata_template = < **Note:** `google_dataplex_aspect_type_iam_policy` **cannot** be used in conjunction with `google_dataplex_aspect_type_iam_binding` and `google_dataplex_aspect_type_iam_member` or they will fight over what your policy should be. + +~> **Note:** `google_dataplex_aspect_type_iam_binding` resources **can be** used in conjunction with `google_dataplex_aspect_type_iam_member` resources **only if** they do not grant privilege to the same role. + + + +## google_dataplex_aspect_type_iam_policy + +```hcl +data "google_iam_policy" "admin" { + binding { + role = "roles/viewer" + members = [ + "user:jane@example.com", + ] + } +} + +resource "google_dataplex_aspect_type_iam_policy" "policy" { + project = google_dataplex_aspect_type.test_aspect_type_basic.project + location = google_dataplex_aspect_type.test_aspect_type_basic.location + aspect_type_id = google_dataplex_aspect_type.test_aspect_type_basic.aspect_type_id + policy_data = data.google_iam_policy.admin.policy_data +} +``` + +## google_dataplex_aspect_type_iam_binding + +```hcl +resource "google_dataplex_aspect_type_iam_binding" "binding" { + project = google_dataplex_aspect_type.test_aspect_type_basic.project + location = google_dataplex_aspect_type.test_aspect_type_basic.location + aspect_type_id = google_dataplex_aspect_type.test_aspect_type_basic.aspect_type_id + role = "roles/viewer" + members = [ + "user:jane@example.com", + ] +} +``` + +## google_dataplex_aspect_type_iam_member + +```hcl +resource "google_dataplex_aspect_type_iam_member" "member" { + project = google_dataplex_aspect_type.test_aspect_type_basic.project + location = google_dataplex_aspect_type.test_aspect_type_basic.location + aspect_type_id = google_dataplex_aspect_type.test_aspect_type_basic.aspect_type_id + role = "roles/viewer" + member = "user:jane@example.com" +} +``` + + +## Argument Reference + +The following arguments are supported: + +* `location` - (Required) The location where aspect type will be created in. + 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. + * **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_dataplex_aspect_type_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_dataplex_aspect_type_iam_policy`) The policy data generated by + a `google_iam_policy` data source. + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are +exported: + +* `etag` - (Computed) The etag of the IAM policy. + +## Import + +For all import syntaxes, the "resource in question" can take any of the following forms: + +* projects/{{project}}/locations/{{location}}/aspectTypes/{{aspect_type_id}} +* {{project}}/{{location}}/{{aspect_type_id}} +* {{location}}/{{aspect_type_id}} +* {{aspect_type_id}} + +Any variables not passed in the import command will be taken from the provider configuration. + +Dataplex aspecttype 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_dataplex_aspect_type_iam_member.editor "projects/{{project}}/locations/{{location}}/aspectTypes/{{aspect_type_id}} roles/viewer user:jane@example.com" +``` + +IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g. +``` +$ terraform import google_dataplex_aspect_type_iam_binding.editor "projects/{{project}}/locations/{{location}}/aspectTypes/{{aspect_type_id}} roles/viewer" +``` + +IAM policy imports use the identifier of the resource in question, e.g. +``` +$ terraform import google_dataplex_aspect_type_iam_policy.editor projects/{{project}}/locations/{{location}}/aspectTypes/{{aspect_type_id}} +``` + +-> **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`. + +## User Project Overrides + +This resource supports [User Project Overrides](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference#user_project_override).