From 41ff348d43361992a955f3e992a32ce928648ad5 Mon Sep 17 00:00:00 2001 From: "alvarez.mauriciotm@gmail.com" Date: Thu, 28 May 2026 13:10:36 -0700 Subject: [PATCH 1/2] add values from import_format not in properties list --- mmv1/api/resource.go | 18 ++++++++++++++---- mmv1/api/resource_test.go | 24 ++++++++++++++++++++++++ mmv1/products/bigquery/Dataset.yaml | 2 -- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/mmv1/api/resource.go b/mmv1/api/resource.go index e191a6636bcd..0c7ba3933762 100644 --- a/mmv1/api/resource.go +++ b/mmv1/api/resource.go @@ -710,21 +710,31 @@ func (r Resource) IdentityProperties() []*Type { identities = nil } importFormat := r.ExtractIdentifiers(ImportIdFormats(r.ImportFormat, identities, r.BaseUrl)[0]) - optionalValues := map[string]bool{"project": false, "zone": false, "region": false} + includedValues := make(map[string]bool) for _, p := range r.AllProperties() { - if slices.Contains(importFormat, google.Underscore(p.Name)) { + name := google.Underscore(p.Name) + if slices.Contains(importFormat, name) { props = append(props, p) - optionalValues[p.Name] = true + includedValues[name] = true } } hasField := map[string]bool{"project": r.HasProject(), "zone": r.HasZone(), "region": r.HasRegion()} for _, field := range []string{"project", "zone", "region"} { // prevents duplicates - if slices.Contains(importFormat, field) && !optionalValues[field] && hasField[field] { + if slices.Contains(importFormat, field) && !includedValues[field] && hasField[field] { props = append(props, &Type{Name: field, Type: "string"}) + includedValues[field] = true } } + for _, field := range importFormat { + if includedValues[field] || field == "project" || field == "zone" || field == "region" { + continue + } + props = append(props, &Type{Name: field, Type: "string", Required: true}) + includedValues[field] = true + } + if len(r.CustomCode.CustomIdentity) > 0 { for _, fieldName := range r.CustomCode.CustomIdentity { props = append(props, &Type{Name: google.Underscore(fieldName), Type: "string", Required: true}) diff --git a/mmv1/api/resource_test.go b/mmv1/api/resource_test.go index f3b35c4913aa..8cc809a7d63b 100644 --- a/mmv1/api/resource_test.go +++ b/mmv1/api/resource_test.go @@ -884,3 +884,27 @@ func TestSample_TestServiceDependencies(t *testing.T) { }) } } + +func TestIdentityPropertiesIncludesMissingImportIdentifiers(t *testing.T) { + t.Parallel() + + r := api.Resource{ + BaseUrl: "projects/{{project}}/datasets", + ImportFormat: []string{"projects/{{project}}/datasets/{{dataset_id}}"}, + } + + got := r.IdentityProperties() + gotNames := make([]string, 0, len(got)) + for _, p := range got { + gotNames = append(gotNames, p.Name) + } + + wantNames := []string{"project", "dataset_id"} + if diff := cmp.Diff(wantNames, gotNames); diff != "" { + t.Fatalf("IdentityProperties() names mismatch (-want +got):\n%s", diff) + } + + if !got[1].Required { + t.Fatalf("dataset_id should be required when synthesized from import format") + } +} diff --git a/mmv1/products/bigquery/Dataset.yaml b/mmv1/products/bigquery/Dataset.yaml index 5d389755f6c4..a27da3faadf9 100644 --- a/mmv1/products/bigquery/Dataset.yaml +++ b/mmv1/products/bigquery/Dataset.yaml @@ -43,8 +43,6 @@ custom_code: pre_read: 'templates/terraform/pre_read/bigquery_dataset.go.tmpl' custom_diff: - 'customCollationDiff' -# exluding resource_identity due to dataset_id field -exclude_identity_generation: true exclude_sweeper: true examples: - name: 'bigquery_dataset_basic' From 72cea868512be2f55610d9cb7ab258aef621e2ab Mon Sep 17 00:00:00 2001 From: "alvarez.mauriciotm@gmail.com" Date: Thu, 28 May 2026 15:31:39 -0700 Subject: [PATCH 2/2] prevent name from being included in identity set --- mmv1/api/resource.go | 6 ++++++ mmv1/api/resource_test.go | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/mmv1/api/resource.go b/mmv1/api/resource.go index 0c7ba3933762..b74dda309f6e 100644 --- a/mmv1/api/resource.go +++ b/mmv1/api/resource.go @@ -731,6 +731,12 @@ func (r Resource) IdentityProperties() []*Type { if includedValues[field] || field == "project" || field == "zone" || field == "region" { continue } + // Avoid creating an identity-only synthetic `name` field when the resource + // schema does not define one. This commonly happens with singleton resources + // when import format defaults to base_url/{{name}}. + if field == "name" { + continue + } props = append(props, &Type{Name: field, Type: "string", Required: true}) includedValues[field] = true } diff --git a/mmv1/api/resource_test.go b/mmv1/api/resource_test.go index 8cc809a7d63b..36aa6073eb85 100644 --- a/mmv1/api/resource_test.go +++ b/mmv1/api/resource_test.go @@ -908,3 +908,25 @@ func TestIdentityPropertiesIncludesMissingImportIdentifiers(t *testing.T) { t.Fatalf("dataset_id should be required when synthesized from import format") } } + +func TestIdentityPropertiesSkipsSyntheticNameWhenNotInSchema(t *testing.T) { + t.Parallel() + + r := api.Resource{ + BaseUrl: "projects/{{project}}/locations/{{location}}/encryptionSpec", + Parameters: []*api.Type{ + {Name: "location", Type: "string"}, + }, + } + + got := r.IdentityProperties() + gotNames := make([]string, 0, len(got)) + for _, p := range got { + gotNames = append(gotNames, p.Name) + } + + wantNames := []string{"location", "project"} + if diff := cmp.Diff(wantNames, gotNames); diff != "" { + t.Fatalf("IdentityProperties() names mismatch (-want +got):\n%s", diff) + } +}