给出了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',
}
如何在连接哈希中为每个哈希添加默认值?
结果也可以是散列数组,但是与连接散列中的键相同的散列会很好。
答案 0 :(得分:4)
Puppet 4提供了许多可以在这里使用的迭代函数,但最清楚和最容易理解的解决方案可能是使用Puppet的map
和merge
函数({{3 }和ref):
$connections = {
'connection_name1' => {
'username' => 'user1',
'password' => 'pass1',
},
'connection_name2' => {
'username' => 'user2',
'password' => 'pass2',
},
}
$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)
然后检查一下:
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中添加Hashes,所以可以避免来自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}
。)
现在,如果您需要Hash of Hashes而不是Hashes数组,您可以通过reduce
函数实现此目的:
$merged = $connections.reduce({}) |$memo, $x| {
$memo + {$x[0] => merge($jdbc_default, $connections[$x[0]])}
}
或:
$merged = $connections.reduce({}) |$memo, $x| {
$memo + {$x[0] => $jdbc_default + $connections[$x[0]]}
}
这是如何运作的:
reduce
遍历来自哈希的每个[key, value]
对。起始值是作为参数传递给{}
的空哈希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 docs ref中给出的解释。
在相关的说明中,Henrik提到Puppet 5将包含一个新函数tree_each
,
可以遍历由Array,Hash和Object组成的结构 容器。它可以在深度或广度上进行迭代 是用于控制要包含的内容(容器和/或值)的选项 和/或包括树的根)。其他操作可以 通过链接到过滤器和映射的其他迭代函数来执行 操作
添加此功能的提示请求为here。