github.com/skyscape-cloud-services/terraform@v0.9.2-0.20170609144644-7ece028a1747/terraform/transform_state.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 "log" 6 7 "github.com/hashicorp/terraform/dag" 8 ) 9 10 // StateTransformer is a GraphTransformer that adds the elements of 11 // the state to the graph. 12 // 13 // This transform is used for example by the DestroyPlanGraphBuilder to ensure 14 // that only resources that are in the state are represented in the graph. 15 type StateTransformer struct { 16 Concrete ConcreteResourceNodeFunc 17 18 State *State 19 } 20 21 func (t *StateTransformer) Transform(g *Graph) error { 22 // If the state is nil or empty (nil is empty) then do nothing 23 if t.State.Empty() { 24 return nil 25 } 26 27 // Go through all the modules in the diff. 28 log.Printf("[TRACE] StateTransformer: starting") 29 var nodes []dag.Vertex 30 for _, ms := range t.State.Modules { 31 log.Printf("[TRACE] StateTransformer: Module: %v", ms.Path) 32 33 // Go through all the resources in this module. 34 for name, rs := range ms.Resources { 35 log.Printf("[TRACE] StateTransformer: Resource %q: %#v", name, rs) 36 37 // Add the resource to the graph 38 addr, err := parseResourceAddressInternal(name) 39 if err != nil { 40 panic(fmt.Sprintf( 41 "Error parsing internal name, this is a bug: %q", name)) 42 } 43 44 // Very important: add the module path for this resource to 45 // the address. Remove "root" from it. 46 addr.Path = ms.Path[1:] 47 48 // Add the resource to the graph 49 abstract := &NodeAbstractResource{Addr: addr} 50 var node dag.Vertex = abstract 51 if f := t.Concrete; f != nil { 52 node = f(abstract) 53 } 54 55 nodes = append(nodes, node) 56 } 57 } 58 59 // Add all the nodes to the graph 60 for _, n := range nodes { 61 g.Add(n) 62 } 63 64 return nil 65 }