hybrid_platforms_conductor 32.12.0 → 32.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1103 -0
  3. data/LICENSE.md +31 -0
  4. data/README.md +395 -0
  5. data/bin/setup +1 -1
  6. data/docs/api.md +349 -0
  7. data/docs/config_dsl.md +315 -0
  8. data/docs/executables.md +226 -0
  9. data/docs/executables/check-node.md +155 -0
  10. data/docs/executables/deploy.md +198 -0
  11. data/docs/executables/dump_nodes_json.md +110 -0
  12. data/docs/executables/free_ips.md +93 -0
  13. data/docs/executables/free_veids.md +73 -0
  14. data/docs/executables/get_impacted_nodes.md +94 -0
  15. data/docs/executables/last_deploys.md +114 -0
  16. data/docs/executables/nodes_to_deploy.md +139 -0
  17. data/docs/executables/report.md +159 -0
  18. data/docs/executables/run.md +126 -0
  19. data/docs/executables/setup.md +92 -0
  20. data/docs/executables/ssh_config.md +151 -0
  21. data/docs/executables/test.md +213 -0
  22. data/docs/executables/topograph.md +139 -0
  23. data/docs/gen/mermaid/README.md-0.png +0 -0
  24. data/docs/gen/mermaid/docs/executables/check-node.md-0.png +0 -0
  25. data/docs/gen/mermaid/docs/executables/deploy.md-0.png +0 -0
  26. data/docs/gen/mermaid/docs/executables/free_ips.md-0.png +0 -0
  27. data/docs/gen/mermaid/docs/executables/free_veids.md-0.png +0 -0
  28. data/docs/gen/mermaid/docs/executables/get_impacted_nodes.md-0.png +0 -0
  29. data/docs/gen/mermaid/docs/executables/last_deploys.md-0.png +0 -0
  30. data/docs/gen/mermaid/docs/executables/nodes_to_deploy.md-0.png +0 -0
  31. data/docs/gen/mermaid/docs/executables/report.md-0.png +0 -0
  32. data/docs/gen/mermaid/docs/executables/run.md-0.png +0 -0
  33. data/docs/gen/mermaid/docs/executables/setup.md-0.png +0 -0
  34. data/docs/gen/mermaid/docs/executables/ssh_config.md-0.png +0 -0
  35. data/docs/gen/mermaid/docs/executables/test.md-0.png +0 -0
  36. data/docs/install.md +161 -0
  37. data/docs/plugins.md +215 -0
  38. data/docs/plugins/action/bash.md +37 -0
  39. data/docs/plugins/action/interactive.md +37 -0
  40. data/docs/plugins/action/remote_bash.md +67 -0
  41. data/docs/plugins/action/ruby.md +69 -0
  42. data/docs/plugins/action/scp.md +61 -0
  43. data/docs/plugins/cmdb/config.md +46 -0
  44. data/docs/plugins/cmdb/host_ip.md +33 -0
  45. data/docs/plugins/cmdb/host_keys.md +33 -0
  46. data/docs/plugins/cmdb/platform_handlers.md +33 -0
  47. data/docs/plugins/connector/local.md +28 -0
  48. data/docs/plugins/connector/ssh.md +95 -0
  49. data/docs/plugins/platform_handler/yaml_inventory.md +105 -0
  50. data/docs/plugins/provisioner/docker.md +27 -0
  51. data/docs/plugins/provisioner/podman.md +27 -0
  52. data/docs/plugins/provisioner/proxmox.md +115 -0
  53. data/docs/plugins/report/confluence.md +49 -0
  54. data/docs/plugins/report/mediawiki.md +28 -0
  55. data/docs/plugins/report/stdout.md +32 -0
  56. data/docs/plugins/test/bitbucket_conf.md +97 -0
  57. data/docs/plugins/test/can_be_checked.md +27 -0
  58. data/docs/plugins/test/check_deploy_and_idempotence.md +61 -0
  59. data/docs/plugins/test/check_from_scratch.md +28 -0
  60. data/docs/plugins/test/connection.md +27 -0
  61. data/docs/plugins/test/deploy_freshness.md +27 -0
  62. data/docs/plugins/test/deploy_from_scratch.md +28 -0
  63. data/docs/plugins/test/deploy_removes_root_access.md +29 -0
  64. data/docs/plugins/test/divergence.md +41 -0
  65. data/docs/plugins/test/executables.md +26 -0
  66. data/docs/plugins/test/file_system.md +49 -0
  67. data/docs/plugins/test/file_system_hdfs.md +65 -0
  68. data/docs/plugins/test/hostname.md +27 -0
  69. data/docs/plugins/test/idempotence.md +56 -0
  70. data/docs/plugins/test/ip.md +28 -0
  71. data/docs/plugins/test/jenkins_ci_conf.md +54 -0
  72. data/docs/plugins/test/jenkins_ci_masters_ok.md +54 -0
  73. data/docs/plugins/test/linear_strategy.md +26 -0
  74. data/docs/plugins/test/local_users.md +48 -0
  75. data/docs/plugins/test/mounts.md +55 -0
  76. data/docs/plugins/test/orphan_files.md +38 -0
  77. data/docs/plugins/test/ports.md +50 -0
  78. data/docs/plugins/test/private_ips.md +27 -0
  79. data/docs/plugins/test/public_ips.md +27 -0
  80. data/docs/plugins/test/spectre.md +26 -0
  81. data/docs/plugins/test/veids.md +27 -0
  82. data/docs/plugins/test/vulnerabilities.md +65 -0
  83. data/docs/plugins/test_report/confluence.md +43 -0
  84. data/docs/plugins/test_report/stdout.md +26 -0
  85. data/docs/plugins_create.md +135 -0
  86. data/docs/tutorial.md +57 -0
  87. data/docs/tutorial/01_installation.md +129 -0
  88. data/docs/tutorial/02_first_node.md +466 -0
  89. data/docs/tutorial/03_scale.md +876 -0
  90. data/docs/tutorial/04_test.md +965 -0
  91. data/docs/tutorial/05_extend_with_plugins.md +1132 -0
  92. data/examples/bare/Gemfile +4 -0
  93. data/examples/bare/hpc_config.rb +2 -0
  94. data/examples/localhost/Gemfile +4 -0
  95. data/examples/localhost/hpc_config.rb +2 -0
  96. data/examples/localhost/inventory.yaml +4 -0
  97. data/lib/hybrid_platforms_conductor/actions_executor.rb +1 -0
  98. data/lib/hybrid_platforms_conductor/deployer.rb +3 -2
  99. data/lib/hybrid_platforms_conductor/hpc_plugins/action/remote_bash.rb +29 -13
  100. data/lib/hybrid_platforms_conductor/hpc_plugins/action/scp.rb +1 -1
  101. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/local.rb +98 -0
  102. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/my_connector.rb.sample +2 -2
  103. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +7 -3
  104. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/platform_handler_plugin.rb.sample +5 -5
  105. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/yaml_inventory.rb +140 -0
  106. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox.rb +5 -2
  107. data/lib/hybrid_platforms_conductor/hpc_plugins/test/bitbucket_conf.rb +4 -4
  108. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_freshness.rb +1 -1
  109. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +19 -17
  110. data/lib/hybrid_platforms_conductor/hpc_plugins/test/divergence.rb +3 -0
  111. data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +2 -1
  112. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +2 -1
  113. data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +2 -1
  114. data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +4 -3
  115. data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +2 -1
  116. data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +1 -1
  117. data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +8 -7
  118. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/confluence.rb +1 -1
  119. data/lib/hybrid_platforms_conductor/json_dumper.rb +1 -1
  120. data/lib/hybrid_platforms_conductor/platform_handler.rb +1 -1
  121. data/lib/hybrid_platforms_conductor/services_handler.rb +18 -16
  122. data/lib/hybrid_platforms_conductor/tests_runner.rb +0 -1
  123. data/lib/hybrid_platforms_conductor/topographer.rb +0 -1
  124. data/lib/hybrid_platforms_conductor/version.rb +1 -1
  125. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/remote_bash_spec.rb +16 -0
  126. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/connectable_nodes_spec.rb +30 -0
  127. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/remote_actions_spec.rb +113 -0
  128. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/cli_options_spec.rb +6 -2
  129. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/global_helpers_spec.rb +38 -1
  130. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb +8 -8
  131. data/spec/hybrid_platforms_conductor_test/docs_spec.rb +10 -0
  132. data/tools/check_md +89 -0
  133. data/tools/generate_mermaid +75 -0
  134. metadata +207 -12
data/LICENSE.md ADDED
@@ -0,0 +1,31 @@
1
+
2
+ The license stated herein is a copy of the BSD License (modified on July 1999).
3
+ The AUTHOR mentionned below refers to the list of people involved in the
4
+ creation and modification of any file included in the delivered package.
5
+ This list is found in the file named AUTHORS.
6
+ The AUTHORS and LICENSE files have to be included in any release of software
7
+ embedding source code of this package, or using it as a derivative software.
8
+
9
+ Copyright (c) 2015 - 2021 Muriel Salvan (muriel@x-aeon.com)
10
+
11
+ Redistribution and use in source and binary forms, with or without
12
+ modification, are permitted provided that the following conditions are met:
13
+
14
+ 1. Redistributions of source code must retain the above copyright notice,
15
+ this list of conditions and the following disclaimer.
16
+ 2. Redistributions in binary form must reproduce the above copyright notice,
17
+ this list of conditions and the following disclaimer in the documentation
18
+ and/or other materials provided with the distribution.
19
+ 3. The name of the author may not be used to endorse or promote products
20
+ derived from this software without specific prior written permission.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
23
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
25
+ EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
27
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
31
+ OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,395 @@
1
+ # **Hybrid Platforms Conductor**
2
+
3
+ **Making DevOps processes agile and robust in an environment integrating multiple technologies and platforms.**
4
+
5
+ # Table of Contents
6
+ * [Overview](#overview)
7
+ * [Installation](#installation)
8
+ * [First time setup](#first_setup)
9
+ * [How to use tools from Hybrid Platforms Conductor](#how_to)
10
+ * [Concepts](#concepts)
11
+ * [Tutorial](#tutorial)
12
+ * [List of tools available](#tools_list)
13
+ * [Credentials](#credentials)
14
+ * [Environment variables](#environment)
15
+ * [Metadata](#metadata)
16
+ * [Development API](#development_api)
17
+ * [Extending Hybrid Platforms Conductor with plugins](#extending)
18
+ * [Development corner](#development_corner)
19
+
20
+ <a name="overview"></a>
21
+ # Overview
22
+
23
+ ## Why?
24
+
25
+ DevOps practices involve a lot of processes definition, automation, testing and good practices in the whole **development and operations workflows**.
26
+ Having agile DevOps processes when dealing with homogeneous platforms (for example on only 1 cloud provider) or a fixed set of technologies (for example deploying using Ansible only) is easy.
27
+
28
+ However reality is not that simple for a lot of organizations:
29
+ * IT professionals may want to **not bind themselves to a single platform's technology or cloud provider**.
30
+ * DevOps teams may not want their processes and their agility to be too much coupled to a platform, cloud provider or a technology. Being able to adopt multiple platforms ensure your **DevOps practices are sane, adaptable and will outlive the current technical choices** that are certainly meant to change in the future.
31
+ * Big companies often **inherit from multiple platforms and technologies** that have been built during years. They have to cope with them, improve them, and migration to common technologies or platforms is not always an option, can be costly and is sometimes not desirable. Standardisation can waste competencies and may miss features or agility for some part of the organization.
32
+
33
+ Now being able to keep DevOps processes agile and robust is really difficult around multiple platforms and technologies.
34
+
35
+ **This is where Hybrid Platforms Conductor can help: it helps DevOps define simple, robust and scalable processes that can adapt easily to ever-changing platforms and technologies in your development and operations environments.**
36
+
37
+ In other words, Hybrid Platforms Conductor lets you **map your DevOps processes in a platform and technology independent way on simple interfaces** (CLI executables, APIs...).
38
+ Having simple interfaces on your processes move the technical complexity in code instead of having it scattered around documentation becoming obsolete and increasing the learning curve.
39
+
40
+ ## How?
41
+
42
+ Hybrid Platforms Conductor provides a complete **tools set mapping DevOps practices** and that can **orchestrate different platforms to be provisioned, configured, maintained and monitored**.
43
+
44
+ 1. It achieves the simplicity, ease of use and integrability of its **interfaces** by having **simple CLI and API** mapping only processes, without technical complexity.
45
+ 2. It achieves the adaptability to various technology by having an extensible **plugins-oriented architecture** in every parts of the processes.
46
+
47
+ ### DevOps interfaces
48
+
49
+ It offers **simple DevOps interfaces** that can **integrate easily in third-party tools**.
50
+
51
+ Hybrid Platforms Conductor covers the following processes:
52
+ * Maintain several platforms handled with **different configuration management tools, in a consistent way**.
53
+ * **Check** configurations in a harmless way.
54
+ * **Deploy** configurations on any nodes of those platforms.
55
+ * **Test** new configurations before applying them.
56
+ * **Monitor** the platforms configuration by having an extensible test framework.
57
+ * **Integrate** DevOps processes easily in Continuous Integration/Deployment -CI/CD workflows, the same way it is being used locally.
58
+ * **Report** easily on platforms, nodes graphs, topology, nodes details in an automated way.
59
+ * **Plug in** from/to simple APIs to programmatically reuse Hybrid Platforms Conductor's functionalities and extend them (platforms provisioning, configuration management tools, tests, reports formats...).
60
+
61
+ It is meant to be used as a **local tool by each DevOps/Developer/IT professional** that needs it. No need to setup a server: it is a client-only tools set that then adapts to the environment it orchestrates using various connectors (SSH, cloud-specific APIs, CLIs...).
62
+
63
+ It is **packaged as a simple Rubygem** that you can either install stand-alone or use as part of a DevOps Ruby repository.
64
+
65
+ The way it works is by having a **configuration file using an extensive DSL to describe the DevOps environment** (platforms, gateways, users, tests configuration...), and then **various executables mapping each DevOps process**.
66
+
67
+ ### Technology plugins
68
+
69
+ It is built around a plugins that allow each DevOps team to **adapt its processes to its own specific environments**:
70
+ * Any kind of **platform** (on-premise, in the cloud, PaaS, SaaS...).
71
+ * Any **configuration tool** (Chef, Puppet, Ansible...).
72
+ * Any kind of **test** (network-level, applicative-level, using external testing services...).
73
+ * Any **Configuration Management Database** - CMDB (Consul, in-house spreadsheets, web services...).
74
+
75
+ Everytime a process uses plugins at a given stage, it means any Hybrid Platforms Conductor's user can extend the functionality by adding its own plugin at this stage of the process.
76
+ Here are the various plugin categories:
77
+ * **[Actions](docs/plugins/action)** implement a given **action**. For example: bash code execution, ruby code execution, file transfer...
78
+ * **[Cmdbs](docs/plugins/cmdb)** parse **metadata** from various sources. For example: a database, Chef/Ansible inventory files, a configuration management database such as Consul...
79
+ * **[Connectors](docs/plugins/connector)** give ways to execute commands and transfer files on **nodes**. For example: using an SSH connection, a CLI for a Cloud provider...
80
+ * **[Platform handlers](docs/plugins/platform_handler)** handle any **platform** of a given **platform type**. They read **nodes**' inventory and **services** from **platforms**, and provide **actions** to deploy a **service** on a **node**.
81
+ * **[Provisioners](docs/plugins/provisioner)** provision (create, destroy, start, stop...) **nodes**. For example: using OpenShift, Proxmox, Docker, Podman...
82
+ * **[Reports](docs/plugins/report)** gather **platforms** and **nodes**' inventory information and publish them to some medium. For example: on command line, as a JSON file, on a content management system like Confluence or Mediawiki...
83
+ * **[Tests](docs/plugins/test)** define tests to be performed on **platforms** and **nodes**.
84
+ * **[Tests reports](docs/plugins/test_report)** publish tests results to some medium. For example: on command line, as a JSON file, on a content management system like Confluence or Mediawiki...
85
+
86
+ <a name="installation"></a>
87
+ # Installation
88
+
89
+ Installing Hybrid Platforms Conductor requires 2 steps:
90
+ 1. Have **Ruby >= 2.5 and < 3.0** installed.
91
+ 2. Install the `hybrid_platforms_conductor` Rubygem.
92
+
93
+ See [installation details](docs/install.md) for more details on how to install those.
94
+
95
+ <a name="first_setup"></a>
96
+ # First time setup
97
+
98
+ ## 1. Create the configuration file in your current or project directory:
99
+
100
+ All Hybrid Platforms Conductor tools use a configuration file to declare the environment (platforms, connectors, configurations...) they will operate on.
101
+ The file is named `hpc_config.rb` and can be empty to start with. It is a Ruby file that can use a Ruby-based DSL.
102
+
103
+ It contains the declaration of the platforms and the configuration needed for Hybrid Platforms Conductor to run correctly. If you are using a Ruby project for your platforms, put this file in it.
104
+
105
+ Example of `hpc_config.rb`:
106
+ ```ruby
107
+ # Define the known platforms, either locally or in a git repository
108
+ yaml_inventory_platform path: "#{hybrid_platforms_dir}/my-platform-conf"
109
+ yaml_inventory_platform git: 'https://www.site.my_company.net/git/scm/team17/xae-platform-conf.git'
110
+
111
+ # Define images that are referenced by the platforms inventory
112
+ os_image :centos, '/path/to/centos/os_image'
113
+ ```
114
+
115
+ See [configuration DSL](docs/config_dsl.md) for more details on this DSL.
116
+
117
+ See [the examples directory](examples/) for some use-cases of configurations.
118
+
119
+ ## 2. Install dependencies
120
+
121
+ The following installs the dependencies for Hybrid Platforms Conductor to work correctly.
122
+ ```bash
123
+ bundle config set --local path vendor/bundle
124
+ bundle install
125
+ bundle binstubs hybrid_platforms_conductor
126
+ ```
127
+ This will create a `bin` directory with all needed executables stored inside. You can then add this directory to your `PATH` environment variable to avoid prefixing your commands by `./bin/`.
128
+
129
+ Alternatively, you can install Hybrid Platforms Conductor in a non-local path, using simply `bundle install`, and use the executables directly from your Ruby's system installation path.
130
+
131
+ This README considers that executables are installed in the `./bin` directory and commands are all issued from the directory containing `hpc_config.rb`.
132
+
133
+ If you want to use tools outside of the directory containing `hpc_config.rb`, you'll have to set the `hpc_platforms` environment variable to the path containing the `hpc_config.rb` file.
134
+ For example if the file `/path/to/hybrid-platforms/hpc_config.rb` exists:
135
+ ```bash
136
+ export hpc_platforms=/path/to/hybrid-platforms
137
+ ```
138
+
139
+ ## 3. Setup the platform repositories
140
+
141
+ This will install the dependencies for any configuration management tool used by the platforms being declared in `hpc_config.rb`.
142
+ ```bash
143
+ ./bin/setup
144
+ ```
145
+
146
+ It is to be re-executed only if the platforms definitions in `hpc_config.rb` are changed or if one of the platforms is updating its tools dependencies.
147
+
148
+ ## 4. Perform a quick test to validate the setup
149
+
150
+ This command will run the tests of platforms handled by HPCs Conductor executables installation, and should return `===== No unexpected errors =====` at the end.
151
+ ```bash
152
+ ./bin/test --test executables
153
+ ```
154
+
155
+ This command will list all the nodes that could be found in the platforms.
156
+ ```bash
157
+ ./bin/check-node --show-nodes
158
+ ```
159
+
160
+ <a name="how_to"></a>
161
+ # How to use tools from Hybrid Platforms Conductor
162
+
163
+ Each executable is installed in a `./bin` directory and can be called directly using its name (for example `./bin/setup`).
164
+ All executables have a `--help` switch that dump their possible usage in a detailed way.
165
+
166
+ Example:
167
+ ```bash
168
+ ./bin/deploy --help
169
+ ```
170
+ Outputs:
171
+ ```
172
+ Usage: ./bin/deploy [options]
173
+
174
+ Main options:
175
+ -d, --debug Activate debug mode
176
+ -h, --help Display help and exit
177
+
178
+ Nodes handler options:
179
+ -o, --show-nodes Display the list of possible nodes and exit
180
+
181
+ Nodes selection options:
182
+ -a, --all-nodes Select all nodes
183
+ -b, --nodes-platform PLATFORM Select nodes belonging to a given platform name. Available platforms are: ansible-repo, chef-repo (can be used several times)
184
+ -l, --nodes-list LIST Select nodes defined in a nodes list (can be used several times)
185
+ -n, --node NODE Select a specific node. Can be a regular expression to select several nodes if used with enclosing "/" characters. (can be used several times).
186
+ --nodes-service SERVICE Select nodes implementing a given service (can be used several times)
187
+ --nodes-git-impact GIT_IMPACT
188
+ Select nodes impacted by a git diff from a platform (can be used several times).
189
+ GIT_IMPACT has the format PLATFORM:FROM_COMMIT:TO_COMMIT:FLAGS
190
+ * PLATFORM: Name of the platform to check git diff from. Available platforms are: ansible-repo, chef-repo
191
+ * FROM_COMMIT: Commit ID or refspec from which we perform the diff. If ommitted, defaults to master
192
+ * TO_COMMIT: Commit ID ot refspec to which we perform the diff. If ommitted, defaults to the currently checked-out files
193
+ * FLAGS: Extra comma-separated flags. The following flags are supported:
194
+ - min: If specified then each impacted service will select only 1 node implementing this service. If not specified then all nodes implementing the impacted services will be selected.
195
+
196
+ Command runner options:
197
+ -s, --show-commands Display the commands that would be run instead of running them
198
+
199
+ Actions Executor options:
200
+ -m, --max-threads NBR Set the number of threads to use for concurrent queries (defaults to 16)
201
+
202
+ Connector ssh options:
203
+ -g, --ssh-gateway-user USER Name of the gateway user to be used by the gateways. Can also be set from environment variable hpc_ssh_gateway_user. Defaults to ubradm.
204
+ -j, --ssh-no-control-master If used, don't create SSH control masters for connections.
205
+ -q, --ssh-no-host-key-checking If used, don't check for SSH host keys.
206
+ -u, --ssh-user USER Name of user to be used in SSH connections (defaults to hpc_ssh_user or USER environment variables)
207
+ -w, --password If used, then expect SSH connections to ask for a password.
208
+ -y GATEWAYS_CONF, Name of the gateways configuration to be used. Can also be set from environment variable hpc_ssh_gateways_conf.
209
+ --ssh-gateways-conf
210
+
211
+ Deployer options:
212
+ -e, --secrets SECRETS_LOCATION Specify a secrets location. Can be specified several times. Location can be:
213
+ * Local path to a JSON file
214
+ * URL of the form http[s]://<url>:<secret_id> to get a secret JSON file from a Thycotic Secret Server at the given URL.
215
+ -p, --parallel Execute the commands in parallel (put the standard output in files <hybrid-platforms-dir>/run_logs/*.stdout)
216
+ -t, --timeout SECS Timeout in seconds to wait for each chef run. Only used in why-run mode. (defaults to no timeout)
217
+ -W, --why-run Use the why-run mode to see what would be the result of the deploy instead of deploying it for real.
218
+ --retries-on-error NBR Number of retries in case of non-deterministic errors (defaults to 0)
219
+ ```
220
+
221
+ All executables also have the `--debug` switch to display more verbose and debugging information.
222
+
223
+ <a name="concepts"></a>
224
+ # Concepts
225
+
226
+ As an example, a DevOps process can be "As a DevOps team member, I configure a newly provisioned node in a platform".
227
+ We want this process to work with what the DevOps team is responsible for:
228
+ * Their services: web servers, firewalls, sshd configurations...
229
+ * The platforms they maintain: in-house bare metals, VPS in cloud providers, shared computers...
230
+ * The nodes belonging to these platforms: Docker containers, VMs, bare metal installations...
231
+ * The configuration management tools they use: Chef, Puppet, Terraform, Ansible, simple scripts...
232
+ * The configuration management databases they use: Chef/Ansible inventories, Consul, spreadsheets...
233
+
234
+ To achieve this, Hybrid Platforms Conductor handles the following generic concepts:
235
+ * A **service** is a software component that can be deployed or configured. Some examples: a web server, a cluster's configuration, a network configuration, a monitoring tool.
236
+ * A **node** is a target for **services** to be deployed, like a VM, a container, an SSH-accessible computer. It can map a provisioned resource (like a VM or a container behind a hostname or ip), or it can be also virtual (like a Cloud managed service - no single hostname/ip behind, but still something to configure services on).
237
+ * A **platform** is a repository (local path or a git URL) defining an inventory of **nodes**, and **services** that can be deployed. Usually a platform is bound and structured to a given configuration management tool (like a Chef or Ansible repository), but it could be as simple as a collection of inventory text files and service bash scripts.
238
+ * A **platform type** is the flavor of a given **platform**. It defines how Hybrid Platforms Conductor is using a **platform**'s repository. For example we can have several **platforms** being different Chef repositories (each one with its own **nodes** inventory and **services**), but the way to use them (deploy a **service** on a **node**) is done the same way (calling the Chef's executables). In this case those **platforms** will have the same **platform type**.
239
+ * A **metadata** is a property (in the form key => value) associated to a **node**. It can be set by various configuration management databases, and also from the **platforms**' inventory. Some Hybrid Platforms Conductor's executables will use **nodes**'s specific **metadata** to adapt their behaviours (for example SSH connection details, IP addresses, operating system...).
240
+ * An **action** is an operation that can be performed as part of a process. For example: bash code execution on a **node**, file copy, ruby code execution...
241
+
242
+ Hybrid Platforms Conductor then provides executables that map the processes we want to address. See [the executables list](docs/executables.md) for an exhaustive list of those executables, but in our process' example the executable used to deploy **services** on a **node** is called **`deploy`**.
243
+
244
+ So with the concepts described above, the process described as deploying **services** on a **node** named `my_node` can be invoked with a simple command line: `./bin/deploy --node my_node`. The resulting process can be pictured as below:
245
+
246
+ <!-- Mermaid generator - Section start -->
247
+ ![Mermaid diagram](/docs/gen/mermaid/README.md-0.png)
248
+ <details>
249
+ <summary>See diagram Mermaid code</summary>
250
+
251
+ ```mermaid
252
+ sequenceDiagram
253
+ participant Deploy as ./bin/deploy --node my_node
254
+ participant CMDB as CMDB
255
+ participant PlatformHandler as Platform Handler
256
+ participant PlatformRepo as Platform repository (ie Chef)
257
+ participant Connector as Connector (ie SSH)
258
+ participant Node as Provisioned node (my_node)
259
+
260
+ Deploy->>+CMDB: Get services to be deployed on my_node
261
+ CMDB->>+PlatformHandler: Get my_node metadata from the platform
262
+ PlatformHandler->>+PlatformRepo: Read platform inventory files
263
+ PlatformRepo-->>-PlatformHandler: Platform inventory
264
+ PlatformHandler-->>-CMDB: Services metadata containing my_web_app
265
+ CMDB-->>-Deploy: my_node has service my_web_app
266
+ Deploy->>+PlatformHandler: Get actions to deploy my_web_app
267
+ PlatformHandler-->>-Deploy: Actions to deploy my_web_app (ie using Chef command line)
268
+ Deploy->>+Connector: Connect to my_node to execute actions
269
+ Connector->>+Node: Execute actions through SSH to deploy my_web_app on my_node
270
+ Node-->>-Connector: my_web_app is deployed successfully
271
+ Connector-->>-Deploy: Close connection
272
+ ```
273
+ </details>
274
+ <!-- Mermaid generator - Section end -->
275
+
276
+ Having such a process defined with extensible plugins lets DevOps teams **adapt very easily to hybrid environments without having to duplicate configuration, inventories, information or workflows**.
277
+
278
+ <a name="tutorial"></a>
279
+ # Tutorial
280
+
281
+ The best way to grasp the power of such agile processes is to learn by doing.
282
+
283
+ [Here is a simple tutorial](docs/tutorial.md) showing how to start playing with Hybrid Platforms Conductor and use it to define simple DevOps processes and extend them easily in a changing environment.
284
+
285
+ <a name="tools_list"></a>
286
+ # List of tools available
287
+
288
+ A bunch of tools are available for handling DevOps processes.
289
+ Before going into the list it's important to note that plugins can also define additional tools. Don't forget to check their `README.md` too.
290
+
291
+ See [the executables list](docs/executables.md) for more details.
292
+
293
+ <a name="credentials"></a>
294
+ # Credentials
295
+
296
+ Some tools or tests require authentication using user/password to an external resource. Examples of such tools are Bitbucket, Thycotic, Confluence...
297
+ Credentials can be given using either environment variables or by parsing the user's `.netrc` file.
298
+
299
+ In case a process needs a credential that has not been set, a warning message will be output so that the user knows which credential is missing, and eventually for which URL.
300
+
301
+ Following sub-sections explain the different ways of setting such credentials.
302
+
303
+ ## Environment variables
304
+
305
+ Environment variables used for credentials are always named following this convention: `hpc_user_for_<credential_id>` and `hpc_password_for_<credential_id>`.
306
+ For example, credentials to connect to Bitbucket can be set this way:
307
+ ```bash
308
+ export hpc_user_for_bitbucket=my_bitbucket_name
309
+ export hpc_password_for_bitbucket=my_bitbucket_PaSsWoRd
310
+ ```
311
+
312
+ ## .netrc file
313
+
314
+ The user can have a `~/.netrc` file containing users and passwords for a list of host names.
315
+ The `.netrc` specification is defined by [gnu.org here](https://www.gnu.org/software/inetutils/manual/html_node/The-_002enetrc-file.html).
316
+
317
+ Here is an example of `.netrc` file defining credentials for some host names:
318
+ ```
319
+ machine my_host.my_domain1.com login my_user password My_PaSsWoRd
320
+ machine my_other_host.my_domain2.com login my_other_user password Pa$$w0Rd!
321
+ ```
322
+
323
+ <a name="environment"></a>
324
+ # Environment variables
325
+
326
+ Environment variables can be used to trive some Hybrid Platform Conductor's processes.
327
+
328
+ | Variable | Usage |
329
+ | --- | --- |
330
+ | `hpc_platforms` | Directory containing the main `hpc_config.rb` file. Defaults to `.` |
331
+
332
+ See [the executables documentation](docs/executables.md) for environment variables used by some executables.
333
+
334
+ See [the plugins documentation](docs/plugins.md) for environment variables used by some plugins.
335
+
336
+ <a name="metadata"></a>
337
+ # Metadata
338
+
339
+ Metadata associated to the nodes (retrieved by CMDB) is used a lot by various processes of Hybrid Platforms Conductor.
340
+ Here is the main metadata used in common processes:
341
+
342
+ | Metadata | Type | Usage
343
+ | --- | --- | --- |
344
+ | `services` | `Array<String>` | List of services attached to a node |
345
+
346
+ See [the executables documentation](docs/executables.md) for metadata used by some executables.
347
+
348
+ See [the plugins documentation](docs/plugins.md) for metadata used by some plugins.
349
+
350
+ <a name="development_api"></a>
351
+ # Development API
352
+
353
+ In case you want to develop other tools using access and nodes configurations, here is the Ruby API you can use in your scripts.
354
+ You can check current executables (`./bin/deploy`, `./bin/last_deploys`, `./bin/report`...) to have concrete examples on how to use platforms handled by HPCs Conductor Ruby API.
355
+
356
+ See [the API](docs/api.md) for more details.
357
+
358
+ <a name="extending"></a>
359
+ # Extending Hybrid Platforms Conductor with plugins
360
+
361
+ Hybrid Platforms Conductor is built around plugins-oriented architecture that lets it easily being extended.
362
+
363
+ See [the plugins documentation](docs/plugins.md) for a list of all plugins already shipped by default.
364
+
365
+ See [how to create a plugin](docs/plugins_create.md) to easily add your own plugins adapting Hybrid Platforms Conductor to your technology stack.
366
+
367
+ <a name="development_corner"></a>
368
+ # Development corner
369
+
370
+ ## Development workflow
371
+
372
+ Contributing to Hybrid Platforms Conductor is done using simple Pull Requests against the `master` branch of the [main repository](https://github.com/sweet-delights/hybrid-platforms-conductor).
373
+ Don't forget to add `[Feature]` or `[Breaking]` into your git commit comment if a commit adds a feature or breaks an existing feature, as this is used to apply automatically semantic versioning.
374
+
375
+ ## Continuous Integration and deliverables
376
+
377
+ [Github Actions](https://github.com/sweet-delights/hybrid-platforms-conductor/actions) automatically catches on new PR merges and publishes a semantically versioned Rubygem on [Rubygems.org](https://rubygems.org/gems/hybrid_platforms_conductor).
378
+
379
+ Automatic semantic releasing is done by [`sem_ver_components`](https://github.com/Muriel-Salvan/sem_ver_components/).
380
+
381
+ Some parts of the documentation (like [Mermaid diagrams](https://mermaid-js.github.io/mermaid/)) is being generated during releasing. To achieve that the [`mermaid-cli` npm package](https://github.com/mermaid-js/mermaid-cli) needs to be installed as a local NodeJS package.
382
+
383
+ Change log can be accessed in the [CHANGELOG.md file](CHANGELOG.md).
384
+
385
+ ## Tests
386
+
387
+ The whole tests suite can be run by using `bundle exec rspec`.
388
+
389
+ A subset of tests (or even a single test) can be run by using a part of their name this way: `bundle exec rspec -e "HybridPlatformsConductor::Deployer checking the docker images provisioning"`
390
+
391
+ To enable debugging logs during tests run, set the environment variable `TEST_DEBUG` to `1`: `TEST_DEBUG=1 bundle exec rspec -e "HybridPlatformsConductor::Deployer checking the docker images provisioning"`
392
+
393
+ ## License
394
+
395
+ BSD license (details in the [LICENSE.md file](LICENSE.md)).
data/bin/setup CHANGED
@@ -7,5 +7,5 @@ platforms_handler = executable.platforms_handler
7
7
  executable.parse_options!
8
8
 
9
9
  platforms_handler.known_platforms.each do |platform|
10
- platform.setup
10
+ platform.setup if platform.respond_to?(:setup)
11
11
  end
data/docs/api.md ADDED
@@ -0,0 +1,349 @@
1
+ # Hybrid Platforms Conductor API
2
+
3
+ Hybrid Platforms Conductor exposes a Ruby API, used internally by all the executables it provides.
4
+ This API is organized around several areas, mapping the processes used internally.
5
+
6
+ Accessing the API in **any Ruby project is done by instantiating an entry point class (`HybridPlatformsConductor::Executable`)** and calling the various Hybrid Platforms Conductor API components from there.
7
+ Example:
8
+ ```ruby
9
+ require 'hybrid_platforms_conductor/executable'
10
+
11
+ executable = HybridPlatformsConductor::Executable.new
12
+
13
+ # Access the Config to read the configuration directory
14
+ puts executable.config.hybrid_platforms_dir
15
+ # => /path/to/my/platforms
16
+
17
+ # Access the NodesHandler to get the list of nodes
18
+ puts executable.nodes_handler.known_nodes.join(', ')
19
+ # => prod_web_server, test_web_server, test_firewall
20
+ ```
21
+
22
+ When **writing plugins, API components are already provided in the plugin's scope and methods using instance variables** such as `@nodes_handler`, `@cmd_runner`...
23
+ Please refer to the [plugins](plugins.md) documentation and method comments to know which API component is available when writing plugins.
24
+
25
+ Following sections are describing the various API components.
26
+
27
+ # Table of Contents
28
+ * [`nodes_handler`](#nodes_handler)
29
+ * [`actions_executor`](#actions_executor)
30
+ * [`config`](#config)
31
+ * [`cmd_runner`](#cmd_runner)
32
+ * [`platforms_handler`](#platforms_handler)
33
+ * [`deployer`](#deployer)
34
+ * [`services_handler`](#services_handler)
35
+ * [`reports_handler`](#reports_handler)
36
+ * [`tests_runner`](#tests_runner)
37
+
38
+ <a name="nodes_handler"></a>
39
+ ## `nodes_handler`
40
+
41
+ The `nodes_handler` API gives ways to handle the nodes inventory and the metadata.
42
+
43
+ Main usage:
44
+ ```ruby
45
+ require 'hybrid_platforms_conductor/executable'
46
+
47
+ nodes_handler = HybridPlatformsConductor::Executable.new.nodes_handler
48
+ ```
49
+
50
+ Then methods can be used on this `nodes_handler` object.
51
+ Check the [NodesHandler public methods](../lib/hybrid_platforms_conductor/nodes_handler.rb) to have an exhaustive list.
52
+
53
+ Examples:
54
+ ```ruby
55
+ # Get the list of nodes
56
+ nodes = nodes_handler.known_nodes
57
+
58
+ # Display a node's description, taken from its metadata
59
+ puts nodes_handler.get_description_of 'prod_node'
60
+ ```
61
+
62
+ <a name="actions_executor"></a>
63
+ ## `actions_executor`
64
+
65
+ The `actions_executor` API gives powerful ways to execute actions, locally or remotely on nodes.
66
+ It handle connectors to nodes (with host names resolution, SSH proxy settings), timeouts, parallel threads, logs in files...
67
+
68
+ Main usage:
69
+ ```ruby
70
+ require 'hybrid_platforms_conductor/executable'
71
+
72
+ actions_executor = HybridPlatformsConductor::Executable.new.actions_executor
73
+ ```
74
+
75
+ Then methods can be used on this `actions_executor` object.
76
+ Check the [ActionsExecutor public methods](../lib/hybrid_platforms_conductor/actions_executor.rb) to have an exhaustive list.
77
+
78
+ Examples:
79
+ ```ruby
80
+ # Set the SSH user name to be used in SSH connections
81
+ actions_executor.connector(:ssh).ssh_user = 'a_usernme'
82
+
83
+ # Set the "Dry run" flag that will display SSH commands without actually executing them
84
+ actions_executor.dry_run = true
85
+
86
+ # Activate log debugs
87
+ actions_executor.debug = true
88
+
89
+ # Run the hostname command on node23hst-nn1
90
+ actions_executor.execute_actions('node23hst-nn1' => { remote_bash: 'hostname' })
91
+
92
+ # Run the echo command on node23hst-nn1 by first setting environment variables
93
+ actions_executor.execute_actions('node23hst-nn1' => { remote_bash: { env: { 'MY_ENV' => 'value' }, commands: 'echo "${MY_ENV}"' } })
94
+
95
+ # Run the commands defined in file my_cmds.list on node23hst-nn1
96
+ actions_executor.execute_actions('node23hst-nn1' => { remote_bash: { file: 'my_cmds.list' } })
97
+
98
+ # Run the hostname command on both node23hst-nn1 and node23hst-nn2 with timeout of 5 seconds
99
+ actions_executor.execute_actions({ ['node23hst-nn1', 'node23hst-nn2'] => { remote_bash: 'hostname' } }, timeout: 5)
100
+
101
+ # Run the hostname and ls commands on both node23hst-nn1 and node23hst-nn2
102
+ actions_executor.execute_actions(['node23hst-nn1', 'node23hst-nn2'] => { remote_bash: ['hostname', 'ls'] })
103
+
104
+ # Run the commands hostname and the ones specified in my_cmds.list file on node23hst-nn1
105
+ actions_executor.execute_actions('node23hst-nn1' => { remote_bash: ['hostname', { file: 'my_cmds.list' }] })
106
+
107
+ # Run the hostname command on node23hst-nn1 and the ls command on node23hst-nn2
108
+ actions_executor.execute_actions('node23hst-nn1' => { remote_bash: 'hostname' }, 'node23hst-nn2' => { remote_bash: 'ls' } )
109
+
110
+ # Run an interactive shell on node23hst-nn1
111
+ actions_executor.execute_actions('node23hst-nn1' => { interactive: true })
112
+
113
+ # Run an scp command on node23hst-nn1
114
+ actions_executor.execute_actions('node23hst-nn1' => { scp: { 'my/local_file' => 'my/remote_file' } })
115
+
116
+ # Run 2 scp commands on node23hst-nn1
117
+ actions_executor.execute_actions('node23hst-nn1' => { scp: { 'my/local_file1' => 'my/remote_file1', 'my/local_file2' => 'my/remote_file2' } })
118
+
119
+ # Run 1 scp command + 1 hostname command on node23hst-nn1
120
+ actions_executor.execute_actions('node23hst-nn1' => [{ scp: { 'my/local_file' => 'my/remote_file' } }, { remote_bash: 'hostname' }])
121
+
122
+ # Run the hostname command on all hosts
123
+ actions_executor.execute_actions({ all: true } => { remote_bash: 'hostname' })
124
+
125
+ # Run the hostname command on all hosts containing xae
126
+ actions_executor.execute_actions('/xae/' => { remote_bash: 'hostname' })
127
+
128
+ # Run the hostname command on all hosts defined in the hosts list named my_host_list (file present in hosts_lists/my_host_list)
129
+ actions_executor.execute_actions({ list: 'my_host_list' } => { remote_bash: 'hostname' })
130
+
131
+ # Run the hostname command on all hosts containing xae, using parallel execution (log files will be output in run_logs/*.stdout)
132
+ actions_executor.execute_actions({ '/xae/' => { remote_bash: 'hostname' } }, concurrent: true)
133
+ ```
134
+
135
+ <a name="config"></a>
136
+ ## `config`
137
+
138
+ The `config` API gives access to the configuration (driven by the main `hpc_config.rb` file).
139
+ You can access the [configuration DSL](config_dsl.md) from it.
140
+
141
+ Main usage:
142
+ ```ruby
143
+ require 'hybrid_platforms_conductor/executable'
144
+
145
+ config = HybridPlatformsConductor::Executable.new.config
146
+ ```
147
+
148
+ Then methods can be used on this `config` object.
149
+ Check the [Config public methods](../lib/hybrid_platforms_conductor/config.rb) and the [configuration DSL](config_dsl.md) to have an exhaustive list.
150
+
151
+ Examples:
152
+ ```ruby
153
+ # Display the directory containing our configuration
154
+ puts config.hybrid_platforms_dir
155
+ # => /path/to/my-platforms
156
+
157
+ # List the OS images declared in the configuration
158
+ puts config.known_os_images.join(', ')
159
+ # => centos_7, debian_10
160
+ ```
161
+
162
+ <a name="cmd_runner"></a>
163
+ ## `cmd_runner`
164
+
165
+ The `cmd_runner` API gives a very extensible way to run commands locally and get back their exit status, stdout and stderr.
166
+ Its main entry point is the [`run_cmd`](../lib/hybrid_platforms_conductor/cmd_runner.rb) method, taking a lot of options to tweak the way commands are run.
167
+ Using this API in your plugins will naturally integrate with logging mechanisms and dry-runs.
168
+
169
+ Main usage:
170
+ ```ruby
171
+ require 'hybrid_platforms_conductor/executable'
172
+
173
+ cmd_runner = HybridPlatformsConductor::Executable.new.cmd_runner
174
+ ```
175
+
176
+ Then methods can be used on this `cmd_runner` object.
177
+ Check the [CmdRunner public methods](../lib/hybrid_platforms_conductor/cmd_runner.rb) to have an exhaustive list.
178
+
179
+ Examples:
180
+ ```ruby
181
+ # Run a simple command
182
+ cmd_runner.run_cmd 'echo Hello'
183
+
184
+ # Get back return code, stdout and stderr
185
+ exit_status, stdout, stderr = cmd_runner.run_cmd 'echo Hello'
186
+ puts stdout
187
+ # => Hello
188
+
189
+ # Add a timeout
190
+ cmd_runner.run_cmd 'sleep 5', timeout: 2
191
+ # => HybridPlatformsConductor::CmdRunner::TimeoutError (Command 'sleep 5' returned error code timeout (expected 0).)
192
+
193
+ # Log stdout in a file
194
+ cmd_runner.run_cmd 'echo Hello', log_to_file: 'hello.stdout'
195
+ puts File.read('hello.stdout')
196
+ # => Hello
197
+
198
+ ```
199
+
200
+ <a name="platforms_handler"></a>
201
+ ## `platforms_handler`
202
+
203
+ The `platforms_handler` API gives access to the various platforms repositories.
204
+
205
+ Main usage:
206
+ ```ruby
207
+ require 'hybrid_platforms_conductor/executable'
208
+
209
+ platforms_handler = HybridPlatformsConductor::Executable.new.platforms_handler
210
+ ```
211
+
212
+ Then methods can be used on this `platforms_handler` object.
213
+ Check the [PlatformsHandler public methods](../lib/hybrid_platforms_conductor/platforms_handler.rb) to have an exhaustive list.
214
+
215
+ Each platform is a [PlatformHandler plugin](plugins.md#platform_handler) that inherits from the base [PlatformHandler class](../lib/hybrid_platforms_conductor/platform_handler.rb).
216
+ So any public from this class is also accessible to each platform given through this API.
217
+
218
+ Examples:
219
+ ```ruby
220
+ # Get the first platform's name
221
+ puts platforms_handler.known_platforms.first.name
222
+
223
+ # Get the first platform's repository path
224
+ puts platforms_handler.known_platforms.first.repository_path
225
+
226
+ # Get the first platform's commit message that is currently targeted for deployment
227
+ puts platforms_handler.known_platforms.first.info[:commit][:message]
228
+ ```
229
+
230
+ <a name="deployer"></a>
231
+ ## `deployer`
232
+
233
+ The `deployer` API gives ways to deploy or check nodes.
234
+ It exposes also some helpers to parse deployment logs and retrieve deployment information.
235
+
236
+ Main usage:
237
+ ```ruby
238
+ require 'hybrid_platforms_conductor/executable'
239
+
240
+ deployer = HybridPlatformsConductor::Executable.new.deployer
241
+ ```
242
+
243
+ Then methods can be used on this `deployer` object.
244
+ Check the [Deployer public methods](../lib/hybrid_platforms_conductor/deployer.rb) to have an exhaustive list.
245
+
246
+ Examples:
247
+ ```ruby
248
+ # Set the check mode on
249
+ deployer.use_why_run = true
250
+
251
+ # Check/deploy on a given nodes' selection
252
+ deployer.deploy_on %w[prod_node test_node]
253
+
254
+ # Check/deploy on nodes selected by service
255
+ deployer.deploy_on({ service: 'firewall' })
256
+
257
+ # Retrieve deployment info from some nodes
258
+ deploy_info = deployer.deployment_info_from %w[prod_node test_node]
259
+ puts deploy_info['prod_node'][:services].join(', ')
260
+ # => firewall, web_server
261
+ ```
262
+
263
+ <a name="services_handler"></a>
264
+ ## `services_handler`
265
+
266
+ The `services_handler` API gives ways to deploy services on nodes.
267
+ It will use mainly the platform handlers' information regarding services to perform packaging, deployment...
268
+
269
+ Main usage:
270
+ ```ruby
271
+ require 'hybrid_platforms_conductor/executable'
272
+
273
+ services_handler = HybridPlatformsConductor::Executable.new.services_handler
274
+ ```
275
+
276
+ Then methods can be used on this `services_handler` object.
277
+ Check the [ServicesHandler public methods](../lib/hybrid_platforms_conductor/services_handler.rb) to have an exhaustive list.
278
+
279
+ Examples:
280
+ ```ruby
281
+ # Package platform repositories ready to be deploying a list of services on some nodes
282
+ services_handler.package(
283
+ services: {
284
+ 'prod_node' => %w[firewall web_server],
285
+ 'test_node' => %w[firewall]
286
+ },
287
+ secrets: {},
288
+ local_environment: false
289
+ )
290
+
291
+ # Get the actions to deploy a list of services on a node
292
+ actions = services_handler.actions_to_deploy_on('prod_node', %w[firewall web_server], false)
293
+ ```
294
+
295
+ <a name="reports_handler"></a>
296
+ ## `reports_handler`
297
+
298
+ The `reports_handler` API gives ways to produce reports.
299
+ It is mainly a wrapper around [`report` plugins](plugins.md#report) allowing any plugin to produce a report.
300
+
301
+ Main usage:
302
+ ```ruby
303
+ require 'hybrid_platforms_conductor/executable'
304
+
305
+ reports_handler = HybridPlatformsConductor::Executable.new.reports_handler
306
+ ```
307
+
308
+ Then methods can be used on this `reports_handler` object.
309
+ Check the [ReportsHandler public methods](../lib/hybrid_platforms_conductor/reports_handler.rb) to have an exhaustive list.
310
+
311
+ Examples:
312
+ ```ruby
313
+ # Set the reports format (corresponds to a reports plugin name)
314
+ reports_handler.format = :mediawiki
315
+
316
+ # Set the reports locale
317
+ reports_handler.locale = :en
318
+
319
+ # Produce a report for a given selection of nodes
320
+ reports_handler.produce_report_for %w[prod_node test_node]
321
+ ```
322
+
323
+ <a name="tests_runner"></a>
324
+ ## `tests_runner`
325
+
326
+ The `tests_runner` API gives ways to run tests.
327
+ It will use [`test` plugins](plugins.md#test) and [`test_report` plugins](plugins.md#test_report).
328
+
329
+ Main usage:
330
+ ```ruby
331
+ require 'hybrid_platforms_conductor/executable'
332
+
333
+ tests_runner = HybridPlatformsConductor::Executable.new.tests_runner
334
+ ```
335
+
336
+ Then methods can be used on this `tests_runner` object.
337
+ Check the [TestsRunner public methods](../lib/hybrid_platforms_conductor/tests_runner.rb) to have an exhaustive list.
338
+
339
+ Examples:
340
+ ```ruby
341
+ # Set the list of tests to be executed (test plugin names)
342
+ tests_runner.tests = %i[connection hostname]
343
+
344
+ # Set the test reports to be produced (test_report plugin names)
345
+ tests_runner.reports = %i[stdout confluence]
346
+
347
+ # Run tests for a given nodes selection
348
+ tests_runner.run_tests %w[prod_node test_node]
349
+ ```