从哈希迭代构造可变字符串

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)连接一个字符串数组。