foreman_remote_execution 6.0.0 → 7.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/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
|