puppetlabs / puppet

Server automation framework and application
https://puppet.com/open-source/#osp
Apache License 2.0
7.34k stars 2.19k forks source link

nested lookup calls interpolate values #9308

Open bastelfreak opened 3 months ago

bastelfreak commented 3 months ago

Describe the Bug

Hi, I've the following code:

braces1: "%{literal('%')}{}"
braces2: "%{lookup('braces1')}"
braces3: "%{alias('braces1')}"
echo { 'braces1:':
  message  => "${lookup('braces1')}",
  withpath => false,
}
echo { 'braces2:':
  message  => "${lookup('braces2')}",
  withpath => false,
}
echo { 'braces3:':
  message  => "${lookup('braces3')}",
  withpath => false,
}

(echo resource from https://forge.puppet.com/modules/ipcrm/echo/readme which is basically a notify)

This outputs:

Notice: %{}
Notice:
Notice: %{}

Expected Behavior

I expect the same output three times:

Notice: %{}
Notice: %{}
Notice: %{}

Steps to Reproduce

Above code with puppet 8.5.1 or 7.29.1

Additional Context

I'm not sure if this is the intended behavior for lookup or a bug. Also the documentation for the literal() seems to be wrong: https://github.com/puppetlabs/puppet-docs/issues/1149 (which made this bug even more confusing).

Sharpie commented 3 months ago

This looks like the documented behavior to me:

lookup - looks up a key using Hiera, and interpolates the value into a string alias - looks up a key using Hiera, and uses the value as a replacement for the enclosing string.

https://www.puppet.com/docs/puppet/8/hiera_merging#interpolation_functions

The difference between the two is that lookup() is doing an interpolation pass where as alias() just copies the value verbatim, so the %{} becomes an empty string in the second result.

jay7x commented 3 months ago

While we're on literal() matters, there is another unexpected behavior I saw ppl were complaining about..

Adding the following will raise a syntax error during the catalog compilation:

braces4: "%{literal('%{}')}"

I'm not sure if it's bug or feature though.. I feel it as a bug, but I can understand that %{} should be interpreted first.. though I'd expect no interpretation in the literal() arguments..