github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/terraform/transform_orphan_resource.go (about)

     1  package terraform
     2  
     3  import (
     4  	"github.com/hashicorp/terraform/config"
     5  	"github.com/hashicorp/terraform/config/module"
     6  	"github.com/hashicorp/terraform/dag"
     7  )
     8  
     9  // OrphanResourceTransformer is a GraphTransformer that adds resource
    10  // orphans to the graph. A resource orphan is a resource that is
    11  // represented in the state but not in the configuration.
    12  //
    13  // This only adds orphans that have no representation at all in the
    14  // configuration.
    15  type OrphanResourceTransformer struct {
    16  	Concrete ConcreteResourceNodeFunc
    17  
    18  	// State is the global state. We require the global state to
    19  	// properly find module orphans at our path.
    20  	State *State
    21  
    22  	// Module is the root module. We'll look up the proper configuration
    23  	// using the graph path.
    24  	Module *module.Tree
    25  }
    26  
    27  func (t *OrphanResourceTransformer) Transform(g *Graph) error {
    28  	if t.State == nil {
    29  		// If the entire state is nil, there can't be any orphans
    30  		return nil
    31  	}
    32  
    33  	// Go through the modules and for each module transform in order
    34  	// to add the orphan.
    35  	for _, ms := range t.State.Modules {
    36  		if err := t.transform(g, ms); err != nil {
    37  			return err
    38  		}
    39  	}
    40  
    41  	return nil
    42  }
    43  
    44  func (t *OrphanResourceTransformer) transform(g *Graph, ms *ModuleState) error {
    45  	if ms == nil {
    46  		return nil
    47  	}
    48  
    49  	// Get the configuration for this path. The configuration might be
    50  	// nil if the module was removed from the configuration. This is okay,
    51  	// this just means that every resource is an orphan.
    52  	var c *config.Config
    53  	if m := t.Module.Child(ms.Path[1:]); m != nil {
    54  		c = m.Config()
    55  	}
    56  
    57  	// Go through the orphans and add them all to the state
    58  	for _, key := range ms.Orphans(c) {
    59  		// Build the abstract resource
    60  		addr, err := parseResourceAddressInternal(key)
    61  		if err != nil {
    62  			return err
    63  		}
    64  		addr.Path = ms.Path[1:]
    65  
    66  		// Build the abstract node and the concrete one
    67  		abstract := &NodeAbstractResource{Addr: addr}
    68  		var node dag.Vertex = abstract
    69  		if f := t.Concrete; f != nil {
    70  			node = f(abstract)
    71  		}
    72  
    73  		// Add it to the graph
    74  		g.Add(node)
    75  	}
    76  
    77  	return nil
    78  }