-
Notifications
You must be signed in to change notification settings - Fork 95
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ephemeral: Initial ephemeral resource type implementation (#1050)
* initial ephemeral resource interfaces * add ephemeral resource configure data * attribute implementations * uncomment custom type tests * added block implementations * add nested attribute implementations * add schema test * remove todo * doc updates, renames, removals * initial protov5 + fwserver implementation (protov6 stubbed) * add fromproto5 tests * add toproto5 tests * add proto5server tests * implement protov6 * schema + metadata tests * add close proto5/6 tests * add fwserver tests for schema/metadata * prevent random false positives * validate fwserver tests * open/renew/close fwserver tests * update error message * update plugin go * remove `config` from renew * remove state from renew/close, add deferred action support * update doc comments * add experimental note * add changelogs * initial website documentation * build(deps): Bump github.com/hashicorp/terraform-plugin-go (#1051) Bumps [github.com/hashicorp/terraform-plugin-go](https://github.com/hashicorp/terraform-plugin-go) from 0.24.0 to 0.25.0. - [Release notes](https://github.com/hashicorp/terraform-plugin-go/releases) - [Changelog](https://github.com/hashicorp/terraform-plugin-go/blob/main/CHANGELOG.md) - [Commits](hashicorp/terraform-plugin-go@v0.24.0...v0.25.0) --- updated-dependencies: - dependency-name: github.com/hashicorp/terraform-plugin-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Update website/docs/plugin/framework/ephemeral-resources/renew.mdx Co-authored-by: Selena Goods <selena.goods@hashicorp.com> * Update website/docs/plugin/framework/ephemeral-resources/validate-configuration.mdx Co-authored-by: Selena Goods <selena.goods@hashicorp.com> * adjust package docs ---------
- Loading branch information
1 parent
a2137d3
commit ae74f93
Showing
216 changed files
with
29,854 additions
and
788 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
kind: ENHANCEMENTS | ||
body: 'provider: Added `ProviderWithEphemeralResources` interface for implementing | ||
ephemeral resources' | ||
time: 2024-10-28T13:04:57.796703-04:00 | ||
custom: | ||
Issue: "1050" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
kind: ENHANCEMENTS | ||
body: 'tfsdk: Added `EphemeralResultData` struct for representing ephemeral values | ||
produced by a provider, such as from an ephemeral resource' | ||
time: 2024-10-28T13:06:18.799164-04:00 | ||
custom: | ||
Issue: "1050" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
kind: ENHANCEMENTS | ||
body: 'provider: Added `EphemeralResourceData` to `ConfigureResponse`, to pass provider-defined | ||
data to `ephemeral.EphemeralResource` implementations' | ||
time: 2024-10-28T13:07:58.9914-04:00 | ||
custom: | ||
Issue: "1050" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
kind: FEATURES | ||
body: 'ephemeral: New package for implementing ephemeral resources' | ||
time: 2024-10-28T13:03:39.23218-04:00 | ||
custom: | ||
Issue: "1050" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
kind: FEATURES | ||
body: 'ephemeral/schema: New package for implementing ephemeral resource schemas' | ||
time: 2024-10-28T13:08:55.520004-04:00 | ||
custom: | ||
Issue: "1050" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
kind: NOTES | ||
body: Ephemeral resource support is in technical preview and offered without compatibility | ||
promises until Terraform 1.10 is generally available. | ||
time: 2024-10-28T13:03:08.373897-04:00 | ||
custom: | ||
Issue: "1050" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
package ephemeral | ||
|
||
import ( | ||
"github.com/hashicorp/terraform-plugin-framework/diag" | ||
"github.com/hashicorp/terraform-plugin-framework/internal/privatestate" | ||
) | ||
|
||
// CloseRequest represents a request for the provider to close an ephemeral | ||
// resource. An instance of this request struct is supplied as an argument to | ||
// the ephemeral resource's Close function. | ||
type CloseRequest struct { | ||
// Private is provider-defined ephemeral resource private state data | ||
// which was previously provided by the latest Open or Renew operation. | ||
// | ||
// Use the GetKey method to read data. | ||
Private *privatestate.ProviderData | ||
} | ||
|
||
// CloseResponse represents a response to a CloseRequest. An | ||
// instance of this response struct is supplied as an argument | ||
// to the ephemeral resource's Close function, in which the provider | ||
// should set values on the CloseResponse as appropriate. | ||
type CloseResponse struct { | ||
// Diagnostics report errors or warnings related to closing the | ||
// resource. An empty slice indicates a successful operation with no | ||
// warnings or errors generated. | ||
Diagnostics diag.Diagnostics | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
package ephemeral | ||
|
||
import "context" | ||
|
||
// ConfigValidator describes reusable EphemeralResource configuration validation functionality. | ||
type ConfigValidator interface { | ||
// Description describes the validation in plain text formatting. | ||
// | ||
// This information may be automatically added to ephemeral resource plain text | ||
// descriptions by external tooling. | ||
Description(context.Context) string | ||
|
||
// MarkdownDescription describes the validation in Markdown formatting. | ||
// | ||
// This information may be automatically added to ephemeral resource Markdown | ||
// descriptions by external tooling. | ||
MarkdownDescription(context.Context) string | ||
|
||
// ValidateEphemeralResource performs the validation. | ||
// | ||
// This method name is separate from the datasource.ConfigValidator | ||
// interface ValidateDataSource method name, provider.ConfigValidator | ||
// interface ValidateProvider method name, and resource.ConfigValidator | ||
// interface ValidateResource method name to allow generic validators. | ||
ValidateEphemeralResource(context.Context, ValidateConfigRequest, *ValidateConfigResponse) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
package ephemeral | ||
|
||
import ( | ||
"github.com/hashicorp/terraform-plugin-framework/diag" | ||
) | ||
|
||
// ConfigureRequest represents a request for the provider to configure an | ||
// ephemeral resource, i.e., set provider-level data or clients. An instance of | ||
// this request struct is supplied as an argument to the EphemeralResource type | ||
// Configure method. | ||
type ConfigureRequest struct { | ||
// ProviderData is the data set in the | ||
// [provider.ConfigureResponse.EphemeralResourceData] field. This data is | ||
// provider-specifc and therefore can contain any necessary remote system | ||
// clients, custom provider data, or anything else pertinent to the | ||
// functionality of the EphemeralResource. | ||
// | ||
// This data is only set after the ConfigureProvider RPC has been called | ||
// by Terraform. | ||
ProviderData any | ||
} | ||
|
||
// ConfigureResponse represents a response to a ConfigureRequest. An | ||
// instance of this response struct is supplied as an argument to the | ||
// EphemeralResource type Configure method. | ||
type ConfigureResponse struct { | ||
// Diagnostics report errors or warnings related to configuring of the | ||
// EphemeralResource. An empty slice indicates a successful operation with no | ||
// warnings or errors generated. | ||
Diagnostics diag.Diagnostics | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
package ephemeral | ||
|
||
const ( | ||
// DeferredReasonUnknown is used to indicate an invalid `DeferredReason`. | ||
// Provider developers should not use it. | ||
DeferredReasonUnknown DeferredReason = 0 | ||
|
||
// DeferredReasonEphemeralResourceConfigUnknown is used to indicate that the resource configuration | ||
// is partially unknown and the real values need to be known before the change can be planned. | ||
DeferredReasonEphemeralResourceConfigUnknown DeferredReason = 1 | ||
|
||
// DeferredReasonProviderConfigUnknown is used to indicate that the provider configuration | ||
// is partially unknown and the real values need to be known before the change can be planned. | ||
DeferredReasonProviderConfigUnknown DeferredReason = 2 | ||
|
||
// DeferredReasonAbsentPrereq is used to indicate that a hard dependency has not been satisfied. | ||
DeferredReasonAbsentPrereq DeferredReason = 3 | ||
) | ||
|
||
// Deferred is used to indicate to Terraform that a change needs to be deferred for a reason. | ||
// | ||
// NOTE: This functionality is related to deferred action support, which is currently experimental and is subject | ||
// to change or break without warning. It is not protected by version compatibility guarantees. | ||
type Deferred struct { | ||
// Reason is the reason for deferring the change. | ||
Reason DeferredReason | ||
} | ||
|
||
// DeferredReason represents different reasons for deferring a change. | ||
// | ||
// NOTE: This functionality is related to deferred action support, which is currently experimental and is subject | ||
// to change or break without warning. It is not protected by version compatibility guarantees. | ||
type DeferredReason int32 | ||
|
||
func (d DeferredReason) String() string { | ||
switch d { | ||
case 0: | ||
return "Unknown" | ||
case 1: | ||
return "Ephemeral Resource Config Unknown" | ||
case 2: | ||
return "Provider Config Unknown" | ||
case 3: | ||
return "Absent Prerequisite" | ||
} | ||
return "Unknown" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
// Package ephemeral contains all interfaces, request types, and response | ||
// types for an ephemeral resource implementation. | ||
// | ||
// In Terraform, an ephemeral resource is a concept which enables provider | ||
// developers to offer practitioners ephemeral values, which will not be stored | ||
// in any artifact produced by Terraform (plan/state). Ephemeral resources can | ||
// optionally implement renewal logic via the (EphemeralResource).Renew method | ||
// and cleanup logic via the (EphemeralResource).Close method. | ||
// | ||
// Ephemeral resources are not saved into the Terraform plan or state and can | ||
// only be referenced in other ephemeral values, such as provider configuration | ||
// attributes. Ephemeral resources are defined by a type/name, such as "examplecloud_thing", | ||
// a schema representing the structure and data types of configuration, and lifecycle logic. | ||
// | ||
// The main starting point for implementations in this package is the | ||
// EphemeralResource type which represents an instance of an ephemeral resource | ||
// that has its own configuration and lifecycle logic. The [ephemeral.EphemeralResource] | ||
// implementations are referenced by the [provider.ProviderWithEphemeralResources] type | ||
// EphemeralResources method, which enables the ephemeral resource practitioner usage. | ||
// | ||
// NOTE: Ephemeral resource support is experimental and exposed without compatibility promises until | ||
// these notices are removed. | ||
package ephemeral |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
package ephemeral | ||
|
||
import ( | ||
"context" | ||
) | ||
|
||
// EphemeralResource represents an instance of an ephemeral resource type. This is the core | ||
// interface that all ephemeral resources must implement. | ||
// | ||
// Ephemeral resources can optionally implement these additional concepts: | ||
// | ||
// - Configure: Include provider-level data or clients via EphemeralResourceWithConfigure | ||
// | ||
// - Validation: Schema-based or entire configuration via EphemeralResourceWithConfigValidators | ||
// or EphemeralResourceWithValidateConfig. | ||
// | ||
// - Renew: Handle renewal of an expired remote object via EphemeralResourceWithRenew. | ||
// Ephemeral resources can indicate to Terraform when a renewal must occur via the RenewAt | ||
// response field of the Open/Renew methods. Renew cannot return new result data for the | ||
// ephemeral resource instance, so this logic is only appropriate for remote objects like | ||
// HashiCorp Vault leases, which can be renewed without changing their data. | ||
// | ||
// - Close: Allows providers to clean up the ephemeral resource via EphemeralResourceWithClose. | ||
// | ||
// NOTE: Ephemeral resource support is experimental and exposed without compatibility promises until | ||
// these notices are removed. | ||
type EphemeralResource interface { | ||
// Metadata should return the full name of the ephemeral resource, such as | ||
// examplecloud_thing. | ||
Metadata(context.Context, MetadataRequest, *MetadataResponse) | ||
|
||
// Schema should return the schema for this ephemeral resource. | ||
Schema(context.Context, SchemaRequest, *SchemaResponse) | ||
|
||
// Open is called when the provider must generate a new ephemeral resource. Config values | ||
// should be read from the OpenRequest and new response values set on the OpenResponse. | ||
Open(context.Context, OpenRequest, *OpenResponse) | ||
} | ||
|
||
// EphemeralResourceWithRenew is an interface type that extends EphemeralResource to | ||
// include a method which the framework will call when Terraform detects that the | ||
// provider-defined returned RenewAt time for an ephemeral resource has passed. This RenewAt | ||
// response field can be set in the OpenResponse and RenewResponse. | ||
type EphemeralResourceWithRenew interface { | ||
EphemeralResource | ||
|
||
// Renew is called when the provider must renew the ephemeral resource based on | ||
// the provided RenewAt time. This RenewAt response field can be set in the OpenResponse and RenewResponse. | ||
// | ||
// Renew cannot return new result data for the ephemeral resource instance, so this logic is only appropriate | ||
// for remote objects like HashiCorp Vault leases, which can be renewed without changing their data. | ||
Renew(context.Context, RenewRequest, *RenewResponse) | ||
} | ||
|
||
// EphemeralResourceWithClose is an interface type that extends | ||
// EphemeralResource to include a method which the framework will call when | ||
// Terraform determines that the ephemeral resource can be safely cleaned up. | ||
type EphemeralResourceWithClose interface { | ||
EphemeralResource | ||
|
||
// Close is called when the provider can clean up the ephemeral resource. | ||
// Config values may be read from the CloseRequest. | ||
Close(context.Context, CloseRequest, *CloseResponse) | ||
} | ||
|
||
// EphemeralResourceWithConfigure is an interface type that extends EphemeralResource to | ||
// include a method which the framework will automatically call so provider | ||
// developers have the opportunity to setup any necessary provider-level data | ||
// or clients in the EphemeralResource type. | ||
type EphemeralResourceWithConfigure interface { | ||
EphemeralResource | ||
|
||
// Configure enables provider-level data or clients to be set in the | ||
// provider-defined EphemeralResource type. | ||
Configure(context.Context, ConfigureRequest, *ConfigureResponse) | ||
} | ||
|
||
// EphemeralResourceWithConfigValidators is an interface type that extends EphemeralResource to include declarative validations. | ||
// | ||
// Declaring validation using this methodology simplifies implementation 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 EphemeralResourceWithConfigValidators interface { | ||
EphemeralResource | ||
|
||
// ConfigValidators returns a list of functions which will all be performed during validation. | ||
ConfigValidators(context.Context) []ConfigValidator | ||
} | ||
|
||
// EphemeralResourceWithValidateConfig is an interface type that extends EphemeralResource to include imperative validation. | ||
// | ||
// Declaring validation using this methodology simplifies one-off | ||
// functionality that typically applies to a single ephemeral resource. 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 EphemeralResourceWithValidateConfig interface { | ||
EphemeralResource | ||
|
||
// ValidateConfig performs the validation. | ||
ValidateConfig(context.Context, ValidateConfigRequest, *ValidateConfigResponse) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
package ephemeral | ||
|
||
// MetadataRequest represents a request for the EphemeralResource to return metadata, | ||
// such as its type name. An instance of this request struct is supplied as | ||
// an argument to the EphemeralResource type Metadata method. | ||
type MetadataRequest struct { | ||
// ProviderTypeName is the string returned from | ||
// [provider.MetadataResponse.TypeName], if the Provider type implements | ||
// the Metadata method. This string should prefix the EphemeralResource type name | ||
// with an underscore in the response. | ||
ProviderTypeName string | ||
} | ||
|
||
// MetadataResponse represents a response to a MetadataRequest. An | ||
// instance of this response struct is supplied as an argument to the | ||
// EphemeralResource type Metadata method. | ||
type MetadataResponse struct { | ||
// TypeName should be the full ephemeral resource type, including the provider | ||
// type prefix and an underscore. For example, examplecloud_thing. | ||
TypeName string | ||
} |
Oops, something went wrong.