opentofu/terraform/transform_destroy_edge.go
2016-10-19 13:38:52 -07:00

65 lines
2.0 KiB
Go

package terraform
// GraphNodeDestroyer must be implemented by nodes that destroy resources.
type GraphNodeDestroyer interface {
// ResourceAddr is the address of the resource that is being
// destroyed by this node. If this returns nil, then this node
// is not destroying anything.
DestroyAddr() *ResourceAddress
}
// DestroyEdgeTransformer is a GraphTransformer that creates the proper
// references for destroy resources. Destroy resources are more complex
// in that they must be depend on the destruction of resources that
// in turn depend on the CREATION of the node being destroy.
//
// That is complicated. Visually:
//
// B_d -> A_d -> A -> B
//
// Notice that A destroy depends on B destroy, while B create depends on
// A create. They're inverted. This must be done for example because often
// dependent resources will block parent resources from deleting. Concrete
// example: VPC with subnets, the VPC can't be deleted while there are
// still subnets.
type DestroyEdgeTransformer struct{}
func (t *DestroyEdgeTransformer) Transform(g *Graph) error {
// Build a map of what is being destroyed (by address string) to
// the list of destroyers. In general there will only be one destroyer
// but to make it more robust we support multiple.
destroyers := make(map[string][]GraphNodeDestroyer)
for _, v := range g.Vertices() {
dn, ok := v.(GraphNodeDestroyer)
if !ok {
continue
}
addr := dn.DestroyAddr()
if addr == nil {
continue
}
key := addr.String()
destroyers[key] = append(destroyers[key], dn)
}
// If we aren't destroying anything, there will be no edges to make
// so just exit early and avoid future work.
if len(destroyers) == 0 {
return nil
}
// Go through the all destroyers and find what they're destroying.
// Use this to find the dependencies, look up if any of them are being
// destroyed, and to make the proper edge.
for _, ds := range destroyers {
for _, d := range ds {
// TODO
println(d)
}
}
return nil
}