Skip to content

Commit

Permalink
Add static files for terraform provider
Browse files Browse the repository at this point in the history
  • Loading branch information
Pawel Imielowski committed Mar 29, 2024
1 parent 8fd2a2c commit 5071a16
Show file tree
Hide file tree
Showing 3 changed files with 234 additions and 0 deletions.
16 changes: 16 additions & 0 deletions assets/internal/provider/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package provider

import (
"github.com/PaloAltoNetworks/pango/errors"
)

var InspectionModeError = "Resources are unavailable when the provider is in inspection mode. Resources are only available in API mode."

func IsObjectNotFound(e error) bool {
e2, ok := e.(errors.Panos)
if ok && e2.ObjectNotFound() {
return true
}

return false
}
141 changes: 141 additions & 0 deletions assets/internal/provider/tfid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package provider

import (
"context"

"github.com/PaloAltoNetworks/pango"

"github.com/hashicorp/terraform-plugin-framework/datasource"
dsschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
)

type genericTfid struct {
Name *string `json:"name,omitempty"`
Names []string `json:"names,omitempty"`
Location map[string]any `json:"location"`
}

func (g genericTfid) IsValid() error { return nil }

// Data source.
var (
_ datasource.DataSource = &tfidDataSource{}
_ datasource.DataSourceWithConfigure = &tfidDataSource{}
)

func NewTfidDataSource() datasource.DataSource {
return &tfidDataSource{}
}

type tfidDataSource struct {
client *pango.XmlApiClient
}

type tfidDsModel struct {
Location types.String `tfsdk:"location"`
Variables types.Map `tfsdk:"variables"`
Name types.String `tfsdk:"name"`
Names types.List `tfsdk:"names"`

Tfid types.String `tfsdk:"tfid"`
}

func (d *tfidDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_tfid"
}

func (d *tfidDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = dsschema.Schema{
Description: "Helper data source: create a tfid from the given information. Note that the tfid ouptut from this data source may not exactly match what a resource uses, but it will still be a valid ID to use for resource imports.",

Attributes: map[string]dsschema.Attribute{
"location": dsschema.StringAttribute{
Description: "The location path name.",
Required: true,
},
"variables": dsschema.MapAttribute{
Description: "The variables and values for the specified location.",
Optional: true,
ElementType: types.StringType,
},
"name": dsschema.StringAttribute{
Description: "(Singleton resource) The config's name.",
Optional: true,
},
"names": dsschema.ListAttribute{
Description: "(Grouping resources) The names of the configs.",
Optional: true,
ElementType: types.StringType,
},
"tfid": dsschema.StringAttribute{
Description: "The tfid created from the given parts.",
Computed: true,
},
},
}
}

func (d *tfidDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
if req.ProviderData == nil {
return
}

d.client = req.ProviderData.(*pango.XmlApiClient)
}

func (d *tfidDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var state tfidDsModel
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

// Basic logging.
tflog.Info(ctx, "performing data source read", map[string]any{
"data_source_name": "panos_tfid",
})

vars := make(map[string]types.String, len(state.Variables.Elements()))
resp.Diagnostics.Append(state.Variables.ElementsAs(ctx, &vars, false).Errors()...)

var names []string
resp.Diagnostics.Append(state.Names.ElementsAs(ctx, &names, false)...)

if resp.Diagnostics.HasError() {
return
}

loc := genericTfid{
Name: state.Name.ValueStringPointer(),
Names: append([]string(nil), names...),
}

if len(vars) == 0 {
loc.Location = map[string]any{
state.Location.ValueString(): true,
}
} else {
content := make(map[string]string)
for key, value := range vars {
content[key] = value.ValueString()
}
loc.Location = map[string]any{
state.Location.ValueString(): content,
}
}

// Encode the tfid from the info given.
idstr, err := EncodeLocation(loc)
if err != nil {
resp.Diagnostics.AddError("error encoding tfid", err.Error())
return
}

// Set the tfid param.
state.Tfid = types.StringValue(idstr)

// Done.
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}
77 changes: 77 additions & 0 deletions assets/internal/provider/tools.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package provider

import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"strings"
)

type Locationer interface {
IsValid() error
}

func EncodeLocation(loc Locationer) (string, error) {
b, err := json.Marshal(loc)
if err != nil {
return "", err
}

return base64.StdEncoding.EncodeToString(b), nil
}

func DecodeLocation(s string, loc Locationer) error {
b, err := base64.StdEncoding.DecodeString(s)
if err != nil {
return err
}

if err = json.Unmarshal(b, loc); err != nil {
return err
}

return loc.IsValid()
}

func base64Encode(v []string) string {
var buf bytes.Buffer

for i := range v {
if i != 0 {
buf.WriteString("\n")
}
buf.WriteString(v[i])
}

return base64.StdEncoding.EncodeToString(buf.Bytes())
}

func base64Decode(v string) []string {
joined, err := base64.StdEncoding.DecodeString(v)
if err != nil {
return nil
}

return strings.Split(string(joined), "\n")
}

func ProviderParamDescription(desc, defaultValue, envName, jsonName string) string {
var b strings.Builder

b.WriteString(desc)

if defaultValue != "" {
b.WriteString(fmt.Sprintf(" Default: `%s`.", defaultValue))
}

if envName != "" {
b.WriteString(fmt.Sprintf(" Environment variable: `%s`.", envName))
}

if jsonName != "" {
b.WriteString(fmt.Sprintf(" JSON config file variable: `%s`.", jsonName))
}

return b.String()
}

0 comments on commit 5071a16

Please sign in to comment.