github.com/hashicorp/terraform-plugin-sdk@v1.17.2/terraform/node_module_removed.go (about)

     1  package terraform
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/hashicorp/terraform-plugin-sdk/internal/addrs"
     7  )
     8  
     9  // NodeModuleRemoved represents a module that is no longer in the
    10  // config.
    11  type NodeModuleRemoved struct {
    12  	Addr addrs.ModuleInstance
    13  }
    14  
    15  var (
    16  	_ GraphNodeSubPath          = (*NodeModuleRemoved)(nil)
    17  	_ RemovableIfNotTargeted    = (*NodeModuleRemoved)(nil)
    18  	_ GraphNodeEvalable         = (*NodeModuleRemoved)(nil)
    19  	_ GraphNodeReferencer       = (*NodeModuleRemoved)(nil)
    20  	_ GraphNodeReferenceOutside = (*NodeModuleRemoved)(nil)
    21  )
    22  
    23  func (n *NodeModuleRemoved) Name() string {
    24  	return fmt.Sprintf("%s (removed)", n.Addr.String())
    25  }
    26  
    27  // GraphNodeSubPath
    28  func (n *NodeModuleRemoved) Path() addrs.ModuleInstance {
    29  	return n.Addr
    30  }
    31  
    32  // GraphNodeEvalable
    33  func (n *NodeModuleRemoved) EvalTree() EvalNode {
    34  	return &EvalOpFilter{
    35  		Ops: []walkOperation{walkRefresh, walkApply, walkDestroy},
    36  		Node: &EvalCheckModuleRemoved{
    37  			Addr: n.Addr,
    38  		},
    39  	}
    40  }
    41  
    42  func (n *NodeModuleRemoved) ReferenceOutside() (selfPath, referencePath addrs.ModuleInstance) {
    43  	// Our "References" implementation indicates that this node depends on
    44  	// the call to the module it represents, which implicitly depends on
    45  	// everything inside the module. That reference must therefore be
    46  	// interpreted in terms of our parent module.
    47  	return n.Addr, n.Addr.Parent()
    48  }
    49  
    50  func (n *NodeModuleRemoved) References() []*addrs.Reference {
    51  	// We depend on the call to the module we represent, because that
    52  	// implicitly then depends on everything inside that module.
    53  	// Our ReferenceOutside implementation causes this to be interpreted
    54  	// within the parent module.
    55  
    56  	_, call := n.Addr.CallInstance()
    57  	return []*addrs.Reference{
    58  		{
    59  			Subject: call,
    60  
    61  			// No source range here, because there's nothing reasonable for
    62  			// us to return.
    63  		},
    64  	}
    65  }
    66  
    67  // RemovableIfNotTargeted
    68  func (n *NodeModuleRemoved) RemoveIfNotTargeted() bool {
    69  	// We need to add this so that this node will be removed if
    70  	// it isn't targeted or a dependency of a target.
    71  	return true
    72  }
    73  
    74  // EvalCheckModuleRemoved is an EvalNode implementation that verifies that
    75  // a module has been removed from the state as expected.
    76  type EvalCheckModuleRemoved struct {
    77  	Addr addrs.ModuleInstance
    78  }
    79  
    80  func (n *EvalCheckModuleRemoved) Eval(ctx EvalContext) (interface{}, error) {
    81  	mod := ctx.State().Module(n.Addr)
    82  	if mod != nil {
    83  		// If we get here then that indicates a bug either in the states
    84  		// module or in an earlier step of the graph walk, since we should've
    85  		// pruned out the module when the last resource was removed from it.
    86  		return nil, fmt.Errorf("leftover module %s in state that should have been removed; this is a bug in Terraform and should be reported", n.Addr)
    87  	}
    88  	return nil, nil
    89  }