hybrid_platforms_conductor 33.3.0 → 33.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|