diff --git a/website/docs/plugin/framework/migrating/attributes-blocks/default-values.mdx b/website/docs/plugin/framework/migrating/attributes-blocks/default-values.mdx index 7ac65760a..53baf431f 100644 --- a/website/docs/plugin/framework/migrating/attributes-blocks/default-values.mdx +++ b/website/docs/plugin/framework/migrating/attributes-blocks/default-values.mdx @@ -41,7 +41,7 @@ In the Framework, you set default values with the `PlanModifiers` field on your struct. ```go -func (d *resourceTypeExample) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { +func (r *resourceExample) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { return tfsdk.Schema{ /* ... */ Attributes: map[string]tfsdk.Attribute{ @@ -91,7 +91,7 @@ The following shows the same section of code after the migration. This code implements the `PlanModifiers` field for the `rsa_bits` attribute with the Framework. ```go -func (rt *privateKeyResourceType) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { +func (r *privateKeyResource) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { return tfsdk.Schema{ Attributes: map[string]tfsdk.Attribute{ "rsa_bits": { diff --git a/website/docs/plugin/framework/migrating/attributes-blocks/force-new.mdx b/website/docs/plugin/framework/migrating/attributes-blocks/force-new.mdx index 3e4f0ed78..9968d51a9 100644 --- a/website/docs/plugin/framework/migrating/attributes-blocks/force-new.mdx +++ b/website/docs/plugin/framework/migrating/attributes-blocks/force-new.mdx @@ -35,7 +35,7 @@ In the Framework, you implement the same behavior by using the `resource.Require attribute's `tfsdk.Attribute` struct. ```go -func (d *resourceTypeExample) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { +func (r *resourceExample) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { return tfsdk.Schema{ /* ... */ Attributes: map[string]tfsdk.Attribute{ @@ -94,7 +94,7 @@ This code forces the replacement of a `random_password` resource when the value The example does this using the `PlanModifiers` field within the `random_password` attribute's schema. ```go -func (r *passwordResourceType) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { +func (r *passwordResource) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { return tfsdk.Schema{ Attributes: map[string]tfsdk.Attribute{ "keepers": { diff --git a/website/docs/plugin/framework/migrating/attributes-blocks/types.mdx b/website/docs/plugin/framework/migrating/attributes-blocks/types.mdx index e3139ba09..acf53d7d8 100644 --- a/website/docs/plugin/framework/migrating/attributes-blocks/types.mdx +++ b/website/docs/plugin/framework/migrating/attributes-blocks/types.mdx @@ -68,7 +68,7 @@ func resourceExample() *schema.Resource { In the Framework, you set your attribute's type with the `Type` field on your attribute's `tfsdk.Attribute` struct. ```go -func (d *resourceTypeExample) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { +func (r *resourceExample) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { return tfsdk.Schema{ /* ... */ Attributes: map[string]tfsdk.Attribute{ @@ -146,7 +146,7 @@ The following example from the `data_source_http.go` file shows how the type of source is defined with the Framework after the migration. ```go -func (d *httpDataSourceType) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { +func (d *httpDataSource) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { return tfsdk.Schema{ Attributes: map[string]tfsdk.Attribute{ "url": { @@ -190,7 +190,7 @@ The following example from the `data_source_http.go` file shows how the type of source is defined with the Framework after the migration. ```go -func (rt *certRequestResourceType) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { +func (r *certRequestResource) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { return tfsdk.Schema{ Attributes: map[string]tfsdk.Attribute{ "dns_names": { diff --git a/website/docs/plugin/framework/migrating/attributes-blocks/validators-custom.mdx b/website/docs/plugin/framework/migrating/attributes-blocks/validators-custom.mdx index 2b59ecc3f..9b6718087 100644 --- a/website/docs/plugin/framework/migrating/attributes-blocks/validators-custom.mdx +++ b/website/docs/plugin/framework/migrating/attributes-blocks/validators-custom.mdx @@ -94,7 +94,7 @@ This code validates that the `random_password`'s `length` attribute is greater t validator. ```go -func (r *passwordResourceType) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { +func (r *passwordResource) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { return tfsdk.Schema{ Attributes: map[string]tfsdk.Attribute{ "length": { diff --git a/website/docs/plugin/framework/migrating/data-sources/index.mdx b/website/docs/plugin/framework/migrating/data-sources/index.mdx index ae8ceb55e..399752ec2 100644 --- a/website/docs/plugin/framework/migrating/data-sources/index.mdx +++ b/website/docs/plugin/framework/migrating/data-sources/index.mdx @@ -45,48 +45,49 @@ schema.Resource { ## Framework -In the Framework, you define data sources by adding them to the map returned by your provider's `GetDataSources` function. +In the Framework, you define data sources by adding them to the map returned by your provider's `DataSources` method. -The `GetDataSources` function on your `provider.Provider` returns a map from the data source name (string) to a type -that implements the `DataSourceType` interface for each data source your provider supports. +The `DataSources` method on your `provider.Provider` returns a slice of functions that return types +that implement the `datasource.DataSource` interface for each data source your provider supports. The following code shows how you add a data source to your provider with the Framework. ```go -func (p *provider) GetDataSources(ctx context.Context) (map[string]provider.DataSourceType, diag.Diagnostics) { - return map[string]provider.DataSourceType{ +func (p *provider) DataSources(ctx context.Context) []func() datasource.DataSource { + return []func() datasource.DataSource{ /* ... */ - }, nil + } } ``` -Like the `provider.ResourceType` interface, `provider.DataSourceType` requires `GetSchema` and `NewResource` functions. -These functions work the same way for data sources as they do for resources. +Like the `resource.Resource` interface, `datasource.DataSource` requires `GetSchema` and `TypeName` methods. +These methods work the same way for data sources as they do for resources. The `Read` method is also required. -The `GetSchema` function returns a `tfsdk.Schema` struct which defines your data source's attributes. This is the same +The `GetSchema` method returns a `tfsdk.Schema` struct which defines your data source's attributes. This is the same struct you use to define provider and resource attributes. -The `NewResource` function returns a type that you define. The type implements the `resource.Resource` interface, -including the CRUD functions for your resource. +The `TypeName` method returns a type name that you define. + +For `Read` method implements the logic for writing into the Terraform state. -The following code shows how you define a `provider.DataSourceType` which implements these two functions with the +The following code shows how you define a `datasource.DataSource` which implements these methods with the Framework. ```go -type dataSourceTypeExample struct{} +type dataSourceExample struct{} -func (r *dataSourceTypeExample) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { +func (d *dataSourceExample) TypeName(ctx context.Context, req datasource.TypeNameRequest, resp *datasource.TypeNameResponse) { /* ... */ } -func (r *dataSourceTypeExample) NewDataSource(ctx context.Context, p provider.Provider) (datasource.DataSource, diag.Diagnostics) { +func (d *dataSourceExample) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { /* ... */ } -``` -Unlike resources, you only need to implement a read function for your data sources. Refer to the -[Resources - CRUD functions](/plugin/framework/migrating/resources/crud) page in this guide to learn how to define this -function on your `datasource.DataSource` type. +func (d *dataSourceExample) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + /* ... */ +} +``` ## Migration Notes @@ -145,18 +146,27 @@ The following example from the `provider.go` file shows how the `http` data sour the migration. ```go -func (p *provider) GetDataSources(context.Context) (map[string]provider.DataSourceType, diag.Diagnostics) { - return map[string]provider.DataSourceType{ - "http": &httpDataSourceType{}, - }, nil +func (p *provider) DataSources(context.Context) []func() datasource.DataSource { + return []func() datasource.DataSource{ + func() datasource.DataSource { + return &httpDataSource{} + }, + } } ``` -This code from the `data_source_http.go` file defines the `GetSchema` function for the `http` data source with the +This code from the `data_source_http.go` file defines the methods for the `http` data source with the Framework. ```go -func (d *httpDataSourceType) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { +func (d *httpDataSource) TypeName(ctx context.Context, req datasource.TypeNameRequest, resp *datasource.TypeNameResponse) { + // This is unconventional in that the data source name matches the provider name. + // Typically these should have the provider name, an underscore, then the type name. + // e.g. http_request + resp.TypeName = "http" +} + +func (d *httpDataSource) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { return tfsdk.Schema{ Attributes: map[string]tfsdk.Attribute{ "url": { @@ -166,14 +176,7 @@ func (d *httpDataSourceType) GetSchema(context.Context) (tfsdk.Schema, diag.Diag }, /* ... */ -func (d *httpDataSourceType) NewDataSource(context.Context, provider.Provider) (datasource.DataSource, diag.Diagnostics) { - return &httpDataSource{}, nil -} -``` - -This code from the `data_source_http.go` file defines the `Read` function for the `http` data source with the Framework. - -```go func (d *httpDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { /* ... */ +} ``` diff --git a/website/docs/plugin/framework/migrating/providers/index.mdx b/website/docs/plugin/framework/migrating/providers/index.mdx index db66b1baa..a356ac68e 100644 --- a/website/docs/plugin/framework/migrating/providers/index.mdx +++ b/website/docs/plugin/framework/migrating/providers/index.mdx @@ -140,9 +140,9 @@ func New() *schema.Provider { In the Framework, the second argument to your `provider.Serve` function requires a function that returns a type satisfying the `provider.Provider` interface. -The following code shows a typical implementation. In this implementation, the `GetResources` function returns a map -from resource names (strings) to types that implement the `provider.ResourceType` interface. The `GetDataSources` -function returns a map from data source names (strings) to types that implement the `provider.DataSourceType` interface. +The following code shows a typical implementation. In this implementation, the `Resources` method returns a slice +of functions that return types that implement the `resource.Resource` interface. The `DataSources` method returns a +slice of functions that return types that implement the `datasource.DataSource` interface. Refer to the [Resources](/plugin/framework/migrating/resources) and [Data Sources](/plugin/framework/migrating/data-sources) pages in this guide to implement these functions for your provider. @@ -162,16 +162,20 @@ func (p *provider) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostic func (p *provider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) { } -func (p *provider) GetResources(ctx context.Context) (map[string]provider.ResourceType, diag.Diagnostics) { - return map[string]provider.ResourceType{ - "resource_example": resourceTypeExample{}, - }, nil +func (p *provider) Resources(ctx context.Context) []func() resource.Resource { + return []func() resource.Resource { + func() resource.Resource { + return resourceExample{}, + }, + } } -func (p *provider) GetDataSources(ctx context.Context) (map[string]provider.DataSourceType, diag.Diagnostics) { - return map[string]provider.DataSourceType{ - "data_source_example": dataSourceTypeExample{}, - }, nil +func (p *provider) GetDataSources(ctx context.Context) []func() datasource.DataSource { + return []func() datasource.DataSource { + func() datasource.DataSource { + return dataSourceExample{}, + }, + } } ``` @@ -187,13 +191,13 @@ names to `schema.Schema` structs. In the Framework, `GetSchema` is a function yo - In SDKv2, `ConfigureContextFunc` is a field on `schema.Provider` containing a function that configures the provider. In the Framework, `Configure` is a function you define on your provider that configures your provider. - In SDKv2, `ResourcesMap` is a field on `schema.Provider` containing `map[string]*schema.Resource`, which maps resource -names to `schema.Resource` structs. In the Framework, `GetResources` is a function you define on your provider that -returns `map[string]provider.ResourceType`, which maps resource names to types that you define, which satisfy the -`provider.ResourceType` interface. +names to `schema.Resource` structs. In the Framework, `Resources` is a method you define on your provider that +returns `[]func() resource.Resource`, which creates resource types that you define, which satisfy the +`resource.Resource` interface. - In SDKv2, `DataSourcesMap` is a field on `schema.Provider` containing `map[string]*schema.Resource`, which maps data source names to `schema.Resource` structs (data sources and resources both use `schema.Resource`). In the Framework, -`GetDataSources` is a function you define on your provider that returns `map[string]provider.DataSourceType`, which -maps data source names to types that you define, which satisfy the `provider.DataSourceType` interface. +`DataSources` is a method you define on your provider that returns `[]func() datasource.DataSource`, which +creates data source types that you define, which satisfy the `datasource.DataSource` interface. ### Example @@ -241,18 +245,22 @@ func New() provider.Provider { return &provider{} } -func (p *provider) GetResources(_ context.Context) (map[string]provider.ResourceType, diag.Diagnostics) { - return map[string]provider.ResourceType{ - "tls_private_key": &privateKeyResourceType{}, +func (p *provider) Resources(_ context.Context) []func() resource.Resource { + return []func() resource.Resource{ + func() resource.Resource { + return &privateKeyResource{} + }, /* ... */ - }, nil + } } -func (p *provider) GetDataSources(_ context.Context) (map[string]provider.DataSourceType, diag.Diagnostics) { - return map[string]provider.DataSourceType{ - "tls_public_key": &publicKeyDataSourceType{}, +func (p *provider) DataSources(_ context.Context) []func() datasource.DataSource { + return []func() datasource.DataSource{ + func() datasource.DataSource { + return &publicKeyDataSource{}, + }, /* ... */ - }, nil + } } func (p *provider) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { diff --git a/website/docs/plugin/framework/migrating/resources/crud.mdx b/website/docs/plugin/framework/migrating/resources/crud.mdx index 83690d5c1..a82458fef 100644 --- a/website/docs/plugin/framework/migrating/resources/crud.mdx +++ b/website/docs/plugin/framework/migrating/resources/crud.mdx @@ -32,8 +32,7 @@ func resourceExample() *schema.Resource { ## Framework In the Framework, you implement CRUD functions for your resource by defining a type that implements the -`resource.Resource` interface. This type is returned by the `NewResource` function on the type implementing the -`provider.ResourceType` interface. To define functions related to state upgrade, import, and plan modification, +`resource.Resource` interface. To define functions related to state upgrade, import, and plan modification, implement their respective interfaces on your resource: `ResourceWithUpgradeState`, `ResourceWithImportState`, and `ResourceWithModifyPlan`. @@ -159,33 +158,16 @@ func (r *passwordResource) Create(ctx context.Context, req resource.CreateReques return } - state := passwordModelV2{ - ID: types.String{Value: "none"}, - Keepers: plan.Keepers, - Length: types.Int64{Value: plan.Length.Value}, - Special: types.Bool{Value: plan.Special.Value}, - Upper: types.Bool{Value: plan.Upper.Value}, - Lower: types.Bool{Value: plan.Lower.Value}, - Numeric: types.Bool{Value: plan.Numeric.Value}, - MinNumeric: types.Int64{Value: plan.MinNumeric.Value}, - MinUpper: types.Int64{Value: plan.MinUpper.Value}, - MinLower: types.Int64{Value: plan.MinLower.Value}, - MinSpecial: types.Int64{Value: plan.MinSpecial.Value}, - OverrideSpecial: types.String{Value: plan.OverrideSpecial.Value}, - Result: types.String{Value: string(result)}, - } - - hash, err := generateHash(plan.Result.Value) + hash, err := generateHash(string(result)) if err != nil { resp.Diagnostics.Append(diagnostics.HashGenerationError(err.Error())...) } - state.BcryptHash = types.String{Value: hash} + plan.BcryptHash = types.String{Value: hash} + plan.ID = types.String{Value: "none"} + plan.Result = types.String{Value: string(result)} - diags = resp.State.Set(ctx, state) + diags = resp.State.Set(ctx, plan) resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } } ``` diff --git a/website/docs/plugin/framework/migrating/resources/index.mdx b/website/docs/plugin/framework/migrating/resources/index.mdx index b3a35e899..a076caf18 100644 --- a/website/docs/plugin/framework/migrating/resources/index.mdx +++ b/website/docs/plugin/framework/migrating/resources/index.mdx @@ -72,41 +72,58 @@ schema.Resource{ ## Framework -In the Framework, you define your provider's resources by adding them to your provider's `GetResources` function. +In the Framework, you define your provider's resources by adding them to your provider's `Resources` method. -The `GetResources` function on your `provider.Provider` returns a map from the resource name (string) to a struct that -implements the `ResourceType` interface for each resource your provider supports. +The `Resources` method on your `provider.Provider` returns a slice of functions that return types that +implement the `resource.Resource` interface for each resource your provider supports. The following code shows how you add a resource to your provider with the Framework. ```go -func (p *provider) GetResources(ctx context.Context) (map[string]provider.ResourceType, diag.Diagnostics) { - return map[string]provider.ResourceType{ - "resource_example": resourceTypeExample{}, - }, nil +func (p *provider) Resources(ctx context.Context) []func() resource.Resource { + return []func() resource.Resource{ + func() resource.Resource { + return resourceTypeExample{} + }, + } } ``` -The `provider.ResourceType` interface requires `GetSchema` and `NewResource` functions. +The `resource.Resource` interface requires `TypeName`, `GetSchema`, `Create`, `Read`, `Update`, and `Delete` methods. -The `GetSchema` function returns a `tfsdk.Schema` struct which defines your resource's attributes. This is the same +The `GetSchema` method returns a `tfsdk.Schema` struct which defines your resource's attributes. This is the same struct you use to define provider and data source attributes. -The `NewResource` function returns a type that you define. The type implements the `resource.Resource` interface, -including the CRUD functions for your resource. +The `TypeName` method returns a type name that you define. -The following code shows how you define a `provider.ResourceType` which implements these two functions with the +The following code shows how you define a `resource.Resource` which implements these methods with the Framework. ```go -type resourceTypeExample struct{} +type resourceExample struct{} + +func (r *resourceExample) TypeName(ctx context.Context, req resource.TypeNameRequest, resp *resource.TypeNameResponse) { + /* ... */ +} -func (r resourceTypeExample) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { - return tfsdk.Schema{}, nil +func (r *resourceExample) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { + /* ... */ } -func (r resourceTypeExample) NewResource(_ context.Context, p provider.Provider) (resource.Resource, diag.Diagnostics) { - return &resourceExample{}, nil +func (r *resourceExample) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + /* ... */ +} + +func (r *resourceExample) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + /* ... */ +} + +func (r *resourceExample) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + /* ... */ +} + +func (r *resourceExample) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + /* ... */ } ``` @@ -125,7 +142,7 @@ type Schema struct { ``` Refer to the [Resources - CRUD functions](/plugin/framework/migrating/resources/crud) page in this guide to learn how to -implement the `resource.Resource` interface returned by your resource type's `NewResource` function. +implement the `resource.Resource` interface. ## Migration Notes @@ -133,9 +150,9 @@ Remember the following differences between SDKv2 and the Framework when completi - SDKv2 uses `schema.Resource` structs to define resources. These structs have a `Schema` field which holds a `schema.Schema` to define the resource's attributes and behavior. In the Framework, you define a type that implements -the `ResourceType` interface, which includes a `GetSchema` function that returns your resource's schema. +the `resource.Resource` interface, which includes a `GetSchema` method that returns your resource's schema. - SDKv2 implements a resource's CRUD operations as functions on the `schema.Resource`. In the Framework, you define a -type that implements the `Resource` interface. The resource interface contains the functions that define your resource's +type that implements the `resource.Resource` interface. The resource interface contains the functions that define your resource's CRUD operations. ## Example @@ -193,16 +210,24 @@ The following shows the same section of provider code after the migration. This code defines the `tls_private_key` resource by mapping the resource name to the `privateKeyResourceType` struct. ```go -func (p *provider) GetResources(_ context.Context) (map[string]provider.ResourceType, diag.Diagnostics) { - return map[string]provider.ResourceType{ - "tls_private_key": &privateKeyResourceType{}, +func (p *provider) Resources(_ context.Context) []func() resource.Resource { + return []func() resource.Resource{ + func() resource.Resource { + return &privateKeyResource{} + }, /* ... */ + } +} ``` -This code defines the `GetSchema` and `NewResource` functions for the `privateKeyResourceType`. +This code defines the `GetSchema` and `TypeName` methods for the `privateKeyResource`. ```go -func (rt *privateKeyResourceType) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { +func (r *privateKeyResource) TypeName(ctx context.Context, req resource.TypeNameRequest, resp *resource.TypeNameResponse) { + resp.TypeName = "tls_private_key" +} + +func (r *privateKeyResource) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { return tfsdk.Schema{ Attributes: map[string]tfsdk.Attribute{ // Required attributes @@ -219,8 +244,7 @@ func (rt *privateKeyResourceType) GetSchema(_ context.Context) (tfsdk.Schema, di fmt.Sprintf("Currently-supported values are: `%s`. ", strings.Join(supportedAlgorithmsStr(), "`, `")), }, /* ... */ - -func (rt *privateKeyResourceType) NewResource(_ context.Context, _ provider.Provider) (resource.Resource, diag.Diagnostics) { - return &privateKeyResource{}, nil + }, + }, nil } ``` diff --git a/website/docs/plugin/framework/migrating/schema/index.mdx b/website/docs/plugin/framework/migrating/schema/index.mdx index afeb1dc89..7154d87af 100644 --- a/website/docs/plugin/framework/migrating/schema/index.mdx +++ b/website/docs/plugin/framework/migrating/schema/index.mdx @@ -96,8 +96,8 @@ type Schema struct { ## Framework -In the Framework, you implement `GetSchema` functions for your provider, resources, and data sources. This function is -required by the `provider.Provider`, `provider.ResourceType`, and `provider.DataSourceType` interfaces, respectively. +In the Framework, you implement `GetSchema` method for your provider, resources, and data sources. This function is +required by the `provider.Provider`, `resource.Resource`, and `datasource.DataSource` interfaces, respectively. The following code shows how you define the `GetSchema` function for your provider, resources, and data sources. @@ -108,13 +108,13 @@ func (p *provider) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostic ``` ```go -func (r resourceTypeExample) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { +func (r *resourceExample) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { return tfsdk.Schema{}, nil } ``` ```go -func (r dataSourceTypeExample) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { +func (r *dataSourceExample) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { return tfsdk.Schema{}, nil } ``` @@ -142,7 +142,7 @@ Remember the following differences between SDKv2 and the Framework when completi - SDKv2 uses `schema.Schema` structs to define the provider, resources, and data sources. The Framework uses `tfsdk.Schema` structs instead. - In SDKv2, schema structs are returned when a provider, resource, or data type is created. In the Framework, the -provider and each resource and data type have a `GetSchema` function that returns the schema. +provider and each resource and data type have a `GetSchema` method that returns the schema. - The `tfsdk.Schema` struct includes fields that you use to define [attributes](/plugin/framework/migrating/attributes-and-blocks/attribute-schema) and [blocks](/plugin/framework/migrating/attributes-and-blocks/blocks) for your provider and each resource