Allow targeting of orphan nodes

Fixes #3852. We now run the OrphanTransformer even when targeting, and
pass it the list of targets following resource expansion.
This commit is contained in:
James Nugent 2015-11-13 13:17:14 -06:00
parent bfb770ee89
commit 38bb9f2416
3 changed files with 28 additions and 16 deletions

View File

@ -105,9 +105,8 @@ func (b *BuiltinGraphBuilder) Steps(path []string) []GraphTransformer {
// Create all our resources from the configuration and state // Create all our resources from the configuration and state
&ConfigTransformer{Module: b.Root}, &ConfigTransformer{Module: b.Root},
&OrphanTransformer{ &OrphanTransformer{
State: b.State, State: b.State,
Module: b.Root, Module: b.Root,
Targeting: len(b.Targets) > 0,
}, },
// Output-related transformations // Output-related transformations

View File

@ -163,9 +163,9 @@ func (n *GraphNodeConfigResource) DynamicExpand(ctx EvalContext) (*Graph, error)
// expand orphans, which have all the same semantics in a destroy // expand orphans, which have all the same semantics in a destroy
// as a primary. // as a primary.
steps = append(steps, &OrphanTransformer{ steps = append(steps, &OrphanTransformer{
State: state, State: state,
View: n.Resource.Id(), View: n.Resource.Id(),
Targeting: len(n.Targets) > 0, Targets: n.Targets,
}) })
steps = append(steps, &DeposedTransformer{ steps = append(steps, &DeposedTransformer{

View File

@ -2,7 +2,7 @@ package terraform
import ( import (
"fmt" "fmt"
"log" "strings"
"github.com/hashicorp/terraform/config" "github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/config/module" "github.com/hashicorp/terraform/config/module"
@ -29,7 +29,7 @@ type OrphanTransformer struct {
// Targets are user-specified resources to target. We need to be aware of // Targets are user-specified resources to target. We need to be aware of
// these so we don't improperly identify orphans when they've just been // these so we don't improperly identify orphans when they've just been
// filtered out of the graph via targeting. // filtered out of the graph via targeting.
Targeting bool Targets []ResourceAddress
// View, if non-nil will set a view on the module state. // View, if non-nil will set a view on the module state.
View string View string
@ -41,13 +41,6 @@ func (t *OrphanTransformer) Transform(g *Graph) error {
return nil return nil
} }
if t.Targeting {
log.Printf("Skipping orphan transformer because we have targets.")
// If we are in a run where we are targeting nodes, we won't process
// orphans for this run.
return nil
}
// Build up all our state representatives // Build up all our state representatives
resourceRep := make(map[string]struct{}) resourceRep := make(map[string]struct{})
for _, v := range g.Vertices() { for _, v := range g.Vertices() {
@ -74,8 +67,24 @@ func (t *OrphanTransformer) Transform(g *Graph) error {
state = state.View(t.View) state = state.View(t.View)
} }
// Go over each resource orphan and add it to the graph.
resourceOrphans := state.Orphans(config) resourceOrphans := state.Orphans(config)
if len(t.Targets) > 0 {
var targetedOrphans []string
for _, o := range resourceOrphans {
targeted := false
for _, t := range t.Targets {
prefix := fmt.Sprintf("%s.%s.%d", t.Type, t.Name, t.Index)
if strings.HasPrefix(o, prefix) {
targeted = true
}
}
if targeted {
targetedOrphans = append(targetedOrphans, o)
}
}
resourceOrphans = targetedOrphans
}
resourceVertexes = make([]dag.Vertex, len(resourceOrphans)) resourceVertexes = make([]dag.Vertex, len(resourceOrphans))
for i, k := range resourceOrphans { for i, k := range resourceOrphans {
// If this orphan is represented by some other node somehow, // If this orphan is represented by some other node somehow,
@ -173,6 +182,10 @@ type graphNodeOrphanResource struct {
dependentOn []string dependentOn []string
} }
func (n *graphNodeOrphanResource) ResourceAddress() *ResourceAddress {
return n.ResourceAddress()
}
func (n *graphNodeOrphanResource) DependableName() []string { func (n *graphNodeOrphanResource) DependableName() []string {
return []string{n.dependableName()} return []string{n.dependableName()}
} }