将哈希附加到Puppet4中的一系列嵌套哈希

将哈希附加到Puppet4中的一系列嵌套哈希,puppet,Puppet,给定的是hieradata中的哈希: profile::jdbc::connections connection_name1: username: 'user1' password: 'pass1' connection_name2: username: 'user2' password: 'pass2' 以及puppet代码中的默认值哈希: $jdbc_default = { 'testWhileIdle' =&g

给定的是hieradata中的哈希:

profile::jdbc::connections
  connection_name1:
    username: 'user1'
    password: 'pass1'
  connection_name2:
    username: 'user2'
    password: 'pass2'
以及puppet代码中的默认值哈希:

$jdbc_default = {  
  'testWhileIdle'                => true,
  'testOnBorrow'                 => true,
  'testOnReturn'                 => false,
  'timeBetweenEvictionRunsMillis'=> '30000',
  'maxActive'                    => '20',
  'maxWait'                      => '10000',
  'initialSize'                  => '5',
  'removeAbandonedTimeout'       => '600',
  'removeAbandoned'              => false,
  'logAbandoned'                 => true,
  'minEvictableIdleTimeMillis'   => '30001',
}
如何将默认值添加到连接哈希中的每个哈希


结果也可以是一个散列数组,但是使用与连接散列中相同的键的散列就更好了。

Puppet 4提供了许多可以在这里使用的迭代函数,但最清晰、最容易理解的解决方案可能是使用Puppet的
map
merge
函数(和):

然后检查它:

Notice: Scope(Class[main]): [{connection_name1 => {username => user1, password => pass1, testWhileIdle => true, testOnBorrow => true, testOnReturn => false, timeBetweenEvictionRunsMillis => 30000, maxActive => 20, maxWait => 10000, initialSize => 5, removeAbandonedTimeout => 600, removeAbandoned => false, logAbandoned => true, minEvictableIdleTimeMillis => 30001}}, {connection_name2 => {username => user2, password => pass2, testWhileIdle => true, testOnBorrow => true, testOnReturn => false, timeBetweenEvictionRunsMillis => 30000, maxActive => 20, maxWait => 10000, initialSize => 5, removeAbandonedTimeout => 600, removeAbandoned => false, logAbandoned => true, minEvictableIdleTimeMillis => 30001}}]
Notice: Compiled catalog for alexs-macbook-pro.local in environment production in 0.07 seconds
Notice: Applied catalog in 0.01 seconds
但是,您提到您的数据来自Hiera。因此,您的实际代码如下所示:

class profile::jdbc (
  Hash[String, Hash[String, String]] $connections,
) {
  $jdbc_default = {
    'testWhileIdle'                => true,
    'testOnBorrow'                 => true,
    'testOnReturn'                 => false,
    'timeBetweenEvictionRunsMillis'=> '30000',
    'maxActive'                    => '20',
    'maxWait'                      => '10000',
    'initialSize'                  => '5',
    'removeAbandonedTimeout'       => '600',
    'removeAbandoned'              => false,
    'logAbandoned'                 => true,
    'minEvictableIdleTimeMillis'   => '30001',
  }

  $merged = $connections.map |$k,$v| {
    {$k => merge($jdbc_default, $v)}
  }

  notice($merged)
}
请注意,由于可以在Puppet中添加哈希,因此可以避免使用stdlib中的
merge
函数:

  $merged = $connections.map |$k,$v| {
    {$k => $jdbc_default + $v}
  }
(请注意,
{'a'=>1}+{'b'=>2}
返回
{'a'=>1,'b'=>2}
。如果两个键都在,则右侧获胜,即
{'a'=>1,'b'=>2}+{'a'=>2}
返回
{'a'=>2,'b'=>2}

现在,如果需要散列而不是散列数组,可以通过
reduce
函数实现:

  $merged = $connections.reduce({}) |$memo, $x| {
    $memo + {$x[0] => merge($jdbc_default, $connections[$x[0]])}
  }
或:

工作原理:

Notice: Scope(Class[Profile::Jdbc]): {connection_name1 => {username => user1, password => pass1, testWhileIdle => true, testOnBorrow => true, testOnReturn => false, timeBetweenEvictionRunsMillis => 30000, maxActive => 20, maxWait => 10000, initialSize => 5, removeAbandonedTimeout => 600, removeAbandoned => false, logAbandoned => true, minEvictableIdleTimeMillis => 30001}, connection_name2 => {username => user2, password => pass2, testWhileIdle => true, testOnBorrow => true, testOnReturn => false, timeBetweenEvictionRunsMillis => 30000, maxActive => 20, maxWait => 10000, initialSize => 5, removeAbandonedTimeout => 600, removeAbandoned => false, logAbandoned => true, minEvictableIdleTimeMillis => 30001}}
Notice: Compiled catalog for alexs-macbook-pro.local in environment production in 0.12 seconds
Notice: Applied catalog in 0.02 seconds
reduce
迭代散列中的每个
[键,值]
对。起始值是作为参数传递给
reduce
的空哈希
{}

在第一轮中,
$memo
被设置为
{}
,而
$x
被设置为第一对
[key,value]
。因此,密钥由
$x[0]
给出

在随后的几轮中,
$memo
保留Lambda中表达式在上一次迭代中返回的值,即
$memo+{$x[0]=>$connections[$x[0]]+$jdbc_default}

展示这些作品:

Notice: Scope(Class[Profile::Jdbc]): {connection_name1 => {username => user1, password => pass1, testWhileIdle => true, testOnBorrow => true, testOnReturn => false, timeBetweenEvictionRunsMillis => 30000, maxActive => 20, maxWait => 10000, initialSize => 5, removeAbandonedTimeout => 600, removeAbandoned => false, logAbandoned => true, minEvictableIdleTimeMillis => 30001}, connection_name2 => {username => user2, password => pass2, testWhileIdle => true, testOnBorrow => true, testOnReturn => false, timeBetweenEvictionRunsMillis => 30000, maxActive => 20, maxWait => 10000, initialSize => 5, removeAbandonedTimeout => 600, removeAbandoned => false, logAbandoned => true, minEvictableIdleTimeMillis => 30001}}
Notice: Compiled catalog for alexs-macbook-pro.local in environment production in 0.12 seconds
Notice: Applied catalog in 0.02 seconds
感谢Henrik Lindberg解释了
reduce

另请参见Ruby文档中给出的解释

在相关说明中,Henrik提到Puppet 5将包含一个新函数,
tree\u each

它可以迭代由数组、哈希和对象组成的结构 容器。它可以按深度或广度一阶迭代,然后 是用于控制要包含的内容(容器和/或值)的选项 和/或包括树的根)。其他操作可以是 通过链接到过滤器和映射的其他迭代函数来执行 行动


添加此功能的请求是。

这不是一个Ruby问题。这不是一个很好的问题,但yout可以从Ruby解决方案派生出一个puppet解决方案。但是这会让在档案中阅读此内容的人感到困惑,他们可能认为Ruby和puppet中的哈希是相同的。好的,我删除了Ruby标记。您还说您提供了一个哈希数组。这是不正确的;您的Hiera数据实际上是一个散列。您的解决方案创建了一个散列数组,但我们如何创建散列呢$连接。每个连接和内部合并都不会导致合并哈希。让我想一想。在Henrik Lindberg在Puppet Community Slack上向我解释后更新。Henrik代码的一点是,虽然很出色,但它通常在某个地方有一些小的拼写错误,所以一定要先测试它。无论如何,map确实返回一个数组,
reduce/with
是两个被忽略的lambda迭代器,它们确实可以做一些有趣的事情。我不确定是否有人的未经测试的代码在某个地方没有小的打字错误!无论如何,以上所有内容都经过了测试。
Notice: Scope(Class[Profile::Jdbc]): {connection_name1 => {username => user1, password => pass1, testWhileIdle => true, testOnBorrow => true, testOnReturn => false, timeBetweenEvictionRunsMillis => 30000, maxActive => 20, maxWait => 10000, initialSize => 5, removeAbandonedTimeout => 600, removeAbandoned => false, logAbandoned => true, minEvictableIdleTimeMillis => 30001}, connection_name2 => {username => user2, password => pass2, testWhileIdle => true, testOnBorrow => true, testOnReturn => false, timeBetweenEvictionRunsMillis => 30000, maxActive => 20, maxWait => 10000, initialSize => 5, removeAbandonedTimeout => 600, removeAbandoned => false, logAbandoned => true, minEvictableIdleTimeMillis => 30001}}
Notice: Compiled catalog for alexs-macbook-pro.local in environment production in 0.12 seconds
Notice: Applied catalog in 0.02 seconds