foreman_remote_execution 5.1.0 → 6.2.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/README.md +7 -0
- data/app/controllers/foreman_remote_execution/concerns/api/v2/registration_controller_extensions.rb +5 -0
- data/app/controllers/ui_job_wizard_controller.rb +13 -2
- data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +20 -9
- data/app/helpers/remote_execution_helper.rb +5 -4
- data/app/lib/actions/remote_execution/run_host_job.rb +1 -1
- data/app/mailers/rex_job_mailer.rb +1 -1
- data/app/models/concerns/foreman_remote_execution/host_extensions.rb +9 -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 +1 -1
- data/app/models/remote_execution_provider.rb +10 -1
- data/app/models/ssh_execution_provider.rb +17 -4
- data/app/models/targeting.rb +1 -1
- 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/dashboard/_latest-jobs.html.erb +1 -1
- data/app/views/job_invocations/_preview_hosts_list.html.erb +1 -1
- data/app/views/template_invocations/show.html.erb +1 -1
- 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/seeds.d/60-ssh_proxy_feature.rb +3 -0
- data/jsconfig.json +8 -0
- data/lib/foreman_remote_execution/engine.rb +10 -4
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/locale/action_names.rb +3 -4
- data/locale/de/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/de/foreman_remote_execution.po +356 -20
- data/locale/en/foreman_remote_execution.po +356 -20
- data/locale/en_GB/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/en_GB/foreman_remote_execution.po +356 -20
- data/locale/es/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/es/foreman_remote_execution.po +357 -21
- data/locale/foreman_remote_execution.pot +808 -296
- data/locale/fr/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/fr/foreman_remote_execution.po +357 -21
- data/locale/ja/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ja/foreman_remote_execution.po +357 -21
- data/locale/ko/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ko/foreman_remote_execution.po +356 -20
- data/locale/pt_BR/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/pt_BR/foreman_remote_execution.po +357 -21
- data/locale/ru/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ru/foreman_remote_execution.po +356 -20
- data/locale/zh_CN/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/zh_CN/foreman_remote_execution.po +357 -21
- data/locale/zh_TW/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/zh_TW/foreman_remote_execution.po +356 -20
- 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 +30 -7
- data/webpack/JobWizard/JobWizard.scss +5 -0
- data/webpack/JobWizard/JobWizardConstants.js +2 -1
- data/webpack/JobWizard/__tests__/fixtures.js +13 -2
- data/webpack/JobWizard/__tests__/integration.test.js +6 -1
- data/webpack/JobWizard/autofill.js +34 -9
- data/webpack/JobWizard/index.js +0 -7
- data/webpack/JobWizard/steps/CategoryAndTemplate/CategoryAndTemplate.js +24 -15
- data/webpack/JobWizard/steps/CategoryAndTemplate/index.js +25 -7
- data/webpack/JobWizard/steps/HostsAndInputs/HostSearch.js +1 -1
- data/webpack/JobWizard/steps/HostsAndInputs/__tests__/HostsAndInputs.test.js +28 -0
- data/webpack/JobWizard/steps/Schedule/RepeatOn.js +1 -1
- data/webpack/JobWizard/steps/form/Formatter.js +18 -3
- data/webpack/JobWizard/steps/form/GroupedSelectField.js +7 -1
- data/webpack/__mocks__/foremanReact/components/Pagination.js +2 -0
- data/webpack/__mocks__/foremanReact/constants.js +1 -0
- data/webpack/global_index.js +4 -0
- 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 +22 -0
- data/webpack/react_app/components/RecentJobsCard/RecentJobsCard.js +6 -1
- 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/TargetingHostsHelpers.js +1 -1
- data/webpack/react_app/components/TargetingHosts/TargetingHostsPage.js +1 -6
- data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHostsPage.test.js.snap +1 -9
- data/webpack/react_app/components/TargetingHosts/index.js +2 -3
- data/webpack/react_app/extend/fillKebabItems.js +11 -0
- data/webpack/react_app/extend/fillRexFeaturesDropdown.js +11 -0
- metadata +24 -16
- data/app/views/templates/README.md +0 -6
- data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +0 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 71b09dd41d7ce39e709e4a45c2c78926d53151ed3625fcf2f4e0d739853cae8e
|
|
4
|
+
data.tar.gz: d01463507ceb52b52f661fa9a55ce413e2f824d74dfe50958063359f5a6fa8e9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2840a0f11ef02ba63f3a981075eae66e50e5fa0f7738518c3bf3a74f0bf5b7cf6be3273c2ebb999d00174244fb73295b3d0f8c74b663ef9839a91a16ad9c9878
|
|
7
|
+
data.tar.gz: 79a0dad8442b9135995a8bcbf62dfde4e112cd765950b61f45db0c490eac0d21e3cf843aea946c2450f69ab8f4d098fe26927b4eafe4cd0b7d6a1097ba04ceb9
|
data/README.md
CHANGED
|
@@ -24,6 +24,13 @@ management functionality with remote management functionality.
|
|
|
24
24
|
|
|
25
25
|
Check the Foreman manual [remote execution section](http://theforeman.org/plugins/foreman_remote_execution/)
|
|
26
26
|
|
|
27
|
+
## Compatibility
|
|
28
|
+
|
|
29
|
+
| Foreman Version | Plugin Version |
|
|
30
|
+
| --------------- | -------------- |
|
|
31
|
+
| >= 3.1 | ~> 5.0.0 |
|
|
32
|
+
| >= 3.2 | >= 6.0.0 |
|
|
33
|
+
|
|
27
34
|
## Simulated runs
|
|
28
35
|
There is an option to use an alternative `ScriptRunner` implementation. Instead of doing ssh connections it discards any input its given and gives back fake output.
|
|
29
36
|
|
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
|
|
@@ -3,10 +3,11 @@ class UiJobWizardController < ApplicationController
|
|
|
3
3
|
def categories
|
|
4
4
|
job_categories = resource_scope
|
|
5
5
|
.search_for("job_category ~ \"#{params[:search]}\"")
|
|
6
|
+
.where(:snippet => false)
|
|
6
7
|
.select(:job_category).distinct
|
|
7
8
|
.reorder(:job_category)
|
|
8
9
|
.pluck(:job_category)
|
|
9
|
-
render :json => {:job_categories =>job_categories, :with_katello => with_katello}
|
|
10
|
+
render :json => {:job_categories => job_categories, :with_katello => with_katello, default_category: default_category, default_template: default_template&.id}
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
def template
|
|
@@ -24,12 +25,22 @@ class UiJobWizardController < ApplicationController
|
|
|
24
25
|
template_inputs_with_foreign.map { |input| input.attributes.merge({:resource_type_tableize => input.resource_type&.tableize }) }
|
|
25
26
|
end
|
|
26
27
|
|
|
28
|
+
def default_category
|
|
29
|
+
default_template&.job_category
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def default_template
|
|
33
|
+
if (setting_value = Setting['remote_execution_form_job_template'])
|
|
34
|
+
JobTemplate.authorized(:view_job_templates).find_by :name => setting_value
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
27
38
|
def resource_name(nested_resource = nil)
|
|
28
39
|
nested_resource || 'job_template'
|
|
29
40
|
end
|
|
30
41
|
|
|
31
42
|
def with_katello
|
|
32
|
-
|
|
43
|
+
::Foreman::Plugin.installed? 'katello'
|
|
33
44
|
end
|
|
34
45
|
|
|
35
46
|
def resource_class
|
|
@@ -8,7 +8,7 @@ module ForemanRemoteExecution
|
|
|
8
8
|
|
|
9
9
|
def multiple_actions
|
|
10
10
|
res = super
|
|
11
|
-
res += [ [_('Schedule Remote Job'), new_job_invocation_path, false] ] if
|
|
11
|
+
res += [ [_('Schedule Remote Job'), new_job_invocation_path, false] ] if can_schedule_jobs?
|
|
12
12
|
res
|
|
13
13
|
end
|
|
14
14
|
|
|
@@ -22,20 +22,20 @@ module ForemanRemoteExecution
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
def rex_host_features(*
|
|
26
|
-
return unless
|
|
25
|
+
def rex_host_features(host, *_rest)
|
|
26
|
+
return [] unless can_execute_on_host?(host)
|
|
27
27
|
RemoteExecutionFeature.with_host_action_button.order(:label).map do |feature|
|
|
28
|
-
link_to(_('%s') % feature.name, job_invocations_path(:host_ids => [
|
|
28
|
+
link_to(_('%s') % feature.name, job_invocations_path(:host_ids => [host.id], :feature => feature.label), :method => :post)
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
def schedule_job_button(*
|
|
33
|
-
return unless
|
|
34
|
-
link_to(_('Schedule Remote Job'), new_job_invocation_path(:host_ids => [
|
|
32
|
+
def schedule_job_button(host, *_rest)
|
|
33
|
+
return unless can_execute_on_host?(host)
|
|
34
|
+
link_to(_('Schedule Remote Job'), new_job_invocation_path(:host_ids => [host.id]), :id => :run_button, :class => 'btn btn-default')
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def web_console_button(host, *args)
|
|
38
|
-
return
|
|
38
|
+
return if !authorized_for(permission: 'cockpit_hosts', auth_object: host) || !can_execute_on_infrastructure_host?(host)
|
|
39
39
|
|
|
40
40
|
url = SSHExecutionProvider.cockpit_url_for_host(host.name)
|
|
41
41
|
url ? link_to(_('Web Console'), url, :class => 'btn btn-default', :id => :'web-console-button', :target => '_new') : nil
|
|
@@ -46,6 +46,17 @@ module ForemanRemoteExecution
|
|
|
46
46
|
button_group(web_console_button(*args)))
|
|
47
47
|
super(*args)
|
|
48
48
|
end
|
|
49
|
-
end
|
|
50
49
|
|
|
50
|
+
def can_schedule_jobs?
|
|
51
|
+
authorized_for(controller: :job_invocations, action: :create)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def can_execute_on_host?(host)
|
|
55
|
+
can_schedule_jobs? && can_execute_on_infrastructure_host?(host)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def can_execute_on_infrastructure_host?(host)
|
|
59
|
+
!host.infrastructure_host? || User.current.can?(:execute_jobs_on_infrastructure_hosts)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
51
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
|
|
@@ -31,7 +31,7 @@ module RemoteExecutionHelper
|
|
|
31
31
|
|
|
32
32
|
if authorized_for(hash_for_host_path(host).merge(auth_object: host, permission: :view_hosts, authorizer: job_hosts_authorizer))
|
|
33
33
|
links << { title: _('Host detail'),
|
|
34
|
-
action: { href:
|
|
34
|
+
action: { href: current_host_details_path(host), 'data-method': 'get', id: "#{host.name}-actions-detail" } }
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
if authorized_for(hash_for_rerun_job_invocation_path(id: job_invocation, host_ids: [ host.id ], authorizer: 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
|
|
@@ -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
|
|
@@ -121,6 +125,10 @@ module ForemanRemoteExecution
|
|
|
121
125
|
@cached_rex_host_params_hash = nil
|
|
122
126
|
end
|
|
123
127
|
|
|
128
|
+
def infrastructure_host?
|
|
129
|
+
infrastructure_facet&.foreman_instance || infrastructure_facet&.smart_proxy_id
|
|
130
|
+
end
|
|
131
|
+
|
|
124
132
|
private
|
|
125
133
|
|
|
126
134
|
def extend_host_params_hash(params)
|
|
@@ -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
|
|
@@ -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,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class ScriptExecutionProvider < RemoteExecutionProvider
|
|
2
2
|
class << self
|
|
3
3
|
def proxy_command_options(template_invocation, host)
|
|
4
4
|
super.merge(:ssh_user => ssh_user(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,6 +52,10 @@ 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
61
|
def ssh_user(host)
|
|
@@ -62,5 +65,15 @@ class SSHExecutionProvider < RemoteExecutionProvider
|
|
|
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
|
data/app/models/targeting.rb
CHANGED
|
@@ -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>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<% if @hosts.any? -%>
|
|
8
8
|
<ul>
|
|
9
9
|
<% @hosts.each do |host| -%>
|
|
10
|
-
<li><%= link_to h(host.name),
|
|
10
|
+
<li><%= link_to h(host.name), current_host_details_path(host), :target => '_blank' %></li>
|
|
11
11
|
<% end -%>
|
|
12
12
|
|
|
13
13
|
<% if @additional > 0 -%>
|
|
@@ -30,7 +30,7 @@ end
|
|
|
30
30
|
<% if @host %>
|
|
31
31
|
<% proxy_id = @template_invocation_task.input[:proxy_id] %>
|
|
32
32
|
<h3>
|
|
33
|
-
<%= _('Target: ') %><%= link_to(@host.name,
|
|
33
|
+
<%= _('Target: ') %><%= link_to(@host.name, current_host_details_path(@host)) %>
|
|
34
34
|
<% if proxy_id && proxy = SmartProxy.find_by(id: proxy_id) %>
|
|
35
35
|
<%= _('using Smart Proxy') %> <%= link_to(proxy.name, smart_proxy_path(proxy)) %>
|
|
36
36
|
<% 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
|
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
f = Feature.where(:name => 'SSH').first_or_create
|
|
2
2
|
raise "Unable to create proxy feature: #{format_errors f}" if f.nil? || f.errors.any?
|
|
3
|
+
|
|
4
|
+
f = Feature.where(:name => 'Script').first_or_create
|
|
5
|
+
raise "Unable to create proxy feature: #{format_errors f}" if f.nil? || f.errors.any?
|