PaloAltoNetworks / pan-os-codegen

Generator for pango SDK and panos Terraform Provider
MIT License
4 stars 0 forks source link

Implement create_import_id Terraform function to convert resources into import IDs #150

Open kklimonda-cl opened 2 weeks ago

kklimonda-cl commented 2 weeks ago

Implementation

Basics

Function signature: provider::panos::create_import_id(string, object)

string -- this is resource name (e.g. _panos_addressgroup) object -- this is an instance of the resource that Import ID is being generated for

Example code

Basic implementation would look similar to the following:

var (
    _ function.Function = &ImportStateCreator{}
)

type ImportStateCreator struct{}

func (o *ImportStateCreator) Metadata(ctx context.Context, req function.MetadataRequest, resp *function.MetadataResponse) {
    resp.Name = "generate_import_id"
}

func (o *ImportStateCreator) Definition(ctx context.Context, req function.DefinitionRequest, resp *function.DefinitionResponse) {
    resp.Definition = function.Definition{
        Summary:     "Generate Import ID",
        Description: "Generate Import ID for the given resource that can be used to import resources into the state.",

        Parameters: []function.Parameter{
            function.StringParameter{
                Name:        "resource_asn",
                Description: "Name of the resource",
            },
            function.DynamicParameter{
                Name:        "resource_data",
                Description: "Resource data",
            },
        },
        Return: function.StringReturn{},
    }
}

func (o *ImportStateCreator) Run(ctx context.Context, req function.RunRequest, resp *function.RunResponse) {
    var resourceAsn string
    var dynamicResource types.Dynamic

    resp.Error = function.ConcatFuncErrors(resp.Error, req.Arguments.Get(ctx, &resourceAsn, &dynamicResource))

    if resp.Error != nil {
        return
    }

    var resource types.Object
    switch value := dynamicResource.UnderlyingValue().(type) {
    case types.Object:
        resource = value
    default:
        return
    }

    var result string
    var err error
    switch resourceAsn {
    case "panos_address_group":
        result, err = AddressGroupImportStateCreator(ctx, resource)
        if err != nil {
            resp.Error = function.ConcatFuncErrors(resp.Error, function.NewFuncError(err.Error()))
            return
        }
    }

    resp.Error = function.ConcatFuncErrors(resp.Error, resp.Result.Set(ctx, result))
}

Instead of switching on resourceAsn value, it would be cleaner to generate a map of resource name -> creator function that can be then used like:

fn, ok := creatorFuncs[resourceAsn]
resource, err := fn(ctx, resource)
[...]

Usage Examples

data "panos_address_group" "test_group" {
  location = {
    shared               = true
    from_panorama_shared = false
  }

  name = "test-group"
}

output "test_group_import_id" {
  value = provider::panos::create_import_id("panos_address_group", data.panos_address_group.test_group)
}