foreman_remote_execution 0.3.0 → 0.3.1

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -5
  3. data/.rubocop_todo.yml +90 -92
  4. data/app/assets/javascripts/job_templates.js +10 -0
  5. data/app/assets/stylesheets/modal_window.css.scss +4 -0
  6. data/app/controllers/api/v2/job_templates_controller.rb +22 -1
  7. data/app/controllers/job_templates_controller.rb +21 -1
  8. data/app/helpers/concerns/foreman_remote_execution/job_templates_extensions.rb +3 -2
  9. data/app/helpers/remote_execution_helper.rb +5 -3
  10. data/app/lib/actions/middleware/bind_job_invocation.rb +1 -1
  11. data/app/lib/actions/remote_execution/run_host_job.rb +15 -8
  12. data/app/lib/actions/remote_execution/run_hosts_job.rb +2 -1
  13. data/app/models/concerns/foreman_remote_execution/exportable.rb +71 -0
  14. data/app/models/foreign_input_set.rb +3 -0
  15. data/app/models/job_invocation.rb +6 -4
  16. data/app/models/job_invocation_composer.rb +1 -1
  17. data/app/models/job_template.rb +22 -6
  18. data/app/models/template_input.rb +4 -0
  19. data/app/models/template_invocation.rb +1 -1
  20. data/app/services/proxy_load_balancer.rb +3 -0
  21. data/app/views/job_invocations/_preview_hosts_modal.html.erb +3 -1
  22. data/app/views/job_templates/_import_job_template_modal.html.erb +20 -0
  23. data/app/views/job_templates/index.html.erb +5 -1
  24. data/config/routes.rb +4 -0
  25. data/lib/foreman_remote_execution/engine.rb +4 -4
  26. data/lib/foreman_remote_execution/version.rb +1 -1
  27. data/locale/Makefile +18 -19
  28. data/locale/action_names.rb +2 -2
  29. data/locale/de/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  30. data/locale/de/foreman_remote_execution.po +823 -0
  31. data/locale/en/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  32. data/locale/en/foreman_remote_execution.po +332 -283
  33. data/locale/en_GB/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  34. data/locale/en_GB/foreman_remote_execution.po +824 -0
  35. data/locale/foreman_remote_execution.pot +277 -131
  36. data/locale/fr/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  37. data/locale/fr/foreman_remote_execution.po +823 -0
  38. data/test/functional/api/v2/job_templates_controller_test.rb +15 -0
  39. data/test/unit/actions/run_host_job_test.rb +50 -0
  40. data/test/unit/concerns/exportable_test.rb +88 -0
  41. data/test/unit/job_invocation_composer_test.rb +1 -1
  42. data/test/unit/job_invocation_test.rb +3 -6
  43. data/test/unit/job_template_test.rb +34 -2
  44. data/test/unit/proxy_load_balancer_test.rb +8 -6
  45. data/test/unit/template_input_test.rb +15 -0
  46. metadata +17 -2
@@ -69,6 +69,21 @@ module Api
69
69
  :job_template => {:name => ''}
70
70
  assert_response :unprocessable_entity
71
71
  end
72
+
73
+ test 'should export template' do
74
+ get :export, :id => @template.to_param
75
+ assert_equal @response.body, @template.to_erb
76
+ assert_response :success
77
+ end
78
+
79
+ test 'should import template' do
80
+ new_name = @template.name = "#{@template.name}_renamed"
81
+ erb_data = @template.to_erb
82
+ post :import, :template => erb_data
83
+ assert_response :success
84
+ assert JobTemplate.find_by_name(new_name)
85
+ end
72
86
  end
87
+
73
88
  end
74
89
  end
@@ -0,0 +1,50 @@
1
+ require 'test_plugin_helper'
2
+
3
+ module ForemanRemoteExecution
4
+ class RunHostJobTest < ActiveSupport::TestCase
5
+ include Dynflow::Testing
6
+
7
+ let(:action) do
8
+ create_action(Actions::RemoteExecution::RunHostJob)
9
+ end
10
+
11
+ describe '#find_ip_or_hostname' do
12
+ let(:host) { FactoryGirl.create(:host) }
13
+ let(:flags) do
14
+ { :primary => false, :provision => false, :execution => false }
15
+ end
16
+
17
+ it 'finds hostname' do
18
+ host.expects(:fqdn).returns('somehost.somedomain.org')
19
+ action.send(:find_ip_or_hostname, host).must_equal 'somehost.somedomain.org'
20
+ end
21
+
22
+ it 'gets ip from unflagged interfaces' do
23
+ ip = '127.0.0.1'
24
+ host.interfaces = [FactoryGirl.build(:nic_managed, flags.merge(:ip => nil)),
25
+ FactoryGirl.build(:nic_managed, flags.merge(:ip => ip))]
26
+ action.send(:find_ip_or_hostname, host).must_equal ip
27
+ end
28
+
29
+ it 'gets ip from flagged interfaces' do
30
+ unflagged_interface = FactoryGirl.build(:nic_managed, flags)
31
+ host.interfaces = [unflagged_interface]
32
+ action.send(:find_ip_or_hostname, host).must_equal unflagged_interface.ip
33
+
34
+ provision_interface = FactoryGirl.build(:nic_managed, flags.merge(:provision => true))
35
+ host.interfaces << provision_interface
36
+ action.send(:find_ip_or_hostname, host).must_equal provision_interface.ip
37
+
38
+ primary_interface = FactoryGirl.build(:nic_managed, flags.merge(:primary => true))
39
+ host.interfaces << primary_interface
40
+ # Workaround, execution flag got enabled when adding the interface to the host
41
+ host.interfaces.last.execution = false
42
+ action.send(:find_ip_or_hostname, host).must_equal primary_interface.ip
43
+
44
+ execution_interface = FactoryGirl.build(:nic_managed, flags.merge(:execution => true))
45
+ host.interfaces << execution_interface
46
+ action.send(:find_ip_or_hostname, host).must_equal execution_interface.ip
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,88 @@
1
+ require 'test_plugin_helper'
2
+
3
+ module ForemanRemoteExecution
4
+ class ExportableTest < ActiveSupport::TestCase
5
+ class SampleModel
6
+ include ::ForemanRemoteExecution::Exportable
7
+
8
+ attr_accessor :name, :attrs, :subnet, :mac, :password, :subnet
9
+ attr_exportable :name, :attrs, :mac, :subnet, :mac => ->(m) { m.mac.upcase if m.mac },
10
+ :custom_attr => ->(m) { 'hello world' }
11
+
12
+ def attributes
13
+ {
14
+ 'name' => name,
15
+ 'attrs' => attrs,
16
+ 'mac' => mac,
17
+ 'password' => password,
18
+ 'subnet' => subnet
19
+ }
20
+ end
21
+ end
22
+
23
+ class SampleSubnet
24
+ include ::ForemanRemoteExecution::Exportable
25
+
26
+ attr_accessor :name, :network
27
+ attr_exportable :name, :network
28
+
29
+ def attributes
30
+ {
31
+ 'name' => name,
32
+ 'network' => network
33
+ }
34
+ end
35
+ end
36
+
37
+ def setup
38
+ @subnet = SampleSubnet.new
39
+ @subnet.name = 'pxe'
40
+ @subnet.network = '192.168.122.0'
41
+
42
+ @sample = SampleModel.new
43
+ @sample.name = 'name'
44
+ @sample.attrs = {'nested' => 'hash'}
45
+ @sample.subnet = @subnet
46
+ @sample.mac = 'aa:bb:cc:dd:ee:ff'
47
+ @sample.password = 'password'
48
+ end
49
+
50
+ test '#to_export includes all specified attributes' do
51
+ assert_equal %w(name attrs mac subnet custom_attr), @sample.to_export.keys
52
+ end
53
+
54
+ test '#to_export does not include all attributes' do
55
+ assert_not_include @sample.to_export.keys, 'password'
56
+ end
57
+
58
+ test '#to_export calls the lambda' do
59
+ export = @sample.to_export
60
+ assert_equal('AA:BB:CC:DD:EE:FF', export['mac'])
61
+ assert_equal(export['custom_attr'], 'hello world')
62
+ end
63
+
64
+ test '#to_export values are exported recursively' do
65
+ export = @sample.to_export
66
+ assert_equal('pxe', export['subnet']['name'])
67
+ assert_equal('192.168.122.0', export['subnet']['network'])
68
+ end
69
+
70
+ test '#to_export nested hashes are primitive' do
71
+ @sample.attrs = {:foo => 'bar', :baz => 'qux'}.with_indifferent_access
72
+ export = @sample.to_export
73
+ assert_instance_of Hash, export['attrs']
74
+ end
75
+
76
+ test '#to_export includes blank values' do
77
+ @sample.attrs = {}
78
+ export = @sample.to_export
79
+ assert_instance_of Hash, export['attrs']
80
+ end
81
+
82
+ test '#to_export(false) does not include blank values' do
83
+ @sample.attrs = {}
84
+ export = @sample.to_export(false)
85
+ assert_nil export['attrs']
86
+ end
87
+ end
88
+ end
@@ -433,7 +433,7 @@ describe JobInvocationComposer do
433
433
 
434
434
  describe 'with concurrency control set' do
435
435
  let(:params) do
436
- { :job_invocation => { :providers => { :ssh => ssh_params }, :concurrency_level => "5", :time_span => "60" } }.with_indifferent_access
436
+ { :job_invocation => { :providers => { :ssh => ssh_params }, :concurrency_level => '5', :time_span => '60' } }.with_indifferent_access
437
437
  end
438
438
 
439
439
  it 'accepts the concurrency options' do
@@ -63,16 +63,14 @@ describe JobInvocation do
63
63
 
64
64
  describe 'descriptions' do
65
65
  it 'generates description from input values' do
66
- job_invocation.expects(:save!)
67
66
  job_invocation.description_format = '%{job_category} - %{foo}'
68
- job_invocation.generate_description!
67
+ job_invocation.generate_description
69
68
  job_invocation.description.must_equal "#{job_invocation.job_category} - #{@input_value.value}"
70
69
  end
71
70
 
72
71
  it 'handles missing keys correctly' do
73
- job_invocation.expects(:save!)
74
72
  job_invocation.description_format = '%{job_category} - %{missing_key}'
75
- job_invocation.generate_description!
73
+ job_invocation.generate_description
76
74
  job_invocation.description.must_equal "#{job_invocation.job_category} - %{missing_key}"
77
75
  end
78
76
 
@@ -80,10 +78,9 @@ describe JobInvocation do
80
78
  column_limit = 255
81
79
  expected_result = 'a' * column_limit
82
80
  JobInvocation.columns_hash['description'].expects(:limit).returns(column_limit)
83
- job_invocation.expects(:save!)
84
81
  job_invocation.description_format = '%{job_category}'
85
82
  job_invocation.job_category = 'a' * 1000
86
- job_invocation.generate_description!
83
+ job_invocation.generate_description
87
84
  job_invocation.description.must_equal expected_result
88
85
  end
89
86
  end
@@ -217,12 +217,44 @@ describe JobTemplate do
217
217
  end
218
218
 
219
219
  it 'syncs content' do
220
- synced_template.template.must_match(/\s+ping -c <%= input\('count'\) %> <%= input\('hostname'\) %>\s+/m)
220
+ synced_template.template.must_match(/ping -c <%= input\('count'\) %> <%= input\('hostname'\) %>/m)
221
221
  end
222
222
 
223
223
  it 'syncs input sets' do
224
224
  synced_template.foreign_input_sets.first.target_template.must_equal included
225
- synced_template.template_inputs_with_foreign.map(&:name).must_equal ["hostname", "count"]
225
+ synced_template.template_inputs_with_foreign.map(&:name).must_equal ['hostname', 'count']
226
+ end
227
+ end
228
+
229
+ context 'template export' do
230
+ let(:exportable_template) do
231
+ FactoryGirl.create(:job_template, :with_input)
232
+ end
233
+
234
+ let(:erb) do
235
+ exportable_template.to_erb
236
+ end
237
+
238
+ it 'exports name' do
239
+ erb.must_match(/^name: #{exportable_template.name}$/)
240
+ end
241
+
242
+ it 'includes template inputs' do
243
+ erb.must_match(/^template_inputs:$/)
244
+ end
245
+
246
+ it 'includes template contents' do
247
+ erb.must_include exportable_template.template
248
+ end
249
+
250
+ it 'is importable' do
251
+ erb
252
+ old_name = exportable_template.name
253
+ exportable_template.update_attributes(:name => "#{old_name}_renamed")
254
+
255
+ imported = JobTemplate.import!(erb)
256
+ imported.name.must_equal old_name
257
+ imported.template_inputs.first.to_export.must_equal exportable_template.template_inputs.first.to_export
226
258
  end
227
259
  end
228
260
 
@@ -8,15 +8,17 @@ describe ProxyLoadBalancer do
8
8
  end
9
9
 
10
10
  it 'load balances' do
11
- proxies = FactoryGirl.create_list(:smart_proxy, 3, :ssh)
12
- not_yet_seen = proxies.dup
11
+ count = 3
12
+ ProxyAPI::ForemanDynflow::DynflowProxy.any_instance.expects(:tasks_count).raises.then.times(count - 1).returns(0)
13
+ proxies = FactoryGirl.create_list(:smart_proxy, count, :ssh)
13
14
 
14
- 3.times do
15
- found = load_balancer.next(proxies)
16
- not_yet_seen.delete(found)
15
+ available = proxies.reduce([]) do |found, _|
16
+ found << load_balancer.next(proxies)
17
17
  end
18
18
 
19
- not_yet_seen.must_be_empty
19
+ available.count.must_equal count
20
+ available.uniq.count.must_equal count - 1
21
+ load_balancer.offline.count.must_equal 1
20
22
  end
21
23
 
22
24
  it 'returns nil for if no proxy is available' do
@@ -3,6 +3,21 @@ require 'test_plugin_helper'
3
3
  describe TemplateInput do
4
4
  let(:template_input) { FactoryGirl.build(:template_input) }
5
5
 
6
+ context 'export' do
7
+ before do
8
+ template_input.input_type = 'user'
9
+ template_input.options = "foo\nbar\nbaz"
10
+ end
11
+
12
+ it 'exports type' do
13
+ template_input.to_export['input_type'].must_equal template_input.input_type
14
+ end
15
+
16
+ it 'exports options' do
17
+ template_input.to_export['options'].must_equal template_input.options
18
+ end
19
+ end
20
+
6
21
  context 'user input' do
7
22
  before { template_input.input_type = 'user' }
8
23
  it { assert template_input.user_template_input? }
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.3.0
4
+ version: 0.3.1
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: 2016-02-17 00:00:00.000000000 Z
11
+ date: 2016-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deface
@@ -136,9 +136,11 @@ files:
136
136
  - README.md
137
137
  - Rakefile
138
138
  - app/assets/javascripts/execution_interface.js
139
+ - app/assets/javascripts/job_templates.js
139
140
  - app/assets/javascripts/template_input.js
140
141
  - app/assets/javascripts/template_invocation.js
141
142
  - app/assets/stylesheets/job_invocations.css.scss
143
+ - app/assets/stylesheets/modal_window.css.scss
142
144
  - app/assets/stylesheets/template_invocation.css.scss
143
145
  - app/controllers/api/v2/foreign_input_sets_controller.rb
144
146
  - app/controllers/api/v2/job_invocations_controller.rb
@@ -161,6 +163,7 @@ files:
161
163
  - app/mailers/.gitkeep
162
164
  - app/models/concerns/foreman_remote_execution/bookmark_extensions.rb
163
165
  - app/models/concerns/foreman_remote_execution/errors_flattener.rb
166
+ - app/models/concerns/foreman_remote_execution/exportable.rb
164
167
  - app/models/concerns/foreman_remote_execution/foreman_tasks_task_extensions.rb
165
168
  - app/models/concerns/foreman_remote_execution/foreman_tasks_triggering_extensions.rb
166
169
  - app/models/concerns/foreman_remote_execution/host_extensions.rb
@@ -234,6 +237,7 @@ files:
234
237
  - app/views/job_invocations/show.js.erb
235
238
  - app/views/job_templates/_custom_tab_headers.html.erb
236
239
  - app/views/job_templates/_custom_tabs.html.erb
240
+ - app/views/job_templates/_import_job_template_modal.html.erb
237
241
  - app/views/job_templates/edit.html.erb
238
242
  - app/views/job_templates/index.html.erb
239
243
  - app/views/job_templates/new.html.erb
@@ -335,8 +339,15 @@ files:
335
339
  - lib/tasks/foreman_remote_execution_tasks.rake
336
340
  - locale/Makefile
337
341
  - locale/action_names.rb
342
+ - locale/de/LC_MESSAGES/foreman_remote_execution.mo
343
+ - locale/de/foreman_remote_execution.po
344
+ - locale/en/LC_MESSAGES/foreman_remote_execution.mo
338
345
  - locale/en/foreman_remote_execution.po
346
+ - locale/en_GB/LC_MESSAGES/foreman_remote_execution.mo
347
+ - locale/en_GB/foreman_remote_execution.po
339
348
  - locale/foreman_remote_execution.pot
349
+ - locale/fr/LC_MESSAGES/foreman_remote_execution.mo
350
+ - locale/fr/foreman_remote_execution.po
340
351
  - locale/gemspec.rb
341
352
  - test/factories/foreman_remote_execution_factories.rb
342
353
  - test/functional/api/v2/foreign_input_sets_controller_test.rb
@@ -345,8 +356,10 @@ files:
345
356
  - test/functional/api/v2/remote_execution_features_controller_test.rb
346
357
  - test/functional/api/v2/template_inputs_controller_test.rb
347
358
  - test/test_plugin_helper.rb
359
+ - test/unit/actions/run_host_job_test.rb
348
360
  - test/unit/actions/run_hosts_job_test.rb
349
361
  - test/unit/actions/run_proxy_command_test.rb
362
+ - test/unit/concerns/exportable_test.rb
350
363
  - test/unit/concerns/host_extensions_test.rb
351
364
  - test/unit/concerns/nic_extensions_test.rb
352
365
  - test/unit/execution_task_status_mapper_test.rb
@@ -393,8 +406,10 @@ test_files:
393
406
  - test/functional/api/v2/remote_execution_features_controller_test.rb
394
407
  - test/functional/api/v2/template_inputs_controller_test.rb
395
408
  - test/test_plugin_helper.rb
409
+ - test/unit/actions/run_host_job_test.rb
396
410
  - test/unit/actions/run_hosts_job_test.rb
397
411
  - test/unit/actions/run_proxy_command_test.rb
412
+ - test/unit/concerns/exportable_test.rb
398
413
  - test/unit/concerns/host_extensions_test.rb
399
414
  - test/unit/concerns/nic_extensions_test.rb
400
415
  - test/unit/execution_task_status_mapper_test.rb