hybrid_platforms_conductor 32.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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