Skip to content

Commit c086fdb

Browse files
committed
Add initial position attribute support
1 parent ba836d2 commit c086fdb

File tree

3 files changed

+139
-2
lines changed

3 files changed

+139
-2
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package provider
2+
3+
import (
4+
"slices"
5+
6+
"github.com/hashicorp/terraform-plugin-framework/path"
7+
"github.com/hashicorp/terraform-plugin-framework/resource"
8+
rsschema "github.com/hashicorp/terraform-plugin-framework/resource/schema"
9+
"github.com/hashicorp/terraform-plugin-framework/types"
10+
11+
"github.com/PaloAltoNetworks/pango/rule"
12+
)
13+
14+
type TerraformPositionObject struct {
15+
Where types.String `tfsdk:"where"`
16+
Pivot types.String `tfsdk:"pivot"`
17+
Directly types.Bool `tfsdk:"directly"`
18+
}
19+
20+
func TerraformPositionObjectSchema() rsschema.SingleNestedAttribute {
21+
return rsschema.SingleNestedAttribute{
22+
Required: true,
23+
Attributes: map[string]rsschema.Attribute{
24+
"where": rsschema.StringAttribute{
25+
Required: true,
26+
},
27+
"pivot": rsschema.StringAttribute{
28+
Optional: true,
29+
},
30+
"directly": rsschema.BoolAttribute{
31+
Optional: true,
32+
},
33+
},
34+
}
35+
}
36+
37+
func (o *TerraformPositionObject) CopyToPango() rule.Position {
38+
trueVal := true
39+
switch o.Where.ValueString() {
40+
case "first":
41+
return rule.Position{
42+
First: &trueVal,
43+
}
44+
case "last":
45+
return rule.Position{
46+
Last: &trueVal,
47+
}
48+
case "before":
49+
if o.Directly.ValueBool() == true {
50+
return rule.Position{
51+
DirectlyBefore: o.Pivot.ValueStringPointer(),
52+
}
53+
} else {
54+
return rule.Position{
55+
SomewhereBefore: o.Pivot.ValueStringPointer(),
56+
}
57+
}
58+
case "after":
59+
if o.Directly.ValueBool() == true {
60+
return rule.Position{
61+
DirectlyAfter: o.Pivot.ValueStringPointer(),
62+
}
63+
} else {
64+
return rule.Position{
65+
SomewhereAfter: o.Pivot.ValueStringPointer(),
66+
}
67+
}
68+
default:
69+
panic("unreachable")
70+
}
71+
}
72+
73+
func (o *TerraformPositionObject) ValidateConfig(resp *resource.ValidateConfigResponse) {
74+
allowedPositions := []string{"first", "last", "before", "after"}
75+
76+
if !slices.Contains(allowedPositions, o.Where.ValueString()) {
77+
resp.Diagnostics.AddAttributeError(
78+
path.Root("position").AtName("directly"),
79+
"Missing attribute configuration",
80+
"where attribute must be one of the valid values: first, last, before, after")
81+
}
82+
83+
if !o.Pivot.IsNull() && o.Directly.IsNull() {
84+
resp.Diagnostics.AddAttributeError(
85+
path.Root("position").AtName("directly"),
86+
"Missing attribute configuration",
87+
"Expected directly to be configured with pivot")
88+
}
89+
90+
if o.Pivot.IsNull() && !o.Directly.IsNull() {
91+
resp.Diagnostics.AddAttributeError(
92+
path.Root("position").AtName("pivot"),
93+
"Missing attribute configuration",
94+
"Expected pivot to be configured with directly")
95+
}
96+
}

pkg/translate/terraform_provider/funcs.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ type attributeCtx struct {
666666
Package string
667667
Name *properties.NameVariant
668668
SchemaType string
669+
ExternalType string
669670
ElementType string
670671
Description string
671672
Required bool
@@ -928,6 +929,20 @@ func createSchemaSpecForUuidModel(resourceTyp properties.ResourceType, schemaTyp
928929
SchemaType: "SingleNestedAttribute",
929930
})
930931

932+
position := &properties.NameVariant{
933+
Underscore: naming.Underscore("", "position", ""),
934+
CamelCase: naming.CamelCase("", "position", "", true),
935+
LowerCamelCase: naming.CamelCase("", "position", "", false),
936+
}
937+
938+
attributes = append(attributes, attributeCtx{
939+
Package: packageName,
940+
Name: position,
941+
Required: true,
942+
SchemaType: "ExternalAttribute",
943+
ExternalType: "TerraformPositionObject",
944+
})
945+
931946
listNameStr := spec.TerraformProviderConfig.PluralName
932947
listName := &properties.NameVariant{
933948
Underscore: naming.Underscore("", listNameStr, ""),
@@ -1226,6 +1241,12 @@ const renderSchemaTemplate = `
12261241
{{- end }}
12271242
{{- end }}
12281243
1244+
{{- define "renderSchemaExternalAttribute" }}
1245+
{{- with .Attribute }}
1246+
"{{ .Name.Underscore }}": {{ .ExternalType }}Schema(),
1247+
{{- end }}
1248+
{{- end }}
1249+
12291250
{{- define "renderSchemaSimpleAttribute" }}
12301251
"{{ .Name.Underscore }}": {{ .Package }}.{{ .SchemaType }} {
12311252
Description: "{{ .Description }}",
@@ -1251,6 +1272,8 @@ const renderSchemaTemplate = `
12511272
{{- template "renderSchemaMapNestedAttribute" Map "StructName" $.StructName "Attribute" . }}
12521273
{{- else if eq .SchemaType "SingleNestedAttribute" }}
12531274
{{- template "renderSchemaSingleNestedAttribute" Map "StructName" $.StructName "Attribute" . }}
1275+
{{- else if eq .SchemaType "ExternalAttribute" }}
1276+
{{- template "renderSchemaExternalAttribute" Map "Attribute" . }}
12541277
{{- else }}
12551278
{{- template "renderSchemaSimpleAttribute" . }}
12561279
{{- end }}
@@ -1522,6 +1545,18 @@ func createStructSpecForUuidModel(resourceTyp properties.ResourceType, schemaTyp
15221545
Tags: []string{"`tfsdk:\"location\"`"},
15231546
})
15241547

1548+
position := &properties.NameVariant{
1549+
Underscore: naming.Underscore("", "position", ""),
1550+
CamelCase: naming.CamelCase("", "position", "", true),
1551+
LowerCamelCase: naming.CamelCase("", "position", "", false),
1552+
}
1553+
1554+
fields = append(fields, datasourceStructFieldSpec{
1555+
Name: position.CamelCase,
1556+
Type: "TerraformPositionObject",
1557+
Tags: []string{"`tfsd:\"position\"`"},
1558+
})
1559+
15251560
var structName string
15261561
switch schemaTyp {
15271562
case schemaResource:

pkg/translate/terraform_provider/template.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,12 +1451,19 @@ if err != nil && err.Error() != "Object not found" {
14511451
}
14521452
14531453
var movementRequired bool
1454+
{{- if .Exhaustive }}
1455+
trueValue := true
1456+
position := rule.Position{First: &trueValue}
14541457
for idx, elt := range existing {
14551458
if processedStateEntries[elt.Name].StateIdx != idx {
14561459
movementRequired = true
14571460
}
14581461
processedStateEntries[elt.Name].Entry.Uuid = elt.Uuid
14591462
}
1463+
{{- else }}
1464+
position := state.Position.CopyToPango()
1465+
movementRequired = true
1466+
{{- end }}
14601467
14611468
if movementRequired {
14621469
entries := make([]{{ $resourceSDKStructName }}, len(processedStateEntries))
@@ -1469,8 +1476,7 @@ if movementRequired {
14691476
finalOrder = append(finalOrder, elt.Name)
14701477
}
14711478
1472-
trueValue := true
1473-
err = svc.MoveGroup(ctx, location, rule.Position{First: &trueValue}, entries)
1479+
err = svc.MoveGroup(ctx, location, position, entries)
14741480
if err != nil {
14751481
resp.Diagnostics.AddError("Failed to reorder entries", err.Error())
14761482
return

0 commit comments

Comments
 (0)