Skip to content
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

Merged
merged 3 commits into from Nov 29, 2022
Merged

provider/metaschema: Initial package #562

merged 3 commits into from Nov 29, 2022

Commits on Nov 29, 2022

  1. provider/metaschema: Initial package

    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,
    }
    ```
    bflad committed Nov 29, 2022
    Copy the full SHA
    0cf8ce4 View commit details
    Browse the repository at this point in the history
  2. Update CHANGELOG for #562

    bflad committed Nov 29, 2022
    Copy the full SHA
    9623b34 View commit details
    Browse the repository at this point in the history
  3. Copy the full SHA
    a21447b View commit details
    Browse the repository at this point in the history