Skip to content

Commit 23ef828

Browse files
kklimonda-clkklimonda
authored andcommitted
feat(codegen): Add support for terraform lists/queries
1 parent 406495c commit 23ef828

31 files changed

Lines changed: 597 additions & 50 deletions

pkg/generate/generator.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,6 @@ func (c *Creator) createFullFilePath(templateName string) string {
224224
}
225225

226226
// listOfTemplates returns a list of templates defined in TemplatesDir.
227-
// Excludes templates in the "partials" subdirectory as those are meant to be
228-
// called from within other templates, not processed independently.
229227
func (c *Creator) listOfTemplates() ([]string, error) {
230228
var files []string
231229
err := filepath.WalkDir(c.TemplatesDir, func(path string, entry os.DirEntry, err error) error {

pkg/properties/normalized.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ type TerraformProviderConfig struct {
6565
Action bool `json:"action" yaml:"action"`
6666
CustomValidation bool `json:"custom_validation" yaml:"custom_validation"`
6767
SkipResource bool `json:"skip_resource" yaml:"skip_resource"`
68+
SkipListResource *bool `json:"skip_list_resource" yaml:"skip_list_resource"`
6869
SkipDatasource bool `json:"skip_datasource" yaml:"skip_datasource"`
6970
SkipDatasourceListing bool `json:"skip_datasource_listing" yaml:"skip_datasource_listing"`
7071
ResourceType TerraformResourceType `json:"resource_type" yaml:"resource_type"`
@@ -702,6 +703,7 @@ func schemaToSpec(object object.Object) (*Normalization, error) {
702703
Action: object.TerraformConfig.Action,
703704
CustomValidation: object.TerraformConfig.CustomValidation,
704705
SkipResource: object.TerraformConfig.SkipResource,
706+
SkipListResource: object.TerraformConfig.SkipListResource,
705707
SkipDatasource: object.TerraformConfig.SkipDatasource,
706708
SkipDatasourceListing: object.TerraformConfig.SkipdatasourceListing,
707709
ResourceType: TerraformResourceType(object.TerraformConfig.ResourceType),

pkg/properties/provider_file.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ func (o TerraformNameProvider) IdentityModelStructName() string {
6868
return fmt.Sprintf("%sIdentityModel", o.ResourceStructName)
6969
}
7070

71+
func (o TerraformNameProvider) ListResourceStructName() string {
72+
return fmt.Sprintf("%sListResource", o.StructName)
73+
}
74+
7175
type TerraformSpecFlags uint
7276

7377
const (
@@ -91,6 +95,7 @@ type TerraformProviderFile struct {
9195
DataSources []string
9296
Resources []string
9397
EphemeralResources []string
98+
ListResources []string
9499
Actions []string
95100
SpecMetadata map[string]TerraformProviderSpecMetadata
96101
Code *strings.Builder

pkg/properties/resourcetype.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ type SchemaType string
1616
const (
1717
SchemaResource SchemaType = "resource"
1818
SchemaEphemeralResource SchemaType = "ephemeral-resource"
19+
SchemaListResource SchemaType = "list-resource"
1920
SchemaAction SchemaType = "action"
2021
SchemaDataSource SchemaType = "datasource"
2122
SchemaCommon SchemaType = "common"
2223
SchemaProvider SchemaType = "provider"
24+
SchemaCustom SchemaType = "custom"
2325
)

pkg/schema/object/object.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ type TerraformConfig struct {
4343
SkipResource bool `yaml:"skip_resource"`
4444
SkipDatasource bool `yaml:"skip_datasource"`
4545
SkipdatasourceListing bool `yaml:"skip_datasource_listing"`
46+
SkipListResource *bool `yaml:"skip_list_resource"`
4647
ResourceType TerraformResourceType `yaml:"resource_type"`
4748
XmlNode *string `yaml:"xml_node"`
4849
CustomFunctions map[string]bool `yaml:"custom_functions"`

pkg/translate/terraform_provider/conversion.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func renderSpecsForParams(names *NameProvider, schemaTyp properties.SchemaType,
8484
structPrefix = names.DataSourceStructName
8585
case properties.SchemaResource, properties.SchemaEphemeralResource:
8686
structPrefix = names.ResourceStructName
87-
case properties.SchemaCommon, properties.SchemaProvider, properties.SchemaAction:
87+
case properties.SchemaListResource, properties.SchemaCommon, properties.SchemaProvider, properties.SchemaAction, properties.SchemaCustom:
8888
panic(fmt.Sprintf("invalid schema type: %s", schemaTyp))
8989
}
9090

pkg/translate/terraform_provider/crud_operations.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func ResourceCreateFunction(resourceTyp properties.ResourceType, names *NameProv
3535
return RendeCreateUpdateMovementRequired(state, entries)
3636
},
3737
"RenderLocationsStateToPango": func(source string, dest string) (string, error) {
38-
return RenderLocationsStateToPango(names, paramSpec, source, dest)
38+
return RenderLocationsStateToPango(names, paramSpec, source, dest, "resp.Diagnostics")
3939
},
4040
}
4141

@@ -151,7 +151,7 @@ func DataSourceReadFunction(resourceTyp properties.ResourceType, names *NameProv
151151
return RenderLocationsPangoToState(names, paramSpec, source, dest)
152152
},
153153
"RenderLocationsStateToPango": func(source string, dest string) (string, error) {
154-
return RenderLocationsStateToPango(names, paramSpec, source, dest)
154+
return RenderLocationsStateToPango(names, paramSpec, source, dest, "resp.Diagnostics")
155155
},
156156
}
157157

@@ -219,7 +219,7 @@ func ResourceReadFunction(resourceTyp properties.ResourceType, names *NameProvid
219219
return RenderLocationsPangoToState(names, paramSpec, source, dest)
220220
},
221221
"RenderLocationsStateToPango": func(source string, dest string) (string, error) {
222-
return RenderLocationsStateToPango(names, paramSpec, source, dest)
222+
return RenderLocationsStateToPango(names, paramSpec, source, dest, "resp.Diagnostics")
223223
},
224224
}
225225

@@ -281,7 +281,7 @@ func ResourceUpdateFunction(resourceTyp properties.ResourceType, names *NameProv
281281
return RendeCreateUpdateMovementRequired(state, entries)
282282
},
283283
"RenderLocationsStateToPango": func(source string, dest string) (string, error) {
284-
return RenderLocationsStateToPango(names, paramSpec, source, dest)
284+
return RenderLocationsStateToPango(names, paramSpec, source, dest, "resp.Diagnostics")
285285
},
286286
"RenderLocationsPangoToState": func(source string, dest string) (string, error) {
287287
return RenderLocationsPangoToState(names, paramSpec, source, dest)
@@ -345,7 +345,7 @@ func ResourceDeleteFunction(resourceTyp properties.ResourceType, names *NameProv
345345
return RenderImportLocationAssignment(names, paramSpec, source, dest)
346346
},
347347
"RenderLocationsStateToPango": func(source string, dest string) (string, error) {
348-
return RenderLocationsStateToPango(names, paramSpec, source, dest)
348+
return RenderLocationsStateToPango(names, paramSpec, source, dest, "resp.Diagnostics")
349349
},
350350
}
351351

pkg/translate/terraform_provider/entity_generators.go

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@ func (g *GenerateTerraformProvider) GenerateTerraformResource(resourceTyp proper
9191
"RenderXpathComponentsGetter": func() (string, error) {
9292
return RenderXpathComponentsGetter(names.ResourceStructName, spec)
9393
},
94+
"RenderMainStruct": func() (string, error) {
95+
return RenderMainStruct(resourceTyp, schemaTyp, names, spec)
96+
},
97+
"RenderConfigureFunc": func() (string, error) {
98+
return RenderConfigureFunc(resourceTyp, schemaTyp, names, spec)
99+
},
100+
"RenderModelStructs": func() (string, error) {
101+
return RenderModelStructs(resourceTyp, schemaTyp, names, spec)
102+
},
94103
"ResourceCreateFunction": func(structName string, serviceName string) (string, error) {
95104
return ResourceCreateFunction(resourceTyp, names, serviceName, spec, terraformProvider, names.PackageName)
96105
},
@@ -265,6 +274,37 @@ func (g *GenerateTerraformProvider) GenerateTerraformResource(resourceTyp proper
265274
return nil
266275
}
267276

277+
// GenerateTerraformListResource generates a Terraform list resource template.
278+
func (o *GenerateTerraformProvider) GenerateTerraformListResource(resourceTyp properties.ResourceType, spec *properties.Normalization, provider *properties.TerraformProviderFile) error {
279+
provider.ImportManager.AddHashicorpImport("github.com/hashicorp/terraform-plugin-framework/list", "")
280+
provider.ImportManager.AddHashicorpImport("github.com/hashicorp/terraform-plugin-framework/list/schema", "listschema")
281+
282+
names := NewNameProvider(spec, resourceTyp)
283+
284+
funcMap := template.FuncMap{
285+
"structName": func() string { return names.StructName },
286+
"metaName": func() string { return names.MetaName },
287+
288+
"RenderModelStructs": func() (string, error) {
289+
return RenderModelStructs(resourceTyp, properties.SchemaListResource, names, spec)
290+
},
291+
"RenderMainStruct": func() (string, error) {
292+
return RenderMainStruct(resourceTyp, properties.SchemaListResource, names, spec)
293+
},
294+
"RenderConfigureFunc": func() (string, error) {
295+
return RenderConfigureFunc(resourceTyp, properties.SchemaListResource, names, spec)
296+
},
297+
"RenderSchema": func() (string, error) {
298+
return RenderSchema(resourceTyp, properties.SchemaListResource, names, spec, provider.ImportManager)
299+
},
300+
"RenderListFunc": func() (string, error) {
301+
return RenderListFunc(resourceTyp, properties.SchemaListResource, names, spec, provider.ImportManager)
302+
},
303+
}
304+
305+
return o.generateTerraformEntityTemplate(resourceTyp, properties.SchemaListResource, names, spec, provider, "resource/list_resource.tmpl", funcMap)
306+
}
307+
268308
// GenerateTerraformAction generates a Terraform action template.
269309
func (o *GenerateTerraformProvider) GenerateTerraformAction(spec *properties.Normalization, provider *properties.TerraformProviderFile) error {
270310
provider.ImportManager.AddStandardImport("context", "")
@@ -288,7 +328,7 @@ func (o *GenerateTerraformProvider) GenerateTerraformAction(spec *properties.Nor
288328
"metaName": func() string { return names.MetaName },
289329
"HasCustomValidation": func() bool { return spec.TerraformProviderConfig.CustomValidation },
290330

291-
"RenderStructs": func() (string, error) { return RenderStructs(resourceTyp, properties.SchemaAction, names, spec) },
331+
"RenderModelStructs": func() (string, error) { return RenderModelStructs(resourceTyp, properties.SchemaAction, names, spec) },
292332
"RenderSchema": func() (string, error) {
293333
return RenderSchema(resourceTyp, properties.SchemaAction, names, spec, provider.ImportManager)
294334
},
@@ -387,6 +427,15 @@ func (g *GenerateTerraformProvider) GenerateTerraformDataSource(resourceTyp prop
387427
"RenderDataSourceSchema": func() (string, error) {
388428
return RenderDataSourceSchema(resourceTyp, names, spec, terraformProvider.ImportManager)
389429
},
430+
"RenderMainStruct": func() (string, error) {
431+
return RenderMainStruct(resourceTyp, properties.SchemaDataSource, names, spec)
432+
},
433+
"RenderConfigureFunc": func() (string, error) {
434+
return RenderConfigureFunc(resourceTyp, properties.SchemaDataSource, names, spec)
435+
},
436+
"RenderModelStructs": func() (string, error) {
437+
return RenderModelStructs(resourceTyp, properties.SchemaDataSource, names, spec)
438+
},
390439
}
391440
err := g.generateTerraformEntityTemplate(resourceTyp, properties.SchemaDataSource, names, spec, terraformProvider, "datasource/datasource.tmpl", funcMap)
392441
if err != nil {

pkg/translate/terraform_provider/generator.go

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"strings"
99
"text/template"
1010

11+
"github.com/paloaltonetworks/pan-os-codegen/pkg/imports"
1112
"github.com/paloaltonetworks/pan-os-codegen/pkg/properties"
1213
)
1314

@@ -80,9 +81,11 @@ func (g *GenerateTerraformProvider) appendResourceType(spec *properties.Normaliz
8081
case properties.SchemaEphemeralResource:
8182
flags |= properties.TerraformSpecEphemeralResource
8283
terraformProvider.EphemeralResources = append(terraformProvider.EphemeralResources, names.ResourceStructName)
84+
case properties.SchemaListResource:
85+
terraformProvider.ListResources = append(terraformProvider.ListResources, names.ListResourceStructName())
8386
case properties.SchemaAction:
8487
terraformProvider.Actions = append(terraformProvider.Actions, names.ActionStructName())
85-
case properties.SchemaProvider, properties.SchemaCommon:
88+
case properties.SchemaProvider, properties.SchemaCommon, properties.SchemaCustom:
8689
default:
8790
panic(fmt.Sprintf("unsupported schemaTyp: '%s'", schemaTyp))
8891
}
@@ -117,13 +120,15 @@ func (g *GenerateTerraformProvider) generateTerraformEntityTemplate(resourceTyp
117120
resourceType = "Resource"
118121
case properties.SchemaEphemeralResource:
119122
resourceType = "EphemeralResource"
123+
case properties.SchemaListResource:
124+
resourceType = "ListResource"
120125
case properties.SchemaCommon:
121126
resourceType = "Common"
122127
case properties.SchemaProvider:
123128
resourceType = "ProviderFile"
124129
case properties.SchemaAction:
125130
resourceType = "Action"
126-
default:
131+
case properties.SchemaCustom:
127132
panic(fmt.Sprintf("unsupported schemaTyp: '%+v'", schemaTyp))
128133
}
129134

@@ -134,3 +139,87 @@ func (g *GenerateTerraformProvider) generateTerraformEntityTemplate(resourceTyp
134139
}
135140
return g.executeTemplate(template, spec, terraformProvider, resourceTyp, schemaTyp, names)
136141
}
142+
143+
func renderMainAndConfigureTmpls(tmpl string, resourceTyp properties.ResourceType, schemaTyp properties.SchemaType, names *NameProvider, spec *properties.Normalization) (string, error) {
144+
type context struct {
145+
BareStructName string
146+
StructName string
147+
PackageName string
148+
SDKName string
149+
IsCustom bool
150+
IsImportableEntry bool
151+
IsEntry bool
152+
IsUuid bool
153+
IsConfig bool
154+
}
155+
156+
data := context{}
157+
158+
switch resourceTyp {
159+
case properties.ResourceConfig:
160+
data.IsConfig = true
161+
case properties.ResourceCustom:
162+
data.IsCustom = true
163+
case properties.ResourceEntry, properties.ResourceEntryPlural:
164+
if len(spec.Imports.Variants) > 0 {
165+
data.IsImportableEntry = true
166+
} else {
167+
data.IsEntry = true
168+
}
169+
case properties.ResourceUuid, properties.ResourceUuidPlural:
170+
data.IsUuid = true
171+
}
172+
173+
data.BareStructName = names.StructName
174+
data.SDKName = names.PackageName
175+
176+
switch schemaTyp {
177+
case properties.SchemaListResource:
178+
data.StructName = names.ListResourceStructName()
179+
case properties.SchemaDataSource:
180+
data.StructName = names.DataSourceStructName
181+
case properties.SchemaResource, properties.SchemaEphemeralResource:
182+
data.StructName = names.ResourceStructName
183+
case properties.SchemaAction, properties.SchemaCommon, properties.SchemaProvider, properties.SchemaCustom:
184+
}
185+
186+
if spec.TerraformProviderConfig.Ephemeral {
187+
data.PackageName = "ephemeral"
188+
} else {
189+
data.PackageName = "resource"
190+
}
191+
192+
return processTemplate(tmpl, "render-main-and-configure-tmpls", data, commonFuncMap)
193+
}
194+
195+
func RenderMainStruct(resourceTyp properties.ResourceType, schemaTyp properties.SchemaType, names *NameProvider, spec *properties.Normalization) (string, error) {
196+
return renderMainAndConfigureTmpls("common/structure.tmpl", resourceTyp, schemaTyp, names, spec)
197+
}
198+
199+
func RenderConfigureFunc(resourceTyp properties.ResourceType, schemaTyp properties.SchemaType, names *NameProvider, spec *properties.Normalization) (string, error) {
200+
return renderMainAndConfigureTmpls("common/configure_func.tmpl", resourceTyp, schemaTyp, names, spec)
201+
}
202+
203+
func RenderListFunc(resourceTyp properties.ResourceType, schemaTyp properties.SchemaType, names *NameProvider, spec *properties.Normalization, manager *imports.Manager) (string, error) {
204+
type context struct {
205+
StructName string
206+
IdentityModel string
207+
ResourceStructName string
208+
SDKName string
209+
}
210+
211+
data := context{
212+
StructName: names.ListResourceStructName(),
213+
IdentityModel: fmt.Sprintf("%sIdentityModel", names.ResourceStructName),
214+
ResourceStructName: names.ResourceStructName,
215+
SDKName: names.PackageName,
216+
}
217+
218+
funcMap := template.FuncMap{
219+
"RenderLocationsStateToPango": func(source string, dest string) (string, error) {
220+
return RenderLocationsStateToPango(names, spec, source, dest, "diags")
221+
},
222+
}
223+
224+
return processTemplate("resource/list_func.tmpl", "render-list-func", data, funcMap)
225+
}

pkg/translate/terraform_provider/location.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,18 +358,20 @@ func RenderLocationsPangoToState(names *NameProvider, spec *properties.Normaliza
358358
}
359359

360360
// RenderLocationsStateToPango generates code to convert Terraform state to Pango locations.
361-
func RenderLocationsStateToPango(names *NameProvider, spec *properties.Normalization, source string, dest string) (string, error) {
361+
func RenderLocationsStateToPango(names *NameProvider, spec *properties.Normalization, source string, dest string, diags string) (string, error) {
362362
type context struct {
363363
TerraformStructName string
364364
Source string
365365
Dest string
366+
Diags string
366367
Locations []locationCtx
367368
}
368369
data := context{
369370
TerraformStructName: fmt.Sprintf("%sLocation", names.StructName),
370371
Locations: renderLocationsGetContext(names, spec),
371372
Source: source,
372373
Dest: dest,
374+
Diags: diags,
373375
}
374376
return processTemplate("location/state_to_pango.tmpl", "render-locations-state-to-pango", data, commonFuncMap)
375377
}

0 commit comments

Comments
 (0)