mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-27 09:21:14 -06:00
1ad97f6be8
Remove the Input flag threaded through the input graph creation process to prevent interpolation failures on module variables. Use an EvalOpFilter instead to inset the correct EvalNode during walkInput. Remove the EvalTryInterpolate type, and use the same ContinueOnErr flag as the output node for consistency and to try and keep the number possible eval node types down.
121 lines
3.2 KiB
Go
121 lines
3.2 KiB
Go
package terraform
|
|
|
|
import (
|
|
"log"
|
|
|
|
"github.com/hashicorp/terraform/config"
|
|
"github.com/hashicorp/terraform/config/module"
|
|
"github.com/hashicorp/terraform/dag"
|
|
)
|
|
|
|
// ModuleVariableTransformer is a GraphTransformer that adds all the variables
|
|
// in the configuration to the graph.
|
|
//
|
|
// This only adds variables that are referenced by other things in the graph.
|
|
// If a module variable is not referenced, it won't be added to the graph.
|
|
type ModuleVariableTransformer struct {
|
|
Module *module.Tree
|
|
|
|
DisablePrune bool // True if pruning unreferenced should be disabled
|
|
}
|
|
|
|
func (t *ModuleVariableTransformer) Transform(g *Graph) error {
|
|
return t.transform(g, nil, t.Module)
|
|
}
|
|
|
|
func (t *ModuleVariableTransformer) transform(g *Graph, parent, m *module.Tree) error {
|
|
// If no config, no variables
|
|
if m == nil {
|
|
return nil
|
|
}
|
|
|
|
// Transform all the children. This must be done BEFORE the transform
|
|
// above since child module variables can reference parent module variables.
|
|
for _, c := range m.Children() {
|
|
if err := t.transform(g, m, c); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// If we have a parent, we can determine if a module variable is being
|
|
// used, so we transform this.
|
|
if parent != nil {
|
|
if err := t.transformSingle(g, parent, m); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (t *ModuleVariableTransformer) transformSingle(g *Graph, parent, m *module.Tree) error {
|
|
// If we have no vars, we're done!
|
|
vars := m.Config().Variables
|
|
if len(vars) == 0 {
|
|
log.Printf("[TRACE] Module %#v has no variables, skipping.", m.Path())
|
|
return nil
|
|
}
|
|
|
|
// Look for usage of this module
|
|
var mod *config.Module
|
|
for _, modUse := range parent.Config().Modules {
|
|
if modUse.Name == m.Name() {
|
|
mod = modUse
|
|
break
|
|
}
|
|
}
|
|
if mod == nil {
|
|
log.Printf("[INFO] Module %#v not used, not adding variables", m.Path())
|
|
return nil
|
|
}
|
|
|
|
// Build the reference map so we can determine if we're referencing things.
|
|
refMap := NewReferenceMap(g.Vertices())
|
|
|
|
// Add all variables here
|
|
for _, v := range vars {
|
|
// Determine the value of the variable. If it isn't in the
|
|
// configuration then it was never set and that's not a problem.
|
|
var value *config.RawConfig
|
|
if raw, ok := mod.RawConfig.Raw[v.Name]; ok {
|
|
var err error
|
|
value, err = config.NewRawConfig(map[string]interface{}{
|
|
v.Name: raw,
|
|
})
|
|
if err != nil {
|
|
// This shouldn't happen because it is already in
|
|
// a RawConfig above meaning it worked once before.
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// Build the node.
|
|
//
|
|
// NOTE: For now this is just an "applyable" variable. As we build
|
|
// new graph builders for the other operations I suspect we'll
|
|
// find a way to parameterize this, require new transforms, etc.
|
|
node := &NodeApplyableModuleVariable{
|
|
PathValue: normalizeModulePath(m.Path()),
|
|
Config: v,
|
|
Value: value,
|
|
Module: t.Module,
|
|
}
|
|
|
|
if !t.DisablePrune {
|
|
// If the node is not referenced by anything, then we don't need
|
|
// to include it since it won't be used.
|
|
if matches := refMap.ReferencedBy(node); len(matches) == 0 {
|
|
log.Printf(
|
|
"[INFO] Not including %q in graph, nothing depends on it",
|
|
dag.VertexName(node))
|
|
continue
|
|
}
|
|
}
|
|
|
|
// Add it!
|
|
g.Add(node)
|
|
}
|
|
|
|
return nil
|
|
}
|