foreman_remote_execution 14.0.2 → 14.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/api/v2/job_invocations_controller.rb +34 -17
  3. data/app/helpers/remote_execution_helper.rb +2 -2
  4. data/app/lib/actions/remote_execution/proxy_action.rb +10 -5
  5. data/app/lib/actions/remote_execution/run_host_job.rb +1 -1
  6. data/app/lib/actions/remote_execution/template_invocation_progress_logging.rb +2 -3
  7. data/app/views/api/v2/job_invocations/hosts.json.rabl +15 -0
  8. data/config/routes.rb +1 -0
  9. data/db/migrate/20240312133027_extend_template_invocation_events.rb +19 -0
  10. data/lib/foreman_remote_execution/version.rb +1 -1
  11. data/webpack/JobInvocationDetail/JobInvocationActions.js +1 -1
  12. data/webpack/JobInvocationDetail/JobInvocationConstants.js +84 -0
  13. data/webpack/JobInvocationDetail/JobInvocationDetail.scss +0 -1
  14. data/webpack/JobInvocationDetail/JobInvocationHostTable.js +210 -0
  15. data/webpack/JobInvocationDetail/JobInvocationSelectors.js +2 -2
  16. data/webpack/JobInvocationDetail/__tests__/MainInformation.test.js +5 -1
  17. data/webpack/JobInvocationDetail/__tests__/fixtures.js +9 -0
  18. data/webpack/JobInvocationDetail/index.js +56 -34
  19. data/webpack/__mocks__/foremanReact/components/HostDetails/DetailsCard/DefaultLoaderEmptyState.js +1 -2
  20. data/webpack/react_app/components/RecentJobsCard/JobStatusIcon.js +38 -7
  21. data/webpack/react_app/components/RecentJobsCard/constants.js +4 -0
  22. data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/HostStatus.test.js.snap +1 -1
  23. data/webpack/react_app/components/TargetingHosts/components/HostStatus.js +6 -6
  24. metadata +6 -94
  25. data/.babelrc.js +0 -3
  26. data/.eslintignore +0 -3
  27. data/.eslintrc +0 -13
  28. data/.github/workflows/js_ci.yml +0 -32
  29. data/.github/workflows/release.yml +0 -16
  30. data/.github/workflows/ruby_ci.yml +0 -19
  31. data/.gitignore +0 -19
  32. data/.packit.yaml +0 -45
  33. data/.prettierrc +0 -4
  34. data/.rubocop.yml +0 -105
  35. data/.rubocop_todo.yml +0 -516
  36. data/.tx/config +0 -10
  37. data/Gemfile +0 -5
  38. data/app/mailers/.gitkeep +0 -0
  39. data/app/views/dashboard/.gitkeep +0 -0
  40. data/foreman_remote_execution.gemspec +0 -33
  41. data/jsconfig.json +0 -8
  42. data/test/benchmark/run_hosts_job_benchmark.rb +0 -70
  43. data/test/benchmark/targeting_benchmark.rb +0 -31
  44. data/test/factories/foreman_remote_execution_factories.rb +0 -147
  45. data/test/functional/api/v2/foreign_input_sets_controller_test.rb +0 -58
  46. data/test/functional/api/v2/job_invocations_controller_test.rb +0 -446
  47. data/test/functional/api/v2/job_templates_controller_test.rb +0 -110
  48. data/test/functional/api/v2/registration_controller_test.rb +0 -73
  49. data/test/functional/api/v2/remote_execution_features_controller_test.rb +0 -34
  50. data/test/functional/api/v2/template_invocations_controller_test.rb +0 -33
  51. data/test/functional/cockpit_controller_test.rb +0 -16
  52. data/test/functional/job_invocations_controller_test.rb +0 -132
  53. data/test/functional/job_templates_controller_test.rb +0 -31
  54. data/test/functional/ui_job_wizard_controller_test.rb +0 -16
  55. data/test/graphql/mutations/job_invocations/create_test.rb +0 -58
  56. data/test/graphql/queries/job_invocation_query_test.rb +0 -31
  57. data/test/graphql/queries/job_invocations_query_test.rb +0 -35
  58. data/test/helpers/remote_execution_helper_test.rb +0 -46
  59. data/test/support/remote_execution_helper.rb +0 -5
  60. data/test/test_plugin_helper.rb +0 -9
  61. data/test/unit/actions/run_host_job_test.rb +0 -115
  62. data/test/unit/actions/run_hosts_job_test.rb +0 -214
  63. data/test/unit/api_params_test.rb +0 -25
  64. data/test/unit/concerns/foreman_tasks_cleaner_extensions_test.rb +0 -29
  65. data/test/unit/concerns/host_extensions_test.rb +0 -219
  66. data/test/unit/concerns/nic_extensions_test.rb +0 -9
  67. data/test/unit/execution_task_status_mapper_test.rb +0 -92
  68. data/test/unit/input_template_renderer_test.rb +0 -503
  69. data/test/unit/job_invocation_composer_test.rb +0 -974
  70. data/test/unit/job_invocation_report_template_test.rb +0 -60
  71. data/test/unit/job_invocation_test.rb +0 -232
  72. data/test/unit/job_template_effective_user_test.rb +0 -37
  73. data/test/unit/job_template_test.rb +0 -316
  74. data/test/unit/remote_execution_feature_test.rb +0 -86
  75. data/test/unit/remote_execution_provider_test.rb +0 -298
  76. data/test/unit/renderer_scope_input_test.rb +0 -49
  77. data/test/unit/targeting_test.rb +0 -206
  78. data/test/unit/template_invocation_input_value_test.rb +0 -38
@@ -1,503 +0,0 @@
1
- require 'test_plugin_helper'
2
-
3
- class InputTemplateRendererTest < ActiveSupport::TestCase
4
- let(:host) { FactoryBot.build(:host) }
5
-
6
- context 'renderer for simple template without inputs' do
7
- let(:renderer) { InputTemplateRenderer.new(FactoryBot.build(:job_template, :template => 'id <%= preview? %>')) }
8
-
9
- it 'should render the content' do
10
- assert_equal 'id false', renderer.render
11
- end
12
-
13
- it 'should render preview' do
14
- assert_equal 'id true', renderer.preview
15
- end
16
-
17
- it 'should allow accessing current_user' do
18
- setup_user(:view_job_templates)
19
- renderer = InputTemplateRenderer.new(FactoryBot.build(:job_template, :template => "They call me '<%= current_user %>'"))
20
- assert_equal "They call me '#{User.current.login}'", renderer.preview
21
- end
22
- end
23
-
24
- context 'renderer for template with user input used' do
25
- let(:template) { FactoryBot.build(:job_template, :template => 'service restart <%= input("service_name") -%>') }
26
- let(:renderer) { InputTemplateRenderer.new(template) }
27
-
28
- context 'but without input defined' do
29
- describe 'rendering' do
30
- let(:result) { renderer.render }
31
- it 'should return false' do
32
- refute result
33
- end
34
-
35
- it 'should register an error' do
36
- result # let is lazy
37
- assert_not_nil renderer.error_message
38
- assert_not_empty renderer.error_message
39
- end
40
- end
41
-
42
- describe 'preview' do
43
- let(:result) { renderer.preview }
44
- it 'should return false' do
45
- refute result
46
- end
47
-
48
- it 'should register an error' do
49
- result # let is lazy
50
- assert_not_nil renderer.error_message
51
- assert_not_empty renderer.error_message
52
- end
53
- end
54
- end
55
-
56
- context 'with matching input defined' do
57
-
58
- let(:job_invocation) { FactoryBot.create(:job_invocation) }
59
- let(:template_invocation) { FactoryBot.build(:template_invocation, :template => template) }
60
- let(:result) { renderer.render }
61
-
62
- before do
63
- template.template_inputs << FactoryBot.build(:template_input, :name => 'service_name', :input_type => 'user')
64
- job_invocation.template_invocations << template_invocation
65
- end
66
-
67
- describe 'rendering' do
68
- it 'can preview' do
69
- assert_equal 'service restart $USER_INPUT[service_name]', renderer.preview
70
- end
71
-
72
- context 'with invocation specified and a required input' do
73
- before do
74
- template.template_inputs.first.update(:required => true)
75
- template_invocation.reload
76
- renderer.invocation = template_invocation
77
- end
78
-
79
- it 'cannot render the content' do
80
- assert_not result
81
- refute_nil renderer.error_message
82
- refute_empty renderer.error_message
83
- end
84
- end
85
-
86
- context 'with invocation specified' do
87
- before do
88
- FactoryBot.create(:template_invocation_input_value,
89
- :template_invocation => template_invocation,
90
- :template_input => template.template_inputs.first,
91
- :value => 'foreman')
92
- template_invocation.reload # need to get input_values findable
93
- renderer.invocation = template_invocation
94
- end
95
-
96
- it 'can render with job invocation with corresponding value' do
97
- assert_equal 'service restart foreman', renderer.render
98
- end
99
- end
100
-
101
- it 'renders even without an input value' do
102
- renderer.invocation = template_invocation
103
- assert_equal 'service restart ', renderer.render
104
- end
105
-
106
- describe 'with circular reference' do
107
- let(:recursive_template_with_inputs) do
108
- FactoryBot.create(:job_template, :name => 'test', :template => 'test')
109
- end
110
-
111
- let(:template_with_inputs) do
112
- FactoryBot.create(:job_template, :template => 'test').tap do |template|
113
- template.foreign_input_sets << FactoryBot.build(:foreign_input_set, :target_template => recursive_template_with_inputs)
114
- end
115
- end
116
-
117
- let(:recursive_template_without_inputs) do
118
- FactoryBot.create(:job_template, :name => 'recursive template', :template => '<%= render_template("template with inputs", "action" => "install") %>')
119
- end
120
-
121
- let(:template_without_inputs) do
122
- FactoryBot.create(:job_template, :name => 'template with inputs', :template => "<%= render_template('#{recursive_template_without_inputs.name}') %>")
123
- end
124
-
125
- before do
126
- User.current = users :admin
127
- end
128
-
129
- it 'handles circular references in templates' do
130
- renderer.invocation = FactoryBot.build(:template_invocation, :template => template_without_inputs)
131
- renderer.template = template_without_inputs
132
- assert_not renderer.render
133
- assert_includes renderer.error_message, 'Recursive rendering of templates detected'
134
- end
135
-
136
- it 'handles circular references in inputs' do
137
- assert_raises(ActiveRecord::RecordInvalid) do
138
- input_set = FactoryBot.build(:foreign_input_set, :target_template => template_with_inputs, :include_all => false,
139
- :include => 'package, debug', :exclude => 'action,debug')
140
- recursive_template_with_inputs.foreign_input_sets << input_set
141
- recursive_template_with_inputs.save!
142
- end
143
- end
144
- end
145
- end
146
- end
147
-
148
- context 'renderer for template with input set and render_template' do
149
- let(:command_template) do
150
- FactoryBot.build(:job_template, :name => 'command action', :template => '<%= input("command") -%>').tap do |template|
151
- template.template_inputs << FactoryBot.build(:template_input, :name => 'command', :input_type => 'user')
152
- template.template_inputs << FactoryBot.build(:template_input, :name => 'debug', :input_type => 'user')
153
- end
154
- end
155
-
156
- let(:package_template) do
157
- FactoryBot.build(:job_template, :name => 'package action', :template => <<-TEMPLATE.strip_heredoc) do |template|
158
- <%= render_template("command action", "command" => "yum -y \#{ input("action") } \#{ input('package') }") -%>
159
- TEMPLATE
160
- template.template_inputs << FactoryBot.build(:template_input, :name => 'package', :input_type => 'user')
161
- template.template_inputs << FactoryBot.build(:template_input, :name => 'action', :input_type => 'user')
162
- template.foreign_input_sets << FactoryBot.build(:foreign_input_set, :target_template => command_template, :include_all => true, :exclude => 'command')
163
- end
164
- end
165
-
166
- let(:template) do
167
- FactoryBot.create(:job_template,
168
- :template => '<%= render_template("package action", { :action => "install" }, { :with_foreign_input_set => true }) %>').tap do |template|
169
- template.foreign_input_sets << FactoryBot.build(:foreign_input_set, :target_template => package_template, :include_all => true, :exclude => 'action')
170
- end
171
- end
172
-
173
- let(:job_invocation) { FactoryBot.create(:job_invocation) }
174
- let(:template_invocation) { FactoryBot.build(:template_invocation, :template => template) }
175
- let(:renderer) { InputTemplateRenderer.new(template) }
176
- let(:result) { renderer.render }
177
-
178
- before do
179
- User.current = users :admin
180
- command_template.save!
181
- package_template.save!
182
- job_invocation.template_invocations << template_invocation
183
- end
184
-
185
- describe 'foreign input set' do
186
- describe 'with include_all' do
187
- let(:template) do
188
- FactoryBot.create(:job_template, :template => '<%= render_template("package action", "action" => "install") %>').tap do |template|
189
- template.foreign_input_sets << FactoryBot.build(:foreign_input_set, :target_template => package_template, :include_all => true)
190
- end
191
- end
192
-
193
- let(:template_2) do
194
- FactoryBot.create(:job_template, :template => '<%= render_template("package action", "action" => "install") %>').tap do |template|
195
- template.foreign_input_sets << FactoryBot.build(:foreign_input_set,
196
- :target_template => package_template, :include_all => true, :include => '', :exclude => '')
197
- end
198
- end
199
-
200
- it 'includes all inputs from the imported template' do
201
- assert_equal ['action', 'debug', 'package'], template.template_inputs_with_foreign.map(&:name).sort
202
- assert_equal ['action', 'debug', 'package'], template_2.template_inputs_with_foreign.map(&:name).sort
203
- end
204
- end
205
-
206
- describe 'with include_all and some excludes' do
207
- let(:template) do
208
- FactoryBot.create(:job_template, :template => '<%= render_template("package action", "action" => "install") %>').tap do |template|
209
- template.foreign_input_sets << FactoryBot.build(:foreign_input_set, :target_template => package_template, :include_all => true, :exclude => 'action,debug')
210
- end
211
- end
212
-
213
- it 'includes all inputs from the imported template except the listed once' do
214
- assert_equal ['package'], template.template_inputs_with_foreign.map(&:name).sort
215
- end
216
- end
217
-
218
- describe 'with some includes and some excludes' do
219
- let(:template) do
220
- FactoryBot.create(:job_template, :template => '<%= render_template("package action", "action" => "install") %>').tap do |template|
221
- template.foreign_input_sets << FactoryBot.build(:foreign_input_set, :target_template => package_template, :include_all => false,
222
- :include => 'package, debug', :exclude => 'action,debug')
223
- end
224
- end
225
-
226
- it 'includes all inputs from the imported template' do
227
- assert_equal ['package'], template.template_inputs_with_foreign.map(&:name).sort
228
- end
229
- end
230
- end
231
-
232
- context 'with invocation specified' do
233
- before do
234
- FactoryBot.create(:template_invocation_input_value,
235
- :template_invocation => template_invocation,
236
- :template_input => template.template_inputs_with_foreign.find { |input| input.name == 'package' },
237
- :value => 'zsh')
238
- renderer.invocation = template_invocation
239
- renderer.invocation.reload
240
- end
241
-
242
- it 'can render with job invocation with corresponding value' do
243
- rendered = renderer.render
244
- assert_nil renderer.error_message
245
- assert_equal 'yum -y install zsh', rendered
246
- end
247
- end
248
-
249
- context 'with explicitly specifying inputs' do
250
- let(:template) do
251
- FactoryBot.create(:job_template,
252
- :template => '<%= render_template("package action", {"action" => "install", :package => "zsh"}) %>')
253
- end
254
-
255
- before do
256
- template_invocation.reload
257
- renderer.invocation = template_invocation
258
- end
259
-
260
- it 'can render with job invocation with corresponding value' do
261
- rendered = renderer.render
262
- assert_nil renderer.error_message
263
- assert_equal 'yum -y install zsh', rendered
264
- end
265
- end
266
-
267
- it 'renders even without an input value' do
268
- renderer.invocation = template_invocation
269
- rendered = renderer.render
270
- assert_nil renderer.error_message
271
- assert_equal 'yum -y install ', rendered
272
- end
273
- end
274
-
275
- context 'with options specified' do
276
- let(:job_invocation) { FactoryBot.create(:job_invocation) }
277
- let(:template_invocation) { FactoryBot.build(:template_invocation, :template => template) }
278
- let(:result) { renderer.render }
279
- let(:required) { false }
280
- let(:input) do
281
- FactoryBot.create(:template_invocation_input_value,
282
- :template_invocation => template_invocation,
283
- :template_input => template.template_inputs.first,
284
- :value => 'foreman')
285
- end
286
-
287
- before do
288
- template.template_inputs << FactoryBot.build(:template_input, :name => 'service_name', :input_type => 'user', :options => "httpd\nforeman", :required => required)
289
- job_invocation.template_invocations << template_invocation
290
- input
291
- template_invocation.reload
292
- renderer.invocation = template_invocation
293
- end
294
-
295
- context 'with a valid input defined' do
296
- context 'with an optional input' do
297
- it 'can render with job invocation with corresponding value' do
298
- assert_equal 'service restart foreman', result
299
- end
300
- end
301
-
302
- context 'with required input' do
303
- let(:required) { true }
304
-
305
- it 'renders the template when the input is provided' do
306
- assert_equal 'service restart foreman', result
307
- end
308
- end
309
- end
310
-
311
- context 'without provided input' do
312
- let(:input) { nil }
313
-
314
- context 'with optional input' do
315
- it 'renders the template' do
316
- assert_equal 'service restart ', result
317
- end
318
- end
319
-
320
- context 'with required input' do
321
- let(:required) { true }
322
-
323
- it 'renders the template' do
324
- result
325
- assert_match(/Value for required input '.*' was not specified/, renderer.error_message)
326
- end
327
- end
328
- end
329
- end
330
- end
331
-
332
- context 'renderer for template with fact input used' do
333
- let(:template) { FactoryBot.build(:job_template, :template => 'echo <%= input("issue") -%> > /etc/issue') }
334
- let(:renderer) { InputTemplateRenderer.new(template) }
335
-
336
- context 'with matching input defined' do
337
- before { renderer.template.template_inputs<< FactoryBot.build(:template_input, :name => 'issue', :input_type => 'fact', :fact_name => 'issue', :required => true) }
338
- let(:result) { renderer.render }
339
-
340
- describe 'rendering' do
341
- it 'can\'t render the content without host since we don\'t have facts' do
342
- assert_not result
343
- end
344
-
345
- it 'registers an error' do
346
- result # let is lazy
347
- assert_not_nil renderer.error_message
348
- assert_not_empty renderer.error_message
349
- end
350
-
351
- context 'with host specified' do
352
- before { renderer.host = FactoryBot.create(:host) }
353
-
354
- describe 'rendering' do
355
- it 'can\'t render the content without host since we don\'t have fact value' do
356
- assert_not result
357
- end
358
-
359
- it 'registers an error' do
360
- result # let is lazy
361
- assert_not_nil renderer.error_message
362
- assert_not_empty renderer.error_message
363
- end
364
- end
365
-
366
- describe 'preview' do
367
- it 'should render preview' do
368
- assert_equal 'echo $FACT_INPUT[issue] > /etc/issue', renderer.preview
369
- end
370
- end
371
-
372
- context 'with existing fact' do
373
- let(:fact) { FactoryBot.create(:fact_name, :name => 'issue') }
374
-
375
- describe 'rendering' do
376
- it 'can\'t render the content without host since we don\'t have fact value' do
377
- fact # let is lazy
378
- assert_not result
379
- end
380
-
381
- it 'registers an error' do
382
- result # let is lazy
383
- assert_not_nil renderer.error_message
384
- assert_not_empty renderer.error_message
385
- end
386
- end
387
-
388
- describe 'preview' do
389
- it 'should render preview' do
390
- assert_equal 'echo $FACT_INPUT[issue] > /etc/issue', renderer.preview
391
- end
392
- end
393
-
394
- context 'with fact issue value' do
395
- before { FactoryBot.create(:fact_value, :host => renderer.host, :fact_name => fact, :value => 'banner') }
396
-
397
- let(:result) { renderer.render }
398
-
399
- it 'can render with job invocation with corresponding value' do
400
- assert_equal 'echo banner > /etc/issue', result
401
- end
402
- end
403
- end
404
- end
405
- end
406
-
407
- describe 'preview' do
408
- it 'should render preview' do
409
- assert_equal 'echo $FACT_INPUT[issue] > /etc/issue', renderer.preview
410
- end
411
-
412
- context 'with host specified' do
413
- before do
414
- host = FactoryBot.create(:host)
415
- fact = FactoryBot.create(:fact_name, :name => 'issue')
416
- FactoryBot.create(:fact_value, :host => host, :fact_name => fact, :value => 'banner')
417
- renderer.host = host
418
- end
419
-
420
- let(:result) { renderer.render }
421
-
422
- it 'uses the value even in preview' do
423
- assert_equal 'echo banner > /etc/issue', result
424
- end
425
- end
426
- end
427
- end
428
- end
429
-
430
- context 'renderer for template with variable input used' do
431
- let(:template) { FactoryBot.build(:job_template, :template => 'echo <%= input("client_key") -%> > /etc/chef/client.pem') }
432
- let(:renderer) { InputTemplateRenderer.new(template) }
433
-
434
- context 'with matching input defined' do
435
- before { renderer.template.template_inputs<< FactoryBot.build(:template_input, :name => 'client_key', :input_type => 'variable', :variable_name => 'client_key') }
436
- let(:result) { renderer.render }
437
-
438
- describe 'rendering' do
439
- it 'can\'t render the content without host since we don\'t have host so no classification' do
440
- assert_not result
441
- end
442
-
443
- it 'registers an error' do
444
- result # let is lazy
445
- refute_nil renderer.error_message
446
- refute_empty renderer.error_message
447
- end
448
-
449
- context 'with host specified' do
450
- before { User.current = FactoryBot.build(:user, :admin) }
451
- after { User.current = nil }
452
-
453
- before { renderer.host = FactoryBot.create(:host) }
454
-
455
- describe 'rendering' do
456
- it 'can\'t render the content without host since we don\'t have variable value in classification' do
457
- assert_not result
458
- end
459
-
460
- it 'registers an error' do
461
- result # let is lazy
462
- refute_nil renderer.error_message
463
- refute_empty renderer.error_message
464
- end
465
- end
466
-
467
- describe 'preview' do
468
- it 'should render preview' do
469
- assert_equal 'echo $VARIABLE_INPUT[client_key] > /etc/chef/client.pem', renderer.preview
470
- end
471
- end
472
-
473
-
474
- context 'with existing variable implemented as host parameter' do
475
- let(:parameter) { FactoryBot.create(:host_parameter, :host => renderer.host, :name => 'client_key', :value => 'RSA KEY') }
476
-
477
- describe 'rendering' do
478
- it 'renders the value from host parameter' do
479
- parameter
480
- renderer.host.reload
481
- assert_equal 'echo RSA KEY > /etc/chef/client.pem', result
482
- end
483
- end
484
-
485
- describe 'preview' do
486
- it 'should render preview' do
487
- parameter
488
- renderer.host.reload
489
- assert_equal 'echo RSA KEY > /etc/chef/client.pem', renderer.preview
490
- end
491
- end
492
- end
493
- end
494
-
495
- describe 'preview' do
496
- it 'should render preview' do
497
- assert_equal 'echo $VARIABLE_INPUT[client_key] > /etc/chef/client.pem', renderer.preview
498
- end
499
- end
500
- end
501
- end
502
- end
503
- end