如何在puppet中有效地测试深层嵌套的数据值以采取行动?

问题描述 投票:1回答:1

鉴于数据结构

$local_users => {
  "user" => {
    "ssh" => {
      "config_entries" => [
        { "host" => "dummyhost",
          "lines" => [
            "ProxyCommand /usr/bin/corkscrew proxy.example.net 8080 %h %p"
          ]
        }
      ]
    }
  }
}

我已经整理了几个reduce调用,但不确定是否有更有效的方法来确定是否存在匹配某些条件的元素。如果发现匹配,我认为这至少会开始跳过后续项目,但是看起来有点笨拙做3次减少调用以提取嵌套这一点的内容并且想知道是否有更好的模式在puppet中提取数据以确定是否有什么东西是否需要。

$require_corkscrew = $local_users.reduce(false) |$memo, $user| {
  $memo or dig44($user[1], ['ssh', 'config_entries'], []).reduce |$memo, $entry| {
    $memo or $entry['lines'].reduce |$memo, $line| {
      $memo or $line.match(/ProxyCommand.*corkscrew/)
    }
  }
}

if $require_corkscrew {
  $corkscrew_ensure = 'present'
} else {
  $corkscrew_ensure = 'absent'
}

package {'corkscrew':
  ensure => $corkscrew_ensure,
}
hash puppet reduce
1个回答
2
投票

想知道在木偶中是否有更好的模式来提取数据以确定是否需要某些东西。

围绕数据结构的方式有一些可能的改进:

  • 考虑避免这种深度嵌套
  • 考虑避免哈希中的可选键,尤其是在中间层
  • 考虑最小化哈希数组的使用,因为除了迭代它们之外,通常没有办法处理这些哈希。
  • 同意使用具有不受控制的键空间的哈希
  • 使用Puppet数据类型来记录和强制执行您选择的数据结构

至于计算模式,

  • 在分析集合以计算布尔属性时,请考虑使用any()函数,因为这可以实现真正的短路。
  • 不要忽视用于分析哈希的keys()values()函数,因为它们至少可以在处理复杂数据结构时降低代码的认知负荷。
  • 考虑使用直接操作集合的函数和函数变体,而不是迭代集合并在元素上使用标量函数。例如,match()在数组上以有用的方式工作。

这是一种我比原始代码更好的方法。它使用嵌套的any()计算和match函数的数组版本,而不是嵌套的缩减。它依赖于undef是假的,并使用dig()then()来处理可选的哈希键。总的来说,我认为它更清晰,重量更轻一些,但是你可以做很多事情来实现分析复杂数据的简单代码。

$require_corkscrew = $local_users.values.any |$user| {
  $user.dig('ssh', 'config_entries').then |$entries| {
    $entries.any |$entry| {
      $entry.dig('lines').then |$lines| {
        ! empty($lines.match(/ProxyCommand.*corkscrew/))
      }
    }
  }
}

有可能用围绕标量match()的另一个any()替换阵列式match(),但是虽然它有可能在元素方面稍早地短路,但必须权衡(可能)效率减少函数调用的数量,以及在函数内部而不是在DSL级别进行迭代的改进。

© www.soinside.com 2019 - 2024. All rights reserved.