hybrid_platforms_conductor 32.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (244) hide show
  1. checksums.yaml +7 -0
  2. data/bin/check-node +24 -0
  3. data/bin/deploy +12 -0
  4. data/bin/dump_nodes_json +12 -0
  5. data/bin/free_ips +23 -0
  6. data/bin/free_veids +17 -0
  7. data/bin/get_impacted_nodes +43 -0
  8. data/bin/last_deploys +56 -0
  9. data/bin/nodes_to_deploy +104 -0
  10. data/bin/report +10 -0
  11. data/bin/run +39 -0
  12. data/bin/setup +11 -0
  13. data/bin/ssh_config +14 -0
  14. data/bin/test +13 -0
  15. data/bin/topograph +54 -0
  16. data/lib/hybrid_platforms_conductor/action.rb +82 -0
  17. data/lib/hybrid_platforms_conductor/actions_executor.rb +307 -0
  18. data/lib/hybrid_platforms_conductor/bitbucket.rb +123 -0
  19. data/lib/hybrid_platforms_conductor/cmd_runner.rb +188 -0
  20. data/lib/hybrid_platforms_conductor/cmdb.rb +34 -0
  21. data/lib/hybrid_platforms_conductor/common_config_dsl/bitbucket.rb +78 -0
  22. data/lib/hybrid_platforms_conductor/common_config_dsl/confluence.rb +43 -0
  23. data/lib/hybrid_platforms_conductor/common_config_dsl/file_system_tests.rb +110 -0
  24. data/lib/hybrid_platforms_conductor/common_config_dsl/idempotence_tests.rb +38 -0
  25. data/lib/hybrid_platforms_conductor/config.rb +263 -0
  26. data/lib/hybrid_platforms_conductor/confluence.rb +119 -0
  27. data/lib/hybrid_platforms_conductor/connector.rb +84 -0
  28. data/lib/hybrid_platforms_conductor/credentials.rb +127 -0
  29. data/lib/hybrid_platforms_conductor/current_dir_monitor.rb +42 -0
  30. data/lib/hybrid_platforms_conductor/deployer.rb +598 -0
  31. data/lib/hybrid_platforms_conductor/executable.rb +145 -0
  32. data/lib/hybrid_platforms_conductor/hpc_plugins/action/bash.rb +44 -0
  33. data/lib/hybrid_platforms_conductor/hpc_plugins/action/interactive.rb +44 -0
  34. data/lib/hybrid_platforms_conductor/hpc_plugins/action/my_action.rb.sample +79 -0
  35. data/lib/hybrid_platforms_conductor/hpc_plugins/action/remote_bash.rb +63 -0
  36. data/lib/hybrid_platforms_conductor/hpc_plugins/action/ruby.rb +69 -0
  37. data/lib/hybrid_platforms_conductor/hpc_plugins/action/scp.rb +61 -0
  38. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/config.rb +78 -0
  39. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/host_ip.rb +104 -0
  40. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/host_keys.rb +114 -0
  41. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/my_cmdb.rb.sample +129 -0
  42. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/platform_handlers.rb +66 -0
  43. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/my_connector.rb.sample +156 -0
  44. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +702 -0
  45. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/platform_handler_plugin.rb.sample +292 -0
  46. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/docker.rb +148 -0
  47. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/my_provisioner.rb.sample +103 -0
  48. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/podman.rb +125 -0
  49. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox.rb +522 -0
  50. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox/proxmox_waiter.rb +707 -0
  51. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox/reserve_proxmox_container +122 -0
  52. data/lib/hybrid_platforms_conductor/hpc_plugins/report/confluence.rb +69 -0
  53. data/lib/hybrid_platforms_conductor/hpc_plugins/report/mediawiki.rb +164 -0
  54. data/lib/hybrid_platforms_conductor/hpc_plugins/report/my_report_plugin.rb.sample +88 -0
  55. data/lib/hybrid_platforms_conductor/hpc_plugins/report/stdout.rb +61 -0
  56. data/lib/hybrid_platforms_conductor/hpc_plugins/report/templates/confluence_inventory.html.erb +33 -0
  57. data/lib/hybrid_platforms_conductor/hpc_plugins/test/bitbucket_conf.rb +137 -0
  58. data/lib/hybrid_platforms_conductor/hpc_plugins/test/can_be_checked.rb +21 -0
  59. data/lib/hybrid_platforms_conductor/hpc_plugins/test/check_deploy_and_idempotence.rb +112 -0
  60. data/lib/hybrid_platforms_conductor/hpc_plugins/test/check_from_scratch.rb +35 -0
  61. data/lib/hybrid_platforms_conductor/hpc_plugins/test/connection.rb +28 -0
  62. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_freshness.rb +44 -0
  63. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_from_scratch.rb +36 -0
  64. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +49 -0
  65. data/lib/hybrid_platforms_conductor/hpc_plugins/test/divergence.rb +25 -0
  66. data/lib/hybrid_platforms_conductor/hpc_plugins/test/executables.rb +46 -0
  67. data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system.rb +45 -0
  68. data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system_hdfs.rb +45 -0
  69. data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +25 -0
  70. data/lib/hybrid_platforms_conductor/hpc_plugins/test/idempotence.rb +77 -0
  71. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +38 -0
  72. data/lib/hybrid_platforms_conductor/hpc_plugins/test/jenkins_ci_conf.rb +56 -0
  73. data/lib/hybrid_platforms_conductor/hpc_plugins/test/jenkins_ci_masters_ok.rb +54 -0
  74. data/lib/hybrid_platforms_conductor/hpc_plugins/test/linear_strategy.rb +47 -0
  75. data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +82 -0
  76. data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +120 -0
  77. data/lib/hybrid_platforms_conductor/hpc_plugins/test/my_test_plugin.rb.sample +143 -0
  78. data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +74 -0
  79. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ports.rb +85 -0
  80. data/lib/hybrid_platforms_conductor/hpc_plugins/test/private_ips.rb +38 -0
  81. data/lib/hybrid_platforms_conductor/hpc_plugins/test/public_ips.rb +38 -0
  82. data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre-meltdown-checker.sh +1930 -0
  83. data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +56 -0
  84. data/lib/hybrid_platforms_conductor/hpc_plugins/test/veids.rb +31 -0
  85. data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +159 -0
  86. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/confluence.rb +122 -0
  87. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/my_test_report.rb.sample +48 -0
  88. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/stdout.rb +120 -0
  89. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/templates/_confluence_errors_status.html.erb +46 -0
  90. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/templates/_confluence_gauge.html.erb +49 -0
  91. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/templates/confluence.html.erb +242 -0
  92. data/lib/hybrid_platforms_conductor/io_router.rb +70 -0
  93. data/lib/hybrid_platforms_conductor/json_dumper.rb +88 -0
  94. data/lib/hybrid_platforms_conductor/logger_helpers.rb +319 -0
  95. data/lib/hybrid_platforms_conductor/mutex_dir +76 -0
  96. data/lib/hybrid_platforms_conductor/nodes_handler.rb +597 -0
  97. data/lib/hybrid_platforms_conductor/parallel_threads.rb +97 -0
  98. data/lib/hybrid_platforms_conductor/platform_handler.rb +188 -0
  99. data/lib/hybrid_platforms_conductor/platforms_handler.rb +118 -0
  100. data/lib/hybrid_platforms_conductor/plugin.rb +53 -0
  101. data/lib/hybrid_platforms_conductor/plugins.rb +101 -0
  102. data/lib/hybrid_platforms_conductor/provisioner.rb +181 -0
  103. data/lib/hybrid_platforms_conductor/report.rb +31 -0
  104. data/lib/hybrid_platforms_conductor/reports_handler.rb +84 -0
  105. data/lib/hybrid_platforms_conductor/services_handler.rb +274 -0
  106. data/lib/hybrid_platforms_conductor/test.rb +141 -0
  107. data/lib/hybrid_platforms_conductor/test_by_service.rb +22 -0
  108. data/lib/hybrid_platforms_conductor/test_report.rb +282 -0
  109. data/lib/hybrid_platforms_conductor/tests_runner.rb +590 -0
  110. data/lib/hybrid_platforms_conductor/thycotic.rb +92 -0
  111. data/lib/hybrid_platforms_conductor/topographer.rb +859 -0
  112. data/lib/hybrid_platforms_conductor/topographer/plugin.rb +20 -0
  113. data/lib/hybrid_platforms_conductor/topographer/plugins/graphviz.rb +127 -0
  114. data/lib/hybrid_platforms_conductor/topographer/plugins/json.rb +72 -0
  115. data/lib/hybrid_platforms_conductor/topographer/plugins/my_topographer_output_plugin.rb.sample +37 -0
  116. data/lib/hybrid_platforms_conductor/topographer/plugins/svg.rb +30 -0
  117. data/lib/hybrid_platforms_conductor/version.rb +5 -0
  118. data/spec/hybrid_platforms_conductor_test.rb +159 -0
  119. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/bash_spec.rb +43 -0
  120. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/interactive_spec.rb +18 -0
  121. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/remote_bash_spec.rb +102 -0
  122. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/ruby_spec.rb +108 -0
  123. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/scp_spec.rb +79 -0
  124. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions_spec.rb +199 -0
  125. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connection_spec.rb +212 -0
  126. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/cli_options_spec.rb +125 -0
  127. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/config_dsl_spec.rb +50 -0
  128. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connectable_nodes_spec.rb +28 -0
  129. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connections_spec.rb +448 -0
  130. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/global_helpers_spec.rb +313 -0
  131. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/node_helpers_spec.rb +32 -0
  132. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb +134 -0
  133. data/spec/hybrid_platforms_conductor_test/api/actions_executor/logging_spec.rb +256 -0
  134. data/spec/hybrid_platforms_conductor_test/api/actions_executor/parallel_spec.rb +338 -0
  135. data/spec/hybrid_platforms_conductor_test/api/actions_executor/timeout_spec.rb +101 -0
  136. data/spec/hybrid_platforms_conductor_test/api/cmd_runner_spec.rb +165 -0
  137. data/spec/hybrid_platforms_conductor_test/api/config_spec.rb +238 -0
  138. data/spec/hybrid_platforms_conductor_test/api/deployer/check_spec.rb +9 -0
  139. data/spec/hybrid_platforms_conductor_test/api/deployer/deploy_spec.rb +243 -0
  140. data/spec/hybrid_platforms_conductor_test/api/deployer/parse_deploy_output_spec.rb +104 -0
  141. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioner_spec.rb +131 -0
  142. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/docker/Dockerfile +10 -0
  143. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/docker_spec.rb +123 -0
  144. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/podman_spec.rb +211 -0
  145. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/config_dsl_spec.rb +126 -0
  146. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/create_spec.rb +290 -0
  147. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/destroy_spec.rb +43 -0
  148. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/ip_spec.rb +60 -0
  149. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/proxmox.json +3 -0
  150. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/destroy_vm_spec.rb +82 -0
  151. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/expired_containers_spec.rb +786 -0
  152. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/ips_assignment_spec.rb +112 -0
  153. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/other_lxc_containers_resources_spec.rb +190 -0
  154. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/pve_node_resources_spec.rb +200 -0
  155. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/retries_spec.rb +35 -0
  156. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/vm_ids_assignment_spec.rb +67 -0
  157. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/start_spec.rb +79 -0
  158. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/state_spec.rb +28 -0
  159. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/stop_spec.rb +41 -0
  160. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/config_spec.rb +33 -0
  161. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/host_ip_spec.rb +64 -0
  162. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/host_keys_spec.rb +133 -0
  163. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/platform_handlers_spec.rb +19 -0
  164. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs_plugins_api_spec.rb +446 -0
  165. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/common_spec.rb +127 -0
  166. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/git_diff_impacts_spec.rb +318 -0
  167. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/nodes_selectors_spec.rb +132 -0
  168. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/platform_handlers_plugins_api_spec.rb +60 -0
  169. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/several_platforms_spec.rb +58 -0
  170. data/spec/hybrid_platforms_conductor_test/api/platform_handler_spec.rb +97 -0
  171. data/spec/hybrid_platforms_conductor_test/api/platforms_handler_spec.rb +104 -0
  172. data/spec/hybrid_platforms_conductor_test/api/plugins_spec.rb +243 -0
  173. data/spec/hybrid_platforms_conductor_test/api/reports_handler_spec.rb +44 -0
  174. data/spec/hybrid_platforms_conductor_test/api/services_handler/actions_to_deploy_spec.rb +121 -0
  175. data/spec/hybrid_platforms_conductor_test/api/services_handler/deploy_allowed_spec.rb +142 -0
  176. data/spec/hybrid_platforms_conductor_test/api/services_handler/log_info_spec.rb +101 -0
  177. data/spec/hybrid_platforms_conductor_test/api/services_handler/package_spec.rb +388 -0
  178. data/spec/hybrid_platforms_conductor_test/api/services_handler/parse_deploy_output_spec.rb +274 -0
  179. data/spec/hybrid_platforms_conductor_test/api/services_handler/prepare_for_deploy_spec.rb +264 -0
  180. data/spec/hybrid_platforms_conductor_test/api/tests_runner/common_spec.rb +194 -0
  181. data/spec/hybrid_platforms_conductor_test/api/tests_runner/global_spec.rb +37 -0
  182. data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_check_spec.rb +194 -0
  183. data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_spec.rb +137 -0
  184. data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_ssh_spec.rb +257 -0
  185. data/spec/hybrid_platforms_conductor_test/api/tests_runner/platform_spec.rb +110 -0
  186. data/spec/hybrid_platforms_conductor_test/api/tests_runner/reports_spec.rb +367 -0
  187. data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/bitbucket_conf_spec.rb +111 -0
  188. data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_reports_plugins/confluence_spec.rb +29 -0
  189. data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb.rb +166 -0
  190. data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb2.rb +93 -0
  191. data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb_others.rb +60 -0
  192. data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb_others2.rb +58 -0
  193. data/spec/hybrid_platforms_conductor_test/executables/check-node_spec.rb +35 -0
  194. data/spec/hybrid_platforms_conductor_test/executables/deploy_spec.rb +35 -0
  195. data/spec/hybrid_platforms_conductor_test/executables/get_impacted_nodes_spec.rb +158 -0
  196. data/spec/hybrid_platforms_conductor_test/executables/last_deploys_spec.rb +173 -0
  197. data/spec/hybrid_platforms_conductor_test/executables/nodes_to_deploy_spec.rb +283 -0
  198. data/spec/hybrid_platforms_conductor_test/executables/options/actions_executor_spec.rb +28 -0
  199. data/spec/hybrid_platforms_conductor_test/executables/options/cmd_runner_spec.rb +28 -0
  200. data/spec/hybrid_platforms_conductor_test/executables/options/common_spec.rb +67 -0
  201. data/spec/hybrid_platforms_conductor_test/executables/options/deployer_spec.rb +251 -0
  202. data/spec/hybrid_platforms_conductor_test/executables/options/nodes_handler_spec.rb +111 -0
  203. data/spec/hybrid_platforms_conductor_test/executables/options/nodes_selectors_spec.rb +71 -0
  204. data/spec/hybrid_platforms_conductor_test/executables/options/reports_handler_spec.rb +54 -0
  205. data/spec/hybrid_platforms_conductor_test/executables/options/tests_runner_spec.rb +139 -0
  206. data/spec/hybrid_platforms_conductor_test/executables/report_spec.rb +60 -0
  207. data/spec/hybrid_platforms_conductor_test/executables/run_spec.rb +173 -0
  208. data/spec/hybrid_platforms_conductor_test/executables/ssh_config_spec.rb +35 -0
  209. data/spec/hybrid_platforms_conductor_test/executables/test_spec.rb +41 -0
  210. data/spec/hybrid_platforms_conductor_test/helpers/actions_executor_helpers.rb +98 -0
  211. data/spec/hybrid_platforms_conductor_test/helpers/cmd_runner_helpers.rb +92 -0
  212. data/spec/hybrid_platforms_conductor_test/helpers/cmdb_helpers.rb +37 -0
  213. data/spec/hybrid_platforms_conductor_test/helpers/config_helpers.rb +20 -0
  214. data/spec/hybrid_platforms_conductor_test/helpers/connector_ssh_helpers.rb +130 -0
  215. data/spec/hybrid_platforms_conductor_test/helpers/deployer_helpers.rb +149 -0
  216. data/spec/hybrid_platforms_conductor_test/helpers/deployer_test_helpers.rb +812 -0
  217. data/spec/hybrid_platforms_conductor_test/helpers/executables_helpers.rb +96 -0
  218. data/spec/hybrid_platforms_conductor_test/helpers/nodes_handler_helpers.rb +20 -0
  219. data/spec/hybrid_platforms_conductor_test/helpers/platform_handler_helpers.rb +35 -0
  220. data/spec/hybrid_platforms_conductor_test/helpers/platforms_handler_helpers.rb +127 -0
  221. data/spec/hybrid_platforms_conductor_test/helpers/plugins_helpers.rb +48 -0
  222. data/spec/hybrid_platforms_conductor_test/helpers/provisioner_proxmox_helpers.rb +789 -0
  223. data/spec/hybrid_platforms_conductor_test/helpers/reports_handler_helpers.rb +29 -0
  224. data/spec/hybrid_platforms_conductor_test/helpers/services_handler_helpers.rb +20 -0
  225. data/spec/hybrid_platforms_conductor_test/helpers/tests_runner_helpers.rb +38 -0
  226. data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem/hpc_plugins/test_plugin_type/test_plugin_id1.rb +22 -0
  227. data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem/hpc_plugins/test_plugin_type/test_plugin_id2.rb +22 -0
  228. data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem2/sub_dir/hpc_plugins/test_plugin_type/test_plugin_id3.rb +26 -0
  229. data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem2/sub_dir/hpc_plugins/test_plugin_type2/test_plugin_id4.rb +26 -0
  230. data/spec/hybrid_platforms_conductor_test/platform_handler_plugins/test.rb +225 -0
  231. data/spec/hybrid_platforms_conductor_test/platform_handler_plugins/test2.rb +11 -0
  232. data/spec/hybrid_platforms_conductor_test/report_plugin.rb +35 -0
  233. data/spec/hybrid_platforms_conductor_test/test_action.rb +66 -0
  234. data/spec/hybrid_platforms_conductor_test/test_connector.rb +151 -0
  235. data/spec/hybrid_platforms_conductor_test/test_plugins/global.rb +30 -0
  236. data/spec/hybrid_platforms_conductor_test/test_plugins/node.rb +53 -0
  237. data/spec/hybrid_platforms_conductor_test/test_plugins/node_check.rb +47 -0
  238. data/spec/hybrid_platforms_conductor_test/test_plugins/node_ssh.rb +42 -0
  239. data/spec/hybrid_platforms_conductor_test/test_plugins/platform.rb +50 -0
  240. data/spec/hybrid_platforms_conductor_test/test_plugins/several_checks.rb +50 -0
  241. data/spec/hybrid_platforms_conductor_test/test_provisioner.rb +95 -0
  242. data/spec/hybrid_platforms_conductor_test/tests_report_plugin.rb +49 -0
  243. data/spec/spec_helper.rb +111 -0
  244. metadata +566 -0
@@ -0,0 +1,212 @@
1
+ describe HybridPlatformsConductor::ActionsExecutor do
2
+
3
+ context 'checking connections handling' do
4
+
5
+ # Get a test platform to test connection, using the test_connector
6
+ #
7
+ # Parameters::
8
+ # * Proc: Code called with platform setup
9
+ # * Parameters::
10
+ # * *repository* (String): Repository where the platform has been setup
11
+ def with_test_platform_for_connections
12
+ with_test_platform_for_executor(nodes: {
13
+ 'node1' => {},
14
+ 'node2' => {},
15
+ 'node3' => {},
16
+ 'node4' => {}
17
+ }) do |repository|
18
+ yield repository
19
+ end
20
+ end
21
+
22
+ it 'connects on a node before executing actions needing connection' do
23
+ with_test_platform_for_connections do
24
+ test_actions_executor.connector(:test_connector).accept_nodes = ['node1']
25
+ test_actions_executor.execute_actions('node1' => { test_action: { need_connector: true } })
26
+ expect(action_executions).to eq [{ node: 'node1', message: 'Action executed' }]
27
+ expect(test_actions_executor.connector(:test_connector).calls).to eq [
28
+ [:connectable_nodes_from, ['node1']],
29
+ [:with_connection_to, ['node1'], { no_exception: true }]
30
+ ]
31
+ end
32
+ end
33
+
34
+ it 'returns an error when no connector can connect to the needed node' do
35
+ with_test_platform_for_connections do
36
+ expect(test_actions_executor.execute_actions('node1' => { test_action: { need_connector: true } })).to eq(
37
+ 'node1' => [:no_connector, '', 'Unable to get a connector to node1']
38
+ )
39
+ end
40
+ end
41
+
42
+ it 'connects on several nodes before executing actions needing connection' do
43
+ with_test_platform_for_connections do
44
+ test_actions_executor.connector(:test_connector).accept_nodes = %w[node1 node2 node3 node4]
45
+ test_actions_executor.execute_actions(%w[node1 node2 node3 node4] => { test_action: { need_connector: true } })
46
+ expect(action_executions).to eq [
47
+ { node: 'node1', message: 'Action executed' },
48
+ { node: 'node2', message: 'Action executed' },
49
+ { node: 'node3', message: 'Action executed' },
50
+ { node: 'node4', message: 'Action executed' }
51
+ ]
52
+ expect(test_actions_executor.connector(:test_connector).calls).to eq [
53
+ [:connectable_nodes_from, %w[node1 node2 node3 node4]],
54
+ [:with_connection_to, %w[node1 node2 node3 node4], { no_exception: true }]
55
+ ]
56
+ end
57
+ end
58
+
59
+ it 'connects on several nodes before executing actions needing connection only on nodes that could be connected' do
60
+ with_test_platform_for_connections do
61
+ test_actions_executor.connector(:test_connector).accept_nodes = %w[node1 node2 node3 node4]
62
+ test_actions_executor.connector(:test_connector).connected_nodes = %w[node1 node2 node4]
63
+ test_actions_executor.execute_actions(%w[node1 node2 node3 node4] => { test_action: { need_connector: true } })
64
+ expect(action_executions).to eq [
65
+ { node: 'node1', message: 'Action executed' },
66
+ { node: 'node2', message: 'Action executed' },
67
+ { node: 'node4', message: 'Action executed' }
68
+ ]
69
+ expect(test_actions_executor.connector(:test_connector).calls).to eq [
70
+ [:connectable_nodes_from, %w[node1 node2 node3 node4]],
71
+ [:with_connection_to, %w[node1 node2 node3 node4], { no_exception: true }]
72
+ ]
73
+ end
74
+ end
75
+
76
+ it 'connects only on nodes having an action needing connection' do
77
+ with_test_platform_for_connections do
78
+ test_actions_executor.connector(:test_connector).accept_nodes = %w[node1 node2 node3 node4]
79
+ test_actions_executor.execute_actions(
80
+ %w[node1 node3] => { test_action: { need_connector: true } },
81
+ %w[node2 node4] => { test_action: { need_connector: false } }
82
+ )
83
+ expect(action_executions).to eq [
84
+ { node: 'node1', message: 'Action executed' },
85
+ { node: 'node2', message: 'Action executed' },
86
+ { node: 'node3', message: 'Action executed' },
87
+ { node: 'node4', message: 'Action executed' }
88
+ ]
89
+ expect(test_actions_executor.connector(:test_connector).calls).to eq [
90
+ [:connectable_nodes_from, %w[node1 node3]],
91
+ [:with_connection_to, %w[node1 node3], { no_exception: true }]
92
+ ]
93
+ end
94
+ end
95
+
96
+ it 'does not ask for any connection if actions don\'t need remote' do
97
+ with_test_platform_for_connections do
98
+ test_actions_executor.connector(:test_connector).accept_nodes = %w[node1 node2 node3 node4]
99
+ test_actions_executor.execute_actions(%w[node1 node2 node3 node4] => { test_action: { need_connector: false } })
100
+ expect(action_executions).to eq [
101
+ { node: 'node1', message: 'Action executed' },
102
+ { node: 'node2', message: 'Action executed' },
103
+ { node: 'node3', message: 'Action executed' },
104
+ { node: 'node4', message: 'Action executed' }
105
+ ]
106
+ expect(test_actions_executor.connector(:test_connector).calls).to eq []
107
+ end
108
+ end
109
+
110
+ it 'uses proper connectors for each node needing connection' do
111
+ with_test_platform_for_connections do
112
+ test_actions_executor.connector(:test_connector).accept_nodes = %w[node1 node3]
113
+ test_actions_executor.connector(:test_connector_2).accept_nodes = %w[node2 node4]
114
+ test_actions_executor.execute_actions(%w[node1 node2 node3 node4] => { test_action: { need_connector: true } })
115
+ expect(action_executions).to eq [
116
+ { node: 'node1', message: 'Action executed' },
117
+ { node: 'node2', message: 'Action executed' },
118
+ { node: 'node3', message: 'Action executed' },
119
+ { node: 'node4', message: 'Action executed' }
120
+ ]
121
+ expect(test_actions_executor.connector(:test_connector).calls).to eq [
122
+ [:connectable_nodes_from, %w[node1 node2 node3 node4]],
123
+ [:with_connection_to, %w[node1 node3], { no_exception: true }]
124
+ ]
125
+ expect(test_actions_executor.connector(:test_connector_2).calls).to eq [
126
+ [:connectable_nodes_from, %w[node2 node4]],
127
+ [:with_connection_to, %w[node2 node4], { no_exception: true }]
128
+ ]
129
+ end
130
+ end
131
+
132
+ it 'uses the first connector available to connect on nodes' do
133
+ with_test_platform_for_connections do
134
+ test_actions_executor.connector(:test_connector).accept_nodes = %w[node1 node2 node3]
135
+ test_actions_executor.connector(:test_connector_2).accept_nodes = %w[node2 node4]
136
+ test_actions_executor.execute_actions(%w[node1 node2 node3 node4] => { test_action: { need_connector: true } })
137
+ expect(action_executions).to eq [
138
+ { node: 'node1', message: 'Action executed' },
139
+ { node: 'node2', message: 'Action executed' },
140
+ { node: 'node3', message: 'Action executed' },
141
+ { node: 'node4', message: 'Action executed' }
142
+ ]
143
+ expect(test_actions_executor.connector(:test_connector).calls).to eq [
144
+ [:connectable_nodes_from, %w[node1 node2 node3 node4]],
145
+ [:with_connection_to, %w[node1 node2 node3], { no_exception: true }]
146
+ ]
147
+ expect(test_actions_executor.connector(:test_connector_2).calls).to eq [
148
+ [:connectable_nodes_from, %w[node4]],
149
+ [:with_connection_to, %w[node4], { no_exception: true }]
150
+ ]
151
+ end
152
+ end
153
+
154
+ it 'can prepare connections to nodes' do
155
+ with_test_platform_for_connections do
156
+ test_actions_executor.connector(:test_connector).accept_nodes = %w[node1 node3]
157
+ test_actions_executor.connector(:test_connector_2).accept_nodes = %w[node2 node4]
158
+ test_actions_executor.with_connections_prepared_to(%w[node1 node2 node3 node4]) do |connected_nodes|
159
+ expect(test_actions_executor.connector(:test_connector).calls).to eq [
160
+ [:connectable_nodes_from, %w[node1 node2 node3 node4]],
161
+ [:with_connection_to, %w[node1 node3], { no_exception: false }]
162
+ ]
163
+ expect(test_actions_executor.connector(:test_connector_2).calls).to eq [
164
+ [:connectable_nodes_from, %w[node2 node4]],
165
+ [:with_connection_to, %w[node2 node4], { no_exception: false }]
166
+ ]
167
+ expect(connected_nodes).to eq(
168
+ 'node1' => test_actions_executor.connector(:test_connector),
169
+ 'node2' => test_actions_executor.connector(:test_connector_2),
170
+ 'node3' => test_actions_executor.connector(:test_connector),
171
+ 'node4' => test_actions_executor.connector(:test_connector_2)
172
+ )
173
+ end
174
+ end
175
+ end
176
+
177
+ it 'fails to prepare connections to nodes when connectors are not available' do
178
+ with_test_platform_for_connections do
179
+ test_actions_executor.connector(:test_connector).accept_nodes = %w[node1 node3]
180
+ test_actions_executor.connector(:test_connector_2).accept_nodes = %w[node2]
181
+ expect do
182
+ test_actions_executor.with_connections_prepared_to(%w[node1 node2 node3 node4]) { |connected_nodes| }
183
+ end.to raise_error(/The following nodes have no possible connector to them: node4/)
184
+ end
185
+ end
186
+
187
+ it 'can prepare connections to nodes ignoring failures if needed' do
188
+ with_test_platform_for_connections do
189
+ test_actions_executor.connector(:test_connector).accept_nodes = %w[node1 node3]
190
+ test_actions_executor.connector(:test_connector_2).accept_nodes = %w[node2]
191
+ test_actions_executor.with_connections_prepared_to(%w[node1 node2 node3 node4], no_exception: true) do |connected_nodes|
192
+ expect(test_actions_executor.connector(:test_connector).calls).to eq [
193
+ [:connectable_nodes_from, %w[node1 node2 node3 node4]],
194
+ [:with_connection_to, %w[node1 node3], { no_exception: true }]
195
+ ]
196
+ expect(test_actions_executor.connector(:test_connector_2).calls).to eq [
197
+ [:connectable_nodes_from, %w[node2 node4]],
198
+ [:with_connection_to, %w[node2], { no_exception: true }]
199
+ ]
200
+ expect(connected_nodes).to eq(
201
+ 'node1' => test_actions_executor.connector(:test_connector),
202
+ 'node2' => test_actions_executor.connector(:test_connector_2),
203
+ 'node3' => test_actions_executor.connector(:test_connector),
204
+ 'node4' => :no_connector
205
+ )
206
+ end
207
+ end
208
+ end
209
+
210
+ end
211
+
212
+ end
@@ -0,0 +1,125 @@
1
+ describe HybridPlatformsConductor::ActionsExecutor do
2
+
3
+ context 'checking connector plugin ssh' do
4
+
5
+ context 'checking command-line interface options' do
6
+
7
+ # Setup a platform for tests
8
+ #
9
+ # Parameters::
10
+ # * Proc: Code called when the platform is setup
11
+ # * Parameters::
12
+ # * *repository* (String): Platform's repository
13
+ def with_test_platform_for_cli
14
+ with_test_platform(
15
+ { nodes: { 'node' => {} } },
16
+ false,
17
+ "
18
+ gateway :test_gateway, 'Host test_gateway'
19
+ gateway :test_gateway2, 'Host test_gateway2'
20
+ "
21
+ ) do |repository|
22
+ ENV['hpc_ssh_gateways_conf'] = 'test_gateway'
23
+ yield repository
24
+ end
25
+ end
26
+
27
+ # Return the connector to be tested
28
+ #
29
+ # Result::
30
+ # * Connector: Connector to be tested
31
+ def test_connector
32
+ test_actions_executor.connector(:ssh)
33
+ end
34
+
35
+ it 'selects the correct gateway user' do
36
+ with_test_platform_for_cli do
37
+ expect_actions_executor_runs([proc do |actions, timeout: nil, concurrent: false, log_to_dir: 'run_logs', log_to_stdout: true|
38
+ expect(test_connector.ssh_gateway_user).to eq 'another_user'
39
+ {}
40
+ end])
41
+ exit_code, stdout, stderr = run 'run', '--node', 'node', '--command', 'echo Hello', '--ssh-gateway-user', 'another_user'
42
+ expect(exit_code).to eq 0
43
+ expect(stdout).to eq ''
44
+ expect(stderr).to eq ''
45
+ end
46
+ end
47
+
48
+ it 'selects the correct gateway conf' do
49
+ with_test_platform_for_cli do
50
+ expect_actions_executor_runs([proc do |actions, timeout: nil, concurrent: false, log_to_dir: 'run_logs', log_to_stdout: true|
51
+ expect(test_connector.ssh_gateways_conf).to eq :test_gateway2
52
+ {}
53
+ end])
54
+ exit_code, stdout, stderr = run 'run', '--node', 'node', '--command', 'echo Hello', '--ssh-gateways-conf', 'test_gateway2'
55
+ expect(exit_code).to eq 0
56
+ expect(stdout).to eq ''
57
+ expect(stderr).to eq ''
58
+ end
59
+ end
60
+
61
+ it 'does not use the SSH control master' do
62
+ with_test_platform_for_cli do
63
+ expect_actions_executor_runs([proc do |actions, timeout: nil, concurrent: false, log_to_dir: 'run_logs', log_to_stdout: true|
64
+ expect(test_connector.ssh_use_control_master).to eq false
65
+ {}
66
+ end])
67
+ exit_code, stdout, stderr = run 'run', '--node', 'node', '--command', 'echo Hello', '--ssh-no-control-master'
68
+ expect(exit_code).to eq 0
69
+ expect(stdout).to eq ''
70
+ expect(stderr).to eq ''
71
+ end
72
+ end
73
+
74
+ it 'does not use strict host key checking' do
75
+ with_test_platform_for_cli do
76
+ expect_actions_executor_runs([proc do |actions, timeout: nil, concurrent: false, log_to_dir: 'run_logs', log_to_stdout: true|
77
+ expect(test_connector.ssh_strict_host_key_checking).to eq false
78
+ {}
79
+ end])
80
+ exit_code, stdout, stderr = run 'run', '--node', 'node', '--command', 'echo Hello', '--ssh-no-host-key-checking'
81
+ expect(exit_code).to eq 0
82
+ expect(stdout).to eq ''
83
+ expect(stderr).to eq ''
84
+ end
85
+ end
86
+
87
+ it 'uses a different SSH user name' do
88
+ with_test_platform_for_cli do
89
+ expect_actions_executor_runs([proc do |actions, timeout: nil, concurrent: false, log_to_dir: 'run_logs', log_to_stdout: true|
90
+ expect(test_connector.ssh_user).to eq 'ssh_new_user'
91
+ {}
92
+ end])
93
+ exit_code, stdout, stderr = run 'run', '--node', 'node', '--command', 'echo Hello', '--ssh-user', 'ssh_new_user'
94
+ expect(exit_code).to eq 0
95
+ expect(stdout).to eq ''
96
+ expect(stderr).to eq ''
97
+ end
98
+ end
99
+
100
+ it 'fails if no user name has been given, either through environment or command-line' do
101
+ ENV.delete 'hpc_ssh_user'
102
+ ENV.delete 'USER'
103
+ with_test_platform_for_cli do
104
+ expect { run 'run', '--node', 'node', '--command', 'echo Hello' }.to raise_error(RuntimeError, 'No SSH user name specified. Please use --ssh-user option or hpc_ssh_user environment variable to set it.')
105
+ end
106
+ end
107
+
108
+ it 'expects passwords to be input' do
109
+ with_test_platform_for_cli do
110
+ expect_actions_executor_runs([proc do |actions, timeout: nil, concurrent: false, log_to_dir: 'run_logs', log_to_stdout: true|
111
+ expect(test_connector.auth_password).to eq true
112
+ {}
113
+ end])
114
+ exit_code, stdout, stderr = run 'run', '--node', 'node', '--command', 'echo Hello', '--password'
115
+ expect(exit_code).to eq 0
116
+ expect(stdout).to eq ''
117
+ expect(stderr).to eq ''
118
+ end
119
+ end
120
+
121
+ end
122
+
123
+ end
124
+
125
+ end
@@ -0,0 +1,50 @@
1
+ describe HybridPlatformsConductor::ActionsExecutor do
2
+
3
+ context 'checking connector plugin ssh' do
4
+
5
+ context 'checking Config DSL extensions' do
6
+
7
+ it 'returns 1 defined gateway' do
8
+ with_repository do |repository|
9
+ with_platforms 'gateway :gateway1, \'\'' do
10
+ expect(test_config.known_gateways).to eq [:gateway1]
11
+ end
12
+ end
13
+ end
14
+
15
+ it 'returns 1 defined gateway with its content' do
16
+ ssh_gateway = '
17
+ Host gateway
18
+ Hostname mygateway.com
19
+ '
20
+ with_repository do |repository|
21
+ with_platforms "gateway :gateway1, '#{ssh_gateway}'" do
22
+ expect(test_config.ssh_for_gateway(:gateway1)).to eq ssh_gateway
23
+ end
24
+ end
25
+ end
26
+
27
+ it 'returns 1 defined gateway with its content and replacing ERB template correctly' do
28
+ with_repository do |repository|
29
+ with_platforms 'gateway :gateway1, \'Host gateway_<%= @user %>\'' do
30
+ expect(test_config.ssh_for_gateway(:gateway1, user: 'test_user')).to eq 'Host gateway_test_user'
31
+ end
32
+ end
33
+ end
34
+
35
+ it 'returns several defined gateways' do
36
+ with_repository do |repository|
37
+ with_platforms '
38
+ gateway :gateway1, \'\'
39
+ gateway :gateway2, \'\'
40
+ ' do
41
+ expect(test_config.known_gateways.sort).to eq %i[gateway1 gateway2].sort
42
+ end
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,28 @@
1
+ describe HybridPlatformsConductor::ActionsExecutor do
2
+
3
+ context 'checking connector plugin ssh' do
4
+
5
+ context 'checking connectable nodes selection' do
6
+
7
+ # Return the connector to be tested
8
+ #
9
+ # Result::
10
+ # * Connector: Connector to be tested
11
+ def test_connector
12
+ test_actions_executor.connector(:ssh)
13
+ end
14
+
15
+ it 'selects connectable nodes correctly' do
16
+ with_test_platform(nodes: {
17
+ 'node1' => { meta: { host_ip: '192.168.42.42' } },
18
+ 'node2' => {}
19
+ }) do
20
+ expect(test_connector.connectable_nodes_from(%w[node1 node2])).to eq ['node1']
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,448 @@
1
+ describe HybridPlatformsConductor::ActionsExecutor do
2
+
3
+ context 'checking connector plugin ssh' do
4
+
5
+ context 'checking connections preparations' do
6
+
7
+ # Return the connector to be tested
8
+ #
9
+ # Result::
10
+ # * Connector: Connector to be tested
11
+ def test_connector
12
+ test_actions_executor.connector(:ssh)
13
+ end
14
+
15
+ it 'creates an SSH master to 1 node' do
16
+ with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42' } } }) do
17
+ with_cmd_runner_mocked(
18
+ [
19
+ ['which env', proc { [0, "/usr/bin/env\n", ''] }],
20
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
21
+ ] + ssh_expected_commands_for('node' => { connection: '192.168.42.42', user: 'test_user' })
22
+ ) do
23
+ test_connector.ssh_user = 'test_user'
24
+ test_connector.with_connection_to(['node']) do |connected_nodes|
25
+ expect(connected_nodes).to eq ['node']
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ it 'creates SSH master to several nodes' do
32
+ with_test_platform(nodes: {
33
+ 'node1' => { meta: { host_ip: '192.168.42.1' } },
34
+ 'node2' => { meta: { host_ip: '192.168.42.2' } },
35
+ 'node3' => { meta: { host_ip: '192.168.42.3' } }
36
+ }) do
37
+ with_cmd_runner_mocked(
38
+ [
39
+ ['which env', proc { [0, "/usr/bin/env\n", ''] }],
40
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
41
+ ] + ssh_expected_commands_for(
42
+ 'node1' => { connection: '192.168.42.1', user: 'test_user' },
43
+ 'node2' => { connection: '192.168.42.2', user: 'test_user' },
44
+ 'node3' => { connection: '192.168.42.3', user: 'test_user' }
45
+ )
46
+ ) do
47
+ test_connector.ssh_user = 'test_user'
48
+ test_connector.with_connection_to(%w[node1 node2 node3]) do |connected_nodes|
49
+ expect(connected_nodes.sort).to eq %w[node1 node2 node3].sort
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ it 'fails when an SSH master can\'t be created' do
56
+ with_test_platform(nodes: {
57
+ 'node1' => { meta: { host_ip: '192.168.42.1' } },
58
+ 'node2' => { meta: { host_ip: '192.168.42.2' } },
59
+ 'node3' => { meta: { host_ip: '192.168.42.3' } }
60
+ }) do
61
+ with_cmd_runner_mocked(
62
+ [
63
+ ['which env', proc { [0, "/usr/bin/env\n", ''] }],
64
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
65
+ ] + ssh_expected_commands_for(
66
+ 'node1' => { connection: '192.168.42.1', user: 'test_user' },
67
+ 'node3' => { connection: '192.168.42.3', user: 'test_user' }
68
+ ) + ssh_expected_commands_for(
69
+ {
70
+ 'node2' => { connection: '192.168.42.2', user: 'test_user', control_master_create_error: 'Can\'t connect to 192.168.42.2' }
71
+ },
72
+ with_control_master_destroy: false
73
+ )
74
+ ) do
75
+ test_connector.ssh_user = 'test_user'
76
+ expect { test_connector.with_connection_to(%w[node1 node2 node3]) }.to raise_error(/^Error while starting SSH Control Master with .+\/ssh -o BatchMode=yes -o ControlMaster=yes -o ControlPersist=yes test_user@hpc.node2 true: Can't connect to 192.168.42.2$/)
77
+ end
78
+ end
79
+ end
80
+
81
+ it 'fails without throwing exception when an SSH master can\'t be created and we use no_exception' do
82
+ with_test_platform(nodes: {
83
+ 'node1' => { meta: { host_ip: '192.168.42.1' } },
84
+ 'node2' => { meta: { host_ip: '192.168.42.2' } },
85
+ 'node3' => { meta: { host_ip: '192.168.42.3' } }
86
+ }) do
87
+ with_cmd_runner_mocked(
88
+ [
89
+ ['which env', proc { [0, "/usr/bin/env\n", ''] }],
90
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
91
+ ] + ssh_expected_commands_for(
92
+ 'node1' => { connection: '192.168.42.1', user: 'test_user' },
93
+ 'node3' => { connection: '192.168.42.3', user: 'test_user' }
94
+ ) + ssh_expected_commands_for(
95
+ {
96
+ 'node2' => { connection: '192.168.42.2', user: 'test_user', control_master_create_error: 'Can\'t connect to 192.168.42.2' }
97
+ },
98
+ with_control_master_destroy: false
99
+ )
100
+ ) do
101
+ test_connector.ssh_user = 'test_user'
102
+ test_connector.with_connection_to(%w[node1 node2 node3], no_exception: true) do |connected_nodes|
103
+ expect(connected_nodes.sort).to eq %w[node1 node3].sort
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ it 'reuses SSH master already created to 1 node' do
110
+ with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42' } } }) do
111
+ with_cmd_runner_mocked(
112
+ [
113
+ ['which env', proc { [0, "/usr/bin/env\n", ''] }],
114
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
115
+ ] +
116
+ ssh_expected_commands_for('node' => { connection: '192.168.42.42', user: 'test_user' }) +
117
+ ssh_expected_commands_for(
118
+ { 'node' => { connection: '192.168.42.42', user: 'test_user' } },
119
+ with_strict_host_key_checking: false,
120
+ with_control_master_create: false,
121
+ with_control_master_check: true,
122
+ with_control_master_destroy: false
123
+ )
124
+ ) do
125
+ test_connector.ssh_user = 'test_user'
126
+ test_connector.with_connection_to(['node']) do
127
+ test_connector.with_connection_to(['node']) do
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ it 'reuses SSH masters already created to some nodes and create new ones if needed' do
135
+ with_test_platform(nodes: {
136
+ 'node1' => { meta: { host_ip: '192.168.42.1' } },
137
+ 'node2' => { meta: { host_ip: '192.168.42.2' } },
138
+ 'node3' => { meta: { host_ip: '192.168.42.3' } },
139
+ 'node4' => { meta: { host_ip: '192.168.42.4' } }
140
+ }) do
141
+ with_cmd_runner_mocked(
142
+ [
143
+ ['which env', proc { [0, "/usr/bin/env\n", ''] }],
144
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
145
+ ] +
146
+ ssh_expected_commands_for(
147
+ 'node1' => { connection: '192.168.42.1', user: 'test_user' },
148
+ 'node3' => { connection: '192.168.42.3', user: 'test_user' }
149
+ ) +
150
+ ssh_expected_commands_for(
151
+ 'node2' => { connection: '192.168.42.2', user: 'test_user' },
152
+ 'node4' => { connection: '192.168.42.4', user: 'test_user' }
153
+ ) +
154
+ ssh_expected_commands_for(
155
+ {
156
+ 'node1' => { connection: '192.168.42.1', user: 'test_user' },
157
+ 'node3' => { connection: '192.168.42.3', user: 'test_user' }
158
+ },
159
+ with_strict_host_key_checking: false,
160
+ with_control_master_create: false,
161
+ with_control_master_check: true,
162
+ with_control_master_destroy: false
163
+ )
164
+ ) do
165
+ test_connector.ssh_user = 'test_user'
166
+ test_connector.with_connection_to(%w[node1 node3]) do
167
+ test_connector.with_connection_to(%w[node1 node2 node3 node4]) do
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
173
+
174
+ it 'makes sure the last client using ControlMaster destroys it, even using a different environment' do
175
+ with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42' } } }) do
176
+ # 1. Current thread creates the ControlMaster.
177
+ # 2. Second thread connects to it.
178
+ # 3. Current thread releases it.
179
+ # 4. Second thread releases it, hence destroying it.
180
+ init_commands = [
181
+ ['which env', proc { [0, "/usr/bin/env\n", ''] }],
182
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }],
183
+ ]
184
+ nodes_connections_to_mock = { 'node' => { connection: '192.168.42.42', user: 'test_user' } }
185
+ step = 0
186
+ second_thread = Thread.new do
187
+ # Use a different environment: CmdRunner, NodesHandler, ActionsExecutor
188
+ second_cmd_runner = HybridPlatformsConductor::CmdRunner.new logger: logger, logger_stderr: logger
189
+ with_cmd_runner_mocked(
190
+ init_commands +
191
+ ssh_expected_commands_for(
192
+ nodes_connections_to_mock,
193
+ with_control_master_create: false,
194
+ with_control_master_check: true
195
+ ),
196
+ cmd_runner: second_cmd_runner
197
+ ) do
198
+ second_config = HybridPlatformsConductor::Config.new logger: logger, logger_stderr: logger
199
+ second_platforms_handler = HybridPlatformsConductor::PlatformsHandler.new logger: logger, logger_stderr: logger, config: second_config, cmd_runner: second_cmd_runner
200
+ second_nodes_handler = HybridPlatformsConductor::NodesHandler.new logger: logger, logger_stderr: logger, config: second_config, cmd_runner: second_cmd_runner, platforms_handler: second_platforms_handler
201
+ second_actions_executor = HybridPlatformsConductor::ActionsExecutor.new logger: logger, logger_stderr: logger, config: second_config, cmd_runner: second_cmd_runner, nodes_handler: second_nodes_handler
202
+ second_actions_executor.connector(:ssh).ssh_user = 'test_user'
203
+ # Wait for the first thread to create ControlMaster
204
+ sleep 0.1 while step == 0
205
+ second_actions_executor.connector(:ssh).with_connection_to(['node']) do
206
+ step = 2
207
+ # Wait for the first thread to release the ControlMaster
208
+ sleep 0.1 while step == 2
209
+ end
210
+ end
211
+ end
212
+ with_cmd_runner_mocked(
213
+ init_commands +
214
+ ssh_expected_commands_for(nodes_connections_to_mock, with_control_master_destroy: false)
215
+ ) do
216
+ test_connector.ssh_user = 'test_user'
217
+ test_connector.with_connection_to(['node']) do
218
+ step = 1
219
+ # Now wait for the second thread to also acquire it
220
+ sleep 0.1 while step == 1
221
+ end
222
+ step = 3
223
+ end
224
+ second_thread.join
225
+ end
226
+ end
227
+
228
+ it 'does not create SSH master if asked' do
229
+ with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42' } } }) do
230
+ with_cmd_runner_mocked(
231
+ [
232
+ ['which env', proc { [0, "/usr/bin/env\n", ''] }],
233
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
234
+ ] + ssh_expected_commands_for(
235
+ { 'node' => { connection: '192.168.42.42', user: 'test_user' } },
236
+ with_control_master_create: false,
237
+ with_control_master_destroy: false
238
+ )
239
+ ) do
240
+ test_connector.ssh_use_control_master = false
241
+ test_connector.ssh_user = 'test_user'
242
+ test_connector.with_connection_to(['node']) do
243
+ end
244
+ end
245
+ end
246
+ end
247
+
248
+ it 'does not check host keys if asked' do
249
+ with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42' } } }) do
250
+ with_cmd_runner_mocked(
251
+ [
252
+ ['which env', proc { [0, "/usr/bin/env\n", ''] }],
253
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
254
+ ] + ssh_expected_commands_for(
255
+ { 'node' => { connection: '192.168.42.42', user: 'test_user' } },
256
+ with_strict_host_key_checking: false
257
+ )
258
+ ) do
259
+ test_connector.ssh_strict_host_key_checking = false
260
+ test_connector.ssh_user = 'test_user'
261
+ test_connector.with_connection_to(['node']) do
262
+ end
263
+ end
264
+ end
265
+ end
266
+
267
+ it 'does not use batch mode when passwords are to be expected' do
268
+ with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42' } } }) do
269
+ with_cmd_runner_mocked(
270
+ [
271
+ ['which env', proc { [0, "/usr/bin/env\n", ''] }],
272
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
273
+ ] + ssh_expected_commands_for(
274
+ { 'node' => { connection: '192.168.42.42', user: 'test_user' } },
275
+ with_batch_mode: false
276
+ )
277
+ ) do
278
+ test_connector.auth_password = true
279
+ test_connector.ssh_user = 'test_user'
280
+ test_connector.with_connection_to(['node']) do
281
+ end
282
+ end
283
+ end
284
+ end
285
+
286
+ it 'uses sshpass to prepare connections needing passwords' do
287
+ with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42' } } }) do
288
+ with_cmd_runner_mocked(
289
+ [
290
+ ['sshpass -V', proc { [0, "sshpass 1.06\n", ''] }],
291
+ ['which env', proc { [0, "/usr/bin/env\n", ''] }],
292
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
293
+ ] + ssh_expected_commands_for(
294
+ { 'node' => { connection: '192.168.42.42', user: 'test_user' } },
295
+ with_batch_mode: false
296
+ )
297
+ ) do
298
+ test_connector.passwords['node'] = 'PaSsWoRd'
299
+ test_connector.ssh_user = 'test_user'
300
+ test_connector.with_connection_to(['node']) do
301
+ end
302
+ end
303
+ end
304
+ end
305
+
306
+ it 'does not reuse provided SSH executables and configs' do
307
+ with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42' } } }) do
308
+ with_cmd_runner_mocked(
309
+ [
310
+ ['which env', proc { [0, "/usr/bin/env\n", ''] }],
311
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
312
+ ] +
313
+ ssh_expected_commands_for('node' => { connection: '192.168.42.42', user: 'test_user' }) +
314
+ ssh_expected_commands_for(
315
+ { 'node' => { connection: '192.168.42.42', user: 'test_user' } },
316
+ with_strict_host_key_checking: false,
317
+ with_control_master_create: false,
318
+ with_control_master_check: true,
319
+ with_control_master_destroy: false
320
+ )
321
+ ) do
322
+ test_connector.ssh_user = 'test_user'
323
+ test_connector.with_connection_to(['node']) do
324
+ stdout = ''
325
+ stderr = ''
326
+ test_connector.prepare_for('node', nil, stdout, stderr)
327
+ first_ssh_exec = test_connector.ssh_exec
328
+ test_connector.with_connection_to(['node']) do
329
+ test_connector.prepare_for('node', nil, stdout, stderr)
330
+ expect(test_connector.ssh_exec).not_to eq first_ssh_exec
331
+ end
332
+ end
333
+ end
334
+ end
335
+ end
336
+
337
+ it 'cleans provided SSH executables and configs after use' do
338
+ with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42' } } }) do
339
+ with_cmd_runner_mocked(
340
+ [
341
+ ['which env', proc { [0, "/usr/bin/env\n", ''] }],
342
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
343
+ ] +
344
+ ssh_expected_commands_for('node' => { connection: '192.168.42.42', user: 'test_user' }) +
345
+ ssh_expected_commands_for(
346
+ { 'node' => { connection: '192.168.42.42', user: 'test_user' } },
347
+ with_strict_host_key_checking: false,
348
+ with_control_master_create: false,
349
+ with_control_master_check: true,
350
+ with_control_master_destroy: false
351
+ )
352
+ ) do
353
+ ssh_exec_1 = nil
354
+ ssh_exec_2 = nil
355
+ test_connector.ssh_user = 'test_user'
356
+ test_connector.with_connection_to(['node']) do
357
+ stdout = ''
358
+ stderr = ''
359
+ test_connector.prepare_for('node', nil, stdout, stderr)
360
+ ssh_exec_1 = test_connector.ssh_exec
361
+ test_connector.with_connection_to(['node']) do
362
+ test_connector.prepare_for('node', nil, stdout, stderr)
363
+ ssh_exec_2 = test_connector.ssh_exec
364
+ expect(File.exist?(ssh_exec_1)).to eq true
365
+ expect(File.exist?(ssh_exec_2)).to eq true
366
+ end
367
+ expect(File.exist?(ssh_exec_1)).to eq true
368
+ expect(File.exist?(ssh_exec_2)).to eq false
369
+ end
370
+ expect(File.exist?(ssh_exec_1)).to eq false
371
+ expect(File.exist?(ssh_exec_2)).to eq false
372
+ end
373
+ end
374
+ end
375
+
376
+ it 'creates an SSH master to 1 node even when there is a stalled ControlMaster file' do
377
+ with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42' } } }) do
378
+ with_cmd_runner_mocked(
379
+ [
380
+ ['which env', proc { [0, "/usr/bin/env\n", ''] }],
381
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
382
+ ] + ssh_expected_commands_for('node' => { connection: '192.168.42.42', user: 'test_user' })
383
+ ) do
384
+ test_connector.ssh_user = 'test_user'
385
+ # Fake a ControlMaster file that is stalled
386
+ File.write(test_actions_executor.connector(:ssh).send(:control_master_file, '192.168.42.42', '22', 'test_user'), '')
387
+ test_connector.with_connection_to(['node']) do
388
+ end
389
+ end
390
+ end
391
+ end
392
+
393
+ it 'creates an SSH master to 1 node even when there is a left-over user for the ControlMaster file that has not been unregistered' do
394
+ with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42' } } }) do
395
+ with_cmd_runner_mocked(
396
+ [
397
+ ['which env', proc { [0, "/usr/bin/env\n", ''] }],
398
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
399
+ ] + ssh_expected_commands_for('node' => { connection: '192.168.42.42', user: 'test_user' })
400
+ ) do
401
+ test_connector.ssh_user = 'test_user'
402
+ # Fake a user that was not cleaned correctly
403
+ File.write('/tmp/hpc_ssh/test_user.node.users', "unregistered_user\n")
404
+ test_connector.with_connection_to(['node']) do
405
+ end
406
+ end
407
+ end
408
+ end
409
+
410
+ it 'retries when the remote node is booting up' do
411
+ with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42' } } }) do
412
+ nbr_boot_messages = 0
413
+ with_cmd_runner_mocked(
414
+ [
415
+ ['which env', proc { [0, "/usr/bin/env\n", ''] }],
416
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }],
417
+ ] +
418
+ [[
419
+ /^.+\/ssh -o BatchMode=yes -o ControlMaster=yes -o ControlPersist=yes test_user@hpc\.node true$/,
420
+ proc do
421
+ nbr_boot_messages += 1
422
+ [255, '', "System is booting up. See pam_nologin(8)\nAuthentication failed.\n"]
423
+ end
424
+ ]] * 3 +
425
+ ssh_expected_commands_for('node' => { connection: '192.168.42.42', user: 'test_user' })
426
+ ) do
427
+ test_connector.ssh_user = 'test_user'
428
+ # To speed up the test, alter the wait time between retries.
429
+ old_wait = HybridPlatformsConductor::HpcPlugins::Connector::Ssh.const_get(:WAIT_TIME_FOR_BOOT)
430
+ begin
431
+ HybridPlatformsConductor::HpcPlugins::Connector::Ssh.send(:remove_const, :WAIT_TIME_FOR_BOOT)
432
+ HybridPlatformsConductor::HpcPlugins::Connector::Ssh.const_set(:WAIT_TIME_FOR_BOOT, 1)
433
+ test_connector.with_connection_to(['node']) do
434
+ end
435
+ expect(nbr_boot_messages).to eq 3
436
+ ensure
437
+ HybridPlatformsConductor::HpcPlugins::Connector::Ssh.send(:remove_const, :WAIT_TIME_FOR_BOOT)
438
+ HybridPlatformsConductor::HpcPlugins::Connector::Ssh.const_set(:WAIT_TIME_FOR_BOOT, old_wait)
439
+ end
440
+ end
441
+ end
442
+ end
443
+
444
+ end
445
+
446
+ end
447
+
448
+ end