2015-01-26 22:17:52 -06:00
|
|
|
package terraform
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/hashicorp/terraform/config"
|
2015-01-27 13:10:51 -06:00
|
|
|
"github.com/hashicorp/terraform/dag"
|
2015-01-26 22:17:52 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
// OrphanTransformer is a GraphTransformer that adds orphans to the
|
|
|
|
// graph. This transformer adds both resource and module orphans.
|
|
|
|
type OrphanTransformer struct {
|
2015-01-26 23:32:32 -06:00
|
|
|
// State is the global state. We require the global state to
|
|
|
|
// properly find module orphans at our path.
|
|
|
|
State *State
|
|
|
|
|
|
|
|
// Config is just the configuration of our current module.
|
2015-01-26 22:17:52 -06:00
|
|
|
Config *config.Config
|
|
|
|
}
|
|
|
|
|
2015-01-26 23:23:27 -06:00
|
|
|
func (t *OrphanTransformer) Transform(g *Graph) error {
|
2015-01-26 23:32:32 -06:00
|
|
|
state := t.State.ModuleByPath(g.Path)
|
|
|
|
if state == nil {
|
|
|
|
// If there is no state for our module, there can't be any orphans
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-01-27 13:00:24 -06:00
|
|
|
// Go over each resource orphan and add it to the graph.
|
2015-01-27 13:18:17 -06:00
|
|
|
resourceOrphans := state.Orphans(t.Config)
|
|
|
|
resourceVertexes := make([]dag.Vertex, len(resourceOrphans))
|
|
|
|
for i, k := range resourceOrphans {
|
2015-01-27 16:56:01 -06:00
|
|
|
resourceVertexes[i] = g.Add(&graphNodeOrphanResource{
|
|
|
|
ResourceName: k,
|
|
|
|
dependentOn: state.Resources[k].Dependencies,
|
|
|
|
})
|
2015-01-26 22:17:52 -06:00
|
|
|
}
|
|
|
|
|
2015-01-27 13:10:51 -06:00
|
|
|
// Go over each module orphan and add it to the graph. We store the
|
|
|
|
// vertexes and states outside so that we can connect dependencies later.
|
|
|
|
moduleOrphans := t.State.ModuleOrphans(g.Path, t.Config)
|
|
|
|
moduleVertexes := make([]dag.Vertex, len(moduleOrphans))
|
|
|
|
for i, path := range moduleOrphans {
|
2015-01-27 16:56:01 -06:00
|
|
|
moduleVertexes[i] = g.Add(&graphNodeOrphanModule{
|
|
|
|
Path: path,
|
|
|
|
dependentOn: t.State.ModuleByPath(path).Dependencies,
|
|
|
|
})
|
2015-01-27 13:10:51 -06:00
|
|
|
}
|
|
|
|
|
2015-01-27 13:18:17 -06:00
|
|
|
// Now do the dependencies. We do this _after_ adding all the orphan
|
|
|
|
// nodes above because there are cases in which the orphans themselves
|
|
|
|
// depend on other orphans.
|
|
|
|
|
|
|
|
// Resource dependencies
|
2015-01-27 16:56:01 -06:00
|
|
|
for _, v := range resourceVertexes {
|
|
|
|
g.ConnectDependent(v)
|
2015-01-27 13:18:17 -06:00
|
|
|
}
|
|
|
|
|
2015-01-27 13:10:51 -06:00
|
|
|
// Module dependencies
|
2015-01-27 16:56:01 -06:00
|
|
|
for _, v := range moduleVertexes {
|
|
|
|
g.ConnectDependent(v)
|
2015-01-27 13:00:24 -06:00
|
|
|
}
|
2015-01-26 22:17:52 -06:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-01-27 13:00:24 -06:00
|
|
|
// graphNodeOrphanModule is the graph vertex representing an orphan resource..
|
|
|
|
type graphNodeOrphanModule struct {
|
|
|
|
Path []string
|
2015-01-27 16:56:01 -06:00
|
|
|
|
|
|
|
dependentOn []string
|
2015-01-27 13:00:24 -06:00
|
|
|
}
|
|
|
|
|
2015-01-27 15:44:27 -06:00
|
|
|
func (n *graphNodeOrphanModule) DependableName() []string {
|
|
|
|
return []string{n.dependableName()}
|
|
|
|
}
|
|
|
|
|
2015-01-27 16:56:01 -06:00
|
|
|
func (n *graphNodeOrphanModule) DependentOn() []string {
|
|
|
|
return n.dependentOn
|
|
|
|
}
|
|
|
|
|
2015-01-27 13:00:24 -06:00
|
|
|
func (n *graphNodeOrphanModule) Name() string {
|
2015-01-27 15:44:27 -06:00
|
|
|
return fmt.Sprintf("%s (orphan)", n.dependableName())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n *graphNodeOrphanModule) dependableName() string {
|
|
|
|
return fmt.Sprintf("module.%s", n.Path[len(n.Path)-1])
|
2015-01-27 13:00:24 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// graphNodeOrphanResource is the graph vertex representing an orphan resource..
|
2015-01-26 22:17:52 -06:00
|
|
|
type graphNodeOrphanResource struct {
|
|
|
|
ResourceName string
|
2015-01-27 16:56:01 -06:00
|
|
|
|
|
|
|
dependentOn []string
|
2015-01-26 22:17:52 -06:00
|
|
|
}
|
|
|
|
|
2015-01-27 15:44:27 -06:00
|
|
|
func (n *graphNodeOrphanResource) DependableName() []string {
|
|
|
|
return []string{n.dependableName()}
|
|
|
|
}
|
|
|
|
|
2015-01-27 16:56:01 -06:00
|
|
|
func (n *graphNodeOrphanResource) DependentOn() []string {
|
|
|
|
return n.dependentOn
|
|
|
|
}
|
|
|
|
|
2015-01-26 22:17:52 -06:00
|
|
|
func (n *graphNodeOrphanResource) Name() string {
|
|
|
|
return fmt.Sprintf("%s (orphan)", n.ResourceName)
|
|
|
|
}
|
2015-01-27 15:44:27 -06:00
|
|
|
|
|
|
|
func (n *graphNodeOrphanResource) dependableName() string {
|
|
|
|
return n.ResourceName
|
|
|
|
}
|