Miki Shapiro
2011-Apr-19 05:42 UTC
[Puppet Users] "Listing" the keys in a hash as an array
Hi all I''ve got node definition on the site with server interface, bonding and TCP/IP configurations inscribed in a per-node [ hash + accompanying array-of-interface-names ] (e.g. $array = [ ''eth0'', ''eth1'' ] $hash = { eth0 => { ipaddress => 1.2.3.4, ... } eth1 => { ipaddress => 5.6.7.8, ... } } What I have right now works, but is clunky and could probably be written better. My 2 questions are: 1. Can I somehow get a list of keys from the hash itself (a list that will behave like an array that I can feed into a defined type) instead of "manually" defining $array for this purpose? 2. If you look further down inside in this post, the code (taken from inside the base class) does this: [a] gets the hash with the configuration passed in as a global variable [b] copies the hash elements into local variables (because a local variable can be double-quoted around, and behave nicely even if it wasn''t set and is blank, whereas a hash element cannot) [c] invokes the interface-configuration defined type with the local variables as parameters. A very messy roundabout way of doing things. Can anyone suggest an easier way (tho still ultimately has to call base::network-common::interface) In the node file I have a configuration block that looks like this: $netiflist = [ ''eth0'' ] $netifcfg = { eth0 => { ipaddress => "1.2.3.4", netmask => "255.255.255.0", gateway => "1.2.3.1", defaultgateway => "yes" }, } include base Then in a subclass of base I have: class base-subclass { # Iterate for all the interfaces that need to be configured: if $netiflist { base::network-common::dointerfaces {[$netiflist]:}} } # the actual defined type: define base::network-common::dointerfaces() { # copy hash elements into local variables: $myipaddress = $netifcfg[$name][ipaddress] $mynetmask = $netifcfg[$name][netmask] $mygateway = $netifcfg[$name][gateway] $mydefaultgateway = $netifcfg[$name][defaultgateway] $myhwaddress = $netifcfg[$name][hwaddress] $myroutes = $netifcfg[$name][routes] $myensure = $netifcfg[$name][ensure] # and finally use the double-quoted local variables to call the interface defined type: base::network-common::interface { $name: ipaddress => "$myipaddress", netmask => "$mynetmask", gateway => "$mygateway", defaultgateway => "$mydefaultgateway", hwaddress => "$myhwaddress", routes => "$myroutes", ensure => "$myensure" } } ... -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Ohad Levy
2011-Apr-19 07:09 UTC
Re: [Puppet Users] "Listing" the keys in a hash as an array
On Tue, Apr 19, 2011 at 8:42 AM, Miki Shapiro <mikishapiro@gmail.com> wrote:> clunky and could probably be written better. > > My 2 questions are: > 1. Can I somehow get a list of keys from the hash itself (a list that will > behave like an array that I can feed into a defined type) instead of > "manually" defining $array for this purpose? > > fuzzy workaround:$keys = inline_template("<%= hash.keys %>") -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Felix Frank
2011-Apr-19 09:55 UTC
Re: [Puppet Users] "Listing" the keys in a hash as an array
On 04/19/2011 09:09 AM, Ohad Levy wrote:> > > On Tue, Apr 19, 2011 at 8:42 AM, Miki Shapiro <mikishapiro@gmail.com > <mailto:mikishapiro@gmail.com>> wrote: > > clunky and could probably be written better. > > My 2 questions are: > 1. Can I somehow get a list of keys from the hash itself (a list > that will behave like an array that I can feed into a defined type) > instead of "manually" defining $array for this purpose? > > fuzzy workaround: > > $keys = inline_template("<%= hash.keys %>")Ah, but won''t that imply a "to_s" on the resulting array of keys? You may want to join the keys (say using ",") and split by that same comma in the DSL. Pseudocode: $keys = split(",", inline_template("<%= hash.keys.join('','') %>")) Cheers, Felix -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Miki Shapiro
2011-Apr-20 01:26 UTC
Re: [Puppet Users] "Listing" the keys in a hash as an array
I must be doing something wrong... As suggested by Ohad: Manifest says: $keys = inline_template("<%= netifcfg.keys %>") exec { "/bin/echo keys are $keys and netifcfg is $netifcfg": logoutput => true } Output says: notice: /Stage[main]/Base::Network-common/Exec[/bin/echo keys are bond0bond1 and netifcfg is bond0ipaddress10.15.69.177netmask255.255.254.0defaultgatewayyesgateway10.15.68.1bond1ipadderss1.2.3.4netmask255.255.254.0gateway1.2.3.1]/returns: is notrun, should be 0 (noop) (DOES work with 2 element tho) As suggested by Felix: Manifest says: $keys = split(",", inline_template("<%= netifcfg.keys.join('','') %>")) exec { "/bin/echo keys are $keys and netifcfg is $netifcfg": logoutput => true } Output says: notice: /Stage[main]/Base::Network-common/Exec[/bin/echo keys are , and netifcfg is bond0ipaddress10.15.69.177netmask255.255.254.0defaultgatewayyesgateway10.15.68.1bond1ipadderss1.2.3.4netmask255.255.254.0gateway1.2.3.1]/returns: keys are , and netifcfg is bond0ipaddress10.15.69.177netmask255.255.254.0defaultgatewayyesgateway10.15.68.1bond1ipadderss1.2.3.4netmask255.255.254.0gateway1.2.3.1 -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Miki Shapiro
2011-Apr-20 01:28 UTC
Re: [Puppet Users] "Listing" the keys in a hash as an array
I must be doing something wrong... As suggested by Ohad: Manifest says: $keys = inline_template("<%= netifcfg.keys %>") exec { "/bin/echo keys are $keys and netifcfg is $netifcfg": logoutput => true } Output says: notice: /Stage[main]/Base::Network-common/Exec[/bin/echo keys are bond0bond1 and netifcfg is bond0ipaddress10.15.69.177netmask255.255.254.0defaultgatewayyesgateway10.15.68.1bond1ipadderss1.2.3.4netmask255.255.254.0gateway1.2.3.1]/returns: is notrun, should be 0 (noop) (DOES work with 1 element tho) As suggested by Felix: Manifest says: $keys = split(",", inline_template("<%= netifcfg.keys.join('','') %>")) exec { "/bin/echo keys are $keys and netifcfg is $netifcfg": logoutput => true } Output says: notice: /Stage[main]/Base::Network-common/Exec[/bin/echo keys are , and netifcfg is bond0ipaddress10.15.69.177netmask255.255.254.0defaultgatewayyesgateway10.15.68.1bond1ipadderss1.2.3.4netmask255.255.254.0gateway1.2.3.1]/returns: keys are , and netifcfg is bond0ipaddress10.15.69.177netmask255.255.254.0defaultgatewayyesgateway10.15.68.1bond1ipadderss1.2.3.4netmask255.255.254.0gateway1.2.3.1 (Split doesn''t seem to work). -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Nigel Kersten
2011-Apr-20 03:08 UTC
Re: [Puppet Users] "Listing" the keys in a hash as an array
On Tue, Apr 19, 2011 at 6:28 PM, Miki Shapiro <mikishapiro@gmail.com> wrote:> $keys = split(",", inline_template("<%= netifcfg.keys.join('','') %>"))Honestly, I''d put this together as a Puppet function at this point, as that''s just resulting in something rather unmaintainable. http://docs.puppetlabs.com/guides/custom_functions.html I''ll have a quick stab at it in a second. -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Nigel Kersten
2011-Apr-20 04:14 UTC
Re: [Puppet Users] "Listing" the keys in a hash as an array
On Tue, Apr 19, 2011 at 8:08 PM, Nigel Kersten <nigel@puppetlabs.com> wrote:> On Tue, Apr 19, 2011 at 6:28 PM, Miki Shapiro <mikishapiro@gmail.com> wrote: > >> $keys = split(",", inline_template("<%= netifcfg.keys.join('','') %>")) > > Honestly, I''d put this together as a Puppet function at this point, as > that''s just resulting in something rather unmaintainable. > > http://docs.puppetlabs.com/guides/custom_functions.html > > I''ll have a quick stab at it in a second. >module Puppet::Parser::Functions newfunction(:hash_keys, :type => :rvalue) do |args| unless args[0].is_a?(Hash) Puppet.warning "hash_keys takes one argument, the input hash" nil else args[0].keys end end end save to lib/puppet/parser/functions/ in a module. -- Nigel Kersten Product, Puppet Labs @nigelkersten -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Miki Shapiro
2011-Apr-20 04:46 UTC
Re: [Puppet Users] "Listing" the keys in a hash as an array
Thanks guys I ended up breaking up what Felix&Ohad suggested into two lines to make it work: $keycsv= inline_template("<%= netifcfg.keys.join('','') %>") $keys = split ($keycsv,'','') Yep, it''s a ''hack'' (sorry, Ohad, workaround ;)), but it saves me having to add puppet functions into SVN... (which is quite involved in my case because we support a big site with versioned modules and a custom module-versioning mechanism that at present does not cover custom functions (a long, painful topic in its own right) so I need to contain this code in the module using it - making this workaround perfect. Should we perhaps nudge the above function into mainstream puppet? Being able to list the keys in a hash is quite a crucial capability to have. -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Ohad Levy
2011-Apr-20 05:54 UTC
Re: [Puppet Users] "Listing" the keys in a hash as an array
On Wed, Apr 20, 2011 at 7:46 AM, Miki Shapiro <mikishapiro@gmail.com> wrote:> Thanks guys > > I ended up breaking up what Felix&Ohad suggested into two lines to make it > work: > $keycsv= inline_template("<%= netifcfg.keys.join('','') %>") > $keys = split ($keycsv,'','') > Yep, it''s a ''hack'' (sorry, Ohad, workaround ;)), but it saves me having to > add puppet functions into SVN... > (which is quite involved in my case because we support a big site with > versioned modules and a custom module-versioning mechanism that at present > does not cover custom functions (a long, painful topic in its own right) so > I need to contain this code in the module using it - making this workaround > perfect. > > when having this issue, one can use a plain template not to clutter themanifest, not sure if it apply 100% in this case, but for most things a template == function... for example $var = template ("x.erb") x.erb--> <%netifcfg.keys.collect |key| key.reverse! key.upcase! key += "woot" File.open("/tmp/#{key}" end %> Ohad Should we perhaps nudge the above function into mainstream puppet? Being> able to list the keys in a hash is quite a crucial capability to have. > > -- > You received this message because you are subscribed to the Google Groups > "Puppet Users" group. > To post to this group, send email to puppet-users@googlegroups.com. > To unsubscribe from this group, send email to > puppet-users+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/puppet-users?hl=en. >-- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Felix Frank
2011-Apr-20 07:17 UTC
Re: [Puppet Users] "Listing" the keys in a hash as an array
> module Puppet::Parser::Functions > newfunction(:hash_keys, :type => :rvalue) do |args| > unless args[0].is_a?(Hash) > Puppet.warning "hash_keys takes one argument, the input hash" > nil > else > args[0].keys > end > end > end > > > save to lib/puppet/parser/functions/ in a module.I think this should be mainline *hint, hint* ;-) Cheers, Felix -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Thomas Bellman
2011-Apr-20 11:16 UTC
Re: [Puppet Users] "Listing" the keys in a hash as an array
On 2011-04-20 03:28, Miki Shapiro wrote:> As suggested by Felix: > Manifest says: > $keys = split(",", inline_template("<%= netifcfg.keys.join('','') > %>")) > exec { "/bin/echo keys are $keys and netifcfg is $netifcfg": > logoutput => true } > > Output says: > notice: /Stage[main]/Base::Network-common/Exec[/bin/echo keys are , and netifcfg is bond0ipaddress10.15.69.177netmask255.255.254.0defaultgatewayyesgateway10.15.68.1bond1ipadderss1.2.3.4netmask255.255.254.0gateway1.2.3.1]/returns: keys are , and netifcfg is bond0ipaddress10.15.69.177netmask255.255.254.0defaultgatewayyesgateway10.15.68.1bond1ipadderss1.2.3.4netmask255.255.254.0gateway1.2.3.1 > (Split doesn''t seem to work).You have two errors. The first is that the split() function takes its parameters in the other order from what Felix wrote. The string to split on goes second, so you should do: $keys = split(inline_template("<%= netifcfg.keys.join('','') %>"), ",") The second error is that when you expand $keys within a string literal, the elements of the array will be joined with nothing inbetween. Try this instead: notify { $keys: ; } Or perhaps: notify { netifcfg-keys: message => shellquote("Keys", "are:", $keys); } Those will show you better the real value of $keys. /Bellman -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Nigel Kersten
2011-Apr-20 15:23 UTC
Re: [Puppet Users] "Listing" the keys in a hash as an array
On Wed, Apr 20, 2011 at 12:17 AM, Felix Frank <felix.frank@alumni.tu-berlin.de> wrote:>> module Puppet::Parser::Functions >> newfunction(:hash_keys, :type => :rvalue) do |args| >> unless args[0].is_a?(Hash) >> Puppet.warning "hash_keys takes one argument, the input hash" >> nil >> else >> args[0].keys >> end >> end >> end >> >> >> save to lib/puppet/parser/functions/ in a module. > > I think this should be mainline *hint, hint* ;-)I might take this as the first step towards collecting a bunch of these in a module, and if there''s enough interest in it during the life of 2.7.x, we''ll merge some of them into Telly, the next feature release. -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Jon Jackson
2012-Jun-26 00:38 UTC
Re: [Puppet Users] "Listing" the keys in a hash as an array
I''m going to add to this thread because this function (keys - Returns the keys of a hash as an array ) and other similar utility functions are now just a download away in the puppet stdlib http://forge.puppetlabs.com/puppetlabs/stdlib (this page currently lists a few of the functions) -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/oAfO6aTmOWkJ. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.