terraform: build resource graph, validate
This commit is contained in:
parent
9480783ee4
commit
d731d033f1
|
@ -9,6 +9,10 @@ import (
|
|||
"github.com/hashicorp/terraform/depgraph"
|
||||
)
|
||||
|
||||
// ResourceGraphRoot is the name of the resource graph root that should be
|
||||
// ignored since it doesn't map to an exact resource.
|
||||
const ResourceGraphRoot = "root"
|
||||
|
||||
// Config is the configuration that comes from loading a collection
|
||||
// of Terraform templates.
|
||||
type Config struct {
|
||||
|
@ -116,7 +120,7 @@ func (c *Config) ResourceGraph() *depgraph.Graph {
|
|||
}
|
||||
|
||||
// Create a root that just depends on everything else finishing.
|
||||
root := &depgraph.Noun{Name: "root"}
|
||||
root := &depgraph.Noun{Name: ResourceGraphRoot}
|
||||
for _, n := range nounsList {
|
||||
root.Deps = append(root.Deps, &depgraph.Dependency{
|
||||
Name: n.Name,
|
||||
|
|
|
@ -4,17 +4,5 @@ package terraform
|
|||
// can use to keep track of what real world resources it is actually
|
||||
// managing.
|
||||
type State struct {
|
||||
resources map[string]resourceState
|
||||
}
|
||||
|
||||
// resourceState is the state of a single resource.
|
||||
//
|
||||
// The ID is required and is some opaque string used to recognize
|
||||
// the realized resource.
|
||||
//
|
||||
// Extra is arbitrary extra metadata that the resource provider returns
|
||||
// that is sent back into the resource provider when it is needed.
|
||||
type resourceState struct {
|
||||
ID string
|
||||
Extra map[string]interface{}
|
||||
resources map[string]ResourceState
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/config"
|
||||
"github.com/hashicorp/terraform/depgraph"
|
||||
)
|
||||
|
||||
// Terraform is the primary structure that is used to interact with
|
||||
|
@ -12,6 +13,7 @@ import (
|
|||
// all resources, a resource tree, a specific resource, etc.
|
||||
type Terraform struct {
|
||||
config *config.Config
|
||||
graph *depgraph.Graph
|
||||
mapping map[*config.Resource]ResourceProvider
|
||||
variables map[string]string
|
||||
}
|
||||
|
@ -98,6 +100,13 @@ func New(c *Config) (*Terraform, error) {
|
|||
mapping[r] = provider
|
||||
}
|
||||
|
||||
// Build the resource graph
|
||||
graph := c.Config.ResourceGraph()
|
||||
if err := graph.Validate(); err != nil {
|
||||
errs = append(errs, fmt.Errorf(
|
||||
"Resource graph has an error: %s", err))
|
||||
}
|
||||
|
||||
// If we accumulated any errors, then return them all
|
||||
if len(errs) > 0 {
|
||||
return nil, &MultiError{Errors: errs}
|
||||
|
@ -105,6 +114,7 @@ func New(c *Config) (*Terraform, error) {
|
|||
|
||||
return &Terraform{
|
||||
config: c.Config,
|
||||
graph: graph,
|
||||
mapping: mapping,
|
||||
variables: c.Variables,
|
||||
}, nil
|
||||
|
|
|
@ -80,6 +80,24 @@ func TestNew(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNew_graphCycle(t *testing.T) {
|
||||
config := testConfig(t, "new-graph-cycle")
|
||||
tfConfig := &Config{
|
||||
Config: config,
|
||||
Providers: map[string]ResourceProviderFactory{
|
||||
"aws": testProviderFunc("aws", []string{"aws_instance"}),
|
||||
},
|
||||
}
|
||||
|
||||
tf, err := New(tfConfig)
|
||||
if err == nil {
|
||||
t.Fatal("should error")
|
||||
}
|
||||
if tf != nil {
|
||||
t.Fatalf("should not return tf")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNew_variables(t *testing.T) {
|
||||
config := testConfig(t, "new-variables")
|
||||
tfConfig := &Config{
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
resource "aws_instance" "foo" {
|
||||
ami = "${aws_instance.bar.id}"
|
||||
}
|
||||
|
||||
resource "aws_instance" "bar" {
|
||||
ami = "${aws_instance.foo.id}"
|
||||
}
|
Loading…
Reference in New Issue