terraform: start FlattenGraph impl.
This commit is contained in:
parent
5e767f63b9
commit
12c30feb0f
|
@ -2,6 +2,7 @@ package terraform
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/config"
|
||||
"github.com/hashicorp/terraform/config/module"
|
||||
|
@ -152,7 +153,75 @@ func (n *graphNodeModuleExpanded) EvalTree() EvalNode {
|
|||
}
|
||||
}
|
||||
|
||||
// GraphNodeFlattenable impl.
|
||||
func (n *graphNodeModuleExpanded) FlattenGraph() *Graph {
|
||||
graph := n.Subgraph()
|
||||
|
||||
// Build the string that represents the path. We do this once here
|
||||
// so that we only have to compute it once. The block below is in {}
|
||||
// so that parts drops out of scope immediately.
|
||||
var pathStr string
|
||||
{
|
||||
parts := make([]string, 0, len(graph.Path)*2)
|
||||
for _, p := range graph.Path[1:] {
|
||||
parts = append(parts, "module", p)
|
||||
}
|
||||
|
||||
pathStr = strings.Join(parts, ".")
|
||||
}
|
||||
|
||||
// Go over each vertex in the graph and wrap the configuration
|
||||
// items so that the dependencies properly map to the modules.
|
||||
// See the docs for graphNodeModuleWrappable for more info.
|
||||
for _, v := range graph.Vertices() {
|
||||
if sn, ok := v.(graphNodeModuleSkippable); ok && sn.FlattenSkip() {
|
||||
graph.Remove(v)
|
||||
continue
|
||||
}
|
||||
|
||||
wn, ok := v.(graphNodeModuleWrappable)
|
||||
if !ok {
|
||||
panic("unwrappable node: " + dag.VertexName(v))
|
||||
}
|
||||
|
||||
graph.Replace(v, &graphNodeModuleFlatWrap{
|
||||
graphNodeModuleWrappable: wn,
|
||||
|
||||
Path: graph.Path,
|
||||
PathString: pathStr,
|
||||
})
|
||||
}
|
||||
|
||||
return graph
|
||||
}
|
||||
|
||||
// GraphNodeSubgraph impl.
|
||||
func (n *graphNodeModuleExpanded) Subgraph() *Graph {
|
||||
return n.Graph
|
||||
}
|
||||
|
||||
// This interface can be implemented to be skipped/ignored when
|
||||
// flattening the module graph.
|
||||
type graphNodeModuleSkippable interface {
|
||||
FlattenSkip() bool
|
||||
}
|
||||
|
||||
// This is the interface that all nodes within a module graph must
|
||||
// implement to be wrapped for flattening.
|
||||
type graphNodeModuleWrappable interface {
|
||||
graphNodeConfig
|
||||
}
|
||||
|
||||
// graphNodeModuleFlatWrap wraps elements of the module graph
|
||||
// when they are flattened so that the dependency information is
|
||||
// correct.
|
||||
type graphNodeModuleFlatWrap struct {
|
||||
graphNodeModuleWrappable
|
||||
|
||||
Path []string
|
||||
PathString string
|
||||
}
|
||||
|
||||
func (n *graphNodeModuleFlatWrap) Name() string {
|
||||
return fmt.Sprintf("%s.%s", n.PathString, n.graphNodeModuleWrappable.Name())
|
||||
}
|
||||
|
|
|
@ -39,3 +39,42 @@ func TestGraphNodeConfigModuleExpand(t *testing.T) {
|
|||
t.Fatalf("bad:\n\n%s", actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGraphNodeConfigModuleExpandFlatten(t *testing.T) {
|
||||
mod := testModule(t, "graph-node-module-flatten")
|
||||
|
||||
node := &GraphNodeConfigModule{
|
||||
Path: []string{RootModuleName, "child"},
|
||||
Module: &config.Module{},
|
||||
Tree: nil,
|
||||
}
|
||||
|
||||
g, err := node.Expand(&BasicGraphBuilder{
|
||||
Steps: []GraphTransformer{
|
||||
&ConfigTransformer{Module: mod},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
fg := g.(GraphNodeFlattenable)
|
||||
|
||||
actual := strings.TrimSpace(fg.FlattenGraph().String())
|
||||
expected := strings.TrimSpace(testGraphNodeModuleExpandFlattenStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad:\n\n%s", actual)
|
||||
}
|
||||
}
|
||||
|
||||
const testGraphNodeModuleExpandStr = `
|
||||
aws_instance.bar
|
||||
aws_instance.foo
|
||||
aws_instance.foo
|
||||
module inputs
|
||||
module inputs
|
||||
`
|
||||
|
||||
const testGraphNodeModuleExpandFlattenStr = `
|
||||
module.child.aws_instance.foo
|
||||
`
|
||||
|
|
|
@ -113,11 +113,3 @@ func TestGraphNodeConfigVariable_impl(t *testing.T) {
|
|||
var _ dag.NamedVertex = new(GraphNodeConfigVariable)
|
||||
var _ graphNodeConfig = new(GraphNodeConfigVariable)
|
||||
}
|
||||
|
||||
const testGraphNodeModuleExpandStr = `
|
||||
aws_instance.bar
|
||||
aws_instance.foo
|
||||
aws_instance.foo
|
||||
module inputs
|
||||
module inputs
|
||||
`
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
resource "aws_instance" "foo" {}
|
|
@ -0,0 +1,3 @@
|
|||
module "child" {
|
||||
source = "./child"
|
||||
}
|
|
@ -45,3 +45,8 @@ func (n *graphNodeModuleInput) Name() string {
|
|||
func (n *graphNodeModuleInput) EvalTree() EvalNode {
|
||||
return &EvalSetVariables{Variables: n.Variables}
|
||||
}
|
||||
|
||||
// graphNodeModuleSkippable impl.
|
||||
func (n *graphNodeModuleInput) FlattenSkip() bool {
|
||||
return true
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue