From a0867421640fc569ed14fec412186d004b2c7f51 Mon Sep 17 00:00:00 2001 From: Krzysztof Klimonda Date: Fri, 9 Aug 2024 11:34:04 +0200 Subject: [PATCH] Implementation of Delete() for entry and uuid-style lists --- pkg/translate/terraform_provider/funcs.go | 48 ++++++++--- pkg/translate/terraform_provider/template.go | 79 ++++++++++++++++++- .../terraform_provider_file.go | 2 +- 3 files changed, 118 insertions(+), 11 deletions(-) diff --git a/pkg/translate/terraform_provider/funcs.go b/pkg/translate/terraform_provider/funcs.go index ca199086..41cefa00 100644 --- a/pkg/translate/terraform_provider/funcs.go +++ b/pkg/translate/terraform_provider/funcs.go @@ -1967,29 +1967,59 @@ func ResourceUpdateFunction(resourceTyp properties.ResourceType, names *NameProv return processTemplate(tmpl, "resource-update-function", data, funcMap) } -func ResourceDeleteFunction(resourceTyp properties.ResourceType, structName string, serviceName string, paramSpec *properties.Normalization, resourceSDKName string) (string, error) { +func ResourceDeleteFunction(resourceTyp properties.ResourceType, names *NameProvider, serviceName string, paramSpec *properties.Normalization, resourceSDKName string) (string, error) { if strings.Contains(serviceName, "group") { serviceName = "group" } + var tmpl string + var listAttribute string + var exhaustive bool + switch resourceTyp { + case properties.ResourceEntry: + tmpl = resourceDeleteFunction + case properties.ResourceEntryPlural: + tmpl = resourceDeleteManyFunction + listAttribute = pascalCase(paramSpec.TerraformProviderConfig.PluralName) + case properties.ResourceUuid: + tmpl = resourceDeleteManyFunction + listAttribute = pascalCase(paramSpec.TerraformProviderConfig.PluralName) + exhaustive = true + case properties.ResourceUuidPlural: + tmpl = resourceDeleteManyFunction + listAttribute = pascalCase(paramSpec.TerraformProviderConfig.PluralName) + } + + listAttributeVariant := &properties.NameVariant{ + Underscore: naming.Underscore("", listAttribute, ""), + CamelCase: naming.CamelCase("", listAttribute, "", true), + LowerCamelCase: naming.CamelCase("", listAttribute, "", false), + } + + var resourceIsMap bool + if resourceTyp == properties.ResourceEntryPlural { + resourceIsMap = true + } + data := map[string]interface{}{ "HasEncryptedResources": paramSpec.HasEncryptedResources(), + "ResourceIsMap": resourceIsMap, "EntryOrConfig": paramSpec.EntryOrConfig(), + "ListAttribute": listAttributeVariant, + "Exhaustive": exhaustive, "HasEntryName": paramSpec.HasEntryName(), - "structName": structName, + "structName": names.ResourceStructName, "serviceName": naming.CamelCase("", serviceName, "", false), "resourceSDKName": resourceSDKName, } - var tmpl string - switch resourceTyp { - case properties.ResourceEntry: - tmpl = resourceDeleteFunction - case properties.ResourceUuid, properties.ResourceUuidPlural: - tmpl = resourceDeleteManyFunction + funcMap := template.FuncMap{ + "RenderLocationsStateToPango": func(source string, dest string) (string, error) { + return RenderLocationsStateToPango(names, paramSpec, source, dest) + }, } - return processTemplate(tmpl, "resource-delete-function", data, nil) + return processTemplate(tmpl, "resource-delete-function", data, funcMap) } func ConfigEntry(entryName string, param *properties.SpecParam) (string, error) { diff --git a/pkg/translate/terraform_provider/template.go b/pkg/translate/terraform_provider/template.go index 0412d288..e2125f7e 100644 --- a/pkg/translate/terraform_provider/template.go +++ b/pkg/translate/terraform_provider/template.go @@ -1592,7 +1592,84 @@ const resourceUpdateFunction = ` resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) ` -const resourceDeleteManyFunction = `` +const resourceDeleteManyFunction = ` +{{ $resourceSDKStructName := printf "%s.%s" .resourceSDKName .EntryOrConfig }} +{{ $resourceTFStructName := printf "%s%sObject" .structName .ListAttribute.CamelCase }} + +var state {{ .structName }}Model +resp.Diagnostics.Append(req.State.Get(ctx, &state)...) +if resp.Diagnostics.HasError() { + return +} + +// Basic logging. +tflog.Info(ctx, "performing resource delete", map[string]any{ + "resource_name": "panos_{{ UnderscoreName .structName }}", + "function": "Delete", +}) + +{{- if .ResourceIsMap }} +elements := make(map[string]{{ $resourceTFStructName }}, len(state.{{ .ListAttribute.CamelCase }}.Elements())) +state.{{ .ListAttribute.CamelCase }}.ElementsAs(ctx, &elements, false) +{{- else }} +var elements []{{ $resourceTFStructName }} +state.{{ .ListAttribute.CamelCase }}.ElementsAs(ctx, &elements, false) +{{- end }} + +var location {{ .resourceSDKName }}.Location +{{ RenderLocationsStateToPango "state.Location" "location" }} + +updates := xmlapi.NewMultiConfig(len(elements)) + +{{- if .Exhausitive }} +existing, err := svc.List(ctx, location, "get", "", "") +if err != nil { + resp.Diagnostics.AddError("sdk error while listing entries", err.Error()) +} +for _, elt := range existing { + path, err := location.XpathWithEntryName(r.client.Versioning(), elt.Name) + if err != nil { + resp.Diagnostics.AddError("sdk error while creating xpath", err.Error()) + } + updates.Add(&xmlapi.Config{ + Action: "delete", + Xpath: util.AsXpath(path), + Target: r.client.GetTarget(), + }) +} +{{- else if .ResourceIsMap }} +for name, _ := range elements { + path, err := location.XpathWithEntryName(r.client.Versioning(), name) + if err != nil { + resp.Diagnostics.AddError("sdk error while creating xpath", err.Error()) + } + updates.Add(&xmlapi.Config{ + Action: "delete", + Xpath: util.AsXpath(path), + Target: r.client.GetTarget(), + }) +} +{{- else }} +for _, elt := range elements { + path, err := location.XpathWithEntryName(r.client.Versioning(), elt.Name.ValueString()) + if err != nil { + resp.Diagnostics.AddError("sdk error while creating xpath", err.Error()) + } + updates.Add(&xmlapi.Config{ + Action: "delete", + Xpath: util.AsXpath(path), + Target: r.client.GetTarget(), + }) +} +{{- end }} + +if len(updates.Operations) > 0 { + if _, _, _, err := r.client.MultiConfig(ctx, updates, false, nil); err != nil { + resp.Diagnostics.AddError("error updating entries", err.Error()) + return + } +} +` const resourceDeleteFunction = ` var state {{ .structName }}Model diff --git a/pkg/translate/terraform_provider/terraform_provider_file.go b/pkg/translate/terraform_provider/terraform_provider_file.go index 039f0aab..2d366fb4 100644 --- a/pkg/translate/terraform_provider/terraform_provider_file.go +++ b/pkg/translate/terraform_provider/terraform_provider_file.go @@ -143,7 +143,7 @@ func (g *GenerateTerraformProvider) GenerateTerraformResource(resourceTyp proper return ResourceUpdateFunction(resourceTyp, names, serviceName, spec, names.PackageName) }, "ResourceDeleteFunction": func(structName string, serviceName string) (string, error) { - return ResourceDeleteFunction(resourceTyp, structName, serviceName, spec, names.PackageName) + return ResourceDeleteFunction(resourceTyp, names, serviceName, spec, names.PackageName) }, "ParamToModelResource": ParamToModelResource, "ModelNestedStruct": ModelNestedStruct,