hybrid_platforms_conductor 32.16.1 → 32.17.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -0
  3. data/docs/plugins.md +1 -0
  4. data/docs/plugins/connector/ssh.md +1 -1
  5. data/docs/plugins/test/bitbucket_conf.md +1 -1
  6. data/docs/plugins/test/check_deploy_and_idempotence.md +1 -1
  7. data/docs/plugins/test/connection.md +1 -0
  8. data/docs/plugins/test/deploy_removes_root_access.md +1 -1
  9. data/docs/plugins/test/file_system.md +1 -0
  10. data/docs/plugins/test/github_ci.md +48 -0
  11. data/docs/plugins/test/hostname.md +1 -0
  12. data/docs/plugins/test/ip.md +1 -0
  13. data/docs/plugins/test/jenkins_ci_conf.md +1 -1
  14. data/docs/plugins/test/jenkins_ci_masters_ok.md +1 -1
  15. data/docs/plugins/test/local_users.md +1 -0
  16. data/docs/plugins/test/mounts.md +1 -0
  17. data/docs/plugins/test/orphan_files.md +1 -0
  18. data/docs/plugins/test/ports.md +1 -0
  19. data/docs/plugins/test/spectre.md +1 -0
  20. data/docs/plugins/test/vulnerabilities.md +1 -0
  21. data/lib/hybrid_platforms_conductor/common_config_dsl/github.rb +62 -0
  22. data/lib/hybrid_platforms_conductor/deployer.rb +1 -1
  23. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +3 -3
  24. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef.rb +5 -5
  25. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/podman.rb +1 -1
  26. data/lib/hybrid_platforms_conductor/hpc_plugins/test/check_deploy_and_idempotence.rb +1 -1
  27. data/lib/hybrid_platforms_conductor/hpc_plugins/test/connection.rb +3 -1
  28. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +1 -1
  29. data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system.rb +2 -1
  30. data/lib/hybrid_platforms_conductor/hpc_plugins/test/github_ci.rb +32 -0
  31. data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +3 -1
  32. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +3 -1
  33. data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +3 -1
  34. data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +3 -1
  35. data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +3 -1
  36. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ports.rb +3 -1
  37. data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +3 -1
  38. data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +2 -1
  39. data/lib/hybrid_platforms_conductor/test_only_remote_node.rb +18 -0
  40. data/lib/hybrid_platforms_conductor/version.rb +1 -1
  41. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connections_spec.rb +3 -3
  42. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioner_spec.rb +4 -4
  43. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/packaging_spec.rb +3 -2
  44. data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/github_ci_spec.rb +72 -0
  45. data/spec/hybrid_platforms_conductor_test/helpers/connector_ssh_helpers.rb +1 -1
  46. metadata +22 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f01de7476f9279e990b054d1b5709c1a549ea2a2069f3a12ace8b40d639451b0
4
- data.tar.gz: f6336d1668fe315ac99bd1268fc91514b1644663633a6299654808597d8d202b
3
+ metadata.gz: 8d66286a0b94c89bde4c7557a1b707158095363ccb854e3af5bdf951fe9065ee
4
+ data.tar.gz: fa1976b8f50dd96a1717ec596540f3ae0cbb35c3b0d44b55e46e53f40e8a460d
5
5
  SHA512:
6
- metadata.gz: 5a931593af6eb20bf83eb478a2a438612dbcf3acf0f0e3cc93541c163b593a0aad88fd59f56340411d4cd95fe60618e58ae5ba845a44e42b0123394c93cab713
7
- data.tar.gz: 5708d46f33bbfa53a0ddd48607b23c93468b7cdb588ba1d969c997047944e89ff8303009f63c54438db02b23b8633b3fdef9989a49527fdcca812d1cf6ce8ddd
6
+ metadata.gz: 2f2e172771aa4925c790d2faa57aaeca5da59914806787f8b19774af9a58ffb3e76766b66997e55a97602e05eeb7395f04c1f866c7a0acb17656adb87fdab8a2
7
+ data.tar.gz: f61b8ede205e1cbbb863b2261fb7f8ad01d57b3cc319eec1fada0dcbcb99ce14384a5d74bbfaf86ef0aa5e3c0fbd5568933bf5ddf0c99e7deaa5e3db900e7e28
data/CHANGELOG.md CHANGED
@@ -1,3 +1,51 @@
1
+ # [v32.17.1](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v32.17.0...v32.17.1) (2021-06-03 16:20:09)
2
+
3
+ ### Patches
4
+
5
+ * [[Hotfix] Don't run remote nodes tests on local nodes](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/fe8e34a4d74f21d4903c14b1e156b9730f4b5fee)
6
+
7
+ # [v32.17.0](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v32.16.4...v32.17.0) (2021-06-02 12:57:44)
8
+
9
+ ## Global changes
10
+ ### Patches
11
+
12
+ * [[Feature(test_github_ci)] [#61] Add the github_ci test plugin to check for CI/CD of projects on Github](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/a0082efe5c138ca88ca91a3c10f777f47fca5034)
13
+
14
+ ## Changes for test_github_ci
15
+ ### Features
16
+
17
+ * [[Feature(test_github_ci)] [#61] Add the github_ci test plugin to check for CI/CD of projects on Github](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/a0082efe5c138ca88ca91a3c10f777f47fca5034)
18
+
19
+ # [v32.16.4](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v32.16.3...v32.16.4) (2021-06-01 13:25:19)
20
+
21
+ ### Patches
22
+
23
+ * [[Hotfix] Fixed boolean values incorrectly used as strings](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/a107f3e0fe4c1512ce7607a303fdf0753d92ddac)
24
+
25
+ # [v32.16.3](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v32.16.2...v32.16.3) (2021-06-01 11:19:50)
26
+
27
+ ## Global changes
28
+ ### Patches
29
+
30
+ * [[Hotfix(platform_handler_serverless_chef)] Fix Chef packaging missing licenses accept](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/69eafc1b23f77de65ba0dd68e5adb7fafb58157e)
31
+
32
+ ## Changes for platform_handler_serverless_chef
33
+ ### Patches
34
+
35
+ * [[Hotfix(platform_handler_serverless_chef)] Fix Chef packaging missing licenses accept](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/69eafc1b23f77de65ba0dd68e5adb7fafb58157e)
36
+
37
+ # [v32.16.2](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v32.16.1...v32.16.2) (2021-06-01 09:52:22)
38
+
39
+ ## Global changes
40
+ ### Patches
41
+
42
+ * [[Hotfix(platform_handler_serverless_chef)] Fix Chef Workstation bash steps when run by root](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/1d99d1faa9cf66cd607eacc00205e312fd589715)
43
+
44
+ ## Changes for platform_handler_serverless_chef
45
+ ### Patches
46
+
47
+ * [[Hotfix(platform_handler_serverless_chef)] Fix Chef Workstation bash steps when run by root](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/1d99d1faa9cf66cd607eacc00205e312fd589715)
48
+
1
49
  # [v32.16.1](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v32.16.0...v32.16.1) (2021-06-01 09:21:47)
2
50
 
3
51
  ## Global changes
data/docs/plugins.md CHANGED
@@ -182,6 +182,7 @@ Plugins shipped by default:
182
182
  * [`executables`](plugins/test/executables.md)
183
183
  * [`file_system_hdfs`](plugins/test/file_system_hdfs.md)
184
184
  * [`file_system`](plugins/test/file_system.md)
185
+ * [`github_ci`](plugins/test/github_ci.md)
185
186
  * [`hostname`](plugins/test/hostname.md)
186
187
  * [`idempotence`](plugins/test/idempotence.md)
187
188
  * [`ip`](plugins/test/ip.md)
@@ -70,7 +70,7 @@ end
70
70
  | `host_keys` | `Array<String>` | The node's host keys used to generate a `known_hosts` file with those to avoid user confirmations when connecting. |
71
71
  | `hostname` | `String` | Host name used to connect in case no IP address can be found in metadata. |
72
72
  | `private_ips` | `Array<String>` | IP list to connect in case `host_ip` is not defined in metadata. |
73
- | `ssh_session_exec` | `String` | If set to the string `false`, then consider that the node does not have any SSH SessionExec capabilities. This will make sure that remote command executions is done using stdin piping on interactive sessions instead of SSH commands execution. |
73
+ | `ssh_session_exec` | `Boolean` | If set to `false`, then consider that the node does not have any SSH SessionExec capabilities. This will make sure that remote command executions is done using stdin piping on interactive sessions instead of SSH commands execution. |
74
74
 
75
75
  ## Used environment variables
76
76
 
@@ -12,7 +12,7 @@ Define a Bitbucket installation to be targeted.
12
12
  It takes the following parameters:
13
13
  * **url** (`String`): URL to the Bitbucket server
14
14
  * **project** (`String`): Project name from the Bitbucket server, storing repositories
15
- * **repos** (`Array<String>` or `Symbol`): List of repository names from this project, or :all for all [default: :all]
15
+ * **repos** (`Array<String>` or `Symbol`): List of repository names from this project, or `:all` for all [default: `:all`]
16
16
  * **checks** (`Hash<Symbol, Object>`): Checks definition to be perform on those repositories [default: {}]
17
17
  * **branch_permissions** (`Array< Hash<Symbol, Object> >`): List of branch permissions to check [optional]
18
18
  * **type** (`String`): Type of branch permissions to check. Examples of values are 'fast-forward-only', 'no-deletes', 'pull-request-only'.
@@ -49,7 +49,7 @@ end
49
49
 
50
50
  | Metadata | Type | Usage
51
51
  | --- | --- | --- |
52
- | `root_access_allowed` | `String` | If set to `true`, then skip the test for `root` access being disabled after deployment |
52
+ | `root_access_allowed` | `Boolean` | If set to `true`, then skip the test for `root` access being disabled after deployment |
53
53
 
54
54
  ## Used environment variables
55
55
 
@@ -16,6 +16,7 @@ None
16
16
 
17
17
  | Metadata | Type | Usage
18
18
  | --- | --- | --- |
19
+ | `local_node` | `Boolean` | Skip this test for nodes having this metadata set to `true` |
19
20
 
20
21
  ## Used environment variables
21
22
 
@@ -17,7 +17,7 @@ None
17
17
 
18
18
  | Metadata | Type | Usage
19
19
  | --- | --- | --- |
20
- | `root_access_allowed` | `String` | If set to `true`, then skip this test |
20
+ | `root_access_allowed` | `Boolean` | If set to `true`, then skip this test |
21
21
 
22
22
  ## Used environment variables
23
23
 
@@ -38,6 +38,7 @@ end
38
38
 
39
39
  | Metadata | Type | Usage
40
40
  | --- | --- | --- |
41
+ | `local_node` | `Boolean` | Skip this test for nodes having this metadata set to `true` |
41
42
 
42
43
  ## Used environment variables
43
44
 
@@ -0,0 +1,48 @@
1
+ # Test plugin: `github_ci`
2
+
3
+ The `github_ci` test plugin checks that the `master` branch of Github repositories has a successful CI result from its [Github Actions](https://github.com/features/actions).
4
+
5
+ ## Config DSL extension
6
+
7
+ ### `github_repos`
8
+
9
+ Define Github repositories to be targeted.
10
+
11
+ It takes the following parameters:
12
+ * **url** (`String`): URL to the Github API [default: `'https://api.github.com'`]
13
+ * **user** (`String`): User or organization name, storing repositories
14
+ * **repos** (`Array<String>` or `Symbol`): List of repository names from this project, or `:all` for all [default: `:all`]
15
+
16
+ Example:
17
+ ```ruby
18
+ github_repos(
19
+ # Github's user containing repositories
20
+ user: 'My-Github-User',
21
+ # List of repositories to check
22
+ repos: [
23
+ 'my-platform-repo',
24
+ 'my-chef-repo',
25
+ 'my-hpc-plugins'
26
+ ]
27
+ )
28
+ ```
29
+
30
+ ## Used credentials
31
+
32
+ | Credential | Usage
33
+ | --- | --- |
34
+ | `github` | Used to connect to the Github API. Password should be the Github API token. |
35
+
36
+ ## Used Metadata
37
+
38
+ | Metadata | Type | Usage
39
+ | --- | --- | --- |
40
+
41
+ ## Used environment variables
42
+
43
+ | Variable | Usage
44
+ | --- | --- |
45
+
46
+ ## External tools dependencies
47
+
48
+ None
@@ -16,6 +16,7 @@ None
16
16
 
17
17
  | Metadata | Type | Usage
18
18
  | --- | --- | --- |
19
+ | `local_node` | `Boolean` | Skip this test for nodes having this metadata set to `true` |
19
20
 
20
21
  ## Used environment variables
21
22
 
@@ -16,6 +16,7 @@ None
16
16
 
17
17
  | Metadata | Type | Usage
18
18
  | --- | --- | --- |
19
+ | `local_node` | `Boolean` | Skip this test for nodes having this metadata set to `true` |
19
20
  | `private_ips` | `Array<String>` | List of possible private IPs the node should have |
20
21
 
21
22
  ## Used environment variables
@@ -12,7 +12,7 @@ It takes the following parameters:
12
12
  * **url** (`String`): URL to the Bitbucket server
13
13
  * **project** (`String`): Project name from the Bitbucket server, storing repositories
14
14
  * **jenkins_ci_url** (`String` or `nil`): Corresponding Jenkins CI URL, or nil if none.
15
- * **repos** (`Array<String>` or `Symbol`): List of repository names from this project, or :all for all [default: :all]
15
+ * **repos** (`Array<String>` or `Symbol`): List of repository names from this project, or `:all` for all [default: `:all`]
16
16
 
17
17
  Example:
18
18
  ```ruby
@@ -12,7 +12,7 @@ It takes the following parameters:
12
12
  * **url** (`String`): URL to the Bitbucket server
13
13
  * **project** (`String`): Project name from the Bitbucket server, storing repositories
14
14
  * **jenkins_ci_url** (`String` or `nil`): Corresponding Jenkins CI URL, or nil if none.
15
- * **repos** (`Array<String>` or `Symbol`): List of repository names from this project, or :all for all [default: :all]
15
+ * **repos** (`Array<String>` or `Symbol`): List of repository names from this project, or `:all` for all [default: `:all`]
16
16
 
17
17
  Example:
18
18
  ```ruby
@@ -37,6 +37,7 @@ check_local_users_do_not_exist %w[olduser1 olduser2]
37
37
 
38
38
  | Metadata | Type | Usage
39
39
  | --- | --- | --- |
40
+ | `local_node` | `Boolean` | Skip this test for nodes having this metadata set to `true` |
40
41
 
41
42
  ## Used environment variables
42
43
 
@@ -44,6 +44,7 @@ end
44
44
 
45
45
  | Metadata | Type | Usage
46
46
  | --- | --- | --- |
47
+ | `local_node` | `Boolean` | Skip this test for nodes having this metadata set to `true` |
47
48
 
48
49
  ## Used environment variables
49
50
 
@@ -27,6 +27,7 @@ end
27
27
 
28
28
  | Metadata | Type | Usage
29
29
  | --- | --- | --- |
30
+ | `local_node` | `Boolean` | Skip this test for nodes having this metadata set to `true` |
30
31
 
31
32
  ## Used environment variables
32
33
 
@@ -39,6 +39,7 @@ check_closed_ports 25, 110
39
39
  | Metadata | Type | Usage
40
40
  | --- | --- | --- |
41
41
  | `host_ip` | `String` | Host IP address to be tested for port listening |
42
+ | `local_node` | `Boolean` | Skip this test for nodes having this metadata set to `true` |
42
43
 
43
44
  ## Used environment variables
44
45
 
@@ -15,6 +15,7 @@ None
15
15
 
16
16
  | Metadata | Type | Usage
17
17
  | --- | --- | --- |
18
+ | `local_node` | `Boolean` | Skip this test for nodes having this metadata set to `true` |
18
19
 
19
20
  ## Used environment variables
20
21
 
@@ -54,6 +54,7 @@ None
54
54
  | Metadata | Type | Usage
55
55
  | --- | --- | --- |
56
56
  | `image` | `String` | The name of the OS image to be used. The [configuration](../../config_dsl.md) should define the image and point it to a directory containing a `oval.json` that will contain definition of OVAL files to be checked for this OS(see above). |
57
+ | `local_node` | `Boolean` | Skip this test for nodes having this metadata set to `true` |
57
58
 
58
59
  ## Used environment variables
59
60
 
@@ -0,0 +1,62 @@
1
+ require 'octokit'
2
+ require 'hybrid_platforms_conductor/credentials'
3
+
4
+ module HybridPlatformsConductor
5
+
6
+ module CommonConfigDsl
7
+
8
+ module Github
9
+
10
+ # Initialize the DSL
11
+ def init_github
12
+ # List of Github repositories definitions
13
+ # Array< Hash<Symbol, Object> >
14
+ # Each definition is just mapping the signature of #github_repos
15
+ @github_repos = []
16
+ end
17
+
18
+ # Register new Github repositories
19
+ #
20
+ # Parameters::
21
+ # * *url* (String): URL to the Github API [default: 'https://api.github.com']
22
+ # * *user* (String): User or organization name, storing repositories
23
+ # * *repos* (Array<String> or Symbol): List of repository names from this project, or :all for all [default: :all]
24
+ def github_repos(url: 'https://api.github.com', user:, repos: :all)
25
+ @github_repos << {
26
+ url: url,
27
+ user: user,
28
+ repos: repos
29
+ }
30
+ end
31
+
32
+ # Iterate over each Github repository
33
+ #
34
+ # Parameters::
35
+ # * Proc: Code called for each Github repository:
36
+ # * Parameters::
37
+ # * *github* (Octokit::Client): The client instance accessing the Github API
38
+ # * *repo_info* (Hash<Symbol, Object>): The repository info:
39
+ # * *name* (String): Repository name.
40
+ # * *slug* (String): Repository slug.
41
+ def for_each_github_repo
42
+ @github_repos.each do |repo_info|
43
+ Octokit.configure do |c|
44
+ c.api_endpoint = repo_info[:url]
45
+ end
46
+ Credentials.with_credentials_for(:github, @logger, @logger_stderr, url: repo_info[:url]) do |_github_user, github_token|
47
+ client = Octokit::Client.new(access_token: github_token)
48
+ (repo_info[:repos] == :all ? client.repositories(repo_info[:user]).map { |repo| repo[:name] } : repo_info[:repos]).each do |name|
49
+ yield client, {
50
+ name: name,
51
+ slug: "#{repo_info[:user]}/#{name}"
52
+ }
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+
62
+ end
@@ -319,7 +319,7 @@ module HybridPlatformsConductor
319
319
  )
320
320
  instance.with_running_instance(stop_on_exit: true, destroy_on_exit: !reuse_instance, port: 22) do
321
321
  # Test-provisioned nodes have SSH Session Exec capabilities and are not local
322
- sub_executable.nodes_handler.override_metadata_of node, :ssh_session_exec, 'true'
322
+ sub_executable.nodes_handler.override_metadata_of node, :ssh_session_exec, true
323
323
  sub_executable.nodes_handler.override_metadata_of node, :local_node, false
324
324
  # Test-provisioned nodes use default sudo
325
325
  sub_executable.config.sudo_procs.replace(sub_executable.config.sudo_procs.map do |sudo_proc_info|
@@ -238,7 +238,7 @@ module HybridPlatformsConductor
238
238
  # * *bash_cmds* (String): Bash commands to execute
239
239
  def remote_bash(bash_cmds)
240
240
  ssh_cmd =
241
- if @nodes_handler.get_ssh_session_exec_of(@node) == 'false'
241
+ if @nodes_handler.get_ssh_session_exec_of(@node) == false
242
242
  # When ExecSession is disabled we need to use stdin directly
243
243
  "{ cat | #{ssh_exec} #{ssh_url} -T; } <<'HPC_EOF'\n#{bash_cmds}\nHPC_EOF"
244
244
  else
@@ -300,7 +300,7 @@ module HybridPlatformsConductor
300
300
  # * *owner* (String or nil): Owner to be used when copying the files, or nil for current one [default: nil]
301
301
  # * *group* (String or nil): Group to be used when copying the files, or nil for current one [default: nil]
302
302
  def remote_copy(from, to, sudo: false, owner: nil, group: nil)
303
- if @nodes_handler.get_ssh_session_exec_of(@node) == 'false'
303
+ if @nodes_handler.get_ssh_session_exec_of(@node) == false
304
304
  # We don't have ExecSession, so don't use ssh, but scp instead.
305
305
  if sudo
306
306
  # We need to first copy the file in an accessible directory, and then sudo mv
@@ -513,7 +513,7 @@ module HybridPlatformsConductor
513
513
  if current_users.empty?
514
514
  log_debug "[ ControlMaster - #{ssh_url} ] - Creating SSH ControlMaster..."
515
515
  exit_status = nil
516
- if @nodes_handler.get_ssh_session_exec_of(node) == 'false'
516
+ if @nodes_handler.get_ssh_session_exec_of(node) == false
517
517
  # Here we have to create a ControlMaster using an interactive session, as the SSH server prohibits ExecSession, and so command executions.
518
518
  # We'll do that using another terminal spawned in the background.
519
519
  if ENV['hpc_interactive'] == 'false'
@@ -84,7 +84,7 @@ module HybridPlatformsConductor
84
84
  expected_match.nil? ? 'unreadable' : expected_match[1]
85
85
  end
86
86
  log_debug "Current Chef version: #{existing_version}. Required version: #{required_version}"
87
- @cmd_runner.run_cmd "curl -L https://omnitruck.chef.io/install.sh | sudo bash -s -- -P chef-workstation -v #{required_version}" unless existing_version == required_version
87
+ @cmd_runner.run_cmd "curl -L https://omnitruck.chef.io/install.sh | #{@cmd_runner.root? ? '' : 'sudo '}bash -s -- -P chef-workstation -v #{required_version}" unless existing_version == required_version
88
88
  end
89
89
  end
90
90
 
@@ -175,11 +175,11 @@ module HybridPlatformsConductor
175
175
  end
176
176
  lock_file = "#{File.dirname(policy_file)}/#{File.basename(policy_file, '.rb')}.lock.json"
177
177
  # If the policy lock file does not exist, generate it
178
- @cmd_runner.run_cmd "cd #{@repository_path} && /opt/chef-workstation/bin/chef install #{policy_file}" unless File.exist?("#{@repository_path}/#{lock_file}")
178
+ @cmd_runner.run_cmd "cd #{@repository_path} && /opt/chef-workstation/bin/chef install #{policy_file} --chef-license accept" unless File.exist?("#{@repository_path}/#{lock_file}")
179
179
  extra_cp_data_bags = File.exist?("#{@repository_path}/data_bags") ? " && cp -ar data_bags/ #{package_dir}/" : ''
180
180
  @cmd_runner.run_cmd "cd #{@repository_path} && \
181
- sudo rm -rf #{package_dir} && \
182
- /opt/chef-workstation/bin/chef export #{policy_file} #{package_dir}#{extra_cp_data_bags}"
181
+ #{@cmd_runner.root? ? '' : 'sudo '}rm -rf #{package_dir} && \
182
+ /opt/chef-workstation/bin/chef export #{policy_file} #{package_dir} --chef-license accept#{extra_cp_data_bags}"
183
183
  end
184
184
  unless @cmd_runner.dry_run
185
185
  # Create secrets file
@@ -236,7 +236,7 @@ module HybridPlatformsConductor
236
236
  client_options << '--why-run' if use_why_run
237
237
  if @nodes_handler.get_use_local_chef_of(node)
238
238
  # Just run the chef-client directly from the packaged repository
239
- [{ bash: "cd #{package_dir} && sudo SSL_CERT_DIR=/etc/ssl/certs /opt/chef-workstation/bin/chef-client #{client_options.join(' ')}" }]
239
+ [{ bash: "cd #{package_dir} && #{@cmd_runner.root? ? '' : 'sudo '}SSL_CERT_DIR=/etc/ssl/certs /opt/chef-workstation/bin/chef-client #{client_options.join(' ')}" }]
240
240
  else
241
241
  # Upload the package and run it from the node
242
242
  package_name = File.basename(package_dir)
@@ -112,7 +112,7 @@ module HybridPlatformsConductor
112
112
  # Result::
113
113
  # * String: The Podman command
114
114
  def podman_cmd
115
- @podman_cmd = @cmd_runner.root? ? 'podman' : 'sudo podman' unless defined?(@podman_cmd)
115
+ @podman_cmd = "#{@cmd_runner.root? ? '' : 'sudo '}podman" unless defined?(@podman_cmd)
116
116
  @podman_cmd
117
117
  end
118
118
 
@@ -54,7 +54,7 @@ module HybridPlatformsConductor
54
54
  instance.stop
55
55
  instance.with_running_instance(port: 22) do
56
56
 
57
- unless @nodes_handler.get_root_access_allowed_of(@node) == 'true'
57
+ unless @nodes_handler.get_root_access_allowed_of(@node)
58
58
  # ===== Deploy removes root access
59
59
  # Check that we can't connect with root
60
60
  ssh_ok = false
@@ -1,3 +1,5 @@
1
+ require 'hybrid_platforms_conductor/test_only_remote_node'
2
+
1
3
  module HybridPlatformsConductor
2
4
 
3
5
  module HpcPlugins
@@ -5,7 +7,7 @@ module HybridPlatformsConductor
5
7
  module Test
6
8
 
7
9
  # Test that the connection works by simply outputing something
8
- class Connection < HybridPlatformsConductor::Test
10
+ class Connection < TestOnlyRemoteNode
9
11
 
10
12
  TEST_CONNECTION_STRING = 'Test connection - ok'
11
13
 
@@ -12,7 +12,7 @@ module HybridPlatformsConductor
12
12
 
13
13
  # Check my_test_plugin.rb.sample documentation for signature details.
14
14
  def test_for_node
15
- unless @nodes_handler.get_root_access_allowed_of(@node) == 'true'
15
+ unless @nodes_handler.get_root_access_allowed_of(@node)
16
16
  @deployer.with_test_provisioned_instance(@config.tests_provisioner_id, @node, environment: 'deploy_removes_root_access', reuse_instance: log_debug?) do |deployer, instance|
17
17
  # Check that we can connect with root
18
18
  ssh_ok = false
@@ -1,3 +1,4 @@
1
+ require 'hybrid_platforms_conductor/test_only_remote_node'
1
2
  require 'hybrid_platforms_conductor/common_config_dsl/file_system_tests'
2
3
 
3
4
  module HybridPlatformsConductor
@@ -7,7 +8,7 @@ module HybridPlatformsConductor
7
8
  module Test
8
9
 
9
10
  # Perform various tests on a node's file system
10
- class FileSystem < HybridPlatformsConductor::Test
11
+ class FileSystem < TestOnlyRemoteNode
11
12
 
12
13
  self.extend_config_dsl_with CommonConfigDsl::FileSystemTests, :init_file_system_tests
13
14
 
@@ -0,0 +1,32 @@
1
+ require 'hybrid_platforms_conductor/common_config_dsl/github'
2
+
3
+ module HybridPlatformsConductor
4
+
5
+ module HpcPlugins
6
+
7
+ module Test
8
+
9
+ # Check that all repositories have a successful Github CI
10
+ class GithubCi < HybridPlatformsConductor::Test
11
+
12
+ self.extend_config_dsl_with CommonConfigDsl::Github, :init_github
13
+
14
+ # Check my_test_plugin.rb.sample documentation for signature details.
15
+ def test
16
+ @config.for_each_github_repo do |client, repo_info|
17
+ log_debug "Checking CI for Github repository #{repo_info[:slug]}"
18
+ last_status = client.repository_workflow_runs(repo_info[:slug])[:workflow_runs].
19
+ select { |run| run[:head_branch] == 'master' }.
20
+ sort_by { |run| run[:created_at] }.
21
+ last[:conclusion]
22
+ error "Last workflow status for repository #{repo_info[:slug]} is #{last_status}" unless last_status == 'success'
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -1,3 +1,5 @@
1
+ require 'hybrid_platforms_conductor/test_only_remote_node'
2
+
1
3
  module HybridPlatformsConductor
2
4
 
3
5
  module HpcPlugins
@@ -5,7 +7,7 @@ module HybridPlatformsConductor
5
7
  module Test
6
8
 
7
9
  # Test that the hostname is correct
8
- class Hostname < HybridPlatformsConductor::Test
10
+ class Hostname < TestOnlyRemoteNode
9
11
 
10
12
  # Check my_test_plugin.rb.sample documentation for signature details.
11
13
  def test_on_node
@@ -1,3 +1,5 @@
1
+ require 'hybrid_platforms_conductor/test_only_remote_node'
2
+
1
3
  module HybridPlatformsConductor
2
4
 
3
5
  module HpcPlugins
@@ -5,7 +7,7 @@ module HybridPlatformsConductor
5
7
  module Test
6
8
 
7
9
  # Test that the private IP address is correct
8
- class Ip < HybridPlatformsConductor::Test
10
+ class Ip < TestOnlyRemoteNode
9
11
 
10
12
  # Check my_test_plugin.rb.sample documentation for signature details.
11
13
  def test_on_node
@@ -1,3 +1,5 @@
1
+ require 'hybrid_platforms_conductor/test_only_remote_node'
2
+
1
3
  module HybridPlatformsConductor
2
4
 
3
5
  module HpcPlugins
@@ -5,7 +7,7 @@ module HybridPlatformsConductor
5
7
  module Test
6
8
 
7
9
  # Test that the node's local users
8
- class LocalUsers < HybridPlatformsConductor::Test
10
+ class LocalUsers < TestOnlyRemoteNode
9
11
 
10
12
  # Config DSL extension for this test plugin
11
13
  module ConfigDslExtension
@@ -1,3 +1,5 @@
1
+ require 'hybrid_platforms_conductor/test_only_remote_node'
2
+
1
3
  module HybridPlatformsConductor
2
4
 
3
5
  module HpcPlugins
@@ -5,7 +7,7 @@ module HybridPlatformsConductor
5
7
  module Test
6
8
 
7
9
  # Various tests on mounts
8
- class Mounts < HybridPlatformsConductor::Test
10
+ class Mounts < TestOnlyRemoteNode
9
11
 
10
12
  # Config DSL extension for this test plugin
11
13
  module ConfigDslExtension
@@ -1,3 +1,5 @@
1
+ require 'hybrid_platforms_conductor/test_only_remote_node'
2
+
1
3
  module HybridPlatformsConductor
2
4
 
3
5
  module HpcPlugins
@@ -5,7 +7,7 @@ module HybridPlatformsConductor
5
7
  module Test
6
8
 
7
9
  # Test that the node has no orphan files
8
- class OrphanFiles < HybridPlatformsConductor::Test
10
+ class OrphanFiles < TestOnlyRemoteNode
9
11
 
10
12
  # Config DSL extension for this test plugin
11
13
  module ConfigDslExtension
@@ -1,3 +1,5 @@
1
+ require 'hybrid_platforms_conductor/test_only_remote_node'
2
+
1
3
  module HybridPlatformsConductor
2
4
 
3
5
  module HpcPlugins
@@ -5,7 +7,7 @@ module HybridPlatformsConductor
5
7
  module Test
6
8
 
7
9
  # Various tests on ports
8
- class Ports < HybridPlatformsConductor::Test
10
+ class Ports < TestOnlyRemoteNode
9
11
 
10
12
  # Config DSL extension for this test plugin
11
13
  module ConfigDslExtension
@@ -1,3 +1,5 @@
1
+ require 'hybrid_platforms_conductor/test_only_remote_node'
2
+
1
3
  module HybridPlatformsConductor
2
4
 
3
5
  module HpcPlugins
@@ -5,7 +7,7 @@ module HybridPlatformsConductor
5
7
  module Test
6
8
 
7
9
  # Test that the vulnerabilities Spectre and Meltdown are patched
8
- class Spectre < HybridPlatformsConductor::Test
10
+ class Spectre < TestOnlyRemoteNode
9
11
 
10
12
  VULNERABILITIES_TO_CHECK = {
11
13
  'CVE-2017-5753' => 'Spectre Variant 1',
@@ -1,4 +1,5 @@
1
1
  require 'nokogiri'
2
+ require 'hybrid_platforms_conductor/test_only_remote_node'
2
3
 
3
4
  module HybridPlatformsConductor
4
5
 
@@ -17,7 +18,7 @@ module HybridPlatformsConductor
17
18
  # Each final OVAL URL can be directly an XML file, either raw or compressed with .gz or .bz2.
18
19
  # This is useful to follow repository links, such as jFrog or web servers serving common file systems structure storing several versions of the OVAL file.
19
20
  # * *reported_severities* (Array<String> or nil): List of severities to report, if any (use Unknown when the severity is not known), or nil for all [default: nil]
20
- class Vulnerabilities < HybridPlatformsConductor::Test
21
+ class Vulnerabilities < TestOnlyRemoteNode
21
22
 
22
23
  # Known compression methods, per file extension, and their corresponding uncompress bash script
23
24
  KNOWN_COMPRESSIONS = {
@@ -0,0 +1,18 @@
1
+ module HybridPlatformsConductor
2
+
3
+ # Ancestor for all tests that should be run just on remote nodes
4
+ class TestOnlyRemoteNode < Test
5
+
6
+ # Limit the list of nodes for these tests.
7
+ #
8
+ # Result::
9
+ # * Array<String or Regex> or nil: List of nodes allowed for this test, or nil for all. Regular expressions matching node names can also be used.
10
+ def self.only_on_nodes
11
+ # Just 1 node per service and platform
12
+ Test.nodes_handler.prefetch_metadata_of Test.nodes_handler.known_nodes, :local_node
13
+ Test.nodes_handler.known_nodes.select { |node| !Test.nodes_handler.get_local_node_of(node) }
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -1,5 +1,5 @@
1
1
  module HybridPlatformsConductor
2
2
 
3
- VERSION = '32.16.1'
3
+ VERSION = '32.17.1'
4
4
 
5
5
  end
@@ -29,7 +29,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
29
29
  end
30
30
 
31
31
  it 'creates an SSH master to 1 node not having Session Exec capabilities' do
32
- with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42', ssh_session_exec: 'false' } } }) do
32
+ with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42', ssh_session_exec: false } } }) do
33
33
  with_cmd_runner_mocked(
34
34
  [
35
35
  ['which env', proc { [0, "/usr/bin/env\n", ''] }],
@@ -45,7 +45,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
45
45
  end
46
46
 
47
47
  it 'can\'t create an SSH master to 1 node not having Session Exec capabilities when hpc_interactive is false' do
48
- with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42', ssh_session_exec: 'false' } } }) do
48
+ with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42', ssh_session_exec: false } } }) do
49
49
  ENV['hpc_interactive'] = 'false'
50
50
  with_cmd_runner_mocked(
51
51
  [
@@ -69,7 +69,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
69
69
  it 'fails without creating exception when creating an SSH master to 1 node not having Session Exec capabilities when hpc_interactive is false and we use no_exception' do
70
70
  with_test_platform(nodes: {
71
71
  'node1' => { meta: { host_ip: '192.168.42.1' } },
72
- 'node2' => { meta: { host_ip: '192.168.42.2', ssh_session_exec: 'false' } },
72
+ 'node2' => { meta: { host_ip: '192.168.42.2', ssh_session_exec: false } },
73
73
  'node3' => { meta: { host_ip: '192.168.42.3' } }
74
74
  }) do
75
75
  ENV['hpc_interactive'] = 'false'
@@ -54,8 +54,8 @@ describe HybridPlatformsConductor::Deployer do
54
54
  with_test_platform(
55
55
  {
56
56
  nodes: {
57
- 'node1' => { meta: { host_ip: '192.168.42.1', ssh_session_exec: 'false' } },
58
- 'node2' => { meta: { host_ip: '192.168.42.2', ssh_session_exec: 'false' } }
57
+ 'node1' => { meta: { host_ip: '192.168.42.1', ssh_session_exec: false } },
58
+ 'node2' => { meta: { host_ip: '192.168.42.2', ssh_session_exec: false } }
59
59
  }
60
60
  },
61
61
  false,
@@ -75,8 +75,8 @@ describe HybridPlatformsConductor::Deployer do
75
75
  block.call
76
76
  end
77
77
  test_deployer.with_test_provisioned_instance(:test_provisioner, 'node1', environment: 'hpc_testing_provisioner') do |sub_test_deployer, test_instance|
78
- expect(sub_test_deployer.instance_eval { @nodes_handler.get_ssh_session_exec_of('node1') }).to eq 'true'
79
- expect(sub_test_deployer.instance_eval { @nodes_handler.get_ssh_session_exec_of('node2') }).to eq 'false'
78
+ expect(sub_test_deployer.instance_eval { @nodes_handler.get_ssh_session_exec_of('node1') }).to eq true
79
+ expect(sub_test_deployer.instance_eval { @nodes_handler.get_ssh_session_exec_of('node2') }).to eq false
80
80
  ssh_transforms = test_instance.instance_eval { @config.ssh_connection_transforms }
81
81
  expect(ssh_transforms.size).to eq 1
82
82
  expect(ssh_transforms[0][:nodes_selectors_stack]).to eq [%w[node2]]
@@ -26,7 +26,7 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
26
26
  if install
27
27
  [
28
28
  [
29
- "cd #{repository} && /opt/chef-workstation/bin/chef install #{policy_file}",
29
+ "cd #{repository} && /opt/chef-workstation/bin/chef install #{policy_file} --chef-license accept",
30
30
  proc do
31
31
  # Mock the run_list stored in the lock file
32
32
  File.write(
@@ -44,8 +44,9 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
44
44
  end +
45
45
  if export
46
46
  [
47
+ ['whoami', proc { [0, 'test_user', ''] }, { optional: true }],
47
48
  [
48
- /^cd #{Regexp.escape(repository)} &&\s+sudo rm -rf dist\/#{Regexp.escape(env)}\/#{Regexp.escape(policy)} &&\s+\/opt\/chef-workstation\/bin\/chef export #{Regexp.escape(policy_file)} dist\/#{Regexp.escape(env)}\/#{Regexp.escape(policy)}#{data_bags ? " && cp -ar data_bags/ dist/#{Regexp.escape(env)}/#{Regexp.escape(policy)}/" : ''}$/,
49
+ /^cd #{Regexp.escape(repository)} &&\s+sudo rm -rf dist\/#{Regexp.escape(env)}\/#{Regexp.escape(policy)} &&\s+\/opt\/chef-workstation\/bin\/chef export #{Regexp.escape(policy_file)} dist\/#{Regexp.escape(env)}\/#{Regexp.escape(policy)} --chef-license accept#{data_bags ? " && cp -ar data_bags/ dist/#{Regexp.escape(env)}/#{Regexp.escape(policy)}/" : ''}$/,
49
50
  proc do
50
51
  FileUtils.mkdir_p "#{repository}/dist/#{env}/#{policy}"
51
52
  FileUtils.cp_r("#{repository}/data_bags", "#{repository}/dist/#{env}/#{policy}/") if data_bags
@@ -0,0 +1,72 @@
1
+ describe HybridPlatformsConductor::TestsRunner do
2
+
3
+ context 'checking test plugins' do
4
+
5
+ context 'checking github_ci' do
6
+
7
+ it 'iterates over defined Github repos' do
8
+ with_repository do |repository|
9
+ platforms = <<~EOS
10
+ github_repos(
11
+ url: 'https://my_gh.my_domain.com',
12
+ user: 'GH-User1',
13
+ repos: [
14
+ 'repo1',
15
+ 'repo2'
16
+ ]
17
+ )
18
+ github_repos(
19
+ user: 'GH-User2',
20
+ repos: [
21
+ 'repo3',
22
+ 'repo4'
23
+ ]
24
+ )
25
+ EOS
26
+ with_platforms platforms do
27
+ repos = []
28
+ test_config.for_each_github_repo do |github, repo_info|
29
+ repos << {
30
+ github_url: github.api_endpoint,
31
+ repo_info: repo_info
32
+ }
33
+ end
34
+ expect(repos).to eq [
35
+ {
36
+ github_url: 'https://my_gh.my_domain.com/',
37
+ repo_info: {
38
+ name: 'repo1',
39
+ slug: 'GH-User1/repo1'
40
+ }
41
+ },
42
+ {
43
+ github_url: 'https://my_gh.my_domain.com/',
44
+ repo_info: {
45
+ name: 'repo2',
46
+ slug: 'GH-User1/repo2'
47
+ }
48
+ },
49
+ {
50
+ github_url: 'https://api.github.com/',
51
+ repo_info: {
52
+ name: 'repo3',
53
+ slug: 'GH-User2/repo3'
54
+ }
55
+ },
56
+ {
57
+ github_url: 'https://api.github.com/',
58
+ repo_info: {
59
+ name: 'repo4',
60
+ slug: 'GH-User2/repo4'
61
+ }
62
+ }
63
+ ]
64
+ end
65
+ end
66
+ end
67
+
68
+ end
69
+
70
+ end
71
+
72
+ end
@@ -136,7 +136,7 @@ module HybridPlatformsConductorTest
136
136
  session_exec: true
137
137
  )
138
138
  with_test_platform(
139
- { nodes: { 'node' => { meta: { host_ip: '192.168.42.42', ssh_session_exec: session_exec ? 'true' : 'false' } } } },
139
+ { nodes: { 'node' => { meta: { host_ip: '192.168.42.42', ssh_session_exec: session_exec } } } },
140
140
  false,
141
141
  additional_config
142
142
  ) do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hybrid_platforms_conductor
3
3
  version: !ruby/object:Gem::Version
4
- version: 32.16.1
4
+ version: 32.17.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muriel Salvan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-01 00:00:00.000000000 Z
11
+ date: 2021-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: range_operators
@@ -248,6 +248,20 @@ dependencies:
248
248
  - - "~>"
249
249
  - !ruby/object:Gem::Version
250
250
  version: '0.16'
251
+ - !ruby/object:Gem::Dependency
252
+ name: octokit
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - "~>"
256
+ - !ruby/object:Gem::Version
257
+ version: '4.21'
258
+ type: :runtime
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - "~>"
263
+ - !ruby/object:Gem::Version
264
+ version: '4.21'
251
265
  - !ruby/object:Gem::Dependency
252
266
  name: rspec
253
267
  requirement: !ruby/object:Gem::Requirement
@@ -345,6 +359,7 @@ extra_rdoc_files:
345
359
  - docs/plugins/provisioner/docker.md
346
360
  - docs/plugins/test/spectre.md
347
361
  - docs/plugins/test/bitbucket_conf.md
362
+ - docs/plugins/test/github_ci.md
348
363
  - docs/plugins/test/vulnerabilities.md
349
364
  - docs/plugins/test/deploy_removes_root_access.md
350
365
  - docs/plugins/test/private_ips.md
@@ -538,6 +553,7 @@ files:
538
553
  - docs/plugins/test/executables.md
539
554
  - docs/plugins/test/file_system.md
540
555
  - docs/plugins/test/file_system_hdfs.md
556
+ - docs/plugins/test/github_ci.md
541
557
  - docs/plugins/test/hostname.md
542
558
  - docs/plugins/test/idempotence.md
543
559
  - docs/plugins/test/ip.md
@@ -640,6 +656,7 @@ files:
640
656
  - lib/hybrid_platforms_conductor/common_config_dsl/bitbucket.rb
641
657
  - lib/hybrid_platforms_conductor/common_config_dsl/confluence.rb
642
658
  - lib/hybrid_platforms_conductor/common_config_dsl/file_system_tests.rb
659
+ - lib/hybrid_platforms_conductor/common_config_dsl/github.rb
643
660
  - lib/hybrid_platforms_conductor/common_config_dsl/idempotence_tests.rb
644
661
  - lib/hybrid_platforms_conductor/config.rb
645
662
  - lib/hybrid_platforms_conductor/confluence.rb
@@ -690,6 +707,7 @@ files:
690
707
  - lib/hybrid_platforms_conductor/hpc_plugins/test/executables.rb
691
708
  - lib/hybrid_platforms_conductor/hpc_plugins/test/file_system.rb
692
709
  - lib/hybrid_platforms_conductor/hpc_plugins/test/file_system_hdfs.rb
710
+ - lib/hybrid_platforms_conductor/hpc_plugins/test/github_ci.rb
693
711
  - lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb
694
712
  - lib/hybrid_platforms_conductor/hpc_plugins/test/idempotence.rb
695
713
  - lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb
@@ -729,6 +747,7 @@ files:
729
747
  - lib/hybrid_platforms_conductor/services_handler.rb
730
748
  - lib/hybrid_platforms_conductor/test.rb
731
749
  - lib/hybrid_platforms_conductor/test_by_service.rb
750
+ - lib/hybrid_platforms_conductor/test_only_remote_node.rb
732
751
  - lib/hybrid_platforms_conductor/test_report.rb
733
752
  - lib/hybrid_platforms_conductor/tests_runner.rb
734
753
  - lib/hybrid_platforms_conductor/thycotic.rb
@@ -819,6 +838,7 @@ files:
819
838
  - spec/hybrid_platforms_conductor_test/api/tests_runner/platform_spec.rb
820
839
  - spec/hybrid_platforms_conductor_test/api/tests_runner/reports_spec.rb
821
840
  - spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/bitbucket_conf_spec.rb
841
+ - spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/github_ci_spec.rb
822
842
  - spec/hybrid_platforms_conductor_test/api/tests_runner/test_reports_plugins/confluence_spec.rb
823
843
  - spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb.rb
824
844
  - spec/hybrid_platforms_conductor_test/cmdb_plugins/test_cmdb2.rb