terraform: TargetsTransformer on destroy plan

This enables targeting to work properly on planning destroys
This commit is contained in:
Mitchell Hashimoto 2016-10-20 18:59:02 -07:00
parent 2d4f65cc94
commit ab4ebcc5c7
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
6 changed files with 33 additions and 6 deletions

View File

@ -528,8 +528,9 @@ func (c *Context) Plan() (*Plan, error) {
var err error var err error
if c.destroy && X_newDestroy { if c.destroy && X_newDestroy {
graph, err = (&DestroyPlanGraphBuilder{ graph, err = (&DestroyPlanGraphBuilder{
Module: c.module, Module: c.module,
State: c.state, State: c.state,
Targets: c.targets,
}).Build(RootModulePath) }).Build(RootModulePath)
} else { } else {
graph, err = c.Graph(&ContextGraphOpts{Validate: true}) graph, err = c.Graph(&ContextGraphOpts{Validate: true})

View File

@ -16,6 +16,9 @@ type DestroyPlanGraphBuilder struct {
// State is the current state // State is the current state
State *State State *State
// Targets are resources to target
Targets []string
} }
// See GraphBuilder // See GraphBuilder
@ -41,6 +44,9 @@ func (b *DestroyPlanGraphBuilder) Steps() []GraphTransformer {
State: b.State, State: b.State,
}, },
// Target
&TargetsTransformer{Targets: b.Targets},
// Attach the configuration to any resources // Attach the configuration to any resources
&AttachResourceConfigTransformer{Module: b.Module}, &AttachResourceConfigTransformer{Module: b.Module},

View File

@ -24,8 +24,6 @@ type graphNodeConfig interface {
// configuration graph need to implement in order to be be addressed / targeted // configuration graph need to implement in order to be be addressed / targeted
// properly. // properly.
type GraphNodeAddressable interface { type GraphNodeAddressable interface {
graphNodeConfig
ResourceAddress() *ResourceAddress ResourceAddress() *ResourceAddress
} }
@ -35,7 +33,5 @@ type GraphNodeAddressable interface {
// provided will contain every target provided, and each implementing graph // provided will contain every target provided, and each implementing graph
// node must filter this list to targets considered relevant. // node must filter this list to targets considered relevant.
type GraphNodeTargetable interface { type GraphNodeTargetable interface {
GraphNodeAddressable
SetTargets([]ResourceAddress) SetTargets([]ResourceAddress)
} }

View File

@ -28,6 +28,8 @@ type NodeAbstractResource struct {
Config *config.Resource // Config is the resource in the config Config *config.Resource // Config is the resource in the config
ResourceState *ResourceState // ResourceState is the ResourceState for this ResourceState *ResourceState // ResourceState is the ResourceState for this
Targets []ResourceAddress // Set from GraphNodeTargetable
} }
func (n *NodeAbstractResource) Name() string { func (n *NodeAbstractResource) Name() string {
@ -111,6 +113,16 @@ func (n *NodeAbstractResource) ResourceAddr() *ResourceAddress {
return n.Addr return n.Addr
} }
// GraphNodeAddressable, TODO: remove, used by target, should unify
func (n *NodeAbstractResource) ResourceAddress() *ResourceAddress {
return n.ResourceAddr()
}
// GraphNodeTargetable
func (n *NodeAbstractResource) SetTargets(targets []ResourceAddress) {
n.Targets = targets
}
// GraphNodeAttachResourceState // GraphNodeAttachResourceState
func (n *NodeAbstractResource) AttachResourceState(s *ResourceState) { func (n *NodeAbstractResource) AttachResourceState(s *ResourceState) {
n.ResourceState = s n.ResourceState = s

View File

@ -63,6 +63,11 @@ func (n *NodeDestroyResource) DynamicExpand(ctx EvalContext) (*Graph, error) {
View: n.Config.Id(), View: n.Config.Id(),
}) })
// Target
steps = append(steps, &TargetsTransformer{
ParsedTargets: n.Targets,
})
// Always end with the root being added // Always end with the root being added
steps = append(steps, &RootTransformer{}) steps = append(steps, &RootTransformer{})

View File

@ -28,8 +28,10 @@ func (t *TargetsTransformer) Transform(g *Graph) error {
if err != nil { if err != nil {
return err return err
} }
t.ParsedTargets = addrs t.ParsedTargets = addrs
} }
if len(t.ParsedTargets) > 0 { if len(t.ParsedTargets) > 0 {
targetedNodes, err := t.selectTargetedNodes(g, t.ParsedTargets) targetedNodes, err := t.selectTargetedNodes(g, t.ParsedTargets)
if err != nil { if err != nil {
@ -50,6 +52,7 @@ func (t *TargetsTransformer) Transform(g *Graph) error {
} }
} }
} }
return nil return nil
} }
@ -62,6 +65,7 @@ func (t *TargetsTransformer) parseTargetAddresses() ([]ResourceAddress, error) {
} }
addrs[i] = *ta addrs[i] = *ta
} }
return addrs, nil return addrs, nil
} }
@ -107,6 +111,7 @@ func (t *TargetsTransformer) selectTargetedNodes(
} }
} }
} }
return targetedNodes, nil return targetedNodes, nil
} }
@ -116,12 +121,14 @@ func (t *TargetsTransformer) nodeIsTarget(
if !ok { if !ok {
return false return false
} }
addr := r.ResourceAddress() addr := r.ResourceAddress()
for _, targetAddr := range addrs { for _, targetAddr := range addrs {
if targetAddr.Equals(addr) { if targetAddr.Equals(addr) {
return true return true
} }
} }
return false return false
} }