hybrid_platforms_conductor 32.16.4 → 33.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +42 -0
- data/README.md +6 -3
- data/bin/check-node +0 -1
- data/bin/deploy +0 -1
- data/bin/get_impacted_nodes +0 -1
- data/bin/last_deploys +12 -8
- data/bin/nodes_to_deploy +6 -6
- data/bin/setup +6 -6
- data/bin/topograph +1 -1
- data/docs/config_dsl.md +45 -1
- data/docs/executables.md +6 -7
- data/docs/executables/check-node.md +3 -3
- data/docs/executables/deploy.md +3 -3
- data/docs/executables/dump_nodes_json.md +3 -3
- data/docs/executables/test.md +3 -3
- data/docs/executables/topograph.md +3 -3
- data/docs/gen/mermaid/README.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/check-node.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/deploy.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/free_ips.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/get_impacted_nodes.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/last_deploys.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/nodes_to_deploy.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/report.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/run.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/ssh_config.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/test.md-0.png +0 -0
- data/docs/plugins.md +47 -0
- data/docs/plugins/connector/ssh.md +1 -1
- data/docs/plugins/log/remote_fs.md +26 -0
- data/docs/plugins/secrets_reader/cli.md +31 -0
- data/docs/plugins/secrets_reader/thycotic.md +46 -0
- data/docs/plugins/test/bitbucket_conf.md +1 -1
- data/docs/plugins/test/check_deploy_and_idempotence.md +1 -1
- data/docs/plugins/test/connection.md +1 -0
- data/docs/plugins/test/deploy_removes_root_access.md +1 -1
- data/docs/plugins/test/file_system.md +1 -0
- data/docs/plugins/test/github_ci.md +48 -0
- data/docs/plugins/test/hostname.md +1 -0
- data/docs/plugins/test/ip.md +1 -0
- data/docs/plugins/test/jenkins_ci_conf.md +1 -1
- data/docs/plugins/test/jenkins_ci_masters_ok.md +1 -1
- data/docs/plugins/test/local_users.md +1 -0
- data/docs/plugins/test/mounts.md +1 -0
- data/docs/plugins/test/orphan_files.md +1 -0
- data/docs/plugins/test/ports.md +1 -0
- data/docs/plugins/test/spectre.md +1 -0
- data/docs/plugins/test/vulnerabilities.md +1 -0
- data/lib/hybrid_platforms_conductor/action.rb +4 -4
- data/lib/hybrid_platforms_conductor/actions_executor.rb +45 -43
- data/lib/hybrid_platforms_conductor/bitbucket.rb +5 -4
- data/lib/hybrid_platforms_conductor/cmd_runner.rb +13 -12
- data/lib/hybrid_platforms_conductor/cmdb.rb +2 -2
- data/lib/hybrid_platforms_conductor/common_config_dsl/bitbucket.rb +2 -1
- data/lib/hybrid_platforms_conductor/common_config_dsl/confluence.rb +2 -1
- data/lib/hybrid_platforms_conductor/common_config_dsl/file_system_tests.rb +5 -4
- data/lib/hybrid_platforms_conductor/common_config_dsl/github.rb +63 -0
- data/lib/hybrid_platforms_conductor/common_config_dsl/idempotence_tests.rb +2 -2
- data/lib/hybrid_platforms_conductor/config.rb +7 -4
- data/lib/hybrid_platforms_conductor/confluence.rb +1 -1
- data/lib/hybrid_platforms_conductor/connector.rb +5 -2
- data/lib/hybrid_platforms_conductor/core_extensions/symbol/zero.rb +24 -0
- data/lib/hybrid_platforms_conductor/credentials.rb +39 -36
- data/lib/hybrid_platforms_conductor/current_dir_monitor.rb +4 -1
- data/lib/hybrid_platforms_conductor/deployer.rb +275 -224
- data/lib/hybrid_platforms_conductor/executable.rb +20 -15
- data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/config.rb +10 -7
- data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/host_ip.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/host_keys.rb +2 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/platform_handlers.rb +4 -4
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/local.rb +2 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +45 -49
- data/lib/hybrid_platforms_conductor/hpc_plugins/log/my_log_plugin.rb.sample +100 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/log/remote_fs.rb +180 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef.rb +68 -66
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/dsl_parser.rb +13 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/recipes_tree_builder.rb +39 -38
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/yaml_inventory.rb +5 -4
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/docker.rb +43 -45
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/podman.rb +18 -20
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox.rb +118 -117
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox/proxmox_waiter.rb +39 -43
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox/reserve_proxmox_container +9 -13
- data/lib/hybrid_platforms_conductor/hpc_plugins/report/confluence.rb +2 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/report/mediawiki.rb +28 -21
- data/lib/hybrid_platforms_conductor/hpc_plugins/report/stdout.rb +26 -22
- data/lib/hybrid_platforms_conductor/hpc_plugins/secrets_reader/cli.rb +77 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/secrets_reader/my_secrets_reader_plugin.rb.sample +46 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/secrets_reader/thycotic.rb +90 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/bitbucket_conf.rb +3 -3
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/check_deploy_and_idempotence.rb +4 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/connection.rb +3 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_freshness.rb +7 -21
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +21 -19
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/divergence.rb +2 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/executables.rb +2 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system.rb +21 -22
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system_hdfs.rb +19 -21
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/github_ci.rb +31 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +3 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/idempotence.rb +2 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +4 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/jenkins_ci_conf.rb +21 -22
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/jenkins_ci_masters_ok.rb +10 -12
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/linear_strategy.rb +9 -9
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +5 -3
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +5 -3
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +13 -10
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/ports.rb +5 -3
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/private_ips.rb +5 -5
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/public_ips.rb +5 -5
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +7 -7
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/veids.rb +3 -3
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +27 -25
- data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/confluence.rb +2 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/stdout.rb +8 -6
- data/lib/hybrid_platforms_conductor/io_router.rb +14 -13
- data/lib/hybrid_platforms_conductor/json_dumper.rb +2 -2
- data/lib/hybrid_platforms_conductor/log.rb +31 -0
- data/lib/hybrid_platforms_conductor/logger_helpers.rb +19 -16
- data/lib/hybrid_platforms_conductor/nodes_handler.rb +89 -71
- data/lib/hybrid_platforms_conductor/parallel_threads.rb +7 -11
- data/lib/hybrid_platforms_conductor/platform_handler.rb +7 -7
- data/lib/hybrid_platforms_conductor/platforms_handler.rb +5 -3
- data/lib/hybrid_platforms_conductor/plugin.rb +2 -2
- data/lib/hybrid_platforms_conductor/plugins.rb +14 -8
- data/lib/hybrid_platforms_conductor/provisioner.rb +4 -4
- data/lib/hybrid_platforms_conductor/report.rb +2 -2
- data/lib/hybrid_platforms_conductor/reports_handler.rb +3 -2
- data/lib/hybrid_platforms_conductor/secrets_reader.rb +31 -0
- data/lib/hybrid_platforms_conductor/services_handler.rb +32 -29
- data/lib/hybrid_platforms_conductor/test_only_remote_node.rb +18 -0
- data/lib/hybrid_platforms_conductor/test_report.rb +15 -18
- data/lib/hybrid_platforms_conductor/tests_runner.rb +116 -118
- data/lib/hybrid_platforms_conductor/thycotic.rb +28 -19
- data/lib/hybrid_platforms_conductor/topographer.rb +200 -190
- data/lib/hybrid_platforms_conductor/topographer/plugins/graphviz.rb +8 -8
- data/lib/hybrid_platforms_conductor/topographer/plugins/json.rb +4 -4
- data/lib/hybrid_platforms_conductor/version.rb +1 -1
- data/spec/hybrid_platforms_conductor_test.rb +33 -12
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/bash_spec.rb +16 -11
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/interactive_spec.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/remote_bash_spec.rb +23 -18
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/ruby_spec.rb +67 -49
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/scp_spec.rb +20 -14
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions_spec.rb +63 -50
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connection_spec.rb +35 -35
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/connectable_nodes_spec.rb +12 -8
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/remote_actions_spec.rb +4 -7
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/cli_options_spec.rb +21 -22
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/config_dsl_spec.rb +23 -24
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connectable_nodes_spec.rb +10 -6
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connections_spec.rb +73 -54
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/global_helpers_spec.rb +145 -126
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/node_helpers_spec.rb +3 -3
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb +29 -25
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/logging_spec.rb +106 -91
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/parallel_spec.rb +272 -244
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/timeout_spec.rb +10 -12
- data/spec/hybrid_platforms_conductor_test/api/cmd_runner_spec.rb +36 -36
- data/spec/hybrid_platforms_conductor_test/api/config_spec.rb +24 -22
- data/spec/hybrid_platforms_conductor_test/api/deployer/check_spec.rb +4 -2
- data/spec/hybrid_platforms_conductor_test/api/deployer/config_dsl_spec.rb +43 -5
- data/spec/hybrid_platforms_conductor_test/api/deployer/deploy_spec.rb +199 -216
- data/spec/hybrid_platforms_conductor_test/api/deployer/log_plugins/remote_fs_spec.rb +223 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/parse_deploy_output_spec.rb +55 -59
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioner_spec.rb +36 -62
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/podman_spec.rb +17 -17
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/config_dsl_spec.rb +4 -4
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/create_spec.rb +44 -51
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/destroy_spec.rb +3 -3
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/ip_spec.rb +12 -16
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/destroy_vm_spec.rb +31 -19
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/expired_containers_spec.rb +324 -266
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/ips_assignment_spec.rb +89 -61
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/other_lxc_containers_resources_spec.rb +117 -93
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/pve_node_resources_spec.rb +71 -54
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/retries_spec.rb +10 -8
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/vm_ids_assignment_spec.rb +80 -60
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/start_spec.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/state_spec.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/stop_spec.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/api/deployer/secrets_reader_plugins/cli_spec.rb +64 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/secrets_reader_plugins/thycotic_spec.rb +268 -0
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/config_spec.rb +8 -10
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/host_ip_spec.rb +33 -24
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/host_keys_spec.rb +64 -51
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/platform_handlers_spec.rb +3 -3
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs_plugins_api_spec.rb +50 -51
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/common_spec.rb +91 -81
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/config_dsl_spec.rb +14 -16
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/git_diff_impacts_spec.rb +51 -75
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/nodes_selectors_spec.rb +35 -26
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/platform_handlers_plugins_api_spec.rb +24 -16
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/several_platforms_spec.rb +29 -19
- data/spec/hybrid_platforms_conductor_test/api/platform_handler_spec.rb +4 -4
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/config_dsl_spec.rb +2 -2
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/deploy_output_parsing_spec.rb +6 -6
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/diff_impacts_spec.rb +57 -99
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/inventory_spec.rb +4 -4
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/packaging_spec.rb +32 -35
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/services_deployment_spec.rb +10 -10
- data/spec/hybrid_platforms_conductor_test/api/platforms_handler_spec.rb +38 -27
- data/spec/hybrid_platforms_conductor_test/api/plugins_spec.rb +46 -52
- data/spec/hybrid_platforms_conductor_test/api/reports_handler_spec.rb +2 -2
- data/spec/hybrid_platforms_conductor_test/api/services_handler/actions_to_deploy_spec.rb +90 -58
- data/spec/hybrid_platforms_conductor_test/api/services_handler/deploy_allowed_spec.rb +38 -34
- data/spec/hybrid_platforms_conductor_test/api/services_handler/log_info_spec.rb +11 -9
- data/spec/hybrid_platforms_conductor_test/api/services_handler/package_spec.rb +193 -171
- data/spec/hybrid_platforms_conductor_test/api/services_handler/parse_deploy_output_spec.rb +66 -54
- data/spec/hybrid_platforms_conductor_test/api/services_handler/prepare_for_deploy_spec.rb +147 -133
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/common_spec.rb +69 -49
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/global_spec.rb +5 -4
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_check_spec.rb +8 -5
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_spec.rb +8 -5
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_ssh_spec.rb +30 -27
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/platform_spec.rb +12 -9
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/reports_spec.rb +48 -47
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/bitbucket_conf_spec.rb +5 -5
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/github_ci_spec.rb +72 -0
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_reports_plugins/confluence_spec.rb +5 -5
- data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb.rb +9 -9
- data/spec/hybrid_platforms_conductor_test/cmdb_plugins/{test_cmdb2.rb → test_cmdb_2.rb} +6 -6
- data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb_others.rb +3 -3
- data/spec/hybrid_platforms_conductor_test/cmdb_plugins/{test_cmdb_others2.rb → test_cmdb_others_2.rb} +2 -2
- data/spec/hybrid_platforms_conductor_test/docs_spec.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/executables/{check-node_spec.rb → check_node_spec.rb} +4 -6
- data/spec/hybrid_platforms_conductor_test/executables/deploy_spec.rb +4 -6
- data/spec/hybrid_platforms_conductor_test/executables/get_impacted_nodes_spec.rb +76 -77
- data/spec/hybrid_platforms_conductor_test/executables/last_deploys_spec.rb +159 -113
- data/spec/hybrid_platforms_conductor_test/executables/nodes_to_deploy_spec.rb +299 -160
- data/spec/hybrid_platforms_conductor_test/executables/options/actions_executor_spec.rb +4 -6
- data/spec/hybrid_platforms_conductor_test/executables/options/cmd_runner_spec.rb +3 -5
- data/spec/hybrid_platforms_conductor_test/executables/options/common_spec.rb +8 -8
- data/spec/hybrid_platforms_conductor_test/executables/options/deployer_spec.rb +12 -196
- data/spec/hybrid_platforms_conductor_test/executables/options/nodes_handler_spec.rb +9 -10
- data/spec/hybrid_platforms_conductor_test/executables/options/nodes_selectors_spec.rb +9 -10
- data/spec/hybrid_platforms_conductor_test/executables/options/reports_handler_spec.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/executables/options/tests_runner_spec.rb +22 -22
- data/spec/hybrid_platforms_conductor_test/executables/report_spec.rb +22 -16
- data/spec/hybrid_platforms_conductor_test/executables/run_spec.rb +32 -32
- data/spec/hybrid_platforms_conductor_test/executables/ssh_config_spec.rb +7 -9
- data/spec/hybrid_platforms_conductor_test/executables/test_spec.rb +3 -5
- data/spec/hybrid_platforms_conductor_test/helpers/actions_executor_helpers.rb +2 -2
- data/spec/hybrid_platforms_conductor_test/helpers/cmd_runner_helpers.rb +4 -3
- data/spec/hybrid_platforms_conductor_test/helpers/cmdb_helpers.rb +2 -2
- data/spec/hybrid_platforms_conductor_test/helpers/config_helpers.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/helpers/connector_ssh_helpers.rb +12 -13
- data/spec/hybrid_platforms_conductor_test/helpers/deployer_helpers.rb +245 -56
- data/spec/hybrid_platforms_conductor_test/helpers/executables_helpers.rb +11 -11
- data/spec/hybrid_platforms_conductor_test/helpers/nodes_handler_helpers.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/helpers/platforms_handler_helpers.rb +39 -28
- data/spec/hybrid_platforms_conductor_test/helpers/plugins_helpers.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/helpers/provisioner_proxmox_helpers.rb +86 -111
- data/spec/hybrid_platforms_conductor_test/helpers/reports_handler_helpers.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/helpers/serverless_chef_helpers.rb +3 -3
- data/spec/hybrid_platforms_conductor_test/helpers/services_handler_helpers.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/helpers/tests_runner_helpers.rb +1 -1
- 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
- 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
- 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
- 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
- data/spec/hybrid_platforms_conductor_test/platform_handler_plugins/test.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/platform_handler_plugins/{test2.rb → test_2.rb} +0 -0
- data/spec/hybrid_platforms_conductor_test/rubocop_spec.rb +31 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/nodes/node.json +3 -3
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/nodes/node.json +3 -3
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/libraries/default.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/other_cookbooks/test_cookbook_2/libraries/default.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/shared_examples/deployer.rb +952 -0
- data/spec/hybrid_platforms_conductor_test/test_connector.rb +3 -3
- data/spec/hybrid_platforms_conductor_test/test_log_no_read_plugin.rb +84 -0
- data/spec/hybrid_platforms_conductor_test/test_log_plugin.rb +105 -0
- data/spec/hybrid_platforms_conductor_test/test_plugins/global.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/test_plugins/node.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/test_plugins/node_check.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/test_plugins/platform.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/test_plugins/several_checks.rb +2 -2
- data/spec/hybrid_platforms_conductor_test/test_secrets_reader_plugin.rb +45 -0
- data/spec/hybrid_platforms_conductor_test/tests_report_plugin.rb +5 -6
- data/spec/spec_helper.rb +17 -18
- data/tools/check_md +16 -20
- data/tools/generate_mermaid +1 -1
- metadata +82 -13
- data/spec/hybrid_platforms_conductor_test/helpers/deployer_test_helpers.rb +0 -916
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'monitor'
|
2
2
|
|
3
|
+
# Decorate methods changing the process' current directory with a mutex to ensure they have an exclusive access
|
3
4
|
module HybridPlatformsConductor
|
4
5
|
|
5
6
|
# Implement a global monitor to protect accesses to the current directory.
|
@@ -7,7 +8,9 @@ module HybridPlatformsConductor
|
|
7
8
|
module CurrentDirMonitor
|
8
9
|
|
9
10
|
class << self
|
11
|
+
|
10
12
|
attr_reader :monitor
|
13
|
+
|
11
14
|
end
|
12
15
|
|
13
16
|
@monitor = Monitor.new
|
@@ -24,7 +27,7 @@ module HybridPlatformsConductor
|
|
24
27
|
result = nil
|
25
28
|
CurrentDirMonitor.monitor.synchronize do
|
26
29
|
# puts "TID #{Thread.current.object_id} from #{caller[2]} - Current dir monitor taken from #{Dir.pwd}"
|
27
|
-
result =
|
30
|
+
result = send(original_method_name, *args, &block)
|
28
31
|
# puts "TID #{Thread.current.object_id} from #{caller[2]} - Current dir monitor released back to #{Dir.pwd}"
|
29
32
|
end
|
30
33
|
result
|
@@ -3,7 +3,6 @@ require 'futex'
|
|
3
3
|
require 'json'
|
4
4
|
require 'securerandom'
|
5
5
|
require 'time'
|
6
|
-
require 'thread'
|
7
6
|
require 'hybrid_platforms_conductor/actions_executor'
|
8
7
|
require 'hybrid_platforms_conductor/cmd_runner'
|
9
8
|
require 'hybrid_platforms_conductor/executable'
|
@@ -11,7 +10,6 @@ require 'hybrid_platforms_conductor/logger_helpers'
|
|
11
10
|
require 'hybrid_platforms_conductor/nodes_handler'
|
12
11
|
require 'hybrid_platforms_conductor/services_handler'
|
13
12
|
require 'hybrid_platforms_conductor/plugins'
|
14
|
-
require 'hybrid_platforms_conductor/thycotic'
|
15
13
|
|
16
14
|
module HybridPlatformsConductor
|
17
15
|
|
@@ -21,12 +19,26 @@ module HybridPlatformsConductor
|
|
21
19
|
# Extend the Config DSL
|
22
20
|
module ConfigDSLExtension
|
23
21
|
|
22
|
+
# List of log plugins. Each info has the following properties:
|
23
|
+
# * *nodes_selectors_stack* (Array<Object>): Stack of nodes selectors impacted by this rule.
|
24
|
+
# * *log_plugins* (Array<Symbol>): List of log plugins to be used to store deployment logs.
|
25
|
+
# Array< Hash<Symbol, Object> >
|
26
|
+
attr_reader :deployment_logs
|
27
|
+
|
28
|
+
# List of secrets reader plugins. Each info has the following properties:
|
29
|
+
# * *nodes_selectors_stack* (Array<Object>): Stack of nodes selectors impacted by this rule.
|
30
|
+
# * *secrets_readers* (Array<Symbol>): List of log plugins to be used to store deployment logs.
|
31
|
+
# Array< Hash<Symbol, Object> >
|
32
|
+
attr_reader :secrets_readers
|
33
|
+
|
24
34
|
# Integer: Timeout (in seconds) for packaging repositories
|
25
35
|
attr_reader :packaging_timeout_secs
|
26
36
|
|
27
37
|
# Mixin initializer
|
28
38
|
def init_deployer_config
|
29
39
|
@packaging_timeout_secs = 60
|
40
|
+
@deployment_logs = []
|
41
|
+
@secrets_readers = []
|
30
42
|
end
|
31
43
|
|
32
44
|
# Set the packaging timeout
|
@@ -37,6 +49,28 @@ module HybridPlatformsConductor
|
|
37
49
|
@packaging_timeout_secs = packaging_timeout_secs
|
38
50
|
end
|
39
51
|
|
52
|
+
# Set the deployment log plugins to be used
|
53
|
+
#
|
54
|
+
# Parameters::
|
55
|
+
# * *log_plugins* (Symbol or Array<Symbol>): The list of (or single) log plugins to be used
|
56
|
+
def send_logs_to(*log_plugins)
|
57
|
+
@deployment_logs << {
|
58
|
+
nodes_selectors_stack: current_nodes_selectors_stack,
|
59
|
+
log_plugins: log_plugins.flatten
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
# Set the secrets readers
|
64
|
+
#
|
65
|
+
# Parameters::
|
66
|
+
# * *secrets_readers* (Symbol or Array<Symbol>): The list of (or single) secrets readers plugins to be used
|
67
|
+
def read_secrets_from(*secrets_readers)
|
68
|
+
@secrets_readers << {
|
69
|
+
nodes_selectors_stack: current_nodes_selectors_stack,
|
70
|
+
secrets_readers: secrets_readers.flatten
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
40
74
|
end
|
41
75
|
|
42
76
|
include LoggerHelpers
|
@@ -55,10 +89,6 @@ module HybridPlatformsConductor
|
|
55
89
|
# Boolean
|
56
90
|
attr_accessor :concurrent_execution
|
57
91
|
|
58
|
-
# The list of JSON secrets
|
59
|
-
# Array<Hash>
|
60
|
-
attr_accessor :secrets
|
61
|
-
|
62
92
|
# Are we deploying in a local environment?
|
63
93
|
# Boolean
|
64
94
|
attr_accessor :local_environment
|
@@ -78,8 +108,8 @@ module HybridPlatformsConductor
|
|
78
108
|
# * *actions_executor* (ActionsExecutor): Actions Executor to be used. [default: ActionsExecutor.new]
|
79
109
|
# * *services_handler* (ServicesHandler): Services Handler to be used. [default: ServicesHandler.new]
|
80
110
|
def initialize(
|
81
|
-
logger: Logger.new(
|
82
|
-
logger_stderr: Logger.new(
|
111
|
+
logger: Logger.new($stdout),
|
112
|
+
logger_stderr: Logger.new($stderr),
|
83
113
|
config: Config.new,
|
84
114
|
cmd_runner: CmdRunner.new,
|
85
115
|
nodes_handler: NodesHandler.new,
|
@@ -92,8 +122,36 @@ module HybridPlatformsConductor
|
|
92
122
|
@nodes_handler = nodes_handler
|
93
123
|
@actions_executor = actions_executor
|
94
124
|
@services_handler = services_handler
|
95
|
-
@
|
125
|
+
@override_secrets = nil
|
126
|
+
@secrets_readers = Plugins.new(
|
127
|
+
:secrets_reader,
|
128
|
+
logger: @logger,
|
129
|
+
logger_stderr: @logger_stderr,
|
130
|
+
init_plugin: proc do |plugin_class|
|
131
|
+
plugin_class.new(
|
132
|
+
logger: @logger,
|
133
|
+
logger_stderr: @logger_stderr,
|
134
|
+
config: @config,
|
135
|
+
cmd_runner: @cmd_runner,
|
136
|
+
nodes_handler: @nodes_handler
|
137
|
+
)
|
138
|
+
end
|
139
|
+
)
|
96
140
|
@provisioners = Plugins.new(:provisioner, logger: @logger, logger_stderr: @logger_stderr)
|
141
|
+
@log_plugins = Plugins.new(
|
142
|
+
:log,
|
143
|
+
logger: @logger,
|
144
|
+
logger_stderr: @logger_stderr,
|
145
|
+
init_plugin: proc do |plugin_class|
|
146
|
+
plugin_class.new(
|
147
|
+
logger: @logger,
|
148
|
+
logger_stderr: @logger_stderr,
|
149
|
+
config: @config,
|
150
|
+
nodes_handler: @nodes_handler,
|
151
|
+
actions_executor: @actions_executor
|
152
|
+
)
|
153
|
+
end
|
154
|
+
)
|
97
155
|
# Default values
|
98
156
|
@use_why_run = false
|
99
157
|
@timeout = nil
|
@@ -112,42 +170,32 @@ module HybridPlatformsConductor
|
|
112
170
|
def options_parse(options_parser, parallel_switch: true, why_run_switch: false, timeout_options: true)
|
113
171
|
options_parser.separator ''
|
114
172
|
options_parser.separator 'Deployer options:'
|
115
|
-
|
116
|
-
'-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
secret = thycotic.download_file_attachment_by_item_id(secret_id, secret_file_item_id)
|
130
|
-
raise "Unable to fetch secret file attachment from #{secrets_location}" if secret.nil?
|
131
|
-
end
|
132
|
-
secret
|
133
|
-
else
|
134
|
-
raise "Missing secret file: #{secrets_location}" unless File.exist?(secrets_location)
|
135
|
-
File.read(secrets_location)
|
136
|
-
end
|
137
|
-
)
|
173
|
+
if parallel_switch
|
174
|
+
options_parser.on('-p', '--parallel', 'Execute the commands in parallel (put the standard output in files <hybrid-platforms-dir>/run_logs/*.stdout)') do
|
175
|
+
@concurrent_execution = true
|
176
|
+
end
|
177
|
+
end
|
178
|
+
if timeout_options
|
179
|
+
options_parser.on('-t', '--timeout SECS', "Timeout in seconds to wait for each chef run. Only used in why-run mode. (defaults to #{@timeout.nil? ? 'no timeout' : @timeout})") do |nbr_secs|
|
180
|
+
@timeout = nbr_secs.to_i
|
181
|
+
end
|
182
|
+
end
|
183
|
+
if why_run_switch
|
184
|
+
options_parser.on('-W', '--why-run', 'Use the why-run mode to see what would be the result of the deploy instead of deploying it for real.') do
|
185
|
+
@use_why_run = true
|
186
|
+
end
|
138
187
|
end
|
139
|
-
options_parser.on('-p', '--parallel', 'Execute the commands in parallel (put the standard output in files <hybrid-platforms-dir>/run_logs/*.stdout)') do
|
140
|
-
@concurrent_execution = true
|
141
|
-
end if parallel_switch
|
142
|
-
options_parser.on('-t', '--timeout SECS', "Timeout in seconds to wait for each chef run. Only used in why-run mode. (defaults to #{@timeout.nil? ? 'no timeout' : @timeout})") do |nbr_secs|
|
143
|
-
@timeout = nbr_secs.to_i
|
144
|
-
end if timeout_options
|
145
|
-
options_parser.on('-W', '--why-run', 'Use the why-run mode to see what would be the result of the deploy instead of deploying it for real.') do
|
146
|
-
@use_why_run = true
|
147
|
-
end if why_run_switch
|
148
188
|
options_parser.on('--retries-on-error NBR', "Number of retries in case of non-deterministic errors (defaults to #{@nbr_retries_on_error})") do |nbr_retries|
|
149
189
|
@nbr_retries_on_error = nbr_retries.to_i
|
150
190
|
end
|
191
|
+
# Display options secrets readers might have
|
192
|
+
@secrets_readers.each do |secret_reader_name, secret_reader|
|
193
|
+
next unless secret_reader.respond_to?(:options_parse)
|
194
|
+
|
195
|
+
options_parser.separator ''
|
196
|
+
options_parser.separator "Secrets reader #{secret_reader_name} options:"
|
197
|
+
secret_reader.options_parse(options_parser)
|
198
|
+
end
|
151
199
|
end
|
152
200
|
|
153
201
|
# Validate that parsed parameters are valid
|
@@ -158,6 +206,16 @@ module HybridPlatformsConductor
|
|
158
206
|
# String: File used as a Futex for packaging
|
159
207
|
PACKAGING_FUTEX_FILE = "#{Dir.tmpdir}/hpc_packaging"
|
160
208
|
|
209
|
+
# Override the secrets with a given JSON.
|
210
|
+
# When using this method with a secrets Hash, further deployments will not query secrets readers, but will use those secrets directly.
|
211
|
+
# Useful to override secrets in test conditions when using dummy secrets for example.
|
212
|
+
#
|
213
|
+
# Parameters::
|
214
|
+
# * *secrets* (Hash or nil): Secrets to take into account in place of secrets readers, or nil to cancel a previous overriding and use secrets readers instead.
|
215
|
+
def override_secrets(secrets)
|
216
|
+
@override_secrets = secrets
|
217
|
+
end
|
218
|
+
|
161
219
|
# Deploy on a given list of nodes selectors.
|
162
220
|
# The workflow is the following:
|
163
221
|
# 1. Package the services to be deployed, considering the nodes, services and context (options, secrets, environment...)
|
@@ -171,16 +229,26 @@ module HybridPlatformsConductor
|
|
171
229
|
def deploy_on(*nodes_selectors)
|
172
230
|
# Get the sorted list of services to be deployed, per node
|
173
231
|
# Hash<String, Array<String> >
|
174
|
-
services_to_deploy =
|
232
|
+
services_to_deploy = @nodes_handler.select_nodes(nodes_selectors.flatten).map do |node|
|
175
233
|
[node, @nodes_handler.get_services_of(node)]
|
176
|
-
end
|
234
|
+
end.to_h
|
177
235
|
|
178
236
|
# Get the secrets to be deployed
|
179
237
|
secrets = {}
|
180
|
-
@
|
181
|
-
secrets
|
182
|
-
|
183
|
-
|
238
|
+
if @override_secrets
|
239
|
+
secrets = @override_secrets
|
240
|
+
else
|
241
|
+
services_to_deploy.each do |node, services|
|
242
|
+
# If there is no config for secrets, just use cli
|
243
|
+
(@config.secrets_readers.empty? ? [{ secrets_readers: %i[cli] }] : @nodes_handler.select_confs_for_node(node, @config.secrets_readers)).inject([]) do |secrets_readers, secrets_readers_info|
|
244
|
+
secrets_readers + secrets_readers_info[:secrets_readers]
|
245
|
+
end.sort.uniq.each do |secrets_reader|
|
246
|
+
services.each do |service|
|
247
|
+
node_secrets = @secrets_readers[secrets_reader].secrets_for(node, service)
|
248
|
+
conflicting_path = safe_merge(secrets, node_secrets)
|
249
|
+
raise "Secret set at path #{conflicting_path.join('->')} by #{secrets_reader} for service #{service} on node #{node} has conflicting values (#{log_debug? ? "#{node_secrets.dig(*conflicting_path)} != #{secrets.dig(*conflicting_path)}" : 'set debug for value details'})." unless conflicting_path.nil?
|
250
|
+
end
|
251
|
+
end
|
184
252
|
end
|
185
253
|
end
|
186
254
|
|
@@ -188,7 +256,6 @@ module HybridPlatformsConductor
|
|
188
256
|
unless @use_why_run
|
189
257
|
reason_for_interdiction = @services_handler.deploy_allowed?(
|
190
258
|
services: services_to_deploy,
|
191
|
-
secrets: secrets,
|
192
259
|
local_environment: @local_environment
|
193
260
|
)
|
194
261
|
raise "Deployment not allowed: #{reason_for_interdiction}" unless reason_for_interdiction.nil?
|
@@ -226,51 +293,50 @@ module HybridPlatformsConductor
|
|
226
293
|
remaining_nodes_to_deploy = services_to_deploy.keys
|
227
294
|
while nbr_retries >= 0 && !remaining_nodes_to_deploy.empty?
|
228
295
|
last_deploy_results = deploy(services_to_deploy.slice(*remaining_nodes_to_deploy))
|
229
|
-
if nbr_retries
|
296
|
+
if nbr_retries.positive?
|
230
297
|
# Check if we need to retry deployment on some nodes
|
231
298
|
# Only parse the last deployment attempt logs
|
232
|
-
retriable_nodes =
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
299
|
+
retriable_nodes = remaining_nodes_to_deploy.
|
300
|
+
map do |node|
|
301
|
+
exit_status, stdout, stderr = last_deploy_results[node]
|
302
|
+
if exit_status.zero?
|
303
|
+
nil
|
304
|
+
else
|
305
|
+
retriable_errors = retriable_errors_from(node, exit_status, stdout, stderr)
|
306
|
+
if retriable_errors.empty?
|
237
307
|
nil
|
238
308
|
else
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
else
|
243
|
-
# Log the issue in the stderr of the deployment
|
244
|
-
stderr << "!!! #{retriable_errors.size} retriable errors detected in this deployment:\n#{retriable_errors.map { |error| "* #{error}" }.join("\n")}\n"
|
245
|
-
[node, retriable_errors]
|
246
|
-
end
|
309
|
+
# Log the issue in the stderr of the deployment
|
310
|
+
stderr << "!!! #{retriable_errors.size} retriable errors detected in this deployment:\n#{retriable_errors.map { |error| "* #{error}" }.join("\n")}\n"
|
311
|
+
[node, retriable_errors]
|
247
312
|
end
|
248
|
-
end
|
249
|
-
|
250
|
-
|
313
|
+
end
|
314
|
+
end.
|
315
|
+
compact.
|
316
|
+
to_h
|
251
317
|
unless retriable_nodes.empty?
|
252
|
-
log_warn <<~
|
318
|
+
log_warn <<~EO_LOG.strip
|
253
319
|
Retry deployment for #{retriable_nodes.size} nodes as they got non-deterministic errors (#{nbr_retries} retries remaining):
|
254
320
|
#{retriable_nodes.map { |node, retriable_errors| " * #{node}:\n#{retriable_errors.map { |error| " - #{error}" }.join("\n")}" }.join("\n")}
|
255
|
-
|
321
|
+
EO_LOG
|
256
322
|
end
|
257
323
|
remaining_nodes_to_deploy = retriable_nodes.keys
|
258
324
|
end
|
259
325
|
# Merge deployment results
|
260
|
-
results.merge!(last_deploy_results) do |
|
326
|
+
results.merge!(last_deploy_results) do |_node, (exit_status_1, stdout_1, stderr_1), (exit_status_2, stdout_2, stderr_2)|
|
261
327
|
[
|
262
328
|
exit_status_2,
|
263
|
-
<<~
|
329
|
+
<<~EO_STDOUT,
|
264
330
|
#{stdout_1}
|
265
331
|
Deployment exit status code: #{exit_status_1}
|
266
332
|
!!! Retry deployment due to non-deterministic error (#{nbr_retries} remaining attempts)...
|
267
333
|
#{stdout_2}
|
268
|
-
|
269
|
-
<<~
|
334
|
+
EO_STDOUT
|
335
|
+
<<~EO_STDERR
|
270
336
|
#{stderr_1}
|
271
337
|
!!! Retry deployment due to non-deterministic error (#{nbr_retries} remaining attempts)...
|
272
338
|
#{stderr_2}
|
273
|
-
|
339
|
+
EO_STDERR
|
274
340
|
]
|
275
341
|
end
|
276
342
|
nbr_retries -= 1
|
@@ -325,7 +391,7 @@ module HybridPlatformsConductor
|
|
325
391
|
sub_executable.config.sudo_procs.replace(sub_executable.config.sudo_procs.map do |sudo_proc_info|
|
326
392
|
{
|
327
393
|
nodes_selectors_stack: sudo_proc_info[:nodes_selectors_stack].map do |nodes_selector|
|
328
|
-
@nodes_handler.select_nodes(nodes_selector).
|
394
|
+
@nodes_handler.select_nodes(nodes_selector).reject { |selected_node| selected_node == node }
|
329
395
|
end,
|
330
396
|
sudo_proc: sudo_proc_info[:sudo_proc]
|
331
397
|
}
|
@@ -338,13 +404,13 @@ module HybridPlatformsConductor
|
|
338
404
|
deployer.local_environment = true
|
339
405
|
# Ignore secrets that might have been given: in Docker containers we always use dummy secrets
|
340
406
|
dummy_secrets_file = "#{@config.hybrid_platforms_dir}/dummy_secrets.json"
|
341
|
-
deployer.
|
407
|
+
deployer.override_secrets(File.exist?(dummy_secrets_file) ? JSON.parse(File.read(dummy_secrets_file)) : {})
|
342
408
|
yield deployer, instance
|
343
409
|
end
|
344
410
|
rescue
|
345
411
|
# Make sure Docker logs are being output to better investigate errors if we were not already outputing them in debug mode
|
346
412
|
stdouts = sub_executable.stdouts_to_s
|
347
|
-
log_error "[ #{node}/#{environment} ] - Encountered unhandled exception #{
|
413
|
+
log_error "[ #{node}/#{environment} ] - Encountered unhandled exception #{$ERROR_INFO}\n#{$ERROR_INFO.backtrace.join("\n")}\n-----\n#{stdouts}" unless stdouts.nil?
|
348
414
|
raise
|
349
415
|
end
|
350
416
|
end
|
@@ -355,72 +421,31 @@ module HybridPlatformsConductor
|
|
355
421
|
# * *nodes* (Array<String>): Nodes to get info from
|
356
422
|
# Result::
|
357
423
|
# * Hash<String, Hash<Symbol,Object>: The deployed info, per node name.
|
358
|
-
#
|
359
|
-
# * *
|
424
|
+
# * *error* (String): Error string in case deployment logs could not be retrieved. If set then further properties will be ignored. [optional]
|
425
|
+
# * *services* (Array<String>): List of services deployed on the node
|
426
|
+
# * *deployment_info* (Hash<Symbol,Object>): Deployment metadata
|
427
|
+
# * *exit_status* (Integer or Symbol): Deployment exit status
|
428
|
+
# * *stdout* (String): Deployment stdout
|
429
|
+
# * *stderr* (String): Deployment stderr
|
360
430
|
def deployment_info_from(*nodes)
|
431
|
+
nodes = nodes.flatten
|
361
432
|
@actions_executor.max_threads = 64
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
# ...
|
379
|
-
# PropertyN: ValueN
|
380
|
-
# ===== STDOUT =====
|
381
|
-
# ...
|
382
|
-
deploy_info = {}
|
383
|
-
if exit_status.is_a?(Symbol)
|
384
|
-
deploy_info[:error] = "Error: #{exit_status}\n#{stderr}"
|
385
|
-
else
|
386
|
-
stdout_lines = stdout.split("\n")
|
387
|
-
if stdout_lines.first =~ /No such file or directory/
|
388
|
-
deploy_info[:error] = '/var/log/deployments missing'
|
389
|
-
else
|
390
|
-
stdout_lines.each do |line|
|
391
|
-
if line =~ /^([^:]+): (.+)$/
|
392
|
-
key_str, value = $1, $2
|
393
|
-
key = key_str.to_sym
|
394
|
-
# Type-cast some values
|
395
|
-
case key_str
|
396
|
-
when 'date'
|
397
|
-
# Date and time values
|
398
|
-
# Thu Nov 23 18:43:01 UTC 2017
|
399
|
-
deploy_info[key] = Time.parse(value)
|
400
|
-
when 'debug'
|
401
|
-
# Boolean values
|
402
|
-
# Yes
|
403
|
-
deploy_info[key] = (value == 'Yes')
|
404
|
-
when /^diff_files_.+$/, 'services'
|
405
|
-
# Array of strings
|
406
|
-
# my_file.txt, other_file.txt
|
407
|
-
deploy_info[key] = value.split(', ')
|
408
|
-
else
|
409
|
-
deploy_info[key] = value
|
410
|
-
end
|
411
|
-
else
|
412
|
-
deploy_info[:unknown_lines] = [] unless deploy_info.key?(:unknown_lines)
|
413
|
-
deploy_info[:unknown_lines] << line
|
414
|
-
end
|
415
|
-
end
|
416
|
-
end
|
417
|
-
end
|
418
|
-
[
|
419
|
-
node,
|
420
|
-
deploy_info
|
421
|
-
]
|
422
|
-
end
|
423
|
-
]
|
433
|
+
read_actions_results = @actions_executor.execute_actions(
|
434
|
+
nodes.map do |node|
|
435
|
+
master_log_plugin = @log_plugins[log_plugins_for(node).first]
|
436
|
+
master_log_plugin.respond_to?(:actions_to_read_logs) ? [node, master_log_plugin.actions_to_read_logs(node)] : nil
|
437
|
+
end.compact.to_h,
|
438
|
+
log_to_stdout: false,
|
439
|
+
concurrent: true,
|
440
|
+
timeout: 10,
|
441
|
+
progress_name: 'Read deployment logs'
|
442
|
+
)
|
443
|
+
nodes.map do |node|
|
444
|
+
[
|
445
|
+
node,
|
446
|
+
@log_plugins[log_plugins_for(node).first].logs_for(node, *(read_actions_results[node] || [nil, nil, nil]))
|
447
|
+
]
|
448
|
+
end.to_h
|
424
449
|
end
|
425
450
|
|
426
451
|
# Parse stdout and stderr of a given deploy run and get the list of tasks with their status
|
@@ -436,12 +461,41 @@ module HybridPlatformsConductor
|
|
436
461
|
# * *:changed*: The task has been changed
|
437
462
|
# * *:identical*: The task has not been changed
|
438
463
|
# * *diffs* (String): Differences, if any
|
439
|
-
def parse_deploy_output(
|
464
|
+
def parse_deploy_output(_node, stdout, stderr)
|
440
465
|
@services_handler.parse_deploy_output(stdout, stderr).map { |deploy_info| deploy_info[:tasks] }.flatten
|
441
466
|
end
|
442
467
|
|
443
468
|
private
|
444
469
|
|
470
|
+
# Safe-merge 2 hashes.
|
471
|
+
# Safe-merging is done by:
|
472
|
+
# * Merging values that are hashes.
|
473
|
+
# * Reporting errors when values conflict.
|
474
|
+
# When values are conflicting, the initial hash won't modify those conflicting values and will stop the merge.
|
475
|
+
#
|
476
|
+
# Parameters::
|
477
|
+
# * *hash* (Hash): Hash to be modified merging hash_to_merge
|
478
|
+
# * *hash_to_merge* (Hash): Hash to be merged into hash
|
479
|
+
# Result::
|
480
|
+
# * nil or Array<Object>: nil in case of success, or the keys path leading to a conflicting value in case of error
|
481
|
+
def safe_merge(hash, hash_to_merge)
|
482
|
+
conflicting_path = nil
|
483
|
+
hash_to_merge.each do |key, value_to_merge|
|
484
|
+
if hash.key?(key)
|
485
|
+
if hash[key].is_a?(Hash) && value_to_merge.is_a?(Hash)
|
486
|
+
sub_conflicting_path = safe_merge(hash[key], value_to_merge)
|
487
|
+
conflicting_path = [key] + sub_conflicting_path unless sub_conflicting_path.nil?
|
488
|
+
elsif hash[key] != value_to_merge
|
489
|
+
conflicting_path = [key]
|
490
|
+
end
|
491
|
+
else
|
492
|
+
hash[key] = value_to_merge
|
493
|
+
end
|
494
|
+
break unless conflicting_path.nil?
|
495
|
+
end
|
496
|
+
conflicting_path
|
497
|
+
end
|
498
|
+
|
445
499
|
# Get the list of retriable errors a node got from deployment logs.
|
446
500
|
# Useful to know if an error is non-deterministic (due to external and temporary factors).
|
447
501
|
#
|
@@ -452,7 +506,7 @@ module HybridPlatformsConductor
|
|
452
506
|
# * *stderr* (String): Deployment stderr
|
453
507
|
# Result::
|
454
508
|
# * Array<String>: List of retriable errors that have been matched
|
455
|
-
def retriable_errors_from(node,
|
509
|
+
def retriable_errors_from(node, _exit_status, stdout, stderr)
|
456
510
|
# List of retriable errors for this node, as exact string match or regexps.
|
457
511
|
# Array<String or Regexp>
|
458
512
|
retriable_errors_on_stdout = []
|
@@ -483,59 +537,55 @@ module HybridPlatformsConductor
|
|
483
537
|
# Result::
|
484
538
|
# * Hash<String, [Integer or Symbol, String, String]>: Exit status code (or Symbol in case of error or dry run), standard output and error for each node.
|
485
539
|
def deploy(services)
|
486
|
-
outputs = {}
|
487
|
-
|
488
540
|
# Get the ssh user directly from the connector
|
489
541
|
ssh_user = @actions_executor.connector(:ssh).ssh_user
|
490
542
|
|
491
543
|
# Deploy for real
|
492
544
|
@nodes_handler.prefetch_metadata_of services.keys, :image
|
493
545
|
outputs = @actions_executor.execute_actions(
|
494
|
-
|
546
|
+
services.map do |node, node_services|
|
495
547
|
image_id = @nodes_handler.get_image_of(node)
|
496
548
|
sudo = (ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(node)} ")
|
497
|
-
# Install
|
549
|
+
# Install corporate certificates if present
|
498
550
|
certificate_actions =
|
499
551
|
if @local_environment && ENV['hpc_certificates']
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
}
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
remote_bash: "#{sudo}update-ca-certificates"
|
514
|
-
}
|
515
|
-
]
|
516
|
-
when 'centos_7'
|
517
|
-
[
|
518
|
-
{
|
519
|
-
remote_bash: "#{sudo}yum install -y ca-certificates"
|
552
|
+
raise "Missing path referenced by the hpc_certificates environment variable: #{ENV['hpc_certificates']}" unless File.exist?(ENV['hpc_certificates'])
|
553
|
+
|
554
|
+
log_debug "Deploy certificates from #{ENV['hpc_certificates']}"
|
555
|
+
case image_id
|
556
|
+
when 'debian_9', 'debian_10'
|
557
|
+
[
|
558
|
+
{
|
559
|
+
remote_bash: "#{sudo}apt update && #{sudo}apt install -y ca-certificates"
|
560
|
+
},
|
561
|
+
{
|
562
|
+
scp: {
|
563
|
+
ENV['hpc_certificates'] => '/usr/local/share/ca-certificates',
|
564
|
+
:sudo => ssh_user != 'root'
|
520
565
|
},
|
521
|
-
{
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
566
|
+
remote_bash: "#{sudo}update-ca-certificates"
|
567
|
+
}
|
568
|
+
]
|
569
|
+
when 'centos_7'
|
570
|
+
[
|
571
|
+
{
|
572
|
+
remote_bash: "#{sudo}yum install -y ca-certificates"
|
573
|
+
},
|
574
|
+
{
|
575
|
+
scp: Dir.glob("#{ENV['hpc_certificates']}/*.crt").map do |cert_file|
|
576
|
+
[
|
577
|
+
cert_file,
|
578
|
+
'/etc/pki/ca-trust/source/anchors'
|
531
579
|
]
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
580
|
+
end.to_h.merge(sudo: ssh_user != 'root'),
|
581
|
+
remote_bash: [
|
582
|
+
"#{sudo}update-ca-trust enable",
|
583
|
+
"#{sudo}update-ca-trust extract"
|
584
|
+
]
|
585
|
+
}
|
586
|
+
]
|
537
587
|
else
|
538
|
-
raise "
|
588
|
+
raise "Unknown image ID for node #{node}: #{image_id}. Check metadata for this node."
|
539
589
|
end
|
540
590
|
else
|
541
591
|
[]
|
@@ -552,19 +602,19 @@ module HybridPlatformsConductor
|
|
552
602
|
certificate_actions +
|
553
603
|
@services_handler.actions_to_deploy_on(node, node_services, @use_why_run)
|
554
604
|
]
|
555
|
-
end
|
605
|
+
end.to_h,
|
556
606
|
timeout: @timeout,
|
557
607
|
concurrent: @concurrent_execution,
|
558
608
|
log_to_stdout: !@concurrent_execution
|
559
609
|
)
|
560
610
|
# Free eventual locks
|
561
611
|
@actions_executor.execute_actions(
|
562
|
-
|
612
|
+
services.keys.map do |node|
|
563
613
|
[
|
564
614
|
node,
|
565
615
|
{ remote_bash: "#{ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(node)} "}./mutex_dir unlock /tmp/hybrid_platforms_conductor_deploy_lock" }
|
566
616
|
]
|
567
|
-
end
|
617
|
+
end.to_h,
|
568
618
|
timeout: 10,
|
569
619
|
concurrent: true,
|
570
620
|
log_to_dir: nil
|
@@ -584,47 +634,48 @@ module HybridPlatformsConductor
|
|
584
634
|
# * *services* (Hash<String, Array<String>>): List of services that have been deployed, per node
|
585
635
|
def save_logs(logs, services)
|
586
636
|
section "Saving deployment logs for #{logs.size} nodes" do
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
end
|
637
|
+
ssh_user = @actions_executor.connector(:ssh).ssh_user
|
638
|
+
@actions_executor.execute_actions(
|
639
|
+
logs.map do |node, (exit_status, stdout, stderr)|
|
640
|
+
[
|
641
|
+
node,
|
642
|
+
log_plugins_for(node).
|
643
|
+
map do |log_plugin|
|
644
|
+
@log_plugins[log_plugin].actions_to_save_logs(
|
645
|
+
node,
|
646
|
+
services[node],
|
647
|
+
@services_handler.log_info_for(node, services[node]).merge(
|
648
|
+
date: Time.now.utc.strftime('%F %T'),
|
649
|
+
user: ssh_user
|
650
|
+
),
|
651
|
+
exit_status,
|
652
|
+
stdout,
|
653
|
+
stderr
|
654
|
+
)
|
655
|
+
end.
|
656
|
+
flatten(1)
|
657
|
+
]
|
658
|
+
end.to_h,
|
659
|
+
timeout: 10,
|
660
|
+
concurrent: true,
|
661
|
+
log_to_dir: nil,
|
662
|
+
progress_name: 'Saving logs'
|
663
|
+
)
|
664
|
+
end
|
665
|
+
end
|
666
|
+
|
667
|
+
# Get the list of log plugins to be used for a given node
|
668
|
+
#
|
669
|
+
# Parameters::
|
670
|
+
# * *node* (String): The node for which log plugins are queried
|
671
|
+
# Result::
|
672
|
+
# * Array<Symbol>: The list of log plugins
|
673
|
+
def log_plugins_for(node)
|
674
|
+
node_log_plugins = @nodes_handler.select_confs_for_node(node, @config.deployment_logs).inject([]) do |log_plugins, deployment_logs_info|
|
675
|
+
log_plugins + deployment_logs_info[:log_plugins]
|
627
676
|
end
|
677
|
+
node_log_plugins << :remote_fs if node_log_plugins.empty?
|
678
|
+
node_log_plugins
|
628
679
|
end
|
629
680
|
|
630
681
|
end
|