mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-28 18:01:01 -06:00
68b900928d
This is a minimal integration of instances.Expander used just for resource count and for_each, for now just forcing modules to always be singletons because the rest of Terraform Core isn't ready to deal with expanding module calls yet. This doesn't integrate super cleanly yet because we still have some cleanup work to do in the design of the plan walk, to make it explicit that the nodes in the plan graph represent static configuration objects rather than expanded instances, including for modules. To make this work in the meantime, there is some shimming between addrs.Module and addrs.ModuleInstance to correct for the discontinuities that result from the fact that Terraform currently assumes that modules are always singletons.
97 lines
3.2 KiB
Go
97 lines
3.2 KiB
Go
package terraform
|
|
|
|
import (
|
|
"log"
|
|
|
|
"github.com/hashicorp/terraform/addrs"
|
|
"github.com/hashicorp/terraform/configs"
|
|
)
|
|
|
|
// nodeExpandModule represents a module call in the configuration that
|
|
// might expand into multiple module instances depending on how it is
|
|
// configured.
|
|
type nodeExpandModule struct {
|
|
CallerAddr addrs.ModuleInstance
|
|
Call addrs.ModuleCall
|
|
Config *configs.Module
|
|
}
|
|
|
|
var (
|
|
_ GraphNodeSubPath = (*nodeExpandModule)(nil)
|
|
_ RemovableIfNotTargeted = (*nodeExpandModule)(nil)
|
|
_ GraphNodeEvalable = (*nodeExpandModule)(nil)
|
|
_ GraphNodeReferencer = (*nodeExpandModule)(nil)
|
|
)
|
|
|
|
func (n *nodeExpandModule) Name() string {
|
|
return n.CallerAddr.Child(n.Call.Name, addrs.NoKey).String()
|
|
}
|
|
|
|
// GraphNodeSubPath implementation
|
|
func (n *nodeExpandModule) Path() addrs.ModuleInstance {
|
|
// Notice that the node represents the module call and so we report
|
|
// the parent module as the path. The module call we're representing
|
|
// might expand into multiple child module instances during our work here.
|
|
return n.CallerAddr
|
|
}
|
|
|
|
// GraphNodeReferencer implementation
|
|
func (n *nodeExpandModule) References() []*addrs.Reference {
|
|
// Expansion only uses the count and for_each expressions, so this
|
|
// particular graph node only refers to those.
|
|
// Individual variable values in the module call definition might also
|
|
// refer to other objects, but that's handled by
|
|
// NodeApplyableModuleVariable.
|
|
//
|
|
// Because our Path method returns the module instance that contains
|
|
// our call, these references will be correctly interpreted as being
|
|
// in the calling module's namespace, not the namespaces of any of the
|
|
// child module instances we might expand to during our evaluation.
|
|
var ret []*addrs.Reference
|
|
// TODO: Once count and for_each are actually supported, analyze their
|
|
// expressions for references here.
|
|
/*
|
|
if n.Config.Count != nil {
|
|
ret = append(ret, n.Config.Count.References()...)
|
|
}
|
|
if n.Config.ForEach != nil {
|
|
ret = append(ret, n.Config.ForEach.References()...)
|
|
}
|
|
*/
|
|
return ret
|
|
}
|
|
|
|
// RemovableIfNotTargeted implementation
|
|
func (n *nodeExpandModule) RemoveIfNotTargeted() bool {
|
|
// We need to add this so that this node will be removed if
|
|
// it isn't targeted or a dependency of a target.
|
|
return true
|
|
}
|
|
|
|
// GraphNodeEvalable
|
|
func (n *nodeExpandModule) EvalTree() EvalNode {
|
|
return &evalPrepareModuleExpansion{
|
|
CallerAddr: n.CallerAddr,
|
|
Call: n.Call,
|
|
Config: n.Config,
|
|
}
|
|
}
|
|
|
|
type evalPrepareModuleExpansion struct {
|
|
CallerAddr addrs.ModuleInstance
|
|
Call addrs.ModuleCall
|
|
Config *configs.Module
|
|
}
|
|
|
|
func (n *evalPrepareModuleExpansion) Eval(ctx EvalContext) (interface{}, error) {
|
|
// Modules don't support any of the repetition arguments yet, so their
|
|
// expansion type is always "single". We just record this here to make
|
|
// the expander data structure consistent for now.
|
|
// FIXME: Once the rest of Terraform Core is ready to support expanding
|
|
// modules, evaluate the "count" and "for_each" arguments here in a
|
|
// similar way as in EvalWriteResourceState.
|
|
log.Printf("[TRACE] evalPrepareModuleExpansion: %s is a singleton", n.CallerAddr.Child(n.Call.Name, addrs.NoKey))
|
|
ctx.InstanceExpander().SetModuleSingle(n.CallerAddr, n.Call)
|
|
return nil, nil
|
|
}
|