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

website: Migration guide updates for provider.DataSourceType and provider.ResourceType deprecation #473

Merged
merged 4 commits into from Sep 13, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -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{
Expand Down Expand Up @@ -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": {
Expand Down
Expand Up @@ -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{
Expand Down Expand Up @@ -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": {
Expand Down
Expand Up @@ -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{
Expand Down Expand Up @@ -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": {
Expand Down Expand Up @@ -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": {
Expand Down
Expand Up @@ -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": {
Expand Down
69 changes: 36 additions & 33 deletions website/docs/plugin/framework/migrating/data-sources/index.mdx
Expand Up @@ -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.
bflad marked this conversation as resolved.
Show resolved Hide resolved

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

Expand Down Expand Up @@ -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": {
Expand All @@ -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) {
/* ... */
}
```
56 changes: 32 additions & 24 deletions website/docs/plugin/framework/migrating/providers/index.mdx
Expand Up @@ -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.
Expand All @@ -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{},
},
}
}
```

Expand All @@ -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

Expand Down Expand Up @@ -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) {
Expand Down
30 changes: 6 additions & 24 deletions website/docs/plugin/framework/migrating/resources/crud.mdx
Expand Up @@ -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`.

Expand Down Expand Up @@ -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
}
}
```