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
@@ -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
@@ -75,9 +76,9 @@ module HybridPlatformsConductor
75
76
  #{
76
77
  case image
77
78
  when :centos_7
78
- "#{sudo} yum install -y wget openscap-scanner #{packages_to_install.join(' ')}"
79
+ "#{sudo}yum install -y wget openscap-scanner #{packages_to_install.join(' ')}"
79
80
  when :debian_9
80
- "#{sudo} apt install -y wget libopenscap8 #{packages_to_install.join(' ')}"
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} 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
+ #{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} make install
95
+ #{sudo}make install
95
96
  fi
96
- #{sudo} apt install -y wget #{packages_to_install.join(' ')}
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} oscap oval eval --skip-valid --results "#{local_oval_file}.results.xml" "#{local_oval_file}"
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 ..
@@ -53,7 +53,7 @@ module HybridPlatformsConductor
53
53
 
54
54
  private
55
55
 
56
- TEMPLATES_PATH = File.expand_path("#{File.dirname(__FILE__)}/templates")
56
+ TEMPLATES_PATH = File.expand_path("#{__dir__}/templates")
57
57
 
58
58
  # Render a given ERB template into a String
59
59
  #
@@ -56,7 +56,7 @@ module HybridPlatformsConductor
56
56
  nodes = @nodes_handler.select_nodes(nodes_selectors)
57
57
  unless @skip_run
58
58
  nodes.map { |node| @nodes_handler.platform_for(node) }.uniq.each.each do |platform_handler|
59
- platform_handler.prepare_why_run_deploy_for_json_dump
59
+ platform_handler.prepare_why_run_deploy_for_json_dump if platform_handler.respond_to?(:prepare_why_run_deploy_for_json_dump)
60
60
  end
61
61
  @deployer.concurrent_execution = true
62
62
  @deployer.use_why_run = true
@@ -142,7 +142,7 @@ module HybridPlatformsConductor
142
142
  git_status = git.status
143
143
  git_commit = git.log.first
144
144
  {
145
- repo_name: File.basename(git.remotes.first.url).gsub(/\.git$/, ''),
145
+ repo_name: git.remotes.empty? ? File.basename(@repository_path) : File.basename(git.remotes.first.url).gsub(/\.git$/, ''),
146
146
  commit: {
147
147
  id: git_commit.sha,
148
148
  ref: git_commit.name,
@@ -108,23 +108,25 @@ module HybridPlatformsConductor
108
108
  local_environment:
109
109
  )
110
110
  platforms_for(services).each do |platform, platform_services|
111
- platform_name = platform.name
112
- # Compute the package ID that is unique to this packaging, so that we don't mix it with others if needed.
113
- package_id = {
114
- platform_name: platform_name,
115
- services: Hash[platform_services.map { |node, node_services| [node, node_services.sort] }].sort,
116
- secrets: secrets.sort,
117
- local_environment: local_environment
118
- }
119
- if ServicesHandler.packaged_deployments.include?(package_id)
120
- log_debug "Platform #{platform_name} has already been packaged for this deployment (package ID #{package_id}). Won't package it another time."
121
- else
122
- platform.package(
123
- services: platform_services,
124
- secrets: secrets,
111
+ if platform.respond_to?(:package)
112
+ platform_name = platform.name
113
+ # Compute the package ID that is unique to this packaging, so that we don't mix it with others if needed.
114
+ package_id = {
115
+ platform_name: platform_name,
116
+ services: Hash[platform_services.map { |node, node_services| [node, node_services.sort] }].sort,
117
+ secrets: secrets.sort,
125
118
  local_environment: local_environment
126
- )
127
- ServicesHandler.packaged_deployments << package_id
119
+ }
120
+ if ServicesHandler.packaged_deployments.include?(package_id)
121
+ log_debug "Platform #{platform_name} has already been packaged for this deployment (package ID #{package_id}). Won't package it another time."
122
+ else
123
+ platform.package(
124
+ services: platform_services,
125
+ secrets: secrets,
126
+ local_environment: local_environment
127
+ )
128
+ ServicesHandler.packaged_deployments << package_id
129
+ end
128
130
  end
129
131
  end
130
132
  end
@@ -452,7 +452,6 @@ module HybridPlatformsConductor
452
452
  end]
453
453
  section "Run test commands on #{@test_cmds.keys.size} connected nodes (timeout to #{timeout} secs)" do
454
454
  start_time = Time.now
455
- nbr_secs = nil
456
455
  @actions_executor.max_threads = @max_threads_connection_on_nodes
457
456
  @actions_result = @actions_executor.execute_actions(
458
457
  @test_cmds,
@@ -110,7 +110,6 @@ module HybridPlatformsConductor
110
110
  @skip_run = false
111
111
 
112
112
  # Parse plugins
113
- root_path = File.expand_path("#{File.dirname(__FILE__)}/..")
114
113
  @plugins = Hash[Dir.
115
114
  glob("#{File.dirname(__FILE__)}/topographer/plugins/*.rb").
116
115
  map do |file_name|
@@ -1,5 +1,5 @@
1
1
  module HybridPlatformsConductor
2
2
 
3
- VERSION = '32.12.0'
3
+ VERSION = '32.13.0'
4
4
 
5
5
  end
@@ -79,6 +79,22 @@ describe HybridPlatformsConductor::ActionsExecutor do
79
79
  end
80
80
  end
81
81
 
82
+ it 'executes remote Bash code both from commands and a file in sequence' do
83
+ with_test_platform_for_action_plugins do |repository|
84
+ File.write("#{repository}/commands.txt", "bash_cmd3.bash\nbash_cmd4.bash")
85
+ test_actions_executor.execute_actions('node' => { remote_bash: [
86
+ 'bash_cmd1.bash',
87
+ 'bash_cmd2.bash',
88
+ { file: "#{repository}/commands.txt" }
89
+ ] })
90
+ expect(test_actions_executor.connector(:test_connector).calls).to eq [
91
+ [:connectable_nodes_from, ['node']],
92
+ [:with_connection_to, ['node'], { no_exception: true }],
93
+ [:remote_bash, "bash_cmd1.bash\nbash_cmd2.bash\nbash_cmd3.bash\nbash_cmd4.bash"]
94
+ ]
95
+ end
96
+ end
97
+
82
98
  it 'executes remote Bash code with environment variables set' do
83
99
  with_test_platform_for_action_plugins do
84
100
  test_actions_executor.execute_actions('node' => { remote_bash: {
@@ -0,0 +1,30 @@
1
+ describe HybridPlatformsConductor::ActionsExecutor do
2
+
3
+ context 'checking connector plugin local' do
4
+
5
+ context 'checking connectable nodes selection' do
6
+
7
+ # Return the connector to be tested
8
+ #
9
+ # Result::
10
+ # * Connector: Connector to be tested
11
+ def test_connector
12
+ test_actions_executor.connector(:local)
13
+ end
14
+
15
+ it 'selects connectable nodes correctly' do
16
+ with_test_platform(nodes: {
17
+ 'node1' => { meta: { host_ip: '192.168.42.42' } },
18
+ 'node2' => {},
19
+ 'node3' => { meta: { host_ip: '127.0.0.1', local_node: true } },
20
+ 'node4' => { meta: { local_node: true } }
21
+ }) do
22
+ expect(test_connector.connectable_nodes_from(%w[node1 node2 node3 node4]).sort).to eq %w[node3 node4].sort
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,113 @@
1
+ describe HybridPlatformsConductor::ActionsExecutor do
2
+
3
+ context 'checking connector plugin local' do
4
+
5
+ context 'checking remote actions' do
6
+
7
+ # Return the connector to be tested
8
+ #
9
+ # Result::
10
+ # * Connector: Connector to be tested
11
+ def test_connector
12
+ test_actions_executor.connector(:local)
13
+ end
14
+
15
+ # Get a test platform and the connector prepared the same way Actions Executor does before calling remote_* methods
16
+ #
17
+ # Parameters::
18
+ # * *expected_cmds* (Array< [String or Regexp, Proc] >): The expected commands that should be used, and their corresponding mocked code [default: []]
19
+ # * *expected_stdout* (String): Expected stdout after client code execution [default: '']
20
+ # * *expected_stderr* (String): Expected stderr after client code execution [default: '']
21
+ # * *timeout* (Integer or nil): Timeout to prepare the connector for [default: nil]
22
+ # * *password* (String or nil): Password to set for the node, or nil for none [default: nil]
23
+ # * *additional_config* (String): Additional config [default: '']
24
+ # * Proc: Client code to execute testing
25
+ def with_test_platform_for_remote_testing(
26
+ expected_cmds: [],
27
+ expected_stdout: '',
28
+ expected_stderr: '',
29
+ timeout: nil,
30
+ password: nil,
31
+ additional_config: ''
32
+ )
33
+ with_test_platform(
34
+ { nodes: { 'node' => { meta: { local_node: true } } } },
35
+ false,
36
+ additional_config
37
+ ) do
38
+ with_cmd_runner_mocked(expected_cmds) do
39
+ test_connector.with_connection_to(['node']) do
40
+ stdout = ''
41
+ stderr = ''
42
+ test_connector.prepare_for('node', timeout, stdout, stderr)
43
+ yield
44
+ expect(stdout).to eq expected_stdout
45
+ expect(stderr).to eq expected_stderr
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ it 'executes bash commands remotely' do
52
+ with_test_platform_for_remote_testing(
53
+ expected_cmds: [['cd /tmp/hpc_local_workspaces/node ; bash_cmd.bash', proc { [0, 'Bash commands executed on node', ''] }]],
54
+ expected_stdout: 'Bash commands executed on node'
55
+ ) do
56
+ test_connector.remote_bash('bash_cmd.bash')
57
+ end
58
+ end
59
+
60
+ it 'executes bash commands remotely with timeout' do
61
+ with_test_platform_for_remote_testing(
62
+ expected_cmds: [
63
+ [
64
+ 'cd /tmp/hpc_local_workspaces/node ; bash_cmd.bash',
65
+ proc do |cmd, log_to_file: nil, log_to_stdout: true, log_stdout_to_io: nil, log_stderr_to_io: nil, expected_code: 0, timeout: nil, no_exception: false|
66
+ expect(timeout).to eq 5
67
+ [0, '', '']
68
+ end
69
+ ]
70
+ ],
71
+ timeout: 5
72
+ ) do
73
+ test_connector.remote_bash('bash_cmd.bash')
74
+ end
75
+ end
76
+
77
+ it 'executes interactive commands remotely' do
78
+ with_test_platform_for_remote_testing do
79
+ expect(test_connector).to receive(:system) do |cmd|
80
+ expect(cmd).to eq 'cd /tmp/hpc_local_workspaces/node ; /bin/bash'
81
+ end
82
+ test_connector.remote_interactive
83
+ end
84
+ end
85
+
86
+ it 'copies files remotely' do
87
+ with_test_platform_for_remote_testing do
88
+ expect(FileUtils).to receive(:cp_r).with('/path/to/src.file', '/remote_path/to/dst.dir')
89
+ test_connector.remote_copy('/path/to/src.file', '/remote_path/to/dst.dir')
90
+ end
91
+ end
92
+
93
+ it 'copies files remotely with timeout' do
94
+ with_test_platform_for_remote_testing(
95
+ timeout: 5
96
+ ) do
97
+ expect(FileUtils).to receive(:cp_r).with('/path/to/src.file', '/remote_path/to/dst.dir')
98
+ test_connector.remote_copy('/path/to/src.file', '/remote_path/to/dst.dir')
99
+ end
100
+ end
101
+
102
+ it 'copies relative files remotely' do
103
+ with_test_platform_for_remote_testing do
104
+ expect(FileUtils).to receive(:cp_r).with('/path/to/src.file', '/tmp/hpc_local_workspaces/node/to/dst.dir')
105
+ test_connector.remote_copy('/path/to/src.file', 'to/dst.dir')
106
+ end
107
+ end
108
+
109
+ end
110
+
111
+ end
112
+
113
+ end