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
经过一些 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