Puppet Hiera 变量 - 在哈希中访问哈希

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

我有一个 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 的建议“将成员提升为顶级密钥”非常有效。我在第一次尝试时显然遇到了语法问题。谢谢!

puppet hiera
1个回答
2
投票

您的数据从清单代码到 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)

如果您没有指定默认值并且找不到请求的密钥,则目录构建将失败。

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