【问题标题】:No attribute precedence across different attribute sources?不同属性源之间没有属性优先级?
【发布时间】:2021-02-14 19:33:01
【问题描述】:

我知道attribute precedence,我也知道不同的attribute sources

我真的无法解释(很长一段时间以来)跨来源的优先级。在阅读attribute precedence 时,人们会假设,

  1. 属性文件:default[:mykey],将被覆盖
  2. recipe: node.default[:mykey] 来自配方,将被覆盖
  3. 配方:node.normal[:mykey] 来自配方

虽然 1. 和 2. 是正确的,但 3. 并不是因为它是“不同的来源”......我找不到一种基本上计算所有来源的一个属性的值的方法,我们称之为 @987654327 @

我明白了

# assume that default[:mykey]=1 in attributes/test.rb

# echo node.default[:mykey] would be 1

node.default[:mykey]=2
# echo node.default[:mykey] would be 2


# echo node.normal[:mykey] would be empty
# echo node[:mykey] would be empty

node.normal[:mykey] = 'foo'
# echo node.normal[:mykey] would 'foo;

在我的脑海中,我总是假设 node[:mykey] 会在未设置 node.normal[:mykey] 时回退到 node.default[:mykey],但显然情况并非如此。

这就是说,根本没有办法使用节点属性“覆盖默认值”?在我的食谱中,我必须决定是要使用“属性文件的默认源”还是“节点对象属性”......但我不能做类似的事情

只要没有节点对象属性覆盖它,就使用默认属性 - 没有getter,似乎不是设计计划的。

我当然可以在我的attribute/file.rb 中做到这一点

default[:mykey] = node.normal.dig(:mykey) unless node.normal.dig(:mykey).nil?

或者在我的食谱中

node.default[:mykey] = node.normal.dig(:mykey) unless node.normal.dig(:mykey).nil?

getting 它时,总是在我的recpie 中使用node.default[:mykey] - 但这闻起来像是缺少一个概念。

我的问题:

a) 我所描述的是设计吗?原因是,有替代路线/不同的概念吗?

b) 什么是正确的概念: “我想在attributes/myvals.rb 中为配方设置默认值,并希望使用节点属性使它们可以覆盖

【问题讨论】:

标签: chef-infra


【解决方案1】:

我正在添加一个答案,以分享我对 Chef 属性及其优先级的理解。 节点的属性最终被计算到节点对象 - node['attr']。这就是我们应该使用它而不是 node.defaultnode.normal 来有效地使用优先级。

正如你所提到的,有不同的属性类型

  • 默认
  • 正常
  • 覆盖

优先逻辑1:

这些类型中的每一种都有一个优先级在它们自己内部基于它们的定义位置(attributes/recipes/角色)。

优先逻辑2:

然后有default < normal < override的优先级(对于节点属性作为一个整体)。最后,override 定义的获胜。

所以

node.override['attr'] 的值不会改变node.default['attr'] 的值,但会改变最终的node['attr'] 值。

示例

为了更容易解释,让我们使用override 属性,因为它的优先级最低(优先级逻辑1)。

定义在attributes/:

override['attr'] = 'baz'

然后更改recipes/中的值:

node.default['attr'] = 2

node.normal['attr'] = 'foo'

log node.default['attr']
#=> 2

log node.normal['attr']
#=> 'foo'

log node['attr']
#=> 'baz'

所以我们可以看到,即使配方属性具有更高级别的优先级,它也不会影响节点属性,因为它是用override 定义的。在 Chef 角色或环境中定义的相同 override 属性将具有高于配方的优先级。

a) 我所描述的是设计吗,原因是,有替代路线/不同的概念吗?

这三种属性之间肯定是有限制的。如果我想更改 node.default 属性,则必须使用优先逻辑 1。

如果我想改变整体节点属性,可以是优先逻辑1和2的组合。

b) 正确的概念是什么:“我想在 attributes/myvals.rb 中为配方设置默认值,并希望使用节点属性使它们可以覆盖

为了简单起见,避免优先逻辑 1 和 2 的排列组合,我们可以在 attributes/ 中使用 default 属性,然后用 defaultnormaloverride 覆盖它们来自recipes/、环境、角色的属性。在下面的示例中,我一直使用default 属性。

定义在attributes/default.rb:

default['cookbook']['attrib'] = 'foo'

如果需要,从配方中覆盖它:

node.default['cookbook']['attrib'] = 'bar'

(此时属性的值为bar

或者,从角色或环境中覆盖它:

    "default_attributes": {
      "cookbook": {
        "attrib": "baz"
    }

最后的node['cookbook']['attrib'] 将是baz

更新:

Chef 属性的 older documentation 表示 node.normal 属性在 chef-client 运行开始时不会重置,因此是一种持久性。

普通属性永远不会重置。

【讨论】:

  • 我的测试证明node[:attr] 只不过是node.normal[:attr] 的缩写,因此绝不是node.default[:attr]node.normal[:attr] 的计算值——我很想拥有它,但是并非如此。没有吸气剂可以做到这一点:
  • 我知道在一个来源中使用优先级是可能的,我得到了你的最后一个例子——但这只能在纸上解决。问题是,当您使用 ktichen tests/chef zero/chef 服务器时,您通过节点调整属性(调整)它们。当你这样做时,这些属性在 node.normal 中,而不是在 node.default 中。因此,当代码使用 node.default[] 来获取值时,当你在那里调整它时,它不会是期望的结果。
  • 好吧,以前的文档中提到过 normal 属性没有被重置,但由于某种原因,最近的文档中没有。如果问题的主要焦点是normal 属性(没有出现),将在答案中添加该链接。
  • 对cmets系列感到抱歉。当您谈论覆盖时,我恰好注意到"default_attributes" 的细节。对我来说,使用厨房时这行不通。 attributesdefault_attributes 最终会出现在 node.normal
  • node.normal 属性不会在 Chef 运行开始时重置(在节点上持续存在)。不知道为什么最新的文档对此没有任何说明。
猜你喜欢
  • 1970-01-01
  • 2013-09-12
  • 1970-01-01
  • 2014-03-15
  • 1970-01-01
  • 1970-01-01
  • 2017-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多