从哈希迭代构造可变字符串
Construct mutable string from hash iteration
几天来我一直卡在下面的木偶代码上,你能帮帮我吗?
在 hiera 中我有以下结构:
my_list::servers:
server1.subnet.env.com:
id: 0
server2.subnet.env.com:
id: 1
server3.subnet.env.com:
id: 2
server4.subnet.env.com:
id: 3
其中各种server1..n
(n=>2) 是特定环境中服务器的FQDN。 ID 始终按顺序排列,但从 0 开始。
我需要创建一个字符串,其中包含逗号分隔的字符串列表,如 broker-${id}-check
,其中 id 不同于我是 运行 傀儡的服务器的 FQDN,例如如果我是 运行 server2.subnet.env.com
上的脚本,则字符串应该是 broker-0-check,broker-2-check,broker-3-check
。如果我在 server1.subnet.env.com
上 运行 它将是 broker-1-check,broker-2-check,broker-3-check
,等等。
我最后的尝试是:
$servers_list = hiera('my_list::servers', {"${::fqdn}" => {'id' => 0 } })
$list_broker=''
$servers_list.each |$key, $value| {
if $key != $::fqdn {
$list_broker="${list_broker},broker-${value['id']}-check"
}
}
notify {"******* ${list_broker}": }
但 list_broker
仍然是空的,然后我将不得不修复前导逗号。
有更好的方法吗?
我正在使用 Puppet 4。
问题在于,尽管 Puppet 具有迭代功能,但它不允许重新分配变量 (ref)。
因此,Puppet 具有许多函数式编程功能,可让您无需重新分配变量即可解决此类问题。
这有效(Puppet < 5.5),其中 join()
来自 stdlib:
$list_broker = join(
$servers_list
.filter |$key, $value| { $key != $::fqdn }
.map |$key, $value| { "broker-${value['id']}-check" },
','
)
或者在 Puppet >= 5.5(如评论中所建议的)中,内置了 join 命令,join 也可以链接起来:
$list_broker = $servers_list
.filter |$key, $value| { $key != $::fqdn }
.map |$key, $value| { "broker-${value['id']}-check" }
.join(',')
如果您更喜欢更多步骤:
$filtered = $servers_list.filter |$key, $value| { $key != $::fqdn }
$mapped = $filtered.map |$key, $value| { "broker-${value['id']}-check" }
$list_broker = join($mapped, ',')
解释:
filter
函数根据某些条件从数组或散列中选择元素。
map
函数对 Array 或 Hash 的所有元素和 returns 转换数据的 Array 执行转换。
join
函数(在 Puppet 5.5 之前来自 stdlib)连接一个字符串数组。
几天来我一直卡在下面的木偶代码上,你能帮帮我吗?
在 hiera 中我有以下结构:
my_list::servers:
server1.subnet.env.com:
id: 0
server2.subnet.env.com:
id: 1
server3.subnet.env.com:
id: 2
server4.subnet.env.com:
id: 3
其中各种server1..n
(n=>2) 是特定环境中服务器的FQDN。 ID 始终按顺序排列,但从 0 开始。
我需要创建一个字符串,其中包含逗号分隔的字符串列表,如 broker-${id}-check
,其中 id 不同于我是 运行 傀儡的服务器的 FQDN,例如如果我是 运行 server2.subnet.env.com
上的脚本,则字符串应该是 broker-0-check,broker-2-check,broker-3-check
。如果我在 server1.subnet.env.com
上 运行 它将是 broker-1-check,broker-2-check,broker-3-check
,等等。
我最后的尝试是:
$servers_list = hiera('my_list::servers', {"${::fqdn}" => {'id' => 0 } })
$list_broker=''
$servers_list.each |$key, $value| {
if $key != $::fqdn {
$list_broker="${list_broker},broker-${value['id']}-check"
}
}
notify {"******* ${list_broker}": }
但 list_broker
仍然是空的,然后我将不得不修复前导逗号。
有更好的方法吗?
我正在使用 Puppet 4。
问题在于,尽管 Puppet 具有迭代功能,但它不允许重新分配变量 (ref)。
因此,Puppet 具有许多函数式编程功能,可让您无需重新分配变量即可解决此类问题。
这有效(Puppet < 5.5),其中 join()
来自 stdlib:
$list_broker = join(
$servers_list
.filter |$key, $value| { $key != $::fqdn }
.map |$key, $value| { "broker-${value['id']}-check" },
','
)
或者在 Puppet >= 5.5(如评论中所建议的)中,内置了 join 命令,join 也可以链接起来:
$list_broker = $servers_list
.filter |$key, $value| { $key != $::fqdn }
.map |$key, $value| { "broker-${value['id']}-check" }
.join(',')
如果您更喜欢更多步骤:
$filtered = $servers_list.filter |$key, $value| { $key != $::fqdn }
$mapped = $filtered.map |$key, $value| { "broker-${value['id']}-check" }
$list_broker = join($mapped, ',')
解释:
filter
函数根据某些条件从数组或散列中选择元素。map
函数对 Array 或 Hash 的所有元素和 returns 转换数据的 Array 执行转换。join
函数(在 Puppet 5.5 之前来自 stdlib)连接一个字符串数组。