Skip to content

Commit f4ad889

Browse files
authored
FEATURE: MMv1 identity() generation support (#15550)
2 parents 49de7f5 + 8523045 commit f4ad889

File tree

15 files changed

+210
-35
lines changed

15 files changed

+210
-35
lines changed

.ci/magician/cmd/vcr_cassette_update_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ func TestExecVCRCassetteUpdate(t *testing.T) {
324324
"GOOGLE_TEST_DIRECTORY": "",
325325
"SA_KEY": "sa_key",
326326
"TF_ACC": "1",
327+
"TF_ACC_REFRESH_AFTER_APPLY": "1",
327328
"TF_LOG": "DEBUG",
328329
"TF_LOG_CORE": "WARN",
329330
"TF_LOG_PATH_MASK": "/mock/dir/magic-modules/.ci/magician/testlogs/replaying/beta/%s.log",
@@ -340,8 +341,8 @@ func TestExecVCRCassetteUpdate(t *testing.T) {
340341
{
341342
name: "replay failed then record",
342343
cmdResults: map[string]string{
343-
"gopath/src/github.com/hashicorp/terraform-provider-google-beta go [test -parallel 32 -v -run=TestAcc -timeout 240m -ldflags=-X=github.com/hashicorp/terraform-provider-google-beta/version.ProviderVersion=acc -vet=off] map[ACCTEST_PARALLELISM:32 GOOGLE_APPLICATION_CREDENTIALS:/mock/dir/magic-modules/.ci/magician/sa_key.json GOOGLE_CREDENTIALS:sa_key GOOGLE_TEST_DIRECTORY: SA_KEY:sa_key TF_ACC:1 TF_LOG:DEBUG TF_LOG_CORE:WARN TF_LOG_PATH_MASK:/mock/dir/magic-modules/.ci/magician/testlogs/replaying/beta/%s.log TF_LOG_SDK_FRAMEWORK:INFO TF_SCHEMA_PANIC_ON_ERROR:1 VCR_MODE:REPLAYING VCR_PATH:/mock/dir/magic-modules/.ci/magician/cassettes/beta]": "--- FAIL: TestAccContainerNodePool_defaultDriverInstallation (590.29s)",
344-
"gopath/src/github.com/hashicorp/terraform-provider-google-beta go [test -parallel 1 -v -run=TestAccContainerNodePool_defaultDriverInstallation$ -timeout 240m -ldflags=-X=github.com/hashicorp/terraform-provider-google-beta/version.ProviderVersion=acc -vet=off] map[ACCTEST_PARALLELISM:1 GOOGLE_APPLICATION_CREDENTIALS:/mock/dir/magic-modules/.ci/magician/sa_key.json GOOGLE_CREDENTIALS:sa_key GOOGLE_TEST_DIRECTORY: SA_KEY:sa_key TF_ACC:1 TF_LOG:DEBUG TF_LOG_CORE:WARN TF_LOG_PATH_MASK:/mock/dir/magic-modules/.ci/magician/testlogs/recording/beta/%s.log TF_LOG_SDK_FRAMEWORK:INFO TF_SCHEMA_PANIC_ON_ERROR:1 VCR_MODE:RECORDING VCR_PATH:/mock/dir/magic-modules/.ci/magician/cassettes/beta]": "--- PASS: TestAccContainerNodePool_defaultDriverInstallation (590.29s)",
344+
"gopath/src/github.com/hashicorp/terraform-provider-google-beta go [test -parallel 32 -v -run=TestAcc -timeout 240m -ldflags=-X=github.com/hashicorp/terraform-provider-google-beta/version.ProviderVersion=acc -vet=off] map[ACCTEST_PARALLELISM:32 GOOGLE_APPLICATION_CREDENTIALS:/mock/dir/magic-modules/.ci/magician/sa_key.json GOOGLE_CREDENTIALS:sa_key GOOGLE_TEST_DIRECTORY: SA_KEY:sa_key TF_ACC:1 TF_ACC_REFRESH_AFTER_APPLY:1 TF_LOG:DEBUG TF_LOG_CORE:WARN TF_LOG_PATH_MASK:/mock/dir/magic-modules/.ci/magician/testlogs/replaying/beta/%s.log TF_LOG_SDK_FRAMEWORK:INFO TF_SCHEMA_PANIC_ON_ERROR:1 VCR_MODE:REPLAYING VCR_PATH:/mock/dir/magic-modules/.ci/magician/cassettes/beta]": "--- FAIL: TestAccContainerNodePool_defaultDriverInstallation (590.29s)",
345+
"gopath/src/github.com/hashicorp/terraform-provider-google-beta go [test -parallel 1 -v -run=TestAccContainerNodePool_defaultDriverInstallation$ -timeout 240m -ldflags=-X=github.com/hashicorp/terraform-provider-google-beta/version.ProviderVersion=acc -vet=off] map[ACCTEST_PARALLELISM:1 GOOGLE_APPLICATION_CREDENTIALS:/mock/dir/magic-modules/.ci/magician/sa_key.json GOOGLE_CREDENTIALS:sa_key GOOGLE_TEST_DIRECTORY: SA_KEY:sa_key TF_ACC:1 TF_ACC_REFRESH_AFTER_APPLY:1 TF_LOG:DEBUG TF_LOG_CORE:WARN TF_LOG_PATH_MASK:/mock/dir/magic-modules/.ci/magician/testlogs/recording/beta/%s.log TF_LOG_SDK_FRAMEWORK:INFO TF_SCHEMA_PANIC_ON_ERROR:1 VCR_MODE:RECORDING VCR_PATH:/mock/dir/magic-modules/.ci/magician/cassettes/beta]": "--- PASS: TestAccContainerNodePool_defaultDriverInstallation (590.29s)",
345346
},
346347
expectedCalls: map[string][]ParameterList{
347348
"Run": {
@@ -357,6 +358,7 @@ func TestExecVCRCassetteUpdate(t *testing.T) {
357358
"GOOGLE_TEST_DIRECTORY": "",
358359
"SA_KEY": "sa_key",
359360
"TF_ACC": "1",
361+
"TF_ACC_REFRESH_AFTER_APPLY": "1",
360362
"TF_LOG": "DEBUG",
361363
"TF_LOG_CORE": "WARN",
362364
"TF_LOG_PATH_MASK": "/mock/dir/magic-modules/.ci/magician/testlogs/replaying/beta/%s.log",
@@ -376,6 +378,7 @@ func TestExecVCRCassetteUpdate(t *testing.T) {
376378
"GOOGLE_TEST_DIRECTORY": "",
377379
"SA_KEY": "sa_key",
378380
"TF_ACC": "1",
381+
"TF_ACC_REFRESH_AFTER_APPLY": "1",
379382
"TF_LOG": "DEBUG",
380383
"TF_LOG_CORE": "WARN",
381384
"TF_LOG_PATH_MASK": "/mock/dir/magic-modules/.ci/magician/testlogs/recording/beta/%s.log",

.ci/magician/vcr/tester.go

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ var safeToLog = map[string]bool{
104104
"PATH": true,
105105
"SA_KEY": false,
106106
"TF_ACC": true,
107+
"TF_ACC_REFRESH_AFTER_APPLY": true,
107108
"TF_LOG": true,
108109
"TF_LOG_CORE": true,
109110
"TF_LOG_PATH_MASK": true,
@@ -253,17 +254,18 @@ func (vt *Tester) Run(opt RunOptions) (Result, error) {
253254
"-vet=off",
254255
)
255256
env := map[string]string{
256-
"VCR_PATH": cassettePath,
257-
"VCR_MODE": opt.Mode.Upper(),
258-
"ACCTEST_PARALLELISM": strconv.Itoa(accTestParallelism),
259-
"GOOGLE_CREDENTIALS": vt.env["SA_KEY"],
260-
"GOOGLE_TEST_DIRECTORY": strings.Join(opt.TestDirs, " "),
261-
"TF_LOG": "DEBUG",
262-
"TF_LOG_CORE": "WARN",
263-
"TF_LOG_SDK_FRAMEWORK": "INFO",
264-
"TF_LOG_PATH_MASK": filepath.Join(logPath, "%s.log"),
265-
"TF_ACC": "1",
266-
"TF_SCHEMA_PANIC_ON_ERROR": "1",
257+
"VCR_PATH": cassettePath,
258+
"VCR_MODE": opt.Mode.Upper(),
259+
"ACCTEST_PARALLELISM": strconv.Itoa(accTestParallelism),
260+
"GOOGLE_CREDENTIALS": vt.env["SA_KEY"],
261+
"GOOGLE_TEST_DIRECTORY": strings.Join(opt.TestDirs, " "),
262+
"TF_LOG": "DEBUG",
263+
"TF_LOG_CORE": "WARN",
264+
"TF_LOG_SDK_FRAMEWORK": "INFO",
265+
"TF_LOG_PATH_MASK": filepath.Join(logPath, "%s.log"),
266+
"TF_ACC": "1",
267+
"TF_ACC_REFRESH_AFTER_APPLY": "1",
268+
"TF_SCHEMA_PANIC_ON_ERROR": "1",
267269
}
268270
if vt.saKeyPath != "" {
269271
env["GOOGLE_APPLICATION_CREDENTIALS"] = filepath.Join(vt.baseDir, vt.saKeyPath)
@@ -401,17 +403,18 @@ func (vt *Tester) runInParallel(mode Mode, version provider.Version, testDir, te
401403
"-vet=off",
402404
}
403405
env := map[string]string{
404-
"VCR_PATH": cassettePath,
405-
"VCR_MODE": mode.Upper(),
406-
"ACCTEST_PARALLELISM": "1",
407-
"GOOGLE_CREDENTIALS": vt.env["SA_KEY"],
408-
"GOOGLE_TEST_DIRECTORY": testDir,
409-
"TF_LOG": "DEBUG",
410-
"TF_LOG_CORE": "WARN",
411-
"TF_LOG_SDK_FRAMEWORK": "INFO",
412-
"TF_LOG_PATH_MASK": filepath.Join(logPath, "%s.log"),
413-
"TF_ACC": "1",
414-
"TF_SCHEMA_PANIC_ON_ERROR": "1",
406+
"VCR_PATH": cassettePath,
407+
"VCR_MODE": mode.Upper(),
408+
"ACCTEST_PARALLELISM": "1",
409+
"GOOGLE_CREDENTIALS": vt.env["SA_KEY"],
410+
"GOOGLE_TEST_DIRECTORY": testDir,
411+
"TF_LOG": "DEBUG",
412+
"TF_LOG_CORE": "WARN",
413+
"TF_LOG_SDK_FRAMEWORK": "INFO",
414+
"TF_LOG_PATH_MASK": filepath.Join(logPath, "%s.log"),
415+
"TF_ACC": "1",
416+
"TF_ACC_REFRESH_AFTER_APPLY": "1",
417+
"TF_SCHEMA_PANIC_ON_ERROR": "1",
415418
}
416419
if vt.saKeyPath != "" {
417420
env["GOOGLE_APPLICATION_CREDENTIALS"] = filepath.Join(vt.baseDir, vt.saKeyPath)

mmv1/api/resource.go

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,11 @@ type Resource struct {
252252
// used for maintaining state stability with resources first provisioned on older api versions.
253253
SchemaVersion int `yaml:"schema_version,omitempty"`
254254

255+
// The version of the identity schema for the resource.
256+
IdentitySchemaVersion int `yaml:"identity_schema_version,omitempty"`
257+
258+
IdentityUpgraders bool `yaml:"identity_upgraders,omitempty"`
259+
255260
// From this schema version on, state_upgrader code is generated for the resource.
256261
// When unset, state_upgrade_base_schema_version defauts to 0.
257262
// Normally, it is not needed to be set.
@@ -634,6 +639,26 @@ func (r Resource) AllNestedProperties(props []*Type) []*Type {
634639
return nested
635640
}
636641

642+
func (r Resource) IdentityProperties() []*Type {
643+
props := make([]*Type, 0)
644+
importFormat := r.ExtractIdentifiers(ImportIdFormats(r.ImportFormat, r.Identity, r.BaseUrl)[0])
645+
optionalValues := map[string]bool{"project": false, "zone": false, "region": false}
646+
for _, p := range r.AllProperties() {
647+
if slices.Contains(importFormat, google.Underscore(p.Name)) {
648+
props = append(props, p)
649+
optionalValues[p.Name] = true
650+
}
651+
}
652+
653+
for _, field := range []string{"project", "zone", "region"} { // prevents duplicates
654+
if slices.Contains(importFormat, field) && !optionalValues[field] {
655+
props = append(props, &Type{Name: field, Type: "string"})
656+
}
657+
}
658+
659+
return props
660+
}
661+
637662
func (r Resource) SensitiveProps() []*Type {
638663
props := r.AllNestedProperties(r.RootProperties())
639664
return google.Select(props, func(p *Type) bool {
@@ -1009,6 +1034,10 @@ func (r Resource) StateMigrationFile() string {
10091034
return fmt.Sprintf("templates/terraform/state_migrations/%s_%s.go.tmpl", google.Underscore(r.ProductMetadata.Name), google.Underscore(r.Name))
10101035
}
10111036

1037+
func (r Resource) IdentityUpgraderFile() string {
1038+
return fmt.Sprintf("templates/terraform/identity_upgraders/%s_%s.go.tmpl", google.Underscore(r.ProductMetadata.Name), google.Underscore(r.Name))
1039+
}
1040+
10121041
// ====================
10131042
// Version-related methods
10141043
// ====================
@@ -1268,7 +1297,6 @@ func ImportIdFormats(importFormat, identity []string, baseUrl string) []string {
12681297
// short id: {{project}}/{{zone}}/{{name}}
12691298
fieldMarkers := regexp.MustCompile(`{{[[:word:]]+}}`).FindAllString(idFormats[0], -1)
12701299
shortIdFormat := strings.Join(fieldMarkers, "/")
1271-
12721300
// short ids without fields with provider-level defaults:
12731301

12741302
// without project
@@ -1314,6 +1342,7 @@ func ImportIdFormats(importFormat, identity []string, baseUrl string) []string {
13141342
uniq = google.Reject(slices.Compact(uniq), func(i string) bool {
13151343
return i == ""
13161344
})
1345+
13171346
return uniq
13181347
}
13191348

@@ -2050,6 +2079,21 @@ func (r Resource) StateUpgradersCount() []int {
20502079
return nums
20512080
}
20522081

2082+
func (r Resource) IdentityUpgradersCount() []int {
2083+
var nums []int
2084+
for i := 1; i < r.IdentitySchemaVersion; i++ {
2085+
nums = append(nums, i)
2086+
}
2087+
return nums
2088+
}
2089+
2090+
func (r Resource) GetIdentitySchemaVersion() int {
2091+
if r.IdentitySchemaVersion == 0 { // default to 1 if not set; a resource with no identity support has a version of 0
2092+
return 1
2093+
}
2094+
return r.IdentitySchemaVersion
2095+
}
2096+
20532097
func (r Resource) CaiProductBaseUrl() string {
20542098
return r.ProductMetadata.ServiceBaseUrl()
20552099
}

mmv1/api/resource/custom_code.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,13 @@ type CustomCode struct {
128128
// inserts that for you - do not include it in your custom code.
129129
CustomImport string `yaml:"custom_import,omitempty"`
130130

131+
// This code replaces the entire identity schema method. Since the identity schema method's function header can't be changed, the template
132+
// inserts that for you - do not include it in your custom code.
133+
CustomIdentitySchema *string `yaml:"custom_identity_schema,omitempty"`
134+
135+
// This code is run in the Read method to set the identity.
136+
CustomIdentityRead string `yaml:"custom_identity_read"`
137+
131138
// This code is run just after the import method succeeds - it
132139
// is useful for parsing attributes that are necessary for
133140
// the Read() method to succeed.

mmv1/products/apigee/AddonsConfig.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ async:
4141
custom_code:
4242
custom_import: 'templates/terraform/custom_import/apigee_addons.go.tmpl'
4343
test_check_destroy: 'templates/terraform/custom_check_destroy/apigee_addons_override.go.tmpl'
44+
custom_identity_schema: 'templates/terraform/custom_identity_schema/apigee_addons.go.tmpl'
45+
custom_identity_read: 'templates/terraform/custom_identity_read/apigee_addons.go.tmpl'
4446
examples:
4547
- name: 'apigee_addons_basic'
4648
exclude_test: true

mmv1/products/iap/Brand.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ identity:
5757
- name
5858
custom_code:
5959
custom_import: 'templates/terraform/custom_import/iap_brand.go.tmpl'
60+
custom_identity_schema: 'templates/terraform/custom_identity_schema/iap_brand.go.tmpl'
61+
custom_identity_read: 'templates/terraform/custom_identity_read/iap_brand.go.tmpl'
6062
examples:
6163
- name: 'iap_brand'
6264
primary_resource_id: 'project_brand'
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
identity, err := d.Identity()
2+
if err != nil {
3+
return fmt.Errorf("Error getting identity: %s", err)
4+
}
5+
if v, ok := identity.GetOk("org"); ok && v != "" {
6+
err = identity.Set("org", d.Get("org").(string))
7+
if err != nil {
8+
return fmt.Errorf("Error setting org: %s", err)
9+
}
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
identity, err := d.Identity()
2+
if err != nil {
3+
return fmt.Errorf("Error getting identity: %s", err)
4+
}
5+
if v, ok := identity.GetOk("project"); ok && v != "" {
6+
err = identity.Set("project", d.Get("project").(string))
7+
if err != nil {
8+
return fmt.Errorf("Error setting project: %s", err)
9+
}
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Identity: &schema.ResourceIdentity{
2+
Version: 1,
3+
SchemaFunc: func() map[string]*schema.Schema {
4+
return map[string]*schema.Schema{
5+
"org": {
6+
Type: schema.TypeString,
7+
RequiredForImport: true,
8+
},
9+
}
10+
},
11+
},
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Identity: &schema.ResourceIdentity{
2+
Version: 1,
3+
SchemaFunc: func() map[string]*schema.Schema {
4+
return map[string]*schema.Schema{
5+
"org": {
6+
Type: schema.TypeString,
7+
RequiredForImport: true,
8+
},
9+
}
10+
},
11+
},

0 commit comments

Comments
 (0)