diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/terraform/transform_module_variable.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/terraform/transform_module_variable.go | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/terraform/transform_module_variable.go b/vendor/github.com/hashicorp/terraform/terraform/transform_module_variable.go new file mode 100644 index 00000000..467950bd --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/terraform/transform_module_variable.go @@ -0,0 +1,120 @@ +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 +} |