2018-02-02 05:33:06 +01:00
|
|
|
package configs
|
|
|
|
|
2018-02-08 01:40:58 +01:00
|
|
|
import (
|
|
|
|
version "github.com/hashicorp/go-version"
|
|
|
|
"github.com/hashicorp/hcl2/hcl"
|
2018-04-06 20:10:21 +02:00
|
|
|
"github.com/hashicorp/terraform/addrs"
|
2018-02-08 01:40:58 +01:00
|
|
|
)
|
|
|
|
|
2018-02-02 05:33:06 +01:00
|
|
|
// A Config is a node in the tree of modules within a configuration.
|
|
|
|
//
|
|
|
|
// The module tree is constructed by following ModuleCall instances recursively
|
|
|
|
// through the root module transitively into descendent modules.
|
|
|
|
//
|
|
|
|
// A module tree described in *this* package represents the static tree
|
|
|
|
// represented by configuration. During evaluation a static ModuleNode may
|
|
|
|
// expand into zero or more module instances depending on the use of count and
|
|
|
|
// for_each configuration attributes within each call.
|
|
|
|
type Config struct {
|
|
|
|
// RootModule points to the Config for the root module within the same
|
|
|
|
// module tree as this module. If this module _is_ the root module then
|
|
|
|
// this is self-referential.
|
|
|
|
Root *Config
|
|
|
|
|
|
|
|
// ParentModule points to the Config for the module that directly calls
|
|
|
|
// this module. If this is the root module then this field is nil.
|
|
|
|
Parent *Config
|
|
|
|
|
2018-02-10 00:32:49 +01:00
|
|
|
// Path is a sequence of module logical names that traverse from the root
|
|
|
|
// module to this config. Path is empty for the root module.
|
|
|
|
//
|
2018-04-06 20:10:21 +02:00
|
|
|
// This should only be used to display paths to the end-user in rare cases
|
|
|
|
// where we are talking about the static module tree, before module calls
|
|
|
|
// have been resolved. In most cases, a addrs.ModuleInstance describing
|
|
|
|
// a node in the dynamic module tree is better, since it will then include
|
|
|
|
// any keys resulting from evaluating "count" and "for_each" arguments.
|
|
|
|
Path addrs.Module
|
2018-02-10 00:32:49 +01:00
|
|
|
|
2018-02-02 05:33:06 +01:00
|
|
|
// ChildModules points to the Config for each of the direct child modules
|
|
|
|
// called from this module. The keys in this map match the keys in
|
|
|
|
// Module.ModuleCalls.
|
|
|
|
Children map[string]*Config
|
|
|
|
|
2018-02-08 01:40:58 +01:00
|
|
|
// Module points to the object describing the configuration for the
|
2018-02-02 05:33:06 +01:00
|
|
|
// various elements (variables, resources, etc) defined by this module.
|
2018-02-08 01:40:58 +01:00
|
|
|
Module *Module
|
|
|
|
|
2018-02-09 03:56:48 +01:00
|
|
|
// CallRange is the source range for the header of the module block that
|
|
|
|
// requested this module.
|
|
|
|
//
|
|
|
|
// This field is meaningless for the root module, where its contents are undefined.
|
|
|
|
CallRange hcl.Range
|
|
|
|
|
2018-02-08 01:40:58 +01:00
|
|
|
// SourceAddr is the source address that the referenced module was requested
|
|
|
|
// from, as specified in configuration.
|
|
|
|
//
|
|
|
|
// This field is meaningless for the root module, where its contents are undefined.
|
|
|
|
SourceAddr string
|
|
|
|
|
|
|
|
// SourceAddrRange is the location in the configuration source where the
|
|
|
|
// SourceAddr value was set, for use in diagnostic messages.
|
|
|
|
//
|
|
|
|
// This field is meaningless for the root module, where its contents are undefined.
|
|
|
|
SourceAddrRange hcl.Range
|
|
|
|
|
|
|
|
// Version is the specific version that was selected for this module,
|
|
|
|
// based on version constraints given in configuration.
|
|
|
|
//
|
2018-02-09 03:56:48 +01:00
|
|
|
// This field is nil if the module was loaded from a non-registry source,
|
|
|
|
// since versions are not supported for other sources.
|
|
|
|
//
|
|
|
|
// This field is meaningless for the root module, where it will always
|
|
|
|
// be nil.
|
2018-02-08 01:40:58 +01:00
|
|
|
Version *version.Version
|
|
|
|
}
|
|
|
|
|
|
|
|
// Depth returns the number of "hops" the receiver is from the root of its
|
|
|
|
// module tree, with the root module having a depth of zero.
|
|
|
|
func (c *Config) Depth() int {
|
|
|
|
ret := 0
|
|
|
|
this := c
|
|
|
|
for this.Parent != nil {
|
|
|
|
ret++
|
|
|
|
this = this.Parent
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
|
|
|
// DeepEach calls the given function once for each module in the tree, starting
|
|
|
|
// with the receiver.
|
|
|
|
//
|
|
|
|
// A parent is always called before its children and children of a particular
|
|
|
|
// node are visited in lexicographic order by their names.
|
|
|
|
func (c *Config) DeepEach(cb func(c *Config)) {
|
|
|
|
cb(c)
|
|
|
|
|
|
|
|
names := make([]string, 0, len(c.Children))
|
|
|
|
for name := range c.Children {
|
|
|
|
names = append(names, name)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, name := range names {
|
|
|
|
c.Children[name].DeepEach(cb)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// AllModules returns a slice of all the receiver and all of its descendent
|
|
|
|
// nodes in the module tree, in the same order they would be visited by
|
|
|
|
// DeepEach.
|
|
|
|
func (c *Config) AllModules() []*Config {
|
|
|
|
var ret []*Config
|
|
|
|
c.DeepEach(func(c *Config) {
|
|
|
|
ret = append(ret, c)
|
|
|
|
})
|
|
|
|
return ret
|
2018-02-02 05:33:06 +01:00
|
|
|
}
|
2018-03-28 00:31:05 +02:00
|
|
|
|
|
|
|
// Descendent returns the descendent config that has the given path beneath
|
|
|
|
// the receiver, or nil if there is no such module.
|
|
|
|
//
|
|
|
|
// The path traverses the static module tree, prior to any expansion to handle
|
|
|
|
// count and for_each arguments.
|
|
|
|
//
|
|
|
|
// An empty path will just return the receiver, and is therefore pointless.
|
2018-04-06 20:10:21 +02:00
|
|
|
func (c *Config) Descendent(path addrs.Module) *Config {
|
2018-03-28 00:31:05 +02:00
|
|
|
current := c
|
|
|
|
for _, name := range path {
|
|
|
|
current = current.Children[name]
|
|
|
|
if current == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return current
|
|
|
|
}
|
2018-04-06 20:10:21 +02:00
|
|
|
|
|
|
|
// DescendentForInstance is like Descendent except that it accepts a path
|
|
|
|
// to a particular module instance in the dynamic module graph, returning
|
|
|
|
// the node from the static module graph that corresponds to it.
|
|
|
|
//
|
|
|
|
// All instances created by a particular module call share the same
|
|
|
|
// configuration, so the keys within the given path are disregarded.
|
|
|
|
func (c *Config) DescendentForInstance(path addrs.ModuleInstance) *Config {
|
|
|
|
current := c
|
|
|
|
for _, step := range path {
|
|
|
|
current = current.Children[step.Name]
|
|
|
|
if current == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return current
|
|
|
|
}
|