diff options
author | Jake Champlin <jake.champlin.27@gmail.com> | 2017-06-06 12:40:07 -0400 |
---|---|---|
committer | Jake Champlin <jake.champlin.27@gmail.com> | 2017-06-06 12:40:07 -0400 |
commit | bae9f6d2fd5eb5bc80929bd393932b23f14d7c93 (patch) | |
tree | ca9ab12a7d78b1fc27a8f734729081357ce6d252 /vendor/github.com/hashicorp/terraform/terraform/shadow_resource_provisioner.go | |
parent | 254c495b6bebab3fb72a243c4bce858d79e6ee99 (diff) | |
download | terraform-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/shadow_resource_provisioner.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/terraform/shadow_resource_provisioner.go | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/terraform/shadow_resource_provisioner.go b/vendor/github.com/hashicorp/terraform/terraform/shadow_resource_provisioner.go new file mode 100644 index 0000000..60a4908 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/terraform/shadow_resource_provisioner.go | |||
@@ -0,0 +1,282 @@ | |||
1 | package terraform | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "io" | ||
6 | "log" | ||
7 | "sync" | ||
8 | |||
9 | "github.com/hashicorp/go-multierror" | ||
10 | "github.com/hashicorp/terraform/helper/shadow" | ||
11 | ) | ||
12 | |||
13 | // shadowResourceProvisioner implements ResourceProvisioner for the shadow | ||
14 | // eval context defined in eval_context_shadow.go. | ||
15 | // | ||
16 | // This is used to verify behavior with a real provisioner. This shouldn't | ||
17 | // be used directly. | ||
18 | type shadowResourceProvisioner interface { | ||
19 | ResourceProvisioner | ||
20 | Shadow | ||
21 | } | ||
22 | |||
23 | // newShadowResourceProvisioner creates a new shadowed ResourceProvisioner. | ||
24 | func newShadowResourceProvisioner( | ||
25 | p ResourceProvisioner) (ResourceProvisioner, shadowResourceProvisioner) { | ||
26 | // Create the shared data | ||
27 | shared := shadowResourceProvisionerShared{ | ||
28 | Validate: shadow.ComparedValue{ | ||
29 | Func: shadowResourceProvisionerValidateCompare, | ||
30 | }, | ||
31 | } | ||
32 | |||
33 | // Create the real provisioner that does actual work | ||
34 | real := &shadowResourceProvisionerReal{ | ||
35 | ResourceProvisioner: p, | ||
36 | Shared: &shared, | ||
37 | } | ||
38 | |||
39 | // Create the shadow that watches the real value | ||
40 | shadow := &shadowResourceProvisionerShadow{ | ||
41 | Shared: &shared, | ||
42 | } | ||
43 | |||
44 | return real, shadow | ||
45 | } | ||
46 | |||
47 | // shadowResourceProvisionerReal is the real resource provisioner. Function calls | ||
48 | // to this will perform real work. This records the parameters and return | ||
49 | // values and call order for the shadow to reproduce. | ||
50 | type shadowResourceProvisionerReal struct { | ||
51 | ResourceProvisioner | ||
52 | |||
53 | Shared *shadowResourceProvisionerShared | ||
54 | } | ||
55 | |||
56 | func (p *shadowResourceProvisionerReal) Close() error { | ||
57 | var result error | ||
58 | if c, ok := p.ResourceProvisioner.(ResourceProvisionerCloser); ok { | ||
59 | result = c.Close() | ||
60 | } | ||
61 | |||
62 | p.Shared.CloseErr.SetValue(result) | ||
63 | return result | ||
64 | } | ||
65 | |||
66 | func (p *shadowResourceProvisionerReal) Validate(c *ResourceConfig) ([]string, []error) { | ||
67 | warns, errs := p.ResourceProvisioner.Validate(c) | ||
68 | p.Shared.Validate.SetValue(&shadowResourceProvisionerValidate{ | ||
69 | Config: c, | ||
70 | ResultWarn: warns, | ||
71 | ResultErr: errs, | ||
72 | }) | ||
73 | |||
74 | return warns, errs | ||
75 | } | ||
76 | |||
77 | func (p *shadowResourceProvisionerReal) Apply( | ||
78 | output UIOutput, s *InstanceState, c *ResourceConfig) error { | ||
79 | err := p.ResourceProvisioner.Apply(output, s, c) | ||
80 | |||
81 | // Write the result, grab a lock for writing. This should nver | ||
82 | // block long since the operations below don't block. | ||
83 | p.Shared.ApplyLock.Lock() | ||
84 | defer p.Shared.ApplyLock.Unlock() | ||
85 | |||
86 | key := s.ID | ||
87 | raw, ok := p.Shared.Apply.ValueOk(key) | ||
88 | if !ok { | ||
89 | // Setup a new value | ||
90 | raw = &shadow.ComparedValue{ | ||
91 | Func: shadowResourceProvisionerApplyCompare, | ||
92 | } | ||
93 | |||
94 | // Set it | ||
95 | p.Shared.Apply.SetValue(key, raw) | ||
96 | } | ||
97 | |||
98 | compareVal, ok := raw.(*shadow.ComparedValue) | ||
99 | if !ok { | ||
100 | // Just log and return so that we don't cause the real side | ||
101 | // any side effects. | ||
102 | log.Printf("[ERROR] unknown value in 'apply': %#v", raw) | ||
103 | return err | ||
104 | } | ||
105 | |||
106 | // Write the resulting value | ||
107 | compareVal.SetValue(&shadowResourceProvisionerApply{ | ||
108 | Config: c, | ||
109 | ResultErr: err, | ||
110 | }) | ||
111 | |||
112 | return err | ||
113 | } | ||
114 | |||
115 | func (p *shadowResourceProvisionerReal) Stop() error { | ||
116 | return p.ResourceProvisioner.Stop() | ||
117 | } | ||
118 | |||
119 | // shadowResourceProvisionerShadow is the shadow resource provisioner. Function | ||
120 | // calls never affect real resources. This is paired with the "real" side | ||
121 | // which must be called properly to enable recording. | ||
122 | type shadowResourceProvisionerShadow struct { | ||
123 | Shared *shadowResourceProvisionerShared | ||
124 | |||
125 | Error error // Error is the list of errors from the shadow | ||
126 | ErrorLock sync.Mutex | ||
127 | } | ||
128 | |||
129 | type shadowResourceProvisionerShared struct { | ||
130 | // NOTE: Anytime a value is added here, be sure to add it to | ||
131 | // the Close() method so that it is closed. | ||
132 | |||
133 | CloseErr shadow.Value | ||
134 | Validate shadow.ComparedValue | ||
135 | Apply shadow.KeyedValue | ||
136 | ApplyLock sync.Mutex // For writing only | ||
137 | } | ||
138 | |||
139 | func (p *shadowResourceProvisionerShared) Close() error { | ||
140 | closers := []io.Closer{ | ||
141 | &p.CloseErr, | ||
142 | } | ||
143 | |||
144 | for _, c := range closers { | ||
145 | // This should never happen, but we don't panic because a panic | ||
146 | // could affect the real behavior of Terraform and a shadow should | ||
147 | // never be able to do that. | ||
148 | if err := c.Close(); err != nil { | ||
149 | return err | ||
150 | } | ||
151 | } | ||
152 | |||
153 | return nil | ||
154 | } | ||
155 | |||
156 | func (p *shadowResourceProvisionerShadow) CloseShadow() error { | ||
157 | err := p.Shared.Close() | ||
158 | if err != nil { | ||
159 | err = fmt.Errorf("close error: %s", err) | ||
160 | } | ||
161 | |||
162 | return err | ||
163 | } | ||
164 | |||
165 | func (p *shadowResourceProvisionerShadow) ShadowError() error { | ||
166 | return p.Error | ||
167 | } | ||
168 | |||
169 | func (p *shadowResourceProvisionerShadow) Close() error { | ||
170 | v := p.Shared.CloseErr.Value() | ||
171 | if v == nil { | ||
172 | return nil | ||
173 | } | ||
174 | |||
175 | return v.(error) | ||
176 | } | ||
177 | |||
178 | func (p *shadowResourceProvisionerShadow) Validate(c *ResourceConfig) ([]string, []error) { | ||
179 | // Get the result of the validate call | ||
180 | raw := p.Shared.Validate.Value(c) | ||
181 | if raw == nil { | ||
182 | return nil, nil | ||
183 | } | ||
184 | |||
185 | result, ok := raw.(*shadowResourceProvisionerValidate) | ||
186 | if !ok { | ||
187 | p.ErrorLock.Lock() | ||
188 | defer p.ErrorLock.Unlock() | ||
189 | p.Error = multierror.Append(p.Error, fmt.Errorf( | ||
190 | "Unknown 'validate' shadow value: %#v", raw)) | ||
191 | return nil, nil | ||
192 | } | ||
193 | |||
194 | // We don't need to compare configurations because we key on the | ||
195 | // configuration so just return right away. | ||
196 | return result.ResultWarn, result.ResultErr | ||
197 | } | ||
198 | |||
199 | func (p *shadowResourceProvisionerShadow) Apply( | ||
200 | output UIOutput, s *InstanceState, c *ResourceConfig) error { | ||
201 | // Get the value based on the key | ||
202 | key := s.ID | ||
203 | raw := p.Shared.Apply.Value(key) | ||
204 | if raw == nil { | ||
205 | return nil | ||
206 | } | ||
207 | |||
208 | compareVal, ok := raw.(*shadow.ComparedValue) | ||
209 | if !ok { | ||
210 | p.ErrorLock.Lock() | ||
211 | defer p.ErrorLock.Unlock() | ||
212 | p.Error = multierror.Append(p.Error, fmt.Errorf( | ||
213 | "Unknown 'apply' shadow value: %#v", raw)) | ||
214 | return nil | ||
215 | } | ||
216 | |||
217 | // With the compared value, we compare against our config | ||
218 | raw = compareVal.Value(c) | ||
219 | if raw == nil { | ||
220 | return nil | ||
221 | } | ||
222 | |||
223 | result, ok := raw.(*shadowResourceProvisionerApply) | ||
224 | if !ok { | ||
225 | p.ErrorLock.Lock() | ||
226 | defer p.ErrorLock.Unlock() | ||
227 | p.Error = multierror.Append(p.Error, fmt.Errorf( | ||
228 | "Unknown 'apply' shadow value: %#v", raw)) | ||
229 | return nil | ||
230 | } | ||
231 | |||
232 | return result.ResultErr | ||
233 | } | ||
234 | |||
235 | func (p *shadowResourceProvisionerShadow) Stop() error { | ||
236 | // For the shadow, we always just return nil since a Stop indicates | ||
237 | // that we were interrupted and shadows are disabled during interrupts | ||
238 | // anyways. | ||
239 | return nil | ||
240 | } | ||
241 | |||
242 | // The structs for the various function calls are put below. These structs | ||
243 | // are used to carry call information across the real/shadow boundaries. | ||
244 | |||
245 | type shadowResourceProvisionerValidate struct { | ||
246 | Config *ResourceConfig | ||
247 | ResultWarn []string | ||
248 | ResultErr []error | ||
249 | } | ||
250 | |||
251 | type shadowResourceProvisionerApply struct { | ||
252 | Config *ResourceConfig | ||
253 | ResultErr error | ||
254 | } | ||
255 | |||
256 | func shadowResourceProvisionerValidateCompare(k, v interface{}) bool { | ||
257 | c, ok := k.(*ResourceConfig) | ||
258 | if !ok { | ||
259 | return false | ||
260 | } | ||
261 | |||
262 | result, ok := v.(*shadowResourceProvisionerValidate) | ||
263 | if !ok { | ||
264 | return false | ||
265 | } | ||
266 | |||
267 | return c.Equal(result.Config) | ||
268 | } | ||
269 | |||
270 | func shadowResourceProvisionerApplyCompare(k, v interface{}) bool { | ||
271 | c, ok := k.(*ResourceConfig) | ||
272 | if !ok { | ||
273 | return false | ||
274 | } | ||
275 | |||
276 | result, ok := v.(*shadowResourceProvisionerApply) | ||
277 | if !ok { | ||
278 | return false | ||
279 | } | ||
280 | |||
281 | return c.Equal(result.Config) | ||
282 | } | ||