mirror of
https://github.com/opentofu/opentofu.git
synced 2025-01-15 11:13:09 -06:00
3bd2293152
The onld logic for locating comparing module paths no longer worked, and we can simplify the comparison by using the addrs.ModuleInstance string.
106 lines
2.8 KiB
Go
106 lines
2.8 KiB
Go
package terraform
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
|
|
"github.com/hashicorp/terraform/addrs"
|
|
)
|
|
|
|
// NodeModuleRemoved represents a module that is no longer in the
|
|
// config.
|
|
type NodeModuleRemoved struct {
|
|
Addr addrs.ModuleInstance
|
|
}
|
|
|
|
var (
|
|
_ GraphNodeSubPath = (*NodeModuleRemoved)(nil)
|
|
_ GraphNodeEvalable = (*NodeModuleRemoved)(nil)
|
|
_ GraphNodeReferencer = (*NodeModuleRemoved)(nil)
|
|
_ GraphNodeReferenceOutside = (*NodeModuleRemoved)(nil)
|
|
)
|
|
|
|
func (n *NodeModuleRemoved) Name() string {
|
|
return fmt.Sprintf("%s (removed)", n.Addr.String())
|
|
}
|
|
|
|
// GraphNodeSubPath
|
|
func (n *NodeModuleRemoved) Path() addrs.ModuleInstance {
|
|
return n.Addr
|
|
}
|
|
|
|
// GraphNodeEvalable
|
|
func (n *NodeModuleRemoved) EvalTree() EvalNode {
|
|
return &EvalOpFilter{
|
|
Ops: []walkOperation{walkRefresh, walkApply, walkDestroy},
|
|
Node: &EvalDeleteModule{
|
|
Addr: n.Addr,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (n *NodeModuleRemoved) ReferenceOutside() (selfPath, referencePath addrs.ModuleInstance) {
|
|
// Our "References" implementation indicates that this node depends on
|
|
// the call to the module it represents, which implicitly depends on
|
|
// everything inside the module. That reference must therefore be
|
|
// interpreted in terms of our parent module.
|
|
return n.Addr, n.Addr.Parent()
|
|
}
|
|
|
|
func (n *NodeModuleRemoved) References() []*addrs.Reference {
|
|
// We depend on the call to the module we represent, because that
|
|
// implicitly then depends on everything inside that module.
|
|
// Our ReferenceOutside implementation causes this to be interpreted
|
|
// within the parent module.
|
|
|
|
_, call := n.Addr.CallInstance()
|
|
return []*addrs.Reference{
|
|
{
|
|
Subject: call,
|
|
|
|
// No source range here, because there's nothing reasonable for
|
|
// us to return.
|
|
},
|
|
}
|
|
}
|
|
|
|
// EvalDeleteModule is an EvalNode implementation that removes an empty module
|
|
// entry from the state.
|
|
type EvalDeleteModule struct {
|
|
Addr addrs.ModuleInstance
|
|
}
|
|
|
|
func (n *EvalDeleteModule) Eval(ctx EvalContext) (interface{}, error) {
|
|
state, lock := ctx.State()
|
|
if state == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
// Get a write lock so we can access this instance
|
|
lock.Lock()
|
|
defer lock.Unlock()
|
|
|
|
// Make sure we have a clean state
|
|
// Destroyed resources aren't deleted, they're written with an ID of "".
|
|
state.prune()
|
|
|
|
// find the module and delete it
|
|
for i, m := range state.Modules {
|
|
// Since state is still using our old-style []string path representation,
|
|
// comparison is a little awkward. This can be simplified once state
|
|
// is updated to use addrs.ModuleInstance too.
|
|
if normalizeModulePath(m.Path).String() != n.Addr.String() {
|
|
continue
|
|
}
|
|
if !m.Empty() {
|
|
// a targeted apply may leave module resources even without a config,
|
|
// so just log this and return.
|
|
log.Printf("[DEBUG] not removing %s from state: not empty", n.Addr)
|
|
break
|
|
}
|
|
state.Modules = append(state.Modules[:i], state.Modules[i+1:]...)
|
|
break
|
|
}
|
|
return nil, nil
|
|
}
|