add a way for action apply and resource instance nodes to announce the providers they need

pull/37368/head
Daniel Schmidt 7 months ago
parent 16b78f1e1b
commit 6fdb348b61

@ -404,9 +404,9 @@ resource "test_object" "b" {
_, diags = ctx.Apply(plan, m, nil)
if tc.expectDiagnostics.HasErrors() {
tfdiags.AssertDiagnosticsMatch(t, diags, tc.expectDiagnostics)
return
} else {
tfdiags.AssertNoDiagnostics(t, diags)
}
tfdiags.AssertNoDiagnostics(t, diags)
if tc.expectInvokeActionCalled && len(invokeActionCalls) == 0 {
t.Fatalf("expected invoke action to be called, but it was not")

@ -21,9 +21,10 @@ type nodeActionApply struct {
}
var (
_ GraphNodeExecutable = (*nodeActionApply)(nil)
_ GraphNodeReferencer = (*nodeActionApply)(nil)
_ dag.GraphNodeDotter = (*nodeActionApply)(nil)
_ GraphNodeExecutable = (*nodeActionApply)(nil)
_ GraphNodeReferencer = (*nodeActionApply)(nil)
_ dag.GraphNodeDotter = (*nodeActionApply)(nil)
_ GraphNodeActionProviders = (*nodeActionApply)(nil)
)
func (n *nodeActionApply) Name() string {
@ -154,3 +155,11 @@ func (n *nodeActionApply) References() []*addrs.Reference {
return refs
}
func (n *nodeActionApply) ActionProviders() []addrs.AbsProviderConfig {
ret := []addrs.AbsProviderConfig{}
for _, invocation := range n.ActionInvocations {
ret = append(ret, invocation.ProviderAddr)
}
return ret
}

@ -41,14 +41,14 @@ type NodeApplyableResourceInstance struct {
}
var (
_ GraphNodeConfigResource = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeResourceInstance = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeCreator = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeReferencer = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeDeposer = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeExecutable = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeAttachDependencies = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeAttachBeforeActions = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeConfigResource = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeResourceInstance = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeCreator = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeReferencer = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeDeposer = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeExecutable = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeAttachDependencies = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeActionProviders = (*NodeApplyableResourceInstance)(nil)
)
// GraphNodeCreator
@ -475,8 +475,12 @@ func (n *NodeApplyableResourceInstance) checkPlannedChange(ctx EvalContext, plan
return diags
}
func (n *NodeApplyableResourceInstance) AttachBeforeActions(ais []*plans.ActionInvocationInstance) {
n.beforeActionInvocations = ais
func (n *NodeApplyableResourceInstance) ActionProviders() []addrs.AbsProviderConfig {
ret := []addrs.AbsProviderConfig{}
for _, ai := range n.beforeActionInvocations {
ret = append(ret, ai.ProviderAddr)
}
return ret
}
// maybeTainted takes the resource addr, new value, planned change, and possible

@ -61,6 +61,7 @@ var (
_ GraphNodeAttachResourceConfig = (*nodeExpandPlannableResource)(nil)
_ GraphNodeAttachDependencies = (*nodeExpandPlannableResource)(nil)
_ GraphNodeTargetable = (*nodeExpandPlannableResource)(nil)
_ GraphNodeActionProviders = (*nodeExpandPlannableResource)(nil)
)
func (n *nodeExpandPlannableResource) Name() string {
@ -681,3 +682,38 @@ func (n *nodeExpandPlannableResource) validForceReplaceTargets(instanceAddrs []a
return diags
}
// GraphNodeActionProviders
func (n *nodeExpandPlannableResource) ActionProviders() []addrs.AbsProviderConfig {
providers := []addrs.AbsProviderConfig{}
if n.Config == nil || n.Config.Managed == nil || n.Config.Managed.ActionTriggers == nil {
return providers
}
for _, at := range n.Config.Managed.ActionTriggers {
for _, actionRef := range at.Actions {
ref, diags := addrs.ParseRef(actionRef.Traversal)
if diags.HasErrors() {
// This should have been validated before, so we panic here
panic(fmt.Sprintf("failed to parse action trigger reference %s: %s", actionRef.Traversal, diags.Err()))
}
var provider addrs.Provider
// TODO: This needs to take the provider field into account once we support it
if a, ok := ref.Subject.(addrs.ActionInstance); ok {
provider = addrs.ImpliedProviderForUnqualifiedType(a.Action.ImpliedProvider())
} else if a, ok := ref.Subject.(addrs.Action); ok {
provider = addrs.ImpliedProviderForUnqualifiedType(a.ImpliedProvider())
} else {
// This should have been validated before, so we panic here
panic(fmt.Sprintf("action trigger %s refers to an invalid address", actionRef.Traversal))
}
providers = append(providers, addrs.AbsProviderConfig{
Provider: provider,
Module: n.ModulePath(),
})
}
}
return providers
}

@ -623,7 +623,7 @@ func (n *NodePlannableResourceInstance) planActionTriggers(ctx EvalContext, chan
if err != nil {
diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error,
"Failed to get provider",
fmt.Sprintf("Failed to get provider for action %s", absActionAddr),
fmt.Sprintf("Failed to get provider: %s", err),
))
return diags

@ -87,6 +87,10 @@ type GraphNodeProviderConsumer interface {
SetProvider(addrs.AbsProviderConfig)
}
type GraphNodeActionProviders interface {
ActionProviders() []addrs.AbsProviderConfig
}
// ProviderTransformer is a GraphTransformer that maps resources to providers
// within the graph. This will error if there are any resources that don't map
// to proper resources.
@ -306,6 +310,22 @@ func (t *CloseProviderTransformer) Transform(g *Graph) error {
g.Connect(dag.BasicEdge(closer, v))
}
// Now look at all action provider consumers and connect them to the appropriate closers.
for _, v := range g.Vertices() {
apc, ok := v.(GraphNodeActionProviders)
if !ok {
continue
}
for _, provider := range apc.ActionProviders() {
closer, ok := cpm[provider.String()]
if !ok {
return fmt.Errorf("no graphNodeCloseProvider for %s", provider)
}
g.Connect(dag.BasicEdge(closer, v))
}
}
return err
}

Loading…
Cancel
Save