foreman_remote_execution 0.1.2 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/.rubocop_todo.yml +0 -6
- data/app/assets/javascripts/template_input.js +5 -0
- data/app/assets/javascripts/template_invocation.js +44 -12
- data/app/controllers/api/v2/foreign_input_sets_controller.rb +80 -0
- data/app/controllers/api/v2/job_invocations_controller.rb +28 -14
- data/app/controllers/api/v2/job_templates_controller.rb +24 -20
- data/app/controllers/api/v2/template_inputs_controller.rb +10 -7
- data/app/controllers/job_invocations_controller.rb +18 -6
- data/app/controllers/job_templates_controller.rb +14 -4
- data/app/controllers/template_invocations_controller.rb +5 -3
- data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +1 -1
- data/app/helpers/concerns/foreman_remote_execution/job_templates_extensions.rb +19 -0
- data/app/helpers/remote_execution_helper.rb +88 -39
- data/app/lib/actions/remote_execution/run_host_job.rb +11 -8
- data/app/lib/actions/remote_execution/run_hosts_job.rb +5 -2
- data/app/lib/actions/remote_execution/run_proxy_command.rb +9 -4
- data/app/models/concerns/foreman_remote_execution/errors_flattener.rb +2 -2
- data/app/models/concerns/foreman_remote_execution/host_extensions.rb +2 -2
- data/app/models/concerns/foreman_remote_execution/smart_proxy_extensions.rb +1 -1
- data/app/models/concerns/foreman_remote_execution/template_extensions.rb +9 -1
- data/app/models/foreign_input_set.rb +49 -0
- data/app/models/host_status/execution_status.rb +50 -5
- data/app/models/input_template_renderer.rb +52 -7
- data/app/models/job_invocation.rb +89 -32
- data/app/models/job_invocation_composer.rb +71 -55
- data/app/models/job_template.rb +43 -7
- data/app/models/remote_execution_provider.rb +1 -1
- data/app/models/setting/remote_execution.rb +7 -7
- data/app/models/ssh_execution_provider.rb +1 -1
- data/app/models/targeting.rb +1 -1
- data/app/models/template_invocation.rb +9 -4
- data/app/views/api/v2/foreign_input_sets/base.json.rabl +3 -0
- data/app/views/api/v2/foreign_input_sets/create.json.rabl +3 -0
- data/app/views/api/v2/foreign_input_sets/index.json.rabl +3 -0
- data/app/views/api/v2/foreign_input_sets/main.json.rabl +5 -0
- data/app/views/api/v2/foreign_input_sets/show.json.rabl +3 -0
- data/app/views/api/v2/job_invocations/base.json.rabl +10 -1
- data/app/views/api/v2/job_invocations/main.json.rabl +14 -1
- data/app/views/api/v2/job_templates/base.json.rabl +1 -1
- data/app/views/api/v2/job_templates/main.json.rabl +9 -1
- data/app/views/api/v2/job_templates/show.json.rabl +0 -10
- data/app/views/api/v2/template_inputs/main.json.rabl +2 -1
- data/app/views/job_invocation_task_groups/_job_invocation_task_group.html.erb +1 -1
- data/app/views/job_invocations/_description_fields.html.erb +4 -0
- data/app/views/job_invocations/_form.html.erb +73 -91
- data/app/views/job_invocations/_host_actions_td.html.erb +2 -2
- data/app/views/job_invocations/_host_name_td.html.erb +7 -0
- data/app/views/job_invocations/_tab_hosts.html.erb +6 -6
- data/app/views/job_invocations/_tab_overview.html.erb +3 -3
- data/app/views/job_invocations/index.html.erb +6 -4
- data/app/views/job_invocations/refresh.js.erb +1 -0
- data/app/views/job_invocations/show.html.erb +1 -1
- data/app/views/job_invocations/show.js.erb +6 -3
- data/app/views/job_templates/_custom_tabs.html.erb +24 -14
- data/app/views/job_templates/index.html.erb +3 -1
- data/app/views/template_inputs/_foreign_input_set_form.html.erb +12 -0
- data/app/views/template_inputs/_form.html.erb +11 -12
- data/app/views/template_invocations/show.html.erb +2 -2
- data/app/views/templates/package_action.erb +2 -2
- data/app/views/templates/puppet_run_once.erb +3 -3
- data/app/views/templates/run_command.erb +3 -3
- data/app/views/templates/service_action.erb +2 -2
- data/app/views/unattended/snippets/_remote_execution_ssh_keys.erb +1 -1
- data/config/routes.rb +5 -3
- data/db/migrate/20150616080015_create_template_input.rb +1 -1
- data/db/migrate/20150708133241_add_targeting.rb +7 -7
- data/db/migrate/20150708133242_add_invocation.rb +2 -2
- data/db/migrate/20150708133305_add_template_invocation.rb +6 -6
- data/db/migrate/20151215114631_add_host_id_to_template_invocation.rb +3 -3
- data/db/migrate/20151217092555_migrate_to_task_groups.rb +1 -1
- data/db/migrate/20160108134600_create_template_input_sets.rb +16 -0
- data/db/migrate/20160108141144_make_job_name_default_to_something.rb +9 -0
- data/db/migrate/20160111113032_upcase_ssh_feature.rb +19 -0
- data/db/migrate/20160113161916_add_run_host_job_task_id_to_template_invocation.rb +6 -0
- data/db/migrate/20160113162007_expand_all_template_invocations.rb +45 -0
- data/db/migrate/20160114120200_rename_job_categories.rb +20 -0
- data/db/migrate/20160114125628_rename_job_name_to_job_category.rb +19 -0
- data/db/seeds.d/60-ssh_proxy_feature.rb +1 -1
- data/db/seeds.d/80-provision_templates.rb +2 -2
- data/db/seeds.d/90-bookmarks.rb +19 -0
- data/doc/plugins/graphviz.rb +5 -5
- data/doc/plugins/plantuml.rb +6 -6
- data/doc/plugins/tags.rb +4 -4
- data/foreman_remote_execution.gemspec +3 -4
- data/lib/foreman_remote_execution/engine.rb +12 -9
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/test/factories/foreman_remote_execution_factories.rb +11 -9
- data/test/functional/api/v2/foreign_input_sets_controller_test.rb +63 -0
- data/test/functional/api/v2/job_invocations_controller_test.rb +45 -13
- data/test/functional/api/v2/job_templates_controller_test.rb +6 -6
- data/test/functional/api/v2/template_inputs_controller_test.rb +3 -3
- data/test/unit/actions/run_hosts_job_test.rb +3 -4
- data/test/unit/actions/run_proxy_command_test.rb +7 -7
- data/test/unit/concerns/host_extensions_test.rb +1 -1
- data/test/unit/execution_task_status_mapper_test.rb +93 -0
- data/test/unit/input_template_renderer_test.rb +182 -9
- data/test/unit/job_invocation_composer_test.rb +144 -168
- data/test/unit/job_invocation_test.rb +67 -15
- data/test/unit/job_template_effective_user_test.rb +2 -2
- data/test/unit/job_template_test.rb +36 -12
- data/test/unit/remote_execution_provider_test.rb +6 -6
- data/test/unit/targeting_test.rb +2 -2
- metadata +27 -21
- data/app/models/concerns/foreman_remote_execution/template_relations.rb +0 -10
- data/app/views/job_invocations/_host_provider_td.html.erb +0 -3
- data/app/views/job_templates/auto_complete_job_name.json.erb +0 -3
@@ -10,7 +10,7 @@ module Api
|
|
10
10
|
test 'should get index' do
|
11
11
|
get :index
|
12
12
|
templates = ActiveSupport::JSON.decode(@response.body)
|
13
|
-
assert !templates.empty?,
|
13
|
+
assert !templates.empty?, 'Should response with template'
|
14
14
|
assert_response :success
|
15
15
|
end
|
16
16
|
|
@@ -19,15 +19,15 @@ module Api
|
|
19
19
|
assert_response :success
|
20
20
|
template = ActiveSupport::JSON.decode(@response.body)
|
21
21
|
assert !template.empty?
|
22
|
-
assert_equal template[
|
22
|
+
assert_equal template['name'], @template.name
|
23
23
|
end
|
24
24
|
|
25
25
|
test 'should create valid' do
|
26
26
|
JobTemplate.any_instance.stubs(:valid?).returns(true)
|
27
|
-
valid_attrs = { :template =>
|
27
|
+
valid_attrs = { :template => 'This is a test template', :name => 'RandomName', :provider_type => 'ssh' }
|
28
28
|
post :create, :job_template => valid_attrs
|
29
29
|
template = ActiveSupport::JSON.decode(@response.body)
|
30
|
-
assert template[
|
30
|
+
assert template['name'] == 'RandomName'
|
31
31
|
assert_response :success
|
32
32
|
end
|
33
33
|
|
@@ -39,13 +39,13 @@ module Api
|
|
39
39
|
test 'should update valid' do
|
40
40
|
JobTemplate.any_instance.stubs(:valid?).returns(true)
|
41
41
|
put :update, :id => @template.to_param,
|
42
|
-
:job_template => { :template =>
|
42
|
+
:job_template => { :template => 'blah' }
|
43
43
|
assert_response :ok
|
44
44
|
end
|
45
45
|
|
46
46
|
test 'should not update invalid' do
|
47
47
|
put :update, :id => @template.to_param,
|
48
|
-
:job_template => { :name =>
|
48
|
+
:job_template => { :name => '' }
|
49
49
|
assert_response :unprocessable_entity
|
50
50
|
end
|
51
51
|
|
@@ -11,7 +11,7 @@ module Api
|
|
11
11
|
test 'should get index' do
|
12
12
|
get :index, :template_id => @template.id
|
13
13
|
inputs = ActiveSupport::JSON.decode(@response.body)
|
14
|
-
assert !inputs.empty?,
|
14
|
+
assert !inputs.empty?, 'Should respond with inputs'
|
15
15
|
assert_response :success
|
16
16
|
end
|
17
17
|
|
@@ -20,7 +20,7 @@ module Api
|
|
20
20
|
assert_response :success
|
21
21
|
input = ActiveSupport::JSON.decode(@response.body)
|
22
22
|
assert !input.empty?
|
23
|
-
assert_equal input[
|
23
|
+
assert_equal input['name'], @input.name
|
24
24
|
end
|
25
25
|
|
26
26
|
test 'should create valid' do
|
@@ -39,7 +39,7 @@ module Api
|
|
39
39
|
test 'should update valid' do
|
40
40
|
put :update, :template_id => @template.to_param,
|
41
41
|
:id => @input.to_param,
|
42
|
-
:template_input => { :name =>
|
42
|
+
:template_input => { :name => 'blah' }
|
43
43
|
assert_response :ok
|
44
44
|
end
|
45
45
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
|
2
|
-
require
|
2
|
+
require 'test_plugin_helper'
|
3
3
|
|
4
4
|
module ForemanRemoteExecution
|
5
5
|
class RunHostsJobTest < ActiveSupport::TestCase
|
6
6
|
include Dynflow::Testing
|
7
7
|
|
8
8
|
let(:host) { FactoryGirl.create(:host, :with_execution) }
|
9
|
-
let(:proxy) { host.remote_execution_proxies('
|
9
|
+
let(:proxy) { host.remote_execution_proxies('SSH')[:subnet].first }
|
10
10
|
let(:targeting) { FactoryGirl.create(:targeting, :search_query => "name = #{host.name}", :user => User.current) }
|
11
11
|
let(:job_invocation) do
|
12
12
|
FactoryGirl.build(:job_invocation, :with_template).tap do |invocation|
|
@@ -39,8 +39,7 @@ module ForemanRemoteExecution
|
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'triggers the RunHostJob actions on the resolved hosts in run phase' do
|
42
|
-
|
43
|
-
action.expects(:trigger).with(Actions::RemoteExecution::RunHostJob, job_invocation, host, template_invocation, proxy)
|
42
|
+
action.expects(:trigger).with() { |*args| args[0] == Actions::RemoteExecution::RunHostJob }
|
44
43
|
action.create_sub_plans
|
45
44
|
end
|
46
45
|
|
@@ -1,11 +1,11 @@
|
|
1
|
-
require
|
1
|
+
require 'test_plugin_helper'
|
2
2
|
|
3
3
|
module ForemanRemoteExecution
|
4
4
|
class RunProxyCommandTest < ActiveSupport::TestCase
|
5
5
|
include Dynflow::Testing
|
6
6
|
|
7
7
|
let(:host) { FactoryGirl.build(:host, :with_execution) }
|
8
|
-
let(:proxy) { host.remote_execution_proxies('
|
8
|
+
let(:proxy) { host.remote_execution_proxies('SSH')[:subnet].first }
|
9
9
|
let(:hostname) { 'myhost.example.com' }
|
10
10
|
let(:script) { 'ping -c 5 redhat.com' }
|
11
11
|
let(:connection_options) { { 'retry_interval' => 15, 'retry_count' => 4, 'timeout' => 60 } }
|
@@ -50,7 +50,7 @@ module ForemanRemoteExecution
|
|
50
50
|
describe 'when the task is finished' do
|
51
51
|
before do
|
52
52
|
task.state = 'stopped'
|
53
|
-
task.ended_at = timestamp + 1
|
53
|
+
task.ended_at = Time.at(timestamp + 1)
|
54
54
|
end
|
55
55
|
|
56
56
|
describe 'the task finished sucessfully' do
|
@@ -88,10 +88,10 @@ module ForemanRemoteExecution
|
|
88
88
|
|
89
89
|
describe 'when something went wrong while fetching the data' do
|
90
90
|
before do
|
91
|
-
action.proxy.expects(:status_of_task).raises(
|
91
|
+
action.proxy.expects(:status_of_task).raises('Something went wrong')
|
92
92
|
end
|
93
93
|
|
94
|
-
it
|
94
|
+
it 'reports the failure as part of the live output' do
|
95
95
|
live_output.size.must_equal 1
|
96
96
|
live_output.first['output_type'].must_equal 'debug'
|
97
97
|
live_output.first['output'].must_equal 'Error loading data from proxy: RuntimeError - Something went wrong'
|
@@ -105,7 +105,7 @@ module ForemanRemoteExecution
|
|
105
105
|
:metadata => { :failed_proxy_tasks => [action.send(:format_exception, RuntimeError.new('Connection error'))]})
|
106
106
|
end
|
107
107
|
|
108
|
-
it
|
108
|
+
it 'reports the failure as part of the live output' do
|
109
109
|
live_output.size.must_equal 1
|
110
110
|
live_output.first['output_type'].must_equal 'debug'
|
111
111
|
live_output.first['output'].must_equal 'Initialization error: RuntimeError - Connection error'
|
@@ -122,7 +122,7 @@ module ForemanRemoteExecution
|
|
122
122
|
'timestamp' => timestamp }]}}])
|
123
123
|
end
|
124
124
|
|
125
|
-
it
|
125
|
+
it 'reports the failure as part of the live output' do
|
126
126
|
live_output.size.must_equal 1
|
127
127
|
live_output.first['output_type'].must_equal 'stdout'
|
128
128
|
live_output.first['output'].must_equal 'Hello'
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'test_plugin_helper'
|
2
|
+
|
3
|
+
describe HostStatus::ExecutionStatus::ExecutionTaskStatusMapper do
|
4
|
+
|
5
|
+
describe '.sql_conditions_for(status)' do
|
6
|
+
subject { HostStatus::ExecutionStatus::ExecutionTaskStatusMapper }
|
7
|
+
|
8
|
+
it 'accepts status number as well as string representation' do
|
9
|
+
subject.sql_conditions_for(HostStatus::ExecutionStatus::ERROR).must_equal subject.sql_conditions_for('failed')
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'does not find any task for unknown state' do
|
13
|
+
subject.sql_conditions_for(-1).must_equal [ '1 = 0' ]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:task) { ForemanTasks::Task.new }
|
18
|
+
let(:mapper) { HostStatus::ExecutionStatus::ExecutionTaskStatusMapper.new(task) }
|
19
|
+
|
20
|
+
describe '#status' do
|
21
|
+
subject { mapper }
|
22
|
+
|
23
|
+
describe 'is queued' do
|
24
|
+
context 'when there is no task' do
|
25
|
+
before { subject.task = nil }
|
26
|
+
specify { subject.status.must_equal HostStatus::ExecutionStatus::QUEUED }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when the task is scheduled in future' do
|
30
|
+
before { subject.task.state = 'scheduled' }
|
31
|
+
specify { subject.status.must_equal HostStatus::ExecutionStatus::QUEUED }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when task is stopped' do
|
36
|
+
before { subject.task.state = 'stopped' }
|
37
|
+
|
38
|
+
describe 'is succeeded' do
|
39
|
+
context 'without error' do
|
40
|
+
before { subject.task.result = 'success' }
|
41
|
+
specify { subject.status.must_equal HostStatus::ExecutionStatus::OK }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'is failed' do
|
46
|
+
context 'with error' do
|
47
|
+
before { subject.task.result = 'error' }
|
48
|
+
specify { subject.status.must_equal HostStatus::ExecutionStatus::ERROR }
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'without error but just with warning (sub task failed)' do
|
52
|
+
before { subject.task.result = 'warning' }
|
53
|
+
specify { subject.status.must_equal HostStatus::ExecutionStatus::ERROR }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when task is pending' do
|
59
|
+
before { subject.task.state = 'running' }
|
60
|
+
|
61
|
+
describe 'is pending' do
|
62
|
+
specify { subject.status.must_equal HostStatus::ExecutionStatus::RUNNING }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#status_label' do
|
68
|
+
subject { mapper.status_label }
|
69
|
+
|
70
|
+
context 'status is OK' do
|
71
|
+
before do
|
72
|
+
mapper.task.state = 'stopped'
|
73
|
+
mapper.task.result = 'success'
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'returns ok label' do
|
77
|
+
subject.must_equal HostStatus::ExecutionStatus::STATUS_NAMES[HostStatus::ExecutionStatus::OK]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'status is ERROR' do
|
82
|
+
before do
|
83
|
+
mapper.task.state = 'stopped'
|
84
|
+
mapper.task.result = 'error'
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'returns failed label' do
|
88
|
+
subject.must_equal HostStatus::ExecutionStatus::STATUS_NAMES[HostStatus::ExecutionStatus::ERROR]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'test_plugin_helper'
|
2
2
|
|
3
3
|
describe InputTemplateRenderer do
|
4
|
-
context
|
4
|
+
context 'renderer for simple template without inputs' do
|
5
5
|
let(:renderer) { InputTemplateRenderer.new(FactoryGirl.build(:job_template, :template => 'id')) }
|
6
6
|
|
7
7
|
it 'should render the content' do
|
@@ -13,7 +13,7 @@ describe InputTemplateRenderer do
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
context
|
16
|
+
context 'renderer for template with user input used' do
|
17
17
|
let(:template) { FactoryGirl.build(:job_template, :template => 'service restart <%= input("service_name") -%>') }
|
18
18
|
let(:renderer) { InputTemplateRenderer.new(template) }
|
19
19
|
|
@@ -95,6 +95,173 @@ describe InputTemplateRenderer do
|
|
95
95
|
renderer.invocation = template_invocation
|
96
96
|
renderer.render.must_equal 'service restart '
|
97
97
|
end
|
98
|
+
|
99
|
+
describe 'with circular reference' do
|
100
|
+
let(:recursive_template_with_inputs) do
|
101
|
+
FactoryGirl.create(:job_template, :name => 'test', :template => 'test')
|
102
|
+
end
|
103
|
+
|
104
|
+
let(:template_with_inputs) do
|
105
|
+
FactoryGirl.create(:job_template, :template => 'test').tap do |template|
|
106
|
+
template.foreign_input_sets << FactoryGirl.build(:foreign_input_set, :target_template => recursive_template_with_inputs)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
let(:recursive_template_without_inputs) do
|
111
|
+
FactoryGirl.create(:job_template, :name => 'recursive template', :template => '<%= render_template("template with inputs", "action" => "install") %>')
|
112
|
+
end
|
113
|
+
|
114
|
+
let(:template_without_inputs) do
|
115
|
+
FactoryGirl.create(:job_template, :name => 'template with inputs', :template => "<%= render_template('#{recursive_template_without_inputs.name}') %>")
|
116
|
+
end
|
117
|
+
|
118
|
+
before do
|
119
|
+
User.current = users :admin
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'handles circular references in templates' do
|
123
|
+
renderer.invocation = FactoryGirl.build(:template_invocation, :template => template_without_inputs)
|
124
|
+
renderer.template = template_without_inputs
|
125
|
+
refute renderer.render
|
126
|
+
renderer.error_message.must_include 'Recursive rendering of templates detected'
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'handles circular references in inputs' do
|
130
|
+
assert_raises(ActiveRecord::RecordInvalid) do
|
131
|
+
input_set = FactoryGirl.build(:foreign_input_set, :target_template => template_with_inputs, :include_all => false,
|
132
|
+
:include => 'package, debug', :exclude => 'action,debug')
|
133
|
+
recursive_template_with_inputs.foreign_input_sets << input_set
|
134
|
+
recursive_template_with_inputs.save!
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context 'renderer for template with input set and render_template' do
|
142
|
+
let(:command_template) do
|
143
|
+
FactoryGirl.build(:job_template, :name => 'command action', :template => '<%= input("command") -%>').tap do |template|
|
144
|
+
template.template_inputs << FactoryGirl.build(:template_input, :name => 'command', :input_type => 'user')
|
145
|
+
template.template_inputs << FactoryGirl.build(:template_input, :name => 'debug', :input_type => 'user')
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
let(:package_template) do
|
150
|
+
FactoryGirl.build(:job_template, :name => 'package action', :template => <<TEMPLATE) do |template|
|
151
|
+
<%= render_template("command action", "command" => "yum -y \#{ input("action") } \#{ input('package') }") -%>
|
152
|
+
TEMPLATE
|
153
|
+
template.template_inputs << FactoryGirl.build(:template_input, :name => 'package', :input_type => 'user')
|
154
|
+
template.template_inputs << FactoryGirl.build(:template_input, :name => 'action', :input_type => 'user')
|
155
|
+
template.foreign_input_sets << FactoryGirl.build(:foreign_input_set, :target_template => command_template, :include_all => true, :exclude => 'command')
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
let(:template) do
|
160
|
+
FactoryGirl.create(:job_template,
|
161
|
+
:template => '<%= render_template("package action", { :action => "install" }, { :with_foreign_input_set => true }) %>').tap do |template|
|
162
|
+
template.foreign_input_sets << FactoryGirl.build(:foreign_input_set, :target_template => package_template, :include_all => true, :exclude => 'action')
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
let(:job_invocation) { FactoryGirl.create(:job_invocation) }
|
167
|
+
let(:template_invocation) { FactoryGirl.build(:template_invocation, :template => template) }
|
168
|
+
let(:renderer) { InputTemplateRenderer.new(template) }
|
169
|
+
let(:result) { renderer.render }
|
170
|
+
|
171
|
+
before do
|
172
|
+
User.current = users :admin
|
173
|
+
command_template.save!
|
174
|
+
package_template.save!
|
175
|
+
job_invocation.template_invocations << template_invocation
|
176
|
+
end
|
177
|
+
|
178
|
+
describe 'foreign input set' do
|
179
|
+
describe 'with include_all' do
|
180
|
+
let(:template) do
|
181
|
+
FactoryGirl.create(:job_template, :template => '<%= render_template("package action", "action" => "install") %>').tap do |template|
|
182
|
+
template.foreign_input_sets << FactoryGirl.build(:foreign_input_set, :target_template => package_template, :include_all => true)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
let(:template_2) do
|
187
|
+
FactoryGirl.create(:job_template, :template => '<%= render_template("package action", "action" => "install") %>').tap do |template|
|
188
|
+
template.foreign_input_sets << FactoryGirl.build(:foreign_input_set,
|
189
|
+
:target_template => package_template, :include_all => true, :include => '', :exclude => '')
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'includes all inputs from the imported template' do
|
194
|
+
template.template_inputs_with_foreign.map(&:name).sort.must_equal ['action', 'debug', 'package']
|
195
|
+
template_2.template_inputs_with_foreign.map(&:name).sort.must_equal ['action', 'debug', 'package']
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
describe 'with include_all and some excludes' do
|
200
|
+
let(:template) do
|
201
|
+
FactoryGirl.create(:job_template, :template => '<%= render_template("package action", "action" => "install") %>').tap do |template|
|
202
|
+
template.foreign_input_sets << FactoryGirl.build(:foreign_input_set, :target_template => package_template, :include_all => true, :exclude => 'action,debug')
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'includes all inputs from the imported template except the listed once' do
|
207
|
+
template.template_inputs_with_foreign.map(&:name).sort.must_equal ['package']
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
describe 'with some includes and some excludes' do
|
212
|
+
let(:template) do
|
213
|
+
FactoryGirl.create(:job_template, :template => '<%= render_template("package action", "action" => "install") %>').tap do |template|
|
214
|
+
template.foreign_input_sets << FactoryGirl.build(:foreign_input_set, :target_template => package_template, :include_all => false,
|
215
|
+
:include => 'package, debug', :exclude => 'action,debug')
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'includes all inputs from the imported template' do
|
220
|
+
template.template_inputs_with_foreign.map(&:name).sort.must_equal ['package']
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
context 'with invocation specified' do
|
226
|
+
before do
|
227
|
+
FactoryGirl.create(:template_invocation_input_value,
|
228
|
+
:template_invocation => template_invocation,
|
229
|
+
:template_input => template.template_inputs_with_foreign.find { |input| input.name == 'package' },
|
230
|
+
:value => 'zsh')
|
231
|
+
renderer.invocation = template_invocation
|
232
|
+
renderer.invocation.reload
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'can render with job invocation with corresponding value' do
|
236
|
+
rendered = renderer.render
|
237
|
+
renderer.error_message.must_be_nil
|
238
|
+
rendered.must_equal 'yum -y install zsh'
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
context 'with explicitly specifying inputs' do
|
243
|
+
let(:template) do
|
244
|
+
FactoryGirl.create(:job_template,
|
245
|
+
:template => '<%= render_template("package action", {"action" => "install", :package => "zsh"}) %>')
|
246
|
+
end
|
247
|
+
|
248
|
+
before do
|
249
|
+
renderer.invocation = template_invocation
|
250
|
+
renderer.invocation.reload
|
251
|
+
end
|
252
|
+
|
253
|
+
it 'can render with job invocation with corresponding value' do
|
254
|
+
rendered = renderer.render
|
255
|
+
renderer.error_message.must_be_nil
|
256
|
+
rendered.must_equal 'yum -y install zsh'
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'renders even without an input value' do
|
261
|
+
renderer.invocation = template_invocation
|
262
|
+
rendered = renderer.render
|
263
|
+
renderer.error_message.must_be_nil
|
264
|
+
rendered.must_equal 'yum -y install '
|
98
265
|
end
|
99
266
|
end
|
100
267
|
|
@@ -127,7 +294,7 @@ describe InputTemplateRenderer do
|
|
127
294
|
end
|
128
295
|
end
|
129
296
|
|
130
|
-
context
|
297
|
+
context 'renderer for template with fact input used' do
|
131
298
|
let(:template) { FactoryGirl.build(:job_template, :template => 'echo <%= input("issue") -%> > /etc/issue') }
|
132
299
|
let(:renderer) { InputTemplateRenderer.new(template) }
|
133
300
|
|
@@ -225,7 +392,7 @@ describe InputTemplateRenderer do
|
|
225
392
|
end
|
226
393
|
end
|
227
394
|
|
228
|
-
context
|
395
|
+
context 'renderer for template with variable input used' do
|
229
396
|
let(:template) { FactoryGirl.build(:job_template, :template => 'echo <%= input("client_key") -%> > /etc/chef/client.pem') }
|
230
397
|
let(:renderer) { InputTemplateRenderer.new(template) }
|
231
398
|
|
@@ -288,13 +455,17 @@ describe InputTemplateRenderer do
|
|
288
455
|
end
|
289
456
|
|
290
457
|
context 'with existing variable implemented as smart variable' do
|
291
|
-
let(:puppet_class)
|
458
|
+
let(:puppet_class) do
|
459
|
+
puppetclass = FactoryGirl.create(:puppetclass, :environments => [environment])
|
460
|
+
puppetclass.update_attribute(:hosts, [renderer.host])
|
461
|
+
puppetclass
|
462
|
+
end
|
292
463
|
let(:lookup_key) do
|
293
464
|
lookup_key_factory = SETTINGS[:version].short == '1.9' ? :lookup_key : :variable_lookup_key
|
294
465
|
FactoryGirl.create(lookup_key_factory,
|
295
466
|
:key => 'client_key',
|
296
467
|
:puppetclass => puppet_class,
|
297
|
-
:overrides => {"fqdn=#{renderer.host.fqdn}" =>
|
468
|
+
:overrides => {"fqdn=#{renderer.host.fqdn}" => 'RSA KEY'})
|
298
469
|
end
|
299
470
|
|
300
471
|
describe 'rendering' do
|
@@ -322,7 +493,7 @@ describe InputTemplateRenderer do
|
|
322
493
|
end
|
323
494
|
end
|
324
495
|
|
325
|
-
context
|
496
|
+
context 'renderer for template with puppet parameter input used' do
|
326
497
|
let(:template) { FactoryGirl.build(:job_template, :template => 'echo "This is WebServer with nginx <%= input("nginx_version") -%>" > /etc/motd') }
|
327
498
|
let(:renderer) { InputTemplateRenderer.new(template) }
|
328
499
|
|
@@ -371,7 +542,9 @@ describe InputTemplateRenderer do
|
|
371
542
|
|
372
543
|
context 'with existing puppet parameter with matching override' do
|
373
544
|
let(:puppet_class) do
|
374
|
-
FactoryGirl.create(:puppetclass, :environments => [environment], :
|
545
|
+
puppetclass = FactoryGirl.create(:puppetclass, :environments => [environment], :name => 'nginx')
|
546
|
+
puppetclass.update_attribute(:hosts, [renderer.host])
|
547
|
+
puppetclass
|
375
548
|
end
|
376
549
|
let(:lookup_key) do
|
377
550
|
lookup_key_factory = SETTINGS[:version].short == '1.9' ? :lookup_key : :puppetclass_lookup_key
|
@@ -380,7 +553,7 @@ describe InputTemplateRenderer do
|
|
380
553
|
:puppetclass => puppet_class,
|
381
554
|
:path => 'fqdn',
|
382
555
|
:override => true,
|
383
|
-
:overrides => {"fqdn=#{renderer.host.fqdn}" =>
|
556
|
+
:overrides => {"fqdn=#{renderer.host.fqdn}" => '1.4.7'})
|
384
557
|
end
|
385
558
|
|
386
559
|
describe 'rendering' do
|