foreman_remote_execution 2.0.2 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 837b065cbfe503343d7eedfb734f5a8d83ca1b5d358f990cc9741d9658b1f4dd
4
- data.tar.gz: 4ff9c2ad68f54faf3cca998b8cb54f74e75dfc3408dbbbfc527a82e88eaa7226
3
+ metadata.gz: a9ac5ddf16b74dec2deb0b11e6235c5074efd9ff22c69df60095998965785eb6
4
+ data.tar.gz: d3a6b6783e5dfe9905e6267b36289c3f2a56274dfc9500cec2947241ad8968da
5
5
  SHA512:
6
- metadata.gz: 9ccb9cd8c75c9e92d69fb22c6024ee242d2917f1410448f781aa0a561505a4e63faa72b9908355ed3672af55a1c4a0bbbeee928e8281388f873bd555093d72ed
7
- data.tar.gz: afadfd61e5a6bc01c1c60496e6a26b5fd5e0e2fd7a4ecaa21895480bbc9455924d0ac12109ed7a71106a7536759d0eaa69033f1f695f34399f3f9bbb862b51f0
6
+ metadata.gz: 39cb455b52d5d6290a6a79d3cd0f48fa9c52f9666a3f8f07b3d4e36c996bc2b16cf4657535f6b80d6be502a3a4c9a4f858821fd0ed94ea54bc4990c0efe430e7
7
+ data.tar.gz: 6c052042b3e9e3d829018dc78967e94aedfbd59db2745c9fe93048404729c9e01e14224c44064f7c294cf8fbb471be9dd9a455681339e4de69f378ddab9e3b3f
@@ -0,0 +1,4 @@
1
+ /*
2
+ *= require_self
3
+ *= require_tree .
4
+ */
@@ -1,4 +1,4 @@
1
- div.modal-body {
1
+ #previewHostsModal div.modal-body {
2
2
  overflow-y: auto;
3
3
  max-height: 500px;
4
4
  }
@@ -203,7 +203,7 @@ class JobInvocationComposer
203
203
  base = { :user_id => User.current.id }
204
204
  if @host_ids
205
205
  search_query = @host_ids.empty? ? 'name ^ ()' : Targeting.build_query_from_hosts(@host_ids)
206
- base.merge(:search_query => search_query, :targeting_type => job_invocation.targeting.targeting_type)
206
+ base.merge(:search_query => search_query).merge(job_invocation.targeting.attributes.slice('targeting_type', 'randomized_ordering'))
207
207
  else
208
208
  base.merge job_invocation.targeting.attributes.slice('search_query', 'bookmark_id', 'targeting_type', 'randomized_ordering')
209
209
  end
@@ -332,7 +332,7 @@ class JobInvocationComposer
332
332
  # rubocop:disable Metrics/AbcSize
333
333
  def compose
334
334
  job_invocation.job_category = validate_job_category(params[:job_category])
335
- job_invocation.job_category ||= available_job_categories.first if @set_defaults
335
+ job_invocation.job_category ||= resolve_job_category(available_job_categories.first) { |tempate| template.job_category } if @set_defaults
336
336
  job_invocation.remote_execution_feature_id = params[:remote_execution_feature_id]
337
337
  job_invocation.targeting = build_targeting
338
338
  job_invocation.triggering = build_triggering
@@ -428,6 +428,16 @@ class JobInvocationComposer
428
428
  (templates_for_provider(provider_type) & selected_job_templates).first
429
429
  end
430
430
 
431
+ def resolve_job_category(default_category)
432
+ resolve_for_composer(default_category) { |form_template| form_template.job_category }
433
+ end
434
+
435
+ def resolve_job_template(provider_templates)
436
+ resolve_for_composer(provider_templates.first) do |form_template|
437
+ provider_templates.include?(form_template) ? form_template : provider_templates.first
438
+ end
439
+ end
440
+
431
441
  def displayed_search_query
432
442
  if @search_query.present?
433
443
  @search_query
@@ -562,4 +572,16 @@ class JobInvocationComposer
562
572
  def validate_host_ids(ids)
563
573
  Host.authorized(Targeting::RESOLVE_PERMISSION, Host).where(:id => ids).pluck(:id)
564
574
  end
575
+
576
+ def resolve_for_composer(default_value, &block)
577
+ setting_value = Setting['remote_execution_form_job_template']
578
+ return default_value unless setting_value
579
+ form_template = JobTemplate.find_by :name => setting_value
580
+ return default_value unless form_template
581
+ if block_given?
582
+ yield form_template
583
+ else
584
+ form_template
585
+ end
586
+ end
565
587
  end
@@ -1,6 +1,6 @@
1
1
  class Setting::RemoteExecution < Setting
2
2
 
3
- ::Setting::BLANK_ATTRS.concat %w{remote_execution_ssh_password remote_execution_ssh_key_passphrase remote_execution_sudo_password remote_execution_cockpit_url}
3
+ ::Setting::BLANK_ATTRS.concat %w{remote_execution_ssh_password remote_execution_ssh_key_passphrase remote_execution_sudo_password remote_execution_cockpit_url remote_execution_form_job_template}
4
4
 
5
5
  # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
6
6
  def self.default_settings
@@ -66,7 +66,13 @@ class Setting::RemoteExecution < Setting
66
66
  N_('Where to find the Cockpit instance for the Web Console button. By default, no button is shown.'),
67
67
  nil,
68
68
  N_('Cockpit URL'),
69
- nil)
69
+ nil),
70
+ self.set('remote_execution_form_job_template',
71
+ N_('Choose a job template that is pre-selected in job invocation form'),
72
+ 'Run Command - SSH Default',
73
+ _('Form Job Template'),
74
+ nil,
75
+ { :collection => proc { Hash[JobTemplate.unscoped.map { |template| [template.name, template.name] }] } })
70
76
  ]
71
77
  end
72
78
  # rubocop:enable AbcSize
@@ -16,7 +16,7 @@
16
16
  <%= f.fields_for 'providers' do |providers_fields| %>
17
17
  <%= providers_fields.fields_for provider_type do |provider_type_fields| %>
18
18
  <% templates_for_provider = @composer.templates_for_provider(provider_type) %>
19
- <% selected_templates_per_provider[provider_type] = @composer.preselected_template_for_provider(provider_type) || templates_for_provider.first %>
19
+ <% selected_templates_per_provider[provider_type] = @composer.preselected_template_for_provider(provider_type) || @composer.resolve_job_template(templates_for_provider) %>
20
20
 
21
21
  <%= selectable_f provider_type_fields, 'job_template_id', templates_for_provider.map { |t| [t.name, t.id] },
22
22
  { :selected => selected_templates_per_provider[provider_type].try(:id) },
@@ -33,7 +33,7 @@
33
33
  <% end %>
34
34
  </span>
35
35
  <%= selectable_f targeting_fields, :bookmark_id, @composer.available_bookmarks.map { |b| [b.name, b.id] }, :selected => @composer.targeting.bookmark_id, :include_blank => true %>
36
- <%= textarea_f targeting_fields, :search_query, :value => @composer.displayed_search_query, :rows => 5 %>
36
+ <%= textarea_f targeting_fields, :search_query, :value => @composer.displayed_search_query, :rows => 5, :class => 'autocomplete-input form-control', :'data-url' => auto_complete_search_hosts_path %>
37
37
 
38
38
  <div class="form-group ">
39
39
  <label class="col-md-2 control-label"><%= _('Resolves to') %></label>
@@ -1,4 +1,4 @@
1
- <% stylesheet 'foreman_remote_execution/modal_window' %>
1
+ <% stylesheet 'foreman_remote_execution/foreman_remote_execution' %>
2
2
 
3
3
  <!-- modal window -->
4
4
  <div class="modal fade" id="previewHostsModal" role="dialog" aria-hidden="true" data-url="<%= preview_hosts_job_invocations_path %>">
@@ -1,4 +1,4 @@
1
1
  <% javascript 'foreman_remote_execution/template_invocation' %>
2
- <% stylesheet 'foreman_remote_execution/template_invocation' %>
2
+ <% stylesheet 'foreman_remote_execution/foreman_remote_execution' %>
3
3
  <% title _('Job invocation') %>
4
4
  <%= render :partial => 'form' %>
@@ -1,5 +1,5 @@
1
1
  <% title @job_invocation.description %>
2
- <% stylesheet 'foreman_remote_execution/job_invocations' %>
2
+ <% stylesheet 'foreman_remote_execution/foreman_remote_execution' %>
3
3
  <% javascript 'charts', 'foreman_remote_execution/template_invocation' %>
4
4
  <%= javascript_include_tag *webpack_asset_paths('foreman_remote_execution', :extension => 'js'), "data-turbolinks-track" => true, 'defer' => 'defer' %>
5
5
 
@@ -1,4 +1,4 @@
1
- <% stylesheet 'foreman_remote_execution/modal_window' %>
1
+ <% stylesheet 'foreman_remote_execution/foreman_remote_execution' %>
2
2
 
3
3
  <!-- modal window -->
4
4
  <div class="modal fade" id="importJobTemplateModal" role="dialog" aria-hidden="true">
@@ -9,7 +9,7 @@
9
9
  :items => items)
10
10
  %>
11
11
 
12
- <% stylesheet 'foreman_remote_execution/template_invocation' %>
12
+ <% stylesheet 'foreman_remote_execution/foreman_remote_execution' %>
13
13
  <% javascript 'foreman_remote_execution/template_invocation' %>
14
14
 
15
15
  <div id="title_action">
@@ -38,6 +38,8 @@ module ForemanRemoteExecution
38
38
 
39
39
  apipie_documented_controllers ["#{ForemanRemoteExecution::Engine.root}/app/controllers/api/v2/*.rb"]
40
40
 
41
+ automatic_assets(false)
42
+
41
43
  # Add permissions
42
44
  security_block :foreman_remote_execution do
43
45
  permission :view_job_templates, { :job_templates => [:index, :show, :revision, :auto_complete_search, :auto_complete_job_category, :preview, :export],
@@ -130,10 +132,12 @@ module ForemanRemoteExecution
130
132
  # content twice.
131
133
  assets_to_precompile =
132
134
  Dir.chdir(root) do
133
- Dir['app/assets/javascripts/**/*', 'app/assets/stylesheets/**/*'].map do |f|
134
- f.split(File::SEPARATOR, 4).last.gsub(/\.scss\Z/, '')
135
+ Dir['app/assets/javascripts/**/*'].map do |f|
136
+ f.split(File::SEPARATOR, 4).last
135
137
  end
136
138
  end
139
+ assets_to_precompile += %w(foreman_remote_execution/foreman_remote_execution.css)
140
+
137
141
  initializer 'foreman_remote_execution.assets.precompile' do |app|
138
142
  app.config.assets.precompile += assets_to_precompile
139
143
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanRemoteExecution
2
- VERSION = '2.0.2'.freeze
2
+ VERSION = '2.0.3'.freeze
3
3
  end
@@ -811,5 +811,55 @@ class JobInvocationComposerTest < ActiveSupport::TestCase
811
811
  assert created.targeting.resolved?
812
812
  assert_equal job_invocation.template_invocations_host_ids, created.targeting.host_ids
813
813
  end
814
+
815
+ it 'takes randomized_ordering from the original job invocation when rerunning failed' do
816
+ job_invocation.targeting.randomized_ordering = true
817
+ job_invocation.targeting.save!
818
+ host_ids = job_invocation.targeting.hosts.pluck(:id)
819
+ composer = JobInvocationComposer.from_job_invocation(job_invocation, :host_ids => host_ids)
820
+ assert composer.job_invocation.targeting.randomized_ordering
821
+ end
822
+ end
823
+
824
+ describe '#resolve_job_category and #resolve job_templates' do
825
+ let(:setting_template) { as_admin { FactoryBot.create(:job_template, :name => 'trying setting', :job_category => 'fluff') } }
826
+ let(:other_template) { as_admin { FactoryBot.create(:job_template, :name => 'trying something', :job_category => 'fluff') } }
827
+ let(:second_template) { as_admin { FactoryBot.create(:job_template, :name => 'second template', :job_category => 'fluff') } }
828
+ let(:params) { { :host_ids => nil, :targeting => { :targeting_type => "static_query", :bookmark_id => nil }, :job_template_id => setting_template.id } }
829
+ let(:composer) { JobInvocationComposer.from_api_params(params) }
830
+
831
+ context 'with template in setting present' do
832
+ before do
833
+ FactoryBot.create(
834
+ :setting,
835
+ :name => 'remote_execution_form_job_template',
836
+ :category => 'Setting::RemoteExecution',
837
+ :value => setting_template.name
838
+ )
839
+ end
840
+
841
+ it 'should resolve category to the setting value' do
842
+ assert_equal setting_template.job_category, composer.resolve_job_category('foo')
843
+ end
844
+
845
+ it 'should resolve template to the setting value' do
846
+ assert_equal setting_template, composer.resolve_job_template([other_template, setting_template])
847
+ end
848
+
849
+ it 'should respect provider templates when resolving templates' do
850
+ assert_equal other_template, composer.resolve_job_template([other_template])
851
+ end
852
+ end
853
+
854
+ context 'with template in setting absent' do
855
+ it 'should resolve category to the default value' do
856
+ category = 'foo'
857
+ assert_equal category, composer.resolve_job_category(category)
858
+ end
859
+
860
+ it 'should resolve template to the first in category' do
861
+ assert_equal other_template, composer.resolve_job_template([other_template, second_template])
862
+ end
863
+ end
814
864
  end
815
865
  end
@@ -7,6 +7,8 @@ import DonutChart from 'foremanReact/components/common/charts/DonutChart';
7
7
  import AggregateStatus from './AggregateStatus/index.js';
8
8
  import * as JobInvocationActions from '../../redux/actions/jobInvocations';
9
9
 
10
+ const colIndexOfMaxValue = columns => columns.reduce((iMax, x, i, arr) => (x[1] > arr[iMax][1] ? i : iMax), 0);
11
+
10
12
  class JobInvocationContainer extends React.Component {
11
13
  componentDidMount() {
12
14
  const { startJobInvocationsPolling, data: { url } } = this.props;
@@ -16,10 +18,12 @@ class JobInvocationContainer extends React.Component {
16
18
 
17
19
  render() {
18
20
  const { jobInvocations, statuses } = this.props;
21
+ const iMax = colIndexOfMaxValue(jobInvocations);
19
22
 
20
23
  return (
21
24
  <div id="job_invocations_chart_container">
22
- <DonutChart data={Immutable.asMutable(jobInvocations)} />
25
+ <DonutChart data={Immutable.asMutable(jobInvocations)}
26
+ title={{type: 'percent', secondary: (jobInvocations[iMax] || [])[0]}}/>
23
27
  <AggregateStatus statuses={statuses} />
24
28
  </div>
25
29
  );
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: 2.0.2
4
+ version: 2.0.3
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: 2019-10-29 00:00:00.000000000 Z
11
+ date: 2019-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deface
@@ -147,9 +147,10 @@ files:
147
147
  - app/assets/javascripts/foreman_remote_execution/job_templates.js
148
148
  - app/assets/javascripts/foreman_remote_execution/template_input.js
149
149
  - app/assets/javascripts/foreman_remote_execution/template_invocation.js
150
- - app/assets/stylesheets/foreman_remote_execution/job_invocations.css.scss
151
- - app/assets/stylesheets/foreman_remote_execution/modal_window.css.scss
152
- - app/assets/stylesheets/foreman_remote_execution/template_invocation.css.scss
150
+ - app/assets/stylesheets/foreman_remote_execution/foreman_remote_execution.css
151
+ - app/assets/stylesheets/foreman_remote_execution/job_invocations.scss
152
+ - app/assets/stylesheets/foreman_remote_execution/modal_window.scss
153
+ - app/assets/stylesheets/foreman_remote_execution/template_invocation.scss
153
154
  - app/controllers/api/v2/foreign_input_sets_controller.rb
154
155
  - app/controllers/api/v2/job_invocations_controller.rb
155
156
  - app/controllers/api/v2/job_templates_controller.rb