hybrid_platforms_conductor 32.13.4 → 32.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/bin/get_impacted_nodes +1 -1
  4. data/bin/setup +6 -1
  5. data/docs/plugins.md +1 -0
  6. data/docs/plugins/platform_handler/serverless_chef.md +105 -0
  7. data/lib/hybrid_platforms_conductor/deployer.rb +2 -1
  8. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef.rb +440 -0
  9. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/dsl_parser.rb +51 -0
  10. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/recipes_tree_builder.rb +271 -0
  11. data/lib/hybrid_platforms_conductor/nodes_handler.rb +9 -5
  12. data/lib/hybrid_platforms_conductor/version.rb +1 -1
  13. data/spec/hybrid_platforms_conductor_test.rb +3 -0
  14. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioner_spec.rb +23 -0
  15. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs_plugins_api_spec.rb +11 -0
  16. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/config_dsl_spec.rb +17 -0
  17. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/deploy_output_parsing_spec.rb +94 -0
  18. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/diff_impacts_spec.rb +317 -0
  19. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/inventory_spec.rb +65 -0
  20. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/packaging_spec.rb +213 -0
  21. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/services_deployment_spec.rb +268 -0
  22. data/spec/hybrid_platforms_conductor_test/helpers/serverless_chef_helpers.rb +53 -0
  23. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/chef_versions.yml +3 -0
  24. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/nodes/node.json +14 -0
  25. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/policyfiles/test_policy.rb +3 -0
  26. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/chef_versions.yml +3 -0
  27. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/data_bags/my_bag/my_item.json +4 -0
  28. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/nodes/node.json +14 -0
  29. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/policyfiles/test_policy.rb +3 -0
  30. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_1/recipes/default.rb +1 -0
  31. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/libraries/default.rb +4 -0
  32. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/recipes/default.rb +1 -0
  33. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/recipes/other_recipe.rb +1 -0
  34. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/resources/my_resource.rb +1 -0
  35. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node1.json +10 -0
  36. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node2.json +10 -0
  37. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_1.rb +4 -0
  38. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_2.rb +4 -0
  39. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/config.rb +1 -0
  40. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/cookbooks/test_cookbook_1/recipes/default.rb +1 -0
  41. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/nodes/node1.json +10 -0
  42. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/nodes/node2.json +10 -0
  43. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/other_cookbooks/test_cookbook_2/libraries/default.rb +4 -0
  44. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/other_cookbooks/test_cookbook_2/recipes/default.rb +1 -0
  45. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/other_cookbooks/test_cookbook_2/recipes/other_recipe.rb +1 -0
  46. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/other_cookbooks/test_cookbook_2/resources/my_resource.rb +1 -0
  47. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/policyfiles/test_policy_1.rb +4 -0
  48. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/policyfiles/test_policy_2.rb +4 -0
  49. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/chef_versions.yml +3 -0
  50. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/nodes/local.json +10 -0
  51. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/nodes/node1.json +10 -0
  52. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/nodes/node2.json +10 -0
  53. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/policyfiles/test_policy_1.rb +3 -0
  54. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/policyfiles/test_policy_2.rb +3 -0
  55. metadata +187 -143
@@ -0,0 +1,317 @@
1
+ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef do
2
+
3
+ context 'checking files diff impacts' do
4
+
5
+ it 'returns no impact for no diffs' do
6
+ with_serverless_chef_platforms('recipes') do |platform, repository|
7
+ expect(platform.impacts_from({})).to eq [
8
+ [],
9
+ [],
10
+ false
11
+ ]
12
+ end
13
+ end
14
+
15
+ it 'ignores files with no impact' do
16
+ with_serverless_chef_platforms('recipes') do |platform, repository|
17
+ expect(platform.impacts_from(
18
+ 'cookbooks/test_cookbook_1/README.md' => {}
19
+ )).to eq [
20
+ [],
21
+ [],
22
+ false
23
+ ]
24
+ end
25
+ end
26
+
27
+ it 'returns all nodes impact for global files' do
28
+ with_serverless_chef_platforms('recipes') do |platform, repository|
29
+ expect(platform.impacts_from(
30
+ 'global.rb' => {}
31
+ )).to eq [
32
+ [],
33
+ [],
34
+ true
35
+ ]
36
+ end
37
+ end
38
+
39
+ it 'returns direct impacted nodes' do
40
+ with_serverless_chef_platforms('recipes') do |platform, repository|
41
+ expect(platform.impacts_from(
42
+ 'nodes/node1.json' => {}
43
+ )).to eq [
44
+ %w[node1],
45
+ [],
46
+ false
47
+ ]
48
+ end
49
+ end
50
+
51
+ it 'returns direct impacted nodes with strange characters' do
52
+ with_serverless_chef_platforms('recipes') do |platform, repository|
53
+ expect(platform.impacts_from(
54
+ 'nodes/node-v45.env_@user.json' => {}
55
+ )).to eq [
56
+ ['node-v45.env_@user'],
57
+ [],
58
+ false
59
+ ]
60
+ end
61
+ end
62
+
63
+ it 'returns impacted service due to a change in its recipes' do
64
+ with_serverless_chef_platforms('recipes') do |platform, repository|
65
+ expect(platform.impacts_from(
66
+ 'cookbooks/test_cookbook_1/recipes/default.rb' => {}
67
+ )).to eq [
68
+ [],
69
+ %w[test_policy_1],
70
+ false
71
+ ]
72
+ end
73
+ end
74
+
75
+ it 'returns impacted service due to a change in its attributes' do
76
+ with_serverless_chef_platforms('recipes') do |platform, repository|
77
+ expect(platform.impacts_from(
78
+ 'cookbooks/test_cookbook_1/attributes/default.rb' => {}
79
+ )).to eq [
80
+ [],
81
+ %w[test_policy_1],
82
+ false
83
+ ]
84
+ end
85
+ end
86
+
87
+ it 'returns impacted service due to a change in an included template' do
88
+ with_serverless_chef_platforms('recipes') do |platform, repository|
89
+ File.write("#{repository}/cookbooks/test_cookbook_1/recipes/default.rb", <<~EOS)
90
+ template '/home/file' do
91
+ source 'test_template.erb'
92
+ end
93
+ EOS
94
+ expect(platform.impacts_from(
95
+ 'cookbooks/test_cookbook_1/templates/default/test_template.erb' => {}
96
+ )).to eq [
97
+ [],
98
+ %w[test_policy_1],
99
+ false
100
+ ]
101
+ end
102
+ end
103
+
104
+ it 'does not return impacted service due to a change in a non included template' do
105
+ with_serverless_chef_platforms('recipes') do |platform, repository|
106
+ expect(platform.impacts_from(
107
+ 'cookbooks/test_cookbook_1/templates/default/test_template.erb' => {}
108
+ )).to eq [
109
+ [],
110
+ [],
111
+ false
112
+ ]
113
+ end
114
+ end
115
+
116
+ it 'returns impacted service due to a change in an included file' do
117
+ with_serverless_chef_platforms('recipes') do |platform, repository|
118
+ File.write("#{repository}/cookbooks/test_cookbook_1/recipes/default.rb", <<~EOS)
119
+ file '/home/file' do
120
+ source 'test_file'
121
+ end
122
+ EOS
123
+ expect(platform.impacts_from(
124
+ 'cookbooks/test_cookbook_1/files/default/test_file' => {}
125
+ )).to eq [
126
+ [],
127
+ %w[test_policy_1],
128
+ false
129
+ ]
130
+ end
131
+ end
132
+
133
+ it 'does not return impacted service due to a change in a non included file' do
134
+ with_serverless_chef_platforms('recipes') do |platform, repository|
135
+ expect(platform.impacts_from(
136
+ 'cookbooks/test_cookbook_1/files/default/test_file' => {}
137
+ )).to eq [
138
+ [],
139
+ [],
140
+ false
141
+ ]
142
+ end
143
+ end
144
+
145
+ it 'returns impacted service due to a resource usage in a recipe' do
146
+ with_serverless_chef_platforms('recipes') do |platform, repository|
147
+ File.write("#{repository}/cookbooks/test_cookbook_1/recipes/default.rb", <<~EOS)
148
+ test_cookbook_2_my_resource
149
+ EOS
150
+ expect(platform.impacts_from(
151
+ 'cookbooks/test_cookbook_2/resources/my_resource.rb' => {}
152
+ )).to eq [
153
+ [],
154
+ %w[test_policy_1],
155
+ false
156
+ ]
157
+ end
158
+ end
159
+
160
+ it 'does not return impacted service due to a resource not being used in a recipe' do
161
+ with_serverless_chef_platforms('recipes') do |platform, repository|
162
+ expect(platform.impacts_from(
163
+ 'cookbooks/test_cookbook_2/resources/my_resource.rb' => {}
164
+ )).to eq [
165
+ [],
166
+ [],
167
+ false
168
+ ]
169
+ end
170
+ end
171
+
172
+ it 'returns impacted service due to a library helper usage in a recipe' do
173
+ with_serverless_chef_platforms('recipes') do |platform, repository|
174
+ File.write("#{repository}/cookbooks/test_cookbook_1/recipes/default.rb", <<~EOS)
175
+ a = my_library_helper(42)
176
+ EOS
177
+ expect(platform.impacts_from(
178
+ 'cookbooks/test_cookbook_2/libraries/default.rb' => {}
179
+ )).to eq [
180
+ [],
181
+ %w[test_policy_1],
182
+ false
183
+ ]
184
+ end
185
+ end
186
+
187
+ it 'ignored impacted service from an unknown helper' do
188
+ with_serverless_chef_platforms('recipes') do |platform, repository|
189
+ File.write("#{repository}/cookbooks/test_cookbook_1/recipes/default.rb", <<~EOS)
190
+ a = unknown_helper(42)
191
+ EOS
192
+ expect(platform.impacts_from(
193
+ 'cookbooks/test_cookbook_2/recipes/default.rb' => {}
194
+ )).to eq [
195
+ [],
196
+ %w[test_policy_2],
197
+ false
198
+ ]
199
+ end
200
+ end
201
+
202
+ it 'returns impacted service due to an unknown library helper usage that has been configured' do
203
+ with_serverless_chef_platforms(
204
+ 'recipes',
205
+ additional_config: <<~EOS
206
+ helpers_including_recipes(unknown_helper: ['test_cookbook_2'])
207
+ EOS
208
+ ) do |platform, repository|
209
+ File.write("#{repository}/cookbooks/test_cookbook_1/recipes/default.rb", <<~EOS)
210
+ a = unknown_helper(42)
211
+ EOS
212
+ expect(platform.impacts_from(
213
+ 'cookbooks/test_cookbook_2/recipes/default.rb' => {}
214
+ )).to eq [
215
+ [],
216
+ %w[test_policy_1 test_policy_2],
217
+ false
218
+ ]
219
+ end
220
+ end
221
+
222
+ it 'does not return impacted service due to a library helper not being used in a recipe' do
223
+ with_serverless_chef_platforms('recipes') do |platform, repository|
224
+ expect(platform.impacts_from(
225
+ 'cookbooks/test_cookbook_2/libraries/default.rb' => {}
226
+ )).to eq [
227
+ [],
228
+ [],
229
+ false
230
+ ]
231
+ end
232
+ end
233
+
234
+ it 'returns impacted service due to a usage of another cookbook\'s default recipe' do
235
+ with_serverless_chef_platforms('recipes') do |platform, repository|
236
+ File.write("#{repository}/cookbooks/test_cookbook_1/recipes/default.rb", <<~EOS)
237
+ include_recipe 'test_cookbook_2'
238
+ EOS
239
+ expect(platform.impacts_from(
240
+ 'cookbooks/test_cookbook_2/recipes/default.rb' => {}
241
+ )).to eq [
242
+ [],
243
+ %w[test_policy_1 test_policy_2],
244
+ false
245
+ ]
246
+ end
247
+ end
248
+
249
+ it 'returns impacted service due to a usage of another cookbook\'s recipe' do
250
+ with_serverless_chef_platforms('recipes') do |platform, repository|
251
+ File.write("#{repository}/cookbooks/test_cookbook_1/recipes/default.rb", <<~EOS)
252
+ include_recipe 'test_cookbook_2::other_recipe'
253
+ EOS
254
+ expect(platform.impacts_from(
255
+ 'cookbooks/test_cookbook_2/recipes/other_recipe.rb' => {}
256
+ )).to eq [
257
+ [],
258
+ %w[test_policy_1],
259
+ false
260
+ ]
261
+ end
262
+ end
263
+
264
+ it 'ignores cookbooks from cookbook paths that are not configured' do
265
+ with_serverless_chef_platforms('several_cookbooks') do |platform, repository|
266
+ File.write("#{repository}/cookbooks/test_cookbook_1/recipes/default.rb", <<~EOS)
267
+ include_recipe 'test_cookbook_2'
268
+ EOS
269
+ expect(platform.impacts_from(
270
+ 'other_cookbooks/test_cookbook_2/recipes/default.rb' => {}
271
+ )).to eq [
272
+ [],
273
+ %w[],
274
+ true
275
+ ]
276
+ end
277
+ end
278
+
279
+ it 'considers cookbooks from non-standard cookbook paths that are configured' do
280
+ with_serverless_chef_platforms('several_cookbooks') do |platform, repository|
281
+ File.write("#{repository}/cookbooks/test_cookbook_1/recipes/default.rb", <<~EOS)
282
+ include_recipe 'test_cookbook_2'
283
+ EOS
284
+ ENV['hpc_test_cookbooks_path'] = 'other_cookbooks'
285
+ expect(platform.impacts_from(
286
+ 'other_cookbooks/test_cookbook_2/recipes/default.rb' => {}
287
+ )).to eq [
288
+ [],
289
+ %w[test_policy_1 test_policy_2],
290
+ false
291
+ ]
292
+ end
293
+ end
294
+
295
+ it 'ignores cookbooks from cookbook paths that are configured but lie outside the platform' do
296
+ with_repository('other_cookbooks') do |other_repo|
297
+ FileUtils.mkdir_p("#{other_repo}/cookbooks/test_cookbook_2/recipes")
298
+ File.write("#{other_repo}/cookbooks/test_cookbook_2/recipes/default.rb", '')
299
+ with_serverless_chef_platforms('several_cookbooks') do |platform, repository|
300
+ File.write("#{repository}/cookbooks/test_cookbook_1/recipes/default.rb", <<~EOS)
301
+ include_recipe 'test_cookbook_2'
302
+ EOS
303
+ ENV['hpc_test_cookbooks_path'] = "#{other_repo}:other_cookbooks"
304
+ expect(platform.impacts_from(
305
+ 'unknown_cookbooks/test_cookbook_2/recipes/default.rb' => {}
306
+ )).to eq [
307
+ [],
308
+ %w[],
309
+ true
310
+ ]
311
+ end
312
+ end
313
+ end
314
+
315
+ end
316
+
317
+ end
@@ -0,0 +1,65 @@
1
+ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef do
2
+
3
+ context 'checking inventory' do
4
+
5
+ context 'with an empty platform' do
6
+
7
+ it 'returns no node' do
8
+ with_serverless_chef_platforms('empty') do |platform|
9
+ expect(platform.known_nodes).to eq []
10
+ end
11
+ end
12
+
13
+ it 'returns no nodes list' do
14
+ with_serverless_chef_platforms('empty') do |platform|
15
+ expect(platform.respond_to?(:known_nodes_lists)).to eq false
16
+ end
17
+ end
18
+
19
+ it 'returns no deployable services' do
20
+ with_serverless_chef_platforms('empty') do |platform|
21
+ expect(platform.deployable_services).to eq []
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ context 'with a platform having 1 node' do
28
+
29
+ it 'returns the node' do
30
+ with_serverless_chef_platforms('1_node') do |platform|
31
+ expect(platform.known_nodes).to eq ['node']
32
+ end
33
+ end
34
+
35
+ it 'returns correct metadata for this node' do
36
+ with_serverless_chef_platforms('1_node') do |platform|
37
+ expect(platform.metadata_for('node')).to eq(
38
+ description: 'Single test node',
39
+ image: 'debian_9',
40
+ private_ips: ['172.16.0.1'],
41
+ property1: {
42
+ 'property11' => 'value11'
43
+ },
44
+ property2: 'value2'
45
+ )
46
+ end
47
+ end
48
+
49
+ it 'returns correct service for this node' do
50
+ with_serverless_chef_platforms('1_node') do |platform|
51
+ expect(platform.services_for('node')).to eq %w[test_policy]
52
+ end
53
+ end
54
+
55
+ it 'returns deployable services' do
56
+ with_serverless_chef_platforms('1_node') do |platform|
57
+ expect(platform.deployable_services).to eq %w[test_policy]
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,213 @@
1
+ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef do
2
+
3
+ context 'checking services packaging' do
4
+
5
+ # Expect a repository to be packaged and mock it
6
+ #
7
+ # Parameters::
8
+ # * *repository* (String): Repository to be packaged
9
+ # * *policy* (String): Expected policy to be packaged [default: 'test_policy']
10
+ # * *install* (Boolean): Are we expecting the chef install stage? [default: true]
11
+ # * *export* (Boolean): Are we expecting the chef export stage? [default: true]
12
+ # * *data_bags* (Boolean): Do we expect data bags copy? [default: false]
13
+ # * Proc: Code called with mock in place
14
+ def with_packaging_mocked(
15
+ repository,
16
+ policy: 'test_policy',
17
+ install: true,
18
+ export: true,
19
+ data_bags: false
20
+ )
21
+ with_cmd_runner_mocked(
22
+ if install
23
+ [
24
+ [
25
+ "cd #{repository} && /opt/chef-workstation/bin/chef install policyfiles/#{policy}.rb",
26
+ proc do
27
+ File.write("#{repository}/policyfiles/#{policy}.lock.json", '{}')
28
+ [0, 'Chef install done', '']
29
+ end
30
+ ]
31
+ ]
32
+ else
33
+ []
34
+ end +
35
+ if export
36
+ [
37
+ [
38
+ /^cd #{Regexp.escape(repository)} &&\s+sudo rm -rf dist\/prod\/#{Regexp.escape(policy)} &&\s+\/opt\/chef-workstation\/bin\/chef export policyfiles\/#{Regexp.escape(policy)}.rb dist\/prod\/#{Regexp.escape(policy)}#{data_bags ? " && cp -ar data_bags/ dist/prod/#{Regexp.escape(policy)}/" : ''}$/,
39
+ proc do
40
+ FileUtils.mkdir_p "#{repository}/dist/prod/#{policy}"
41
+ FileUtils.cp_r("#{repository}/data_bags", "#{repository}/dist/prod/#{policy}/") if data_bags
42
+ [0, 'Chef export done', '']
43
+ end
44
+ ]
45
+ ]
46
+ else
47
+ []
48
+ end
49
+ ) do
50
+ yield
51
+ end
52
+ end
53
+
54
+ context 'with an empty platform' do
55
+
56
+ it 'packages the repository doing nothing' do
57
+ with_serverless_chef_platforms('empty') do |platform, repository|
58
+ with_cmd_runner_mocked([]) do
59
+ platform.package(services: {}, secrets: {}, local_environment: false)
60
+ end
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ context 'with a platform having 1 node' do
67
+
68
+ it 'packages the repository for a given node and service' do
69
+ with_serverless_chef_platforms('1_node') do |platform, repository|
70
+ with_packaging_mocked(repository) do
71
+ platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
72
+ end
73
+ end
74
+ end
75
+
76
+ it 'packages the repository without resolving dependencies when the lock file already exists' do
77
+ with_serverless_chef_platforms('1_node') do |platform, repository|
78
+ File.write("#{repository}/policyfiles/test_policy.lock.json", '{}')
79
+ with_packaging_mocked(repository, install: false) do
80
+ platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
81
+ end
82
+ end
83
+ end
84
+
85
+ it 'packages the repository with secrets' do
86
+ with_serverless_chef_platforms('1_node') do |platform, repository|
87
+ with_packaging_mocked(repository) do
88
+ platform.package(services: { 'node' => %w[test_policy] }, secrets: { secret: 'value' }, local_environment: false)
89
+ secret_file = "#{repository}/dist/prod/test_policy/data_bags/hpc_secrets/hpc_secrets.json"
90
+ expect(File.exist?(secret_file)).to eq true
91
+ expect(JSON.parse(File.read(secret_file))).to eq(
92
+ 'id' => 'hpc_secrets',
93
+ 'secret' => 'value'
94
+ )
95
+ end
96
+ end
97
+ end
98
+
99
+ it 'does not package the repository twice for the same config' do
100
+ with_serverless_chef_platforms('1_node', as_git: true) do |platform, repository|
101
+ with_packaging_mocked(repository) do
102
+ platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
103
+ end
104
+ with_cmd_runner_mocked([]) do
105
+ platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
106
+ end
107
+ end
108
+ end
109
+
110
+ it 'packages the repository twice when the platform is not taken from git' do
111
+ with_serverless_chef_platforms('1_node') do |platform, repository|
112
+ with_packaging_mocked(repository) do
113
+ platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
114
+ end
115
+ # Wait 2 seconds so that we are sure later Time.now will return different timestamps
116
+ sleep 2
117
+ with_packaging_mocked(repository, install: false) do
118
+ platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
119
+ end
120
+ end
121
+ end
122
+
123
+ it 'packages the repository twice when the platform needs different secrets' do
124
+ with_serverless_chef_platforms('1_node', as_git: true) do |platform, repository|
125
+ with_packaging_mocked(repository) do
126
+ platform.package(services: { 'node' => %w[test_policy] }, secrets: { secret: 'value1' }, local_environment: false)
127
+ end
128
+ with_packaging_mocked(repository, install: false) do
129
+ platform.package(services: { 'node' => %w[test_policy] }, secrets: { secret: 'value2' }, local_environment: false)
130
+ end
131
+ end
132
+ end
133
+
134
+ it 'packages the repository twice when the platform has new local files' do
135
+ with_serverless_chef_platforms('1_node', as_git: true) do |platform, repository|
136
+ with_packaging_mocked(repository) do
137
+ platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
138
+ end
139
+ # Make sure we clean the cache (this mocks another Platform Handler instance running)
140
+ platform.remove_instance_variable :@info
141
+ with_packaging_mocked(repository, install: false) do
142
+ File.write("#{repository}/new_file", 'New file')
143
+ platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
144
+ end
145
+ end
146
+ end
147
+
148
+ it 'packages the repository twice when the platform has modified local files' do
149
+ with_serverless_chef_platforms('1_node', as_git: true) do |platform, repository|
150
+ with_packaging_mocked(repository) do
151
+ platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
152
+ end
153
+ # Wait 2 seconds so that we are sure the modified file will return a different timestamp
154
+ sleep 2
155
+ with_packaging_mocked(repository, install: false) do
156
+ File.write("#{repository}/chef_versions.yml", File.read("#{repository}/chef_versions.yml") + "\n\n")
157
+ platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
158
+ end
159
+ end
160
+ end
161
+
162
+ end
163
+
164
+ context 'with a platform having several nodes' do
165
+
166
+ it 'packages 1 service independently from another' do
167
+ with_serverless_chef_platforms('several_nodes') do |platform, repository|
168
+ with_packaging_mocked(repository, policy: 'test_policy_1') do
169
+ platform.package(services: { 'node1' => %w[test_policy_1] }, secrets: {}, local_environment: false)
170
+ end
171
+ with_packaging_mocked(repository, policy: 'test_policy_2') do
172
+ platform.package(services: { 'node2' => %w[test_policy_2] }, secrets: {}, local_environment: false)
173
+ end
174
+ with_cmd_runner_mocked([]) do
175
+ platform.package(services: { 'node1' => %w[test_policy_1] }, secrets: {}, local_environment: false)
176
+ end
177
+ end
178
+ end
179
+
180
+ it 'packages 1 service independently of the node on which it is to be deployed' do
181
+ with_serverless_chef_platforms('several_nodes') do |platform, repository|
182
+ with_packaging_mocked(repository, policy: 'test_policy_1') do
183
+ platform.package(services: { 'node1' => %w[test_policy_1] }, secrets: {}, local_environment: false)
184
+ end
185
+ with_cmd_runner_mocked([]) do
186
+ platform.package(services: { 'node2' => %w[test_policy_1] }, secrets: {}, local_environment: false)
187
+ end
188
+ end
189
+ end
190
+
191
+ end
192
+
193
+ context 'with a platform having data bags' do
194
+
195
+ it 'packages data bags' do
196
+ with_serverless_chef_platforms('data_bags') do |platform, repository|
197
+ with_packaging_mocked(repository, data_bags: true) do
198
+ platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
199
+ data_bag_file = "#{repository}/dist/prod/test_policy/data_bags/my_bag/my_item.json"
200
+ expect(File.exist?(data_bag_file)).to eq true
201
+ expect(JSON.parse(File.read(data_bag_file))).to eq(
202
+ 'id' => 'my_item',
203
+ 'content' => 'Bag content'
204
+ )
205
+ end
206
+ end
207
+ end
208
+
209
+ end
210
+
211
+ end
212
+
213
+ end