Puppet Hiera在更具体的文件中访问全局对象

时间:2013-12-23 19:15:49

标签: puppet hiera

我很难理解使用数据的hiera方式,在我看来,使用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中的关注点和木偶代码的分离。如果我必须这样做,我可以完全跳过hiera并将我的数据放入puppet模块中。

1 个答案:

答案 0 :(得分: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 函数都可以在任何上下文(语句或值)中使用,所以我们在解析时不知道是否我们希望“块”的最后一个“标记”是一个语句或一个表达式。