]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/terraform/transform_config.go
Initial transfer of provider code
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / terraform / transform_config.go
1 package terraform
2
3 import (
4 "errors"
5 "fmt"
6 "log"
7 "sync"
8
9 "github.com/hashicorp/terraform/config"
10 "github.com/hashicorp/terraform/config/module"
11 "github.com/hashicorp/terraform/dag"
12 )
13
14 // ConfigTransformer is a GraphTransformer that adds all the resources
15 // from the configuration to the graph.
16 //
17 // The module used to configure this transformer must be the root module.
18 //
19 // Only resources are added to the graph. Variables, outputs, and
20 // providers must be added via other transforms.
21 //
22 // Unlike ConfigTransformerOld, this transformer creates a graph with
23 // all resources including module resources, rather than creating module
24 // nodes that are then "flattened".
25 type ConfigTransformer struct {
26 Concrete ConcreteResourceNodeFunc
27
28 // Module is the module to add resources from.
29 Module *module.Tree
30
31 // Unique will only add resources that aren't already present in the graph.
32 Unique bool
33
34 // Mode will only add resources that match the given mode
35 ModeFilter bool
36 Mode config.ResourceMode
37
38 l sync.Mutex
39 uniqueMap map[string]struct{}
40 }
41
42 func (t *ConfigTransformer) Transform(g *Graph) error {
43 // Lock since we use some internal state
44 t.l.Lock()
45 defer t.l.Unlock()
46
47 // If no module is given, we don't do anything
48 if t.Module == nil {
49 return nil
50 }
51
52 // If the module isn't loaded, that is simply an error
53 if !t.Module.Loaded() {
54 return errors.New("module must be loaded for ConfigTransformer")
55 }
56
57 // Reset the uniqueness map. If we're tracking uniques, then populate
58 // it with addresses.
59 t.uniqueMap = make(map[string]struct{})
60 defer func() { t.uniqueMap = nil }()
61 if t.Unique {
62 for _, v := range g.Vertices() {
63 if rn, ok := v.(GraphNodeResource); ok {
64 t.uniqueMap[rn.ResourceAddr().String()] = struct{}{}
65 }
66 }
67 }
68
69 // Start the transformation process
70 return t.transform(g, t.Module)
71 }
72
73 func (t *ConfigTransformer) transform(g *Graph, m *module.Tree) error {
74 // If no config, do nothing
75 if m == nil {
76 return nil
77 }
78
79 // Add our resources
80 if err := t.transformSingle(g, m); err != nil {
81 return err
82 }
83
84 // Transform all the children.
85 for _, c := range m.Children() {
86 if err := t.transform(g, c); err != nil {
87 return err
88 }
89 }
90
91 return nil
92 }
93
94 func (t *ConfigTransformer) transformSingle(g *Graph, m *module.Tree) error {
95 log.Printf("[TRACE] ConfigTransformer: Starting for path: %v", m.Path())
96
97 // Get the configuration for this module
98 conf := m.Config()
99
100 // Build the path we're at
101 path := m.Path()
102
103 // Write all the resources out
104 for _, r := range conf.Resources {
105 // Build the resource address
106 addr, err := parseResourceAddressConfig(r)
107 if err != nil {
108 panic(fmt.Sprintf(
109 "Error parsing config address, this is a bug: %#v", r))
110 }
111 addr.Path = path
112
113 // If this is already in our uniqueness map, don't add it again
114 if _, ok := t.uniqueMap[addr.String()]; ok {
115 continue
116 }
117
118 // Remove non-matching modes
119 if t.ModeFilter && addr.Mode != t.Mode {
120 continue
121 }
122
123 // Build the abstract node and the concrete one
124 abstract := &NodeAbstractResource{Addr: addr}
125 var node dag.Vertex = abstract
126 if f := t.Concrete; f != nil {
127 node = f(abstract)
128 }
129
130 // Add it to the graph
131 g.Add(node)
132 }
133
134 return nil
135 }