Skip to content

Commit

Permalink
website: Migration guide updates for provider.DataSourceType and prov…
Browse files Browse the repository at this point in the history
…ider.ResourceType deprecation

Reference: #472
  • Loading branch information
bflad committed Sep 9, 2022
1 parent 8ce2dcd commit e28870e
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 122 deletions.
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.
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
}
}
```

0 comments on commit e28870e

Please sign in to comment.