Skip to content

Commit dfc399d

Browse files
shuyama1melinath
andauthored
Update Test Generation: IAM (#15657)
Co-authored-by: Stephen Lewis (Burrows) <[email protected]>
1 parent ffda1d5 commit dfc399d

File tree

11 files changed

+861
-11
lines changed

11 files changed

+861
-11
lines changed

mmv1/api/resource.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1696,6 +1696,22 @@ func (r Resource) ExamplePrimaryResourceId() string {
16961696
return examples[0].PrimaryResourceId
16971697
}
16981698

1699+
func (r Resource) SamplePrimaryResourceId() string {
1700+
samples := google.Reject(r.Samples, func(s *resource.Sample) bool {
1701+
return s.ExcludeTest
1702+
})
1703+
samples = google.Reject(samples, func(s *resource.Sample) bool {
1704+
return (r.ProductMetadata.VersionObjOrClosest(r.TargetVersionName).CompareTo(r.ProductMetadata.VersionObjOrClosest(s.MinVersion)) < 0)
1705+
})
1706+
1707+
if len(samples) == 0 {
1708+
samples = google.Reject(r.Samples, func(s *resource.Sample) bool {
1709+
return (r.ProductMetadata.VersionObjOrClosest(r.TargetVersionName).CompareTo(r.ProductMetadata.VersionObjOrClosest(s.MinVersion)) < 0)
1710+
})
1711+
}
1712+
return samples[0].PrimaryResourceId
1713+
}
1714+
16991715
func (r Resource) IamParentSourceType() string {
17001716
t := r.IamPolicy.ParentResourceType
17011717
if t == "" {
@@ -1765,6 +1781,53 @@ func (r Resource) IamImportQualifiersForTest() string {
17651781
return strings.Join(importQualifiers, ", ")
17661782
}
17671783

1784+
func (r Resource) IamImportQualifiersForTestSample() string {
1785+
var importFormat string
1786+
if len(r.IamPolicy.ImportFormat) > 0 {
1787+
importFormat = r.IamPolicy.ImportFormat[0]
1788+
} else {
1789+
importFormat = r.IamPolicy.SelfLink
1790+
if importFormat == "" {
1791+
importFormat = r.SelfLinkUrl()
1792+
}
1793+
}
1794+
1795+
params := r.ExtractIdentifiers(importFormat)
1796+
var importQualifiers []string
1797+
for i, param := range params {
1798+
if param == "project" {
1799+
if i != len(params)-1 {
1800+
// If the last parameter is project then we want to create a new project to use for the test, so don't default from the environment
1801+
if r.IamPolicy.TestProjectName == "" {
1802+
importQualifiers = append(importQualifiers, "envvar.GetTestProjectFromEnv()")
1803+
} else {
1804+
importQualifiers = append(importQualifiers, `context["project_id"]`)
1805+
}
1806+
}
1807+
} else if param == "zone" && r.IamPolicy.SubstituteZoneValue {
1808+
importQualifiers = append(importQualifiers, "envvar.GetTestZoneFromEnv()")
1809+
} else if param == "region" || param == "location" {
1810+
testConfig := r.FirstTestConfig()
1811+
sample := testConfig.Sample
1812+
if sample.RegionOverride == "" {
1813+
importQualifiers = append(importQualifiers, "envvar.GetTestRegionFromEnv()")
1814+
} else {
1815+
importQualifiers = append(importQualifiers, fmt.Sprintf("\"%s\"", sample.RegionOverride))
1816+
}
1817+
} else if param == "universe_domain" {
1818+
importQualifiers = append(importQualifiers, "envvar.GetTestUniverseDomainFromEnv()")
1819+
} else {
1820+
break
1821+
}
1822+
}
1823+
1824+
if len(importQualifiers) == 0 {
1825+
return ""
1826+
}
1827+
1828+
return strings.Join(importQualifiers, ", ")
1829+
}
1830+
17681831
func (r Resource) OrderProperties(props []*Type) []*Type {
17691832
req := google.Select(props, func(p *Type) bool {
17701833
return p.Required

mmv1/api/resource/iam_policy.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ type IamPolicy struct {
9090
// config with the test/example attributes of the IAM resource.
9191
ExampleConfigBody string `yaml:"example_config_body,omitempty"`
9292

93+
SampleConfigBody string `yaml:"sample_config_body"`
94+
9395
// How the API supports IAM conditions
9496
IamConditionsRequestType string `yaml:"iam_conditions_request_type,omitempty"`
9597

@@ -130,7 +132,6 @@ func (p *IamPolicy) UnmarshalYAML(value *yaml.Node) error {
130132
p.WrappedPolicyObj = true
131133
p.AllowedIamRole = "roles/viewer"
132134
p.ParentResourceAttribute = "id"
133-
p.ExampleConfigBody = "templates/terraform/iam/iam_attributes.go.tmpl"
134135
p.SubstituteZoneValue = true
135136

136137
type iamPolicyAlias IamPolicy

mmv1/provider/template_data.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,18 @@ func (td *TemplateData) GenerateIamDatasourceDocumentationFile(filePath string,
254254
td.GenerateFile(filePath, templatePath, resource, false, templates...)
255255
}
256256

257-
func (td *TemplateData) GenerateIamPolicyTestFile(filePath string, resource api.Resource) {
257+
func (td *TemplateData) GenerateIamPolicyTestFileLegacy(filePath string, resource api.Resource) {
258258
templatePath := "templates/terraform/examples/base_configs/iam_test_file.go.tmpl"
259+
templates := []string{
260+
templatePath,
261+
"templates/terraform/env_var_context.go.tmpl",
262+
"templates/terraform/iam/iam_test_setup_legacy.go.tmpl",
263+
}
264+
td.GenerateFile(filePath, templatePath, resource, true, templates...)
265+
}
266+
267+
func (td *TemplateData) GenerateIamPolicyTestFile(filePath string, resource api.Resource) {
268+
templatePath := "templates/terraform/samples/base_configs/iam_test_file.go.tmpl"
259269
templates := []string{
260270
templatePath,
261271
"templates/terraform/env_var_context.go.tmpl",

mmv1/provider/terraform.go

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,10 @@ func (t *Terraform) GenerateOperation(outputFolder string) {
326326

327327
// Generate the IAM policy for this object. This is used to query and test
328328
// IAM policies separately from the resource itself
329-
func (t *Terraform) GenerateIamPolicy(object api.Resource, templateData TemplateData, outputFolder string, generateCode, generateDocs bool) {
329+
func (t *Terraform) GenerateIamPolicyLegacy(object api.Resource, templateData TemplateData, outputFolder string, generateCode, generateDocs bool) {
330+
if object.IamPolicy.ExampleConfigBody == "" {
331+
object.IamPolicy.ExampleConfigBody = "templates/terraform/iam/iam_attributes_legacy.go.tmpl"
332+
}
330333
if generateCode && object.IamPolicy != nil && (object.IamPolicy.MinVersion == "" || slices.Index(product.ORDER, object.IamPolicy.MinVersion) <= slices.Index(product.ORDER, t.TargetVersionName)) {
331334
productName := t.Product.ApiName
332335
targetFolder := path.Join(outputFolder, t.FolderName(), "services", productName)
@@ -341,6 +344,42 @@ func (t *Terraform) GenerateIamPolicy(object api.Resource, templateData Template
341344
return e.ExcludeTest
342345
})
343346
if len(examples) != 0 {
347+
targetFilePath := path.Join(targetFolder, fmt.Sprintf("iam_%s_generated_test.go", t.ResourceGoFilename(object)))
348+
templateData.GenerateIamPolicyTestFileLegacy(targetFilePath, object)
349+
}
350+
}
351+
if generateDocs {
352+
t.GenerateIamDocumentation(object, templateData, outputFolder, generateCode, generateDocs)
353+
}
354+
}
355+
356+
func (t *Terraform) GenerateIamPolicy(object api.Resource, templateData TemplateData, outputFolder string, generateCode, generateDocs bool) {
357+
if object.Samples != nil && object.Examples != nil {
358+
log.Fatalf("Both Samples and Examples block exist in %v", object.Name)
359+
}
360+
if object.Examples != nil {
361+
t.GenerateIamPolicyLegacy(object, templateData, outputFolder, generateCode, generateDocs)
362+
return
363+
}
364+
365+
if object.IamPolicy.SampleConfigBody == "" {
366+
object.IamPolicy.SampleConfigBody = "templates/terraform/iam/iam_attributes.go.tmpl"
367+
}
368+
369+
if generateCode && object.IamPolicy != nil && (object.IamPolicy.MinVersion == "" || slices.Index(product.ORDER, object.IamPolicy.MinVersion) <= slices.Index(product.ORDER, t.TargetVersionName)) {
370+
productName := t.Product.ApiName
371+
targetFolder := path.Join(outputFolder, t.FolderName(), "services", productName)
372+
if err := os.MkdirAll(targetFolder, os.ModePerm); err != nil {
373+
log.Println(fmt.Errorf("error creating parent directory %v: %v", targetFolder, err))
374+
}
375+
targetFilePath := path.Join(targetFolder, fmt.Sprintf("iam_%s.go", t.ResourceGoFilename(object)))
376+
templateData.GenerateIamPolicyFile(targetFilePath, object)
377+
378+
// Only generate test if testable example configs exist.
379+
samples := google.Reject(object.Samples, func(s *resource.Sample) bool {
380+
return s.ExcludeTest
381+
})
382+
if len(samples) != 0 {
344383
targetFilePath := path.Join(targetFolder, fmt.Sprintf("iam_%s_generated_test.go", t.ResourceGoFilename(object)))
345384
templateData.GenerateIamPolicyTestFile(targetFilePath, object)
346385
}

mmv1/templates/terraform/datasource_iam.html.markdown.tmpl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,13 @@ data "{{ $.IamTerraformName }}_policy" "policy" {
6262
{{- if eq $.MinVersionObj.Name "beta" }}
6363
provider = google-beta
6464
{{- end }}
65+
{{- if $.IamPolicy.ExampleConfigBody}}
6566
{{- $.CustomTemplate $.IamPolicy.ExampleConfigBody false }}
67+
{{- end }}
68+
69+
{{- if $.IamPolicy.SampleConfigBody}}
70+
{{- $.CustomTemplate $.IamPolicy.SampleConfigBody false }}
71+
{{- end }}
6672
}
6773
```
6874

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
{{- $primaryResourceId := $.ExamplePrimaryResourceId }}
1+
{{- $primaryResourceId := $.SamplePrimaryResourceId }}
22
{{- $ids := $.IamSelfLinkIdentifiers }}
33
{{- range $i, $attribute := $.IamAttributes}}
44
{{ $attribute }} = {{ $.IamParentSourceType }}.{{ $primaryResourceId }}.{{ underscore (index $ids $i)}}
5-
{{- end }}
5+
{{- end }}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{{- $primaryResourceId := $.ExamplePrimaryResourceId }}
2+
{{- $ids := $.IamSelfLinkIdentifiers }}
3+
{{- range $i, $attribute := $.IamAttributes}}
4+
{{ $attribute }} = {{ $.IamParentSourceType }}.{{ $primaryResourceId }}.{{ underscore (index $ids $i)}}
5+
{{- end }}

mmv1/templates/terraform/iam/iam_test_setup.go.tmpl

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
{{- define "IamTestSetup" }}
2-
{{- if $.FirstTestExample.BootstrapIam }}
1+
{{- define "IamTestSetupSample" }}
2+
{{ $config := $.FirstTestConfig }}
3+
{{ $sample := $config.Sample }}
4+
{{ $step := $config.Step }}
5+
{{- if $sample.BootstrapIam }}
36
acctest.BootstrapIamMembers(t, []acctest.IamMember{
4-
{{- range $iam := $.FirstTestExample.BootstrapIam }}
7+
{{- range $iam := $sample.BootstrapIam }}
58
{
69
Member: "{{$iam.Member}}",
710
Role: "{{$iam.Role}}",
@@ -18,9 +21,9 @@
1821
{{- if $.IamPolicy.TestProjectName }}
1922
"project_id" : fmt.Sprintf("{{ $.IamPolicy.TestProjectName }}%s", acctest.RandString(t, 10)),
2023
{{- end }}
21-
{{- template "EnvVarContext" dict "TestEnvVars" $.FirstTestExample.TestEnvVars "HasNewLine" true}}
22-
{{- if $.FirstTestExample.TestVarsOverrides }}
23-
{{- range $varName, $override := $.FirstTestExample.TestVarsOverrides }}
24+
{{- template "EnvVarContext" dict "TestEnvVars" $step.TestEnvVars "HasNewLine" true}}
25+
{{- if $step.TestVarsOverrides }}
26+
{{- range $varName, $override := $step.TestVarsOverrides }}
2427
"{{ $varName }}": {{ $override }},
2528
{{- end }}
2629
{{- end }}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{{- define "IamTestSetup" }}
2+
{{- if $.FirstTestExample.BootstrapIam }}
3+
acctest.BootstrapIamMembers(t, []acctest.IamMember{
4+
{{- range $iam := $.FirstTestExample.BootstrapIam }}
5+
{
6+
Member: "{{$iam.Member}}",
7+
Role: "{{$iam.Role}}",
8+
},
9+
{{- end}}
10+
})
11+
{{- end }}
12+
context := map[string]interface{}{
13+
"random_suffix": acctest.RandString(t, 10),
14+
"role": "{{ $.IamPolicy.AllowedIamRole }}",
15+
{{- if $.IamPolicy.AdminIamRole }}
16+
"admin_role": "{{ $.IamPolicy.AdminIamRole }}",
17+
{{- end }}
18+
{{- if $.IamPolicy.TestProjectName }}
19+
"project_id" : fmt.Sprintf("{{ $.IamPolicy.TestProjectName }}%s", acctest.RandString(t, 10)),
20+
{{- end }}
21+
{{- template "EnvVarContext" dict "TestEnvVars" $.FirstTestExample.TestEnvVars "HasNewLine" true}}
22+
{{- if $.FirstTestExample.TestVarsOverrides }}
23+
{{- range $varName, $override := $.FirstTestExample.TestVarsOverrides }}
24+
"{{ $varName }}": {{ $override }},
25+
{{- end }}
26+
{{- end }}
27+
{{- if $.IamPolicy.IamConditionsRequestType }}
28+
"condition_title": "expires_after_2019_12_31",
29+
"condition_expr": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`,
30+
"condition_desc": "Expiring at midnight of 2019-12-31",
31+
"condition_title_no_desc": "expires_after_2019_12_31-no-description",
32+
"condition_expr_no_desc": `request.time < timestamp(\"2020-01-01T00:00:00Z\")`,
33+
{{- end }}
34+
}
35+
{{- end }}

mmv1/templates/terraform/resource_iam.html.markdown.tmpl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,13 @@ resource "{{ $.IamTerraformName }}_policy" "policy" {
8686
{{- if eq $.MinVersionObj.Name "beta" }}
8787
provider = google-beta
8888
{{- end }}
89+
{{- if $.IamPolicy.ExampleConfigBody}}
8990
{{- $.CustomTemplate $.IamPolicy.ExampleConfigBody false }}
91+
{{- end }}
92+
93+
{{- if $.IamPolicy.SampleConfigBody}}
94+
{{- $.CustomTemplate $.IamPolicy.SampleConfigBody false }}
95+
{{- end }}
9096
policy_data = data.google_iam_policy.admin.policy_data
9197
}
9298
```
@@ -116,7 +122,13 @@ resource "{{ $.IamTerraformName }}_policy" "policy" {
116122
{{- if eq $.MinVersionObj.Name "beta" }}
117123
provider = google-beta
118124
{{- end }}
125+
{{- if $.IamPolicy.ExampleConfigBody}}
119126
{{- $.CustomTemplate $.IamPolicy.ExampleConfigBody false }}
127+
{{- end }}
128+
129+
{{- if $.IamPolicy.SampleConfigBody}}
130+
{{- $.CustomTemplate $.IamPolicy.SampleConfigBody false }}
131+
{{- end }}
120132
policy_data = data.google_iam_policy.admin.policy_data
121133
}
122134
```
@@ -128,7 +140,13 @@ resource "{{ $.IamTerraformName }}_binding" "binding" {
128140
{{- if eq $.MinVersionObj.Name "beta" }}
129141
provider = google-beta
130142
{{- end }}
143+
{{- if $.IamPolicy.ExampleConfigBody}}
131144
{{- $.CustomTemplate $.IamPolicy.ExampleConfigBody false }}
145+
{{- end }}
146+
147+
{{- if $.IamPolicy.SampleConfigBody}}
148+
{{- $.CustomTemplate $.IamPolicy.SampleConfigBody false }}
149+
{{- end }}
132150
role = "{{if $.IamPolicy.AdminIamRole}}{{$.IamPolicy.AdminIamRole }}{{else}}{{$.IamPolicy.AllowedIamRole}}{{end}}"
133151
members = [
134152
@@ -143,7 +161,13 @@ resource "{{ $.IamTerraformName }}_binding" "binding" {
143161
{{- if eq $.MinVersionObj.Name "beta" }}
144162
provider = google-beta
145163
{{- end }}
164+
{{- if $.IamPolicy.ExampleConfigBody}}
146165
{{- $.CustomTemplate $.IamPolicy.ExampleConfigBody false }}
166+
{{- end }}
167+
168+
{{- if $.IamPolicy.SampleConfigBody}}
169+
{{- $.CustomTemplate $.IamPolicy.SampleConfigBody false }}
170+
{{- end }}
147171
role = "{{if $.IamPolicy.AdminIamRole}}{{$.IamPolicy.AdminIamRole }}{{else}}{{$.IamPolicy.AllowedIamRole}}{{end}}"
148172
members = [
149173
@@ -164,7 +188,13 @@ resource "{{ $.IamTerraformName }}_member" "member" {
164188
{{- if eq $.MinVersionObj.Name "beta" }}
165189
provider = google-beta
166190
{{- end }}
191+
{{- if $.IamPolicy.ExampleConfigBody}}
167192
{{- $.CustomTemplate $.IamPolicy.ExampleConfigBody false }}
193+
{{- end }}
194+
195+
{{- if $.IamPolicy.SampleConfigBody}}
196+
{{- $.CustomTemplate $.IamPolicy.SampleConfigBody false }}
197+
{{- end }}
168198
role = "{{if $.IamPolicy.AdminIamRole}}{{$.IamPolicy.AdminIamRole }}{{else}}{{$.IamPolicy.AllowedIamRole}}{{end}}"
169199
member = "user:[email protected]"
170200
}
@@ -177,7 +207,13 @@ resource "{{ $.IamTerraformName }}_member" "member" {
177207
{{- if eq $.MinVersionObj.Name "beta" }}
178208
provider = google-beta
179209
{{- end }}
210+
{{- if $.IamPolicy.ExampleConfigBody}}
180211
{{- $.CustomTemplate $.IamPolicy.ExampleConfigBody false }}
212+
{{- end }}
213+
214+
{{- if $.IamPolicy.SampleConfigBody}}
215+
{{- $.CustomTemplate $.IamPolicy.SampleConfigBody false }}
216+
{{- end }}
181217
role = "{{if $.IamPolicy.AdminIamRole}}{{$.IamPolicy.AdminIamRole}}{{else}}{{$.IamPolicy.AllowedIamRole}}{{end}}"
182218
member = "user:[email protected]"
183219

0 commit comments

Comments
 (0)