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.
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