我有一个 Puppet 类,它使用这种格式为以后的深度合并创建一个变量。
$config = {
'foo' => {
'fvar1' => 'fvar1-string',
'fvar2' => 'fvar2-string',
},
'bar' => {
'bvar1' => 'bvar1-string',
'bvar2' => 'bvar2-string',
},
}
我正在努力重构代码,以便在 hiera 中而不是在代码本身中管理数据。在这样做时,我宁愿只需要为每个散列(
foo
和 bar
)进行一次 hiera 查找。这可能吗?
这是我到目前为止尝试过的:
希拉数据:
role::fb:
foo:
fvar1: 'fvar1-string'
fvar2: 'fvar2-string'
bar:
bvar1: 'bvar1-string'
bvar2: 'bvar2-string'
代码:
class test {
$config = {
'foo' => hiera('role::fb::foo', undef),
'bar' => hiera('role::fb::bar', undef),
}
notify { "Config: ${config}": }
}
include test
输出:
[root@puppetclient1 ~]# puppet agent -t
Info: Using configured environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Retrieving locales
Info: Caching catalog for puppetclient1.home.arpa
Info: Applying configuration version '1684256670'
Notice: Config: {foo => , bar => }
Notice: /Stage[main]/Test/Notify[Config: {foo => , bar => }]/message: defined 'message' as 'Config: {foo => , bar => }'
Notice: Applied catalog in 0.01 seconds
[root@puppetclient1 ~]#
我想要的输出是
foo
和bar
包含hiera数据的内容,分别包括fvar{1,2}
和bvar{1,2}
编辑: John Bollinger 在下面的回答极大地帮助了我的理解。我已经能够在 Puppet 5 中重新创建解决方案。但是,我应该早点提到这一点,目前我需要与 Puppet 3 兼容。针对 3.8.7 版本运行代码时,遇到语法错误,编译失败。
更新的代码(此处使用 hiera() 实现版本兼容性):
class fb {
$config = {
'foo' => hiera('role::fb', undef)['foo'],
'bar' => hiera('role::fb', undef)['bar'],
}
notify { "Config: ${config}": }
}
include fb
使用 Puppet 3.8.7 时出错:
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Syntax error at '['; expected ']' at /etc/puppet/environments/production/modules/A/manifests/fb.pp:3 on node puppetclient1.home.arpa
Warning: Not using cache on failed catalog
Error: Could not retrieve catalog; skipping run
最终编辑:
我说得太快了。 John 的建议“将成员提升为顶级密钥”非常有效。我在第一次尝试时显然遇到了语法问题。谢谢!
您的数据从清单代码到 Hiera 的最自然映射是这样的:
module_name::class_name::config:
foo:
fvar1: 'fvar1-string'
fvar2: 'fvar2-string'
bar:
bvar1: 'bvar1-string'
bvar2: 'bvar2-string'
最自然的retrieve方式是通过自动数据绑定到类参数:
class module_name::class_name (
$config
) {
// ... $config data automatically looked up in Hiera ...
}
自动数据绑定依赖于具有形式
module_name::class_name::param_name
.的Hiera密钥
但是,如果您愿意,您仍然可以执行显式查找:
class module_name::class_name {
// lookup() is now the preferred data-lookup function; hiera() is deprecated
$config = lookup('module_name::class_name::config')
}
可以对任何键执行显式查找,因此如果这是您的目标案例,那么您不限于
module_name::class_name::specific_name
形式的键。
如果您一次只想要一个或另一个成员散列,那么您可以检索整个配置,然后从中选择想要的值:
$foo_config = lookup('module_name::class_name::config')['foo']
或者,如果您想要单独查找
foo
和 bar
成员的能力,并且可以失去一次查找整个配置的能力,那么您可以简单地将成员提升为顶级键:
role::fb::foo:
fvar1: 'fvar1-string'
fvar2: 'fvar2-string'
role::fb::bar:
bvar1: 'bvar1-string'
bvar2: 'bvar2-string'
附加说明:根据@MattSchuchard 的评论,如果您希望
lookup()
提供默认值,甚至undef
,当找不到密钥时,您需要在lookup()
调用中指定。这与遗留 hiera()
函数的行为不同。有不止一种方法可以做到这一点,但如果您想像 undef
那样默认为 hiera()
,那么最简单的方法是将三个可选参数添加到 lookup()
调用中,最后一个是想要的默认值:
$config = lookup('module_name::class_name::config', Hash, 'first', undef)
如果您没有指定默认值并且找不到请求的密钥,则目录构建将失败。