From 61fcf428b0c1596b03133bfdd640b9943564f196 Mon Sep 17 00:00:00 2001 From: Zhenhua Li Date: Wed, 10 Apr 2024 11:57:14 -0700 Subject: [PATCH] Show diff for computed nested labels fields when creating resources (#10401) --- .../resource_cloud_run_service_test.go.erb | 70 +++++++++++++++++++ .../terraform/tpgresource/annotations.go | 10 +++ .../terraform/tpgresource/labels.go | 10 +++ 3 files changed, 90 insertions(+) diff --git a/mmv1/third_party/terraform/services/cloudrun/resource_cloud_run_service_test.go.erb b/mmv1/third_party/terraform/services/cloudrun/resource_cloud_run_service_test.go.erb index e73d70762477..0ffb06087aeb 100644 --- a/mmv1/third_party/terraform/services/cloudrun/resource_cloud_run_service_test.go.erb +++ b/mmv1/third_party/terraform/services/cloudrun/resource_cloud_run_service_test.go.erb @@ -554,6 +554,76 @@ func TestAccCloudRunServiceMigration_withLabels(t *testing.T) { }) } +func TestAccCloudRunService_withComputedLabels(t *testing.T) { + // Skip it in VCR test because of the randomness of uuid in "labels" field + // which causes the replaying mode after recording mode failing in VCR test + acctest.SkipIfVcr(t) + t.Parallel() + + name := "tftest-cloudrun-" + acctest.RandString(t, 6) + project := envvar.GetTestProjectFromEnv() + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ExternalProviders: map[string]resource.ExternalProvider{ + "random": {}, + }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccCloudRunService_withComputedLabels(name, project, "10", "600"), + }, + { + ResourceName: "google_cloud_run_service.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"metadata.0.resource_version", "metadata.0.annotations", "metadata.0.labels", "metadata.0.terraform_labels", "status.0.conditions"}, + }, + }, + }) +} + +func testAccCloudRunService_withComputedLabels(name, project, concurrency, timeoutSeconds string) string { + return fmt.Sprintf(` +resource "random_uuid" "test" { +} + +resource "google_cloud_run_service" "default" { + name = "%s" + location = "us-central1" + + metadata { + namespace = "%s" + annotations = { + env = "${random_uuid.test.result}" + } + labels = { + key1 = "${random_uuid.test.result}" + } + } + + template { + spec { + containers { + image = "gcr.io/cloudrun/hello" + ports { + container_port = 8080 + } + } + container_concurrency = %s + timeout_seconds = %s + } + } + + traffic { + percent = 100 + latest_revision = true + tag = "magic-module" + } +} +`, name, project, concurrency, timeoutSeconds) +} + func testAccCloudRunService_withProviderDefaultLabels(context map[string]interface{}) string { return acctest.Nprintf(` provider "google" { diff --git a/mmv1/third_party/terraform/tpgresource/annotations.go b/mmv1/third_party/terraform/tpgresource/annotations.go index d43d608d16de..1f93dcfac94b 100644 --- a/mmv1/third_party/terraform/tpgresource/annotations.go +++ b/mmv1/third_party/terraform/tpgresource/annotations.go @@ -52,6 +52,16 @@ func SetMetadataAnnotationsDiff(_ context.Context, d *schema.ResourceDiff, meta return nil } + // Fix the bug that the computed and nested "annotations" field disappears from the terraform plan. + // https://github.com/hashicorp/terraform-provider-google/issues/17756 + // The bug is introduced by SetNew on "metadata" field with the object including "effective_annotations". + // "effective_annotations" cannot be set directly due to a bug that SetNew doesn't work on nested fields + // in terraform sdk. + // https://github.com/hashicorp/terraform-plugin-sdk/issues/459 + if !d.GetRawPlan().GetAttr("metadata").AsValueSlice()[0].GetAttr("annotations").IsWhollyKnown() { + return nil + } + raw := d.Get("metadata.0.annotations") if raw == nil { return nil diff --git a/mmv1/third_party/terraform/tpgresource/labels.go b/mmv1/third_party/terraform/tpgresource/labels.go index 5cfaa93ef41a..a9e01442819a 100644 --- a/mmv1/third_party/terraform/tpgresource/labels.go +++ b/mmv1/third_party/terraform/tpgresource/labels.go @@ -137,6 +137,16 @@ func SetMetadataLabelsDiff(_ context.Context, d *schema.ResourceDiff, meta inter return nil } + // Fix the bug that the computed and nested "labels" field disappears from the terraform plan. + // https://github.com/hashicorp/terraform-provider-google/issues/17756 + // The bug is introduced by SetNew on "metadata" field with the object including terraform_labels and effective_labels. + // "terraform_labels" and "effective_labels" cannot be set directly due to a bug that SetNew doesn't work on nested fields + // in terraform sdk. + // https://github.com/hashicorp/terraform-plugin-sdk/issues/459 + if !d.GetRawPlan().GetAttr("metadata").AsValueSlice()[0].GetAttr("labels").IsWhollyKnown() { + return nil + } + raw := d.Get("metadata.0.labels") if raw == nil { return nil