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

tfprotov5+tfprotov6: Add deferred action support to related RPCs #403

Merged
merged 20 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/unreleased/FEATURES-20240501-174028.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: FEATURES
body: 'tfprotov5+tfprotov6: Upgraded protocols and added types to support deferred
actions'
time: 2024-05-01T17:40:28.845566-04:00
custom:
Issue: "403"
6 changes: 6 additions & 0 deletions internal/logging/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,15 @@ const (
// The protocol version being used, as a string, such as "6"
KeyProtocolVersion = "tf_proto_version"

// The Deferred reason for an RPC response
KeyDeferredReason = "tf_deferred_reason"

// Whether the GetProviderSchemaOptional server capability is enabled
KeyServerCapabilityGetProviderSchemaOptional = "tf_server_capability_get_provider_schema_optional"

// Whether the PlanDestroy server capability is enabled
KeyServerCapabilityPlanDestroy = "tf_server_capability_plan_destroy"

// Whether the DeferralAllowed client capability is enabled
KeyClientCapabilityDeferralAllowed = "tf_client_capability_deferral_allowed"
)
49 changes: 49 additions & 0 deletions tfprotov5/client_capabilities.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package tfprotov5

// ConfigureProviderClientCapabilities allows Terraform to publish information
// regarding optionally supported protocol features for the ConfigureProvider RPC,
// such as forward-compatible Terraform behavior changes.
type ConfigureProviderClientCapabilities struct {
// DeferralAllowed signals that the request from Terraform is able to
// handle deferred responses from the provider.
DeferralAllowed bool
}

// ReadDataSourceClientCapabilities allows Terraform to publish information
// regarding optionally supported protocol features for the ReadDataSource RPC,
// such as forward-compatible Terraform behavior changes.
type ReadDataSourceClientCapabilities struct {
// DeferralAllowed signals that the request from Terraform is able to
// handle deferred responses from the provider.
DeferralAllowed bool
}

// ReadResourceClientCapabilities allows Terraform to publish information
// regarding optionally supported protocol features for the ReadResource RPC,
// such as forward-compatible Terraform behavior changes.
type ReadResourceClientCapabilities struct {
// DeferralAllowed signals that the request from Terraform is able to
// handle deferred responses from the provider.
DeferralAllowed bool
}

// PlanResourceChangeClientCapabilities allows Terraform to publish information
// regarding optionally supported protocol features for the PlanResourceChange RPC,
// such as forward-compatible Terraform behavior changes.
type PlanResourceChangeClientCapabilities struct {
// DeferralAllowed signals that the request from Terraform is able to
// handle deferred responses from the provider.
DeferralAllowed bool
}

// ImportResourceStateClientCapabilities allows Terraform to publish information
// regarding optionally supported protocol features for the ImportResourceState RPC,
// such as forward-compatible Terraform behavior changes.
type ImportResourceStateClientCapabilities struct {
// DeferralAllowed signals that the request from Terraform is able to
// handle deferred responses from the provider.
DeferralAllowed bool
}
8 changes: 8 additions & 0 deletions tfprotov5/data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ type ReadDataSourceRequest struct {
//
// This configuration will have known values for all fields.
ProviderMeta *DynamicValue

// ClientCapabilities defines optionally supported protocol features for the
// ReadDataSource RPC, such as forward-compatible Terraform behavior changes.
ClientCapabilities *ReadDataSourceClientCapabilities
}

// ReadDataSourceResponse is the response from the provider about the current
Expand All @@ -105,4 +109,8 @@ type ReadDataSourceResponse struct {
// indicates a successful validation with no warnings or errors
// generated.
Diagnostics []*Diagnostic

// Deferred is used to indicate to Terraform that the ReadDataSource operation
// needs to be deferred for a reason.
Deferred *Deferred
}
44 changes: 44 additions & 0 deletions tfprotov5/deferred.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package tfprotov5

const (
// DeferredReasonUnknown is used to indicate an invalid `DeferredReason`.
// Provider developers should not use it.
DeferredReasonUnknown DeferredReason = 0

// DeferredReasonResourceConfigUnknown 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.
DeferredReasonResourceConfigUnknown 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.
type Deferred struct {
// Reason is the reason for deferring the change.
Reason DeferredReason
}

// DeferredReason represents different reasons for deferring a change.
type DeferredReason int32

func (d DeferredReason) String() string {
switch d {
case 0:
return "UNKNOWN"
case 1:
return "RESOURCE_CONFIG_UNKNOWN"
case 2:
return "PROVIDER_CONFIG_UNKNOWN"
case 3:
return "ABSENT_PREREQ"
}
return "UNKNOWN"
}
69 changes: 69 additions & 0 deletions tfprotov5/internal/fromproto/client_capabilities.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// 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 ConfigureProviderClientCapabilities(in *tfplugin5.ClientCapabilities) *tfprotov5.ConfigureProviderClientCapabilities {
if in == nil {
return nil
}

resp := &tfprotov5.ConfigureProviderClientCapabilities{
DeferralAllowed: in.DeferralAllowed,
}

return resp
}

func ReadDataSourceClientCapabilities(in *tfplugin5.ClientCapabilities) *tfprotov5.ReadDataSourceClientCapabilities {
if in == nil {
return nil
}

resp := &tfprotov5.ReadDataSourceClientCapabilities{
DeferralAllowed: in.DeferralAllowed,
}

return resp
}

func ReadResourceClientCapabilities(in *tfplugin5.ClientCapabilities) *tfprotov5.ReadResourceClientCapabilities {
if in == nil {
return nil
}

resp := &tfprotov5.ReadResourceClientCapabilities{
DeferralAllowed: in.DeferralAllowed,
}

return resp
}

func PlanResourceChangeClientCapabilities(in *tfplugin5.ClientCapabilities) *tfprotov5.PlanResourceChangeClientCapabilities {
if in == nil {
return nil
}

resp := &tfprotov5.PlanResourceChangeClientCapabilities{
DeferralAllowed: in.DeferralAllowed,
}

return resp
}

func ImportResourceStateClientCapabilities(in *tfplugin5.ClientCapabilities) *tfprotov5.ImportResourceStateClientCapabilities {
if in == nil {
return nil
}

resp := &tfprotov5.ImportResourceStateClientCapabilities{
DeferralAllowed: in.DeferralAllowed,
}

return resp
}
Loading
Loading