foreman_remote_execution 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/template_invocation.js +48 -5
  3. data/app/controllers/api/v2/job_invocations_controller.rb +55 -10
  4. data/app/controllers/api/v2/job_templates_controller.rb +19 -4
  5. data/app/controllers/api/v2/template_inputs_controller.rb +88 -0
  6. data/app/controllers/job_invocations_controller.rb +17 -15
  7. data/app/controllers/template_invocations_controller.rb +2 -0
  8. data/app/helpers/remote_execution_helper.rb +27 -16
  9. data/app/lib/actions/middleware/bind_job_invocation.rb +7 -3
  10. data/app/lib/actions/remote_execution/run_host_job.rb +28 -17
  11. data/app/lib/actions/remote_execution/run_hosts_job.rb +9 -6
  12. data/app/models/concerns/foreman_remote_execution/foreman_tasks_task_extensions.rb +1 -1
  13. data/app/models/concerns/foreman_remote_execution/foreman_tasks_triggering_extensions.rb +9 -0
  14. data/app/models/concerns/foreman_remote_execution/host_extensions.rb +3 -1
  15. data/app/models/job_invocation.rb +48 -41
  16. data/app/models/job_invocation_composer.rb +205 -80
  17. data/app/models/job_invocation_task_group.rb +18 -0
  18. data/app/models/job_template.rb +25 -1
  19. data/app/models/job_template_effective_user.rb +23 -0
  20. data/app/models/remote_execution_provider.rb +25 -11
  21. data/app/models/setting/remote_execution.rb +6 -0
  22. data/app/models/ssh_execution_provider.rb +37 -0
  23. data/app/models/targeting.rb +13 -0
  24. data/app/models/template_input.rb +4 -1
  25. data/app/models/template_invocation.rb +23 -0
  26. data/app/views/api/v2/job_invocations/base.json.rabl +4 -0
  27. data/app/views/api/v2/job_invocations/index.json.rabl +1 -1
  28. data/app/views/api/v2/job_invocations/main.json.rabl +19 -0
  29. data/app/views/api/v2/job_invocations/show.json.rabl +0 -15
  30. data/app/views/api/v2/job_templates/base.json.rabl +1 -1
  31. data/app/views/api/v2/job_templates/index.json.rabl +1 -1
  32. data/app/views/api/v2/job_templates/main.json.rabl +5 -1
  33. data/app/views/api/v2/job_templates/show.json.rabl +4 -0
  34. data/app/views/api/v2/job_templates/update.json.rabl +3 -0
  35. data/app/views/api/v2/template_inputs/base.json.rabl +3 -0
  36. data/app/views/api/v2/template_inputs/create.json.rabl +3 -0
  37. data/app/views/api/v2/template_inputs/index.json.rabl +3 -0
  38. data/app/views/api/v2/template_inputs/main.json.rabl +9 -0
  39. data/app/views/api/v2/template_inputs/show.json.rabl +3 -0
  40. data/app/views/job_invocation_task_groups/_job_invocation_task_group.html.erb +31 -0
  41. data/app/views/job_invocation_task_groups/_job_invocation_task_groups.html.erb +3 -0
  42. data/app/views/job_invocations/_form.html.erb +102 -71
  43. data/app/views/job_invocations/_tab_overview.html.erb +5 -2
  44. data/app/views/job_invocations/index.html.erb +4 -4
  45. data/app/views/job_invocations/refresh.js.erb +2 -1
  46. data/app/views/job_invocations/show.html.erb +13 -2
  47. data/app/views/job_invocations/show.js.erb +1 -1
  48. data/app/views/job_templates/_custom_tabs.html.erb +16 -0
  49. data/app/views/templates/package_action.erb +1 -0
  50. data/app/views/templates/puppet_run_once.erb +1 -0
  51. data/app/views/templates/run_command.erb +1 -0
  52. data/app/views/templates/service_action.erb +1 -0
  53. data/config/routes.rb +15 -2
  54. data/db/migrate/20150923125825_add_job_invocation_task_group.rb +10 -0
  55. data/db/migrate/20151022105508_rename_last_task_id_column.rb +6 -0
  56. data/db/migrate/20151116105412_add_triggering_to_job_invocation.rb +10 -0
  57. data/db/migrate/20151120171100_add_effective_user_to_template_invocation.rb +5 -0
  58. data/db/migrate/20151124162300_create_job_template_effective_users.rb +13 -0
  59. data/db/migrate/20151203100824_add_description_to_job_invocation.rb +11 -0
  60. data/db/migrate/20151215114631_add_host_id_to_template_invocation.rb +29 -0
  61. data/db/migrate/20151217092555_migrate_to_task_groups.rb +16 -0
  62. data/foreman_remote_execution.gemspec +2 -1
  63. data/lib/foreman_remote_execution/engine.rb +30 -5
  64. data/lib/foreman_remote_execution/version.rb +1 -1
  65. data/test/factories/foreman_remote_execution_factories.rb +5 -0
  66. data/test/functional/api/v2/job_invocations_controller_test.rb +3 -3
  67. data/test/functional/api/v2/template_inputs_controller_test.rb +61 -0
  68. data/test/unit/actions/run_hosts_job_test.rb +10 -3
  69. data/test/unit/concerns/host_extensions_test.rb +10 -6
  70. data/test/unit/job_invocation_composer_test.rb +229 -10
  71. data/test/unit/job_invocation_test.rb +27 -27
  72. data/test/unit/job_template_effective_user_test.rb +41 -0
  73. data/test/unit/job_template_test.rb +24 -0
  74. data/test/unit/remote_execution_provider_test.rb +39 -0
  75. metadata +42 -7
  76. data/app/models/job_invocation_api_composer.rb +0 -69
  77. data/test/unit/job_invocation_api_composer_test.rb +0 -143
@@ -27,8 +27,10 @@ describe JobInvocationComposer do
27
27
  let(:unauthorized_job_template_1) { FactoryGirl.create(:job_template, :job_name => 'testing_job_template_1', :name => 'unauth1', :provider_type => 'Ssh') }
28
28
  let(:unauthorized_job_template_2) { FactoryGirl.create(:job_template, :job_name => 'unauthorized_job_template_2', :name => 'unauth2', :provider_type => 'Ansible') }
29
29
 
30
+
30
31
  let(:input1) { FactoryGirl.create(:template_input, :template => testing_job_template_1, :input_type => 'user') }
31
32
  let(:input2) { FactoryGirl.create(:template_input, :template => testing_job_template_3, :input_type => 'user') }
33
+ let(:input3) { FactoryGirl.create(:template_input, :template => testing_job_template_1, :input_type => 'user', :required => true) }
32
34
  let(:unauthorized_input1) { FactoryGirl.create(:template_input, :template => unauthorized_job_template_1, :input_type => 'user') }
33
35
 
34
36
  let(:ansible_params) { { } }
@@ -38,8 +40,7 @@ describe JobInvocationComposer do
38
40
 
39
41
  context 'with general new invocation and empty params' do
40
42
  let(:params) { {} }
41
- let(:job_invocation) { JobInvocation.new.tap { |job_invocation| job_invocation.stubs(:trigger_mode=) } }
42
- let(:composer) { JobInvocationComposer.new(job_invocation).compose_from_params(params) }
43
+ let(:composer) { JobInvocationComposer.from_ui_params(params) }
43
44
 
44
45
  describe '#available_templates' do
45
46
  it 'obeys authorization' do
@@ -108,7 +109,9 @@ describe JobInvocationComposer do
108
109
  end
109
110
 
110
111
  it 'returns only authorized inputs based on templates' do
111
- composer.available_template_inputs.must_be_empty
112
+ composer.available_template_inputs.must_include(input1)
113
+ composer.available_template_inputs.must_include(input2)
114
+ composer.available_template_inputs.wont_include(unauthorized_input1)
112
115
  end
113
116
 
114
117
  context 'params contains job template ids' do
@@ -246,6 +249,54 @@ describe JobInvocationComposer do
246
249
  end
247
250
  end
248
251
 
252
+ describe '#effective_user' do
253
+ let(:ssh_params) do
254
+ { :job_template_id => testing_job_template_1.id.to_s,
255
+ :job_templates => {
256
+ testing_job_template_1.id.to_s => {
257
+ :effective_user => invocation_effective_user
258
+ }
259
+ }
260
+ }
261
+ end
262
+ let(:params) { { :job_invocation => { :providers => { :ssh => ssh_params } } }.with_indifferent_access }
263
+ let(:template_invocation) do
264
+ testing_job_template_1.effective_user.update_attributes(:overridable => overridable, :value => 'template user')
265
+ composer.template_invocations.first
266
+ end
267
+
268
+ before do
269
+ Setting::RemoteExecution.load_defaults
270
+ end
271
+
272
+ context 'when overridable and provided' do
273
+ let(:overridable) { true }
274
+ let(:invocation_effective_user) { 'invocation user' }
275
+
276
+ it 'takes the value from the template invocation' do
277
+ template_invocation.effective_user.must_equal 'invocation user'
278
+ end
279
+ end
280
+
281
+ context 'when overridable and not provided' do
282
+ let(:overridable) { true }
283
+ let(:invocation_effective_user) { "" }
284
+
285
+ it 'takes the value from the job template' do
286
+ template_invocation.effective_user.must_equal 'template user'
287
+ end
288
+ end
289
+
290
+ context 'when not overridable and provided' do
291
+ let(:overridable) { false }
292
+ let(:invocation_effective_user) { "invocation user" }
293
+
294
+ it 'takes the value from the job template' do
295
+ template_invocation.effective_user.must_equal 'template user'
296
+ end
297
+ end
298
+ end
299
+
249
300
  describe '#displayed_search_query' do
250
301
  it 'is empty by default' do
251
302
  composer.displayed_search_query.must_be_empty
@@ -395,23 +446,33 @@ describe JobInvocationComposer do
395
446
 
396
447
  it 'validates all associated objects even if some of the is invalid' do
397
448
  composer
398
- job_invocation.expects(:valid?).returns(false)
449
+ composer.job_invocation.expects(:valid?).returns(false)
399
450
  composer.targeting.expects(:valid?).returns(false)
400
451
  composer.template_invocations.each { |invocation| invocation.expects(:valid?).returns(false) }
401
452
  refute composer.valid?
402
453
  end
403
454
  end
404
455
 
456
+ describe 'triggering' do
457
+ let(:params) do
458
+ { :job_invocation => { :providers => { :ssh => ssh_params } }, :triggering => { :mode => 'future' }}.with_indifferent_access
459
+ end
460
+
461
+ it 'accepts the triggering params' do
462
+ composer.job_invocation.triggering.mode.must_equal :future
463
+ end
464
+ end
465
+
405
466
  describe '#save' do
406
467
  it 'triggers save on job_invocation if it is valid' do
407
468
  composer.stubs(:valid? => true)
408
- job_invocation.expects(:save)
469
+ composer.job_invocation.expects(:save)
409
470
  composer.save
410
471
  end
411
472
 
412
473
  it 'does not trigger save on job_invocation if it is invalid' do
413
474
  composer.stubs(:valid? => false)
414
- job_invocation.expects(:save).never
475
+ composer.job_invocation.expects(:save).never
415
476
  composer.save
416
477
  end
417
478
  end
@@ -419,7 +480,7 @@ describe JobInvocationComposer do
419
480
  describe '#job_name' do
420
481
  it 'triggers job_name on job_invocation' do
421
482
  composer
422
- job_invocation.expects(:job_name)
483
+ composer.job_invocation.expects(:job_name)
423
484
  composer.job_name
424
485
  end
425
486
  end
@@ -427,7 +488,7 @@ describe JobInvocationComposer do
427
488
  describe '#targeting' do
428
489
  it 'triggers targeting on job_invocation' do
429
490
  composer
430
- job_invocation.expects(:targeting)
491
+ composer.job_invocation.expects(:targeting)
431
492
  composer.targeting
432
493
  end
433
494
  end
@@ -452,9 +513,9 @@ describe JobInvocationComposer do
452
513
  }
453
514
  }.with_indifferent_access
454
515
  end
455
- let(:existing) { job_invocation.reload }
516
+ let(:existing) { composer.job_invocation.reload }
456
517
  let(:new_job_invocation) { JobInvocation.new }
457
- let(:new_composer) { JobInvocationComposer.new(new_job_invocation).compose_from_invocation(job_invocation) }
518
+ let(:new_composer) { JobInvocationComposer.from_job_invocation(composer.job_invocation) }
458
519
 
459
520
  before do
460
521
  composer.save
@@ -480,4 +541,162 @@ describe JobInvocationComposer do
480
541
  end
481
542
  end
482
543
  end
544
+
545
+ describe '#from_api_params' do
546
+ let(:composer) { JobInvocationComposer.from_api_params(params) }
547
+ let(:bookmark) { bookmarks(:one) }
548
+
549
+ context 'with targeting from bookmark' do
550
+
551
+ before do
552
+ [testing_job_template_1, testing_job_template_3] # mentioning templates we want to have initialized in the test
553
+ end
554
+
555
+ let(:params) do
556
+ { :job_name => testing_job_template_1.job_name,
557
+ :job_template_id => testing_job_template_1.id,
558
+ :targeting_type => "static_query",
559
+ :bookmark_id => bookmark.id }
560
+ end
561
+
562
+ it "creates invocation with a bookmark" do
563
+ assert composer.save!
564
+ assert_equal bookmark, composer.job_invocation.targeting.bookmark
565
+ assert_equal composer.job_invocation.targeting.user, User.current
566
+ refute_empty composer.job_invocation.template_invocations
567
+ end
568
+ end
569
+
570
+ context "with targeting from search query" do
571
+ let(:params) do
572
+ { :job_name => testing_job_template_1.job_name,
573
+ :job_template_id => testing_job_template_1.id,
574
+ :targeting_type => "static_query",
575
+ :search_query => "some hosts" }
576
+ end
577
+
578
+ it "creates invocation with a search query" do
579
+ assert composer.save!
580
+ assert_equal "some hosts", composer.job_invocation.targeting.search_query
581
+ refute_empty composer.job_invocation.template_invocations
582
+ end
583
+ end
584
+
585
+ context "with with inputs" do
586
+ let(:params) do
587
+ { :job_name => testing_job_template_1.job_name,
588
+ :job_template_id => testing_job_template_1.id,
589
+ :targeting_type => "static_query",
590
+ :search_query => "some hosts",
591
+ :inputs => {input1.name => "some_value"}}
592
+ end
593
+
594
+ it "finds the inputs by name" do
595
+ assert composer.save!
596
+ assert_equal 1, composer.template_invocations.first.input_values.count
597
+ end
598
+ end
599
+
600
+ context "with effective user" do
601
+ let(:params) do
602
+ { :job_name => testing_job_template_1.job_name,
603
+ :job_template_id => testing_job_template_1.id,
604
+ :effective_user => 'invocation user',
605
+ :targeting_type => "static_query",
606
+ :search_query => "some hosts",
607
+ :inputs => {input1.name => "some_value"}}
608
+ end
609
+
610
+ let(:template_invocation) { composer.job_invocation.template_invocations.first }
611
+
612
+ it "sets the effective user based on the input" do
613
+ assert composer.save!
614
+ template_invocation.effective_user.must_equal 'invocation user'
615
+ end
616
+ end
617
+
618
+ context "with invalid targeting" do
619
+ let(:params) do
620
+ { :job_name => testing_job_template_1.job_name,
621
+ :job_template_id => testing_job_template_1.id,
622
+ :search_query => "some hosts",
623
+ :inputs => {input1.name => "some_value"}}
624
+ end
625
+
626
+ it "handles errors" do
627
+ assert_raises(ActiveRecord::RecordNotSaved) do
628
+ composer.save!
629
+ end
630
+ end
631
+ end
632
+
633
+ context "with invalid bookmark and search query" do
634
+ let(:params) do
635
+ { :job_name => testing_job_template_1.job_name,
636
+ :job_template_id => testing_job_template_1.id,
637
+ :targeting_type => "static_query",
638
+ :search_query => "some hosts",
639
+ :bookmark_id => bookmark.id,
640
+ :inputs => {input1.name => "some_value"}}
641
+ end
642
+
643
+ it "handles errors" do
644
+ assert_raises(Foreman::Exception) do
645
+ JobInvocationComposer.from_api_params(params)
646
+ end
647
+ end
648
+ end
649
+
650
+ context "with invalid inputs" do
651
+ let(:params) do
652
+ { :job_name => testing_job_template_1.job_name,
653
+ :job_template_id => testing_job_template_1.id,
654
+ :targeting_type => "static_query",
655
+ :search_query => "some hosts",
656
+ :inputs => {input3.name => nil}}
657
+ end
658
+
659
+ it "handles errors" do
660
+ error = assert_raises(ActiveRecord::RecordNotSaved) do
661
+ composer.save!
662
+ end
663
+ error.message.must_include "Template #{testing_job_template_1.name}: Input #{input3.name.downcase}: Value can't be blank"
664
+ end
665
+ end
666
+
667
+ context "with empty values for non-required inputs" do
668
+ let(:params) do
669
+ { :job_name => testing_job_template_1.job_name,
670
+ :job_template_id => testing_job_template_1.id,
671
+ :targeting_type => "static_query",
672
+ :search_query => "some hosts",
673
+ :inputs => {input3.name => "some value"}}
674
+ end
675
+
676
+ it "accepts the params" do
677
+ composer.save!
678
+ refute composer.job_invocation.new_record?
679
+ end
680
+ end
681
+
682
+ context "with missing required inputs" do
683
+ let(:params) do
684
+ { :job_name => testing_job_template_1.job_name,
685
+ :job_template_id => testing_job_template_1.id,
686
+ :targeting_type => "static_query",
687
+ :search_query => "some hosts",
688
+ :inputs => {input1.name => "some_value"}}
689
+ end
690
+
691
+ it "handles errors" do
692
+ input3.must_be :required
693
+
694
+ error = assert_raises(ActiveRecord::RecordNotSaved) do
695
+ composer.save!
696
+ end
697
+
698
+ error.message.must_include "Template #{testing_job_template_1.name}: Not all required inputs have values. Missing inputs: #{input3.name}"
699
+ end
700
+ end
701
+ end
483
702
  end
@@ -5,6 +5,17 @@ describe JobInvocation do
5
5
  let(:job_invocation) { FactoryGirl.build(:job_invocation) }
6
6
  let(:template) { FactoryGirl.create(:job_template, :with_input) }
7
7
 
8
+ context 'Search for job invocations' do
9
+ before do
10
+ job_invocation.save
11
+ end
12
+
13
+ it 'is able to perform search through job invocations' do
14
+ found_jobs = JobInvocation.search_for(%{job_name = "#{job_invocation.job_name}"}).paginate(:page => 1).with_task.order('job_invocations.id DESC')
15
+ found_jobs.must_equal [job_invocation]
16
+ end
17
+ end
18
+
8
19
  context 'Able to be created' do
9
20
  it { assert job_invocation.save }
10
21
  end
@@ -35,6 +46,22 @@ describe JobInvocation do
35
46
  @input_value.destroy
36
47
  refute job_invocation.reload.valid?
37
48
  end
49
+
50
+ describe 'descriptions' do
51
+ it 'generates description from input values' do
52
+ job_invocation.expects(:save!)
53
+ job_invocation.description_format = '%{job_name} - %{foo}'
54
+ job_invocation.generate_description!
55
+ job_invocation.description.must_equal "#{job_invocation.job_name} - #{@input_value.value}"
56
+ end
57
+
58
+ it 'handles missing keys correctly' do
59
+ job_invocation.expects(:save!)
60
+ job_invocation.description_format = '%{job_name} - %{missing_key}'
61
+ job_invocation.generate_description!
62
+ job_invocation.description.must_equal "#{job_invocation.job_name} - %{missing_key}"
63
+ end
64
+ end
38
65
  end
39
66
 
40
67
  context 'future execution' do
@@ -45,32 +72,5 @@ describe JobInvocation do
45
72
  job_invocation.total_hosts_count.must_equal 0
46
73
  end
47
74
 
48
- it 'has default trigger mode' do
49
- job_invocation.trigger_mode.must_equal :immediate
50
- end
51
-
52
- it 'cannot set trigger mode to anything other than :immediate or :future' do
53
- proc { job_invocation.trigger_mode = 'test' }.must_raise ::Foreman::Exception
54
- job_invocation.trigger_mode.must_equal :immediate
55
- end
56
-
57
- it 'cannot change trigger mode once set' do
58
- job_invocation.trigger_mode = 'future'
59
- job_invocation.trigger_mode = 'immediate'
60
- job_invocation.trigger_mode.must_equal :future
61
- end
62
-
63
- it 'parses times' do
64
- time = Time.new(2015, 9, 16, 13, 56)
65
- time_string = time.strftime(job_invocation.time_format)
66
- job_invocation.start_at_parsed.must_equal false
67
- job_invocation.start_at = time_string
68
- job_invocation.start_at_parsed.must_equal time
69
- job_invocation.start_before.must_be_nil
70
- job_invocation.start_before_parsed.must_be_nil
71
- job_invocation.start_before = time_string
72
- job_invocation.start_before_parsed.must_equal time
73
- end
74
-
75
75
  end
76
76
  end
@@ -0,0 +1,41 @@
1
+ require 'test_plugin_helper'
2
+
3
+ describe JobTemplateEffectiveUser do
4
+ let(:job_template) { FactoryGirl.build(:job_template, :job_name => '') }
5
+ let(:effective_user) { job_template.effective_user }
6
+
7
+ before do
8
+ Setting::RemoteExecution.load_defaults
9
+ end
10
+
11
+ describe 'by default' do
12
+ it 'is overridable' do
13
+ assert effective_user.overridable?
14
+ end
15
+
16
+ it 'does not use the current user' do
17
+ refute effective_user.current_user?
18
+ end
19
+ end
20
+
21
+ describe 'compute value' do
22
+ it 'computes the value based on the current user when current_user set to true' do
23
+ user = FactoryGirl.create(:user)
24
+ User.current = user
25
+ effective_user.current_user = true
26
+ effective_user.compute_value.must_equal user.login
27
+ end
28
+
29
+ it 'returns the value when not current user is set to true' do
30
+ effective_user.current_user = false
31
+ effective_user.value = 'testuser'
32
+ effective_user.compute_value.must_equal 'testuser'
33
+ end
34
+
35
+ it 'returns a default value when no value is specified for the user' do
36
+ effective_user.value = ""
37
+ Setting[:remote_execution_effective_user] = 'myuser'
38
+ effective_user.compute_value.must_equal 'myuser'
39
+ end
40
+ end
41
+ end
@@ -14,6 +14,30 @@ describe JobTemplate do
14
14
  end
15
15
  end
16
16
 
17
+ context 'description format' do
18
+ let(:template_with_description) { FactoryGirl.build(:job_template, :with_description_format, :job_name => 'test job') }
19
+ let(:template) { FactoryGirl.build(:job_template, :with_input, :job_name => 'test job') }
20
+ let(:minimal_template) { FactoryGirl.build(:job_template) }
21
+
22
+ it 'uses the description_format attribute if set' do
23
+ template_with_description.generate_description_format.must_equal template_with_description.description_format
24
+ end
25
+
26
+ it 'uses the job name as description_format if not set or blank and has no inputs' do
27
+ minimal_template.generate_description_format.must_equal '%{job_name}'
28
+ minimal_template.description_format = ''
29
+ minimal_template.generate_description_format.must_equal '%{job_name}'
30
+ end
31
+
32
+ it 'generates the description_format if not set or blank and has inputs' do
33
+ input_name = template.template_inputs.first.name
34
+ expected_result = %Q(%{job_name} with inputs #{input_name}="%{#{input_name}}")
35
+ template.generate_description_format.must_equal expected_result
36
+ template.description_format = ''
37
+ template.generate_description_format.must_equal expected_result
38
+ end
39
+ end
40
+
17
41
  context 'cloning' do
18
42
  let(:job_template) { FactoryGirl.build(:job_template, :with_input) }
19
43
 
@@ -48,4 +48,43 @@ describe RemoteExecutionProvider do
48
48
  it { provider_names.must_include 'Custom' }
49
49
  end
50
50
  end
51
+
52
+ describe SSHExecutionProvider do
53
+ before do
54
+ Setting::RemoteExecution.load_defaults
55
+ end
56
+
57
+ let(:job_invocation) { FactoryGirl.create(:job_invocation, :with_template) }
58
+ let(:template_invocation) { job_invocation.template_invocations.first }
59
+ let(:host) { FactoryGirl.create(:host) }
60
+ let(:proxy_options) { SSHExecutionProvider.proxy_command_options(template_invocation, host) }
61
+
62
+ describe 'effective user' do
63
+ it 'takes the effective user from value from the template invocation' do
64
+ template_invocation.effective_user = 'my user'
65
+ proxy_options[:effective_user].must_equal 'my user'
66
+ end
67
+ end
68
+
69
+ describe 'ssh user' do
70
+ it 'uses the remote_execution_ssh_user on the host param' do
71
+ host.params['remote_execution_ssh_user'] = 'my user'
72
+ host.host_parameters << FactoryGirl.build(:host_parameter, :name => 'remote_execution_ssh_user', :value => 'my user')
73
+ proxy_options[:ssh_user].must_equal 'my user'
74
+ end
75
+ end
76
+
77
+ describe 'sudo' do
78
+ it 'uses the remote_execution_ssh_user on the host param' do
79
+ host.params['remote_execution_effective_user_method'] = 'sudo'
80
+ method_param = FactoryGirl.build(:host_parameter, :name => 'remote_execution_effective_user_method', :value => 'sudo')
81
+ host.host_parameters << method_param
82
+ proxy_options[:effective_user_method].must_equal 'sudo'
83
+ method_param.update_attributes!(:value => 'su')
84
+ host.clear_host_parameters_cache!
85
+ proxy_options = SSHExecutionProvider.proxy_command_options(template_invocation, host)
86
+ proxy_options[:effective_user_method].must_equal 'su'
87
+ end
88
+ end
89
+ end
51
90
  end
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: 0.1.1
4
+ version: 0.1.2
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: 2015-11-12 00:00:00.000000000 Z
11
+ date: 2015-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deface
@@ -38,20 +38,34 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 3.2.8
41
+ - !ruby/object:Gem::Dependency
42
+ name: dynflow
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.8.8
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.8.8
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: foreman-tasks
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: 0.7.6
61
+ version: 0.7.8
48
62
  type: :runtime
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: 0.7.6
68
+ version: 0.7.8
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rubocop
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -142,6 +156,7 @@ files:
142
156
  - app/assets/stylesheets/template_invocation.css.scss
143
157
  - app/controllers/api/v2/job_invocations_controller.rb
144
158
  - app/controllers/api/v2/job_templates_controller.rb
159
+ - app/controllers/api/v2/template_inputs_controller.rb
145
160
  - app/controllers/job_invocations_controller.rb
146
161
  - app/controllers/job_templates_controller.rb
147
162
  - app/controllers/template_invocations_controller.rb
@@ -157,6 +172,7 @@ files:
157
172
  - app/models/concerns/foreman_remote_execution/bookmark_extensions.rb
158
173
  - app/models/concerns/foreman_remote_execution/errors_flattener.rb
159
174
  - app/models/concerns/foreman_remote_execution/foreman_tasks_task_extensions.rb
175
+ - app/models/concerns/foreman_remote_execution/foreman_tasks_triggering_extensions.rb
160
176
  - app/models/concerns/foreman_remote_execution/host_extensions.rb
161
177
  - app/models/concerns/foreman_remote_execution/nic_extensions.rb
162
178
  - app/models/concerns/foreman_remote_execution/smart_proxy_extensions.rb
@@ -168,9 +184,10 @@ files:
168
184
  - app/models/host_status/execution_status.rb
169
185
  - app/models/input_template_renderer.rb
170
186
  - app/models/job_invocation.rb
171
- - app/models/job_invocation_api_composer.rb
172
187
  - app/models/job_invocation_composer.rb
188
+ - app/models/job_invocation_task_group.rb
173
189
  - app/models/job_template.rb
190
+ - app/models/job_template_effective_user.rb
174
191
  - app/models/remote_execution_provider.rb
175
192
  - app/models/setting/remote_execution.rb
176
193
  - app/models/ssh_execution_provider.rb
@@ -196,7 +213,15 @@ files:
196
213
  - app/views/api/v2/job_templates/index.json.rabl
197
214
  - app/views/api/v2/job_templates/main.json.rabl
198
215
  - app/views/api/v2/job_templates/show.json.rabl
216
+ - app/views/api/v2/job_templates/update.json.rabl
217
+ - app/views/api/v2/template_inputs/base.json.rabl
218
+ - app/views/api/v2/template_inputs/create.json.rabl
219
+ - app/views/api/v2/template_inputs/index.json.rabl
220
+ - app/views/api/v2/template_inputs/main.json.rabl
221
+ - app/views/api/v2/template_inputs/show.json.rabl
199
222
  - app/views/dashboard/.gitkeep
223
+ - app/views/job_invocation_task_groups/_job_invocation_task_group.html.erb
224
+ - app/views/job_invocation_task_groups/_job_invocation_task_groups.html.erb
200
225
  - app/views/job_invocations/_form.html.erb
201
226
  - app/views/job_invocations/_host_actions_td.html.erb
202
227
  - app/views/job_invocations/_host_provider_td.html.erb
@@ -238,7 +263,15 @@ files:
238
263
  - db/migrate/20150827144500_change_targeting_search_query_type.rb
239
264
  - db/migrate/20150827152730_add_options_to_template_input.rb
240
265
  - db/migrate/20150903192731_add_execution_to_interface.rb
266
+ - db/migrate/20150923125825_add_job_invocation_task_group.rb
241
267
  - db/migrate/20151013135415_add_pub_key_to_smart_proxy.rb
268
+ - db/migrate/20151022105508_rename_last_task_id_column.rb
269
+ - db/migrate/20151116105412_add_triggering_to_job_invocation.rb
270
+ - db/migrate/20151120171100_add_effective_user_to_template_invocation.rb
271
+ - db/migrate/20151124162300_create_job_template_effective_users.rb
272
+ - db/migrate/20151203100824_add_description_to_job_invocation.rb
273
+ - db/migrate/20151215114631_add_host_id_to_template_invocation.rb
274
+ - db/migrate/20151217092555_migrate_to_task_groups.rb
242
275
  - db/seeds.d/60-ssh_proxy_feature.rb
243
276
  - db/seeds.d/70-job_templates.rb
244
277
  - db/seeds.d/80-provision_templates.rb
@@ -291,15 +324,16 @@ files:
291
324
  - test/factories/foreman_remote_execution_factories.rb
292
325
  - test/functional/api/v2/job_invocations_controller_test.rb
293
326
  - test/functional/api/v2/job_templates_controller_test.rb
327
+ - test/functional/api/v2/template_inputs_controller_test.rb
294
328
  - test/test_plugin_helper.rb
295
329
  - test/unit/actions/run_hosts_job_test.rb
296
330
  - test/unit/actions/run_proxy_command_test.rb
297
331
  - test/unit/concerns/host_extensions_test.rb
298
332
  - test/unit/concerns/nic_extensions_test.rb
299
333
  - test/unit/input_template_renderer_test.rb
300
- - test/unit/job_invocation_api_composer_test.rb
301
334
  - test/unit/job_invocation_composer_test.rb
302
335
  - test/unit/job_invocation_test.rb
336
+ - test/unit/job_template_effective_user_test.rb
303
337
  - test/unit/job_template_test.rb
304
338
  - test/unit/proxy_load_balancer_test.rb
305
339
  - test/unit/remote_execution_provider_test.rb
@@ -334,15 +368,16 @@ test_files:
334
368
  - test/factories/foreman_remote_execution_factories.rb
335
369
  - test/functional/api/v2/job_invocations_controller_test.rb
336
370
  - test/functional/api/v2/job_templates_controller_test.rb
371
+ - test/functional/api/v2/template_inputs_controller_test.rb
337
372
  - test/test_plugin_helper.rb
338
373
  - test/unit/actions/run_hosts_job_test.rb
339
374
  - test/unit/actions/run_proxy_command_test.rb
340
375
  - test/unit/concerns/host_extensions_test.rb
341
376
  - test/unit/concerns/nic_extensions_test.rb
342
377
  - test/unit/input_template_renderer_test.rb
343
- - test/unit/job_invocation_api_composer_test.rb
344
378
  - test/unit/job_invocation_composer_test.rb
345
379
  - test/unit/job_invocation_test.rb
380
+ - test/unit/job_template_effective_user_test.rb
346
381
  - test/unit/job_template_test.rb
347
382
  - test/unit/proxy_load_balancer_test.rb
348
383
  - test/unit/remote_execution_provider_test.rb