foreman_remote_execution 7.0.0 → 7.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (26) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby_ci.yml +2 -0
  3. data/app/controllers/foreman_remote_execution/concerns/api/v2/registration_commands_controller_extensions.rb +1 -0
  4. data/app/controllers/foreman_remote_execution/concerns/api/v2/registration_controller_extensions.rb +8 -0
  5. data/app/models/concerns/foreman_remote_execution/foreman_tasks_task_extensions.rb +6 -0
  6. data/app/models/host_status/execution_status.rb +2 -1
  7. data/app/models/job_invocation.rb +1 -1
  8. data/app/models/job_invocation_composer.rb +1 -1
  9. data/app/models/job_template.rb +2 -0
  10. data/app/models/remote_execution_provider.rb +4 -0
  11. data/app/models/template_invocation.rb +2 -0
  12. data/app/services/remote_execution_proxy_selector.rb +1 -1
  13. data/app/views/overrides/subnets/_rex_tab_pane.html.erb +1 -1
  14. data/lib/foreman_remote_execution/engine.rb +1 -0
  15. data/lib/foreman_remote_execution/version.rb +1 -1
  16. data/test/unit/api_params_test.rb +33 -0
  17. data/test/unit/remote_execution_provider_test.rb +26 -0
  18. data/webpack/JobWizard/steps/AdvancedFields/AdvancedFields.js +9 -0
  19. data/webpack/JobWizard/steps/AdvancedFields/Fields.js +21 -0
  20. data/webpack/JobWizard/steps/AdvancedFields/__tests__/AdvancedFields.test.js +5 -0
  21. data/webpack/JobWizard/steps/ReviewDetails/index.js +1 -0
  22. data/webpack/JobWizard/submit.js +2 -0
  23. data/webpack/react_app/components/FeaturesDropdown/index.js +1 -1
  24. data/webpack/react_app/components/RegistrationExtension/RexPull.js +73 -0
  25. data/webpack/react_app/extend/Fills.js +7 -0
  26. metadata +6 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9183b3b81c3033d696f4aedf861cb5eed143fb9eacccb144a23d859e3ccae69
4
- data.tar.gz: 4c7c6c09c84f3d4cbef2aaa8330b7bf048d42570e9319ad227c30abc5613770c
3
+ metadata.gz: b4f9d5aa836e3804a0b602bca132a51f4d3032b1276360f321867c135f9793c3
4
+ data.tar.gz: 7a6f9b518f336bbe91882e6c431a465b4aa80c3a262dba9e0789fecf1c9edf51
5
5
  SHA512:
6
- metadata.gz: b35e41908b57f97f80272070d84b8d2ceeb7e061e22ad673d07c694a643d057399e207af9c8f36d14d535a7ddb3eddefa013e04b3d63689796e66e6d9aeae88b
7
- data.tar.gz: 5c0b0d79edaab4c28721ad26df27ad8ac14878e09349929d28175c2cc1714ebb1f81ceb9f4824215d781dc1b4b0662962a9043f4f56963fea4d0aaa3e2483f8d
6
+ metadata.gz: 14cf218a2c1267baedcd0980adbe51207e9beebbe8c262e2506167a5a095fb5c14447bf58147efdb5eaaf3f56120d4463572ad1d01d981f93c33f37050b0115e
7
+ data.tar.gz: f2b7c73889c483a6f134c213c65df5ba21eddcc61b2b578b5f070a98e7ff9a9a0d269c1ad6dbc341285021189e02b973b0b77e90258537b8995adddd901bc5da
@@ -18,6 +18,8 @@ jobs:
18
18
  with:
19
19
  ruby-version: 2.5
20
20
  bundler-cache: true
21
+ cache-version: 1
22
+ rubygems: 3.0.0
21
23
  - name: Run rubocop
22
24
  if: github.event_name != 'push'
23
25
  run: bundle exec rubocop --format github
@@ -9,6 +9,7 @@ module ForemanRemoteExecution
9
9
  update_api(:create) do
10
10
  param :registration_command, Hash do
11
11
  param :remote_execution_interface, String, desc: N_("Identifier of the Host interface for Remote execution")
12
+ param :setup_remote_execution_pull, :bool, desc: N_("Set 'host_registration_remote_execution_pull' parameter for the host. If it is set to true, pull provider client will be deployed on the host")
12
13
  end
13
14
  end
14
15
  end
@@ -6,6 +6,7 @@ module ForemanRemoteExecution
6
6
 
7
7
  update_api(:global, :host) do
8
8
  param :remote_execution_interface, String, desc: N_("Identifier of the Host interface for Remote execution")
9
+ param :setup_remote_execution_pull, :bool, desc: N_("Set 'host_registration_remote_execution_pull' parameter for the host. If it is set to true, pull provider client will be deployed on the host")
9
10
  end
10
11
  end
11
12
 
@@ -13,10 +14,17 @@ module ForemanRemoteExecution
13
14
 
14
15
  def host_setup_extension
15
16
  remote_execution_interface
17
+ remote_execution_pull
16
18
  reset_host_known_keys! unless @host.new_record?
17
19
  super
18
20
  end
19
21
 
22
+ def remote_execution_pull
23
+ HostParameter.where(host: @host, name: 'host_registration_remote_execution_pull').destroy_all
24
+
25
+ setup_host_param('host_registration_remote_execution_pull', ActiveRecord::Type::Boolean.new.deserialize(params['setup_remote_execution_pull']))
26
+ end
27
+
20
28
  def remote_execution_interface
21
29
  return unless params['remote_execution_interface'].present?
22
30
 
@@ -4,6 +4,12 @@ module ForemanRemoteExecution
4
4
 
5
5
  included do
6
6
  has_many :job_invocations, :dependent => :destroy, :foreign_key => 'task_id'
7
+ has_one :template_invocation, :inverse_of => :run_host_job_task, :foreign_key => 'run_host_job_task_id', :dependent => :nullify
8
+ has_one :template, :through => :template_invocation
9
+ has_many :remote_execution_features, :through => :template
10
+
11
+ scoped_search :relation => :remote_execution_features, :on => :name, :rename => 'remote_execution_feature.name'
12
+ scoped_search :relation => :remote_execution_features, :on => :label, :rename => 'remote_execution_feature.label'
7
13
  end
8
14
  end
9
15
  end
@@ -50,7 +50,8 @@ class HostStatus::ExecutionStatus < HostStatus::Status
50
50
  end
51
51
 
52
52
  def status_link
53
- job_invocation = last_stopped_task.parent_task.job_invocations.first
53
+ job_invocation = last_stopped_task&.parent_task&.job_invocations&.first
54
+ return unless job_invocation
54
55
  return nil unless User.current.can?(:view_job_invocations, job_invocation)
55
56
 
56
57
  Rails.application.routes.url_helpers.job_invocation_path(job_invocation)
@@ -25,7 +25,7 @@ class JobInvocation < ApplicationRecord
25
25
  validates :job_category, :presence => true
26
26
  validates_associated :targeting, :all_template_invocations
27
27
 
28
- scoped_search :on => :id, :complete_value => true
28
+ scoped_search :on => :id, :complete_value => true, :validator => ScopedSearch::Validators::INTEGER
29
29
  scoped_search :on => :job_category, :complete_value => true
30
30
  scoped_search :on => :description, :complete_value => true
31
31
 
@@ -219,7 +219,7 @@ class JobInvocationComposer
219
219
  def format_datetime(datetime)
220
220
  return datetime if datetime.blank?
221
221
 
222
- Time.parse(datetime).in_time_zone.strftime('%Y-%m-%d %H:%M')
222
+ Time.zone.parse(datetime).strftime('%Y-%m-%d %H:%M')
223
223
  end
224
224
  end
225
225
 
@@ -32,6 +32,8 @@ class JobTemplate < ::Template
32
32
  scoped_search :on => :snippet, :complete_value => {:true => true, :false => false}
33
33
  scoped_search :on => :provider_type, :complete_value => true
34
34
  scoped_search :on => :template
35
+ scoped_search :relation => :remote_execution_features, :on => :name, :rename => 'feature.name'
36
+ scoped_search :relation => :remote_execution_features, :on => :label, :rename => 'feature.label'
35
37
 
36
38
  # with proc support, default_scope can no longer be chained
37
39
  # include all default scoping here
@@ -28,6 +28,10 @@ class RemoteExecutionProvider
28
28
  providers.keys.map(&:to_s)
29
29
  end
30
30
 
31
+ def provider_proxy_features
32
+ providers.values.map(&:proxy_feature).flatten.uniq.compact
33
+ end
34
+
31
35
  def proxy_command_options(template_invocation, host)
32
36
  {:proxy_operation_name => proxy_operation_name}.merge(proxy_command_provider_inputs(template_invocation))
33
37
  end
@@ -16,6 +16,7 @@ class TemplateInvocation < ApplicationRecord
16
16
  belongs_to :host, :class_name => 'Host::Managed', :foreign_key => :host_id
17
17
  has_one :host_group, :through => :host, :source => :hostgroup
18
18
  belongs_to :run_host_job_task, :class_name => 'ForemanTasks::Task'
19
+ has_many :remote_execution_features, :through => :template
19
20
 
20
21
  validates_associated :input_values
21
22
  validate :provides_required_input_values
@@ -25,6 +26,7 @@ class TemplateInvocation < ApplicationRecord
25
26
  scoped_search :relation => :host_group, :on => :name, :rename => 'host_group.name', :complete_value => true
26
27
  scoped_search :relation => :template, :on => :job_category, :complete_value => true
27
28
  scoped_search :relation => :template, :on => :name, :complete_value => true
29
+ scoped_search :relation => :remote_execution_features, :on => :name, :rename => 'feature'
28
30
 
29
31
  class TaskResultMap
30
32
  MAP = {
@@ -7,7 +7,7 @@ class RemoteExecutionProxySelector < ::ForemanTasks::ProxySelector
7
7
  return proxies if capability.nil?
8
8
 
9
9
  proxies.reduce({}) do |acc, (strategy, possible_proxies)|
10
- acc.merge(strategy => possible_proxies.select { |proxy| proxy.has_capability?(capability) })
10
+ acc.merge(strategy => possible_proxies.select { |proxy| proxy.has_capability?(provider, capability) })
11
11
  end
12
12
  end
13
13
  end
@@ -1,5 +1,5 @@
1
1
  <div class="tab-pane" id="rex_proxies">
2
2
  <%= fields_for :subnet do |f| %>
3
- <%= multiple_selects f, :remote_execution_proxies, SmartProxy.authorized.with_features(*RemoteExecutionProvider.provider_names).distinct, @subnet.remote_execution_proxy_ids, {:label => _("Proxies"), :help_inline => _("Select as many remote execution proxies as applicable for this subnet. When multiple proxies with the same provider are added, actions will be load balanced among them.")} %>
3
+ <%= multiple_selects f, :remote_execution_proxies, SmartProxy.authorized.with_features(*RemoteExecutionProvider.provider_proxy_features).distinct, @subnet.remote_execution_proxy_ids, {:label => _("Proxies"), :help_inline => _("Select as many remote execution proxies as applicable for this subnet. When multiple proxies with the same provider are added, actions will be load balanced among them.")} %>
4
4
  <% end %>
5
5
  </div>
@@ -275,6 +275,7 @@ module ForemanRemoteExecution
275
275
 
276
276
  # Extend Registration module
277
277
  extend_allowed_registration_vars :remote_execution_interface
278
+ extend_allowed_registration_vars :setup_remote_execution_pull
278
279
  ForemanTasks.dynflow.eager_load_actions!
279
280
  extend_observable_events(
280
281
  ::Dynflow::Action.descendants.select do |klass|
@@ -1,3 +1,3 @@
1
1
  module ForemanRemoteExecution
2
- VERSION = '7.0.0'.freeze
2
+ VERSION = '7.2.0'.freeze
3
3
  end
@@ -0,0 +1,33 @@
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
@@ -33,6 +33,10 @@ class RemoteExecutionProviderTest < ActiveSupport::TestCase
33
33
  it 'accepts strings' do
34
34
  RemoteExecutionProvider.provider_for('SSH').must_equal SSHExecutionProvider
35
35
  end
36
+
37
+ it 'returns a default one if unknown value is provided' do
38
+ RemoteExecutionProvider.provider_for('WinRM').must_equal ScriptExecutionProvider
39
+ end
36
40
  end
37
41
 
38
42
  describe '.provider_names' do
@@ -52,6 +56,28 @@ class RemoteExecutionProviderTest < ActiveSupport::TestCase
52
56
  end
53
57
  end
54
58
 
59
+ describe '.provider_proxy_features' do
60
+ it 'returns correct values' do
61
+ RemoteExecutionProvider.stubs(:providers).returns(
62
+ :SSH => SSHExecutionProvider,
63
+ :script => ScriptExecutionProvider
64
+ )
65
+
66
+ features = RemoteExecutionProvider.provider_proxy_features
67
+ _(features).must_include 'SSH'
68
+ _(features).must_include 'Script'
69
+ RemoteExecutionProvider.unstub(:providers)
70
+ end
71
+
72
+ it 'can deal with non-arrays' do
73
+ provider = OpenStruct.new(proxy_feature: 'Testing')
74
+ RemoteExecutionProvider.stubs(:providers).returns(:testing => provider)
75
+ features = RemoteExecutionProvider.provider_proxy_features
76
+ _(features).must_include 'Testing'
77
+ RemoteExecutionProvider.unstub(:providers)
78
+ end
79
+ end
80
+
55
81
  describe '.host_setting' do
56
82
  let(:host) { FactoryBot.create(:host) }
57
83
 
@@ -16,6 +16,7 @@ import {
16
16
  TimeSpanLevelField,
17
17
  TemplateInputsFields,
18
18
  ExecutionOrderingField,
19
+ SSHUserField,
19
20
  } from './Fields';
20
21
  import { DescriptionField } from './DescriptionField';
21
22
  import { WIZARD_TITLES } from '../../JobWizardConstants';
@@ -40,6 +41,14 @@ export const AdvancedFields = ({
40
41
  value={advancedValues.templateValues}
41
42
  setValue={newValue => setAdvancedValues({ templateValues: newValue })}
42
43
  />
44
+ <SSHUserField
45
+ value={advancedValues.sshUser}
46
+ setValue={newValue =>
47
+ setAdvancedValues({
48
+ sshUser: newValue,
49
+ })
50
+ }
51
+ />
43
52
  {effectiveUser?.overridable && (
44
53
  <EffectiveUserField
45
54
  value={advancedValues.effectiveUserValue}
@@ -203,6 +203,24 @@ export const ExecutionOrderingField = ({ isRandomizedOrdering, setValue }) => (
203
203
  export const TemplateInputsFields = ({ inputs, value, setValue }) => (
204
204
  <>{inputs?.map(input => formatter(input, value, setValue))}</>
205
205
  );
206
+
207
+ export const SSHUserField = ({ value, setValue }) => (
208
+ <FormGroup
209
+ label={__('SSH user')}
210
+ labelIcon={helpLabel(__('A user to be used for SSH.'), 'ssh-user')}
211
+ fieldId="ssh-user"
212
+ >
213
+ <TextInput
214
+ aria-label="ssh user"
215
+ autoComplete="ssh-user"
216
+ id="ssh-user"
217
+ type="text"
218
+ value={value}
219
+ onChange={newValue => setValue(newValue)}
220
+ />
221
+ </FormGroup>
222
+ );
223
+
206
224
  EffectiveUserField.propTypes = {
207
225
  value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
208
226
  setValue: PropTypes.func.isRequired,
@@ -240,3 +258,6 @@ TemplateInputsFields.propTypes = {
240
258
  TemplateInputsFields.defaultProps = {
241
259
  value: {},
242
260
  };
261
+
262
+ SSHUserField.propTypes = EffectiveUserField.propTypes;
263
+ SSHUserField.defaultProps = EffectiveUserField.defaultProps;
@@ -165,6 +165,11 @@ describe('AdvancedFields', () => {
165
165
  fireEvent.click(screen.getByText('Advanced fields'));
166
166
  });
167
167
 
168
+ expect(
169
+ screen.getByLabelText('ssh user', {
170
+ selector: 'input',
171
+ }).value
172
+ ).toBe('');
168
173
  expect(
169
174
  screen.getByLabelText('effective user', {
170
175
  selector: 'input',
@@ -125,6 +125,7 @@ const ReviewDetails = ({
125
125
  ].filter(d => d);
126
126
 
127
127
  const advancedFields = [
128
+ { label: __('SSH user'), value: advancedValues.sshUser },
128
129
  { label: __('Effective user'), value: advancedValues.effectiveUserValue },
129
130
  { label: __('Description Template'), value: advancedValues.description },
130
131
  { label: __('Timeout to kill'), value: advancedValues.timeoutToKill },
@@ -23,6 +23,7 @@ export const submit = ({
23
23
  purpose,
24
24
  } = scheduleValue;
25
25
  const {
26
+ sshUser,
26
27
  effectiveUserValue,
27
28
  effectiveUserPassword,
28
29
  description,
@@ -64,6 +65,7 @@ export const submit = ({
64
65
  : 'dynamic_query',
65
66
  randomized_ordering: isRandomizedOrdering,
66
67
  inputs: { ...templateValues, ...advancedTemplateValues },
68
+ ssh_user: sshUser,
67
69
  ssh: {
68
70
  effective_user: effectiveUserValue,
69
71
  effective_user_password: effectiveUserPassword,
@@ -52,7 +52,7 @@ const FeaturesDropdown = ({ hostId }) => {
52
52
  toggle={
53
53
  <DropdownToggle
54
54
  splitButtonItems={scheduleJob}
55
- toggleVariant="primary"
55
+ toggleVariant="secondary"
56
56
  onToggle={() => setIsOpen(prev => !prev)}
57
57
  isDisabled={status === STATUS.PENDING}
58
58
  splitButtonVariant="action"
@@ -0,0 +1,73 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import { translate as __ } from 'foremanReact/common/I18n';
5
+ import LabelIcon from 'foremanReact/components/common/LabelIcon';
6
+
7
+ import {
8
+ FormGroup,
9
+ FormSelectOption,
10
+ FormSelect,
11
+ } from '@patternfly/react-core';
12
+
13
+ const options = (value = '') => {
14
+ const defaultValue = value ? __('yes') : __('no');
15
+ const defaultLabel = `${__('Inherit from host parameter')} (${defaultValue})`;
16
+
17
+ return (
18
+ <>
19
+ <FormSelectOption key={0} value="" label={defaultLabel} />
20
+ <FormSelectOption key={1} value label={__('Yes (override)')} />
21
+ <FormSelectOption key={2} value={false} label={__('No (override)')} />
22
+ </>
23
+ );
24
+ };
25
+
26
+ const RexPull = ({ isLoading, onChange, pluginValues, configParams }) => (
27
+ <FormGroup
28
+ label={__('REX pull mode')}
29
+ isRequired
30
+ labelIcon={
31
+ <LabelIcon
32
+ text={__(
33
+ 'Setup remote execution pull mode. If set to `Yes`, pull provider client will be deployed on the registered host. The inherited value is based on the `host_registration_remote_execution_pull` parameter. It can be inherited e.g. from host group, operating system, organization. When overridden, the selected value will be stored on host parameter level.'
34
+ )}
35
+ />
36
+ }
37
+ fieldId="registration_setup_remote_execution_pull"
38
+ >
39
+ <FormSelect
40
+ value={pluginValues.setupRemoteExecutionPull}
41
+ onChange={setupRemoteExecutionPull =>
42
+ onChange({ setupRemoteExecutionPull })
43
+ }
44
+ className="without_select2"
45
+ id="registration_setup_remote_execution_pull"
46
+ isDisabled={isLoading}
47
+ isRequired
48
+ >
49
+ {/* eslint-disable-next-line camelcase */
50
+ options(configParams?.host_registration_remote_execution_pull)}
51
+ </FormSelect>
52
+ </FormGroup>
53
+ );
54
+
55
+ RexPull.propTypes = {
56
+ onChange: PropTypes.func,
57
+ isLoading: PropTypes.bool,
58
+ pluginValues: PropTypes.shape({
59
+ setupRemoteExecutionPull: PropTypes.bool,
60
+ }),
61
+ configParams: PropTypes.shape({
62
+ host_registration_remote_execution_pull: PropTypes.bool,
63
+ }),
64
+ };
65
+
66
+ RexPull.defaultProps = {
67
+ onChange: undefined,
68
+ isLoading: false,
69
+ pluginValues: {},
70
+ configParams: {},
71
+ };
72
+
73
+ export default RexPull;
@@ -3,6 +3,7 @@ import { addGlobalFill } from 'foremanReact/components/common/Fill/GlobalFill';
3
3
 
4
4
  import FeaturesDropdown from '../components/FeaturesDropdown';
5
5
  import RexInterface from '../components/RegistrationExtension/RexInterface';
6
+ import RexPull from '../components/RegistrationExtension/RexPull';
6
7
  import RecentJobsCard from '../components/RecentJobsCard';
7
8
  import KebabItems from '../components/HostKebab/KebabItems';
8
9
 
@@ -25,6 +26,12 @@ const fills = [
25
26
  component: props => <RexInterface {...props} />,
26
27
  weight: 500,
27
28
  },
29
+ {
30
+ slot: 'registrationAdvanced',
31
+ name: 'pull',
32
+ component: props => <RexPull {...props} />,
33
+ weight: 500,
34
+ },
28
35
  {
29
36
  slot: '_rex-host-features',
30
37
  name: '_rex-host-features',
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: 7.0.0
4
+ version: 7.2.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-05-16 00:00:00.000000000 Z
11
+ date: 2022-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deface
@@ -389,6 +389,7 @@ files:
389
389
  - test/test_plugin_helper.rb
390
390
  - test/unit/actions/run_host_job_test.rb
391
391
  - test/unit/actions/run_hosts_job_test.rb
392
+ - test/unit/api_params_test.rb
392
393
  - test/unit/concerns/foreman_tasks_cleaner_extensions_test.rb
393
394
  - test/unit/concerns/host_extensions_test.rb
394
395
  - test/unit/concerns/nic_extensions_test.rb
@@ -491,6 +492,7 @@ files:
491
492
  - webpack/react_app/components/RecentJobsCard/index.js
492
493
  - webpack/react_app/components/RecentJobsCard/styles.scss
493
494
  - webpack/react_app/components/RegistrationExtension/RexInterface.js
495
+ - webpack/react_app/components/RegistrationExtension/RexPull.js
494
496
  - webpack/react_app/components/RegistrationExtension/__tests__/RexInterface.test.js
495
497
  - webpack/react_app/components/RegistrationExtension/__tests__/__snapshots__/RexInterface.test.js.snap
496
498
  - webpack/react_app/components/TargetingHosts/TargetingHosts.js
@@ -544,7 +546,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
544
546
  - !ruby/object:Gem::Version
545
547
  version: '0'
546
548
  requirements: []
547
- rubygems_version: 3.1.4
549
+ rubygems_version: 3.2.26
548
550
  signing_key:
549
551
  specification_version: 4
550
552
  summary: A plugin bringing remote execution to the Foreman, completing the config
@@ -571,6 +573,7 @@ test_files:
571
573
  - test/test_plugin_helper.rb
572
574
  - test/unit/actions/run_host_job_test.rb
573
575
  - test/unit/actions/run_hosts_job_test.rb
576
+ - test/unit/api_params_test.rb
574
577
  - test/unit/concerns/foreman_tasks_cleaner_extensions_test.rb
575
578
  - test/unit/concerns/host_extensions_test.rb
576
579
  - test/unit/concerns/nic_extensions_test.rb