1
votes

I have a hash, built from yaml via stdlib, which includes arrays within the hash. Here is a sample of the yaml:

datacenter1:
  propertyA:
    - associatedItem
  cage1:
    serviceA:
    - server1
    - server2
    serviceB:
    - server10
    backupCage:
      cage2
  cage2:
   serviceA:
    - server3
    - server4
    - server5
   serviceB:
    - server11
   backupCage:
     cage1
datacenter2:
  cage1:
    serviceA:
    - server20
    - server21
datacenter3:
  propertyZ:
    serviceD:
    - server200
    - server201

in this case I need to get a list of servers which offer a service within a particular datacenter in erb. Ultimately this is just going to need to output in text with some arbitrary data added for an conf file. I'm trying to get all servers providing serviceA for a given datacenter, in this example for datacenter1:

thiscommand blahblah server1 
thiscommand blahblah server2
thiscommand blahblah server3
thiscommand blahblah server4
thiscommand blahblah server5

I use this map extensively for a variety of things, but this is the first case in which i can't just set a variable in puppet and iterate over that as a single array in erb.

EDIT1: This data comes from puppet but i am trying to use it in erb via template().

EDIT2: Note this code would never run against datacenter3, since this code is specific to datacenters which run serviceA.

Edit3: This is the form that ended up working: <% @hash['datacenter1'].values.each do |v| %>

 <%- if v.is_a?(Hash) and v.has_key?('serviceA') -%> 

   <% v['serviceA'].each do |myservice| %>

         thiscommand blah blah <%= myservice -%> 

     <% end %>

  <% end %>
1

1 Answers

1
votes

It is unclear if you are trying to do this within Puppet or Ruby, so here is how to do it within both.

Puppet:

$hash['datacenter1'].each |$dc_key, $dc_nest_hash| {
  if $dc_nest_hash['serviceA'] {
    $dc_nest_hash['serviceA'].each |$serviceA_element| {
      notify { "thiscommand blahblah ${serviceA_element}": }
    }
  }
}

https://docs.puppet.com/puppet/4.9/function.html#each

Ruby in ERB before passed through Puppet template function (comments are elucidation for this answer; remove before actually forming template):

<% @hash['datacenter1'].each do |_, dc_nest_hash| -%>
  # contents of each datacenter1 nested hash in dc_nest_hash and iterate over each hash
  <%- if dc_nest_hash.key?('serviceA') -%>
    <%- dc_nest_hash['serviceA'].each do |serviceA_element| -%>
      # lookup serviceA key in each dc_nest_hash and iterate over elements
      thiscommand blahblah <%= serviceA_element %>
    <%- end -%>
  <%- end -%>>
<% end -%>

https://ruby-doc.org/core-2.1.1/Object.html#method-i-enum_for

http://ruby-doc.org/core-2.1.0/Array.html#method-i-each