configs: Start using the new "addrs" package types for modules
We initially just mimicked our old practice of using []string for module paths here, but the addrs package now gives us a pair of types that better capture the two different kinds of module addresses we are dealing with: static addresses (nodes in the configuration tree) and dynamic/instance addresses (which can represent the situation where multiple instances are created from a single module call). This distinction still remains rather artificial since we don't yet have support for count or for_each on module calls, but this is intended to lay the foundations for that to be added later, and in the mean time just gives us some handy helper functions for parsing and formatting these address types.
This commit is contained in:
parent
a16ca2ec53
commit
cd51864d84
|
@ -1,5 +1,9 @@
|
||||||
package addrs
|
package addrs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
// Module is an address for a module call within configuration. This is
|
// Module is an address for a module call within configuration. This is
|
||||||
// the static counterpart of ModuleInstance, representing a traversal through
|
// the static counterpart of ModuleInstance, representing a traversal through
|
||||||
// the static module call tree in configuration and does not take into account
|
// the static module call tree in configuration and does not take into account
|
||||||
|
@ -19,6 +23,13 @@ type Module []string
|
||||||
// represented by RootModuleInstance.
|
// represented by RootModuleInstance.
|
||||||
var RootModule Module
|
var RootModule Module
|
||||||
|
|
||||||
|
func (m Module) String() string {
|
||||||
|
if len(m) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strings.Join([]string(m), ".")
|
||||||
|
}
|
||||||
|
|
||||||
// Child returns the address of a child call in the receiver, identified by the
|
// Child returns the address of a child call in the receiver, identified by the
|
||||||
// given name.
|
// given name.
|
||||||
func (m Module) Child(name string) Module {
|
func (m Module) Child(name string) Module {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package addrs
|
package addrs
|
||||||
|
|
||||||
|
import "bytes"
|
||||||
|
|
||||||
// ModuleInstance is an address for a particular module instance within the
|
// ModuleInstance is an address for a particular module instance within the
|
||||||
// dynamic module tree. This is an extension of the static traversals
|
// dynamic module tree. This is an extension of the static traversals
|
||||||
// represented by type Module that deals with the possibility of a single
|
// represented by type Module that deals with the possibility of a single
|
||||||
|
@ -40,3 +42,22 @@ func (m ModuleInstance) Parent() ModuleInstance {
|
||||||
}
|
}
|
||||||
return m[:len(m)-1]
|
return m[:len(m)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// String returns a string representation of the receiver, in the format used
|
||||||
|
// within e.g. user-provided resource addresses.
|
||||||
|
//
|
||||||
|
// The address of the root module has the empty string as its representation.
|
||||||
|
func (m ModuleInstance) String() string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
sep := ""
|
||||||
|
for _, step := range m {
|
||||||
|
buf.WriteString(sep)
|
||||||
|
buf.WriteString("module.")
|
||||||
|
buf.WriteString(step.Name)
|
||||||
|
if step.InstanceKey != NoKey {
|
||||||
|
buf.WriteString(step.InstanceKey.String())
|
||||||
|
}
|
||||||
|
sep = "."
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package configs
|
||||||
import (
|
import (
|
||||||
version "github.com/hashicorp/go-version"
|
version "github.com/hashicorp/go-version"
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl2/hcl"
|
||||||
|
"github.com/hashicorp/terraform/addrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Config is a node in the tree of modules within a configuration.
|
// A Config is a node in the tree of modules within a configuration.
|
||||||
|
@ -27,13 +28,12 @@ type Config struct {
|
||||||
// Path is a sequence of module logical names that traverse from the root
|
// Path is a sequence of module logical names that traverse from the root
|
||||||
// module to this config. Path is empty for the root module.
|
// module to this config. Path is empty for the root module.
|
||||||
//
|
//
|
||||||
// This should not be used to display a path to the end-user, since
|
// This should only be used to display paths to the end-user in rare cases
|
||||||
// our UI conventions call for us to return a module address string in that
|
// where we are talking about the static module tree, before module calls
|
||||||
// case, and a module address string ought to be built from the dynamic
|
// have been resolved. In most cases, a addrs.ModuleInstance describing
|
||||||
// module tree (resulting from evaluating "count" and "for_each" arguments
|
// a node in the dynamic module tree is better, since it will then include
|
||||||
// on our calls to produce potentially multiple child instances per call)
|
// any keys resulting from evaluating "count" and "for_each" arguments.
|
||||||
// rather than from our static module tree.
|
Path addrs.Module
|
||||||
Path []string
|
|
||||||
|
|
||||||
// ChildModules points to the Config for each of the direct child modules
|
// 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
|
// called from this module. The keys in this map match the keys in
|
||||||
|
@ -121,7 +121,7 @@ func (c *Config) AllModules() []*Config {
|
||||||
// count and for_each arguments.
|
// count and for_each arguments.
|
||||||
//
|
//
|
||||||
// An empty path will just return the receiver, and is therefore pointless.
|
// An empty path will just return the receiver, and is therefore pointless.
|
||||||
func (c *Config) Descendent(path []string) *Config {
|
func (c *Config) Descendent(path addrs.Module) *Config {
|
||||||
current := c
|
current := c
|
||||||
for _, name := range path {
|
for _, name := range path {
|
||||||
current = current.Children[name]
|
current = current.Children[name]
|
||||||
|
@ -131,3 +131,20 @@ func (c *Config) Descendent(path []string) *Config {
|
||||||
}
|
}
|
||||||
return current
|
return current
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue