diff --git a/provider/labels.go b/provider/labels.go index debe79eee2..7d66df1227 100644 --- a/provider/labels.go +++ b/provider/labels.go @@ -24,6 +24,11 @@ func fixEmptyLabels(_ context.Context, req shimv2.PlanStateEditRequest) (cty.Val // effective_labels can include labels read from the cloud provider. programLabels := property.Map{} + labelsPropertyName := "labels" + if req.TfToken == "google_container_cluster" { + labelsPropertyName = "resourceLabels" + } + // Apply default labels first. if pConfig := resource.FromResourcePropertyValue(resource.NewProperty(req.ProviderConfig)); pConfig.IsMap() { l := pConfig.AsMap()["defaultLabels"] @@ -33,7 +38,7 @@ func fixEmptyLabels(_ context.Context, req shimv2.PlanStateEditRequest) (cty.Val } // Apply labels next, allowing labels to override defaultLabels. - if inputs, ok := (resource.PropertyPath{"labels"}.Get(resource.NewProperty(req.NewInputs))); ok { + if inputs, ok := (resource.PropertyPath{labelsPropertyName}.Get(resource.NewProperty(req.NewInputs))); ok { if labels := resource.FromResourcePropertyValue(inputs); labels.IsMap() { for k, v := range labels.AsMap() { programLabels[k] = v diff --git a/provider/provider_yaml_test.go b/provider/provider_yaml_test.go index 0167163ecd..3c6c41d325 100644 --- a/provider/provider_yaml_test.go +++ b/provider/provider_yaml_test.go @@ -1132,28 +1132,10 @@ func TestFirestoreDatabaseAutoname(t *testing.T) { func TestEmptyLabels(t *testing.T) { tests := []struct { - program string - previewStdout autogold.Value - upOutputs autogold.Value + program string + upOutputs autogold.Value }{ - {"empty-label", autogold.Expect(`Previewing update (test): - - + pulumi:pulumi:Stack empty-label-test create - + gcp:kms:KeyRing ring create - + gcp:kms:CryptoKey key create - + pulumi:pulumi:Stack empty-label-test create -Outputs: - effectiveLabels: [secret] - labels : { - empty : "" - static: "value" - } - pulumiLabels : [secret] - -Resources: - + 3 to create - -`), autogold.Expect(auto.OutputMap{ + {"empty-label", autogold.Expect(auto.OutputMap{ "effectiveLabels": auto.OutputValue{ Value: map[string]interface{}{ "empty": "", @@ -1175,23 +1157,7 @@ Resources: Secret: true, }, })}, - {"empty-alone-label", autogold.Expect(`Previewing update (test): - - + pulumi:pulumi:Stack empty-alone-label-test create - + gcp:kms:KeyRing ring create - + gcp:kms:CryptoKey key create - + pulumi:pulumi:Stack empty-alone-label-test create -Outputs: - effectiveLabels: [secret] - labels : { - empty: "" - } - pulumiLabels : [secret] - -Resources: - + 3 to create - -`), autogold.Expect(auto.OutputMap{ + {"empty-alone-label", autogold.Expect(auto.OutputMap{ "effectiveLabels": auto.OutputValue{ Value: map[string]interface{}{ "empty": "", @@ -1208,23 +1174,7 @@ Resources: Secret: true, }, })}, - {"empty-default-label", autogold.Expect(`Previewing update (test): - - + pulumi:pulumi:Stack empty-default-label-test create - + gcp:kms:KeyRing ring create - + gcp:kms:CryptoKey key create - + pulumi:pulumi:Stack empty-default-label-test create -Outputs: - effectiveLabels: [secret] - labels : { - static: "value" - } - pulumiLabels : [secret] - -Resources: - + 3 to create - -`), autogold.Expect(auto.OutputMap{ + {"empty-default-label", autogold.Expect(auto.OutputMap{ "effectiveLabels": auto.OutputValue{ Value: map[string]interface{}{ "empty-default": "", @@ -1243,6 +1193,32 @@ Resources: Secret: true, }, })}, + { + // Cluster overloads the labels field and instead uses resourceLabels for GCP labels. + "empty-label-cluster", + autogold.Expect(auto.OutputMap{ + "effectiveLabels": auto.OutputValue{ + Value: map[string]interface{}{ + "environment": "dev", + "goog-pulumi-provisioned": "true", + "test": "", + }, + Secret: true, + }, + "labels": auto.OutputValue{Value: map[string]interface{}{ + "environment": "dev", + "test": "", + }}, + "pulumiLabels": auto.OutputValue{ + Value: map[string]interface{}{ + "environment": "dev", + "goog-pulumi-provisioned": "true", + "test": "", + }, + Secret: true, + }, + }), + }, } for _, tt := range tests { @@ -1253,9 +1229,6 @@ Resources: proj := getProject() pt.SetConfig("gcpProj", proj) - previewResult := pt.Preview(optpreview.SuppressProgress()) - tt.previewStdout.Equal(t, previewResult.StdOut) - upResult := pt.Up(optup.SuppressProgress()) tt.upOutputs.Equal(t, upResult.Outputs) diff --git a/provider/test-programs/empty-label-cluster/Pulumi.yaml b/provider/test-programs/empty-label-cluster/Pulumi.yaml new file mode 100644 index 0000000000..9c64157e36 --- /dev/null +++ b/provider/test-programs/empty-label-cluster/Pulumi.yaml @@ -0,0 +1,31 @@ +name: empty-label-cluster +runtime: yaml +resources: + random-account-id: + type: random:RandomString + properties: + length: 10 + special: false + upper: false + number: false + serviceAccount: + type: gcp:serviceaccount:Account + properties: + accountId: ${random-account-id.result} + primary: + type: gcp:container:Cluster + properties: + location: us-central1 + # We can't create a cluster with no node pool defined, but we want to only use + # separately managed node pools. So we create the smallest possible default + # node pool and immediately delete it. + removeDefaultNodePool: true + initialNodeCount: 1 + deletionProtection: false + resourceLabels: + environment: "dev" + test: "" +outputs: + labels: ${primary.resourceLabels} + effectiveLabels: ${primary.effectiveLabels} + pulumiLabels: ${primary.pulumiLabels}