Skip to content

Commit d61cf5a

Browse files
stejskalleosShimShtein
authored andcommitted
Fixes #38939 - host_param macro & transient parameters
:host_param macro now allows rendering host parameters that are assigned to the host, but are not in the database. Background Transient (new) host parameters associated with the host are not rendered in the template check action nor in the 'Orchestration:Templates' queue. This behavior causes issues for image-based provisioning when the activation key is defined on the host level, rather than on the hostgroup. Fixed scenarios * 'host_param' macro now renders all host parameters * 'hosts#template_used' action now renders templates with all host parameters * 'Orchestration::Templates' now renders templates with all host parameters Links * Community RFC: https://community.theforeman.org/t/provisioning-hosts-doesnt-work-well-with-host-parameters/44334 * Original ticket: https://projects.theforeman.org/issues/38422
1 parent e326764 commit d61cf5a

File tree

5 files changed

+99
-24
lines changed

5 files changed

+99
-24
lines changed

app/models/concerns/host_params.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ def inherited_params_hash
2121
end
2222

2323
def non_inherited_params_hash
24-
params_to_hash(host_parameters.authorized(:view_params))
24+
items = host_parameters.authorized(:view_params).to_a
25+
# Add transient host parameters to the array
26+
# :authorized removes records that are not saved in the db
27+
items += host_parameters.reject(&:persisted?) if User.current.can?(:view_params)
28+
params_to_hash(items.uniq(&:name))
2529
end
2630

2731
def params_to_hash(params)

test/controllers/hosts_controller_test.rb

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,28 +1128,52 @@ class Host::Valid < Host::Managed; end
11281128
describe '#template_used' do
11291129
setup do
11301130
@host.setBuild
1131-
ActiveRecord::Base.any_instance.expects(:destroy).never
1132-
ActiveRecord::Base.any_instance.expects(:save).never
11331131
@attrs = host_attributes(@host)
11341132
@attrs['hostgroup_id'] = hostgroups(:common).id
11351133
end
11361134

11371135
test 'returns templates with interfaces' do
1136+
ActiveRecord::Base.any_instance.expects(:destroy).never
1137+
ActiveRecord::Base.any_instance.expects(:save).never
1138+
11381139
nic = FactoryBot.build(:nic_managed, :host => @host)
11391140
@attrs[:interfaces_attributes] = nic.attributes.except 'updated_at', 'created_at', 'attrs'
11401141
put :template_used, params: {:provisioning => 'build', :host => @attrs, :id => @host.id }, session: set_session_user, xhr: true
11411142
assert_response :success
11421143
assert_template :partial => '_provisioning'
11431144
end
11441145

1145-
test 'returns templates with host parameters' do
1146-
@attrs[:host_parameters_attributes] = {'0' => {:name => 'foo', :value => 'bar'}}
1147-
put :template_used, params: {:provisioning => 'build', :host => @attrs }, session: set_session_user
1146+
test 'render templates with host parameters' do
1147+
template_kind = TemplateKind.find_by_name('provision')
1148+
template_with_error = FactoryBot.create :provisioning_template,
1149+
name: 'fail_without_hp_parameter',
1150+
template: "<% raise 'BOOOM' if host_param('transient-hp', '').empty? -%>",
1151+
template_kind: template_kind
1152+
os = FactoryBot.create(:operatingsystem, :with_archs, :with_os_defaults, provisioning_templates: [template_with_error])
1153+
host = FactoryBot.create(:host, :managed, operatingsystem: os)
1154+
attrs = host_attributes(host)
1155+
1156+
ActiveRecord::Base.any_instance.expects(:destroy).never
1157+
ActiveRecord::Base.any_instance.expects(:save).never
1158+
1159+
put :template_used, params: {:provisioning => 'build', :host => attrs }, session: set_session_user
1160+
assert_response :success
1161+
assert_template :partial => '_provisioning'
1162+
assert response.body.include? 'Templates rendered with errors'
1163+
assert response.body.include? 'BOOOM'
1164+
1165+
attrs[:host_parameters_attributes] = {'0' => {:name => 'transient-hp', :value => 'i-am-not-saved-in-db'}}
1166+
put :template_used, params: {:provisioning => 'build', :host => attrs }, session: set_session_user
11481167
assert_response :success
11491168
assert_template :partial => '_provisioning'
1169+
refute response.body.include? 'Templates rendered with errors'
1170+
refute response.body.include? 'BOOOM'
11501171
end
11511172

11521173
test 'shows templates for image provisioning' do
1174+
ActiveRecord::Base.any_instance.expects(:destroy).never
1175+
ActiveRecord::Base.any_instance.expects(:save).never
1176+
11531177
image = compute_resources(:one).images.first
11541178
@attrs[:compute_resource_id] = compute_resources(:one).id
11551179
@attrs[:operatingsystem_id] = image.operatingsystem.id
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
require 'test_helper'
2+
3+
class HostParamsTest < ActiveSupport::TestCase
4+
test 'shows global params' do
5+
host = FactoryBot.build_stubbed(:host)
6+
7+
FactoryBot.create(:common_parameter, :name => 'test_param1', :value => 'test_value1')
8+
9+
assert_equal 'test_value1', host.host_params['test_param1']
10+
end
11+
12+
test 'renders global params if template specified' do
13+
host = FactoryBot.build_stubbed(:host)
14+
# rubocop:disable Lint/InterpolationCheck
15+
FactoryBot.create(:common_parameter, :name => 'test_param1', :value => '<%= "test_value1-#{@host.name}" %>')
16+
# rubocop:enable Lint/InterpolationCheck
17+
18+
assert_equal "test_value1-#{host.name}", host.host_params['test_param1']
19+
end
20+
21+
test 'transient host parameters in host_params' do
22+
host = FactoryBot.build(:host)
23+
hp = FactoryBot.build(:host_parameter, name: 'transient-hp', value: 'i-am-not-saved-in-db')
24+
host.host_parameters << hp
25+
26+
assert host.host_params.key? hp.name
27+
assert_equal hp.value, host.host_params[hp.name]
28+
29+
assert host.host_params_hash.key? hp.name
30+
assert_equal hp.value, host.host_params_hash.dig(hp.name, :value)
31+
end
32+
33+
test 'transient host params without :view_params permission' do
34+
user_role = FactoryBot.create(:user_user_role)
35+
36+
as_user user_role.owner do
37+
host = FactoryBot.build(:host)
38+
hp = FactoryBot.build(:host_parameter, name: 'transient-hp', value: 'i-am-not-saved-in-db')
39+
host.host_parameters << hp
40+
41+
refute host.host_params.key? hp.name
42+
assert host.host_params.key? parameters(:common).name
43+
44+
refute host.host_params_hash.key? hp.name
45+
assert host.host_params_hash.key? parameters(:common).name
46+
end
47+
end
48+
end

test/models/host_test.rb

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3381,24 +3381,6 @@ def to_managed!
33813381
end
33823382
end
33833383

3384-
describe 'HostParams module' do
3385-
test 'shows global params' do
3386-
host = FactoryBot.build_stubbed(:host)
3387-
FactoryBot.create(:common_parameter, :name => 'test_param1', :value => 'test_value1')
3388-
3389-
assert_equal 'test_value1', host.host_params['test_param1']
3390-
end
3391-
3392-
test 'renders global params if template specified' do
3393-
host = FactoryBot.build_stubbed(:host)
3394-
# rubocop:disable Lint/InterpolationCheck
3395-
FactoryBot.create(:common_parameter, :name => 'test_param1', :value => '<%= "test_value1-#{@host.name}" %>')
3396-
# rubocop:enable Lint/InterpolationCheck
3397-
3398-
assert_equal "test_value1-#{host.name}", host.host_params['test_param1']
3399-
end
3400-
end
3401-
34023384
test "should find smart proxy ids" do
34033385
host_1 = FactoryBot.create(:host, :with_tftp_orchestration)
34043386
host_2 = FactoryBot.create(:host, :with_dns_orchestration)

test/unit/orchestration/templates_test.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,21 @@ class TemplatesTest < ActiveSupport::TestCase
2727
assert_equal 1, @queue.count
2828
refute @host.set_renderability
2929
end
30+
31+
test 'with transient host parameter' do
32+
template = FactoryBot.build :provisioning_template,
33+
name: 'fail_without_hp_parameter',
34+
template: "<% raise 'BOOOM' if host_param('transient-hp', '').empty? -%>"
35+
@host.stubs(:provisioning_template).returns(template)
36+
37+
@host.queue_render_checks
38+
assert_equal 1, @queue.count
39+
refute @host.set_renderability
40+
41+
@host.clear_host_parameters_cache!
42+
@host.host_parameters << FactoryBot.build(:host_parameter, name: 'transient-hp', value: 'i-am-not-saved-in-db')
43+
@host.queue_render_checks
44+
assert_equal 1, @queue.count
45+
assert @host.set_renderability
46+
end
3047
end

0 commit comments

Comments
 (0)