manipulating new facts

307 views
Skip to first unread message

Diego Roccia

unread,
Jan 25, 2016, 6:48:18 PM1/25/16
to Puppet Users
Hi

I'm migrating my puppet configuration from 3.6 to v4.2, but I'm having some problem with ip type facts. For example, I have this line :

priority          => inline_template('<%= 256 - ipaddress.split(".")[3].to_i %>')

on puppet 3.6 and it works, putting there the last octet of my ip address. on puppet 4.2 I get:

==> node-1: Error: Evaluation Error: Error while evaluating a Function Call, Failed to parse inline template: undefined local variable or method `ipaddress' for #<Puppet::Parser::TemplateWrapper:0x00000003d44628> at /tmp/vagrant-puppet/environments/test/manifests/default.pp:25:16 on node node-1.station

I think it depends on the new facts being no longer strings. in facts this works:

file { "/var/lib/zookeeper/myid":
    ensure => present,                                                                                                                          
    content => "${ipaddress}"
}

my file contains the whole ip address, but with this:

file { "/var/lib/zookeeper/myid":
    ensure => present,                                                                                                                          
    content => "${ipaddress.split('.')[3]}"
}

the file is empty
any idea?

thanks in advance
the file contains



jcbollinger

unread,
Jan 26, 2016, 9:16:32 AM1/26/16
to Puppet Users


On Monday, January 25, 2016 at 5:48:18 PM UTC-6, Diego Roccia wrote:
Hi

I'm migrating my puppet configuration from 3.6 to v4.2, but I'm having some problem with ip type facts. For example, I have this line :

priority          => inline_template('<%= 256 - ipaddress.split(".")[3].to_i %>')

on puppet 3.6 and it works, putting there the last octet of my ip address. on puppet 4.2 I get:

==> node-1: Error: Evaluation Error: Error while evaluating a Function Call, Failed to parse inline template: undefined local variable or method `ipaddress' for #<Puppet::Parser::TemplateWrapper:0x00000003d44628> at /tmp/vagrant-puppet/environments/test/manifests/default.pp:25:16 on node node-1.station

I think it depends on the new facts being no longer strings.


It is apparently true that in Facter 3, $ipaddress is of type 'ip' rather than of type string, but "undefined" is very different from "incorrect type".

 
in facts this works:

file { "/var/lib/zookeeper/myid":
    ensure => present,                                                                                                                          
    content => "${ipaddress}"
}

my file contains the whole ip address, but with this:

file { "/var/lib/zookeeper/myid":
    ensure => present,                                                                                                                          
    content => "${ipaddress.split('.')[3]}"
}


the file is empty


As far as I am aware, that last form shouldn't work at all.  Unlike Ruby values, Puppet values do not have methods, unless you count array and hash indexing.  You cannot split a string like that (even if $ipaddress were a string).

 
any idea?


In Puppet 3.6 you could access Puppet variables, including facts, via their bare names, but that form was deprecated well before the end of the 3.x series.  In ERB templates you should instead use the form @variable to access in-scope variables; this works in 3.x, too.  You can also use the scope object to access variables, including (counter-intuitively) those that are not in scope inside the template.  More details are available in the templating docs.

I'm not actually sure where to find any documentation on the type 'ip' that legacy fact $ipaddress now has, but you could try indexing into it as if it were an array of integers:

priority => inline_template('<%= 256 - @ipaddress.[3] %>')

Failing that, the value's stringification seems to be the same as the old string value, so you could very likely do this:

priority => inline_template('<%= 256 - @ipaddress.to_s.split(".")[3].to_i %>')


John

Peter Huene

unread,
Jan 26, 2016, 1:08:07 PM1/26/16
to puppet...@googlegroups.com
On Tue, Jan 26, 2016 at 6:16 AM, jcbollinger <John.Bo...@stjude.org> wrote:


On Monday, January 25, 2016 at 5:48:18 PM UTC-6, Diego Roccia wrote:
Hi

I'm migrating my puppet configuration from 3.6 to v4.2, but I'm having some problem with ip type facts. For example, I have this line :

priority          => inline_template('<%= 256 - ipaddress.split(".")[3].to_i %>')

on puppet 3.6 and it works, putting there the last octet of my ip address. on puppet 4.2 I get:

==> node-1: Error: Evaluation Error: Error while evaluating a Function Call, Failed to parse inline template: undefined local variable or method `ipaddress' for #<Puppet::Parser::TemplateWrapper:0x00000003d44628> at /tmp/vagrant-puppet/environments/test/manifests/default.pp:25:16 on node node-1.station

I think it depends on the new facts being no longer strings.


It is apparently true that in Facter 3, $ipaddress is of type 'ip' rather than of type string, but "undefined" is very different from "incorrect type".

The `ipaddress` fact should still be a string.  I think the confusion lies in the schema calling it an "ip", which is really just a regular expression that confines the string to a particular format, e.g. an IPv4 address).  If you observe the `ipaddress` fact to be any other type please let us know, as that would be a serious regression.
 

 
in facts this works:

file { "/var/lib/zookeeper/myid":
    ensure => present,                                                                                                                          
    content => "${ipaddress}"
}

my file contains the whole ip address, but with this:

file { "/var/lib/zookeeper/myid":
    ensure => present,                                                                                                                          
    content => "${ipaddress.split('.')[3]}"
}


the file is empty


As far as I am aware, that last form shouldn't work at all.  Unlike Ruby values, Puppet values do not have methods, unless you count array and hash indexing.  You cannot split a string like that (even if $ipaddress were a string).

Puppet 4 supports two different function call expressions: `foo(bar)` and `bar.foo()`, where the latter form is called the "method call" expression.  As John said, Puppet doesn't have "methods" in the Ruby sense, only free functions, so calls with the "method call" form are simply translated into calling a free function with the same name (e.g. `foo`), passing the target operand (e.g. `bar`) as the first argument to the function.  I hope that makes sense.

 
any idea?


In Puppet 3.6 you could access Puppet variables, including facts, via their bare names, but that form was deprecated well before the end of the 3.x series.  In ERB templates you should instead use the form @variable to access in-scope variables; this works in 3.x, too.  You can also use the scope object to access variables, including (counter-intuitively) those that are not in scope inside the template.  More details are available in the templating docs.

I'm not actually sure where to find any documentation on the type 'ip' that legacy fact $ipaddress now has, but you could try indexing into it as if it were an array of integers:

priority => inline_template('<%= 256 - @ipaddress.[3] %>')

Failing that, the value's stringification seems to be the same as the old string value, so you could very likely do this:

priority => inline_template('<%= 256 - @ipaddress.to_s.split(".")[3].to_i %>')


John

--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/6def4fc8-f97f-4de4-85e5-31afd2de5e2a%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages