]>
Commit | Line | Data |
---|---|---|
bae9f6d2 JC |
1 | package terraform |
2 | ||
3 | import ( | |
4 | "log" | |
5 | ||
6 | "github.com/hashicorp/terraform/config" | |
7 | "github.com/hashicorp/terraform/config/module" | |
8 | "github.com/hashicorp/terraform/dag" | |
9 | ) | |
10 | ||
11 | // ModuleVariableTransformer is a GraphTransformer that adds all the variables | |
12 | // in the configuration to the graph. | |
13 | // | |
14 | // This only adds variables that are referenced by other things in the graph. | |
15 | // If a module variable is not referenced, it won't be added to the graph. | |
16 | type ModuleVariableTransformer struct { | |
17 | Module *module.Tree | |
18 | ||
19 | DisablePrune bool // True if pruning unreferenced should be disabled | |
20 | } | |
21 | ||
22 | func (t *ModuleVariableTransformer) Transform(g *Graph) error { | |
23 | return t.transform(g, nil, t.Module) | |
24 | } | |
25 | ||
26 | func (t *ModuleVariableTransformer) transform(g *Graph, parent, m *module.Tree) error { | |
27 | // If no config, no variables | |
28 | if m == nil { | |
29 | return nil | |
30 | } | |
31 | ||
32 | // Transform all the children. This must be done BEFORE the transform | |
33 | // above since child module variables can reference parent module variables. | |
34 | for _, c := range m.Children() { | |
35 | if err := t.transform(g, m, c); err != nil { | |
36 | return err | |
37 | } | |
38 | } | |
39 | ||
40 | // If we have a parent, we can determine if a module variable is being | |
41 | // used, so we transform this. | |
42 | if parent != nil { | |
43 | if err := t.transformSingle(g, parent, m); err != nil { | |
44 | return err | |
45 | } | |
46 | } | |
47 | ||
48 | return nil | |
49 | } | |
50 | ||
51 | func (t *ModuleVariableTransformer) transformSingle(g *Graph, parent, m *module.Tree) error { | |
52 | // If we have no vars, we're done! | |
53 | vars := m.Config().Variables | |
54 | if len(vars) == 0 { | |
55 | log.Printf("[TRACE] Module %#v has no variables, skipping.", m.Path()) | |
56 | return nil | |
57 | } | |
58 | ||
59 | // Look for usage of this module | |
60 | var mod *config.Module | |
61 | for _, modUse := range parent.Config().Modules { | |
62 | if modUse.Name == m.Name() { | |
63 | mod = modUse | |
64 | break | |
65 | } | |
66 | } | |
67 | if mod == nil { | |
68 | log.Printf("[INFO] Module %#v not used, not adding variables", m.Path()) | |
69 | return nil | |
70 | } | |
71 | ||
72 | // Build the reference map so we can determine if we're referencing things. | |
73 | refMap := NewReferenceMap(g.Vertices()) | |
74 | ||
75 | // Add all variables here | |
76 | for _, v := range vars { | |
77 | // Determine the value of the variable. If it isn't in the | |
78 | // configuration then it was never set and that's not a problem. | |
79 | var value *config.RawConfig | |
80 | if raw, ok := mod.RawConfig.Raw[v.Name]; ok { | |
81 | var err error | |
82 | value, err = config.NewRawConfig(map[string]interface{}{ | |
83 | v.Name: raw, | |
84 | }) | |
85 | if err != nil { | |
86 | // This shouldn't happen because it is already in | |
87 | // a RawConfig above meaning it worked once before. | |
88 | panic(err) | |
89 | } | |
90 | } | |
91 | ||
92 | // Build the node. | |
93 | // | |
94 | // NOTE: For now this is just an "applyable" variable. As we build | |
95 | // new graph builders for the other operations I suspect we'll | |
96 | // find a way to parameterize this, require new transforms, etc. | |
97 | node := &NodeApplyableModuleVariable{ | |
98 | PathValue: normalizeModulePath(m.Path()), | |
99 | Config: v, | |
100 | Value: value, | |
101 | Module: t.Module, | |
102 | } | |
103 | ||
104 | if !t.DisablePrune { | |
105 | // If the node is not referenced by anything, then we don't need | |
106 | // to include it since it won't be used. | |
107 | if matches := refMap.ReferencedBy(node); len(matches) == 0 { | |
108 | log.Printf( | |
109 | "[INFO] Not including %q in graph, nothing depends on it", | |
110 | dag.VertexName(node)) | |
111 | continue | |
112 | } | |
113 | } | |
114 | ||
115 | // Add it! | |
116 | g.Add(node) | |
117 | } | |
118 | ||
119 | return nil | |
120 | } |