opentofu/terraform/node_local.go
Martin Atkins de7b834de7 core: Local and output values must reference destroy nodes too
Because we currently rely on the ReferenceTransformer to introduce the
necessary edges between local/output values and resource destroy nodes, we
must include the destroy phase of any resource we depend on in the
references of these.

This works in conjunction with the changes in the prior commit to restore
correct handling of dependencies for local and output values during
destroy.

With the current design, several seemingly-separate parts of the code must
all coincidentally agree with one another for destroy edges to be created
properly, which makes this code very hard to maintain. In future we should
refactor this so that ReferenceTransformer doesn't create edges for
destroy nodes at all, and have _all_ destroy edges (including
create_before_destroy) be dealt with in the single DestroyEdgeTransformer,
where they can be maintained and unit tested together.
2018-10-16 18:49:20 -07:00

71 lines
1.6 KiB
Go

package terraform
import (
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs"
"github.com/hashicorp/terraform/dag"
"github.com/hashicorp/terraform/lang"
)
// NodeLocal represents a named local value in a particular module.
//
// Local value nodes only have one operation, common to all walk types:
// evaluate the result and place it in state.
type NodeLocal struct {
Addr addrs.AbsLocalValue
Config *configs.Local
}
var (
_ GraphNodeSubPath = (*NodeLocal)(nil)
_ RemovableIfNotTargeted = (*NodeLocal)(nil)
_ GraphNodeReferenceable = (*NodeLocal)(nil)
_ GraphNodeReferencer = (*NodeLocal)(nil)
_ GraphNodeEvalable = (*NodeLocal)(nil)
_ dag.GraphNodeDotter = (*NodeLocal)(nil)
)
func (n *NodeLocal) Name() string {
return n.Addr.String()
}
// GraphNodeSubPath
func (n *NodeLocal) Path() addrs.ModuleInstance {
return n.Addr.Module
}
// RemovableIfNotTargeted
func (n *NodeLocal) RemoveIfNotTargeted() bool {
return true
}
// GraphNodeReferenceable
func (n *NodeLocal) ReferenceableAddrs() []addrs.Referenceable {
return []addrs.Referenceable{n.Addr.LocalValue}
}
// GraphNodeReferencer
func (n *NodeLocal) References() []*addrs.Reference {
refs, _ := lang.ReferencesInExpr(n.Config.Expr)
return appendResourceDestroyReferences(refs)
}
// GraphNodeEvalable
func (n *NodeLocal) EvalTree() EvalNode {
return &EvalLocal{
Addr: n.Addr.LocalValue,
Expr: n.Config.Expr,
}
}
// dag.GraphNodeDotter impl.
func (n *NodeLocal) DotNode(name string, opts *dag.DotOpts) *dag.DotNode {
return &dag.DotNode{
Name: name,
Attrs: map[string]string{
"label": n.Name(),
"shape": "note",
},
}
}