Skip to content

Commit 1cc2cb1

Browse files
authored
resourceIdentity: add Identity support in MMv1/DCL resources (#14125)
2 parents 1bd4eb0 + 918cbfc commit 1cc2cb1

File tree

21 files changed

+504
-186
lines changed

21 files changed

+504
-186
lines changed

mmv1/api/resource.go

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

252+
// The version of the identity schema for the resource.
253+
IdentitySchemaVersion int `yaml:"identity_schema_version,omitempty"`
254+
255+
IdentityUpgraders bool `yaml:"identity_upgraders,omitempty"`
256+
252257
// From this schema version on, state_upgrader code is generated for the resource.
253258
// When unset, state_upgrade_base_schema_version defauts to 0.
254259
// Normally, it is not needed to be set.
@@ -598,6 +603,26 @@ func (r Resource) AllNestedProperties(props []*Type) []*Type {
598603
return nested
599604
}
600605

606+
func (r Resource) IdentityProperties() []*Type {
607+
props := make([]*Type, 0)
608+
importFormat := r.ExtractIdentifiers(ImportIdFormats(r.ImportFormat, r.Identity, r.BaseUrl)[0])
609+
optionalValues := map[string]bool{"project": false, "zone": false, "region": false}
610+
for _, p := range r.AllProperties() {
611+
if slices.Contains(importFormat, google.Underscore(p.Name)) {
612+
props = append(props, p)
613+
optionalValues[p.Name] = true
614+
}
615+
}
616+
617+
for _, field := range []string{"project", "zone", "region"} { // prevents duplicates
618+
if slices.Contains(importFormat, field) && !optionalValues[field] {
619+
props = append(props, &Type{Name: field, Type: "string"})
620+
}
621+
}
622+
623+
return props
624+
}
625+
601626
func (r Resource) SensitiveProps() []*Type {
602627
props := r.AllNestedProperties(r.RootProperties())
603628
return google.Select(props, func(p *Type) bool {
@@ -886,6 +911,10 @@ func (r Resource) StateMigrationFile() string {
886911
return fmt.Sprintf("templates/terraform/state_migrations/%s_%s.go.tmpl", google.Underscore(r.ProductMetadata.Name), google.Underscore(r.Name))
887912
}
888913

914+
func (r Resource) IdentityUpgraderFile() string {
915+
return fmt.Sprintf("templates/terraform/identity_upgraders/%s_%s.go.tmpl", google.Underscore(r.ProductMetadata.Name), google.Underscore(r.Name))
916+
}
917+
889918
// ====================
890919
// Version-related methods
891920
// ====================
@@ -1145,7 +1174,6 @@ func ImportIdFormats(importFormat, identity []string, baseUrl string) []string {
11451174
// short id: {{project}}/{{zone}}/{{name}}
11461175
fieldMarkers := regexp.MustCompile(`{{[[:word:]]+}}`).FindAllString(idFormats[0], -1)
11471176
shortIdFormat := strings.Join(fieldMarkers, "/")
1148-
11491177
// short ids without fields with provider-level defaults:
11501178

11511179
// without project
@@ -1191,6 +1219,7 @@ func ImportIdFormats(importFormat, identity []string, baseUrl string) []string {
11911219
uniq = google.Reject(slices.Compact(uniq), func(i string) bool {
11921220
return i == ""
11931221
})
1222+
11941223
return uniq
11951224
}
11961225

@@ -1835,6 +1864,21 @@ func (r Resource) StateUpgradersCount() []int {
18351864
return nums
18361865
}
18371866

1867+
func (r Resource) IdentityUpgradersCount() []int {
1868+
var nums []int
1869+
for i := 1; i < r.IdentitySchemaVersion; i++ {
1870+
nums = append(nums, i)
1871+
}
1872+
return nums
1873+
}
1874+
1875+
func (r Resource) GetIdentitySchemaVersion() int {
1876+
if r.IdentitySchemaVersion == 0 { // default to 1 if not set; a resource with no identity support has a version of 0
1877+
return 1
1878+
}
1879+
return r.IdentitySchemaVersion
1880+
}
1881+
18381882
func (r Resource) CaiProductBaseUrl() string {
18391883
version := r.ProductMetadata.VersionObjOrClosest(r.TargetVersionName)
18401884
baseUrl := version.CaiBaseUrl

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"`
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
@@ -53,6 +53,8 @@ identity:
5353
- name
5454
custom_code:
5555
custom_import: 'templates/terraform/custom_import/iap_brand.go.tmpl'
56+
custom_identity_schema: 'templates/terraform/custom_identity_schema/iap_brand.go.tmpl'
57+
custom_identity_read: 'templates/terraform/custom_identity_read/iap_brand.go.tmpl'
5658
examples:
5759
- name: 'iap_brand'
5860
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+
},
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+
"name": {
6+
Type: schema.TypeString,
7+
RequiredForImport: true,
8+
},
9+
}
10+
},
11+
},

mmv1/templates/terraform/resource.go.tmpl

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,38 @@ func Resource{{ $.ResourceName -}}() *schema.Resource {
131131
DeprecationMessage: "{{ $.DeprecationMessage -}}",
132132
{{- end}}
133133

134+
{{ if $.CustomCode.CustomIdentitySchema }}
135+
{{ $.CustomTemplate $.CustomCode.CustomIdentitySchema false -}}
136+
{{ else }}
137+
Identity: &schema.ResourceIdentity{
138+
Version: {{ $.GetIdentitySchemaVersion }},
139+
SchemaFunc: func() map[string]*schema.Schema {
140+
return map[string]*schema.Schema{
141+
{{- range $p := .IdentityProperties }}
142+
"{{ underscore $p.Name}}": {
143+
Type: schema.TypeString,
144+
{{- if or $p.Required $p.Output }}
145+
RequiredForImport: true,
146+
{{- else }}
147+
OptionalForImport: true,
148+
{{- end }}
149+
},
150+
{{- end }}
151+
}
152+
},
153+
{{- if $.IdentityUpgraders }}
154+
IdentityUpgraders: []schema.IdentityUpgrader{
155+
{{- range $v := $.IdentityUpgradersCount }}
156+
{
157+
Type: identity{{ $.ResourceName }}ResourceV{{$v}}(),
158+
Upgrade: Identity{{ $.ResourceName }}UpgradeV{{$v}},
159+
Version: {{$v}},
160+
},
161+
{{- end }}
162+
},
163+
{{- end }}
164+
},
165+
{{- end }}
134166
Schema: map[string]*schema.Schema{
135167
{{- range $prop := $.OrderProperties $.AllUserProperties }}
136168
{{template "SchemaFields" $prop -}}
@@ -686,8 +718,24 @@ func resource{{ $.ResourceName -}}Read(d *schema.ResourceData, meta interface{})
686718
}
687719
{{- end}}
688720

689-
return nil
721+
{{- if $.CustomCode.CustomIdentityRead }}
722+
{{ $.CustomTemplate $.CustomCode.CustomIdentityRead true -}}
723+
{{- else }}
724+
identity, err := d.Identity()
725+
if err != nil {
726+
return fmt.Errorf("Error getting identity: %s", err)
727+
}
728+
{{- range $p := $.IdentityProperties }}
729+
if v, ok := identity.GetOk("{{ underscore $p.Name}}"); ok && v != "" {
730+
err = identity.Set("{{ underscore $p.Name}}", d.Get("{{ underscore $p.Name}}").(string))
731+
if err != nil {
732+
return fmt.Errorf("Error setting {{ underscore $p.Name}}: %s", err)
733+
}
734+
}
735+
{{- end }}
736+
{{- end }}
690737
{{ end -}}
738+
return nil
691739
}
692740

693741
{{if $.Updatable -}}
@@ -1222,6 +1270,12 @@ func resource{{ $.ResourceName -}}PostCreateFailure(d *schema.ResourceData, meta
12221270

12231271
{{ $.CustomTemplate $.StateMigrationFile false -}}
12241272
{{- end }}
1273+
1274+
{{- if and $.IdentitySchemaVersion $.IdentityUpgraders }}
1275+
1276+
{{ $.CustomTemplate $.IdentityUpgraderFile false -}}
1277+
{{- end }}
1278+
12251279
{{- if and $.HasPostCreateComputedFields (or (or (not $.GetAsync) (not ($.GetAsync.Allow "Create"))) (and $.GetAsync (and ($.GetAsync.IsA "PollAsync") ($.GetAsync.Allow "Create"))))}}
12261280
func resource{{ $.ResourceName -}}PostCreateSetComputedFields(d *schema.ResourceData, meta interface{}, res map[string]interface{}) error {
12271281
config := meta.(*transport_tpg.Config)

0 commit comments

Comments
 (0)