hybrid_platforms_conductor 32.12.0 → 32.13.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1133 -0
  3. data/LICENSE.md +31 -0
  4. data/README.md +402 -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 +61 -0
  87. data/docs/tutorial/01_installation.md +131 -0
  88. data/docs/tutorial/02_first_node.md +468 -0
  89. data/docs/tutorial/03_scale.md +878 -0
  90. data/docs/tutorial/04_test.md +977 -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/examples/tutorial/01_installation/my-platforms/Gemfile +3 -0
  98. data/examples/tutorial/01_installation/my-platforms/hpc_config.rb +0 -0
  99. data/examples/tutorial/02_first_node/my-platforms/Gemfile +3 -0
  100. data/examples/tutorial/02_first_node/my-platforms/hpc_config.rb +1 -0
  101. data/examples/tutorial/02_first_node/my-service-conf-repo/inventory.yaml +13 -0
  102. data/examples/tutorial/02_first_node/my-service-conf-repo/my-service.conf.erb +3 -0
  103. data/examples/tutorial/02_first_node/my-service-conf-repo/service_my-service.rb +58 -0
  104. data/examples/tutorial/02_first_node/node/my-service.conf +4 -0
  105. data/examples/tutorial/03_scale/my-platforms/Gemfile +3 -0
  106. data/examples/tutorial/03_scale/my-platforms/hpc_config.rb +1 -0
  107. data/examples/tutorial/03_scale/my-platforms/my_commands.bash +2 -0
  108. data/examples/tutorial/03_scale/my-service-conf-repo/inventory.yaml +90 -0
  109. data/examples/tutorial/03_scale/my-service-conf-repo/my-service.conf.erb +3 -0
  110. data/examples/tutorial/03_scale/my-service-conf-repo/service_my-service.rb +58 -0
  111. data/examples/tutorial/03_scale/my-service-conf-repo/service_web-hello.rb +43 -0
  112. data/examples/tutorial/03_scale/node/my-service.conf +4 -0
  113. data/examples/tutorial/03_scale/web_docker_image/Dockerfile +33 -0
  114. data/examples/tutorial/03_scale/web_docker_image/hello_world.txt +1 -0
  115. data/examples/tutorial/03_scale/web_docker_image/hpc_root.key +27 -0
  116. data/examples/tutorial/03_scale/web_docker_image/hpc_root.key.pub +1 -0
  117. data/examples/tutorial/03_scale/web_docker_image/main.go +43 -0
  118. data/examples/tutorial/03_scale/web_docker_image/start.sh +7 -0
  119. data/examples/tutorial/03_scale/web_docker_image/test.bash +6 -0
  120. data/examples/tutorial/04_test/my-platforms/Gemfile +3 -0
  121. data/examples/tutorial/04_test/my-platforms/hpc_config.rb +12 -0
  122. data/examples/tutorial/04_test/my-platforms/images/debian_10/Dockerfile +13 -0
  123. data/examples/tutorial/04_test/my-platforms/my_commands.bash +2 -0
  124. data/examples/tutorial/04_test/my-service-conf-repo/inventory.yaml +100 -0
  125. data/examples/tutorial/04_test/my-service-conf-repo/my-service.conf.erb +3 -0
  126. data/examples/tutorial/04_test/my-service-conf-repo/service_my-service.rb +58 -0
  127. data/examples/tutorial/04_test/my-service-conf-repo/service_web-hello.rb +43 -0
  128. data/examples/tutorial/04_test/node/my-service.conf +4 -0
  129. data/examples/tutorial/04_test/web_docker_image/Dockerfile +33 -0
  130. data/examples/tutorial/04_test/web_docker_image/hello_world.txt +1 -0
  131. data/examples/tutorial/04_test/web_docker_image/hpc_root.key +27 -0
  132. data/examples/tutorial/04_test/web_docker_image/hpc_root.key.pub +1 -0
  133. data/examples/tutorial/04_test/web_docker_image/main.go +43 -0
  134. data/examples/tutorial/04_test/web_docker_image/start.sh +7 -0
  135. data/examples/tutorial/04_test/web_docker_image/test.bash +6 -0
  136. data/examples/tutorial/05_extend_with_plugins/dev-servers-conf-repo/hosts.json +12 -0
  137. data/examples/tutorial/05_extend_with_plugins/dev-servers-conf-repo/install-gcc.bash +14 -0
  138. data/examples/tutorial/05_extend_with_plugins/dev-servers-conf-repo/install-python.bash +14 -0
  139. data/examples/tutorial/05_extend_with_plugins/dev_docker_image/Dockerfile +20 -0
  140. data/examples/tutorial/05_extend_with_plugins/dev_docker_image/hpc_root.key +27 -0
  141. data/examples/tutorial/05_extend_with_plugins/dev_docker_image/hpc_root.key.pub +1 -0
  142. data/examples/tutorial/05_extend_with_plugins/my-platforms/Gemfile +4 -0
  143. data/examples/tutorial/05_extend_with_plugins/my-platforms/hpc_config.rb +13 -0
  144. data/examples/tutorial/05_extend_with_plugins/my-platforms/images/debian_10/Dockerfile +13 -0
  145. data/examples/tutorial/05_extend_with_plugins/my-platforms/my_commands.bash +2 -0
  146. data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/inventory.yaml +100 -0
  147. data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/my-service.conf.erb +3 -0
  148. data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/service_my-service.rb +58 -0
  149. data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/service_web-hello.rb +43 -0
  150. data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/lib/my_hpc_plugins/hpc_plugins/platform_handler/json_bash.rb +115 -0
  151. data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/lib/my_hpc_plugins/hpc_plugins/report/web_report.rb +52 -0
  152. data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/lib/my_hpc_plugins/hpc_plugins/test/root_space.rb +44 -0
  153. data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/my_hpc_plugins.gemspec +15 -0
  154. data/examples/tutorial/05_extend_with_plugins/node/my-service.conf +4 -0
  155. data/examples/tutorial/05_extend_with_plugins/web_docker_image/Dockerfile +33 -0
  156. data/examples/tutorial/05_extend_with_plugins/web_docker_image/hello_world.txt +1 -0
  157. data/examples/tutorial/05_extend_with_plugins/web_docker_image/hpc_root.key +27 -0
  158. data/examples/tutorial/05_extend_with_plugins/web_docker_image/hpc_root.key.pub +1 -0
  159. data/examples/tutorial/05_extend_with_plugins/web_docker_image/main.go +43 -0
  160. data/examples/tutorial/05_extend_with_plugins/web_docker_image/start.sh +7 -0
  161. data/examples/tutorial/05_extend_with_plugins/web_docker_image/test.bash +6 -0
  162. data/lib/hybrid_platforms_conductor/actions_executor.rb +1 -0
  163. data/lib/hybrid_platforms_conductor/deployer.rb +3 -2
  164. data/lib/hybrid_platforms_conductor/hpc_plugins/action/remote_bash.rb +29 -13
  165. data/lib/hybrid_platforms_conductor/hpc_plugins/action/scp.rb +1 -1
  166. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/local.rb +98 -0
  167. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/my_connector.rb.sample +2 -2
  168. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +7 -3
  169. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/platform_handler_plugin.rb.sample +5 -5
  170. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/yaml_inventory.rb +140 -0
  171. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox.rb +5 -2
  172. data/lib/hybrid_platforms_conductor/hpc_plugins/test/bitbucket_conf.rb +4 -4
  173. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_freshness.rb +1 -1
  174. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +19 -17
  175. data/lib/hybrid_platforms_conductor/hpc_plugins/test/divergence.rb +3 -0
  176. data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +2 -1
  177. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +2 -1
  178. data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +2 -1
  179. data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +4 -3
  180. data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +2 -1
  181. data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +1 -1
  182. data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +9 -7
  183. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/confluence.rb +1 -1
  184. data/lib/hybrid_platforms_conductor/json_dumper.rb +1 -1
  185. data/lib/hybrid_platforms_conductor/platform_handler.rb +1 -1
  186. data/lib/hybrid_platforms_conductor/services_handler.rb +18 -16
  187. data/lib/hybrid_platforms_conductor/tests_runner.rb +0 -1
  188. data/lib/hybrid_platforms_conductor/topographer.rb +0 -1
  189. data/lib/hybrid_platforms_conductor/version.rb +1 -1
  190. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/remote_bash_spec.rb +16 -0
  191. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/connectable_nodes_spec.rb +30 -0
  192. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/remote_actions_spec.rb +113 -0
  193. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/cli_options_spec.rb +6 -2
  194. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/global_helpers_spec.rb +38 -1
  195. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb +8 -8
  196. data/spec/hybrid_platforms_conductor_test/docs_spec.rb +10 -0
  197. data/tools/check_md +89 -0
  198. data/tools/generate_mermaid +75 -0
  199. metadata +337 -12
@@ -69,7 +69,7 @@ module HybridPlatformsConductor
69
69
  end
70
70
 
71
71
  # Setup the platform, install dependencies...
72
- # [API] - This method is mandatory.
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 mandatory.
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 actions_executor.rb file, in the execute_actions_on method description.
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 mandatory.
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 on of:
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 *%i[logger logger_stderr]
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}"
@@ -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. Check #request_lxc_creation_for results to get details.
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 *%i[checks pr_settings required_approvers]
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 *%i[checks pr_settings required_builds]
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 *%i[checks pr_settings default_merge_strategy]
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 *%i[checks pr_settings mandatory_default_reviewers]
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
- # 2017-12-01_093418_a_usernme
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
- @deployer.with_test_provisioned_instance(@config.tests_provisioner_id, @node, environment: 'deploy_removes_root_access', reuse_instance: log_debug?) do |deployer, instance|
16
- # Check that we can connect with root
17
- ssh_ok = false
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, false, 'Root can still connect on the image after deployment'
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
- "#{@nodes_handler.sudo_on(@node)} hostname -s" => proc do |stdout|
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
- "#{@nodes_handler.sudo_on(@node)} hostname -I" => proc do |stdout|
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
- "#{@nodes_handler.sudo_on(@node)} cat /etc/passwd" => proc do |stdout|
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
- # List of (or single) sets of { source => destination } mounts that should not be present.
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
- # List of (or single) sets of { source => destination } mounts that should be present.
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
- "#{@nodes_handler.sudo_on(@node)} mount" => proc do |stdout|
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
- "#{@nodes_handler.sudo_on(@node)} /usr/bin/find / \\( #{@nodes_handler.
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
- sudo = @nodes_handler.sudo_on(@node)
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
@@ -72,12 +73,13 @@ module HybridPlatformsConductor
72
73
  end
73
74
  end
74
75
  cmds = <<~EOS
76
+ set -e
75
77
  #{
76
78
  case image
77
79
  when :centos_7
78
- "#{sudo} yum install -y wget openscap-scanner #{packages_to_install.join(' ')}"
80
+ "#{sudo}yum install -y wget openscap-scanner #{packages_to_install.join(' ')}"
79
81
  when :debian_9
80
- "#{sudo} apt install -y wget libopenscap8 #{packages_to_install.join(' ')}"
82
+ "#{sudo}apt install -y wget libopenscap8 #{packages_to_install.join(' ')}"
81
83
  when :debian_10
82
84
  # On Debian 10 we have to compile it from sources, as the packaged official version has core dumps.
83
85
  # cf https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1688223.html
@@ -87,13 +89,13 @@ module HybridPlatformsConductor
87
89
  rm -rf openscap
88
90
  git clone --recurse-submodules https://github.com/OpenSCAP/openscap.git
89
91
  cd openscap
90
- #{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
92
+ #{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
93
  cd build
92
94
  cmake ../
93
95
  make
94
- #{sudo} make install
96
+ #{sudo}make install
95
97
  fi
96
- #{sudo} apt install -y wget #{packages_to_install.join(' ')}
98
+ #{sudo}apt install -y wget #{packages_to_install.join(' ')}
97
99
  EOS2
98
100
  else
99
101
  raise "Non supported image: #{image}. Please adapt this test's code."
@@ -104,7 +106,7 @@ module HybridPlatformsConductor
104
106
  cd hpc_vulnerabilities_test
105
107
  wget -N #{url}
106
108
  #{uncompress_cmds.join("\n")}
107
- #{sudo} oscap oval eval --skip-valid --results "#{local_oval_file}.results.xml" "#{local_oval_file}"
109
+ #{sudo}oscap oval eval --skip-valid --results "#{local_oval_file}.results.xml" "#{local_oval_file}"
108
110
  echo "===== RESULTS ====="
109
111
  cat "#{local_oval_file}.results.xml"
110
112
  cd ..