mirror of
https://github.com/opentofu/opentofu.git
synced 2025-01-27 00:46:25 -06:00
terraform: destroy edge must include resources through outputs
This fixes: `TestContext2Apply_moduleDestroyOrder` The new destroy graph wasn't properly creating edges that happened _through_ an output, it was only created the edges for _direct_ dependents. To fix this, the DestroyEdgeTransformer now creates the full transitive list of destroy edges by walking all ancestors. This will create more edges than are necessary but also will no longer miss resources through an output.
This commit is contained in:
parent
008b8b4c23
commit
f6161a7dc9
@ -0,0 +1,5 @@
|
||||
resource "aws_instance" "b" {
|
||||
value = "foo"
|
||||
}
|
||||
|
||||
output "output" { value = "${aws_instance.b.value}" }
|
@ -0,0 +1,7 @@
|
||||
resource "aws_instance" "a" {
|
||||
value = "${module.child.output}"
|
||||
}
|
||||
|
||||
module "child" {
|
||||
source = "./child"
|
||||
}
|
@ -116,8 +116,10 @@ func (t *DestroyEdgeTransformer) Transform(g *Graph) error {
|
||||
// in the graph. BUT if resource A is just pure destroy, then only
|
||||
// destroy A is in the graph, and create A is not.
|
||||
steps := []GraphTransformer{
|
||||
&OutputTransformer{Module: t.Module},
|
||||
&AttachResourceConfigTransformer{Module: t.Module},
|
||||
&AttachStateTransformer{State: t.State},
|
||||
&ReferenceTransformer{},
|
||||
}
|
||||
|
||||
// Go through all the nodes being destroyed and create a graph.
|
||||
@ -127,6 +129,7 @@ func (t *DestroyEdgeTransformer) Transform(g *Graph) error {
|
||||
// A, B (with no edges)
|
||||
//
|
||||
var tempG Graph
|
||||
var tempDestroyed []dag.Vertex
|
||||
for d, _ := range destroyers {
|
||||
// d is what is being destroyed. We parse the resource address
|
||||
// which it came from it is a panic if this fails.
|
||||
@ -140,6 +143,7 @@ func (t *DestroyEdgeTransformer) Transform(g *Graph) error {
|
||||
// attach config and state transformers then ask for references.
|
||||
node := &NodeAbstractResource{Addr: addr}
|
||||
tempG.Add(node)
|
||||
tempDestroyed = append(tempDestroyed, node)
|
||||
}
|
||||
|
||||
// Run the graph transforms so we have the information we need to
|
||||
@ -150,14 +154,22 @@ func (t *DestroyEdgeTransformer) Transform(g *Graph) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Create a reference map for easy lookup
|
||||
refMap := NewReferenceMap(tempG.Vertices())
|
||||
log.Printf("[TRACE] DestroyEdgeTransformer: reference graph: %s", tempG.String())
|
||||
|
||||
// Go through all the nodes in the graph and determine what they
|
||||
// depend on.
|
||||
for _, v := range tempG.Vertices() {
|
||||
// Find all the references
|
||||
refs, _ := refMap.References(v)
|
||||
for _, v := range tempDestroyed {
|
||||
// Find all descendents of this to determine the edges we'll depend on
|
||||
vs, err := tempG.Ancestors(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
refs := make([]dag.Vertex, 0, vs.Len())
|
||||
for _, raw := range vs.List() {
|
||||
refs = append(refs, raw.(dag.Vertex))
|
||||
}
|
||||
|
||||
log.Printf(
|
||||
"[TRACE] DestroyEdgeTransformer: creation node %q references %v",
|
||||
dag.VertexName(v), refs)
|
||||
|
@ -78,6 +78,24 @@ func TestDestroyEdgeTransformer_selfRef(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDestroyEdgeTransformer_module(t *testing.T) {
|
||||
g := Graph{Path: RootModulePath}
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "module.child.aws_instance.b"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "aws_instance.a"})
|
||||
tf := &DestroyEdgeTransformer{
|
||||
Module: testModule(t, "transform-destroy-edge-module"),
|
||||
}
|
||||
if err := tf.Transform(&g); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
actual := strings.TrimSpace(g.String())
|
||||
expected := strings.TrimSpace(testTransformDestroyEdgeModuleStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad:\n\n%s", actual)
|
||||
}
|
||||
}
|
||||
|
||||
type graphNodeCreatorTest struct {
|
||||
AddrString string
|
||||
}
|
||||
@ -125,6 +143,7 @@ test.B (destroy)
|
||||
const testTransformDestroyEdgeMultiStr = `
|
||||
test.A (destroy)
|
||||
test.B (destroy)
|
||||
test.C (destroy)
|
||||
test.B (destroy)
|
||||
test.C (destroy)
|
||||
test.C (destroy)
|
||||
@ -133,3 +152,9 @@ test.C (destroy)
|
||||
const testTransformDestroyEdgeSelfRefStr = `
|
||||
test.A (destroy)
|
||||
`
|
||||
|
||||
const testTransformDestroyEdgeModuleStr = `
|
||||
aws_instance.a (destroy)
|
||||
module.child.aws_instance.b (destroy)
|
||||
aws_instance.a (destroy)
|
||||
`
|
||||
|
Loading…
Reference in New Issue
Block a user