github.com/rliebz/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/terraform/transform_diff.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 "log" 6 7 "github.com/hashicorp/terraform/config/module" 8 "github.com/hashicorp/terraform/dag" 9 ) 10 11 // DiffTransformer is a GraphTransformer that adds the elements of 12 // the diff to the graph. 13 // 14 // This transform is used for example by the ApplyGraphBuilder to ensure 15 // that only resources that are being modified are represented in the graph. 16 // 17 // Module and State is still required for the DiffTransformer for annotations 18 // since the Diff doesn't contain all the information required to build the 19 // complete graph (such as create-before-destroy information). The graph 20 // is built based on the diff first, though, ensuring that only resources 21 // that are being modified are present in the graph. 22 type DiffTransformer struct { 23 Concrete ConcreteResourceNodeFunc 24 25 Diff *Diff 26 Module *module.Tree 27 State *State 28 } 29 30 func (t *DiffTransformer) Transform(g *Graph) error { 31 // If the diff is nil or empty (nil is empty) then do nothing 32 if t.Diff.Empty() { 33 return nil 34 } 35 36 // Go through all the modules in the diff. 37 log.Printf("[TRACE] DiffTransformer: starting") 38 var nodes []dag.Vertex 39 for _, m := range t.Diff.Modules { 40 log.Printf("[TRACE] DiffTransformer: Module: %s", m) 41 // TODO: If this is a destroy diff then add a module destroy node 42 43 // Go through all the resources in this module. 44 for name, inst := range m.Resources { 45 log.Printf("[TRACE] DiffTransformer: Resource %q: %#v", name, inst) 46 47 // We have changes! This is a create or update operation. 48 // First grab the address so we have a unique way to 49 // reference this resource. 50 addr, err := parseResourceAddressInternal(name) 51 if err != nil { 52 panic(fmt.Sprintf( 53 "Error parsing internal name, this is a bug: %q", name)) 54 } 55 56 // Very important: add the module path for this resource to 57 // the address. Remove "root" from it. 58 addr.Path = m.Path[1:] 59 60 // If we're destroying, add the destroy node 61 if inst.Destroy || inst.GetDestroyDeposed() { 62 abstract := &NodeAbstractResource{Addr: addr} 63 g.Add(&NodeDestroyResource{NodeAbstractResource: abstract}) 64 } 65 66 // If we have changes, then add the applyable version 67 if len(inst.Attributes) > 0 { 68 // Add the resource to the graph 69 abstract := &NodeAbstractResource{Addr: addr} 70 var node dag.Vertex = abstract 71 if f := t.Concrete; f != nil { 72 node = f(abstract) 73 } 74 75 nodes = append(nodes, node) 76 } 77 } 78 } 79 80 // Add all the nodes to the graph 81 for _, n := range nodes { 82 g.Add(n) 83 } 84 85 return nil 86 }