terraform: initial GraphBuilder impl

This commit is contained in:
Mitchell Hashimoto 2015-02-02 12:04:02 +01:00
parent 02bedd6850
commit a73f939ee9
3 changed files with 102 additions and 0 deletions

View File

@ -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{},
}
}

View File

@ -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
`

View File

@ -0,0 +1,5 @@
provider "aws" {}
resource "aws_instance" "db" {}
resource "aws_instance" "web" {
foo = "${aws_instance.db.id}"
}