Puppet - 如果迭代散列时在 hiera 中不存在,则在清单中设置默认值

Puppet - set defaults in manifest if not present in hiera when iterating over hash

我正在遍历 hiera 哈希中的许多条目,并希望通过在清单中设置默认值(例如 ensuregroupsmanagehome 等),如果 hiera 中存在重复的 key/value 对,则覆盖默认值。

迄今为止,我尝试的所有操作都无法获得默认值。我知道我需要声明一个资源,但不确定。

我尝试在查找和其他方法中设置 "default_values_hash",但似乎没有任何东西将默认值传递给迭代和 --debug 输出

这是我的清单和 hiera 数据的(伪)示例。真诚地感谢任何指导。谢谢。

class test (
  Hash $testhash = lookup('test::hash', "merge" => 'hash'}),
){

  $testhash.each |$key, $value| {
    user { $key :
      ensure     => $value['ensure'],
      name       => $value['name'],
      password   => $value['password'],
      groups     => $value['groups'],
      managehome => $value['managehome'],
    }
  }
}
include class test

在希拉:

test::hash:

'fred':
  name:         fred
  password:     somepassword
  groups:       wheel
  managehome:   true

'mary':
  name:         mary
  password:     otherpassword

'john':
  name:         john
  password:     anotherpassword

'harry':

在清单中设置资源默认值(大写 User)不会传递到迭代中,但如果我将所有数据都保留在清单中它会传递(太多数据无法做到这一点)。

lookup 函数使您能够为散列本身建立默认值,但不能真正为散列中的键和值建立默认值。此外,在 Puppet 中使用 lookup 函数作为 class 参数值将被自动参数绑定所取代。换句话说,你的 lookup 函数在这种情况下什么都不做,因为 Puppet 更喜欢自动参数绑定而不是它,而你正在使用那些(这对于 lookup 与 Hiera 5 结合使用绝对是正确的,它显示您正在使用)。我个人觉得这种行为很烦人,但事实就是如此。编辑:别介意那个具体的推理;该参数称为 $testhash 而不是 $hash。如果该参数来自模块数据,那么 lookup 仍将被忽略,因为 Puppet 只允许模块数据的自动参数绑定。

令我惊讶的是资源默认值在这里对您不起作用。我不得不相信这要么是无意的,要么是当你走那条路时对他们实施了错误。

无论如何,这里有一个为您提供保证的方法。首先,我们实现每个表达式的默认属性:https://puppet.com/docs/puppet/5.3/lang_resources_advanced.html#per-expression-default-attributes

class test (
  Hash $testhash = lookup('test::hash', "merge" => 'hash'}),
){

  $testhash.each |String $key, Hash $value| {
    user { 
      default:
        ensure     => present,
        name       => 'username',
        password   => 'userpassword',
        groups     => ['usergroups'],
        managehome => false,
      ;
      $key:
        ensure     => $value['ensure'],
        name       => $value['name'],
        password   => $value['password'],
        groups     => $value['groups'],
        managehome => $value['managehome'],
      ;
    }
  }
}

这里仍然存在一个问题,即您正在为所有迭代的第二个块中的属性建立值。如果这些键值对未定义,Puppet 将出错而不是默认为另一个值。如果您首先为属性定义了值,我们需要指示 Puppet 只为属性建立值。值得庆幸的是,我们可以使用 * 属性来做到这一点:https://puppet.com/docs/puppet/5.3/lang_resources_advanced.html#setting-attributes-from-a-hash

class test (
  Hash $testhash = lookup('test::hash', "merge" => 'hash'}),
){

  $testhash.each |String $key, Hash $value| {
    user { 
      default:
        ensure     => present,
        name       => 'username',
        password   => 'userpassword',
        groups     => ['usergroups'],
        managehome => false,
      ;
      $key:
        * => $value,
      ;
    }
  }
}

这里的一个建议是使您的 lambda 迭代器变量 $key, $value 的命名更透明一些。另一个注意事项是要使 * 属性起作用,您的哈希键必须与 Puppet 属性名称相匹配。

更新的问题:在散列有一个键值 nil 的情况下,您可以在 lambda 迭代器参数中设置一个空散列作为键值的默认值。在该迭代期间,空哈希将替换 undef(Puppet nil)作为 $value。这将确保 * 运算符中不包含任何属性和值,并且所有默认值都适用。

class test (
  Hash $testhash = lookup('test::hash', "merge" => 'hash'}),
){

  $testhash.each |String $key, Hash $value = {}| {
    user { 
      default:
        ensure     => present,
        name       => 'username',
        password   => 'userpassword',
        groups     => ['usergroups'],
        managehome => false,
      ;
      $key:
        * => $value,
      ;
    }
  }
}