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,225 @@
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 'destroy', destroy: true do
17
+ context 'when -f without cfndk.yml' do
18
+ before(:each) { run_command('cfndk stack destroy -f') }
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
+ stacks:
30
+ YAML
31
+ before(:each) { write_file(file2, yaml) }
32
+ context 'when -c cfndk2.yml -f and empty stacks' do
33
+ before(:each) { run_command("cfndk stack destroy -c=#{file2} -f") }
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 destroy.../)
38
+ end
39
+ end
40
+ end
41
+
42
+ context 'when --config-path cfndk2.yml -f and empty stacks' do
43
+ before(:each) { run_command("cfndk stack destroy --config-path=#{file2} -f") }
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 destroy.../)
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 destroy -f') }
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 enter no' do
65
+ yaml = <<-"YAML"
66
+ keypairs:
67
+ Test1:
68
+ stacks:
69
+ Test:
70
+ template_file: vpc.yaml
71
+ parameter_input: vpc.json
72
+ parameters:
73
+ VpcName: sample<%= append_uuid%>
74
+ timeout_in_minutes: 2
75
+ YAML
76
+ before(:each) { write_file(file, yaml) }
77
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
78
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
79
+ before(:each) { run_command('cfndk stack destroy') }
80
+ before(:each) { type('no') }
81
+ it 'displays confirm message and cancel message and status code = 2' do
82
+ aggregate_failures do
83
+ expect(last_command_started).to have_exit_status(2)
84
+ expect(last_command_started).to have_output(/INFO destroy../)
85
+ expect(last_command_started).to have_output(%r{Are you sure you want to destroy\? \(y/n\)})
86
+ expect(last_command_started).to have_output(/INFO destroy command was canceled/)
87
+ expect(last_command_started).not_to have_output(/INFO deleting stack:/)
88
+ expect(last_command_started).not_to have_output(/INFO deleted stack:/)
89
+ expect(last_command_started).not_to have_output(/INFO do not delete keypair: Test1$/)
90
+ expect(last_command_started).not_to have_output(/INFO do not delete stack: Test$/)
91
+ end
92
+ end
93
+ end
94
+ context 'when enter yes' do
95
+ context 'when keyparis and stacks do not exist' do
96
+ yaml = <<-"YAML"
97
+ keypairs:
98
+ Test1:
99
+ stacks:
100
+ Test:
101
+ template_file: vpc.yaml
102
+ parameter_input: vpc.json
103
+ parameters:
104
+ VpcName: sample<%= append_uuid%>
105
+ timeout_in_minutes: 2
106
+ YAML
107
+ before(:each) { write_file(file, yaml) }
108
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
109
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
110
+ before(:each) { run_command('cfndk destroy -f') }
111
+ before(:each) { stop_all_commands }
112
+ before(:each) { run_command('cfndk stack destroy') }
113
+ before(:each) { type('yes') }
114
+ before(:each) { stop_all_commands }
115
+ it 'displays confirm message and do not delete message' do
116
+ aggregate_failures do
117
+ expect(last_command_started).to be_successfully_executed
118
+ expect(last_command_started).to have_output(/INFO destroy../)
119
+ expect(last_command_started).to have_output(%r{Are you sure you want to destroy\? \(y/n\)})
120
+ expect(last_command_started).not_to have_output(/INFO do not delete keypair: Test1$/)
121
+ expect(last_command_started).to have_output(/INFO do not delete stack: Test$/)
122
+ end
123
+ end
124
+ end
125
+ context 'when keyparis and stacks exist' do
126
+ yaml = <<-"YAML"
127
+ keypairs:
128
+ Test1:
129
+ stacks:
130
+ Test:
131
+ template_file: vpc.yaml
132
+ parameter_input: vpc.json
133
+ parameters:
134
+ VpcName: sample<%= append_uuid%>
135
+ timeout_in_minutes: 2
136
+ YAML
137
+ before(:each) { write_file(file, yaml) }
138
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
139
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
140
+ before(:each) { run_command('cfndk create') }
141
+ before(:each) { stop_all_commands }
142
+ before(:each) { run_command('cfndk stack destroy') }
143
+ before(:each) { type('yes') }
144
+ before(:each) { stop_all_commands }
145
+ it 'displays confirm message and delete message' do
146
+ aggregate_failures do
147
+ expect(last_command_started).to be_successfully_executed
148
+ expect(last_command_started).to have_output(/INFO destroy../)
149
+ expect(last_command_started).to have_output(%r{Are you sure you want to destroy\? \(y/n\)})
150
+ expect(last_command_started).not_to have_output(/INFO deleted keypair: Test1$/)
151
+ expect(last_command_started).to have_output(/INFO deleted stack: Test$/)
152
+ end
153
+ end
154
+ after(:each) { run_command('cfndk destroy -f') }
155
+ end
156
+ context 'when keyparis and stacks exist and enabled is true', enabled: true do
157
+ yaml = <<-"YAML"
158
+ keypairs:
159
+ Test1:
160
+ stacks:
161
+ Test:
162
+ template_file: vpc.yaml
163
+ parameter_input: vpc.json
164
+ parameters:
165
+ VpcName: sample<%= append_uuid%>
166
+ timeout_in_minutes: 2
167
+ enabled: true
168
+ YAML
169
+ before(:each) { write_file(file, yaml) }
170
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
171
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
172
+ before(:each) { run_command('cfndk create') }
173
+ before(:each) { stop_all_commands }
174
+ before(:each) { run_command('cfndk stack destroy') }
175
+ before(:each) { type('yes') }
176
+ before(:each) { stop_all_commands }
177
+ it 'displays confirm message and delete message' do
178
+ aggregate_failures do
179
+ expect(last_command_started).to be_successfully_executed
180
+ expect(last_command_started).to have_output(/INFO destroy../)
181
+ expect(last_command_started).to have_output(%r{Are you sure you want to destroy\? \(y/n\)})
182
+ expect(last_command_started).not_to have_output(/INFO deleted keypair: Test1$/)
183
+ expect(last_command_started).to have_output(/INFO deleted stack: Test$/)
184
+ end
185
+ end
186
+ after(:each) { run_command('cfndk destroy -f') }
187
+ end
188
+ context 'when keyparis and stacks exist and enabled is false', enabled: true do
189
+ yaml = <<-"YAML"
190
+ keypairs:
191
+ Test1:
192
+ stacks:
193
+ Test:
194
+ template_file: vpc.yaml
195
+ parameter_input: vpc.json
196
+ parameters:
197
+ VpcName: sample<%= append_uuid%>
198
+ timeout_in_minutes: 2
199
+ enabled: false
200
+ YAML
201
+ before(:each) { write_file(file, yaml) }
202
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
203
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
204
+ before(:each) { run_command('cfndk create') }
205
+ before(:each) { stop_all_commands }
206
+ before(:each) { run_command('cfndk stack destroy') }
207
+ before(:each) { type('yes') }
208
+ before(:each) { stop_all_commands }
209
+ it 'displays confirm message and delete message' do
210
+ aggregate_failures do
211
+ expect(last_command_started).to be_successfully_executed
212
+ expect(last_command_started).to have_output(/INFO destroy../)
213
+ expect(last_command_started).to have_output(%r{Are you sure you want to destroy\? \(y/n\)})
214
+ expect(last_command_started).not_to have_output(/INFO deleted keypair: Test1$/)
215
+ expect(last_command_started).not_to have_output(/INFO deleted stack: Test$/)
216
+ end
217
+ end
218
+ after(:each) { run_command('cfndk destroy -f') }
219
+ end
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end
225
+ end
@@ -0,0 +1,181 @@
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 'report', report: true do
17
+ context 'without cfndk.yml' do
18
+ before(:each) { run_command('cfndk stack report') }
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 report -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 report.../)
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 report --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 report.../)
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('cfndk.yml') }
56
+ before(:each) { run_command('cfndk stack report') }
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
+
65
+ context 'with empty keypairs and stacks' do
66
+ yaml = <<-"YAML"
67
+ keypairs:
68
+ stacks:
69
+ YAML
70
+ before(:each) { write_file('cfndk.yml', yaml) }
71
+ before(:each) { run_command('cfndk stack report') }
72
+ it 'displays empty stacks and keypairs report' do
73
+ aggregate_failures do
74
+ expect(last_command_started).to be_successfully_executed
75
+ expect(last_command_started).to have_output(/INFO report.../)
76
+ end
77
+ end
78
+ end
79
+
80
+ context 'with keypairs and stacks' do
81
+ yaml = <<-"YAML"
82
+ keypairs:
83
+ Key1:
84
+ Key2:
85
+ stacks:
86
+ Test:
87
+ template_file: vpc.yaml
88
+ parameter_input: vpc.json
89
+ timeout_in_minutes: 2
90
+ Test2:
91
+ template_file: sg.yaml
92
+ parameter_input: sg.json
93
+ depends:
94
+ - Test
95
+ YAML
96
+ context 'without UUID' do
97
+ before(:each) { write_file('cfndk.yml', yaml) }
98
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
99
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
100
+ before(:each) { copy('%/sg.yaml', 'sg.yaml') }
101
+ before(:each) { copy('%/sg.json', 'sg.json') }
102
+ before(:each) { run_command_and_stop('cfndk create') }
103
+ context 'without option' do
104
+ before(:each) { run_command('cfndk stack report') }
105
+ it 'displays stacks report' do
106
+ aggregate_failures do
107
+ expect(last_command_started).to be_successfully_executed
108
+ expect(last_command_started).to have_output(/INFO stack: Test$/)
109
+ expect(last_command_started).to have_output(/INFO stack: Test2$/)
110
+ end
111
+ end
112
+ end
113
+ context 'when --stack-names Test2' do
114
+ before(:each) { run_command('cfndk stack report --stack-names Test2') }
115
+ it 'displays stacks report' do
116
+ aggregate_failures do
117
+ expect(last_command_started).to be_successfully_executed
118
+ expect(last_command_started).not_to have_output(/INFO stack: Test$/)
119
+ expect(last_command_started).to have_output(/INFO stack: Test2$/)
120
+ end
121
+ end
122
+ end
123
+ context 'when --stack-names Test3' do
124
+ before(:each) { run_command('cfndk stack report --stack-names Test3') }
125
+ it 'displays stacks report' do
126
+ aggregate_failures do
127
+ expect(last_command_started).to be_successfully_executed
128
+ expect(last_command_started).not_to have_output(/INFO stack: Test$/)
129
+ expect(last_command_started).not_to have_output(/INFO stack: Test2$/)
130
+ expect(last_command_started).not_to have_output(/INFO stack: Test3$/)
131
+ end
132
+ end
133
+ end
134
+ after(:each) { run_command('cfndk destroy -f') }
135
+ end
136
+ context 'with UUID' do
137
+ before(:each) { write_file('cfndk.yml', yaml) }
138
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
139
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
140
+ before(:each) { copy('%/sg.yaml', 'sg.yaml') }
141
+ before(:each) { copy('%/sg.json', 'sg.json') }
142
+ before(:each) { run_command_and_stop('cfndk create -u 38437346-c75c-47c5-83b4-d504f85e275b') }
143
+ context 'without option' do
144
+ before(:each) { run_command('cfndk stack report -u 38437346-c75c-47c5-83b4-d504f85e275b') }
145
+ it 'displays stacks report' do
146
+ aggregate_failures do
147
+ expect(last_command_started).to be_successfully_executed
148
+ expect(last_command_started).to have_output(/INFO stack: Test-38437346-c75c-47c5-83b4-d504f85e275b$/)
149
+ expect(last_command_started).to have_output(/INFO stack: Test2-38437346-c75c-47c5-83b4-d504f85e275b$/)
150
+ end
151
+ end
152
+ end
153
+ context 'when --stack-names Test2' do
154
+ before(:each) { run_command('cfndk stack report -u 38437346-c75c-47c5-83b4-d504f85e275b --stack-names Test2') }
155
+ it 'displays stacks report' do
156
+ aggregate_failures do
157
+ expect(last_command_started).to be_successfully_executed
158
+ expect(last_command_started).not_to have_output(/INFO stack: Test-38437346-c75c-47c5-83b4-d504f85e275b$/)
159
+ expect(last_command_started).to have_output(/INFO stack: Test2-38437346-c75c-47c5-83b4-d504f85e275b$/)
160
+ end
161
+ end
162
+ end
163
+ context 'when --stack-names Test3' do
164
+ before(:each) { run_command('cfndk stack report -u 38437346-c75c-47c5-83b4-d504f85e275b --stack-names Test3') }
165
+ it 'displays stacks report' do
166
+ aggregate_failures do
167
+ expect(last_command_started).to be_successfully_executed
168
+ expect(last_command_started).not_to have_output(/INFO stack: Test-/)
169
+ expect(last_command_started).not_to have_output(/INFO stack: Test2-/)
170
+ expect(last_command_started).not_to have_output(/INFO stack: Test3-/)
171
+ end
172
+ end
173
+ end
174
+ after(:each) { run_command('cfndk destroy -f -u 38437346-c75c-47c5-83b4-d504f85e275b') }
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,133 @@
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
+ context 'without subcommand', help: true do
17
+ before(:each) { run_command('cfndk stack') }
18
+ it 'displays help and status code = 2' do
19
+ aggregate_failures do
20
+ expect(last_command_started).to have_exit_status(2)
21
+ end
22
+ end
23
+ end
24
+
25
+ describe 'help', help: true do
26
+ context 'without subsubcommand' do
27
+ before(:each) { run_command('cfndk stack help') }
28
+ it 'displays help and status code = 2' do
29
+ aggregate_failures do
30
+ expect(last_command_started).to have_exit_status(2)
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ describe 'validate', validate: true do
37
+ context 'without cfndk.yml' do
38
+ before(:each) { run_command('cfndk stack validate') }
39
+ it 'displays file does not exist error and status code = 1' do
40
+ aggregate_failures do
41
+ expect(last_command_started).to have_exit_status(1)
42
+ expect(last_command_started).to have_output(/ERROR RuntimeError: File does not exist./)
43
+ end
44
+ end
45
+ end
46
+
47
+ context 'with cfndk2.yml' do
48
+ yaml = <<-"YAML"
49
+ keypairs:
50
+ YAML
51
+ before(:each) { write_file(file2, yaml) }
52
+ context 'when -c cfndk2.yml and empty stacks' do
53
+ before(:each) { run_command("cfndk stack validate -c=#{file2}") }
54
+ it 'displays empty stack log' do
55
+ aggregate_failures do
56
+ expect(last_command_started).to be_successfully_executed
57
+ expect(last_command_started).to have_output(/INFO validate.../)
58
+ end
59
+ end
60
+ end
61
+ context 'when --config-path cfndk2.yml and empty stacks' do
62
+ before(:each) { run_command("cfndk stack validate --config-path=#{file2}") }
63
+ it 'displays empty stack log' do
64
+ aggregate_failures do
65
+ expect(last_command_started).to be_successfully_executed
66
+ expect(last_command_started).to have_output(/INFO validate.../)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ context 'with cfndk.yml' do
72
+ context 'when valid yaml' do
73
+ yaml = <<-"YAML"
74
+ stacks:
75
+ Test:
76
+ template_file: vpc.yaml
77
+ parameter_input: vpc.json
78
+ timeout_in_minutes: 2
79
+ YAML
80
+ before(:each) { write_file(file, yaml) }
81
+ before(:each) { copy('%/vpc.yaml', 'vpc.yaml') }
82
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
83
+ before(:each) { run_command('cfndk stack validate') }
84
+ it 'Displays validate message' do
85
+ aggregate_failures do
86
+ expect(last_command_started).to have_exit_status(0)
87
+ expect(last_command_started).to have_output(/INFO validate stack: Test$/)
88
+ end
89
+ end
90
+ end
91
+ context 'when empty yaml' do
92
+ yaml = <<-"YAML"
93
+ stacks:
94
+ Test:
95
+ template_file: vpc.yaml
96
+ timeout_in_minutes: 2
97
+ YAML
98
+ before(:each) { write_file(file, yaml) }
99
+ before(:each) { copy('%/empty_resource.yaml', 'vpc.yaml') }
100
+ before(:each) { run_command('cfndk stack validate') }
101
+ it 'Displays error message and status code = 1' do
102
+ aggregate_failures do
103
+ expect(last_command_started).to have_exit_status(1)
104
+ expect(last_command_started).to have_output(/INFO validate stack: Test$/)
105
+ expect(last_command_started).to have_output(/ERROR Aws::CloudFormation::Errors::ValidationError: Template format error: At least one Resources member must be defined\.$/)
106
+ end
107
+ end
108
+ end
109
+ context 'when invalid yaml' do
110
+ yaml = <<-"YAML"
111
+ stacks:
112
+ Test:
113
+ template_file: vpc.yaml
114
+ parameter_input: vpc.json
115
+ timeout_in_minutes: 2
116
+ YAML
117
+ before(:each) { write_file(file, yaml) }
118
+ before(:each) { copy('%/invalid_vpc.yaml', 'vpc.yaml') }
119
+ before(:each) { copy('%/vpc.json', 'vpc.json') }
120
+ before(:each) { run_command('cfndk stack validate') }
121
+ it 'Displays error message and status code = 1' do
122
+ aggregate_failures do
123
+ expect(last_command_started).to have_exit_status(1)
124
+ expect(last_command_started).to have_output(/INFO validate stack: Test$/)
125
+ expect(last_command_started).to have_output(/ERROR Aws::CloudFormation::Errors::ValidationError: \[\/Resources\] 'null' values are not allowed in templates$/)
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end