diff --git a/terraform/graph.go b/terraform/graph.go index 175db7b86..22866dc82 100644 --- a/terraform/graph.go +++ b/terraform/graph.go @@ -73,6 +73,16 @@ func Graph(c *config.Config, s *State) *depgraph.Graph { return g } +// GraphFull completes the raw graph returned by Graph by initializing +// all the resource providers. +// +// This may add new nodes to the graph, since it can add new resource +// providers based on the mapping given in the case that a provider +// configuration was not specified. +// +// Various errors can be returned from this function, such as if there +// is no matching provider for a resource, a resource provider can't be +// created, etc. func GraphFull(g *depgraph.Graph, ps map[string]ResourceProviderFactory) error { // Add missing providers from the mapping if err := graphAddMissingResourceProviders(g, ps); err != nil { diff --git a/terraform/graph_test.go b/terraform/graph_test.go index dd721dc07..76a795e2a 100644 --- a/terraform/graph_test.go +++ b/terraform/graph_test.go @@ -52,6 +52,63 @@ func TestGraph_state(t *testing.T) { } } +func TestGraphFull(t *testing.T) { + rpAws := new(MockResourceProvider) + rpOS := new(MockResourceProvider) + + rpAws.ResourcesReturn = []ResourceType{ + ResourceType{Name: "aws_instance"}, + ResourceType{Name: "aws_load_balancer"}, + ResourceType{Name: "aws_security_group"}, + } + rpOS.ResourcesReturn = []ResourceType{ + ResourceType{Name: "openstack_floating_ip"}, + } + + ps := map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(rpAws), + "open": testProviderFuncFixed(rpOS), + } + + c := testConfig(t, "graph-basic") + g := Graph(c, nil) + if err := GraphFull(g, ps); err != nil { + t.Fatalf("err: %s", err) + } + if err := g.Validate(); err != nil { + t.Fatalf("err: %s", err) + } + + // A helper to help get us the provider for a resource. + graphProvider := func(n string) ResourceProvider { + return g.Noun(n).Meta.(*GraphNodeResource).Resource.Provider + } + + // Test a couple + if graphProvider("aws_instance.web") != rpAws { + t.Fatalf("bad: %#v", graphProvider("aws_instance.web")) + } + if graphProvider("openstack_floating_ip.random") != rpOS { + t.Fatalf("bad: %#v", graphProvider("openstack_floating_ip.random")) + } + + // Test that all providers have been set + for _, n := range g.Nouns { + switch m := n.Meta.(type) { + case *GraphNodeResource: + if m.Resource.Provider == nil { + t.Fatalf("bad: %#v", m) + } + case *GraphNodeResourceProvider: + if len(m.Providers) == 0 { + t.Fatalf("bad: %#v", m) + } + default: + continue + } + } +} + const testTerraformGraphStr = ` root: root aws_instance.web diff --git a/terraform/terraform_test.go b/terraform/terraform_test.go index 2d958d2b1..2f425be29 100644 --- a/terraform/terraform_test.go +++ b/terraform/terraform_test.go @@ -110,46 +110,6 @@ func TestTerraformApply_vars(t *testing.T) { } } -func TestTerraformGraph(t *testing.T) { - rpAws := new(MockResourceProvider) - rpOS := new(MockResourceProvider) - - rpAws.ResourcesReturn = []ResourceType{ - ResourceType{Name: "aws_instance"}, - ResourceType{Name: "aws_load_balancer"}, - ResourceType{Name: "aws_security_group"}, - } - rpOS.ResourcesReturn = []ResourceType{ - ResourceType{Name: "openstack_floating_ip"}, - } - - tf := testTerraform2(t, &Config{ - Providers: map[string]ResourceProviderFactory{ - "aws": testProviderFuncFixed(rpAws), - "open": testProviderFuncFixed(rpOS), - }, - }) - - c := testConfig(t, "graph-basic") - - g, err := tf.Graph(c, nil) - if err != nil { - t.Fatalf("err: %s", err) - } - - // A helper to help get us the provider for a resource. - graphProvider := func(n string) ResourceProvider { - return g.Noun(n).Meta.(*GraphNodeResource).Resource.Provider - } - - if graphProvider("aws_instance.web") != rpAws { - t.Fatalf("bad: %#v", graphProvider("aws_instance.web")) - } - if graphProvider("openstack_floating_ip.random") != rpOS { - t.Fatalf("bad: %#v", graphProvider("openstack_floating_ip.random")) - } -} - func TestTerraformPlan(t *testing.T) { tf := testTerraform(t, "plan-good")