Jira (PUP-9005) epp template fails to translate <%= ... %> when it is followed by a left parenthesis

13 views
Skip to first unread message

Helmut Ritter (JIRA)

unread,
Jul 16, 2018, 6:31:02 AM7/16/18
to puppe...@googlegroups.com
Helmut Ritter created an issue
 
Puppet / Bug PUP-9005
epp template fails to translate <%= ... %> when it is followed by a left parenthesis
Issue Type: Bug Bug
Affects Versions: PUP 4.10.12
Assignee: Unassigned
Components: Epp
Created: 2018/07/16 3:30 AM
Environment:

helmut@puppet:~$ uname -a
Linux puppet 4.4.0-97-generic #120-Ubuntu SMP Tue Sep 19 17:28:18 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
helmut@puppet:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.4 LTS
Release: 16.04
Codename: xenial
helmut@puppet:~$ puppet -V
4.10.12
helmut@puppet:~$

Priority: Normal Normal
Reporter: Helmut Ritter

See https://groups.google.com/d/msg/puppet-users/pQC6AspIC4M/a1KzBXjqBgAJ

Given the following code:

<%- | Hash $openvpnConf, String $openvpnMode, String $instance| -%>
<% (

{ 'Mode' => [ "$openvpnMode", ], }

).each |$category, $parameters| { -%>

      1. <%= $category %> ###
        <% $parameters.each |$parameter|
        Unknown macro: { -%><% if $parameter == 'remote' { -%> <%= $parameter %> <%= $openvpnConf['server'] %> <%= $openvpnConf['port'] %> <% } else { -%> <%= $parameter %> <%= $openvpnConf[$parameter] %> <% } -%><% }

        %>

Adding anything between

<%- | Hash $openvpnConf, String $openvpnMode, String $instance | -%>

and

<% ({
'Mode' => [

throws an error. As example:

<%- | Hash $openvpnConf, String $openvpnMode, String $instance | -%>
<%= $openvpnMode %>
<% (

{ 'Mode' => [         "$openvpnMode", ],   Results in Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Error while evaluating a Function Call, epp(): Invalid EPP: Ambiguous EPP parameter expression. Probably missing '<%-' before parameters to remove leading whitespace at /etc/puppetlabs/code/modules/openvpn/templates/etc/openvpn/config.epp:2:20 at /etc/puppetlabs/code/modules/openvpn/manifests/init.pp:29:22 on node h2786452.stratoserver.net /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/indirector/rest.rb:269:in `is_http_200?' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/indirector/rest.rb:167:in `find' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/indirector/indirection.rb:194:in `find' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/configurer.rb:439:in `block in retrieve_new_catalog' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/util.rb:507:in `block in thinmark' /opt/puppetlabs/puppet/lib/ruby/2.1.0/benchmark.rb:294:in `realtime' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/util.rb:506:in `thinmark' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/configurer.rb:438:in `retrieve_new_catalog' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/configurer.rb:78:in `retrieve_catalog' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/configurer.rb:147:in `prepare_and_retrieve_catalog' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/configurer.rb:309:in `run_internal' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/configurer.rb:221:in `block in run' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/context.rb:65:in `override' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet.rb:306:in `override' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/configurer.rb:195:in `run' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/agent.rb:58:in `block (5 levels) in run' /opt/puppetlabs/puppet/lib/ruby/2.1.0/timeout.rb:75:in `timeout' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/agent.rb:57:in `block (4 levels) in run' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/agent/locker.rb:21:in `lock' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/agent.rb:51:in `block (3 levels) in run' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/agent.rb:118:in `with_client' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/agent.rb:48:in `block (2 levels) in run' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/agent.rb:85:in `run_in_fork' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/agent.rb:47:in `block in run' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/application.rb:179:in `call' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/application.rb:179:in `controlled_run' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/agent.rb:45:in `run' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/application/agent.rb:360:in `onetime' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/application/agent.rb:338:in `run_command' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/application.rb:375:in `block in run' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/util.rb:662:in `exit_on_fail' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/application.rb:375:in `run' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/util/command_line.rb:132:in `run' /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/util/command_line.rb:72:in `execute' /opt/puppetlabs/puppet/bin/puppet:5:in `<main>'are also helpful. The template is called via content => epp("openvpn/etc/openvpn/config.epp", \{ openvpnConf => $openvpnConf, openvpnMode => $openvpnMode, instance => $instance }

),

Add Comment Add Comment
 
This message was sent by Atlassian JIRA (v7.7.1#77002-sha1:e75ca93)
Atlassian logo

Henrik Lindberg (JIRA)

unread,
Jul 16, 2018, 9:27:03 AM7/16/18
to puppe...@googlegroups.com
Henrik Lindberg updated an issue
Change By: Henrik Lindberg
{code}
<%- | Hash $openvpnConf, String $openvpnMode, String $instance| -%>
<% ({
'Mode' => [
"$openvpnMode",
],
}).each |$category, $parameters| { -%>
### <%= $category %> ###
<% $parameters.each |$parameter| { -%>

<% if $parameter == 'remote' { -%>
<%= $parameter %> <%= $openvpnConf['server'] %> <%= $openvpnConf['port'] %>
<% } else { -%>
<%= $parameter %> <%= $openvpnConf[$parameter] %>
<% } -%>
<% } %>
{code}
Adding anything between
{code}
<%- | Hash $openvpnConf, String $openvpnMode, String $instance | -%>
{code}
and
{code}
<% ({
'Mode' => [
{code}
throws an error. As example:
{code}
<%- | Hash $openvpnConf, String $openvpnMode, String $instance | -%>
*<%= $openvpnMode %>*
<% ({
'Mode' => [
        "$openvpnMode",
],
  {code}
{code}
content => epp("openvpn/etc/openvpn/config.epp", \{ openvpnConf => $openvpnConf, openvpnMode => $openvpnMode, instance => $instance }),

{code}

Jorie Tappa (JIRA)

unread,
Oct 8, 2018, 5:10:05 PM10/8/18
to puppe...@googlegroups.com

Jorie Tappa (JIRA)

unread,
Oct 8, 2018, 5:10:05 PM10/8/18
to puppe...@googlegroups.com

Henrik Lindberg (JIRA)

unread,
Oct 9, 2018, 7:02:04 AM10/9/18
to puppe...@googlegroups.com
Henrik Lindberg commented on Bug PUP-9005
 
Re: epp template fails to translate <%= ... %> when it is followed by a left parenthesis

The sample has many problems. I fixed them up to create a reproducer but I cannot reproduce the reported problem:
This is my example (test.pp)

$template = @(END)
<%- | Hash $openvpnConf, String $openvpnMode, String $instance| -%>
<% ({
'Mode' => [
 "$openvpnMode",
],
}).each |$category, $parameters| { -%>
### <%= $category %>  ###
<% $parameters.each |$parameter| { -%>
<% if $parameter == 'remote' { -%>
<%= $parameter %> <%= $openvpnConf['server'] %> <%= $openvpnConf['port'] %>
<% } else { -%>
<%= $parameter %> <%= $openvpnConf[$parameter] %>
<% } -%>
<% }} %>
END
notice inline_epp($template, {
  openvpnConf => {server => '"a server"', port => 666},
  openvpnMode => remote, 
  instance => "unused"
})

And it works as it should. Helmut Ritter, can you run that example on your version of puppet? (My test was on Puppet 6).

Henrik Lindberg (JIRA)

unread,
Oct 9, 2018, 7:02:04 AM10/9/18
to puppe...@googlegroups.com

Helmut Ritter (JIRA)

unread,
Oct 9, 2018, 7:55:04 AM10/9/18
to puppe...@googlegroups.com
Helmut Ritter commented on Bug PUP-9005
 
Re: epp template fails to translate <%= ... %> when it is followed by a left parenthesis

Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Error while evaluating a Function Call, epp(): Invalid EPP: Syntax error at '|' at /etc/puppetlabs/code/modules/openvpn/templates/etc/openvpn/config.test.epp:2:5 at /etc/puppetlabs/code/modules/openvpn/manifests/init.pp:36:22 on node h2786452.stratoserver.net
 helmut@h2786452:~$ puppet -V
 4.10.12
 helmut@h2786452:~${code}

Henrik Lindberg (JIRA)

unread,
Oct 9, 2018, 9:23:06 AM10/9/18
to puppe...@googlegroups.com

Ok, there has been bugfixes to epp and the language since 4.10.12 (which is EOL Dec 31 2018). Since I could not reproduce your problem on Puppet 6 there is not much we can do. If this is reproducible on a 5.x, then it will be fixed there.

Helmut Ritter Can you try your code on a newer Puppet?

Josh Cooper (JIRA)

unread,
Apr 5, 2019, 1:31:02 AM4/5/19
to puppe...@googlegroups.com

Helmut Ritter (Jira)

unread,
Jun 19, 2020, 6:30:03 AM6/19/20
to puppe...@googlegroups.com
Helmut Ritter updated an issue
Change By: Helmut Ritter
Attachment: main.cf.epp
This message was sent by Atlassian Jira (v8.5.2#805002-sha1:a66f935)
Atlassian logo

Helmut Ritter (Jira)

unread,
Jun 19, 2020, 6:30:04 AM6/19/20
to puppe...@googlegroups.com
Helmut Ritter commented on Bug PUP-9005
 
Re: epp template fails to translate <%= ... %> when it is followed by a left parenthesis

Hi,

I tried now with 6.16 but the issue still exists:

helmut@ubuntu:~$ sudo puppet agent -t -v
Info: Using configured environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Retrieving locales
Info: Loading facts
Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Error while evaluating a Function Call, epp(): Invalid EPP: Ambiguous EPP parameter expression. Probably missing '<%-' before parameters to remove leading whitespace (file: /etc/puppetlabs/code/modules/postfix/templates/common/etc/postfix/main.cf.epp, line: 5, column: 6) (file: /etc/puppetlabs/code/modules/postfix/manifests/common.pp, line: 77, column: 20) on node ubuntu.charlieroot.de
Warning: Not using cache on failed catalog
Error: Could not retrieve catalog; skipping run
helmut@ubuntu:~$ puppet -V
6.16.0
helmut@ubuntu:~$

helmut@puppet:~$ puppetserver -v
puppetserver version: 6.12.0
helmut@puppet:~$

main.cf.epp

Helmut Ritter (Jira)

unread,
Jun 19, 2020, 5:07:04 PM6/19/20
to puppe...@googlegroups.com

Helmut Ritter (Jira)

unread,
Jul 16, 2020, 5:55:03 AM7/16/20
to puppe...@googlegroups.com
Helmut Ritter commented on Bug PUP-9005
 
Re: epp template fails to translate <%= ... %> when it is followed by a left parenthesis

Maybe a simpler example:

<%- | Hash $opensshCfg | -%>

  1. This file is managed by Puppet, don't edit it by hand.
  2. All changes will be overwritten!
    ################################################################################
    <% if $opensshCfg { -%> <% (\{ 'a' => [ 'b', 'c' ]}

    ).each |String $my_hash, $my_array|

    { -%> ### <%= $my_hash %> <%= $my_array %> ### <% } -%>
    <% } -%>

    Works:


  1. helmut@ubuntu:~$ sudo puppet agent -t -v
    Info: Using configured environment 'production'
    Info: Retrieving pluginfacts
    Info: Retrieving plugin
    Info: Retrieving locales
    Info: Loading facts
  1. Info: Caching catalog for ubuntu
    Info: Applying configuration version '1594891368'
    Notice: Applied catalog in 8.78 seconds
    helmut@ubuntu:~$

     

    Now put anything between <% if $opensshCfg { -%> and <% ({ (here: ###):

    <%- | Hash $opensshCfg | -%>
    # This file is managed by Puppet, don't edit it by hand.
    # All changes will be overwritten!
    ################################################################################
    <% if $opensshCfg { -%> ### <% (\{ 'a' => [ 'b', 'c' ]}).each |String $my_hash, $my_array| { -%> ### <%= $my_hash %> <%= $my_array %> ### <% }

    -%>
    <% } -%>

Doesn't work:

helmut@ubuntu:~$ sudo puppet agent -t -v
Info: Using configured environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Retrieving locales
Info: Loading facts

Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Error while evaluating a Function Call, epp(): Invalid EPP: Ambiguous EPP parameter expression. Probably missing '<%-' before parameters to remove leading whitespace (file: /etc/puppetlabs/code/modules/openssh/templates/etc/ssh/ssh_config.epp, line: 5, column: 24) (file: /etc/puppetlabs/code/modules/openssh/manifests/init.pp, line: 31, column: 20) on node ubuntu.charlieroot.de


Warning: Not using cache on failed catalog
Error: Could not retrieve catalog; skipping run
helmut@ubuntu:~$

 

I found out what does work is to assign to a variable first:

<%- | Hash $opensshCfg | -%>

  1. This file is managed by Puppet, don't edit it by hand.
  2. All changes will be overwritten!
    ################################################################################
    <% if $opensshCfg { -%> ### <% $data = \{ 'a' => [ 'b', 'c' ]}

    -%>
    <% $data.each |String $my_hash, $my_array|

    { -%> ### <%= $my_hash %> <%= $my_array %> ### <% }

    -%>
    <% } -%>

helmut@ubuntu:~$ puppet -V
6.16.0
helmut@ubuntu:~$

helmut@puppet:~$ puppetserver -v
puppetserver version: 6.12.0
helmut@puppet:~$

Henrik Lindberg (Jira)

unread,
Jul 16, 2020, 6:26:03 AM7/16/20
to puppe...@googlegroups.com

This bit:

<% if $opensshCfg { -%> ### <% (\{ 'a' => [ 'b', 'c' ]}).each |String $my_hash, $my_array| { -%> ### <%= $my_hash %> <%= $my_array %> ### <% }

When turned into puppet language is:

if $opensshCfg { emitString("###")({ 'a' => [ 'b', 'c' ]}).each |String $my_hash, $my_array| { emitString("###") emitExpr($my_hash) emitExpr($my_array) emitString("###"(}

The emitString, and emitExpr are internal instructions that are expressions that are specific to EPP.

And I suspect that the problem is here:

emitString("###")({ 'a' => [ 'b', 'c' ]})

As that may be seen as an attempt of calling the result of emitString with the literal hash as an argument. This is why an intermediate assignment makes it work (since it cannot possibly be a continuation of what is to the left of it). You could probably use a semicolon "statement separator" there instead of the assignment to clearly state to the parser that "don't try to take the rest as part of the same expression".

Helmut Ritter (Jira)

unread,
Jul 16, 2020, 6:54:03 AM7/16/20
to puppe...@googlegroups.com
Helmut Ritter commented on Bug PUP-9005

I'm fine with assigning a variable first so for me the ticket is solved and just for the records.

Reply all
Reply to author
Forward
0 new messages