Mike D
Mike D

Reputation: 365

chef fill in xml values in template with hash in attribute

I have an array of hashes with values in my attributes/default.rb file in chef like what I have below:

default['server']['database'] = [
    {
        'name' => 'srv1'
        'user' => 'usr1'
        'pass' => 'pwd1'
    },
    {
        'name' => 'srv2'
        'user' => 'user2'
        'pass' => 'pwd3'
    }
]

Then, I've got a templates/default/server.xml.erb file with the following nested loop:

<% node['server']['database'].each do |hash| %>
    <% hash.each do |key, value| %>
        <%if key == "name" %>
            <Resource name="#{value}"
                <% else %>
                    #{key}="#{value}"
                <% end %>
            <% end %>
            />
        <% end %>

The expected result is:

<Resource name="srv1"
    user="usr1"
    pass="pwd1"
/>
<Resource name="srv2"
    user="usr2"
    pass="pwd2"
/>

What I end up getting with this is:

<Resource name="#{value}"
    #{key}="#{value}"
    #{key}="#{value}"
/>
<Resource name="#{value}"
    #{key}="#{value}"
    #{key}="#{value}"
/>

I've tried this in plain ruby and got it to print expected results. Not sure what I'm doing wrong here, but please, if you could shed some light I would appreciate it.

Upvotes: 0

Views: 1029

Answers (2)

spickermann
spickermann

Reputation: 107142

I would do something like this:

<% node['server']['database'].each do |hash| %>
  <Resource name="<%= hash['name'] %>"
            user="<%= hash['user'] %>"
            pass="<%= hash['pass'] %>" />
<% end %>

Or:

<% node['server']['database'].each do |hash| %>
  <Resource <%= hash.map { |k, v| "#{k}=#{v.inspect}" }.join(' ') %> />
<% end %>

Please note that the order of keys in a hash can be difficult to debug in corner cases. In contrast to your nested example do my examples do not rely on a specific key ordering.

Upvotes: 0

Alejandro C.
Alejandro C.

Reputation: 3801

You need to use erb <%= %>

<% node['server']['database'].each do |hash| %>
    <% hash.each do |key, value| %>
        <%if key == "name" %>
            <Resource name="<%= value %>"
                <% else %>
                    <%= "#{key}=\"#{value}\"" %>
                <% end %>
            <% end %>
            />
        <% end %>

Upvotes: 1

Related Questions