-
Notifications
You must be signed in to change notification settings - Fork 95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
provider/metaschema: Initial package #562
Conversation
Reference: #132 Reference: #326 Reference: #437 Reference: #491 Reference: #508 Reference: #532 This change introduces a new `provider/metaschema` package, which contains schema interfaces and types relevant to provider meta schemas, such as omitting `Computed`, `DeprecatedMessage`, `Sensitive`, plan modifiers, validators, blocks, schema descriptions, and schema versioning. This new schema implementation also provides strongly typed attributes and nested attributes with customizable types. Nested attributes are exposed with a separate nested object for customization. The implementation leans heavily on the design choice of the framework being responsible for preventing provider developer runtime errors. The tailored fields no longer expose functionality that is not available for provider meta schemas. No changes are required for data handling during requests. Example definition: ```go package test import ( "context" "github.com/bflad/terraform-plugin-framework-type-time/timetypes" "github.com/hashicorp/terraform-plugin-framework-validators/float64validator" "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/provider" "github.com/hashicorp/terraform-plugin-framework/provider/metaschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" ) type ExampleCloudProvider struct{} func (p ExampleCloudProvider) MetaSchema(ctx context.Context, req provider.MetaSchemaRequest, resp *provider.MetaSchemaResponse) { resp.Schema = metaschema.Schema{ Attributes: map[string]schema.Attribute{ "string_attribute": schema.StringAttribute{ Required: true, }, "custom_string_attribute": schema.StringAttribute{ CustomType: timetypes.RFC3339Type, Optional: true, }, "list_attribute": schema.ListAttribute{ ElementType: types.StringType, Optional: true, }, "list_nested_attribute": schema.ListNestedAttribute{ NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ "bool_attribute": schema.BoolAttribute{ Optional: true, }, }, }, Optional: true, }, "single_nested_attribute": schema.SingleNestedAttribute{ Attributes: map[string]schema.Attribute{ "int64_attribute": schema.Int64Attribute{ Optional: true, }, }, Optional: true, }, }, } } ``` To migrate a provider meta schema: - Add `github.com/hashicorp/terraform-plugin-framework/provider/metaschema` to the `import` statement - Switch the `provider.ProviderWithMetaSchema` implementation `GetMetaSchema` method to `MetaSchema` whose response includes a `metaschema.Schema` from the new package. Prior implementation: ```go func (p ExampleCloudProvider) GetMetaSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) { return tfsdk.Schema{/* ... */}, nil } ``` Migrated implementation: ```go func (p ExampleCloudProvider) MetaSchema(ctx context.Context, req provider.MetaSchemaRequest, resp *provider.MetaSchemaResponse) { resp.Schema = metaschema.Schema{/*...*/} } ``` If the provider requires no meta schema, the method can be removed entirely. - Switch `map[string]tfsdk.Attribute` with `map[string]metaschema.Attribute` - Switch individual attribute definitions. Unless the code was already taking advantage of custom attribute types (uncommon so far), the `Type` field will be removed and the map entries must declare the typed implementation, e.g. a `tfsdk.Attribute` with `Type: types.StringType` is equivalent to `metaschema.StringAttribute`. Custom attribute types can be specified via the `CustomType` field in each of the implementations. Prior primitive type (`types.BoolType`, `types.Float64Type`, `types.Int64Type`, `types.NumberType`, `types.StringType`) attribute implementation: ```go // The "tfsdk.Attribute" could be omitted inside a map[string]tfsdk.Attribute tfsdk.Attribute{ Required: true, Type: types.StringType, } ``` Migrated implementation: ```go // The metaschema.XXXAttribute must be declared inside map[string]metaschema.Attribute schema.StringAttribute{ Required: true, } ``` Prior collection type (`types.ListType`, `types.MapType`, `types.SetType`) attribute implementation: ```go // The "tfsdk.Attribute" could be omitted inside a map[string]tfsdk.Attribute tfsdk.Attribute{ Required: true, Type: types.ListType{ ElemType: types.StringType, }, } ``` Migrated implementation: ```go // The metaschema.XXXAttribute must be declared inside map[string]metaschema.Attribute metaschema.ListAttribute{ ElementType: types.StringType, Required: true, } ``` Prior single nested attributes type (`tfsdk.SingleNestedAttributes()`) attribute implementation: ```go // The "tfsdk.Attribute" could be omitted inside a map[string]tfsdk.Attribute tfsdk.Attribute{ Attributes: tfsdk.SingleNestedAttributes(map[string]tfsdk.Attribute{/*...*/}), Required: true, }, ``` Migrated implementation: ```go // The metaschema.XXXAttribute must be declared inside map[string]metaschema.Attribute metaschema.SingleNestedAttribute{ Attributes: map[string]metaschema.Attribute{/*...*/}, Required: true, } ``` Prior collection nested attributes type (`tfsdk.ListNestedAttributes()`, `tfsdk.MapNestedAttributes()`, `tfsdk.SetNestedAttributes()`) attribute implementation: ```go // The "tfsdk.Attribute" could be omitted inside a map[string]tfsdk.Attribute tfsdk.Attribute{ Attributes: tfsdk.ListNestedAttributes(map[string]tfsdk.Attribute{/*...*/}), Required: true, }, ``` Migrated implementation: ```go // The metaschema.XXXAttribute must be declared inside map[string]metaschema.Attribute metaschema.ListNestedAttribute{ NestedObject: metaschema.NestedAttributeObject{ Attributes: map[string]metaschema.Attribute{/*...*/}, }, Required: true, } ```
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions. |
Reference: #132
Reference: #326
Reference: #437
Reference: #491
Reference: #508
Reference: #532
NOTE: Almost all providers will not use this functionality and it is already marked as experimental.
This change introduces a new
provider/metaschema
package, which contains schema interfaces and types relevant to provider meta schemas, such as omittingComputed
,DeprecatedMessage
,Sensitive
, plan modifiers, validators, blocks, schema descriptions, and schema versioning. This new schema implementation also provides strongly typed attributes and nested attributes with customizable types. Nested attributes are exposed with a separate nested object for customization.The implementation leans heavily on the design choice of the framework being responsible for preventing provider developer runtime errors. The tailored fields no longer expose functionality that is not available for provider meta schemas.
No changes are required for data handling during requests.
Example definition:
To migrate a provider meta schema:
github.com/hashicorp/terraform-plugin-framework/provider/metaschema
to theimport
statementprovider.ProviderWithMetaSchema
implementationGetMetaSchema
method toMetaSchema
whose response includes ametaschema.Schema
from the new package.Prior implementation:
Migrated implementation:
If the provider requires no meta schema, the method can be removed entirely.
map[string]tfsdk.Attribute
withmap[string]metaschema.Attribute
Type
field will be removed and the map entries must declare the typed implementation, e.g. atfsdk.Attribute
withType: types.StringType
is equivalent tometaschema.StringAttribute
. Custom attribute types can be specified via theCustomType
field in each of the implementations.Prior primitive type (
types.BoolType
,types.Float64Type
,types.Int64Type
,types.NumberType
,types.StringType
) attribute implementation:Migrated implementation:
Prior collection type (
types.ListType
,types.MapType
,types.SetType
) attribute implementation:Migrated implementation:
Prior single nested attributes type (
tfsdk.SingleNestedAttributes()
) attribute implementation:Migrated implementation:
Prior collection nested attributes type (
tfsdk.ListNestedAttributes()
,tfsdk.MapNestedAttributes()
,tfsdk.SetNestedAttributes()
) attribute implementation:Migrated implementation: