terraform: test that unused providers are pruned

This commit is contained in:
Mitchell Hashimoto 2014-09-24 16:02:42 -07:00
parent a36b3e1ec5
commit 6904c131a7
3 changed files with 73 additions and 0 deletions

View File

@ -234,6 +234,9 @@ func Graph(opts *GraphOpts) (*depgraph.Graph, error) {
// Add the provider dependencies // Add the provider dependencies
graphAddResourceProviderDeps(g) graphAddResourceProviderDeps(g)
// Now, prune the providers that we aren't using.
graphPruneResourceProviders(g)
// Add explicit dependsOn dependencies to the graph // Add explicit dependsOn dependencies to the graph
graphAddExplicitDeps(g) graphAddExplicitDeps(g)
@ -1177,6 +1180,47 @@ func graphAddResourceProviderDeps(g *depgraph.Graph) {
} }
} }
// graphPruneResourceProviders will remove the GraphNodeResourceProvider
// nodes that aren't used in any way.
func graphPruneResourceProviders(g *depgraph.Graph) {
// First, build a mapping of the providers we have.
ps := make(map[string]struct{})
for _, n := range g.Nouns {
_, ok := n.Meta.(*GraphNodeResourceProvider)
if !ok {
continue
}
ps[n.Name] = struct{}{}
}
// Now go through all the dependencies throughout and find
// if any of these aren't reachable.
for _, n := range g.Nouns {
for _, dep := range n.Deps {
delete(ps, dep.Target.Name)
}
}
if len(ps) == 0 {
// We used all of them!
return
}
// Now go through and remove these nodes that aren't used
for i := 0; i < len(g.Nouns); i++ {
if _, ok := ps[g.Nouns[i].Name]; !ok {
continue
}
// Delete this node
copy(g.Nouns[i:], g.Nouns[i+1:])
g.Nouns[len(g.Nouns)-1] = nil
g.Nouns = g.Nouns[:len(g.Nouns)-1]
i--
}
}
// graphMapResourceProviderId goes through the graph and maps the // graphMapResourceProviderId goes through the graph and maps the
// ID of a resource provider node to each resource. This lets us know which // ID of a resource provider node to each resource. This lets us know which
// configuration is for which resource. // configuration is for which resource.

View File

@ -159,6 +159,21 @@ func TestGraph_moduleOrphan(t *testing.T) {
} }
} }
func TestGraph_providerPrune(t *testing.T) {
m := testModule(t, "graph-provider-prune")
g, err := Graph(&GraphOpts{Module: m})
if err != nil {
t.Fatalf("err: %s", err)
}
actual := strings.TrimSpace(g.String())
expected := strings.TrimSpace(testTerraformGraphProviderPruneStr)
if actual != expected {
t.Fatalf("bad:\n\n%s", actual)
}
}
func TestGraph_state(t *testing.T) { func TestGraph_state(t *testing.T) {
m := testModule(t, "graph-basic") m := testModule(t, "graph-basic")
state := &State{ state := &State{
@ -910,6 +925,15 @@ root
root -> aws_instance.old root -> aws_instance.old
` `
const testTerraformGraphProviderPruneStr = `
root: root
aws_load_balancer.weblb
aws_load_balancer.weblb -> provider.aws
provider.aws
root
root -> aws_load_balancer.weblb
`
const testTerraformGraphStateStr = ` const testTerraformGraphStateStr = `
root: root root: root
aws_instance.old aws_instance.old

View File

@ -0,0 +1,5 @@
provider "aws" {}
provider "digitalocean" {}
provider "openstack" {}
resource "aws_load_balancer" "weblb" {}