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

tfsdk: Migrate data source, provider, and resource types into new Go packages #432

Merged
merged 3 commits into from Aug 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
27 changes: 27 additions & 0 deletions .changelog/432.txt
@@ -0,0 +1,27 @@
```release-note:feature
datasource: New package, which colocates all data source implementation types from the `tfsdk` package
```

```release-note:feature
provider: New package, which colocates all provider implementation types from the `tfsdk` package
```

```release-note:feature
resource: New package, which colocates all resource implementation types from the `tfsdk` package
```

```release-note:breaking-change
tfsdk: Go types relating to data source handling have been migrated to the new `datasource` package. Consult the pull request description for a full listing of find-and-replace information.
```

```release-note:breaking-change
tfsdk: Go types relating to provider handling have been migrated to the new `provider` package. Consult the pull request description for a full listing of find-and-replace information.
```

```release-note:breaking-change
tfsdk: Go types relating to resource handling have been migrated to the new `resource` package. Consult the pull request description for a full listing of find-and-replace information.
```

```release-note:breaking-change
tfsdk: The `ResourceImportStatePassthroughID()` function has been moved to `resource.ImportStatePassthroughID()`.
```
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -30,7 +30,7 @@ Currently, that means Go **1.17** or later must be used when including this proj

Documentation for terraform-plugin-framework is still in development. In the meantime, the [GoDoc](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework) is the best source of documentation.

The [`tfsdk.Provider`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/tfsdk#Provider) type is the root of your provider implementation. From there, [`tfsdk.ResourceType`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/tfsdk#ResourceType) and [`tfsdk.DataSourceType`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/tfsdk#DataSourceType) implementations define the [schema](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/schema#Schema) of your resources and data sources, and how to create [`tfsdk.Resource`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/tfsdk#Resource) and [`tfsdk.DataSource`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/tfsdk#DataSource) implementations that talk to the API.
The [`provider.Provider`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/provider#Provider) type is the root of your provider implementation. From there, [`provider.ResourceType`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/provider#ResourceType) and [`provider.DataSourceType`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/provider#DataSourceType) implementations define the [schema](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/tfsdk#Schema) of your resources and data sources, and how to create [`resource.Resource`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#Resource) and [`datasource.DataSource`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/datasource#DataSource) implementations that talk to the API.

## Contributing

Expand Down
25 changes: 25 additions & 0 deletions datasource/config_validator.go
@@ -0,0 +1,25 @@
package datasource

import "context"

// ConfigValidator describes reusable data source configuration validation functionality.
type ConfigValidator interface {
// Description describes the validation in plain text formatting.
//
// This information may be automatically added to data source plain text
// descriptions by external tooling.
Description(context.Context) string

// MarkdownDescription describes the validation in Markdown formatting.
//
// This information may be automatically added to data source Markdown
// descriptions by external tooling.
MarkdownDescription(context.Context) string

// ValidateDataSource performs the validation.
//
// This method name is separate from the provider.ConfigValidator
// interface ValidateProvider method name and resource.ConfigValidator
// interface ValidateResource method name to allow generic validators.
ValidateDataSource(context.Context, ValidateConfigRequest, *ValidateConfigResponse)
}
43 changes: 43 additions & 0 deletions datasource/data_source.go
@@ -0,0 +1,43 @@
package datasource

import "context"

// DataSource represents a data source instance. This is the core interface that
// all data sources must implement.
type DataSource interface {
// Read is called when the provider must read data source values in
// order to update state. Config values should be read from the
// ReadRequest and new state values set on the ReadResponse.
Read(context.Context, ReadRequest, *ReadResponse)
}

// DataSourceWithConfigValidators is an interface type that extends DataSource to include declarative validations.
//
// Declaring validation using this methodology simplifies implmentation of
// reusable functionality. These also include descriptions, which can be used
// for automating documentation.
//
// Validation will include ConfigValidators and ValidateConfig, if both are
// implemented, in addition to any Attribute or Type validation.
type DataSourceWithConfigValidators interface {
DataSource

// ConfigValidators returns a list of ConfigValidators. Each ConfigValidator's Validate method will be called when validating the data source.
ConfigValidators(context.Context) []ConfigValidator
}

// DataSourceWithValidateConfig is an interface type that extends DataSource to include imperative validation.
//
// Declaring validation using this methodology simplifies one-off
// functionality that typically applies to a single data source. Any
// documentation of this functionality must be manually added into schema
// descriptions.
//
// Validation will include ConfigValidators and ValidateConfig, if both are
// implemented, in addition to any Attribute or Type validation.
type DataSourceWithValidateConfig interface {
DataSource

// ValidateConfig performs the validation.
ValidateConfig(context.Context, ValidateConfigRequest, *ValidateConfigResponse)
}
3 changes: 3 additions & 0 deletions datasource/doc.go
@@ -0,0 +1,3 @@
// Package datasource contains all interfaces, request types, and response
// types for a data source implementation.
package datasource
37 changes: 37 additions & 0 deletions datasource/read.go
@@ -0,0 +1,37 @@
package datasource

import (
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
)

// ReadRequest represents a request for the provider to read a data
// source, i.e., update values in state according to the real state of the
// data source. An instance of this request struct is supplied as an argument
// to the data source's Read function.
type ReadRequest struct {
// Config is the configuration the user supplied for the data source.
//
// This configuration may contain unknown values if a user uses
// interpolation or other functionality that would prevent Terraform
// from knowing the value at request time.
Config tfsdk.Config

// ProviderMeta is metadata from the provider_meta block of the module.
ProviderMeta tfsdk.Config
}

// ReadResponse represents a response to a ReadRequest. An
// instance of this response struct is supplied as an argument to the data
// source's Read function, in which the provider should set values on the
// ReadResponse as appropriate.
type ReadResponse struct {
// State is the state of the data source following the Read operation.
// This field should be set during the resource's Read operation.
State tfsdk.State

// Diagnostics report errors or warnings related to reading the data
// source. An empty slice indicates a successful operation with no
// warnings or errors generated.
Diagnostics diag.Diagnostics
}
30 changes: 30 additions & 0 deletions datasource/validate_config.go
@@ -0,0 +1,30 @@
package datasource

import (
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
)

// ValidateConfigRequest represents a request to validate the
// configuration of a data source. An instance of this request struct is
// supplied as an argument to the DataSource ValidateConfig receiver method
// or automatically passed through to each ConfigValidator.
type ValidateConfigRequest struct {
// Config is the configuration the user supplied for the data source.
//
// This configuration may contain unknown values if a user uses
// interpolation or other functionality that would prevent Terraform
// from knowing the value at request time.
Config tfsdk.Config
}

// ValidateConfigResponse represents a response to a
// ValidateConfigRequest. An instance of this response struct is
// supplied as an argument to the DataSource ValidateConfig receiver method
// or automatically passed through to each ConfigValidator.
type ValidateConfigResponse struct {
// Diagnostics report errors or warnings related to validating the data
// source configuration. An empty slice indicates success, with no warnings
// or errors generated.
Diagnostics diag.Diagnostics
}
3 changes: 2 additions & 1 deletion internal/fromproto5/applyresourcechange.go
Expand Up @@ -5,13 +5,14 @@ import (

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
)

// ApplyResourceChangeRequest returns the *fwserver.ApplyResourceChangeRequest
// equivalent of a *tfprotov5.ApplyResourceChangeRequest.
func ApplyResourceChangeRequest(ctx context.Context, proto5 *tfprotov5.ApplyResourceChangeRequest, resourceType tfsdk.ResourceType, resourceSchema *tfsdk.Schema, providerMetaSchema *tfsdk.Schema) (*fwserver.ApplyResourceChangeRequest, diag.Diagnostics) {
func ApplyResourceChangeRequest(ctx context.Context, proto5 *tfprotov5.ApplyResourceChangeRequest, resourceType provider.ResourceType, resourceSchema *tfsdk.Schema, providerMetaSchema *tfsdk.Schema) (*fwserver.ApplyResourceChangeRequest, diag.Diagnostics) {
if proto5 == nil {
return nil, nil
}
Expand Down
3 changes: 2 additions & 1 deletion internal/fromproto5/applyresourcechange_test.go
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fromproto5"
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
Expand Down Expand Up @@ -45,7 +46,7 @@ func TestApplyResourceChangeRequest(t *testing.T) {
testCases := map[string]struct {
input *tfprotov5.ApplyResourceChangeRequest
resourceSchema *tfsdk.Schema
resourceType tfsdk.ResourceType
resourceType provider.ResourceType
providerMetaSchema *tfsdk.Schema
expected *fwserver.ApplyResourceChangeRequest
expectedDiagnostics diag.Diagnostics
Expand Down
5 changes: 3 additions & 2 deletions internal/fromproto5/configureprovider.go
Expand Up @@ -4,18 +4,19 @@ import (
"context"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
)

// ConfigureProviderRequest returns the *fwserver.ConfigureProviderRequest
// equivalent of a *tfprotov5.ConfigureProviderRequest.
func ConfigureProviderRequest(ctx context.Context, proto5 *tfprotov5.ConfigureProviderRequest, providerSchema *tfsdk.Schema) (*tfsdk.ConfigureProviderRequest, diag.Diagnostics) {
func ConfigureProviderRequest(ctx context.Context, proto5 *tfprotov5.ConfigureProviderRequest, providerSchema *tfsdk.Schema) (*provider.ConfigureRequest, diag.Diagnostics) {
if proto5 == nil {
return nil, nil
}

fw := &tfsdk.ConfigureProviderRequest{
fw := &provider.ConfigureRequest{
TerraformVersion: proto5.TerraformVersion,
}

Expand Down
11 changes: 6 additions & 5 deletions internal/fromproto5/configureprovider_test.go
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fromproto5"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
Expand Down Expand Up @@ -44,7 +45,7 @@ func TestConfigureProviderRequest(t *testing.T) {
testCases := map[string]struct {
input *tfprotov5.ConfigureProviderRequest
providerSchema *tfsdk.Schema
expected *tfsdk.ConfigureProviderRequest
expected *provider.ConfigureRequest
expectedDiagnostics diag.Diagnostics
}{
"nil": {
Expand All @@ -53,13 +54,13 @@ func TestConfigureProviderRequest(t *testing.T) {
},
"empty": {
input: &tfprotov5.ConfigureProviderRequest{},
expected: &tfsdk.ConfigureProviderRequest{},
expected: &provider.ConfigureRequest{},
},
"config-missing-schema": {
input: &tfprotov5.ConfigureProviderRequest{
Config: &testProto5DynamicValue,
},
expected: &tfsdk.ConfigureProviderRequest{},
expected: &provider.ConfigureRequest{},
expectedDiagnostics: diag.Diagnostics{
diag.NewErrorDiagnostic(
"Unable to Convert Configuration",
Expand All @@ -75,7 +76,7 @@ func TestConfigureProviderRequest(t *testing.T) {
Config: &testProto5DynamicValue,
},
providerSchema: testFwSchema,
expected: &tfsdk.ConfigureProviderRequest{
expected: &provider.ConfigureRequest{
Config: tfsdk.Config{
Raw: testProto5Value,
Schema: *testFwSchema,
Expand All @@ -86,7 +87,7 @@ func TestConfigureProviderRequest(t *testing.T) {
input: &tfprotov5.ConfigureProviderRequest{
TerraformVersion: "99.99.99",
},
expected: &tfsdk.ConfigureProviderRequest{
expected: &provider.ConfigureRequest{
TerraformVersion: "99.99.99",
},
},
Expand Down
3 changes: 2 additions & 1 deletion internal/fromproto5/importresourcestate.go
Expand Up @@ -5,14 +5,15 @@ import (

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
"github.com/hashicorp/terraform-plugin-go/tftypes"
)

// ImportResourceStateRequest returns the *fwserver.ImportResourceStateRequest
// equivalent of a *tfprotov5.ImportResourceStateRequest.
func ImportResourceStateRequest(ctx context.Context, proto5 *tfprotov5.ImportResourceStateRequest, resourceType tfsdk.ResourceType, resourceSchema *tfsdk.Schema) (*fwserver.ImportResourceStateRequest, diag.Diagnostics) {
func ImportResourceStateRequest(ctx context.Context, proto5 *tfprotov5.ImportResourceStateRequest, resourceType provider.ResourceType, resourceSchema *tfsdk.Schema) (*fwserver.ImportResourceStateRequest, diag.Diagnostics) {
if proto5 == nil {
return nil, nil
}
Expand Down
3 changes: 2 additions & 1 deletion internal/fromproto5/importresourcestate_test.go
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fromproto5"
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
Expand All @@ -34,7 +35,7 @@ func TestImportResourceStateRequest(t *testing.T) {
testCases := map[string]struct {
input *tfprotov5.ImportResourceStateRequest
resourceSchema *tfsdk.Schema
resourceType tfsdk.ResourceType
resourceType provider.ResourceType
expected *fwserver.ImportResourceStateRequest
expectedDiagnostics diag.Diagnostics
}{
Expand Down
3 changes: 2 additions & 1 deletion internal/fromproto5/planresourcechange.go
Expand Up @@ -5,13 +5,14 @@ import (

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
)

// PlanResourceChangeRequest returns the *fwserver.PlanResourceChangeRequest
// equivalent of a *tfprotov5.PlanResourceChangeRequest.
func PlanResourceChangeRequest(ctx context.Context, proto5 *tfprotov5.PlanResourceChangeRequest, resourceType tfsdk.ResourceType, resourceSchema *tfsdk.Schema, providerMetaSchema *tfsdk.Schema) (*fwserver.PlanResourceChangeRequest, diag.Diagnostics) {
func PlanResourceChangeRequest(ctx context.Context, proto5 *tfprotov5.PlanResourceChangeRequest, resourceType provider.ResourceType, resourceSchema *tfsdk.Schema, providerMetaSchema *tfsdk.Schema) (*fwserver.PlanResourceChangeRequest, diag.Diagnostics) {
if proto5 == nil {
return nil, nil
}
Expand Down
3 changes: 2 additions & 1 deletion internal/fromproto5/planresourcechange_test.go
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fromproto5"
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
Expand Down Expand Up @@ -45,7 +46,7 @@ func TestPlanResourceChangeRequest(t *testing.T) {
testCases := map[string]struct {
input *tfprotov5.PlanResourceChangeRequest
resourceSchema *tfsdk.Schema
resourceType tfsdk.ResourceType
resourceType provider.ResourceType
providerMetaSchema *tfsdk.Schema
expected *fwserver.PlanResourceChangeRequest
expectedDiagnostics diag.Diagnostics
Expand Down
3 changes: 2 additions & 1 deletion internal/fromproto5/readdatasource.go
Expand Up @@ -5,13 +5,14 @@ import (

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
)

// ReadDataSourceRequest returns the *fwserver.ReadDataSourceRequest
// equivalent of a *tfprotov5.ReadDataSourceRequest.
func ReadDataSourceRequest(ctx context.Context, proto5 *tfprotov5.ReadDataSourceRequest, dataSourceType tfsdk.DataSourceType, dataSourceSchema *tfsdk.Schema, providerMetaSchema *tfsdk.Schema) (*fwserver.ReadDataSourceRequest, diag.Diagnostics) {
func ReadDataSourceRequest(ctx context.Context, proto5 *tfprotov5.ReadDataSourceRequest, dataSourceType provider.DataSourceType, dataSourceSchema *tfsdk.Schema, providerMetaSchema *tfsdk.Schema) (*fwserver.ReadDataSourceRequest, diag.Diagnostics) {
if proto5 == nil {
return nil, nil
}
Expand Down
3 changes: 2 additions & 1 deletion internal/fromproto5/readdatasource_test.go
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fromproto5"
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
Expand Down Expand Up @@ -45,7 +46,7 @@ func TestReadDataSourceRequest(t *testing.T) {
testCases := map[string]struct {
input *tfprotov5.ReadDataSourceRequest
dataSourceSchema *tfsdk.Schema
dataSourceType tfsdk.DataSourceType
dataSourceType provider.DataSourceType
providerMetaSchema *tfsdk.Schema
expected *fwserver.ReadDataSourceRequest
expectedDiagnostics diag.Diagnostics
Expand Down