Skip to content

Commit

Permalink
Add initial position attribute support
Browse files Browse the repository at this point in the history
  • Loading branch information
kklimonda-cl committed Aug 9, 2024
1 parent ba836d2 commit c086fdb
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 2 deletions.
96 changes: 96 additions & 0 deletions assets/terraform/internal/provider/position.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package provider

import (
"slices"

"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
rsschema "github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"

"github.com/PaloAltoNetworks/pango/rule"
)

type TerraformPositionObject struct {
Where types.String `tfsdk:"where"`
Pivot types.String `tfsdk:"pivot"`
Directly types.Bool `tfsdk:"directly"`
}

func TerraformPositionObjectSchema() rsschema.SingleNestedAttribute {
return rsschema.SingleNestedAttribute{
Required: true,
Attributes: map[string]rsschema.Attribute{
"where": rsschema.StringAttribute{
Required: true,
},
"pivot": rsschema.StringAttribute{
Optional: true,
},
"directly": rsschema.BoolAttribute{
Optional: true,
},
},
}
}

func (o *TerraformPositionObject) CopyToPango() rule.Position {
trueVal := true
switch o.Where.ValueString() {
case "first":
return rule.Position{
First: &trueVal,
}
case "last":
return rule.Position{
Last: &trueVal,
}
case "before":
if o.Directly.ValueBool() == true {
return rule.Position{
DirectlyBefore: o.Pivot.ValueStringPointer(),
}
} else {
return rule.Position{
SomewhereBefore: o.Pivot.ValueStringPointer(),
}
}
case "after":
if o.Directly.ValueBool() == true {
return rule.Position{
DirectlyAfter: o.Pivot.ValueStringPointer(),
}
} else {
return rule.Position{
SomewhereAfter: o.Pivot.ValueStringPointer(),
}
}
default:
panic("unreachable")
}
}

func (o *TerraformPositionObject) ValidateConfig(resp *resource.ValidateConfigResponse) {
allowedPositions := []string{"first", "last", "before", "after"}

if !slices.Contains(allowedPositions, o.Where.ValueString()) {
resp.Diagnostics.AddAttributeError(
path.Root("position").AtName("directly"),
"Missing attribute configuration",
"where attribute must be one of the valid values: first, last, before, after")
}

if !o.Pivot.IsNull() && o.Directly.IsNull() {
resp.Diagnostics.AddAttributeError(
path.Root("position").AtName("directly"),
"Missing attribute configuration",
"Expected directly to be configured with pivot")
}

if o.Pivot.IsNull() && !o.Directly.IsNull() {
resp.Diagnostics.AddAttributeError(
path.Root("position").AtName("pivot"),
"Missing attribute configuration",
"Expected pivot to be configured with directly")
}
}
35 changes: 35 additions & 0 deletions pkg/translate/terraform_provider/funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,7 @@ type attributeCtx struct {
Package string
Name *properties.NameVariant
SchemaType string
ExternalType string
ElementType string
Description string
Required bool
Expand Down Expand Up @@ -928,6 +929,20 @@ func createSchemaSpecForUuidModel(resourceTyp properties.ResourceType, schemaTyp
SchemaType: "SingleNestedAttribute",
})

position := &properties.NameVariant{
Underscore: naming.Underscore("", "position", ""),
CamelCase: naming.CamelCase("", "position", "", true),
LowerCamelCase: naming.CamelCase("", "position", "", false),
}

attributes = append(attributes, attributeCtx{
Package: packageName,
Name: position,
Required: true,
SchemaType: "ExternalAttribute",
ExternalType: "TerraformPositionObject",
})

listNameStr := spec.TerraformProviderConfig.PluralName
listName := &properties.NameVariant{
Underscore: naming.Underscore("", listNameStr, ""),
Expand Down Expand Up @@ -1226,6 +1241,12 @@ const renderSchemaTemplate = `
{{- end }}
{{- end }}
{{- define "renderSchemaExternalAttribute" }}
{{- with .Attribute }}
"{{ .Name.Underscore }}": {{ .ExternalType }}Schema(),
{{- end }}
{{- end }}
{{- define "renderSchemaSimpleAttribute" }}
"{{ .Name.Underscore }}": {{ .Package }}.{{ .SchemaType }} {
Description: "{{ .Description }}",
Expand All @@ -1251,6 +1272,8 @@ const renderSchemaTemplate = `
{{- template "renderSchemaMapNestedAttribute" Map "StructName" $.StructName "Attribute" . }}
{{- else if eq .SchemaType "SingleNestedAttribute" }}
{{- template "renderSchemaSingleNestedAttribute" Map "StructName" $.StructName "Attribute" . }}
{{- else if eq .SchemaType "ExternalAttribute" }}
{{- template "renderSchemaExternalAttribute" Map "Attribute" . }}
{{- else }}
{{- template "renderSchemaSimpleAttribute" . }}
{{- end }}
Expand Down Expand Up @@ -1522,6 +1545,18 @@ func createStructSpecForUuidModel(resourceTyp properties.ResourceType, schemaTyp
Tags: []string{"`tfsdk:\"location\"`"},
})

position := &properties.NameVariant{
Underscore: naming.Underscore("", "position", ""),
CamelCase: naming.CamelCase("", "position", "", true),
LowerCamelCase: naming.CamelCase("", "position", "", false),
}

fields = append(fields, datasourceStructFieldSpec{
Name: position.CamelCase,
Type: "TerraformPositionObject",
Tags: []string{"`tfsd:\"position\"`"},
})

var structName string
switch schemaTyp {
case schemaResource:
Expand Down
10 changes: 8 additions & 2 deletions pkg/translate/terraform_provider/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -1451,12 +1451,19 @@ if err != nil && err.Error() != "Object not found" {
}
var movementRequired bool
{{- if .Exhaustive }}
trueValue := true
position := rule.Position{First: &trueValue}
for idx, elt := range existing {
if processedStateEntries[elt.Name].StateIdx != idx {
movementRequired = true
}
processedStateEntries[elt.Name].Entry.Uuid = elt.Uuid
}
{{- else }}
position := state.Position.CopyToPango()
movementRequired = true
{{- end }}
if movementRequired {
entries := make([]{{ $resourceSDKStructName }}, len(processedStateEntries))
Expand All @@ -1469,8 +1476,7 @@ if movementRequired {
finalOrder = append(finalOrder, elt.Name)
}
trueValue := true
err = svc.MoveGroup(ctx, location, rule.Position{First: &trueValue}, entries)
err = svc.MoveGroup(ctx, location, position, entries)
if err != nil {
resp.Diagnostics.AddError("Failed to reorder entries", err.Error())
return
Expand Down

0 comments on commit c086fdb

Please sign in to comment.