erb sudoers遍历数组的哈希值

时间:2016-10-31 11:53:37

标签: ruby puppet erb

我尝试通过puppet动态生成sudoers文件。在这里我有这样的hieradata:

---
  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

这样的erb模板:

<% @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 -%> 

我迭代cmnd_aliases和runas_aliases的方法不起作用。如果这些数组存在于sudoparameter hash中,我怎样才能生成一个逗号分隔列表,如果Cmnd_Aliases和Runas_Aliases?

干杯

基督教

2 个答案:

答案 0 :(得分:1)

要解决这个问题,我将每个块包装成:

<% 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 -%>

但是现在cmnd_alias.map无法按预期工作。我收到以下错误。

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

要解决此问题,我将密钥和值保存到不同的变量,并将连接直接应用于值。

<% 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 -%>

答案 1 :(得分:1)

如果Hash中的某些值为nil,则可以使用以下语法:

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

a || b语法有助于避免未定义的方法错误:

{:a => :b} || {}
#=> {:a => :b}

nil || {}
#=> {}

最后,如果cmnd_alias_value是一个数组,它应该写成复数:cmnd_alias_values。这不是必须的,但它可能会使您的代码更容易理解。