hybrid_platforms_conductor 32.3.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/check-node +24 -0
- data/bin/deploy +12 -0
- data/bin/dump_nodes_json +12 -0
- data/bin/free_ips +23 -0
- data/bin/free_veids +17 -0
- data/bin/get_impacted_nodes +43 -0
- data/bin/last_deploys +56 -0
- data/bin/nodes_to_deploy +104 -0
- data/bin/report +10 -0
- data/bin/run +39 -0
- data/bin/setup +11 -0
- data/bin/ssh_config +14 -0
- data/bin/test +13 -0
- data/bin/topograph +54 -0
- data/lib/hybrid_platforms_conductor/action.rb +82 -0
- data/lib/hybrid_platforms_conductor/actions_executor.rb +307 -0
- data/lib/hybrid_platforms_conductor/bitbucket.rb +123 -0
- data/lib/hybrid_platforms_conductor/cmd_runner.rb +188 -0
- data/lib/hybrid_platforms_conductor/cmdb.rb +34 -0
- data/lib/hybrid_platforms_conductor/common_config_dsl/bitbucket.rb +78 -0
- data/lib/hybrid_platforms_conductor/common_config_dsl/confluence.rb +43 -0
- data/lib/hybrid_platforms_conductor/common_config_dsl/file_system_tests.rb +110 -0
- data/lib/hybrid_platforms_conductor/common_config_dsl/idempotence_tests.rb +38 -0
- data/lib/hybrid_platforms_conductor/config.rb +263 -0
- data/lib/hybrid_platforms_conductor/confluence.rb +119 -0
- data/lib/hybrid_platforms_conductor/connector.rb +84 -0
- data/lib/hybrid_platforms_conductor/credentials.rb +127 -0
- data/lib/hybrid_platforms_conductor/current_dir_monitor.rb +42 -0
- data/lib/hybrid_platforms_conductor/deployer.rb +598 -0
- data/lib/hybrid_platforms_conductor/executable.rb +145 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/action/bash.rb +44 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/action/interactive.rb +44 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/action/my_action.rb.sample +79 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/action/remote_bash.rb +63 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/action/ruby.rb +69 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/action/scp.rb +61 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/config.rb +78 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/host_ip.rb +104 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/host_keys.rb +114 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/my_cmdb.rb.sample +129 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/platform_handlers.rb +66 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/my_connector.rb.sample +156 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +702 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/platform_handler_plugin.rb.sample +292 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/docker.rb +148 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/my_provisioner.rb.sample +103 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/podman.rb +125 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox.rb +522 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox/proxmox_waiter.rb +707 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox/reserve_proxmox_container +122 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/report/confluence.rb +69 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/report/mediawiki.rb +164 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/report/my_report_plugin.rb.sample +88 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/report/stdout.rb +61 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/report/templates/confluence_inventory.html.erb +33 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/bitbucket_conf.rb +137 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/can_be_checked.rb +21 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/check_deploy_and_idempotence.rb +112 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/check_from_scratch.rb +35 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/connection.rb +28 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_freshness.rb +44 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_from_scratch.rb +36 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +49 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/divergence.rb +25 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/executables.rb +46 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system.rb +45 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system_hdfs.rb +45 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +25 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/idempotence.rb +77 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +38 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/jenkins_ci_conf.rb +56 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/jenkins_ci_masters_ok.rb +54 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/linear_strategy.rb +47 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +82 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +120 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/my_test_plugin.rb.sample +143 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +74 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/ports.rb +85 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/private_ips.rb +38 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/public_ips.rb +38 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre-meltdown-checker.sh +1930 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +56 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/veids.rb +31 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +159 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/confluence.rb +122 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/my_test_report.rb.sample +48 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/stdout.rb +120 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/templates/_confluence_errors_status.html.erb +46 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/templates/_confluence_gauge.html.erb +49 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/templates/confluence.html.erb +242 -0
- data/lib/hybrid_platforms_conductor/io_router.rb +70 -0
- data/lib/hybrid_platforms_conductor/json_dumper.rb +88 -0
- data/lib/hybrid_platforms_conductor/logger_helpers.rb +319 -0
- data/lib/hybrid_platforms_conductor/mutex_dir +76 -0
- data/lib/hybrid_platforms_conductor/nodes_handler.rb +597 -0
- data/lib/hybrid_platforms_conductor/parallel_threads.rb +97 -0
- data/lib/hybrid_platforms_conductor/platform_handler.rb +188 -0
- data/lib/hybrid_platforms_conductor/platforms_handler.rb +118 -0
- data/lib/hybrid_platforms_conductor/plugin.rb +53 -0
- data/lib/hybrid_platforms_conductor/plugins.rb +101 -0
- data/lib/hybrid_platforms_conductor/provisioner.rb +181 -0
- data/lib/hybrid_platforms_conductor/report.rb +31 -0
- data/lib/hybrid_platforms_conductor/reports_handler.rb +84 -0
- data/lib/hybrid_platforms_conductor/services_handler.rb +274 -0
- data/lib/hybrid_platforms_conductor/test.rb +141 -0
- data/lib/hybrid_platforms_conductor/test_by_service.rb +22 -0
- data/lib/hybrid_platforms_conductor/test_report.rb +282 -0
- data/lib/hybrid_platforms_conductor/tests_runner.rb +590 -0
- data/lib/hybrid_platforms_conductor/thycotic.rb +92 -0
- data/lib/hybrid_platforms_conductor/topographer.rb +859 -0
- data/lib/hybrid_platforms_conductor/topographer/plugin.rb +20 -0
- data/lib/hybrid_platforms_conductor/topographer/plugins/graphviz.rb +127 -0
- data/lib/hybrid_platforms_conductor/topographer/plugins/json.rb +72 -0
- data/lib/hybrid_platforms_conductor/topographer/plugins/my_topographer_output_plugin.rb.sample +37 -0
- data/lib/hybrid_platforms_conductor/topographer/plugins/svg.rb +30 -0
- data/lib/hybrid_platforms_conductor/version.rb +5 -0
- data/spec/hybrid_platforms_conductor_test.rb +159 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/bash_spec.rb +43 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/interactive_spec.rb +18 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/remote_bash_spec.rb +102 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/ruby_spec.rb +108 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/scp_spec.rb +79 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions_spec.rb +199 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connection_spec.rb +212 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/cli_options_spec.rb +125 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/config_dsl_spec.rb +50 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connectable_nodes_spec.rb +28 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connections_spec.rb +448 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/global_helpers_spec.rb +313 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/node_helpers_spec.rb +32 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb +134 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/logging_spec.rb +256 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/parallel_spec.rb +338 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/timeout_spec.rb +101 -0
- data/spec/hybrid_platforms_conductor_test/api/cmd_runner_spec.rb +165 -0
- data/spec/hybrid_platforms_conductor_test/api/config_spec.rb +238 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/check_spec.rb +9 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/deploy_spec.rb +243 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/parse_deploy_output_spec.rb +104 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioner_spec.rb +131 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/docker/Dockerfile +10 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/docker_spec.rb +123 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/podman_spec.rb +211 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/config_dsl_spec.rb +126 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/create_spec.rb +290 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/destroy_spec.rb +43 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/ip_spec.rb +60 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/proxmox.json +3 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/destroy_vm_spec.rb +82 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/expired_containers_spec.rb +786 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/ips_assignment_spec.rb +112 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/other_lxc_containers_resources_spec.rb +190 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/pve_node_resources_spec.rb +200 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/retries_spec.rb +35 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/reserve_proxmox_container/vm_ids_assignment_spec.rb +67 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/start_spec.rb +79 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/state_spec.rb +28 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioners/proxmox/stop_spec.rb +41 -0
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/config_spec.rb +33 -0
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/host_ip_spec.rb +64 -0
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/host_keys_spec.rb +133 -0
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/platform_handlers_spec.rb +19 -0
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs_plugins_api_spec.rb +446 -0
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/common_spec.rb +127 -0
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/git_diff_impacts_spec.rb +318 -0
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/nodes_selectors_spec.rb +132 -0
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/platform_handlers_plugins_api_spec.rb +60 -0
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/several_platforms_spec.rb +58 -0
- data/spec/hybrid_platforms_conductor_test/api/platform_handler_spec.rb +97 -0
- data/spec/hybrid_platforms_conductor_test/api/platforms_handler_spec.rb +104 -0
- data/spec/hybrid_platforms_conductor_test/api/plugins_spec.rb +243 -0
- data/spec/hybrid_platforms_conductor_test/api/reports_handler_spec.rb +44 -0
- data/spec/hybrid_platforms_conductor_test/api/services_handler/actions_to_deploy_spec.rb +121 -0
- data/spec/hybrid_platforms_conductor_test/api/services_handler/deploy_allowed_spec.rb +142 -0
- data/spec/hybrid_platforms_conductor_test/api/services_handler/log_info_spec.rb +101 -0
- data/spec/hybrid_platforms_conductor_test/api/services_handler/package_spec.rb +388 -0
- data/spec/hybrid_platforms_conductor_test/api/services_handler/parse_deploy_output_spec.rb +274 -0
- data/spec/hybrid_platforms_conductor_test/api/services_handler/prepare_for_deploy_spec.rb +264 -0
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/common_spec.rb +194 -0
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/global_spec.rb +37 -0
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_check_spec.rb +194 -0
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_spec.rb +137 -0
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/node_ssh_spec.rb +257 -0
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/platform_spec.rb +110 -0
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/reports_spec.rb +367 -0
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/bitbucket_conf_spec.rb +111 -0
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_reports_plugins/confluence_spec.rb +29 -0
- data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb.rb +166 -0
- data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb2.rb +93 -0
- data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb_others.rb +60 -0
- data/spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb_others2.rb +58 -0
- data/spec/hybrid_platforms_conductor_test/executables/check-node_spec.rb +35 -0
- data/spec/hybrid_platforms_conductor_test/executables/deploy_spec.rb +35 -0
- data/spec/hybrid_platforms_conductor_test/executables/get_impacted_nodes_spec.rb +158 -0
- data/spec/hybrid_platforms_conductor_test/executables/last_deploys_spec.rb +173 -0
- data/spec/hybrid_platforms_conductor_test/executables/nodes_to_deploy_spec.rb +283 -0
- data/spec/hybrid_platforms_conductor_test/executables/options/actions_executor_spec.rb +28 -0
- data/spec/hybrid_platforms_conductor_test/executables/options/cmd_runner_spec.rb +28 -0
- data/spec/hybrid_platforms_conductor_test/executables/options/common_spec.rb +67 -0
- data/spec/hybrid_platforms_conductor_test/executables/options/deployer_spec.rb +251 -0
- data/spec/hybrid_platforms_conductor_test/executables/options/nodes_handler_spec.rb +111 -0
- data/spec/hybrid_platforms_conductor_test/executables/options/nodes_selectors_spec.rb +71 -0
- data/spec/hybrid_platforms_conductor_test/executables/options/reports_handler_spec.rb +54 -0
- data/spec/hybrid_platforms_conductor_test/executables/options/tests_runner_spec.rb +139 -0
- data/spec/hybrid_platforms_conductor_test/executables/report_spec.rb +60 -0
- data/spec/hybrid_platforms_conductor_test/executables/run_spec.rb +173 -0
- data/spec/hybrid_platforms_conductor_test/executables/ssh_config_spec.rb +35 -0
- data/spec/hybrid_platforms_conductor_test/executables/test_spec.rb +41 -0
- data/spec/hybrid_platforms_conductor_test/helpers/actions_executor_helpers.rb +98 -0
- data/spec/hybrid_platforms_conductor_test/helpers/cmd_runner_helpers.rb +92 -0
- data/spec/hybrid_platforms_conductor_test/helpers/cmdb_helpers.rb +37 -0
- data/spec/hybrid_platforms_conductor_test/helpers/config_helpers.rb +20 -0
- data/spec/hybrid_platforms_conductor_test/helpers/connector_ssh_helpers.rb +130 -0
- data/spec/hybrid_platforms_conductor_test/helpers/deployer_helpers.rb +149 -0
- data/spec/hybrid_platforms_conductor_test/helpers/deployer_test_helpers.rb +812 -0
- data/spec/hybrid_platforms_conductor_test/helpers/executables_helpers.rb +96 -0
- data/spec/hybrid_platforms_conductor_test/helpers/nodes_handler_helpers.rb +20 -0
- data/spec/hybrid_platforms_conductor_test/helpers/platform_handler_helpers.rb +35 -0
- data/spec/hybrid_platforms_conductor_test/helpers/platforms_handler_helpers.rb +127 -0
- data/spec/hybrid_platforms_conductor_test/helpers/plugins_helpers.rb +48 -0
- data/spec/hybrid_platforms_conductor_test/helpers/provisioner_proxmox_helpers.rb +789 -0
- data/spec/hybrid_platforms_conductor_test/helpers/reports_handler_helpers.rb +29 -0
- data/spec/hybrid_platforms_conductor_test/helpers/services_handler_helpers.rb +20 -0
- data/spec/hybrid_platforms_conductor_test/helpers/tests_runner_helpers.rb +38 -0
- data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem/hpc_plugins/test_plugin_type/test_plugin_id1.rb +22 -0
- data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem/hpc_plugins/test_plugin_type/test_plugin_id2.rb +22 -0
- data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem2/sub_dir/hpc_plugins/test_plugin_type/test_plugin_id3.rb +26 -0
- data/spec/hybrid_platforms_conductor_test/mocked_lib/my_test_gem2/sub_dir/hpc_plugins/test_plugin_type2/test_plugin_id4.rb +26 -0
- data/spec/hybrid_platforms_conductor_test/platform_handler_plugins/test.rb +225 -0
- data/spec/hybrid_platforms_conductor_test/platform_handler_plugins/test2.rb +11 -0
- data/spec/hybrid_platforms_conductor_test/report_plugin.rb +35 -0
- data/spec/hybrid_platforms_conductor_test/test_action.rb +66 -0
- data/spec/hybrid_platforms_conductor_test/test_connector.rb +151 -0
- data/spec/hybrid_platforms_conductor_test/test_plugins/global.rb +30 -0
- data/spec/hybrid_platforms_conductor_test/test_plugins/node.rb +53 -0
- data/spec/hybrid_platforms_conductor_test/test_plugins/node_check.rb +47 -0
- data/spec/hybrid_platforms_conductor_test/test_plugins/node_ssh.rb +42 -0
- data/spec/hybrid_platforms_conductor_test/test_plugins/platform.rb +50 -0
- data/spec/hybrid_platforms_conductor_test/test_plugins/several_checks.rb +50 -0
- data/spec/hybrid_platforms_conductor_test/test_provisioner.rb +95 -0
- data/spec/hybrid_platforms_conductor_test/tests_report_plugin.rb +49 -0
- data/spec/spec_helper.rb +111 -0
- metadata +566 -0
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'hybrid_platforms_conductor/logger_helpers'
|
2
|
+
require 'hybrid_platforms_conductor/plugin'
|
3
|
+
|
4
|
+
module HybridPlatformsConductor
|
5
|
+
|
6
|
+
# Base class for any action that could be run on a node.
|
7
|
+
class Action < Plugin
|
8
|
+
|
9
|
+
# Constructor
|
10
|
+
#
|
11
|
+
# Parameters::
|
12
|
+
# * *logger* (Logger): Logger to be used [default: Logger.new(STDOUT)]
|
13
|
+
# * *logger_stderr* (Logger): Logger to be used for stderr [default: Logger.new(STDERR)]
|
14
|
+
# * *config* (Config): Config to be used. [default: Config.new]
|
15
|
+
# * *cmd_runner* (CmdRunner): Command executor to be used. [default: CmdRunner.new]
|
16
|
+
# * *actions_executor* (ActionsExecutor): Actions Executor to be used. [default: ActionsExecutor.new]
|
17
|
+
# * *action_info* (Object or nil): Action info needed to setup the action, or nil if none [default: nil]
|
18
|
+
def initialize(
|
19
|
+
logger: Logger.new(STDOUT),
|
20
|
+
logger_stderr: Logger.new(STDERR),
|
21
|
+
config: Config.new,
|
22
|
+
cmd_runner: CmdRunner.new,
|
23
|
+
actions_executor: ActionsExecutor.new,
|
24
|
+
action_info: nil
|
25
|
+
)
|
26
|
+
super(logger: logger, logger_stderr: logger_stderr, config: config)
|
27
|
+
@cmd_runner = cmd_runner
|
28
|
+
@actions_executor = actions_executor
|
29
|
+
@action_info = action_info
|
30
|
+
setup(@action_info) if self.respond_to?(:setup)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Do we need a connector to execute this action on a node?
|
34
|
+
#
|
35
|
+
# Result::
|
36
|
+
# * Boolean: Do we need a connector to execute this action on a node?
|
37
|
+
def need_connector?
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
# Prepare an action to be run for a given node in a given context.
|
42
|
+
# It is required to call this method before executing the action.
|
43
|
+
#
|
44
|
+
# Paramaters::
|
45
|
+
# * *node* (String): The node this actions is targetting
|
46
|
+
# * *connector* (Connector or nil): Connector to use to connect to this node, or nil if none
|
47
|
+
# * *timeout* (Integer or nil): Timeout this action should have (in seconds), or nil if none
|
48
|
+
# * *stdout_io* (IO): IO to log stdout to
|
49
|
+
# * *stderr_io* (IO): IO to log stderr to
|
50
|
+
def prepare_for(node, connector, timeout, stdout_io, stderr_io)
|
51
|
+
@node = node
|
52
|
+
@connector = connector
|
53
|
+
@timeout = timeout
|
54
|
+
@stdout_io = stdout_io
|
55
|
+
@stderr_io = stderr_io
|
56
|
+
@connector.prepare_for(@node, @timeout, @stdout_io, @stderr_io) if @connector
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# Run a command.
|
62
|
+
# Handle the redirection of standard output and standard error to file and stdout depending on the context of the run.
|
63
|
+
#
|
64
|
+
# Parameters::
|
65
|
+
# * *cmd* (String): The command to be run
|
66
|
+
# Result::
|
67
|
+
# * Integer: Exit code
|
68
|
+
# * String: Standard output
|
69
|
+
# * String: Error output
|
70
|
+
def run_cmd(cmd)
|
71
|
+
@cmd_runner.run_cmd(
|
72
|
+
cmd,
|
73
|
+
timeout: @timeout,
|
74
|
+
log_to_stdout: false,
|
75
|
+
log_stdout_to_io: @stdout_io,
|
76
|
+
log_stderr_to_io: @stderr_io
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,307 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'futex'
|
3
|
+
require 'logger'
|
4
|
+
require 'securerandom'
|
5
|
+
require 'tmpdir'
|
6
|
+
require 'hybrid_platforms_conductor/action'
|
7
|
+
require 'hybrid_platforms_conductor/cmd_runner'
|
8
|
+
require 'hybrid_platforms_conductor/connector'
|
9
|
+
require 'hybrid_platforms_conductor/io_router'
|
10
|
+
require 'hybrid_platforms_conductor/logger_helpers'
|
11
|
+
require 'hybrid_platforms_conductor/nodes_handler'
|
12
|
+
require 'hybrid_platforms_conductor/plugins'
|
13
|
+
|
14
|
+
module HybridPlatformsConductor
|
15
|
+
|
16
|
+
# Gives ways to execute actions on the nodes
|
17
|
+
class ActionsExecutor
|
18
|
+
|
19
|
+
# Error class returned when the issue is due to a connection issue to the node
|
20
|
+
class ConnectionError < RuntimeError
|
21
|
+
end
|
22
|
+
|
23
|
+
include LoggerHelpers
|
24
|
+
|
25
|
+
# Maximum number of threads to spawn in parallel [default: 8]
|
26
|
+
# Integer
|
27
|
+
attr_accessor :max_threads
|
28
|
+
|
29
|
+
# Constructor
|
30
|
+
#
|
31
|
+
# Parameters::
|
32
|
+
# * *logger* (Logger): Logger to be used [default = Logger.new(STDOUT)]
|
33
|
+
# * *logger_stderr* (Logger): Logger to be used for stderr [default = Logger.new(STDERR)]
|
34
|
+
# * *config* (Config): Config to be used. [default = Config.new]
|
35
|
+
# * *cmd_runner* (CmdRunner): Command runner to be used. [default = CmdRunner.new]
|
36
|
+
# * *nodes_handler* (NodesHandler): Nodes handler to be used. [default = NodesHandler.new]
|
37
|
+
def initialize(logger: Logger.new(STDOUT), logger_stderr: Logger.new(STDERR), config: Config.new, cmd_runner: CmdRunner.new, nodes_handler: NodesHandler.new)
|
38
|
+
init_loggers(logger, logger_stderr)
|
39
|
+
@config = config
|
40
|
+
@cmd_runner = cmd_runner
|
41
|
+
@nodes_handler = nodes_handler
|
42
|
+
# Default values
|
43
|
+
@max_threads = 16
|
44
|
+
@action_plugins = Plugins.new(:action, logger: @logger, logger_stderr: @logger_stderr)
|
45
|
+
@connector_plugins = Plugins.new(
|
46
|
+
:connector,
|
47
|
+
logger: @logger,
|
48
|
+
logger_stderr: @logger_stderr,
|
49
|
+
init_plugin: proc do |plugin_class|
|
50
|
+
plugin_class.new(
|
51
|
+
logger: @logger,
|
52
|
+
logger_stderr: @logger_stderr,
|
53
|
+
config: @config,
|
54
|
+
cmd_runner: @cmd_runner,
|
55
|
+
nodes_handler: @nodes_handler
|
56
|
+
)
|
57
|
+
end
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Complete an option parser with options meant to control this Actions Executor
|
62
|
+
#
|
63
|
+
# Parameters::
|
64
|
+
# * *options_parser* (OptionParser): The option parser to complete
|
65
|
+
# * *parallel* (Boolean): Do we activate options regarding parallel execution? [default = true]
|
66
|
+
def options_parse(options_parser, parallel: true)
|
67
|
+
if parallel
|
68
|
+
options_parser.separator ''
|
69
|
+
options_parser.separator 'Actions Executor options:'
|
70
|
+
options_parser.on('-m', '--max-threads NBR', "Set the number of threads to use for concurrent queries (defaults to #{@max_threads})") do |nbr_threads|
|
71
|
+
@max_threads = nbr_threads.to_i
|
72
|
+
end
|
73
|
+
end
|
74
|
+
# Display options connectors might have
|
75
|
+
@connector_plugins.each do |connector_name, connector|
|
76
|
+
if connector.respond_to?(:options_parse)
|
77
|
+
options_parser.separator ''
|
78
|
+
options_parser.separator "Connector #{connector_name} options:"
|
79
|
+
connector.options_parse(options_parser)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Validate that parsed parameters are valid
|
85
|
+
def validate_params
|
86
|
+
@connector_plugins.values.each do |connector|
|
87
|
+
connector.validate_params if connector.respond_to?(:validate_params)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Execute actions on nodes.
|
92
|
+
#
|
93
|
+
# Parameters::
|
94
|
+
# * *actions_per_nodes* (Hash<Object, Hash<Symbol,Object> or Array< Hash<Symbol,Object> >): Actions (as a Hash of actions or a list of Hash), per nodes selector.
|
95
|
+
# See NodesHandler#select_nodes for details about possible nodes selectors.
|
96
|
+
# See each action's setup in actions directory to know about the possible action types and data.
|
97
|
+
# * *timeout* (Integer): Timeout in seconds, or nil if none. [default: nil]
|
98
|
+
# * *concurrent* (Boolean): Do we run the commands in parallel? If yes, then stdout of commands is stored in log files. [default: false]
|
99
|
+
# * *log_to_dir* (String or nil): Directory name to store log files. Can be nil to not store log files. [default: "#{@config.hybrid_platforms_dir}/run_logs"]
|
100
|
+
# * *log_to_stdout* (Boolean): Do we log the command result on stdout? [default: true]
|
101
|
+
# * *progress_name* (String): Name to display on the progress bar [default: 'Executing actions']
|
102
|
+
# Result::
|
103
|
+
# * 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.
|
104
|
+
def execute_actions(actions_per_nodes, timeout: nil, concurrent: false, log_to_dir: "#{@config.hybrid_platforms_dir}/run_logs", log_to_stdout: true, progress_name: 'Executing actions')
|
105
|
+
# Keep a list of nodes that will need remote access
|
106
|
+
nodes_needing_connectors = []
|
107
|
+
# Compute the ordered list of actions per selected node
|
108
|
+
# Hash< String, Array< [Symbol, Object ]> >
|
109
|
+
# Hash< node, Array< [action_type, action_data]> >
|
110
|
+
actions_per_node = {}
|
111
|
+
actions_per_nodes.each do |nodes_selector, nodes_actions|
|
112
|
+
# Resolved actions, as Action objects
|
113
|
+
resolved_nodes_actions = []
|
114
|
+
need_remote = false
|
115
|
+
(nodes_actions.is_a?(Array) ? nodes_actions : [nodes_actions]).each do |nodes_actions_set|
|
116
|
+
nodes_actions_set.each do |action_type, action_info|
|
117
|
+
raise 'Cannot have concurrent executions for interactive sessions' if concurrent && action_type == :interactive && action_info
|
118
|
+
raise "Unknown action type #{action_type}" unless @action_plugins.key?(action_type)
|
119
|
+
action = @action_plugins[action_type].new(
|
120
|
+
logger: @logger,
|
121
|
+
logger_stderr: @logger_stderr,
|
122
|
+
config: @config,
|
123
|
+
cmd_runner: @cmd_runner,
|
124
|
+
actions_executor: self,
|
125
|
+
action_info: action_info
|
126
|
+
)
|
127
|
+
need_remote = true if action.need_connector?
|
128
|
+
resolved_nodes_actions << action
|
129
|
+
end
|
130
|
+
end
|
131
|
+
# Resolve nodes
|
132
|
+
resolved_nodes = @nodes_handler.select_nodes(nodes_selector)
|
133
|
+
nodes_needing_connectors.concat(resolved_nodes) if need_remote
|
134
|
+
resolved_nodes.each do |node|
|
135
|
+
actions_per_node[node] = [] unless actions_per_node.key?(node)
|
136
|
+
actions_per_node[node].concat(resolved_nodes_actions)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
result = Hash[actions_per_node.keys.map { |node| [node, nil] }]
|
140
|
+
with_connections_prepared_to(nodes_needing_connectors, no_exception: true) do |connected_nodes|
|
141
|
+
missing_nodes = []
|
142
|
+
connected_nodes.each do |node, connector|
|
143
|
+
if connector.is_a?(Symbol)
|
144
|
+
result[node] = [connector, '', "Unable to get a connector to #{node}"]
|
145
|
+
missing_nodes << node
|
146
|
+
end
|
147
|
+
end
|
148
|
+
accessible_nodes = actions_per_node.keys - missing_nodes
|
149
|
+
log_debug "Running actions on #{accessible_nodes.size} nodes#{log_to_dir.nil? ? '' : " (logs dumped in #{log_to_dir})"}"
|
150
|
+
# Prepare the result (stdout or nil per node)
|
151
|
+
unless accessible_nodes.empty?
|
152
|
+
# If we run in parallel then clone the connectors, so that each node has its own instance for thread-safe code.
|
153
|
+
connected_nodes = Hash[connected_nodes.map { |node, connector| [node, connector.clone] }] if concurrent
|
154
|
+
@nodes_handler.for_each_node_in(
|
155
|
+
accessible_nodes,
|
156
|
+
parallel: concurrent,
|
157
|
+
nbr_threads_max: @max_threads,
|
158
|
+
progress: progress_name
|
159
|
+
) do |node|
|
160
|
+
node_actions = actions_per_node[node]
|
161
|
+
# If we run in parallel then clone the actions, so that each node has its own instance for thread-safe code.
|
162
|
+
node_actions.map!(&:clone) if concurrent
|
163
|
+
result[node] = execute_actions_on(
|
164
|
+
node,
|
165
|
+
node_actions,
|
166
|
+
connected_nodes[node],
|
167
|
+
timeout: timeout,
|
168
|
+
log_to_file: log_to_dir.nil? ? nil : "#{log_to_dir}/#{node}.stdout",
|
169
|
+
log_to_stdout: log_to_stdout
|
170
|
+
)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
result
|
175
|
+
end
|
176
|
+
|
177
|
+
# Prepare connections to a set of nodes
|
178
|
+
#
|
179
|
+
# Parameters::
|
180
|
+
# * *nodes* (Array<String>): List of nodes to connect to
|
181
|
+
# * *no_exception* (Boolean): Should we continue even if some nodes can't be connected to? [default: false]
|
182
|
+
# * Proc: Code called with connections prepared
|
183
|
+
# * Parameters::
|
184
|
+
# * *connected_nodes* (Hash<String, Connector or Symbol>): Prepared connectors (or Symbol in case of failure with no_exception), per node name
|
185
|
+
def with_connections_prepared_to(nodes, no_exception: false)
|
186
|
+
# Make sure every node needing connectors finds a connector
|
187
|
+
nodes_needing_connectors = Hash[nodes.map { |node| [node, nil] }]
|
188
|
+
@connector_plugins.each do |connector_name, connector|
|
189
|
+
nodes_without_connectors = nodes_needing_connectors.select { |_node, selected_connector| selected_connector.nil? }.keys
|
190
|
+
break if nodes_without_connectors.empty?
|
191
|
+
(connector.connectable_nodes_from(nodes_without_connectors) & nodes_without_connectors).each do |node|
|
192
|
+
nodes_needing_connectors[node] = connector if nodes_needing_connectors[node].nil?
|
193
|
+
end
|
194
|
+
end
|
195
|
+
# If some nodes need connectors but can't find any, then fail
|
196
|
+
nodes_without_connectors = nodes_needing_connectors.select { |_node, selected_connector| selected_connector.nil? }.keys
|
197
|
+
unless nodes_without_connectors.empty?
|
198
|
+
message = "The following nodes have no possible connector to them: #{nodes_without_connectors.sort.join(', ')}"
|
199
|
+
log_warn message
|
200
|
+
raise message unless no_exception
|
201
|
+
end
|
202
|
+
# Prepare the connectors to operate on the nodes they have been assigned to
|
203
|
+
preparation_code = proc do |remaining_plugins_to_prepare|
|
204
|
+
connector_name = remaining_plugins_to_prepare.first
|
205
|
+
if connector_name.nil?
|
206
|
+
# All plugins have been prepared.
|
207
|
+
# Call our client code.
|
208
|
+
yield Hash[nodes_needing_connectors.map do |node, selected_connector|
|
209
|
+
[
|
210
|
+
node,
|
211
|
+
selected_connector.nil? ? :no_connector : selected_connector
|
212
|
+
]
|
213
|
+
end]
|
214
|
+
else
|
215
|
+
connector = @connector_plugins[connector_name]
|
216
|
+
selected_nodes = nodes_needing_connectors.select { |_node, selected_connector| selected_connector == connector }.keys
|
217
|
+
if selected_nodes.empty?
|
218
|
+
preparation_code.call(remaining_plugins_to_prepare[1..-1])
|
219
|
+
else
|
220
|
+
connector.with_connection_to(selected_nodes, no_exception: no_exception) do |connected_nodes|
|
221
|
+
(selected_nodes - connected_nodes).each do |node_in_error|
|
222
|
+
nodes_needing_connectors[node_in_error] = :connection_error
|
223
|
+
end
|
224
|
+
preparation_code.call(remaining_plugins_to_prepare[1..-1])
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
preparation_code.call(@connector_plugins.select { |_connector_name, connector| connector.respond_to?(:with_connection_to) }.keys)
|
230
|
+
end
|
231
|
+
|
232
|
+
# Get a given connector
|
233
|
+
#
|
234
|
+
# Parameters::
|
235
|
+
# * *connector_name* (Symbol): The connector name
|
236
|
+
# Result::
|
237
|
+
# * Connector or nil: The connector, or nil if none found
|
238
|
+
def connector(connector_name)
|
239
|
+
@connector_plugins[connector_name]
|
240
|
+
end
|
241
|
+
|
242
|
+
private
|
243
|
+
|
244
|
+
# Execute a list of actions for a node, and return exit codes, stdout and stderr of those actions.
|
245
|
+
#
|
246
|
+
# Parameters::
|
247
|
+
# * *node* (String): The node
|
248
|
+
# * *actions* (Array<Action>): Ordered list of actions to perform.
|
249
|
+
# * *connector* (Connector or nil): Connector to use to connect to this node, or nil if none.
|
250
|
+
# * *timeout* (Integer): Timeout in seconds, or nil if none. [default: nil]
|
251
|
+
# * *log_to_file* (String or nil): Log file capturing stdout and stderr (or nil for none). [default: nil]
|
252
|
+
# * *log_to_stdout* (Boolean): Do we send the output to stdout and stderr? [default: true]
|
253
|
+
# Result::
|
254
|
+
# * Integer or Symbol: Exit status of the last command, or Symbol in case of error
|
255
|
+
# * String: Standard output of the commands
|
256
|
+
# * String: Standard error output of the commands
|
257
|
+
def execute_actions_on(node, actions, connector, timeout: nil, log_to_file: nil, log_to_stdout: true)
|
258
|
+
remaining_timeout = timeout
|
259
|
+
exit_status = 0
|
260
|
+
file_output =
|
261
|
+
if log_to_file
|
262
|
+
FileUtils.mkdir_p(File.dirname(log_to_file))
|
263
|
+
File.open(log_to_file, 'w')
|
264
|
+
else
|
265
|
+
nil
|
266
|
+
end
|
267
|
+
stdout_queue = Queue.new
|
268
|
+
stderr_queue = Queue.new
|
269
|
+
stdout = ''
|
270
|
+
stderr = ''
|
271
|
+
IoRouter.with_io_router(
|
272
|
+
stdout_queue => [stdout] +
|
273
|
+
(log_to_stdout ? [@logger] : []) +
|
274
|
+
(file_output.nil? ? [] : [file_output]),
|
275
|
+
stderr_queue => [stderr] +
|
276
|
+
(log_to_stdout ? [@logger_stderr] : []) +
|
277
|
+
(file_output.nil? ? [] : [file_output])
|
278
|
+
) do
|
279
|
+
begin
|
280
|
+
log_debug "[#{node}] - Execute #{actions.size} actions on #{node}..."
|
281
|
+
actions.each do |action|
|
282
|
+
action.prepare_for(node, connector, remaining_timeout, stdout_queue, stderr_queue)
|
283
|
+
start_time = Time.now
|
284
|
+
action.execute
|
285
|
+
remaining_timeout -= Time.now - start_time unless remaining_timeout.nil?
|
286
|
+
end
|
287
|
+
rescue ConnectionError
|
288
|
+
exit_status = :connection_error
|
289
|
+
stderr_queue << "#{$!}\n"
|
290
|
+
rescue CmdRunner::UnexpectedExitCodeError
|
291
|
+
exit_status = :failed_command
|
292
|
+
stderr_queue << "#{$!}\n"
|
293
|
+
rescue CmdRunner::TimeoutError
|
294
|
+
# Error has already been logged in stderr
|
295
|
+
exit_status = :timeout
|
296
|
+
rescue
|
297
|
+
log_error "Uncaught exception while executing actions on #{node}: #{$!}\n#{$!.backtrace.join("\n")}"
|
298
|
+
stderr_queue << "#{$!}\n"
|
299
|
+
exit_status = :failed_action
|
300
|
+
end
|
301
|
+
end
|
302
|
+
[exit_status, stdout, stderr]
|
303
|
+
end
|
304
|
+
|
305
|
+
end
|
306
|
+
|
307
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'logger'
|
3
|
+
require 'open-uri'
|
4
|
+
require 'uri'
|
5
|
+
require 'hybrid_platforms_conductor/credentials'
|
6
|
+
require 'hybrid_platforms_conductor/logger_helpers'
|
7
|
+
|
8
|
+
module HybridPlatformsConductor
|
9
|
+
|
10
|
+
# Object used to access Bitbucket API
|
11
|
+
class Bitbucket
|
12
|
+
|
13
|
+
include LoggerHelpers
|
14
|
+
|
15
|
+
# Provide a Bitbucket connector, and make sure the password is being cleaned when exiting.
|
16
|
+
#
|
17
|
+
# Parameters::
|
18
|
+
# * *bitbucket_url* (String): The Bitbucket URL
|
19
|
+
# * *logger* (Logger): Logger to be used
|
20
|
+
# * *logger_stderr* (Logger): Logger to be used for stderr
|
21
|
+
# * Proc: Code called with the Bitbucket instance.
|
22
|
+
# * *bitbucket* (Bitbucket): The Bitbucket instance to use.
|
23
|
+
def self.with_bitbucket(bitbucket_url, logger, logger_stderr)
|
24
|
+
Credentials.with_credentials_for(:bitbucket, logger, logger_stderr, url: bitbucket_url) do |bitbucket_user, bitbucket_password|
|
25
|
+
yield Bitbucket.new(bitbucket_url, bitbucket_user, bitbucket_password, logger: logger, logger_stderr: logger_stderr)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# The Bitbucket URL
|
30
|
+
# String
|
31
|
+
attr_reader :bitbucket_url
|
32
|
+
|
33
|
+
# Constructor
|
34
|
+
#
|
35
|
+
# Parameters::
|
36
|
+
# * *bitbucket_url* (String): The Bitbucket URL
|
37
|
+
# * *bitbucket_user_name* (String): Bitbucket user name to be used when querying the API
|
38
|
+
# * *bitbucket_password* (String): Bitbucket password to be used when querying the API
|
39
|
+
# * *logger* (Logger): Logger to be used [default = Logger.new(STDOUT)]
|
40
|
+
# * *logger_stderr* (Logger): Logger to be used for stderr [default = Logger.new(STDERR)]
|
41
|
+
def initialize(bitbucket_url, bitbucket_user_name, bitbucket_password, logger: Logger.new(STDOUT), logger_stderr: Logger.new(STDERR))
|
42
|
+
init_loggers(logger, logger_stderr)
|
43
|
+
@bitbucket_url = bitbucket_url
|
44
|
+
@bitbucket_user_name = bitbucket_user_name
|
45
|
+
@bitbucket_password = bitbucket_password
|
46
|
+
end
|
47
|
+
|
48
|
+
# Get the repositories of a given project.
|
49
|
+
# Limit to 1000 results max.
|
50
|
+
#
|
51
|
+
# Parameters::
|
52
|
+
# * *project* (String): Project name
|
53
|
+
# Result::
|
54
|
+
# * Object: Corresponding JSON
|
55
|
+
def repos(project)
|
56
|
+
get_api("projects/#{project}/repos?limit=1000")
|
57
|
+
end
|
58
|
+
|
59
|
+
# Get the PR settings of a given repository
|
60
|
+
#
|
61
|
+
# Parameters::
|
62
|
+
# * *project* (String): Project name
|
63
|
+
# * *repo* (String): Repository name
|
64
|
+
# Result::
|
65
|
+
# * Object: Corresponding JSON
|
66
|
+
def settings_pr(project, repo)
|
67
|
+
get_api("projects/#{project}/repos/#{repo}/settings/pull-requests")
|
68
|
+
end
|
69
|
+
|
70
|
+
# Get the default reviewers of a given repository
|
71
|
+
#
|
72
|
+
# Parameters::
|
73
|
+
# * *project* (String): Project name
|
74
|
+
# * *repo* (String): Repository name
|
75
|
+
# Result::
|
76
|
+
# * Object: Corresponding JSON
|
77
|
+
def default_reviewers(project, repo)
|
78
|
+
get_api("projects/#{project}/repos/#{repo}/conditions", api_domain: 'default-reviewers')
|
79
|
+
end
|
80
|
+
|
81
|
+
# Get the branch permissions of a given repository
|
82
|
+
#
|
83
|
+
# Parameters::
|
84
|
+
# * *project* (String): Project name
|
85
|
+
# * *repo* (String): Repository name
|
86
|
+
# Result::
|
87
|
+
# * Object: Corresponding JSON
|
88
|
+
def branch_permissions(project, repo)
|
89
|
+
# Put 3 retries here as the Bitbucket installation has a very unstable API 2.0 and often returns random 401 errors.
|
90
|
+
get_api("projects/#{project}/repos/#{repo}/restrictions", api_domain: 'branch-permissions', api_version: '2.0', retries: 3)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Issue an HTTP get on the API.
|
94
|
+
# Handle authentication.
|
95
|
+
#
|
96
|
+
# Parameters::
|
97
|
+
# * *path* (String): API path to access
|
98
|
+
# * *api_domain* (String): API domain to access [default: 'api']
|
99
|
+
# * *api_version* (String): API version to access [default: '1.0']
|
100
|
+
# * *retries* (Integer): Number of retries in case of failures [default: 0]
|
101
|
+
# Result::
|
102
|
+
# * Object: Returned JSON
|
103
|
+
def get_api(path, api_domain: 'api', api_version: '1.0', retries: 0)
|
104
|
+
api_url = "#{@bitbucket_url}/rest/#{api_domain}/#{api_version}/#{path}"
|
105
|
+
log_debug "Call Bitbucket API #{@bitbucket_user_name}@#{api_url}..."
|
106
|
+
http_response = nil
|
107
|
+
loop do
|
108
|
+
begin
|
109
|
+
http_response = URI.open(api_url, http_basic_authentication: [@bitbucket_user_name, @bitbucket_password])
|
110
|
+
rescue
|
111
|
+
raise if retries == 0
|
112
|
+
log_warn "Got error #{$!} on #{@bitbucket_user_name}@#{api_url}. Will retry #{retries} times..."
|
113
|
+
retries -= 1
|
114
|
+
sleep 1
|
115
|
+
end
|
116
|
+
break unless http_response.nil?
|
117
|
+
end
|
118
|
+
JSON.parse(http_response.read)
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|