tfwrapper 0.2.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +54 -0
- data/.rubocop.yml +22 -0
- data/ChangeLog.md +3 -0
- data/Gemfile +4 -0
- data/Guardfile +21 -0
- data/LICENSE +21 -0
- data/README.md +320 -0
- data/Rakefile +60 -0
- data/circle.yml +24 -0
- data/lib/tfwrapper/helpers.rb +81 -0
- data/lib/tfwrapper/raketasks.rb +357 -0
- data/lib/tfwrapper/version.rb +6 -0
- data/lib/tfwrapper.rb +8 -0
- data/spec/acceptance/acceptance_helpers.rb +99 -0
- data/spec/acceptance/acceptance_spec.rb +461 -0
- data/spec/acceptance/consulserver.rb +34 -0
- data/spec/fixtures/Rakefile +7 -0
- data/spec/fixtures/testOne.tf +22 -0
- data/spec/fixtures/testThree/Rakefile +32 -0
- data/spec/fixtures/testThree/bar/testThreeBar.tf +28 -0
- data/spec/fixtures/testThree/baz/testThreeBaz.tf +22 -0
- data/spec/fixtures/testThree/foo/testThreeFoo.tf +27 -0
- data/spec/fixtures/testTwo/Rakefile +9 -0
- data/spec/fixtures/testTwo/foo/bar/testTwo.tf +28 -0
- data/spec/spec_helper.rb +58 -0
- data/spec/unit/helpers_spec.rb +143 -0
- data/spec/unit/raketasks_spec.rb +851 -0
- data/tfwrapper.gemspec +61 -0
- metadata +419 -0
@@ -0,0 +1,851 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'tfwrapper/raketasks'
|
5
|
+
require 'tfwrapper/helpers'
|
6
|
+
require 'tfwrapper/version'
|
7
|
+
require 'json'
|
8
|
+
require 'retries'
|
9
|
+
require 'diplomat'
|
10
|
+
require 'rubygems'
|
11
|
+
|
12
|
+
describe TFWrapper::RakeTasks do
|
13
|
+
subject do
|
14
|
+
allow(Rake.application).to receive(:rakefile).and_return('Rakefile')
|
15
|
+
allow(File).to receive(:realpath) { |p| p }
|
16
|
+
subj = TFWrapper::RakeTasks.new('tfdir')
|
17
|
+
subj.instance_variable_set('@tf_dir', 'tfdir')
|
18
|
+
subj
|
19
|
+
end
|
20
|
+
describe '#install_tasks' do
|
21
|
+
it 'calls constructor without opts if none are passed' do
|
22
|
+
dbl = double(TFWrapper::RakeTasks)
|
23
|
+
allow(TFWrapper::RakeTasks)
|
24
|
+
.to receive(:new).and_return(dbl)
|
25
|
+
allow(dbl).to receive(:install)
|
26
|
+
|
27
|
+
expect(TFWrapper::RakeTasks).to receive(:new).once
|
28
|
+
.with('tfdir', {})
|
29
|
+
expect(dbl).to receive(:install).once
|
30
|
+
TFWrapper::RakeTasks.install_tasks('tfdir')
|
31
|
+
end
|
32
|
+
it 'passes opts to constructor' do
|
33
|
+
dbl = double(TFWrapper::RakeTasks)
|
34
|
+
allow(TFWrapper::RakeTasks)
|
35
|
+
.to receive(:new).and_return(dbl)
|
36
|
+
allow(dbl).to receive(:install)
|
37
|
+
|
38
|
+
expect(TFWrapper::RakeTasks).to receive(:new).once
|
39
|
+
.with('tfdir', tf_vars_from_env: { 'foo' => 'bar' })
|
40
|
+
expect(dbl).to receive(:install).once
|
41
|
+
TFWrapper::RakeTasks.install_tasks(
|
42
|
+
'tfdir', tf_vars_from_env: { 'foo' => 'bar' }
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
describe '#initialize' do
|
47
|
+
it 'sets instance variable defaults' do
|
48
|
+
allow(ENV).to receive(:[])
|
49
|
+
allow(ENV).to receive(:[]).with('CONSUL_HOST').and_return('chost')
|
50
|
+
allow(ENV).to receive(:[]).with('ENVIRONMENT').and_return('myenv')
|
51
|
+
allow(ENV).to receive(:[]).with('PROJECT').and_return('myproj')
|
52
|
+
allow(Rake.application).to receive(:rakefile)
|
53
|
+
.and_return('/rake/dir/Rakefile')
|
54
|
+
allow(File).to receive(:realpath) { |p| p.sub('../', '') }
|
55
|
+
allow(File).to receive(:file?).and_return(true)
|
56
|
+
cls = TFWrapper::RakeTasks.new('tfdir')
|
57
|
+
expect(cls.instance_variable_get('@tf_dir')).to eq('/rake/dir/tfdir')
|
58
|
+
expect(cls.instance_variable_get('@consul_env_vars_prefix')).to eq(nil)
|
59
|
+
expect(cls.instance_variable_get('@tf_vars_from_env')).to eq({})
|
60
|
+
expect(cls.instance_variable_get('@tf_extra_vars')).to eq({})
|
61
|
+
expect(cls.instance_variable_get('@backend_config')).to eq({})
|
62
|
+
expect(cls.instance_variable_get('@consul_url')).to eq(nil)
|
63
|
+
end
|
64
|
+
it 'sets options' do
|
65
|
+
allow(ENV).to receive(:[])
|
66
|
+
allow(ENV).to receive(:[]).with('CONSUL_HOST').and_return('chost')
|
67
|
+
allow(Rake.application).to receive(:rakefile)
|
68
|
+
.and_return('/path/to')
|
69
|
+
allow(File).to receive(:realpath) { |p| p.sub('../', '') }
|
70
|
+
cls = TFWrapper::RakeTasks.new(
|
71
|
+
'tf/dir',
|
72
|
+
consul_env_vars_prefix: 'cvprefix',
|
73
|
+
tf_vars_from_env: { 'foo' => 'bar' },
|
74
|
+
tf_extra_vars: { 'baz' => 'blam' },
|
75
|
+
consul_url: 'foobar'
|
76
|
+
)
|
77
|
+
expect(cls.instance_variable_get('@tf_dir'))
|
78
|
+
.to eq('/path/to/tf/dir')
|
79
|
+
expect(cls.instance_variable_get('@consul_env_vars_prefix'))
|
80
|
+
.to eq('cvprefix')
|
81
|
+
expect(cls.instance_variable_get('@tf_vars_from_env'))
|
82
|
+
.to eq('foo' => 'bar')
|
83
|
+
expect(cls.instance_variable_get('@tf_extra_vars'))
|
84
|
+
.to eq('baz' => 'blam')
|
85
|
+
expect(cls.instance_variable_get('@backend_config')).to eq({})
|
86
|
+
expect(cls.instance_variable_get('@consul_url')).to eq('foobar')
|
87
|
+
end
|
88
|
+
context 'when consul_url is nil but consul_env_vars_prefix is not' do
|
89
|
+
it 'raises an error' do
|
90
|
+
allow(Rake.application).to receive(:original_dir)
|
91
|
+
.and_return('/rake/dir')
|
92
|
+
allow(Rake.application).to receive(:rakefile).and_return('Rakefile')
|
93
|
+
allow(File).to receive(:realpath) { |p| p }
|
94
|
+
expect do
|
95
|
+
TFWrapper::RakeTasks.new(
|
96
|
+
'tfdir',
|
97
|
+
consul_env_vars_prefix: 'cvprefix',
|
98
|
+
tf_vars_from_env: { 'foo' => 'bar' }
|
99
|
+
)
|
100
|
+
end.to raise_error(
|
101
|
+
StandardError,
|
102
|
+
'Cannot set env vars in Consul when consul_url option is nil.'
|
103
|
+
)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
describe '#nsprefix' do
|
108
|
+
context 'return value' do
|
109
|
+
it 'returns default if namespace_prefix nil' do
|
110
|
+
subject.instance_variable_set('@ns_prefix', nil)
|
111
|
+
expect(subject.nsprefix).to eq(:tf)
|
112
|
+
end
|
113
|
+
it 'prefixes namespace if namespace_prefix is not nill' do
|
114
|
+
subject.instance_variable_set('@ns_prefix', 'foo')
|
115
|
+
expect(subject.nsprefix).to eq(:foo_tf)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
context 'jobs' do
|
119
|
+
let(:tasknames) do
|
120
|
+
%w[
|
121
|
+
init
|
122
|
+
plan
|
123
|
+
apply
|
124
|
+
refresh
|
125
|
+
destroy
|
126
|
+
write_tf_vars
|
127
|
+
]
|
128
|
+
end
|
129
|
+
describe 'when namespace_prefix nil' do
|
130
|
+
# these let/before/after come from bundler's gem_helper_spec.rb
|
131
|
+
let!(:rake_application) { Rake.application }
|
132
|
+
before(:each) do
|
133
|
+
Rake::Task.clear
|
134
|
+
Rake.application = Rake::Application.new
|
135
|
+
end
|
136
|
+
after(:each) do
|
137
|
+
Rake.application = rake_application
|
138
|
+
end
|
139
|
+
before do
|
140
|
+
subject.install
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'sets the default namespace' do
|
144
|
+
tasknames.each do |tname|
|
145
|
+
expect(Rake.application["tf:#{tname}"])
|
146
|
+
.to be_instance_of(Rake::Task)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
it 'includes the correct namespace in all dependencies' do
|
150
|
+
tasknames.each do |tname|
|
151
|
+
Rake.application["tf:#{tname}"].prerequisites.each do |prer|
|
152
|
+
expect(prer.to_s).to start_with('tf:')
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
describe 'when namespace_prefix set' do
|
158
|
+
# these let/before/after come from bundler's gem_helper_spec.rb
|
159
|
+
let!(:rake_application) { Rake.application }
|
160
|
+
before(:each) do
|
161
|
+
Rake::Task.clear
|
162
|
+
Rake.application = Rake::Application.new
|
163
|
+
end
|
164
|
+
after(:each) do
|
165
|
+
Rake.application = rake_application
|
166
|
+
end
|
167
|
+
before do
|
168
|
+
subject.instance_variable_set('@ns_prefix', 'foo')
|
169
|
+
subject.install
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'sets the default namespace' do
|
173
|
+
tasknames.each do |tname|
|
174
|
+
expect(Rake.application["foo_tf:#{tname}"])
|
175
|
+
.to be_instance_of(Rake::Task)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
it 'includes the correct namespace in all dependencies' do
|
179
|
+
tasknames.each do |tname|
|
180
|
+
Rake.application["foo_tf:#{tname}"].prerequisites.each do |prer|
|
181
|
+
expect(prer.to_s).to start_with('foo_tf:')
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
describe '#var_file_path' do
|
189
|
+
context 'return value' do
|
190
|
+
it 'returns default if namespace_prefix nil' do
|
191
|
+
allow(File).to receive(:absolute_path)
|
192
|
+
.and_return('/foo/build.tfvars.json')
|
193
|
+
expect(File).to receive(:absolute_path).once.with('build.tfvars.json')
|
194
|
+
subject.instance_variable_set('@ns_prefix', nil)
|
195
|
+
expect(subject.var_file_path).to eq('/foo/build.tfvars.json')
|
196
|
+
end
|
197
|
+
it 'prefixes if namespace_prefix is not nill' do
|
198
|
+
allow(File).to receive(:absolute_path)
|
199
|
+
.and_return('/foo/foo_build.tfvars.json')
|
200
|
+
subject.instance_variable_set('@ns_prefix', 'foo')
|
201
|
+
expect(File).to receive(:absolute_path).once
|
202
|
+
.with('foo_build.tfvars.json')
|
203
|
+
expect(subject.var_file_path).to eq('/foo/foo_build.tfvars.json')
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
describe '#install' do
|
208
|
+
it 'calls the install methods' do
|
209
|
+
allow(subject).to receive(:install_init)
|
210
|
+
allow(subject).to receive(:install_plan)
|
211
|
+
allow(subject).to receive(:install_apply)
|
212
|
+
allow(subject).to receive(:install_refresh)
|
213
|
+
allow(subject).to receive(:install_destroy)
|
214
|
+
allow(subject).to receive(:install_write_tf_vars)
|
215
|
+
expect(subject).to receive(:install_init).once
|
216
|
+
expect(subject).to receive(:install_plan).once
|
217
|
+
expect(subject).to receive(:install_apply).once
|
218
|
+
expect(subject).to receive(:install_refresh).once
|
219
|
+
expect(subject).to receive(:install_destroy).once
|
220
|
+
expect(subject).to receive(:install_write_tf_vars).once
|
221
|
+
subject.install
|
222
|
+
end
|
223
|
+
end
|
224
|
+
describe '#install_init' do
|
225
|
+
# these let/before/after come from bundler's gem_helper_spec.rb
|
226
|
+
let!(:rake_application) { Rake.application }
|
227
|
+
before(:each) do
|
228
|
+
Rake::Task.clear
|
229
|
+
Rake.application = Rake::Application.new
|
230
|
+
end
|
231
|
+
after(:each) do
|
232
|
+
Rake.application = rake_application
|
233
|
+
end
|
234
|
+
before do
|
235
|
+
subject.install_init
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'adds the init task' do
|
239
|
+
expect(Rake.application['tf:init']).to be_instance_of(Rake::Task)
|
240
|
+
end
|
241
|
+
it 'runs the init command with backend_config options' do
|
242
|
+
Rake.application['tf:init'].clear_prerequisites
|
243
|
+
vars = { foo: 'bar', baz: 'blam' }
|
244
|
+
subject.instance_variable_set('@tf_vars_from_env', vars)
|
245
|
+
allow(TFWrapper::Helpers).to receive(:check_env_vars)
|
246
|
+
allow(ENV).to receive(:[])
|
247
|
+
subject.instance_variable_set(
|
248
|
+
'@backend_config',
|
249
|
+
'address' => 'chost',
|
250
|
+
'path' => 'consulprefix',
|
251
|
+
'foo' => 'bar'
|
252
|
+
)
|
253
|
+
allow(subject).to receive(:terraform_runner)
|
254
|
+
allow(subject).to receive(:check_tf_version)
|
255
|
+
expect(TFWrapper::Helpers)
|
256
|
+
.to receive(:check_env_vars).once.ordered.with(vars.values)
|
257
|
+
expect(subject).to receive(:check_tf_version).once.ordered
|
258
|
+
expect(subject).to receive(:terraform_runner).once.ordered
|
259
|
+
.with('terraform init -input=false '\
|
260
|
+
'-backend-config=\'address=chost\'' \
|
261
|
+
' -backend-config=\'path=consulprefix\''\
|
262
|
+
' -backend-config=\'foo=bar\'')
|
263
|
+
Rake.application['tf:init'].invoke
|
264
|
+
end
|
265
|
+
it 'runs the init command without backend_config options' do
|
266
|
+
Rake.application['tf:init'].clear_prerequisites
|
267
|
+
vars = { foo: 'bar', baz: 'blam' }
|
268
|
+
subject.instance_variable_set('@tf_vars_from_env', vars)
|
269
|
+
allow(TFWrapper::Helpers).to receive(:check_env_vars)
|
270
|
+
allow(ENV).to receive(:[])
|
271
|
+
subject.instance_variable_set('@backend_config', {})
|
272
|
+
allow(subject).to receive(:terraform_runner)
|
273
|
+
allow(subject).to receive(:check_tf_version)
|
274
|
+
expect(TFWrapper::Helpers)
|
275
|
+
.to receive(:check_env_vars).once.ordered.with(vars.values)
|
276
|
+
expect(subject).to receive(:check_tf_version).once.ordered
|
277
|
+
expect(subject).to receive(:terraform_runner).once.ordered
|
278
|
+
.with('terraform init -input=false')
|
279
|
+
Rake.application['tf:init'].invoke
|
280
|
+
end
|
281
|
+
end
|
282
|
+
describe '#install_plan' do
|
283
|
+
# these let/before/after come from bundler's gem_helper_spec.rb
|
284
|
+
let!(:rake_application) { Rake.application }
|
285
|
+
before(:each) do
|
286
|
+
Rake::Task.clear
|
287
|
+
Rake.application = Rake::Application.new
|
288
|
+
end
|
289
|
+
after(:each) do
|
290
|
+
Rake.application = rake_application
|
291
|
+
end
|
292
|
+
before do
|
293
|
+
subject.install_plan
|
294
|
+
end
|
295
|
+
|
296
|
+
it 'adds the plan task' do
|
297
|
+
expect(Rake.application['tf:plan']).to be_instance_of(Rake::Task)
|
298
|
+
expect(Rake.application['tf:plan'].prerequisites)
|
299
|
+
.to eq(%w[tf:init tf:write_tf_vars])
|
300
|
+
expect(Rake.application['tf:plan'].arg_names).to eq([:target])
|
301
|
+
end
|
302
|
+
it 'runs the plan command with no targets' do
|
303
|
+
Rake.application['tf:plan'].clear_prerequisites
|
304
|
+
allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
|
305
|
+
allow(subject).to receive(:terraform_runner)
|
306
|
+
expect(subject).to receive(:terraform_runner).once
|
307
|
+
.with('terraform plan -var-file file.tfvars.json')
|
308
|
+
Rake.application['tf:plan'].invoke
|
309
|
+
end
|
310
|
+
it 'runs the plan command with one target' do
|
311
|
+
Rake.application['tf:plan'].clear_prerequisites
|
312
|
+
allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
|
313
|
+
allow(subject).to receive(:terraform_runner)
|
314
|
+
expect(subject).to receive(:terraform_runner).once
|
315
|
+
.with('terraform plan -var-file file.tfvars.json ' \
|
316
|
+
'-target tar.get[1]')
|
317
|
+
Rake.application['tf:plan'].invoke('tar.get[1]')
|
318
|
+
end
|
319
|
+
it 'runs the plan command with three targets' do
|
320
|
+
Rake.application['tf:plan'].clear_prerequisites
|
321
|
+
allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
|
322
|
+
allow(subject).to receive(:terraform_runner)
|
323
|
+
expect(subject).to receive(:terraform_runner).once
|
324
|
+
.with('terraform plan -var-file file.tfvars.json ' \
|
325
|
+
'-target tar.get[1] -target t.gt[2] -target my.target[3]')
|
326
|
+
Rake.application['tf:plan'].invoke(
|
327
|
+
'tar.get[1]', 't.gt[2]', 'my.target[3]'
|
328
|
+
)
|
329
|
+
end
|
330
|
+
end
|
331
|
+
describe '#install_apply' do
|
332
|
+
# these let/before/after come from bundler's gem_helper_spec.rb
|
333
|
+
let!(:rake_application) { Rake.application }
|
334
|
+
before(:each) do
|
335
|
+
Rake::Task.clear
|
336
|
+
Rake.application = Rake::Application.new
|
337
|
+
end
|
338
|
+
after(:each) do
|
339
|
+
Rake.application = rake_application
|
340
|
+
end
|
341
|
+
before do
|
342
|
+
subject.install_apply
|
343
|
+
end
|
344
|
+
|
345
|
+
it 'adds the apply task' do
|
346
|
+
expect(Rake.application['tf:apply']).to be_instance_of(Rake::Task)
|
347
|
+
expect(Rake.application['tf:apply'].prerequisites)
|
348
|
+
.to eq(%w[tf:init tf:write_tf_vars tf:plan])
|
349
|
+
expect(Rake.application['tf:apply'].arg_names).to eq([:target])
|
350
|
+
end
|
351
|
+
it 'runs the apply command with no targets' do
|
352
|
+
Rake.application['tf:apply'].clear_prerequisites
|
353
|
+
allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
|
354
|
+
allow(subject).to receive(:terraform_runner)
|
355
|
+
allow(subject).to receive(:update_consul_stack_env_vars)
|
356
|
+
expect(subject).to receive(:terraform_runner).once
|
357
|
+
.with('terraform apply -var-file file.tfvars.json')
|
358
|
+
expect(subject).to_not receive(:update_consul_stack_env_vars)
|
359
|
+
Rake.application['tf:apply'].invoke
|
360
|
+
end
|
361
|
+
it 'runs the apply command with one target' do
|
362
|
+
Rake.application['tf:apply'].clear_prerequisites
|
363
|
+
allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
|
364
|
+
allow(subject).to receive(:terraform_runner)
|
365
|
+
expect(subject).to receive(:terraform_runner).once
|
366
|
+
.with('terraform apply -var-file file.tfvars.json ' \
|
367
|
+
'-target tar.get[1]')
|
368
|
+
Rake.application['tf:apply'].invoke('tar.get[1]')
|
369
|
+
end
|
370
|
+
it 'runs the apply command with three targets' do
|
371
|
+
Rake.application['tf:apply'].clear_prerequisites
|
372
|
+
allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
|
373
|
+
allow(subject).to receive(:terraform_runner)
|
374
|
+
expect(subject).to receive(:terraform_runner).once
|
375
|
+
.with('terraform apply -var-file file.tfvars.json ' \
|
376
|
+
'-target tar.get[1] -target t.gt[2] -target my.target[3]')
|
377
|
+
Rake.application['tf:apply'].invoke(
|
378
|
+
'tar.get[1]', 't.gt[2]', 'my.target[3]'
|
379
|
+
)
|
380
|
+
end
|
381
|
+
it 'runs update_consul_stack_env_vars if consul_env_vars_prefix not nil' do
|
382
|
+
subject.instance_variable_set('@consul_env_vars_prefix', 'foo')
|
383
|
+
Rake.application['tf:apply'].clear_prerequisites
|
384
|
+
allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
|
385
|
+
allow(subject).to receive(:terraform_runner)
|
386
|
+
allow(subject).to receive(:update_consul_stack_env_vars)
|
387
|
+
expect(subject).to receive(:terraform_runner).once
|
388
|
+
.with('terraform apply -var-file file.tfvars.json')
|
389
|
+
expect(subject).to receive(:update_consul_stack_env_vars).once
|
390
|
+
Rake.application['tf:apply'].invoke
|
391
|
+
end
|
392
|
+
end
|
393
|
+
describe '#install_refresh' do
|
394
|
+
# these let/before/after come from bundler's gem_helper_spec.rb
|
395
|
+
let!(:rake_application) { Rake.application }
|
396
|
+
before(:each) do
|
397
|
+
Rake::Task.clear
|
398
|
+
Rake.application = Rake::Application.new
|
399
|
+
end
|
400
|
+
after(:each) do
|
401
|
+
Rake.application = rake_application
|
402
|
+
end
|
403
|
+
before do
|
404
|
+
subject.install_refresh
|
405
|
+
end
|
406
|
+
|
407
|
+
it 'adds the refresh task' do
|
408
|
+
expect(Rake.application['tf:refresh']).to be_instance_of(Rake::Task)
|
409
|
+
expect(Rake.application['tf:refresh'].prerequisites)
|
410
|
+
.to eq(%w[tf:init tf:write_tf_vars])
|
411
|
+
end
|
412
|
+
it 'runs the refresh command' do
|
413
|
+
Rake.application['tf:refresh'].clear_prerequisites
|
414
|
+
allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
|
415
|
+
allow(subject).to receive(:terraform_runner)
|
416
|
+
expect(subject).to receive(:terraform_runner).once
|
417
|
+
.with('terraform refresh -var-file file.tfvars.json')
|
418
|
+
Rake.application['tf:refresh'].invoke
|
419
|
+
end
|
420
|
+
end
|
421
|
+
describe '#install_destroy' do
|
422
|
+
# these let/before/after come from bundler's gem_helper_spec.rb
|
423
|
+
let!(:rake_application) { Rake.application }
|
424
|
+
before(:each) do
|
425
|
+
Rake::Task.clear
|
426
|
+
Rake.application = Rake::Application.new
|
427
|
+
end
|
428
|
+
after(:each) do
|
429
|
+
Rake.application = rake_application
|
430
|
+
end
|
431
|
+
before do
|
432
|
+
subject.install_destroy
|
433
|
+
end
|
434
|
+
|
435
|
+
it 'adds the destroy task' do
|
436
|
+
expect(Rake.application['tf:destroy']).to be_instance_of(Rake::Task)
|
437
|
+
expect(Rake.application['tf:destroy'].prerequisites)
|
438
|
+
.to eq(%w[tf:init tf:write_tf_vars])
|
439
|
+
expect(Rake.application['tf:destroy'].arg_names).to eq([:target])
|
440
|
+
end
|
441
|
+
it 'runs the destroy command with no targets' do
|
442
|
+
Rake.application['tf:destroy'].clear_prerequisites
|
443
|
+
allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
|
444
|
+
allow(subject).to receive(:terraform_runner)
|
445
|
+
expect(subject).to receive(:terraform_runner).once
|
446
|
+
.with('terraform destroy -force -var-file file.tfvars.json')
|
447
|
+
Rake.application['tf:destroy'].invoke
|
448
|
+
end
|
449
|
+
it 'runs the destroy command with one target' do
|
450
|
+
Rake.application['tf:destroy'].clear_prerequisites
|
451
|
+
allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
|
452
|
+
allow(subject).to receive(:terraform_runner)
|
453
|
+
expect(subject).to receive(:terraform_runner).once
|
454
|
+
.with('terraform destroy -force -var-file file.tfvars.json ' \
|
455
|
+
'-target tar.get[1]')
|
456
|
+
Rake.application['tf:destroy'].invoke('tar.get[1]')
|
457
|
+
end
|
458
|
+
it 'runs the destroy command with three targets' do
|
459
|
+
Rake.application['tf:destroy'].clear_prerequisites
|
460
|
+
allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
|
461
|
+
allow(subject).to receive(:terraform_runner)
|
462
|
+
expect(subject).to receive(:terraform_runner).once
|
463
|
+
.with('terraform destroy -force -var-file file.tfvars.json ' \
|
464
|
+
'-target tar.get[1] -target t.gt[2] -target my.target[3]')
|
465
|
+
Rake.application['tf:destroy'].invoke(
|
466
|
+
'tar.get[1]', 't.gt[2]', 'my.target[3]'
|
467
|
+
)
|
468
|
+
end
|
469
|
+
end
|
470
|
+
describe '#install_write_tf_vars' do
|
471
|
+
# these let/before/after come from bundler's gem_helper_spec.rb
|
472
|
+
context 'when ns_prefix is nil' do
|
473
|
+
let!(:rake_application) { Rake.application }
|
474
|
+
before(:each) do
|
475
|
+
Rake::Task.clear
|
476
|
+
Rake.application = Rake::Application.new
|
477
|
+
end
|
478
|
+
after(:each) do
|
479
|
+
Rake.application = rake_application
|
480
|
+
end
|
481
|
+
before do
|
482
|
+
subject.install_write_tf_vars
|
483
|
+
end
|
484
|
+
|
485
|
+
it 'adds the write_tf_vars task' do
|
486
|
+
expect(Rake.application['tf:write_tf_vars'])
|
487
|
+
.to be_instance_of(Rake::Task)
|
488
|
+
expect(Rake.application['tf:write_tf_vars'].prerequisites).to eq([])
|
489
|
+
end
|
490
|
+
it 'runs the write_tf_vars command' do
|
491
|
+
vars = {
|
492
|
+
'foo' => 'bar',
|
493
|
+
'baz' => 'blam',
|
494
|
+
'aws_access_key' => 'ak'
|
495
|
+
}
|
496
|
+
allow(subject).to receive(:terraform_vars).and_return(vars)
|
497
|
+
allow(subject).to receive(:var_file_path).and_return('file.tfvars.json')
|
498
|
+
f_dbl = double(File)
|
499
|
+
allow(File).to receive(:open).and_yield(f_dbl)
|
500
|
+
allow(f_dbl).to receive(:write)
|
501
|
+
|
502
|
+
expect(subject).to receive(:terraform_vars).once
|
503
|
+
expect(STDOUT).to receive(:puts).once.with('Terraform vars:')
|
504
|
+
expect(STDOUT).to receive(:puts)
|
505
|
+
.once.with('aws_access_key => (redacted)')
|
506
|
+
expect(STDOUT).to receive(:puts).once.with('baz => blam')
|
507
|
+
expect(STDOUT).to receive(:puts).once.with('foo => bar')
|
508
|
+
expect(File).to receive(:open).once.with('file.tfvars.json', 'w')
|
509
|
+
expect(f_dbl).to receive(:write).once.with(vars.to_json)
|
510
|
+
expect(STDERR).to receive(:puts)
|
511
|
+
.once.with('Terraform vars written to: file.tfvars.json')
|
512
|
+
Rake.application['tf:write_tf_vars'].invoke
|
513
|
+
end
|
514
|
+
end
|
515
|
+
context 'when ns_prefix is specified' do
|
516
|
+
let!(:rake_application) { Rake.application }
|
517
|
+
before(:each) do
|
518
|
+
Rake::Task.clear
|
519
|
+
Rake.application = Rake::Application.new
|
520
|
+
end
|
521
|
+
after(:each) do
|
522
|
+
Rake.application = rake_application
|
523
|
+
end
|
524
|
+
before do
|
525
|
+
subject.instance_variable_set('@ns_prefix', 'foo')
|
526
|
+
subject.install_write_tf_vars
|
527
|
+
end
|
528
|
+
|
529
|
+
it 'adds the write_tf_vars task' do
|
530
|
+
expect(Rake.application['foo_tf:write_tf_vars'])
|
531
|
+
.to be_instance_of(Rake::Task)
|
532
|
+
expect(Rake.application['foo_tf:write_tf_vars'].prerequisites).to eq([])
|
533
|
+
end
|
534
|
+
it 'runs the write_tf_vars command' do
|
535
|
+
vars = {
|
536
|
+
'foo' => 'bar',
|
537
|
+
'baz' => 'blam',
|
538
|
+
'aws_access_key' => 'ak'
|
539
|
+
}
|
540
|
+
allow(subject).to receive(:terraform_vars).and_return(vars)
|
541
|
+
allow(subject).to receive(:var_file_path)
|
542
|
+
.and_return('foo_file.tfvars.json')
|
543
|
+
f_dbl = double(File)
|
544
|
+
allow(File).to receive(:open).and_yield(f_dbl)
|
545
|
+
allow(f_dbl).to receive(:write)
|
546
|
+
|
547
|
+
expect(subject).to receive(:terraform_vars).once
|
548
|
+
expect(STDOUT).to receive(:puts).once.with('Terraform vars:')
|
549
|
+
expect(STDOUT).to receive(:puts)
|
550
|
+
.once.with('aws_access_key => (redacted)')
|
551
|
+
expect(STDOUT).to receive(:puts).once.with('baz => blam')
|
552
|
+
expect(STDOUT).to receive(:puts).once.with('foo => bar')
|
553
|
+
expect(File).to receive(:open).once.with('foo_file.tfvars.json', 'w')
|
554
|
+
expect(f_dbl).to receive(:write).once.with(vars.to_json)
|
555
|
+
expect(STDERR).to receive(:puts)
|
556
|
+
.once.with('Terraform vars written to: foo_file.tfvars.json')
|
557
|
+
Rake.application['foo_tf:write_tf_vars'].invoke
|
558
|
+
end
|
559
|
+
end
|
560
|
+
end
|
561
|
+
describe '#terraform_vars' do
|
562
|
+
it 'builds a hash and sets overrides' do
|
563
|
+
v_from_e = { 'vfe1' => 'vfe1name', 'vfe2' => 'vfe2name' }
|
564
|
+
extra_v = { 'ev1' => 'ev1val', 'vfe2' => 'ev_vfe2val' }
|
565
|
+
subject.instance_variable_set('@tf_vars_from_env', v_from_e)
|
566
|
+
subject.instance_variable_set('@tf_extra_vars', extra_v)
|
567
|
+
allow(ENV).to receive(:[])
|
568
|
+
allow(ENV).to receive(:[]).with('vfe1name').and_return('env_vfe1val')
|
569
|
+
allow(ENV).to receive(:[]).with('vfe2name').and_return('env_vfe2val')
|
570
|
+
expect(subject.terraform_vars).to eq(
|
571
|
+
'vfe1' => 'env_vfe1val',
|
572
|
+
'vfe2' => 'ev_vfe2val',
|
573
|
+
'ev1' => 'ev1val'
|
574
|
+
)
|
575
|
+
end
|
576
|
+
end
|
577
|
+
describe '#terraform_runner' do
|
578
|
+
before do
|
579
|
+
Retries.sleep_enabled = false
|
580
|
+
end
|
581
|
+
it 'outputs nothing and succeeds when command succeeds' do
|
582
|
+
allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
|
583
|
+
.with(any_args).and_return(['', 0])
|
584
|
+
expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
|
585
|
+
.once.with('foo', 'tfdir')
|
586
|
+
expect(STDERR).to receive(:puts).once
|
587
|
+
.with("terraform_runner command: 'foo' (in tfdir)")
|
588
|
+
expect(STDERR).to receive(:puts).once
|
589
|
+
.with("terraform_runner command 'foo' finished and exited 0")
|
590
|
+
subject.terraform_runner('foo')
|
591
|
+
end
|
592
|
+
it 'retries if needed' do
|
593
|
+
@times_called = 0
|
594
|
+
allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output) do
|
595
|
+
@times_called += 1
|
596
|
+
raise StandardError if @times_called == 1
|
597
|
+
['', 0]
|
598
|
+
end
|
599
|
+
|
600
|
+
expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
|
601
|
+
.exactly(2).times.with('foo', 'tfdir')
|
602
|
+
expect(STDERR).to receive(:puts).once
|
603
|
+
.with("terraform_runner command: 'foo' (in tfdir)")
|
604
|
+
expect(STDERR).to receive(:puts).once
|
605
|
+
.with(/terraform_runner\sfailed\swith\sStandardError;\sretry\s
|
606
|
+
attempt\s1;\s.+\sseconds\shave\spassed\./x)
|
607
|
+
expect(STDERR).to receive(:puts).once
|
608
|
+
.with("terraform_runner command 'foo' finished and exited 0")
|
609
|
+
subject.terraform_runner('foo')
|
610
|
+
end
|
611
|
+
it 'retries if throttling' do
|
612
|
+
@times_called = 0
|
613
|
+
allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output) do
|
614
|
+
@times_called += 1
|
615
|
+
if @times_called < 3
|
616
|
+
['foo Throttling bar', 2]
|
617
|
+
else
|
618
|
+
['', 0]
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
622
|
+
expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
|
623
|
+
.exactly(3).times.with('foo', 'tfdir')
|
624
|
+
expect(STDERR).to receive(:puts).once
|
625
|
+
.with("terraform_runner command: 'foo' (in tfdir)")
|
626
|
+
expect(STDERR).to receive(:puts).once
|
627
|
+
.with(/terraform_runner\sfailed\swith\sTerraform\shit\sAWS\sAPI\srate\s
|
628
|
+
limiting;\sretry\sattempt\s1;\s.+\sseconds\shave\spassed\./x)
|
629
|
+
expect(STDERR).to receive(:puts).once
|
630
|
+
.with(/terraform_runner\sfailed\swith\sTerraform\shit\sAWS\sAPI\srate\s
|
631
|
+
limiting;\sretry\sattempt\s2;\s.+\sseconds\shave\spassed\./x)
|
632
|
+
expect(STDERR).to receive(:puts).once
|
633
|
+
.with("terraform_runner command 'foo' finished and exited 0")
|
634
|
+
subject.terraform_runner('foo')
|
635
|
+
end
|
636
|
+
it 'retries if status code 403' do
|
637
|
+
@times_called = 0
|
638
|
+
allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output) do
|
639
|
+
@times_called += 1
|
640
|
+
if @times_called < 3
|
641
|
+
['foo status code: 403 bar', 2]
|
642
|
+
else
|
643
|
+
['', 0]
|
644
|
+
end
|
645
|
+
end
|
646
|
+
|
647
|
+
expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
|
648
|
+
.exactly(3).times.with('foo', 'tfdir')
|
649
|
+
expect(STDERR).to receive(:puts).once
|
650
|
+
.with("terraform_runner command: 'foo' (in tfdir)")
|
651
|
+
expect(STDERR).to receive(:puts).once
|
652
|
+
.with(/terraform_runner\sfailed\swith\sTerraform\scommand\sgot\s403\s
|
653
|
+
error\s-\saccess\sdenied\sor\scredentials\snot\spropagated;\sretry\s
|
654
|
+
attempt\s1;\s.+\sseconds\shave\spassed\./x)
|
655
|
+
expect(STDERR).to receive(:puts).once
|
656
|
+
.with(/terraform_runner\sfailed\swith\sTerraform\scommand\sgot\s403\s
|
657
|
+
error\s-\saccess\sdenied\sor\scredentials\snot\spropagated;\sretry\s
|
658
|
+
attempt\s2;\s.+\sseconds\shave\spassed\./x)
|
659
|
+
expect(STDERR).to receive(:puts).once
|
660
|
+
.with("terraform_runner command 'foo' finished and exited 0")
|
661
|
+
subject.terraform_runner('foo')
|
662
|
+
end
|
663
|
+
it 'retries if status code 401' do
|
664
|
+
@times_called = 0
|
665
|
+
allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output) do
|
666
|
+
@times_called += 1
|
667
|
+
if @times_called < 3
|
668
|
+
['foo status code: 401 bar', 2]
|
669
|
+
else
|
670
|
+
['', 0]
|
671
|
+
end
|
672
|
+
end
|
673
|
+
|
674
|
+
expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
|
675
|
+
.exactly(3).times.with('foo', 'tfdir')
|
676
|
+
expect(STDERR).to receive(:puts).once
|
677
|
+
.with("terraform_runner command: 'foo' (in tfdir)")
|
678
|
+
expect(STDERR).to receive(:puts).once
|
679
|
+
.with(/terraform_runner\sfailed\swith\sTerraform\scommand\sgot\s401\s
|
680
|
+
error\s-\saccess\sdenied\sor\scredentials\snot\spropagated;\sretry\s
|
681
|
+
attempt\s1;\s.+\sseconds\shave\spassed\./x)
|
682
|
+
expect(STDERR).to receive(:puts).once
|
683
|
+
.with(/terraform_runner\sfailed\swith\sTerraform\scommand\sgot\s401\s
|
684
|
+
error\s-\saccess\sdenied\sor\scredentials\snot\spropagated;\sretry\s
|
685
|
+
attempt\s2;\s.+\sseconds\shave\spassed\./x)
|
686
|
+
expect(STDERR).to receive(:puts).once
|
687
|
+
.with("terraform_runner command 'foo' finished and exited 0")
|
688
|
+
subject.terraform_runner('foo')
|
689
|
+
end
|
690
|
+
it 'raises an error if the command exits non-zero' do
|
691
|
+
allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
|
692
|
+
.and_return(['', 1])
|
693
|
+
expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output).once
|
694
|
+
.with('foo', 'tfdir')
|
695
|
+
expect(STDERR).to receive(:puts).once
|
696
|
+
.with('terraform_runner command: \'foo\' (in tfdir)')
|
697
|
+
expect { subject.terraform_runner('foo') }
|
698
|
+
.to raise_error('Errors have occurred executing: \'foo\' (exited 1)')
|
699
|
+
end
|
700
|
+
end
|
701
|
+
describe '#check_tf_version' do
|
702
|
+
it 'fails if the command exits non-zero' do
|
703
|
+
allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
|
704
|
+
.and_return(['myout', 2])
|
705
|
+
allow(STDOUT).to receive(:puts)
|
706
|
+
expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output).once
|
707
|
+
.with('terraform version', 'tfdir')
|
708
|
+
expect(STDOUT).to_not receive(:puts)
|
709
|
+
expect { subject.check_tf_version }
|
710
|
+
.to raise_error(
|
711
|
+
StandardError,
|
712
|
+
'ERROR: \'terraform -version\' exited 2: myout'
|
713
|
+
)
|
714
|
+
end
|
715
|
+
it 'strips build information from the version' do
|
716
|
+
ver = Gem::Version.new('3.4.5')
|
717
|
+
allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
|
718
|
+
.and_return(['Terraform v3.4.5-dev (abcde1234+CHANGES)', 0])
|
719
|
+
allow(Gem::Version).to receive(:new).and_return(ver)
|
720
|
+
expect(Gem::Version).to receive(:new).once.with('3.4.5')
|
721
|
+
subject.check_tf_version
|
722
|
+
end
|
723
|
+
it 'fails if the version cannot be identified' do
|
724
|
+
allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
|
725
|
+
.and_return(['myout', 0])
|
726
|
+
allow(STDOUT).to receive(:puts)
|
727
|
+
expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output).once
|
728
|
+
.with('terraform version', 'tfdir')
|
729
|
+
expect(STDOUT).to_not receive(:puts)
|
730
|
+
expect { subject.check_tf_version }
|
731
|
+
.to raise_error(
|
732
|
+
StandardError,
|
733
|
+
'ERROR: could not determine terraform version from \'terraform ' \
|
734
|
+
'-version\' output: myout'
|
735
|
+
)
|
736
|
+
end
|
737
|
+
it 'fails if the version is too old' do
|
738
|
+
allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
|
739
|
+
.and_return(['Terraform v0.0.1-dev (foo)', 0])
|
740
|
+
allow(STDOUT).to receive(:puts)
|
741
|
+
expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output).once
|
742
|
+
.with('terraform version', 'tfdir')
|
743
|
+
expect(STDOUT).to_not receive(:puts)
|
744
|
+
expect { subject.check_tf_version }
|
745
|
+
.to raise_error(
|
746
|
+
StandardError,
|
747
|
+
"ERROR: tfwrapper #{TFWrapper::VERSION} is only compatible with "\
|
748
|
+
"Terraform >= #{subject.min_tf_version} but your terraform "\
|
749
|
+
'binary reports itself as 0.0.1 (Terraform v0.0.1-dev (foo))'
|
750
|
+
)
|
751
|
+
end
|
752
|
+
it 'prints the version if compatible' do
|
753
|
+
allow(TFWrapper::Helpers).to receive(:run_cmd_stream_output)
|
754
|
+
.and_return(['Terraform v999.9.9', 0])
|
755
|
+
allow(STDOUT).to receive(:puts)
|
756
|
+
expect(TFWrapper::Helpers).to receive(:run_cmd_stream_output).once
|
757
|
+
.with('terraform version', 'tfdir')
|
758
|
+
expect(STDOUT).to receive(:puts).once
|
759
|
+
.with('Running with: Terraform v999.9.9')
|
760
|
+
subject.check_tf_version
|
761
|
+
end
|
762
|
+
end
|
763
|
+
describe '#min_tf_version' do
|
764
|
+
it 'returns a Gem::Version for the minimum version' do
|
765
|
+
expect(subject.min_tf_version).to eq(Gem::Version.new('0.9.0'))
|
766
|
+
end
|
767
|
+
end
|
768
|
+
describe '#update_consul_stack_env_vars' do
|
769
|
+
context 'when @consul_url and @consul_env_vars_prefix are specified' do
|
770
|
+
it 'saves the variables in Consul' do
|
771
|
+
vars = { 'foo' => 'bar', 'baz' => 'blam' }
|
772
|
+
expected = { 'bar' => 'barVal', 'blam' => 'blamVal' }
|
773
|
+
subject.instance_variable_set('@tf_vars_from_env', vars)
|
774
|
+
subject.instance_variable_set('@consul_url', 'foo://bar')
|
775
|
+
subject.instance_variable_set('@consul_env_vars_prefix', 'my/prefix')
|
776
|
+
dbl_config = double
|
777
|
+
allow(dbl_config).to receive(:url=)
|
778
|
+
allow(Diplomat).to receive(:configure).and_yield(dbl_config)
|
779
|
+
allow(ENV).to receive(:[])
|
780
|
+
allow(ENV).to receive(:[]).with('CONSUL_HOST').and_return('chost')
|
781
|
+
allow(ENV).to receive(:[]).with('bar').and_return('barVal')
|
782
|
+
allow(ENV).to receive(:[]).with('blam').and_return('blamVal')
|
783
|
+
allow(Diplomat::Kv).to receive(:put)
|
784
|
+
|
785
|
+
expect(Diplomat).to receive(:configure).once
|
786
|
+
expect(dbl_config).to receive(:url=).once.with('foo://bar')
|
787
|
+
expect(STDOUT).to receive(:puts).once
|
788
|
+
.with('Writing stack information to foo://bar at: my/prefix')
|
789
|
+
expect(STDOUT).to receive(:puts).once
|
790
|
+
.with(JSON.pretty_generate(expected))
|
791
|
+
expect(Diplomat::Kv).to receive(:put)
|
792
|
+
.once.with('my/prefix', JSON.generate(expected))
|
793
|
+
subject.update_consul_stack_env_vars
|
794
|
+
end
|
795
|
+
end
|
796
|
+
end
|
797
|
+
describe '#cmd_with_targets' do
|
798
|
+
it 'creates the command string if no targets specified' do
|
799
|
+
expect(
|
800
|
+
subject.cmd_with_targets(
|
801
|
+
['terraform', 'plan', '-var-file', 'foo'],
|
802
|
+
nil,
|
803
|
+
nil
|
804
|
+
)
|
805
|
+
)
|
806
|
+
.to eq('terraform plan -var-file foo')
|
807
|
+
end
|
808
|
+
it 'creates the command string with no targets and a long suffix' do
|
809
|
+
expect(
|
810
|
+
subject.cmd_with_targets(
|
811
|
+
['terraform', 'plan', '-var-file', 'foo'],
|
812
|
+
nil,
|
813
|
+
nil
|
814
|
+
)
|
815
|
+
)
|
816
|
+
.to eq('terraform plan -var-file foo')
|
817
|
+
end
|
818
|
+
it 'creates the command string if one target specified' do
|
819
|
+
expect(
|
820
|
+
subject.cmd_with_targets(
|
821
|
+
['terraform', 'plan', '-var-file', 'foo'],
|
822
|
+
'tar.get[1]',
|
823
|
+
nil
|
824
|
+
)
|
825
|
+
)
|
826
|
+
.to eq('terraform plan -var-file foo -target tar.get[1]')
|
827
|
+
end
|
828
|
+
it 'creates the command string if two targets specified' do
|
829
|
+
expect(
|
830
|
+
subject.cmd_with_targets(
|
831
|
+
['terraform', 'plan', '-var-file', 'foo'],
|
832
|
+
'tar.get[1]',
|
833
|
+
['tar.get[2]']
|
834
|
+
)
|
835
|
+
)
|
836
|
+
.to eq('terraform plan -var-file foo -target tar.get[1] ' \
|
837
|
+
'-target tar.get[2]')
|
838
|
+
end
|
839
|
+
it 'creates the command string if four targets specified' do
|
840
|
+
expect(
|
841
|
+
subject.cmd_with_targets(
|
842
|
+
['terraform', 'plan', '-var-file', 'foo'],
|
843
|
+
'tar.get[1]',
|
844
|
+
['tar.get[2]', 'my.target[3]']
|
845
|
+
)
|
846
|
+
)
|
847
|
+
.to eq('terraform plan -var-file foo -target tar.get[1] ' \
|
848
|
+
'-target tar.get[2] -target my.target[3]')
|
849
|
+
end
|
850
|
+
end
|
851
|
+
end
|