Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
17 changes: 17 additions & 0 deletions docs/plugin-protocol/tfplugin5.proto
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ service Provider {
//////// Actions
rpc PlanAction(PlanAction.Request) returns (PlanAction.Response);
rpc InvokeAction(InvokeAction.Request) returns (stream InvokeAction.Event);
rpc ValidateActionConfig(ValidateActionConfig.Request) returns (ValidateActionConfig.Response);

//////// Graceful Shutdown
rpc Stop(Stop.Request) returns (Stop.Response);
Expand Down Expand Up @@ -994,3 +995,19 @@ message InvokeAction {
}
}
}

message ValidateActionConfig {
message Request {
string type_name = 1;
DynamicValue config = 2;
repeated LinkedResourceConfig linked_resources = 3;
}
message Response {
repeated Diagnostic diagnostics = 1;
}
}

message LinkedResourceConfig {
string type_name = 1;
DynamicValue config = 2;
}
17 changes: 17 additions & 0 deletions docs/plugin-protocol/tfplugin6.proto
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ service Provider {
//////// Actions
rpc PlanAction(PlanAction.Request) returns (PlanAction.Response);
rpc InvokeAction(InvokeAction.Request) returns (stream InvokeAction.Event);
rpc ValidateActionConfig(ValidateActionConfig.Request) returns (ValidateActionConfig.Response);

//////// Graceful Shutdown
rpc StopProvider(StopProvider.Request) returns (StopProvider.Response);
Expand Down Expand Up @@ -1033,3 +1034,19 @@ message InvokeAction {
}
}
}

message ValidateActionConfig {
message Request {
string type_name = 1;
DynamicValue config = 2;
repeated LinkedResourceConfig linked_resources = 3;
}
message Response {
repeated Diagnostic diagnostics = 1;
}
}

message LinkedResourceConfig {
string type_name = 1;
DynamicValue config = 2;
}
13 changes: 12 additions & 1 deletion internal/builtin/providers/terraform/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (
"fmt"
"log"

tfaddr "github.com/hashicorp/terraform-registry-address"
"github.com/zclconf/go-cty/cty"

tfaddr "github.com/hashicorp/terraform-registry-address"
"github.com/hashicorp/terraform/internal/providers"
)

Expand Down Expand Up @@ -325,6 +325,17 @@ func (p *Provider) InvokeAction(req providers.InvokeActionRequest) providers.Inv
return resp
}

func (p *Provider) ValidateActionConfig(req providers.ValidateActionConfigRequest) providers.ValidateActionConfigResponse {
var resp providers.ValidateActionConfigResponse

switch req.TypeName {
default:
resp.Diagnostics = resp.Diagnostics.Append(fmt.Errorf("unsupported action %q", req.TypeName))
}

return resp
}

// Close is a noop for this provider, since it's run in-process.
func (p *Provider) Close() error {
return nil
Expand Down
39 changes: 39 additions & 0 deletions internal/grpcwrap/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,45 @@ func (p *provider) InvokeAction(req *tfplugin5.InvokeAction_Request, server tfpl
return nil
}

func (p *provider) ValidateActionConfig(_ context.Context, req *tfplugin5.ValidateActionConfig_Request) (*tfplugin5.ValidateActionConfig_Response, error) {
resp := &tfplugin5.ValidateActionConfig_Response{}
ty := p.schema.Actions[req.TypeName].ConfigSchema.ImpliedType()

configVal, err := decodeDynamicValue(req.Config, ty)
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
return resp, nil
}

protoReq := providers.ValidateActionConfigRequest{
TypeName: req.TypeName,
Config: configVal,
}

lrs := make([]providers.LinkedResourceConfig, 0, len(req.LinkedResources))
for _, lr := range req.LinkedResources {
ty := p.schema.ResourceTypes[lr.TypeName].Body.ImpliedType()

configVal, err := decodeDynamicValue(lr.Config, ty)
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
return resp, nil
}
lrs = append(lrs, providers.LinkedResourceConfig{
TypeName: lr.TypeName,
Config: configVal,
})
}

if len(lrs) > 0 {
protoReq.LinkedResources = lrs
}

validateResp := p.provider.ValidateActionConfig(protoReq)
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, validateResp.Diagnostics)
return resp, nil
}

func (p *provider) Stop(context.Context, *tfplugin5.Stop_Request) (*tfplugin5.Stop_Response, error) {
resp := &tfplugin5.Stop_Response{}
err := p.provider.Stop()
Expand Down
39 changes: 39 additions & 0 deletions internal/grpcwrap/provider6.go
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,45 @@ func (p *provider6) InvokeAction(req *tfplugin6.InvokeAction_Request, server tfp
return nil
}

func (p *provider6) ValidateActionConfig(_ context.Context, req *tfplugin6.ValidateActionConfig_Request) (*tfplugin6.ValidateActionConfig_Response, error) {
resp := &tfplugin6.ValidateActionConfig_Response{}
ty := p.schema.Actions[req.TypeName].ConfigSchema.ImpliedType()

configVal, err := decodeDynamicValue6(req.Config, ty)
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
return resp, nil
}

protoReq := providers.ValidateActionConfigRequest{
TypeName: req.TypeName,
Config: configVal,
}

lrs := make([]providers.LinkedResourceConfig, 0, len(req.LinkedResources))
for _, lr := range req.LinkedResources {
ty := p.schema.ResourceTypes[lr.TypeName].Body.ImpliedType()

configVal, err := decodeDynamicValue6(lr.Config, ty)
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
return resp, nil
}
lrs = append(lrs, providers.LinkedResourceConfig{
TypeName: lr.TypeName,
Config: configVal,
})
}

if len(lrs) > 0 {
protoReq.LinkedResources = lrs
}

validateResp := p.provider.ValidateActionConfig(protoReq)
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, validateResp.Diagnostics)
return resp, nil
}

func (p *provider6) StopProvider(context.Context, *tfplugin6.StopProvider_Request) (*tfplugin6.StopProvider_Response, error) {
resp := &tfplugin6.StopProvider_Response{}
err := p.provider.Stop()
Expand Down
8 changes: 4 additions & 4 deletions internal/plans/planfile/tfplan.go
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ func writeTfplan(plan *plans.Plan, w io.Writer) error {
ResourceChanges: []*planproto.ResourceInstanceChange{},
ResourceDrift: []*planproto.ResourceInstanceChange{},
DeferredChanges: []*planproto.DeferredResourceInstanceChange{},
ActionInvocations: []*planproto.ActionInvocation{},
ActionInvocations: []*planproto.ActionInvocationInstance{},
}

rawPlan.Applyable = plan.Applyable
Expand Down Expand Up @@ -1245,7 +1245,7 @@ func CheckResultsToPlanProto(checkResults *states.CheckResults) ([]*planproto.Ch
}
}

func actionInvocationFromTfplan(rawAction *planproto.ActionInvocation) (*plans.ActionInvocationInstanceSrc, error) {
func actionInvocationFromTfplan(rawAction *planproto.ActionInvocationInstance) (*plans.ActionInvocationInstanceSrc, error) {
if rawAction == nil {
// Should never happen in practice, since protobuf can't represent
// a nil value in a list.
Expand All @@ -1268,12 +1268,12 @@ func actionInvocationFromTfplan(rawAction *planproto.ActionInvocation) (*plans.A
return ret, nil
}

func actionInvocationToTfPlan(action *plans.ActionInvocationInstanceSrc) (*planproto.ActionInvocation, error) {
func actionInvocationToTfPlan(action *plans.ActionInvocationInstanceSrc) (*planproto.ActionInvocationInstance, error) {
if action == nil {
return nil, nil
}

ret := &planproto.ActionInvocation{
ret := &planproto.ActionInvocationInstance{
Addr: action.Addr.String(),
Provider: action.ProviderAddr.String(),
}
Expand Down
Loading