hybrid_platforms_conductor 32.13.0 → 32.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +42 -0
- data/README.md +10 -3
- data/bin/get_impacted_nodes +1 -1
- data/bin/setup +6 -1
- data/docs/executables/check-node.md +1 -1
- data/docs/executables/deploy.md +1 -1
- data/docs/executables/free_ips.md +1 -1
- data/docs/executables/free_veids.md +1 -1
- data/docs/executables/get_impacted_nodes.md +1 -1
- data/docs/executables/last_deploys.md +1 -1
- data/docs/executables/nodes_to_deploy.md +1 -1
- data/docs/executables/report.md +1 -1
- data/docs/executables/run.md +1 -1
- data/docs/executables/setup.md +1 -1
- data/docs/executables/ssh_config.md +1 -1
- data/docs/executables/test.md +1 -1
- data/docs/plugins.md +1 -0
- data/docs/plugins/platform_handler/serverless_chef.md +105 -0
- data/docs/tutorial.md +10 -6
- data/docs/tutorial/01_installation.md +14 -12
- data/docs/tutorial/02_first_node.md +14 -12
- data/docs/tutorial/03_scale.md +14 -12
- data/docs/tutorial/04_test.md +26 -14
- data/docs/tutorial/05_extend_with_plugins.md +17 -17
- data/examples/tutorial/01_installation/my-platforms/Gemfile +3 -0
- data/examples/tutorial/01_installation/my-platforms/hpc_config.rb +0 -0
- data/examples/tutorial/02_first_node/my-platforms/Gemfile +3 -0
- data/examples/tutorial/02_first_node/my-platforms/hpc_config.rb +1 -0
- data/examples/tutorial/02_first_node/my-service-conf-repo/inventory.yaml +13 -0
- data/examples/tutorial/02_first_node/my-service-conf-repo/my-service.conf.erb +3 -0
- data/examples/tutorial/02_first_node/my-service-conf-repo/service_my-service.rb +58 -0
- data/examples/tutorial/02_first_node/node/my-service.conf +4 -0
- data/examples/tutorial/03_scale/my-platforms/Gemfile +3 -0
- data/examples/tutorial/03_scale/my-platforms/hpc_config.rb +1 -0
- data/examples/tutorial/03_scale/my-platforms/my_commands.bash +2 -0
- data/examples/tutorial/03_scale/my-service-conf-repo/inventory.yaml +90 -0
- data/examples/tutorial/03_scale/my-service-conf-repo/my-service.conf.erb +3 -0
- data/examples/tutorial/03_scale/my-service-conf-repo/service_my-service.rb +58 -0
- data/examples/tutorial/03_scale/my-service-conf-repo/service_web-hello.rb +43 -0
- data/examples/tutorial/03_scale/node/my-service.conf +4 -0
- data/examples/tutorial/03_scale/web_docker_image/Dockerfile +33 -0
- data/examples/tutorial/03_scale/web_docker_image/hello_world.txt +1 -0
- data/examples/tutorial/03_scale/web_docker_image/hpc_root.key +27 -0
- data/examples/tutorial/03_scale/web_docker_image/hpc_root.key.pub +1 -0
- data/examples/tutorial/03_scale/web_docker_image/main.go +43 -0
- data/examples/tutorial/03_scale/web_docker_image/start.sh +7 -0
- data/examples/tutorial/03_scale/web_docker_image/test.bash +6 -0
- data/examples/tutorial/04_test/my-platforms/Gemfile +3 -0
- data/examples/tutorial/04_test/my-platforms/hpc_config.rb +12 -0
- data/examples/tutorial/04_test/my-platforms/images/debian_10/Dockerfile +13 -0
- data/examples/tutorial/04_test/my-platforms/my_commands.bash +2 -0
- data/examples/tutorial/04_test/my-service-conf-repo/inventory.yaml +100 -0
- data/examples/tutorial/04_test/my-service-conf-repo/my-service.conf.erb +3 -0
- data/examples/tutorial/04_test/my-service-conf-repo/service_my-service.rb +58 -0
- data/examples/tutorial/04_test/my-service-conf-repo/service_web-hello.rb +43 -0
- data/examples/tutorial/04_test/node/my-service.conf +4 -0
- data/examples/tutorial/04_test/web_docker_image/Dockerfile +33 -0
- data/examples/tutorial/04_test/web_docker_image/hello_world.txt +1 -0
- data/examples/tutorial/04_test/web_docker_image/hpc_root.key +27 -0
- data/examples/tutorial/04_test/web_docker_image/hpc_root.key.pub +1 -0
- data/examples/tutorial/04_test/web_docker_image/main.go +43 -0
- data/examples/tutorial/04_test/web_docker_image/start.sh +7 -0
- data/examples/tutorial/04_test/web_docker_image/test.bash +6 -0
- data/examples/tutorial/05_extend_with_plugins/dev-servers-conf-repo/hosts.json +12 -0
- data/examples/tutorial/05_extend_with_plugins/dev-servers-conf-repo/install-gcc.bash +14 -0
- data/examples/tutorial/05_extend_with_plugins/dev-servers-conf-repo/install-python.bash +14 -0
- data/examples/tutorial/05_extend_with_plugins/dev_docker_image/Dockerfile +20 -0
- data/examples/tutorial/05_extend_with_plugins/dev_docker_image/hpc_root.key +27 -0
- data/examples/tutorial/05_extend_with_plugins/dev_docker_image/hpc_root.key.pub +1 -0
- data/examples/tutorial/05_extend_with_plugins/my-platforms/Gemfile +4 -0
- data/examples/tutorial/05_extend_with_plugins/my-platforms/hpc_config.rb +13 -0
- data/examples/tutorial/05_extend_with_plugins/my-platforms/images/debian_10/Dockerfile +13 -0
- data/examples/tutorial/05_extend_with_plugins/my-platforms/my_commands.bash +2 -0
- data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/inventory.yaml +100 -0
- data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/my-service.conf.erb +3 -0
- data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/service_my-service.rb +58 -0
- data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/service_web-hello.rb +43 -0
- data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/lib/my_hpc_plugins/hpc_plugins/platform_handler/json_bash.rb +115 -0
- data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/lib/my_hpc_plugins/hpc_plugins/report/web_report.rb +52 -0
- data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/lib/my_hpc_plugins/hpc_plugins/test/root_space.rb +44 -0
- data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/my_hpc_plugins.gemspec +15 -0
- data/examples/tutorial/05_extend_with_plugins/node/my-service.conf +4 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/Dockerfile +33 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/hello_world.txt +1 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/hpc_root.key +27 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/hpc_root.key.pub +1 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/main.go +43 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/start.sh +7 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/test.bash +6 -0
- data/lib/hybrid_platforms_conductor/deployer.rb +2 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef.rb +440 -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 +271 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +1 -0
- 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/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 +213 -0
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/services_deployment_spec.rb +268 -0
- 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/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
- data/tools/generate_mermaid +1 -1
- metadata +260 -86
data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/packaging_spec.rb
ADDED
@@ -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
|
@@ -0,0 +1,268 @@
|
|
1
|
+
describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef do
|
2
|
+
|
3
|
+
context 'checking services deployment' do
|
4
|
+
|
5
|
+
# Simulate a packaging of a given repository
|
6
|
+
#
|
7
|
+
# Parameters::
|
8
|
+
# * *repository* (String): The repository we package
|
9
|
+
# * *service* (String): The service being packaged in this repository [default: 'test_policy']
|
10
|
+
def mock_package(repository, service: 'test_policy')
|
11
|
+
FileUtils.mkdir_p "#{repository}/dist/prod/#{service}"
|
12
|
+
end
|
13
|
+
|
14
|
+
# Get expected actions to deploy a service on a given node
|
15
|
+
#
|
16
|
+
# Parameters::
|
17
|
+
# * *repository* (String): Platform repository
|
18
|
+
# * *check_mode* (Boolean): Are we expected check-mode? [default: false]
|
19
|
+
# * *sudo* (String): sudo prefix command [default: 'sudo -u root ']
|
20
|
+
# * *env* (String): Environment expected to be packaged [default: 'prod']
|
21
|
+
# * *policy* (String): Expected policy to be packaged [default: 'test_policy']
|
22
|
+
# * *node* (String): Expected node to be deployed [default: 'node']
|
23
|
+
# Result::
|
24
|
+
# * Array: Expected actions
|
25
|
+
def expected_actions_to_deploy_chef(
|
26
|
+
repository,
|
27
|
+
check_mode: false,
|
28
|
+
sudo: 'sudo -u root ',
|
29
|
+
env: 'prod',
|
30
|
+
policy: 'test_policy',
|
31
|
+
node: 'node'
|
32
|
+
)
|
33
|
+
[
|
34
|
+
{
|
35
|
+
remote_bash: [
|
36
|
+
'set -e',
|
37
|
+
'set -o pipefail',
|
38
|
+
"if [ -n \"$(command -v apt)\" ]; then #{sudo}apt update && #{sudo}apt install -y curl build-essential ; else #{sudo}yum groupinstall 'Development Tools' && #{sudo}yum install -y curl ; fi",
|
39
|
+
'mkdir -p ./hpc_deploy',
|
40
|
+
"curl --location https://omnitruck.chef.io/install.sh | tac | tac | #{sudo}bash -s -- -d /opt/artefacts -v 17.0 -s once"
|
41
|
+
]
|
42
|
+
},
|
43
|
+
{
|
44
|
+
scp: { "#{repository}/dist/#{env}/#{policy}" => './hpc_deploy' },
|
45
|
+
remote_bash: [
|
46
|
+
'set -e',
|
47
|
+
"cd ./hpc_deploy/#{policy}",
|
48
|
+
"#{sudo}SSL_CERT_DIR=/etc/ssl/certs /opt/chef/bin/chef-client --local-mode --chef-license=accept --json-attributes nodes/#{node}.json#{check_mode ? ' --why-run' : ''}",
|
49
|
+
'cd ..',
|
50
|
+
"#{sudo}rm -rf #{policy}"
|
51
|
+
]
|
52
|
+
}
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'with an empty platform' do
|
57
|
+
|
58
|
+
it 'prepares for deploy' do
|
59
|
+
with_serverless_chef_platforms('empty') do |platform, repository|
|
60
|
+
platform.prepare_for_deploy(
|
61
|
+
services: {},
|
62
|
+
secrets: {},
|
63
|
+
local_environment: false,
|
64
|
+
why_run: false
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'prepares for deploy in why-run mode' do
|
70
|
+
with_serverless_chef_platforms('empty') do |platform, repository|
|
71
|
+
platform.prepare_for_deploy(
|
72
|
+
services: {},
|
73
|
+
secrets: {},
|
74
|
+
local_environment: false,
|
75
|
+
why_run: true
|
76
|
+
)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'prepares for deploy in local mode' do
|
81
|
+
with_serverless_chef_platforms('empty') do |platform, repository|
|
82
|
+
platform.prepare_for_deploy(
|
83
|
+
services: {},
|
84
|
+
secrets: {},
|
85
|
+
local_environment: true,
|
86
|
+
why_run: false
|
87
|
+
)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'with a platform having 1 node' do
|
94
|
+
|
95
|
+
it 'returns actions to deploy on this node' do
|
96
|
+
with_serverless_chef_platforms('1_node') do |platform, repository|
|
97
|
+
mock_package(repository)
|
98
|
+
platform.prepare_for_deploy(
|
99
|
+
services: { 'node' => %w[test_policy] },
|
100
|
+
secrets: {},
|
101
|
+
local_environment: false,
|
102
|
+
why_run: false
|
103
|
+
)
|
104
|
+
expect(platform.actions_to_deploy_on('node', 'test_policy', use_why_run: false)).to eq expected_actions_to_deploy_chef(repository)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'returns actions to deploy on this node with node attributes setup from metadata' do
|
109
|
+
with_serverless_chef_platforms('1_node') do |platform, repository|
|
110
|
+
test_nodes_handler.override_metadata_of 'node', :new_metadata, 'new_value'
|
111
|
+
mock_package(repository)
|
112
|
+
platform.prepare_for_deploy(
|
113
|
+
services: { 'node' => %w[test_policy] },
|
114
|
+
secrets: {},
|
115
|
+
local_environment: false,
|
116
|
+
why_run: false
|
117
|
+
)
|
118
|
+
expect(platform.actions_to_deploy_on('node', 'test_policy', use_why_run: false)).to eq expected_actions_to_deploy_chef(repository)
|
119
|
+
attributes_file = "#{repository}/dist/prod/test_policy/nodes/node.json"
|
120
|
+
expect(File.exist?(attributes_file)).to eq true
|
121
|
+
expect(JSON.parse(File.read(attributes_file))).to eq(
|
122
|
+
'description' => 'Single test node',
|
123
|
+
'image' => 'debian_9',
|
124
|
+
'new_metadata' => 'new_value',
|
125
|
+
'private_ips' => ['172.16.0.1'],
|
126
|
+
'property1' => { 'property11' => 'value11' },
|
127
|
+
'property2' => 'value2',
|
128
|
+
)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'returns actions to deploy on this node with secrets' do
|
133
|
+
with_serverless_chef_platforms('1_node') do |platform, repository|
|
134
|
+
mock_package(repository)
|
135
|
+
platform.prepare_for_deploy(
|
136
|
+
services: { 'node' => %w[test_policy] },
|
137
|
+
secrets: { 'my_secret' => 'secret_value' },
|
138
|
+
local_environment: false,
|
139
|
+
why_run: false
|
140
|
+
)
|
141
|
+
expect(platform.actions_to_deploy_on('node', 'test_policy', use_why_run: false)).to eq expected_actions_to_deploy_chef(repository)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'returns actions to deploy on this node in why-run mode' do
|
146
|
+
with_serverless_chef_platforms('1_node') do |platform, repository|
|
147
|
+
mock_package(repository)
|
148
|
+
platform.prepare_for_deploy(
|
149
|
+
services: { 'node' => %w[test_policy] },
|
150
|
+
secrets: {},
|
151
|
+
local_environment: false,
|
152
|
+
why_run: true
|
153
|
+
)
|
154
|
+
expect(platform.actions_to_deploy_on('node', 'test_policy', use_why_run: true)).to eq expected_actions_to_deploy_chef(repository, check_mode: true)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'returns actions to deploy on this node using local mode' do
|
159
|
+
with_serverless_chef_platforms('1_node') do |platform, repository|
|
160
|
+
mock_package(repository)
|
161
|
+
platform.prepare_for_deploy(
|
162
|
+
services: { 'node' => %w[test_policy] },
|
163
|
+
secrets: {},
|
164
|
+
local_environment: true,
|
165
|
+
why_run: false
|
166
|
+
)
|
167
|
+
expect(platform.actions_to_deploy_on('node', 'test_policy', use_why_run: false)).to eq expected_actions_to_deploy_chef(repository, env: 'local')
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'returns actions to deploy on this node in why-run mode and local mode' do
|
172
|
+
with_serverless_chef_platforms('1_node') do |platform, repository|
|
173
|
+
mock_package(repository)
|
174
|
+
platform.prepare_for_deploy(
|
175
|
+
services: { 'node' => %w[test_policy] },
|
176
|
+
secrets: {},
|
177
|
+
local_environment: true,
|
178
|
+
why_run: true
|
179
|
+
)
|
180
|
+
expect(platform.actions_to_deploy_on('node', 'test_policy', use_why_run: true)).to eq expected_actions_to_deploy_chef(repository, env: 'local', check_mode: true)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'returns actions to deploy on this node using root user' do
|
185
|
+
with_serverless_chef_platforms('1_node') do |platform, repository|
|
186
|
+
test_actions_executor.connector(:ssh).ssh_user = 'root'
|
187
|
+
mock_package(repository)
|
188
|
+
platform.prepare_for_deploy(
|
189
|
+
services: { 'node' => %w[test_policy] },
|
190
|
+
secrets: {},
|
191
|
+
local_environment: false,
|
192
|
+
why_run: false
|
193
|
+
)
|
194
|
+
expect(platform.actions_to_deploy_on('node', 'test_policy', use_why_run: false)).to eq expected_actions_to_deploy_chef(repository, sudo: '')
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'fails with a nice message when chef_versions.yml is missing' do
|
199
|
+
with_serverless_chef_platforms('1_node') do |platform, repository|
|
200
|
+
mock_package(repository)
|
201
|
+
platform.prepare_for_deploy(
|
202
|
+
services: { 'node' => %w[test_policy] },
|
203
|
+
secrets: {},
|
204
|
+
local_environment: false,
|
205
|
+
why_run: false
|
206
|
+
)
|
207
|
+
File.unlink("#{repository}/chef_versions.yml")
|
208
|
+
expect { platform.actions_to_deploy_on('node', 'test_policy', use_why_run: false) }.to raise_error "Missing file #{repository}/chef_versions.yml specifying the Chef Infra Client version to be deployed"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
|
214
|
+
context 'with a platform having several nodes' do
|
215
|
+
|
216
|
+
it 'deploys services declared on 1 node on another node if asked' do
|
217
|
+
with_serverless_chef_platforms('several_nodes') do |platform, repository|
|
218
|
+
mock_package(repository)
|
219
|
+
platform.prepare_for_deploy(
|
220
|
+
services: { 'node2' => %w[test_policy_1] },
|
221
|
+
secrets: {},
|
222
|
+
local_environment: false,
|
223
|
+
why_run: false
|
224
|
+
)
|
225
|
+
expect(platform.actions_to_deploy_on('node2', 'test_policy_1', use_why_run: false)).to eq expected_actions_to_deploy_chef(repository, policy: 'test_policy_1', node: 'node2')
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'deploys local nodes' do
|
230
|
+
with_serverless_chef_platforms('several_nodes') do |platform, repository|
|
231
|
+
mock_package(repository)
|
232
|
+
platform.prepare_for_deploy(
|
233
|
+
services: { 'local' => %w[test_policy_1] },
|
234
|
+
secrets: {},
|
235
|
+
local_environment: false,
|
236
|
+
why_run: false
|
237
|
+
)
|
238
|
+
expect(platform.actions_to_deploy_on('local', 'test_policy_1', use_why_run: false)).to eq [
|
239
|
+
{
|
240
|
+
bash: "cd #{repository}/dist/prod/test_policy_1 && sudo SSL_CERT_DIR=/etc/ssl/certs /opt/chef-workstation/bin/chef-client --local-mode --json-attributes nodes/local.json"
|
241
|
+
}
|
242
|
+
]
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|
247
|
+
|
248
|
+
context 'with 2 platforms' do
|
249
|
+
|
250
|
+
it 'deploys a service on a node belonging to another platform' do
|
251
|
+
with_serverless_chef_platforms({ 'p1' => '1_node', 'p2' => 'several_nodes' }) do |repositories|
|
252
|
+
platform_p1, repository_p1 = repositories.find { |platform, _repository| platform.name == 'p1' }
|
253
|
+
mock_package(repository_p1)
|
254
|
+
platform_p1.prepare_for_deploy(
|
255
|
+
services: { 'node2' => %w[test_policy_1] },
|
256
|
+
secrets: {},
|
257
|
+
local_environment: false,
|
258
|
+
why_run: false
|
259
|
+
)
|
260
|
+
expect(platform_p1.actions_to_deploy_on('node2', 'test_policy_1', use_why_run: false)).to eq expected_actions_to_deploy_chef(repository_p1, policy: 'test_policy_1', node: 'node2')
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
end
|
265
|
+
|
266
|
+
end
|
267
|
+
|
268
|
+
end
|