github.com/adrian-bl/terraform@v0.7.0-rc2.0.20160705220747-de0a34fc3517/terraform/transform_output.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 6 "github.com/hashicorp/terraform/dag" 7 ) 8 9 // GraphNodeOutput is an interface that nodes that are outputs must 10 // implement. The OutputName returned is the name of the output key 11 // that they manage. 12 type GraphNodeOutput interface { 13 OutputName() string 14 } 15 16 // AddOutputOrphanTransformer is a transformer that adds output orphans 17 // to the graph. Output orphans are outputs that are no longer in the 18 // configuration and therefore need to be removed from the state. 19 type AddOutputOrphanTransformer struct { 20 State *State 21 } 22 23 func (t *AddOutputOrphanTransformer) Transform(g *Graph) error { 24 // Get the state for this module. If we have no state, we have no orphans 25 state := t.State.ModuleByPath(g.Path) 26 if state == nil { 27 return nil 28 } 29 30 // Create the set of outputs we do have in the graph 31 found := make(map[string]struct{}) 32 for _, v := range g.Vertices() { 33 on, ok := v.(GraphNodeOutput) 34 if !ok { 35 continue 36 } 37 38 found[on.OutputName()] = struct{}{} 39 } 40 41 // Go over all the outputs. If we don't have a graph node for it, 42 // create it. It doesn't need to depend on anything, since its just 43 // setting it empty. 44 for k, _ := range state.Outputs { 45 if _, ok := found[k]; ok { 46 continue 47 } 48 49 g.Add(&graphNodeOrphanOutput{OutputName: k}) 50 } 51 52 return nil 53 } 54 55 type graphNodeOrphanOutput struct { 56 OutputName string 57 } 58 59 func (n *graphNodeOrphanOutput) Name() string { 60 return fmt.Sprintf("output.%s (orphan)", n.OutputName) 61 } 62 63 func (n *graphNodeOrphanOutput) EvalTree() EvalNode { 64 return &EvalOpFilter{ 65 Ops: []walkOperation{walkApply, walkDestroy, walkRefresh}, 66 Node: &EvalDeleteOutput{ 67 Name: n.OutputName, 68 }, 69 } 70 } 71 72 // GraphNodeFlattenable impl. 73 func (n *graphNodeOrphanOutput) Flatten(p []string) (dag.Vertex, error) { 74 return &graphNodeOrphanOutputFlat{ 75 graphNodeOrphanOutput: n, 76 PathValue: p, 77 }, nil 78 } 79 80 type graphNodeOrphanOutputFlat struct { 81 *graphNodeOrphanOutput 82 83 PathValue []string 84 } 85 86 func (n *graphNodeOrphanOutputFlat) Name() string { 87 return fmt.Sprintf( 88 "%s.%s", modulePrefixStr(n.PathValue), n.graphNodeOrphanOutput.Name()) 89 } 90 91 func (n *graphNodeOrphanOutputFlat) EvalTree() EvalNode { 92 return &EvalOpFilter{ 93 Ops: []walkOperation{walkApply, walkDestroy, walkRefresh}, 94 Node: &EvalDeleteOutput{ 95 Name: n.OutputName, 96 }, 97 } 98 }