hybrid_platforms_conductor 32.11.2 → 32.13.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1121 -0
- data/LICENSE.md +31 -0
- data/README.md +402 -0
- data/bin/setup +1 -1
- data/docs/api.md +349 -0
- data/docs/config_dsl.md +315 -0
- data/docs/executables.md +226 -0
- data/docs/executables/check-node.md +155 -0
- data/docs/executables/deploy.md +198 -0
- data/docs/executables/dump_nodes_json.md +110 -0
- data/docs/executables/free_ips.md +93 -0
- data/docs/executables/free_veids.md +73 -0
- data/docs/executables/get_impacted_nodes.md +94 -0
- data/docs/executables/last_deploys.md +114 -0
- data/docs/executables/nodes_to_deploy.md +139 -0
- data/docs/executables/report.md +159 -0
- data/docs/executables/run.md +126 -0
- data/docs/executables/setup.md +92 -0
- data/docs/executables/ssh_config.md +151 -0
- data/docs/executables/test.md +213 -0
- data/docs/executables/topograph.md +139 -0
- data/docs/gen/mermaid/README.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/check-node.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/deploy.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/free_ips.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/free_veids.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/get_impacted_nodes.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/last_deploys.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/nodes_to_deploy.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/report.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/run.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/setup.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/ssh_config.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/test.md-0.png +0 -0
- data/docs/install.md +161 -0
- data/docs/plugins.md +215 -0
- data/docs/plugins/action/bash.md +37 -0
- data/docs/plugins/action/interactive.md +37 -0
- data/docs/plugins/action/remote_bash.md +67 -0
- data/docs/plugins/action/ruby.md +69 -0
- data/docs/plugins/action/scp.md +61 -0
- data/docs/plugins/cmdb/config.md +46 -0
- data/docs/plugins/cmdb/host_ip.md +33 -0
- data/docs/plugins/cmdb/host_keys.md +33 -0
- data/docs/plugins/cmdb/platform_handlers.md +33 -0
- data/docs/plugins/connector/local.md +28 -0
- data/docs/plugins/connector/ssh.md +95 -0
- data/docs/plugins/platform_handler/yaml_inventory.md +105 -0
- data/docs/plugins/provisioner/docker.md +27 -0
- data/docs/plugins/provisioner/podman.md +27 -0
- data/docs/plugins/provisioner/proxmox.md +115 -0
- data/docs/plugins/report/confluence.md +49 -0
- data/docs/plugins/report/mediawiki.md +28 -0
- data/docs/plugins/report/stdout.md +32 -0
- data/docs/plugins/test/bitbucket_conf.md +97 -0
- data/docs/plugins/test/can_be_checked.md +27 -0
- data/docs/plugins/test/check_deploy_and_idempotence.md +61 -0
- data/docs/plugins/test/check_from_scratch.md +28 -0
- data/docs/plugins/test/connection.md +27 -0
- data/docs/plugins/test/deploy_freshness.md +27 -0
- data/docs/plugins/test/deploy_from_scratch.md +28 -0
- data/docs/plugins/test/deploy_removes_root_access.md +29 -0
- data/docs/plugins/test/divergence.md +41 -0
- data/docs/plugins/test/executables.md +26 -0
- data/docs/plugins/test/file_system.md +49 -0
- data/docs/plugins/test/file_system_hdfs.md +65 -0
- data/docs/plugins/test/hostname.md +27 -0
- data/docs/plugins/test/idempotence.md +56 -0
- data/docs/plugins/test/ip.md +28 -0
- data/docs/plugins/test/jenkins_ci_conf.md +54 -0
- data/docs/plugins/test/jenkins_ci_masters_ok.md +54 -0
- data/docs/plugins/test/linear_strategy.md +26 -0
- data/docs/plugins/test/local_users.md +48 -0
- data/docs/plugins/test/mounts.md +55 -0
- data/docs/plugins/test/orphan_files.md +38 -0
- data/docs/plugins/test/ports.md +50 -0
- data/docs/plugins/test/private_ips.md +27 -0
- data/docs/plugins/test/public_ips.md +27 -0
- data/docs/plugins/test/spectre.md +26 -0
- data/docs/plugins/test/veids.md +27 -0
- data/docs/plugins/test/vulnerabilities.md +65 -0
- data/docs/plugins/test_report/confluence.md +43 -0
- data/docs/plugins/test_report/stdout.md +26 -0
- data/docs/plugins_create.md +135 -0
- data/docs/tutorial.md +61 -0
- data/docs/tutorial/01_installation.md +131 -0
- data/docs/tutorial/02_first_node.md +468 -0
- data/docs/tutorial/03_scale.md +878 -0
- data/docs/tutorial/04_test.md +977 -0
- data/docs/tutorial/05_extend_with_plugins.md +1132 -0
- data/examples/bare/Gemfile +4 -0
- data/examples/bare/hpc_config.rb +2 -0
- data/examples/localhost/Gemfile +4 -0
- data/examples/localhost/hpc_config.rb +2 -0
- data/examples/localhost/inventory.yaml +4 -0
- data/examples/tutorial/01_installation/my-platforms/Gemfile +3 -0
- data/examples/tutorial/01_installation/my-platforms/hpc_config.rb +0 -0
- data/examples/tutorial/02_first_node/my-platforms/Gemfile +3 -0
- data/examples/tutorial/02_first_node/my-platforms/hpc_config.rb +1 -0
- data/examples/tutorial/02_first_node/my-service-conf-repo/inventory.yaml +13 -0
- data/examples/tutorial/02_first_node/my-service-conf-repo/my-service.conf.erb +3 -0
- data/examples/tutorial/02_first_node/my-service-conf-repo/service_my-service.rb +58 -0
- data/examples/tutorial/02_first_node/node/my-service.conf +4 -0
- data/examples/tutorial/03_scale/my-platforms/Gemfile +3 -0
- data/examples/tutorial/03_scale/my-platforms/hpc_config.rb +1 -0
- data/examples/tutorial/03_scale/my-platforms/my_commands.bash +2 -0
- data/examples/tutorial/03_scale/my-service-conf-repo/inventory.yaml +90 -0
- data/examples/tutorial/03_scale/my-service-conf-repo/my-service.conf.erb +3 -0
- data/examples/tutorial/03_scale/my-service-conf-repo/service_my-service.rb +58 -0
- data/examples/tutorial/03_scale/my-service-conf-repo/service_web-hello.rb +43 -0
- data/examples/tutorial/03_scale/node/my-service.conf +4 -0
- data/examples/tutorial/03_scale/web_docker_image/Dockerfile +33 -0
- data/examples/tutorial/03_scale/web_docker_image/hello_world.txt +1 -0
- data/examples/tutorial/03_scale/web_docker_image/hpc_root.key +27 -0
- data/examples/tutorial/03_scale/web_docker_image/hpc_root.key.pub +1 -0
- data/examples/tutorial/03_scale/web_docker_image/main.go +43 -0
- data/examples/tutorial/03_scale/web_docker_image/start.sh +7 -0
- data/examples/tutorial/03_scale/web_docker_image/test.bash +6 -0
- data/examples/tutorial/04_test/my-platforms/Gemfile +3 -0
- data/examples/tutorial/04_test/my-platforms/hpc_config.rb +12 -0
- data/examples/tutorial/04_test/my-platforms/images/debian_10/Dockerfile +13 -0
- data/examples/tutorial/04_test/my-platforms/my_commands.bash +2 -0
- data/examples/tutorial/04_test/my-service-conf-repo/inventory.yaml +100 -0
- data/examples/tutorial/04_test/my-service-conf-repo/my-service.conf.erb +3 -0
- data/examples/tutorial/04_test/my-service-conf-repo/service_my-service.rb +58 -0
- data/examples/tutorial/04_test/my-service-conf-repo/service_web-hello.rb +43 -0
- data/examples/tutorial/04_test/node/my-service.conf +4 -0
- data/examples/tutorial/04_test/web_docker_image/Dockerfile +33 -0
- data/examples/tutorial/04_test/web_docker_image/hello_world.txt +1 -0
- data/examples/tutorial/04_test/web_docker_image/hpc_root.key +27 -0
- data/examples/tutorial/04_test/web_docker_image/hpc_root.key.pub +1 -0
- data/examples/tutorial/04_test/web_docker_image/main.go +43 -0
- data/examples/tutorial/04_test/web_docker_image/start.sh +7 -0
- data/examples/tutorial/04_test/web_docker_image/test.bash +6 -0
- data/examples/tutorial/05_extend_with_plugins/dev-servers-conf-repo/hosts.json +12 -0
- data/examples/tutorial/05_extend_with_plugins/dev-servers-conf-repo/install-gcc.bash +14 -0
- data/examples/tutorial/05_extend_with_plugins/dev-servers-conf-repo/install-python.bash +14 -0
- data/examples/tutorial/05_extend_with_plugins/dev_docker_image/Dockerfile +20 -0
- data/examples/tutorial/05_extend_with_plugins/dev_docker_image/hpc_root.key +27 -0
- data/examples/tutorial/05_extend_with_plugins/dev_docker_image/hpc_root.key.pub +1 -0
- data/examples/tutorial/05_extend_with_plugins/my-platforms/Gemfile +4 -0
- data/examples/tutorial/05_extend_with_plugins/my-platforms/hpc_config.rb +13 -0
- data/examples/tutorial/05_extend_with_plugins/my-platforms/images/debian_10/Dockerfile +13 -0
- data/examples/tutorial/05_extend_with_plugins/my-platforms/my_commands.bash +2 -0
- data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/inventory.yaml +100 -0
- data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/my-service.conf.erb +3 -0
- data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/service_my-service.rb +58 -0
- data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/service_web-hello.rb +43 -0
- data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/lib/my_hpc_plugins/hpc_plugins/platform_handler/json_bash.rb +115 -0
- data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/lib/my_hpc_plugins/hpc_plugins/report/web_report.rb +52 -0
- data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/lib/my_hpc_plugins/hpc_plugins/test/root_space.rb +44 -0
- data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/my_hpc_plugins.gemspec +15 -0
- data/examples/tutorial/05_extend_with_plugins/node/my-service.conf +4 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/Dockerfile +33 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/hello_world.txt +1 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/hpc_root.key +27 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/hpc_root.key.pub +1 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/main.go +43 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/start.sh +7 -0
- data/examples/tutorial/05_extend_with_plugins/web_docker_image/test.bash +6 -0
- data/lib/hybrid_platforms_conductor/actions_executor.rb +1 -0
- data/lib/hybrid_platforms_conductor/deployer.rb +3 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/action/remote_bash.rb +29 -13
- data/lib/hybrid_platforms_conductor/hpc_plugins/action/scp.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/local.rb +98 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/my_connector.rb.sample +2 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +15 -4
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/platform_handler_plugin.rb.sample +5 -5
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/yaml_inventory.rb +140 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox.rb +6 -3
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/bitbucket_conf.rb +4 -4
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_freshness.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +19 -17
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/divergence.rb +3 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +2 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +2 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +2 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +4 -3
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +2 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +8 -7
- data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/confluence.rb +1 -1
- data/lib/hybrid_platforms_conductor/json_dumper.rb +1 -1
- data/lib/hybrid_platforms_conductor/platform_handler.rb +1 -1
- data/lib/hybrid_platforms_conductor/services_handler.rb +18 -16
- data/lib/hybrid_platforms_conductor/tests_runner.rb +0 -1
- data/lib/hybrid_platforms_conductor/topographer.rb +0 -1
- data/lib/hybrid_platforms_conductor/version.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/remote_bash_spec.rb +16 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/connectable_nodes_spec.rb +30 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/remote_actions_spec.rb +113 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/cli_options_spec.rb +6 -2
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/global_helpers_spec.rb +38 -1
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb +37 -4
- data/spec/hybrid_platforms_conductor_test/docs_spec.rb +10 -0
- data/tools/check_md +89 -0
- data/tools/generate_mermaid +75 -0
- metadata +337 -12
data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/platform_handler_plugin.rb.sample
CHANGED
@@ -69,7 +69,7 @@ module HybridPlatformsConductor
|
|
69
69
|
end
|
70
70
|
|
71
71
|
# Setup the platform, install dependencies...
|
72
|
-
# [API] - This method is
|
72
|
+
# [API] - This method is optional.
|
73
73
|
# [API] - @cmd_runner is accessible.
|
74
74
|
def setup
|
75
75
|
# This method is called by the setup executable.
|
@@ -163,7 +163,7 @@ module HybridPlatformsConductor
|
|
163
163
|
end
|
164
164
|
|
165
165
|
# Package the repository, ready to be deployed on artefacts or directly to a node.
|
166
|
-
# [API] - This method is
|
166
|
+
# [API] - This method is optional.
|
167
167
|
# [API] - @cmd_runner is accessible.
|
168
168
|
# [API] - @actions_executor is accessible.
|
169
169
|
#
|
@@ -212,7 +212,7 @@ module HybridPlatformsConductor
|
|
212
212
|
# This method returns all the actions to execute to deploy on a node.
|
213
213
|
# The use_why_run switch is on if the deployment should just be simulated.
|
214
214
|
# Those actions (bash commands, scp of files, ruby code...) should be thread safe as they can be executed in parallel with other deployment actions for other nodes in case of a concurrent deployment on several nodes.
|
215
|
-
# The complete description of an action can be found in
|
215
|
+
# The complete description of an action can be found in the action plugins' documentation.
|
216
216
|
[
|
217
217
|
{
|
218
218
|
scp: {
|
@@ -229,7 +229,7 @@ module HybridPlatformsConductor
|
|
229
229
|
end
|
230
230
|
|
231
231
|
# Prepare a why-run deployment so that a JSON file describing the nodes will be output in the run_logs.
|
232
|
-
# [API] - This method is
|
232
|
+
# [API] - This method is optional.
|
233
233
|
# [API] - @cmd_runner is accessible.
|
234
234
|
# [API] - @actions_executor is accessible.
|
235
235
|
# [API] - @deployer is accessible.
|
@@ -247,7 +247,7 @@ module HybridPlatformsConductor
|
|
247
247
|
# Result::
|
248
248
|
# * Array< Hash<Symbol,Object> >: List of task properties. The following properties should be returned, among free ones:
|
249
249
|
# * *name* (String): Task name
|
250
|
-
# * *status* (Symbol): Task status. Should be
|
250
|
+
# * *status* (Symbol): Task status. Should be one of:
|
251
251
|
# * *:changed*: The task has been changed
|
252
252
|
# * *:identical*: The task has not been changed
|
253
253
|
# * *diffs* (String): Differences, if any
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'hybrid_platforms_conductor/platform_handler'
|
3
|
+
|
4
|
+
module HybridPlatformsConductor
|
5
|
+
|
6
|
+
module HpcPlugins
|
7
|
+
|
8
|
+
module PlatformHandler
|
9
|
+
|
10
|
+
# Basic platform handler, reading inventory and metadata from simple Yaml files.
|
11
|
+
class YamlInventory < HybridPlatformsConductor::PlatformHandler
|
12
|
+
|
13
|
+
# Initialize a new instance of this platform handler.
|
14
|
+
# [API] - This method is optional.
|
15
|
+
# [API] - @cmd_runner is accessible.
|
16
|
+
def init
|
17
|
+
# This method is called when initializing a new instance of this platform handler, for a given repository.
|
18
|
+
inv_file = "#{@repository_path}/inventory.yaml"
|
19
|
+
@inventory = File.exist?(inv_file) ? YAML.load(File.read(inv_file)) : {}
|
20
|
+
end
|
21
|
+
|
22
|
+
# Get the list of known nodes.
|
23
|
+
# [API] - This method is mandatory.
|
24
|
+
#
|
25
|
+
# Result::
|
26
|
+
# * Array<String>: List of node names
|
27
|
+
def known_nodes
|
28
|
+
@inventory.keys
|
29
|
+
end
|
30
|
+
|
31
|
+
# Get the metadata of a given node.
|
32
|
+
# [API] - This method is mandatory.
|
33
|
+
#
|
34
|
+
# Parameters::
|
35
|
+
# * *node* (String): Node to read metadata from
|
36
|
+
# Result::
|
37
|
+
# * Hash<Symbol,Object>: The corresponding metadata
|
38
|
+
def metadata_for(node)
|
39
|
+
(@inventory[node]['metadata'] || {}).transform_keys(&:to_sym)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Return the services for a given node
|
43
|
+
# [API] - This method is mandatory.
|
44
|
+
#
|
45
|
+
# Parameters::
|
46
|
+
# * *node* (String): node to read configuration from
|
47
|
+
# Result::
|
48
|
+
# * Array<String>: The corresponding services
|
49
|
+
def services_for(node)
|
50
|
+
@inventory[node]['services'] || []
|
51
|
+
end
|
52
|
+
|
53
|
+
# Get the list of services we can deploy
|
54
|
+
# [API] - This method is mandatory.
|
55
|
+
#
|
56
|
+
# Result::
|
57
|
+
# * Array<String>: The corresponding services
|
58
|
+
def deployable_services
|
59
|
+
Dir.glob("#{@repository_path}/service_*.rb").map { |file| File.basename(file).match(/^service_(.*)\.rb$/)[1] }
|
60
|
+
end
|
61
|
+
|
62
|
+
# Get the list of actions to perform to deploy on a given node.
|
63
|
+
# Those actions can be executed in parallel with other deployments on other nodes. They must be thread safe.
|
64
|
+
# [API] - This method is mandatory.
|
65
|
+
# [API] - @cmd_runner is accessible.
|
66
|
+
# [API] - @actions_executor is accessible.
|
67
|
+
#
|
68
|
+
# Parameters::
|
69
|
+
# * *node* (String): Node to deploy on
|
70
|
+
# * *service* (String): Service to be deployed
|
71
|
+
# * *use_why_run* (Boolean): Do we use a why-run mode? [default = true]
|
72
|
+
# Result::
|
73
|
+
# * Array< Hash<Symbol,Object> >: List of actions to be done
|
74
|
+
def actions_to_deploy_on(node, service, use_why_run: true)
|
75
|
+
# Load the check and deploy methods in a temporary class for encapsulation
|
76
|
+
service_file = "#{@repository_path}/service_#{service}.rb"
|
77
|
+
Class.new do
|
78
|
+
|
79
|
+
include LoggerHelpers
|
80
|
+
|
81
|
+
# Constructor
|
82
|
+
#
|
83
|
+
# Parameters::
|
84
|
+
# * *platform_handler* (PlatformHandler): PlatformHandler needing this service to be deployed
|
85
|
+
# * *logger* (Logger): Logger to be used [default: Logger.new(STDOUT)]
|
86
|
+
# * *logger_stderr* (Logger): Logger to be used for stderr [default: Logger.new(STDERR)]
|
87
|
+
# * *config* (Config): Config to be used. [default: Config.new]
|
88
|
+
# * *nodes_handler* (NodesHandler): NodesHandler to be used [default: NodesHandler.new]
|
89
|
+
# * *cmd_runner* (CmdRunner): CmdRunner to be used [default: CmdRunner.new]
|
90
|
+
def initialize(
|
91
|
+
platform_handler,
|
92
|
+
logger: Logger.new(STDOUT),
|
93
|
+
logger_stderr: Logger.new(STDERR),
|
94
|
+
config: Config.new,
|
95
|
+
nodes_handler: NodesHandler.new,
|
96
|
+
cmd_runner: CmdRunner.new
|
97
|
+
)
|
98
|
+
init_loggers(logger, logger_stderr)
|
99
|
+
@platform_handler = platform_handler
|
100
|
+
@config = config
|
101
|
+
@nodes_handler = nodes_handler
|
102
|
+
@cmd_runner = cmd_runner
|
103
|
+
end
|
104
|
+
|
105
|
+
class_eval(File.read(service_file))
|
106
|
+
|
107
|
+
end.new(
|
108
|
+
self,
|
109
|
+
logger: @logger,
|
110
|
+
logger_stderr: @logger_stderr,
|
111
|
+
config: @config,
|
112
|
+
nodes_handler: @nodes_handler,
|
113
|
+
cmd_runner: @cmd_runner
|
114
|
+
).send(use_why_run ? :check : :deploy, node)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Parse stdout and stderr of a given deploy run and get the list of tasks with their status
|
118
|
+
# [API] - This method is mandatory.
|
119
|
+
#
|
120
|
+
# Parameters::
|
121
|
+
# * *stdout* (String): stdout to be parsed
|
122
|
+
# * *stderr* (String): stderr to be parsed
|
123
|
+
# Result::
|
124
|
+
# * Array< Hash<Symbol,Object> >: List of task properties. The following properties should be returned, among free ones:
|
125
|
+
# * *name* (String): Task name
|
126
|
+
# * *status* (Symbol): Task status. Should be one of:
|
127
|
+
# * *:changed*: The task has been changed
|
128
|
+
# * *:identical*: The task has not been changed
|
129
|
+
# * *diffs* (String): Differences, if any
|
130
|
+
def parse_deploy_output(stdout, stderr)
|
131
|
+
[]
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
@@ -15,7 +15,7 @@ module HybridPlatformsConductor
|
|
15
15
|
|
16
16
|
include LoggerHelpers
|
17
17
|
|
18
|
-
attr_accessor
|
18
|
+
attr_accessor(*%i[logger logger_stderr])
|
19
19
|
|
20
20
|
def check_response(response)
|
21
21
|
msg = "Response from Proxmox API: #{response} - #{response.net_http_res.message}"
|
@@ -154,7 +154,7 @@ module HybridPlatformsConductor
|
|
154
154
|
hostname = "-#{Digest::MD5.hexdigest(hostname)[0..7]}.hpc-test.com"
|
155
155
|
hostname = "#{@node}.#{@environment}"[0..MAX_PROXMOX_HOSTNAME_SIZE - hostname.size - 1] + hostname
|
156
156
|
end
|
157
|
-
@lxc_details = request_lxc_creation_for(
|
157
|
+
@lxc_details = request_lxc_creation_for({
|
158
158
|
ostemplate: pve_template,
|
159
159
|
hostname: hostname.gsub('_', '-'),
|
160
160
|
cores: min_resources_to_deploy[:cpus],
|
@@ -540,7 +540,10 @@ module HybridPlatformsConductor
|
|
540
540
|
# * *api_wait_between_retries_secs* (Integer): Number of seconds to wait between API retries
|
541
541
|
# * *sync_node* (String): Node to be used to synchronize Proxmox resources acquisition
|
542
542
|
# * *test_config* (Hash<Symbol,Object>): The test configuration. Check ProxmoxWaiter#initialize (config_file structure) method to get details.
|
543
|
-
# * *vm_config* (Hash<Symbol,Object>): Extra configuration of a created container
|
543
|
+
# * *vm_config* (Hash<Symbol,Object>): Extra configuration of a created container:
|
544
|
+
# * *vm_dns_servers* (Array<String>): List of DNS servers
|
545
|
+
# * *vm_search_domain* (String): Default search domain
|
546
|
+
# * *vm_gateway* (String): Gateway hostname or IP
|
544
547
|
# * *default_timeout* (Integer): The default timeout tobe applied when starting/stopping containers [default: 3600].
|
545
548
|
def proxmox_test_info
|
546
549
|
@config.proxmox_servers.first
|
@@ -60,7 +60,7 @@ module HybridPlatformsConductor
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
# Merge checks
|
63
|
-
required_approvers = repo_info.dig
|
63
|
+
required_approvers = repo_info.dig(*%i[checks pr_settings required_approvers])
|
64
64
|
if required_approvers
|
65
65
|
assert_equal(
|
66
66
|
settings_pr.dig('com.atlassian.bitbucket.server.bitbucket-bundled-hooks:requiredApprovers', 'enable'),
|
@@ -73,7 +73,7 @@ module HybridPlatformsConductor
|
|
73
73
|
"[#{repo_id}] - Number of required approvers should be #{required_approvers}"
|
74
74
|
)
|
75
75
|
end
|
76
|
-
required_builds = repo_info.dig
|
76
|
+
required_builds = repo_info.dig(*%i[checks pr_settings required_builds])
|
77
77
|
if required_builds
|
78
78
|
assert_equal(
|
79
79
|
settings_pr.dig('com.atlassian.bitbucket.server.bitbucket-build:requiredBuilds', 'enable'),
|
@@ -87,7 +87,7 @@ module HybridPlatformsConductor
|
|
87
87
|
)
|
88
88
|
end
|
89
89
|
# Default merge strategy
|
90
|
-
default_merge_strategy = repo_info.dig
|
90
|
+
default_merge_strategy = repo_info.dig(*%i[checks pr_settings default_merge_strategy])
|
91
91
|
if default_merge_strategy
|
92
92
|
assert_equal(
|
93
93
|
settings_pr.dig('mergeConfig', 'defaultStrategy', 'id'),
|
@@ -104,7 +104,7 @@ module HybridPlatformsConductor
|
|
104
104
|
)
|
105
105
|
end
|
106
106
|
# Default reviewers should include our team from any branch to any branch
|
107
|
-
mandatory_default_reviewers = repo_info.dig
|
107
|
+
mandatory_default_reviewers = repo_info.dig(*%i[checks pr_settings mandatory_default_reviewers])
|
108
108
|
if mandatory_default_reviewers
|
109
109
|
reviewers_found = default_reviewers.any? do |condition_info|
|
110
110
|
reviewers = condition_info.dig('reviewers')
|
@@ -22,7 +22,7 @@ module HybridPlatformsConductor
|
|
22
22
|
error 'Node has never been deployed using deploy (/var/log/deployments does not exist)'
|
23
23
|
else
|
24
24
|
# Expecting following file names
|
25
|
-
#
|
25
|
+
# node-name_2017-12-01_093418_user-name
|
26
26
|
file_match = stdout.first.match(/^#{Regexp.escape(@node)}_(\d{4}-\d{2}-\d{2})_.+$/)
|
27
27
|
if file_match.nil?
|
28
28
|
error "Invalid chef deployment log file found: #{stdout.first}"
|
@@ -12,22 +12,9 @@ module HybridPlatformsConductor
|
|
12
12
|
|
13
13
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
14
14
|
def test_for_node
|
15
|
-
@
|
16
|
-
|
17
|
-
|
18
|
-
begin
|
19
|
-
Net::SSH.start(instance.ip, 'root', password: 'root_pwd', auth_methods: ['password'], verify_host_key: :never) do |ssh|
|
20
|
-
ssh_ok = ssh.exec!('echo Works').strip == 'Works'
|
21
|
-
end
|
22
|
-
rescue
|
23
|
-
end
|
24
|
-
assert_equal ssh_ok, true, 'Root does not have access from the empty image'
|
25
|
-
if ssh_ok
|
26
|
-
deployer.nbr_retries_on_error = 3
|
27
|
-
deployer.deploy_on @node
|
28
|
-
# As sshd is certainly being restarted, start and stop the container to reload it.
|
29
|
-
deployer.restart @node
|
30
|
-
# Check that we can't connect with root
|
15
|
+
unless @nodes_handler.get_root_access_allowed_of(@node) == 'true'
|
16
|
+
@deployer.with_test_provisioned_instance(@config.tests_provisioner_id, @node, environment: 'deploy_removes_root_access', reuse_instance: log_debug?) do |deployer, instance|
|
17
|
+
# Check that we can connect with root
|
31
18
|
ssh_ok = false
|
32
19
|
begin
|
33
20
|
Net::SSH.start(instance.ip, 'root', password: 'root_pwd', auth_methods: ['password'], verify_host_key: :never) do |ssh|
|
@@ -35,7 +22,22 @@ module HybridPlatformsConductor
|
|
35
22
|
end
|
36
23
|
rescue
|
37
24
|
end
|
38
|
-
assert_equal ssh_ok,
|
25
|
+
assert_equal ssh_ok, true, 'Root does not have access from the empty image'
|
26
|
+
if ssh_ok
|
27
|
+
deployer.nbr_retries_on_error = 3
|
28
|
+
deployer.deploy_on @node
|
29
|
+
# As sshd is certainly being restarted, start and stop the container to reload it.
|
30
|
+
deployer.restart @node
|
31
|
+
# Check that we can't connect with root
|
32
|
+
ssh_ok = false
|
33
|
+
begin
|
34
|
+
Net::SSH.start(instance.ip, 'root', password: 'root_pwd', auth_methods: ['password'], verify_host_key: :never) do |ssh|
|
35
|
+
ssh_ok = ssh.exec!('echo Works').strip == 'Works'
|
36
|
+
end
|
37
|
+
rescue
|
38
|
+
end
|
39
|
+
assert_equal ssh_ok, false, 'Root can still connect on the image after deployment'
|
40
|
+
end
|
39
41
|
end
|
40
42
|
end
|
41
43
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'json'
|
2
|
+
require 'hybrid_platforms_conductor/common_config_dsl/idempotence_tests'
|
2
3
|
|
3
4
|
module HybridPlatformsConductor
|
4
5
|
|
@@ -9,6 +10,8 @@ module HybridPlatformsConductor
|
|
9
10
|
# Test that the node has not diverged since last deployment
|
10
11
|
class Divergence < HybridPlatformsConductor::Test
|
11
12
|
|
13
|
+
self.extend_config_dsl_with CommonConfigDsl::IdempotenceTests, :init_idempotence_tests
|
14
|
+
|
12
15
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
13
16
|
def test_on_check_node(stdout, stderr, exit_status)
|
14
17
|
# Check that the output of the check-node returns no changes.
|
@@ -10,7 +10,8 @@ module HybridPlatformsConductor
|
|
10
10
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
11
11
|
def test_on_node
|
12
12
|
{
|
13
|
-
|
13
|
+
# TODO: Access the user correctly when the user notion will be moved out of the ssh connector
|
14
|
+
"#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}hostname -s" => proc do |stdout|
|
14
15
|
assert_equal stdout.first, @node, "Expected hostname to be #{@node}, but got #{stdout.first} instead."
|
15
16
|
end
|
16
17
|
}
|
@@ -10,7 +10,8 @@ module HybridPlatformsConductor
|
|
10
10
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
11
11
|
def test_on_node
|
12
12
|
{
|
13
|
-
|
13
|
+
# TODO: Access the user correctly when the user notion will be moved out of the ssh connector
|
14
|
+
"#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}hostname -I" => proc do |stdout|
|
14
15
|
if stdout.first.nil?
|
15
16
|
error 'No IP returned by "hostname -I"'
|
16
17
|
else
|
@@ -57,7 +57,8 @@ module HybridPlatformsConductor
|
|
57
57
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
58
58
|
def test_on_node
|
59
59
|
{
|
60
|
-
|
60
|
+
# TODO: Access the user correctly when the user notion will be moved out of the ssh connector
|
61
|
+
"#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}cat /etc/passwd" => proc do |stdout|
|
61
62
|
passwd_users = stdout.map { |passwd_line| passwd_line.split(':').first }
|
62
63
|
missing_users = @nodes_handler.
|
63
64
|
select_confs_for_node(@node, @config.users_that_should_be_present).
|
@@ -32,7 +32,7 @@ module HybridPlatformsConductor
|
|
32
32
|
#
|
33
33
|
# Parameters::
|
34
34
|
# * *mount_rules* (Hash<String or Regexp, String or Regexp>):
|
35
|
-
#
|
35
|
+
# Set of { source => destination } mounts that should not be present.
|
36
36
|
# Each source or destination can be a string for exact match, or a regexp to match a pattern on the mounts done on the node.
|
37
37
|
def check_mounts_do_not_include(mount_rules)
|
38
38
|
@mount_rules_that_should_be_absent << {
|
@@ -45,7 +45,7 @@ module HybridPlatformsConductor
|
|
45
45
|
#
|
46
46
|
# Parameters::
|
47
47
|
# * *mount_rules* (Hash<String or Regexp, String or Regexp>):
|
48
|
-
#
|
48
|
+
# Set of { source => destination } mounts that should be present.
|
49
49
|
# Each source or destination can be a string for exact match, or a regexp to match a pattern on the mounts done on the node.
|
50
50
|
def check_mounts_do_include(mount_rules)
|
51
51
|
@mount_rules_that_should_be_present << {
|
@@ -61,7 +61,8 @@ module HybridPlatformsConductor
|
|
61
61
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
62
62
|
def test_on_node
|
63
63
|
{
|
64
|
-
|
64
|
+
# TODO: Access the user correctly when the user notion will be moved out of the ssh connector
|
65
|
+
"#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}mount" => proc do |stdout|
|
65
66
|
mounts_info = stdout.map do |line|
|
66
67
|
fields = line.split
|
67
68
|
{
|
@@ -50,7 +50,8 @@ module HybridPlatformsConductor
|
|
50
50
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
51
51
|
def test_on_node
|
52
52
|
{
|
53
|
-
|
53
|
+
# TODO: Access the user correctly when the user notion will be moved out of the ssh connector
|
54
|
+
"#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}/usr/bin/find / \\( #{@nodes_handler.
|
54
55
|
select_confs_for_node(@node, @config.ignored_orphan_files_paths).
|
55
56
|
inject(DIRECTORIES_TO_ALWAYS_IGNORE) { |merged_paths, paths_to_ignore_info| merged_paths + paths_to_ignore_info[:ignored_paths] }.
|
56
57
|
uniq.
|
@@ -16,7 +16,7 @@ module HybridPlatformsConductor
|
|
16
16
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
17
17
|
def test_on_node
|
18
18
|
spectre_cmd = <<~EOS
|
19
|
-
#{@nodes_handler.sudo_on(@node)} /bin/bash <<'EOAction'
|
19
|
+
#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}/bin/bash <<'EOAction'
|
20
20
|
#{File.read("#{__dir__}/spectre-meltdown-checker.sh")}
|
21
21
|
EOAction
|
22
22
|
EOS
|
@@ -54,7 +54,8 @@ module HybridPlatformsConductor
|
|
54
54
|
current_url
|
55
55
|
end
|
56
56
|
)
|
57
|
-
|
57
|
+
# TODO: Access the user correctly when the user notion will be moved out of the ssh connector
|
58
|
+
sudo = @deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "
|
58
59
|
Hash[urls.map do |url|
|
59
60
|
# 1. Get the OVAL file on the node to be tested (uncompress it if needed)
|
60
61
|
# 2. Make sure oscap is installed
|
@@ -75,9 +76,9 @@ module HybridPlatformsConductor
|
|
75
76
|
#{
|
76
77
|
case image
|
77
78
|
when :centos_7
|
78
|
-
"#{sudo}
|
79
|
+
"#{sudo}yum install -y wget openscap-scanner #{packages_to_install.join(' ')}"
|
79
80
|
when :debian_9
|
80
|
-
"#{sudo}
|
81
|
+
"#{sudo}apt install -y wget libopenscap8 #{packages_to_install.join(' ')}"
|
81
82
|
when :debian_10
|
82
83
|
# On Debian 10 we have to compile it from sources, as the packaged official version has core dumps.
|
83
84
|
# cf https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1688223.html
|
@@ -87,13 +88,13 @@ module HybridPlatformsConductor
|
|
87
88
|
rm -rf openscap
|
88
89
|
git clone --recurse-submodules https://github.com/OpenSCAP/openscap.git
|
89
90
|
cd openscap
|
90
|
-
#{sudo}
|
91
|
+
#{sudo}apt install -y cmake libdbus-1-dev libdbus-glib-1-dev libcurl4-openssl-dev libgcrypt20-dev libselinux1-dev libxslt1-dev libgconf2-dev libacl1-dev libblkid-dev libcap-dev libxml2-dev libldap2-dev libpcre3-dev python-dev swig libxml-parser-perl libxml-xpath-perl libperl-dev libbz2-dev librpm-dev g++ libapt-pkg-dev libyaml-dev
|
91
92
|
cd build
|
92
93
|
cmake ../
|
93
94
|
make
|
94
|
-
#{sudo}
|
95
|
+
#{sudo}make install
|
95
96
|
fi
|
96
|
-
#{sudo}
|
97
|
+
#{sudo}apt install -y wget #{packages_to_install.join(' ')}
|
97
98
|
EOS2
|
98
99
|
else
|
99
100
|
raise "Non supported image: #{image}. Please adapt this test's code."
|
@@ -104,7 +105,7 @@ module HybridPlatformsConductor
|
|
104
105
|
cd hpc_vulnerabilities_test
|
105
106
|
wget -N #{url}
|
106
107
|
#{uncompress_cmds.join("\n")}
|
107
|
-
#{sudo}
|
108
|
+
#{sudo}oscap oval eval --skip-valid --results "#{local_oval_file}.results.xml" "#{local_oval_file}"
|
108
109
|
echo "===== RESULTS ====="
|
109
110
|
cat "#{local_oval_file}.results.xml"
|
110
111
|
cd ..
|