1

我正在努力理解使用数据的分层方式,在我看来,使用 frontmatter 包含全局数据文件的普通 yaml 会更简单、更强大。

无论如何,我想完成这样的事情:

# global.yaml
collection1: &collection1
    foo: 1
collection2: &collection2
    bar: 2
collection3: &collection3
    baz: 3

# development_environment.yaml
collection:
    <<: *collection1
    <<: *collection2

# production_environment.yaml
collection:
    <<: *collection2
    <<: *collection3

本质上,这样我就可以在一个地方维护几个事物列表,然后根据环境以不同的方式组合它们。Hiera 有一个合并顶级键与深度合并的选项,但我找不到任何关于在层次结构中包含更高层数据的信息(对于我的特殊问题,如果有办法覆盖全局文件中的数据,而不是将其合并到更具体的文件中,但这似乎也不可能)。

我怎样才能做到这一点?我是否在所有不同的环境中手动复制基本数据?

我意识到我可以在 puppet 代码中放置一个环境案例语句来选择要包含哪些基本集合,但这打破了将数据保存在 hiera 中和代码在 puppet 中的关注点分离。如果我必须这样做,我不妨完全跳过 hiera 并将我的数据放入 puppet 模块中。

4

1 回答 1

1

您可以通过手动加载集合列表并对其进行迭代来完成:

# global.yaml
collection1:
    foo: 1
collection2:
    bar: 2
collection3:
    baz: 3

# development_environment.yaml
collection:
    - collection1
    - collection2

# production_environment.yaml
collection:
    - collection2
    - collection3

现在你可以写这样的东西:

# this variable will contain something like ['collection1','collection2']
$collections = hiera('collection')
# Now get all the corresponding values
$hashparts = $collections.map |$r| { $x = hiera($r); $x } # [{"baz"=>3}, {"bar"=>2}]
# Now we merge all the parts
$hash = $hashparts.reduce |$a,$b| { $x = merge($a,$b); $x } # {"baz"=>3, "bar"=>2}

这很丑陋,但应该做你所期望的。之所以讨论$x = function(); $x这里,是因为不幸的决定是所有lambda函数都可以在任何上下文(语句或值)中使用,所以我们在解析时不知道我们是否期望“块”的最后一个“令牌”成为陈述或表达。

于 2013-12-24T09:52:23.467 回答