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.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -5
- data/.rubocop_todo.yml +90 -92
- data/app/assets/javascripts/job_templates.js +10 -0
- data/app/assets/stylesheets/modal_window.css.scss +4 -0
- data/app/controllers/api/v2/job_templates_controller.rb +22 -1
- data/app/controllers/job_templates_controller.rb +21 -1
- data/app/helpers/concerns/foreman_remote_execution/job_templates_extensions.rb +3 -2
- data/app/helpers/remote_execution_helper.rb +5 -3
- data/app/lib/actions/middleware/bind_job_invocation.rb +1 -1
- data/app/lib/actions/remote_execution/run_host_job.rb +15 -8
- data/app/lib/actions/remote_execution/run_hosts_job.rb +2 -1
- data/app/models/concerns/foreman_remote_execution/exportable.rb +71 -0
- data/app/models/foreign_input_set.rb +3 -0
- data/app/models/job_invocation.rb +6 -4
- data/app/models/job_invocation_composer.rb +1 -1
- data/app/models/job_template.rb +22 -6
- data/app/models/template_input.rb +4 -0
- data/app/models/template_invocation.rb +1 -1
- data/app/services/proxy_load_balancer.rb +3 -0
- data/app/views/job_invocations/_preview_hosts_modal.html.erb +3 -1
- data/app/views/job_templates/_import_job_template_modal.html.erb +20 -0
- data/app/views/job_templates/index.html.erb +5 -1
- data/config/routes.rb +4 -0
- data/lib/foreman_remote_execution/engine.rb +4 -4
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/locale/Makefile +18 -19
- data/locale/action_names.rb +2 -2
- data/locale/de/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/de/foreman_remote_execution.po +823 -0
- data/locale/en/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/en/foreman_remote_execution.po +332 -283
- data/locale/en_GB/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/en_GB/foreman_remote_execution.po +824 -0
- data/locale/foreman_remote_execution.pot +277 -131
- data/locale/fr/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/fr/foreman_remote_execution.po +823 -0
- data/test/functional/api/v2/job_templates_controller_test.rb +15 -0
- data/test/unit/actions/run_host_job_test.rb +50 -0
- data/test/unit/concerns/exportable_test.rb +88 -0
- data/test/unit/job_invocation_composer_test.rb +1 -1
- data/test/unit/job_invocation_test.rb +3 -6
- data/test/unit/job_template_test.rb +34 -2
- data/test/unit/proxy_load_balancer_test.rb +8 -6
- data/test/unit/template_input_test.rb +15 -0
- 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 =>
|
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(
|
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 [
|
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
|
-
|
12
|
-
|
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
|
-
|
15
|
-
found
|
16
|
-
not_yet_seen.delete(found)
|
15
|
+
available = proxies.reduce([]) do |found, _|
|
16
|
+
found << load_balancer.next(proxies)
|
17
17
|
end
|
18
18
|
|
19
|
-
|
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.
|
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-
|
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
|