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
@@ -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