cfndk 0.0.7 → 0.1.2

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.
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