Passing a generated variable inside a template...how?

149 views
Skip to first unread message

Dayton Jones

unread,
Nov 25, 2015, 3:25:22 PM11/25/15
to Puppet Users
I'm writing a template to populate a file - easy enough...

What I want is to to grab the list of interfaces, get the ip assigned to that interface and then do a lookup of the ip to get the dns name.

I'm able to get the interfaces/ips just fine, but can't figure out how to then pass the IP to the function to do the lookup.  Any help is greatly appreciated...

=======================
start ERB

<% scope.lookupvar('interfaces').split(",").each do |interface| %>
<% @int_ip = scope.lookupvar('ipaddress_'+interface) %>
<% @int_name = Resolv.new.getname @int_ip %>
...
<% end %>

end ERB
========================

@int_ip gets popluated and I can manipulate it as needed, but how do I properly pass it to 'Resolv.new.getname' to set the int_name string?

Denmat

unread,
Nov 25, 2015, 3:53:21 PM11/25/15
to puppet...@googlegroups.com
<%= @int_name = Resolv.new.getname @int_ip %>
??

Maybe this would work better as a custom fact though?

HTH
Den
--
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/6bf51a8e-eb7f-4bcd-ac77-2451bcbec5ce%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Denmat

unread,
Nov 25, 2015, 3:54:36 PM11/25/15
to puppet...@googlegroups.com
Sorry, ignore my suggestion. That won't work.

On 26 Nov 2015, at 06:57, Dayton Jones <jones....@gmail.com> wrote:

--

denmat

unread,
Nov 25, 2015, 4:10:55 PM11/25/15
to puppet...@googlegroups.com
Sorry, rushing around on trains. Try this:

irb(main):002:0> require 'resolv'
=> true
irb(main):003:0> Resolv.new.getname('127.0.0.1')
=> "localhost"

Dayton Jones

unread,
Nov 25, 2015, 4:21:25 PM11/25/15
to Puppet Users
Right, that works -- but I want to get the IP by using the scope.lookup var and not hardcode an IP in the template.  I know both the "scope.lookupvar('ipaddress_'+interface)" and "@int_name = Resolv.new.getname <ip>" works, but I'm struggling on how to send the IP gained from the lookupvar to the Resolv.new.getname function inside the template.. It should just be a syntax issue, but I'm new to ruby/erb  so I'm not sure the correct way to pass a generated string to a function within the same structure... 

denmat

unread,
Nov 25, 2015, 4:36:12 PM11/25/15
to puppet...@googlegroups.com
okay, this works. 

test.pp
class a {

  $inline = inline_template(
'<% scope.lookupvar("interfaces").split(",").each do |interface| %>
 <% @int_ip = scope.lookupvar("ipaddress_" + interface) %>
 <% @int_name = Resolv.new.getname @int_ip %>
 <%= "#{@int_ip} :::::::: #{@int_name}" %>
 <% end %>')

notify { $inline: }

}

include a


$ puppet apply test.pp

Notice: /Stage[main]/A/Notify[
 10.0.2.15 :::::::: fake.name.net
 172.28.128.5 :::::::: another.faker.net
 127.0.0.1 :::::::: localhost
 ]/

Sorry to mess you around before. Maybe it was your mixing of "'" and """?



Dayton Jones

unread,
Nov 25, 2015, 4:54:57 PM11/25/15
to Puppet Users
First, thanks for the help - I've been banging my head against the wall too much on this.

Unfortunately, it's still not working for me..  

I'm not using an inline template, I have an actual .erb file called out in my manifest - though I don't see why this would be any different.

my erb now looks like:
<% scope.lookupvar("interfaces").split(",").each do |interface| %>
<% @int_ip = scope.lookupvar("ipaddress_" + interface) %>
<% @int_name = Resolv.new.getname @int_ip %>
<%= "#{@int_ip} :::::::: #{@int_name}" %>
<% end %>
(thanks, didn't realize I'd mixed up the single/double quotes)

and here is the result when puppet runs and the class is applied:
  Filepath: /usr/lib/ruby/1.8/resolv.rb
  Line: 429
  Detail: cannot interpret as address: 

Is there a difference in using an inline template inside of the class defintion as opposed to using an erb file called as a resource?

denmat

unread,
Nov 25, 2015, 5:04:00 PM11/25/15
to puppet...@googlegroups.com
No, it is the same for the this test. You do need to have a resolvable IP address for each interface IP it finds or it will error. For example I had to add hostnames in my /etc/hosts file for my vagrant IPs (10.0.2.15, 172.28.128.5). 

That maybe the error you're seeing there, "cannot interpret as address".

--
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.

Dayton Jones

unread,
Nov 25, 2015, 5:11:12 PM11/25/15
to Puppet Users
Yep...the IP's are all resolvable, and if I hardcode one of them in to the Resolv... line, it works and writes to the file... so I have no idea why passing @int_ip to Resolv (instead of the hardcoded IP) fails...

Thanks again for the help...

Rodent of Unusual Size

unread,
Nov 25, 2015, 8:28:39 PM11/25/15
to puppet...@googlegroups.com
It's probably returning an object. Try resolving @int_ip.to_s

--
Ken Coar
Sanagendamgagwedweinini

Dayton Jones

unread,
Nov 30, 2015, 9:52:00 AM11/30/15
to Puppet Users
Ok... I switched tactics somewhat and have more or less what I wanted:

=== start ERB file ===
<% @interfaces.split(',').each do |int| if has_variable?("ipaddress_#{int}") -%>
<%= scope["ipaddress_#{int}"] -%> <%= Resolv.getname(scope["ipaddress_#{int}"]) -%>
<% end -%>
<% end -%>
=== end ERB file ===

this will give the the IP and associated FQDN of all the interfaces but I was wondering if the community could give me a little more help..

1) Once I have all the interfaces/names, how can I split the FQDN and get the short name (myhost vs myhost.domain.com)
2) Is there a way to order the output (put 127.0.0.1 at the top, etc)?

Dayton Jones

unread,
Nov 30, 2015, 3:42:16 PM11/30/15
to Puppet Users
Ah...nevermind, figured this out!

Sorting (well, reverse sorting so lo0 gets put first):
<% @interfaces.split(',').sort!{|x, y| y <=> x}.each do |int| if has_variable?("ipaddress_#{int}") -%>

Splitting:
<% fqdn =  Resolv.getname(scope["ipaddress_#{int}"]) -%>
<% name = (fqdn.split('.')) -%>
<%= scope["ipaddress_#{int}"] -%> <%= fqdn -%> <%= name.first %>
Reply all
Reply to author
Forward
0 new messages