I'm using the terraform-plugin-framework
.
This is a contrived example, but say I have a resource like:
type R struct {
IsAdmin types.Bool `tfsdk:"isAdmin"`
F1 types.String `tfsdk:"f1"`
}
How do I define a schema such that:
a. if IsAdmin
is true, F1
must be empty string
b. if IsAdmin
is false, F1
must not be empty string
A simple way would be set F1
as Optional
in schema, then in say Create
handler do validation there. I don't think this is the right way. Shouldn't Schema
function do this ?
You can accomplish this with ValidateConfig:
func (_ *RResource) ValidateConfig(ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse) {
// determine input values
var state R
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}
// return if either field member/attribute is unknown
if state.IsAdmin.IsUnknown() || state.F1.IsUnknown() {
return
}
// validate F1
if state.IsAdmin.ValueBool() && len(state.F1.ValueString()) > 0 {
resp.Diagnostics.AddAttributeError(
path.Root("f1"),
"Invalid Attribute Value",
"Parameter 'f1' cannot be assigned a value if parameter isAdmin is assigned a value of 'true'",
)
} else {
if !state.IsAdmin.ValueBool() && len(state.F1.ValueString()) == 0 {
resp.Diagnostics.AddAttributeError(
path.Root("f1"),
"Invalid Attribute Value",
"Parameter 'f1' must be assigned a value if parameter isAdmin is assigned a value of 'false'",
)
}
}
}
This solution makes the assumption that the attribute schema for the resource follows the typical convention of lowercase for the data model struct field members as it was not shared in the question.
Normally it would be easier to accomplish multiple resource attribute validation with the resource validator, but in your situation the above would be easier and cleaner.