foreman_remote_execution 1.8.4 → 2.0.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/.rubocop.yml +2 -0
- data/app/assets/stylesheets/foreman_remote_execution/job_invocations.css.scss +23 -0
- data/app/controllers/api/v2/job_templates_controller.rb +1 -0
- data/app/helpers/remote_execution_helper.rb +10 -10
- data/app/lib/actions/remote_execution/run_host_job.rb +9 -5
- data/app/models/concerns/foreman_remote_execution/host_extensions.rb +1 -1
- data/app/models/job_template.rb +2 -2
- data/app/models/remote_execution_provider.rb +4 -0
- data/app/models/setting/remote_execution.rb +65 -74
- data/app/models/ssh_execution_provider.rb +8 -1
- data/app/views/api/v2/job_templates/main.json.rabl +1 -1
- data/config/routes.rb +6 -10
- data/db/seeds.d/70-job_templates.rb +2 -2
- data/lib/foreman_remote_execution/engine.rb +1 -1
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/package.json +2 -2
- data/test/factories/foreman_remote_execution_factories.rb +2 -2
- data/test/unit/actions/run_host_job_test.rb +35 -4
- data/test/unit/concerns/host_extensions_test.rb +0 -6
- data/test/unit/remote_execution_provider_test.rb +3 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 766047d4727a67b60506ac42744f41cf0f70782e5b0a7d6bc2d0f44d2529fd44
|
4
|
+
data.tar.gz: bb9469b1b90526a88b596b5fb4b7f6e96210bd33d4050123bfca218b691527f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cecd364c6bc6147a10dd6c9d5414e6d7e069caad3eab0b5fdec6633ced750c30cbf5787797ee84397fda682665d4dad964302fc1adfce9deb871504f10638b3f
|
7
|
+
data.tar.gz: 95bd2381ac1b1e4ecb1854536474939d4c21724a9db7859d4efe223386510fbda7704450b7e3c3c8e90a1ee77bdf54022c57b3e7dd56307c5969178ec5f54636
|
data/.rubocop.yml
CHANGED
@@ -6,3 +6,26 @@ div.infoblock {
|
|
6
6
|
margin-top: 5px;
|
7
7
|
}
|
8
8
|
}
|
9
|
+
|
10
|
+
#title_action {
|
11
|
+
.button_to {
|
12
|
+
display: inline-block;
|
13
|
+
}
|
14
|
+
|
15
|
+
.btn-toolbar {
|
16
|
+
.button_to {
|
17
|
+
float: left;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
.btn-group {
|
22
|
+
.btn + .button_to,
|
23
|
+
.button_to + .button_to {
|
24
|
+
margin-left: -1px;
|
25
|
+
}
|
26
|
+
|
27
|
+
.button_to:not(:first-child):not(:last-child) .btn {
|
28
|
+
border-radius: 0;
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
@@ -47,6 +47,7 @@ module Api
|
|
47
47
|
def_param_group :job_template do
|
48
48
|
param :job_template, Hash, :required => true, :action_aware => true do
|
49
49
|
param :name, String, :required => true, :desc => N_('Template name')
|
50
|
+
param :description, String
|
50
51
|
param :job_category, String, :required => true, :desc => N_('Job category')
|
51
52
|
param :description_format, String, :required => false, :desc => N_('This template is used to generate the description. ' +
|
52
53
|
'Input values can be used using the syntax %{package}. ' +
|
@@ -83,16 +83,16 @@ module RemoteExecutionHelper
|
|
83
83
|
:title => _('See the last task details'))
|
84
84
|
end
|
85
85
|
if authorized_for(:permission => :cancel_job_invocations, :auth_object => job_invocation)
|
86
|
-
buttons <<
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
buttons <<
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
86
|
+
buttons << button_to(_('Cancel Job'), cancel_job_invocation_path(job_invocation),
|
87
|
+
:class => 'btn btn-danger',
|
88
|
+
:title => _('Try to cancel the job'),
|
89
|
+
:disabled => !task.cancellable?,
|
90
|
+
:method => :post)
|
91
|
+
buttons << button_to(_('Abort Job'), cancel_job_invocation_path(job_invocation, :force => true),
|
92
|
+
:class => 'btn btn-danger',
|
93
|
+
:title => _('Try to abort the job without waiting for the results from the remote hosts'),
|
94
|
+
:disabled => !task.cancellable?,
|
95
|
+
:method => :post)
|
96
96
|
end
|
97
97
|
return buttons
|
98
98
|
end
|
@@ -38,14 +38,10 @@ module Actions
|
|
38
38
|
|
39
39
|
provider = template_invocation.template.provider
|
40
40
|
|
41
|
-
secrets = { :ssh_password => job_invocation.password || provider.ssh_password(host),
|
42
|
-
:key_passphrase => job_invocation.key_passphrase || provider.ssh_key_passphrase(host),
|
43
|
-
:sudo_password => job_invocation.sudo_password || provider.sudo_password(host) }
|
44
|
-
|
45
41
|
additional_options = { :hostname => provider.find_ip_or_hostname(host),
|
46
42
|
:script => script,
|
47
43
|
:execution_timeout_interval => job_invocation.execution_timeout_interval,
|
48
|
-
:secrets => secrets,
|
44
|
+
:secrets => secrets(host, job_invocation, provider),
|
49
45
|
:use_batch_triggering => true}
|
50
46
|
action_options = provider.proxy_command_options(template_invocation, host)
|
51
47
|
.merge(additional_options)
|
@@ -59,6 +55,14 @@ module Actions
|
|
59
55
|
check_exit_status
|
60
56
|
end
|
61
57
|
|
58
|
+
def secrets(host, job_invocation, provider)
|
59
|
+
job_secrets = { :ssh_password => job_invocation.password,
|
60
|
+
:key_passphrase => job_invocation.key_passphrase,
|
61
|
+
:sudo_password => job_invocation.sudo_password }
|
62
|
+
|
63
|
+
job_secrets.merge(provider.secrets(host)) { |_key, job_secret, provider_secret| job_secret || provider_secret }
|
64
|
+
end
|
65
|
+
|
62
66
|
def check_exit_status
|
63
67
|
error! ForemanTasks::Task::TaskCancelledException.new(_('Task cancelled')) if delegated_action && delegated_action.output[:cancel_sent]
|
64
68
|
error! _('Job execution failed') if exit_status.to_s != '0'
|
@@ -71,7 +71,7 @@ module ForemanRemoteExecution
|
|
71
71
|
proxies[:fallback] = smart_proxies.with_features(provider) if Setting[:remote_execution_fallback_proxy]
|
72
72
|
|
73
73
|
if Setting[:remote_execution_global_proxy]
|
74
|
-
proxy_scope = if
|
74
|
+
proxy_scope = if User.current.present?
|
75
75
|
::SmartProxy.with_taxonomy_scope_override(location, organization)
|
76
76
|
else
|
77
77
|
::SmartProxy.unscoped
|
data/app/models/job_template.rb
CHANGED
@@ -119,8 +119,8 @@ class JobTemplate < ::Template
|
|
119
119
|
|
120
120
|
def assign_taxonomies
|
121
121
|
if default
|
122
|
-
organizations << Organization.all
|
123
|
-
locations << Location.all
|
122
|
+
organizations << Organization.all
|
123
|
+
locations << Location.all
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
@@ -3,80 +3,71 @@ class Setting::RemoteExecution < Setting
|
|
3
3
|
::Setting::BLANK_ATTRS.concat %w{remote_execution_ssh_password remote_execution_ssh_key_passphrase remote_execution_sudo_password remote_execution_cockpit_url}
|
4
4
|
|
5
5
|
# rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
6
|
-
def self.
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
self.set('remote_execution_cockpit_url',
|
72
|
-
N_('Where to find the Cockpit instance for the Web Console button. By default, no button is shown.'),
|
73
|
-
nil,
|
74
|
-
N_('Cockpit URL'),
|
75
|
-
nil)
|
76
|
-
].each { |s| self.create! s.update(:category => 'Setting::RemoteExecution') }
|
77
|
-
end
|
78
|
-
|
79
|
-
true
|
6
|
+
def self.default_settings
|
7
|
+
[
|
8
|
+
self.set('remote_execution_fallback_proxy',
|
9
|
+
N_('Search the host for any proxy with Remote Execution, useful when the host has no subnet or the subnet does not have an execution proxy'),
|
10
|
+
false,
|
11
|
+
N_('Fallback to Any Proxy')),
|
12
|
+
self.set('remote_execution_global_proxy',
|
13
|
+
N_('Search for remote execution proxy outside of the proxies assigned to the host. ' +
|
14
|
+
"The search will be limited to the host's organization and location."),
|
15
|
+
true,
|
16
|
+
N_('Enable Global Proxy')),
|
17
|
+
self.set('remote_execution_ssh_user',
|
18
|
+
N_('Default user to use for SSH. You may override per host by setting a parameter called remote_execution_ssh_user.'),
|
19
|
+
'root',
|
20
|
+
N_('SSH User')),
|
21
|
+
self.set('remote_execution_effective_user',
|
22
|
+
N_('Default user to use for executing the script. If the user differs from the SSH user, su or sudo is used to switch the user.'),
|
23
|
+
'root',
|
24
|
+
N_('Effective User')),
|
25
|
+
self.set('remote_execution_effective_user_method',
|
26
|
+
N_('What command should be used to switch to the effective user. One of %s') % SSHExecutionProvider::EFFECTIVE_USER_METHODS.inspect,
|
27
|
+
'sudo',
|
28
|
+
N_('Effective User Method'),
|
29
|
+
nil,
|
30
|
+
{ :collection => proc { Hash[SSHExecutionProvider::EFFECTIVE_USER_METHODS.map { |method| [method, method] }] } }),
|
31
|
+
self.set('remote_execution_sudo_password', N_("Sudo password"), '', N_("Sudo password"), nil, {:encrypted => true}),
|
32
|
+
self.set('remote_execution_sync_templates',
|
33
|
+
N_('Whether we should sync templates from disk when running db:seed.'),
|
34
|
+
true,
|
35
|
+
N_('Sync Job Templates')),
|
36
|
+
self.set('remote_execution_ssh_port',
|
37
|
+
N_('Port to use for SSH communication. Default port 22. You may override per host by setting a parameter called remote_execution_ssh_port.'),
|
38
|
+
'22',
|
39
|
+
N_('SSH Port')),
|
40
|
+
self.set('remote_execution_connect_by_ip',
|
41
|
+
N_('Should the ip addresses on host interfaces be preferred over the fqdn? '\
|
42
|
+
'It is useful, when DNS not resolving the fqdns properly. You may override this per host by setting a parameter called remote_execution_connect_by_ip.'),
|
43
|
+
false,
|
44
|
+
N_('Connect by IP')),
|
45
|
+
self.set('remote_execution_ssh_password',
|
46
|
+
N_('Default password to use for SSH. You may override per host by setting a parameter called remote_execution_ssh_password'),
|
47
|
+
nil,
|
48
|
+
N_('Default SSH password'),
|
49
|
+
nil,
|
50
|
+
{ :encrypted => true }),
|
51
|
+
self.set('remote_execution_ssh_key_passphrase',
|
52
|
+
N_('Default key passphrase to use for SSH. You may override per host by setting a parameter called remote_execution_ssh_key_passphrase'),
|
53
|
+
nil,
|
54
|
+
N_('Default SSH key passphrase'),
|
55
|
+
nil,
|
56
|
+
{ :encrypted => true }),
|
57
|
+
self.set('remote_execution_workers_pool_size',
|
58
|
+
N_('Amount of workers in the pool to handle the execution of the remote execution jobs. Restart of the dynflowd/foreman-tasks service is required.'),
|
59
|
+
5,
|
60
|
+
N_('Workers pool size')),
|
61
|
+
self.set('remote_execution_cleanup_working_dirs',
|
62
|
+
N_('When enabled, working directories will be removed after task completion. You may override this per host by setting a parameter called remote_execution_cleanup_working_dirs.'),
|
63
|
+
true,
|
64
|
+
N_('Cleanup working directories')),
|
65
|
+
self.set('remote_execution_cockpit_url',
|
66
|
+
N_('Where to find the Cockpit instance for the Web Console button. By default, no button is shown.'),
|
67
|
+
nil,
|
68
|
+
N_('Cockpit URL'),
|
69
|
+
nil)
|
70
|
+
]
|
80
71
|
end
|
81
72
|
# rubocop:enable AbcSize
|
82
73
|
# rubocop:enable Metrics/MethodLength,Metrics/AbcSize
|
@@ -5,7 +5,6 @@ class SSHExecutionProvider < RemoteExecutionProvider
|
|
5
5
|
:effective_user => effective_user(template_invocation),
|
6
6
|
:effective_user_method => effective_user_method(host),
|
7
7
|
:cleanup_working_dirs => cleanup_working_dirs?(host),
|
8
|
-
:sudo_password => sudo_password(host),
|
9
8
|
:ssh_port => ssh_port(host))
|
10
9
|
end
|
11
10
|
|
@@ -29,6 +28,14 @@ class SSHExecutionProvider < RemoteExecutionProvider
|
|
29
28
|
'ssh'
|
30
29
|
end
|
31
30
|
|
31
|
+
def secrets(host)
|
32
|
+
{
|
33
|
+
:ssh_password => ssh_password(host),
|
34
|
+
:key_passphrase => ssh_key_passphrase(host),
|
35
|
+
:sudo_password => sudo_password(host)
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
32
39
|
def ssh_params(host)
|
33
40
|
proxy_selector = ::RemoteExecutionProxySelector.new
|
34
41
|
proxy = proxy_selector.determine_proxy(host, 'SSH')
|
@@ -2,7 +2,7 @@ object @job_template
|
|
2
2
|
|
3
3
|
extends 'api/v2/job_templates/base'
|
4
4
|
|
5
|
-
attributes :audit_comment, :description_format, :created_at, :updated_at, :template, :locked
|
5
|
+
attributes :description, :audit_comment, :description_format, :created_at, :updated_at, :template, :locked
|
6
6
|
|
7
7
|
child :template_inputs do
|
8
8
|
extends 'api/v2/template_inputs/base'
|
data/config/routes.rb
CHANGED
@@ -58,8 +58,8 @@ Rails.application.routes.draw do
|
|
58
58
|
end
|
59
59
|
|
60
60
|
resources :job_templates, :except => [:new, :edit] do
|
61
|
-
|
62
|
-
|
61
|
+
resources :locations, :only => [:index, :show]
|
62
|
+
resources :organizations, :only => [:index, :show]
|
63
63
|
get :export, :on => :member
|
64
64
|
post :clone, :on => :member
|
65
65
|
collection do
|
@@ -68,16 +68,12 @@ Rails.application.routes.draw do
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
|
72
|
-
resources :
|
73
|
-
resources :job_templates, :only => [:index, :show]
|
74
|
-
end
|
71
|
+
resources :organizations, :only => [:index] do
|
72
|
+
resources :job_templates, :only => [:index, :show]
|
75
73
|
end
|
76
74
|
|
77
|
-
|
78
|
-
resources :
|
79
|
-
resources :job_templates, :only => [:index, :show]
|
80
|
-
end
|
75
|
+
resources :locations, :only => [:index] do
|
76
|
+
resources :job_templates, :only => [:index, :show]
|
81
77
|
end
|
82
78
|
|
83
79
|
resources :templates, :only => :none do
|
@@ -5,8 +5,8 @@ User.as_anonymous_admin do
|
|
5
5
|
Dir[File.join("#{ForemanRemoteExecution::Engine.root}/app/views/templates/**/*.erb")].each do |template|
|
6
6
|
sync = !Rails.env.test? && Setting[:remote_execution_sync_templates]
|
7
7
|
template = JobTemplate.import_raw!(File.read(template), :default => true, :locked => true, :update => sync)
|
8
|
-
template.organizations = organizations if
|
9
|
-
template.locations = locations if
|
8
|
+
template.organizations = organizations if template.present?
|
9
|
+
template.locations = locations if template.present?
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -34,7 +34,7 @@ module ForemanRemoteExecution
|
|
34
34
|
|
35
35
|
initializer 'foreman_remote_execution.register_plugin', before: :finisher_hook do |_app|
|
36
36
|
Foreman::Plugin.register :foreman_remote_execution do
|
37
|
-
requires_foreman '>= 1.
|
37
|
+
requires_foreman '>= 1.24'
|
38
38
|
|
39
39
|
apipie_documented_controllers ["#{ForemanRemoteExecution::Engine.root}/app/controllers/api/v2/*.rb"]
|
40
40
|
|
data/package.json
CHANGED
@@ -31,7 +31,7 @@
|
|
31
31
|
"url": "http://projects.theforeman.org/projects/foreman_remote_execution/issues"
|
32
32
|
},
|
33
33
|
"devDependencies": {
|
34
|
-
"@theforeman/vendor-dev": "^
|
34
|
+
"@theforeman/vendor-dev": "^1.4.0",
|
35
35
|
"babel-eslint": "^8.2.1",
|
36
36
|
"babel-plugin-lodash": "^3.3.2",
|
37
37
|
"babel-plugin-transform-class-properties": "^6.24.1",
|
@@ -51,6 +51,6 @@
|
|
51
51
|
"jest": "^21.2.1"
|
52
52
|
},
|
53
53
|
"dependencies": {
|
54
|
-
"@theforeman/vendor": "^
|
54
|
+
"@theforeman/vendor": "^1.4.0"
|
55
55
|
}
|
56
56
|
}
|
@@ -4,8 +4,8 @@ FactoryBot.define do
|
|
4
4
|
sequence(:job_category) { |n| "Job name #{n}" }
|
5
5
|
template { 'id' }
|
6
6
|
provider_type { 'SSH' }
|
7
|
-
organizations { [Organization.find_by(name: 'Organization 1')] }
|
8
|
-
locations { [Location.find_by(name: 'Location 1')] }
|
7
|
+
organizations { [Organization.find_by(name: 'Organization 1')] }
|
8
|
+
locations { [Location.find_by(name: 'Location 1')] }
|
9
9
|
|
10
10
|
trait :with_input do
|
11
11
|
after(:build) do |template, evaluator|
|
@@ -5,14 +5,45 @@ module ForemanRemoteExecution
|
|
5
5
|
include Dynflow::Testing
|
6
6
|
|
7
7
|
subject { create_action(Actions::RemoteExecution::RunHostJob) }
|
8
|
-
let(:host) { FactoryBot.create(:host, :with_execution) }
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
describe '#secrets' do
|
10
|
+
let(:job_invocation) { FactoryBot.create(:job_invocation, :with_task) }
|
11
|
+
let(:host) { job_invocation.template_invocations.first.host }
|
12
|
+
let(:provider) do
|
13
|
+
provider = ::SSHExecutionProvider
|
14
|
+
provider.expects(:ssh_password).with(host).returns('sshpass')
|
15
|
+
provider.expects(:sudo_password).with(host).returns('sudopass')
|
16
|
+
provider.expects(:ssh_key_passphrase).with(host).returns('keypass')
|
17
|
+
provider
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'uses provider secrets' do
|
21
|
+
secrets = subject.secrets(host, job_invocation, provider)
|
22
|
+
|
23
|
+
assert_equal 'sshpass', secrets[:ssh_password]
|
24
|
+
assert_equal 'sudopass', secrets[:sudo_password]
|
25
|
+
assert_equal 'keypass', secrets[:key_passphrase]
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'prefers job secrets over provider secrets' do
|
29
|
+
job_invocation.password = 'jobsshpass'
|
30
|
+
job_invocation.key_passphrase = 'jobkeypass'
|
31
|
+
secrets = subject.secrets(host, job_invocation, provider)
|
32
|
+
|
33
|
+
assert_equal 'jobsshpass', secrets[:ssh_password]
|
34
|
+
assert_equal 'sudopass', secrets[:sudo_password]
|
35
|
+
assert_equal 'jobkeypass', secrets[:key_passphrase]
|
36
|
+
end
|
13
37
|
end
|
14
38
|
|
15
39
|
describe '#finalize' do
|
40
|
+
let(:host) { FactoryBot.create(:host, :with_execution) }
|
41
|
+
|
42
|
+
before do
|
43
|
+
subject.stubs(:input).returns({ host: { id: host.id } })
|
44
|
+
Host.expects(:find).with(host.id).returns(host)
|
45
|
+
end
|
46
|
+
|
16
47
|
describe 'updates the host status' do
|
17
48
|
before do
|
18
49
|
subject.expects(:check_exit_status).returns(nil)
|
@@ -158,12 +158,6 @@ class ForemanRemoteExecutionHostExtensionsTest < ActiveSupport::TestCase
|
|
158
158
|
host.remote_execution_proxies(provider)[:global].must_include proxy_in_taxonomies
|
159
159
|
host.remote_execution_proxies(provider)[:global].wont_include proxy_no_taxonomies
|
160
160
|
end
|
161
|
-
|
162
|
-
it 'returns all proxies when there\'s no taxonomies' do
|
163
|
-
Taxonomy.stubs(:enabled_taxonomies).returns([])
|
164
|
-
host.remote_execution_proxies(provider)[:global].must_include proxy_in_taxonomies
|
165
|
-
host.remote_execution_proxies(provider)[:global].must_include proxy_no_taxonomies
|
166
|
-
end
|
167
161
|
end
|
168
162
|
|
169
163
|
context 'disabled' do
|
@@ -62,6 +62,7 @@ class RemoteExecutionProviderTest < ActiveSupport::TestCase
|
|
62
62
|
let(:template_invocation) { job_invocation.pattern_template_invocations.first }
|
63
63
|
let(:host) { FactoryBot.create(:host) }
|
64
64
|
let(:proxy_options) { SSHExecutionProvider.proxy_command_options(template_invocation, host) }
|
65
|
+
let(:secrets) { SSHExecutionProvider.secrets(host) }
|
65
66
|
|
66
67
|
describe 'effective user' do
|
67
68
|
it 'takes the effective user from value from the template invocation' do
|
@@ -81,7 +82,8 @@ class RemoteExecutionProviderTest < ActiveSupport::TestCase
|
|
81
82
|
it 'uses the remote_execution_sudo_password on the host param' do
|
82
83
|
host.params['remote_execution_sudo_password'] = 'mypassword'
|
83
84
|
host.host_parameters << FactoryBot.create(:host_parameter, :host => host, :name => 'remote_execution_sudo_password', :value => 'mypassword')
|
84
|
-
proxy_options
|
85
|
+
assert_not proxy_options.key?(:sudo_password)
|
86
|
+
secrets[:sudo_password].must_equal 'mypassword'
|
85
87
|
end
|
86
88
|
end
|
87
89
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_remote_execution
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Foreman Remote Execution team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-10-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deface
|