hybrid_platforms_conductor 33.3.0 → 33.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -0
- data/README.md +31 -2
- data/docs/config_dsl.md +45 -0
- data/docs/plugins/cmdb/host_keys.md +3 -1
- data/docs/plugins/connector/ssh.md +1 -0
- data/lib/hybrid_platforms_conductor/actions_executor.rb +29 -1
- data/lib/hybrid_platforms_conductor/bitbucket.rb +134 -90
- data/lib/hybrid_platforms_conductor/cmd_runner.rb +4 -4
- data/lib/hybrid_platforms_conductor/common_config_dsl/bitbucket.rb +12 -44
- data/lib/hybrid_platforms_conductor/common_config_dsl/github.rb +9 -31
- data/lib/hybrid_platforms_conductor/config.rb +2 -0
- data/lib/hybrid_platforms_conductor/confluence.rb +93 -88
- data/lib/hybrid_platforms_conductor/connector.rb +5 -2
- data/lib/hybrid_platforms_conductor/credentials.rb +122 -97
- data/lib/hybrid_platforms_conductor/deployer.rb +7 -9
- data/lib/hybrid_platforms_conductor/github.rb +39 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/action/bash.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/action/remote_bash.rb +27 -17
- data/lib/hybrid_platforms_conductor/hpc_plugins/cmdb/host_keys.rb +13 -12
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/local.rb +6 -4
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/my_connector.rb.sample +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +37 -25
- data/lib/hybrid_platforms_conductor/hpc_plugins/log/remote_fs.rb +5 -6
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/docker.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox.rb +7 -4
- data/lib/hybrid_platforms_conductor/hpc_plugins/report/confluence.rb +3 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/secrets_reader/keepass.rb +3 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/secrets_reader/thycotic.rb +3 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/bitbucket_conf.rb +4 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/check_deploy_and_idempotence.rb +17 -3
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +30 -10
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/github_ci.rb +4 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +1 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/idempotence.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +1 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/jenkins_ci_conf.rb +7 -3
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/jenkins_ci_masters_ok.rb +8 -4
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +1 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +1 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +1 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +1 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/confluence.rb +3 -1
- data/lib/hybrid_platforms_conductor/logger_helpers.rb +24 -1
- data/lib/hybrid_platforms_conductor/test.rb +21 -7
- data/lib/hybrid_platforms_conductor/tests_runner.rb +7 -6
- data/lib/hybrid_platforms_conductor/thycotic.rb +80 -75
- data/lib/hybrid_platforms_conductor/version.rb +1 -1
- data/spec/hybrid_platforms_conductor_test.rb +6 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/bash_spec.rb +15 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/remote_bash_spec.rb +32 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/remote_actions_spec.rb +87 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connections_spec.rb +30 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/global_helpers_spec.rb +10 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb +38 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/helpers_spec.rb +195 -0
- data/spec/hybrid_platforms_conductor_test/api/cmd_runner_spec.rb +14 -0
- data/spec/hybrid_platforms_conductor_test/api/config_spec.rb +11 -0
- data/spec/hybrid_platforms_conductor_test/api/credentials_spec.rb +251 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/log_plugins/remote_fs_spec.rb +215 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/secrets_reader_plugins/keepass_spec.rb +280 -319
- data/spec/hybrid_platforms_conductor_test/api/deployer/secrets_reader_plugins/thycotic_spec.rb +2 -2
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/host_keys_spec.rb +49 -10
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/services_deployment_spec.rb +38 -0
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/bitbucket_conf_spec.rb +49 -69
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/github_ci_spec.rb +29 -39
- data/spec/hybrid_platforms_conductor_test/helpers/connector_ssh_helpers.rb +5 -3
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_local_node/chef_versions.yml +3 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_local_node/nodes/node.json +15 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_local_node/policyfiles/test_policy.rb +3 -0
- data/spec/hybrid_platforms_conductor_test/shared_examples/deployer.rb +134 -0
- data/spec/hybrid_platforms_conductor_test/test_connector.rb +2 -2
- metadata +36 -2
|
@@ -2,6 +2,7 @@ require 'json'
|
|
|
2
2
|
require 'proxmox'
|
|
3
3
|
require 'digest'
|
|
4
4
|
require 'hybrid_platforms_conductor/actions_executor'
|
|
5
|
+
require 'hybrid_platforms_conductor/credentials'
|
|
5
6
|
require 'hybrid_platforms_conductor/provisioner'
|
|
6
7
|
|
|
7
8
|
module HybridPlatformsConductor
|
|
@@ -263,6 +264,8 @@ module HybridPlatformsConductor
|
|
|
263
264
|
|
|
264
265
|
private
|
|
265
266
|
|
|
267
|
+
include Credentials
|
|
268
|
+
|
|
266
269
|
# Connect to the Proxmox API
|
|
267
270
|
#
|
|
268
271
|
# Parameters::
|
|
@@ -273,7 +276,7 @@ module HybridPlatformsConductor
|
|
|
273
276
|
url = proxmox_test_info[:api_url]
|
|
274
277
|
raise 'No Proxmox server defined' if url.nil?
|
|
275
278
|
|
|
276
|
-
|
|
279
|
+
with_credentials_for(:proxmox, resource: url) do |user, password|
|
|
277
280
|
log_debug "[ #{@node}/#{@environment} ] - Connect to Proxmox #{url}"
|
|
278
281
|
proxmox_logs = StringIO.new
|
|
279
282
|
proxmox = ::Proxmox::Proxmox.new(
|
|
@@ -282,7 +285,7 @@ module HybridPlatformsConductor
|
|
|
282
285
|
# cf https://pve.proxmox.com/wiki/Renaming_a_PVE_node
|
|
283
286
|
URI.parse(url).host.downcase.split('.').first,
|
|
284
287
|
user,
|
|
285
|
-
password,
|
|
288
|
+
password&.to_unprotected,
|
|
286
289
|
ENV['hpc_realm_for_proxmox'] || 'pam',
|
|
287
290
|
{
|
|
288
291
|
verify_ssl: false,
|
|
@@ -415,7 +418,7 @@ module HybridPlatformsConductor
|
|
|
415
418
|
extra_files[config_file] = './proxmox/config'
|
|
416
419
|
cmd << " --config ./proxmox/config/#{File.basename(config_file)}"
|
|
417
420
|
stdout = nil
|
|
418
|
-
|
|
421
|
+
with_credentials_for(:proxmox, resource: proxmox_test_info[:api_url]) do |user, password|
|
|
419
422
|
# To avoid too fine concurrent accesses on the sync node file system, make sure all threads of our process wait for their turn to upload their files.
|
|
420
423
|
# Otherwise there is a small probability that a directory scp makes previously copied files inaccessible for a short period of time.
|
|
421
424
|
self.class.proxmox_waiter_files_mutex.synchronize do
|
|
@@ -434,7 +437,7 @@ module HybridPlatformsConductor
|
|
|
434
437
|
{
|
|
435
438
|
proxmox_test_info[:sync_node] => {
|
|
436
439
|
remote_bash: {
|
|
437
|
-
commands: "#{@actions_executor.
|
|
440
|
+
commands: "#{@actions_executor.sudo_prefix(proxmox_test_info[:sync_node], forward_env: true)}./proxmox/#{cmd}",
|
|
438
441
|
env: {
|
|
439
442
|
'hpc_user_for_proxmox' => user,
|
|
440
443
|
'hpc_password_for_proxmox' => password,
|
|
@@ -14,6 +14,8 @@ module HybridPlatformsConductor
|
|
|
14
14
|
|
|
15
15
|
extend_config_dsl_with CommonConfigDsl::Confluence, :init_confluence
|
|
16
16
|
|
|
17
|
+
include HybridPlatformsConductor::Confluence
|
|
18
|
+
|
|
17
19
|
# Give the list of supported locales by this report generator
|
|
18
20
|
# [API] - This method is mandatory.
|
|
19
21
|
#
|
|
@@ -34,7 +36,7 @@ module HybridPlatformsConductor
|
|
|
34
36
|
if confluence_info
|
|
35
37
|
if confluence_info[:inventory_report_page_id]
|
|
36
38
|
@nodes = nodes
|
|
37
|
-
|
|
39
|
+
with_confluence(confluence_info[:url]) do |confluence|
|
|
38
40
|
confluence.update_page(confluence_info[:inventory_report_page_id], render('confluence_inventory'))
|
|
39
41
|
end
|
|
40
42
|
out "Inventory report Confluence page updated. Please visit #{confluence_info[:url]}/pages/viewpage.action?pageId=#{confluence_info[:inventory_report_page_id]}"
|
|
@@ -17,6 +17,7 @@ module HybridPlatformsConductor
|
|
|
17
17
|
class Keepass < HybridPlatformsConductor::SecretsReader
|
|
18
18
|
|
|
19
19
|
include SafeMerge
|
|
20
|
+
include Credentials
|
|
20
21
|
|
|
21
22
|
# Extend the Config DSL
|
|
22
23
|
module ConfigDSLExtension
|
|
@@ -84,12 +85,12 @@ module HybridPlatformsConductor
|
|
|
84
85
|
unless @secrets.key?(secret_id)
|
|
85
86
|
raise 'Missing KPScript configuration. Please use use_kpscript_from to set it.' if @config.kpscript.nil?
|
|
86
87
|
|
|
87
|
-
|
|
88
|
+
with_credentials_for(:keepass, resource: keepass_secrets_info[:database]) do |_user, password|
|
|
88
89
|
Tempfile.create('hpc_keepass') do |xml_file|
|
|
89
90
|
key_file = ENV['hpc_key_file_for_keepass']
|
|
90
91
|
password_enc = ENV['hpc_password_enc_for_keepass']
|
|
91
92
|
keepass_credentials = {}
|
|
92
|
-
keepass_credentials[:password] = password if password
|
|
93
|
+
keepass_credentials[:password] = password.to_unprotected if password
|
|
93
94
|
keepass_credentials[:password_enc] = password_enc if password_enc
|
|
94
95
|
keepass_credentials[:key_file] = key_file if key_file
|
|
95
96
|
KeepassKpscript.
|
|
@@ -42,6 +42,8 @@ module HybridPlatformsConductor
|
|
|
42
42
|
|
|
43
43
|
Config.extend_config_dsl_with ConfigDSLExtension, :init_thycotic_config
|
|
44
44
|
|
|
45
|
+
include HybridPlatformsConductor::Thycotic
|
|
46
|
+
|
|
45
47
|
# Return secrets for a given service to be deployed on a node.
|
|
46
48
|
# [API] - This method is mandatory
|
|
47
49
|
# [API] - The following API components are accessible:
|
|
@@ -62,7 +64,7 @@ module HybridPlatformsConductor
|
|
|
62
64
|
@nodes_handler.select_confs_for_node(node, @config.thycotic_secrets).each do |thycotic_secrets_info|
|
|
63
65
|
server_id = "#{thycotic_secrets_info[:thycotic_url]}:#{thycotic_secrets_info[:secret_id]}"
|
|
64
66
|
unless @secrets.key?(server_id)
|
|
65
|
-
|
|
67
|
+
with_thycotic(thycotic_secrets_info[:thycotic_url]) do |thycotic|
|
|
66
68
|
secret_file_item_id = thycotic.get_secret(thycotic_secrets_info[:secret_id]).dig(:secret, :items, :secret_item, :id)
|
|
67
69
|
raise "Unable to fetch secret file ID #{thycotic_secrets_info[:secret_id]} from #{thycotic_secrets_info[:thycotic_url]}" if secret_file_item_id.nil?
|
|
68
70
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'git'
|
|
2
|
+
require 'hybrid_platforms_conductor/bitbucket'
|
|
2
3
|
require 'hybrid_platforms_conductor/common_config_dsl/bitbucket'
|
|
3
4
|
|
|
4
5
|
module HybridPlatformsConductor
|
|
@@ -12,9 +13,11 @@ module HybridPlatformsConductor
|
|
|
12
13
|
|
|
13
14
|
extend_config_dsl_with CommonConfigDsl::Bitbucket, :init_bitbucket
|
|
14
15
|
|
|
16
|
+
include HybridPlatformsConductor::Bitbucket
|
|
17
|
+
|
|
15
18
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
|
16
19
|
def test
|
|
17
|
-
|
|
20
|
+
for_each_bitbucket_repo do |bitbucket, repo_info|
|
|
18
21
|
# Test repo_info
|
|
19
22
|
repo_id = "#{repo_info[:project]}/#{repo_info[:name]}"
|
|
20
23
|
settings_pr = bitbucket.settings_pr(repo_info[:project], repo_info[:name])
|
|
@@ -26,7 +26,13 @@ module HybridPlatformsConductor
|
|
|
26
26
|
# Check that we can connect with root
|
|
27
27
|
ssh_ok = false
|
|
28
28
|
begin
|
|
29
|
-
Net::SSH.start(
|
|
29
|
+
Net::SSH.start(
|
|
30
|
+
instance.ip,
|
|
31
|
+
'root',
|
|
32
|
+
password: 'root_pwd',
|
|
33
|
+
auth_methods: ['password'],
|
|
34
|
+
verify_host_key: :never
|
|
35
|
+
) do |ssh|
|
|
30
36
|
ssh_ok = ssh.exec!('echo Works').strip == 'Works'
|
|
31
37
|
end
|
|
32
38
|
rescue
|
|
@@ -53,14 +59,22 @@ module HybridPlatformsConductor
|
|
|
53
59
|
# System is booting up. See pam_nologin(8)
|
|
54
60
|
# Authentication failed.
|
|
55
61
|
instance.stop
|
|
56
|
-
|
|
62
|
+
ssh_port = @nodes_handler.get_ssh_port_of(@node) || 22
|
|
63
|
+
instance.with_running_instance(port: ssh_port) do
|
|
57
64
|
|
|
58
65
|
unless @nodes_handler.get_root_access_allowed_of(@node)
|
|
59
66
|
# ===== Deploy removes root access
|
|
60
67
|
# Check that we can't connect with root
|
|
61
68
|
ssh_ok = false
|
|
62
69
|
begin
|
|
63
|
-
Net::SSH.start(
|
|
70
|
+
Net::SSH.start(
|
|
71
|
+
instance.ip,
|
|
72
|
+
'root',
|
|
73
|
+
password: 'root_pwd',
|
|
74
|
+
auth_methods: ['password'],
|
|
75
|
+
verify_host_key: :never,
|
|
76
|
+
port: ssh_port
|
|
77
|
+
) do |ssh|
|
|
64
78
|
ssh_ok = ssh.exec!('echo Works').strip == 'Works'
|
|
65
79
|
end
|
|
66
80
|
rescue
|
|
@@ -18,7 +18,13 @@ module HybridPlatformsConductor
|
|
|
18
18
|
# Check that we can connect with root
|
|
19
19
|
ssh_ok = false
|
|
20
20
|
begin
|
|
21
|
-
Net::SSH.start(
|
|
21
|
+
Net::SSH.start(
|
|
22
|
+
instance.ip,
|
|
23
|
+
'root',
|
|
24
|
+
password: 'root_pwd',
|
|
25
|
+
auth_methods: ['password'],
|
|
26
|
+
verify_host_key: :never
|
|
27
|
+
) do |ssh|
|
|
22
28
|
ssh_ok = ssh.exec!('echo Works').strip == 'Works'
|
|
23
29
|
end
|
|
24
30
|
rescue
|
|
@@ -29,17 +35,31 @@ module HybridPlatformsConductor
|
|
|
29
35
|
deployer.nbr_retries_on_error = 3
|
|
30
36
|
deployer.deploy_on @node
|
|
31
37
|
# As sshd is certainly being restarted, start and stop the container to reload it.
|
|
32
|
-
|
|
33
|
-
#
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
# As it's possible sshd has to be restarted because of a change in its conf, restart the container.
|
|
39
|
+
# Otherwise you'll get the following error upon reconnection:
|
|
40
|
+
# System is booting up. See pam_nologin(8)
|
|
41
|
+
# Authentication failed.
|
|
42
|
+
instance.stop
|
|
43
|
+
ssh_port = @nodes_handler.get_ssh_port_of(@node) || 22
|
|
44
|
+
instance.with_running_instance(port: ssh_port) do
|
|
45
|
+
# Check that we can't connect with root
|
|
46
|
+
ssh_ok = false
|
|
47
|
+
begin
|
|
48
|
+
Net::SSH.start(
|
|
49
|
+
instance.ip,
|
|
50
|
+
'root',
|
|
51
|
+
password: 'root_pwd',
|
|
52
|
+
auth_methods: ['password'],
|
|
53
|
+
verify_host_key: :never,
|
|
54
|
+
port: ssh_port
|
|
55
|
+
) do |ssh|
|
|
56
|
+
ssh_ok = ssh.exec!('echo Works').strip == 'Works'
|
|
57
|
+
end
|
|
58
|
+
rescue
|
|
59
|
+
nil
|
|
38
60
|
end
|
|
39
|
-
|
|
40
|
-
nil
|
|
61
|
+
assert_equal ssh_ok, false, 'Root can still connect on the image after deployment'
|
|
41
62
|
end
|
|
42
|
-
assert_equal ssh_ok, false, 'Root can still connect on the image after deployment'
|
|
43
63
|
end
|
|
44
64
|
end
|
|
45
65
|
end
|
|
@@ -17,7 +17,7 @@ module HybridPlatformsConductor
|
|
|
17
17
|
# Flatten the paths rules so that we can spot inconsistencies in configuration
|
|
18
18
|
@config.aggregate_files_rules(@nodes_handler, @node).map do |path, rule_info|
|
|
19
19
|
[
|
|
20
|
-
"if #{@
|
|
20
|
+
"if #{@actions_executor.sudo_prefix(@node)}/bin/bash -c '[[ -d \"#{path}\" ]]' ; then echo 1 ; else echo 0 ; fi",
|
|
21
21
|
{
|
|
22
22
|
validator: proc do |stdout, stderr|
|
|
23
23
|
case stdout.last
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'hybrid_platforms_conductor/github'
|
|
1
2
|
require 'hybrid_platforms_conductor/common_config_dsl/github'
|
|
2
3
|
|
|
3
4
|
module HybridPlatformsConductor
|
|
@@ -11,9 +12,11 @@ module HybridPlatformsConductor
|
|
|
11
12
|
|
|
12
13
|
extend_config_dsl_with CommonConfigDsl::Github, :init_github
|
|
13
14
|
|
|
15
|
+
include HybridPlatformsConductor::Github
|
|
16
|
+
|
|
14
17
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
|
15
18
|
def test
|
|
16
|
-
|
|
19
|
+
for_each_github_repo do |client, repo_info|
|
|
17
20
|
log_debug "Checking CI for Github repository #{repo_info[:slug]}"
|
|
18
21
|
last_status = client.repository_workflow_runs(repo_info[:slug])[:workflow_runs].
|
|
19
22
|
select { |run| run[:head_branch] == 'master' }.
|
|
@@ -12,8 +12,7 @@ module HybridPlatformsConductor
|
|
|
12
12
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
|
13
13
|
def test_on_node
|
|
14
14
|
{
|
|
15
|
-
#
|
|
16
|
-
"#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}hostname -s" => proc do |stdout|
|
|
15
|
+
"#{@actions_executor.sudo_prefix(@node)}hostname -s" => proc do |stdout|
|
|
17
16
|
assert_equal stdout.first, @node, "Expected hostname to be #{@node}, but got #{stdout.first} instead."
|
|
18
17
|
end
|
|
19
18
|
}
|
|
@@ -27,7 +27,7 @@ module HybridPlatformsConductor
|
|
|
27
27
|
# System is booting up. See pam_nologin(8)
|
|
28
28
|
# Authentication failed.
|
|
29
29
|
instance.stop
|
|
30
|
-
instance.with_running_instance(port: 22) do
|
|
30
|
+
instance.with_running_instance(port: @nodes_handler.get_ssh_port_of(@node) || 22) do
|
|
31
31
|
# Now that the node has been deployed, use the a_testadmin user for the check-node (as root has no more access)
|
|
32
32
|
deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user = 'a_testadmin'
|
|
33
33
|
deployer.instance_variable_get(:@actions_executor).connector(:ssh).passwords.delete(@node)
|
|
@@ -12,8 +12,7 @@ module HybridPlatformsConductor
|
|
|
12
12
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
|
13
13
|
def test_on_node
|
|
14
14
|
{
|
|
15
|
-
#
|
|
16
|
-
"#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}hostname -I" => proc do |stdout|
|
|
15
|
+
"#{@actions_executor.sudo_prefix(@node)}hostname -I" => proc do |stdout|
|
|
17
16
|
if stdout.first.nil?
|
|
18
17
|
error 'No IP returned by "hostname -I"'
|
|
19
18
|
else
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'open-uri'
|
|
2
2
|
require 'nokogiri'
|
|
3
3
|
require 'hybrid_platforms_conductor/credentials'
|
|
4
|
+
require 'hybrid_platforms_conductor/bitbucket'
|
|
4
5
|
require 'hybrid_platforms_conductor/common_config_dsl/bitbucket'
|
|
5
6
|
|
|
6
7
|
module HybridPlatformsConductor
|
|
@@ -14,15 +15,18 @@ module HybridPlatformsConductor
|
|
|
14
15
|
|
|
15
16
|
extend_config_dsl_with CommonConfigDsl::Bitbucket, :init_bitbucket
|
|
16
17
|
|
|
18
|
+
include Credentials
|
|
19
|
+
include HybridPlatformsConductor::Bitbucket
|
|
20
|
+
|
|
17
21
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
|
18
22
|
def test
|
|
19
|
-
|
|
23
|
+
for_each_bitbucket_repo do |bitbucket, repo_info|
|
|
20
24
|
if repo_info[:jenkins_ci_url].nil?
|
|
21
25
|
error "Repository #{repo_info[:name]} does not have any Jenkins CI URL configured."
|
|
22
26
|
else
|
|
23
|
-
|
|
27
|
+
with_credentials_for(:jenkins_ci, resource: repo_info[:jenkins_ci_url]) do |jenkins_user, jenkins_password|
|
|
24
28
|
# Get its config
|
|
25
|
-
doc = Nokogiri::XML(URI.parse("#{repo_info[:jenkins_ci_url]}/config.xml").open(http_basic_authentication: [jenkins_user, jenkins_password]).read)
|
|
29
|
+
doc = Nokogiri::XML(URI.parse("#{repo_info[:jenkins_ci_url]}/config.xml").open(http_basic_authentication: [jenkins_user, jenkins_password&.to_unprotected]).read)
|
|
26
30
|
# Check that this job builds the correct Bitbucket repository
|
|
27
31
|
assert_equal(
|
|
28
32
|
doc.xpath('/org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject/sources/data/jenkins.branch.BranchSource/source/serverUrl').text,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'json'
|
|
2
2
|
require 'hybrid_platforms_conductor/credentials'
|
|
3
|
+
require 'hybrid_platforms_conductor/bitbucket'
|
|
3
4
|
require 'hybrid_platforms_conductor/common_config_dsl/bitbucket'
|
|
4
5
|
|
|
5
6
|
module HybridPlatformsConductor
|
|
@@ -13,6 +14,9 @@ module HybridPlatformsConductor
|
|
|
13
14
|
|
|
14
15
|
extend_config_dsl_with CommonConfigDsl::Bitbucket, :init_bitbucket
|
|
15
16
|
|
|
17
|
+
include Credentials
|
|
18
|
+
include HybridPlatformsConductor::Bitbucket
|
|
19
|
+
|
|
16
20
|
SUCCESS_STATUSES = [
|
|
17
21
|
# Add nil as the status of a currently running job (which is always the case for hybrid-platforms) is null
|
|
18
22
|
nil,
|
|
@@ -23,17 +27,17 @@ module HybridPlatformsConductor
|
|
|
23
27
|
|
|
24
28
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
|
25
29
|
def test
|
|
26
|
-
|
|
30
|
+
for_each_bitbucket_repo do |_bitbucket, repo_info|
|
|
27
31
|
if repo_info[:jenkins_ci_url].nil?
|
|
28
32
|
error "Repository #{repo_info[:name]} does not have any Jenkins CI URL configured."
|
|
29
33
|
else
|
|
30
34
|
master_info_url = "#{repo_info[:jenkins_ci_url]}/job/master/api/json"
|
|
31
|
-
|
|
35
|
+
with_credentials_for(:jenkins_ci, resource: master_info_url) do |jenkins_user, jenkins_password|
|
|
32
36
|
# Get the master branch info from the API
|
|
33
|
-
master_info = JSON.parse(URI.parse(master_info_url).open(http_basic_authentication: [jenkins_user, jenkins_password]).read)
|
|
37
|
+
master_info = JSON.parse(URI.parse(master_info_url).open(http_basic_authentication: [jenkins_user, jenkins_password&.to_unprotected]).read)
|
|
34
38
|
# Get the last build's URL
|
|
35
39
|
last_build_info_url = "#{master_info['lastBuild']['url']}/api/json"
|
|
36
|
-
last_build_info = JSON.parse(URI.parse(last_build_info_url).open(http_basic_authentication: [jenkins_user, jenkins_password]).read)
|
|
40
|
+
last_build_info = JSON.parse(URI.parse(last_build_info_url).open(http_basic_authentication: [jenkins_user, jenkins_password&.to_unprotected]).read)
|
|
37
41
|
log_debug "Build info for #{master_info_url}:\n#{JSON.pretty_generate(last_build_info)}"
|
|
38
42
|
error "Last build for job #{repo_info[:project]}/#{repo_info[:name]} is in status #{last_build_info['result']}: #{master_info['lastBuild']['url']}" unless SUCCESS_STATUSES.include?(last_build_info['result'])
|
|
39
43
|
rescue
|
|
@@ -59,8 +59,7 @@ module HybridPlatformsConductor
|
|
|
59
59
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
|
60
60
|
def test_on_node
|
|
61
61
|
{
|
|
62
|
-
#
|
|
63
|
-
"#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}cat /etc/passwd" => proc do |stdout|
|
|
62
|
+
"#{@actions_executor.sudo_prefix(@node)}cat /etc/passwd" => proc do |stdout|
|
|
64
63
|
passwd_users = stdout.map { |passwd_line| passwd_line.split(':').first }
|
|
65
64
|
missing_users = @nodes_handler.
|
|
66
65
|
select_confs_for_node(@node, @config.users_that_should_be_present).
|
|
@@ -63,8 +63,7 @@ module HybridPlatformsConductor
|
|
|
63
63
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
|
64
64
|
def test_on_node
|
|
65
65
|
{
|
|
66
|
-
#
|
|
67
|
-
"#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}mount" => proc do |stdout|
|
|
66
|
+
"#{@actions_executor.sudo_prefix(@node)}mount" => proc do |stdout|
|
|
68
67
|
mounts_info = stdout.map do |line|
|
|
69
68
|
fields = line.split
|
|
70
69
|
{
|
|
@@ -52,8 +52,7 @@ module HybridPlatformsConductor
|
|
|
52
52
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
|
53
53
|
def test_on_node
|
|
54
54
|
{
|
|
55
|
-
#
|
|
56
|
-
"#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}/usr/bin/find / \\( #{
|
|
55
|
+
"#{@actions_executor.sudo_prefix(@node)}/usr/bin/find / \\( #{
|
|
57
56
|
@nodes_handler.
|
|
58
57
|
select_confs_for_node(@node, @config.ignored_orphan_files_paths).
|
|
59
58
|
inject(DIRECTORIES_TO_ALWAYS_IGNORE) { |merged_paths, paths_to_ignore_info| merged_paths + paths_to_ignore_info[:ignored_paths] }.
|
|
@@ -18,7 +18,7 @@ module HybridPlatformsConductor
|
|
|
18
18
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
|
19
19
|
def test_on_node
|
|
20
20
|
spectre_cmd = <<~EO_BASH
|
|
21
|
-
#{@
|
|
21
|
+
#{@actions_executor.sudo_prefix(@node)}/bin/bash <<'EOAction'
|
|
22
22
|
#{File.read("#{__dir__}/spectre-meltdown-checker.sh")}
|
|
23
23
|
EOAction
|
|
24
24
|
EO_BASH
|
|
@@ -56,8 +56,7 @@ module HybridPlatformsConductor
|
|
|
56
56
|
current_url
|
|
57
57
|
end
|
|
58
58
|
)
|
|
59
|
-
|
|
60
|
-
sudo = @deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "
|
|
59
|
+
sudo = @actions_executor.sudo_prefix(@node)
|
|
61
60
|
urls.map do |url|
|
|
62
61
|
# 1. Get the OVAL file on the node to be tested (uncompress it if needed)
|
|
63
62
|
# 2. Make sure oscap is installed
|
|
@@ -14,6 +14,8 @@ module HybridPlatformsConductor
|
|
|
14
14
|
|
|
15
15
|
extend_config_dsl_with CommonConfigDsl::Confluence, :init_confluence
|
|
16
16
|
|
|
17
|
+
include HybridPlatformsConductor::Confluence
|
|
18
|
+
|
|
17
19
|
# Maximum errors to be reported by item
|
|
18
20
|
MAX_ERROR_ITEMS_DISPLAYED = 10
|
|
19
21
|
|
|
@@ -28,7 +30,7 @@ module HybridPlatformsConductor
|
|
|
28
30
|
confluence_info = @config.confluence_info
|
|
29
31
|
if confluence_info
|
|
30
32
|
if confluence_info[:tests_report_page_id]
|
|
31
|
-
|
|
33
|
+
with_confluence(confluence_info[:url]) do |confluence|
|
|
32
34
|
# Get previous percentages for the evolution
|
|
33
35
|
@previous_success_percentages = confluence.page_storage_format(confluence_info[:tests_report_page_id]).
|
|
34
36
|
at('h1:contains("Evolution")').
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
require 'colorize'
|
|
2
2
|
require 'logger'
|
|
3
3
|
require 'ruby-progressbar'
|
|
4
|
+
require 'secret_string'
|
|
5
|
+
|
|
6
|
+
# Add colorization methods to SecretString, but always directed to the silenced string as we NEVER want to modiy/clone a secret
|
|
7
|
+
class SecretString
|
|
8
|
+
|
|
9
|
+
extend Colorize::ClassMethods
|
|
10
|
+
|
|
11
|
+
def_delegators :@silenced_str, *%i[
|
|
12
|
+
colorize
|
|
13
|
+
uncolorize
|
|
14
|
+
colorized?
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
color_methods
|
|
18
|
+
modes_methods
|
|
19
|
+
|
|
20
|
+
end
|
|
4
21
|
|
|
5
22
|
module HybridPlatformsConductor
|
|
6
23
|
|
|
@@ -88,7 +105,13 @@ module HybridPlatformsConductor
|
|
|
88
105
|
define_method("log_#{level}") do |message|
|
|
89
106
|
(LEVELS_TO_STDERR.include?(level) ? @logger_stderr : @logger).send(
|
|
90
107
|
level,
|
|
91
|
-
defined?(@log_component)
|
|
108
|
+
if defined?(@log_component)
|
|
109
|
+
@log_component
|
|
110
|
+
else
|
|
111
|
+
# Handle the case when the class is unnamed
|
|
112
|
+
class_name = self.class.name
|
|
113
|
+
class_name.nil? ? '<Unnamed class>' : class_name.split('::').last
|
|
114
|
+
end
|
|
92
115
|
) { message }
|
|
93
116
|
end
|
|
94
117
|
end
|