remove GraphNodeModuleInstance from Resource types

Remove the requirement for most *Resource types to be a
GraphNodeModuleInstance, ensuring that they never call ctx.Path while
being evaluated. This gets rid of most of the direct need for the Path
method currently implemented by NodeResourceAbstract, leaving the
provider and schema related calls for a subsequent PR.
This commit is contained in:
James Bardin 2020-03-09 15:43:56 -04:00
parent 68b500c5c7
commit fae5f9958d
8 changed files with 43 additions and 46 deletions

View File

@ -453,6 +453,7 @@ func (n *EvalMaybeRestoreDeposedObject) Eval(ctx EvalContext) (interface{}, erro
// list rather than as not set at all. // list rather than as not set at all.
type EvalWriteResourceState struct { type EvalWriteResourceState struct {
Addr addrs.Resource Addr addrs.Resource
Module addrs.Module
Config *configs.Resource Config *configs.Resource
ProviderAddr addrs.AbsProviderConfig ProviderAddr addrs.AbsProviderConfig
} }
@ -460,7 +461,6 @@ type EvalWriteResourceState struct {
// TODO: test // TODO: test
func (n *EvalWriteResourceState) Eval(ctx EvalContext) (interface{}, error) { func (n *EvalWriteResourceState) Eval(ctx EvalContext) (interface{}, error) {
var diags tfdiags.Diagnostics var diags tfdiags.Diagnostics
absAddr := n.Addr.Absolute(ctx.Path())
state := ctx.State() state := ctx.State()
count, countDiags := evaluateResourceCountExpression(n.Config.Count, ctx) count, countDiags := evaluateResourceCountExpression(n.Config.Count, ctx)
@ -484,16 +484,16 @@ func (n *EvalWriteResourceState) Eval(ctx EvalContext) (interface{}, error) {
eachMode = states.EachMap eachMode = states.EachMap
} }
// This method takes care of all of the business logic of updating this
// while ensuring that any existing instances are preserved, etc.
state.SetResourceMeta(absAddr, eachMode, n.ProviderAddr)
// We'll record our expansion decision in the shared "expander" object // We'll record our expansion decision in the shared "expander" object
// so that later operations (i.e. DynamicExpand and expression evaluation) // so that later operations (i.e. DynamicExpand and expression evaluation)
// can refer to it. Since this node represents the abstract module, we need // can refer to it. Since this node represents the abstract module, we need
// to expand the module here to create all resources. // to expand the module here to create all resources.
expander := ctx.InstanceExpander() expander := ctx.InstanceExpander()
for _, module := range expander.ExpandModule(ctx.Path().Module()) { for _, module := range expander.ExpandModule(n.Module) {
// This method takes care of all of the business logic of updating this
// while ensuring that any existing instances are preserved, etc.
state.SetResourceMeta(n.Addr.Absolute(module), eachMode, n.ProviderAddr)
switch eachMode { switch eachMode {
case states.EachList: case states.EachList:
expander.SetResourceCount(module, n.Addr, count) expander.SetResourceCount(module, n.Addr, count)

View File

@ -1,6 +1,7 @@
package terraform package terraform
import ( import (
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/dag" "github.com/hashicorp/terraform/dag"
"github.com/hashicorp/terraform/plans" "github.com/hashicorp/terraform/plans"
"github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/providers"
@ -15,7 +16,6 @@ type NodeRefreshableDataResource struct {
} }
var ( var (
_ GraphNodeModuleInstance = (*NodeRefreshableDataResource)(nil)
_ GraphNodeDynamicExpandable = (*NodeRefreshableDataResource)(nil) _ GraphNodeDynamicExpandable = (*NodeRefreshableDataResource)(nil)
_ GraphNodeReferenceable = (*NodeRefreshableDataResource)(nil) _ GraphNodeReferenceable = (*NodeRefreshableDataResource)(nil)
_ GraphNodeReferencer = (*NodeRefreshableDataResource)(nil) _ GraphNodeReferencer = (*NodeRefreshableDataResource)(nil)
@ -54,18 +54,22 @@ func (n *NodeRefreshableDataResource) DynamicExpand(ctx EvalContext) (*Graph, er
// if we're transitioning whether "count" is set at all. // if we're transitioning whether "count" is set at all.
fixResourceCountSetTransition(ctx, n.ResourceAddr(), count != -1) fixResourceCountSetTransition(ctx, n.ResourceAddr(), count != -1)
var instanceAddrs []addrs.AbsResourceInstance
// Inform our instance expander about our expansion results above, // Inform our instance expander about our expansion results above,
// and then use it to calculate the instance addresses we'll expand for. // and then use it to calculate the instance addresses we'll expand for.
expander := ctx.InstanceExpander() expander := ctx.InstanceExpander()
switch { for _, path := range expander.ExpandModule(n.Module) {
case count >= 0: switch {
expander.SetResourceCount(ctx.Path(), n.ResourceAddr().Resource, count) case count >= 0:
case forEachMap != nil: expander.SetResourceCount(path, n.ResourceAddr().Resource, count)
expander.SetResourceForEach(ctx.Path(), n.ResourceAddr().Resource, forEachMap) case forEachMap != nil:
default: expander.SetResourceForEach(path, n.ResourceAddr().Resource, forEachMap)
expander.SetResourceSingle(ctx.Path(), n.ResourceAddr().Resource) default:
expander.SetResourceSingle(path, n.ResourceAddr().Resource)
}
instanceAddrs = append(instanceAddrs, expander.ExpandResource(path.Module(), n.ResourceAddr().Resource)...)
} }
instanceAddrs := expander.ExpandResource(ctx.Path().Module(), n.ResourceAddr().Resource)
// Our graph transformers require access to the full state, so we'll // Our graph transformers require access to the full state, so we'll
// temporarily lock it while we work on this. // temporarily lock it while we work on this.
@ -135,7 +139,7 @@ func (n *NodeRefreshableDataResource) DynamicExpand(ctx EvalContext) (*Graph, er
Name: "NodeRefreshableDataResource", Name: "NodeRefreshableDataResource",
} }
graph, diags := b.Build(ctx.Path()) graph, diags := b.Build(nil)
return graph, diags.ErrWithWarnings() return graph, diags.ErrWithWarnings()
} }

View File

@ -99,7 +99,8 @@ func NewNodeAbstractResource(addr addrs.AbsResource) *NodeAbstractResource {
// the "count" or "for_each" arguments. // the "count" or "for_each" arguments.
type NodeAbstractResourceInstance struct { type NodeAbstractResourceInstance struct {
NodeAbstractResource NodeAbstractResource
InstanceKey addrs.InstanceKey ModuleInstance addrs.ModuleInstance
InstanceKey addrs.InstanceKey
// The fields below will be automatically set using the Attach // The fields below will be automatically set using the Attach
// interfaces if you're running those transforms, but also be explicitly // interfaces if you're running those transforms, but also be explicitly
@ -138,7 +139,8 @@ func NewNodeAbstractResourceInstance(addr addrs.AbsResourceInstance) *NodeAbstra
Addr: addr.Resource.Resource, Addr: addr.Resource.Resource,
Module: addr.Module.Module(), Module: addr.Module.Module(),
}, },
InstanceKey: addr.Resource.Key, ModuleInstance: addr.Module,
InstanceKey: addr.Resource.Key,
} }
} }
@ -155,6 +157,10 @@ func (n *NodeAbstractResource) Path() addrs.ModuleInstance {
return n.Module.UnkeyedInstanceShim() return n.Module.UnkeyedInstanceShim()
} }
func (n *NodeAbstractResourceInstance) Path() addrs.ModuleInstance {
return n.ModuleInstance
}
// GraphNodeModulePath // GraphNodeModulePath
func (n *NodeAbstractResource) ModulePath() addrs.Module { func (n *NodeAbstractResource) ModulePath() addrs.Module {
return n.Module return n.Module

View File

@ -53,19 +53,16 @@ func (n *NodeApplyableResource) References() []*addrs.Reference {
// GraphNodeEvalable // GraphNodeEvalable
func (n *NodeApplyableResource) EvalTree() EvalNode { func (n *NodeApplyableResource) EvalTree() EvalNode {
addr := n.ResourceAddr() if n.Config == nil {
config := n.Config
providerAddr := n.ResolvedProvider
if config == nil {
// Nothing to do, then. // Nothing to do, then.
log.Printf("[TRACE] NodeApplyableResource: no configuration present for %s", addr) log.Printf("[TRACE] NodeApplyableResource: no configuration present for %s", n.Name())
return &EvalNoop{} return &EvalNoop{}
} }
return &EvalWriteResourceState{ return &EvalWriteResourceState{
Addr: addr.Resource, Addr: n.Addr,
Config: config, Module: n.Module,
ProviderAddr: providerAddr, Config: n.Config,
ProviderAddr: n.ResolvedProvider,
} }
} }

View File

@ -288,6 +288,7 @@ func (n *NodeDestroyResourceInstance) EvalTree() EvalNode {
// all been destroyed. // all been destroyed.
type NodeDestroyResource struct { type NodeDestroyResource struct {
*NodeAbstractResource *NodeAbstractResource
Addr addrs.AbsResource
} }
var ( var (
@ -342,11 +343,6 @@ func (n *NodeDestroyResource) ResourceAddr() addrs.AbsResource {
return n.NodeAbstractResource.ResourceAddr() return n.NodeAbstractResource.ResourceAddr()
} }
// GraphNodeSubpath
func (n *NodeDestroyResource) Path() addrs.ModuleInstance {
return n.NodeAbstractResource.Path()
}
// GraphNodeNoProvider // GraphNodeNoProvider
// FIXME: this should be removed once the node can be separated from the // FIXME: this should be removed once the node can be separated from the
// Internal NodeAbstractResource behavior. // Internal NodeAbstractResource behavior.

View File

@ -19,7 +19,6 @@ type NodePlannableResource struct {
} }
var ( var (
_ GraphNodeModuleInstance = (*NodePlannableResource)(nil)
_ GraphNodeDestroyerCBD = (*NodePlannableResource)(nil) _ GraphNodeDestroyerCBD = (*NodePlannableResource)(nil)
_ GraphNodeDynamicExpandable = (*NodePlannableResource)(nil) _ GraphNodeDynamicExpandable = (*NodePlannableResource)(nil)
_ GraphNodeReferenceable = (*NodePlannableResource)(nil) _ GraphNodeReferenceable = (*NodePlannableResource)(nil)
@ -30,19 +29,17 @@ var (
// GraphNodeEvalable // GraphNodeEvalable
func (n *NodePlannableResource) EvalTree() EvalNode { func (n *NodePlannableResource) EvalTree() EvalNode {
addr := n.ResourceAddr() if n.Config == nil {
config := n.Config
if config == nil {
// Nothing to do, then. // Nothing to do, then.
log.Printf("[TRACE] NodeApplyableResource: no configuration present for %s", addr) log.Printf("[TRACE] NodeApplyableResource: no configuration present for %s", n.Name())
return &EvalNoop{} return &EvalNoop{}
} }
// this ensures we can reference the resource even if the count is 0 // this ensures we can reference the resource even if the count is 0
return &EvalWriteResourceState{ return &EvalWriteResourceState{
Addr: addr.Resource, Addr: n.Addr,
Config: config, Module: n.Module,
Config: n.Config,
ProviderAddr: n.ResolvedProvider, ProviderAddr: n.ResolvedProvider,
} }
} }

View File

@ -25,7 +25,6 @@ type NodeRefreshableManagedResource struct {
} }
var ( var (
_ GraphNodeModuleInstance = (*NodeRefreshableManagedResource)(nil)
_ GraphNodeDynamicExpandable = (*NodeRefreshableManagedResource)(nil) _ GraphNodeDynamicExpandable = (*NodeRefreshableManagedResource)(nil)
_ GraphNodeReferenceable = (*NodeRefreshableManagedResource)(nil) _ GraphNodeReferenceable = (*NodeRefreshableManagedResource)(nil)
_ GraphNodeReferencer = (*NodeRefreshableManagedResource)(nil) _ GraphNodeReferencer = (*NodeRefreshableManagedResource)(nil)
@ -61,8 +60,7 @@ func (n *NodeRefreshableManagedResource) DynamicExpand(ctx EvalContext) (*Graph,
// Inform our instance expander about our expansion results above, // Inform our instance expander about our expansion results above,
// and then use it to calculate the instance addresses we'll expand for. // and then use it to calculate the instance addresses we'll expand for.
expander := ctx.InstanceExpander() expander := ctx.InstanceExpander()
for _, module := range expander.ExpandModule(n.Module) {
for _, module := range expander.ExpandModule(ctx.Path().Module()) {
switch { switch {
case count >= 0: case count >= 0:
expander.SetResourceCount(module, n.ResourceAddr().Resource, count) expander.SetResourceCount(module, n.ResourceAddr().Resource, count)
@ -72,7 +70,7 @@ func (n *NodeRefreshableManagedResource) DynamicExpand(ctx EvalContext) (*Graph,
expander.SetResourceSingle(module, n.ResourceAddr().Resource) expander.SetResourceSingle(module, n.ResourceAddr().Resource)
} }
} }
instanceAddrs := expander.ExpandResource(ctx.Path().Module(), n.ResourceAddr().Resource) instanceAddrs := expander.ExpandResource(n.Module, n.ResourceAddr().Resource)
// Our graph transformers require access to the full state, so we'll // Our graph transformers require access to the full state, so we'll
// temporarily lock it while we work on this. // temporarily lock it while we work on this.
@ -131,7 +129,7 @@ func (n *NodeRefreshableManagedResource) DynamicExpand(ctx EvalContext) (*Graph,
Name: "NodeRefreshableManagedResource", Name: "NodeRefreshableManagedResource",
} }
graph, diags := b.Build(ctx.Path()) graph, diags := b.Build(nil)
return graph, diags.ErrWithWarnings() return graph, diags.ErrWithWarnings()
} }

View File

@ -15,7 +15,6 @@ type NodeValidatableResource struct {
} }
var ( var (
_ GraphNodeModuleInstance = (*NodeValidatableResource)(nil)
_ GraphNodeEvalable = (*NodeValidatableResource)(nil) _ GraphNodeEvalable = (*NodeValidatableResource)(nil)
_ GraphNodeReferenceable = (*NodeValidatableResource)(nil) _ GraphNodeReferenceable = (*NodeValidatableResource)(nil)
_ GraphNodeReferencer = (*NodeValidatableResource)(nil) _ GraphNodeReferencer = (*NodeValidatableResource)(nil)