将散列附加到 Puppet4 中的一系列嵌套散列
Append a hash to a series of nested hashes in Puppet4
给出的是 hieradata 中哈希的哈希:
profile::jdbc::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',
}
如何将默认值添加到连接哈希中的每个哈希?
结果也可以是散列数组,但最好是与连接散列中的键相同的散列。
Puppet 4 提供了许多可以在这里使用的迭代函数,但最清晰和最容易理解的解决方案可能是使用 Puppet 的 map
和 merge
函数(ref and 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}
returns {'a' => 1, 'b' => 2}
。如果两个键都在,则右侧获胜,即 {'a' => 1, 'b' => 2} + {'a' => 2}
returns {'a' => 2, 'b' => 2}
.)
现在,如果您需要哈希的哈希,而不是哈希数组,您可以通过 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 文档中给出的解释 here。
在相关说明中,Henrik 提到 Puppet 5 将包含一个新功能,tree_each
,
that can iterate over a structure consisting of Array, Hash and Object
containers. It can iterate in depth or breadth first order and there
are options for controling what to include (containers and/or values
and/or include the root of the tree). Other operations can be
performed by chaining to other iterative functions for filter and map
operations.
添加此功能的拉取请求是 here。
给出的是 hieradata 中哈希的哈希:
profile::jdbc::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',
}
如何将默认值添加到连接哈希中的每个哈希?
结果也可以是散列数组,但最好是与连接散列中的键相同的散列。
Puppet 4 提供了许多可以在这里使用的迭代函数,但最清晰和最容易理解的解决方案可能是使用 Puppet 的 map
和 merge
函数(ref and 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}
returns {'a' => 1, 'b' => 2}
。如果两个键都在,则右侧获胜,即 {'a' => 1, 'b' => 2} + {'a' => 2}
returns {'a' => 2, 'b' => 2}
.)
现在,如果您需要哈希的哈希,而不是哈希数组,您可以通过 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 文档中给出的解释 here。
在相关说明中,Henrik 提到 Puppet 5 将包含一个新功能,tree_each
,
that can iterate over a structure consisting of Array, Hash and Object containers. It can iterate in depth or breadth first order and there are options for controling what to include (containers and/or values and/or include the root of the tree). Other operations can be performed by chaining to other iterative functions for filter and map operations.
添加此功能的拉取请求是 here。