foreman_remote_execution 5.0.8 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/app/controllers/foreman_remote_execution/concerns/api/v2/registration_controller_extensions.rb +0 -5
  4. data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +9 -20
  5. data/app/helpers/remote_execution_helper.rb +3 -4
  6. data/app/lib/actions/remote_execution/run_host_job.rb +2 -0
  7. data/app/lib/foreman_remote_execution/renderer/scope/input.rb +1 -1
  8. data/app/models/concerns/foreman_remote_execution/host_extensions.rb +0 -8
  9. data/app/models/concerns/foreman_remote_execution/nic_extensions.rb +4 -6
  10. data/app/models/job_invocation.rb +2 -0
  11. data/app/models/job_invocation_composer.rb +1 -1
  12. data/app/models/job_template.rb +3 -1
  13. data/app/models/targeting.rb +1 -1
  14. data/app/views/dashboard/_latest-jobs.html.erb +1 -1
  15. data/app/views/job_invocations/_preview_hosts_list.html.erb +1 -1
  16. data/app/views/job_templates/_custom_tabs.html.erb +4 -9
  17. data/app/views/template_invocations/show.html.erb +7 -1
  18. data/app/views/templates/ssh/package_action.erb +0 -3
  19. data/lib/foreman_remote_execution/engine.rb +2 -7
  20. data/lib/foreman_remote_execution/version.rb +1 -1
  21. data/package.json +7 -6
  22. data/test/unit/concerns/host_extensions_test.rb +1 -2
  23. data/test/unit/job_invocation_report_template_test.rb +1 -1
  24. data/test/unit/targeting_test.rb +1 -1
  25. data/webpack/JobWizard/steps/form/GroupedSelectField.js +0 -2
  26. data/webpack/global_index.js +0 -4
  27. data/webpack/react_app/components/RecentJobsCard/RecentJobsCard.js +1 -6
  28. data/webpack/react_app/components/RecentJobsCard/RecentJobsTable.js +2 -2
  29. data/webpack/react_app/components/RecentJobsCard/constants.js +0 -1
  30. metadata +3 -13
  31. data/app/views/api/v2/host/main.rabl +0 -1
  32. data/jsconfig.json +0 -8
  33. data/test/unit/api_params_test.rb +0 -33
  34. data/webpack/react_app/components/FeaturesDropdown/actions.js +0 -13
  35. data/webpack/react_app/components/FeaturesDropdown/constant.js +0 -2
  36. data/webpack/react_app/components/FeaturesDropdown/index.js +0 -74
  37. data/webpack/react_app/components/HostKebab/KebabItems.js +0 -27
  38. data/webpack/react_app/extend/fillKebabItems.js +0 -11
  39. data/webpack/react_app/extend/fillRexFeaturesDropdown.js +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a2e413a1866d81800d45a4e108897ffb2c219abbe3db4273f7276f44ae94267
4
- data.tar.gz: da9d69d1268afa1e3a7acd289f3a8c4163364eb06d54eb0a1df780300a889e45
3
+ metadata.gz: 831ec5aca2ec4aaa3df1229f7addd9a968c7c49b0fc49a15253e33d2ab0f5689
4
+ data.tar.gz: 07a4f17f0d4d694c4b927291ee8e55dafd839cf902a9ef06c79b227fdf65760f
5
5
  SHA512:
6
- metadata.gz: 77af52b52f1e49a2f855cec4ad19209248df85915c9411630a842e4446dd0eb9c0f73acccf4d91a42730d32cf6bb6caed916a351e8ed8c6a8211c8836fc281b2
7
- data.tar.gz: 917f3540ee35e95fb431ebc37e69e852ffd6fbbcd82e5ddbfb6b5ddfc504f85ce1950ab143e7f40d7c481f56a87b3a91887cb39bafd9bcfd8df73b7fe29c043b
6
+ metadata.gz: 75fd11cfe45b5223a2427561c0859c39f19923535283fa919927af9b4ffd67ea56a4c9b791632e73c72c4dff1946f2e1046cb10a1f84ed7dae0e686daff2d90d
7
+ data.tar.gz: 03557c309e25a902c0def6e7575ad74a02e724482da823b4580f4bbe9b80358eadb2e0781b832f45a2e9101196447edf887476fa79782a3d6ee125640dccd92a
data/Gemfile CHANGED
@@ -2,4 +2,4 @@ source 'http://rubygems.org'
2
2
 
3
3
  gemspec :name => 'foreman_remote_execution'
4
4
 
5
- gem 'theforeman-rubocop', '~> 0.1.0.pre'
5
+ gem 'theforeman-rubocop', '~> 0.1.1'
@@ -13,7 +13,6 @@ module ForemanRemoteExecution
13
13
 
14
14
  def host_setup_extension
15
15
  remote_execution_interface
16
- reset_host_known_keys! unless @host.new_record?
17
16
  super
18
17
  end
19
18
 
@@ -22,10 +21,6 @@ module ForemanRemoteExecution
22
21
 
23
22
  @host.set_execution_interface(params['remote_execution_interface'])
24
23
  end
25
-
26
- def reset_host_known_keys!
27
- @host.host_proxy_invocations.destroy_all
28
- end
29
24
  end
30
25
  end
31
26
  end
@@ -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 can_schedule_jobs?
11
+ res += [ [_('Schedule Remote Job'), new_job_invocation_path, false] ] if authorized_for(controller: :job_invocations, action: :new)
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(host, *_rest)
26
- return [] unless can_execute_on_host?(host)
25
+ def rex_host_features(*args)
26
+ return unless authorized_for(controller: :job_invocations, action: :create)
27
27
  RemoteExecutionFeature.with_host_action_button.order(:label).map do |feature|
28
- link_to(_('%s') % feature.name, job_invocations_path(:host_ids => [host.id], :feature => feature.label), :method => :post)
28
+ link_to(_('%s') % feature.name, job_invocations_path(:host_ids => [args.first.id], :feature => feature.label), :method => :post)
29
29
  end
30
30
  end
31
31
 
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')
32
+ def schedule_job_button(*args)
33
+ return unless authorized_for(controller: :job_invocations, action: :new)
34
+ link_to(_('Schedule Remote Job'), new_job_invocation_path(:host_ids => [args.first.id]), :id => :run_button, :class => 'btn btn-default')
35
35
  end
36
36
 
37
37
  def web_console_button(host, *args)
38
- return if !authorized_for(permission: 'cockpit_hosts', auth_object: host) || !can_execute_on_infrastructure_host?(host)
38
+ return unless authorized_for(permission: 'cockpit_hosts', auth_object: 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,17 +46,6 @@ module ForemanRemoteExecution
46
46
  button_group(web_console_button(*args)))
47
47
  super(*args)
48
48
  end
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
49
  end
50
+
62
51
  end
@@ -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: current_host_details_path(host), 'data-method': 'get', id: "#{host.name}-actions-detail" } }
34
+ action: { href: host_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,10 +147,9 @@ module RemoteExecutionHelper
147
147
  end
148
148
  end
149
149
 
150
- def invocation_description(invocation, keep_tooltip: true)
150
+ def invocation_description(invocation)
151
151
  description = invocation.description.try(:capitalize) || invocation.job_category
152
- description = trunc_with_tooltip(description, 80) if keep_tooltip
153
- description
152
+ trunc_with_tooltip(description, 80)
154
153
  end
155
154
 
156
155
  def invocation_result(invocation, key)
@@ -42,6 +42,8 @@ module Actions
42
42
 
43
43
  provider_type = template_invocation.template.provider_type.to_s
44
44
  proxy = determine_proxy!(proxy_selector, provider_type, host)
45
+ link!(proxy)
46
+ input[:proxy_id] = proxy.id
45
47
 
46
48
  renderer = InputTemplateRenderer.new(template_invocation.template, host, template_invocation)
47
49
  script = renderer.render
@@ -98,7 +98,7 @@ module ForemanRemoteExecution
98
98
  def input(name)
99
99
  return template_input_values[name.to_s] if template_input_values.key?(name.to_s)
100
100
 
101
- input = find_by_name(template.template_inputs_with_foreign, name) # rubocop:disable Rails/DynamicFindBy
101
+ input = find_by_name(template.template_inputs_with_foreign, name)
102
102
  if input
103
103
  @preview ? input.preview(self) : input.value(self)
104
104
  else
@@ -46,10 +46,6 @@ 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
-
53
49
  def execution_status(options = {})
54
50
  @execution_status ||= get_status(HostStatus::ExecutionStatus).to_status(options)
55
51
  end
@@ -125,10 +121,6 @@ module ForemanRemoteExecution
125
121
  @cached_rex_host_params_hash = nil
126
122
  end
127
123
 
128
- def infrastructure_host?
129
- infrastructure_facet&.foreman_instance || infrastructure_facet&.smart_proxy_id
130
- end
131
-
132
124
  private
133
125
 
134
126
  def extend_host_params_hash(params)
@@ -3,18 +3,16 @@ module ForemanRemoteExecution
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
+ before_validation :set_execution_flag
6
7
  validate :exclusive_execution_interface
7
- before_validation :move_execution_flag
8
8
  end
9
9
 
10
10
  private
11
11
 
12
- def move_execution_flag
13
- return unless host && self.execution?
12
+ def set_execution_flag
13
+ return unless primary? && host.present?
14
14
 
15
- host.interfaces
16
- .select { |i| i.execution? && i != self }
17
- .each { |i| i.execution = false }
15
+ self.execution = true if host.interfaces.detect(&:execution).nil?
18
16
  end
19
17
 
20
18
  def exclusive_execution_interface
@@ -15,8 +15,10 @@ class JobInvocation < ApplicationRecord
15
15
 
16
16
  belongs_to :targeting, :dependent => :destroy
17
17
  has_many :all_template_invocations, :inverse_of => :job_invocation, :dependent => :destroy, :class_name => 'TemplateInvocation'
18
+ # rubocop:disable Rails/HasManyOrHasOneDependent
18
19
  has_many :template_invocations, -> { where('template_invocations.host_id IS NOT NULL') }, :inverse_of => :job_invocation
19
20
  has_many :pattern_template_invocations, -> { where('template_invocations.host_id IS NULL') }, :inverse_of => :job_invocation, :class_name => 'TemplateInvocation'
21
+ # rubocop:enable Rails/HasManyOrHasOneDependent
20
22
  has_many :pattern_templates, :through => :pattern_template_invocations, :source => :template
21
23
 
22
24
  validates :targeting, :presence => true
@@ -217,7 +217,7 @@ class JobInvocationComposer
217
217
  def format_datetime(datetime)
218
218
  return datetime if datetime.blank?
219
219
 
220
- Time.zone.parse(datetime).strftime('%Y-%m-%d %H:%M')
220
+ Time.parse(datetime).utc.strftime('%Y-%m-%d %H:%M')
221
221
  end
222
222
  end
223
223
 
@@ -17,8 +17,10 @@ class JobTemplate < ::Template
17
17
 
18
18
  has_many :audits, :as => :auditable, :class_name => Audited.audit_class.name, :dependent => :nullify
19
19
  has_many :all_template_invocations, :dependent => :destroy, :foreign_key => 'template_id', :class_name => 'TemplateInvocation'
20
+ # rubocop:disable Rails/HasManyOrHasOneDependent
20
21
  has_many :template_invocations, -> { where('host_id IS NOT NULL') }, :foreign_key => 'template_id'
21
22
  has_many :pattern_template_invocations, -> { where('host_id IS NULL') }, :foreign_key => 'template_id', :class_name => 'TemplateInvocation'
23
+ # rubocop:enable Rails/HasManyOrHasOneDependent
22
24
  has_many :remote_execution_features, :dependent => :nullify
23
25
 
24
26
  # these can't be shared in parent class, scoped search can't handle STI properly
@@ -192,7 +194,7 @@ class JobTemplate < ::Template
192
194
  end
193
195
 
194
196
  def default_input_values(ignore_keys)
195
- result = self.template_inputs_with_foreign.select { |ti| !ti.required? && ti.user_template_input? }.map { |ti| ti.name.to_s }
197
+ result = self.template_inputs_with_foreign.select { |ti| !ti.required? && ti.input_type == 'user' }.map { |ti| ti.name.to_s }
196
198
  result -= ignore_keys.map(&:to_s)
197
199
  Hash[result.map { |k| [ k, nil ] }]
198
200
  end
@@ -67,7 +67,7 @@ class Targeting < ApplicationRecord
67
67
  return '' if ids.empty?
68
68
 
69
69
  hosts = Host.execution_scope.where(:id => ids).distinct.pluck(:name)
70
- hosts.any? ? "name ^ (#{hosts.join(', ')})" : ''
70
+ "name ^ (#{hosts.join(', ')})"
71
71
  end
72
72
 
73
73
  def resolved?
@@ -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, keep_tooltip: false), 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), 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), current_host_details_path(host), :target => '_blank' %></li>
10
+ <li><%= link_to h(host.name), host_path(host), :target => '_blank' %></li>
11
11
  <% end -%>
12
12
 
13
13
  <% if @additional > 0 -%>
@@ -1,14 +1,9 @@
1
1
  <div class="tab-pane" id="template_job">
2
2
 
3
- <%= field(f, :job_category, :label => _('Job category')) do %>
4
- <%= auto_complete_search(:job_category,
5
- f.object.job_category,
6
- :placeholder => _("Job category") + ' ...',
7
- :name => 'job_template[job_category]',
8
- :id => 'search',
9
- :disabled => @template.locked?) %>
10
- <% end %>
11
-
3
+ <%= autocomplete_f(f, :job_category,
4
+ :search_query => '',
5
+ :placeholder => _("Job category") + ' ...',
6
+ :disabled => @template.locked?) %>
12
7
  <%= text_f f, :description_format,
13
8
  :disabled => @template.locked?,
14
9
  :label_help => description_format_help %>
@@ -28,7 +28,13 @@ end
28
28
  </div>
29
29
  </div>
30
30
  <% if @host %>
31
- <h3><%= _('Target: ') %><%= link_to(@host.name, current_host_details_path(@host)) %></h3>
31
+ <% proxy_id = @template_invocation_task.input[:proxy_id] %>
32
+ <h3>
33
+ <%= _('Target: ') %><%= link_to(@host.name, host_path(@host)) %>
34
+ <% if proxy_id && proxy = SmartProxy.find_by(id: proxy_id) %>
35
+ <%= _('using Smart Proxy') %> <%= link_to(proxy.name, smart_proxy_path(proxy)) %>
36
+ <% end %>
37
+ </h3>
32
38
 
33
39
  <div class="preview hidden">
34
40
  <%= preview_box(@template_invocation, @host) %>
@@ -69,11 +69,8 @@ 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
74
72
  RETVAL=0
75
73
  fi
76
-
77
74
  return $RETVAL
78
75
  }
79
76
  <% end -%>
@@ -152,7 +152,7 @@ module ForemanRemoteExecution
152
152
  setting 'remote_execution_job_invocation_report_template',
153
153
  type: :string,
154
154
  description: N_('Select a report template used for generating a report for a particular remote execution job'),
155
- default: 'Jobs - Invocation report template',
155
+ default: 'Job invocation - report template',
156
156
  full_name: N_('Job Invocation Report Template'),
157
157
  collection: proc { ForemanRemoteExecution.job_invocation_report_templates_select }
158
158
  end
@@ -214,11 +214,7 @@ module ForemanRemoteExecution
214
214
  role 'Remote Execution User', USER_PERMISSIONS, 'Role with permissions to run remote execution jobs against hosts'
215
215
  role 'Remote Execution Manager', MANAGER_PERMISSIONS, 'Role with permissions to manage job templates, remote execution features, cancel jobs and view audit logs'
216
216
 
217
- add_all_permissions_to_default_roles(except: [:execute_jobs_on_infrastructure_hosts])
218
- add_permissions_to_default_roles({
219
- Role::MANAGER => [:execute_jobs_on_infrastructure_hosts],
220
- Role::SITE_MANAGER => USER_PERMISSIONS + [:execute_jobs_on_infrastructure_hosts],
221
- })
217
+ add_all_permissions_to_default_roles
222
218
 
223
219
  # add menu entry
224
220
  menu :top_menu, :job_templates,
@@ -265,7 +261,6 @@ module ForemanRemoteExecution
265
261
  extend_rabl_template 'api/v2/smart_proxies/main', 'api/v2/smart_proxies/pubkey'
266
262
  extend_rabl_template 'api/v2/interfaces/main', 'api/v2/interfaces/execution_flag'
267
263
  extend_rabl_template 'api/v2/subnets/show', 'api/v2/subnets/remote_execution_proxies'
268
- extend_rabl_template 'api/v2/hosts/main', 'api/v2/host/main'
269
264
  parameter_filter ::Subnet, :remote_execution_proxy_ids
270
265
  describe_host { overview_buttons_provider :host_overview_buttons }
271
266
 
@@ -1,3 +1,3 @@
1
1
  module ForemanRemoteExecution
2
- VERSION = '5.0.8'.freeze
2
+ VERSION = '5.1.0'.freeze
3
3
  end
data/package.json CHANGED
@@ -21,19 +21,20 @@
21
21
  },
22
22
  "devDependencies": {
23
23
  "@babel/core": "^7.7.0",
24
- "@theforeman/builder": "^10.1.0",
25
- "@theforeman/eslint-plugin-foreman": "^10.1.0",
26
- "@theforeman/stories": "^10.1.0",
27
- "@theforeman/test": "^10.1.0",
28
- "@theforeman/vendor-dev": "^10.1.0",
24
+ "@theforeman/builder": "^8.16.0",
25
+ "@theforeman/eslint-plugin-foreman": "^8.16.0",
26
+ "@theforeman/stories": "^8.16.0",
27
+ "@theforeman/test": "^8.16.0",
28
+ "@theforeman/vendor-dev": "^8.16.0",
29
29
  "babel-eslint": "^10.0.0",
30
30
  "eslint": "^6.8.0",
31
31
  "prettier": "^1.19.1",
32
+ "@patternfly/react-catalog-view-extension": "^4.8.126",
32
33
  "redux-mock-store": "^1.2.2",
33
34
  "graphql-tag": "^2.11.0",
34
35
  "graphql": "^15.5.0"
35
36
  },
36
37
  "peerDependencies": {
37
- "@theforeman/vendor": "^10.1.0"
38
+ "@theforeman/vendor": "^8.16.0"
38
39
  }
39
40
  }
@@ -67,8 +67,7 @@ class ForemanRemoteExecutionHostExtensionsTest < ActiveSupport::TestCase
67
67
  it 'should only have one execution interface' do
68
68
  host.interfaces << FactoryBot.build(:nic_managed)
69
69
  host.interfaces.each { |interface| interface.execution = true }
70
- _(host).must_be :valid?
71
- _(host.interfaces.count(&:execution?)).must_equal 1
70
+ _(host).wont_be :valid?
72
71
  end
73
72
 
74
73
  it 'returns the execution interface' do
@@ -9,7 +9,7 @@ class JobReportTemplateTest < ActiveSupport::TestCase
9
9
 
10
10
  context 'with valid job invocation report template' do
11
11
  let(:job_invocation_template) do
12
- file_path = File.read(File.expand_path(Rails.root + "app/views/unattended/report_templates/jobs_-_invocation_report_template.erb"))
12
+ file_path = File.read(File.expand_path(Rails.root + "app/views/unattended/report_templates/job_invocation_-_report_template.erb"))
13
13
  template = ReportTemplate.import_without_save("Job Invocation Report Template", file_path)
14
14
  template.save!
15
15
  template
@@ -61,7 +61,7 @@ class TargetingTest < ActiveSupport::TestCase
61
61
  users(:one).destroy
62
62
  end
63
63
 
64
- it { assert targeting.reload.user.nil? }
64
+ it { assert_nil targeting.reload.user }
65
65
  it do
66
66
  -> { targeting.resolve_hosts! }.must_raise(Foreman::Exception)
67
67
  end
@@ -69,8 +69,6 @@ export const GroupedSelectField = ({
69
69
  className="without_select2"
70
70
  onClear={onClear}
71
71
  menuAppendTo={() => document.body}
72
- aria-labelledby={fieldId}
73
- toggleAriaLabel={`${label} toggle`}
74
72
  {...props}
75
73
  >
76
74
  {options}
@@ -2,13 +2,9 @@ import { registerRoutes } from 'foremanReact/routes/RoutingService';
2
2
  import routes from './Routes/routes';
3
3
  import fillregistrationAdvanced from './react_app/extend/fillregistrationAdvanced';
4
4
  import fillRecentJobsCard from './react_app/extend/fillRecentJobsCard';
5
- import fillFeaturesDropdown from './react_app/extend/fillRexFeaturesDropdown';
6
- import fillKebabItems from './react_app/extend/fillKebabItems';
7
5
  import registerReducers from './react_app/extend/reducers';
8
6
 
9
7
  registerReducers();
10
8
  registerRoutes('foreman_remote_execution', routes);
11
- fillFeaturesDropdown();
12
9
  fillRecentJobsCard();
13
10
  fillregistrationAdvanced();
14
- fillKebabItems();
@@ -52,12 +52,7 @@ const RecentJobsCard = ({ hostDetails: { name, id } }) => {
52
52
  </DropdownItem>,
53
53
  ]}
54
54
  >
55
- <Tabs
56
- mountOnEnter
57
- unmountOnExit
58
- activeKey={activeTab}
59
- onSelect={handleTabClick}
60
- >
55
+ <Tabs mountOnEnter activeKey={activeTab} onSelect={handleTabClick}>
61
56
  <Tab
62
57
  eventKey={FINISHED_TAB}
63
58
  title={<TabTitleText>{__('Finished')}</TabTitleText>}
@@ -19,7 +19,7 @@ import { translate as __ } from 'foremanReact/common/I18n';
19
19
  import { foremanUrl } from 'foremanReact/common/helpers';
20
20
 
21
21
  import JobStatusIcon from './JobStatusIcon';
22
- import { JOB_API_URL, JOBS_IN_CARD, RECENT_JOBS_KEY } from './constants';
22
+ import { JOB_API_URL, JOBS_IN_CARD } from './constants';
23
23
 
24
24
  const RecentJobsTable = ({ status, hostId }) => {
25
25
  const jobsUrl =
@@ -30,7 +30,7 @@ const RecentJobsTable = ({ status, hostId }) => {
30
30
  const {
31
31
  response: { results: jobs },
32
32
  status: responseStatus,
33
- } = useAPI('get', jobsUrl, RECENT_JOBS_KEY);
33
+ } = useAPI('get', jobsUrl);
34
34
 
35
35
  return (
36
36
  <DataList aria-label="recent-jobs-table" isCompact>
@@ -10,4 +10,3 @@ export const JOB_BASE_URL = '/job_invocations?search=host+%3D+';
10
10
  export const JOB_API_URL =
11
11
  '/api/job_invocations?order=start_at+DESC&search=targeted_host_id%3D';
12
12
  export const JOBS_IN_CARD = 3;
13
- export const RECENT_JOBS_KEY = { key: 'RECENT_JOBS_KEY' };
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_remote_execution
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.8
4
+ version: 5.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Foreman Remote Execution team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-04 00:00:00.000000000 Z
11
+ date: 2021-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deface
@@ -201,7 +201,6 @@ files:
201
201
  - app/views/api/v2/foreign_input_sets/index.json.rabl
202
202
  - app/views/api/v2/foreign_input_sets/main.json.rabl
203
203
  - app/views/api/v2/foreign_input_sets/show.json.rabl
204
- - app/views/api/v2/host/main.rabl
205
204
  - app/views/api/v2/interfaces/execution_flag.json.rabl
206
205
  - app/views/api/v2/job_invocations/base.json.rabl
207
206
  - app/views/api/v2/job_invocations/create.json.rabl
@@ -335,7 +334,6 @@ files:
335
334
  - extra/cockpit/foreman-cockpit.service
336
335
  - extra/cockpit/settings.yml.example
337
336
  - foreman_remote_execution.gemspec
338
- - jsconfig.json
339
337
  - lib/foreman_remote_execution.rb
340
338
  - lib/foreman_remote_execution/engine.rb
341
339
  - lib/foreman_remote_execution/version.rb
@@ -388,7 +386,6 @@ files:
388
386
  - test/test_plugin_helper.rb
389
387
  - test/unit/actions/run_host_job_test.rb
390
388
  - test/unit/actions/run_hosts_job_test.rb
391
- - test/unit/api_params_test.rb
392
389
  - test/unit/concerns/foreman_tasks_cleaner_extensions_test.rb
393
390
  - test/unit/concerns/host_extensions_test.rb
394
391
  - test/unit/concerns/nic_extensions_test.rb
@@ -479,10 +476,6 @@ files:
479
476
  - webpack/global_index.js
480
477
  - webpack/helpers.js
481
478
  - webpack/index.js
482
- - webpack/react_app/components/FeaturesDropdown/actions.js
483
- - webpack/react_app/components/FeaturesDropdown/constant.js
484
- - webpack/react_app/components/FeaturesDropdown/index.js
485
- - webpack/react_app/components/HostKebab/KebabItems.js
486
479
  - webpack/react_app/components/RecentJobsCard/JobStatusIcon.js
487
480
  - webpack/react_app/components/RecentJobsCard/RecentJobsCard.js
488
481
  - webpack/react_app/components/RecentJobsCard/RecentJobsTable.js
@@ -515,9 +508,7 @@ files:
515
508
  - webpack/react_app/components/jobInvocations/AggregateStatus/index.js
516
509
  - webpack/react_app/components/jobInvocations/AggregateStatus/index.test.js
517
510
  - webpack/react_app/components/jobInvocations/index.js
518
- - webpack/react_app/extend/fillKebabItems.js
519
511
  - webpack/react_app/extend/fillRecentJobsCard.js
520
- - webpack/react_app/extend/fillRexFeaturesDropdown.js
521
512
  - webpack/react_app/extend/fillregistrationAdvanced.js
522
513
  - webpack/react_app/extend/reducers.js
523
514
  - webpack/react_app/redux/actions/jobInvocations/index.js
@@ -546,7 +537,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
546
537
  - !ruby/object:Gem::Version
547
538
  version: '0'
548
539
  requirements: []
549
- rubygems_version: 3.2.26
540
+ rubygems_version: 3.1.2
550
541
  signing_key:
551
542
  specification_version: 4
552
543
  summary: A plugin bringing remote execution to the Foreman, completing the config
@@ -573,7 +564,6 @@ test_files:
573
564
  - test/test_plugin_helper.rb
574
565
  - test/unit/actions/run_host_job_test.rb
575
566
  - test/unit/actions/run_hosts_job_test.rb
576
- - test/unit/api_params_test.rb
577
567
  - test/unit/concerns/foreman_tasks_cleaner_extensions_test.rb
578
568
  - test/unit/concerns/host_extensions_test.rb
579
569
  - test/unit/concerns/nic_extensions_test.rb
@@ -1 +0,0 @@
1
- attributes :cockpit_url
data/jsconfig.json DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "es6",
4
- "paths": {
5
- "foremanReact/*": ["../foreman/webpack/assets/javascripts/react_app/*"]
6
- }
7
- }
8
- }
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'test_plugin_helper'
4
-
5
- class ApiParamsTest < ActiveSupport::TestCase
6
- describe '#format_datetime' do
7
- let(:params) { JobInvocationComposer::ApiParams.allocate }
8
-
9
- it 'leaves empty string as is' do
10
- assert_equal params.send(:format_datetime, ''), ''
11
- end
12
-
13
- it 'honors explicitly supplied time zone' do
14
- in_time_zone(ActiveSupport::TimeZone['America/New_York']) do
15
- assert_equal '2022-07-08 08:53', params.send(:format_datetime, '2022-07-08 12:53:20 UTC')
16
- end
17
- end
18
-
19
- it 'implicitly honors current user\'s time zone' do
20
- in_time_zone(ActiveSupport::TimeZone['America/New_York']) do
21
- assert_equal '2022-07-08 12:53', params.send(:format_datetime, '2022-07-08 12:53:20')
22
- end
23
- end
24
- end
25
-
26
- def in_time_zone(zone)
27
- old_tz = Time.zone
28
- Time.zone = zone
29
- yield
30
- ensure
31
- Time.zone = old_tz
32
- end
33
- end
@@ -1,13 +0,0 @@
1
- import { foremanUrl } from 'foremanReact/common/helpers';
2
- import { sprintf, translate as __ } from 'foremanReact/common/I18n';
3
- import { post } from 'foremanReact/redux/API';
4
-
5
- export const runFeature = (hostId, feature, label) => dispatch => {
6
- const url = foremanUrl(
7
- `/job_invocations?feature=${feature}&host_ids%5B%5D=${hostId}`
8
- );
9
-
10
- const successToast = () => sprintf(__('%s job has been invoked'), label);
11
- const errorToast = ({ message }) => message;
12
- dispatch(post({ key: feature.toUpperCase(), url, successToast, errorToast }));
13
- };
@@ -1,2 +0,0 @@
1
- export const REX_FEATURES_API = '/api/remote_execution_features';
2
- export const NEW_JOB_PAGE = '/job_invocations/new?host_ids%5B%5D';
@@ -1,74 +0,0 @@
1
- import PropTypes from 'prop-types';
2
- import React, { useState } from 'react';
3
- import { useDispatch } from 'react-redux';
4
- import {
5
- DropdownItem,
6
- Dropdown,
7
- DropdownToggle,
8
- DropdownToggleAction,
9
- } from '@patternfly/react-core';
10
- import { push } from 'connected-react-router';
11
-
12
- import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
13
- import { translate as __ } from 'foremanReact/common/I18n';
14
- import { foremanUrl } from 'foremanReact/common/helpers';
15
- import { STATUS } from 'foremanReact/constants';
16
-
17
- import { REX_FEATURES_API, NEW_JOB_PAGE } from './constant';
18
- import { runFeature } from './actions';
19
-
20
- const FeaturesDropdown = ({ hostId }) => {
21
- const [isOpen, setIsOpen] = useState(false);
22
- const {
23
- response: { results: features },
24
- status,
25
- } = useAPI('get', foremanUrl(REX_FEATURES_API));
26
-
27
- const dispatch = useDispatch();
28
- const dropdownItems = features
29
- ?.filter(feature => feature.host_action_button)
30
- ?.map(({ name, label, id, description }) => (
31
- <DropdownItem
32
- onClick={() => dispatch(runFeature(hostId, label, name))}
33
- key={id}
34
- description={description}
35
- >
36
- {name}
37
- </DropdownItem>
38
- ));
39
- const scheduleJob = [
40
- <DropdownToggleAction
41
- onClick={() => dispatch(push(`${NEW_JOB_PAGE}=${hostId}`))}
42
- key="schedule-job-action"
43
- >
44
- {__('Schedule a job')}
45
- </DropdownToggleAction>,
46
- ];
47
-
48
- return (
49
- <Dropdown
50
- alignments={{ default: 'right' }}
51
- onSelect={() => setIsOpen(false)}
52
- toggle={
53
- <DropdownToggle
54
- splitButtonItems={scheduleJob}
55
- toggleVariant="primary"
56
- onToggle={() => setIsOpen(prev => !prev)}
57
- isDisabled={status === STATUS.PENDING}
58
- splitButtonVariant="action"
59
- />
60
- }
61
- isOpen={isOpen}
62
- dropdownItems={dropdownItems}
63
- />
64
- );
65
- };
66
-
67
- FeaturesDropdown.propTypes = {
68
- hostId: PropTypes.number,
69
- };
70
- FeaturesDropdown.defaultProps = {
71
- hostId: undefined,
72
- };
73
-
74
- export default FeaturesDropdown;
@@ -1,27 +0,0 @@
1
- import React from 'react';
2
- import { useSelector } from 'react-redux';
3
- import { DropdownItem } from '@patternfly/react-core';
4
- import { CodeIcon } from '@patternfly/react-icons';
5
- import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors';
6
- import { translate as __ } from 'foremanReact/common/I18n';
7
- import { HOST_DETAILS_KEY } from 'foremanReact/components/HostDetails/consts';
8
-
9
- const HostKebabItems = () => {
10
- const { cockpit_url: consoleUrl } = useSelector(state =>
11
- selectAPIResponse(state, HOST_DETAILS_KEY)
12
- );
13
-
14
- if (!consoleUrl) return null;
15
- return (
16
- <DropdownItem
17
- icon={<CodeIcon />}
18
- href={consoleUrl}
19
- target="_blank"
20
- rel="noreferrer"
21
- >
22
- {__('Web Console')}
23
- </DropdownItem>
24
- );
25
- };
26
-
27
- export default HostKebabItems;
@@ -1,11 +0,0 @@
1
- import React from 'react';
2
- import { addGlobalFill } from 'foremanReact/components/common/Fill/GlobalFill';
3
- import KebabItems from '../components/HostKebab/KebabItems';
4
-
5
- export default () =>
6
- addGlobalFill(
7
- 'host-details-kebab',
8
- 'rex-host-details-kebab-job',
9
- <KebabItems key="rex-host-details-kebab-job" />,
10
- 100
11
- );
@@ -1,11 +0,0 @@
1
- import React from 'react';
2
- import { addGlobalFill } from 'foremanReact/components/common/Fill/GlobalFill';
3
- import FeaturesDropdown from '../components/FeaturesDropdown';
4
-
5
- export default () =>
6
- addGlobalFill(
7
- '_rex-host-features',
8
- '_rex-host-features',
9
- <FeaturesDropdown key="_rex-host-features" />,
10
- 1000
11
- );