hybrid_platforms_conductor 32.13.4 → 32.16.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +60 -0
- data/bin/get_impacted_nodes +1 -1
- data/bin/setup +6 -1
- data/docs/plugins.md +1 -0
- data/docs/plugins/platform_handler/serverless_chef.md +111 -0
- data/lib/hybrid_platforms_conductor/cmd_runner.rb +13 -1
- data/lib/hybrid_platforms_conductor/connector.rb +4 -2
- data/lib/hybrid_platforms_conductor/deployer.rb +2 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/local.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef.rb +535 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/dsl_parser.rb +51 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/recipes_tree_builder.rb +232 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/podman.rb +1 -1
- data/lib/hybrid_platforms_conductor/nodes_handler.rb +9 -5
- data/lib/hybrid_platforms_conductor/version.rb +1 -1
- data/spec/hybrid_platforms_conductor_test.rb +3 -0
- data/spec/hybrid_platforms_conductor_test/api/cmd_runner_spec.rb +7 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioner_spec.rb +23 -0
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs_plugins_api_spec.rb +11 -0
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/config_dsl_spec.rb +17 -0
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/deploy_output_parsing_spec.rb +94 -0
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/diff_impacts_spec.rb +317 -0
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/inventory_spec.rb +65 -0
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/packaging_spec.rb +293 -0
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/services_deployment_spec.rb +272 -0
- data/spec/hybrid_platforms_conductor_test/helpers/cmd_runner_helpers.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/helpers/serverless_chef_helpers.rb +53 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/chef_versions.yml +3 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/nodes/node.json +14 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/policyfiles/test_policy.rb +3 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/chef_versions.yml +3 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/data_bags/my_bag/my_item.json +4 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/nodes/node.json +14 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/policyfiles/test_policy.rb +3 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/chef_versions.yml +3 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/cookbooks/hpc_test/recipes/after_run.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/cookbooks/hpc_test/recipes/before_run.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/nodes/node.json +10 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/policyfiles/test_policy.rb +3 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_1/recipes/default.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/libraries/default.rb +4 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/recipes/default.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/recipes/other_recipe.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/resources/my_resource.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node1.json +10 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node2.json +10 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_1.rb +4 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_2.rb +4 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/config.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/cookbooks/test_cookbook_1/recipes/default.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/nodes/node1.json +10 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/nodes/node2.json +10 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/other_cookbooks/test_cookbook_2/libraries/default.rb +4 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/other_cookbooks/test_cookbook_2/recipes/default.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/other_cookbooks/test_cookbook_2/recipes/other_recipe.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/other_cookbooks/test_cookbook_2/resources/my_resource.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/policyfiles/test_policy_1.rb +4 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/policyfiles/test_policy_2.rb +4 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/chef_versions.yml +3 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/nodes/local.json +10 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/nodes/node1.json +10 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/nodes/node2.json +10 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/policyfiles/test_policy_1.rb +3 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_nodes/policyfiles/test_policy_2.rb +3 -0
- metadata +192 -143
data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/diff_impacts_spec.rb
ADDED
|
@@ -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
|
data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/inventory_spec.rb
ADDED
|
@@ -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
|
data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/packaging_spec.rb
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
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
|
+
# * *policy_file* (String): Expected policy file used [default: "policyfiles/#{policy}.rb"]
|
|
11
|
+
# * *install* (Boolean): Are we expecting the chef install stage? [default: true]
|
|
12
|
+
# * *export* (Boolean): Are we expecting the chef export stage? [default: true]
|
|
13
|
+
# * *data_bags* (Boolean): Do we expect data bags copy? [default: false]
|
|
14
|
+
# * *env* (String): Expected environment being packaged [default: 'prod']
|
|
15
|
+
# * Proc: Code called with mock in place
|
|
16
|
+
def with_packaging_mocked(
|
|
17
|
+
repository,
|
|
18
|
+
policy: 'test_policy',
|
|
19
|
+
policy_file: "policyfiles/#{policy}.rb",
|
|
20
|
+
install: true,
|
|
21
|
+
export: true,
|
|
22
|
+
data_bags: false,
|
|
23
|
+
env: 'prod'
|
|
24
|
+
)
|
|
25
|
+
with_cmd_runner_mocked(
|
|
26
|
+
if install
|
|
27
|
+
[
|
|
28
|
+
[
|
|
29
|
+
"cd #{repository} && /opt/chef-workstation/bin/chef install #{policy_file}",
|
|
30
|
+
proc do
|
|
31
|
+
# Mock the run_list stored in the lock file
|
|
32
|
+
File.write(
|
|
33
|
+
"#{repository}/#{policy_file.gsub(/.rb$/, '.lock.json')}",
|
|
34
|
+
{
|
|
35
|
+
run_list: eval("[#{File.read("#{repository}/#{policy_file}").split("\n").select { |line| line =~ /^run_list.+$/ }.last.match(/^run_list(.+)$/)[1]}]").flatten
|
|
36
|
+
}.to_json
|
|
37
|
+
)
|
|
38
|
+
[0, 'Chef install done', '']
|
|
39
|
+
end
|
|
40
|
+
]
|
|
41
|
+
]
|
|
42
|
+
else
|
|
43
|
+
[]
|
|
44
|
+
end +
|
|
45
|
+
if export
|
|
46
|
+
[
|
|
47
|
+
['whoami', proc { [0, 'test_user', ''] }, { optional: true }],
|
|
48
|
+
[
|
|
49
|
+
/^cd #{Regexp.escape(repository)} &&\s+sudo rm -rf dist\/#{Regexp.escape(env)}\/#{Regexp.escape(policy)} &&\s+\/opt\/chef-workstation\/bin\/chef export #{Regexp.escape(policy_file)} dist\/#{Regexp.escape(env)}\/#{Regexp.escape(policy)}#{data_bags ? " && cp -ar data_bags/ dist/#{Regexp.escape(env)}/#{Regexp.escape(policy)}/" : ''}$/,
|
|
50
|
+
proc do
|
|
51
|
+
FileUtils.mkdir_p "#{repository}/dist/#{env}/#{policy}"
|
|
52
|
+
FileUtils.cp_r("#{repository}/data_bags", "#{repository}/dist/#{env}/#{policy}/") if data_bags
|
|
53
|
+
[0, 'Chef export done', '']
|
|
54
|
+
end
|
|
55
|
+
]
|
|
56
|
+
]
|
|
57
|
+
else
|
|
58
|
+
[]
|
|
59
|
+
end
|
|
60
|
+
) do
|
|
61
|
+
yield
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context 'with an empty platform' do
|
|
66
|
+
|
|
67
|
+
it 'packages the repository doing nothing' do
|
|
68
|
+
with_serverless_chef_platforms('empty') do |platform, repository|
|
|
69
|
+
with_cmd_runner_mocked([]) do
|
|
70
|
+
platform.package(services: {}, secrets: {}, local_environment: false)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context 'with a platform having 1 node' do
|
|
78
|
+
|
|
79
|
+
it 'packages the repository for a given node and service' do
|
|
80
|
+
with_serverless_chef_platforms('1_node') do |platform, repository|
|
|
81
|
+
with_packaging_mocked(repository) do
|
|
82
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'packages the repository without resolving dependencies when the lock file already exists' do
|
|
88
|
+
with_serverless_chef_platforms('1_node') do |platform, repository|
|
|
89
|
+
File.write("#{repository}/policyfiles/test_policy.lock.json", '{}')
|
|
90
|
+
with_packaging_mocked(repository, install: false) do
|
|
91
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it 'packages the repository with secrets' do
|
|
97
|
+
with_serverless_chef_platforms('1_node') do |platform, repository|
|
|
98
|
+
with_packaging_mocked(repository) do
|
|
99
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: { secret: 'value' }, local_environment: false)
|
|
100
|
+
secret_file = "#{repository}/dist/prod/test_policy/data_bags/hpc_secrets/hpc_secrets.json"
|
|
101
|
+
expect(File.exist?(secret_file)).to eq true
|
|
102
|
+
expect(JSON.parse(File.read(secret_file))).to eq(
|
|
103
|
+
'id' => 'hpc_secrets',
|
|
104
|
+
'secret' => 'value'
|
|
105
|
+
)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it 'packages the repository for a given node and service in local mode' do
|
|
111
|
+
with_serverless_chef_platforms('1_node') do |platform, repository|
|
|
112
|
+
with_packaging_mocked(repository, policy_file: 'policyfiles/test_policy.local.rb', env: 'local') do
|
|
113
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: true)
|
|
114
|
+
local_policy_file = "#{repository}/policyfiles/test_policy.local.lock.json"
|
|
115
|
+
expect(File.exist?(local_policy_file)).to eq true
|
|
116
|
+
expect(JSON.parse(File.read(local_policy_file))).to eq('run_list' => ['recipe[test_cookbook]'])
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it 'packages the repository without resolving dependencies when the lock file already exists' do
|
|
122
|
+
with_serverless_chef_platforms('1_node') do |platform, repository|
|
|
123
|
+
File.write("#{repository}/policyfiles/test_policy.lock.json", '{}')
|
|
124
|
+
with_packaging_mocked(repository, install: false) do
|
|
125
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it 'does not package the repository twice for the same config' do
|
|
131
|
+
with_serverless_chef_platforms('1_node', as_git: true) do |platform, repository|
|
|
132
|
+
with_packaging_mocked(repository) do
|
|
133
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
|
|
134
|
+
end
|
|
135
|
+
with_cmd_runner_mocked([]) do
|
|
136
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it 'packages the repository twice when the platform is not taken from git' do
|
|
142
|
+
with_serverless_chef_platforms('1_node') do |platform, repository|
|
|
143
|
+
with_packaging_mocked(repository) do
|
|
144
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
|
|
145
|
+
end
|
|
146
|
+
# Wait 2 seconds so that we are sure later Time.now will return different timestamps
|
|
147
|
+
sleep 2
|
|
148
|
+
with_packaging_mocked(repository, install: false) do
|
|
149
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it 'packages the repository twice when the platform needs different secrets' do
|
|
155
|
+
with_serverless_chef_platforms('1_node', as_git: true) do |platform, repository|
|
|
156
|
+
with_packaging_mocked(repository) do
|
|
157
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: { secret: 'value1' }, local_environment: false)
|
|
158
|
+
end
|
|
159
|
+
with_packaging_mocked(repository, install: false) do
|
|
160
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: { secret: 'value2' }, local_environment: false)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it 'packages the repository twice when the platform has new local files' do
|
|
166
|
+
with_serverless_chef_platforms('1_node', as_git: true) do |platform, repository|
|
|
167
|
+
with_packaging_mocked(repository) do
|
|
168
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
|
|
169
|
+
end
|
|
170
|
+
# Make sure we clean the cache (this mocks another Platform Handler instance running)
|
|
171
|
+
platform.remove_instance_variable :@info
|
|
172
|
+
with_packaging_mocked(repository, install: false) do
|
|
173
|
+
File.write("#{repository}/new_file", 'New file')
|
|
174
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
it 'packages the repository twice when the platform has modified local files' do
|
|
180
|
+
with_serverless_chef_platforms('1_node', as_git: true) do |platform, repository|
|
|
181
|
+
with_packaging_mocked(repository) do
|
|
182
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
|
|
183
|
+
end
|
|
184
|
+
# Wait 2 seconds so that we are sure the modified file will return a different timestamp
|
|
185
|
+
sleep 2
|
|
186
|
+
with_packaging_mocked(repository, install: false) do
|
|
187
|
+
File.write("#{repository}/chef_versions.yml", File.read("#{repository}/chef_versions.yml") + "\n\n")
|
|
188
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
context 'with a platform having several nodes' do
|
|
196
|
+
|
|
197
|
+
it 'packages 1 service independently from another' do
|
|
198
|
+
with_serverless_chef_platforms('several_nodes') do |platform, repository|
|
|
199
|
+
with_packaging_mocked(repository, policy: 'test_policy_1') do
|
|
200
|
+
platform.package(services: { 'node1' => %w[test_policy_1] }, secrets: {}, local_environment: false)
|
|
201
|
+
end
|
|
202
|
+
with_packaging_mocked(repository, policy: 'test_policy_2') do
|
|
203
|
+
platform.package(services: { 'node2' => %w[test_policy_2] }, secrets: {}, local_environment: false)
|
|
204
|
+
end
|
|
205
|
+
with_cmd_runner_mocked([]) do
|
|
206
|
+
platform.package(services: { 'node1' => %w[test_policy_1] }, secrets: {}, local_environment: false)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it 'packages 1 service independently of the node on which it is to be deployed' do
|
|
212
|
+
with_serverless_chef_platforms('several_nodes') do |platform, repository|
|
|
213
|
+
with_packaging_mocked(repository, policy: 'test_policy_1') do
|
|
214
|
+
platform.package(services: { 'node1' => %w[test_policy_1] }, secrets: {}, local_environment: false)
|
|
215
|
+
end
|
|
216
|
+
with_cmd_runner_mocked([]) do
|
|
217
|
+
platform.package(services: { 'node2' => %w[test_policy_1] }, secrets: {}, local_environment: false)
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
context 'with a platform having data bags' do
|
|
225
|
+
|
|
226
|
+
it 'packages data bags' do
|
|
227
|
+
with_serverless_chef_platforms('data_bags') do |platform, repository|
|
|
228
|
+
with_packaging_mocked(repository, data_bags: true) do
|
|
229
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
|
|
230
|
+
data_bag_file = "#{repository}/dist/prod/test_policy/data_bags/my_bag/my_item.json"
|
|
231
|
+
expect(File.exist?(data_bag_file)).to eq true
|
|
232
|
+
expect(JSON.parse(File.read(data_bag_file))).to eq(
|
|
233
|
+
'id' => 'my_item',
|
|
234
|
+
'content' => 'Bag content'
|
|
235
|
+
)
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
context 'with a platform having hpc_test cookbook' do
|
|
243
|
+
|
|
244
|
+
it 'packages the repository with before_run and after_run recipes wrapping the run list' do
|
|
245
|
+
with_serverless_chef_platforms('hpc_test') do |platform, repository|
|
|
246
|
+
with_packaging_mocked(repository, policy_file: 'policyfiles/test_policy.local.rb', env: 'local') do
|
|
247
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: true)
|
|
248
|
+
local_policy_file = "#{repository}/policyfiles/test_policy.local.lock.json"
|
|
249
|
+
expect(File.exist?(local_policy_file)).to eq true
|
|
250
|
+
expect(JSON.parse(File.read(local_policy_file))).to eq('run_list' => [
|
|
251
|
+
'hpc_test::before_run',
|
|
252
|
+
'recipe[test_cookbook]',
|
|
253
|
+
'hpc_test::after_run'
|
|
254
|
+
])
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
it 'packages the repository with before_run only recipe' do
|
|
260
|
+
with_serverless_chef_platforms('hpc_test') do |platform, repository|
|
|
261
|
+
File.unlink "#{repository}/cookbooks/hpc_test/recipes/after_run.rb"
|
|
262
|
+
with_packaging_mocked(repository, policy_file: 'policyfiles/test_policy.local.rb', env: 'local') do
|
|
263
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: true)
|
|
264
|
+
local_policy_file = "#{repository}/policyfiles/test_policy.local.lock.json"
|
|
265
|
+
expect(File.exist?(local_policy_file)).to eq true
|
|
266
|
+
expect(JSON.parse(File.read(local_policy_file))).to eq('run_list' => [
|
|
267
|
+
'hpc_test::before_run',
|
|
268
|
+
'recipe[test_cookbook]'
|
|
269
|
+
])
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
it 'packages the repository with after_run only recipe' do
|
|
275
|
+
with_serverless_chef_platforms('hpc_test') do |platform, repository|
|
|
276
|
+
File.unlink "#{repository}/cookbooks/hpc_test/recipes/before_run.rb"
|
|
277
|
+
with_packaging_mocked(repository, policy_file: 'policyfiles/test_policy.local.rb', env: 'local') do
|
|
278
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: true)
|
|
279
|
+
local_policy_file = "#{repository}/policyfiles/test_policy.local.lock.json"
|
|
280
|
+
expect(File.exist?(local_policy_file)).to eq true
|
|
281
|
+
expect(JSON.parse(File.read(local_policy_file))).to eq('run_list' => [
|
|
282
|
+
'recipe[test_cookbook]',
|
|
283
|
+
'hpc_test::after_run'
|
|
284
|
+
])
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
end
|