|
5 | 5 | "fmt" |
6 | 6 | "io/fs" |
7 | 7 | "maps" |
8 | | - "os" |
9 | 8 | "path/filepath" |
10 | 9 | "regexp" |
11 | 10 | "runtime" |
@@ -85,6 +84,7 @@ type TerraformProviderConfig struct { |
85 | 84 | Action bool `json:"action" yaml:"action"` |
86 | 85 | CustomValidation bool `json:"custom_validation" yaml:"custom_validation"` |
87 | 86 | SkipResource bool `json:"skip_resource" yaml:"skip_resource"` |
| 87 | + SkipListResource *bool `json:"skip_list_resource", yaml:"skip_list_resource"` |
88 | 88 | SkipDatasource bool `json:"skip_datasource" yaml:"skip_datasource"` |
89 | 89 | SkipDatasourceListing bool `json:"skip_datasource_listing" yaml:"skip_datasource_listing"` |
90 | 90 | ResourceType TerraformResourceType `json:"resource_type" yaml:"resource_type"` |
@@ -722,6 +722,7 @@ func schemaToSpec(object object.Object) (*Normalization, error) { |
722 | 722 | Action: object.TerraformConfig.Action, |
723 | 723 | CustomValidation: object.TerraformConfig.CustomValidation, |
724 | 724 | SkipResource: object.TerraformConfig.SkipResource, |
| 725 | + SkipListResource: object.TerraformConfig.SkipListResource, |
725 | 726 | SkipDatasource: object.TerraformConfig.SkipDatasource, |
726 | 727 | SkipDatasourceListing: object.TerraformConfig.SkipdatasourceListing, |
727 | 728 | ResourceType: TerraformResourceType(object.TerraformConfig.ResourceType), |
@@ -1126,26 +1127,20 @@ func (spec *Normalization) ResourceXpathVariablesCount() int { |
1126 | 1127 | return len(spec.PanosXpath.Variables) |
1127 | 1128 | } |
1128 | 1129 |
|
1129 | | -// loadTemplate loads a template from either sdk or terraform-provider templates directory |
1130 | | -func loadTemplate(templateType string, templatePath string) (string, error) { |
1131 | | - fullPath := filepath.Join("templates", templateType, templatePath) |
1132 | | - content, err := os.ReadFile(fullPath) |
1133 | | - if err != nil { |
1134 | | - // Try from parent directories (for when running from subdirectories) |
1135 | | - for i := 1; i <= 3; i++ { |
1136 | | - prefix := strings.Repeat("../", i) |
1137 | | - altPath := filepath.Join(prefix, "templates", templateType, templatePath) |
1138 | | - content, err = os.ReadFile(altPath) |
1139 | | - if err == nil { |
1140 | | - break |
1141 | | - } |
1142 | | - } |
1143 | | - if err != nil { |
1144 | | - return "", fmt.Errorf("failed to read template %s: %w", fullPath, err) |
1145 | | - } |
1146 | | - } |
1147 | | - return string(content), nil |
| 1130 | +const attributesFromXpathComponentsTmpl = ` |
| 1131 | +{{- range .Components }} |
| 1132 | + {{ if eq .Type "value" }} |
| 1133 | + {{ $.Target }}.{{ .Name }} = types.StringValue(components[{{ .Idx }}]) |
| 1134 | + {{- else if eq .Type "entry" }} |
| 1135 | +{ |
| 1136 | + component := components[{{ .Idx }}] |
| 1137 | + component = strings.TrimPrefix(component, "entry[@name='") |
| 1138 | + component = strings.TrimSuffix(component, "']") |
| 1139 | + {{ $.Target }}.{{ .Name.CamelCase }} = types.StringValue(component) |
1148 | 1140 | } |
| 1141 | + {{- end }} |
| 1142 | +{{- end }} |
| 1143 | +` |
1149 | 1144 |
|
1150 | 1145 | func (spec *Normalization) AttributesFromXpathComponents(target string) (string, error) { |
1151 | 1146 | type componentCtx struct { |
@@ -1182,43 +1177,66 @@ func (spec *Normalization) AttributesFromXpathComponents(target string) (string, |
1182 | 1177 | Components: components, |
1183 | 1178 | } |
1184 | 1179 |
|
1185 | | - tmplContent, err := loadTemplate("terraform-provider", "partials/attributes_from_xpath_components.tmpl") |
1186 | | - if err != nil { |
1187 | | - return "", err |
1188 | | - } |
1189 | | - |
1190 | | - tmpl := template.Must(template.New("attributes-from-xpath-components").Parse(tmplContent)) |
| 1180 | + tmpl := template.Must(template.New("attributes-from-xpath-components").Parse(attributesFromXpathComponentsTmpl)) |
1191 | 1181 |
|
1192 | 1182 | var buf bytes.Buffer |
1193 | | - err = tmpl.Execute(&buf, data) |
| 1183 | + err := tmpl.Execute(&buf, data) |
1194 | 1184 | if err != nil { |
1195 | 1185 | panic(err) |
1196 | 1186 | } |
1197 | 1187 |
|
1198 | 1188 | return buf.String(), nil |
1199 | 1189 | } |
1200 | 1190 |
|
| 1191 | +const resourceXpathAssignmentsTmpl = ` |
| 1192 | +{{- range .Variables }} |
| 1193 | + {{- if or (eq .Type "entry") (eq .Type "value") }} |
| 1194 | + ans = append(ans, components[{{ .Idx }}]) |
| 1195 | + {{- else if eq .Type "static" }} |
| 1196 | + ans = append(ans, "{{ .Name.Original }}") |
| 1197 | + {{- end }} |
| 1198 | +{{- end }} |
| 1199 | +` |
| 1200 | + |
1201 | 1201 | func (spec *Normalization) ResourceXpathAssignments() (string, error) { |
1202 | 1202 | data := xpathVariablesCtx{ |
1203 | 1203 | Variables: createXpathVariablesContext(spec), |
1204 | 1204 | } |
1205 | 1205 |
|
1206 | | - tmplContent, err := loadTemplate("sdk", "partials/resource_xpath_assignments.tmpl") |
1207 | | - if err != nil { |
1208 | | - return "", err |
1209 | | - } |
1210 | | - |
1211 | | - tmpl := template.Must(template.New("resource-xpath-assignments").Parse(tmplContent)) |
| 1206 | + tmpl := template.Must(template.New("resource-xpath-assignments").Parse(resourceXpathAssignmentsTmpl)) |
1212 | 1207 |
|
1213 | 1208 | var buf bytes.Buffer |
1214 | | - err = tmpl.Execute(&buf, data) |
| 1209 | + err := tmpl.Execute(&buf, data) |
1215 | 1210 | if err != nil { |
1216 | 1211 | panic(err) |
1217 | 1212 | } |
1218 | 1213 |
|
1219 | 1214 | return buf.String(), nil |
1220 | 1215 | } |
1221 | 1216 |
|
| 1217 | +const xpathVariableChecksTmpl = ` |
| 1218 | +{{- range .Variables }} |
| 1219 | + {{- if eq .Type "entry" }} |
| 1220 | +{ |
| 1221 | + component := components[{{ .Idx }}] |
| 1222 | + {{- if .AllowEmpty }} |
| 1223 | + if component != "entry" { |
| 1224 | + {{- end }} |
| 1225 | + if !strings.HasPrefix(component, "entry[@name=\"]") && !strings.HasPrefix(component, "entry[@name='") { |
| 1226 | + return nil, errors.NewInvalidXpathComponentError(fmt.Sprintf("{{ .Name.CamelCase }} must be formatted as entry: %s", component)) |
| 1227 | + } |
| 1228 | +
|
| 1229 | + if !strings.HasSuffix(component, "\"]") && !strings.HasSuffix(component, "']") { |
| 1230 | + return nil, errors.NewInvalidXpathComponentError(fmt.Sprintf("{{ .Name.CamelCase }} must be formatted as entry: %s", component)) |
| 1231 | + } |
| 1232 | + {{- if .AllowEmpty }} |
| 1233 | + } |
| 1234 | + {{- end }} |
| 1235 | +} |
| 1236 | + {{- end }} |
| 1237 | +{{- end }} |
| 1238 | +` |
| 1239 | + |
1222 | 1240 | type xpathVariableCtx struct { |
1223 | 1241 | Type object.PanosXpathVariableType |
1224 | 1242 | Name *NameVariant |
@@ -1283,15 +1301,10 @@ func (spec *Normalization) ResourceXpathVariableChecks() (string, error) { |
1283 | 1301 | Variables: createXpathVariablesContext(spec), |
1284 | 1302 | } |
1285 | 1303 |
|
1286 | | - tmplContent, err := loadTemplate("sdk", "partials/xpath_variable_checks.tmpl") |
1287 | | - if err != nil { |
1288 | | - return "", err |
1289 | | - } |
1290 | | - |
1291 | 1304 | var buf bytes.Buffer |
1292 | | - tmpl := template.Must(template.New("xpath-variable-checks").Parse(tmplContent)) |
| 1305 | + tmpl := template.Must(template.New("xpath-variable-checks").Parse(xpathVariableChecksTmpl)) |
1293 | 1306 |
|
1294 | | - err = tmpl.Execute(&buf, data) |
| 1307 | + err := tmpl.Execute(&buf, data) |
1295 | 1308 | if err != nil { |
1296 | 1309 | panic(err) |
1297 | 1310 | } |
|
0 commit comments