hybrid_platforms_conductor 32.4.2 → 32.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/hybrid_platforms_conductor/deployer.rb +9 -8
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_freshness.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +6 -7
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +7 -6
- data/lib/hybrid_platforms_conductor/nodes_handler.rb +37 -0
- data/lib/hybrid_platforms_conductor/version.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb +15 -1
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/common_spec.rb +28 -0
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/config_spec.rb +71 -0
- data/spec/hybrid_platforms_conductor_test/helpers/connector_ssh_helpers.rb +10 -2
- data/spec/hybrid_platforms_conductor_test/helpers/deployer_helpers.rb +14 -14
- data/spec/hybrid_platforms_conductor_test/helpers/deployer_test_helpers.rb +70 -11
- data/spec/hybrid_platforms_conductor_test/helpers/provisioner_proxmox_helpers.rb +2 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 834a3af157221b88e6a150738b146f90fdf832c43fe5e8471619879c47a22d5b
|
4
|
+
data.tar.gz: c4f54b879fbfba923fda2a8aee1b299cb846ed9478ca9bd81535f220ec622f69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42ae65da627c812b096c0e9f9b4bb8c9ac4dde3185e1f6cf8d1405acbab960d5c5c88050c25e3d45906acb6054c73fd7ec29b2e5751b1ec38734f83a33f34bef
|
7
|
+
data.tar.gz: 41e641381b34d9d0841770974c4401612bfc3a4d11a5ec2fe85969f40ab1bfce0952cb4bbf5b7d2fce5420d9090a4962e278b9fb84d4251e0f13ee84db405e6c
|
@@ -480,6 +480,7 @@ module HybridPlatformsConductor
|
|
480
480
|
outputs = @actions_executor.execute_actions(
|
481
481
|
Hash[services.map do |node, node_services|
|
482
482
|
image_id = @nodes_handler.get_image_of(node)
|
483
|
+
sudo = (ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(node)} ")
|
483
484
|
# Install My_company corporate certificates if present
|
484
485
|
certificate_actions =
|
485
486
|
if @local_environment && ENV['hpc_certificates']
|
@@ -489,20 +490,20 @@ module HybridPlatformsConductor
|
|
489
490
|
when 'debian_9', 'debian_10'
|
490
491
|
[
|
491
492
|
{
|
492
|
-
remote_bash: "#{
|
493
|
+
remote_bash: "#{sudo}apt update && #{sudo}apt install -y ca-certificates"
|
493
494
|
},
|
494
495
|
{
|
495
496
|
scp: {
|
496
497
|
ENV['hpc_certificates'] => '/usr/local/share/ca-certificates',
|
497
498
|
:sudo => ssh_user != 'root'
|
498
499
|
},
|
499
|
-
remote_bash: "#{
|
500
|
+
remote_bash: "#{sudo}update-ca-certificates"
|
500
501
|
}
|
501
502
|
]
|
502
503
|
when 'centos_7'
|
503
504
|
[
|
504
505
|
{
|
505
|
-
remote_bash: "#{
|
506
|
+
remote_bash: "#{sudo}yum install -y ca-certificates"
|
506
507
|
},
|
507
508
|
{
|
508
509
|
scp: Hash[Dir.glob("#{ENV['hpc_certificates']}/*.crt").map do |cert_file|
|
@@ -512,8 +513,8 @@ module HybridPlatformsConductor
|
|
512
513
|
]
|
513
514
|
end].merge(sudo: ssh_user != 'root'),
|
514
515
|
remote_bash: [
|
515
|
-
"#{
|
516
|
-
"#{
|
516
|
+
"#{sudo}update-ca-trust enable",
|
517
|
+
"#{sudo}update-ca-trust extract"
|
517
518
|
]
|
518
519
|
}
|
519
520
|
]
|
@@ -532,7 +533,7 @@ module HybridPlatformsConductor
|
|
532
533
|
# Install the mutex lock and acquire it
|
533
534
|
{
|
534
535
|
scp: { "#{__dir__}/mutex_dir" => '.' },
|
535
|
-
remote_bash: "while ! #{
|
536
|
+
remote_bash: "while ! #{sudo}./mutex_dir lock /tmp/hybrid_platforms_conductor_deploy_lock \"$(ps -o ppid= -p $$)\"; do echo -e 'Another deployment is running on #{node}. Waiting for it to finish to continue...' ; sleep 5 ; done"
|
536
537
|
}
|
537
538
|
] +
|
538
539
|
certificate_actions +
|
@@ -548,7 +549,7 @@ module HybridPlatformsConductor
|
|
548
549
|
Hash[services.keys.map do |node|
|
549
550
|
[
|
550
551
|
node,
|
551
|
-
{ remote_bash: "#{ssh_user == 'root' ? '' :
|
552
|
+
{ remote_bash: "#{ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(node)} "}./mutex_dir unlock /tmp/hybrid_platforms_conductor_deploy_lock" }
|
552
553
|
]
|
553
554
|
end],
|
554
555
|
timeout: 10,
|
@@ -595,7 +596,7 @@ module HybridPlatformsConductor
|
|
595
596
|
[
|
596
597
|
node,
|
597
598
|
{
|
598
|
-
remote_bash: "#{ssh_user == 'root' ? '' :
|
599
|
+
remote_bash: "#{ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(node)} "}mkdir -p /var/log/deployments",
|
599
600
|
scp: {
|
600
601
|
log_file => '/var/log/deployments',
|
601
602
|
:sudo => ssh_user != 'root',
|
@@ -404,7 +404,7 @@ module HybridPlatformsConductor
|
|
404
404
|
{
|
405
405
|
proxmox_test_info[:sync_node] => {
|
406
406
|
remote_bash: {
|
407
|
-
commands: "#{@actions_executor.connector(:ssh).ssh_user == 'root' ? '' :
|
407
|
+
commands: "#{@actions_executor.connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(proxmox_test_info[:sync_node])} -E "}./proxmox/#{cmd}",
|
408
408
|
env: {
|
409
409
|
'hpc_user_for_proxmox' => user,
|
410
410
|
'hpc_password_for_proxmox' => password,
|
@@ -15,7 +15,7 @@ module HybridPlatformsConductor
|
|
15
15
|
def test_on_node
|
16
16
|
now = Time.now
|
17
17
|
{
|
18
|
-
|
18
|
+
"#{@nodes_handler.sudo_on(@node)} ls -t /var/log/deployments" => proc do |stdout|
|
19
19
|
if stdout.empty?
|
20
20
|
error 'Node has never been deployed using deploy (/var/log/deployments is empty)'
|
21
21
|
elsif stdout.first =~ /No such file or directory/
|
@@ -17,7 +17,7 @@ module HybridPlatformsConductor
|
|
17
17
|
Hash[
|
18
18
|
@config.aggregate_files_rules(@nodes_handler, @node).map do |path, rule_info|
|
19
19
|
[
|
20
|
-
"if
|
20
|
+
"if #{@nodes_handler.sudo_on(@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
|
@@ -10,7 +10,7 @@ module HybridPlatformsConductor
|
|
10
10
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
11
11
|
def test_on_node
|
12
12
|
{
|
13
|
-
|
13
|
+
"#{@nodes_handler.sudo_on(@node)} hostname -s" => proc do |stdout|
|
14
14
|
assert_equal stdout.first, @node, "Expected hostname to be #{@node}, but got #{stdout.first} instead."
|
15
15
|
end
|
16
16
|
}
|
@@ -10,7 +10,7 @@ module HybridPlatformsConductor
|
|
10
10
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
11
11
|
def test_on_node
|
12
12
|
{
|
13
|
-
|
13
|
+
"#{@nodes_handler.sudo_on(@node)} hostname -I" => proc do |stdout|
|
14
14
|
if stdout.first.nil?
|
15
15
|
error 'No IP returned by "hostname -I"'
|
16
16
|
else
|
@@ -57,7 +57,7 @@ module HybridPlatformsConductor
|
|
57
57
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
58
58
|
def test_on_node
|
59
59
|
{
|
60
|
-
"
|
60
|
+
"#{@nodes_handler.sudo_on(@node)} cat /etc/passwd" => proc do |stdout|
|
61
61
|
passwd_users = stdout.map { |passwd_line| passwd_line.split(':').first }
|
62
62
|
missing_users = @nodes_handler.
|
63
63
|
select_confs_for_node(@node, @config.users_that_should_be_present).
|
@@ -61,7 +61,7 @@ module HybridPlatformsConductor
|
|
61
61
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
62
62
|
def test_on_node
|
63
63
|
{
|
64
|
-
|
64
|
+
"#{@nodes_handler.sudo_on(@node)} mount" => proc do |stdout|
|
65
65
|
mounts_info = stdout.map do |line|
|
66
66
|
fields = line.split
|
67
67
|
{
|
@@ -50,7 +50,7 @@ module HybridPlatformsConductor
|
|
50
50
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
51
51
|
def test_on_node
|
52
52
|
{
|
53
|
-
"
|
53
|
+
"#{@nodes_handler.sudo_on(@node)} /usr/bin/find / \\( #{@nodes_handler.
|
54
54
|
select_confs_for_node(@node, @config.ignored_orphan_files_paths).
|
55
55
|
inject(DIRECTORIES_TO_ALWAYS_IGNORE) { |merged_paths, paths_to_ignore_info| merged_paths + paths_to_ignore_info[:ignored_paths] }.
|
56
56
|
uniq.
|
@@ -13,16 +13,15 @@ module HybridPlatformsConductor
|
|
13
13
|
'CVE-2017-5754' => 'Meltdown'
|
14
14
|
}
|
15
15
|
|
16
|
-
SPECTRE_CMD = <<~EOS
|
17
|
-
sudo /bin/bash <<'EOAction'
|
18
|
-
#{File.read("#{__dir__}/spectre-meltdown-checker.sh")}
|
19
|
-
EOAction
|
20
|
-
EOS
|
21
|
-
|
22
16
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
23
17
|
def test_on_node
|
18
|
+
spectre_cmd = <<~EOS
|
19
|
+
#{@nodes_handler.sudo_on(@node)} /bin/bash <<'EOAction'
|
20
|
+
#{File.read("#{__dir__}/spectre-meltdown-checker.sh")}
|
21
|
+
EOAction
|
22
|
+
EOS
|
24
23
|
{
|
25
|
-
|
24
|
+
spectre_cmd => {
|
26
25
|
validator: proc do |stdout|
|
27
26
|
VULNERABILITIES_TO_CHECK.each do |id, name|
|
28
27
|
id_regexp = /#{Regexp.escape(id)}/
|
@@ -54,6 +54,7 @@ module HybridPlatformsConductor
|
|
54
54
|
current_url
|
55
55
|
end
|
56
56
|
)
|
57
|
+
sudo = @nodes_handler.sudo_on(@node)
|
57
58
|
Hash[urls.map do |url|
|
58
59
|
# 1. Get the OVAL file on the node to be tested (uncompress it if needed)
|
59
60
|
# 2. Make sure oscap is installed
|
@@ -74,9 +75,9 @@ module HybridPlatformsConductor
|
|
74
75
|
#{
|
75
76
|
case image
|
76
77
|
when :centos_7
|
77
|
-
"sudo yum install -y wget openscap-scanner #{packages_to_install.join(' ')}"
|
78
|
+
"#{sudo} yum install -y wget openscap-scanner #{packages_to_install.join(' ')}"
|
78
79
|
when :debian_9
|
79
|
-
"sudo apt install -y wget libopenscap8 #{packages_to_install.join(' ')}"
|
80
|
+
"#{sudo} apt install -y wget libopenscap8 #{packages_to_install.join(' ')}"
|
80
81
|
when :debian_10
|
81
82
|
# On Debian 10 we have to compile it from sources, as the packaged official version has core dumps.
|
82
83
|
# cf https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1688223.html
|
@@ -86,13 +87,13 @@ module HybridPlatformsConductor
|
|
86
87
|
rm -rf openscap
|
87
88
|
git clone --recurse-submodules https://github.com/OpenSCAP/openscap.git
|
88
89
|
cd openscap
|
89
|
-
sudo apt install -y cmake libdbus-1-dev libdbus-glib-1-dev libcurl4-openssl-dev libgcrypt20-dev libselinux1-dev libxslt1-dev libgconf2-dev libacl1-dev libblkid-dev libcap-dev libxml2-dev libldap2-dev libpcre3-dev python-dev swig libxml-parser-perl libxml-xpath-perl libperl-dev libbz2-dev librpm-dev g++ libapt-pkg-dev libyaml-dev
|
90
|
+
#{sudo} apt install -y cmake libdbus-1-dev libdbus-glib-1-dev libcurl4-openssl-dev libgcrypt20-dev libselinux1-dev libxslt1-dev libgconf2-dev libacl1-dev libblkid-dev libcap-dev libxml2-dev libldap2-dev libpcre3-dev python-dev swig libxml-parser-perl libxml-xpath-perl libperl-dev libbz2-dev librpm-dev g++ libapt-pkg-dev libyaml-dev
|
90
91
|
cd build
|
91
92
|
cmake ../
|
92
93
|
make
|
93
|
-
sudo make install
|
94
|
+
#{sudo} make install
|
94
95
|
fi
|
95
|
-
sudo apt install -y wget #{packages_to_install.join(' ')}
|
96
|
+
#{sudo} apt install -y wget #{packages_to_install.join(' ')}
|
96
97
|
EOS2
|
97
98
|
else
|
98
99
|
raise "Non supported image: #{image}. Please adapt this test's code."
|
@@ -103,7 +104,7 @@ module HybridPlatformsConductor
|
|
103
104
|
cd hpc_vulnerabilities_test
|
104
105
|
wget -N #{url}
|
105
106
|
#{uncompress_cmds.join("\n")}
|
106
|
-
sudo oscap oval eval --skip-valid --results "#{local_oval_file}.results.xml" "#{local_oval_file}"
|
107
|
+
#{sudo} oscap oval eval --skip-valid --results "#{local_oval_file}.results.xml" "#{local_oval_file}"
|
107
108
|
echo "===== RESULTS ====="
|
108
109
|
cat "#{local_oval_file}.results.xml"
|
109
110
|
cd ..
|
@@ -18,9 +18,20 @@ module HybridPlatformsConductor
|
|
18
18
|
# Array< Hash<Symbol, Object> >
|
19
19
|
attr_reader :cmdb_masters
|
20
20
|
|
21
|
+
# List of sudo methods. Each info has the following properties:
|
22
|
+
# * *nodes_selectors_stack* (Array<Object>): Stack of nodes selectors impacted by this rule.
|
23
|
+
# * *sudo_proc* (Proc): Code giving the sudo line for a given user
|
24
|
+
# Parameters::
|
25
|
+
# * *user* (String): User for which we want sudo
|
26
|
+
# Result::
|
27
|
+
# * String: Corresponding sudo string
|
28
|
+
# Array< Hash<Symbol, Object> >
|
29
|
+
attr_reader :sudo_procs
|
30
|
+
|
21
31
|
# Mixin initializer
|
22
32
|
def init_nodes_handler_config
|
23
33
|
@cmdb_masters = []
|
34
|
+
@sudo_procs = []
|
24
35
|
end
|
25
36
|
|
26
37
|
# Set CMDB masters
|
@@ -34,6 +45,17 @@ module HybridPlatformsConductor
|
|
34
45
|
}
|
35
46
|
end
|
36
47
|
|
48
|
+
# Set a sudo proc
|
49
|
+
#
|
50
|
+
# Parameters::
|
51
|
+
# * *sudo_proc* (Proc): The sudo proc (see #sudo_procs doc to know the signature)
|
52
|
+
def sudo_for(&sudo_proc)
|
53
|
+
@sudo_procs << {
|
54
|
+
nodes_selectors_stack: current_nodes_selectors_stack,
|
55
|
+
sudo_proc: sudo_proc
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
37
59
|
end
|
38
60
|
|
39
61
|
Config.extend_config_dsl_with ConfigDSLExtension, :init_nodes_handler_config
|
@@ -568,6 +590,21 @@ module HybridPlatformsConductor
|
|
568
590
|
nodes_selector_stack.inject(known_nodes) { |selected_nodes, nodes_selector| selected_nodes & select_nodes(nodes_selector) }
|
569
591
|
end
|
570
592
|
|
593
|
+
# Get the sudo command for a given user on a given node
|
594
|
+
#
|
595
|
+
# Parameters::
|
596
|
+
# * *node* (String): Node on which we need sudo
|
597
|
+
# * *user* (String): User for which we need sudo [default = 'root']
|
598
|
+
# Result::
|
599
|
+
# * String: The corresponding sudo string
|
600
|
+
def sudo_on(node, user = 'root')
|
601
|
+
sudo = nil
|
602
|
+
select_confs_for_node(node, @config.sudo_procs).each do |sudo_proc_info|
|
603
|
+
sudo = sudo_proc_info[:sudo_proc].call(user)
|
604
|
+
end
|
605
|
+
sudo.nil? ? "sudo -u #{user}" : sudo
|
606
|
+
end
|
607
|
+
|
571
608
|
private
|
572
609
|
|
573
610
|
# Get the CMDB master for a given property.
|
data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb
CHANGED
@@ -92,7 +92,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
92
92
|
with_test_platform_for_remote_testing(
|
93
93
|
expected_cmds: [
|
94
94
|
[
|
95
|
-
/cd \/path\/to && tar\s+--create\s+--gzip\s+--file -\s+src.file \| \/.+\/ssh\s+test_user@hpc\.node\s+"sudo tar\s+--extract\s+--gunzip\s+--file -\s+--directory \/remote_path\/to\/dst.dir\s+--owner root\s+"/,
|
95
|
+
/cd \/path\/to && tar\s+--create\s+--gzip\s+--file -\s+src.file \| \/.+\/ssh\s+test_user@hpc\.node\s+"sudo -u root tar\s+--extract\s+--gunzip\s+--file -\s+--directory \/remote_path\/to\/dst.dir\s+--owner root\s+"/,
|
96
96
|
proc { [0, '', ''] }
|
97
97
|
]
|
98
98
|
]
|
@@ -101,6 +101,20 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
104
|
+
it 'copies files remotely with a different sudo' do
|
105
|
+
with_test_platform_for_remote_testing(
|
106
|
+
expected_cmds: [
|
107
|
+
[
|
108
|
+
/cd \/path\/to && tar\s+--create\s+--gzip\s+--file -\s+src.file \| \/.+\/ssh\s+test_user@hpc\.node\s+"other_sudo --user root tar\s+--extract\s+--gunzip\s+--file -\s+--directory \/remote_path\/to\/dst.dir\s+--owner root\s+"/,
|
109
|
+
proc { [0, '', ''] }
|
110
|
+
]
|
111
|
+
],
|
112
|
+
additional_config: 'sudo_for { |user| "other_sudo --user #{user}" }'
|
113
|
+
) do
|
114
|
+
test_connector.remote_copy('/path/to/src.file', '/remote_path/to/dst.dir', sudo: true)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
104
118
|
it 'copies files remotely with a different owner' do
|
105
119
|
with_test_platform_for_remote_testing(
|
106
120
|
expected_cmds: [
|
@@ -124,4 +124,32 @@ describe HybridPlatformsConductor::NodesHandler do
|
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
127
|
+
it 'computes the correct sudo for different nodes' do
|
128
|
+
with_test_platform(
|
129
|
+
{
|
130
|
+
nodes: {
|
131
|
+
'node1' => {},
|
132
|
+
'node2' => {},
|
133
|
+
'node3' => {}
|
134
|
+
}
|
135
|
+
},
|
136
|
+
false,
|
137
|
+
'
|
138
|
+
for_nodes(%w[node1 node2]) do
|
139
|
+
sudo_for { |user| "alt_sudo1 -p #{user}" }
|
140
|
+
end
|
141
|
+
for_nodes(\'node2\') do
|
142
|
+
sudo_for { |user| "alt_sudo2 -q #{user}" }
|
143
|
+
end
|
144
|
+
'
|
145
|
+
) do
|
146
|
+
expect(test_nodes_handler.sudo_on('node1')).to eq 'alt_sudo1 -p root'
|
147
|
+
expect(test_nodes_handler.sudo_on('node1', 'test_user')).to eq 'alt_sudo1 -p test_user'
|
148
|
+
expect(test_nodes_handler.sudo_on('node2')).to eq 'alt_sudo2 -q root'
|
149
|
+
expect(test_nodes_handler.sudo_on('node2', 'test_user')).to eq 'alt_sudo2 -q test_user'
|
150
|
+
expect(test_nodes_handler.sudo_on('node3')).to eq 'sudo -u root'
|
151
|
+
expect(test_nodes_handler.sudo_on('node3', 'test_user')).to eq 'sudo -u test_user'
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
127
155
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
describe HybridPlatformsConductor::NodesHandler do
|
2
|
+
|
3
|
+
context 'checking config DSL' do
|
4
|
+
|
5
|
+
it 'adds helpers for master cmdbs' do
|
6
|
+
with_test_platform(
|
7
|
+
{
|
8
|
+
nodes: {
|
9
|
+
'node1' => {},
|
10
|
+
'node2' => {},
|
11
|
+
'node3' => {}
|
12
|
+
}
|
13
|
+
},
|
14
|
+
false,
|
15
|
+
'
|
16
|
+
master_cmdbs(
|
17
|
+
test_cmdb: :property1,
|
18
|
+
test_cmdb2: :property2
|
19
|
+
)
|
20
|
+
for_nodes(\'node2\') do
|
21
|
+
master_cmdbs(test_cmdb: :property3)
|
22
|
+
end
|
23
|
+
'
|
24
|
+
) do
|
25
|
+
register_test_cmdb(%i[test_cmdb test_cmdb2])
|
26
|
+
expect(test_config.cmdb_masters).to eq [
|
27
|
+
{
|
28
|
+
nodes_selectors_stack: [],
|
29
|
+
cmdb_masters: {
|
30
|
+
test_cmdb: [:property1],
|
31
|
+
test_cmdb2: [:property2]
|
32
|
+
}
|
33
|
+
},
|
34
|
+
{
|
35
|
+
nodes_selectors_stack: ['node2'],
|
36
|
+
cmdb_masters: {
|
37
|
+
test_cmdb: [:property3]
|
38
|
+
}
|
39
|
+
}
|
40
|
+
]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'adds helpers for configurable sudo' do
|
45
|
+
with_test_platform(
|
46
|
+
{
|
47
|
+
nodes: {
|
48
|
+
'node1' => {},
|
49
|
+
'node2' => {},
|
50
|
+
'node3' => {}
|
51
|
+
}
|
52
|
+
},
|
53
|
+
false,
|
54
|
+
'
|
55
|
+
sudo_for { |user| "alt_sudo1 -p #{user}" }
|
56
|
+
for_nodes(\'node2\') do
|
57
|
+
sudo_for { |user| "alt_sudo2 -q #{user}" }
|
58
|
+
end
|
59
|
+
'
|
60
|
+
) do
|
61
|
+
expect(test_config.sudo_procs.size).to eq 2
|
62
|
+
expect(test_config.sudo_procs[0][:nodes_selectors_stack]). to eq []
|
63
|
+
expect(test_config.sudo_procs[0][:sudo_proc].call('test_user')). to eq 'alt_sudo1 -p test_user'
|
64
|
+
expect(test_config.sudo_procs[1][:nodes_selectors_stack]). to eq ['node2']
|
65
|
+
expect(test_config.sudo_procs[1][:sudo_proc].call('test_user')). to eq 'alt_sudo2 -q test_user'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -94,9 +94,17 @@ module HybridPlatformsConductorTest
|
|
94
94
|
# * *expected_stderr* (String): Expected stderr after client code execution [default: '']
|
95
95
|
# * *timeout* (Integer or nil): Timeout to prepare the connector for [default: nil]
|
96
96
|
# * *password* (String or nil): Password to set for the node, or nil for none [default: nil]
|
97
|
+
# * *additional_config* (String): Additional config [default: '']
|
97
98
|
# * Proc: Client code to execute testing
|
98
|
-
def with_test_platform_for_remote_testing(
|
99
|
-
|
99
|
+
def with_test_platform_for_remote_testing(
|
100
|
+
expected_cmds: [],
|
101
|
+
expected_stdout: '',
|
102
|
+
expected_stderr: '',
|
103
|
+
timeout: nil,
|
104
|
+
password: nil,
|
105
|
+
additional_config: ''
|
106
|
+
)
|
107
|
+
with_test_platform({ nodes: { 'node' => { meta: { host_ip: '192.168.42.42' } } } }, false, additional_config) do
|
100
108
|
with_cmd_runner_mocked(
|
101
109
|
[
|
102
110
|
['which env', proc { [0, "/usr/bin/env\n", ''] }],
|
@@ -9,12 +9,12 @@ module HybridPlatformsConductorTest
|
|
9
9
|
# Parameters::
|
10
10
|
# * *action* (Hash<Symbol,Object>): The action to check
|
11
11
|
# * *node* (String): The concerned node
|
12
|
-
# * *sudo* (
|
13
|
-
def expect_action_to_lock_node(action, node, sudo:
|
12
|
+
# * *sudo* (String or nil): sudo supposed to be used, or nil if none [default: 'sudo -u root']
|
13
|
+
def expect_action_to_lock_node(action, node, sudo: 'sudo -u root')
|
14
14
|
expect(action[:scp].size).to eq 1
|
15
15
|
expect(action[:scp].first[0]).to match /^.+\/mutex_dir$/
|
16
16
|
expect(action[:scp].first[1]).to eq '.'
|
17
|
-
expect(action[:remote_bash]).to eq "while ! #{sudo ?
|
17
|
+
expect(action[:remote_bash]).to eq "while ! #{sudo ? "#{sudo} " : ''}./mutex_dir lock /tmp/hybrid_platforms_conductor_deploy_lock \"$(ps -o ppid= -p $$)\"; do echo -e 'Another deployment is running on #{node}. Waiting for it to finish to continue...' ; sleep 5 ; done"
|
18
18
|
end
|
19
19
|
|
20
20
|
# Expect a given action to be releasing the mutex on a given node
|
@@ -22,9 +22,9 @@ module HybridPlatformsConductorTest
|
|
22
22
|
# Parameters::
|
23
23
|
# * *action* (Hash<Symbol,Object>): The action to check
|
24
24
|
# * *node* (String): The concerned node
|
25
|
-
# * *sudo* (
|
26
|
-
def expect_action_to_unlock_node(action, node, sudo:
|
27
|
-
expect(action).to eq(remote_bash: "#{sudo ?
|
25
|
+
# * *sudo* (String or nil): sudo supposed to be used, or nil if none [default: 'sudo -u root']
|
26
|
+
def expect_action_to_unlock_node(action, node, sudo: 'sudo -u root')
|
27
|
+
expect(action).to eq(remote_bash: "#{sudo ? "#{sudo} " : ''}./mutex_dir unlock /tmp/hybrid_platforms_conductor_deploy_lock")
|
28
28
|
end
|
29
29
|
|
30
30
|
# Expect a given set of actions to be a deployment
|
@@ -33,12 +33,12 @@ module HybridPlatformsConductorTest
|
|
33
33
|
# * *actions* (Object): Actions
|
34
34
|
# * *nodes* (String or Array<String>): Node (or list of nodes) that should be checked
|
35
35
|
# * *check* (Boolean): Is the deploy only a check? [default: false]
|
36
|
-
# * *sudo* (
|
36
|
+
# * *sudo* (String or nil): sudo supposed to be used, or nil if none [default: 'sudo -u root']
|
37
37
|
# * *expected_actions* (Array<Object>): Additional expected actions [default: []]
|
38
38
|
# * *mocked_result* (Hash<String, [Object, String, String]>): Expected result of the actions, per node, or nil for success [default: nil]
|
39
39
|
# Result::
|
40
40
|
# * Hash<String, [Integer or Symbol, String, String] >: Expected result of those expected actions
|
41
|
-
def expect_actions_to_deploy_on(actions, nodes, check: false, sudo:
|
41
|
+
def expect_actions_to_deploy_on(actions, nodes, check: false, sudo: 'sudo -u root', expected_actions: [], mocked_result: nil)
|
42
42
|
nodes = [nodes] if nodes.is_a?(String)
|
43
43
|
mocked_result = Hash[nodes.map { |node| [node, [0, "#{check ? 'Check' : 'Deploy'} successful", '']] }] if mocked_result.nil?
|
44
44
|
expect(actions.size).to eq nodes.size
|
@@ -57,8 +57,8 @@ module HybridPlatformsConductorTest
|
|
57
57
|
# Parameters::
|
58
58
|
# * *actions* (Object): Actions
|
59
59
|
# * *nodes* (String or Array<String>): Node (or list of nodes) that should be checked
|
60
|
-
# * *sudo* (
|
61
|
-
def expect_actions_to_unlock(actions, nodes, sudo:
|
60
|
+
# * *sudo* (String or nil): sudo supposed to be used, or nil if none [default: 'sudo -u root']
|
61
|
+
def expect_actions_to_unlock(actions, nodes, sudo: 'sudo -u root')
|
62
62
|
nodes = [nodes] if nodes.is_a?(String)
|
63
63
|
expect(actions.size).to eq nodes.size
|
64
64
|
nodes.each do |node|
|
@@ -73,17 +73,17 @@ module HybridPlatformsConductorTest
|
|
73
73
|
# Parameters::
|
74
74
|
# * *actions* (Object): Actions
|
75
75
|
# * *nodes* (String or Array<String>): Node (or list of nodes) that should be checked
|
76
|
-
# * *sudo* (
|
77
|
-
def expect_actions_to_upload_logs(actions, nodes, sudo:
|
76
|
+
# * *sudo* (String or nil): sudo supposed to be used, or nil if none [default: 'sudo -u root']
|
77
|
+
def expect_actions_to_upload_logs(actions, nodes, sudo: 'sudo -u root')
|
78
78
|
nodes = [nodes] if nodes.is_a?(String)
|
79
79
|
expect(actions.size).to eq nodes.size
|
80
80
|
nodes.each do |node|
|
81
81
|
expect(actions.key?(node)).to eq true
|
82
|
-
expect(actions[node][:remote_bash]).to eq "#{sudo ?
|
82
|
+
expect(actions[node][:remote_bash]).to eq "#{sudo ? "#{sudo} " : ''}mkdir -p /var/log/deployments"
|
83
83
|
expect(actions[node][:scp].first[1]).to eq '/var/log/deployments'
|
84
84
|
expect(actions[node][:scp][:group]).to eq 'root'
|
85
85
|
expect(actions[node][:scp][:owner]).to eq 'root'
|
86
|
-
expect(actions[node][:scp][:sudo]).to eq sudo
|
86
|
+
expect(actions[node][:scp][:sudo]).to eq (!sudo.nil?)
|
87
87
|
end
|
88
88
|
Hash[nodes.map { |node| [node, [0, 'Logs uploaded', '']] }]
|
89
89
|
end
|
@@ -20,7 +20,7 @@ module HybridPlatformsConductorTest
|
|
20
20
|
#
|
21
21
|
# Parameters::
|
22
22
|
# * *services* (Hash<String, Array<String> >): Expected nodes that should be deployed, with their corresponding services [default: { 'node' => %w[service] }]
|
23
|
-
# * *sudo* (
|
23
|
+
# * *sudo* (String or nil): sudo supposed to be used, or nil if none [default: 'sudo -u root']
|
24
24
|
# * *check_mode* (Boolean): Are we testing in check mode? [default: @check_mode]
|
25
25
|
# * *mocked_deploy_result* (Hash or nil): Mocked result of the deployment actions, or nil to use the helper's default [default: nil]
|
26
26
|
# * *additional_expected_actions* (Array): Additional expected actions [default: []]
|
@@ -28,7 +28,7 @@ module HybridPlatformsConductorTest
|
|
28
28
|
# * *expect_actions_timeout* (Integer or nil): Expected timeout in actions, or nil for none [default: nil]
|
29
29
|
def expected_actions_for_deploy_on(
|
30
30
|
services: { 'node' => %w[service] },
|
31
|
-
sudo:
|
31
|
+
sudo: 'sudo -u root',
|
32
32
|
check_mode: @check_mode,
|
33
33
|
mocked_deploy_result: nil,
|
34
34
|
additional_expected_actions: [],
|
@@ -82,7 +82,7 @@ module HybridPlatformsConductorTest
|
|
82
82
|
# * *expect_prepare_for_deploy* (Boolean): Should we expect calls to prepare for deploy? [default: true]
|
83
83
|
# * *expect_connections_to_nodes* (Boolean): Should we expect connections to nodes? [default: true]
|
84
84
|
# * *expect_default_actions* (Boolean): Should we expect default actions? [default: true]
|
85
|
-
# * *expect_sudo* (
|
85
|
+
# * *expect_sudo* (String or nil): Expected sudo command, or nil if none [default: 'sudo -u root']
|
86
86
|
# * *expect_secrets* (Hash): Secrets to be expected during deployment [default: {}]
|
87
87
|
# * *expect_local_environment* (Boolean): Expected local environment flag [default: false]
|
88
88
|
# * *expect_additional_actions* (Array): Additional expected actions [default: []]
|
@@ -99,7 +99,7 @@ module HybridPlatformsConductorTest
|
|
99
99
|
expect_prepare_for_deploy: true,
|
100
100
|
expect_connections_to_nodes: true,
|
101
101
|
expect_default_actions: true,
|
102
|
-
expect_sudo:
|
102
|
+
expect_sudo: 'sudo -u root',
|
103
103
|
expect_secrets: {},
|
104
104
|
expect_local_environment: false,
|
105
105
|
expect_additional_actions: [],
|
@@ -201,12 +201,21 @@ module HybridPlatformsConductorTest
|
|
201
201
|
end
|
202
202
|
|
203
203
|
it 'deploys on 1 node using root' do
|
204
|
-
with_platform_to_deploy(expect_sudo:
|
204
|
+
with_platform_to_deploy(expect_sudo: nil) do
|
205
205
|
test_actions_executor.connector(:ssh).ssh_user = 'root'
|
206
206
|
expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
|
207
207
|
end
|
208
208
|
end
|
209
209
|
|
210
|
+
it 'deploys on 1 node using an alternate sudo' do
|
211
|
+
with_platform_to_deploy(
|
212
|
+
expect_sudo: 'other_sudo --user root',
|
213
|
+
additional_config: 'sudo_for { |user| "other_sudo --user #{user}" }'
|
214
|
+
) do
|
215
|
+
expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
210
219
|
it 'deploys on 1 node using 1 secret' do
|
211
220
|
with_platform_to_deploy(expect_secrets: { 'secret1' => 'password1' }) do
|
212
221
|
test_deployer.secrets = [{ 'secret1' => 'password1' }]
|
@@ -227,9 +236,9 @@ module HybridPlatformsConductorTest
|
|
227
236
|
nodes_info: { nodes: { 'node' => { meta: { image: 'debian_9' }, services: %w[service] } } },
|
228
237
|
expect_local_environment: true,
|
229
238
|
expect_additional_actions: [
|
230
|
-
{ remote_bash: 'sudo apt update && sudo apt install -y ca-certificates' },
|
239
|
+
{ remote_bash: 'sudo -u root apt update && sudo -u root apt install -y ca-certificates' },
|
231
240
|
{
|
232
|
-
remote_bash: 'sudo update-ca-certificates',
|
241
|
+
remote_bash: 'sudo -u root update-ca-certificates',
|
233
242
|
scp: {
|
234
243
|
certs_dir => '/usr/local/share/ca-certificates',
|
235
244
|
:sudo => true
|
@@ -244,6 +253,31 @@ module HybridPlatformsConductorTest
|
|
244
253
|
end
|
245
254
|
end
|
246
255
|
|
256
|
+
it 'deploys on 1 node in local environment with certificates to install using hpc_certificates on Debian and an alternate sudo' do
|
257
|
+
with_certs_dir do |certs_dir|
|
258
|
+
with_platform_to_deploy(
|
259
|
+
nodes_info: { nodes: { 'node' => { meta: { image: 'debian_9' }, services: %w[service] } } },
|
260
|
+
expect_sudo: 'other_sudo --user root',
|
261
|
+
expect_local_environment: true,
|
262
|
+
expect_additional_actions: [
|
263
|
+
{ remote_bash: 'other_sudo --user root apt update && other_sudo --user root apt install -y ca-certificates' },
|
264
|
+
{
|
265
|
+
remote_bash: 'other_sudo --user root update-ca-certificates',
|
266
|
+
scp: {
|
267
|
+
certs_dir => '/usr/local/share/ca-certificates',
|
268
|
+
:sudo => true
|
269
|
+
}
|
270
|
+
}
|
271
|
+
],
|
272
|
+
additional_config: 'sudo_for { |user| "other_sudo --user #{user}" }'
|
273
|
+
) do
|
274
|
+
ENV['hpc_certificates'] = certs_dir
|
275
|
+
test_deployer.local_environment = true
|
276
|
+
expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
247
281
|
it 'deploys on 1 node with certificates to install using hpc_certificates on Debian but ignores them in non-local environment' do
|
248
282
|
with_certs_dir do |certs_dir|
|
249
283
|
with_platform_to_deploy(nodes_info: { nodes: { 'node' => { meta: { image: 'debian_9' }, services: %w[service] } } }) do
|
@@ -257,7 +291,7 @@ module HybridPlatformsConductorTest
|
|
257
291
|
with_certs_dir do |certs_dir|
|
258
292
|
with_platform_to_deploy(
|
259
293
|
nodes_info: { nodes: { 'node' => { meta: { image: 'debian_9' }, services: %w[service] } } },
|
260
|
-
expect_sudo:
|
294
|
+
expect_sudo: nil,
|
261
295
|
expect_local_environment: true,
|
262
296
|
expect_additional_actions: [
|
263
297
|
{ remote_bash: 'apt update && apt install -y ca-certificates' },
|
@@ -284,9 +318,9 @@ module HybridPlatformsConductorTest
|
|
284
318
|
nodes_info: { nodes: { 'node' => { meta: { image: 'centos_7' }, services: %w[service] } } },
|
285
319
|
expect_local_environment: true,
|
286
320
|
expect_additional_actions: [
|
287
|
-
{ remote_bash: 'sudo yum install -y ca-certificates' },
|
321
|
+
{ remote_bash: 'sudo -u root yum install -y ca-certificates' },
|
288
322
|
{
|
289
|
-
remote_bash: ['sudo update-ca-trust enable', 'sudo update-ca-trust extract'],
|
323
|
+
remote_bash: ['sudo -u root update-ca-trust enable', 'sudo -u root update-ca-trust extract'],
|
290
324
|
scp: {
|
291
325
|
"#{certs_dir}/test_cert.crt" => '/etc/pki/ca-trust/source/anchors',
|
292
326
|
:sudo => true
|
@@ -301,11 +335,36 @@ module HybridPlatformsConductorTest
|
|
301
335
|
end
|
302
336
|
end
|
303
337
|
|
338
|
+
it 'deploys on 1 node with certificates to install using hpc_certificates on CentOS and an alternate sudo' do
|
339
|
+
with_certs_dir do |certs_dir|
|
340
|
+
with_platform_to_deploy(
|
341
|
+
nodes_info: { nodes: { 'node' => { meta: { image: 'centos_7' }, services: %w[service] } } },
|
342
|
+
expect_sudo: 'other_sudo --user root',
|
343
|
+
expect_local_environment: true,
|
344
|
+
expect_additional_actions: [
|
345
|
+
{ remote_bash: 'other_sudo --user root yum install -y ca-certificates' },
|
346
|
+
{
|
347
|
+
remote_bash: ['other_sudo --user root update-ca-trust enable', 'other_sudo --user root update-ca-trust extract'],
|
348
|
+
scp: {
|
349
|
+
"#{certs_dir}/test_cert.crt" => '/etc/pki/ca-trust/source/anchors',
|
350
|
+
:sudo => true
|
351
|
+
}
|
352
|
+
}
|
353
|
+
],
|
354
|
+
additional_config: 'sudo_for { |user| "other_sudo --user #{user}" }'
|
355
|
+
) do
|
356
|
+
ENV['hpc_certificates'] = certs_dir
|
357
|
+
test_deployer.local_environment = true
|
358
|
+
expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
304
363
|
it 'deploys on 1 node with certificates to install using hpc_certificates on CentOS using root' do
|
305
364
|
with_certs_dir do |certs_dir|
|
306
365
|
with_platform_to_deploy(
|
307
366
|
nodes_info: { nodes: { 'node' => { meta: { image: 'centos_7' }, services: %w[service] } } },
|
308
|
-
expect_sudo:
|
367
|
+
expect_sudo: nil,
|
309
368
|
expect_local_environment: true,
|
310
369
|
expect_additional_actions: [
|
311
370
|
{ remote_bash: 'yum install -y ca-certificates' },
|
@@ -330,7 +330,7 @@ module HybridPlatformsConductorTest
|
|
330
330
|
expect(actions).to eq({
|
331
331
|
'node' => {
|
332
332
|
remote_bash: {
|
333
|
-
commands: "#{expected_sudo ? 'sudo -E ' : ''}./proxmox/reserve_proxmox_container --create ./proxmox/create/create_#{expected_file_id}.json --config ./proxmox/config/config_#{expected_file_id}.json",
|
333
|
+
commands: "#{expected_sudo ? 'sudo -u root -E ' : ''}./proxmox/reserve_proxmox_container --create ./proxmox/create/create_#{expected_file_id}.json --config ./proxmox/config/config_#{expected_file_id}.json",
|
334
334
|
env: {
|
335
335
|
'hpc_user_for_proxmox' => proxmox_user,
|
336
336
|
'hpc_password_for_proxmox' => proxmox_password,
|
@@ -382,7 +382,7 @@ module HybridPlatformsConductorTest
|
|
382
382
|
expect(actions).to eq({
|
383
383
|
'node' => {
|
384
384
|
remote_bash: {
|
385
|
-
commands: "#{expected_sudo ? 'sudo -E ' : ''}./proxmox/reserve_proxmox_container --destroy ./proxmox/destroy/destroy_#{expected_file_id}.json --config ./proxmox/config/config_#{expected_file_id}.json",
|
385
|
+
commands: "#{expected_sudo ? 'sudo -u root -E ' : ''}./proxmox/reserve_proxmox_container --destroy ./proxmox/destroy/destroy_#{expected_file_id}.json --config ./proxmox/config/config_#{expected_file_id}.json",
|
386
386
|
env: {
|
387
387
|
'hpc_user_for_proxmox' => proxmox_user,
|
388
388
|
'hpc_password_for_proxmox' => proxmox_password,
|
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.
|
4
|
+
version: 32.5.0
|
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-03-
|
11
|
+
date: 2021-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: range_operators
|
@@ -463,6 +463,7 @@ files:
|
|
463
463
|
- spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs/platform_handlers_spec.rb
|
464
464
|
- spec/hybrid_platforms_conductor_test/api/nodes_handler/cmdbs_plugins_api_spec.rb
|
465
465
|
- spec/hybrid_platforms_conductor_test/api/nodes_handler/common_spec.rb
|
466
|
+
- spec/hybrid_platforms_conductor_test/api/nodes_handler/config_spec.rb
|
466
467
|
- spec/hybrid_platforms_conductor_test/api/nodes_handler/git_diff_impacts_spec.rb
|
467
468
|
- spec/hybrid_platforms_conductor_test/api/nodes_handler/nodes_selectors_spec.rb
|
468
469
|
- spec/hybrid_platforms_conductor_test/api/nodes_handler/platform_handlers_plugins_api_spec.rb
|