I am trying to construct a terraform provider that can deal with arbitrary map and list inputs. (I am using the provider "framework")
Let's assume my upstream API expects a JSON payload like this (in psuedo-code):
name: string
input1: map(any)
input2: list(any)
So we could send this:
{
"name": "foobar"
"input1": {
"apple": "tree"
},
"input2": ["hello", 123]
}
But also this:
{
"name": "foobaz"
"input1": {
"this": {
"is": "nested"
},
"this-though": "isnt"
},
"input2": [{"here": "things}]
}
etc.
To achieve the above I am using the following as my payload in the API client:
type MyModel struct {
Name string `json:"name,omitempty"`
Input1 map[string]interface{} `json:"input1,omitempty"`
Input2 []interface{} `json:"input2,omitempty"`
}
For the resource schema I am using:
resp.Schema = schema.Schema{
Description: "Manages a smart contract.",
Attributes: map[string]schema.Attribute{
"ID": schema.StringAttribute{
Computed: true,
},
"Name": schema.StringAttribute{
Required: true,
},
"input1": schema.MapAttribute{ <---- What should this be?
Required: true,
},
"input2": schema.ListAttribute{ <---- What should this be?
Required: true,
},
},
Below is an example of how I am attempting to implement Create
// Create a new resource.
func (r *myModelResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
// Retrieve values from plan
var plan myModelModel
diags := req.Plan.Get(ctx, &plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
newMyModel := client.MyModel{
Name: plan.Name.ValueString(),
Input1: plan.Input1.ValueString(), // <---- THIS IS WRONG. What should I do here?
Input2: plan.Input2.ValueString(), // <---- THIS IS WRONG. What should I do here?
}
// Update existing myModel
myModel, err := r.client.CreateMyModel(newMyModel)
if err != nil {
resp.Diagnostics.AddError(
"Error Updating MyModel",
"Could not update MyModel, unexpected error: "+err.Error(),
)
return
}
plan.Name = types.StringValue(myModel.Name)
plan.Input1 = types.StringValue(myModel.Input1) // <---- THIS IS WRONG. What should I do here?
plan.Input2 = types.StringValue(myModel.Input2) // <---- THIS IS WRONG. What should I do here?
// Set state to fully populated data
diags = resp.State.Set(ctx, plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
What should my schema attribute types be, and how should I do the conversion to and from MyModel?