From 0543daf8320123286e17d9f60bb43463556cd128 Mon Sep 17 00:00:00 2001 From: The Magician Date: Thu, 8 Oct 2020 13:19:15 -0700 Subject: [PATCH] fix permadiff with new access approval cloud product mappings (#4065) (#2565) Signed-off-by: Modular Magician --- .changelog/4065.txt | 3 + ...esource_access_approval_folder_settings.go | 62 +++++++++++++++---- ...e_access_approval_organization_settings.go | 4 +- ...ess_approval_organization_settings_test.go | 2 +- ...source_access_approval_project_settings.go | 4 +- ...ess_approval_folder_settings.html.markdown | 32 +++++++--- 6 files changed, 80 insertions(+), 27 deletions(-) create mode 100644 .changelog/4065.txt diff --git a/.changelog/4065.txt b/.changelog/4065.txt new file mode 100644 index 0000000000..b36ac7291f --- /dev/null +++ b/.changelog/4065.txt @@ -0,0 +1,3 @@ +```release-note:bug +accessapproval: fixed issue where, due to a recent API change, `google_*_access_approval.enrolled_services.cloud_product` entries specified as a URL would result in a permadiff +``` diff --git a/google-beta/resource_access_approval_folder_settings.go b/google-beta/resource_access_approval_folder_settings.go index fce95c0c41..0f8fdfc3d2 100644 --- a/google-beta/resource_access_approval_folder_settings.go +++ b/google-beta/resource_access_approval_folder_settings.go @@ -15,6 +15,7 @@ package google import ( + "bytes" "fmt" "log" "reflect" @@ -25,6 +26,30 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) +var accessApprovalCloudProductMapping = map[string]string{ + "appengine.googleapis.com": "App Engine", + "bigquery.googleapis.com": "BigQuery", + "bigtable.googleapis.com": "Cloud Bigtable", + "cloudkms.googleapis.com": "Cloud Key Management Service", + "compute.googleapis.com": "Compute Engine", + "dataflow.googleapis.com": "Cloud Dataflow", + "iam.googleapis.com": "Cloud Identity and Access Management", + "pubsub.googleapis.com": "Cloud Pub/Sub", + "storage.googleapis.com": "Cloud Storage", +} + +func accessApprovalEnrolledServicesHash(v interface{}) int { + var buf bytes.Buffer + m := v.(map[string]interface{}) + cp := m["cloud_product"].(string) + if n, ok := accessApprovalCloudProductMapping[cp]; ok { + cp = n + } + buf.WriteString(fmt.Sprintf("%s-", strings.ToLower(cp))) // ToLower just in case + buf.WriteString(fmt.Sprintf("%s-", strings.ToLower(m["enrollment_level"].(string)))) + return hashcode(buf.String()) +} + func resourceAccessApprovalFolderSettings() *schema.Resource { return &schema.Resource{ Create: resourceAccessApprovalFolderSettingsCreate, @@ -52,7 +77,7 @@ to have explicit approval. Enrollment can only be done on an all or nothing basi A maximum of 10 enrolled services will be enforced, to be expanded as the set of supported services is expanded.`, Elem: accessapprovalFolderSettingsEnrolledServicesSchema(), - // Default schema.HashSchema is used. + Set: accessApprovalEnrolledServicesHash, }, "folder_id": { Type: schema.TypeString, @@ -94,16 +119,29 @@ func accessapprovalFolderSettingsEnrolledServicesSchema() *schema.Resource { Type: schema.TypeString, Required: true, Description: `The product for which Access Approval will be enrolled. Allowed values are listed (case-sensitive): - all - appengine.googleapis.com - bigquery.googleapis.com - bigtable.googleapis.com - cloudkms.googleapis.com - compute.googleapis.com - dataflow.googleapis.com - iam.googleapis.com - pubsub.googleapis.com - storage.googleapis.com`, + * all + * App Engine + * BigQuery + * Cloud Bigtable + * Cloud Key Management Service + * Compute Engine + * Cloud Dataflow + * Cloud Identity and Access Management + * Cloud Pub/Sub + * Cloud Storage + * Persistent Disk + +Note: These values are supported as input, but considered a legacy format: + * all + * appengine.googleapis.com + * bigquery.googleapis.com + * bigtable.googleapis.com + * cloudkms.googleapis.com + * compute.googleapis.com + * dataflow.googleapis.com + * iam.googleapis.com + * pubsub.googleapis.com + * storage.googleapis.com`, }, "enrollment_level": { Type: schema.TypeString, @@ -363,7 +401,7 @@ func flattenAccessApprovalFolderSettingsEnrolledServices(v interface{}, d *schem return v } l := v.([]interface{}) - transformed := schema.NewSet(schema.HashResource(accessapprovalFolderSettingsEnrolledServicesSchema()), []interface{}{}) + transformed := schema.NewSet(accessApprovalEnrolledServicesHash, []interface{}{}) for _, raw := range l { original := raw.(map[string]interface{}) if len(original) < 1 { diff --git a/google-beta/resource_access_approval_organization_settings.go b/google-beta/resource_access_approval_organization_settings.go index 0e898ac1cc..7b16b3e235 100644 --- a/google-beta/resource_access_approval_organization_settings.go +++ b/google-beta/resource_access_approval_organization_settings.go @@ -52,7 +52,7 @@ to have explicit approval. Enrollment can be done for individual services. A maximum of 10 enrolled services will be enforced, to be expanded as the set of supported services is expanded.`, Elem: accessapprovalOrganizationSettingsEnrolledServicesSchema(), - // Default schema.HashSchema is used. + Set: accessApprovalEnrolledServicesHash, }, "organization_id": { Type: schema.TypeString, @@ -363,7 +363,7 @@ func flattenAccessApprovalOrganizationSettingsEnrolledServices(v interface{}, d return v } l := v.([]interface{}) - transformed := schema.NewSet(schema.HashResource(accessapprovalOrganizationSettingsEnrolledServicesSchema()), []interface{}{}) + transformed := schema.NewSet(accessApprovalEnrolledServicesHash, []interface{}{}) for _, raw := range l { original := raw.(map[string]interface{}) if len(original) < 1 { diff --git a/google-beta/resource_access_approval_organization_settings_test.go b/google-beta/resource_access_approval_organization_settings_test.go index fc2d4ae4bf..fc3f2c5f8d 100644 --- a/google-beta/resource_access_approval_organization_settings_test.go +++ b/google-beta/resource_access_approval_organization_settings_test.go @@ -51,7 +51,7 @@ resource "google_organization_access_approval_settings" "organization_access_app notification_emails = ["testuser@example.com"] enrolled_services { - cloud_product = "appengine.googleapis.com" + cloud_product = "App Engine" } enrolled_services { diff --git a/google-beta/resource_access_approval_project_settings.go b/google-beta/resource_access_approval_project_settings.go index 3150141a6e..6a3a216f00 100644 --- a/google-beta/resource_access_approval_project_settings.go +++ b/google-beta/resource_access_approval_project_settings.go @@ -52,7 +52,7 @@ to have explicit approval. Enrollment can only be done on an all or nothing basi A maximum of 10 enrolled services will be enforced, to be expanded as the set of supported services is expanded.`, Elem: accessapprovalProjectSettingsEnrolledServicesSchema(), - // Default schema.HashSchema is used. + Set: accessApprovalEnrolledServicesHash, }, "project_id": { Type: schema.TypeString, @@ -391,7 +391,7 @@ func flattenAccessApprovalProjectSettingsEnrolledServices(v interface{}, d *sche return v } l := v.([]interface{}) - transformed := schema.NewSet(schema.HashResource(accessapprovalProjectSettingsEnrolledServicesSchema()), []interface{}{}) + transformed := schema.NewSet(accessApprovalEnrolledServicesHash, []interface{}{}) for _, raw := range l { original := raw.(map[string]interface{}) if len(original) < 1 { diff --git a/website/docs/r/access_approval_folder_settings.html.markdown b/website/docs/r/access_approval_folder_settings.html.markdown index 073fa1ab6c..82b96426f2 100644 --- a/website/docs/r/access_approval_folder_settings.html.markdown +++ b/website/docs/r/access_approval_folder_settings.html.markdown @@ -71,16 +71,28 @@ The `enrolled_services` block supports: * `cloud_product` - (Required) The product for which Access Approval will be enrolled. Allowed values are listed (case-sensitive): - all - appengine.googleapis.com - bigquery.googleapis.com - bigtable.googleapis.com - cloudkms.googleapis.com - compute.googleapis.com - dataflow.googleapis.com - iam.googleapis.com - pubsub.googleapis.com - storage.googleapis.com + * all + * App Engine + * BigQuery + * Cloud Bigtable + * Cloud Key Management Service + * Compute Engine + * Cloud Dataflow + * Cloud Identity and Access Management + * Cloud Pub/Sub + * Cloud Storage + * Persistent Disk + Note: These values are supported as input, but considered a legacy format: + * all + * appengine.googleapis.com + * bigquery.googleapis.com + * bigtable.googleapis.com + * cloudkms.googleapis.com + * compute.googleapis.com + * dataflow.googleapis.com + * iam.googleapis.com + * pubsub.googleapis.com + * storage.googleapis.com * `enrollment_level` - (Optional)