Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
115 changes: 7 additions & 108 deletions tfprotov5/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,6 @@ type ValidateActionConfigRequest struct {
// from knowing the value at request time. Any attributes not directly
// set in the configuration will be null.
Config *DynamicValue

// LinkedResources contains the configuration data of the managed resource types that are linked to this action.
//
// - If the action schema type is Unlinked, this field will be empty.
LinkedResources []*LinkedResourceConfig
}

// LinkedResourceConfig represents linked resource config data used in the ValidateActionConfig RPC.
Expand Down Expand Up @@ -98,11 +93,6 @@ type PlanActionRequest struct {
// ActionType is the name of the action being called.
ActionType string

// LinkedResources contains the data of the managed resource types that are linked to this action.
//
// - If the action schema type is Unlinked, this field will be empty.
LinkedResources []*ProposedLinkedResource

// Config is the configuration the user supplied for the action. See
// the documentation on `DynamicValue` for more information about
// safely accessing the configuration.
Expand All @@ -113,43 +103,9 @@ type PlanActionRequest struct {
ClientCapabilities *PlanActionClientCapabilities
}

// ProposedLinkedResource represents linked resource data before PlanAction is called.
type ProposedLinkedResource struct {
// PriorState is the state of the linked resource before the plan is applied,
// represented as a `DynamicValue`. See the documentation for
// `DynamicValue` for information about safely accessing the state.
PriorState *DynamicValue

// PlannedState is the latest indication of what the state for the
// linked resource should be after apply, represented as a `DynamicValue`.
// See the documentation for `DynamicValue` for information about safely
// accessing the planned state.
//
// Since PlannedState is the most recent plan for the linked resource, it could
// be the result of an RPC call to PlanResourceChange or an RPC call to PlanAction
// for a predecessor action
PlannedState *DynamicValue

// Config is the configuration the user supplied for the linked resource. See
// the documentation on `DynamicValue` for more information about
// safely accessing the configuration.
Config *DynamicValue

// PriorIdentity is the identity of the resource before the plan is
// applied, represented as a `ResourceIdentityData`.
PriorIdentity *ResourceIdentityData
}

// PlanActionResponse is the response from the provider when planning an action. If the action
// has linked resources, it will contain any modifications made to the planned state or identity.
// PlanActionResponse is the response from the provider when planning an action.
type PlanActionResponse struct {
// LinkedResources contains the provider modified data of the managed resource types that are linked to this action.
//
// This field is not currently in-use, but future action schema types will use this field to plan modifications of state data for linked resources.
LinkedResources []*PlannedLinkedResource

// Diagnostics report errors or warnings related to plannning the action and calculating
// the planned state of the requested linked resources. Returning an empty slice
// Diagnostics report errors or warnings related to planning the action. Returning an empty slice
// indicates a successful validation with no warnings or errors generated.
Diagnostics []*Diagnostic

Expand Down Expand Up @@ -177,42 +133,14 @@ type InvokeActionRequest struct {
// ActionType is the name of the action being called.
ActionType string

// LinkedResources contains the data of the managed resource types that are linked to this action.
//
// - If the action schema type is Unlinked, this field will be empty.
LinkedResources []*InvokeLinkedResource

// Config is the configuration the user supplied for the action. See
// the documentation on `DynamicValue` for more information about
// safely accessing the configuration.
Config *DynamicValue
}

// InvokeLinkedResource represents linked resource data before InvokeAction is called.
type InvokeLinkedResource struct {
// PriorState is the state of the linked resource before changes are applied,
// represented as a `DynamicValue`. See the documentation for
// `DynamicValue` for information about safely accessing the state.
PriorState *DynamicValue

// PlannedState is the latest indication of what the state for the
// linked resource should look like after changes are applied, represented
// as a `DynamicValue`. See the documentation for `DynamicValue` for
// information about safely accessing the planned state.
//
// Since PlannedState is the most recent state for the linked resource, it could
// be the result of an RPC call to ApplyResourceChange or an RPC call to InvokeAction
// for a predecessor action.
PlannedState *DynamicValue

// Config is the configuration the user supplied for the linked resource. See
// the documentation on `DynamicValue` for more information about
// safely accessing the configuration.
Config *DynamicValue

// PlannedIdentity is Terraform's plan for what the linked resource identity should
// look like after the changes are applied, represented as a `ResourceIdentityData`.
PlannedIdentity *ResourceIdentityData
// ClientCapabilities defines optionally supported protocol features for the
// InvokeAction RPC, such as forward-compatible Terraform behavior changes.
ClientCapabilities *InvokeActionClientCapabilities
}

// InvokeActionServerStream represents a streaming response to an
Expand Down Expand Up @@ -255,42 +183,13 @@ type ProgressInvokeActionEventType struct {

func (a ProgressInvokeActionEventType) isInvokeActionEventType() {}

// CompletedInvokeActionEventType represents the final completed event, along with all of the linked resource
// data modified by the provider or diagnostics about an action invocation failure.
// CompletedInvokeActionEventType represents the final completed event, along with
// potential diagnostics about an action invocation failure.
type CompletedInvokeActionEventType struct {
// LinkedResources contains the provider modified data of the managed resource types that are linked to this action.
//
// This field is not currently in-use, but future action schema types will use this field to modify state data for linked resources.
LinkedResources []*NewLinkedResource

// Diagnostics report errors or warnings related to invoking an action.
// Returning an empty slice indicates a successful invocation with no warnings
// or errors generated.
Diagnostics []*Diagnostic
}

func (a CompletedInvokeActionEventType) isInvokeActionEventType() {}

// NewLinkedResource represents linked resource data that was changed during InvokeAction and returned.
//
// Depending on how the action was invoked, the modified state data will either be immediately recorded in
// state or reconcicled in a future terraform apply operation.
type NewLinkedResource struct {
// NewState is the provider's understanding of what the linked resource's
// state is after changes are applied, 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 PlannedState in the InvokeActionRequest must be preserved
// exactly as it was in NewState.
NewState *DynamicValue

// NewIdentity is the provider's understanding of what the linked resource's
// identity is after changes are applied, represented as a `ResourceIdentityData`.
NewIdentity *ResourceIdentityData

// RequiresReplace can only be set if diagnostics are returned for the action and indicate
// the linked resource must be replaced as a result of the action invocation error.
RequiresReplace bool
}
24 changes: 0 additions & 24 deletions tfprotov5/action_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,4 @@ package tfprotov5
type ActionSchema struct {
// Schema is the definition for the action data itself, which will be specified in an action block in the user's configuration.
Schema *Schema

// Type defines how a practitioner can trigger an action, as well as what effect the action can have on the state
// of the linked managed resources. There is currently only one type of action supported:
// - Unlinked actions are actions that cannot cause changes to resource states.
Type ActionSchemaType
}

// ActionSchemaType is an intentionally unimplementable interface that
// functions as an enum, allowing us to use different strongly-typed action schema types
// that contain additional, but different data, as a generic "action" type.
//
// An action can currently only be one type (Unlinked), which is statically defined in the protocol. Future action types
// will be added to the protocol first, then implemented in this package.
type ActionSchemaType interface {
isActionSchemaType()
}

var (
_ ActionSchemaType = UnlinkedActionSchemaType{}
)

// UnlinkedActionSchemaType represents an unlinked action, which cannot cause changes to resource states.
type UnlinkedActionSchemaType struct{}

func (a UnlinkedActionSchemaType) isActionSchemaType() {}
9 changes: 9 additions & 0 deletions tfprotov5/client_capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,12 @@ type PlanActionClientCapabilities struct {
// handle deferred responses from the provider.
DeferralAllowed bool
}

// InvokeActionClientCapabilities allows Terraform to publish information
// regarding optionally supported protocol features for the InvokeAction RPC,
// such as forward-compatible Terraform behavior changes.
//
// Maintainer Note: This is in the protocol in Terraform Core,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice note, answered my question 😆

// but currently they are not sending any capabilities for this RPC.
type InvokeActionClientCapabilities struct {
}
55 changes: 5 additions & 50 deletions tfprotov5/internal/fromproto/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,79 +14,34 @@ func ValidateActionConfigRequest(in *tfplugin5.ValidateActionConfig_Request) *tf
}

return &tfprotov5.ValidateActionConfigRequest{
ActionType: in.ActionType,
Config: DynamicValue(in.Config),
LinkedResources: LinkedResourceConfigs(in.LinkedResources),
ActionType: in.ActionType,
Config: DynamicValue(in.Config),
}
}

func LinkedResourceConfigs(in []*tfplugin5.LinkedResourceConfig) []*tfprotov5.LinkedResourceConfig {
resp := make([]*tfprotov5.LinkedResourceConfig, 0, len(in))

for _, inLinkedResource := range in {
resp = append(resp, &tfprotov5.LinkedResourceConfig{
TypeName: inLinkedResource.TypeName,
Config: DynamicValue(inLinkedResource.Config),
})
}

return resp
}

func PlanActionRequest(in *tfplugin5.PlanAction_Request) *tfprotov5.PlanActionRequest {
if in == nil {
return nil
}

resp := &tfprotov5.PlanActionRequest{
ActionType: in.ActionType,
LinkedResources: ProposedLinkedResources(in.LinkedResources),
Config: DynamicValue(in.Config),
ClientCapabilities: PlanActionClientCapabilities(in.ClientCapabilities),
}

return resp
}

func ProposedLinkedResources(in []*tfplugin5.PlanAction_Request_LinkedResource) []*tfprotov5.ProposedLinkedResource {
resp := make([]*tfprotov5.ProposedLinkedResource, 0, len(in))

for _, inLinkedResource := range in {
resp = append(resp, &tfprotov5.ProposedLinkedResource{
PriorState: DynamicValue(inLinkedResource.PriorState),
PlannedState: DynamicValue(inLinkedResource.PlannedState),
Config: DynamicValue(inLinkedResource.Config),
PriorIdentity: ResourceIdentityData(inLinkedResource.PriorIdentity),
})
}

return resp
}

func InvokeActionRequest(in *tfplugin5.InvokeAction_Request) *tfprotov5.InvokeActionRequest {
if in == nil {
return nil
}

resp := &tfprotov5.InvokeActionRequest{
ActionType: in.ActionType,
LinkedResources: InvokeLinkedResources(in.LinkedResources),
Config: DynamicValue(in.Config),
}

return resp
}

func InvokeLinkedResources(in []*tfplugin5.InvokeAction_Request_LinkedResource) []*tfprotov5.InvokeLinkedResource {
resp := make([]*tfprotov5.InvokeLinkedResource, 0, len(in))

for _, inLinkedResource := range in {
resp = append(resp, &tfprotov5.InvokeLinkedResource{
PriorState: DynamicValue(inLinkedResource.PriorState),
PlannedState: DynamicValue(inLinkedResource.PlannedState),
Config: DynamicValue(inLinkedResource.Config),
PlannedIdentity: ResourceIdentityData(inLinkedResource.PlannedIdentity),
})
ActionType: in.ActionType,
Config: DynamicValue(in.Config),
ClientCapabilities: InvokeActionClientCapabilities(in.ClientCapabilities),
}

return resp
Expand Down
Loading
Loading