6

I am starting to develop in puppet (ruby) and I have the following problem.

I have the current hash that I want to iterate in a template file.

$database_profile_hash = 
{
  cpu   => {
    governor => ondemand
    energy_perf_bias => powersave
  }
  sysctl => {
    kernel.sched.min.granularity.ns => 10000000
    kernel.sched.wakeup.granularity.ns => 15000000
    kernel.msgmnb => 6
  }
  ...
}

And my current template is the following:

<% @database_profile_array.each do |arrayValue| %>
[<%= arrayValue %>]
<% database_profile_hash[arrayValue].each do |key,value| %>
<%= key %> <%= value %>
<% end %>
<% end %>

To iterate the array I am trying to use an array to store all the first level names and then use it to iterate the hash:

$database_profile_array = [cpu,sysctl,...]

But I am not able to make it work and I am looking for an exit like this:

[cpu]
governor=ondemand
energy_perf_bias=powersave

[sysctl]
vm.laptop_mode=5
vm.dirty_writeback_centisecs=1500
kernel.nmi_watchdog=0

What I am doing wrong in the template? There is a way to pass the content of the variable "arrayValue" to iterate the hash?

Thanks a lot in advance...

Daniel Cano
  • 95
  • 1
  • 2
  • 4

1 Answers1

14

Your template looks fine for the most part, but few things here. First off, you may not be able to use periods for your variable names, but more importantly, don't forget commas to separate key/value pairs:

$database_profile_array = [cpu,sysctl]
$database_profile_hash =
{
  cpu   => {
    governor => ondemand,
    energy_perf_bias => powersave,
  },
  sysctl => {
    kernel_sched_min_granularity_ns => 10000000,
    kernel_sched_wakeup_granularity_ns => 15000000,
    kernel_msgmnb => 6,
  }
}

In your template, you're forgetting the equal signs, and you also might want to omit new line characters for each iteration by using -%>:

<% @database_profile_array.each do |arrayValue| -%>
[<%= arrayValue %>]
<% database_profile_hash[arrayValue].each do |key,value| -%>
<%= key %>=<%= value %>
<% end %>
<% end -%>

 

Edit: OP, note the comments others have left. If the iteration sequence doesn't matter, you don't need the separate array $database_profile_array to reference the keys, rather you can iterate the hash directly:

<% @database_profile_hash.each do |key, hash| -%>
[<%= key %>]
<% hash.each do |key,value| -%>
<%= key %>=<%= value %>
<% end %>
<% end -%>

Also, the -%> erb puppet trim tag is documented here.

drewyupdrew
  • 1,549
  • 1
  • 11
  • 16
  • 1
    Note also that you don't necessarily need a separate array of the top-level keys. You can iterate the top-level hash to get those keys and their associated hashes (values). The separate array is useful only if you want to specify the exact sequence in which the sections are presented or if you want to select an externally-directed subset of the top-level keys. – John Bollinger May 31 '16 at 17:33
  • 1
    RE answer: you may want to mention `-%>` is because Puppet ERB trim mode is `-`. RE comment: he can also automatically generate that array with `keys` from `puppetlabs-stdlib`. – Matthew Schuchard May 31 '16 at 17:48
  • @JohnBollinger Very good point, edited my answer to include your tip. Thanks! – drewyupdrew May 31 '16 at 18:36
  • @MattSchuchard, yes, he can generate the array of keys via stdlib's `keys()` function. That might be useful if he wanted sometimes to be selective and sometimes all-inclusive. If he wants *always* to be all-inclusive, however, then it is better to get rid of the array altogether. – John Bollinger May 31 '16 at 21:06
  • @JohnBollinger yes I know, and he probably knows too, but I mentioned that in case he would be interested in a dynamic method for generating the array he was manually hardcoding, so he knows that ability exists for the future – Matthew Schuchard May 31 '16 at 21:37