Chef:如何测试 Chef Server 上没有存储节点属性?

Chef: How to test that a node attribute is not stored on Chef Server?

经过一些 chef 零运行(将节点状态保存为本地 .json 文件)后,我很沮丧地在节点文件中找到了这个: ... "ssmtp": { "auth_username": "secret user name", "auth_password": "even-more-secret password" } 在 Chef Server 上运行相同的操作会将节点数据保存在服务器上。这当然是个问题,我必须更换凭据、修改食谱等。我仍在调查最初导致此问题的原因,但我的问题是:

如何为配方创建 rspec/chefspec 测试以验证特定节点属性未永久保存在节点的 .json 文件或 Chef 服务器上?

我想将此添加到我的规格中,以确保它不再发生。

结语

这里的重要教训是,任何进入任何节点属性的东西最终都会保存在节点对象表示中。

关键在 Chef 文档的注释中,"A normal attribute is a setting that persists in the node object. A normal attribute has a higher attribute precedence than a default attribute." 将问题分解为测试属性是否为 "normal" 属性。

深入研究 Chef::Node 和 Chef::Node::Attribute class 代码,我发现您可以调用 node.attributes.normal 来获取普通属性。所以这个简洁的测试正确地失败了,表明我的秘密信息将被持久存储在节点对象中!

it 'does not have a normal attribute node[ssmtp][auth_password]' do expect(subject.node.attributes.normal['ssmtp'].keys).to_not include 'auth_password' end

导致这个像样的错误消息:

Failure/Error: expect(subject.node.attributes.normal['ssmtp'].keys).to_not include 'auth_password' expected ["auth_username", "auth_password"] not to include "auth_password"

如果未设置特定值,您也可以对此进行测试,但我认为测试键不存在更切题。

不知何故,我总能从这里简单地提出一个问题到 post 来获得新的见解。就这样吧。

Chef Server 将保存所有属性,即使它们是正常的、默认的或其他优先级别。您可以使用 node.run_state 来解决这个问题,它可用于 "stash transient data during a chef-client run."

您可以在 elkstack community cookbook, most notably in the _lumberjack_secrets.rb 食谱中看到这一点。

node.run_state 正在设置:

if <CONDITION ABBREVIATED>
  node.run_state['lumberjack_decoded_key'] = Base64.decode64(lumberjack_secrets['key'])
  ....
end

node.run_state 正在使用:

lumberjack_keypair = node.run_state['lumberjack_decoded_key'] && node.run_state['lumberjack_decoded_certificate']

至于测试,我自己还没有 "tested" 这个,但是你会测试以确保未设置该属性,如下所示:

it 'should not have secret attributes set' do
  node = chef_run.node
  expect (node['my_secret']).to be_nil
end