Skip to content

Commit

Permalink
website: Create concept-specific configuration validation pages (#501)
Browse files Browse the repository at this point in the history
In an effort to show provider developers the per-concept functionality, dedicated pages have been created.

This also moves the current providers page as an index of a new Providers subsection of the navigation, which will likely contain other pages.

Lastly, this adjusts the navigation wording of resource pages for active voice consistency.
  • Loading branch information
bflad committed Sep 30, 2022
1 parent 254863a commit 5e9e49f
Show file tree
Hide file tree
Showing 8 changed files with 275 additions and 100 deletions.
29 changes: 23 additions & 6 deletions website/data/plugin-framework-nav-data.json
Expand Up @@ -16,7 +16,16 @@
},
{
"title": "Providers",
"path": "providers"
"routes": [
{
"title": "Overview",
"path": "providers"
},
{
"title": "Validate Configuration",
"path": "providers/validate-configuration"
}
]
},
{
"title": "Resources",
Expand All @@ -30,19 +39,23 @@
"path": "resources/configure"
},
{
"title": "Import",
"path": "resources/import"
"title": "Validate Configuration",
"path": "resources/validate-configuration"
},
{
"title": "Plan Modification",
"title": "Modify Plan",
"path": "resources/plan-modification"
},
{
"title": "State Upgrade",
"title": "Import State",
"path": "resources/import"
},
{
"title": "Upgrade State",
"path": "resources/state-upgrade"
},
{
"title": "Private State Management",
"title": "Manage Private State",
"path": "resources/private-state"
},
{
Expand All @@ -62,6 +75,10 @@
"title": "Configure Clients",
"path": "data-sources/configure"
},
{
"title": "Validate Configuration",
"path": "data-sources/validate-configuration"
},
{
"title": "Timeouts",
"path": "data-sources/timeouts"
Expand Down
2 changes: 1 addition & 1 deletion website/docs/plugin/framework/data-sources/index.mdx
Expand Up @@ -14,7 +14,7 @@ description: >-
This page describes the basic implementation details required for supporting a data source within the provider. Further documentation is available for deeper data source concepts:

- [Configure](/plugin/framework/data-sources/configure) data sources with provider-level data types or clients.
- [Validate](/plugin/framework/validation) practitioner configuration against acceptable values.
- [Validate](/plugin/framework/data-sources/validate-configuration) practitioner configuration against acceptable values.
- [Timeouts](/plugin/framework/data-sources/timeouts) in practitioner configuration for use in a data source read function.

## Define Data Source Type
Expand Down
@@ -0,0 +1,81 @@
---
page_title: 'Plugin Development - Framework: Validate Data Source Configurations'
description: >-
How to validate data source configurations with the provider development framework.
---

# Validate Configuration

-> Note: The Plugin Framework is in beta.

[Data sources](/plugin/framework/data-sources) support validating an entire practitioner configuration in either declarative or imperative logic. Feedback, such as required syntax or acceptable combinations of values, is returned via [diagnostics](/plugin/framework/diagnostics).

This page describes implementation details for validating entire data source configurations, typically referencing multiple attributes. Further documentation is available for other configuration validation concepts:

- [Single attribute validation](/plugin/framework/validation#attribute-validation) is a schema-based mechanism for implementing attribute-specific validation logic.
- [Type validation](/plugin/framework/validation#type-validation) is a schema-based mechanism for implementing reusable validation logic for any attribute using the type.

## ConfigValidators Method

The [`datasource.DataSourceWithConfigValidators` interface](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/datasource#DataSourceWithConfigValidators) follows a similar pattern to attribute validation and allows for a more declarative approach. This enables consistent validation logic across multiple data sources. Each validator intended for this interface must implement the [`datasource.ConfigValidator` interface](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/datasource#ConfigValidator).

The [`terraform-plugin-framework-validators` Go module](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators) has a collection of common use case data source configuration validators in the [`datasourcevalidator` package](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/datasourcevalidator). These use [path expressions](/plugin/framework/path-expressions) for matching attributes.

This example will raise an error if a practitioner attempts to configure both `attribute_one` and `attribute_two`:

```go
// Other methods to implement the datasource.DataSource interface are omitted for brevity
type ThingDataSource struct {}

func (d ThingDataSource) ConfigValidators(ctx context.Context) []datasource.ConfigValidator {
return []datasource.ConfigValidator{
datasourcevalidator.Conflicting(
path.MatchRoot("attribute_one"),
path.MatchRoot("attribute_two"),
),
}
}
```

## ValidateConfig Method

The [`datasource.DataSourceWithValidateConfig` interface](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/datasource#DataSourceWithValidateConfig) is more imperative in design and is useful for validating unique functionality across multiple attributes that typically applies to a single data source.

This example will raise a warning if a practitioner attempts to configure `attribute_one`, but not `attribute_two`:

```go
// Other methods to implement the datasource.DataSource interface are omitted for brevity
type ThingDataSource struct {}

type ThingDataSourceModel struct {
AttributeOne types.String `tfsdk:"attribute_one"`
AttributeTwo types.String `tfsdk:"attribute_two"`
}

func (d ThingDataSource) ValidateConfig(ctx context.Context, req datasource.ValidateConfigRequest, resp *datasource.ValidateConfigResponse) {
var data ThingDataSourceModel

resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)

if resp.Diagnostics.HasError() {
return
}

// If attribute_one is not configured, return without warning.
if data.AttributeOne.IsNull() || data.AttributeOne.IsUnknown() {
return
}

// If attribute_two is not null, return without warning.
if !data.AttributeTwo.IsNull() {
return
}

resp.Diagnostics.AddAttributeWarning(
path.Root("attribute_two"),
"Missing Attribute Configuration",
"Expected attribute_two to be configured with attribute_one. "+
"The data source may return unexpected results.",
)
}
```
Expand Up @@ -16,7 +16,7 @@ This page describes the basic implementation details required for defining a pro

- [Configure data sources](/plugin/framework/data-sources/configure) with provider-level data types or clients.
- [Configure resources](/plugin/framework/resources/configure) with provider-level data types or clients.
- [Validate](/plugin/framework/validation) practitioner configuration against acceptable values.
- [Validate](/plugin/framework/providers/validate-configuration) practitioner configuration against acceptable values.

## Define Provider Type

Expand Down
81 changes: 81 additions & 0 deletions website/docs/plugin/framework/providers/validate-configuration.mdx
@@ -0,0 +1,81 @@
---
page_title: 'Plugin Development - Framework: Validate Provider Configurations'
description: >-
How to validate provider configurations with the provider development framework.
---

# Validate Configuration

-> Note: The Plugin Framework is in beta.

[Providers](/plugin/framework/providers) support validating an entire practitioner configuration in either declarative or imperative logic. Feedback, such as required syntax or acceptable combinations of values, is returned via [diagnostics](/plugin/framework/diagnostics).

This page describes implementation details for validating entire provider configurations, typically referencing multiple attributes. Further documentation is available for other configuration validation concepts:

- [Single attribute validation](/plugin/framework/validation#attribute-validation) is a schema-based mechanism for implementing attribute-specific validation logic.
- [Type validation](/plugin/framework/validation#type-validation) is a schema-based mechanism for implementing reusable validation logic for any attribute using the type.

## ConfigValidators Method

The [`provider.ProviderWithConfigValidators` interface](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/provider#ProviderWithConfigValidators) follows a similar pattern to attribute validation and allows for a more declarative approach. This enables consistent validation logic across multiple providers. Each validator intended for this interface must implement the [`provider.ConfigValidator` interface](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/provider#ConfigValidator).

The [`terraform-plugin-framework-validators` Go module](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators) has a collection of common use case provider configuration validators in the [`providervalidator` package](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/providervalidator). These use [path expressions](/plugin/framework/path-expressions) for matching attributes.

This example will raise an error if a practitioner attempts to configure both `attribute_one` and `attribute_two`:

```go
// Other methods to implement the provider.Provider interface are omitted for brevity
type ExampleCloudProvider struct {}

func (p ExampleCloudProvider) ConfigValidators(ctx context.Context) []provider.ConfigValidator {
return []provider.ConfigValidator{
providervalidator.Conflicting(
path.MatchRoot("attribute_one"),
path.MatchRoot("attribute_two"),
),
}
}
```

## ValidateConfig Method

The [`provider.ProviderWithValidateConfig` interface](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/provider#ProviderWithValidateConfig) is more imperative in design and is useful for validating unique functionality across multiple attributes that typically applies to a single provider.

This example will raise a warning if a practitioner attempts to configure `attribute_one`, but not `attribute_two`:

```go
// Other methods to implement the provider.Provider interface are omitted for brevity
type ExampleCloudProvider struct {}

type ExampleCloudProviderModel struct {
AttributeOne types.String `tfsdk:"attribute_one"`
AttributeTwo types.String `tfsdk:"attribute_two"`
}

func (p ExampleCloudProvider) ValidateConfig(ctx context.Context, req provider.ValidateConfigRequest, resp *provider.ValidateConfigResponse) {
var data ExampleCloudProviderModel

resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)

if resp.Diagnostics.HasError() {
return
}

// If attribute_one is not configured, return without warning.
if data.AttributeOne.IsNull() || data.AttributeOne.IsUnknown() {
return
}

// If attribute_two is not null, return without warning.
if !data.AttributeTwo.IsNull() {
return
}

resp.Diagnostics.AddAttributeWarning(
path.Root("attribute_two"),
"Missing Attribute Configuration",
"Expected attribute_two to be configured with attribute_one. "+
"The provider may return unexpected results.",
)
}
```
2 changes: 1 addition & 1 deletion website/docs/plugin/framework/resources/index.mdx
Expand Up @@ -22,7 +22,7 @@ This page describes the basic implementation details required for supporting a r
- [Manage private state](/plugin/framework/resources/private-state) to store additional data in resource state that is not shown in plans.
- [Modify plans](/plugin/framework/resources/plan-modification) to enrich the output for expected resource behaviors during changes, such as including default values for missing configurations or marking a resource for replacement if an in-place update cannot occur.
- [Upgrade state](/plugin/framework/resources/state-upgrade) to transparently update state data outside plans.
- [Validate](/plugin/framework/validation) practitioner configuration against acceptable values.
- [Validate](/plugin/framework/resources/validate-configuration) practitioner configuration against acceptable values.
- [Timeouts](/plugin/framework/resources/timeouts) in practitioner configuration for use in resource create, read, update and delete functions.

## Define Resource Type
Expand Down
81 changes: 81 additions & 0 deletions website/docs/plugin/framework/resources/validate-configuration.mdx
@@ -0,0 +1,81 @@
---
page_title: 'Plugin Development - Framework: Validate Resource Configurations'
description: >-
How to validate resource configurations with the provider development framework.
---

# Validate Configuration

-> Note: The Plugin Framework is in beta.

[Resources](/plugin/framework/resources) support validating an entire practitioner configuration in either declarative or imperative logic. Feedback, such as required syntax or acceptable combinations of values, is returned via [diagnostics](/plugin/framework/diagnostics).

This page describes implementation details for validating entire resource configurations, typically referencing multiple attributes. Further documentation is available for other configuration validation concepts:

- [Single attribute validation](/plugin/framework/validation#attribute-validation) is a schema-based mechanism for implementing attribute-specific validation logic.
- [Type validation](/plugin/framework/validation#type-validation) is a schema-based mechanism for implementing reusable validation logic for any attribute using the type.

## ConfigValidators Method

The [`resource.ResourceWithConfigValidators` interface](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#ResourceWithConfigValidators) follows a similar pattern to attribute validation and allows for a more declarative approach. This enables consistent validation logic across multiple resources. Each validator intended for this interface must implement the [`resource.ConfigValidator` interface](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#ConfigValidator).

The [`terraform-plugin-framework-validators` Go module](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators) has a collection of common use case resource configuration validators in the [`resourcevalidator` package](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/resourcevalidator). These use [path expressions](/plugin/framework/path-expressions) for matching attributes.

This example will raise an error if a practitioner attempts to configure both `attribute_one` and `attribute_two`:

```go
// Other methods to implement the resource.Resource interface are omitted for brevity
type ThingResource struct {}

func (r ThingResource) ConfigValidators(ctx context.Context) []resource.ConfigValidator {
return []resource.ConfigValidator{
resourcevalidator.Conflicting(
path.MatchRoot("attribute_one"),
path.MatchRoot("attribute_two"),
),
}
}
```

## ValidateConfig Method

The [`resource.ResourceWithValidateConfig` interface](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#ResourceWithValidateConfig) is more imperative in design and is useful for validating unique functionality across multiple attributes that typically applies to a single resource.

This example will raise a warning if a practitioner attempts to configure `attribute_one`, but not `attribute_two`:

```go
// Other methods to implement the resource.Resource interface are omitted for brevity
type ThingResource struct {}

type ThingResourceModel struct {
AttributeOne types.String `tfsdk:"attribute_one"`
AttributeTwo types.String `tfsdk:"attribute_two"`
}

func (r ThingResource) ValidateConfig(ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse) {
var data ThingResourceModel

resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)

if resp.Diagnostics.HasError() {
return
}

// If attribute_one is not configured, return without warning.
if data.AttributeOne.IsNull() || data.AttributeOne.IsUnknown() {
return
}

// If attribute_two is not null, return without warning.
if !data.AttributeTwo.IsNull() {
return
}

resp.Diagnostics.AddAttributeWarning(
path.Root("attribute_two"),
"Missing Attribute Configuration",
"Expected attribute_two to be configured with attribute_one. "+
"The resource may return unexpected results.",
)
}
```

0 comments on commit 5e9e49f

Please sign in to comment.