core: GraphNodeAttachDestroyer
Add a graphNodeAttachDestroy interface, so destroy nodes can be attached to their companion create node. The creator can then reference the CreateBeforeDestroy status of the destroyer, determining if the current state needs to be replaced or deposed. This is needed when a node is forced to become CreateBeforeDestroy by a dependency rather than the config, since because the config is immutable, only the destroyer is aware that it has been forced CreateBeforeDestroy.
This commit is contained in:
parent
fb70eaa7d1
commit
fa87397f50
|
@ -12,6 +12,8 @@ import (
|
||||||
// it is ready to be applied and is represented by a diff.
|
// it is ready to be applied and is represented by a diff.
|
||||||
type NodeApplyableResourceInstance struct {
|
type NodeApplyableResourceInstance struct {
|
||||||
*NodeAbstractResourceInstance
|
*NodeAbstractResourceInstance
|
||||||
|
|
||||||
|
destroyNode GraphNodeDestroyerCBD
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -22,6 +24,27 @@ var (
|
||||||
_ GraphNodeEvalable = (*NodeApplyableResourceInstance)(nil)
|
_ GraphNodeEvalable = (*NodeApplyableResourceInstance)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GraphNodeAttachDestroyer
|
||||||
|
func (n *NodeApplyableResourceInstance) AttachDestroyNode(d GraphNodeDestroyerCBD) {
|
||||||
|
n.destroyNode = d
|
||||||
|
}
|
||||||
|
|
||||||
|
// createBeforeDestroy checks this nodes config status and the status af any
|
||||||
|
// companion destroy node for CreateBeforeDestroy.
|
||||||
|
func (n *NodeApplyableResourceInstance) createBeforeDestroy() bool {
|
||||||
|
cbd := false
|
||||||
|
|
||||||
|
if n.Config != nil && n.Config.Managed != nil {
|
||||||
|
cbd = n.Config.Managed.CreateBeforeDestroy
|
||||||
|
}
|
||||||
|
|
||||||
|
if n.destroyNode != nil {
|
||||||
|
cbd = cbd || n.destroyNode.CreateBeforeDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
return cbd
|
||||||
|
}
|
||||||
|
|
||||||
// GraphNodeCreator
|
// GraphNodeCreator
|
||||||
func (n *NodeApplyableResourceInstance) CreateAddr() *addrs.AbsResourceInstance {
|
func (n *NodeApplyableResourceInstance) CreateAddr() *addrs.AbsResourceInstance {
|
||||||
addr := n.ResourceInstanceAddr()
|
addr := n.ResourceInstanceAddr()
|
||||||
|
@ -42,8 +65,7 @@ func (n *NodeApplyableResourceInstance) References() []*addrs.Reference {
|
||||||
// would create a dependency cycle. We make a compromise here of requiring
|
// would create a dependency cycle. We make a compromise here of requiring
|
||||||
// changes to be updated across two applies in this case, since the first
|
// changes to be updated across two applies in this case, since the first
|
||||||
// plan will use the old values.
|
// plan will use the old values.
|
||||||
cbd := n.Config != nil && n.Config.Managed != nil && n.Config.Managed.CreateBeforeDestroy
|
if !n.createBeforeDestroy() {
|
||||||
if !cbd {
|
|
||||||
for _, ref := range ret {
|
for _, ref := range ret {
|
||||||
switch tr := ref.Subject.(type) {
|
switch tr := ref.Subject.(type) {
|
||||||
case addrs.ResourceInstance:
|
case addrs.ResourceInstance:
|
||||||
|
@ -214,7 +236,7 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
|
||||||
destroy = diffApply.GetDestroy() || diffApply.RequiresNew()
|
destroy = diffApply.GetDestroy() || diffApply.RequiresNew()
|
||||||
}
|
}
|
||||||
|
|
||||||
if destroy && n.Config.Managed != nil && n.Config.Managed.CreateBeforeDestroy {
|
if destroy && n.createBeforeDestroy() {
|
||||||
createBeforeDestroyEnabled = true
|
createBeforeDestroyEnabled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,20 @@ type GraphNodeDestroyerCBD interface {
|
||||||
ModifyCreateBeforeDestroy(bool) error
|
ModifyCreateBeforeDestroy(bool) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GraphNodeAttachDestroyer is implemented by applyable nodes that have a
|
||||||
|
// companion destroy node. This allows the creation node to look up the status
|
||||||
|
// of the destroy node and determine if it needs to depose the existing state,
|
||||||
|
// or replace it.
|
||||||
|
// If a node is not marked as create-before-destroy in the configuration, but a
|
||||||
|
// dependency forces that status, only the destroy node will be aware of that
|
||||||
|
// status.
|
||||||
|
type GraphNodeAttachDestroyer interface {
|
||||||
|
// AttachDestroyNode takes a destroy node and saves a reference to that
|
||||||
|
// node in the receiver, so it can later check the status of
|
||||||
|
// CreateBeforeDestroy().
|
||||||
|
AttachDestroyNode(n GraphNodeDestroyerCBD)
|
||||||
|
}
|
||||||
|
|
||||||
// CBDEdgeTransformer modifies the edges of CBD nodes that went through
|
// CBDEdgeTransformer modifies the edges of CBD nodes that went through
|
||||||
// the DestroyEdgeTransformer to have the right dependencies. There are
|
// the DestroyEdgeTransformer to have the right dependencies. There are
|
||||||
// two real tasks here:
|
// two real tasks here:
|
||||||
|
|
|
@ -110,6 +110,16 @@ func (t *DestroyEdgeTransformer) Transform(g *Graph) error {
|
||||||
dag.VertexName(a), dag.VertexName(a_d))
|
dag.VertexName(a), dag.VertexName(a_d))
|
||||||
|
|
||||||
g.Connect(&DestroyEdge{S: a, T: a_d})
|
g.Connect(&DestroyEdge{S: a, T: a_d})
|
||||||
|
|
||||||
|
// Attach the destroy node to the creator
|
||||||
|
// There really shouldn't be more than one destroyer, but even if
|
||||||
|
// there are, any of them will represent the correct
|
||||||
|
// CreateBeforeDestroy status.
|
||||||
|
if n, ok := cn.(GraphNodeAttachDestroyer); ok {
|
||||||
|
if d, ok := d.(GraphNodeDestroyerCBD); ok {
|
||||||
|
n.AttachDestroyNode(d)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue