aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/terraform/terraform/eval_state.go
diff options
context:
space:
mode:
authorJake Champlin <jake.champlin.27@gmail.com>2017-06-06 12:40:07 -0400
committerJake Champlin <jake.champlin.27@gmail.com>2017-06-06 12:40:07 -0400
commitbae9f6d2fd5eb5bc80929bd393932b23f14d7c93 (patch)
treeca9ab12a7d78b1fc27a8f734729081357ce6d252 /vendor/github.com/hashicorp/terraform/terraform/eval_state.go
parent254c495b6bebab3fb72a243c4bce858d79e6ee99 (diff)
downloadterraform-provider-statuscake-bae9f6d2fd5eb5bc80929bd393932b23f14d7c93.tar.gz
terraform-provider-statuscake-bae9f6d2fd5eb5bc80929bd393932b23f14d7c93.tar.zst
terraform-provider-statuscake-bae9f6d2fd5eb5bc80929bd393932b23f14d7c93.zip
Initial transfer of provider code
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/terraform/eval_state.go')
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/eval_state.go324
1 files changed, 324 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/terraform/eval_state.go b/vendor/github.com/hashicorp/terraform/terraform/eval_state.go
new file mode 100644
index 0000000..126a0e6
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/terraform/eval_state.go
@@ -0,0 +1,324 @@
1package terraform
2
3import "fmt"
4
5// EvalReadState is an EvalNode implementation that reads the
6// primary InstanceState for a specific resource out of the state.
7type EvalReadState struct {
8 Name string
9 Output **InstanceState
10}
11
12func (n *EvalReadState) Eval(ctx EvalContext) (interface{}, error) {
13 return readInstanceFromState(ctx, n.Name, n.Output, func(rs *ResourceState) (*InstanceState, error) {
14 return rs.Primary, nil
15 })
16}
17
18// EvalReadStateDeposed is an EvalNode implementation that reads the
19// deposed InstanceState for a specific resource out of the state
20type EvalReadStateDeposed struct {
21 Name string
22 Output **InstanceState
23 // Index indicates which instance in the Deposed list to target, or -1 for
24 // the last item.
25 Index int
26}
27
28func (n *EvalReadStateDeposed) Eval(ctx EvalContext) (interface{}, error) {
29 return readInstanceFromState(ctx, n.Name, n.Output, func(rs *ResourceState) (*InstanceState, error) {
30 // Get the index. If it is negative, then we get the last one
31 idx := n.Index
32 if idx < 0 {
33 idx = len(rs.Deposed) - 1
34 }
35 if idx >= 0 && idx < len(rs.Deposed) {
36 return rs.Deposed[idx], nil
37 } else {
38 return nil, fmt.Errorf("bad deposed index: %d, for resource: %#v", idx, rs)
39 }
40 })
41}
42
43// Does the bulk of the work for the various flavors of ReadState eval nodes.
44// Each node just provides a reader function to get from the ResourceState to the
45// InstanceState, and this takes care of all the plumbing.
46func readInstanceFromState(
47 ctx EvalContext,
48 resourceName string,
49 output **InstanceState,
50 readerFn func(*ResourceState) (*InstanceState, error),
51) (*InstanceState, error) {
52 state, lock := ctx.State()
53
54 // Get a read lock so we can access this instance
55 lock.RLock()
56 defer lock.RUnlock()
57
58 // Look for the module state. If we don't have one, then it doesn't matter.
59 mod := state.ModuleByPath(ctx.Path())
60 if mod == nil {
61 return nil, nil
62 }
63
64 // Look for the resource state. If we don't have one, then it is okay.
65 rs := mod.Resources[resourceName]
66 if rs == nil {
67 return nil, nil
68 }
69
70 // Use the delegate function to get the instance state from the resource state
71 is, err := readerFn(rs)
72 if err != nil {
73 return nil, err
74 }
75
76 // Write the result to the output pointer
77 if output != nil {
78 *output = is
79 }
80
81 return is, nil
82}
83
84// EvalRequireState is an EvalNode implementation that early exits
85// if the state doesn't have an ID.
86type EvalRequireState struct {
87 State **InstanceState
88}
89
90func (n *EvalRequireState) Eval(ctx EvalContext) (interface{}, error) {
91 if n.State == nil {
92 return nil, EvalEarlyExitError{}
93 }
94
95 state := *n.State
96 if state == nil || state.ID == "" {
97 return nil, EvalEarlyExitError{}
98 }
99
100 return nil, nil
101}
102
103// EvalUpdateStateHook is an EvalNode implementation that calls the
104// PostStateUpdate hook with the current state.
105type EvalUpdateStateHook struct{}
106
107func (n *EvalUpdateStateHook) Eval(ctx EvalContext) (interface{}, error) {
108 state, lock := ctx.State()
109
110 // Get a full lock. Even calling something like WriteState can modify
111 // (prune) the state, so we need the full lock.
112 lock.Lock()
113 defer lock.Unlock()
114
115 // Call the hook
116 err := ctx.Hook(func(h Hook) (HookAction, error) {
117 return h.PostStateUpdate(state)
118 })
119 if err != nil {
120 return nil, err
121 }
122
123 return nil, nil
124}
125
126// EvalWriteState is an EvalNode implementation that writes the
127// primary InstanceState for a specific resource into the state.
128type EvalWriteState struct {
129 Name string
130 ResourceType string
131 Provider string
132 Dependencies []string
133 State **InstanceState
134}
135
136func (n *EvalWriteState) Eval(ctx EvalContext) (interface{}, error) {
137 return writeInstanceToState(ctx, n.Name, n.ResourceType, n.Provider, n.Dependencies,
138 func(rs *ResourceState) error {
139 rs.Primary = *n.State
140 return nil
141 },
142 )
143}
144
145// EvalWriteStateDeposed is an EvalNode implementation that writes
146// an InstanceState out to the Deposed list of a resource in the state.
147type EvalWriteStateDeposed struct {
148 Name string
149 ResourceType string
150 Provider string
151 Dependencies []string
152 State **InstanceState
153 // Index indicates which instance in the Deposed list to target, or -1 to append.
154 Index int
155}
156
157func (n *EvalWriteStateDeposed) Eval(ctx EvalContext) (interface{}, error) {
158 return writeInstanceToState(ctx, n.Name, n.ResourceType, n.Provider, n.Dependencies,
159 func(rs *ResourceState) error {
160 if n.Index == -1 {
161 rs.Deposed = append(rs.Deposed, *n.State)
162 } else {
163 rs.Deposed[n.Index] = *n.State
164 }
165 return nil
166 },
167 )
168}
169
170// Pulls together the common tasks of the EvalWriteState nodes. All the args
171// are passed directly down from the EvalNode along with a `writer` function
172// which is yielded the *ResourceState and is responsible for writing an
173// InstanceState to the proper field in the ResourceState.
174func writeInstanceToState(
175 ctx EvalContext,
176 resourceName string,
177 resourceType string,
178 provider string,
179 dependencies []string,
180 writerFn func(*ResourceState) error,
181) (*InstanceState, error) {
182 state, lock := ctx.State()
183 if state == nil {
184 return nil, fmt.Errorf("cannot write state to nil state")
185 }
186
187 // Get a write lock so we can access this instance
188 lock.Lock()
189 defer lock.Unlock()
190
191 // Look for the module state. If we don't have one, create it.
192 mod := state.ModuleByPath(ctx.Path())
193 if mod == nil {
194 mod = state.AddModule(ctx.Path())
195 }
196
197 // Look for the resource state.
198 rs := mod.Resources[resourceName]
199 if rs == nil {
200 rs = &ResourceState{}
201 rs.init()
202 mod.Resources[resourceName] = rs
203 }
204 rs.Type = resourceType
205 rs.Dependencies = dependencies
206 rs.Provider = provider
207
208 if err := writerFn(rs); err != nil {
209 return nil, err
210 }
211
212 return nil, nil
213}
214
215// EvalClearPrimaryState is an EvalNode implementation that clears the primary
216// instance from a resource state.
217type EvalClearPrimaryState struct {
218 Name string
219}
220
221func (n *EvalClearPrimaryState) Eval(ctx EvalContext) (interface{}, error) {
222 state, lock := ctx.State()
223
224 // Get a read lock so we can access this instance
225 lock.RLock()
226 defer lock.RUnlock()
227
228 // Look for the module state. If we don't have one, then it doesn't matter.
229 mod := state.ModuleByPath(ctx.Path())
230 if mod == nil {
231 return nil, nil
232 }
233
234 // Look for the resource state. If we don't have one, then it is okay.
235 rs := mod.Resources[n.Name]
236 if rs == nil {
237 return nil, nil
238 }
239
240 // Clear primary from the resource state
241 rs.Primary = nil
242
243 return nil, nil
244}
245
246// EvalDeposeState is an EvalNode implementation that takes the primary
247// out of a state and makes it Deposed. This is done at the beginning of
248// create-before-destroy calls so that the create can create while preserving
249// the old state of the to-be-destroyed resource.
250type EvalDeposeState struct {
251 Name string
252}
253
254// TODO: test
255func (n *EvalDeposeState) Eval(ctx EvalContext) (interface{}, error) {
256 state, lock := ctx.State()
257
258 // Get a read lock so we can access this instance
259 lock.RLock()
260 defer lock.RUnlock()
261
262 // Look for the module state. If we don't have one, then it doesn't matter.
263 mod := state.ModuleByPath(ctx.Path())
264 if mod == nil {
265 return nil, nil
266 }
267
268 // Look for the resource state. If we don't have one, then it is okay.
269 rs := mod.Resources[n.Name]
270 if rs == nil {
271 return nil, nil
272 }
273
274 // If we don't have a primary, we have nothing to depose
275 if rs.Primary == nil {
276 return nil, nil
277 }
278
279 // Depose
280 rs.Deposed = append(rs.Deposed, rs.Primary)
281 rs.Primary = nil
282
283 return nil, nil
284}
285
286// EvalUndeposeState is an EvalNode implementation that reads the
287// InstanceState for a specific resource out of the state.
288type EvalUndeposeState struct {
289 Name string
290 State **InstanceState
291}
292
293// TODO: test
294func (n *EvalUndeposeState) Eval(ctx EvalContext) (interface{}, error) {
295 state, lock := ctx.State()
296
297 // Get a read lock so we can access this instance
298 lock.RLock()
299 defer lock.RUnlock()
300
301 // Look for the module state. If we don't have one, then it doesn't matter.
302 mod := state.ModuleByPath(ctx.Path())
303 if mod == nil {
304 return nil, nil
305 }
306
307 // Look for the resource state. If we don't have one, then it is okay.
308 rs := mod.Resources[n.Name]
309 if rs == nil {
310 return nil, nil
311 }
312
313 // If we don't have any desposed resource, then we don't have anything to do
314 if len(rs.Deposed) == 0 {
315 return nil, nil
316 }
317
318 // Undepose
319 idx := len(rs.Deposed) - 1
320 rs.Primary = rs.Deposed[idx]
321 rs.Deposed[idx] = *n.State
322
323 return nil, nil
324}