Search code examples
rubypuppeterb

erb sudoers iterate over hash of arrays


I try to generate sudoers file dynamically via puppet. Here i have hieradata like this:

---
  sudoparameters:
    cmnd_aliases:
      CMND_ALIAS_A:
        - /path/to/command_a *
        - /path/to/command_b *
      CMND_ALIAS_B:
        - /path/to/command_c
        - /path/to/command_d *
    runas_aliases:
      RUNAS_ALIAS_A:
        - runas_user_a, runas_user_b
      RUNAS_ALIAS_B:
        - runas_user_a, runas_user_c
    defaults:
      - user!authenticate
      - user!systlog
    commands:
      - user ALL=(root) NOPASSWD:/usr/sbin/puppetd --test agent --server=*
      - user ALL=(root) NOPASSWD:/usr/bin/lsof -a *
      - user ALL=(RUNAS_ALIAS_A) NOPASSWD: CMND_ALIAS_A

And an erb template like this:

<% @sudoparameters['cmnd_aliases'].each do |cmnd_alias| -%> 
Cmnd_Alias <%= cmnd_alias %> <%= cmnd_alias.map { |path| path.join(', ') } %>
<% end -%> 

<% @sudoparameters['runas_aliases'].each do |runas_alias| -%> 
Runas_Aliases <%= runas_alias %> <%= runas_alias.map { |path| path.join(', ') } %>
<% end -%> 

<% @sudoparameters['defaults'].each do |default| -%> 
Defaults:<%= default %>
<% end -%> 

<% @sudoparameters['commands'].each do |command| -%> 
<%= command %>
<% end -%> 

My approach to iterate over the cmnd_aliases and runas_aliases doesn't work. How can i accomplish it to generate a comma seperatet list für Cmnd_Aliases and Runas_Aliases if these arrays exists in sudoparameter hash?

Cheers

Christian


Solution

  • To solve the issue i wrapped the each blocks into:

    <% if (@sudoparameters['cmnd_aliases'] != nil) then -%>
      <% @sudoparameters['cmnd_aliases'].each do |cmnd_alias| -%>
      Cmnd_Alias <%= cmnd_alias %> <%= cmnd_alias.map { |path| path.join(', ') } %>
      <% end -%>
    
    <% end -%>
    

    But for now the cmnd_alias.mapdoesn't work as expected. i get the following error.

    Detail: undefined method `join' for "CMND_ALIAS_A":String
    

    To solve that i save key and value to different vars and apply the join directly to the values.

    <% if (@sudoparameters['cmnd_aliases'] != nil) then -%> 
    <% @sudoparameters['cmnd_aliases'].each do |cmnd_alias_key, cmnd_alias_value| -%> 
    Cmnd_Alias <%= cmnd_alias_key %> <%= cmnd_alias_value.join(', ') %>
    <% end -%> 
    
    <% end -%> 
    <% if (@sudoparameters['runas_aliases'] != nil) then -%> 
    <% @sudoparameters['runas_aliases'].each do |runas_alias_key, runas_alias_value| -%> 
    Runas_Aliases <%= runas_alias_key %> <%= runas_alias_value.join(', ') %>
    <% end -%> 
    
    <% end -%> 
    <% if (@sudoparameters['defaults'] != nil) then -%> 
    <% @sudoparameters['defaults'].each do |default| -%> 
    Defaults:<%= default %>
    <% end -%> 
    
    <% end -%> 
    <% @sudoparameters['commands'].each do |command| -%> 
    <%= command %>
    <% end -%>