Skip to content

Commit

Permalink
Add codegen support for rendering single-elements list as strings (#200)
Browse files Browse the repository at this point in the history
  • Loading branch information
kklimonda-cl authored Dec 13, 2024
1 parent 7313292 commit a6e7dad
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 29 deletions.
10 changes: 4 additions & 6 deletions assets/terraform/test/resource_security_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ resource "panos_security_policy" "policy" {
# source_hips = ["hip-profile"]
negate_source = false
destination_zones = ["any"]
destination_zone = "any"
destination_addresses = ["any"]
# destination_hips = ["hip-device"]
Expand Down Expand Up @@ -262,10 +262,8 @@ func TestAccSecurityPolicyExtended(t *testing.T) {
"panos_security_policy.policy",
tfjsonpath.New("rules").
AtSliceIndex(0).
AtMapKey("destination_zones"),
knownvalue.ListExact([]knownvalue.Check{
knownvalue.StringExact("any"),
}),
AtMapKey("destination_zone"),
knownvalue.StringExact("any"),
),
statecheck.ExpectKnownValue(
"panos_security_policy.policy",
Expand Down Expand Up @@ -412,7 +410,7 @@ resource "panos_security_policy" "policy" {
source_zones = ["any"]
source_addresses = ["any"]
destination_zones = ["any"]
destination_zone = "any"
destination_addresses = ["any"]
services = ["any"]
Expand Down
21 changes: 21 additions & 0 deletions pkg/properties/normalized.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,27 @@ func (o *SpecParam) NameVariant() *NameVariant {
return o.Name
}

func (o *SpecParam) ComplexType() string {
var terraformType *string
if o.TerraformProviderConfig != nil {
terraformType = o.TerraformProviderConfig.Type
}

if terraformType != nil && o.Type == "list" && o.Items.Type == "string" {
return "string-as-member"
}

return ""
}

func (o *SpecParam) FinalType() string {
if o.TerraformProviderConfig != nil && o.TerraformProviderConfig.Type != nil {
return *o.TerraformProviderConfig.Type
}

return o.Type
}

func (o *SpecParam) FinalSensitive() bool {
if o.TerraformProviderConfig != nil && o.TerraformProviderConfig.Sensitive != nil {
return *o.TerraformProviderConfig.Sensitive
Expand Down
92 changes: 70 additions & 22 deletions pkg/translate/terraform_provider/funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type parameterEncryptionSpec struct {
type parameterSpec struct {
PangoName *properties.NameVariant
TerraformName *properties.NameVariant
ComplexType string
Type string
Required bool
ItemsType string
Expand Down Expand Up @@ -73,7 +74,8 @@ func renderSpecsForParams(params map[string]*properties.SpecParam, parentNames [
specs = append(specs, parameterSpec{
PangoName: elt.Name,
TerraformName: elt.NameVariant(),
Type: elt.Type,
ComplexType: elt.ComplexType(),
Type: elt.FinalType(),
ItemsType: itemsType,
Encryption: encryptionSpec,
})
Expand Down Expand Up @@ -253,6 +255,14 @@ const copyToPangoTmpl = `
{{- end }}
{{- end }}
{{- define "renderStringAsMemberAssignment" }}
{{- with .Parameter }}
{{- $pangoType := printf "%s%s" $.Spec.PangoType .PangoName.CamelCase }}
{{- $pangoEntries := printf "%s_pango_entries" .TerraformName.LowerCamelCase }}
{{ $pangoEntries }} := []string{o.{{ .TerraformName.CamelCase }}.ValueString()}
{{- end }}
{{- end }}
{{- define "renderSimpleAssignment" }}
{{- if .Encryption }}
(*encrypted)["{{ .Encryption.PlaintextPath }}"] = o.{{ .TerraformName.CamelCase }}
Expand All @@ -266,7 +276,9 @@ func (o *{{ .TerraformType }}{{ .ModelOrObject }}) CopyToPango(ctx context.Conte
var diags diag.Diagnostics
{{- range .Params }}
{{- $terraformType := printf "%s%s" $spec.TerraformType .TerraformName.CamelCase }}
{{- if eq .Type "" }}
{{- if eq .ComplexType "string-as-member" }}
{{- template "renderStringAsMemberAssignment" Map "Parameter" . "Spec" $spec }}
{{- else if eq .Type "" }}
{{- $pangoType := printf "%sObject" $spec.PangoType }}
{{- template "terraformNestedElementsAssign" Map "Parameter" . "Spec" $spec }}
{{- else if eq .Type "list" }}
Expand All @@ -278,7 +290,9 @@ func (o *{{ .TerraformType }}{{ .ModelOrObject }}) CopyToPango(ctx context.Conte
{{- end }}
{{- range .OneOf }}
{{- if eq .Type "" }}
{{- if eq .ComplexType "string-as-member" }}
{{- template "renderStringAsMemberAssignment" Map "Parameter" . "Spec" $spec }}
{{- else if eq .Type "" }}
{{- $pangoType := printf "%sObject" $spec.PangoType }}
{{- template "terraformNestedElementsAssign" Map "Parameter" . "Spec" $spec }}
{{- else if eq .Type "list" }}
Expand All @@ -295,7 +309,9 @@ func (o *{{ .TerraformType }}{{ .ModelOrObject }}) CopyToPango(ctx context.Conte
(*obj).Name = o.Name.ValueString()
{{- end }}
{{- range .Params }}
{{- if eq .Type "" }}
{{- if eq .ComplexType "string-as-member" }}
(*obj).{{ .PangoName.CamelCase }} = {{ .TerraformName.LowerCamelCase }}_pango_entries
{{- else if eq .Type "" }}
(*obj).{{ .PangoName.CamelCase }} = {{ .TerraformName.LowerCamelCase }}_entry
{{- else if eq .Type "list" }}
(*obj).{{ .PangoName.CamelCase }} = {{ .TerraformName.LowerCamelCase }}_pango_entries
Expand All @@ -305,7 +321,9 @@ func (o *{{ .TerraformType }}{{ .ModelOrObject }}) CopyToPango(ctx context.Conte
{{- end }}
{{- range .OneOf }}
{{- if eq .Type "" }}
{{- if eq .ComplexType "string-as-member" }}
(*obj).{{ .PangoName.CamelCase }} = {{ .TerraformName.LowerCamelCase }}_pango_entries
{{- else if eq .Type "" }}
(*obj).{{ .PangoName.CamelCase }} = {{ .TerraformName.LowerCamelCase }}_entry
{{- else if eq .Type "list" }}
(*obj).{{ .PangoName.CamelCase }} = {{ .TerraformName.LowerCamelCase }}_pango_entries
Expand Down Expand Up @@ -447,10 +465,26 @@ var {{ .TerraformName.LowerCamelCase }}_list types.List
{{- end }}
{{- end }}
{{- define "terraformCreateStringAsMemberValues" }}
{{- range .Params }}
{{ if not (eq .ComplexType "string-as-member") }}
{{- continue }}
{{- end }}
{{ .TerraformName.LowerCamelCase }}_value := types.StringValue(obj.{{ .PangoName.CamelCase }}[0])
{{- end }}
{{- range .OneOf }}
{{ if not (eq .ComplexType "string-as-member") }}
{{- continue }}
{{- end }}
{{ .TerraformName.LowerCamelCase }}_value := types.StringValue(*obj.{{ .PangoName.CamelCase }}[0])
{{- end }}
{{- end }}
{{- define "terraformCreateSimpleValues" }}
{{- range .Params }}
{{- $terraformType := printf "types.%s" (.Type | PascalCase) }}
{{- if (not (or (eq .Type "") (eq .Type "list"))) }}
{{- if (not (or (eq .Type "") (eq .Type "list") (eq .ComplexType "string-as-member"))) }}
var {{ .TerraformName.LowerCamelCase }}_value {{ $terraformType }}
if obj.{{ .PangoName.CamelCase }} != nil {
{{- if .Encryption }}
Expand All @@ -467,7 +501,7 @@ var {{ .TerraformName.LowerCamelCase }}_list types.List
{{- range .OneOf }}
{{- $terraformType := printf "types.%s" (.Type | PascalCase) }}
{{- if (not (or (eq .Type "") (eq .Type "list"))) }}
{{- if (not (or (eq .Type "") (eq .Type "list") (eq .ComplexType "string-as-member"))) }}
var {{ .TerraformName.LowerCamelCase }}_value {{ $terraformType }}
if obj.{{ .PangoName.CamelCase }} != nil {
{{ .TerraformName.LowerCamelCase }}_value = types.{{ .Type | PascalCase }}Value(*obj.{{ .PangoName.CamelCase }})
Expand All @@ -478,7 +512,9 @@ var {{ .TerraformName.LowerCamelCase }}_list types.List
{{- define "assignFromPangoToTerraform" }}
{{- with .Parameter }}
{{- if eq .Type "" }}
{{- if eq .ComplexType "string-as-member" }}
o.{{ .TerraformName.CamelCase }} = {{ .TerraformName.LowerCamelCase }}_value
{{- else if eq .Type "" }}
o.{{ .TerraformName.CamelCase }} = {{ .TerraformName.LowerCamelCase }}_object
{{- else if eq .Type "list" }}
o.{{ .TerraformName.CamelCase }} = {{ .TerraformName.LowerCamelCase }}_list
Expand All @@ -496,6 +532,7 @@ func (o *{{ $terraformType }}) CopyFromPango(ctx context.Context, obj *{{ .Pango
{{- template "terraformListElementsAs" $spec }}
{{- template "terraformCreateEntryAssignment" $spec }}
{{- template "terraformCreateStringAsMemberValues" $spec }}
{{- template "terraformCreateSimpleValues" $spec }}
{{- if .HasEntryName }}
Expand Down Expand Up @@ -1217,22 +1254,28 @@ func createSchemaSpecForParameter(schemaTyp properties.SchemaType, manager *impo

func createSchemaAttributeForParameter(schemaTyp properties.SchemaType, manager *imports.Manager, packageName string, param *properties.SpecParam, validators *validatorCtx) attributeCtx {
var schemaType, elementType string
switch param.Type {
case "":
schemaType = "SingleNestedAttribute"
case "list":
switch param.Items.Type {
case "entry":
schemaType = "ListNestedAttribute"
case "member":
schemaType = "ListAttribute"
elementType = "types.StringType"

switch param.ComplexType() {
case "string-as-member":
schemaType = "StringAttribute"
default:
switch param.Type {
case "":
schemaType = "SingleNestedAttribute"
case "list":
switch param.Items.Type {
case "entry":
schemaType = "ListNestedAttribute"
case "member":
schemaType = "ListAttribute"
elementType = "types.StringType"
default:
schemaType = "ListAttribute"
elementType = fmt.Sprintf("types.%sType", pascalCase(param.Items.Type))
}
default:
schemaType = "ListAttribute"
elementType = fmt.Sprintf("types.%sType", pascalCase(param.Items.Type))
schemaType = fmt.Sprintf("%sAttribute", pascalCase(param.Type))
}
default:
schemaType = fmt.Sprintf("%sAttribute", pascalCase(param.Type))
}

var defaultValue *defaultCtx
Expand Down Expand Up @@ -2101,6 +2144,11 @@ func terraformTypeForProperty(structPrefix string, prop *properties.SpecParam) s
return fmt.Sprintf("*%s%sObject", structPrefix, prop.NameVariant().CamelCase)
}

switch prop.ComplexType() {
case "string-as-member":
return "types.String"
}

if prop.Type == "list" && prop.Items.Type == "entry" {
return "types.List"
}
Expand Down
3 changes: 2 additions & 1 deletion specs/policies/security-policy-rule.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,8 @@ spec:
required: false
codegen_overrides:
terraform:
name: destination_zones
name: destination_zone
type: string
- name: uuid
type: string
profiles:
Expand Down

0 comments on commit a6e7dad

Please sign in to comment.