-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tfprotov5+tfprotov6: Initial ephemeral resource type implementation (#…
…441) * Upgrade Go to `v1.22` * Add support for ephemeral resources in protocol version 6 * Add support for ephemeral resources in protocol version 5 * Add ephemeral resources field to `GetMetadata_Response()` * Remove `State` field from `RenewEphemeralResource` RPC response and rename `PriorState` request fields to `State`. * switch interfaces to be optional * removed `config` from renew request * update protocol to match core + added logging * Update protocol bindings * Add changelog entries * Fix comment wording based off of PR feedback --------- Co-authored-by: Austin Valle <[email protected]>
- Loading branch information
1 parent
8e75df6
commit 879185f
Showing
43 changed files
with
7,028 additions
and
2,166 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,5 @@ | ||
kind: FEATURES | ||
body: 'tfprotov5+tfprotov6: Upgraded protocols and added types to support the new ephemeral resource type' | ||
time: 2024-10-28T16:19:24.079728-04:00 | ||
custom: | ||
Issue: "441" |
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: NOTES | ||
body: 'tfprotov5+tfprotov6: An upcoming release will require the `EphemeralResourceServer` implementation as part of `ProviderServer`. ' | ||
time: 2024-10-28T16:28:25.504018-04:00 | ||
custom: | ||
Issue: "441" |
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
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
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
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
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,185 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
package tfprotov5 | ||
|
||
import ( | ||
"context" | ||
"time" | ||
) | ||
|
||
// EphemeralResourceMetadata describes metadata for an ephemeral resource in the GetMetadata | ||
// RPC. | ||
type EphemeralResourceMetadata struct { | ||
// TypeName is the name of the ephemeral resource. | ||
TypeName string | ||
} | ||
|
||
// EphemeralResourceServer is an interface containing the methods an ephemeral resource | ||
// implementation needs to fill. | ||
type EphemeralResourceServer interface { | ||
// ValidateEphemeralResourceConfig is called when Terraform is checking that an | ||
// ephemeral resource configuration is valid. It is guaranteed to have types | ||
// conforming to your schema, but it is not guaranteed that all values | ||
// will be known. This is your opportunity to do custom or advanced | ||
// validation prior to an ephemeral resource being opened. | ||
ValidateEphemeralResourceConfig(context.Context, *ValidateEphemeralResourceConfigRequest) (*ValidateEphemeralResourceConfigResponse, error) | ||
|
||
// OpenEphemeralResource is called when Terraform wants to open the ephemeral resource, | ||
// usually during planning. If the config for the ephemeral resource contains unknown | ||
// values, Terraform will defer the OpenEphemeralResource call until apply. | ||
OpenEphemeralResource(context.Context, *OpenEphemeralResourceRequest) (*OpenEphemeralResourceResponse, error) | ||
|
||
// RenewEphemeralResource is called when Terraform detects that the previously specified | ||
// RenewAt timestamp has passed. The RenewAt timestamp is supplied either from the | ||
// OpenEphemeralResource call or a previous RenewEphemeralResource call. | ||
RenewEphemeralResource(context.Context, *RenewEphemeralResourceRequest) (*RenewEphemeralResourceResponse, error) | ||
|
||
// CloseEphemeralResource is called when Terraform is closing the ephemeral resource. | ||
CloseEphemeralResource(context.Context, *CloseEphemeralResourceRequest) (*CloseEphemeralResourceResponse, error) | ||
} | ||
|
||
// ValidateEphemeralResourceConfigRequest is the request Terraform sends when it | ||
// wants to validate an ephemeral resource's configuration. | ||
type ValidateEphemeralResourceConfigRequest struct { | ||
// TypeName is the type of resource Terraform is validating. | ||
TypeName string | ||
|
||
// Config is the configuration the user supplied for that ephemeral resource. See | ||
// the documentation on `DynamicValue` for more information about | ||
// safely accessing the configuration. | ||
// | ||
// The configuration is represented as a tftypes.Object, with each | ||
// attribute and nested block getting its own key and value. | ||
// | ||
// 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. Any attributes not directly | ||
// set in the configuration will be null. | ||
Config *DynamicValue | ||
} | ||
|
||
// ValidateEphemeralResourceConfigResponse is the response from the provider about | ||
// the validity of an ephemeral resource's configuration. | ||
type ValidateEphemeralResourceConfigResponse struct { | ||
// Diagnostics report errors or warnings related to the given | ||
// configuration. Returning an empty slice indicates a successful | ||
// validation with no warnings or errors generated. | ||
Diagnostics []*Diagnostic | ||
} | ||
|
||
// OpenEphemeralResourceRequest is the request Terraform sends when it | ||
// wants to open an ephemeral resource. | ||
type OpenEphemeralResourceRequest struct { | ||
// TypeName is the type of resource Terraform is opening. | ||
TypeName string | ||
|
||
// Config is the configuration the user supplied for that ephemeral resource. See | ||
// the documentation on `DynamicValue` for more information about | ||
// safely accessing the configuration. | ||
// | ||
// The configuration is represented as a tftypes.Object, with each | ||
// attribute and nested block getting its own key and value. | ||
// | ||
// This configuration will always be fully known. If Config contains unknown values, | ||
// Terraform will defer the OpenEphemeralResource RPC until apply. | ||
Config *DynamicValue | ||
|
||
// ClientCapabilities defines optionally supported protocol features for the | ||
// OpenEphemeralResource RPC, such as forward-compatible Terraform behavior changes. | ||
ClientCapabilities *OpenEphemeralResourceClientCapabilities | ||
} | ||
|
||
// OpenEphemeralResourceResponse is the response from the provider about the current | ||
// state of the opened ephemeral resource. | ||
type OpenEphemeralResourceResponse struct { | ||
// Result is the provider's understanding of what the ephemeral resource's | ||
// data is after it has been opened, represented as a `DynamicValue`. | ||
// See the documentation for `DynamicValue` for information about | ||
// safely creating the `DynamicValue`. | ||
// | ||
// Any attribute, whether computed or not, that has a known value in | ||
// the Config in the OpenEphemeralResourceRequest must be preserved | ||
// exactly as it was in Result. | ||
// | ||
// Any attribute in the Config in the OpenEphemeralResourceRequest | ||
// that is unknown must take on a known value at this time. No unknown | ||
// values are allowed in the Result. | ||
// | ||
// The result should be represented as a tftypes.Object, with each | ||
// attribute and nested block getting its own key and value. | ||
Result *DynamicValue | ||
|
||
// Diagnostics report errors or warnings related to opening the | ||
// requested ephemeral resource. Returning an empty slice | ||
// indicates a successful creation with no warnings or errors | ||
// generated. | ||
Diagnostics []*Diagnostic | ||
|
||
// Private should be set to any private data that the provider would like to be | ||
// sent to the next Renew or Close call. | ||
Private []byte | ||
|
||
// RenewAt indicates to Terraform that the ephemeral resource | ||
// needs to be renewed at the specified time. Terraform will | ||
// call the RenewEphemeralResource RPC when the specified time has passed. | ||
RenewAt time.Time | ||
|
||
// Deferred is used to indicate to Terraform that the OpenEphemeralResource operation | ||
// needs to be deferred for a reason. | ||
Deferred *Deferred | ||
} | ||
|
||
// RenewEphemeralResourceRequest is the request Terraform sends when it | ||
// wants to renew an ephemeral resource. | ||
type RenewEphemeralResourceRequest struct { | ||
// TypeName is the type of resource Terraform is renewing. | ||
TypeName string | ||
|
||
// Private is any provider-defined private data stored with the | ||
// ephemeral resource from the most recent Open or Renew call. | ||
// | ||
// To ensure private data is preserved, copy any necessary data to | ||
// the RenewEphemeralResourceResponse type Private field. | ||
Private []byte | ||
} | ||
|
||
// RenewEphemeralResourceResponse is the response from the provider after an ephemeral resource | ||
// has been renewed. | ||
type RenewEphemeralResourceResponse struct { | ||
// Diagnostics report errors or warnings related to renewing the | ||
// requested ephemeral resource. Returning an empty slice | ||
// indicates a successful creation with no warnings or errors | ||
// generated. | ||
Diagnostics []*Diagnostic | ||
|
||
// Private should be set to any private data that the provider would like to be | ||
// sent to the next Renew or Close call. | ||
Private []byte | ||
|
||
// RenewAt indicates to Terraform that the ephemeral resource | ||
// needs to be renewed at the specified time. Terraform will | ||
// call the RenewEphemeralResource RPC when the specified time has passed. | ||
RenewAt time.Time | ||
} | ||
|
||
// CloseEphemeralResourceRequest is the request Terraform sends when it | ||
// wants to close an ephemeral resource. | ||
type CloseEphemeralResourceRequest struct { | ||
// TypeName is the type of resource Terraform is closing. | ||
TypeName string | ||
|
||
// Private is any provider-defined private data stored with the | ||
// ephemeral resource from the most recent Open or Renew call. | ||
Private []byte | ||
} | ||
|
||
// CloseEphemeralResourceResponse is the response from the provider about | ||
// the closed ephemeral resource. | ||
type CloseEphemeralResourceResponse struct { | ||
// Diagnostics report errors or warnings related to closing the | ||
// requested ephemeral resource. Returning an empty slice | ||
// indicates a successful creation with no warnings or errors | ||
// generated. | ||
Diagnostics []*Diagnostic | ||
} |
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
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
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,54 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
package fromproto | ||
|
||
import ( | ||
"github.com/hashicorp/terraform-plugin-go/tfprotov5" | ||
"github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5" | ||
) | ||
|
||
func ValidateEphemeralResourceConfigRequest(in *tfplugin5.ValidateEphemeralResourceConfig_Request) *tfprotov5.ValidateEphemeralResourceConfigRequest { | ||
if in == nil { | ||
return nil | ||
} | ||
|
||
return &tfprotov5.ValidateEphemeralResourceConfigRequest{ | ||
TypeName: in.TypeName, | ||
Config: DynamicValue(in.Config), | ||
} | ||
} | ||
|
||
func OpenEphemeralResourceRequest(in *tfplugin5.OpenEphemeralResource_Request) *tfprotov5.OpenEphemeralResourceRequest { | ||
if in == nil { | ||
return nil | ||
} | ||
|
||
return &tfprotov5.OpenEphemeralResourceRequest{ | ||
TypeName: in.TypeName, | ||
Config: DynamicValue(in.Config), | ||
ClientCapabilities: OpenEphemeralResourceClientCapabilities(in.ClientCapabilities), | ||
} | ||
} | ||
|
||
func RenewEphemeralResourceRequest(in *tfplugin5.RenewEphemeralResource_Request) *tfprotov5.RenewEphemeralResourceRequest { | ||
if in == nil { | ||
return nil | ||
} | ||
|
||
return &tfprotov5.RenewEphemeralResourceRequest{ | ||
TypeName: in.TypeName, | ||
Private: in.Private, | ||
} | ||
} | ||
|
||
func CloseEphemeralResourceRequest(in *tfplugin5.CloseEphemeralResource_Request) *tfprotov5.CloseEphemeralResourceRequest { | ||
if in == nil { | ||
return nil | ||
} | ||
|
||
return &tfprotov5.CloseEphemeralResourceRequest{ | ||
TypeName: in.TypeName, | ||
Private: in.Private, | ||
} | ||
} |
Oops, something went wrong.