Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9ec6758
go mod
austinvalle Jul 9, 2025
5eeac4c
generate RPC methods
austinvalle Jul 9, 2025
bf10880
protov5 and fwserver impl
austinvalle Jul 9, 2025
3c21a45
protov6 copy
austinvalle Jul 9, 2025
61eadc9
add initial schema attributes and unlinked schema
austinvalle Jul 10, 2025
0e5df9c
implement unlinked schemas, some attributes, and the rpcs
austinvalle Jul 10, 2025
32b2083
the rest of the tests
austinvalle Jul 10, 2025
dcd6748
Merge branch 'main' into av/action-schema
austinvalle Jul 11, 2025
3a1048c
fix double import
austinvalle Jul 11, 2025
7e5fd9f
external interfaces for plan / configure
austinvalle Jul 11, 2025
95e7673
plan action impl and fwserver tests
austinvalle Jul 14, 2025
5d5960a
proto server tests
austinvalle Jul 14, 2025
7ec37c2
from/to plan tests
austinvalle Jul 14, 2025
e43f576
from invoke
austinvalle Jul 14, 2025
2f08b28
add invoke impl with just completed event
austinvalle Jul 14, 2025
261ef7d
fix map access in unit tests
austinvalle Jul 14, 2025
8fdf71d
Merge branch 'main' into av/unlinked-action-impl
austinvalle Jul 15, 2025
47f9631
implementation of sending progress events
austinvalle Jul 15, 2025
119f4c5
mention progress events
austinvalle Jul 15, 2025
98f7232
comments
austinvalle Jul 15, 2025
ea2deb8
all attributes (primitive, collection, nested)
austinvalle Jul 15, 2025
21ffee7
add blocks and docs
austinvalle Jul 15, 2025
1503be5
update all commented out custom type tests
austinvalle Jul 16, 2025
68a38e4
Merge branch 'main' into av/all-schemas-types
austinvalle Jul 16, 2025
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
37 changes: 36 additions & 1 deletion action/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,40 @@ type Action interface {
// Metadata should return the full name of the action, such as examplecloud_do_thing.
Metadata(context.Context, MetadataRequest, *MetadataResponse)

// TODO:Actions: Eventual landing place for all required methods to implement for an action
// Invoke is called to run the logic of the action and update linked resources if applicable.
// Config, linked resource planned state, and linked resource prior state values should
// be read from the InvokeRequest and new linked resource state values set on the InvokeResponse.
//
// The [InvokeResponse.SendProgress] function can be called in the Invoke method to immediately
// report progress events related to the invocation of the action to Terraform.
Invoke(context.Context, InvokeRequest, *InvokeResponse)
}

// ActionWithConfigure is an interface type that extends Action 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 Action type.
type ActionWithConfigure interface {
Action

// Configure enables provider-level data or clients to be set in the
// provider-defined Action type.
Configure(context.Context, ConfigureRequest, *ConfigureResponse)
}

// ActionWithModifyPlan represents an action with a ModifyPlan function.
type ActionWithModifyPlan interface {
Action

// ModifyPlan is called when the provider has an opportunity to modify
// the plan for an action: once during the plan phase, and once
// during the apply phase with any unknown values from configuration
// filled in with their final values.
//
// Actions do not have computed attributes that can be modified during the plan,
// but linked and lifecycle actions can modify the plan of linked resources.
//
// All action schema types can use the plan as an opportunity to raise early
// diagnostics to practitioners, such as validation errors.
ModifyPlan(context.Context, ModifyPlanRequest, *ModifyPlanResponse)
}
32 changes: 32 additions & 0 deletions action/configure.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package action

import "github.com/hashicorp/terraform-plugin-framework/diag"

// ConfigureRequest represents a request for the provider to configure an
// action, i.e., set provider-level data or clients. An instance of this
// request struct is supplied as an argument to the Action type Configure
// method.
type ConfigureRequest struct {
// ProviderData is the data set in the
// [provider.ConfigureResponse.ActionData] 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 Action.
//
// 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
// Action type Configure method.
type ConfigureResponse struct {
// Diagnostics report errors or warnings related to configuring of the
// Datasource. An empty slice indicates a successful operation with no
// warnings or errors generated.
Diagnostics diag.Diagnostics
}
50 changes: 50 additions & 0 deletions action/deferred.go
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 action

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

// DeferredReasonActionConfigUnknown is used to indicate that the action configuration
// is partially unknown and the real values need to be known before the change can be planned.
DeferredReasonActionConfigUnknown 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 "Action Config Unknown"
case 2:
return "Provider Config Unknown"
case 3:
return "Absent Prerequisite"
}
return "Unknown"
}
45 changes: 45 additions & 0 deletions action/invoke.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package action

import (
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
)

// InvokeRequest represents a request for the provider to invoke the action and update
// the requested action's linked resources.
type InvokeRequest struct {
// Config is the configuration the user supplied for the action.
Config tfsdk.Config

// TODO:Actions: Add linked resources once lifecycle/linked actions are implemented
}

// InvokeResponse represents a response to an InvokeRequest. An
// instance of this response struct is supplied as
// an argument to the action's Invoke function, in which the provider
// should set values on the InvokeResponse as appropriate.
type InvokeResponse struct {
// Diagnostics report errors or warnings related to invoking the action or updating
// the state of the requested action's linked resources. Returning an empty slice
// indicates a successful invocation with no warnings or errors
// generated.
Diagnostics diag.Diagnostics

// SendProgress will immediately send a progress update to Terraform core during action invocation.
// This function is provided by the framework and can be called multiple times while action logic is running.
//
// TODO:Actions: More documentation about when you should use this / when you shouldn't
SendProgress func(event InvokeProgressEvent)

// TODO:Actions: Add linked resources once lifecycle/linked actions are implemented
}

// InvokeProgressEvent is the event returned to Terraform while an action is being invoked.
type InvokeProgressEvent struct {
// Message is the string that will be presented to the practitioner either via the console
// or an external system like HCP Terraform.
Message string
}
62 changes: 62 additions & 0 deletions action/modify_plan.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package action

import (
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
)

// ModifyPlanClientCapabilities allows Terraform to publish information
// regarding optionally supported protocol features for the PlanAction RPC,
// such as forward-compatible Terraform behavior changes.
type ModifyPlanClientCapabilities struct {
// DeferralAllowed indicates whether the Terraform client initiating
// the request allows a deferral response.
//
// 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.
DeferralAllowed bool
}

// ModifyPlanRequest represents a request for the provider to modify the
// planned new state that Terraform has generated for any linked resources.
type ModifyPlanRequest struct {
// Config is the configuration the user supplied for the action.
//
// 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.
Config tfsdk.Config

// TODO:Actions: Add linked resources once lifecycle/linked actions are implemented

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

// ModifyPlanResponse represents a response to a
// ModifyPlanRequest. An instance of this response struct is supplied
// as an argument to the action's ModifyPlan function, in which the provider
// should modify the Plan of any linked resources as appropriate.
type ModifyPlanResponse struct {
// Diagnostics report errors or warnings related to determining the
// planned state of the requested action's linked resources. Returning an empty slice
// indicates a successful plan modification with no warnings or errors
// generated.
Diagnostics diag.Diagnostics

// TODO:Actions: Add linked resources once lifecycle/linked actions are implemented

// Deferred indicates that Terraform should defer planning this
// action until a follow-up apply operation.
//
// This field can only be set if
// `(action.ModifyPlanRequest).ClientCapabilities.DeferralAllowed` is true.
//
// 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.
Deferred *Deferred
}
2 changes: 0 additions & 2 deletions action/schema/attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
)

// TODO:Actions: Add all of the attribute and nested attribute types listed below
//
// Attribute define a value field inside an action type schema. Implementations in this
// package include:
// - BoolAttribute
Expand Down
2 changes: 0 additions & 2 deletions action/schema/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
)

// TODO:Actions: Add all of the block and nested block types listed below
//
// Block defines a structural field inside an action type schema. Implementations in this
// package include:
// - ListNestedBlock
Expand Down
3 changes: 1 addition & 2 deletions action/schema/bool_attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ type BoolAttribute struct {
CustomType basetypes.BoolTypable

// Required indicates whether the practitioner must enter a value for
// this attribute or not. Required and Optional cannot both be true,
// and Required and Computed cannot both be true.
// this attribute or not. Required and Optional cannot both be true.
Required bool

// Optional indicates whether the practitioner can choose to enter a value
Expand Down
13 changes: 13 additions & 0 deletions action/schema/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

// Package schema contains all available schema functionality for actions.
// Action schemas define the structure and value types for configuration data.
// Schemas are implemented via the action.Action type Schema method.
//
// There are three different types of action schemas, which define how a practitioner can trigger an action,
// as well as what effect the action can have on the state.
// - [UnlinkedSchema] actions are actions that cannot cause changes to resource states.
// - [LifecycleSchema] actions are actions that can cause changes to exactly one resource state.
// - [LinkedSchema] actions are actions that can cause changes to one or more resource states.
package schema
Loading