cfndk 0.0.7 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +79 -0
  3. data/.gitignore +1 -1
  4. data/.rspec +2 -0
  5. data/.rspec_parallel +6 -0
  6. data/.simplecov +9 -0
  7. data/Gemfile +11 -1
  8. data/Gemfile.lock +815 -0
  9. data/README.md +269 -76
  10. data/bin/cfndk +3 -18
  11. data/cfndk.gemspec +15 -6
  12. data/docker/Dockerfile +8 -0
  13. data/docker/build.sh +3 -0
  14. data/docker/cfndk.sh +14 -0
  15. data/lib/cfndk.rb +36 -0
  16. data/lib/cfndk/change_set_command.rb +103 -0
  17. data/lib/cfndk/command.rb +125 -119
  18. data/lib/cfndk/config_file_loadable.rb +13 -0
  19. data/lib/cfndk/credential_provider_chain.rb +12 -42
  20. data/lib/cfndk/credential_resolvable.rb +10 -0
  21. data/lib/cfndk/diff.rb +38 -0
  22. data/lib/cfndk/global_config.rb +46 -0
  23. data/lib/cfndk/key_pair.rb +66 -14
  24. data/lib/cfndk/key_pair_command.rb +60 -0
  25. data/lib/cfndk/key_pairs.rb +22 -5
  26. data/lib/cfndk/logger.rb +12 -3
  27. data/lib/cfndk/stack.rb +427 -126
  28. data/lib/cfndk/stack_command.rb +128 -0
  29. data/lib/cfndk/stacks.rb +48 -22
  30. data/lib/cfndk/subcommand_help_returnable.rb +16 -0
  31. data/lib/cfndk/template_packager.rb +210 -0
  32. data/lib/cfndk/uuid.rb +10 -0
  33. data/lib/cfndk/version.rb +1 -1
  34. data/skel/cfndk.yml +4 -0
  35. data/spec/.gitignore +1 -0
  36. data/spec/cfndk_change_set_create_spec.rb +436 -0
  37. data/spec/cfndk_change_set_destroy_spec.rb +160 -0
  38. data/spec/cfndk_change_set_execute_spec.rb +179 -0
  39. data/spec/cfndk_change_set_report_spec.rb +107 -0
  40. data/spec/cfndk_change_set_spec.rb +37 -0
  41. data/spec/cfndk_create_spec.rb +504 -0
  42. data/spec/cfndk_destroy_spec.rb +148 -0
  43. data/spec/cfndk_keypiar_spec.rb +397 -0
  44. data/spec/cfndk_report_spec.rb +164 -0
  45. data/spec/cfndk_spec.rb +103 -0
  46. data/spec/cfndk_stack_create_spec.rb +814 -0
  47. data/spec/cfndk_stack_destroy_spec.rb +225 -0
  48. data/spec/cfndk_stack_report_spec.rb +181 -0
  49. data/spec/cfndk_stack_spec.rb +133 -0
  50. data/spec/cfndk_stack_update_spec.rb +553 -0
  51. data/spec/fixtures/big_vpc.yaml +533 -0
  52. data/spec/fixtures/empty_resource.yaml +2 -0
  53. data/spec/fixtures/iam.json +8 -0
  54. data/spec/fixtures/iam.yaml +38 -0
  55. data/spec/fixtures/iam_different.json +8 -0
  56. data/spec/fixtures/invalid_vpc.yaml +21 -0
  57. data/spec/fixtures/lambda_function/index.js +4 -0
  58. data/spec/fixtures/lambda_function/lambda_function.json +4 -0
  59. data/spec/fixtures/lambda_function/lambda_function.yaml +28 -0
  60. data/spec/fixtures/nested_stack.json +35 -0
  61. data/spec/fixtures/nested_stack.yaml +20 -0
  62. data/spec/fixtures/serverless_function/index.js +4 -0
  63. data/spec/fixtures/serverless_function/serverless_function.json +4 -0
  64. data/spec/fixtures/serverless_function/serverless_function.yaml +21 -0
  65. data/spec/fixtures/sg.json +8 -0
  66. data/spec/fixtures/sg.yaml +27 -0
  67. data/spec/fixtures/sg_different.yaml +22 -0
  68. data/spec/fixtures/stack.json +8 -0
  69. data/spec/fixtures/stack.template.json +39 -0
  70. data/spec/fixtures/stack.yaml +22 -0
  71. data/spec/fixtures/vpc.json +8 -0
  72. data/spec/fixtures/vpc.template.json +40 -0
  73. data/spec/fixtures/vpc.yaml +21 -0
  74. data/spec/fixtures/vpc_different.yaml +21 -0
  75. data/spec/spec_helper.rb +14 -0
  76. data/spec/support/aruba.rb +6 -0
  77. data/vagrant/Vagrantfile +89 -0
  78. metadata +259 -31
@@ -0,0 +1,553 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'CFnDK', type: :aruba do
4
+ before(:each) { set_environment_variable('AWS_REGION', ENV['AWS_REGION']) }
5
+ before(:each) { set_environment_variable('AWS_PROFILE', ENV['AWS_PROFILE']) }
6
+ before(:each) { set_environment_variable('AWS_ACCESS_KEY_ID', ENV["AWS_ACCESS_KEY_ID#{ENV['TEST_ENV_NUMBER']}"]) }
7
+ before(:each) { set_environment_variable('AWS_SECRET_ACCESS_KEY', ENV["AWS_SECRET_ACCESS_KEY#{ENV['TEST_ENV_NUMBER']}"]) }
8
+ describe 'bin/cfndk' do
9
+ before(:each) { setup_aruba }
10
+ let(:file) { 'cfndk.yml' }
11
+ let(:file2) { 'cfndk2.yml' }
12
+ let(:pem) { 'test.pem' }
13
+ let(:uuid) { '38437346-c75c-47c5-83b4-d504f85e275b' }
14
+
15
+ describe 'stack' do
16
+ describe 'update', update: true do
17
+ context 'without cfndk.yml' do
18
+ before(:each) { run_command('cfndk stack update') }
19
+ it 'displays file does not exist error and status code = 1' do
20
+ aggregate_failures do
21
+ expect(last_command_started).to have_exit_status(1)
22
+ expect(last_command_started).to have_output(/ERROR RuntimeError: File does not exist./)
23
+ end
24
+ end
25
+ end
26
+
27
+ context 'with cfndk2.yml' do
28
+ yaml = <<-"YAML"
29
+ keypairs:
30
+ YAML
31
+ before(:each) { write_file(file2, yaml) }
32
+ context 'when -c cfndk2.yml and empty stacks' do
33
+ before(:each) { run_command("cfndk stack update -c=#{file2}") }
34
+ it 'displays empty stack log' do
35
+ aggregate_failures do
36
+ expect(last_command_started).to be_successfully_executed
37
+ expect(last_command_started).to have_output(/INFO update.../)
38
+ end
39
+ end
40
+ end
41
+
42
+ context 'when --config-path cfndk2.yml and empty stacks' do
43
+ before(:each) { run_command("cfndk stack update --config-path=#{file2}") }
44
+ it 'displays empty stack log' do
45
+ aggregate_failures do
46
+ expect(last_command_started).to be_successfully_executed
47
+ expect(last_command_started).to have_output(/INFO update.../)
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ context 'with cfndk.yml' do
54
+ context 'when cfndk.yml is empty' do
55
+ before(:each) { touch(file) }
56
+ before(:each) { run_command('cfndk stack update') }
57
+ it 'displays File is empty error and status code = 1' do
58
+ aggregate_failures do
59
+ expect(last_command_started).to have_exit_status(1)
60
+ expect(last_command_started).to have_output(/ERROR File is empty./)
61
+ end
62
+ end
63
+ end
64
+ context 'when empty yaml' do
65
+ yaml = <<-"YAML"
66
+ stacks:
67
+ Test:
68
+ template_file: vpc.yaml
69
+ timeout_in_minutes: 2
70
+ YAML
71
+ before(:each) { write_file(file, yaml) }
72
+ before(:each) { copy('%/empty_resource.yaml', 'vpc.yaml') }
73
+ before(:each) { run_command('cfndk stack update') }
74
+ it 'Displays error message and status code = 1' do
75
+ aggregate_failures do
76
+ expect(last_command_started).to have_exit_status(1)
77
+ expect(last_command_started).to have_output(/INFO validate stack: Test$/)
78
+ expect(last_command_started).to have_output(/ERROR Aws::CloudFormation::Errors::ValidationError: Template format error: At least one Resources member must be defined\.$/)
79
+ end
80
+ end
81
+ end
82
+ context 'when invalid yaml' do
83
+ yaml = <<-"YAML"
84
+ stacks:
85
+ Test:
86
+ template_file: vpc.yaml
87
+ parameter_input: vpc.json
88
+ timeout_in_minutes: 2
89
+ YAML
90
+ before(:each) { write_file(file, yaml) }
91
+ before(:each) { copy('%/invalid_vpc.yaml', 'vpc.yaml') }
92
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
93
+ before(:each) { run_command('cfndk stack update') }
94
+ it 'Displays error message and status code = 1' do
95
+ aggregate_failures do
96
+ expect(last_command_started).to have_exit_status(1)
97
+ expect(last_command_started).to have_output(/INFO validate stack: Test$/)
98
+ expect(last_command_started).to have_output(/ERROR Aws::CloudFormation::Errors::ValidationError: \[\/Resources\] 'null' values are not allowed in templates$/)
99
+ end
100
+ end
101
+ end
102
+
103
+ context 'with stacks:' do
104
+ context 'without stack' do
105
+ before(:each) { write_file(file, 'stacks:') }
106
+ before(:each) { run_command('cfndk stack update') }
107
+ it do
108
+ aggregate_failures do
109
+ expect(last_command_started).to be_successfully_executed
110
+ expect(last_command_started).to have_output(/INFO update.../)
111
+ end
112
+ end
113
+ end
114
+
115
+ context 'with a stack', with_stack: true do
116
+ yaml = <<-"YAML"
117
+ stacks:
118
+ Test:
119
+ template_file: vpc.yaml
120
+ parameter_input: vpc.json
121
+ timeout_in_minutes: 2
122
+ YAML
123
+ before(:each) { write_file(file, yaml) }
124
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
125
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
126
+ context 'when stack already exist' do
127
+ context 'when same yaml' do
128
+ before(:each) { run_command_and_stop('cfndk stack create') }
129
+ before(:each) { run_command('cfndk stack update') }
130
+ it 'displays No update warn' do
131
+ aggregate_failures do
132
+ expect(last_command_started).to have_exit_status(0)
133
+ expect(last_command_started).to have_output(/INFO validate stack: Test$/)
134
+ expect(last_command_started).to have_output(/INFO updating stack: Test$/)
135
+ expect(last_command_started).to have_output(/WARN No updates are to be performed\.: Test$/)
136
+ end
137
+ end
138
+ end
139
+ context 'when different yaml' do
140
+ before(:each) { run_command_and_stop('cfndk stack create') }
141
+ before(:each) { copy('%/vpc_different.yaml', 'vpc.yaml') }
142
+ before(:each) { run_command('cfndk stack update') }
143
+ before(:each) { append_to_file('vpc.yaml', ' ' * (51200 + 1 - file_size('vpc.yaml').to_i)) }
144
+ it 'displays update log' do
145
+ aggregate_failures do
146
+ expect(last_command_started).to be_successfully_executed
147
+ expect(last_command_started).to have_output(/INFO validate stack: Test$/)
148
+ expect(last_command_started).to have_output(/INFO updating stack: Test$/)
149
+ expect(last_command_started).to have_output(/INFO updated stack: Test$/)
150
+ end
151
+ end
152
+ end
153
+ end
154
+ context 'when stack does not exist' do
155
+ before(:each) { run_command('cfndk stack update') }
156
+ it 'displays no stack error and statu code = 1' do
157
+ aggregate_failures do
158
+ expect(last_command_started).to have_exit_status(1)
159
+ expect(last_command_started).to have_output(/INFO validate stack: Test$/)
160
+ expect(last_command_started).to have_output(/INFO updating stack: Test$/)
161
+ expect(last_command_started).to have_output(/ERROR Aws::CloudFormation::Errors::ValidationError: Stack \[Test\] does not exist$/)
162
+ end
163
+ end
164
+ end
165
+ after(:each) { run_command('cfndk destroy -f') }
166
+ end
167
+ context 'with a stack and enabled is true', test: true do
168
+ yaml = <<-"YAML"
169
+ stacks:
170
+ Test:
171
+ template_file: vpc.yaml
172
+ parameter_input: vpc.json
173
+ timeout_in_minutes: 2
174
+ enabled: true
175
+ YAML
176
+ before(:each) { write_file(file, yaml) }
177
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
178
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
179
+ context 'when stack already exist' do
180
+ context 'when same yaml' do
181
+ before(:each) { run_command_and_stop('cfndk stack create') }
182
+ before(:each) { run_command('cfndk stack update') }
183
+ it 'displays No update warn' do
184
+ aggregate_failures do
185
+ expect(last_command_started).to have_exit_status(0)
186
+ expect(last_command_started).to have_output(/INFO validate stack: Test$/)
187
+ expect(last_command_started).to have_output(/INFO updating stack: Test$/)
188
+ expect(last_command_started).to have_output(/WARN No updates are to be performed\.: Test$/)
189
+ end
190
+ end
191
+ end
192
+ context 'when different yaml' do
193
+ before(:each) { run_command_and_stop('cfndk stack create') }
194
+ before(:each) { copy('%/vpc_different.yaml', 'vpc.yaml') }
195
+ before(:each) { run_command('cfndk stack update') }
196
+ before(:each) { append_to_file('vpc.yaml', ' ' * (51200 + 1 - file_size('vpc.yaml').to_i)) }
197
+ it 'displays update log' do
198
+ aggregate_failures do
199
+ expect(last_command_started).to be_successfully_executed
200
+ expect(last_command_started).to have_output(/INFO validate stack: Test$/)
201
+ expect(last_command_started).to have_output(/INFO updating stack: Test$/)
202
+ expect(last_command_started).to have_output(/INFO updated stack: Test$/)
203
+ end
204
+ end
205
+ end
206
+ end
207
+ after(:each) { run_command('cfndk destroy -f') }
208
+ end
209
+ context 'with a stack and enabled is false', test: true do
210
+ yaml = <<-"YAML"
211
+ stacks:
212
+ Test:
213
+ template_file: vpc.yaml
214
+ parameter_input: vpc.json
215
+ timeout_in_minutes: 2
216
+ enabled: false
217
+ YAML
218
+ before(:each) { write_file(file, yaml) }
219
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
220
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
221
+ context 'when stack already exist' do
222
+ context 'when same yaml' do
223
+ before(:each) { run_command_and_stop('cfndk stack create') }
224
+ before(:each) { run_command('cfndk stack update') }
225
+ it 'displays No update warn' do
226
+ aggregate_failures do
227
+ expect(last_command_started).to have_exit_status(0)
228
+ expect(last_command_started).to have_output(/INFO update...$/)
229
+ expect(last_command_started).not_to have_output(/INFO validate stack: Test$/)
230
+ expect(last_command_started).not_to have_output(/INFO updating stack: Test$/)
231
+ expect(last_command_started).not_to have_output(/WARN No updates are to be performed\.: Test$/)
232
+ end
233
+ end
234
+ end
235
+ context 'when different yaml' do
236
+ before(:each) { run_command_and_stop('cfndk stack create') }
237
+ before(:each) { copy('%/vpc_different.yaml', 'vpc.yaml') }
238
+ before(:each) { run_command('cfndk stack update') }
239
+ before(:each) { append_to_file('vpc.yaml', ' ' * (51200 + 1 - file_size('vpc.yaml').to_i)) }
240
+ it 'displays update log' do
241
+ aggregate_failures do
242
+ expect(last_command_started).to be_successfully_executed
243
+ expect(last_command_started).to have_output(/INFO update...$/)
244
+ expect(last_command_started).not_to have_output(/INFO validate stack: Test$/)
245
+ expect(last_command_started).not_to have_output(/INFO updating stack: Test$/)
246
+ expect(last_command_started).not_to have_output(/INFO updated stack: Test$/)
247
+ end
248
+ end
249
+ end
250
+ end
251
+ after(:each) { run_command('cfndk destroy -f') }
252
+ end
253
+ context 'with two stacks' do
254
+ yaml = <<-"YAML"
255
+ stacks:
256
+ Test:
257
+ template_file: vpc.yaml
258
+ parameter_input: vpc.json
259
+ timeout_in_minutes: 4
260
+ Test2:
261
+ template_file: sg.yaml
262
+ parameter_input: sg.json
263
+ depends:
264
+ - Test
265
+ YAML
266
+ before(:each) { write_file(file, yaml) }
267
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
268
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
269
+ before(:each) { copy('%/sg.yaml', 'sg.yaml') }
270
+ before(:each) { copy('%/sg.json', 'sg.json') }
271
+ before(:each) { run_command_and_stop('cfndk stack create') }
272
+ before(:each) { copy('%/sg_different.yaml', 'sg.yaml') }
273
+ before(:each) { run_command('cfndk stack update') }
274
+ it 'displays updated logs' do
275
+ aggregate_failures do
276
+ expect(last_command_started).to be_successfully_executed
277
+ expect(last_command_started).to have_output(/INFO validate stack: Test$/)
278
+ expect(last_command_started).to have_output(/INFO updating stack: Test$/)
279
+ expect(last_command_started).to have_output(/WARN No updates are to be performed.: Test$/)
280
+ expect(last_command_started).to have_output(/INFO validate stack: Test2$/)
281
+ expect(last_command_started).to have_output(/INFO updating stack: Test2$/)
282
+ expect(last_command_started).to have_output(/INFO updated stack: Test2$/)
283
+ end
284
+ end
285
+ after(:each) { run_command('cfndk destroy -f') }
286
+ end
287
+ context 'when cyclic dependency', dependency: true do
288
+ yaml = <<-"YAML"
289
+ stacks:
290
+ Test:
291
+ template_file: vpc.yaml
292
+ parameter_input: vpc.json
293
+ timeout_in_minutes: 2
294
+ depends:
295
+ - Test2
296
+ Test2:
297
+ template_file: sg.yaml
298
+ parameter_input: sg.json
299
+ depends:
300
+ - Test
301
+ YAML
302
+
303
+ before(:each) { write_file(file, yaml) }
304
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
305
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
306
+ before(:each) { copy('%/sg.yaml', 'sg.yaml') }
307
+ before(:each) { copy('%/sg.json', 'sg.json') }
308
+ before(:each) { run_command('cfndk stack update') }
309
+ it 'displays cyclic error log and exit status = 1' do
310
+ aggregate_failures do
311
+ expect(last_command_started).to have_exit_status(1)
312
+ expect(last_command_started).to have_output(/ERROR RuntimeError: There are cyclic dependency or stack doesn't exist. unprocessed_stack: Test,Test2$/)
313
+ end
314
+ end
315
+ after(:each) { run_command('cfndk destroy -f') }
316
+ end
317
+ context 'when requires capabilities without capabilities', capabilities: true do
318
+ yaml = <<-"YAML"
319
+ stacks:
320
+ Test:
321
+ template_file: iam.yaml
322
+ parameter_input: iam.json
323
+ capabilities:
324
+ - CAPABILITY_NAMED_IAM
325
+ timeout_in_minutes: 3
326
+ YAML
327
+ yaml2 = <<-"YAML"
328
+ stacks:
329
+ Test:
330
+ template_file: iam.yaml
331
+ parameter_input: iam.json
332
+ timeout_in_minutes: 2
333
+ YAML
334
+ before(:each) { write_file(file, yaml) }
335
+ before(:each) { copy('%/iam.yaml', 'iam.yaml') }
336
+ before(:each) { copy('%/iam.json', 'iam.json') }
337
+ before(:each) { run_command_and_stop('cfndk stack create') }
338
+ before(:each) { write_file(file, yaml2) }
339
+ before(:each) { run_command('cfndk stack update') }
340
+ it 'displays Requires capabilities log and exit status = 1' do
341
+ aggregate_failures do
342
+ expect(last_command_started).to have_exit_status(1)
343
+ expect(last_command_started).to have_output(/ERROR Aws::CloudFormation::Errors::InsufficientCapabilitiesException: Requires capabilities : \[CAPABILITY_NAMED_IAM\]/)
344
+ end
345
+ end
346
+ after(:each) { run_command('cfndk destroy -f') }
347
+ end
348
+ context 'when success with capabilities', capabilities: true do
349
+ yaml = <<-"YAML"
350
+ stacks:
351
+ Test:
352
+ template_file: iam.yaml
353
+ parameter_input: iam.json
354
+ capabilities:
355
+ - CAPABILITY_NAMED_IAM
356
+ timeout_in_minutes: 3
357
+ YAML
358
+
359
+ before(:each) { write_file(file, yaml) }
360
+ before(:each) { copy('%/iam.yaml', 'iam.yaml') }
361
+ before(:each) { copy('%/iam.json', 'iam.json') }
362
+ before(:each) { run_command_and_stop('cfndk stack create') }
363
+ before(:each) { copy('%/iam_different.json', 'iam.json') }
364
+ before(:each) { run_command('cfndk stack update') }
365
+ it 'displays updated log' do
366
+ aggregate_failures do
367
+ expect(last_command_started).to be_successfully_executed
368
+ expect(last_command_started).to have_output(/INFO updated stack: Test$/)
369
+ end
370
+ end
371
+ after(:each) { run_command('cfndk destroy -f') }
372
+ end
373
+ context 'with UUID', uuid: true do
374
+ context 'when -u 38437346-c75c-47c5-83b4-d504f85e275b' do
375
+ yaml = <<-"YAML"
376
+ stacks:
377
+ Test:
378
+ template_file: vpc.yaml
379
+ parameter_input: vpc.json
380
+ parameters:
381
+ VpcName: sample<%= append_uuid%>
382
+ timeout_in_minutes: 2
383
+ Test2:
384
+ template_file: sg.yaml
385
+ parameter_input: sg.json
386
+ parameters:
387
+ VpcName: sample<%= append_uuid%>
388
+ depends:
389
+ - Test
390
+ YAML
391
+ before(:each) { write_file(file, yaml) }
392
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
393
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
394
+ before(:each) { copy('%/sg.yaml', 'sg.yaml') }
395
+ before(:each) { copy('%/sg.json', 'sg.json') }
396
+ before(:each) { run_command_and_stop("cfndk stack create -u=#{uuid}") }
397
+ before(:each) { copy('%/vpc_different.yaml', 'vpc.yaml') }
398
+ before(:each) { copy('%/sg_different.yaml', 'sg.yaml') }
399
+ before(:each) { run_command("cfndk stack update -u=#{uuid}") }
400
+ it 'displays updated logs' do
401
+ aggregate_failures do
402
+ expect(last_command_started).to be_successfully_executed
403
+ expect(last_command_started).to have_output(/INFO validate stack: Test-#{uuid}$/)
404
+ expect(last_command_started).to have_output(/INFO updating stack: Test-#{uuid}$/)
405
+ expect(last_command_started).to have_output(/INFO updated stack: Test-#{uuid}$/)
406
+ expect(last_command_started).to have_output(/INFO validate stack: Test2-#{uuid}$/)
407
+ expect(last_command_started).to have_output(/INFO updating stack: Test2-#{uuid}$/)
408
+ expect(last_command_started).to have_output(/INFO updated stack: Test2-#{uuid}$/)
409
+ end
410
+ end
411
+ after(:each) { run_command("cfndk destroy -f -u=#{uuid}") }
412
+ end
413
+ context 'when env CFNDK_UUID=38437346-c75c-47c5-83b4-d504f85e275b' do
414
+ before(:each) { set_environment_variable('CFNDK_UUID', uuid) }
415
+ context 'with two stacks' do
416
+ yaml = <<-"YAML"
417
+ stacks:
418
+ Test:
419
+ template_file: vpc.yaml
420
+ parameter_input: vpc.json
421
+ parameters:
422
+ VpcName: sample<%= append_uuid%>
423
+ timeout_in_minutes: 2
424
+ Test2:
425
+ template_file: sg.yaml
426
+ parameter_input: sg.json
427
+ parameters:
428
+ VpcName: sample<%= append_uuid%>
429
+ depends:
430
+ - Test
431
+ YAML
432
+ before(:each) { write_file(file, yaml) }
433
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
434
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
435
+ before(:each) { copy('%/sg.yaml', 'sg.yaml') }
436
+ before(:each) { copy('%/sg.json', 'sg.json') }
437
+ before(:each) { run_command_and_stop('cfndk stack create') }
438
+ before(:each) { copy('%/vpc_different.yaml', 'vpc.yaml') }
439
+ before(:each) { copy('%/sg_different.yaml', 'sg.yaml') }
440
+ before(:each) { run_command('cfndk stack update') }
441
+ it 'displays updated logs' do
442
+ aggregate_failures do
443
+ expect(last_command_started).to be_successfully_executed
444
+ expect(last_command_started).to have_output(/INFO validate stack: Test-#{uuid}$/)
445
+ expect(last_command_started).to have_output(/INFO updating stack: Test-#{uuid}$/)
446
+ expect(last_command_started).to have_output(/INFO updated stack: Test-#{uuid}$/)
447
+ expect(last_command_started).to have_output(/INFO validate stack: Test2-#{uuid}$/)
448
+ expect(last_command_started).to have_output(/INFO updating stack: Test2-#{uuid}$/)
449
+ expect(last_command_started).to have_output(/INFO updated stack: Test2-#{uuid}$/)
450
+ end
451
+ end
452
+ after(:each) { run_command('cfndk destroy -f') }
453
+ end
454
+ context 'when --stack-names=Test' do
455
+ yaml = <<-"YAML"
456
+ stacks:
457
+ Test:
458
+ template_file: vpc.yaml
459
+ parameter_input: vpc.json
460
+ parameters:
461
+ VpcName: sample<%= append_uuid%>
462
+ timeout_in_minutes: 2
463
+ Test2:
464
+ template_file: sg.yaml
465
+ parameter_input: sg.json
466
+ parameters:
467
+ VpcName: sample<%= append_uuid%>
468
+ depends:
469
+ - Test
470
+ YAML
471
+ before(:each) { write_file(file, yaml) }
472
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
473
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
474
+ before(:each) { copy('%/sg.yaml', 'sg.yaml') }
475
+ before(:each) { copy('%/sg.json', 'sg.json') }
476
+ before(:each) { run_command_and_stop('cfndk stack create') }
477
+ before(:each) { copy('%/vpc_different.yaml', 'vpc.yaml') }
478
+ before(:each) { run_command('cfndk stack update --stack-names=Test') }
479
+ it 'displays updated log of Test stack' do
480
+ aggregate_failures do
481
+ expect(last_command_started).to be_successfully_executed
482
+ expect(last_command_started).to have_output(/INFO update.../)
483
+ expect(last_command_started).to have_output(/INFO validate stack: Test-#{uuid}$/)
484
+ expect(last_command_started).to have_output(/INFO updating stack: Test-#{uuid}$/)
485
+ expect(last_command_started).to have_output(/INFO updated stack: Test-#{uuid}$/)
486
+ expect(last_command_started).not_to have_output(/INFO validate stack: Test2-#{uuid}$/)
487
+ expect(last_command_started).not_to have_output(/INFO updating stack: Test2-#{uuid}$/)
488
+ expect(last_command_started).not_to have_output(/INFO updated stack: Test2-#{uuid}$/)
489
+ end
490
+ end
491
+ after(:each) { run_command('cfndk destroy -f') }
492
+ end
493
+ context 'when --stack-names=Test Test2' do
494
+ yaml = <<-"YAML"
495
+ stacks:
496
+ Test:
497
+ template_file: vpc.yaml
498
+ parameter_input: vpc.json
499
+ parameters:
500
+ VpcName: sample<%= append_uuid%>
501
+ timeout_in_minutes: 2
502
+ Test2:
503
+ template_file: sg.yaml
504
+ parameter_input: sg.json
505
+ parameters:
506
+ VpcName: sample<%= append_uuid%>
507
+ depends:
508
+ - Test
509
+ Test3:
510
+ template_file: iam.yaml
511
+ parameter_input: iam.json
512
+ parameters:
513
+ WebRoleName: WebhRole<%= append_uuid%>
514
+ capabilities:
515
+ - CAPABILITY_NAMED_IAM
516
+ timeout_in_minutes: 3
517
+ YAML
518
+ before(:each) { write_file(file, yaml) }
519
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
520
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
521
+ before(:each) { copy('%/sg.yaml', 'sg.yaml') }
522
+ before(:each) { copy('%/sg.json', 'sg.json') }
523
+ before(:each) { copy('%/iam.yaml', 'iam.yaml') }
524
+ before(:each) { copy('%/iam.json', 'iam.json') }
525
+ before(:each) { run_command_and_stop('cfndk stack create') }
526
+ before(:each) { copy('%/vpc_different.yaml', 'vpc.yaml') }
527
+ before(:each) { copy('%/sg_different.yaml', 'sg.yaml') }
528
+ before(:each) { run_command('cfndk stack update --stack-names=Test Test2') }
529
+ it 'displays updated logs of Test1/Test2 stacks' do
530
+ aggregate_failures do
531
+ expect(last_command_started).to be_successfully_executed
532
+ expect(last_command_started).to have_output(/INFO update.../)
533
+ expect(last_command_started).to have_output(/INFO validate stack: Test-#{uuid}$/)
534
+ expect(last_command_started).to have_output(/INFO updating stack: Test-#{uuid}$/)
535
+ expect(last_command_started).to have_output(/INFO updated stack: Test-#{uuid}$/)
536
+ expect(last_command_started).to have_output(/INFO validate stack: Test2-#{uuid}$/)
537
+ expect(last_command_started).to have_output(/INFO updating stack: Test2-#{uuid}$/)
538
+ expect(last_command_started).to have_output(/INFO updated stack: Test2-#{uuid}$/)
539
+ expect(last_command_started).not_to have_output(/INFO validate stack: Test3-#{uuid}$/)
540
+ expect(last_command_started).not_to have_output(/INFO updating stack: Test3-#{uuid}$/)
541
+ expect(last_command_started).not_to have_output(/INFO updated stack: Test3-#{uuid}$/)
542
+ end
543
+ end
544
+ after(:each) { run_command('cfndk destroy -f') }
545
+ end
546
+ end
547
+ end
548
+ end
549
+ end
550
+ end
551
+ end
552
+ end
553
+ end