Skip to content

Commit

Permalink
use a model's ToSchema function if it has one
Browse files Browse the repository at this point in the history
  • Loading branch information
rauchy committed Dec 27, 2024
1 parent 151ed6d commit 2051469
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ func (r *ShareResource) Schema(ctx context.Context, req resource.SchemaRequest,
c.SetRequired("object", "partition", "value", "op")
c.SetRequired("object", "partition", "value", "name")

c.SetOptional("owner")
return c
})
resp.Schema = schema.Schema{
Expand Down
38 changes: 27 additions & 11 deletions internal/providers/pluginfw/tfschema/struct_to_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ import (
"github.com/hashicorp/terraform-plugin-framework/types"
)

type CustomizableSchemaProvider interface {
ToSchema(cs CustomizableSchema, path ...string) CustomizableSchema
}

type structTag struct {
optional bool
computed bool
Expand All @@ -26,6 +30,7 @@ type structTag struct {
func typeToSchema(ctx context.Context, v reflect.Value) NestedBlockObject {
scmAttr := map[string]AttributeBuilder{}
rk := v.Kind()
typeProvidesSchemaCustomization := v.Type().Implements(reflect.TypeOf((*CustomizableSchemaProvider)(nil)).Elem())
if rk == reflect.Ptr {
v = v.Elem()
rk = v.Kind()
Expand Down Expand Up @@ -139,21 +144,28 @@ func typeToSchema(ctx context.Context, v reflect.Value) NestedBlockObject {
}
panic(fmt.Errorf("unexpected type %T in tfsdk structs, expected a plugin framework value type. %s", value, common.TerraformBugErrorMessage))
}

attr := scmAttr[fieldName]
if structTag.computed {
// Computed attributes are always computed and may be optional.
attr = attr.SetComputed()
if structTag.optional {
attr = attr.SetOptional()
}

if typeProvidesSchemaCustomization {
attr = attr.SetOptional() // default to optional, ToSchema may override this
} else {
// Non-computed attributes must be either optional or required.
if structTag.optional {
attr = attr.SetOptional()
if structTag.computed {
// Computed attributes are always computed and may be optional.
attr = attr.SetComputed()
if structTag.optional {
attr = attr.SetOptional()
}
} else {
attr = attr.SetRequired()
// Non-computed attributes must be either optional or required.
if structTag.optional {
attr = attr.SetOptional()
} else {
attr = attr.SetRequired()
}
}
}

scmAttr[fieldName] = attr
}
return NestedBlockObject{Attributes: scmAttr}
Expand Down Expand Up @@ -185,7 +197,11 @@ func ResourceStructToSchemaMap(ctx context.Context, v any, customizeSchema func(
nestedBlockObj := typeToSchema(ctx, reflect.ValueOf(v))

if customizeSchema != nil {
cs := customizeSchema(*ConstructCustomizableSchema(nestedBlockObj))
cs := *ConstructCustomizableSchema(nestedBlockObj)
if schemaProvider, ok := v.(CustomizableSchemaProvider); ok {
cs = schemaProvider.ToSchema(cs)
}
cs = customizeSchema(cs)
return BuildResourceAttributeMap(cs.ToNestedBlockObject().Attributes), BuildResourceBlockMap(cs.ToNestedBlockObject().Blocks)
} else {
return BuildResourceAttributeMap(nestedBlockObj.Attributes), BuildResourceBlockMap(nestedBlockObj.Blocks)
Expand Down

0 comments on commit 2051469

Please sign in to comment.