github.com/Hashicorp/terraform@v0.11.12-beta1/terraform/transform_deposed.go (about) 1 package terraform 2 3 import "fmt" 4 5 // DeposedTransformer is a GraphTransformer that adds deposed resources 6 // to the graph. 7 type DeposedTransformer struct { 8 // State is the global state. We'll automatically find the correct 9 // ModuleState based on the Graph.Path that is being transformed. 10 State *State 11 12 // View, if non-empty, is the ModuleState.View used around the state 13 // to find deposed resources. 14 View string 15 16 // The provider used by the resourced which were deposed 17 ResolvedProvider string 18 } 19 20 func (t *DeposedTransformer) Transform(g *Graph) error { 21 state := t.State.ModuleByPath(g.Path) 22 if state == nil { 23 // If there is no state for our module there can't be any deposed 24 // resources, since they live in the state. 25 return nil 26 } 27 28 // If we have a view, apply it now 29 if t.View != "" { 30 state = state.View(t.View) 31 } 32 33 // Go through all the resources in our state to look for deposed resources 34 for k, rs := range state.Resources { 35 // If we have no deposed resources, then move on 36 if len(rs.Deposed) == 0 { 37 continue 38 } 39 40 deposed := rs.Deposed 41 42 for i, _ := range deposed { 43 g.Add(&graphNodeDeposedResource{ 44 Index: i, 45 ResourceName: k, 46 ResourceType: rs.Type, 47 ProviderName: rs.Provider, 48 ResolvedProvider: t.ResolvedProvider, 49 }) 50 } 51 } 52 53 return nil 54 } 55 56 // graphNodeDeposedResource is the graph vertex representing a deposed resource. 57 type graphNodeDeposedResource struct { 58 Index int 59 ResourceName string 60 ResourceType string 61 ProviderName string 62 ResolvedProvider string 63 } 64 65 func (n *graphNodeDeposedResource) Name() string { 66 return fmt.Sprintf("%s (deposed #%d)", n.ResourceName, n.Index) 67 } 68 69 func (n *graphNodeDeposedResource) ProvidedBy() string { 70 return resourceProvider(n.ResourceName, n.ProviderName) 71 } 72 73 func (n *graphNodeDeposedResource) SetProvider(p string) { 74 n.ResolvedProvider = p 75 } 76 77 // GraphNodeEvalable impl. 78 func (n *graphNodeDeposedResource) EvalTree() EvalNode { 79 var provider ResourceProvider 80 var state *InstanceState 81 82 seq := &EvalSequence{Nodes: make([]EvalNode, 0, 5)} 83 84 // Build instance info 85 info := &InstanceInfo{Id: n.Name(), Type: n.ResourceType} 86 seq.Nodes = append(seq.Nodes, &EvalInstanceInfo{Info: info}) 87 88 // Refresh the resource 89 seq.Nodes = append(seq.Nodes, &EvalOpFilter{ 90 Ops: []walkOperation{walkRefresh}, 91 Node: &EvalSequence{ 92 Nodes: []EvalNode{ 93 &EvalGetProvider{ 94 Name: n.ResolvedProvider, 95 Output: &provider, 96 }, 97 &EvalReadStateDeposed{ 98 Name: n.ResourceName, 99 Output: &state, 100 Index: n.Index, 101 }, 102 &EvalRefresh{ 103 Info: info, 104 Provider: &provider, 105 State: &state, 106 Output: &state, 107 }, 108 &EvalWriteStateDeposed{ 109 Name: n.ResourceName, 110 ResourceType: n.ResourceType, 111 Provider: n.ResolvedProvider, 112 State: &state, 113 Index: n.Index, 114 }, 115 }, 116 }, 117 }) 118 119 // Apply 120 var diff *InstanceDiff 121 var err error 122 seq.Nodes = append(seq.Nodes, &EvalOpFilter{ 123 Ops: []walkOperation{walkApply, walkDestroy}, 124 Node: &EvalSequence{ 125 Nodes: []EvalNode{ 126 &EvalGetProvider{ 127 Name: n.ResolvedProvider, 128 Output: &provider, 129 }, 130 &EvalReadStateDeposed{ 131 Name: n.ResourceName, 132 Output: &state, 133 Index: n.Index, 134 }, 135 &EvalDiffDestroy{ 136 Info: info, 137 State: &state, 138 Output: &diff, 139 }, 140 // Call pre-apply hook 141 &EvalApplyPre{ 142 Info: info, 143 State: &state, 144 Diff: &diff, 145 }, 146 &EvalApply{ 147 Info: info, 148 State: &state, 149 Diff: &diff, 150 Provider: &provider, 151 Output: &state, 152 Error: &err, 153 }, 154 // Always write the resource back to the state deposed... if it 155 // was successfully destroyed it will be pruned. If it was not, it will 156 // be caught on the next run. 157 &EvalWriteStateDeposed{ 158 Name: n.ResourceName, 159 ResourceType: n.ResourceType, 160 Provider: n.ResolvedProvider, 161 State: &state, 162 Index: n.Index, 163 }, 164 &EvalApplyPost{ 165 Info: info, 166 State: &state, 167 Error: &err, 168 }, 169 &EvalReturnError{ 170 Error: &err, 171 }, 172 &EvalUpdateStateHook{}, 173 }, 174 }, 175 }) 176 177 return seq 178 }