I’ve spent some time going through the docs but I stumped at present. Currently migrating a provider to the plugin framework from SDK V2.
The terraform config for this resource can look like this:
resource "my_resource" "resource_name" {
app_id = 223590
settings = {
name = "Aoo Name"
hidden_group_ids = "1, 2, 3"
default_last_used = false
}
}
The settings configuration can have any number of fields with potentially any value type.
Previously in SDKV2 we defined the schema for settings as:
"settings": {
Description: "Settings fields.",
Type: schema.TypeMap,
Required: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
and then we had methods to convert from the API/Terraform as follows:
func resourceApplicationInstallationFlattenSettings(settings client.ApplicationSettings) map[string]interface{} {
attrs := make(map[string]interface{})
for key, value := range settings {
if value != nil {
//Exclude title as it's not something we can terraform but comes back in the settings response
if key != "title" {
attrs[key] = fmt.Sprintf("%v", value)
}
}
}
return attrs
}
func resourceApplicationInstallationExpandConfigurationAttributes(settingsAttributes map[string]interface{}) map[string]interface{} {
result := make(map[string]interface{})
for key, value := range settingsAttributes {
if boolVal, err := strconv.ParseBool(value.(string)); err == nil {
result[key] = boolVal
} else {
result[key] = value
}
}
return result
}
Note we only actually worry about booleans and strings but potentially we might one day see other types. We also just set everything to a String when sending back to the Schema model (not sure if there’s a better way to do this but not too worried with it being the code we are migrating away from).
In the framework plugin migration we’ve defined the schema as:
"settings": schema.MapAttribute{
ElementType: types.StringType,
Required: true,
Description: "Setting fields.",
},
Then we are trying to do similar to determine whether the field is boolean/string as follows:
settings := make(map[string]interface{}, len(data.Settings.Elements()))
for key, value := range data.Settings.Elements() {
if boolVal, err := strconv.ParseBool(value.String()); err == nil {
settings[key] = boolVal
} else {
settings[key] = value
}
}
value.String() seems to always return multiple sets of quotes but the ValueString() method is not available - I assume that is due to the use of Elements() here?
In addition to this we were trying to write tests to test our conversion method but couldn’t work out how to manually create the schema representation. We tried this:
elements := map[string]attr.Value{
"name": types.StringValue("app name"),
"some-bool": types.BoolValue(false),
}
settings, _ := types.MapValue(types.StringType, elements)
schemaModelAppInstallation := ApplicationInstallationResourceModel{
Id: types.StringValue("12345"),
AppId: types.Int64Value(999),
Enabled: types.BoolValue(true),
Settings: settings,
}
but the MapValue call fails due to the fact it expects types.StringType. How would we use the types.ObjectType here to copy all values into the map?
Sorry for the long post but I’ve been struggling with this today so if anyone else has tackled this I would greatly appreciate any advice you can offer.
Thanks
Paul