Project

General

Profile

« Previous | Next » 

Revision 84ae9603

Added by Greg Sutcliffe over 10 years ago

fixes #2260 Allow ERB in ENC global / class parameters

Adds code to parse the global & class parameters, and adds a setting (default true)
to disable this if needed. Also has some tests.

View differences:

app/models/host/managed.rb
end
param.update self.params
# Parse ERB values contained in the parameters
param = SafeRender.new(:variables => { :host => self }).parse(param)
classes = if Setting[:Parametrized_Classes_in_ENC] && Setting[:Enable_Smart_Variables_in_ENC]
lookup_keys_class_params
else
app/models/setting/puppet.rb
self.set('Default_variables_Lookup_Path', N_("The Default path in which Foreman resolves host specific variables"), ["fqdn", "hostgroup", "os", "domain"]),
self.set('Enable_Smart_Variables_in_ENC', N_("Should the smart variables be exposed via the ENC yaml output?"), true),
self.set('Parametrized_Classes_in_ENC', N_("Should Foreman use the new format (2.6.5+) to answer Puppet in its ENC yaml output?"), true),
self.set('interpolate_erb_in_parameters', N_("Should Foreman parse ERB to return dynamic parameters?"), true),
self.set('enc_environment', N_("Should Foreman provide puppet environment in ENC yaml output? (this avoids the mismatch error between puppet.conf and ENC environment)"), true),
self.set('use_uuid_for_certificates', N_("Should Foreman use random UUID's for certificate signing instead of hostnames"), false),
self.set('update_environment_from_facts', N_("Should Foreman update a host's environment from its facts"), false),
app/services/classification/base.rb
def initialize args = { }
@host = args[:host]
@safe_render = SafeRender.new(:variables => { :host => host } )
end
#override to return the relevant enc data and format
......
end
def value_of_key(key, values)
if values[key.id] and values[key.id][key.to_s]
values[key.id][key.to_s][:value]
else
key.default_value
end
value = if values[key.id] and values[key.id][key.to_s]
values[key.id][key.to_s][:value]
else
key.default_value
end
@safe_render.parse(value)
end
def hostgroup_matches
app/services/safe_render.rb
# Class to parse ERB with or without Safemode rendering. Needs a set
# of variables, usually something like:
# @allowed_vars = { :host => @host }
# so that <%= @host.name %> has the right @host variable
#
class SafeRender
def initialize(args = {})
@allowed_methods = args[:methods] || []
@allowed_vars = args[:variables] || {}
end
def parse(object)
return object if (!Setting[:interpolate_erb_in_parameters])
# recurse over object types until we're dealing with a String
case object
when String
parse_string object
when Array
object.map { |v| parse v }
when Hash
object.merge(object) { |k, v| parse v }
else
# Don't know how to parse this, send it back
object
end
end
private
def parse_string(string)
raise ::ForemanException.new(N_('SafeRender#parse_string was passed a %s instead of a string') % string.class) unless string.is_a? String
if Setting[:safemode_render]
box = Safemode::Box.new self, @allowed_methods
box.eval(ERB.new(string, nil, '-').src, @allowed_vars)
else
@allowed_vars.each { |k, v| instance_variable_set "@#{k}", v }
ERB.new(string, nil, '-').result(binding)
end
end
end
test/fixtures/settings.yml
category: Setting::Puppet
default: "false"
description: "Foreman will truncate hostname to 'puppet' if it starts with puppet"
attribute40:
name: interpolate_erb_in_parameters
category: Setting::Puppet
default: "true"
description: "Should Foreman parse ERB to return dynamic parameters?"
test/unit/safe_render_test.rb
require 'test_helper'
class SafeRenderTest < ActiveSupport::TestCase
def setup
@safe_render = SafeRender.new(:variables => { :host => hosts(:one) })
end
test 'safe_render should return raw strings when interpolate is false' do
Setting[:interpolate_erb_in_parameters] = false
s=@safe_render.parse('<%= @host.name %>')
assert_equal '<%= @host.name %>', s
end
test 'safe_render should return correct strings when interpolate is true' do
Setting[:interpolate_erb_in_parameters] = true
s=@safe_render.parse('<%= @host.name %>')
assert_equal 'my5name.mydomain.net', s
end
test 'safe_render should return correct arrays when interpolate is true' do
Setting[:interpolate_erb_in_parameters] = true
s=@safe_render.parse("['1.2.3.4','<%= @host.name %>']")
assert_equal "['1.2.3.4','my5name.mydomain.net']", s
end
test 'safe_render should return correct hashes when interpolate is true' do
Setting[:interpolate_erb_in_parameters] = true
s=@safe_render.parse("{'ip=>'1.2.3.4','name'=>'<%= @host.name %>'}")
assert_equal "{'ip=>'1.2.3.4','name'=>'my5name.mydomain.net'}", s
end
test 'safe_render can handle recursion' do
Setting[:interpolate_erb_in_parameters] = true
s=@safe_render.parse("['level1','<%= @host.name %>',['level2','<%= @host.name %>']]")
assert_equal "['level1','my5name.mydomain.net',['level2','my5name.mydomain.net']]", s
end
end

Also available in: Unified diff