diff --git a/.changelog/8950.txt b/.changelog/8950.txt new file mode 100644 index 00000000000..8ec013c0699 --- /dev/null +++ b/.changelog/8950.txt @@ -0,0 +1,3 @@ +```release-note:none + +``` diff --git a/google/acctest/test_utils.go b/google/acctest/test_utils.go index c6055045aa0..cac1ed64fc4 100644 --- a/google/acctest/test_utils.go +++ b/google/acctest/test_utils.go @@ -50,6 +50,12 @@ func CheckDataSourceStateMatchesResourceStateWithIgnores(dataSourceName, resourc if _, ok := ignoreFields[k]; ok { continue } + if _, ok := ignoreFields["labels.%"]; ok && strings.HasPrefix(k, "labels.") { + continue + } + if _, ok := ignoreFields["terraform_labels.%"]; ok && strings.HasPrefix(k, "terraform_labels.") { + continue + } if k == "%" { continue } diff --git a/google/services/activedirectory/resource_active_directory_domain.go b/google/services/activedirectory/resource_active_directory_domain.go index 85e34438e63..417affb1f21 100644 --- a/google/services/activedirectory/resource_active_directory_domain.go +++ b/google/services/activedirectory/resource_active_directory_domain.go @@ -50,6 +50,7 @@ func ResourceActiveDirectoryDomain() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -102,6 +103,12 @@ If CIDR subnets overlap between networks, domain creation will fail.`, Description: `Resource labels that can contain user-provided metadata`, Elem: &schema.Schema{Type: schema.TypeString}, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "fqdn": { Type: schema.TypeString, Computed: true, @@ -113,6 +120,13 @@ Similar to what would be chosen for an Active Directory set up on an internal ne Computed: true, Description: `The unique name of the domain using the format: 'projects/{project}/locations/global/domains/{domainName}'.`, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "project": { Type: schema.TypeString, Optional: true, @@ -132,12 +146,6 @@ func resourceActiveDirectoryDomainCreate(d *schema.ResourceData, meta interface{ } obj := make(map[string]interface{}) - labelsProp, err := expandActiveDirectoryDomainLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } authorizedNetworksProp, err := expandActiveDirectoryDomainAuthorizedNetworks(d.Get("authorized_networks"), d, config) if err != nil { return err @@ -162,6 +170,12 @@ func resourceActiveDirectoryDomainCreate(d *schema.ResourceData, meta interface{ } else if v, ok := d.GetOkExists("admin"); !tpgresource.IsEmptyValue(reflect.ValueOf(adminProp)) && (ok || !reflect.DeepEqual(v, adminProp)) { obj["admin"] = adminProp } + labelsProp, err := expandActiveDirectoryDomainEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{ActiveDirectoryBasePath}}projects/{{project}}/locations/global/domains?domainName={{domain_name}}") if err != nil { @@ -294,6 +308,12 @@ func resourceActiveDirectoryDomainRead(d *schema.ResourceData, meta interface{}) if err := d.Set("fqdn", flattenActiveDirectoryDomainFqdn(res["fqdn"], d, config)); err != nil { return fmt.Errorf("Error reading Domain: %s", err) } + if err := d.Set("terraform_labels", flattenActiveDirectoryDomainTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Domain: %s", err) + } + if err := d.Set("effective_labels", flattenActiveDirectoryDomainEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Domain: %s", err) + } return nil } @@ -314,12 +334,6 @@ func resourceActiveDirectoryDomainUpdate(d *schema.ResourceData, meta interface{ billingProject = project obj := make(map[string]interface{}) - labelsProp, err := expandActiveDirectoryDomainLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } authorizedNetworksProp, err := expandActiveDirectoryDomainAuthorizedNetworks(d.Get("authorized_networks"), d, config) if err != nil { return err @@ -332,6 +346,12 @@ func resourceActiveDirectoryDomainUpdate(d *schema.ResourceData, meta interface{ } else if v, ok := d.GetOkExists("locations"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, locationsProp)) { obj["locations"] = locationsProp } + labelsProp, err := expandActiveDirectoryDomainEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{ActiveDirectoryBasePath}}{{name}}") if err != nil { @@ -341,10 +361,6 @@ func resourceActiveDirectoryDomainUpdate(d *schema.ResourceData, meta interface{ log.Printf("[DEBUG] Updating Domain %q: %#v", d.Id(), obj) updateMask := []string{} - if d.HasChange("labels") { - updateMask = append(updateMask, "labels") - } - if d.HasChange("authorized_networks") { updateMask = append(updateMask, "authorizedNetworks") } @@ -352,6 +368,10 @@ func resourceActiveDirectoryDomainUpdate(d *schema.ResourceData, meta interface{ if d.HasChange("locations") { updateMask = append(updateMask, "locations") } + + if d.HasChange("effective_labels") { + updateMask = append(updateMask, "labels") + } // updateMask is a URL parameter but not present in the schema, so ReplaceVars // won't set it url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -463,7 +483,18 @@ func flattenActiveDirectoryDomainName(v interface{}, d *schema.ResourceData, con } func flattenActiveDirectoryDomainLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenActiveDirectoryDomainAuthorizedNetworks(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -489,15 +520,23 @@ func flattenActiveDirectoryDomainFqdn(v interface{}, d *schema.ResourceData, con return v } -func expandActiveDirectoryDomainLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func flattenActiveDirectoryDomainTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { - return map[string]string{}, nil + return v } - m := make(map[string]string) - for k, val := range v.(map[string]interface{}) { - m[k] = val.(string) + + 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 m, nil + + return transformed +} + +func flattenActiveDirectoryDomainEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v } func expandActiveDirectoryDomainAuthorizedNetworks(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { @@ -516,3 +555,14 @@ func expandActiveDirectoryDomainLocations(v interface{}, d tpgresource.Terraform func expandActiveDirectoryDomainAdmin(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } + +func expandActiveDirectoryDomainEffectiveLabels(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/activedirectory/resource_active_directory_domain_update_test.go b/google/services/activedirectory/resource_active_directory_domain_update_test.go index ebc3d6aa1c4..5ca49632f78 100644 --- a/google/services/activedirectory/resource_active_directory_domain_update_test.go +++ b/google/services/activedirectory/resource_active_directory_domain_update_test.go @@ -41,7 +41,7 @@ func TestAccActiveDirectoryDomain_update(t *testing.T) { ResourceName: resourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"domain_name"}, + ImportStateVerifyIgnore: []string{"domain_name", "labels", "terraform_labels"}, }, { Config: testAccADDomainUpdate(context), @@ -50,7 +50,7 @@ func TestAccActiveDirectoryDomain_update(t *testing.T) { ResourceName: resourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"domain_name"}, + ImportStateVerifyIgnore: []string{"domain_name", "labels", "terraform_labels"}, }, { Config: testAccADDomainBasic(context), @@ -59,7 +59,7 @@ func TestAccActiveDirectoryDomain_update(t *testing.T) { ResourceName: resourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"domain_name"}, + ImportStateVerifyIgnore: []string{"domain_name", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/alloydb/resource_alloydb_backup.go b/google/services/alloydb/resource_alloydb_backup.go index 7d5a883a648..62e4c4ca16a 100644 --- a/google/services/alloydb/resource_alloydb_backup.go +++ b/google/services/alloydb/resource_alloydb_backup.go @@ -49,6 +49,7 @@ func ResourceAlloydbBackup() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -105,6 +106,12 @@ func ResourceAlloydbBackup() *schema.Resource { Computed: true, Description: `Time the Backup was created in UTC.`, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "encryption_info": { Type: schema.TypeList, Computed: true, @@ -147,6 +154,13 @@ func ResourceAlloydbBackup() *schema.Resource { Computed: true, Description: `The current state of the backup.`, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "uid": { Type: schema.TypeString, Computed: true, @@ -182,12 +196,6 @@ func resourceAlloydbBackupCreate(d *schema.ResourceData, meta interface{}) error } else if v, ok := d.GetOkExists("cluster_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(clusterNameProp)) && (ok || !reflect.DeepEqual(v, clusterNameProp)) { obj["clusterName"] = clusterNameProp } - labelsProp, err := expandAlloydbBackupLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } descriptionProp, err := expandAlloydbBackupDescription(d.Get("description"), d, config) if err != nil { return err @@ -200,6 +208,12 @@ func resourceAlloydbBackupCreate(d *schema.ResourceData, meta interface{}) error } else if v, ok := d.GetOkExists("encryption_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(encryptionConfigProp)) && (ok || !reflect.DeepEqual(v, encryptionConfigProp)) { obj["encryptionConfig"] = encryptionConfigProp } + labelsProp, err := expandAlloydbBackupEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } obj, err = resourceAlloydbBackupEncoder(d, meta, obj) if err != nil { @@ -336,6 +350,12 @@ func resourceAlloydbBackupRead(d *schema.ResourceData, meta interface{}) error { if err := d.Set("encryption_info", flattenAlloydbBackupEncryptionInfo(res["encryptionInfo"], d, config)); err != nil { return fmt.Errorf("Error reading Backup: %s", err) } + if err := d.Set("terraform_labels", flattenAlloydbBackupTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Backup: %s", err) + } + if err := d.Set("effective_labels", flattenAlloydbBackupEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Backup: %s", err) + } return nil } @@ -356,18 +376,18 @@ func resourceAlloydbBackupUpdate(d *schema.ResourceData, meta interface{}) error billingProject = project obj := make(map[string]interface{}) - labelsProp, err := expandAlloydbBackupLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } encryptionConfigProp, err := expandAlloydbBackupEncryptionConfig(d.Get("encryption_config"), d, config) if err != nil { return err } else if v, ok := d.GetOkExists("encryption_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, encryptionConfigProp)) { obj["encryptionConfig"] = encryptionConfigProp } + labelsProp, err := expandAlloydbBackupEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } obj, err = resourceAlloydbBackupEncoder(d, meta, obj) if err != nil { @@ -382,13 +402,13 @@ func resourceAlloydbBackupUpdate(d *schema.ResourceData, meta interface{}) error log.Printf("[DEBUG] Updating Backup %q: %#v", d.Id(), obj) updateMask := []string{} - if d.HasChange("labels") { - updateMask = append(updateMask, "labels") - } - if d.HasChange("encryption_config") { updateMask = append(updateMask, "encryptionConfig") } + + if d.HasChange("effective_labels") { + updateMask = append(updateMask, "labels") + } // updateMask is a URL parameter but not present in the schema, so ReplaceVars // won't set it url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -514,7 +534,18 @@ func flattenAlloydbBackupClusterName(v interface{}, d *schema.ResourceData, conf } func flattenAlloydbBackupLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenAlloydbBackupCreateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -581,19 +612,27 @@ func flattenAlloydbBackupEncryptionInfoKmsKeyVersions(v interface{}, d *schema.R return v } -func expandAlloydbBackupClusterName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandAlloydbBackupLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func flattenAlloydbBackupTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { - return map[string]string{}, nil + return v } - m := make(map[string]string) - for k, val := range v.(map[string]interface{}) { - m[k] = val.(string) + + 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 m, nil + + return transformed +} + +func flattenAlloydbBackupEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func expandAlloydbBackupClusterName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil } func expandAlloydbBackupDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { @@ -623,6 +662,17 @@ func expandAlloydbBackupEncryptionConfigKmsKeyName(v interface{}, d tpgresource. return v, nil } +func expandAlloydbBackupEffectiveLabels(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 +} + func resourceAlloydbBackupEncoder(d *schema.ResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) { // The only other available type is AUTOMATED which cannot be set manually obj["type"] = "ON_DEMAND" diff --git a/google/services/alloydb/resource_alloydb_backup_generated_test.go b/google/services/alloydb/resource_alloydb_backup_generated_test.go index 07a79632a02..f0aa7de3000 100644 --- a/google/services/alloydb/resource_alloydb_backup_generated_test.go +++ b/google/services/alloydb/resource_alloydb_backup_generated_test.go @@ -49,7 +49,7 @@ func TestAccAlloydbBackup_alloydbBackupBasicExample(t *testing.T) { ResourceName: "google_alloydb_backup.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"backup_id", "location", "reconciling", "update_time"}, + ImportStateVerifyIgnore: []string{"backup_id", "location", "reconciling", "update_time", "labels", "terraform_labels"}, }, }, }) @@ -118,7 +118,7 @@ func TestAccAlloydbBackup_alloydbBackupFullExample(t *testing.T) { ResourceName: "google_alloydb_backup.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"backup_id", "location", "reconciling", "update_time"}, + ImportStateVerifyIgnore: []string{"backup_id", "location", "reconciling", "update_time", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/alloydb/resource_alloydb_backup_test.go b/google/services/alloydb/resource_alloydb_backup_test.go index 51eaa11676c..a57a7cd9f67 100644 --- a/google/services/alloydb/resource_alloydb_backup_test.go +++ b/google/services/alloydb/resource_alloydb_backup_test.go @@ -30,7 +30,7 @@ func TestAccAlloydbBackup_update(t *testing.T) { ResourceName: "google_alloydb_backup.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"backup_id", "location", "reconciling", "update_time"}, + ImportStateVerifyIgnore: []string{"backup_id", "location", "reconciling", "update_time", "labels", "terraform_labels"}, }, { Config: testAccAlloydbBackup_update(context), @@ -39,7 +39,7 @@ func TestAccAlloydbBackup_update(t *testing.T) { ResourceName: "google_alloydb_backup.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"backup_id", "location", "reconciling", "update_time"}, + ImportStateVerifyIgnore: []string{"backup_id", "location", "reconciling", "update_time", "labels", "terraform_labels"}, }, }, }) @@ -192,7 +192,7 @@ func TestAccAlloydbBackup_usingCMEK(t *testing.T) { ResourceName: "google_alloydb_backup.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"backup_id", "location", "reconciling", "update_time"}, + ImportStateVerifyIgnore: []string{"backup_id", "location", "reconciling", "update_time", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/alloydb/resource_alloydb_cluster.go b/google/services/alloydb/resource_alloydb_cluster.go index 144529133b5..04a33b28e8f 100644 --- a/google/services/alloydb/resource_alloydb_cluster.go +++ b/google/services/alloydb/resource_alloydb_cluster.go @@ -50,6 +50,7 @@ func ResourceAlloydbCluster() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -411,6 +412,12 @@ If not set, defaults to 14 days.`, Computed: true, Description: `The database engine major version. This is an output-only field and it's populated at the Cluster creation time. This field cannot be changed after cluster creation.`, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "encryption_info": { Type: schema.TypeList, Computed: true, @@ -462,6 +469,13 @@ If not set, defaults to 14 days.`, Computed: true, Description: `The name of the cluster resource.`, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "uid": { Type: schema.TypeString, Computed: true, @@ -486,12 +500,6 @@ func resourceAlloydbClusterCreate(d *schema.ResourceData, meta interface{}) erro } obj := make(map[string]interface{}) - labelsProp, err := expandAlloydbClusterLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } encryptionConfigProp, err := expandAlloydbClusterEncryptionConfig(d.Get("encryption_config"), d, config) if err != nil { return err @@ -540,6 +548,12 @@ func resourceAlloydbClusterCreate(d *schema.ResourceData, meta interface{}) erro } else if v, ok := d.GetOkExists("automated_backup_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(automatedBackupPolicyProp)) && (ok || !reflect.DeepEqual(v, automatedBackupPolicyProp)) { obj["automatedBackupPolicy"] = automatedBackupPolicyProp } + labelsProp, err := expandAlloydbClusterEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{AlloydbBasePath}}projects/{{project}}/locations/{{location}}/clusters?clusterId={{cluster_id}}") if err != nil { @@ -707,6 +721,12 @@ func resourceAlloydbClusterRead(d *schema.ResourceData, meta interface{}) error if err := d.Set("migration_source", flattenAlloydbClusterMigrationSource(res["migrationSource"], d, config)); err != nil { return fmt.Errorf("Error reading Cluster: %s", err) } + if err := d.Set("terraform_labels", flattenAlloydbClusterTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Cluster: %s", err) + } + if err := d.Set("effective_labels", flattenAlloydbClusterEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Cluster: %s", err) + } return nil } @@ -727,12 +747,6 @@ func resourceAlloydbClusterUpdate(d *schema.ResourceData, meta interface{}) erro billingProject = project obj := make(map[string]interface{}) - labelsProp, err := expandAlloydbClusterLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } encryptionConfigProp, err := expandAlloydbClusterEncryptionConfig(d.Get("encryption_config"), d, config) if err != nil { return err @@ -769,6 +783,12 @@ func resourceAlloydbClusterUpdate(d *schema.ResourceData, meta interface{}) erro } else if v, ok := d.GetOkExists("automated_backup_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, automatedBackupPolicyProp)) { obj["automatedBackupPolicy"] = automatedBackupPolicyProp } + labelsProp, err := expandAlloydbClusterEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{AlloydbBasePath}}projects/{{project}}/locations/{{location}}/clusters/{{cluster_id}}") if err != nil { @@ -778,10 +798,6 @@ func resourceAlloydbClusterUpdate(d *schema.ResourceData, meta interface{}) erro log.Printf("[DEBUG] Updating Cluster %q: %#v", d.Id(), obj) updateMask := []string{} - if d.HasChange("labels") { - updateMask = append(updateMask, "labels") - } - if d.HasChange("encryption_config") { updateMask = append(updateMask, "encryptionConfig") } @@ -805,6 +821,10 @@ func resourceAlloydbClusterUpdate(d *schema.ResourceData, meta interface{}) erro if d.HasChange("automated_backup_policy") { updateMask = append(updateMask, "automatedBackupPolicy") } + + if d.HasChange("effective_labels") { + updateMask = append(updateMask, "labels") + } // updateMask is a URL parameter but not present in the schema, so ReplaceVars // won't set it url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -927,7 +947,18 @@ func flattenAlloydbClusterUid(v interface{}, d *schema.ResourceData, config *tra } func flattenAlloydbClusterLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenAlloydbClusterEncryptionConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -1353,15 +1384,23 @@ func flattenAlloydbClusterMigrationSourceSourceType(v interface{}, d *schema.Res return v } -func expandAlloydbClusterLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func flattenAlloydbClusterTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { - return map[string]string{}, nil + return v } - m := make(map[string]string) - for k, val := range v.(map[string]interface{}) { - m[k] = val.(string) + + 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 m, nil + + return transformed +} + +func flattenAlloydbClusterEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v } func expandAlloydbClusterEncryptionConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { @@ -1798,3 +1837,14 @@ func expandAlloydbClusterAutomatedBackupPolicyQuantityBasedRetentionCount(v inte func expandAlloydbClusterAutomatedBackupPolicyEnabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } + +func expandAlloydbClusterEffectiveLabels(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/alloydb/resource_alloydb_cluster_generated_test.go b/google/services/alloydb/resource_alloydb_cluster_generated_test.go index c6b6bddf127..a841ef90fbd 100644 --- a/google/services/alloydb/resource_alloydb_cluster_generated_test.go +++ b/google/services/alloydb/resource_alloydb_cluster_generated_test.go @@ -49,7 +49,7 @@ func TestAccAlloydbCluster_alloydbClusterBasicExample(t *testing.T) { ResourceName: "google_alloydb_cluster.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"initial_user", "restore_backup_source", "restore_continuous_backup_source", "cluster_id", "location"}, + ImportStateVerifyIgnore: []string{"initial_user", "restore_backup_source", "restore_continuous_backup_source", "cluster_id", "location", "labels", "terraform_labels"}, }, }, }) @@ -90,7 +90,7 @@ func TestAccAlloydbCluster_alloydbClusterFullExample(t *testing.T) { ResourceName: "google_alloydb_cluster.full", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"initial_user", "restore_backup_source", "restore_continuous_backup_source", "cluster_id", "location"}, + ImportStateVerifyIgnore: []string{"initial_user", "restore_backup_source", "restore_continuous_backup_source", "cluster_id", "location", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/alloydb/resource_alloydb_cluster_test.go b/google/services/alloydb/resource_alloydb_cluster_test.go index f95995b581c..8db6b51d0cf 100644 --- a/google/services/alloydb/resource_alloydb_cluster_test.go +++ b/google/services/alloydb/resource_alloydb_cluster_test.go @@ -28,7 +28,7 @@ func TestAccAlloydbCluster_update(t *testing.T) { ResourceName: "google_alloydb_cluster.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"initial_user", "cluster_id", "location"}, + ImportStateVerifyIgnore: []string{"initial_user", "cluster_id", "location", "labels", "terraform_labels"}, }, { Config: testAccAlloydbCluster_update(context), @@ -37,7 +37,7 @@ func TestAccAlloydbCluster_update(t *testing.T) { ResourceName: "google_alloydb_cluster.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"initial_user", "cluster_id", "location"}, + ImportStateVerifyIgnore: []string{"initial_user", "cluster_id", "location", "labels", "terraform_labels"}, }, { Config: testAccAlloydbCluster_alloydbClusterBasicExample(context), diff --git a/google/services/alloydb/resource_alloydb_instance_generated_test.go b/google/services/alloydb/resource_alloydb_instance_generated_test.go index 4e57b8ac73c..1e2f6aa572f 100644 --- a/google/services/alloydb/resource_alloydb_instance_generated_test.go +++ b/google/services/alloydb/resource_alloydb_instance_generated_test.go @@ -49,7 +49,7 @@ func TestAccAlloydbInstance_alloydbInstanceBasicExample(t *testing.T) { ResourceName: "google_alloydb_instance.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"labels", "annotations", "display_name", "terraform_labels", "cluster", "instance_id", "reconciling", "update_time"}, + ImportStateVerifyIgnore: []string{"display_name", "cluster", "instance_id", "reconciling", "update_time", "labels", "annotations", "terraform_labels"}, }, }, }) diff --git a/google/services/artifactregistry/data_source_artifact_registry_repository_test.go b/google/services/artifactregistry/data_source_artifact_registry_repository_test.go index 108b1c3c6ee..352b2b27c5b 100644 --- a/google/services/artifactregistry/data_source_artifact_registry_repository_test.go +++ b/google/services/artifactregistry/data_source_artifact_registry_repository_test.go @@ -25,8 +25,8 @@ func TestAccDataSourceGoogleArtifactRegistryRepositoryConfig(t *testing.T) { { Config: testAccDataSourceGoogleArtifactRegistryRepositoryConfig(context), Check: resource.ComposeTestCheckFunc( - acctest.CheckDataSourceStateMatchesResourceState(funcDataName, - "google_artifact_registry_repository.my-repo"), + acctest.CheckDataSourceStateMatchesResourceStateWithIgnores(funcDataName, + "google_artifact_registry_repository.my-repo", map[string]struct{}{"labels.%": {}, "terraform_labels.%": {}}), ), }, }, @@ -40,6 +40,10 @@ resource "google_artifact_registry_repository" "my-repo" { repository_id = "tf-test-my-repository%{random_suffix}" description = "example docker repository%{random_suffix}" format = "DOCKER" + labels = { + my_key = "my_val" + other_key = "other_val" + } } data "google_artifact_registry_repository" "my-repo" { diff --git a/google/services/artifactregistry/resource_artifact_registry_repository.go b/google/services/artifactregistry/resource_artifact_registry_repository.go index 01284e8d5d1..0eca15c5f2c 100644 --- a/google/services/artifactregistry/resource_artifact_registry_repository.go +++ b/google/services/artifactregistry/resource_artifact_registry_repository.go @@ -50,6 +50,7 @@ func ResourceArtifactRegistryRepository() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -296,12 +297,25 @@ Repository. Upstream policies cannot be set on a standard repository.`, Computed: true, Description: `The time when the repository was created.`, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "name": { Type: schema.TypeString, Computed: true, Description: `The name of the repository, for example: "repo1"`, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "update_time": { Type: schema.TypeString, Computed: true, @@ -338,12 +352,6 @@ func resourceArtifactRegistryRepositoryCreate(d *schema.ResourceData, meta inter } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { obj["description"] = descriptionProp } - labelsProp, err := expandArtifactRegistryRepositoryLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } kmsKeyNameProp, err := expandArtifactRegistryRepositoryKmsKeyName(d.Get("kms_key_name"), d, config) if err != nil { return err @@ -380,6 +388,12 @@ func resourceArtifactRegistryRepositoryCreate(d *schema.ResourceData, meta inter } else if v, ok := d.GetOkExists("remote_repository_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(remoteRepositoryConfigProp)) && (ok || !reflect.DeepEqual(v, remoteRepositoryConfigProp)) { obj["remoteRepositoryConfig"] = remoteRepositoryConfigProp } + labelsProp, err := expandArtifactRegistryRepositoryEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } obj, err = resourceArtifactRegistryRepositoryEncoder(d, meta, obj) if err != nil { @@ -530,6 +544,12 @@ func resourceArtifactRegistryRepositoryRead(d *schema.ResourceData, meta interfa if err := d.Set("remote_repository_config", flattenArtifactRegistryRepositoryRemoteRepositoryConfig(res["remoteRepositoryConfig"], d, config)); err != nil { return fmt.Errorf("Error reading Repository: %s", err) } + if err := d.Set("terraform_labels", flattenArtifactRegistryRepositoryTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Repository: %s", err) + } + if err := d.Set("effective_labels", flattenArtifactRegistryRepositoryEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Repository: %s", err) + } return nil } @@ -556,12 +576,6 @@ func resourceArtifactRegistryRepositoryUpdate(d *schema.ResourceData, meta inter } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { obj["description"] = descriptionProp } - labelsProp, err := expandArtifactRegistryRepositoryLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } dockerConfigProp, err := expandArtifactRegistryRepositoryDockerConfig(d.Get("docker_config"), d, config) if err != nil { return err @@ -580,6 +594,12 @@ func resourceArtifactRegistryRepositoryUpdate(d *schema.ResourceData, meta inter } else if v, ok := d.GetOkExists("virtual_repository_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, virtualRepositoryConfigProp)) { obj["virtualRepositoryConfig"] = virtualRepositoryConfigProp } + labelsProp, err := expandArtifactRegistryRepositoryEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } obj, err = resourceArtifactRegistryRepositoryEncoder(d, meta, obj) if err != nil { @@ -598,10 +618,6 @@ func resourceArtifactRegistryRepositoryUpdate(d *schema.ResourceData, meta inter updateMask = append(updateMask, "description") } - if d.HasChange("labels") { - updateMask = append(updateMask, "labels") - } - if d.HasChange("docker_config") { updateMask = append(updateMask, "dockerConfig") } @@ -613,6 +629,10 @@ func resourceArtifactRegistryRepositoryUpdate(d *schema.ResourceData, meta inter if d.HasChange("virtual_repository_config") { updateMask = append(updateMask, "virtualRepositoryConfig") } + + if d.HasChange("effective_labels") { + updateMask = append(updateMask, "labels") + } // updateMask is a URL parameter but not present in the schema, so ReplaceVars // won't set it url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -734,7 +754,18 @@ func flattenArtifactRegistryRepositoryDescription(v interface{}, d *schema.Resou } func flattenArtifactRegistryRepositoryLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenArtifactRegistryRepositoryKmsKeyName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -945,6 +976,25 @@ func flattenArtifactRegistryRepositoryRemoteRepositoryConfigPythonRepositoryPubl return v } +func flattenArtifactRegistryRepositoryTerraformLabels(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 flattenArtifactRegistryRepositoryEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func expandArtifactRegistryRepositoryFormat(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } @@ -953,17 +1003,6 @@ func expandArtifactRegistryRepositoryDescription(v interface{}, d tpgresource.Te return v, nil } -func expandArtifactRegistryRepositoryLabels(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 -} - func expandArtifactRegistryRepositoryKmsKeyName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } @@ -1244,6 +1283,17 @@ func expandArtifactRegistryRepositoryRemoteRepositoryConfigPythonRepositoryPubli return v, nil } +func expandArtifactRegistryRepositoryEffectiveLabels(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 +} + func resourceArtifactRegistryRepositoryEncoder(d *schema.ResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) { config := meta.(*transport_tpg.Config) if _, ok := d.GetOk("location"); !ok { diff --git a/google/services/artifactregistry/resource_artifact_registry_repository_generated_test.go b/google/services/artifactregistry/resource_artifact_registry_repository_generated_test.go index 31414d2ba3c..4fab59739a2 100644 --- a/google/services/artifactregistry/resource_artifact_registry_repository_generated_test.go +++ b/google/services/artifactregistry/resource_artifact_registry_repository_generated_test.go @@ -49,7 +49,7 @@ func TestAccArtifactRegistryRepository_artifactRegistryRepositoryBasicExample(t ResourceName: "google_artifact_registry_repository.my-repo", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"repository_id", "location"}, + ImportStateVerifyIgnore: []string{"repository_id", "location", "labels", "terraform_labels"}, }, }, }) @@ -85,7 +85,7 @@ func TestAccArtifactRegistryRepository_artifactRegistryRepositoryDockerExample(t ResourceName: "google_artifact_registry_repository.my-repo", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"repository_id", "location"}, + ImportStateVerifyIgnore: []string{"repository_id", "location", "labels", "terraform_labels"}, }, }, }) @@ -126,7 +126,7 @@ func TestAccArtifactRegistryRepository_artifactRegistryRepositoryCmekExample(t * ResourceName: "google_artifact_registry_repository.my-repo", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"repository_id", "location"}, + ImportStateVerifyIgnore: []string{"repository_id", "location", "labels", "terraform_labels"}, }, }, }) @@ -174,7 +174,7 @@ func TestAccArtifactRegistryRepository_artifactRegistryRepositoryVirtualExample( ResourceName: "google_artifact_registry_repository.my-repo", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"repository_id", "location"}, + ImportStateVerifyIgnore: []string{"repository_id", "location", "labels", "terraform_labels"}, }, }, }) @@ -226,7 +226,7 @@ func TestAccArtifactRegistryRepository_artifactRegistryRepositoryRemoteExample(t ResourceName: "google_artifact_registry_repository.my-repo", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"repository_id", "location"}, + ImportStateVerifyIgnore: []string{"repository_id", "location", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/artifactregistry/resource_artifact_registry_repository_test.go b/google/services/artifactregistry/resource_artifact_registry_repository_test.go index 7951044d348..c9b37c3d4e5 100644 --- a/google/services/artifactregistry/resource_artifact_registry_repository_test.go +++ b/google/services/artifactregistry/resource_artifact_registry_repository_test.go @@ -24,17 +24,19 @@ func TestAccArtifactRegistryRepository_update(t *testing.T) { Config: testAccArtifactRegistryRepository_update(repositoryID), }, { - ResourceName: "google_artifact_registry_repository.test", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_artifact_registry_repository.test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, { Config: testAccArtifactRegistryRepository_update2(repositoryID), }, { - ResourceName: "google_artifact_registry_repository.test", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_artifact_registry_repository.test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, }, }) diff --git a/google/services/beyondcorp/resource_beyondcorp_app_connection.go b/google/services/beyondcorp/resource_beyondcorp_app_connection.go index 6d35ad16d4e..9d7f6118f68 100644 --- a/google/services/beyondcorp/resource_beyondcorp_app_connection.go +++ b/google/services/beyondcorp/resource_beyondcorp_app_connection.go @@ -49,6 +49,7 @@ func ResourceBeyondcorpAppConnection() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -145,6 +146,19 @@ for a list of possible values.`, https://cloud.google.com/beyondcorp/docs/reference/rest/v1/projects.locations.appConnections#type for a list of possible values.`, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "project": { Type: schema.TypeString, Optional: true, @@ -170,12 +184,6 @@ func resourceBeyondcorpAppConnectionCreate(d *schema.ResourceData, meta interfac } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { obj["displayName"] = displayNameProp } - labelsProp, err := expandBeyondcorpAppConnectionLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } typeProp, err := expandBeyondcorpAppConnectionType(d.Get("type"), d, config) if err != nil { return err @@ -200,6 +208,12 @@ func resourceBeyondcorpAppConnectionCreate(d *schema.ResourceData, meta interfac } else if v, ok := d.GetOkExists("gateway"); !tpgresource.IsEmptyValue(reflect.ValueOf(gatewayProp)) && (ok || !reflect.DeepEqual(v, gatewayProp)) { obj["gateway"] = gatewayProp } + labelsProp, err := expandBeyondcorpAppConnectionEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{BeyondcorpBasePath}}projects/{{project}}/locations/{{region}}/appConnections?app_connection_id={{name}}") if err != nil { @@ -323,6 +337,12 @@ func resourceBeyondcorpAppConnectionRead(d *schema.ResourceData, meta interface{ if err := d.Set("gateway", flattenBeyondcorpAppConnectionGateway(res["gateway"], d, config)); err != nil { return fmt.Errorf("Error reading AppConnection: %s", err) } + if err := d.Set("terraform_labels", flattenBeyondcorpAppConnectionTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading AppConnection: %s", err) + } + if err := d.Set("effective_labels", flattenBeyondcorpAppConnectionEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading AppConnection: %s", err) + } return nil } @@ -349,12 +369,6 @@ func resourceBeyondcorpAppConnectionUpdate(d *schema.ResourceData, meta interfac } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { obj["displayName"] = displayNameProp } - labelsProp, err := expandBeyondcorpAppConnectionLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } applicationEndpointProp, err := expandBeyondcorpAppConnectionApplicationEndpoint(d.Get("application_endpoint"), d, config) if err != nil { return err @@ -373,6 +387,12 @@ func resourceBeyondcorpAppConnectionUpdate(d *schema.ResourceData, meta interfac } else if v, ok := d.GetOkExists("gateway"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, gatewayProp)) { obj["gateway"] = gatewayProp } + labelsProp, err := expandBeyondcorpAppConnectionEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{BeyondcorpBasePath}}projects/{{project}}/locations/{{region}}/appConnections/{{name}}") if err != nil { @@ -386,10 +406,6 @@ func resourceBeyondcorpAppConnectionUpdate(d *schema.ResourceData, meta interfac updateMask = append(updateMask, "displayName") } - if d.HasChange("labels") { - updateMask = append(updateMask, "labels") - } - if d.HasChange("application_endpoint") { updateMask = append(updateMask, "applicationEndpoint") } @@ -401,6 +417,10 @@ func resourceBeyondcorpAppConnectionUpdate(d *schema.ResourceData, meta interfac if d.HasChange("gateway") { updateMask = append(updateMask, "gateway") } + + if d.HasChange("effective_labels") { + updateMask = append(updateMask, "labels") + } // updateMask is a URL parameter but not present in the schema, so ReplaceVars // won't set it url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -519,7 +539,18 @@ func flattenBeyondcorpAppConnectionDisplayName(v interface{}, d *schema.Resource } func flattenBeyondcorpAppConnectionLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenBeyondcorpAppConnectionType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -614,19 +645,27 @@ func flattenBeyondcorpAppConnectionGatewayIngressPort(v interface{}, d *schema.R return v // let terraform core handle it otherwise } -func expandBeyondcorpAppConnectionDisplayName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandBeyondcorpAppConnectionLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func flattenBeyondcorpAppConnectionTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { - return map[string]string{}, nil + return v } - m := make(map[string]string) - for k, val := range v.(map[string]interface{}) { - m[k] = val.(string) + + 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 m, nil + + return transformed +} + +func flattenBeyondcorpAppConnectionEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func expandBeyondcorpAppConnectionDisplayName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil } func expandBeyondcorpAppConnectionType(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { @@ -726,3 +765,14 @@ func expandBeyondcorpAppConnectionGatewayUri(v interface{}, d tpgresource.Terraf func expandBeyondcorpAppConnectionGatewayIngressPort(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } + +func expandBeyondcorpAppConnectionEffectiveLabels(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/beyondcorp/resource_beyondcorp_app_connection_generated_test.go b/google/services/beyondcorp/resource_beyondcorp_app_connection_generated_test.go index 4c4e0847a94..3d9abd88d4c 100644 --- a/google/services/beyondcorp/resource_beyondcorp_app_connection_generated_test.go +++ b/google/services/beyondcorp/resource_beyondcorp_app_connection_generated_test.go @@ -49,7 +49,7 @@ func TestAccBeyondcorpAppConnection_beyondcorpAppConnectionBasicExample(t *testi ResourceName: "google_beyondcorp_app_connection.app_connection", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "region"}, + ImportStateVerifyIgnore: []string{"name", "region", "labels", "terraform_labels"}, }, }, }) @@ -102,7 +102,7 @@ func TestAccBeyondcorpAppConnection_beyondcorpAppConnectionFullExample(t *testin ResourceName: "google_beyondcorp_app_connection.app_connection", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "region"}, + ImportStateVerifyIgnore: []string{"name", "region", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/beyondcorp/resource_beyondcorp_app_connector.go b/google/services/beyondcorp/resource_beyondcorp_app_connector.go index 76942f70d66..877c9525794 100644 --- a/google/services/beyondcorp/resource_beyondcorp_app_connector.go +++ b/google/services/beyondcorp/resource_beyondcorp_app_connector.go @@ -49,6 +49,7 @@ func ResourceBeyondcorpAppConnector() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -101,11 +102,24 @@ func ResourceBeyondcorpAppConnector() *schema.Resource { ForceNew: true, Description: `The region of the AppConnector.`, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "state": { Type: schema.TypeString, Computed: true, Description: `Represents the different states of a AppConnector.`, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "project": { Type: schema.TypeString, Optional: true, @@ -131,18 +145,18 @@ func resourceBeyondcorpAppConnectorCreate(d *schema.ResourceData, meta interface } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { obj["displayName"] = displayNameProp } - labelsProp, err := expandBeyondcorpAppConnectorLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } principalInfoProp, err := expandBeyondcorpAppConnectorPrincipalInfo(d.Get("principal_info"), d, config) if err != nil { return err } else if v, ok := d.GetOkExists("principal_info"); !tpgresource.IsEmptyValue(reflect.ValueOf(principalInfoProp)) && (ok || !reflect.DeepEqual(v, principalInfoProp)) { obj["principalInfo"] = principalInfoProp } + labelsProp, err := expandBeyondcorpAppConnectorEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{BeyondcorpBasePath}}projects/{{project}}/locations/{{region}}/appConnectors?app_connector_id={{name}}") if err != nil { @@ -260,6 +274,12 @@ func resourceBeyondcorpAppConnectorRead(d *schema.ResourceData, meta interface{} if err := d.Set("state", flattenBeyondcorpAppConnectorState(res["state"], d, config)); err != nil { return fmt.Errorf("Error reading AppConnector: %s", err) } + if err := d.Set("terraform_labels", flattenBeyondcorpAppConnectorTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading AppConnector: %s", err) + } + if err := d.Set("effective_labels", flattenBeyondcorpAppConnectorEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading AppConnector: %s", err) + } return nil } @@ -286,18 +306,18 @@ func resourceBeyondcorpAppConnectorUpdate(d *schema.ResourceData, meta interface } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { obj["displayName"] = displayNameProp } - labelsProp, err := expandBeyondcorpAppConnectorLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } principalInfoProp, err := expandBeyondcorpAppConnectorPrincipalInfo(d.Get("principal_info"), d, config) if err != nil { return err } else if v, ok := d.GetOkExists("principal_info"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, principalInfoProp)) { obj["principalInfo"] = principalInfoProp } + labelsProp, err := expandBeyondcorpAppConnectorEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{BeyondcorpBasePath}}projects/{{project}}/locations/{{region}}/appConnectors/{{name}}") if err != nil { @@ -311,13 +331,13 @@ func resourceBeyondcorpAppConnectorUpdate(d *schema.ResourceData, meta interface updateMask = append(updateMask, "displayName") } - if d.HasChange("labels") { - updateMask = append(updateMask, "labels") - } - if d.HasChange("principal_info") { updateMask = append(updateMask, "principalInfo") } + + if d.HasChange("effective_labels") { + updateMask = append(updateMask, "labels") + } // updateMask is a URL parameter but not present in the schema, so ReplaceVars // won't set it url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -436,7 +456,18 @@ func flattenBeyondcorpAppConnectorDisplayName(v interface{}, d *schema.ResourceD } func flattenBeyondcorpAppConnectorLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenBeyondcorpAppConnectorPrincipalInfo(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -473,19 +504,27 @@ func flattenBeyondcorpAppConnectorState(v interface{}, d *schema.ResourceData, c return v } -func expandBeyondcorpAppConnectorDisplayName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandBeyondcorpAppConnectorLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func flattenBeyondcorpAppConnectorTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { - return map[string]string{}, nil + return v } - m := make(map[string]string) - for k, val := range v.(map[string]interface{}) { - m[k] = val.(string) + + 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 m, nil + + return transformed +} + +func flattenBeyondcorpAppConnectorEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func expandBeyondcorpAppConnectorDisplayName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil } func expandBeyondcorpAppConnectorPrincipalInfo(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { @@ -529,3 +568,14 @@ func expandBeyondcorpAppConnectorPrincipalInfoServiceAccount(v interface{}, d tp func expandBeyondcorpAppConnectorPrincipalInfoServiceAccountEmail(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } + +func expandBeyondcorpAppConnectorEffectiveLabels(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/beyondcorp/resource_beyondcorp_app_connector_generated_test.go b/google/services/beyondcorp/resource_beyondcorp_app_connector_generated_test.go index cfed37e12d5..ca9a86e8c1e 100644 --- a/google/services/beyondcorp/resource_beyondcorp_app_connector_generated_test.go +++ b/google/services/beyondcorp/resource_beyondcorp_app_connector_generated_test.go @@ -49,7 +49,7 @@ func TestAccBeyondcorpAppConnector_beyondcorpAppConnectorBasicExample(t *testing ResourceName: "google_beyondcorp_app_connector.app_connector", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "region"}, + ImportStateVerifyIgnore: []string{"name", "region", "labels", "terraform_labels"}, }, }, }) @@ -92,7 +92,7 @@ func TestAccBeyondcorpAppConnector_beyondcorpAppConnectorFullExample(t *testing. ResourceName: "google_beyondcorp_app_connector.app_connector", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "region"}, + ImportStateVerifyIgnore: []string{"name", "region", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/beyondcorp/resource_beyondcorp_app_gateway.go b/google/services/beyondcorp/resource_beyondcorp_app_gateway.go index 8aadd3c1274..33560003791 100644 --- a/google/services/beyondcorp/resource_beyondcorp_app_gateway.go +++ b/google/services/beyondcorp/resource_beyondcorp_app_gateway.go @@ -47,6 +47,7 @@ func ResourceBeyondcorpAppGateway() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -111,11 +112,25 @@ func ResourceBeyondcorpAppGateway() *schema.Resource { }, }, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + ForceNew: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "state": { Type: schema.TypeString, Computed: true, Description: `Represents the different states of a AppGateway.`, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "uri": { Type: schema.TypeString, Computed: true, @@ -158,10 +173,10 @@ func resourceBeyondcorpAppGatewayCreate(d *schema.ResourceData, meta interface{} } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { obj["displayName"] = displayNameProp } - labelsProp, err := expandBeyondcorpAppGatewayLabels(d.Get("labels"), d, config) + labelsProp, err := expandBeyondcorpAppGatewayEffectiveLabels(d.Get("effective_labels"), d, config) if err != nil { return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { obj["labels"] = labelsProp } @@ -290,6 +305,12 @@ func resourceBeyondcorpAppGatewayRead(d *schema.ResourceData, meta interface{}) if err := d.Set("allocated_connections", flattenBeyondcorpAppGatewayAllocatedConnections(res["allocatedConnections"], d, config)); err != nil { return fmt.Errorf("Error reading AppGateway: %s", err) } + if err := d.Set("terraform_labels", flattenBeyondcorpAppGatewayTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading AppGateway: %s", err) + } + if err := d.Set("effective_labels", flattenBeyondcorpAppGatewayEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading AppGateway: %s", err) + } return nil } @@ -381,7 +402,18 @@ func flattenBeyondcorpAppGatewayDisplayName(v interface{}, d *schema.ResourceDat } func flattenBeyondcorpAppGatewayLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenBeyondcorpAppGatewayState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -428,6 +460,25 @@ func flattenBeyondcorpAppGatewayAllocatedConnectionsIngressPort(v interface{}, d return v // let terraform core handle it otherwise } +func flattenBeyondcorpAppGatewayTerraformLabels(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 flattenBeyondcorpAppGatewayEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func expandBeyondcorpAppGatewayType(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } @@ -440,7 +491,7 @@ func expandBeyondcorpAppGatewayDisplayName(v interface{}, d tpgresource.Terrafor return v, nil } -func expandBeyondcorpAppGatewayLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func expandBeyondcorpAppGatewayEffectiveLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { if v == nil { return map[string]string{}, nil } diff --git a/google/services/beyondcorp/resource_beyondcorp_app_gateway_generated_test.go b/google/services/beyondcorp/resource_beyondcorp_app_gateway_generated_test.go index a4e9f27f9f7..e7eb64e62a4 100644 --- a/google/services/beyondcorp/resource_beyondcorp_app_gateway_generated_test.go +++ b/google/services/beyondcorp/resource_beyondcorp_app_gateway_generated_test.go @@ -49,7 +49,7 @@ func TestAccBeyondcorpAppGateway_beyondcorpAppGatewayBasicExample(t *testing.T) ResourceName: "google_beyondcorp_app_gateway.app_gateway", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "region"}, + ImportStateVerifyIgnore: []string{"name", "region", "labels", "terraform_labels"}, }, }, }) @@ -85,7 +85,7 @@ func TestAccBeyondcorpAppGateway_beyondcorpAppGatewayFullExample(t *testing.T) { ResourceName: "google_beyondcorp_app_gateway.app_gateway", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "region"}, + ImportStateVerifyIgnore: []string{"name", "region", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/bigquery/resource_bigquery_job.go b/google/services/bigquery/resource_bigquery_job.go index b7678b11e0a..20c6115f2e3 100644 --- a/google/services/bigquery/resource_bigquery_job.go +++ b/google/services/bigquery/resource_bigquery_job.go @@ -56,6 +56,7 @@ func ResourceBigQueryJob() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -883,11 +884,25 @@ Creation, truncation and append actions occur as one atomic update upon job comp }, ExactlyOneOf: []string{"query", "load", "copy", "extract"}, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + ForceNew: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "job_type": { Type: schema.TypeString, Computed: true, Description: `The type of the job.`, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "job_id": { Type: schema.TypeString, @@ -1238,6 +1253,10 @@ func flattenBigQueryJobConfiguration(v interface{}, d *schema.ResourceData, conf flattenBigQueryJobConfigurationCopy(original["copy"], d, config) transformed["extract"] = flattenBigQueryJobConfigurationExtract(original["extract"], d, config) + transformed["terraform_labels"] = + flattenBigQueryJobConfigurationTerraformLabels(original["labels"], d, config) + transformed["effective_labels"] = + flattenBigQueryJobConfigurationEffectiveLabels(original["labels"], d, config) return []interface{}{transformed} } func flattenBigQueryJobConfigurationJobType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -1249,7 +1268,18 @@ func flattenBigQueryJobConfigurationJobTimeoutMs(v interface{}, d *schema.Resour } func flattenBigQueryJobConfigurationLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenBigQueryJobConfigurationQuery(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -1924,6 +1954,25 @@ func flattenBigQueryJobConfigurationExtractSourceModelModelId(v interface{}, d * return v } +func flattenBigQueryJobConfigurationTerraformLabels(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 flattenBigQueryJobConfigurationEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func flattenBigQueryJobJobReference(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { return nil @@ -2045,13 +2094,6 @@ func expandBigQueryJobConfiguration(v interface{}, d tpgresource.TerraformResour transformed["jobTimeoutMs"] = transformedJobTimeoutMs } - transformedLabels, err := expandBigQueryJobConfigurationLabels(d.Get("labels"), d, config) - if err != nil { - return nil, err - } else if val := reflect.ValueOf(transformedLabels); val.IsValid() && !tpgresource.IsEmptyValue(val) { - transformed["labels"] = transformedLabels - } - transformedQuery, err := expandBigQueryJobConfigurationQuery(d.Get("query"), d, config) if err != nil { return nil, err @@ -2080,6 +2122,13 @@ func expandBigQueryJobConfiguration(v interface{}, d tpgresource.TerraformResour transformed["extract"] = transformedExtract } + transformedEffectiveLabels, err := expandBigQueryJobConfigurationEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEffectiveLabels); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["labels"] = transformedEffectiveLabels + } + return transformed, nil } @@ -2091,17 +2140,6 @@ func expandBigQueryJobConfigurationJobTimeoutMs(v interface{}, d tpgresource.Ter return v, nil } -func expandBigQueryJobConfigurationLabels(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 -} - func expandBigQueryJobConfigurationQuery(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { l := v.([]interface{}) if len(l) == 0 || l[0] == nil { @@ -3159,6 +3197,17 @@ func expandBigQueryJobConfigurationExtractSourceModelModelId(v interface{}, d tp return v, nil } +func expandBigQueryJobConfigurationEffectiveLabels(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 +} + func expandBigQueryJobJobReference(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { transformed := make(map[string]interface{}) transformedJobId, err := expandBigQueryJobJobReferenceJobId(d.Get("job_id"), d, config) diff --git a/google/services/bigquery/resource_bigquery_job_generated_test.go b/google/services/bigquery/resource_bigquery_job_generated_test.go index 1689301deec..0ef144ca057 100644 --- a/google/services/bigquery/resource_bigquery_job_generated_test.go +++ b/google/services/bigquery/resource_bigquery_job_generated_test.go @@ -44,7 +44,7 @@ func TestAccBigQueryJob_bigqueryJobQueryExample(t *testing.T) { ResourceName: "google_bigquery_job.job", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "status.0.state"}, + ImportStateVerifyIgnore: []string{"etag", "status.0.state", "labels", "terraform_labels"}, }, }, }) @@ -110,7 +110,7 @@ func TestAccBigQueryJob_bigqueryJobQueryTableReferenceExample(t *testing.T) { ResourceName: "google_bigquery_job.job", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "query.0.default_dataset.0.dataset_id", "query.0.destination_table.0.table_id", "status.0.state"}, + ImportStateVerifyIgnore: []string{"etag", "query.0.default_dataset.0.dataset_id", "query.0.destination_table.0.table_id", "status.0.state", "labels", "terraform_labels"}, }, }, }) @@ -178,7 +178,7 @@ func TestAccBigQueryJob_bigqueryJobLoadExample(t *testing.T) { ResourceName: "google_bigquery_job.job", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "status.0.state"}, + ImportStateVerifyIgnore: []string{"etag", "status.0.state", "labels", "terraform_labels"}, }, }, }) @@ -246,7 +246,7 @@ func TestAccBigQueryJob_bigqueryJobLoadGeojsonExample(t *testing.T) { ResourceName: "google_bigquery_job.job", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "status.0.state"}, + ImportStateVerifyIgnore: []string{"etag", "status.0.state", "labels", "terraform_labels"}, }, }, }) @@ -333,7 +333,7 @@ func TestAccBigQueryJob_bigqueryJobLoadParquetExample(t *testing.T) { ResourceName: "google_bigquery_job.job", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "status.0.state"}, + ImportStateVerifyIgnore: []string{"etag", "status.0.state", "labels", "terraform_labels"}, }, }, }) @@ -416,7 +416,7 @@ func TestAccBigQueryJob_bigqueryJobLoadTableReferenceExample(t *testing.T) { ResourceName: "google_bigquery_job.job", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "load.0.destination_table.0.table_id", "status.0.state"}, + ImportStateVerifyIgnore: []string{"etag", "load.0.destination_table.0.table_id", "status.0.state", "labels", "terraform_labels"}, }, }, }) @@ -482,7 +482,7 @@ func TestAccBigQueryJob_bigqueryJobCopyExample(t *testing.T) { ResourceName: "google_bigquery_job.job", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "status.0.state"}, + ImportStateVerifyIgnore: []string{"etag", "status.0.state", "labels", "terraform_labels"}, }, }, }) @@ -637,7 +637,7 @@ func TestAccBigQueryJob_bigqueryJobCopyTableReferenceExample(t *testing.T) { ResourceName: "google_bigquery_job.job", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "copy.0.destination_table.0.table_id", "copy.0.source_tables.0.table_id", "copy.0.source_tables.1.table_id", "status.0.state"}, + ImportStateVerifyIgnore: []string{"etag", "copy.0.destination_table.0.table_id", "copy.0.source_tables.0.table_id", "copy.0.source_tables.1.table_id", "status.0.state", "labels", "terraform_labels"}, }, }, }) @@ -785,7 +785,7 @@ func TestAccBigQueryJob_bigqueryJobExtractExample(t *testing.T) { ResourceName: "google_bigquery_job.job", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "status.0.state"}, + ImportStateVerifyIgnore: []string{"etag", "status.0.state", "labels", "terraform_labels"}, }, }, }) @@ -869,7 +869,7 @@ func TestAccBigQueryJob_bigqueryJobExtractTableReferenceExample(t *testing.T) { ResourceName: "google_bigquery_job.job", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "extract.0.source_table.0.table_id", "status.0.state"}, + ImportStateVerifyIgnore: []string{"etag", "extract.0.source_table.0.table_id", "status.0.state", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/bigquery/resource_bigquery_job_test.go b/google/services/bigquery/resource_bigquery_job_test.go index ec3e34abce0..2dfff8156e9 100644 --- a/google/services/bigquery/resource_bigquery_job_test.go +++ b/google/services/bigquery/resource_bigquery_job_test.go @@ -34,7 +34,7 @@ func TestAccBigQueryJob_withLocation(t *testing.T) { ImportStateId: importID, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "status.0.state"}, + ImportStateVerifyIgnore: []string{"etag", "status.0.state", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/bigquery/resource_bigquery_table_test.go b/google/services/bigquery/resource_bigquery_table_test.go index d4efad84397..befe8478bf8 100644 --- a/google/services/bigquery/resource_bigquery_table_test.go +++ b/google/services/bigquery/resource_bigquery_table_test.go @@ -1033,7 +1033,7 @@ func TestAccBigQueryDataTable_jsonEquivalency(t *testing.T) { ResourceName: "google_bigquery_table.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels"}, + ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels", "terraform_labels"}, }, { Config: testAccBigQueryTable_jsonEqModeRemoved(datasetID, tableID), @@ -1042,7 +1042,7 @@ func TestAccBigQueryDataTable_jsonEquivalency(t *testing.T) { ResourceName: "google_bigquery_table.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels"}, + ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels", "terraform_labels"}, }, }, }) @@ -1092,7 +1092,7 @@ func TestAccBigQueryDataTable_expandArray(t *testing.T) { ResourceName: "google_bigquery_table.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels"}, + ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels", "terraform_labels"}, }, { Config: testAccBigQueryTable_arrayExpanded(datasetID, tableID), @@ -1101,7 +1101,7 @@ func TestAccBigQueryDataTable_expandArray(t *testing.T) { ResourceName: "google_bigquery_table.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels"}, + ImportStateVerifyIgnore: []string{"etag", "last_modified_time", "deletion_protection", "labels", "terraform_labels"}, }, }, }) @@ -1125,7 +1125,7 @@ func TestAccBigQueryTable_allowDestroy(t *testing.T) { ResourceName: "google_bigquery_table.test", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"deletion_protection", "labels"}, + ImportStateVerifyIgnore: []string{"deletion_protection", "labels", "terraform_labels"}, }, { Config: testAccBigQueryTable_noAllowDestroy(datasetID, tableID), diff --git a/google/services/certificatemanager/resource_certificate_manager_certificate.go b/google/services/certificatemanager/resource_certificate_manager_certificate.go index 6cb195f38da..cc95bbe6848 100644 --- a/google/services/certificatemanager/resource_certificate_manager_certificate.go +++ b/google/services/certificatemanager/resource_certificate_manager_certificate.go @@ -66,6 +66,7 @@ func ResourceCertificateManagerCertificate() *schema.Resource { }, }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -265,6 +266,19 @@ Leaf certificate comes first, followed by intermediate ones if any.`, }, ExactlyOneOf: []string{"self_managed", "managed"}, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "project": { Type: schema.TypeString, Optional: true, @@ -290,12 +304,6 @@ func resourceCertificateManagerCertificateCreate(d *schema.ResourceData, meta in } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { obj["description"] = descriptionProp } - labelsProp, err := expandCertificateManagerCertificateLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } scopeProp, err := expandCertificateManagerCertificateScope(d.Get("scope"), d, config) if err != nil { return err @@ -314,6 +322,12 @@ func resourceCertificateManagerCertificateCreate(d *schema.ResourceData, meta in } else if v, ok := d.GetOkExists("managed"); !tpgresource.IsEmptyValue(reflect.ValueOf(managedProp)) && (ok || !reflect.DeepEqual(v, managedProp)) { obj["managed"] = managedProp } + labelsProp, err := expandCertificateManagerCertificateEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{CertificateManagerBasePath}}projects/{{project}}/locations/{{location}}/certificates?certificateId={{name}}") if err != nil { @@ -421,6 +435,12 @@ func resourceCertificateManagerCertificateRead(d *schema.ResourceData, meta inte if err := d.Set("managed", flattenCertificateManagerCertificateManaged(res["managed"], d, config)); err != nil { return fmt.Errorf("Error reading Certificate: %s", err) } + if err := d.Set("terraform_labels", flattenCertificateManagerCertificateTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Certificate: %s", err) + } + if err := d.Set("effective_labels", flattenCertificateManagerCertificateEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Certificate: %s", err) + } return nil } @@ -447,10 +467,10 @@ func resourceCertificateManagerCertificateUpdate(d *schema.ResourceData, meta in } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { obj["description"] = descriptionProp } - labelsProp, err := expandCertificateManagerCertificateLabels(d.Get("labels"), d, config) + labelsProp, err := expandCertificateManagerCertificateEffectiveLabels(d.Get("effective_labels"), d, config) if err != nil { return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { obj["labels"] = labelsProp } @@ -466,7 +486,7 @@ func resourceCertificateManagerCertificateUpdate(d *schema.ResourceData, meta in updateMask = append(updateMask, "description") } - if d.HasChange("labels") { + if d.HasChange("effective_labels") { updateMask = append(updateMask, "labels") } // updateMask is a URL parameter but not present in the schema, so ReplaceVars @@ -586,7 +606,18 @@ func flattenCertificateManagerCertificateDescription(v interface{}, d *schema.Re } func flattenCertificateManagerCertificateLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenCertificateManagerCertificateScope(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -692,19 +723,27 @@ func flattenCertificateManagerCertificateManagedAuthorizationAttemptInfoDetails( return v } -func expandCertificateManagerCertificateDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandCertificateManagerCertificateLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func flattenCertificateManagerCertificateTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { - return map[string]string{}, nil + return v } - m := make(map[string]string) - for k, val := range v.(map[string]interface{}) { - m[k] = val.(string) + + 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 m, nil + + return transformed +} + +func flattenCertificateManagerCertificateEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func expandCertificateManagerCertificateDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil } func expandCertificateManagerCertificateScope(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { @@ -930,6 +969,17 @@ func expandCertificateManagerCertificateManagedAuthorizationAttemptInfoDetails(v return v, nil } +func expandCertificateManagerCertificateEffectiveLabels(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 +} + func ResourceCertificateManagerCertificateUpgradeV0(_ context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) { log.Printf("[DEBUG] Attributes before migration: %#v", rawState) // Version 0 didn't support location. Default it to global. diff --git a/google/services/certificatemanager/resource_certificate_manager_certificate_generated_test.go b/google/services/certificatemanager/resource_certificate_manager_certificate_generated_test.go index 6fbf2706350..6bbd0d83d2c 100644 --- a/google/services/certificatemanager/resource_certificate_manager_certificate_generated_test.go +++ b/google/services/certificatemanager/resource_certificate_manager_certificate_generated_test.go @@ -49,7 +49,7 @@ func TestAccCertificateManagerCertificate_certificateManagerGoogleManagedCertifi ResourceName: "google_certificate_manager_certificate.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"self_managed", "name", "location"}, + ImportStateVerifyIgnore: []string{"self_managed", "name", "location", "labels", "terraform_labels"}, }, }, }) @@ -61,6 +61,9 @@ resource "google_certificate_manager_certificate" "default" { name = "tf-test-dns-cert%{random_suffix}" description = "The default cert" scope = "EDGE_CACHE" + labels = { + env = "test" + } managed { domains = [ google_certificate_manager_dns_authorization.instance.domain, @@ -107,7 +110,7 @@ func TestAccCertificateManagerCertificate_certificateManagerGoogleManagedCertifi ResourceName: "google_certificate_manager_certificate.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"self_managed", "name", "location"}, + ImportStateVerifyIgnore: []string{"self_managed", "name", "location", "labels", "terraform_labels"}, }, }, }) @@ -210,7 +213,7 @@ func TestAccCertificateManagerCertificate_certificateManagerSelfManagedCertifica ResourceName: "google_certificate_manager_certificate.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"self_managed", "name", "location"}, + ImportStateVerifyIgnore: []string{"self_managed", "name", "location", "labels", "terraform_labels"}, }, }, }) @@ -249,7 +252,7 @@ func TestAccCertificateManagerCertificate_certificateManagerSelfManagedCertifica ResourceName: "google_certificate_manager_certificate.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"self_managed", "name", "location"}, + ImportStateVerifyIgnore: []string{"self_managed", "name", "location", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/certificatemanager/resource_certificate_manager_certificate_issuance_config.go b/google/services/certificatemanager/resource_certificate_manager_certificate_issuance_config.go index 9fd3958aeb0..960eb0ec7b2 100644 --- a/google/services/certificatemanager/resource_certificate_manager_certificate_issuance_config.go +++ b/google/services/certificatemanager/resource_certificate_manager_certificate_issuance_config.go @@ -47,6 +47,7 @@ func ResourceCertificateManagerCertificateIssuanceConfig() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -140,6 +141,20 @@ the certificate has been issued and at least 7 days before it expires.`, accurate to nanoseconds with up to nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".`, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + ForceNew: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "update_time": { Type: schema.TypeString, Computed: true, @@ -190,18 +205,18 @@ func resourceCertificateManagerCertificateIssuanceConfigCreate(d *schema.Resourc } else if v, ok := d.GetOkExists("lifetime"); !tpgresource.IsEmptyValue(reflect.ValueOf(lifetimeProp)) && (ok || !reflect.DeepEqual(v, lifetimeProp)) { obj["lifetime"] = lifetimeProp } - labelsProp, err := expandCertificateManagerCertificateIssuanceConfigLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } certificateAuthorityConfigProp, err := expandCertificateManagerCertificateIssuanceConfigCertificateAuthorityConfig(d.Get("certificate_authority_config"), d, config) if err != nil { return err } else if v, ok := d.GetOkExists("certificate_authority_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(certificateAuthorityConfigProp)) && (ok || !reflect.DeepEqual(v, certificateAuthorityConfigProp)) { obj["certificateAuthorityConfig"] = certificateAuthorityConfigProp } + labelsProp, err := expandCertificateManagerCertificateIssuanceConfigEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{CertificateManagerBasePath}}projects/{{project}}/locations/{{location}}/certificateIssuanceConfigs?certificateIssuanceConfigId={{name}}") if err != nil { @@ -321,6 +336,12 @@ func resourceCertificateManagerCertificateIssuanceConfigRead(d *schema.ResourceD if err := d.Set("certificate_authority_config", flattenCertificateManagerCertificateIssuanceConfigCertificateAuthorityConfig(res["certificateAuthorityConfig"], d, config)); err != nil { return fmt.Errorf("Error reading CertificateIssuanceConfig: %s", err) } + if err := d.Set("terraform_labels", flattenCertificateManagerCertificateIssuanceConfigTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading CertificateIssuanceConfig: %s", err) + } + if err := d.Set("effective_labels", flattenCertificateManagerCertificateIssuanceConfigEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading CertificateIssuanceConfig: %s", err) + } return nil } @@ -436,7 +457,18 @@ func flattenCertificateManagerCertificateIssuanceConfigUpdateTime(v interface{}, } func flattenCertificateManagerCertificateIssuanceConfigLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenCertificateManagerCertificateIssuanceConfigCertificateAuthorityConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -469,6 +501,25 @@ func flattenCertificateManagerCertificateIssuanceConfigCertificateAuthorityConfi return v } +func flattenCertificateManagerCertificateIssuanceConfigTerraformLabels(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 flattenCertificateManagerCertificateIssuanceConfigEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func expandCertificateManagerCertificateIssuanceConfigDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } @@ -485,17 +536,6 @@ func expandCertificateManagerCertificateIssuanceConfigLifetime(v interface{}, d return v, nil } -func expandCertificateManagerCertificateIssuanceConfigLabels(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 -} - func expandCertificateManagerCertificateIssuanceConfigCertificateAuthorityConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { l := v.([]interface{}) if len(l) == 0 || l[0] == nil { @@ -537,3 +577,14 @@ func expandCertificateManagerCertificateIssuanceConfigCertificateAuthorityConfig func expandCertificateManagerCertificateIssuanceConfigCertificateAuthorityConfigCertificateAuthorityServiceConfigCaPool(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } + +func expandCertificateManagerCertificateIssuanceConfigEffectiveLabels(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/certificatemanager/resource_certificate_manager_certificate_issuance_config_generated_test.go b/google/services/certificatemanager/resource_certificate_manager_certificate_issuance_config_generated_test.go index f538d05fa1b..84980ece1f5 100644 --- a/google/services/certificatemanager/resource_certificate_manager_certificate_issuance_config_generated_test.go +++ b/google/services/certificatemanager/resource_certificate_manager_certificate_issuance_config_generated_test.go @@ -49,7 +49,7 @@ func TestAccCertificateManagerCertificateIssuanceConfig_certificateManagerCertif ResourceName: "google_certificate_manager_certificate_issuance_config.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/certificatemanager/resource_certificate_manager_certificate_map.go b/google/services/certificatemanager/resource_certificate_manager_certificate_map.go index c60674a5421..86468d5309f 100644 --- a/google/services/certificatemanager/resource_certificate_manager_certificate_map.go +++ b/google/services/certificatemanager/resource_certificate_manager_certificate_map.go @@ -49,6 +49,7 @@ func ResourceCertificateManagerCertificateMap() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -67,7 +68,6 @@ globally and match the pattern 'projects/*/locations/*/certificateMaps/*'.`, }, "labels": { Type: schema.TypeMap, - Computed: true, Optional: true, Description: `Set of labels associated with a Certificate Map resource.`, Elem: &schema.Schema{Type: schema.TypeString}, @@ -79,6 +79,12 @@ globally and match the pattern 'projects/*/locations/*/certificateMaps/*'.`, accurate to nanoseconds with up to nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".`, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "gclb_targets": { Type: schema.TypeList, Computed: true, @@ -124,6 +130,13 @@ This field is part of a union field 'target_proxy': Only one of 'targetHttpsProx }, }, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "update_time": { Type: schema.TypeString, Computed: true, @@ -156,10 +169,10 @@ func resourceCertificateManagerCertificateMapCreate(d *schema.ResourceData, meta } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { obj["description"] = descriptionProp } - labelsProp, err := expandCertificateManagerCertificateMapLabels(d.Get("labels"), d, config) + labelsProp, err := expandCertificateManagerCertificateMapEffectiveLabels(d.Get("effective_labels"), d, config) if err != nil { return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { obj["labels"] = labelsProp } @@ -272,6 +285,12 @@ func resourceCertificateManagerCertificateMapRead(d *schema.ResourceData, meta i if err := d.Set("gclb_targets", flattenCertificateManagerCertificateMapGclbTargets(res["gclbTargets"], d, config)); err != nil { return fmt.Errorf("Error reading CertificateMap: %s", err) } + if err := d.Set("terraform_labels", flattenCertificateManagerCertificateMapTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading CertificateMap: %s", err) + } + if err := d.Set("effective_labels", flattenCertificateManagerCertificateMapEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading CertificateMap: %s", err) + } return nil } @@ -298,10 +317,10 @@ func resourceCertificateManagerCertificateMapUpdate(d *schema.ResourceData, meta } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { obj["description"] = descriptionProp } - labelsProp, err := expandCertificateManagerCertificateMapLabels(d.Get("labels"), d, config) + labelsProp, err := expandCertificateManagerCertificateMapEffectiveLabels(d.Get("effective_labels"), d, config) if err != nil { return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { obj["labels"] = labelsProp } @@ -317,7 +336,7 @@ func resourceCertificateManagerCertificateMapUpdate(d *schema.ResourceData, meta updateMask = append(updateMask, "description") } - if d.HasChange("labels") { + if d.HasChange("effective_labels") { updateMask = append(updateMask, "labels") } // updateMask is a URL parameter but not present in the schema, so ReplaceVars @@ -445,7 +464,18 @@ func flattenCertificateManagerCertificateMapUpdateTime(v interface{}, d *schema. } func flattenCertificateManagerCertificateMapLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenCertificateManagerCertificateMapGclbTargets(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -503,11 +533,30 @@ func flattenCertificateManagerCertificateMapGclbTargetsTargetSslProxy(v interfac return v } +func flattenCertificateManagerCertificateMapTerraformLabels(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 flattenCertificateManagerCertificateMapEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func expandCertificateManagerCertificateMapDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } -func expandCertificateManagerCertificateMapLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func expandCertificateManagerCertificateMapEffectiveLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { if v == nil { return map[string]string{}, nil } diff --git a/google/services/certificatemanager/resource_certificate_manager_certificate_map_entry.go b/google/services/certificatemanager/resource_certificate_manager_certificate_map_entry.go index 93dbf9ff95d..5c351ea3bec 100644 --- a/google/services/certificatemanager/resource_certificate_manager_certificate_map_entry.go +++ b/google/services/certificatemanager/resource_certificate_manager_certificate_map_entry.go @@ -49,6 +49,7 @@ func ResourceCertificateManagerCertificateMapEntry() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -95,7 +96,6 @@ selecting a proper certificate.`, }, "labels": { Type: schema.TypeMap, - Computed: true, Optional: true, Description: `Set of labels associated with a Certificate Map Entry. An object containing a list of "key": value pairs. @@ -116,11 +116,24 @@ Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.`, with nanosecond resolution and up to nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".`, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "state": { Type: schema.TypeString, Computed: true, Description: `A serving state of this Certificate Map Entry.`, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "update_time": { Type: schema.TypeString, Computed: true, @@ -153,12 +166,6 @@ func resourceCertificateManagerCertificateMapEntryCreate(d *schema.ResourceData, } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { obj["description"] = descriptionProp } - labelsProp, err := expandCertificateManagerCertificateMapEntryLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } certificatesProp, err := expandCertificateManagerCertificateMapEntryCertificates(d.Get("certificates"), d, config) if err != nil { return err @@ -177,6 +184,12 @@ func resourceCertificateManagerCertificateMapEntryCreate(d *schema.ResourceData, } else if v, ok := d.GetOkExists("matcher"); !tpgresource.IsEmptyValue(reflect.ValueOf(matcherProp)) && (ok || !reflect.DeepEqual(v, matcherProp)) { obj["matcher"] = matcherProp } + labelsProp, err := expandCertificateManagerCertificateMapEntryEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } nameProp, err := expandCertificateManagerCertificateMapEntryName(d.Get("name"), d, config) if err != nil { return err @@ -302,6 +315,12 @@ func resourceCertificateManagerCertificateMapEntryRead(d *schema.ResourceData, m if err := d.Set("matcher", flattenCertificateManagerCertificateMapEntryMatcher(res["matcher"], d, config)); err != nil { return fmt.Errorf("Error reading CertificateMapEntry: %s", err) } + if err := d.Set("terraform_labels", flattenCertificateManagerCertificateMapEntryTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading CertificateMapEntry: %s", err) + } + if err := d.Set("effective_labels", flattenCertificateManagerCertificateMapEntryEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading CertificateMapEntry: %s", err) + } if err := d.Set("name", flattenCertificateManagerCertificateMapEntryName(res["name"], d, config)); err != nil { return fmt.Errorf("Error reading CertificateMapEntry: %s", err) } @@ -331,18 +350,18 @@ func resourceCertificateManagerCertificateMapEntryUpdate(d *schema.ResourceData, } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { obj["description"] = descriptionProp } - labelsProp, err := expandCertificateManagerCertificateMapEntryLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } certificatesProp, err := expandCertificateManagerCertificateMapEntryCertificates(d.Get("certificates"), d, config) if err != nil { return err } else if v, ok := d.GetOkExists("certificates"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, certificatesProp)) { obj["certificates"] = certificatesProp } + labelsProp, err := expandCertificateManagerCertificateMapEntryEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{CertificateManagerBasePath}}projects/{{project}}/locations/global/certificateMaps/{{map}}/certificateMapEntries/{{name}}") if err != nil { @@ -356,13 +375,13 @@ func resourceCertificateManagerCertificateMapEntryUpdate(d *schema.ResourceData, updateMask = append(updateMask, "description") } - if d.HasChange("labels") { - updateMask = append(updateMask, "labels") - } - if d.HasChange("certificates") { updateMask = append(updateMask, "certificates") } + + if d.HasChange("effective_labels") { + updateMask = append(updateMask, "labels") + } // updateMask is a URL parameter but not present in the schema, so ReplaceVars // won't set it url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -488,7 +507,18 @@ func flattenCertificateManagerCertificateMapEntryUpdateTime(v interface{}, d *sc } func flattenCertificateManagerCertificateMapEntryLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenCertificateManagerCertificateMapEntryCertificates(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -507,26 +537,34 @@ func flattenCertificateManagerCertificateMapEntryMatcher(v interface{}, d *schem return v } -func flattenCertificateManagerCertificateMapEntryName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { +func flattenCertificateManagerCertificateMapEntryTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { return v } - return tpgresource.NameFromSelfLinkStateFunc(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 expandCertificateManagerCertificateMapEntryDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil +func flattenCertificateManagerCertificateMapEntryEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v } -func expandCertificateManagerCertificateMapEntryLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func flattenCertificateManagerCertificateMapEntryName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { 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 v } - return m, nil + return tpgresource.NameFromSelfLinkStateFunc(v) +} + +func expandCertificateManagerCertificateMapEntryDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil } func expandCertificateManagerCertificateMapEntryCertificates(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { @@ -541,6 +579,17 @@ func expandCertificateManagerCertificateMapEntryMatcher(v interface{}, d tpgreso return v, nil } +func expandCertificateManagerCertificateMapEntryEffectiveLabels(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 +} + func expandCertificateManagerCertificateMapEntryName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return tpgresource.GetResourceNameFromSelfLink(v.(string)), nil } diff --git a/google/services/certificatemanager/resource_certificate_manager_certificate_map_entry_generated_test.go b/google/services/certificatemanager/resource_certificate_manager_certificate_map_entry_generated_test.go index bde7bf4c59e..45099b9f2c8 100644 --- a/google/services/certificatemanager/resource_certificate_manager_certificate_map_entry_generated_test.go +++ b/google/services/certificatemanager/resource_certificate_manager_certificate_map_entry_generated_test.go @@ -49,7 +49,7 @@ func TestAccCertificateManagerCertificateMapEntry_certificateManagerCertificateM ResourceName: "google_certificate_manager_certificate_map_entry.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"map"}, + ImportStateVerifyIgnore: []string{"map", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/certificatemanager/resource_certificate_manager_certificate_map_generated_test.go b/google/services/certificatemanager/resource_certificate_manager_certificate_map_generated_test.go index 211a1d38017..a16f47095b1 100644 --- a/google/services/certificatemanager/resource_certificate_manager_certificate_map_generated_test.go +++ b/google/services/certificatemanager/resource_certificate_manager_certificate_map_generated_test.go @@ -49,7 +49,7 @@ func TestAccCertificateManagerCertificateMap_certificateManagerCertificateMapBas ResourceName: "google_certificate_manager_certificate_map.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name"}, + ImportStateVerifyIgnore: []string{"name", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/certificatemanager/resource_certificate_manager_dns_authorization.go b/google/services/certificatemanager/resource_certificate_manager_dns_authorization.go index ae99c8e2786..af960b07b71 100644 --- a/google/services/certificatemanager/resource_certificate_manager_dns_authorization.go +++ b/google/services/certificatemanager/resource_certificate_manager_dns_authorization.go @@ -49,6 +49,7 @@ func ResourceCertificateManagerDnsAuthorization() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -107,6 +108,19 @@ E.g. '_acme-challenge.example.com'.`, }, }, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "project": { Type: schema.TypeString, Optional: true, @@ -132,18 +146,18 @@ func resourceCertificateManagerDnsAuthorizationCreate(d *schema.ResourceData, me } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { obj["description"] = descriptionProp } - labelsProp, err := expandCertificateManagerDnsAuthorizationLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } domainProp, err := expandCertificateManagerDnsAuthorizationDomain(d.Get("domain"), d, config) if err != nil { return err } else if v, ok := d.GetOkExists("domain"); !tpgresource.IsEmptyValue(reflect.ValueOf(domainProp)) && (ok || !reflect.DeepEqual(v, domainProp)) { obj["domain"] = domainProp } + labelsProp, err := expandCertificateManagerDnsAuthorizationEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{CertificateManagerBasePath}}projects/{{project}}/locations/global/dnsAuthorizations?dnsAuthorizationId={{name}}") if err != nil { @@ -251,6 +265,12 @@ func resourceCertificateManagerDnsAuthorizationRead(d *schema.ResourceData, meta if err := d.Set("dns_resource_record", flattenCertificateManagerDnsAuthorizationDnsResourceRecord(res["dnsResourceRecord"], d, config)); err != nil { return fmt.Errorf("Error reading DnsAuthorization: %s", err) } + if err := d.Set("terraform_labels", flattenCertificateManagerDnsAuthorizationTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading DnsAuthorization: %s", err) + } + if err := d.Set("effective_labels", flattenCertificateManagerDnsAuthorizationEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading DnsAuthorization: %s", err) + } return nil } @@ -277,10 +297,10 @@ func resourceCertificateManagerDnsAuthorizationUpdate(d *schema.ResourceData, me } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { obj["description"] = descriptionProp } - labelsProp, err := expandCertificateManagerDnsAuthorizationLabels(d.Get("labels"), d, config) + labelsProp, err := expandCertificateManagerDnsAuthorizationEffectiveLabels(d.Get("effective_labels"), d, config) if err != nil { return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { obj["labels"] = labelsProp } @@ -296,7 +316,7 @@ func resourceCertificateManagerDnsAuthorizationUpdate(d *schema.ResourceData, me updateMask = append(updateMask, "description") } - if d.HasChange("labels") { + if d.HasChange("effective_labels") { updateMask = append(updateMask, "labels") } // updateMask is a URL parameter but not present in the schema, so ReplaceVars @@ -416,7 +436,18 @@ func flattenCertificateManagerDnsAuthorizationDescription(v interface{}, d *sche } func flattenCertificateManagerDnsAuthorizationLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenCertificateManagerDnsAuthorizationDomain(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -452,11 +483,34 @@ func flattenCertificateManagerDnsAuthorizationDnsResourceRecordData(v interface{ return v } +func flattenCertificateManagerDnsAuthorizationTerraformLabels(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 flattenCertificateManagerDnsAuthorizationEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func expandCertificateManagerDnsAuthorizationDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } -func expandCertificateManagerDnsAuthorizationLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func expandCertificateManagerDnsAuthorizationDomain(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandCertificateManagerDnsAuthorizationEffectiveLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { if v == nil { return map[string]string{}, nil } @@ -466,7 +520,3 @@ func expandCertificateManagerDnsAuthorizationLabels(v interface{}, d tpgresource } return m, nil } - -func expandCertificateManagerDnsAuthorizationDomain(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} diff --git a/google/services/certificatemanager/resource_certificate_manager_dns_authorization_generated_test.go b/google/services/certificatemanager/resource_certificate_manager_dns_authorization_generated_test.go index b5c1afcb67c..e1b25407cd7 100644 --- a/google/services/certificatemanager/resource_certificate_manager_dns_authorization_generated_test.go +++ b/google/services/certificatemanager/resource_certificate_manager_dns_authorization_generated_test.go @@ -49,7 +49,7 @@ func TestAccCertificateManagerDnsAuthorization_certificateManagerDnsAuthorizatio ResourceName: "google_certificate_manager_dns_authorization.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name"}, + ImportStateVerifyIgnore: []string{"name", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/certificatemanager/resource_certificate_manager_dns_authorization_test.go b/google/services/certificatemanager/resource_certificate_manager_dns_authorization_test.go index e6f985f2cce..1dfd8cdd317 100644 --- a/google/services/certificatemanager/resource_certificate_manager_dns_authorization_test.go +++ b/google/services/certificatemanager/resource_certificate_manager_dns_authorization_test.go @@ -28,7 +28,7 @@ func TestAccCertificateManagerDnsAuthorization_update(t *testing.T) { ResourceName: "google_certificate_manager_dns_authorization.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name"}, + ImportStateVerifyIgnore: []string{"name", "labels", "terraform_labels"}, }, { Config: testAccCertificateManagerDnsAuthorization_update1(context), @@ -37,7 +37,7 @@ func TestAccCertificateManagerDnsAuthorization_update(t *testing.T) { ResourceName: "google_certificate_manager_dns_authorization.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name"}, + ImportStateVerifyIgnore: []string{"name", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/certificatemanager/resource_certificate_manager_trust_config.go b/google/services/certificatemanager/resource_certificate_manager_trust_config.go index b5914658788..e1f2d016244 100644 --- a/google/services/certificatemanager/resource_certificate_manager_trust_config.go +++ b/google/services/certificatemanager/resource_certificate_manager_trust_config.go @@ -48,6 +48,7 @@ func ResourceCertificateManagerTrustConfig() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -127,6 +128,20 @@ Each certificate provided in PEM format may occupy up to 5kB.`, A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".`, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + ForceNew: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "update_time": { Type: schema.TypeString, Computed: true, @@ -154,12 +169,6 @@ func resourceCertificateManagerTrustConfigCreate(d *schema.ResourceData, meta in } obj := make(map[string]interface{}) - labelsProp, err := expandCertificateManagerTrustConfigLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } descriptionProp, err := expandCertificateManagerTrustConfigDescription(d.Get("description"), d, config) if err != nil { return err @@ -172,6 +181,12 @@ func resourceCertificateManagerTrustConfigCreate(d *schema.ResourceData, meta in } else if v, ok := d.GetOkExists("trust_stores"); !tpgresource.IsEmptyValue(reflect.ValueOf(trustStoresProp)) && (ok || !reflect.DeepEqual(v, trustStoresProp)) { obj["trustStores"] = trustStoresProp } + labelsProp, err := expandCertificateManagerTrustConfigEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{CertificateManagerBasePath}}projects/{{project}}/locations/{{location}}/trustConfigs?trustConfigId={{name}}") if err != nil { @@ -282,6 +297,12 @@ func resourceCertificateManagerTrustConfigRead(d *schema.ResourceData, meta inte if err := d.Set("trust_stores", flattenCertificateManagerTrustConfigTrustStores(res["trustStores"], d, config)); err != nil { return fmt.Errorf("Error reading TrustConfig: %s", err) } + if err := d.Set("terraform_labels", flattenCertificateManagerTrustConfigTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading TrustConfig: %s", err) + } + if err := d.Set("effective_labels", flattenCertificateManagerTrustConfigEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading TrustConfig: %s", err) + } return nil } @@ -440,7 +461,18 @@ func flattenCertificateManagerTrustConfigUpdateTime(v interface{}, d *schema.Res } func flattenCertificateManagerTrustConfigLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenCertificateManagerTrustConfigDescription(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -510,15 +542,23 @@ func flattenCertificateManagerTrustConfigTrustStoresIntermediateCasPemCertificat return v } -func expandCertificateManagerTrustConfigLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func flattenCertificateManagerTrustConfigTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { - return map[string]string{}, nil + return v } - m := make(map[string]string) - for k, val := range v.(map[string]interface{}) { - m[k] = val.(string) + + 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 m, nil + + return transformed +} + +func flattenCertificateManagerTrustConfigEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v } func expandCertificateManagerTrustConfigDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { @@ -605,3 +645,14 @@ func expandCertificateManagerTrustConfigTrustStoresIntermediateCas(v interface{} func expandCertificateManagerTrustConfigTrustStoresIntermediateCasPemCertificate(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } + +func expandCertificateManagerTrustConfigEffectiveLabels(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/certificatemanager/resource_certificate_manager_trust_config_generated_test.go b/google/services/certificatemanager/resource_certificate_manager_trust_config_generated_test.go index 9e338217d02..b4276418ef4 100644 --- a/google/services/certificatemanager/resource_certificate_manager_trust_config_generated_test.go +++ b/google/services/certificatemanager/resource_certificate_manager_trust_config_generated_test.go @@ -49,7 +49,7 @@ func TestAccCertificateManagerTrustConfig_certificateManagerTrustConfigExample(t ResourceName: "google_certificate_manager_trust_config.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/certificatemanager/resource_certificate_manager_trust_config_test.go b/google/services/certificatemanager/resource_certificate_manager_trust_config_test.go index b0e7773e665..17b32795f90 100644 --- a/google/services/certificatemanager/resource_certificate_manager_trust_config_test.go +++ b/google/services/certificatemanager/resource_certificate_manager_trust_config_test.go @@ -25,17 +25,19 @@ func TestAccCertificateManagerTrustConfig_update(t *testing.T) { Config: testAccCertificateManagerTrustConfig_update0(context), }, { - ResourceName: "google_certificate_manager_trust_config.default", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_certificate_manager_trust_config.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, { Config: testAccCertificateManagerTrustConfig_update1(context), }, { - ResourceName: "google_certificate_manager_trust_config.default", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_certificate_manager_trust_config.default", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, }, }) diff --git a/google/services/cloudfunctions/resource_cloudfunctions_function_test.go b/google/services/cloudfunctions/resource_cloudfunctions_function_test.go index 0551b66d454..5949bf0bc88 100644 --- a/google/services/cloudfunctions/resource_cloudfunctions_function_test.go +++ b/google/services/cloudfunctions/resource_cloudfunctions_function_test.go @@ -81,7 +81,7 @@ func TestAccCloudFunctionsFunction_basic(t *testing.T) { ResourceName: funcResourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"build_environment_variables", "labels"}, + ImportStateVerifyIgnore: []string{"build_environment_variables", "labels", "terraform_labels"}, }, }, }) @@ -118,7 +118,7 @@ func TestAccCloudFunctionsFunction_update(t *testing.T) { ResourceName: funcResourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"build_environment_variables", "labels"}, + ImportStateVerifyIgnore: []string{"build_environment_variables", "labels", "terraform_labels"}, }, { Config: testAccCloudFunctionsFunction_updated(functionName, bucketName, zipFileUpdatePath, random_suffix), @@ -151,7 +151,7 @@ func TestAccCloudFunctionsFunction_update(t *testing.T) { ResourceName: funcResourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"build_environment_variables", "labels"}, + ImportStateVerifyIgnore: []string{"build_environment_variables", "labels", "terraform_labels"}, }, }, }) @@ -367,7 +367,7 @@ func TestAccCloudFunctionsFunction_vpcConnector(t *testing.T) { ResourceName: funcResourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"build_environment_variables", "labels"}, + ImportStateVerifyIgnore: []string{"build_environment_variables", "labels", "terraform_labels"}, }, { Config: testAccCloudFunctionsFunction_vpcConnector(projectNumber, networkName, functionName, bucketName, zipFilePath, "10.20.0.0/28", vpcConnectorName+"-update"), @@ -376,7 +376,7 @@ func TestAccCloudFunctionsFunction_vpcConnector(t *testing.T) { ResourceName: funcResourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"build_environment_variables", "labels"}, + ImportStateVerifyIgnore: []string{"build_environment_variables", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/cloudfunctions2/data_source_google_cloudfunctions2_function_test.go b/google/services/cloudfunctions2/data_source_google_cloudfunctions2_function_test.go index b851c22d40b..7c8ea3704e8 100644 --- a/google/services/cloudfunctions2/data_source_google_cloudfunctions2_function_test.go +++ b/google/services/cloudfunctions2/data_source_google_cloudfunctions2_function_test.go @@ -26,9 +26,11 @@ func TestAccDataSourceGoogleCloudFunctions2Function_basic(t *testing.T) { { Config: testAccDataSourceGoogleCloudFunctions2FunctionConfig(functionName, bucketName, zipFilePath), + // As the value of "labels" and "terraform_labels" in the state is dependent on the configuration, + // and these fields are not set in the configuration of the data source, so these fields are empty in the state of the data source. Check: resource.ComposeTestCheckFunc( acctest.CheckDataSourceStateMatchesResourceStateWithIgnores(funcDataNameHttp, - "google_cloudfunctions2_function.function_http_v2", map[string]struct{}{"build_config.0.source.0.storage_source.0.bucket": {}, "build_config.0.source.0.storage_source.0.object": {}}), + "google_cloudfunctions2_function.function_http_v2", map[string]struct{}{"build_config.0.source.0.storage_source.0.bucket": {}, "build_config.0.source.0.storage_source.0.object": {}, "labels.%": {}, "terraform_labels.%": {}}), ), }, }, @@ -37,6 +39,12 @@ func TestAccDataSourceGoogleCloudFunctions2Function_basic(t *testing.T) { func testAccDataSourceGoogleCloudFunctions2FunctionConfig(functionName, bucketName, zipFilePath string) string { return fmt.Sprintf(` +provider "google" { + default_labels = { + default_key1 = "default_value1" + } +} + resource "google_storage_bucket" "bucket" { name = "%s" location = "US" @@ -52,7 +60,9 @@ resource "google_cloudfunctions2_function" "function_http_v2" { name = "%s" location = "us-central1" description = "a new function" - + labels = { + env = "test" + } build_config { runtime = "nodejs12" entry_point = "helloHttp" diff --git a/google/services/cloudfunctions2/resource_cloudfunctions2_function.go b/google/services/cloudfunctions2/resource_cloudfunctions2_function.go index 973734342a1..69785288e60 100644 --- a/google/services/cloudfunctions2/resource_cloudfunctions2_function.go +++ b/google/services/cloudfunctions2/resource_cloudfunctions2_function.go @@ -50,6 +50,7 @@ func ResourceCloudfunctions2function() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -455,6 +456,12 @@ timeout period. Defaults to 60 seconds.`, }, }, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "environment": { Type: schema.TypeString, Computed: true, @@ -465,6 +472,13 @@ timeout period. Defaults to 60 seconds.`, Computed: true, Description: `Describes the current state of the function.`, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "update_time": { Type: schema.TypeString, Computed: true, @@ -553,18 +567,18 @@ func resourceCloudfunctions2functionCreate(d *schema.ResourceData, meta interfac } else if v, ok := d.GetOkExists("event_trigger"); !tpgresource.IsEmptyValue(reflect.ValueOf(eventTriggerProp)) && (ok || !reflect.DeepEqual(v, eventTriggerProp)) { obj["eventTrigger"] = eventTriggerProp } - labelsProp, err := expandCloudfunctions2functionLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } kmsKeyNameProp, err := expandCloudfunctions2functionKmsKeyName(d.Get("kms_key_name"), d, config) if err != nil { return err } else if v, ok := d.GetOkExists("kms_key_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(kmsKeyNameProp)) && (ok || !reflect.DeepEqual(v, kmsKeyNameProp)) { obj["kmsKeyName"] = kmsKeyNameProp } + labelsProp, err := expandCloudfunctions2functionEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{Cloudfunctions2BasePath}}projects/{{project}}/locations/{{location}}/functions?functionId={{name}}") if err != nil { @@ -704,6 +718,12 @@ func resourceCloudfunctions2functionRead(d *schema.ResourceData, meta interface{ if err := d.Set("kms_key_name", flattenCloudfunctions2functionKmsKeyName(res["kmsKeyName"], d, config)); err != nil { return fmt.Errorf("Error reading function: %s", err) } + if err := d.Set("terraform_labels", flattenCloudfunctions2functionTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading function: %s", err) + } + if err := d.Set("effective_labels", flattenCloudfunctions2functionEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading function: %s", err) + } return nil } @@ -748,18 +768,18 @@ func resourceCloudfunctions2functionUpdate(d *schema.ResourceData, meta interfac } else if v, ok := d.GetOkExists("event_trigger"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, eventTriggerProp)) { obj["eventTrigger"] = eventTriggerProp } - labelsProp, err := expandCloudfunctions2functionLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } kmsKeyNameProp, err := expandCloudfunctions2functionKmsKeyName(d.Get("kms_key_name"), d, config) if err != nil { return err } else if v, ok := d.GetOkExists("kms_key_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, kmsKeyNameProp)) { obj["kmsKeyName"] = kmsKeyNameProp } + labelsProp, err := expandCloudfunctions2functionEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{Cloudfunctions2BasePath}}projects/{{project}}/locations/{{location}}/functions/{{name}}") if err != nil { @@ -785,13 +805,13 @@ func resourceCloudfunctions2functionUpdate(d *schema.ResourceData, meta interfac updateMask = append(updateMask, "eventTrigger") } - if d.HasChange("labels") { - updateMask = append(updateMask, "labels") - } - if d.HasChange("kms_key_name") { updateMask = append(updateMask, "kmsKeyName") } + + if d.HasChange("effective_labels") { + updateMask = append(updateMask, "labels") + } // updateMask is a URL parameter but not present in the schema, so ReplaceVars // won't set it url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -1453,13 +1473,43 @@ func flattenCloudfunctions2functionUpdateTime(v interface{}, d *schema.ResourceD } func flattenCloudfunctions2functionLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenCloudfunctions2functionKmsKeyName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { return v } +func flattenCloudfunctions2functionTerraformLabels(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 flattenCloudfunctions2functionEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func expandCloudfunctions2functionName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/functions/{{name}}") } @@ -2203,7 +2253,11 @@ func expandCloudfunctions2functionEventTriggerRetryPolicy(v interface{}, d tpgre return v, nil } -func expandCloudfunctions2functionLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func expandCloudfunctions2functionKmsKeyName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandCloudfunctions2functionEffectiveLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { if v == nil { return map[string]string{}, nil } @@ -2213,7 +2267,3 @@ func expandCloudfunctions2functionLabels(v interface{}, d tpgresource.TerraformR } return m, nil } - -func expandCloudfunctions2functionKmsKeyName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} diff --git a/google/services/cloudfunctions2/resource_cloudfunctions2_function_generated_test.go b/google/services/cloudfunctions2/resource_cloudfunctions2_function_generated_test.go index d61ed091b0c..c0a426ff3d0 100644 --- a/google/services/cloudfunctions2/resource_cloudfunctions2_function_generated_test.go +++ b/google/services/cloudfunctions2/resource_cloudfunctions2_function_generated_test.go @@ -53,7 +53,7 @@ func TestAccCloudfunctions2function_cloudfunctions2BasicExample(t *testing.T) { ResourceName: "google_cloudfunctions2_function.function", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket"}, + ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket", "labels", "terraform_labels"}, }, }, }) @@ -129,7 +129,7 @@ func TestAccCloudfunctions2function_cloudfunctions2FullExample(t *testing.T) { ResourceName: "google_cloudfunctions2_function.function", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket"}, + ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket", "labels", "terraform_labels"}, }, }, }) @@ -229,7 +229,7 @@ func TestAccCloudfunctions2function_cloudfunctions2BasicGcsExample(t *testing.T) ResourceName: "google_cloudfunctions2_function.function", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket"}, + ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket", "labels", "terraform_labels"}, }, }, }) @@ -366,7 +366,7 @@ func TestAccCloudfunctions2function_cloudfunctions2BasicAuditlogsExample(t *test ResourceName: "google_cloudfunctions2_function.function", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket"}, + ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket", "labels", "terraform_labels"}, }, }, }) @@ -508,7 +508,7 @@ func TestAccCloudfunctions2function_cloudfunctions2SecretEnvExample(t *testing.T ResourceName: "google_cloudfunctions2_function.function", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket"}, + ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket", "labels", "terraform_labels"}, }, }, }) @@ -607,7 +607,7 @@ func TestAccCloudfunctions2function_cloudfunctions2SecretVolumeExample(t *testin ResourceName: "google_cloudfunctions2_function.function", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket"}, + ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket", "labels", "terraform_labels"}, }, }, }) @@ -704,7 +704,7 @@ func TestAccCloudfunctions2function_cloudfunctions2PrivateWorkerpoolExample(t *t ResourceName: "google_cloudfunctions2_function.function", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket"}, + ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/cloudfunctions2/resource_cloudfunctions2_function_test.go b/google/services/cloudfunctions2/resource_cloudfunctions2_function_test.go index e85e419cf5f..eb5e31432cf 100644 --- a/google/services/cloudfunctions2/resource_cloudfunctions2_function_test.go +++ b/google/services/cloudfunctions2/resource_cloudfunctions2_function_test.go @@ -30,7 +30,7 @@ func TestAccCloudFunctions2Function_update(t *testing.T) { ResourceName: "google_cloudfunctions2_function.terraform-test2", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket"}, + ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket", "labels", "terraform_labels"}, }, { Config: testAccCloudFunctions2Function_test_update(context), @@ -39,7 +39,7 @@ func TestAccCloudFunctions2Function_update(t *testing.T) { ResourceName: "google_cloudfunctions2_function.terraform-test2", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket"}, + ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket", "labels", "terraform_labels"}, }, { Config: testAccCloudFunctions2Function_test_redeploy(context), @@ -48,7 +48,7 @@ func TestAccCloudFunctions2Function_update(t *testing.T) { ResourceName: "google_cloudfunctions2_function.terraform-test2", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket"}, + ImportStateVerifyIgnore: []string{"location", "build_config.0.source.0.storage_source.0.object", "build_config.0.source.0.storage_source.0.bucket", "labels", "terraform_labels"}, }, }, }) @@ -72,6 +72,9 @@ resource "google_cloudfunctions2_function" "terraform-test2" { name = "tf-test-test-function%{random_suffix}" location = "us-central1" description = "a new function" + labels = { + env = "test" + } build_config { runtime = "nodejs12" @@ -111,7 +114,10 @@ resource "google_cloudfunctions2_function" "terraform-test2" { name = "tf-test-test-function%{random_suffix}" location = "us-central1" description = "an updated function" - + labels = { + env = "test-update" + } + build_config { runtime = "nodejs12" entry_point = "helloHttp" diff --git a/google/services/cloudrunv2/resource_cloud_run_v2_job.go b/google/services/cloudrunv2/resource_cloud_run_v2_job.go index b2c1b402f9b..4acb04b6190 100644 --- a/google/services/cloudrunv2/resource_cloud_run_v2_job.go +++ b/google/services/cloudrunv2/resource_cloud_run_v2_job.go @@ -49,6 +49,7 @@ func ResourceCloudRunV2Job() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.SetAnnotationsDiff, tpgresource.DefaultProviderProject, ), @@ -531,6 +532,12 @@ A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to n Description: `All of annotations (key/value pairs) present on the resource in GCP, including the annotations configured through Terraform, other clients and services.`, Elem: &schema.Schema{Type: schema.TypeString}, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "etag": { Type: schema.TypeString, Computed: true, @@ -651,6 +658,13 @@ A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to n }, }, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "uid": { Type: schema.TypeString, Computed: true, @@ -680,12 +694,6 @@ func resourceCloudRunV2JobCreate(d *schema.ResourceData, meta interface{}) error } obj := make(map[string]interface{}) - labelsProp, err := expandCloudRunV2JobLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } clientProp, err := expandCloudRunV2JobClient(d.Get("client"), d, config) if err != nil { return err @@ -716,6 +724,12 @@ func resourceCloudRunV2JobCreate(d *schema.ResourceData, meta interface{}) error } else if v, ok := d.GetOkExists("template"); !tpgresource.IsEmptyValue(reflect.ValueOf(templateProp)) && (ok || !reflect.DeepEqual(v, templateProp)) { obj["template"] = templateProp } + labelsProp, err := expandCloudRunV2JobEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } annotationsProp, err := expandCloudRunV2JobEffectiveAnnotations(d.Get("effective_annotations"), d, config) if err != nil { return err @@ -893,6 +907,12 @@ func resourceCloudRunV2JobRead(d *schema.ResourceData, meta interface{}) error { if err := d.Set("etag", flattenCloudRunV2JobEtag(res["etag"], d, config)); err != nil { return fmt.Errorf("Error reading Job: %s", err) } + if err := d.Set("terraform_labels", flattenCloudRunV2JobTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Job: %s", err) + } + if err := d.Set("effective_labels", flattenCloudRunV2JobEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Job: %s", err) + } if err := d.Set("effective_annotations", flattenCloudRunV2JobEffectiveAnnotations(res["annotations"], d, config)); err != nil { return fmt.Errorf("Error reading Job: %s", err) } @@ -916,12 +936,6 @@ func resourceCloudRunV2JobUpdate(d *schema.ResourceData, meta interface{}) error billingProject = project obj := make(map[string]interface{}) - labelsProp, err := expandCloudRunV2JobLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } clientProp, err := expandCloudRunV2JobClient(d.Get("client"), d, config) if err != nil { return err @@ -952,6 +966,12 @@ func resourceCloudRunV2JobUpdate(d *schema.ResourceData, meta interface{}) error } else if v, ok := d.GetOkExists("template"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, templateProp)) { obj["template"] = templateProp } + labelsProp, err := expandCloudRunV2JobEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } annotationsProp, err := expandCloudRunV2JobEffectiveAnnotations(d.Get("effective_annotations"), d, config) if err != nil { return err @@ -1080,7 +1100,18 @@ func flattenCloudRunV2JobGeneration(v interface{}, d *schema.ResourceData, confi } func flattenCloudRunV2JobLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenCloudRunV2JobAnnotations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -1795,19 +1826,27 @@ func flattenCloudRunV2JobEtag(v interface{}, d *schema.ResourceData, config *tra return v } -func flattenCloudRunV2JobEffectiveAnnotations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v -} - -func expandCloudRunV2JobLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func flattenCloudRunV2JobTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { - return map[string]string{}, nil + return v } - m := make(map[string]string) - for k, val := range v.(map[string]interface{}) { - m[k] = val.(string) + + 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 m, nil + + return transformed +} + +func flattenCloudRunV2JobEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenCloudRunV2JobEffectiveAnnotations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v } func expandCloudRunV2JobClient(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { @@ -2506,6 +2545,17 @@ func expandCloudRunV2JobTemplateTemplateMaxRetries(v interface{}, d tpgresource. return v, nil } +func expandCloudRunV2JobEffectiveLabels(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 +} + func expandCloudRunV2JobEffectiveAnnotations(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { if v == nil { return map[string]string{}, nil diff --git a/google/services/cloudrunv2/resource_cloud_run_v2_job_generated_test.go b/google/services/cloudrunv2/resource_cloud_run_v2_job_generated_test.go index 966d0b917ef..b2e2aac5b01 100644 --- a/google/services/cloudrunv2/resource_cloud_run_v2_job_generated_test.go +++ b/google/services/cloudrunv2/resource_cloud_run_v2_job_generated_test.go @@ -49,7 +49,7 @@ func TestAccCloudRunV2Job_cloudrunv2JobBasicExample(t *testing.T) { ResourceName: "google_cloud_run_v2_job.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "annotations", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "labels", "annotations", "terraform_labels"}, }, }, }) @@ -98,7 +98,7 @@ func TestAccCloudRunV2Job_cloudrunv2JobSqlExample(t *testing.T) { ResourceName: "google_cloud_run_v2_job.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "annotations", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "labels", "annotations", "terraform_labels"}, }, }, }) @@ -204,7 +204,7 @@ func TestAccCloudRunV2Job_cloudrunv2JobVpcaccessExample(t *testing.T) { ResourceName: "google_cloud_run_v2_job.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "annotations", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "labels", "annotations", "terraform_labels"}, }, }, }) @@ -277,7 +277,7 @@ func TestAccCloudRunV2Job_cloudrunv2JobSecretExample(t *testing.T) { ResourceName: "google_cloud_run_v2_job.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "annotations", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "labels", "annotations", "terraform_labels"}, }, }, }) diff --git a/google/services/cloudrunv2/resource_cloud_run_v2_job_test.go b/google/services/cloudrunv2/resource_cloud_run_v2_job_test.go index 1d02b88778e..89e06729030 100644 --- a/google/services/cloudrunv2/resource_cloud_run_v2_job_test.go +++ b/google/services/cloudrunv2/resource_cloud_run_v2_job_test.go @@ -28,7 +28,7 @@ func TestAccCloudRunV2Job_cloudrunv2JobFullUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_job.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "launch_stage", "annotations"}, + ImportStateVerifyIgnore: []string{"location", "launch_stage", "labels", "terraform_labels", "annotations"}, }, { Config: testAccCloudRunV2Job_cloudrunv2JobFullUpdate(context), @@ -37,7 +37,7 @@ func TestAccCloudRunV2Job_cloudrunv2JobFullUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_job.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "launch_stage", "annotations"}, + ImportStateVerifyIgnore: []string{"location", "launch_stage", "labels", "terraform_labels", "annotations"}, }, }, }) diff --git a/google/services/cloudrunv2/resource_cloud_run_v2_service.go b/google/services/cloudrunv2/resource_cloud_run_v2_service.go index f59cb0f8dbf..80d26885d12 100644 --- a/google/services/cloudrunv2/resource_cloud_run_v2_service.go +++ b/google/services/cloudrunv2/resource_cloud_run_v2_service.go @@ -49,6 +49,7 @@ func ResourceCloudRunV2Service() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.SetAnnotationsDiff, tpgresource.DefaultProviderProject, ), @@ -815,6 +816,12 @@ A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to n Description: `All of annotations (key/value pairs) present on the resource in GCP, including the annotations configured through Terraform, other clients and services.`, Elem: &schema.Schema{Type: schema.TypeString}, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "etag": { Type: schema.TypeString, Computed: true, @@ -910,6 +917,13 @@ If reconciliation failed, trafficStatuses, observedGeneration, and latestReadyRe }, }, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "traffic_statuses": { Type: schema.TypeList, Computed: true, @@ -984,12 +998,6 @@ func resourceCloudRunV2ServiceCreate(d *schema.ResourceData, meta interface{}) e } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { obj["description"] = descriptionProp } - labelsProp, err := expandCloudRunV2ServiceLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } clientProp, err := expandCloudRunV2ServiceClient(d.Get("client"), d, config) if err != nil { return err @@ -1032,6 +1040,12 @@ func resourceCloudRunV2ServiceCreate(d *schema.ResourceData, meta interface{}) e } else if v, ok := d.GetOkExists("traffic"); !tpgresource.IsEmptyValue(reflect.ValueOf(trafficProp)) && (ok || !reflect.DeepEqual(v, trafficProp)) { obj["traffic"] = trafficProp } + labelsProp, err := expandCloudRunV2ServiceEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } annotationsProp, err := expandCloudRunV2ServiceEffectiveAnnotations(d.Get("effective_annotations"), d, config) if err != nil { return err @@ -1224,6 +1238,12 @@ func resourceCloudRunV2ServiceRead(d *schema.ResourceData, meta interface{}) err if err := d.Set("etag", flattenCloudRunV2ServiceEtag(res["etag"], d, config)); err != nil { return fmt.Errorf("Error reading Service: %s", err) } + if err := d.Set("terraform_labels", flattenCloudRunV2ServiceTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Service: %s", err) + } + if err := d.Set("effective_labels", flattenCloudRunV2ServiceEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Service: %s", err) + } if err := d.Set("effective_annotations", flattenCloudRunV2ServiceEffectiveAnnotations(res["annotations"], d, config)); err != nil { return fmt.Errorf("Error reading Service: %s", err) } @@ -1253,12 +1273,6 @@ func resourceCloudRunV2ServiceUpdate(d *schema.ResourceData, meta interface{}) e } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { obj["description"] = descriptionProp } - labelsProp, err := expandCloudRunV2ServiceLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } clientProp, err := expandCloudRunV2ServiceClient(d.Get("client"), d, config) if err != nil { return err @@ -1301,6 +1315,12 @@ func resourceCloudRunV2ServiceUpdate(d *schema.ResourceData, meta interface{}) e } else if v, ok := d.GetOkExists("traffic"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, trafficProp)) { obj["traffic"] = trafficProp } + labelsProp, err := expandCloudRunV2ServiceEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } annotationsProp, err := expandCloudRunV2ServiceEffectiveAnnotations(d.Get("effective_annotations"), d, config) if err != nil { return err @@ -1433,7 +1453,18 @@ func flattenCloudRunV2ServiceGeneration(v interface{}, d *schema.ResourceData, c } func flattenCloudRunV2ServiceLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenCloudRunV2ServiceAnnotations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -2653,6 +2684,25 @@ func flattenCloudRunV2ServiceEtag(v interface{}, d *schema.ResourceData, config return v } +func flattenCloudRunV2ServiceTerraformLabels(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 flattenCloudRunV2ServiceEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func flattenCloudRunV2ServiceEffectiveAnnotations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { return v } @@ -2661,17 +2711,6 @@ func expandCloudRunV2ServiceDescription(v interface{}, d tpgresource.TerraformRe return v, nil } -func expandCloudRunV2ServiceLabels(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 -} - func expandCloudRunV2ServiceClient(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } @@ -3909,6 +3948,17 @@ func expandCloudRunV2ServiceTrafficTag(v interface{}, d tpgresource.TerraformRes return v, nil } +func expandCloudRunV2ServiceEffectiveLabels(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 +} + func expandCloudRunV2ServiceEffectiveAnnotations(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { if v == nil { return map[string]string{}, nil diff --git a/google/services/cloudrunv2/resource_cloud_run_v2_service_generated_test.go b/google/services/cloudrunv2/resource_cloud_run_v2_service_generated_test.go index d395c244020..63d1e72c385 100644 --- a/google/services/cloudrunv2/resource_cloud_run_v2_service_generated_test.go +++ b/google/services/cloudrunv2/resource_cloud_run_v2_service_generated_test.go @@ -49,7 +49,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceBasicExample(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "annotations", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "labels", "annotations", "terraform_labels"}, }, }, }) @@ -91,7 +91,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceSqlExample(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "annotations", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "labels", "annotations", "terraform_labels"}, }, }, }) @@ -200,7 +200,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceVpcaccessExample(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "annotations", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "labels", "annotations", "terraform_labels"}, }, }, }) @@ -265,7 +265,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceProbesExample(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "annotations", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "labels", "annotations", "terraform_labels"}, }, }, }) @@ -319,7 +319,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceSecretExample(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "annotations", "location"}, + ImportStateVerifyIgnore: []string{"name", "location", "labels", "annotations", "terraform_labels"}, }, }, }) diff --git a/google/services/cloudrunv2/resource_cloud_run_v2_service_test.go b/google/services/cloudrunv2/resource_cloud_run_v2_service_test.go index f23707fc322..dda339b018c 100644 --- a/google/services/cloudrunv2/resource_cloud_run_v2_service_test.go +++ b/google/services/cloudrunv2/resource_cloud_run_v2_service_test.go @@ -32,7 +32,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceFullUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, + ImportStateVerifyIgnore: []string{"name", "location", "annotations", "labels", "terraform_labels"}, }, { Config: testAccCloudRunV2Service_cloudrunv2ServiceFullUpdate(context), @@ -41,7 +41,7 @@ func TestAccCloudRunV2Service_cloudrunv2ServiceFullUpdate(t *testing.T) { ResourceName: "google_cloud_run_v2_service.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, + ImportStateVerifyIgnore: []string{"name", "location", "annotations", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/compute/resource_compute_address_generated_test.go b/google/services/compute/resource_compute_address_generated_test.go index 98794e13a4a..fa4399835ed 100644 --- a/google/services/compute/resource_compute_address_generated_test.go +++ b/google/services/compute/resource_compute_address_generated_test.go @@ -49,7 +49,7 @@ func TestAccComputeAddress_addressBasicExample(t *testing.T) { ResourceName: "google_compute_address.ip_address", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"subnetwork", "network", "region"}, + ImportStateVerifyIgnore: []string{"subnetwork", "network", "region", "labels", "terraform_labels"}, }, }, }) @@ -82,7 +82,7 @@ func TestAccComputeAddress_addressWithSubnetworkExample(t *testing.T) { ResourceName: "google_compute_address.internal_with_subnet_and_address", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"subnetwork", "network", "region"}, + ImportStateVerifyIgnore: []string{"subnetwork", "network", "region", "labels", "terraform_labels"}, }, }, }) @@ -130,7 +130,7 @@ func TestAccComputeAddress_addressWithGceEndpointExample(t *testing.T) { ResourceName: "google_compute_address.internal_with_gce_endpoint", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"subnetwork", "network", "region"}, + ImportStateVerifyIgnore: []string{"subnetwork", "network", "region", "labels", "terraform_labels"}, }, }, }) @@ -165,7 +165,7 @@ func TestAccComputeAddress_addressWithSharedLoadbalancerVipExample(t *testing.T) ResourceName: "google_compute_address.internal_with_shared_loadbalancer_vip", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"subnetwork", "network", "region"}, + ImportStateVerifyIgnore: []string{"subnetwork", "network", "region", "labels", "terraform_labels"}, }, }, }) @@ -200,7 +200,7 @@ func TestAccComputeAddress_instanceWithIpExample(t *testing.T) { ResourceName: "google_compute_address.static", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"subnetwork", "network", "region"}, + ImportStateVerifyIgnore: []string{"subnetwork", "network", "region", "labels", "terraform_labels"}, }, }, }) @@ -257,7 +257,7 @@ func TestAccComputeAddress_computeAddressIpsecInterconnectExample(t *testing.T) ResourceName: "google_compute_address.ipsec-interconnect-address", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"subnetwork", "network", "region"}, + ImportStateVerifyIgnore: []string{"subnetwork", "network", "region", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/compute/resource_compute_forwarding_rule_generated_test.go b/google/services/compute/resource_compute_forwarding_rule_generated_test.go index c3a31e46a73..e9a20bdb168 100644 --- a/google/services/compute/resource_compute_forwarding_rule_generated_test.go +++ b/google/services/compute/resource_compute_forwarding_rule_generated_test.go @@ -49,7 +49,7 @@ func TestAccComputeForwardingRule_forwardingRuleGlobalInternallbExample(t *testi ResourceName: "google_compute_forwarding_rule.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"backend_service", "network", "subnetwork", "labels", "no_automate_dns_zone", "terraform_labels", "region"}, + ImportStateVerifyIgnore: []string{"backend_service", "network", "subnetwork", "no_automate_dns_zone", "region", "labels", "terraform_labels"}, }, }, }) @@ -113,7 +113,7 @@ func TestAccComputeForwardingRule_forwardingRuleBasicExample(t *testing.T) { ResourceName: "google_compute_forwarding_rule.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"backend_service", "network", "subnetwork", "labels", "no_automate_dns_zone", "terraform_labels", "region", "port_range", "target"}, + ImportStateVerifyIgnore: []string{"backend_service", "network", "subnetwork", "no_automate_dns_zone", "region", "port_range", "target", "labels", "terraform_labels"}, }, }, }) @@ -152,7 +152,7 @@ func TestAccComputeForwardingRule_forwardingRuleInternallbExample(t *testing.T) ResourceName: "google_compute_forwarding_rule.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"backend_service", "network", "subnetwork", "labels", "no_automate_dns_zone", "terraform_labels", "region", "port_range", "target"}, + ImportStateVerifyIgnore: []string{"backend_service", "network", "subnetwork", "no_automate_dns_zone", "region", "port_range", "target", "labels", "terraform_labels"}, }, }, }) @@ -222,7 +222,7 @@ func TestAccComputeForwardingRule_forwardingRuleVpcPscExample(t *testing.T) { ResourceName: "google_compute_forwarding_rule.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"backend_service", "network", "subnetwork", "labels", "no_automate_dns_zone", "terraform_labels", "region", "port_range", "target", "ip_address"}, + ImportStateVerifyIgnore: []string{"backend_service", "network", "subnetwork", "no_automate_dns_zone", "region", "port_range", "target", "ip_address", "labels", "terraform_labels"}, }, }, }) @@ -346,7 +346,7 @@ func TestAccComputeForwardingRule_forwardingRuleVpcPscNoAutomateDnsExample(t *te ResourceName: "google_compute_forwarding_rule.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"backend_service", "network", "subnetwork", "labels", "no_automate_dns_zone", "terraform_labels", "region", "port_range", "target", "ip_address"}, + ImportStateVerifyIgnore: []string{"backend_service", "network", "subnetwork", "no_automate_dns_zone", "region", "port_range", "target", "ip_address", "labels", "terraform_labels"}, }, }, }) @@ -466,7 +466,7 @@ func TestAccComputeForwardingRule_forwardingRuleRegionalSteeringExample(t *testi ResourceName: "google_compute_forwarding_rule.steering", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"backend_service", "network", "subnetwork", "labels", "no_automate_dns_zone", "terraform_labels", "region"}, + ImportStateVerifyIgnore: []string{"backend_service", "network", "subnetwork", "no_automate_dns_zone", "region", "labels", "terraform_labels"}, }, }, }) @@ -524,7 +524,7 @@ func TestAccComputeForwardingRule_forwardingRuleInternallbIpv6Example(t *testing ResourceName: "google_compute_forwarding_rule.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"backend_service", "network", "subnetwork", "labels", "no_automate_dns_zone", "terraform_labels", "region", "port_range", "target"}, + ImportStateVerifyIgnore: []string{"backend_service", "network", "subnetwork", "no_automate_dns_zone", "region", "port_range", "target", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/compute/resource_compute_global_address_generated_test.go b/google/services/compute/resource_compute_global_address_generated_test.go index e9d1bcbc1bc..d6ad1d538ab 100644 --- a/google/services/compute/resource_compute_global_address_generated_test.go +++ b/google/services/compute/resource_compute_global_address_generated_test.go @@ -49,7 +49,7 @@ func TestAccComputeGlobalAddress_globalAddressBasicExample(t *testing.T) { ResourceName: "google_compute_global_address.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"network"}, + ImportStateVerifyIgnore: []string{"network", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/compute/resource_compute_global_forwarding_rule_generated_test.go b/google/services/compute/resource_compute_global_forwarding_rule_generated_test.go index c278e848892..083ca2f5d47 100644 --- a/google/services/compute/resource_compute_global_forwarding_rule_generated_test.go +++ b/google/services/compute/resource_compute_global_forwarding_rule_generated_test.go @@ -49,7 +49,7 @@ func TestAccComputeGlobalForwardingRule_globalForwardingRuleHttpExample(t *testi ResourceName: "google_compute_global_forwarding_rule.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"labels", "network", "subnetwork", "no_automate_dns_zone", "terraform_labels", "port_range", "target"}, + ImportStateVerifyIgnore: []string{"network", "subnetwork", "no_automate_dns_zone", "port_range", "target", "labels", "terraform_labels"}, }, }, }) @@ -127,7 +127,7 @@ func TestAccComputeGlobalForwardingRule_globalForwardingRuleExternalManagedExamp ResourceName: "google_compute_global_forwarding_rule.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"labels", "network", "subnetwork", "no_automate_dns_zone", "terraform_labels", "port_range", "target"}, + ImportStateVerifyIgnore: []string{"network", "subnetwork", "no_automate_dns_zone", "port_range", "target", "labels", "terraform_labels"}, }, }, }) @@ -198,7 +198,7 @@ func TestAccComputeGlobalForwardingRule_globalForwardingRuleHybridExample(t *tes ResourceName: "google_compute_global_forwarding_rule.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"labels", "network", "subnetwork", "no_automate_dns_zone", "terraform_labels", "port_range", "target"}, + ImportStateVerifyIgnore: []string{"network", "subnetwork", "no_automate_dns_zone", "port_range", "target", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/compute/resource_compute_vpn_tunnel_generated_test.go b/google/services/compute/resource_compute_vpn_tunnel_generated_test.go index 1ddcb2e5244..33e1774a3a7 100644 --- a/google/services/compute/resource_compute_vpn_tunnel_generated_test.go +++ b/google/services/compute/resource_compute_vpn_tunnel_generated_test.go @@ -49,7 +49,7 @@ func TestAccComputeVpnTunnel_vpnTunnelBasicExample(t *testing.T) { ResourceName: "google_compute_vpn_tunnel.tunnel1", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"target_vpn_gateway", "vpn_gateway", "peer_external_gateway", "peer_gcp_gateway", "router", "shared_secret", "region"}, + ImportStateVerifyIgnore: []string{"target_vpn_gateway", "vpn_gateway", "peer_external_gateway", "peer_gcp_gateway", "router", "shared_secret", "region", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/containerattached/resource_container_attached_cluster_generated_test.go b/google/services/containerattached/resource_container_attached_cluster_generated_test.go index 2c4429a4174..0bb8f68d758 100644 --- a/google/services/containerattached/resource_container_attached_cluster_generated_test.go +++ b/google/services/containerattached/resource_container_attached_cluster_generated_test.go @@ -173,7 +173,7 @@ func TestAccContainerAttachedCluster_containerAttachedClusterIgnoreErrorsExample ResourceName: "google_container_attached_cluster.primary", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "annotations", "deletion_policy"}, + ImportStateVerifyIgnore: []string{"location", "deletion_policy", "annotations"}, }, }, }) diff --git a/google/services/databasemigrationservice/resource_database_migration_service_connection_profile.go b/google/services/databasemigrationservice/resource_database_migration_service_connection_profile.go index b9836884dae..9b7823dd15e 100644 --- a/google/services/databasemigrationservice/resource_database_migration_service_connection_profile.go +++ b/google/services/databasemigrationservice/resource_database_migration_service_connection_profile.go @@ -50,6 +50,7 @@ func ResourceDatabaseMigrationServiceConnectionProfile() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -558,6 +559,12 @@ If this field is used then the 'clientCertificate' field is mandatory.`, Computed: true, Description: `The database provider.`, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "error": { Type: schema.TypeList, Computed: true, @@ -595,6 +602,13 @@ If this field is used then the 'clientCertificate' field is mandatory.`, Computed: true, Description: `The current connection profile state.`, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "project": { Type: schema.TypeString, Optional: true, @@ -620,12 +634,6 @@ func resourceDatabaseMigrationServiceConnectionProfileCreate(d *schema.ResourceD } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { obj["displayName"] = displayNameProp } - labelsProp, err := expandDatabaseMigrationServiceConnectionProfileLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } mysqlProp, err := expandDatabaseMigrationServiceConnectionProfileMysql(d.Get("mysql"), d, config) if err != nil { return err @@ -650,6 +658,12 @@ func resourceDatabaseMigrationServiceConnectionProfileCreate(d *schema.ResourceD } else if v, ok := d.GetOkExists("alloydb"); !tpgresource.IsEmptyValue(reflect.ValueOf(alloydbProp)) && (ok || !reflect.DeepEqual(v, alloydbProp)) { obj["alloydb"] = alloydbProp } + labelsProp, err := expandDatabaseMigrationServiceConnectionProfileEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{DatabaseMigrationServiceBasePath}}projects/{{project}}/locations/{{location}}/connectionProfiles?connectionProfileId={{connection_profile_id}}") if err != nil { @@ -778,6 +792,12 @@ func resourceDatabaseMigrationServiceConnectionProfileRead(d *schema.ResourceDat if err := d.Set("alloydb", flattenDatabaseMigrationServiceConnectionProfileAlloydb(res["alloydb"], d, config)); err != nil { return fmt.Errorf("Error reading ConnectionProfile: %s", err) } + if err := d.Set("terraform_labels", flattenDatabaseMigrationServiceConnectionProfileTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading ConnectionProfile: %s", err) + } + if err := d.Set("effective_labels", flattenDatabaseMigrationServiceConnectionProfileEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading ConnectionProfile: %s", err) + } return nil } @@ -804,12 +824,6 @@ func resourceDatabaseMigrationServiceConnectionProfileUpdate(d *schema.ResourceD } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { obj["displayName"] = displayNameProp } - labelsProp, err := expandDatabaseMigrationServiceConnectionProfileLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } mysqlProp, err := expandDatabaseMigrationServiceConnectionProfileMysql(d.Get("mysql"), d, config) if err != nil { return err @@ -834,6 +848,12 @@ func resourceDatabaseMigrationServiceConnectionProfileUpdate(d *schema.ResourceD } else if v, ok := d.GetOkExists("alloydb"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, alloydbProp)) { obj["alloydb"] = alloydbProp } + labelsProp, err := expandDatabaseMigrationServiceConnectionProfileEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{DatabaseMigrationServiceBasePath}}projects/{{project}}/locations/{{location}}/connectionProfiles/{{connection_profile_id}}") if err != nil { @@ -847,10 +867,6 @@ func resourceDatabaseMigrationServiceConnectionProfileUpdate(d *schema.ResourceD updateMask = append(updateMask, "displayName") } - if d.HasChange("labels") { - updateMask = append(updateMask, "labels") - } - if d.HasChange("mysql") { updateMask = append(updateMask, "mysql") } @@ -866,6 +882,10 @@ func resourceDatabaseMigrationServiceConnectionProfileUpdate(d *schema.ResourceD if d.HasChange("alloydb") { updateMask = append(updateMask, "alloydb") } + + if d.HasChange("effective_labels") { + updateMask = append(updateMask, "labels") + } // updateMask is a URL parameter but not present in the schema, so ReplaceVars // won't set it url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -991,7 +1011,18 @@ func flattenDatabaseMigrationServiceConnectionProfileCreateTime(v interface{}, d } func flattenDatabaseMigrationServiceConnectionProfileLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenDatabaseMigrationServiceConnectionProfileState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -1594,19 +1625,27 @@ func flattenDatabaseMigrationServiceConnectionProfileAlloydbSettingsPrimaryInsta return v } -func expandDatabaseMigrationServiceConnectionProfileDisplayName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil -} - -func expandDatabaseMigrationServiceConnectionProfileLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func flattenDatabaseMigrationServiceConnectionProfileTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { - return map[string]string{}, nil + return v } - m := make(map[string]string) - for k, val := range v.(map[string]interface{}) { - m[k] = val.(string) + + 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 m, nil + + return transformed +} + +func flattenDatabaseMigrationServiceConnectionProfileEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func expandDatabaseMigrationServiceConnectionProfileDisplayName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil } func expandDatabaseMigrationServiceConnectionProfileMysql(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { @@ -2503,3 +2542,14 @@ func expandDatabaseMigrationServiceConnectionProfileAlloydbSettingsPrimaryInstan func expandDatabaseMigrationServiceConnectionProfileAlloydbSettingsPrimaryInstanceSettingsPrivateIp(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } + +func expandDatabaseMigrationServiceConnectionProfileEffectiveLabels(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/databasemigrationservice/resource_database_migration_service_connection_profile_generated_test.go b/google/services/databasemigrationservice/resource_database_migration_service_connection_profile_generated_test.go index 41d184aa228..996ac625824 100644 --- a/google/services/databasemigrationservice/resource_database_migration_service_connection_profile_generated_test.go +++ b/google/services/databasemigrationservice/resource_database_migration_service_connection_profile_generated_test.go @@ -49,7 +49,7 @@ func TestAccDatabaseMigrationServiceConnectionProfile_databaseMigrationServiceCo ResourceName: "google_database_migration_service_connection_profile.cloudsqlprofile", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "mysql.0.password", "mysql.0.ssl.0.ca_certificate", "mysql.0.ssl.0.client_certificate", "mysql.0.ssl.0.client_key"}, + ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "mysql.0.password", "mysql.0.ssl.0.ca_certificate", "mysql.0.ssl.0.client_certificate", "mysql.0.ssl.0.client_key", "labels", "terraform_labels"}, }, }, }) @@ -164,7 +164,7 @@ func TestAccDatabaseMigrationServiceConnectionProfile_databaseMigrationServiceCo ResourceName: "google_database_migration_service_connection_profile.postgresprofile", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "postgresql.0.password", "postgresql.0.ssl.0.ca_certificate", "postgresql.0.ssl.0.client_certificate", "postgresql.0.ssl.0.client_key"}, + ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "postgresql.0.password", "postgresql.0.ssl.0.ca_certificate", "postgresql.0.ssl.0.client_certificate", "postgresql.0.ssl.0.client_key", "labels", "terraform_labels"}, }, }, }) @@ -240,7 +240,7 @@ func TestAccDatabaseMigrationServiceConnectionProfile_databaseMigrationServiceCo ResourceName: "google_database_migration_service_connection_profile.alloydbprofile", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "alloydb.0.settings.0.initial_user.0.password"}, + ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "alloydb.0.settings.0.initial_user.0.password", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/databasemigrationservice/resource_database_migration_service_connection_profile_test.go b/google/services/databasemigrationservice/resource_database_migration_service_connection_profile_test.go index 05f0184461b..e9d461ee10e 100644 --- a/google/services/databasemigrationservice/resource_database_migration_service_connection_profile_test.go +++ b/google/services/databasemigrationservice/resource_database_migration_service_connection_profile_test.go @@ -27,7 +27,7 @@ func TestAccDatabaseMigrationServiceConnectionProfile_update(t *testing.T) { ResourceName: "google_database_migration_service_connection_profile.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "mysql.0.password"}, + ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "mysql.0.password", "labels", "terraform_labels"}, }, { Config: testAccDatabaseMigrationServiceConnectionProfile_update(suffix), @@ -36,7 +36,7 @@ func TestAccDatabaseMigrationServiceConnectionProfile_update(t *testing.T) { ResourceName: "google_database_migration_service_connection_profile.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "mysql.0.password"}, + ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "mysql.0.password", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/datafusion/resource_data_fusion_instance.go b/google/services/datafusion/resource_data_fusion_instance.go index 28f102b16d3..98d1b70ec22 100644 --- a/google/services/datafusion/resource_data_fusion_instance.go +++ b/google/services/datafusion/resource_data_fusion_instance.go @@ -72,6 +72,7 @@ func ResourceDataFusionInstance() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, tpgresource.DefaultProviderRegion, ), @@ -274,6 +275,12 @@ able to access the public internet.`, Computed: true, Description: `The time the instance was created in RFC3339 UTC "Zulu" format, accurate to nanoseconds.`, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "gcs_bucket": { Type: schema.TypeString, Computed: true, @@ -310,6 +317,13 @@ able to access the public internet.`, Computed: true, Description: `The name of the tenant project.`, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "update_time": { Type: schema.TypeString, Computed: true, @@ -370,12 +384,6 @@ func resourceDataFusionInstanceCreate(d *schema.ResourceData, meta interface{}) } else if v, ok := d.GetOkExists("enable_rbac"); !tpgresource.IsEmptyValue(reflect.ValueOf(enableRbacProp)) && (ok || !reflect.DeepEqual(v, enableRbacProp)) { obj["enableRbac"] = enableRbacProp } - labelsProp, err := expandDataFusionInstanceLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } optionsProp, err := expandDataFusionInstanceOptions(d.Get("options"), d, config) if err != nil { return err @@ -436,6 +444,12 @@ func resourceDataFusionInstanceCreate(d *schema.ResourceData, meta interface{}) } else if v, ok := d.GetOkExists("accelerators"); !tpgresource.IsEmptyValue(reflect.ValueOf(acceleratorsProp)) && (ok || !reflect.DeepEqual(v, acceleratorsProp)) { obj["accelerators"] = acceleratorsProp } + labelsProp, err := expandDataFusionInstanceEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{DataFusionBasePath}}projects/{{project}}/locations/{{region}}/instances?instanceId={{name}}") if err != nil { @@ -631,6 +645,12 @@ func resourceDataFusionInstanceRead(d *schema.ResourceData, meta interface{}) er if err := d.Set("accelerators", flattenDataFusionInstanceAccelerators(res["accelerators"], d, config)); err != nil { return fmt.Errorf("Error reading Instance: %s", err) } + if err := d.Set("terraform_labels", flattenDataFusionInstanceTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Instance: %s", err) + } + if err := d.Set("effective_labels", flattenDataFusionInstanceEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Instance: %s", err) + } return nil } @@ -669,12 +689,6 @@ func resourceDataFusionInstanceUpdate(d *schema.ResourceData, meta interface{}) } else if v, ok := d.GetOkExists("enable_rbac"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, enableRbacProp)) { obj["enableRbac"] = enableRbacProp } - labelsProp, err := expandDataFusionInstanceLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } versionProp, err := expandDataFusionInstanceVersion(d.Get("version"), d, config) if err != nil { return err @@ -693,6 +707,12 @@ func resourceDataFusionInstanceUpdate(d *schema.ResourceData, meta interface{}) } else if v, ok := d.GetOkExists("accelerators"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, acceleratorsProp)) { obj["accelerators"] = acceleratorsProp } + labelsProp, err := expandDataFusionInstanceEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{DataFusionBasePath}}projects/{{project}}/locations/{{region}}/instances/{{name}}") if err != nil { @@ -856,7 +876,18 @@ func flattenDataFusionInstanceEnableRbac(v interface{}, d *schema.ResourceData, } func flattenDataFusionInstanceLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenDataFusionInstanceOptions(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -1009,6 +1040,25 @@ func flattenDataFusionInstanceAcceleratorsState(v interface{}, d *schema.Resourc return v } +func flattenDataFusionInstanceTerraformLabels(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 flattenDataFusionInstanceEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func expandDataFusionInstanceName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{region}}/instances/{{name}}") } @@ -1033,17 +1083,6 @@ func expandDataFusionInstanceEnableRbac(v interface{}, d tpgresource.TerraformRe return v, nil } -func expandDataFusionInstanceLabels(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 -} - func expandDataFusionInstanceOptions(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { if v == nil { return map[string]string{}, nil @@ -1202,3 +1241,14 @@ func expandDataFusionInstanceAcceleratorsAcceleratorType(v interface{}, d tpgres func expandDataFusionInstanceAcceleratorsState(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } + +func expandDataFusionInstanceEffectiveLabels(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/datafusion/resource_data_fusion_instance_generated_test.go b/google/services/datafusion/resource_data_fusion_instance_generated_test.go index a29dcf48126..5f59752e78f 100644 --- a/google/services/datafusion/resource_data_fusion_instance_generated_test.go +++ b/google/services/datafusion/resource_data_fusion_instance_generated_test.go @@ -50,7 +50,7 @@ func TestAccDataFusionInstance_dataFusionInstanceBasicExample(t *testing.T) { ResourceName: "google_data_fusion_instance.basic_instance", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"region"}, + ImportStateVerifyIgnore: []string{"region", "labels", "terraform_labels"}, }, }, }) @@ -87,7 +87,7 @@ func TestAccDataFusionInstance_dataFusionInstanceFullExample(t *testing.T) { ResourceName: "google_data_fusion_instance.extended_instance", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"region"}, + ImportStateVerifyIgnore: []string{"region", "labels", "terraform_labels"}, }, }, }) @@ -158,7 +158,7 @@ func TestAccDataFusionInstance_dataFusionInstanceCmekExample(t *testing.T) { ResourceName: "google_data_fusion_instance.cmek", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"region"}, + ImportStateVerifyIgnore: []string{"region", "labels", "terraform_labels"}, }, }, }) @@ -221,7 +221,7 @@ func TestAccDataFusionInstance_dataFusionInstanceEnterpriseExample(t *testing.T) ResourceName: "google_data_fusion_instance.enterprise_instance", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"region"}, + ImportStateVerifyIgnore: []string{"region", "labels", "terraform_labels"}, }, }, }) @@ -258,7 +258,7 @@ func TestAccDataFusionInstance_dataFusionInstanceEventExample(t *testing.T) { ResourceName: "google_data_fusion_instance.event", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"region"}, + ImportStateVerifyIgnore: []string{"region", "labels", "terraform_labels"}, }, }, }) @@ -302,7 +302,7 @@ func TestAccDataFusionInstance_dataFusionInstanceZoneExample(t *testing.T) { ResourceName: "google_data_fusion_instance.zone", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"region"}, + ImportStateVerifyIgnore: []string{"region", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/datafusion/resource_data_fusion_instance_test.go b/google/services/datafusion/resource_data_fusion_instance_test.go index 338c64e7d12..b2517a8fa05 100644 --- a/google/services/datafusion/resource_data_fusion_instance_test.go +++ b/google/services/datafusion/resource_data_fusion_instance_test.go @@ -23,17 +23,19 @@ func TestAccDataFusionInstance_update(t *testing.T) { Config: testAccDataFusionInstance_basic(instanceName), }, { - ResourceName: "google_data_fusion_instance.foobar", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_data_fusion_instance.foobar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, { Config: testAccDataFusionInstance_updated(instanceName), }, { - ResourceName: "google_data_fusion_instance.foobar", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_data_fusion_instance.foobar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, }, }) @@ -99,17 +101,19 @@ func TestAccDataFusionInstanceEnterprise_update(t *testing.T) { Config: testAccDataFusionInstanceEnterprise_basic(instanceName), }, { - ResourceName: "google_data_fusion_instance.foobar", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_data_fusion_instance.foobar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, { Config: testAccDataFusionInstanceEnterprise_updated(instanceName), }, { - ResourceName: "google_data_fusion_instance.foobar", - ImportState: true, - ImportStateVerify: true, + ResourceName: "google_data_fusion_instance.foobar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, }, }, }) diff --git a/google/services/dataplex/resource_dataplex_datascan.go b/google/services/dataplex/resource_dataplex_datascan.go index 84506d43d31..5c22e6f1f6e 100644 --- a/google/services/dataplex/resource_dataplex_datascan.go +++ b/google/services/dataplex/resource_dataplex_datascan.go @@ -50,6 +50,7 @@ func ResourceDataplexDatascan() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -507,6 +508,12 @@ Sampling is not applied if 'sampling_percent' is not specified, 0 or 100.`, Computed: true, Description: `The time when the scan was created.`, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "execution_status": { Type: schema.TypeList, Computed: true, @@ -536,6 +543,13 @@ Sampling is not applied if 'sampling_percent' is not specified, 0 or 100.`, Computed: true, Description: `Current state of the DataScan.`, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "type": { Type: schema.TypeString, Computed: true, @@ -582,12 +596,6 @@ func resourceDataplexDatascanCreate(d *schema.ResourceData, meta interface{}) er } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { obj["displayName"] = displayNameProp } - labelsProp, err := expandDataplexDatascanLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } dataProp, err := expandDataplexDatascanData(d.Get("data"), d, config) if err != nil { return err @@ -612,6 +620,12 @@ func resourceDataplexDatascanCreate(d *schema.ResourceData, meta interface{}) er } else if v, ok := d.GetOkExists("data_profile_spec"); ok || !reflect.DeepEqual(v, dataProfileSpecProp) { obj["dataProfileSpec"] = dataProfileSpecProp } + labelsProp, err := expandDataplexDatascanEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{DataplexBasePath}}projects/{{project}}/locations/{{location}}/dataScans?dataScanId={{data_scan_id}}") if err != nil { @@ -749,6 +763,12 @@ func resourceDataplexDatascanRead(d *schema.ResourceData, meta interface{}) erro if err := d.Set("data_profile_spec", flattenDataplexDatascanDataProfileSpec(res["dataProfileSpec"], d, config)); err != nil { return fmt.Errorf("Error reading Datascan: %s", err) } + if err := d.Set("terraform_labels", flattenDataplexDatascanTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Datascan: %s", err) + } + if err := d.Set("effective_labels", flattenDataplexDatascanEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Datascan: %s", err) + } return nil } @@ -781,12 +801,6 @@ func resourceDataplexDatascanUpdate(d *schema.ResourceData, meta interface{}) er } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { obj["displayName"] = displayNameProp } - labelsProp, err := expandDataplexDatascanLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } executionSpecProp, err := expandDataplexDatascanExecutionSpec(d.Get("execution_spec"), d, config) if err != nil { return err @@ -805,6 +819,12 @@ func resourceDataplexDatascanUpdate(d *schema.ResourceData, meta interface{}) er } else if v, ok := d.GetOkExists("data_profile_spec"); ok || !reflect.DeepEqual(v, dataProfileSpecProp) { obj["dataProfileSpec"] = dataProfileSpecProp } + labelsProp, err := expandDataplexDatascanEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{DataplexBasePath}}projects/{{project}}/locations/{{location}}/dataScans/{{data_scan_id}}") if err != nil { @@ -822,10 +842,6 @@ func resourceDataplexDatascanUpdate(d *schema.ResourceData, meta interface{}) er updateMask = append(updateMask, "displayName") } - if d.HasChange("labels") { - updateMask = append(updateMask, "labels") - } - if d.HasChange("execution_spec") { updateMask = append(updateMask, "executionSpec") } @@ -837,6 +853,10 @@ func resourceDataplexDatascanUpdate(d *schema.ResourceData, meta interface{}) er if d.HasChange("data_profile_spec") { updateMask = append(updateMask, "dataProfileSpec") } + + if d.HasChange("effective_labels") { + updateMask = append(updateMask, "labels") + } // updateMask is a URL parameter but not present in the schema, so ReplaceVars // won't set it url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -967,7 +987,18 @@ func flattenDataplexDatascanDisplayName(v interface{}, d *schema.ResourceData, c } func flattenDataplexDatascanLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenDataplexDatascanState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -1453,6 +1484,25 @@ func flattenDataplexDatascanDataProfileSpecExcludeFieldsFieldNames(v interface{} return v } +func flattenDataplexDatascanTerraformLabels(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 flattenDataplexDatascanEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func expandDataplexDatascanDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } @@ -1461,17 +1511,6 @@ func expandDataplexDatascanDisplayName(v interface{}, d tpgresource.TerraformRes return v, nil } -func expandDataplexDatascanLabels(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 -} - func expandDataplexDatascanData(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { l := v.([]interface{}) if len(l) == 0 || l[0] == nil { @@ -2219,3 +2258,14 @@ func expandDataplexDatascanDataProfileSpecExcludeFields(v interface{}, d tpgreso func expandDataplexDatascanDataProfileSpecExcludeFieldsFieldNames(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } + +func expandDataplexDatascanEffectiveLabels(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_datascan_generated_test.go b/google/services/dataplex/resource_dataplex_datascan_generated_test.go index 32ba8541f6d..aadcd0f31aa 100644 --- a/google/services/dataplex/resource_dataplex_datascan_generated_test.go +++ b/google/services/dataplex/resource_dataplex_datascan_generated_test.go @@ -51,7 +51,7 @@ func TestAccDataplexDatascan_dataplexDatascanBasicProfileExample(t *testing.T) { ResourceName: "google_dataplex_datascan.basic_profile", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "data_scan_id"}, + ImportStateVerifyIgnore: []string{"location", "data_scan_id", "labels", "terraform_labels"}, }, }, }) @@ -100,7 +100,7 @@ func TestAccDataplexDatascan_dataplexDatascanFullProfileExample(t *testing.T) { ResourceName: "google_dataplex_datascan.full_profile", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "data_scan_id"}, + ImportStateVerifyIgnore: []string{"location", "data_scan_id", "labels", "terraform_labels"}, }, }, }) @@ -182,7 +182,7 @@ func TestAccDataplexDatascan_dataplexDatascanBasicQualityExample(t *testing.T) { ResourceName: "google_dataplex_datascan.basic_quality", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "data_scan_id"}, + ImportStateVerifyIgnore: []string{"location", "data_scan_id", "labels", "terraform_labels"}, }, }, }) @@ -240,7 +240,7 @@ func TestAccDataplexDatascan_dataplexDatascanFullQualityExample(t *testing.T) { ResourceName: "google_dataplex_datascan.full_quality", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "data_scan_id"}, + ImportStateVerifyIgnore: []string{"location", "data_scan_id", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/dataplex/resource_dataplex_task.go b/google/services/dataplex/resource_dataplex_task.go index e0020b979cb..0e580496771 100644 --- a/google/services/dataplex/resource_dataplex_task.go +++ b/google/services/dataplex/resource_dataplex_task.go @@ -50,6 +50,7 @@ func ResourceDataplexTask() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -453,6 +454,12 @@ func ResourceDataplexTask() *schema.Resource { Computed: true, Description: `The time when the task was created.`, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "execution_status": { Type: schema.TypeList, Computed: true, @@ -531,6 +538,13 @@ func ResourceDataplexTask() *schema.Resource { Computed: true, Description: `Current state of the task.`, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "uid": { Type: schema.TypeString, Computed: true, @@ -572,12 +586,6 @@ func resourceDataplexTaskCreate(d *schema.ResourceData, meta interface{}) error } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { obj["displayName"] = displayNameProp } - labelsProp, err := expandDataplexTaskLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } triggerSpecProp, err := expandDataplexTaskTriggerSpec(d.Get("trigger_spec"), d, config) if err != nil { return err @@ -602,6 +610,12 @@ func resourceDataplexTaskCreate(d *schema.ResourceData, meta interface{}) error } else if v, ok := d.GetOkExists("notebook"); !tpgresource.IsEmptyValue(reflect.ValueOf(notebookProp)) && (ok || !reflect.DeepEqual(v, notebookProp)) { obj["notebook"] = notebookProp } + labelsProp, err := expandDataplexTaskEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{DataplexBasePath}}projects/{{project}}/locations/{{location}}/lakes/{{lake}}/tasks?task_id={{task_id}}") if err != nil { @@ -736,6 +750,12 @@ func resourceDataplexTaskRead(d *schema.ResourceData, meta interface{}) error { if err := d.Set("notebook", flattenDataplexTaskNotebook(res["notebook"], d, config)); err != nil { return fmt.Errorf("Error reading Task: %s", err) } + if err := d.Set("terraform_labels", flattenDataplexTaskTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Task: %s", err) + } + if err := d.Set("effective_labels", flattenDataplexTaskEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Task: %s", err) + } return nil } @@ -768,12 +788,6 @@ func resourceDataplexTaskUpdate(d *schema.ResourceData, meta interface{}) error } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { obj["displayName"] = displayNameProp } - labelsProp, err := expandDataplexTaskLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } triggerSpecProp, err := expandDataplexTaskTriggerSpec(d.Get("trigger_spec"), d, config) if err != nil { return err @@ -798,6 +812,12 @@ func resourceDataplexTaskUpdate(d *schema.ResourceData, meta interface{}) error } else if v, ok := d.GetOkExists("notebook"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, notebookProp)) { obj["notebook"] = notebookProp } + labelsProp, err := expandDataplexTaskEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{DataplexBasePath}}projects/{{project}}/locations/{{location}}/lakes/{{lake}}/tasks/{{task_id}}") if err != nil { @@ -815,10 +835,6 @@ func resourceDataplexTaskUpdate(d *schema.ResourceData, meta interface{}) error updateMask = append(updateMask, "displayName") } - if d.HasChange("labels") { - updateMask = append(updateMask, "labels") - } - if d.HasChange("trigger_spec") { updateMask = append(updateMask, "triggerSpec") } @@ -834,6 +850,10 @@ func resourceDataplexTaskUpdate(d *schema.ResourceData, meta interface{}) error if d.HasChange("notebook") { updateMask = append(updateMask, "notebook") } + + if d.HasChange("effective_labels") { + updateMask = append(updateMask, "labels") + } // updateMask is a URL parameter but not present in the schema, so ReplaceVars // won't set it url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -975,7 +995,18 @@ func flattenDataplexTaskState(v interface{}, d *schema.ResourceData, config *tra } func flattenDataplexTaskLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenDataplexTaskTriggerSpec(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -1516,6 +1547,25 @@ func flattenDataplexTaskNotebookArchiveUris(v interface{}, d *schema.ResourceDat return v } +func flattenDataplexTaskTerraformLabels(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 flattenDataplexTaskEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func expandDataplexTaskDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } @@ -1524,17 +1574,6 @@ func expandDataplexTaskDisplayName(v interface{}, d tpgresource.TerraformResourc return v, nil } -func expandDataplexTaskLabels(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 -} - func expandDataplexTaskTriggerSpec(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { l := v.([]interface{}) if len(l) == 0 || l[0] == nil { @@ -2173,3 +2212,14 @@ func expandDataplexTaskNotebookFileUris(v interface{}, d tpgresource.TerraformRe func expandDataplexTaskNotebookArchiveUris(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } + +func expandDataplexTaskEffectiveLabels(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_task_generated_test.go b/google/services/dataplex/resource_dataplex_task_generated_test.go index 61005f7d1b6..5b4a32c2d78 100644 --- a/google/services/dataplex/resource_dataplex_task_generated_test.go +++ b/google/services/dataplex/resource_dataplex_task_generated_test.go @@ -51,7 +51,7 @@ func TestAccDataplexTask_dataplexTaskBasicExample(t *testing.T) { ResourceName: "google_dataplex_task.example", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "lake", "task_id"}, + ImportStateVerifyIgnore: []string{"location", "lake", "task_id", "labels", "terraform_labels"}, }, }, }) @@ -128,7 +128,7 @@ func TestAccDataplexTask_dataplexTaskSparkExample(t *testing.T) { ResourceName: "google_dataplex_task.example_spark", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "lake", "task_id"}, + ImportStateVerifyIgnore: []string{"location", "lake", "task_id", "labels", "terraform_labels"}, }, }, }) @@ -220,7 +220,7 @@ func TestAccDataplexTask_dataplexTaskNotebookExample(t *testing.T) { ResourceName: "google_dataplex_task.example_notebook", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"location", "lake", "task_id"}, + ImportStateVerifyIgnore: []string{"location", "lake", "task_id", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/datastream/resource_datastream_connection_profile.go b/google/services/datastream/resource_datastream_connection_profile.go index b53b99e7c76..1b68afad4ce 100644 --- a/google/services/datastream/resource_datastream_connection_profile.go +++ b/google/services/datastream/resource_datastream_connection_profile.go @@ -49,6 +49,7 @@ func ResourceDatastreamConnectionProfile() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -333,11 +334,24 @@ If this field is used then the 'client_certificate' and the }, ConflictsWith: []string{"forward_ssh_connectivity"}, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "name": { Type: schema.TypeString, Computed: true, Description: `The resource's name.`, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "project": { Type: schema.TypeString, Optional: true, @@ -357,12 +371,6 @@ func resourceDatastreamConnectionProfileCreate(d *schema.ResourceData, meta inte } obj := make(map[string]interface{}) - labelsProp, err := expandDatastreamConnectionProfileLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } displayNameProp, err := expandDatastreamConnectionProfileDisplayName(d.Get("display_name"), d, config) if err != nil { return err @@ -411,6 +419,12 @@ func resourceDatastreamConnectionProfileCreate(d *schema.ResourceData, meta inte } else if v, ok := d.GetOkExists("private_connectivity"); !tpgresource.IsEmptyValue(reflect.ValueOf(privateConnectivityProp)) && (ok || !reflect.DeepEqual(v, privateConnectivityProp)) { obj["privateConnectivity"] = privateConnectivityProp } + labelsProp, err := expandDatastreamConnectionProfileEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{DatastreamBasePath}}projects/{{project}}/locations/{{location}}/connectionProfiles?connectionProfileId={{connection_profile_id}}") if err != nil { @@ -550,6 +564,12 @@ func resourceDatastreamConnectionProfileRead(d *schema.ResourceData, meta interf if err := d.Set("private_connectivity", flattenDatastreamConnectionProfilePrivateConnectivity(res["privateConnectivity"], d, config)); err != nil { return fmt.Errorf("Error reading ConnectionProfile: %s", err) } + if err := d.Set("terraform_labels", flattenDatastreamConnectionProfileTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading ConnectionProfile: %s", err) + } + if err := d.Set("effective_labels", flattenDatastreamConnectionProfileEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading ConnectionProfile: %s", err) + } return nil } @@ -570,12 +590,6 @@ func resourceDatastreamConnectionProfileUpdate(d *schema.ResourceData, meta inte billingProject = project obj := make(map[string]interface{}) - labelsProp, err := expandDatastreamConnectionProfileLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } displayNameProp, err := expandDatastreamConnectionProfileDisplayName(d.Get("display_name"), d, config) if err != nil { return err @@ -624,6 +638,12 @@ func resourceDatastreamConnectionProfileUpdate(d *schema.ResourceData, meta inte } else if v, ok := d.GetOkExists("private_connectivity"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, privateConnectivityProp)) { obj["privateConnectivity"] = privateConnectivityProp } + labelsProp, err := expandDatastreamConnectionProfileEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{DatastreamBasePath}}projects/{{project}}/locations/{{location}}/connectionProfiles/{{connection_profile_id}}") if err != nil { @@ -633,10 +653,6 @@ func resourceDatastreamConnectionProfileUpdate(d *schema.ResourceData, meta inte log.Printf("[DEBUG] Updating ConnectionProfile %q: %#v", d.Id(), obj) updateMask := []string{} - if d.HasChange("labels") { - updateMask = append(updateMask, "labels") - } - if d.HasChange("display_name") { updateMask = append(updateMask, "displayName") } @@ -668,6 +684,10 @@ func resourceDatastreamConnectionProfileUpdate(d *schema.ResourceData, meta inte if d.HasChange("private_connectivity") { updateMask = append(updateMask, "privateConnectivity") } + + if d.HasChange("effective_labels") { + updateMask = append(updateMask, "labels") + } // updateMask is a URL parameter but not present in the schema, so ReplaceVars // won't set it url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -785,7 +805,18 @@ func flattenDatastreamConnectionProfileName(v interface{}, d *schema.ResourceDat } func flattenDatastreamConnectionProfileLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenDatastreamConnectionProfileDisplayName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -1106,15 +1137,23 @@ func flattenDatastreamConnectionProfilePrivateConnectivityPrivateConnection(v in return v } -func expandDatastreamConnectionProfileLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func flattenDatastreamConnectionProfileTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { - return map[string]string{}, nil + return v } - m := make(map[string]string) - for k, val := range v.(map[string]interface{}) { - m[k] = val.(string) + + 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 m, nil + + return transformed +} + +func flattenDatastreamConnectionProfileEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v } func expandDatastreamConnectionProfileDisplayName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { @@ -1552,3 +1591,14 @@ func expandDatastreamConnectionProfilePrivateConnectivity(v interface{}, d tpgre func expandDatastreamConnectionProfilePrivateConnectivityPrivateConnection(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } + +func expandDatastreamConnectionProfileEffectiveLabels(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/datastream/resource_datastream_connection_profile_generated_test.go b/google/services/datastream/resource_datastream_connection_profile_generated_test.go index 7df4dff2c24..2423616e597 100644 --- a/google/services/datastream/resource_datastream_connection_profile_generated_test.go +++ b/google/services/datastream/resource_datastream_connection_profile_generated_test.go @@ -49,7 +49,7 @@ func TestAccDatastreamConnectionProfile_datastreamConnectionProfileBasicExample( ResourceName: "google_datastream_connection_profile.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"connection_profile_id", "location"}, + ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "labels", "terraform_labels"}, }, }, }) @@ -89,7 +89,7 @@ func TestAccDatastreamConnectionProfile_datastreamConnectionProfileBigqueryPriva ResourceName: "google_datastream_connection_profile.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"connection_profile_id", "location"}, + ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "labels", "terraform_labels"}, }, }, }) @@ -149,7 +149,7 @@ func TestAccDatastreamConnectionProfile_datastreamConnectionProfileFullExample(t ResourceName: "google_datastream_connection_profile.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "forward_ssh_connectivity.0.password"}, + ImportStateVerifyIgnore: []string{"connection_profile_id", "location", "forward_ssh_connectivity.0.password", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/datastream/resource_datastream_private_connection.go b/google/services/datastream/resource_datastream_private_connection.go index d662599fba6..bdc5ddec550 100644 --- a/google/services/datastream/resource_datastream_private_connection.go +++ b/google/services/datastream/resource_datastream_private_connection.go @@ -80,6 +80,7 @@ func ResourceDatastreamPrivateConnection() *schema.Resource { }, CustomizeDiff: customdiff.All( + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -134,6 +135,13 @@ Format: projects/{project}/global/{networks}/{name}`, Description: `Labels.`, Elem: &schema.Schema{Type: schema.TypeString}, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + ForceNew: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "error": { Type: schema.TypeList, Computed: true, @@ -164,6 +172,13 @@ Format: projects/{project}/global/{networks}/{name}`, Computed: true, Description: `State of the PrivateConnection.`, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "project": { Type: schema.TypeString, Optional: true, @@ -183,12 +198,6 @@ func resourceDatastreamPrivateConnectionCreate(d *schema.ResourceData, meta inte } obj := make(map[string]interface{}) - labelsProp, err := expandDatastreamPrivateConnectionLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } displayNameProp, err := expandDatastreamPrivateConnectionDisplayName(d.Get("display_name"), d, config) if err != nil { return err @@ -201,6 +210,12 @@ func resourceDatastreamPrivateConnectionCreate(d *schema.ResourceData, meta inte } else if v, ok := d.GetOkExists("vpc_peering_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(vpcPeeringConfigProp)) && (ok || !reflect.DeepEqual(v, vpcPeeringConfigProp)) { obj["vpcPeeringConfig"] = vpcPeeringConfigProp } + labelsProp, err := expandDatastreamPrivateConnectionEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } url, err := tpgresource.ReplaceVars(d, config, "{{DatastreamBasePath}}projects/{{project}}/locations/{{location}}/privateConnections?privateConnectionId={{private_connection_id}}") if err != nil { @@ -332,6 +347,12 @@ func resourceDatastreamPrivateConnectionRead(d *schema.ResourceData, meta interf if err := d.Set("vpc_peering_config", flattenDatastreamPrivateConnectionVpcPeeringConfig(res["vpcPeeringConfig"], d, config)); err != nil { return fmt.Errorf("Error reading PrivateConnection: %s", err) } + if err := d.Set("terraform_labels", flattenDatastreamPrivateConnectionTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading PrivateConnection: %s", err) + } + if err := d.Set("effective_labels", flattenDatastreamPrivateConnectionEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading PrivateConnection: %s", err) + } return nil } @@ -418,7 +439,18 @@ func flattenDatastreamPrivateConnectionName(v interface{}, d *schema.ResourceDat } func flattenDatastreamPrivateConnectionLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenDatastreamPrivateConnectionDisplayName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -475,15 +507,23 @@ func flattenDatastreamPrivateConnectionVpcPeeringConfigSubnet(v interface{}, d * return v } -func expandDatastreamPrivateConnectionLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func flattenDatastreamPrivateConnectionTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { - return map[string]string{}, nil + return v } - m := make(map[string]string) - for k, val := range v.(map[string]interface{}) { - m[k] = val.(string) + + 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 m, nil + + return transformed +} + +func flattenDatastreamPrivateConnectionEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v } func expandDatastreamPrivateConnectionDisplayName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { @@ -523,3 +563,14 @@ func expandDatastreamPrivateConnectionVpcPeeringConfigVpc(v interface{}, d tpgre func expandDatastreamPrivateConnectionVpcPeeringConfigSubnet(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } + +func expandDatastreamPrivateConnectionEffectiveLabels(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/datastream/resource_datastream_private_connection_generated_test.go b/google/services/datastream/resource_datastream_private_connection_generated_test.go index fe5bfc6cbb5..db47ff23818 100644 --- a/google/services/datastream/resource_datastream_private_connection_generated_test.go +++ b/google/services/datastream/resource_datastream_private_connection_generated_test.go @@ -49,7 +49,7 @@ func TestAccDatastreamPrivateConnection_datastreamPrivateConnectionFullExample(t ResourceName: "google_datastream_private_connection.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"private_connection_id", "location"}, + ImportStateVerifyIgnore: []string{"private_connection_id", "location", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/datastream/resource_datastream_stream.go b/google/services/datastream/resource_datastream_stream.go index 864899292c7..24ccec67cfe 100644 --- a/google/services/datastream/resource_datastream_stream.go +++ b/google/services/datastream/resource_datastream_stream.go @@ -120,6 +120,7 @@ func ResourceDatastreamStream() *schema.Resource { CustomizeDiff: customdiff.All( resourceDatastreamStreamCustomDiff, + tpgresource.SetLabelsDiff, tpgresource.DefaultProviderProject, ), @@ -1272,6 +1273,12 @@ will be encrypted using an internal Stream-specific encryption key provisioned t Description: `Labels.`, Elem: &schema.Schema{Type: schema.TypeString}, }, + "effective_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "name": { Type: schema.TypeString, Computed: true, @@ -1282,6 +1289,13 @@ will be encrypted using an internal Stream-specific encryption key provisioned t Computed: true, Description: `The state of the stream.`, }, + "terraform_labels": { + Type: schema.TypeMap, + Computed: true, + Description: `The combination of labels configured directly on the resource + and default labels configured on the provider.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "desired_state": { Type: schema.TypeString, Optional: true, @@ -1307,12 +1321,6 @@ func resourceDatastreamStreamCreate(d *schema.ResourceData, meta interface{}) er } obj := make(map[string]interface{}) - labelsProp, err := expandDatastreamStreamLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } displayNameProp, err := expandDatastreamStreamDisplayName(d.Get("display_name"), d, config) if err != nil { return err @@ -1349,6 +1357,12 @@ func resourceDatastreamStreamCreate(d *schema.ResourceData, meta interface{}) er } else if v, ok := d.GetOkExists("customer_managed_encryption_key"); !tpgresource.IsEmptyValue(reflect.ValueOf(customerManagedEncryptionKeyProp)) && (ok || !reflect.DeepEqual(v, customerManagedEncryptionKeyProp)) { obj["customerManagedEncryptionKey"] = customerManagedEncryptionKeyProp } + labelsProp, err := expandDatastreamStreamEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } obj, err = resourceDatastreamStreamEncoder(d, meta, obj) if err != nil { @@ -1507,6 +1521,12 @@ func resourceDatastreamStreamRead(d *schema.ResourceData, meta interface{}) erro if err := d.Set("customer_managed_encryption_key", flattenDatastreamStreamCustomerManagedEncryptionKey(res["customerManagedEncryptionKey"], d, config)); err != nil { return fmt.Errorf("Error reading Stream: %s", err) } + if err := d.Set("terraform_labels", flattenDatastreamStreamTerraformLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Stream: %s", err) + } + if err := d.Set("effective_labels", flattenDatastreamStreamEffectiveLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Stream: %s", err) + } return nil } @@ -1527,12 +1547,6 @@ func resourceDatastreamStreamUpdate(d *schema.ResourceData, meta interface{}) er billingProject = project obj := make(map[string]interface{}) - labelsProp, err := expandDatastreamStreamLabels(d.Get("labels"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { - obj["labels"] = labelsProp - } displayNameProp, err := expandDatastreamStreamDisplayName(d.Get("display_name"), d, config) if err != nil { return err @@ -1563,6 +1577,12 @@ func resourceDatastreamStreamUpdate(d *schema.ResourceData, meta interface{}) er } else if v, ok := d.GetOkExists("backfill_none"); ok || !reflect.DeepEqual(v, backfillNoneProp) { obj["backfillNone"] = backfillNoneProp } + labelsProp, err := expandDatastreamStreamEffectiveLabels(d.Get("effective_labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } obj, err = resourceDatastreamStreamEncoder(d, meta, obj) if err != nil { @@ -1577,10 +1597,6 @@ func resourceDatastreamStreamUpdate(d *schema.ResourceData, meta interface{}) er log.Printf("[DEBUG] Updating Stream %q: %#v", d.Id(), obj) updateMask := []string{} - if d.HasChange("labels") { - updateMask = append(updateMask, "labels") - } - if d.HasChange("display_name") { updateMask = append(updateMask, "displayName") } @@ -1600,6 +1616,10 @@ func resourceDatastreamStreamUpdate(d *schema.ResourceData, meta interface{}) er if d.HasChange("backfill_none") { updateMask = append(updateMask, "backfillNone") } + + if d.HasChange("effective_labels") { + updateMask = append(updateMask, "labels") + } // updateMask is a URL parameter but not present in the schema, so ReplaceVars // won't set it url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -1744,7 +1764,18 @@ func flattenDatastreamStreamName(v interface{}, d *schema.ResourceData, config * } func flattenDatastreamStreamLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + 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 flattenDatastreamStreamDisplayName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -3579,15 +3610,23 @@ func flattenDatastreamStreamCustomerManagedEncryptionKey(v interface{}, d *schem return v } -func expandDatastreamStreamLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { +func flattenDatastreamStreamTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { if v == nil { - return map[string]string{}, nil + return v } - m := make(map[string]string) - for k, val := range v.(map[string]interface{}) { - m[k] = val.(string) + + 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 m, nil + + return transformed +} + +func flattenDatastreamStreamEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v } func expandDatastreamStreamDisplayName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { @@ -5879,6 +5918,17 @@ func expandDatastreamStreamCustomerManagedEncryptionKey(v interface{}, d tpgreso return v, nil } +func expandDatastreamStreamEffectiveLabels(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 +} + func resourceDatastreamStreamEncoder(d *schema.ResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) { if d.HasChange("desired_state") { obj["state"] = d.Get("desired_state") diff --git a/google/services/datastream/resource_datastream_stream_generated_test.go b/google/services/datastream/resource_datastream_stream_generated_test.go index a59d11417fc..7a08f5bd0ef 100644 --- a/google/services/datastream/resource_datastream_stream_generated_test.go +++ b/google/services/datastream/resource_datastream_stream_generated_test.go @@ -55,7 +55,7 @@ func TestAccDatastreamStream_datastreamStreamBasicExample(t *testing.T) { ResourceName: "google_datastream_stream.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"stream_id", "location"}, + ImportStateVerifyIgnore: []string{"stream_id", "location", "labels", "terraform_labels"}, }, }, }) @@ -218,7 +218,7 @@ func TestAccDatastreamStream_datastreamStreamFullExample(t *testing.T) { ResourceName: "google_datastream_stream.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"stream_id", "location"}, + ImportStateVerifyIgnore: []string{"stream_id", "location", "labels", "terraform_labels"}, }, }, }) @@ -448,7 +448,7 @@ func TestAccDatastreamStream_datastreamStreamPostgresqlBigqueryDatasetIdExample( ResourceName: "google_datastream_stream.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"stream_id", "location"}, + ImportStateVerifyIgnore: []string{"stream_id", "location", "labels", "terraform_labels"}, }, }, }) @@ -591,7 +591,7 @@ func TestAccDatastreamStream_datastreamStreamBigqueryExample(t *testing.T) { ResourceName: "google_datastream_stream.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"stream_id", "location"}, + ImportStateVerifyIgnore: []string{"stream_id", "location", "labels", "terraform_labels"}, }, }, }) diff --git a/google/services/datastream/resource_datastream_stream_test.go b/google/services/datastream/resource_datastream_stream_test.go index 92ddb2b6e77..ec9eea0e99c 100644 --- a/google/services/datastream/resource_datastream_stream_test.go +++ b/google/services/datastream/resource_datastream_stream_test.go @@ -35,7 +35,7 @@ func TestAccDatastreamStream_update(t *testing.T) { ResourceName: "google_datastream_stream.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"stream_id", "location", "desired_state"}, + ImportStateVerifyIgnore: []string{"stream_id", "location", "desired_state", "labels", "terraform_labels"}, }, { Config: testAccDatastreamStream_datastreamStreamBasicUpdate(context, "RUNNING", true), @@ -45,7 +45,7 @@ func TestAccDatastreamStream_update(t *testing.T) { ResourceName: "google_datastream_stream.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"stream_id", "location", "desired_state"}, + ImportStateVerifyIgnore: []string{"stream_id", "location", "desired_state", "labels", "terraform_labels"}, }, { Config: testAccDatastreamStream_datastreamStreamBasicUpdate(context, "PAUSED", true), @@ -55,7 +55,7 @@ func TestAccDatastreamStream_update(t *testing.T) { ResourceName: "google_datastream_stream.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"stream_id", "location", "desired_state"}, + ImportStateVerifyIgnore: []string{"stream_id", "location", "desired_state", "labels", "terraform_labels"}, }, { Config: testAccDatastreamStream_datastreamStreamBasicUpdate(context, "RUNNING", true), @@ -65,7 +65,7 @@ func TestAccDatastreamStream_update(t *testing.T) { ResourceName: "google_datastream_stream.default", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"stream_id", "location", "desired_state"}, + ImportStateVerifyIgnore: []string{"stream_id", "location", "desired_state", "labels", "terraform_labels"}, }, { // Disable prevent_destroy diff --git a/google/services/secretmanager/resource_secret_manager_secret_generated_test.go b/google/services/secretmanager/resource_secret_manager_secret_generated_test.go index b1a278da7b0..4a729b72cfa 100644 --- a/google/services/secretmanager/resource_secret_manager_secret_generated_test.go +++ b/google/services/secretmanager/resource_secret_manager_secret_generated_test.go @@ -49,7 +49,7 @@ func TestAccSecretManagerSecret_secretConfigBasicExample(t *testing.T) { ResourceName: "google_secret_manager_secret.secret-basic", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"annotations", "ttl", "secret_id"}, + ImportStateVerifyIgnore: []string{"ttl", "secret_id", "annotations"}, }, }, }) @@ -97,7 +97,7 @@ func TestAccSecretManagerSecret_secretWithAnnotationsExample(t *testing.T) { ResourceName: "google_secret_manager_secret.secret-with-annotations", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"annotations", "ttl", "secret_id"}, + ImportStateVerifyIgnore: []string{"ttl", "secret_id", "annotations"}, }, }, }) @@ -147,7 +147,7 @@ func TestAccSecretManagerSecret_secretWithAutomaticCmekExample(t *testing.T) { ResourceName: "google_secret_manager_secret.secret-with-automatic-cmek", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"annotations", "ttl", "secret_id"}, + ImportStateVerifyIgnore: []string{"ttl", "secret_id", "annotations"}, }, }, }) diff --git a/website/docs/r/active_directory_domain.html.markdown b/website/docs/r/active_directory_domain.html.markdown index 706e2275fde..7b7cf3c3413 100644 --- a/website/docs/r/active_directory_domain.html.markdown +++ b/website/docs/r/active_directory_domain.html.markdown @@ -94,6 +94,13 @@ In addition to the arguments listed above, the following computed attributes are The fully-qualified domain name of the exposed domain used by clients to connect to the service. Similar to what would be chosen for an Active Directory set up on an internal network. +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + ## Timeouts diff --git a/website/docs/r/active_directory_peering.html.markdown b/website/docs/r/active_directory_peering.html.markdown index e8874dd3bb8..c293a81393f 100644 --- a/website/docs/r/active_directory_peering.html.markdown +++ b/website/docs/r/active_directory_peering.html.markdown @@ -123,6 +123,13 @@ In addition to the arguments listed above, the following computed attributes are * `name` - Unique name of the peering in this scope including projects and location using the form: projects/{projectId}/locations/global/peerings/{peeringId}. +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + ## Timeouts diff --git a/website/docs/r/alloydb_backup.html.markdown b/website/docs/r/alloydb_backup.html.markdown index a389694a19f..9aeec78984f 100644 --- a/website/docs/r/alloydb_backup.html.markdown +++ b/website/docs/r/alloydb_backup.html.markdown @@ -206,6 +206,13 @@ In addition to the arguments listed above, the following computed attributes are EncryptionInfo describes the encryption information of a cluster or a backup. Structure is [documented below](#nested_encryption_info). +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + The `encryption_info` block contains: diff --git a/website/docs/r/alloydb_cluster.html.markdown b/website/docs/r/alloydb_cluster.html.markdown index 5dd119a1102..1c31db94a1d 100644 --- a/website/docs/r/alloydb_cluster.html.markdown +++ b/website/docs/r/alloydb_cluster.html.markdown @@ -431,6 +431,13 @@ In addition to the arguments listed above, the following computed attributes are Cluster created via DMS migration. Structure is [documented below](#nested_migration_source). +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + The `encryption_info` block contains: diff --git a/website/docs/r/api_gateway_api.html.markdown b/website/docs/r/api_gateway_api.html.markdown index 6a905acc40a..9b3e6db8ee9 100644 --- a/website/docs/r/api_gateway_api.html.markdown +++ b/website/docs/r/api_gateway_api.html.markdown @@ -87,6 +87,13 @@ In addition to the arguments listed above, the following computed attributes are * `create_time` - Creation timestamp in RFC3339 text format. +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + ## Timeouts diff --git a/website/docs/r/api_gateway_api_config.html.markdown b/website/docs/r/api_gateway_api_config.html.markdown index 1a538d3025e..b0cc2459900 100644 --- a/website/docs/r/api_gateway_api_config.html.markdown +++ b/website/docs/r/api_gateway_api_config.html.markdown @@ -256,6 +256,13 @@ In addition to the arguments listed above, the following computed attributes are * `service_config_id` - The ID of the associated Service Config (https://cloud.google.com/service-infrastructure/docs/glossary#config). +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + ## Timeouts diff --git a/website/docs/r/api_gateway_gateway.html.markdown b/website/docs/r/api_gateway_gateway.html.markdown index a856b9a7ef3..8ef18b3c502 100644 --- a/website/docs/r/api_gateway_gateway.html.markdown +++ b/website/docs/r/api_gateway_gateway.html.markdown @@ -113,6 +113,13 @@ In addition to the arguments listed above, the following computed attributes are * `default_hostname` - The default API Gateway host name of the form {gatewayId}-{hash}.{region_code}.gateway.dev. +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + ## Timeouts diff --git a/website/docs/r/artifact_registry_repository.html.markdown b/website/docs/r/artifact_registry_repository.html.markdown index 6830fb9507a..135d5b08adc 100644 --- a/website/docs/r/artifact_registry_repository.html.markdown +++ b/website/docs/r/artifact_registry_repository.html.markdown @@ -458,6 +458,13 @@ In addition to the arguments listed above, the following computed attributes are * `update_time` - The time when the repository was last updated. +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + ## Timeouts diff --git a/website/docs/r/beyondcorp_app_connection.html.markdown b/website/docs/r/beyondcorp_app_connection.html.markdown index 6b3c225d7a2..56b6c38da1c 100644 --- a/website/docs/r/beyondcorp_app_connection.html.markdown +++ b/website/docs/r/beyondcorp_app_connection.html.markdown @@ -196,6 +196,13 @@ In addition to the arguments listed above, the following computed attributes are * `id` - an identifier for the resource with format `projects/{{project}}/locations/{{region}}/appConnections/{{name}}` +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + ## Timeouts diff --git a/website/docs/r/beyondcorp_app_connector.html.markdown b/website/docs/r/beyondcorp_app_connector.html.markdown index 99667a30a12..b0c9539db76 100644 --- a/website/docs/r/beyondcorp_app_connector.html.markdown +++ b/website/docs/r/beyondcorp_app_connector.html.markdown @@ -142,6 +142,13 @@ In addition to the arguments listed above, the following computed attributes are * `state` - Represents the different states of a AppConnector. +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + ## Timeouts diff --git a/website/docs/r/beyondcorp_app_gateway.html.markdown b/website/docs/r/beyondcorp_app_gateway.html.markdown index 3e4975bf23e..e8763290502 100644 --- a/website/docs/r/beyondcorp_app_gateway.html.markdown +++ b/website/docs/r/beyondcorp_app_gateway.html.markdown @@ -125,6 +125,13 @@ In addition to the arguments listed above, the following computed attributes are A list of connections allocated for the Gateway. Structure is [documented below](#nested_allocated_connections). +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + The `allocated_connections` block contains: diff --git a/website/docs/r/bigquery_job.html.markdown b/website/docs/r/bigquery_job.html.markdown index 1b5396fd475..9a2b0fefce0 100644 --- a/website/docs/r/bigquery_job.html.markdown +++ b/website/docs/r/bigquery_job.html.markdown @@ -1081,6 +1081,15 @@ In addition to the arguments listed above, the following computed attributes are (Output) The type of the job. +* `terraform_labels` - + (Output) + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + (Output) + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + * `status` - The status of this job. Examine this value when polling an asynchronous job to see if the job is complete. Structure is [documented below](#nested_status). diff --git a/website/docs/r/certificate_manager_certificate.html.markdown b/website/docs/r/certificate_manager_certificate.html.markdown index 518872c14e0..6091f8d161e 100644 --- a/website/docs/r/certificate_manager_certificate.html.markdown +++ b/website/docs/r/certificate_manager_certificate.html.markdown @@ -40,6 +40,9 @@ resource "google_certificate_manager_certificate" "default" { name = "dns-cert" description = "The default cert" scope = "EDGE_CACHE" + labels = { + env = "test" + } managed { domains = [ google_certificate_manager_dns_authorization.instance.domain, @@ -340,6 +343,13 @@ In addition to the arguments listed above, the following computed attributes are * `id` - an identifier for the resource with format `projects/{{project}}/locations/{{location}}/certificates/{{name}}` +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + ## Timeouts diff --git a/website/docs/r/certificate_manager_certificate_issuance_config.html.markdown b/website/docs/r/certificate_manager_certificate_issuance_config.html.markdown index 73ad8dfdec8..1d258297f8a 100644 --- a/website/docs/r/certificate_manager_certificate_issuance_config.html.markdown +++ b/website/docs/r/certificate_manager_certificate_issuance_config.html.markdown @@ -184,6 +184,13 @@ In addition to the arguments listed above, the following computed attributes are accurate to nanoseconds with up to nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z". +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + ## Timeouts diff --git a/website/docs/r/certificate_manager_certificate_map.html.markdown b/website/docs/r/certificate_manager_certificate_map.html.markdown index 6eddf8570cf..82d3f24efb6 100644 --- a/website/docs/r/certificate_manager_certificate_map.html.markdown +++ b/website/docs/r/certificate_manager_certificate_map.html.markdown @@ -90,6 +90,13 @@ In addition to the arguments listed above, the following computed attributes are A list of target proxies that use this Certificate Map Structure is [documented below](#nested_gclb_targets). +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + The `gclb_targets` block contains: diff --git a/website/docs/r/certificate_manager_certificate_map_entry.html.markdown b/website/docs/r/certificate_manager_certificate_map_entry.html.markdown index 71632a447eb..a94f10e178d 100644 --- a/website/docs/r/certificate_manager_certificate_map_entry.html.markdown +++ b/website/docs/r/certificate_manager_certificate_map_entry.html.markdown @@ -153,6 +153,13 @@ In addition to the arguments listed above, the following computed attributes are * `state` - A serving state of this Certificate Map Entry. +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + ## Timeouts diff --git a/website/docs/r/certificate_manager_dns_authorization.html.markdown b/website/docs/r/certificate_manager_dns_authorization.html.markdown index 6e209fe4f33..bde2d3fcdde 100644 --- a/website/docs/r/certificate_manager_dns_authorization.html.markdown +++ b/website/docs/r/certificate_manager_dns_authorization.html.markdown @@ -96,6 +96,13 @@ In addition to the arguments listed above, the following computed attributes are certificate. Structure is [documented below](#nested_dns_resource_record). +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + The `dns_resource_record` block contains: diff --git a/website/docs/r/certificate_manager_trust_config.html.markdown b/website/docs/r/certificate_manager_trust_config.html.markdown index 5e4306c2c82..fb8ce20ea60 100644 --- a/website/docs/r/certificate_manager_trust_config.html.markdown +++ b/website/docs/r/certificate_manager_trust_config.html.markdown @@ -142,6 +142,13 @@ In addition to the arguments listed above, the following computed attributes are A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z". +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + ## Timeouts diff --git a/website/docs/r/cloud_run_v2_job.html.markdown b/website/docs/r/cloud_run_v2_job.html.markdown index 36768344130..b6b3a4effb4 100644 --- a/website/docs/r/cloud_run_v2_job.html.markdown +++ b/website/docs/r/cloud_run_v2_job.html.markdown @@ -690,6 +690,13 @@ In addition to the arguments listed above, the following computed attributes are * `etag` - A system-generated fingerprint for this version of the resource. May be used to detect modification conflict during updates. +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + * `effective_annotations` - All of annotations (key/value pairs) present on the resource in GCP, including the annotations configured through Terraform, other clients and services. diff --git a/website/docs/r/cloud_run_v2_service.html.markdown b/website/docs/r/cloud_run_v2_service.html.markdown index 73c123c474d..832006939b5 100644 --- a/website/docs/r/cloud_run_v2_service.html.markdown +++ b/website/docs/r/cloud_run_v2_service.html.markdown @@ -930,6 +930,13 @@ In addition to the arguments listed above, the following computed attributes are * `etag` - A system-generated fingerprint for this version of the resource. May be used to detect modification conflict during updates. +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + * `effective_annotations` - All of annotations (key/value pairs) present on the resource in GCP, including the annotations configured through Terraform, other clients and services. diff --git a/website/docs/r/cloudfunctions2_function.html.markdown b/website/docs/r/cloudfunctions2_function.html.markdown index ba9beba1d79..47b4d4d9607 100644 --- a/website/docs/r/cloudfunctions2_function.html.markdown +++ b/website/docs/r/cloudfunctions2_function.html.markdown @@ -1116,6 +1116,13 @@ In addition to the arguments listed above, the following computed attributes are * `update_time` - The last update timestamp of a Cloud Function. +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + ## Timeouts diff --git a/website/docs/r/data_fusion_instance.html.markdown b/website/docs/r/data_fusion_instance.html.markdown index f7e056e8e81..03f2f9be9d4 100644 --- a/website/docs/r/data_fusion_instance.html.markdown +++ b/website/docs/r/data_fusion_instance.html.markdown @@ -385,6 +385,13 @@ In addition to the arguments listed above, the following computed attributes are * `p4_service_account` - P4 service account for the customer project. +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + ## Timeouts diff --git a/website/docs/r/database_migration_service_connection_profile.html.markdown b/website/docs/r/database_migration_service_connection_profile.html.markdown index 41f5b865708..0454352d75e 100644 --- a/website/docs/r/database_migration_service_connection_profile.html.markdown +++ b/website/docs/r/database_migration_service_connection_profile.html.markdown @@ -658,6 +658,13 @@ In addition to the arguments listed above, the following computed attributes are * `dbprovider` - The database provider. +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + The `error` block contains: diff --git a/website/docs/r/dataplex_datascan.html.markdown b/website/docs/r/dataplex_datascan.html.markdown index a415eaab1e8..b4d9742d32e 100644 --- a/website/docs/r/dataplex_datascan.html.markdown +++ b/website/docs/r/dataplex_datascan.html.markdown @@ -608,6 +608,13 @@ In addition to the arguments listed above, the following computed attributes are * `type` - The type of DataScan. +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + The `execution_status` block contains: diff --git a/website/docs/r/dataplex_task.html.markdown b/website/docs/r/dataplex_task.html.markdown index 5a93731ab84..f2697c328b5 100644 --- a/website/docs/r/dataplex_task.html.markdown +++ b/website/docs/r/dataplex_task.html.markdown @@ -514,6 +514,13 @@ In addition to the arguments listed above, the following computed attributes are Configuration for the cluster Structure is [documented below](#nested_execution_status). +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + The `execution_status` block contains: diff --git a/website/docs/r/datastream_connection_profile.html.markdown b/website/docs/r/datastream_connection_profile.html.markdown index b00939d1602..24598e6df86 100644 --- a/website/docs/r/datastream_connection_profile.html.markdown +++ b/website/docs/r/datastream_connection_profile.html.markdown @@ -413,6 +413,13 @@ In addition to the arguments listed above, the following computed attributes are * `name` - The resource's name. +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + ## Timeouts diff --git a/website/docs/r/datastream_private_connection.html.markdown b/website/docs/r/datastream_private_connection.html.markdown index ad91a07306c..4d1b9daf0e5 100644 --- a/website/docs/r/datastream_private_connection.html.markdown +++ b/website/docs/r/datastream_private_connection.html.markdown @@ -119,6 +119,13 @@ In addition to the arguments listed above, the following computed attributes are The PrivateConnection error in case of failure. Structure is [documented below](#nested_error). +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + The `error` block contains: diff --git a/website/docs/r/datastream_stream.html.markdown b/website/docs/r/datastream_stream.html.markdown index 83b63f8eb61..e5456a1078b 100644 --- a/website/docs/r/datastream_stream.html.markdown +++ b/website/docs/r/datastream_stream.html.markdown @@ -1554,6 +1554,13 @@ In addition to the arguments listed above, the following computed attributes are * `state` - The state of the stream. +* `terraform_labels` - + The combination of labels configured directly on the resource + and default labels configured on the provider. + +* `effective_labels` - + All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services. + ## Timeouts