foreman_remote_execution 0.1.1 → 0.1.2

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.
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
@@ -1,69 +0,0 @@
1
- class JobInvocationApiComposer
2
- attr_accessor :params, :job_invocation, :host_ids, :search_query
3
-
4
- delegate :job_name, :to => :job_invocation
5
- delegate :targeting, :to => :job_invocation
6
- delegate :template_invocations, :to => :job_invocation
7
-
8
- def initialize(job_invocation, user, params)
9
- @job_invocation = job_invocation
10
- @params = params
11
-
12
- self.job_invocation.job_name = params[:job_name] if params[:job_name]
13
- self.job_invocation.targeting = build_targeting(user)
14
- self.job_invocation.template_invocations = [build_template_invocation]
15
- end
16
-
17
- def build_targeting(user)
18
- raise ::Foreman::Exception, _('Cannot specify both bookmark_id and search_query') if params[:bookmark_id] && params[:search_query]
19
- targeting ||= job_invocation.targeting || job_invocation.build_targeting
20
- targeting.targeting_type = params[:targeting_type] if params[:targeting_type]
21
- targeting.bookmark = available_bookmarks.find(params[:bookmark_id]) if params[:bookmark_id]
22
- targeting.search_query = params[:search_query]
23
- targeting.user = user
24
- targeting
25
- end
26
-
27
- def build_template_invocation
28
- invocation = TemplateInvocation.new
29
- invocation.template = find_job_template
30
- build_input_values(invocation) if invocation.template
31
- invocation
32
- end
33
-
34
- def find_job_template
35
- templates = JobTemplate.authorized(:view_job_templates).where(:job_name => job_name)
36
- template = templates.find(params[:template_id]) if params[:template_id]
37
- template = templates.first if templates.count == 1
38
- template
39
- end
40
-
41
- def build_input_values(invocation)
42
- input_values = params.fetch(:inputs, []).map do |input_hash|
43
- if (input = template_input(invocation.template, input_hash[:name]))
44
- invocation.input_values.build(:template_input => input, :value => input_hash[:value])
45
- end
46
- end
47
- input_values.compact
48
- end
49
-
50
- def template_input(template, name)
51
- template.template_inputs.find_by_name(name)
52
- end
53
-
54
- def valid?
55
- targeting.valid? & job_invocation.valid? & template_invocations.all?(&:valid?)
56
- end
57
-
58
- def save!
59
- if valid?
60
- job_invocation.save!
61
- else
62
- raise job_invocation.flattened_validation_exception
63
- end
64
- end
65
-
66
- def available_bookmarks
67
- Bookmark.authorized(:view_bookmarks).my_bookmarks
68
- end
69
- end
@@ -1,143 +0,0 @@
1
- require 'test_plugin_helper'
2
-
3
- describe JobInvocationApiComposer do
4
- before do
5
- permission1 = FactoryGirl.create(:permission, :name => 'view_job_templates', :resource_type => 'JobTemplate')
6
- permission2 = Permission.find_by_name('view_bookmarks')
7
- permission3 = Permission.find_by_name('view_hosts')
8
- filter1 = FactoryGirl.build(:filter, :permissions => [permission1], :search => 'name ~ testing*')
9
- filter2 = FactoryGirl.build(:filter, :permissions => [permission2])
10
- filter3 = FactoryGirl.build(:filter, :permissions => [permission3])
11
- filter1.save
12
- filter2.save
13
- filter3.save
14
- role = FactoryGirl.build(:role)
15
- role.filters = filter1, filter2, filter3
16
- role.save
17
- User.current = FactoryGirl.build(:user)
18
- User.current.roles<< role
19
- User.current.save
20
- end
21
-
22
- let(:testing_job_template_1) { FactoryGirl.create(:job_template, :job_name => 'testing_job_template_1', :name => 'testing1', :provider_type => 'Ssh') }
23
-
24
- let(:input1) { FactoryGirl.create(:template_input, :template => testing_job_template_1, :input_type => 'user', :required => true) }
25
- let(:input2) { FactoryGirl.create(:template_input, :template => testing_job_template_1, :input_type => 'user') }
26
-
27
- let(:bookmark) { bookmarks(:one) }
28
- let(:providers_params) { { :providers => { :ansible => ansible_params, :ssh => ssh_params, :mcollective => mcollective_params } } }
29
-
30
- context 'composer' do
31
- it "creates invocation with a bookmark" do
32
- params = {:job_name => testing_job_template_1.job_name,
33
- :template_id => testing_job_template_1.id,
34
- :targeting_type => "static_query",
35
- :bookmark_id => bookmark.id}
36
- ji = JobInvocation.new
37
-
38
- composer = JobInvocationApiComposer.new(ji, User.current, params)
39
- assert composer.save!
40
- assert_equal bookmark, ji.targeting.bookmark
41
- assert_equal ji.targeting.user, User.current
42
- refute_empty ji.template_invocations
43
- end
44
-
45
- it "creates invocation with a search query" do
46
- params = {:job_name => testing_job_template_1.job_name,
47
- :template_id => testing_job_template_1.id,
48
- :targeting_type => "static_query",
49
- :search_query => "some hosts"}
50
- ji = JobInvocation.new
51
-
52
- composer = JobInvocationApiComposer.new(ji, User.current, params)
53
- assert composer.save!
54
- assert_equal "some hosts", ji.targeting.search_query
55
- refute_empty ji.template_invocations
56
- end
57
-
58
- it "creates invocation with inputs" do
59
- params = {:job_name => testing_job_template_1.job_name,
60
- :template_id => testing_job_template_1.id,
61
- :targeting_type => "static_query",
62
- :search_query => "some hosts",
63
- :inputs => [{:name => input1.name, :value => "some_value"}]}
64
- ji = JobInvocation.new
65
-
66
- composer = JobInvocationApiComposer.new(ji, User.current, params)
67
- assert composer.save!
68
- assert_equal 1, ji.template_invocations.first.input_values.count
69
- end
70
-
71
- it "handles errors on invalid targeting" do
72
- params = {:job_name => testing_job_template_1.job_name,
73
- :template_id => testing_job_template_1.id,
74
- :search_query => "some hosts",
75
- :inputs => [{:name => input1.name, :value => "some_value"}]}
76
- ji = JobInvocation.new
77
-
78
- composer = JobInvocationApiComposer.new(ji, User.current, params)
79
- assert_raises(ActiveRecord::RecordNotSaved) do
80
- composer.save!
81
- end
82
- end
83
-
84
- it "handles errors with both bookmark and search_query" do
85
- params = {:job_name => testing_job_template_1.job_name,
86
- :template_id => testing_job_template_1.id,
87
- :targeting_type => "static_query",
88
- :search_query => "some hosts",
89
- :bookmark_id => bookmark.id,
90
- :inputs => [{:name => input1.name, :value => "some_value"}]}
91
- ji = JobInvocation.new
92
-
93
- assert_raises(Foreman::Exception) do
94
- JobInvocationApiComposer.new(ji, User.current, params)
95
- end
96
- end
97
-
98
- it "handles errors on invalid inputs" do
99
- params = {:job_name => testing_job_template_1.job_name,
100
- :template_id => testing_job_template_1.id,
101
- :targeting_type => "static_query",
102
- :search_query => "some hosts",
103
- :inputs => [{:name => input1.name, :value => "some_value"}, {:name => input2.name}]}
104
- ji = JobInvocation.new
105
- composer = JobInvocationApiComposer.new(ji, User.current, params)
106
-
107
- error = assert_raises(ActiveRecord::RecordNotSaved) do
108
- composer.save!
109
- end
110
- error.message.must_include "Template #{testing_job_template_1.name}: Input #{input2.name.downcase}: Value can't be blank"
111
- end
112
-
113
- it "accepts empty values for non-required inputs" do
114
- params = {:job_name => testing_job_template_1.job_name,
115
- :template_id => testing_job_template_1.id,
116
- :targeting_type => "static_query",
117
- :search_query => "some hosts",
118
- :inputs => [{:name => input1.name, :value => "some_value"}, {:name => input2.name, :value => ""}]}
119
- ji = JobInvocation.new
120
- composer = JobInvocationApiComposer.new(ji, User.current, params)
121
-
122
- composer.save!
123
- assert !ji.new_record?
124
- end
125
-
126
- it "handles errors on missing required inputs" do
127
- input1.must_be :required
128
- params = {:job_name => testing_job_template_1.job_name,
129
- :template_id => testing_job_template_1.id,
130
- :targeting_type => "static_query",
131
- :search_query => "some hosts",
132
- :inputs => [{:name => input2.name, :value => "some_value"}]}
133
- ji = JobInvocation.new
134
- composer = JobInvocationApiComposer.new(ji, User.current, params)
135
-
136
- error = assert_raises(ActiveRecord::RecordNotSaved) do
137
- composer.save!
138
- end
139
-
140
- error.message.must_include "Template #{testing_job_template_1.name}: Not all required inputs have values. Missing inputs: #{input1.name}"
141
- end
142
- end
143
- end