foreman_remote_execution 1.5.6 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: e46050a5990faad87a961e071259349d70484bd1a3a5dc591f2dc2d99a8ed5fd
4
- data.tar.gz: 2024c485f96831c771299629dee1eae498fbc078cd9a97fded7db60a66c88b4f
2
+ SHA1:
3
+ metadata.gz: d32b2841ada7024991eaaa445876b288bdb7e659
4
+ data.tar.gz: ac0e476c16619599050ed2ee18fe8a36c6676612
5
5
  SHA512:
6
- metadata.gz: fc474783987a76f8fa74304887f7a54aba2d1a4a64619087d891266916cff2f9c4527e2a53fff719bf8736f10d9fbf8542da2d99cd78d87d946f1048965c24a8
7
- data.tar.gz: af6e2aa4211743d8e210f2dfc823f81110ff6100ba4cb046b90ab85ca8a13048e6087eaaeebe9d856112cd525b2ae957e5d112a5734d96754fc77013b51b4cd7
6
+ metadata.gz: b359f35fd8d49fb8648cf9e166bde983c7559b7137b76704018ebd8998ac5d3d45600934dc459edf20b75982ccc9d7622e3872c6d75570c845f7378e149ca5d1
7
+ data.tar.gz: a35c2128ec33e5c54aff10a860d7515356a44bca013295e5066b916e89fc116e5384716904c4b30fd4808fde9eb67bbdefbd1e2240df8d6237625a858387f062
@@ -111,14 +111,9 @@ module Api
111
111
  param :failed_only, :bool
112
112
  def rerun
113
113
  composer = JobInvocationComposer.from_job_invocation(@job_invocation, params)
114
- if composer.rerun_possible?
115
- composer.trigger!
116
- @job_invocation = composer.job_invocation
117
- process_response @job_invocation
118
- else
119
- render :json => { :error => _('Could not rerun job %{id} because its template could not be found') % { :id => composer.reruns } },
120
- :status => 404
121
- end
114
+ composer.trigger!
115
+ @job_invocation = composer.job_invocation
116
+ process_response @job_invocation
122
117
  end
123
118
 
124
119
  private
@@ -161,7 +161,7 @@ module RemoteExecutionHelper
161
161
 
162
162
  def preview_box(template_invocation, target)
163
163
  renderer = InputTemplateRenderer.new(template_invocation.template, target, template_invocation)
164
- if (preview = (load_template_from_task(template_invocation, target) || renderer.preview))
164
+ if (preview = renderer.preview)
165
165
  content_tag :pre, preview
166
166
  elsif target.nil?
167
167
  alert :text => _('Could not render the preview because no host matches the search query.'),
@@ -234,10 +234,4 @@ module RemoteExecutionHelper
234
234
  end
235
235
  end
236
236
  end
237
-
238
- def load_template_from_task(template_invocation, target)
239
- task = template_invocation.job_invocation.sub_task_for_host(target)
240
- return if task.nil?
241
- task.execution_plan.actions[1].try(:input) { |input| input['script'] }
242
- end
243
237
  end
@@ -49,8 +49,6 @@ module Actions
49
49
  job_invocation.password = job_invocation.key_passphrase = job_invocation.sudo_password = nil
50
50
  job_invocation.save!
51
51
 
52
- Rails.logger.debug "cleaning cache for keys that begin with 'job_invocation_#{job_invocation.id}'"
53
- Rails.cache.delete_matched(/\A#{JobInvocation::CACHE_PREFIX}_#{job_invocation.id}/)
54
52
  # creating the success notification should be the very last thing this tasks do
55
53
  job_invocation.build_notification.deliver!
56
54
  end
@@ -0,0 +1,57 @@
1
+ module ForemanRemoteExecution
2
+ module Renderer
3
+ module Scope
4
+ class Input < ::Foreman::Renderer::Scope::Base
5
+ include Foreman::Renderer::Scope::Macros::HostTemplate
6
+
7
+ attr_reader :template, :host, :invocation, :input_values, :input_template_instance
8
+ delegate :input, to: :input_template_instance
9
+
10
+ def render_error(message)
11
+ raise ::InputTemplateRenderer::RenderError.new(message)
12
+ end
13
+
14
+ def preview?
15
+ !!@preview
16
+ end
17
+
18
+ def render_template(template_name, input_values = {}, options = {})
19
+ options.assert_valid_keys(:with_foreign_input_set)
20
+ with_foreign_input_set = options.fetch(:with_foreign_input_set, true)
21
+ template = @template.class.authorized("view_#{@template.class.to_s.underscore.pluralize}").find_by(name: template_name)
22
+ unless template
23
+ self.error_message = _('included template \'%s\' not found') % template_name
24
+ raise error_message
25
+ end
26
+ if with_foreign_input_set
27
+ input_values = foreign_input_set_values(template, input_values)
28
+ end
29
+ included_renderer = InputTemplateRenderer.new(template, host, invocation, input_values.with_indifferent_access, @preview, @templates_stack)
30
+ out = included_renderer.render
31
+ if included_renderer.error_message
32
+ @input_template_instance.error_message = included_renderer.error_message
33
+ raise error_message
34
+ else
35
+ out
36
+ end
37
+ end
38
+
39
+ def foreign_input_set_values(target_template, overrides = {})
40
+ input_set = @template.foreign_input_sets.find_by(:target_template_id => target_template)
41
+ return overrides if input_set.nil?
42
+
43
+ inputs_to_generate = input_set.inputs.map(&:name) - overrides.keys.map(&:to_s)
44
+ included_renderer = InputTemplateRenderer.new(input_set.target_template, host, invocation, nil, @preview, @templates_stack)
45
+ input_values = inputs_to_generate.inject(HashWithIndifferentAccess.new) do |hash, input_name|
46
+ hash.merge(input_name => included_renderer.input(input_name))
47
+ end
48
+ input_values.merge(overrides)
49
+ end
50
+
51
+ def allowed_helpers
52
+ super + [:input, :render_template, :preview?, :render_error]
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -5,9 +5,9 @@ class InputTemplateRenderer
5
5
  class RenderError < ::Foreman::Exception
6
6
  end
7
7
 
8
- include UnattendedHelper
8
+ delegate :logger, to: Rails
9
9
 
10
- attr_accessor :template, :host, :invocation, :input_values, :error_message
10
+ attr_accessor :template, :host, :invocation, :input_values, :error_message, :templates_stack
11
11
 
12
12
  # takes template object that should be rendered
13
13
  # host and template invocation arguments are optional
@@ -16,8 +16,8 @@ class InputTemplateRenderer
16
16
  raise Foreman::Exception, N_('Recursive rendering of templates detected') if templates_stack.include?(template)
17
17
 
18
18
  @host = host
19
- @invocation = invocation
20
19
  @template = template
20
+ @invocation = invocation
21
21
  @input_values = input_values
22
22
  @preview = preview
23
23
  @templates_stack = templates_stack + [template]
@@ -25,82 +25,53 @@ class InputTemplateRenderer
25
25
 
26
26
  def render
27
27
  @template.validate_unique_inputs!
28
- render_safe(@template.template, ::Foreman::Renderer::ALLOWED_HELPERS + [ :input, :render_template, :preview?, :render_error, :cached ], :host => @host)
28
+ source = Foreman::Renderer.get_source(
29
+ template: template,
30
+ host: host
31
+ )
32
+ scope = Foreman::Renderer.get_scope(
33
+ host: host,
34
+ klass: renderer_scope,
35
+ variables: {
36
+ host: host,
37
+ template: template,
38
+ preview: @preview,
39
+ invocation: invocation,
40
+ input_values: input_values,
41
+ templates_stack: templates_stack,
42
+ input_template_instance: self
43
+ }
44
+ )
45
+ Foreman::Renderer.render(source, scope)
29
46
  rescue => e
30
47
  self.error_message ||= _('error during rendering: %s') % e.message
31
- Rails.logger.debug e.to_s + "\n" + e.backtrace.join("\n")
32
- return false
33
- end
34
-
35
- def preview
36
- old_preview = @preview
37
- @preview = true
38
- render
39
- ensure
40
- @preview = old_preview
41
- end
42
-
43
- def cached(key, &block)
44
- return yield if preview?
45
- cache_key = "#{JobInvocation::CACHE_PREFIX}_#{invocation.job_invocation_id}_#{key}"
46
- Rails.logger.debug "cache hit for #{cache_key}" if Rails.cache.exist?(cache_key)
47
- Rails.cache.fetch(cache_key, &block)
48
+ Foreman::Logging.exception('Error during rendering of a job template', e)
49
+ false
48
50
  end
49
51
 
50
52
  def input(name)
51
53
  return @input_values[name.to_s] if @input_values
52
- input = find_by_name(@template.template_inputs_with_foreign, name) # rubocop:disable Rails/DynamicFindBy
54
+ input = find_by_name(template.template_inputs_with_foreign, name) # rubocop:disable Rails/DynamicFindBy
53
55
  if input
54
56
  @preview ? input.preview(self) : input.value(self)
55
57
  else
56
- self.error_message = _('input macro with name \'%s\' used, but no input with such name defined for this template') % name
58
+ error_message = _('input macro with name \'%s\' used, but no input with such name defined for this template') % name
57
59
  raise UndefinedInput, "Rendering failed, no input with name #{name} for input macro found"
58
60
  end
59
61
  end
60
62
 
61
- def render_error(message)
62
- raise RenderError.new(message)
63
- end
64
-
65
- def render_template(template_name, input_values = {}, options = {})
66
- options.assert_valid_keys(:with_foreign_input_set)
67
- with_foreign_input_set = options.fetch(:with_foreign_input_set, true)
68
- template = @template.class.authorized("view_#{@template.class.to_s.underscore.pluralize}").find_by(:name => template_name)
69
- unless template
70
- self.error_message = _('included template \'%s\' not found') % template_name
71
- raise error_message
72
- end
73
- if with_foreign_input_set
74
- input_values = foreign_input_set_values(template, input_values)
75
- end
76
- included_renderer = self.class.new(template, host, invocation, input_values.with_indifferent_access, @preview, @templates_stack)
77
- out = included_renderer.render
78
- if included_renderer.error_message
79
- self.error_message = included_renderer.error_message
80
- raise error_message
81
- else
82
- out
83
- end
84
- end
85
-
86
- def preview?
87
- !!@preview
63
+ def preview
64
+ old_preview = @preview
65
+ @preview = true
66
+ render
67
+ ensure
68
+ @preview = old_preview
88
69
  end
89
70
 
90
- def foreign_input_set_values(target_template, overrides = {})
91
- input_set = @template.foreign_input_sets.find_by(:target_template_id => target_template)
92
- return overrides if input_set.nil?
93
-
94
- inputs_to_generate = input_set.inputs.map(&:name) - overrides.keys.map(&:to_s)
95
- included_renderer = self.class.new(input_set.target_template, host, invocation, nil, @preview, @templates_stack)
96
- input_values = inputs_to_generate.inject(HashWithIndifferentAccess.new) do |hash, input_name|
97
- hash.merge(input_name => included_renderer.input(input_name))
98
- end
99
- input_values.merge(overrides)
100
- end
71
+ private
101
72
 
102
- def logger
103
- Rails.logger
73
+ def renderer_scope
74
+ ForemanRemoteExecution::Renderer::Scope::Input
104
75
  end
105
76
 
106
77
  def find_by_name(collection, name)
@@ -1,6 +1,4 @@
1
1
  class JobInvocation < ApplicationRecord
2
- CACHE_PREFIX = "job_invocation".freeze
3
-
4
2
  audited :except => [:task_id, :targeting_id, :task_group_id, :triggering_id]
5
3
 
6
4
  include Authorizable
@@ -186,8 +186,7 @@ class JobInvocationComposer
186
186
  :concurrency_control => concurrency_control_params,
187
187
  :execution_timeout_interval => job_invocation.execution_timeout_interval,
188
188
  :remote_execution_feature_id => job_invocation.remote_execution_feature_id,
189
- :template_invocations => template_invocations_params,
190
- :reruns => job_invocation.id }.with_indifferent_access
189
+ :template_invocations => template_invocations_params }.with_indifferent_access
191
190
  end
192
191
 
193
192
  private
@@ -298,7 +297,6 @@ class JobInvocationComposer
298
297
  end
299
298
 
300
299
  attr_accessor :params, :job_invocation, :host_ids, :search_query
301
- attr_reader :reruns
302
300
  delegate :job_category, :remote_execution_feature_id, :pattern_template_invocations, :template_invocations, :targeting, :triggering, :to => :job_invocation
303
301
 
304
302
  def initialize(params, set_defaults = false)
@@ -306,7 +304,6 @@ class JobInvocationComposer
306
304
  @set_defaults = set_defaults
307
305
  @job_invocation = JobInvocation.new
308
306
  @job_invocation.task_group = JobInvocationTaskGroup.new
309
- @reruns = params[:reruns]
310
307
  compose
311
308
 
312
309
  @host_ids = validate_host_ids(params[:host_ids])
@@ -345,8 +342,6 @@ class JobInvocationComposer
345
342
  job_invocation.key_passphrase = params[:key_passphrase]
346
343
  job_invocation.sudo_password = params[:sudo_password]
347
344
 
348
- job_invocation.job_category = nil unless rerun_possible?
349
-
350
345
  self
351
346
  end
352
347
  # rubocop:enable Metrics/AbcSize
@@ -475,10 +470,6 @@ class JobInvocationComposer
475
470
  job_invocation.pattern_template_invocations.map(&:template_id)
476
471
  end
477
472
 
478
- def rerun_possible?
479
- !(reruns && job_invocation.pattern_template_invocations.empty?)
480
- end
481
-
482
473
  private
483
474
 
484
475
  # builds input values for a given templates id based on params
@@ -136,7 +136,7 @@ class JobTemplate < ::Template
136
136
 
137
137
  def generate_description_format
138
138
  if description_format.blank?
139
- generated_description = '%{template_name}'
139
+ generated_description = '%{job_category}'
140
140
  unless template_inputs_with_foreign.empty?
141
141
  inputs = template_inputs_with_foreign.map(&:name).map { |name| %{#{name}="%{#{name}}"} }.join(' ')
142
142
  generated_description << " with inputs #{inputs}"
@@ -173,11 +173,7 @@ class TemplateInput < ApplicationRecord
173
173
  private
174
174
 
175
175
  def get_enc
176
- @enc ||= if SETTINGS[:version].short <= '1.15'
177
- Classification::ClassParam.new(:host => @renderer.host).enc
178
- else
179
- HostInfoProviders::PuppetInfo.new(@renderer.host).puppetclass_parameters
180
- end
176
+ @enc ||= HostInfoProviders::PuppetInfo.new(@renderer.host).puppetclass_parameters
181
177
  end
182
178
  end
183
179
  end
@@ -6,15 +6,7 @@
6
6
 
7
7
  <%= form_for @composer.job_invocation, :html => {'data-refresh-url' => refresh_job_invocations_path, :id => 'job_invocation_form'} do |f| %>
8
8
 
9
- <% unless @composer.rerun_possible? %>
10
- <%= alert :text => _('Could not rerun job %{id} because its template could not be found') % { :id => @composer.reruns },
11
- :class => 'alert alert-block alert-danger has-error',
12
- :close => false %>
13
- <% end %>
14
-
15
- <%= selectable_f f, :job_category, @composer.available_job_categories,
16
- { :selected => @composer.job_invocation.job_category, :include_blank => @composer.job_invocation.job_category.nil? },
17
- :label => _('Job category') %>
9
+ <%= selectable_f f, :job_category, @composer.available_job_categories, {}, :label => _('Job category') %>
18
10
  <%= f.hidden_field(:remote_execution_feature_id, :value => @composer.remote_execution_feature_id) %>
19
11
 
20
12
  <% selected_templates_per_provider = {} %>
@@ -124,5 +116,5 @@
124
116
 
125
117
  <%= render :partial => 'preview_hosts_modal' %>
126
118
 
127
- <%= submit_or_cancel f, false, :cancel_path => job_invocations_path, :disabled => !@composer.rerun_possible? %>
119
+ <%= submit_or_cancel f, false, :cancel_path => job_invocations_path %>
128
120
  <% end %>
@@ -34,7 +34,7 @@ module ForemanRemoteExecution
34
34
 
35
35
  initializer 'foreman_remote_execution.register_plugin', before: :finisher_hook do |_app|
36
36
  Foreman::Plugin.register :foreman_remote_execution do
37
- requires_foreman '>= 1.18'
37
+ requires_foreman '>= 1.20'
38
38
 
39
39
  apipie_documented_controllers ["#{ForemanRemoteExecution::Engine.root}/app/controllers/api/v2/*.rb"]
40
40
 
@@ -1,3 +1,3 @@
1
1
  module ForemanRemoteExecution
2
- VERSION = '1.5.6'.freeze
2
+ VERSION = '1.6.0'.freeze
3
3
  end
@@ -1,7 +1,7 @@
1
1
  FactoryBot.define do
2
2
  factory :job_template do
3
3
  sequence(:name) { |n| "Job template #{n}" }
4
- sequence(:job_category) { |n| "Job name #{n}" }
4
+ sequence(:job_category) { |n| "job name #{n}" }
5
5
  template 'id'
6
6
  provider_type 'SSH'
7
7
  organizations { [Organization.find_by(name: 'Organization 1')] } if SETTINGS[:organizations_enabled]
@@ -6,11 +6,6 @@ module Api
6
6
  setup do
7
7
  @invocation = FactoryBot.create(:job_invocation, :with_template, :with_task)
8
8
  @template = FactoryBot.create(:job_template, :with_input)
9
-
10
- # Without this the template in template_invocations and in pattern_template_invocations
11
- # would belong to different job_categories, causing trouble when trying to rerun
12
- @invocation.job_category = @invocation.pattern_template_invocations.first.template.job_category
13
- @invocation.save!
14
9
  end
15
10
 
16
11
  test 'should get index' do
@@ -183,8 +178,6 @@ module Api
183
178
 
184
179
  test 'should rerun failed only' do
185
180
  @invocation = FactoryBot.create(:job_invocation, :with_template, :with_failed_task)
186
- @invocation.job_category = @invocation.pattern_template_invocations.first.template.job_category
187
- @invocation.save!
188
181
  JobInvocation.any_instance.expects(:generate_description)
189
182
  JobInvocationComposer.any_instance
190
183
  .expects(:validate_job_category)
@@ -198,13 +191,6 @@ module Api
198
191
  targeting.user_id.must_equal users(:admin).id
199
192
  targeting.search_query.must_equal "name ^ (#{hostnames.join(',')})"
200
193
  end
201
-
202
- test 'should return 404 if template is not found' do
203
- @invocation.job_category = 'Missing category'
204
- @invocation.save!
205
- post :rerun, params: { :id => @invocation.id }
206
- assert_response 404
207
- end
208
194
  end
209
195
  end
210
196
  end
@@ -39,36 +39,6 @@ class InputTemplateRendererTest < ActiveSupport::TestCase
39
39
  renderer.error_message.wont_be_empty
40
40
  end
41
41
  end
42
-
43
- describe 'caching helper' do
44
- it 'caches the value under given key in real mode' do
45
- renderer.stubs(:invocation => OpenStruct.new(:job_invocation_id => 1))
46
-
47
- i = 1
48
- result = renderer.cached('some_key') { i }
49
- result.must_equal 1
50
- i += 1
51
- result = renderer.cached('some_key') { i }
52
- result.must_equal 1
53
- i += 1
54
- result = renderer.cached('different_key') { i }
55
- result.must_equal 3
56
- end
57
-
58
- it 'does not cache the value in preview mode' do
59
- renderer.stubs(:invocation => OpenStruct.new(:job_invocation_id => 1), :preview? => true)
60
-
61
- i = 1
62
- result = renderer.cached('some_key') { i }
63
- result.must_equal 1
64
- i += 1
65
- result = renderer.cached('some_key') { i }
66
- result.must_equal 2
67
- i += 1
68
- result = renderer.cached('different_key') { i }
69
- result.must_equal 3
70
- end
71
- end
72
42
  end
73
43
 
74
44
  context 'with matching input defined' do
@@ -156,24 +156,6 @@ class JobInvocationComposerTest < ActiveSupport::TestCase
156
156
  end
157
157
  end
158
158
 
159
- describe '#rerun_possible?' do
160
- it 'is true when not rerunning' do
161
- composer.must_be :rerun_possible?
162
- end
163
-
164
- it 'is true when rerunning with pattern tempalte invocations' do
165
- composer.expects(:reruns).returns(1)
166
- composer.job_invocation.expects(:pattern_template_invocations).returns([1])
167
- composer.must_be :rerun_possible?
168
- end
169
-
170
- it 'is false when rerunning without pattern template invocations' do
171
- composer.expects(:reruns).returns(1)
172
- composer.job_invocation.expects(:pattern_template_invocations).returns([])
173
- composer.wont_be :rerun_possible?
174
- end
175
- end
176
-
177
159
  describe '#selected_job_templates' do
178
160
  it 'returns no template if none was selected through params' do
179
161
  composer.selected_job_templates.must_be_empty
@@ -44,14 +44,14 @@ class JobTemplateTest < ActiveSupport::TestCase
44
44
  end
45
45
 
46
46
  it 'uses the job name as description_format if not set or blank and has no inputs' do
47
- minimal_template.generate_description_format.must_equal '%{template_name}'
47
+ minimal_template.generate_description_format.must_equal '%{job_category}'
48
48
  minimal_template.description_format = ''
49
- minimal_template.generate_description_format.must_equal '%{template_name}'
49
+ minimal_template.generate_description_format.must_equal '%{job_category}'
50
50
  end
51
51
 
52
52
  it 'generates the description_format if not set or blank and has inputs' do
53
53
  input_name = template.template_inputs.first.name
54
- expected_result = %(%{template_name} with inputs #{input_name}="%{#{input_name}}")
54
+ expected_result = %(%{job_category} with inputs #{input_name}="%{#{input_name}}")
55
55
  template.generate_description_format.must_equal expected_result
56
56
  template.description_format = ''
57
57
  template.generate_description_format.must_equal expected_result
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: 1.5.6
4
+ version: 1.6.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: 2018-09-13 00:00:00.000000000 Z
11
+ date: 2018-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deface
@@ -168,6 +168,7 @@ files:
168
168
  - app/lib/actions/middleware/bind_job_invocation.rb
169
169
  - app/lib/actions/remote_execution/run_host_job.rb
170
170
  - app/lib/actions/remote_execution/run_hosts_job.rb
171
+ - app/lib/foreman_remote_execution/renderer/scope/input.rb
171
172
  - app/lib/proxy_api/remote_execution_ssh.rb
172
173
  - app/mailers/.gitkeep
173
174
  - app/models/concerns/foreman_remote_execution/bookmark_extensions.rb
@@ -417,7 +418,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
417
418
  version: '0'
418
419
  requirements: []
419
420
  rubyforge_project:
420
- rubygems_version: 2.7.3
421
+ rubygems_version: 2.6.12
421
422
  signing_key:
422
423
  specification_version: 4
423
424
  summary: A plugin bringing remote execution to the Foreman, completing the config