Make sure outputs are removed when targeting

Similar to NodeApplyableOuptut, NodeDestroyableOutputs also need to stay
in the graph if any ancestor nodes

Use the same GraphNodeTargetDownstream method to keep them from being
pruned, since they are dependent on the output node and all its
descendants.
This commit is contained in:
James Bardin 2018-01-31 13:51:40 -05:00
parent ca4178b9ec
commit 7fbc35a36c
3 changed files with 29 additions and 1 deletions

View File

@ -7741,6 +7741,12 @@ func TestContext2Apply_destroyProvisionerWithOutput(t *testing.T) {
Resources: map[string]*ResourceState{
"aws_instance.foo": resourceState("aws_instance", "1"),
},
Outputs: map[string]*OutputState{
"value": {
Type: "string",
Value: "3",
},
},
},
&ModuleState{
Path: []string{"root", "mod"},
@ -7759,18 +7765,30 @@ func TestContext2Apply_destroyProvisionerWithOutput(t *testing.T) {
},
},
Destroy: true,
// targeting the source of the value used by all resources shoudl still
// destroy them all.
Targets: []string{"module.mod.aws_instance.baz"},
})
if _, err := ctx.Plan(); err != nil {
t.Fatal(err)
}
if _, err := ctx.Apply(); err != nil {
state, err := ctx.Apply()
if err != nil {
t.Fatal(err)
}
if !pr.ApplyCalled {
t.Fatal("provisioner not called")
}
// confirm all outputs were removed too
for _, mod := range state.Modules {
if len(mod.Outputs) > 0 {
t.Fatalf("output left in module state: %#v\n", mod)
}
}
}
func TestContext2Apply_targetedDestroyCountDeps(t *testing.T) {

View File

@ -122,6 +122,12 @@ func (n *NodeDestroyableOutput) RemoveIfNotTargeted() bool {
return true
}
// This will keep the destroy node in the graph if its corresponding output
// node is also in the destroy graph.
func (n *NodeDestroyableOutput) TargetDownstream(targetedDeps, untargetedDeps *dag.Set) bool {
return true
}
// GraphNodeReferencer
func (n *NodeDestroyableOutput) References() []string {
var result []string

View File

@ -17,3 +17,7 @@ module "mod2" {
source = "./mod2"
value = "${module.mod.value}"
}
output "value" {
value = "${local.value}"
}