github.com/skyscape-cloud-services/terraform@v0.9.2-0.20170609144644-7ece028a1747/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 }