From ced4bfbe53aa3cdd6ec57ff9279b33eaddddf884 Mon Sep 17 00:00:00 2001 From: Pat Riehecky Date: Fri, 24 Apr 2026 08:48:31 -0500 Subject: [PATCH] Add option to provide inline epp templates --- REFERENCE.md | 37 +++++++++++++++++++--------- manifests/manage.pp | 33 +++++++++++++++++++++---- spec/classes/manage_spec.rb | 49 +++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 17 deletions(-) diff --git a/REFERENCE.md b/REFERENCE.md index 0d78da93d..efc901cb8 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -114,7 +114,7 @@ the provided regular expression. * [`squeeze`](#squeeze): Returns a new string where runs of the same character that occur in this set are replaced by a single character. * [`stdlib::batch_escape`](#stdlib--batch_escape): Escapes a string so that it can be safely used in a batch shell command line. * [`stdlib::crc32`](#stdlib--crc32): Run a CRC32 calculation against a given value. -* [`stdlib::deferrable_epp`](#stdlib--deferrable_epp): This function returns either a rendered template or a deferred function to render at runtime. If any of the values in the variables hash are +* [`stdlib::deferrable_epp`](#stdlib--deferrable_epp): This function returns either a rendered template or a deferred function to render at runtime. If any of the values in the variables hash are * [`stdlib::end_with`](#stdlib--end_with): Returns true if str ends with one of the prefixes given. Each of the prefixes should be a String. * [`stdlib::ensure`](#stdlib--ensure): function to cast ensure parameter to resource specific value * [`stdlib::ensure_packages`](#stdlib--ensure_packages): Takes a list of packages and only installs them if they don't already exist. @@ -264,7 +264,7 @@ and `subscribe`. #### Examples -##### +##### ```puppet class { 'stdlib::manage': @@ -280,6 +280,13 @@ class { 'stdlib::manage': 'template' => 'profile/motd.epp', } }, + '/etc/inline' => { + 'ensure' => 'file', + 'epp' => { + 'inline' => 'Hello <%= $name %>', + 'context' => { 'name' => 'world' }, + } + }, '/etc/information' => { 'ensure' => 'file', 'erb' => { @@ -297,7 +304,7 @@ class { 'stdlib::manage': } ``` -##### +##### ```puppet stdlib::manage::create_resources: @@ -310,6 +317,12 @@ stdlib::manage::create_resources: epp: template: 'profile/motd.epp' context: {} + '/etc/inline': + ensure: 'file' + epp: + inline: 'Hello <%= $name %>' + context: + name: world '/etc/information': ensure: 'file' erb: @@ -355,7 +368,7 @@ The high level stages are (in order): #### Examples -##### +##### ```puppet node default { @@ -3176,7 +3189,7 @@ Returns true if str ends with one of the prefixes given. Each of the prefixes sh #### Examples -##### +##### ```puppet 'foobar'.stdlib::end_with('bar') => true @@ -3192,7 +3205,7 @@ Returns: `Boolean` True or False ##### Examples -###### +###### ```puppet 'foobar'.stdlib::end_with('bar') => true @@ -4152,7 +4165,7 @@ Returns true if str starts with one of the prefixes given. Each of the prefixes #### Examples -##### +##### ```puppet 'foobar'.stdlib::start_with('foo') => true @@ -4168,7 +4181,7 @@ Returns: `Boolean` True or False ##### Examples -###### +###### ```puppet 'foobar'.stdlib::start_with('foo') => true @@ -4204,7 +4217,7 @@ manifests/modules as it inspects the catalog thus far. #### Examples -##### +##### ```puppet stdlib::str2resource('File[/foo]') => File[/foo] @@ -4226,7 +4239,7 @@ Returns: `Any` Puppet::Resource ##### Examples -###### +###### ```puppet stdlib::str2resource('File[/foo]') => File[/foo] @@ -5577,7 +5590,7 @@ Takes one element from first array and merges corresponding elements from second #### Examples -##### +##### ```puppet zip(['1','2','3'],['4','5','6']) @@ -5592,7 +5605,7 @@ Returns: `Any` This generates a sequence of n-element arrays, where n is one mor ##### Examples -###### +###### ```puppet zip(['1','2','3'],['4','5','6']) diff --git a/manifests/manage.pp b/manifests/manage.pp index cb8c3351a..09710524c 100644 --- a/manifests/manage.pp +++ b/manifests/manage.pp @@ -27,6 +27,13 @@ # 'template' => 'profile/motd.epp', # } # }, +# '/etc/inline' => { +# 'ensure' => 'file', +# 'epp' => { +# 'inline' => 'Hello <%= $name %>', +# 'context' => { 'name' => 'world' }, +# } +# }, # '/etc/information' => { # 'ensure' => 'file', # 'erb' => { @@ -54,6 +61,12 @@ # epp: # template: 'profile/motd.epp' # context: {} +# '/etc/inline': +# ensure: 'file' +# epp: +# inline: 'Hello <%= $name %>' +# context: +# name: world # '/etc/information': # ensure: 'file' # erb: @@ -84,14 +97,24 @@ } if 'epp' in $attributes { - if 'template' in $attributes['epp'] { - if 'context' in $attributes['epp'] { - $content = epp($attributes['epp']['template'], $attributes['epp']['context']) + $epp_hash = $attributes['epp'] + if 'template' in $epp_hash and 'inline' in $epp_hash { + fail("You can not set both 'template' and 'inline' for epp for ${type} ${title}") + } + if 'template' in $epp_hash { + if 'context' in $epp_hash { + $content = epp($epp_hash['template'], $epp_hash['context']) + } else { + $content = epp($epp_hash['template']) + } + } elsif 'inline' in $epp_hash { + if 'context' in $epp_hash { + $content = inline_epp($epp_hash['inline'], $epp_hash['context']) } else { - $content = epp($attributes['epp']['template']) + $content = inline_epp($epp_hash['inline']) } } else { - fail("No template configured for epp for ${type} ${title}") + fail("No template or inline configured for epp for ${type} ${title}") } } elsif 'erb' in $attributes { if 'template' in $attributes['erb'] { diff --git a/spec/classes/manage_spec.rb b/spec/classes/manage_spec.rb index db4b6a64e..d6503699c 100644 --- a/spec/classes/manage_spec.rb +++ b/spec/classes/manage_spec.rb @@ -31,6 +31,12 @@ 'template' => 'profile/motd.epp' } }, + '/etc/inline' => { + 'epp' => { + 'inline' => 'Hello <%= $name %>', + 'context' => { 'name' => 'world' } + } + }, '/etc/information' => { 'erb' => { 'template' => 'profile/information.erb' @@ -73,6 +79,9 @@ Puppet::Functions.create_function(:epp) do return 'I am an epp template' end + Puppet::Functions.create_function(:inline_epp) do + return 'I am an inline epp template' + end Puppet::Functions.create_function(:template) do return 'I am an erb template' end @@ -80,6 +89,7 @@ it { is_expected.to compile } it { is_expected.to contain_file('/etc/motd.d/hello').with_content('I say Hi').with_notify('Service[sshd]') } it { is_expected.to contain_file('/etc/motd').with_content(%r{I am an epp template}) } + it { is_expected.to contain_file('/etc/inline').with_content(%r{I am an inline epp template}) } it { is_expected.to contain_file('/etc/information').with_content(%r{I am an erb template}) } it { is_expected.to contain_concat('/tmp/filename') } it { is_expected.to contain_concat__fragment('rawcontent').with_content('test content') } @@ -87,4 +97,43 @@ it { is_expected.to contain_concat__fragment('erbcontent').with_content(%r{I am an erb template}) } it { is_expected.to contain_package('example').with_ensure('installed').that_subscribes_to(['Service[sshd]', 'File[/etc/motd.d]']) } end + + describe 'error cases' do + context 'both template and inline specified in epp' do + let :params do + { + 'create_resources' => { + 'file' => { + '/etc/test' => { + 'epp' => { + 'template' => 'profile/test.epp', + 'inline' => 'Hello <%= $name %>' + } + } + } + } + } + end + + it { is_expected.to compile.and_raise_error(%r{both 'template' and 'inline'}) } + end + + context 'neither template nor inline specified in epp' do + let :params do + { + 'create_resources' => { + 'file' => { + '/etc/test' => { + 'epp' => { + 'context' => { 'name' => 'world' } + } + } + } + } + } + end + + it { is_expected.to compile.and_raise_error(%r{No template or inline configured for epp}) } + end + end end