You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Reference: #132
Reference: #326
Reference: #437
Reference: #491
Reference: #508
Reference: #532
This change introduces a new `provider/schema` package, which contains schema interfaces and types relevant to providers, such as omitting `Computed`, plan modifiers, and schema versioning. This new schema implementation also provides strongly typed attributes, nested attributes, and blocks with customizable types. Nested attributes and blocks are exposed with a separate nested object for customization and validation.
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 providers. The framework design will also raise compiler-time errors for errant typing of validators.
No changes are required for data handling in the `Read` method.
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/schema"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
)
type ExampleCloudProvider struct{}
func (p ExampleCloudProvider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"string_attribute": schema.StringAttribute{
Required: true,
Validators: []validator.String{
stringvalidator.LengthBetween(3, 256),
},
},
"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,
},
},
Validators: []validator.Object{ /*...*/ },
},
Optional: true,
Validators: []validator.List{
listvalidator.SizeAtMost(2),
},
},
"single_nested_attribute": schema.SingleNestedAttribute{
Attributes: map[string]schema.Attribute{
"int64_attribute": schema.Int64Attribute{
Optional: true,
},
},
Optional: true,
},
},
Blocks: map[string]schema.Block{
"list_block": schema.ListNestedBlock{
NestedObject: schema.NestedBlockObject{
Attributes: map[string]schema.Attribute{
"float64_attribute": schema.Float64Attribute{
Optional: true,
Validators: []validator.Float64{
float64validator.OneOf(1.2, 2.4),
},
},
},
Validators: []validator.Object{ /*...*/ },
},
Validators: []validator.List{
listvalidator.SizeAtMost(2),
},
},
},
}
}
```
To migrate a provider schema:
- Add `github.com/hashicorp/terraform-plugin-framework/provider/schema` to the `import` statement
- Switch the `provider.Provider` implementation `GetSchema` method to `Schema` whose response includes a `schema.Schema` from the new package.
Prior implementation:
```go
func (p ExampleCloudProvider) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) {
return tfsdk.Schema{/* ... */}, nil
}
```
Migrated implementation:
```go
func (p ExampleCloudProvider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) {
resp.Schema = schema.Schema{/*...*/}
}
```
If the provider requires no schema, the method can be entirely empty.
- Switch `map[string]tfsdk.Attribute` with `map[string]schema.Attribute`
- Switch `map[string]tfsdk.Block` with `map[string]schema.Block`
- Switch individual attribute and block 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 `schema.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 schema.XXXAttribute must be declared inside map[string]schema.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 schema.XXXAttribute must be declared inside map[string]schema.Attribute
schema.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 schema.XXXAttribute must be declared inside map[string]schema.Attribute
schema.SingleNestedAttribute{
Attributes: map[string]schema.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 schema.XXXAttribute must be declared inside map[string]schema.Attribute
schema.ListNestedAttribute{
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{/*...*/},
},
Required: true,
}
```
Prior collection blocks type (`tfsdk.Block`) attribute implementation:
```go
// The "tfsdk.Block" could be omitted inside a map[string]tfsdk.Block
tfsdk.Block{
Attributes: map[string]tfsdk.Attribute{/*...*/},
Blocks: map[string]tfsdk.Block{/*...*/},
NestingMode: tfsdk.BlockNestingModeList,
},
```
Migrated implementation:
```go
// The schema.XXXBlock must be declared inside map[string]schema.Block
schema.ListNestedBlock{
NestedObject: schema.NestedBlockObject{
Attributes: map[string]schema.Attribute{/*...*/},
Blocks: map[string]schema.Block{/*...*/},
},
}
```
0 commit comments