]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/configs/config.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / configs / config.go
1 package configs
2
3 import (
4 "sort"
5
6 version "github.com/hashicorp/go-version"
7 "github.com/hashicorp/hcl2/hcl"
8 "github.com/hashicorp/terraform/addrs"
9 )
10
11 // A Config is a node in the tree of modules within a configuration.
12 //
13 // The module tree is constructed by following ModuleCall instances recursively
14 // through the root module transitively into descendent modules.
15 //
16 // A module tree described in *this* package represents the static tree
17 // represented by configuration. During evaluation a static ModuleNode may
18 // expand into zero or more module instances depending on the use of count and
19 // for_each configuration attributes within each call.
20 type Config struct {
21 // RootModule points to the Config for the root module within the same
22 // module tree as this module. If this module _is_ the root module then
23 // this is self-referential.
24 Root *Config
25
26 // ParentModule points to the Config for the module that directly calls
27 // this module. If this is the root module then this field is nil.
28 Parent *Config
29
30 // Path is a sequence of module logical names that traverse from the root
31 // module to this config. Path is empty for the root module.
32 //
33 // This should only be used to display paths to the end-user in rare cases
34 // where we are talking about the static module tree, before module calls
35 // have been resolved. In most cases, an addrs.ModuleInstance describing
36 // a node in the dynamic module tree is better, since it will then include
37 // any keys resulting from evaluating "count" and "for_each" arguments.
38 Path addrs.Module
39
40 // ChildModules points to the Config for each of the direct child modules
41 // called from this module. The keys in this map match the keys in
42 // Module.ModuleCalls.
43 Children map[string]*Config
44
45 // Module points to the object describing the configuration for the
46 // various elements (variables, resources, etc) defined by this module.
47 Module *Module
48
49 // CallRange is the source range for the header of the module block that
50 // requested this module.
51 //
52 // This field is meaningless for the root module, where its contents are undefined.
53 CallRange hcl.Range
54
55 // SourceAddr is the source address that the referenced module was requested
56 // from, as specified in configuration.
57 //
58 // This field is meaningless for the root module, where its contents are undefined.
59 SourceAddr string
60
61 // SourceAddrRange is the location in the configuration source where the
62 // SourceAddr value was set, for use in diagnostic messages.
63 //
64 // This field is meaningless for the root module, where its contents are undefined.
65 SourceAddrRange hcl.Range
66
67 // Version is the specific version that was selected for this module,
68 // based on version constraints given in configuration.
69 //
70 // This field is nil if the module was loaded from a non-registry source,
71 // since versions are not supported for other sources.
72 //
73 // This field is meaningless for the root module, where it will always
74 // be nil.
75 Version *version.Version
76 }
77
78 // NewEmptyConfig constructs a single-node configuration tree with an empty
79 // root module. This is generally a pretty useless thing to do, so most callers
80 // should instead use BuildConfig.
81 func NewEmptyConfig() *Config {
82 ret := &Config{}
83 ret.Root = ret
84 ret.Children = make(map[string]*Config)
85 ret.Module = &Module{}
86 return ret
87 }
88
89 // Depth returns the number of "hops" the receiver is from the root of its
90 // module tree, with the root module having a depth of zero.
91 func (c *Config) Depth() int {
92 ret := 0
93 this := c
94 for this.Parent != nil {
95 ret++
96 this = this.Parent
97 }
98 return ret
99 }
100
101 // DeepEach calls the given function once for each module in the tree, starting
102 // with the receiver.
103 //
104 // A parent is always called before its children and children of a particular
105 // node are visited in lexicographic order by their names.
106 func (c *Config) DeepEach(cb func(c *Config)) {
107 cb(c)
108
109 names := make([]string, 0, len(c.Children))
110 for name := range c.Children {
111 names = append(names, name)
112 }
113
114 for _, name := range names {
115 c.Children[name].DeepEach(cb)
116 }
117 }
118
119 // AllModules returns a slice of all the receiver and all of its descendent
120 // nodes in the module tree, in the same order they would be visited by
121 // DeepEach.
122 func (c *Config) AllModules() []*Config {
123 var ret []*Config
124 c.DeepEach(func(c *Config) {
125 ret = append(ret, c)
126 })
127 return ret
128 }
129
130 // Descendent returns the descendent config that has the given path beneath
131 // the receiver, or nil if there is no such module.
132 //
133 // The path traverses the static module tree, prior to any expansion to handle
134 // count and for_each arguments.
135 //
136 // An empty path will just return the receiver, and is therefore pointless.
137 func (c *Config) Descendent(path addrs.Module) *Config {
138 current := c
139 for _, name := range path {
140 current = current.Children[name]
141 if current == nil {
142 return nil
143 }
144 }
145 return current
146 }
147
148 // DescendentForInstance is like Descendent except that it accepts a path
149 // to a particular module instance in the dynamic module graph, returning
150 // the node from the static module graph that corresponds to it.
151 //
152 // All instances created by a particular module call share the same
153 // configuration, so the keys within the given path are disregarded.
154 func (c *Config) DescendentForInstance(path addrs.ModuleInstance) *Config {
155 current := c
156 for _, step := range path {
157 current = current.Children[step.Name]
158 if current == nil {
159 return nil
160 }
161 }
162 return current
163 }
164
165 // ProviderTypes returns the names of each distinct provider type referenced
166 // in the receiving configuration.
167 //
168 // This is a helper for easily determining which provider types are required
169 // to fully interpret the configuration, though it does not include version
170 // information and so callers are expected to have already dealt with
171 // provider version selection in an earlier step and have identified suitable
172 // versions for each provider.
173 func (c *Config) ProviderTypes() []string {
174 m := make(map[string]struct{})
175 c.gatherProviderTypes(m)
176
177 ret := make([]string, 0, len(m))
178 for k := range m {
179 ret = append(ret, k)
180 }
181 sort.Strings(ret)
182 return ret
183 }
184 func (c *Config) gatherProviderTypes(m map[string]struct{}) {
185 if c == nil {
186 return
187 }
188
189 for _, pc := range c.Module.ProviderConfigs {
190 m[pc.Name] = struct{}{}
191 }
192 for _, rc := range c.Module.ManagedResources {
193 providerAddr := rc.ProviderConfigAddr()
194 m[providerAddr.Type] = struct{}{}
195 }
196 for _, rc := range c.Module.DataResources {
197 providerAddr := rc.ProviderConfigAddr()
198 m[providerAddr.Type] = struct{}{}
199 }
200
201 // Must also visit our child modules, recursively.
202 for _, cc := range c.Children {
203 cc.gatherProviderTypes(m)
204 }
205 }