Search code examples
puppet

Using puppet hash for epp templates


I have next code in erb template:

<% if @proxy_cache_path.is_a?(Hash) -%>
<% @proxy_cache_path.sort_by{|k,v| k}.each do |key,value| -%>
  proxy_cache_path        <%= key %> keys_zone=<%= value %> levels=<%= @proxy_cache_levels %> max_size=<%= @proxy_cache_max_size %> inactive=<%= @proxy_cache_inactive -%>
<% end -%>

How to porting it for epp template? Im find very low information for it. Please help.


Solution

  • Here's how you can do that:

    Showing an example class and how to declare both an ERB and EPP template for comparison:

    # manifests/init.pp
    class foo () {
      $proxy_cache_path = {
        'apples'  => 1,
        'bananas' => 2,
      }
      $proxy_cache_levels = 2
      $proxy_cache_max_size = 2
      $proxy_cache_inactive = 2
    
      # Showing use of ERB:
      file { '/foo':
        ensure  => file,
        content => template('foo/mytemplate.erb')
      }
    
      # Showing use of EPP, which requires an explicit parameters hash:
      file { '/bar':
        ensure  => file,
        content => epp('foo/mytemplate.epp', {
          'proxy_cache_path'     => $proxy_cache_path,
          'proxy_cache_levels'   => $proxy_cache_levels,
          'proxy_cache_max_size' => $proxy_cache_max_size,
          'proxy_cache_inactive' => $proxy_cache_inactive,
        }),
      }
    }
    

    Corrected* contents of the ERB file for comparison:

    # templates/mytemplate.erb     
    <% if @proxy_cache_path.is_a?(Hash) -%>
    <% @proxy_cache_path.sort_by{|k,v| k}.each do |key,value| -%>
      proxy_cache_path        <%= key %> keys_zone=<%= value %> levels=<%= @proxy_cache_levels %> max_size=<%= @proxy_cache_max_size %> inactive=<%= @proxy_cache_inactive -%>
    <% end -%>
    <% end -%>
    

    (*The code in the question is missing the closing end.)

    Contents of EPP file:

    # templates/mytemplate.epp 
    <%- | Hash[String, Integer] $proxy_cache_path, Integer $proxy_cache_levels, Integer $proxy_cache_max_size, Integer $proxy_cache_inactive | -%>
    <% include stdlib -%>
    <% $proxy_cache_path.keys.sort.each |$key| { -%>
      proxy_cache_path        <%= $key %> keys_zone=<%= $proxy_cache_path[$key] %> levels=<%= $proxy_cache_levels %> max_size=<%= $proxy_cache_max_size %> inactive=<%= $proxy_cache_inactive -%>
    <% } -%>
    

    Things to note about the EPP template file content:

    1) The parameters and their types are defined on the first line of the template. Use of this line is optional, but good practice.

    2) Since we declared the types on the first line, it is unnecessary and redundant to test if $proxy_cache_path is a Hash.

    3) We need to include stdlib in order to access the functions keys and sort. This is different to Ruby (ERB) where these methods are built-in to the language.

    4) I simplified the code relative to the Ruby (ERB) because Puppet (EPP) has no sort_by function - and actually there was no need to use it in the ERB either, which could be re-written as:

    <% if @proxy_cache_path.is_a?(Hash) -%>
    <%   @proxy_cache_path.sort.each do |key,value| -%>
      proxy_cache_path        <%= key %> keys_zone=<%= value %> levels=<%= @proxy_cache_levels %> max_size=<%= @proxy_cache_max_size %> inactive=<%= @proxy_cache_inactive -%>
    <%   end -%>
    <% end -%>
    

    Finally some tests:

    # spec/classes/test_spec.rb:
    require 'spec_helper'
    
    describe 'foo', :type => :class do
      it 'content in foo should be the same as in bar' do
        foo = catalogue.resource('file', '/foo').send(:parameters)[:content]
        bar = catalogue.resource('file', '/bar').send(:parameters)[:content]
        expect(foo).to eq bar
      end
    end
    

    And the tests pass.

    See docs here.