hybrid_platforms_conductor 32.17.0 → 33.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +36 -0
  3. data/README.md +6 -3
  4. data/bin/check-node +0 -1
  5. data/bin/deploy +0 -1
  6. data/bin/get_impacted_nodes +0 -1
  7. data/bin/last_deploys +12 -8
  8. data/bin/nodes_to_deploy +6 -6
  9. data/bin/setup +6 -6
  10. data/bin/topograph +1 -1
  11. data/docs/config_dsl.md +45 -1
  12. data/docs/executables.md +6 -7
  13. data/docs/executables/check-node.md +3 -3
  14. data/docs/executables/deploy.md +3 -3
  15. data/docs/executables/dump_nodes_json.md +3 -3
  16. data/docs/executables/test.md +3 -3
  17. data/docs/executables/topograph.md +3 -3
  18. data/docs/gen/mermaid/README.md-0.png +0 -0
  19. data/docs/gen/mermaid/docs/executables/check-node.md-0.png +0 -0
  20. data/docs/gen/mermaid/docs/executables/deploy.md-0.png +0 -0
  21. data/docs/gen/mermaid/docs/executables/free_ips.md-0.png +0 -0
  22. data/docs/gen/mermaid/docs/executables/get_impacted_nodes.md-0.png +0 -0
  23. data/docs/gen/mermaid/docs/executables/last_deploys.md-0.png +0 -0
  24. data/docs/gen/mermaid/docs/executables/nodes_to_deploy.md-0.png +0 -0
  25. data/docs/gen/mermaid/docs/executables/report.md-0.png +0 -0
  26. data/docs/gen/mermaid/docs/executables/run.md-0.png +0 -0
  27. data/docs/gen/mermaid/docs/executables/ssh_config.md-0.png +0 -0
  28. data/docs/gen/mermaid/docs/executables/test.md-0.png +0 -0
  29. data/docs/plugins.md +46 -0
  30. data/docs/plugins/connector/ssh.md +1 -1
  31. data/docs/plugins/log/remote_fs.md +26 -0
  32. data/docs/plugins/secrets_reader/cli.md +31 -0
  33. data/docs/plugins/secrets_reader/thycotic.md +46 -0
  34. data/docs/plugins/test/check_deploy_and_idempotence.md +1 -1
  35. data/docs/plugins/test/connection.md +1 -0
  36. data/docs/plugins/test/deploy_removes_root_access.md +1 -1
  37. data/docs/plugins/test/file_system.md +1 -0
  38. data/docs/plugins/test/hostname.md +1 -0
  39. data/docs/plugins/test/ip.md +1 -0
  40. data/docs/plugins/test/local_users.md +1 -0
  41. data/docs/plugins/test/mounts.md +1 -0
  42. data/docs/plugins/test/orphan_files.md +1 -0
  43. data/docs/plugins/test/ports.md +1 -0
  44. data/docs/plugins/test/spectre.md +1 -0
  45. data/docs/plugins/test/vulnerabilities.md +1 -0
  46. data/lib/hybrid_platforms_conductor/action.rb +4 -4
  47. data/lib/hybrid_platforms_conductor/actions_executor.rb +45 -43
  48. data/lib/hybrid_platforms_conductor/bitbucket.rb +5 -4
  49. data/lib/hybrid_platforms_conductor/cmd_runner.rb +13 -12
  50. data/lib/hybrid_platforms_conductor/cmdb.rb +2 -2
  51. data/lib/hybrid_platforms_conductor/common_config_dsl/bitbucket.rb +2 -1
  52. data/lib/hybrid_platforms_conductor/common_config_dsl/confluence.rb +2 -1
  53. data/lib/hybrid_platforms_conductor/common_config_dsl/file_system_tests.rb +5 -4
  54. data/lib/hybrid_platforms_conductor/common_config_dsl/github.rb +4 -3
  55. data/lib/hybrid_platforms_conductor/common_config_dsl/idempotence_tests.rb +2 -2
  56. data/lib/hybrid_platforms_conductor/config.rb +8 -4
  57. data/lib/hybrid_platforms_conductor/confluence.rb +1 -1
  58. data/lib/hybrid_platforms_conductor/connector.rb +5 -2
  59. data/lib/hybrid_platforms_conductor/core_extensions/cleanroom/fix_kwargs.rb +116 -0
  60. data/lib/hybrid_platforms_conductor/core_extensions/symbol/zero.rb +24 -0
  61. data/lib/hybrid_platforms_conductor/credentials.rb +39 -36
  62. data/lib/hybrid_platforms_conductor/current_dir_monitor.rb +4 -1
  63. data/lib/hybrid_platforms_conductor/deployer.rb +275 -224
  64. data/lib/hybrid_platforms_conductor/executable.rb +20 -15
  65. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/config.rb +10 -7
  66. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/host_ip.rb +1 -1
  67. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/host_keys.rb +2 -2
  68. data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/platform_handlers.rb +4 -4
  69. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/local.rb +2 -0
  70. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +45 -49
  71. data/lib/hybrid_platforms_conductor/hpc_plugins/log/my_log_plugin.rb.sample +100 -0
  72. data/lib/hybrid_platforms_conductor/hpc_plugins/log/remote_fs.rb +180 -0
  73. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef.rb +68 -66
  74. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/dsl_parser.rb +13 -0
  75. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/recipes_tree_builder.rb +39 -38
  76. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/yaml_inventory.rb +5 -4
  77. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/docker.rb +43 -45
  78. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/podman.rb +18 -20
  79. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox.rb +118 -117
  80. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox/proxmox_waiter.rb +39 -43
  81. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox/reserve_proxmox_container +9 -13
  82. data/lib/hybrid_platforms_conductor/hpc_plugins/report/confluence.rb +2 -2
  83. data/lib/hybrid_platforms_conductor/hpc_plugins/report/mediawiki.rb +28 -21
  84. data/lib/hybrid_platforms_conductor/hpc_plugins/report/stdout.rb +26 -22
  85. data/lib/hybrid_platforms_conductor/hpc_plugins/secrets_reader/cli.rb +77 -0
  86. data/lib/hybrid_platforms_conductor/hpc_plugins/secrets_reader/my_secrets_reader_plugin.rb.sample +46 -0
  87. data/lib/hybrid_platforms_conductor/hpc_plugins/secrets_reader/thycotic.rb +90 -0
  88. data/lib/hybrid_platforms_conductor/hpc_plugins/test/bitbucket_conf.rb +3 -3
  89. data/lib/hybrid_platforms_conductor/hpc_plugins/test/check_deploy_and_idempotence.rb +4 -2
  90. data/lib/hybrid_platforms_conductor/hpc_plugins/test/connection.rb +3 -1
  91. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_freshness.rb +7 -21
  92. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +21 -19
  93. data/lib/hybrid_platforms_conductor/hpc_plugins/test/divergence.rb +2 -2
  94. data/lib/hybrid_platforms_conductor/hpc_plugins/test/executables.rb +2 -2
  95. data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system.rb +21 -22
  96. data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system_hdfs.rb +19 -21
  97. data/lib/hybrid_platforms_conductor/hpc_plugins/test/github_ci.rb +2 -3
  98. data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +3 -1
  99. data/lib/hybrid_platforms_conductor/hpc_plugins/test/idempotence.rb +2 -2
  100. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +4 -2
  101. data/lib/hybrid_platforms_conductor/hpc_plugins/test/jenkins_ci_conf.rb +21 -22
  102. data/lib/hybrid_platforms_conductor/hpc_plugins/test/jenkins_ci_masters_ok.rb +10 -12
  103. data/lib/hybrid_platforms_conductor/hpc_plugins/test/linear_strategy.rb +9 -9
  104. data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +5 -3
  105. data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +5 -3
  106. data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +13 -10
  107. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ports.rb +5 -3
  108. data/lib/hybrid_platforms_conductor/hpc_plugins/test/private_ips.rb +5 -5
  109. data/lib/hybrid_platforms_conductor/hpc_plugins/test/public_ips.rb +5 -5
  110. data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +7 -7
  111. data/lib/hybrid_platforms_conductor/hpc_plugins/test/veids.rb +3 -3
  112. data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +27 -25
  113. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/confluence.rb +2 -2
  114. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/stdout.rb +8 -6
  115. data/lib/hybrid_platforms_conductor/io_router.rb +14 -13
  116. data/lib/hybrid_platforms_conductor/json_dumper.rb +2 -2
  117. data/lib/hybrid_platforms_conductor/log.rb +31 -0
  118. data/lib/hybrid_platforms_conductor/logger_helpers.rb +19 -16
  119. data/lib/hybrid_platforms_conductor/nodes_handler.rb +89 -71
  120. data/lib/hybrid_platforms_conductor/parallel_threads.rb +7 -11
  121. data/lib/hybrid_platforms_conductor/platform_handler.rb +7 -7
  122. data/lib/hybrid_platforms_conductor/platforms_handler.rb +5 -3
  123. data/lib/hybrid_platforms_conductor/plugin.rb +2 -2
  124. data/lib/hybrid_platforms_conductor/plugins.rb +14 -8
  125. data/lib/hybrid_platforms_conductor/provisioner.rb +4 -4
  126. data/lib/hybrid_platforms_conductor/report.rb +2 -2
  127. data/lib/hybrid_platforms_conductor/reports_handler.rb +3 -2
  128. data/lib/hybrid_platforms_conductor/secrets_reader.rb +31 -0
  129. data/lib/hybrid_platforms_conductor/services_handler.rb +32 -29
  130. data/lib/hybrid_platforms_conductor/test_only_remote_node.rb +18 -0
  131. data/lib/hybrid_platforms_conductor/test_report.rb +15 -18
  132. data/lib/hybrid_platforms_conductor/tests_runner.rb +116 -118
  133. data/lib/hybrid_platforms_conductor/thycotic.rb +28 -19
  134. data/lib/hybrid_platforms_conductor/topographer.rb +200 -190
  135. data/lib/hybrid_platforms_conductor/topographer/plugins/graphviz.rb +8 -8
  136. data/lib/hybrid_platforms_conductor/topographer/plugins/json.rb +4 -4
  137. data/lib/hybrid_platforms_conductor/version.rb +1 -1
  138. data/spec/hybrid_platforms_conductor_test.rb +33 -12
  139. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/bash_spec.rb +18 -11
  140. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/interactive_spec.rb +2 -2
  141. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/remote_bash_spec.rb +32 -21
  142. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/ruby_spec.rb +75 -49
  143. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/scp_spec.rb +27 -15
  144. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions_spec.rb +90 -59
  145. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connection_spec.rb +46 -44
  146. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/connectable_nodes_spec.rb +12 -8
  147. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/remote_actions_spec.rb +4 -7
  148. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/cli_options_spec.rb +21 -22
  149. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/config_dsl_spec.rb +23 -24
  150. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connectable_nodes_spec.rb +10 -6
  151. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connections_spec.rb +106 -75
  152. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/global_helpers_spec.rb +145 -126
  153. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/node_helpers_spec.rb +3 -3
  154. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb +29 -25
  155. data/spec/hybrid_platforms_conductor_test/api/actions_executor/logging_spec.rb +167 -142
  156. data/spec/hybrid_platforms_conductor_test/api/actions_executor/parallel_spec.rb +272 -244
  157. data/spec/hybrid_platforms_conductor_test/api/actions_executor/timeout_spec.rb +16 -16
  158. data/spec/hybrid_platforms_conductor_test/api/cmd_runner_spec.rb +36 -36
  159. data/spec/hybrid_platforms_conductor_test/api/config_spec.rb +24 -22
  160. data/spec/hybrid_platforms_conductor_test/api/deployer/check_spec.rb +4 -2
  161. data/spec/hybrid_platforms_conductor_test/api/deployer/config_dsl_spec.rb +43 -5
  162. data/spec/hybrid_platforms_conductor_test/api/deployer/deploy_spec.rb +199 -216
  163. data/spec/hybrid_platforms_conductor_test/api/deployer/log_plugins/remote_fs_spec.rb +223 -0
  164. data/spec/hybrid_platforms_conductor_test/api/deployer/parse_deploy_output_spec.rb +55 -59
  165. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioner_spec.rb +36 -62
  166. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/podman_spec.rb +17 -17
  167. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/config_dsl_spec.rb +4 -4
  168. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/create_spec.rb +44 -51
  169. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/destroy_spec.rb +3 -3
  170. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/ip_spec.rb +12 -16
  171. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/destroy_vm_spec.rb +31 -19
  172. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/expired_containers_spec.rb +324 -266
  173. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/ips_assignment_spec.rb +89 -61
  174. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/other_lxc_containers_resources_spec.rb +117 -93
  175. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/pve_node_resources_spec.rb +71 -54
  176. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/retries_spec.rb +10 -8
  177. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/vm_ids_assignment_spec.rb +80 -60
  178. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/start_spec.rb +1 -1
  179. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/state_spec.rb +1 -1
  180. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/stop_spec.rb +1 -1
  181. data/spec/hybrid_platforms_conductor_test/api/deployer/secrets_reader_plugins/cli_spec.rb +64 -0
  182. data/spec/hybrid_platforms_conductor_test/api/deployer/secrets_reader_plugins/thycotic_spec.rb +268 -0
  183. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/config_spec.rb +8 -10
  184. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/host_ip_spec.rb +33 -24
  185. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/host_keys_spec.rb +64 -51
  186. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/platform_handlers_spec.rb +3 -3
  187. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs_plugins_api_spec.rb +50 -51
  188. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/common_spec.rb +91 -81
  189. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/config_dsl_spec.rb +14 -16
  190. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/git_diff_impacts_spec.rb +51 -75
  191. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/nodes_selectors_spec.rb +35 -26
  192. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/platform_handlers_plugins_api_spec.rb +24 -16
  193. data/spec/hybrid_platforms_conductor_test/api/nodes_handler/several_platforms_spec.rb +29 -19
  194. data/spec/hybrid_platforms_conductor_test/api/platform_handler_spec.rb +4 -4
  195. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/config_dsl_spec.rb +2 -2
  196. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/deploy_output_parsing_spec.rb +6 -6
  197. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/diff_impacts_spec.rb +57 -99
  198. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/inventory_spec.rb +4 -4
  199. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/packaging_spec.rb +32 -35
  200. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/services_deployment_spec.rb +10 -10
  201. data/spec/hybrid_platforms_conductor_test/api/platforms_handler_spec.rb +38 -27
  202. data/spec/hybrid_platforms_conductor_test/api/plugins_spec.rb +46 -52
  203. data/spec/hybrid_platforms_conductor_test/api/reports_handler_spec.rb +2 -2
  204. data/spec/hybrid_platforms_conductor_test/api/services_handler/actions_to_deploy_spec.rb +90 -58
  205. data/spec/hybrid_platforms_conductor_test/api/services_handler/deploy_allowed_spec.rb +38 -34
  206. data/spec/hybrid_platforms_conductor_test/api/services_handler/log_info_spec.rb +11 -9
  207. data/spec/hybrid_platforms_conductor_test/api/services_handler/package_spec.rb +193 -171
  208. data/spec/hybrid_platforms_conductor_test/api/services_handler/parse_deploy_output_spec.rb +66 -54
  209. data/spec/hybrid_platforms_conductor_test/api/services_handler/prepare_for_deploy_spec.rb +147 -133
  210. data/spec/hybrid_platforms_conductor_test/api/tests_runner/common_spec.rb +69 -49
  211. data/spec/hybrid_platforms_conductor_test/api/tests_runner/global_spec.rb +5 -4
  212. data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_check_spec.rb +8 -5
  213. data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_spec.rb +8 -5
  214. data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_ssh_spec.rb +30 -27
  215. data/spec/hybrid_platforms_conductor_test/api/tests_runner/platform_spec.rb +12 -9
  216. data/spec/hybrid_platforms_conductor_test/api/tests_runner/reports_spec.rb +48 -47
  217. data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/bitbucket_conf_spec.rb +5 -5
  218. data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/github_ci_spec.rb +5 -5
  219. data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_reports_plugins/confluence_spec.rb +5 -5
  220. data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb.rb +9 -9
  221. data/spec/hybrid_platforms_conductor_test/cmdb_plugins/{test_cmdb2.rb → test_cmdb_2.rb} +6 -6
  222. data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb_others.rb +3 -3
  223. data/spec/hybrid_platforms_conductor_test/cmdb_plugins/{test_cmdb_others2.rb → test_cmdb_others_2.rb} +2 -2
  224. data/spec/hybrid_platforms_conductor_test/docs_spec.rb +1 -1
  225. data/spec/hybrid_platforms_conductor_test/executables/{check-node_spec.rb → check_node_spec.rb} +4 -6
  226. data/spec/hybrid_platforms_conductor_test/executables/deploy_spec.rb +4 -6
  227. data/spec/hybrid_platforms_conductor_test/executables/get_impacted_nodes_spec.rb +76 -77
  228. data/spec/hybrid_platforms_conductor_test/executables/last_deploys_spec.rb +159 -113
  229. data/spec/hybrid_platforms_conductor_test/executables/nodes_to_deploy_spec.rb +299 -160
  230. data/spec/hybrid_platforms_conductor_test/executables/options/actions_executor_spec.rb +4 -6
  231. data/spec/hybrid_platforms_conductor_test/executables/options/cmd_runner_spec.rb +3 -5
  232. data/spec/hybrid_platforms_conductor_test/executables/options/common_spec.rb +8 -8
  233. data/spec/hybrid_platforms_conductor_test/executables/options/deployer_spec.rb +12 -196
  234. data/spec/hybrid_platforms_conductor_test/executables/options/nodes_handler_spec.rb +9 -10
  235. data/spec/hybrid_platforms_conductor_test/executables/options/nodes_selectors_spec.rb +9 -10
  236. data/spec/hybrid_platforms_conductor_test/executables/options/reports_handler_spec.rb +1 -1
  237. data/spec/hybrid_platforms_conductor_test/executables/options/tests_runner_spec.rb +22 -22
  238. data/spec/hybrid_platforms_conductor_test/executables/report_spec.rb +22 -16
  239. data/spec/hybrid_platforms_conductor_test/executables/run_spec.rb +32 -32
  240. data/spec/hybrid_platforms_conductor_test/executables/ssh_config_spec.rb +7 -9
  241. data/spec/hybrid_platforms_conductor_test/executables/test_spec.rb +3 -5
  242. data/spec/hybrid_platforms_conductor_test/helpers/actions_executor_helpers.rb +2 -2
  243. data/spec/hybrid_platforms_conductor_test/helpers/cmd_runner_helpers.rb +4 -3
  244. data/spec/hybrid_platforms_conductor_test/helpers/cmdb_helpers.rb +2 -2
  245. data/spec/hybrid_platforms_conductor_test/helpers/config_helpers.rb +1 -1
  246. data/spec/hybrid_platforms_conductor_test/helpers/connector_ssh_helpers.rb +12 -13
  247. data/spec/hybrid_platforms_conductor_test/helpers/deployer_helpers.rb +245 -56
  248. data/spec/hybrid_platforms_conductor_test/helpers/executables_helpers.rb +11 -11
  249. data/spec/hybrid_platforms_conductor_test/helpers/nodes_handler_helpers.rb +1 -1
  250. data/spec/hybrid_platforms_conductor_test/helpers/platforms_handler_helpers.rb +39 -28
  251. data/spec/hybrid_platforms_conductor_test/helpers/plugins_helpers.rb +1 -1
  252. data/spec/hybrid_platforms_conductor_test/helpers/provisioner_proxmox_helpers.rb +86 -111
  253. data/spec/hybrid_platforms_conductor_test/helpers/reports_handler_helpers.rb +1 -1
  254. data/spec/hybrid_platforms_conductor_test/helpers/serverless_chef_helpers.rb +3 -3
  255. data/spec/hybrid_platforms_conductor_test/helpers/services_handler_helpers.rb +1 -1
  256. data/spec/hybrid_platforms_conductor_test/helpers/tests_runner_helpers.rb +1 -1
  257. data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem/hpc_plugins/test_plugin_type/{test_plugin_id1.rb → test_plugin_id_1.rb} +0 -0
  258. data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem/hpc_plugins/test_plugin_type/{test_plugin_id2.rb → test_plugin_id_2.rb} +0 -0
  259. data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem2/sub_dir/hpc_plugins/test_plugin_type/{test_plugin_id3.rb → test_plugin_id_3.rb} +0 -0
  260. data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem2/sub_dir/hpc_plugins/{test_plugin_type2/test_plugin_id4.rb → test_plugin_type_2/test_plugin_id_4.rb} +0 -0
  261. data/spec/hybrid_platforms_conductor_test/platform_handler_plugins/test.rb +1 -1
  262. data/spec/hybrid_platforms_conductor_test/platform_handler_plugins/{test2.rb → test_2.rb} +0 -0
  263. data/spec/hybrid_platforms_conductor_test/rubocop_spec.rb +31 -0
  264. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/nodes/node.json +3 -3
  265. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/nodes/node.json +3 -3
  266. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/libraries/default.rb +1 -0
  267. data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/other_cookbooks/test_cookbook_2/libraries/default.rb +1 -0
  268. data/spec/hybrid_platforms_conductor_test/shared_examples/deployer.rb +952 -0
  269. data/spec/hybrid_platforms_conductor_test/test_connector.rb +3 -3
  270. data/spec/hybrid_platforms_conductor_test/test_log_no_read_plugin.rb +84 -0
  271. data/spec/hybrid_platforms_conductor_test/test_log_plugin.rb +105 -0
  272. data/spec/hybrid_platforms_conductor_test/test_plugins/global.rb +1 -0
  273. data/spec/hybrid_platforms_conductor_test/test_plugins/node.rb +1 -0
  274. data/spec/hybrid_platforms_conductor_test/test_plugins/node_check.rb +1 -0
  275. data/spec/hybrid_platforms_conductor_test/test_plugins/platform.rb +1 -0
  276. data/spec/hybrid_platforms_conductor_test/test_plugins/several_checks.rb +2 -2
  277. data/spec/hybrid_platforms_conductor_test/test_secrets_reader_plugin.rb +45 -0
  278. data/spec/hybrid_platforms_conductor_test/tests_report_plugin.rb +5 -6
  279. data/spec/spec_helper.rb +17 -18
  280. data/tools/check_md +16 -20
  281. data/tools/generate_mermaid +1 -1
  282. metadata +195 -144
  283. data/spec/hybrid_platforms_conductor_test/helpers/deployer_test_helpers.rb +0 -916
@@ -21,7 +21,7 @@ module HybridPlatformsConductor
21
21
  # * *thycotic* (Thyctotic): The Thyctotic instance to use.
22
22
  def self.with_thycotic(thycotic_url, logger, logger_stderr, domain: ENV['hpc_domain_for_thycotic'])
23
23
  Credentials.with_credentials_for(:thycotic, logger, logger_stderr, url: thycotic_url) do |thycotic_user, thycotic_password|
24
- yield Thycotic.new(thycotic_url, thycotic_user, thycotic_password, logger: logger, logger_stderr: logger_stderr)
24
+ yield Thycotic.new(thycotic_url, thycotic_user, thycotic_password, domain: domain, logger: logger, logger_stderr: logger_stderr)
25
25
  end
26
26
  end
27
27
 
@@ -39,8 +39,8 @@ module HybridPlatformsConductor
39
39
  user,
40
40
  password,
41
41
  domain: ENV['hpc_domain_for_thycotic'],
42
- logger: Logger.new(STDOUT),
43
- logger_stderr: Logger.new(STDERR)
42
+ logger: Logger.new($stdout),
43
+ logger_stderr: Logger.new($stderr)
44
44
  )
45
45
  init_loggers(logger, logger_stderr)
46
46
  # Get a token to this SOAP API
@@ -50,11 +50,14 @@ module HybridPlatformsConductor
50
50
  logger: @logger,
51
51
  log: log_debug?
52
52
  )
53
- @token = @client.call(:authenticate, message: {
54
- username: user,
55
- password: password,
56
- domain: domain
57
- }).to_hash.dig(:authenticate_response, :authenticate_result, :token)
53
+ @token = @client.call(
54
+ :authenticate,
55
+ message: {
56
+ username: user,
57
+ password: password,
58
+ domain: domain
59
+ }
60
+ ).to_hash.dig(:authenticate_response, :authenticate_result, :token)
58
61
  raise "Unable to get token from SOAP authentication to #{url}" if @token.nil?
59
62
  end
60
63
 
@@ -65,13 +68,16 @@ module HybridPlatformsConductor
65
68
  # Result::
66
69
  # * Hash: The corresponding API result
67
70
  def get_secret(secret_id)
68
- @client.call(:get_secret, message: {
69
- token: @token,
70
- secretId: secret_id
71
- }).to_hash.dig(:get_secret_response, :get_secret_result)
71
+ @client.call(
72
+ :get_secret,
73
+ message: {
74
+ token: @token,
75
+ secretId: secret_id
76
+ }
77
+ ).to_hash.dig(:get_secret_response, :get_secret_result)
72
78
  end
73
79
 
74
- # Get a file attached to a given secret
80
+ # Get a file attached to a given secret
75
81
  #
76
82
  # Parameters::
77
83
  # * *secret_id* (Object): The secret ID
@@ -79,12 +85,15 @@ module HybridPlatformsConductor
79
85
  # Result::
80
86
  # * String or nil: The file content, or nil if none
81
87
  def download_file_attachment_by_item_id(secret_id, secret_item_id)
82
- file_in_base64 = @client.call(:download_file_attachment_by_item_id, message: {
83
- token: @token,
84
- secretId: secret_id,
85
- secretItemId: secret_item_id
86
- }).to_hash.dig(:download_file_attachment_by_item_id_response, :download_file_attachment_by_item_id_result, :file_attachment)
87
- file_in_base64.nil? ? nil : Base64.decode64(file_in_base64)
88
+ encoded_file = @client.call(
89
+ :download_file_attachment_by_item_id,
90
+ message: {
91
+ token: @token,
92
+ secretId: secret_id,
93
+ secretItemId: secret_item_id
94
+ }
95
+ ).to_hash.dig(:download_file_attachment_by_item_id_response, :download_file_attachment_by_item_id_result, :file_attachment)
96
+ encoded_file.nil? ? nil : Base64.decode64(encoded_file)
88
97
  end
89
98
 
90
99
  end
@@ -78,7 +78,7 @@ module HybridPlatformsConductor
78
78
  # * *config* (Hash<Symbol,Object>): Some configuration parameters that can override defaults. [default = {}] Here are the possible keys:
79
79
  # * *json_files_dir* (String): Directory from which JSON files are taken. [default = nodes_json]
80
80
  # * *connections_max_level* (Integer or nil): Number maximal of recursive passes to get hostname connections (nil means no limit). [default = nil]
81
- def initialize(logger: Logger.new(STDOUT), logger_stderr: Logger.new(STDERR), nodes_handler: NodesHandler.new, json_dumper: JsonDumper.new, config: {})
81
+ def initialize(logger: Logger.new($stdout), logger_stderr: Logger.new($stderr), nodes_handler: NodesHandler.new, json_dumper: JsonDumper.new, config: {})
82
82
  init_loggers(logger, logger_stderr)
83
83
  @nodes_handler = nodes_handler
84
84
  @json_dumper = json_dumper
@@ -110,8 +110,8 @@ module HybridPlatformsConductor
110
110
  @skip_run = false
111
111
 
112
112
  # Parse plugins
113
- @plugins = Hash[Dir.
114
- glob("#{File.dirname(__FILE__)}/topographer/plugins/*.rb").
113
+ @plugins = Dir.
114
+ glob("#{__dir__}/topographer/plugins/*.rb").
115
115
  map do |file_name|
116
116
  plugin_name = File.basename(file_name)[0..-4].to_sym
117
117
  require file_name
@@ -119,7 +119,8 @@ module HybridPlatformsConductor
119
119
  plugin_name,
120
120
  Topographer::Plugins.const_get(plugin_name.to_s.split('_').collect(&:capitalize).join.to_sym)
121
121
  ]
122
- end]
122
+ end.
123
+ to_h
123
124
 
124
125
  @ips_to_host = known_ips.clone
125
126
 
@@ -131,14 +132,14 @@ module HybridPlatformsConductor
131
132
  ]
132
133
  @nodes_handler.prefetch_metadata_of @nodes_handler.known_nodes, metadata_properties
133
134
  @nodes_handler.known_nodes.each do |hostname|
134
- @node_metadata[hostname] = Hash[metadata_properties.map { |property| [property, @nodes_handler.metadata_of(hostname, property)] }]
135
+ @node_metadata[hostname] = metadata_properties.map { |property| [property, @nodes_handler.metadata_of(hostname, property)] }.to_h
135
136
  end
136
137
 
137
138
  # Small cache of hostnames used a lot to parse JSON
138
- @known_nodes = Hash[@nodes_handler.known_nodes.map { |hostname| [hostname, nil] }]
139
+ @known_nodes = @nodes_handler.known_nodes.map { |hostname| [hostname, nil] }.to_h
139
140
  # Cache of objects being used a lot in parsing for performance
140
141
  @non_word_regexp = /\W+/
141
- @ip_regexp = /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(\/(\d{1,2})|[^\d\/]|$)/
142
+ @ip_regexp = %r{(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(/(\d{1,2})|[^\d/]|$)}
142
143
  # Cache of ignored IPs
143
144
  @ips_ignored = {}
144
145
  end
@@ -156,8 +157,8 @@ module HybridPlatformsConductor
156
157
  end
157
158
  options_parser.separator ''
158
159
  options_parser.separator 'Topographer options:'
159
- options_parser.on('-F', '--from HOSTS_OPTIONS', 'Specify options for the set of nodes to start from (enclose them with ""). Default: all nodes. HOSTS_OPTIONS follows the following:', *from_hosts_opts_parser.to_s.split("\n")[3..-1]) do |hosts_options|
160
- args = hosts_options.split(' ')
160
+ options_parser.on('-F', '--from HOSTS_OPTIONS', 'Specify options for the set of nodes to start from (enclose them with ""). Default: all nodes. HOSTS_OPTIONS follows the following:', *from_hosts_opts_parser.to_s.split("\n")[3..]) do |hosts_options|
161
+ args = hosts_options.split
161
162
  from_hosts_opts_parser.parse!(args)
162
163
  raise "Unknown --from options: #{args.join(' ')}" unless args.empty?
163
164
  end
@@ -168,10 +169,11 @@ module HybridPlatformsConductor
168
169
  format_str, file_name = output.split(':')
169
170
  format = format_str.to_sym
170
171
  raise "Unknown format: #{format}." unless available_plugins.include?(format)
172
+
171
173
  @outputs << [format, file_name]
172
174
  end
173
- options_parser.on('-T', '--to HOSTS_OPTIONS', 'Specify options for the set of nodes to get to (enclose them with ""). Default: all nodes. HOSTS_OPTIONS follows the following:', *to_hosts_opts_parser.to_s.split("\n")[3..-1]) do |hosts_options|
174
- args = hosts_options.split(' ')
175
+ options_parser.on('-T', '--to HOSTS_OPTIONS', 'Specify options for the set of nodes to get to (enclose them with ""). Default: all nodes. HOSTS_OPTIONS follows the following:', *to_hosts_opts_parser.to_s.split("\n")[3..]) do |hosts_options|
176
+ args = hosts_options.split
175
177
  to_hosts_opts_parser.parse!(args)
176
178
  raise "Unknown --to options: #{args.join(' ')}" unless args.empty?
177
179
  end
@@ -197,12 +199,12 @@ module HybridPlatformsConductor
197
199
  end
198
200
 
199
201
  # Generate the JSON files to be used
200
- def get_json_files
201
- unless @skip_run
202
- @json_dumper.dump_dir = @config[:json_files_dir]
203
- # Generate all the jsons, even if 1 hostname is given, as it might be useful for the rest of the graph.
204
- @json_dumper.dump_json_for(@nodes_handler.known_nodes)
205
- end
202
+ def json_files
203
+ return if @skip_run
204
+
205
+ @json_dumper.dump_dir = @config[:json_files_dir]
206
+ # Generate all the jsons, even if 1 hostname is given, as it might be useful for the rest of the graph.
207
+ @json_dumper.dump_json_for(@nodes_handler.known_nodes)
206
208
  end
207
209
 
208
210
  # Dump the graph in the desired outputs
@@ -250,12 +252,14 @@ module HybridPlatformsConductor
250
252
  parse_connections_for(hostname, @config[:connections_max_level])
251
253
  end
252
254
  end
253
- @nodes_graph[nodes_list] = {
254
- type: :cluster,
255
- connections: {},
256
- includes: [],
257
- includes_proc: proc { |node_name| hosts_list.include?(node_name) }
258
- } unless @nodes_graph.key?(nodes_list)
255
+ unless @nodes_graph.key?(nodes_list)
256
+ @nodes_graph[nodes_list] = {
257
+ type: :cluster,
258
+ connections: {},
259
+ includes: [],
260
+ includes_proc: proc { |node_name| hosts_list.include?(node_name) }
261
+ }
262
+ end
259
263
  @nodes_graph[nodes_list][:includes].concat(hosts_list)
260
264
  @nodes_graph[nodes_list][:includes].uniq!
261
265
  end
@@ -273,7 +277,7 @@ module HybridPlatformsConductor
273
277
  # Then collapse this one
274
278
  collapsed_connections = {}
275
279
  included_nodes.each do |included_node_name|
276
- collapsed_connections.merge!(@nodes_graph[included_node_name][:connections]) { |_connected_node, labels1, labels2| (labels1 + labels2).uniq }
280
+ collapsed_connections.merge!(@nodes_graph[included_node_name][:connections]) { |_connected_node, labels_1, labels_2| (labels_1 + labels_2).uniq }
277
281
  end
278
282
  @nodes_graph[node_name_to_collapse][:connections] = collapsed_connections
279
283
  @nodes_graph[node_name_to_collapse][:includes] = []
@@ -293,18 +297,19 @@ module HybridPlatformsConductor
293
297
  loop do
294
298
  empty_clusters = @nodes_graph.keys.select { |node_name| @nodes_graph[node_name][:type] == :cluster && @nodes_graph[node_name][:includes].empty? }
295
299
  break if empty_clusters.empty?
300
+
296
301
  filter_out_nodes(empty_clusters)
297
302
  end
298
303
  end
299
304
 
300
305
  # Define clusters of ips with 24 bits ranges.
301
306
  def define_clusters_ip_24
302
- @nodes_graph.keys.each do |node_name|
303
- if @nodes_graph[node_name][:type] == :node && !@node_metadata[node_name][:private_ips].nil? && !@node_metadata[node_name][:private_ips].empty?
304
- ip_24 = "#{@node_metadata[node_name][:private_ips].first.split('.')[0..2].join('.')}.0/24"
305
- @nodes_graph[ip_24] = ip_range_graph_info(ip_24) unless @nodes_graph.key?(ip_24)
306
- @nodes_graph[ip_24][:includes] << node_name unless @nodes_graph[ip_24][:includes].include?(node_name)
307
- end
307
+ @nodes_graph.each_key do |node_name|
308
+ next unless @nodes_graph[node_name][:type] == :node && !@node_metadata[node_name][:private_ips].nil? && !@node_metadata[node_name][:private_ips].empty?
309
+
310
+ ip_24 = "#{@node_metadata[node_name][:private_ips].first.split('.')[0..2].join('.')}.0/24"
311
+ @nodes_graph[ip_24] = ip_range_graph_info(ip_24) unless @nodes_graph.key?(ip_24)
312
+ @nodes_graph[ip_24][:includes] << node_name unless @nodes_graph[ip_24][:includes].include?(node_name)
308
313
  end
309
314
  end
310
315
 
@@ -373,10 +378,12 @@ module HybridPlatformsConductor
373
378
  def filter_in_nodes(nodes_list)
374
379
  new_nodes_graph = {}
375
380
  @nodes_graph.each do |node_name, node_info|
381
+ next unless nodes_list.include?(node_name)
382
+
376
383
  new_nodes_graph[node_name] = node_info.merge(
377
384
  connections: node_info[:connections].select { |connected_hostname, _labels| nodes_list.include?(connected_hostname) },
378
385
  includes: node_info[:includes] & nodes_list
379
- ) if nodes_list.include?(node_name)
386
+ )
380
387
  end
381
388
  @nodes_graph = new_nodes_graph
382
389
  end
@@ -388,10 +395,12 @@ module HybridPlatformsConductor
388
395
  def filter_out_nodes(nodes_list)
389
396
  new_nodes_graph = {}
390
397
  @nodes_graph.each do |node_name, node_info|
398
+ next if nodes_list.include?(node_name)
399
+
391
400
  new_nodes_graph[node_name] = node_info.merge(
392
- connections: node_info[:connections].select { |connected_hostname, _labels| !nodes_list.include?(connected_hostname) },
401
+ connections: node_info[:connections].reject { |connected_hostname, _labels| nodes_list.include?(connected_hostname) },
393
402
  includes: node_info[:includes] - nodes_list
394
- ) unless nodes_list.include?(node_name)
403
+ )
395
404
  end
396
405
  @nodes_graph = new_nodes_graph
397
406
  end
@@ -405,7 +414,7 @@ module HybridPlatformsConductor
405
414
  # Delete references to the nodes to be replaced
406
415
  @nodes_graph.delete_if { |node_name, _node_info| nodes_to_be_replaced.include?(node_name) }
407
416
  # Change any connection or inclusions using nodes to be replaced
408
- @nodes_graph.each do |node_name, node_info|
417
+ @nodes_graph.each_value do |node_info|
409
418
  node_info[:includes] = node_info[:includes].map { |included_node_name| nodes_to_be_replaced.include?(included_node_name) ? replacement_node : included_node_name }.uniq
410
419
  new_connections = {}
411
420
  node_info[:connections].each do |connected_node_name, labels|
@@ -442,46 +451,44 @@ module HybridPlatformsConductor
442
451
  end
443
452
  break unless conflicting_clusters.nil?
444
453
  end
445
- if conflicting_clusters.nil?
446
- break
447
- else
448
- # We have conflicting clusters to resolve
449
- cluster_1, cluster_2 = conflicting_clusters
450
- c1_belongs_to_c2 = @nodes_graph[cluster_1][:includes].all? { |cluster_1_node_name| @nodes_graph[cluster_2][:includes_proc].call(cluster_1_node_name) }
451
- c2_belongs_to_c1 = @nodes_graph[cluster_2][:includes].all? { |cluster_2_node_name| @nodes_graph[cluster_1][:includes_proc].call(cluster_2_node_name) }
452
- if c1_belongs_to_c2
453
- if c2_belongs_to_c1
454
- # Both clusters have the same nodes
455
- if @nodes_graph[cluster_1][:includes_proc].call(cluster_2)
456
- @nodes_graph[cluster_2][:includes] = (@nodes_graph[cluster_1][:includes] + @nodes_graph[cluster_2][:includes]).uniq
457
- @nodes_graph[cluster_1][:includes] = [cluster_2]
458
- else
459
- @nodes_graph[cluster_1][:includes] = (@nodes_graph[cluster_1][:includes] + @nodes_graph[cluster_2][:includes]).uniq
460
- @nodes_graph[cluster_2][:includes] = [cluster_1]
461
- end
454
+ break if conflicting_clusters.nil?
455
+
456
+ # We have conflicting clusters to resolve
457
+ cluster_1, cluster_2 = conflicting_clusters
458
+ cluster_1_belongs_to_cluster_2 = @nodes_graph[cluster_1][:includes].all? { |cluster_1_node_name| @nodes_graph[cluster_2][:includes_proc].call(cluster_1_node_name) }
459
+ cluster_2_belongs_to_cluster_1 = @nodes_graph[cluster_2][:includes].all? { |cluster_2_node_name| @nodes_graph[cluster_1][:includes_proc].call(cluster_2_node_name) }
460
+ if cluster_1_belongs_to_cluster_2
461
+ if cluster_2_belongs_to_cluster_1
462
+ # Both clusters have the same nodes
463
+ if @nodes_graph[cluster_1][:includes_proc].call(cluster_2)
464
+ @nodes_graph[cluster_2][:includes] = (@nodes_graph[cluster_1][:includes] + @nodes_graph[cluster_2][:includes]).uniq
465
+ @nodes_graph[cluster_1][:includes] = [cluster_2]
462
466
  else
463
- # All nodes of cluster_1 belong to cluster_2, but some nodes of cluster_2 don't belong to cluster_1
464
- @nodes_graph[cluster_2][:includes] = @nodes_graph[cluster_2][:includes] - @nodes_graph[cluster_1][:includes] + [cluster_1]
467
+ @nodes_graph[cluster_1][:includes] = (@nodes_graph[cluster_1][:includes] + @nodes_graph[cluster_2][:includes]).uniq
468
+ @nodes_graph[cluster_2][:includes] = [cluster_1]
465
469
  end
466
- elsif c2_belongs_to_c1
467
- # All nodes of cluster_2 belong to cluster_1, but some nodes of cluster_1 don't belong to cluster_2
468
- @nodes_graph[cluster_1][:includes] = @nodes_graph[cluster_1][:includes] - @nodes_graph[cluster_2][:includes] + [cluster_2]
469
470
  else
470
- # cluster_1 and cluster_2 have to be merged
471
- new_cluster_name = "#{cluster_1}_&_#{cluster_2}"
472
- # Store thos proc in those variables as the cluster_1 and cluster_2 references are going to be removed
473
- includes_proc_1 = @nodes_graph[cluster_1][:includes_proc]
474
- includes_proc_2 = @nodes_graph[cluster_2][:includes_proc]
475
- @nodes_graph[new_cluster_name] = {
476
- type: :cluster,
477
- includes: (@nodes_graph[cluster_1][:includes] + @nodes_graph[cluster_2][:includes]).uniq,
478
- connections: @nodes_graph[cluster_1][:connections].merge!(@nodes_graph[cluster_2][:connections]) { |_connected_node, labels1, labels2| (labels1 + labels2).uniq },
479
- includes_proc: proc do |hostname|
480
- includes_proc_1.call(hostname) || includes_proc_2.call(hostname)
481
- end
482
- }
483
- replace_nodes([cluster_1, cluster_2], new_cluster_name)
471
+ # All nodes of cluster_1 belong to cluster_2, but some nodes of cluster_2 don't belong to cluster_1
472
+ @nodes_graph[cluster_2][:includes] = @nodes_graph[cluster_2][:includes] - @nodes_graph[cluster_1][:includes] + [cluster_1]
484
473
  end
474
+ elsif cluster_2_belongs_to_cluster_1
475
+ # All nodes of cluster_2 belong to cluster_1, but some nodes of cluster_1 don't belong to cluster_2
476
+ @nodes_graph[cluster_1][:includes] = @nodes_graph[cluster_1][:includes] - @nodes_graph[cluster_2][:includes] + [cluster_2]
477
+ else
478
+ # cluster_1 and cluster_2 have to be merged
479
+ new_cluster_name = "#{cluster_1}_&_#{cluster_2}"
480
+ # Store thos proc in those variables as the cluster_1 and cluster_2 references are going to be removed
481
+ includes_proc_1 = @nodes_graph[cluster_1][:includes_proc]
482
+ includes_proc_2 = @nodes_graph[cluster_2][:includes_proc]
483
+ @nodes_graph[new_cluster_name] = {
484
+ type: :cluster,
485
+ includes: (@nodes_graph[cluster_1][:includes] + @nodes_graph[cluster_2][:includes]).uniq,
486
+ connections: @nodes_graph[cluster_1][:connections].merge!(@nodes_graph[cluster_2][:connections]) { |_connected_node, labels_1, labels_2| (labels_1 + labels_2).uniq },
487
+ includes_proc: proc do |hostname|
488
+ includes_proc_1.call(hostname) || includes_proc_2.call(hostname)
489
+ end
490
+ }
491
+ replace_nodes([cluster_1, cluster_2], new_cluster_name)
485
492
  end
486
493
  end
487
494
  end
@@ -492,7 +499,7 @@ module HybridPlatformsConductor
492
499
  # * *node_name* (String): Node name
493
500
  # Result::
494
501
  # * Boolean: Is the node represented as a cluster?
495
- def is_node_cluster?(node_name)
502
+ def node_cluster?(node_name)
496
503
  @nodes_graph[node_name][:type] == :cluster || !@nodes_graph[node_name][:includes].empty?
497
504
  end
498
505
 
@@ -502,7 +509,7 @@ module HybridPlatformsConductor
502
509
  # * *node_name* (String): Node name
503
510
  # Result::
504
511
  # * Boolean: Is the node a physical node?
505
- def is_node_physical?(node_name)
512
+ def node_physical?(node_name)
506
513
  @nodes_graph[node_name][:type] == :node && @node_metadata[node_name][:physical_node]
507
514
  end
508
515
 
@@ -512,11 +519,9 @@ module HybridPlatformsConductor
512
519
  # * *file_name* (String): File name to output to.
513
520
  # * *output_format* (Symbol): Output format to use (should be part of the plugins).
514
521
  def write_graph(file_name, output_format)
515
- if @plugins.key?(output_format)
516
- @plugins[output_format].new(self).write_graph(file_name)
517
- else
518
- raise "Unknown topographer plugin #{output_format}"
519
- end
522
+ raise "Unknown topographer plugin #{output_format}" unless @plugins.key?(output_format)
523
+
524
+ @plugins[output_format].new(self).write_graph(file_name)
520
525
  end
521
526
 
522
527
  # Get the title of a given node
@@ -543,14 +548,10 @@ module HybridPlatformsConductor
543
548
  # Result::
544
549
  # * String: Node description, or nil if none
545
550
  def description_for(node_name)
546
- require 'byebug'
547
- byebug if node_name == 'xaesbghad51'
548
551
  case @nodes_graph[node_name][:type]
549
552
  when :node
550
553
  @node_metadata[node_name][:description]
551
- when :cluster
552
- nil
553
- when :unknown
554
+ when :cluster, :unknown
554
555
  nil
555
556
  end
556
557
  end
@@ -570,11 +571,12 @@ module HybridPlatformsConductor
570
571
  @nodes_handler.known_nodes.each do |node|
571
572
  %i[private_ips public_ips].each do |ip_type|
572
573
  ips = @nodes_handler.metadata_of(node, ip_type)
573
- if ips
574
- ips.each do |ip|
575
- raise "Conflict: #{ip} is already associated to #{@known_ips[ip]}. Cannot associate it to #{node}." if @known_ips.key?(ip)
576
- @known_ips[ip] = node
577
- end
574
+ next unless ips
575
+
576
+ ips.each do |ip|
577
+ raise "Conflict: #{ip} is already associated to #{@known_ips[ip]}. Cannot associate it to #{node}." if @known_ips.key?(ip)
578
+
579
+ @known_ips[ip] = node
578
580
  end
579
581
  end
580
582
  end
@@ -597,9 +599,9 @@ module HybridPlatformsConductor
597
599
  @ips_mask[ip_def] = {} unless @ips_mask.key?(ip_def)
598
600
  unless @ips_mask[ip_def].key?(ip_mask)
599
601
  # For performance, keep a cache of all the IPAddress::IPv4 objects
600
- @ip_v4_cache = Hash[known_ips.keys.map { |ip, _node| [ip, IPAddress::IPv4.new(ip)] }] unless defined?(@ip_v4_cache)
602
+ @ip_v4_cache = known_ips.keys.map { |ip, _node| [ip, IPAddress::IPv4.new(ip)] }.to_h unless defined?(@ip_v4_cache)
601
603
  ip_range = IPAddress::IPv4.new("#{ip_def}/#{ip_mask}")
602
- @ips_mask[ip_def][ip_mask] = @ip_v4_cache.select { |_ip, ip_v4| ip_range.include?(ip_v4) }.keys
604
+ @ips_mask[ip_def][ip_mask] = @ip_v4_cache.select { |_ip, ipv4| ip_range.include?(ipv4) }.keys
603
605
  end
604
606
  @ips_mask[ip_def][ip_mask]
605
607
  end
@@ -638,7 +640,7 @@ module HybridPlatformsConductor
638
640
  ipv4 = IPAddress::IPv4.new(ip)
639
641
  includes_proc = proc do |node_name|
640
642
  if @nodes_graph[node_name][:ipv4].nil?
641
- if is_node_cluster?(node_name)
643
+ if node_cluster?(node_name)
642
644
  # Here the node is a cluster that is not an IP range.
643
645
  @nodes_graph[node_name][:includes].all? { |included_node_name| includes_proc.call(included_node_name) }
644
646
  else
@@ -706,7 +708,8 @@ module HybridPlatformsConductor
706
708
  # * Hash<String,Array<String>>: List of references for each node.
707
709
  def connections_from_json(json, current_ref = nil)
708
710
  nodes = {}
709
- if json.is_a?(String)
711
+ case json
712
+ when String
710
713
  # Look for any IP
711
714
  json.scan(@ip_regexp).each do |(ip_def, _grp_match, ip_mask_str)|
712
715
  ip_mask = ip_mask_str.nil? ? 32 : ip_mask_str.to_i
@@ -719,95 +722,93 @@ module HybridPlatformsConductor
719
722
  "#{ip_def}/#{ip_mask}"
720
723
  end
721
724
  # First check that we don't ignore this IP range
722
- unless @ips_ignored.key?(ip_str)
723
- connected_node_name =
724
- if @nodes_graph.key?(ip_str)
725
- # IP group already exists
726
- ip_str
727
- elsif @config[:ignore_ips].any? { |ip_regexp| ip_str =~ ip_regexp }
728
- # This IP should be ignored
729
- @ips_ignored[ip_str] = nil
730
- nil
731
- else
732
- # New group to create.
733
- if ip_mask <= 24
734
- # This group will include all needed ip_24 IPs.
735
- # Compute the list of 24 bits IPs that are referenced here.
736
- ip_24_list =
737
- if ip_mask == 24
738
- [ip_str]
739
- else
740
- ips_24_matching_mask(ip_def, ip_mask).select do |ip|
741
- unless @ips_ignored.key?(ip_str)
742
- # Check if we should ignore it.
743
- @ips_ignored[ip] = nil if @config[:ignore_ips].any? { |ip_regexp| ip =~ ip_regexp }
744
- end
745
- !@ips_ignored.key?(ip)
746
- end
747
- end
748
- if ip_24_list.empty?
749
- # All IPs of the group are to be ignored
750
- nil
751
- elsif ip_24_list.size == 1
752
- # Just create 1 group.
753
- ip_24 = ip_24_list.first
754
- @nodes_graph[ip_24] = ip_range_graph_info(ip_24) unless @nodes_graph.key?(ip_24)
755
- ip_24
756
- else
757
- # Create all ip_24 groups.
758
- ip_24_list.each do |included_ip_24|
759
- @nodes_graph[included_ip_24] = ip_range_graph_info(included_ip_24) unless @nodes_graph.key?(included_ip_24)
725
+ next if @ips_ignored.key?(ip_str)
726
+
727
+ connected_node_name =
728
+ if @nodes_graph.key?(ip_str)
729
+ # IP group already exists
730
+ ip_str
731
+ elsif @config[:ignore_ips].any? { |ip_regexp| ip_str =~ ip_regexp }
732
+ # This IP should be ignored
733
+ @ips_ignored[ip_str] = nil
734
+ nil
735
+ elsif ip_mask <= 24
736
+ # New group to create.
737
+ ip_24_list =
738
+ if ip_mask == 24
739
+ [ip_str]
740
+ else
741
+ ips_24_matching_mask(ip_def, ip_mask).reject do |ip|
742
+ if !@ips_ignored.key?(ip_str) && @config[:ignore_ips].any? { |ip_regexp| ip =~ ip_regexp }
743
+ # Check if we should ignore it.
744
+ @ips_ignored[ip] = nil
760
745
  end
761
- # Create a super group of it
762
- @nodes_graph[ip_str] = ip_range_graph_info(ip_str)
763
- @nodes_graph[ip_str][:includes] = ip_24_list
764
- ip_str
746
+ @ips_ignored.key?(ip)
765
747
  end
748
+ end
749
+ if ip_24_list.empty?
750
+ # All IPs of the group are to be ignored
751
+ nil
752
+ elsif ip_24_list.size == 1
753
+ # Just create 1 group.
754
+ ip_24 = ip_24_list.first
755
+ @nodes_graph[ip_24] = ip_range_graph_info(ip_24) unless @nodes_graph.key?(ip_24)
756
+ ip_24
757
+ else
758
+ # Create all ip_24 groups.
759
+ ip_24_list.each do |included_ip_24|
760
+ @nodes_graph[included_ip_24] = ip_range_graph_info(included_ip_24) unless @nodes_graph.key?(included_ip_24)
761
+ end
762
+ # Create a super group of it
763
+ @nodes_graph[ip_str] = ip_range_graph_info(ip_str)
764
+ @nodes_graph[ip_str][:includes] = ip_24_list
765
+ ip_str
766
+ end
767
+ # This group will include all needed ip_24 IPs.
768
+ # Compute the list of 24 bits IPs that are referenced here.
769
+ else
770
+ # This group will include all individual IP addresses.
771
+ ips_list =
772
+ if ip_mask == 32
773
+ [ip_def]
766
774
  else
767
- # This group will include all individual IP addresses.
768
- ips_list =
769
- if ip_mask == 32
770
- [ip_def]
771
- else
772
- ips_matching_mask(ip_def, ip_mask).select do |ip|
773
- unless @ips_ignored.key?(ip_str)
774
- # Check if we should ignore it.
775
- @ips_ignored[ip] = nil if @config[:ignore_ips].any? { |ip_regexp| ip =~ ip_regexp }
776
- end
777
- !@ips_ignored.key?(ip)
778
- end
779
- end
780
- if ips_list.empty?
781
- # All IPs of the group are to be ignored
782
- nil
783
- elsif ips_list.size == 1
784
- # Just create 1 node.
785
- ip = ips_list.first
786
- if @ips_to_host.key?(ip)
787
- # Known hostname
788
- @ips_to_host[ip]
789
- else
790
- # Unknown IP that should be added.
791
- @nodes_graph[ip] = {
792
- type: :unknown,
793
- connections: {},
794
- includes: [],
795
- ipv4: IPAddress::IPv4.new(ip)
796
- }
797
- ip
775
+ ips_matching_mask(ip_def, ip_mask).reject do |ip|
776
+ if !@ips_ignored.key?(ip_str) && @config[:ignore_ips].any? { |ip_regexp| ip =~ ip_regexp }
777
+ # Check if we should ignore it.
778
+ @ips_ignored[ip] = nil
798
779
  end
799
- else
800
- # Create a super group of it
801
- @nodes_graph[ip_str] = ip_range_graph_info(ip_str)
802
- @nodes_graph[ip_str][:includes] = ips_list.map { |included_ip| @ips_to_host[included_ip] }
803
- ip_str
780
+ @ips_ignored.key?(ip)
804
781
  end
805
782
  end
783
+ if ips_list.empty?
784
+ # All IPs of the group are to be ignored
785
+ nil
786
+ elsif ips_list.size == 1
787
+ # Just create 1 node.
788
+ ip = ips_list.first
789
+ if @ips_to_host.key?(ip)
790
+ # Known hostname
791
+ @ips_to_host[ip]
792
+ else
793
+ # Unknown IP that should be added.
794
+ @nodes_graph[ip] = {
795
+ type: :unknown,
796
+ connections: {},
797
+ includes: [],
798
+ ipv4: IPAddress::IPv4.new(ip)
799
+ }
800
+ ip
801
+ end
802
+ else
803
+ # Create a super group of it
804
+ @nodes_graph[ip_str] = ip_range_graph_info(ip_str)
805
+ @nodes_graph[ip_str][:includes] = ips_list.map { |included_ip| @ips_to_host[included_ip] }
806
+ ip_str
806
807
  end
807
- unless connected_node_name.nil?
808
- nodes[connected_node_name] = [] unless nodes.key?(connected_node_name)
809
- nodes[connected_node_name] << current_ref
810
808
  end
809
+ unless connected_node_name.nil?
810
+ nodes[connected_node_name] = [] unless nodes.key?(connected_node_name)
811
+ nodes[connected_node_name] << current_ref
811
812
  end
812
813
  end
813
814
  # Look for any known hostname
@@ -817,15 +818,24 @@ module HybridPlatformsConductor
817
818
  nodes[hostname] << current_ref
818
819
  end
819
820
  end
820
- elsif json.is_a?(Array)
821
+ when Array
821
822
  json.each do |sub_json|
822
- nodes.merge!(connections_from_json(sub_json, current_ref)) { |_node_name, refs1, refs2| (refs1 + refs2).uniq }
823
+ nodes.merge!(connections_from_json(sub_json, current_ref)) { |_node_name, refs_1, refs_2| (refs_1 + refs_2).uniq }
823
824
  end
824
- elsif json.is_a?(Hash)
825
+ when Hash
825
826
  json.each do |sub_json_1, sub_json_2|
826
- nodes.merge!(connections_from_json(sub_json_1, current_ref)) { |_node_name, refs1, refs2| (refs1 + refs2).uniq }
827
+ nodes.merge!(connections_from_json(sub_json_1, current_ref)) { |_node_name, refs_1, refs_2| (refs_1 + refs_2).uniq }
827
828
  key_is_str = sub_json_1.is_a?(String)
828
- nodes.merge!(connections_from_json(sub_json_2, key_is_str ? (current_ref.nil? ? sub_json_1 : "#{current_ref}/#{sub_json_1}") : current_ref)) { |_hostname, refs1, refs2| (refs1 + refs2).uniq } if !key_is_str || !@config[:ignore_any_json_keys].include?(sub_json_1)
829
+ nodes.merge!(
830
+ connections_from_json(
831
+ sub_json_2,
832
+ if key_is_str
833
+ current_ref.nil? ? sub_json_1 : "#{current_ref}/#{sub_json_1}"
834
+ else
835
+ current_ref
836
+ end
837
+ )
838
+ ) { |_hostname, refs_1, refs_2| (refs_1 + refs_2).uniq } if !key_is_str || !@config[:ignore_any_json_keys].include?(sub_json_1)
829
839
  end
830
840
  end
831
841
  nodes
@@ -837,19 +847,19 @@ module HybridPlatformsConductor
837
847
  # * *hostname* (String): Hostname to parse for connections.
838
848
  # * *max_level* (Integer): Maximum level of recursive passes (nil for no limit).
839
849
  def parse_connections_for(hostname, max_level)
840
- unless @nodes_graph.key?(hostname)
841
- @nodes_graph[hostname] = {
842
- type: :node,
843
- connections: connections_from_json(node_json_for(hostname)),
844
- includes: []
845
- }
846
- @nodes_graph[hostname][:ipv4] = IPAddress::IPv4.new(@node_metadata[hostname][:private_ips].first) if !@node_metadata[hostname][:private_ips].nil? && !@node_metadata[hostname][:private_ips].empty?
847
- sub_max_level = max_level.nil? ? nil : max_level - 1
848
- if sub_max_level != -1
849
- @nodes_graph[hostname][:connections].keys.each do |connected_hostname|
850
- parse_connections_for(connected_hostname, sub_max_level)
851
- end
852
- end
850
+ return if @nodes_graph.key?(hostname)
851
+
852
+ @nodes_graph[hostname] = {
853
+ type: :node,
854
+ connections: connections_from_json(node_json_for(hostname)),
855
+ includes: []
856
+ }
857
+ @nodes_graph[hostname][:ipv4] = IPAddress::IPv4.new(@node_metadata[hostname][:private_ips].first) if !@node_metadata[hostname][:private_ips].nil? && !@node_metadata[hostname][:private_ips].empty?
858
+ sub_max_level = max_level.nil? ? nil : max_level - 1
859
+ return if sub_max_level == -1
860
+
861
+ @nodes_graph[hostname][:connections].each_key do |connected_hostname|
862
+ parse_connections_for(connected_hostname, sub_max_level)
853
863
  end
854
864
  end
855
865