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.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/api/v2/job_invocations_controller.rb +1 -0
  3. data/app/controllers/foreman_remote_execution/concerns/api/v2/registration_controller_extensions.rb +5 -0
  4. data/app/controllers/ui_job_wizard_controller.rb +1 -1
  5. data/app/helpers/hosts_extensions_helper.rb +62 -0
  6. data/app/helpers/remote_execution_helper.rb +4 -3
  7. data/app/lib/actions/remote_execution/run_host_job.rb +5 -1
  8. data/app/lib/actions/remote_execution/run_hosts_job.rb +4 -0
  9. data/app/models/concerns/foreman_remote_execution/host_extensions.rb +5 -1
  10. data/app/models/concerns/foreman_remote_execution/nic_extensions.rb +6 -4
  11. data/app/models/concerns/foreman_remote_execution/smart_proxy_extensions.rb +1 -1
  12. data/app/models/job_invocation_composer.rb +7 -3
  13. data/app/models/job_template.rb +4 -1
  14. data/app/models/remote_execution_provider.rb +10 -1
  15. data/app/models/ssh_execution_provider.rb +20 -7
  16. data/app/services/default_proxy_proxy_selector.rb +1 -1
  17. data/app/services/remote_execution_proxy_selector.rb +7 -2
  18. data/app/views/api/v2/host/main.rabl +1 -0
  19. data/app/views/api/v2/job_invocations/base.json.rabl +1 -1
  20. data/app/views/dashboard/_latest-jobs.html.erb +1 -1
  21. data/app/views/job_invocations/_card_target_hosts.html.erb +8 -0
  22. data/app/views/job_invocations/_form.html.erb +2 -0
  23. data/app/views/templates/{ssh → script}/check_update.erb +2 -2
  24. data/app/views/templates/{ssh → script}/module_action.erb +2 -2
  25. data/app/views/templates/{ssh → script}/package_action.erb +5 -2
  26. data/app/views/templates/{ssh → script}/power_action.erb +2 -2
  27. data/app/views/templates/{ssh → script}/puppet_agent_disable.erb +2 -2
  28. data/app/views/templates/{ssh → script}/puppet_agent_enable.erb +2 -2
  29. data/app/views/templates/{ssh → script}/puppet_install_modules_from_forge.erb +2 -2
  30. data/app/views/templates/{ssh → script}/puppet_install_modules_from_git.erb +2 -2
  31. data/app/views/templates/{ssh → script}/puppet_run_once.erb +2 -2
  32. data/app/views/templates/{ssh → script}/run_command.erb +2 -2
  33. data/app/views/templates/{ssh → script}/service_action.erb +2 -2
  34. data/db/migrate/20220321101835_rename_ssh_provider_to_script.rb +29 -0
  35. data/db/migrate/20220331112719_add_ssh_user_to_job_invocation.rb +5 -0
  36. data/db/seeds.d/60-ssh_proxy_feature.rb +3 -0
  37. data/jsconfig.json +8 -0
  38. data/lib/foreman_remote_execution/engine.rb +10 -5
  39. data/lib/foreman_remote_execution/version.rb +1 -1
  40. data/locale/action_names.rb +3 -3
  41. data/locale/de/foreman_remote_execution.po +23 -23
  42. data/locale/en/foreman_remote_execution.po +23 -23
  43. data/locale/en_GB/foreman_remote_execution.po +23 -23
  44. data/locale/es/foreman_remote_execution.po +23 -23
  45. data/locale/foreman_remote_execution.pot +64 -66
  46. data/locale/fr/foreman_remote_execution.po +23 -23
  47. data/locale/ja/foreman_remote_execution.po +23 -23
  48. data/locale/ko/foreman_remote_execution.po +23 -23
  49. data/locale/pt_BR/foreman_remote_execution.po +23 -23
  50. data/locale/ru/foreman_remote_execution.po +23 -23
  51. data/locale/zh_CN/foreman_remote_execution.po +23 -23
  52. data/locale/zh_TW/foreman_remote_execution.po +23 -23
  53. data/package.json +6 -7
  54. data/test/unit/concerns/host_extensions_test.rb +2 -1
  55. data/test/unit/remote_execution_provider_test.rb +2 -0
  56. data/webpack/JobWizard/JobWizard.js +8 -2
  57. data/webpack/JobWizard/JobWizardConstants.js +2 -2
  58. data/webpack/JobWizard/__tests__/fixtures.js +8 -4
  59. data/webpack/JobWizard/steps/AdvancedFields/__tests__/AdvancedFields.test.js +2 -2
  60. data/webpack/JobWizard/steps/CategoryAndTemplate/CategoryAndTemplate.js +24 -15
  61. data/webpack/JobWizard/steps/HostsAndInputs/SelectGQL.js +2 -1
  62. data/webpack/JobWizard/steps/HostsAndInputs/SelectedChips.js +1 -1
  63. data/webpack/JobWizard/steps/HostsAndInputs/buildHostQuery.js +1 -1
  64. data/webpack/JobWizard/steps/HostsAndInputs/hostgroups.gql +1 -0
  65. data/webpack/JobWizard/steps/HostsAndInputs/hosts.gql +1 -0
  66. data/webpack/JobWizard/steps/ReviewDetails/index.js +1 -1
  67. data/webpack/JobWizard/steps/Schedule/__tests__/Schedule.test.js +15 -15
  68. data/webpack/JobWizard/steps/form/GroupedSelectField.js +7 -1
  69. data/webpack/JobWizard/steps/form/SearchSelect.js +0 -1
  70. data/webpack/__mocks__/foremanReact/common/globalIdHelpers.js +1 -0
  71. data/webpack/global_index.js +2 -4
  72. data/webpack/react_app/components/FeaturesDropdown/actions.js +13 -0
  73. data/webpack/react_app/components/FeaturesDropdown/constant.js +2 -0
  74. data/webpack/react_app/components/FeaturesDropdown/index.js +74 -0
  75. data/webpack/react_app/components/HostKebab/KebabItems.js +27 -0
  76. data/webpack/react_app/components/RecentJobsCard/RecentJobsCard.js +10 -5
  77. data/webpack/react_app/components/RecentJobsCard/RecentJobsTable.js +2 -2
  78. data/webpack/react_app/components/RecentJobsCard/constants.js +1 -0
  79. data/webpack/react_app/components/TargetingHosts/TargetingHostsConsts.js +1 -0
  80. data/webpack/react_app/components/TargetingHosts/TargetingHostsPage.js +8 -3
  81. data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHostsPage.test.js.snap +9 -1
  82. data/webpack/react_app/components/TargetingHosts/__tests__/fixtures.js +1 -4
  83. data/webpack/react_app/components/TargetingHosts/index.js +1 -0
  84. data/webpack/react_app/extend/Fills.js +48 -0
  85. metadata +25 -17
  86. data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +0 -62
  87. data/webpack/react_app/extend/fillRecentJobsCard.js +0 -11
  88. data/webpack/react_app/extend/fillregistrationAdvanced.js +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61d64bd14e3ce43367e26ad39ec10408baf8ec7920f45aa4ea1353340d3cf742
4
- data.tar.gz: 0ab68114a29368fa4c2a269287b875368cdcc31db63dd481df223a1f91a36cef
3
+ metadata.gz: e9183b3b81c3033d696f4aedf861cb5eed143fb9eacccb144a23d859e3ccae69
4
+ data.tar.gz: 4c7c6c09c84f3d4cbef2aaa8330b7bf048d42570e9319ad227c30abc5613770c
5
5
  SHA512:
6
- metadata.gz: 5d908f4f766c2b55bf6814035058b5faea29ba1ae3c61729275d2492e62b5f5aba2f60838d0b8383b9075f75daed15788d34ae1b2b9e091fea3ec26f812c670a
7
- data.tar.gz: 05d63bba759d31d2b85030bc8cb4e39faeb9af50e784374e016edb4637d84906f6527b533efd5600da969a1b2315f34392f5f994d1ae17bbc840f5a2dfdf04a9
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
 
@@ -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
@@ -40,7 +40,7 @@ class UiJobWizardController < ApplicationController
40
40
  end
41
41
 
42
42
  def with_katello
43
- !!defined?(::Katello)
43
+ ::Foreman::Plugin.installed? 'katello'
44
44
  end
45
45
 
46
46
  def resource_class
@@ -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 = template_invocation.template.provider_type.to_s
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
@@ -153,6 +153,10 @@ module Actions
153
153
  input[:proxy_batch_size]
154
154
  end
155
155
 
156
+ def self.cleanup_after
157
+ '90d'
158
+ end
159
+
156
160
  private
157
161
 
158
162
  def mail_notification_preference
@@ -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('SSH', false).values.flatten.uniq.map { |proxy| proxy.pubkey }.compact.uniq
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 set_execution_flag
13
- return unless primary? && host.present?
12
+ def move_execution_flag
13
+ return unless host && self.execution?
14
14
 
15
- self.execution = true if host.interfaces.detect(&:execution).nil?
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
@@ -11,7 +11,7 @@ module ForemanRemoteExecution
11
11
  end
12
12
 
13
13
  def update_pubkey
14
- return unless has_feature?('SSH')
14
+ return unless has_feature?(%w(SSH Script))
15
15
 
16
16
  key = ::ProxyAPI::RemoteExecutionSSH.new(:url => url).pubkey
17
17
  self.update_attribute(:pubkey, key) if key
@@ -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).utc.strftime('%Y-%m-%d %H:%M')
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) { |tempate| template.job_category } if @set_defaults
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
 
@@ -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
- Hash[result.map { |k| [ k, nil ] }]
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[:SSH]
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 SSHExecutionProvider < RemoteExecutionProvider
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
- _('SSH')
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
- proxy_selector = ::RemoteExecutionProxySelector.new
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
@@ -1,6 +1,6 @@
1
1
  object @job_invocation
2
2
 
3
- attributes :id, :description, :job_category, :targeting_id, :status, :start_at, :status_label
3
+ attributes :id, :description, :job_category, :targeting_id, :status, :start_at, :status_label, :ssh_user
4
4
 
5
5
  node do |invocation|
6
6
  {
@@ -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: Check Update - SSH Default
3
+ name: Check Update - Script Default
4
4
  model: JobTemplate
5
5
  job_category: Packages
6
6
  description_format: "Check for package updates"
7
- provider_type: SSH
7
+ provider_type: script
8
8
  %>
9
9
 
10
10
  <%
@@ -1,10 +1,10 @@
1
1
  <%#
2
2
  kind: job_template
3
- name: Module Action - SSH Default
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: SSH
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 - SSH Default
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: SSH
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 - SSH Default
3
+ name: Power Action - Script Default
4
4
  model: JobTemplate
5
5
  job_category: Power
6
6
  description_format: '%{action} host'
7
- provider_type: SSH
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 - SSH Default
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: SSH
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 - SSH Default
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: SSH
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 - SSH Default
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: SSH
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 - SSH Default
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: SSH
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 - SSH Default
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: SSH
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 - SSH Default
3
+ name: Run Command - Script Default
4
4
  model: JobTemplate
5
5
  job_category: Commands
6
6
  description_format: "Run %{command}"
7
- provider_type: SSH
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 - SSH Default
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: SSH
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
@@ -0,0 +1,5 @@
1
+ class AddSshUserToJobInvocation < ActiveRecord::Migration[6.0]
2
+ def change
3
+ add_column :job_invocations, :ssh_user, :string
4
+ end
5
+ end