foreman_remote_execution 6.0.0 → 7.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/api/v2/job_invocations_controller.rb +1 -0
- data/app/controllers/foreman_remote_execution/concerns/api/v2/registration_controller_extensions.rb +5 -0
- data/app/controllers/ui_job_wizard_controller.rb +1 -1
- data/app/helpers/hosts_extensions_helper.rb +62 -0
- data/app/helpers/remote_execution_helper.rb +4 -3
- data/app/lib/actions/remote_execution/run_host_job.rb +5 -1
- data/app/lib/actions/remote_execution/run_hosts_job.rb +4 -0
- data/app/models/concerns/foreman_remote_execution/host_extensions.rb +5 -1
- data/app/models/concerns/foreman_remote_execution/nic_extensions.rb +6 -4
- data/app/models/concerns/foreman_remote_execution/smart_proxy_extensions.rb +1 -1
- data/app/models/job_invocation_composer.rb +7 -3
- data/app/models/job_template.rb +4 -1
- data/app/models/remote_execution_provider.rb +10 -1
- data/app/models/ssh_execution_provider.rb +20 -7
- data/app/services/default_proxy_proxy_selector.rb +1 -1
- data/app/services/remote_execution_proxy_selector.rb +7 -2
- data/app/views/api/v2/host/main.rabl +1 -0
- data/app/views/api/v2/job_invocations/base.json.rabl +1 -1
- data/app/views/dashboard/_latest-jobs.html.erb +1 -1
- data/app/views/job_invocations/_card_target_hosts.html.erb +8 -0
- data/app/views/job_invocations/_form.html.erb +2 -0
- data/app/views/templates/{ssh → script}/check_update.erb +2 -2
- data/app/views/templates/{ssh → script}/module_action.erb +2 -2
- data/app/views/templates/{ssh → script}/package_action.erb +5 -2
- data/app/views/templates/{ssh → script}/power_action.erb +2 -2
- data/app/views/templates/{ssh → script}/puppet_agent_disable.erb +2 -2
- data/app/views/templates/{ssh → script}/puppet_agent_enable.erb +2 -2
- data/app/views/templates/{ssh → script}/puppet_install_modules_from_forge.erb +2 -2
- data/app/views/templates/{ssh → script}/puppet_install_modules_from_git.erb +2 -2
- data/app/views/templates/{ssh → script}/puppet_run_once.erb +2 -2
- data/app/views/templates/{ssh → script}/run_command.erb +2 -2
- data/app/views/templates/{ssh → script}/service_action.erb +2 -2
- data/db/migrate/20220321101835_rename_ssh_provider_to_script.rb +29 -0
- data/db/migrate/20220331112719_add_ssh_user_to_job_invocation.rb +5 -0
- data/db/seeds.d/60-ssh_proxy_feature.rb +3 -0
- data/jsconfig.json +8 -0
- data/lib/foreman_remote_execution/engine.rb +10 -5
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/locale/action_names.rb +3 -3
- data/locale/de/foreman_remote_execution.po +23 -23
- data/locale/en/foreman_remote_execution.po +23 -23
- data/locale/en_GB/foreman_remote_execution.po +23 -23
- data/locale/es/foreman_remote_execution.po +23 -23
- data/locale/foreman_remote_execution.pot +64 -66
- data/locale/fr/foreman_remote_execution.po +23 -23
- data/locale/ja/foreman_remote_execution.po +23 -23
- data/locale/ko/foreman_remote_execution.po +23 -23
- data/locale/pt_BR/foreman_remote_execution.po +23 -23
- data/locale/ru/foreman_remote_execution.po +23 -23
- data/locale/zh_CN/foreman_remote_execution.po +23 -23
- data/locale/zh_TW/foreman_remote_execution.po +23 -23
- data/package.json +6 -7
- data/test/unit/concerns/host_extensions_test.rb +2 -1
- data/test/unit/remote_execution_provider_test.rb +2 -0
- data/webpack/JobWizard/JobWizard.js +8 -2
- data/webpack/JobWizard/JobWizardConstants.js +2 -2
- data/webpack/JobWizard/__tests__/fixtures.js +8 -4
- data/webpack/JobWizard/steps/AdvancedFields/__tests__/AdvancedFields.test.js +2 -2
- data/webpack/JobWizard/steps/CategoryAndTemplate/CategoryAndTemplate.js +24 -15
- data/webpack/JobWizard/steps/HostsAndInputs/SelectGQL.js +2 -1
- data/webpack/JobWizard/steps/HostsAndInputs/SelectedChips.js +1 -1
- data/webpack/JobWizard/steps/HostsAndInputs/buildHostQuery.js +1 -1
- data/webpack/JobWizard/steps/HostsAndInputs/hostgroups.gql +1 -0
- data/webpack/JobWizard/steps/HostsAndInputs/hosts.gql +1 -0
- data/webpack/JobWizard/steps/ReviewDetails/index.js +1 -1
- data/webpack/JobWizard/steps/Schedule/__tests__/Schedule.test.js +15 -15
- data/webpack/JobWizard/steps/form/GroupedSelectField.js +7 -1
- data/webpack/JobWizard/steps/form/SearchSelect.js +0 -1
- data/webpack/__mocks__/foremanReact/common/globalIdHelpers.js +1 -0
- data/webpack/global_index.js +2 -4
- data/webpack/react_app/components/FeaturesDropdown/actions.js +13 -0
- data/webpack/react_app/components/FeaturesDropdown/constant.js +2 -0
- data/webpack/react_app/components/FeaturesDropdown/index.js +74 -0
- data/webpack/react_app/components/HostKebab/KebabItems.js +27 -0
- data/webpack/react_app/components/RecentJobsCard/RecentJobsCard.js +10 -5
- data/webpack/react_app/components/RecentJobsCard/RecentJobsTable.js +2 -2
- data/webpack/react_app/components/RecentJobsCard/constants.js +1 -0
- data/webpack/react_app/components/TargetingHosts/TargetingHostsConsts.js +1 -0
- data/webpack/react_app/components/TargetingHosts/TargetingHostsPage.js +8 -3
- data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHostsPage.test.js.snap +9 -1
- data/webpack/react_app/components/TargetingHosts/__tests__/fixtures.js +1 -4
- data/webpack/react_app/components/TargetingHosts/index.js +1 -0
- data/webpack/react_app/extend/Fills.js +48 -0
- metadata +25 -17
- data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +0 -62
- data/webpack/react_app/extend/fillRecentJobsCard.js +0 -11
- data/webpack/react_app/extend/fillregistrationAdvanced.js +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e9183b3b81c3033d696f4aedf861cb5eed143fb9eacccb144a23d859e3ccae69
|
4
|
+
data.tar.gz: 4c7c6c09c84f3d4cbef2aaa8330b7bf048d42570e9319ad227c30abc5613770c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b35e41908b57f97f80272070d84b8d2ceeb7e061e22ad673d07c694a643d057399e207af9c8f36d14d535a7ddb3eddefa013e04b3d63689796e66e6d9aeae88b
|
7
|
+
data.tar.gz: 5c0b0d79edaab4c28721ad26df27ad8ac14878e09349929d28175c2cc1714ebb1f81ceb9f4824215d781dc1b4b0662962a9043f4f56963fea4d0aaa3e2483f8d
|
@@ -45,6 +45,7 @@ module Api
|
|
45
45
|
:required => false,
|
46
46
|
:desc => N_('Set password for effective user (using sudo-like mechanisms)')
|
47
47
|
end
|
48
|
+
param :ssh_user, String, :required => false, :desc => N_('Set SSH user')
|
48
49
|
param :password, String, :required => false, :desc => N_('Set SSH password')
|
49
50
|
param :key_passphrase, String, :required => false, :desc => N_('Set SSH key passphrase')
|
50
51
|
|
data/app/controllers/foreman_remote_execution/concerns/api/v2/registration_controller_extensions.rb
CHANGED
@@ -13,6 +13,7 @@ module ForemanRemoteExecution
|
|
13
13
|
|
14
14
|
def host_setup_extension
|
15
15
|
remote_execution_interface
|
16
|
+
reset_host_known_keys! unless @host.new_record?
|
16
17
|
super
|
17
18
|
end
|
18
19
|
|
@@ -21,6 +22,10 @@ module ForemanRemoteExecution
|
|
21
22
|
|
22
23
|
@host.set_execution_interface(params['remote_execution_interface'])
|
23
24
|
end
|
25
|
+
|
26
|
+
def reset_host_known_keys!
|
27
|
+
@host.host_proxy_invocations.destroy_all
|
28
|
+
end
|
24
29
|
end
|
25
30
|
end
|
26
31
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module HostsExtensionsHelper
|
2
|
+
def rex_hosts_multiple_actions
|
3
|
+
return [] unless can_schedule_jobs?
|
4
|
+
|
5
|
+
[{ action: [_('Schedule Remote Job'), new_job_invocation_path, false], priority: 1000 }]
|
6
|
+
end
|
7
|
+
|
8
|
+
def rex_host_overview_buttons(host)
|
9
|
+
[
|
10
|
+
{ button: link_to_if_authorized(_("Jobs"), hash_for_job_invocations_path(search: "host=#{host.name}"), title: _("Job invocations"), class: 'btn btn-default'), priority: 200 },
|
11
|
+
]
|
12
|
+
end
|
13
|
+
|
14
|
+
def host_title_actions(*args)
|
15
|
+
title_actions(button_group(schedule_job_multi_button(*args)),
|
16
|
+
button_group(web_console_button(*args)))
|
17
|
+
super(*args)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def schedule_job_multi_button(*args)
|
23
|
+
host_features = rex_host_features(*args)
|
24
|
+
|
25
|
+
if host_features.present?
|
26
|
+
action_buttons(schedule_job_button(*args), *host_features)
|
27
|
+
else
|
28
|
+
schedule_job_button(*args)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def rex_host_features(host, *_rest)
|
33
|
+
return [] unless can_execute_on_host?(host)
|
34
|
+
RemoteExecutionFeature.with_host_action_button.order(:label).map do |feature|
|
35
|
+
link_to(_('%s') % feature.name, job_invocations_path(:host_ids => [host.id], :feature => feature.label), :method => :post)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def schedule_job_button(host, *_rest)
|
40
|
+
return unless can_execute_on_host?(host)
|
41
|
+
link_to(_('Schedule Remote Job'), new_job_invocation_path(:host_ids => [host.id]), :id => :run_button, :class => 'btn btn-default')
|
42
|
+
end
|
43
|
+
|
44
|
+
def web_console_button(host, *_args)
|
45
|
+
return if !authorized_for(permission: 'cockpit_hosts', auth_object: host) || !can_execute_on_infrastructure_host?(host)
|
46
|
+
|
47
|
+
url = SSHExecutionProvider.cockpit_url_for_host(host.name)
|
48
|
+
url ? link_to(_('Web Console'), url, :class => 'btn btn-default', :id => :'web-console-button', :target => '_new') : nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def can_schedule_jobs?
|
52
|
+
authorized_for(controller: :job_invocations, action: :create)
|
53
|
+
end
|
54
|
+
|
55
|
+
def can_execute_on_host?(host)
|
56
|
+
can_schedule_jobs? && can_execute_on_infrastructure_host?(host)
|
57
|
+
end
|
58
|
+
|
59
|
+
def can_execute_on_infrastructure_host?(host)
|
60
|
+
!host.infrastructure_host? || User.current.can?(:execute_jobs_on_infrastructure_hosts)
|
61
|
+
end
|
62
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module RemoteExecutionHelper
|
2
2
|
def providers_options
|
3
|
-
RemoteExecutionProvider.providers.map { |key, provider| [ key, _(provider.humanized_name) ] }
|
3
|
+
RemoteExecutionProvider.providers.reject { |key, _provider| key == 'SSH' }.map { |key, provider| [ key, _(provider.humanized_name) ] }
|
4
4
|
end
|
5
5
|
|
6
6
|
def job_hosts_authorizer
|
@@ -147,9 +147,10 @@ module RemoteExecutionHelper
|
|
147
147
|
end
|
148
148
|
end
|
149
149
|
|
150
|
-
def invocation_description(invocation)
|
150
|
+
def invocation_description(invocation, keep_tooltip: true)
|
151
151
|
description = invocation.description.try(:capitalize) || invocation.job_category
|
152
|
-
trunc_with_tooltip(description, 80)
|
152
|
+
description = trunc_with_tooltip(description, 80) if keep_tooltip
|
153
|
+
description
|
153
154
|
end
|
154
155
|
|
155
156
|
def invocation_result(invocation, key)
|
@@ -40,7 +40,7 @@ module Actions
|
|
40
40
|
provider = template_invocation.template.provider
|
41
41
|
proxy_selector = provider.required_proxy_selector_for(template_invocation.template) || proxy_selector
|
42
42
|
|
43
|
-
provider_type =
|
43
|
+
provider_type = provider.proxy_feature
|
44
44
|
proxy = determine_proxy!(proxy_selector, provider_type, host)
|
45
45
|
link!(proxy)
|
46
46
|
input[:proxy_id] = proxy.id
|
@@ -172,6 +172,10 @@ module Actions
|
|
172
172
|
@host ||= ::Host.authorized.find(host_id)
|
173
173
|
end
|
174
174
|
|
175
|
+
def self.cleanup_after
|
176
|
+
'90d'
|
177
|
+
end
|
178
|
+
|
175
179
|
private
|
176
180
|
|
177
181
|
def update_host_status
|
@@ -46,6 +46,10 @@ module ForemanRemoteExecution
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
+
def cockpit_url
|
50
|
+
SSHExecutionProvider.cockpit_url_for_host(self.name)
|
51
|
+
end
|
52
|
+
|
49
53
|
def execution_status(options = {})
|
50
54
|
@execution_status ||= get_status(HostStatus::ExecutionStatus).to_status(options)
|
51
55
|
end
|
@@ -98,7 +102,7 @@ module ForemanRemoteExecution
|
|
98
102
|
end
|
99
103
|
|
100
104
|
def remote_execution_ssh_keys
|
101
|
-
remote_execution_proxies(
|
105
|
+
remote_execution_proxies(%w(SSH Script), false).values.flatten.uniq.map { |proxy| proxy.pubkey }.compact.uniq
|
102
106
|
end
|
103
107
|
|
104
108
|
def drop_execution_interface_cache
|
@@ -3,16 +3,18 @@ module ForemanRemoteExecution
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
-
before_validation :set_execution_flag
|
7
6
|
validate :exclusive_execution_interface
|
7
|
+
before_validation :move_execution_flag
|
8
8
|
end
|
9
9
|
|
10
10
|
private
|
11
11
|
|
12
|
-
def
|
13
|
-
return unless
|
12
|
+
def move_execution_flag
|
13
|
+
return unless host && self.execution?
|
14
14
|
|
15
|
-
|
15
|
+
host.interfaces
|
16
|
+
.select { |i| i.execution? && i != self }
|
17
|
+
.each { |i| i.execution = false }
|
16
18
|
end
|
17
19
|
|
18
20
|
def exclusive_execution_interface
|
@@ -16,6 +16,7 @@ class JobInvocationComposer
|
|
16
16
|
:host_ids => ui_params[:host_ids],
|
17
17
|
:remote_execution_feature_id => job_invocation_base[:remote_execution_feature_id],
|
18
18
|
:description_format => job_invocation_base[:description_format],
|
19
|
+
:ssh_user => blank_to_nil(job_invocation_base[:ssh_user]),
|
19
20
|
:password => blank_to_nil(job_invocation_base[:password]),
|
20
21
|
:key_passphrase => blank_to_nil(job_invocation_base[:key_passphrase]),
|
21
22
|
:effective_user_password => blank_to_nil(job_invocation_base[:effective_user_password]),
|
@@ -121,6 +122,7 @@ class JobInvocationComposer
|
|
121
122
|
:targeting => targeting_params,
|
122
123
|
:triggering => triggering_params,
|
123
124
|
:description_format => api_params[:description_format],
|
125
|
+
:ssh_user => api_params[:ssh_user],
|
124
126
|
:password => api_params[:password],
|
125
127
|
:remote_execution_feature_id => remote_execution_feature_id,
|
126
128
|
:effective_user_password => api_params[:effective_user_password],
|
@@ -217,7 +219,7 @@ class JobInvocationComposer
|
|
217
219
|
def format_datetime(datetime)
|
218
220
|
return datetime if datetime.blank?
|
219
221
|
|
220
|
-
Time.parse(datetime).
|
222
|
+
Time.parse(datetime).in_time_zone.strftime('%Y-%m-%d %H:%M')
|
221
223
|
end
|
222
224
|
end
|
223
225
|
|
@@ -237,6 +239,7 @@ class JobInvocationComposer
|
|
237
239
|
{ :job_category => job_invocation.job_category,
|
238
240
|
:targeting => targeting_params,
|
239
241
|
:triggering => triggering_params,
|
242
|
+
:ssh_user => job_invocation.ssh_user,
|
240
243
|
:description_format => job_invocation.description_format,
|
241
244
|
:concurrency_control => concurrency_control_params,
|
242
245
|
:execution_timeout_interval => job_invocation.execution_timeout_interval,
|
@@ -399,7 +402,7 @@ class JobInvocationComposer
|
|
399
402
|
|
400
403
|
def compose
|
401
404
|
job_invocation.job_category = validate_job_category(params[:job_category])
|
402
|
-
job_invocation.job_category ||= resolve_job_category(available_job_categories.first) { |
|
405
|
+
job_invocation.job_category ||= resolve_job_category(available_job_categories.first) { |template| template.job_category } if @set_defaults
|
403
406
|
job_invocation.remote_execution_feature_id = params[:remote_execution_feature_id]
|
404
407
|
job_invocation.targeting = build_targeting
|
405
408
|
job_invocation.triggering = build_triggering
|
@@ -411,6 +414,7 @@ class JobInvocationComposer
|
|
411
414
|
job_invocation.password = params[:password]
|
412
415
|
job_invocation.key_passphrase = params[:key_passphrase]
|
413
416
|
job_invocation.effective_user_password = params[:effective_user_password]
|
417
|
+
job_invocation.ssh_user = params[:ssh_user]
|
414
418
|
|
415
419
|
if @reruns && job_invocation.targeting.static?
|
416
420
|
job_invocation.targeting.assign_host_ids(JobInvocation.find(@reruns).targeting.host_ids)
|
@@ -544,7 +548,7 @@ class JobInvocationComposer
|
|
544
548
|
|
545
549
|
def input_value_for(input)
|
546
550
|
invocations = pattern_template_invocations
|
547
|
-
default = TemplateInvocationInputValue.new(:template_input_id => input.id)
|
551
|
+
default = TemplateInvocationInputValue.new(:template_input_id => input.id, :value => input.default)
|
548
552
|
invocations.map(&:input_values).flatten.detect { |iv| iv.template_input_id == input.id } || default
|
549
553
|
end
|
550
554
|
|
data/app/models/job_template.rb
CHANGED
@@ -196,7 +196,10 @@ class JobTemplate < ::Template
|
|
196
196
|
def default_input_values(ignore_keys)
|
197
197
|
result = self.template_inputs_with_foreign.select { |ti| !ti.required? && ti.input_type == 'user' }.map { |ti| ti.name.to_s }
|
198
198
|
result -= ignore_keys.map(&:to_s)
|
199
|
-
|
199
|
+
default_values = self.template_inputs_with_foreign.reduce({}) do |acc, input|
|
200
|
+
acc.merge(input.name.to_s => input.default)
|
201
|
+
end
|
202
|
+
Hash[result.map { |k| [ k, default_values[k]] }]
|
200
203
|
end
|
201
204
|
|
202
205
|
private
|
@@ -4,7 +4,16 @@ class RemoteExecutionProvider
|
|
4
4
|
|
5
5
|
class << self
|
6
6
|
def provider_for(type)
|
7
|
-
providers[type.to_s] || providers[:
|
7
|
+
providers[type.to_s] || providers[:script]
|
8
|
+
end
|
9
|
+
|
10
|
+
def registered_name
|
11
|
+
klass = self
|
12
|
+
providers.key(klass)
|
13
|
+
end
|
14
|
+
|
15
|
+
def proxy_feature
|
16
|
+
registered_name
|
8
17
|
end
|
9
18
|
|
10
19
|
def providers
|
@@ -1,7 +1,7 @@
|
|
1
|
-
class
|
1
|
+
class ScriptExecutionProvider < RemoteExecutionProvider
|
2
2
|
class << self
|
3
3
|
def proxy_command_options(template_invocation, host)
|
4
|
-
super.merge(:ssh_user => ssh_user(host),
|
4
|
+
super.merge(:ssh_user => ssh_user(host, template_invocation.job_invocation),
|
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),
|
@@ -9,7 +9,7 @@ class SSHExecutionProvider < RemoteExecutionProvider
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def humanized_name
|
12
|
-
_('
|
12
|
+
_('Script')
|
13
13
|
end
|
14
14
|
|
15
15
|
def supports_effective_user?
|
@@ -37,8 +37,7 @@ class SSHExecutionProvider < RemoteExecutionProvider
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def ssh_params(host)
|
40
|
-
|
41
|
-
proxy = proxy_selector.determine_proxy(host, 'SSH')
|
40
|
+
proxy = proxy_for_cockpit(host)
|
42
41
|
{
|
43
42
|
:hostname => find_ip_or_hostname(host),
|
44
43
|
:proxy => proxy.class == Symbol ? proxy : proxy.url,
|
@@ -53,14 +52,28 @@ class SSHExecutionProvider < RemoteExecutionProvider
|
|
53
52
|
Setting[:remote_execution_cockpit_url] % { :host => host } if Setting[:remote_execution_cockpit_url].present?
|
54
53
|
end
|
55
54
|
|
55
|
+
def proxy_feature
|
56
|
+
%w(SSH Script)
|
57
|
+
end
|
58
|
+
|
56
59
|
private
|
57
60
|
|
58
|
-
def ssh_user(host)
|
59
|
-
host.host_param('remote_execution_ssh_user')
|
61
|
+
def ssh_user(host, job_invocation = nil)
|
62
|
+
job_invocation&.ssh_user || host.host_param('remote_execution_ssh_user')
|
60
63
|
end
|
61
64
|
|
62
65
|
def ssh_port(host)
|
63
66
|
Integer(host_setting(host, :remote_execution_ssh_port))
|
64
67
|
end
|
68
|
+
|
69
|
+
def proxy_for_cockpit(host)
|
70
|
+
proxy_selector = ::RemoteExecutionProxySelector.new
|
71
|
+
proxy = proxy_selector.determine_proxy(host, 'Script', capability: 'cockpit')
|
72
|
+
return proxy unless [:not_defined, :not_available, nil].include?(proxy)
|
73
|
+
|
74
|
+
proxy_selector.determine_proxy(host, 'SSH')
|
75
|
+
end
|
65
76
|
end
|
66
77
|
end
|
78
|
+
|
79
|
+
SSHExecutionProvider = ScriptExecutionProvider
|
@@ -7,7 +7,7 @@ class DefaultProxyProxySelector < ::RemoteExecutionProxySelector
|
|
7
7
|
super
|
8
8
|
end
|
9
9
|
|
10
|
-
def available_proxies(host, provider)
|
10
|
+
def available_proxies(host, provider, capability: nil)
|
11
11
|
# TODO: Once we have a internal proxy marker/feature on the proxy, we can
|
12
12
|
# swap the implementation
|
13
13
|
raise _('default_capsule method missing from SmartProxy') unless ::SmartProxy.respond_to?(:default_capsule)
|
@@ -2,7 +2,12 @@ class RemoteExecutionProxySelector < ::ForemanTasks::ProxySelector
|
|
2
2
|
|
3
3
|
INTERNAL_PROXY = 'internal'.freeze
|
4
4
|
|
5
|
-
def available_proxies(host, provider)
|
6
|
-
host.remote_execution_proxies(provider)
|
5
|
+
def available_proxies(host, provider, capability: nil)
|
6
|
+
proxies = host.remote_execution_proxies(provider)
|
7
|
+
return proxies if capability.nil?
|
8
|
+
|
9
|
+
proxies.reduce({}) do |acc, (strategy, possible_proxies)|
|
10
|
+
acc.merge(strategy => possible_proxies.select { |proxy| proxy.has_capability?(capability) })
|
11
|
+
end
|
7
12
|
end
|
8
13
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
attributes :cockpit_url
|
@@ -10,7 +10,7 @@
|
|
10
10
|
</tr>
|
11
11
|
<% JobInvocation.latest_jobs.each do |invocation| %>
|
12
12
|
<tr>
|
13
|
-
<td class="ellipsis"><%= link_to_if_authorized invocation_description(invocation), hash_for_job_invocation_path(invocation).merge(:auth_object => invocation, :permission => :view_job_invocations, :authorizer => authorizer) %></td>
|
13
|
+
<td class="ellipsis"><%= link_to_if_authorized invocation_description(invocation, keep_tooltip: false), hash_for_job_invocation_path(invocation).merge(:auth_object => invocation, :permission => :view_job_invocations, :authorizer => authorizer) %></td>
|
14
14
|
<td><%= link_to_invocation_task_if_authorized(invocation) %></td>
|
15
15
|
<td><%= time_in_words_span(invocation.start_at) %></td>
|
16
16
|
</tr>
|
@@ -32,6 +32,14 @@
|
|
32
32
|
<%= show_job_location(@job_location) %>
|
33
33
|
</strong>
|
34
34
|
</p>
|
35
|
+
<% if job_invocation[:ssh_user] %>
|
36
|
+
<p>
|
37
|
+
<%= _('SSH User') %>:
|
38
|
+
<strong>
|
39
|
+
<%= job_invocation[:ssh_user] %>
|
40
|
+
</strong>
|
41
|
+
</p>
|
42
|
+
<% end %>
|
35
43
|
</div>
|
36
44
|
<div class='card-pf-footer'>
|
37
45
|
<p>
|
@@ -82,6 +82,8 @@
|
|
82
82
|
<% end %>
|
83
83
|
<% end %>
|
84
84
|
|
85
|
+
<%= text_f f, :ssh_user, :value => f.object.ssh_user, :label => _('SSH user'), :label_help => N_('A user to be used for SSH.') %>
|
86
|
+
|
85
87
|
<% if job_template.effective_user.overridable? %>
|
86
88
|
<%= text_f job_template_fields, :effective_user, :value => @composer.template_invocation(job_template).try(:effective_user), :label => _('Effective user'), :label_help => N_("A user to be used for executing the script. If it differs from the SSH user, su or sudo is used to switch the accounts.") %>
|
87
89
|
<% end %>
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<%#
|
2
2
|
kind: job_template
|
3
|
-
name: Module Action -
|
3
|
+
name: Module Action - Script Default
|
4
4
|
model: JobTemplate
|
5
5
|
job_category: Modules
|
6
6
|
description_format: "Module %{action} %{module_spec}"
|
7
|
-
provider_type:
|
7
|
+
provider_type: script
|
8
8
|
template_inputs:
|
9
9
|
- name: pre_script
|
10
10
|
description: A script to run prior to the module action
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<%#
|
2
2
|
kind: job_template
|
3
|
-
name: Package Action -
|
3
|
+
name: Package Action - Script Default
|
4
4
|
model: JobTemplate
|
5
5
|
job_category: Packages
|
6
6
|
description_format: "%{action} package(s) %{package}"
|
7
|
-
provider_type:
|
7
|
+
provider_type: script
|
8
8
|
template_inputs:
|
9
9
|
- name: pre_script
|
10
10
|
description: A script to run prior to the package action
|
@@ -69,8 +69,11 @@ handle_zypp_res_codes () {
|
|
69
69
|
|
70
70
|
if [ "${ZYPP_RES_CODES[$RETVAL]}" != "" ]; then
|
71
71
|
echo ${ZYPP_RES_CODES[$RETVAL]}
|
72
|
+
fi
|
73
|
+
if [[ $RETVAL -ge 100 && $RETVAL -le 103 ]]; then
|
72
74
|
RETVAL=0
|
73
75
|
fi
|
76
|
+
|
74
77
|
return $RETVAL
|
75
78
|
}
|
76
79
|
<% end -%>
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<%#
|
2
2
|
kind: job_template
|
3
|
-
name: Power Action -
|
3
|
+
name: Power Action - Script Default
|
4
4
|
model: JobTemplate
|
5
5
|
job_category: Power
|
6
6
|
description_format: '%{action} host'
|
7
|
-
provider_type:
|
7
|
+
provider_type: script
|
8
8
|
template_inputs:
|
9
9
|
- name: action
|
10
10
|
description: Action to perform on the service
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<%#
|
2
|
-
name: Puppet Agent Disable -
|
2
|
+
name: Puppet Agent Disable - Script Default
|
3
3
|
model: JobTemplate
|
4
4
|
job_category: Puppet
|
5
5
|
description_format: Disable Puppet agent
|
@@ -10,7 +10,7 @@ template_inputs:
|
|
10
10
|
input_type: user
|
11
11
|
description: Reason for disabling the Puppet agent
|
12
12
|
advanced: false
|
13
|
-
provider_type:
|
13
|
+
provider_type: script
|
14
14
|
kind: job_template
|
15
15
|
-%>
|
16
16
|
<% if @host.operatingsystem.family == 'Debian' -%>
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<%#
|
2
|
-
name: Puppet Agent Enable -
|
2
|
+
name: Puppet Agent Enable - Script Default
|
3
3
|
model: JobTemplate
|
4
4
|
job_category: Puppet
|
5
5
|
description_format: Enable Puppet agent
|
6
6
|
snippet: false
|
7
|
-
provider_type:
|
7
|
+
provider_type: script
|
8
8
|
kind: job_template
|
9
9
|
-%>
|
10
10
|
<% if @host.operatingsystem.family == 'Debian' -%>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<%#
|
2
|
-
name: Puppet Module - Install from forge -
|
2
|
+
name: Puppet Module - Install from forge - Script Default
|
3
3
|
model: JobTemplate
|
4
4
|
job_category: Puppet
|
5
5
|
description_format: Install Puppet Module "%{puppet_module}" from forge
|
@@ -30,7 +30,7 @@ template_inputs:
|
|
30
30
|
input_type: user
|
31
31
|
description: Do not attempt to install dependencies. Type "true" to ignore dependencies.
|
32
32
|
advanced: true
|
33
|
-
provider_type:
|
33
|
+
provider_type: script
|
34
34
|
kind: job_template
|
35
35
|
-%>
|
36
36
|
<% if @host.operatingsystem.family == 'Debian' -%>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<%#
|
2
|
-
name: Puppet Module - Install from git -
|
2
|
+
name: Puppet Module - Install from git - Script Default
|
3
3
|
model: JobTemplate
|
4
4
|
job_category: Puppet
|
5
5
|
description_format: Install Puppet Module "%{puppet_module}" from git
|
@@ -15,7 +15,7 @@ template_inputs:
|
|
15
15
|
input_type: user
|
16
16
|
description: For example, '/etc/puppetlabs/code/environments/production/modules/puppet'.
|
17
17
|
advanced: false
|
18
|
-
provider_type:
|
18
|
+
provider_type: script
|
19
19
|
kind: job_template
|
20
20
|
-%>
|
21
21
|
git clone <%= input('git_repository') %> <%= input('target_dir') %>
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<%#
|
2
2
|
kind: job_template
|
3
|
-
name: Puppet Run Once -
|
3
|
+
name: Puppet Run Once - Script Default
|
4
4
|
model: JobTemplate
|
5
5
|
job_category: Puppet
|
6
6
|
description_format: 'Run Puppet once with "%{puppet_options}"'
|
7
|
-
provider_type:
|
7
|
+
provider_type: script
|
8
8
|
template_inputs:
|
9
9
|
- name: puppet_options
|
10
10
|
description: Additional options to pass to puppet
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<%#
|
2
2
|
kind: job_template
|
3
|
-
name: Run Command -
|
3
|
+
name: Run Command - Script Default
|
4
4
|
model: JobTemplate
|
5
5
|
job_category: Commands
|
6
6
|
description_format: "Run %{command}"
|
7
|
-
provider_type:
|
7
|
+
provider_type: script
|
8
8
|
template_inputs:
|
9
9
|
- name: command
|
10
10
|
description: Command to run on the host
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<%#
|
2
2
|
kind: job_template
|
3
|
-
name: Service Action -
|
3
|
+
name: Service Action - Script Default
|
4
4
|
model: JobTemplate
|
5
5
|
job_category: Services
|
6
6
|
description_format: '%{action} service %{service}'
|
7
|
-
provider_type:
|
7
|
+
provider_type: script
|
8
8
|
template_inputs:
|
9
9
|
- name: action
|
10
10
|
description: Action to perform on the service
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class RenameSshProviderToScript < ActiveRecord::Migration[6.0]
|
4
|
+
|
5
|
+
def do_change(from, to, from_re, new_label)
|
6
|
+
setting = Setting.find_by(:name => 'remote_execution_form_job_template')
|
7
|
+
default_template = nil
|
8
|
+
|
9
|
+
Template.where(:provider_type => from).each do |t|
|
10
|
+
default_template = t if t.name == setting&.value
|
11
|
+
t.provider_type = to
|
12
|
+
t.name = t.name.gsub(from_re, new_label)
|
13
|
+
t.save!
|
14
|
+
end
|
15
|
+
|
16
|
+
if default_template
|
17
|
+
setting.value = default_template.name
|
18
|
+
setting.save!
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def up
|
23
|
+
do_change 'SSH', 'script', /SSH Default$/, 'Script Default'
|
24
|
+
end
|
25
|
+
|
26
|
+
def down
|
27
|
+
do_change 'script', 'SSH', /Script Default$/, 'SSH Default'
|
28
|
+
end
|
29
|
+
end
|