terraform: initial GraphBuilder impl
This commit is contained in:
parent
02bedd6850
commit
a73f939ee9
|
@ -0,0 +1,58 @@
|
||||||
|
package terraform
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform/config/module"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GraphBuilder is an interface that can be implemented and used with
|
||||||
|
// Terraform to build the graph that Terraform walks.
|
||||||
|
type GraphBuilder interface {
|
||||||
|
// Build builds the graph for the given module path. It is up to
|
||||||
|
// the interface implementation whether this build should expand
|
||||||
|
// the graph or not.
|
||||||
|
Build(path []string) (*Graph, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuiltinGraphBuilder is responsible for building the complete graph that
|
||||||
|
// Terraform uses for execution. It is an opinionated builder that defines
|
||||||
|
// the step order required to build a complete graph as is used and expected
|
||||||
|
// by Terraform.
|
||||||
|
//
|
||||||
|
// If you require a custom graph, you'll have to build it up manually
|
||||||
|
// on your own by building a new GraphBuilder implementation.
|
||||||
|
type BuiltinGraphBuilder struct {
|
||||||
|
// Root is the root module of the graph to build.
|
||||||
|
Root *module.Tree
|
||||||
|
|
||||||
|
// State is the global state. The proper module states will be looked
|
||||||
|
// up by graph path.
|
||||||
|
State *State
|
||||||
|
|
||||||
|
// Providers is the list of providers supported.
|
||||||
|
Providers []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build builds the graph according to the steps returned by Steps.
|
||||||
|
func (b *BuiltinGraphBuilder) Build(path []string) (*Graph, error) {
|
||||||
|
g := &Graph{Path: path}
|
||||||
|
for _, step := range b.Steps() {
|
||||||
|
if err := step.Transform(g); err != nil {
|
||||||
|
return g, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return g, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Steps returns the ordered list of GraphTransformers that must be executed
|
||||||
|
// to build a complete graph.
|
||||||
|
func (b *BuiltinGraphBuilder) Steps() []GraphTransformer {
|
||||||
|
return []GraphTransformer{
|
||||||
|
&ConfigTransformer{Module: b.Root},
|
||||||
|
&OrphanTransformer{State: b.State, Module: b.Root},
|
||||||
|
&TaintedTransformer{State: b.State},
|
||||||
|
&MissingProviderTransformer{Providers: b.Providers},
|
||||||
|
&ProviderTransformer{},
|
||||||
|
&PruneProviderTransformer{},
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package terraform
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBuiltinGraphBuilder_impl(t *testing.T) {
|
||||||
|
var _ GraphBuilder = new(BuiltinGraphBuilder)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test is not meant to test all the transforms but rather just
|
||||||
|
// to verify we get some basic sane graph out. Special tests to ensure
|
||||||
|
// specific ordering of steps should be added in other tests.
|
||||||
|
func TestBuiltinGraphBuilder(t *testing.T) {
|
||||||
|
b := &BuiltinGraphBuilder{
|
||||||
|
Root: testModule(t, "graph-builder-basic"),
|
||||||
|
}
|
||||||
|
|
||||||
|
g, err := b.Build(RootModulePath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := strings.TrimSpace(g.String())
|
||||||
|
expected := strings.TrimSpace(testBuiltinGraphBuilderBasicStr)
|
||||||
|
if actual != expected {
|
||||||
|
t.Fatalf("bad: %s", actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testBuiltinGraphBuilderBasicStr = `
|
||||||
|
aws_instance.db
|
||||||
|
provider.aws
|
||||||
|
aws_instance.web
|
||||||
|
aws_instance.db
|
||||||
|
provider.aws
|
||||||
|
provider.aws
|
||||||
|
`
|
|
@ -0,0 +1,5 @@
|
||||||
|
provider "aws" {}
|
||||||
|
resource "aws_instance" "db" {}
|
||||||
|
resource "aws_instance" "web" {
|
||||||
|
foo = "${aws_instance.db.id}"
|
||||||
|
}
|
Loading…
Reference in New Issue