terraform: improved refactor of EvalWriteResourceState

EvalWriteResourceState finds new life as a method called WriteResourceState on NodeAbstractResource.
This commit is contained in:
Kristin Laemmert 2020-09-25 11:15:53 -04:00
parent db9a9ed5a5
commit 9c721a4131
3 changed files with 54 additions and 75 deletions

View File

@ -10,6 +10,7 @@ import (
"github.com/hashicorp/terraform/dag"
"github.com/hashicorp/terraform/lang"
"github.com/hashicorp/terraform/states"
"github.com/hashicorp/terraform/tfdiags"
)
// ConcreteResourceNodeFunc is a callback type used to convert an
@ -446,6 +447,55 @@ func (n *NodeAbstractResource) DotNode(name string, opts *dag.DotOpts) *dag.DotN
}
}
// WriteResourceState ensures that a suitable resource-level state record is
// present in the state, if that's required for the "each mode" of that
// resource.
//å
// This is important primarily for the situation where count = 0, since this
// eval is the only change we get to set the resource "each mode" to list
// in that case, allowing expression evaluation to see it as a zero-element list
// rather than as not set at all.
func (n *NodeAbstractResource) WriteResourceState(ctx EvalContext, addr addrs.AbsResource) error {
var diags tfdiags.Diagnostics
state := ctx.State()
// We'll record our expansion decision in the shared "expander" object
// so that later operations (i.e. DynamicExpand and expression evaluation)
// can refer to it. Since this node represents the abstract module, we need
// to expand the module here to create all resources.
expander := ctx.InstanceExpander()
switch {
case n.Config.Count != nil:
count, countDiags := evaluateCountExpression(n.Config.Count, ctx)
diags = diags.Append(countDiags)
if countDiags.HasErrors() {
return diags.Err()
}
state.SetResourceProvider(addr, n.ResolvedProvider)
expander.SetResourceCount(addr.Module, n.Addr.Resource, count)
case n.Config.ForEach != nil:
forEach, forEachDiags := evaluateForEachExpression(n.Config.ForEach, ctx)
diags = diags.Append(forEachDiags)
if forEachDiags.HasErrors() {
return diags.Err()
}
// This method takes care of all of the business logic of updating this
// while ensuring that any existing instances are preserved, etc.
state.SetResourceProvider(addr, n.ResolvedProvider)
expander.SetResourceForEach(addr.Module, n.Addr.Resource, forEach)
default:
state.SetResourceProvider(addr, n.ResolvedProvider)
expander.SetResourceSingle(addr.Module, n.Addr.Resource)
}
return nil
}
// graphNodesAreResourceInstancesInDifferentInstancesOfSameModule is an
// annoyingly-task-specific helper function that returns true if and only if
// the following conditions hold:

View File

@ -6,7 +6,6 @@ import (
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/dag"
"github.com/hashicorp/terraform/lang"
"github.com/hashicorp/terraform/tfdiags"
)
// nodeExpandApplyableResource handles the first layer of resource
@ -109,41 +108,6 @@ func (n *NodeApplyableResource) Execute(ctx EvalContext, op walkOperation) error
return nil
}
var diags tfdiags.Diagnostics
state := ctx.State()
// We'll record our expansion decision in the shared "expander" object
// so that later operations (i.e. DynamicExpand and expression evaluation)
// can refer to it. Since this node represents the abstract module, we need
// to expand the module here to create all resources.
expander := ctx.InstanceExpander()
switch {
case n.Config.Count != nil:
count, countDiags := evaluateCountExpression(n.Config.Count, ctx)
diags = diags.Append(countDiags)
if countDiags.HasErrors() {
return diags.Err()
}
state.SetResourceProvider(n.Addr, n.ResolvedProvider)
expander.SetResourceCount(n.Addr.Module, n.Addr.Resource, count)
case n.Config.ForEach != nil:
forEach, forEachDiags := evaluateForEachExpression(n.Config.ForEach, ctx)
diags = diags.Append(forEachDiags)
if forEachDiags.HasErrors() {
return diags.Err()
}
// This method takes care of all of the business logic of updating this
// while ensuring that any existing instances are preserved, etc.
state.SetResourceProvider(n.Addr, n.ResolvedProvider)
expander.SetResourceForEach(n.Addr.Module, n.Addr.Resource, forEach)
default:
state.SetResourceProvider(n.Addr, n.ResolvedProvider)
expander.SetResourceSingle(n.Addr.Module, n.Addr.Resource)
}
return nil
err := n.WriteResourceState(ctx, n.Addr)
return err
}

View File

@ -185,43 +185,8 @@ func (n *NodePlannableResource) Execute(ctx EvalContext, op walkOperation) error
return nil
}
var diags tfdiags.Diagnostics
state := ctx.State()
// We'll record our expansion decision in the shared "expander" object
// so that later operations (i.e. DynamicExpand and expression evaluation)
// can refer to it. Since this node represents the abstract module, we need
// to expand the module here to create all resources.
expander := ctx.InstanceExpander()
switch {
case n.Config.Count != nil:
count, countDiags := evaluateCountExpression(n.Config.Count, ctx)
diags = diags.Append(countDiags)
if countDiags.HasErrors() {
return diags.Err()
}
state.SetResourceProvider(n.Addr, n.ResolvedProvider)
expander.SetResourceCount(n.Addr.Module, n.Addr.Resource, count)
case n.Config.ForEach != nil:
forEach, forEachDiags := evaluateForEachExpression(n.Config.ForEach, ctx)
diags = diags.Append(forEachDiags)
if forEachDiags.HasErrors() {
return diags.Err()
}
// This method takes care of all of the business logic of updating this
// while ensuring that any existing instances are preserved, etc.
state.SetResourceProvider(n.Addr, n.ResolvedProvider)
expander.SetResourceForEach(n.Addr.Module, n.Addr.Resource, forEach)
default:
state.SetResourceProvider(n.Addr, n.ResolvedProvider)
expander.SetResourceSingle(n.Addr.Module, n.Addr.Resource)
}
return nil
err := n.WriteResourceState(ctx, n.Addr)
return err
}
// GraphNodeDestroyerCBD