Chef通过数据包延迟属性赋值
Chef delay attribute assignment via data bag
所以我有一点泡菜。
我有一个加密的数据包来存储 LDAP 密码。在我的节点 运行 列表中,我的一个食谱将密钥安装到我的客户端机器上。
在我有问题的食谱中,我有一个助手(在 /libraries 中)从 AD 中提取数据(使用 LDAP)。问题是,我找不到在初始编译阶段后延迟节点属性分配的方法。
以这行代码为例:
node.override['yp_chefserver']['osAdminUser'] = node['yp_chefserver']['osAdminUser'] + get_sam("#{data_bag_item('yp_chefserver', 'ldap', IO.read('/etc/chef/secret/yp_chefserver'))['ldap_password']}")
我试图通过添加由我的辅助函数 "get_sam" 返回的数组来覆盖属性,其中 returns 一个数组,但它需要 运行 在编译阶段之后,因为文件“/etc/chef/secret/yp_chefserver”在我的 运行 列表收敛之前不存在。
所以我的问题是:有没有办法在执行阶段通过 data_bag_items 分配节点属性?
我尝试过的一些事情:
ruby_block 'attribution' do
only_if { File.exist?('/etc/chef/secret/yp_chefserver')}
block do
node.override['yp_chefserver']['osAdminUser'] = node['yp_chefserver']['osAdminUser'] + get_sam("#{data_bag_item('yp_chefserver', 'ldap', IO.read('/etc/chef/secret/yp_chefserver'))['ldap_password']}")
Chef::Log.warn("content of osAdminUser : #{node['yp_chefserver']['osAdminUser']}")
end
end
这不起作用,因为自定义资源 ruby_block 没有方法 "data_bag_item"。我试过在我的 "chef_server" 自定义资源中使用惰性属性,但同样的问题。
我也试过直接在我的辅助模块中完成属性,但是由于辅助模块在exec阶段之前编译,所以当它分配变量时文件不存在。
如果有人想知道,这是有问题的辅助函数,它从 LDAP 中提取 SamAccountName 以将管理员用户分配到我的 Chef 服务器。 :
module YpChefserver
module LDAP
require 'net-ldap'
@ldap
def get_ldap(ldap_password)
if @ldap.nil?
@ldap = Net::LDAP.new :host => "ADSERVER",
:port => 389,
:auth => {
:method => :simple,
:username => "CN=USERNAME,OU=East Service Accounts,OU=System Accounts,DC=ad,DC=ypg,DC=com",
:password => "#{ldap_password}"
}
end
@ldap
end
def get_ldap_users(ldap_password)
filter = Net::LDAP::Filter.eq("cn", "DevOps")
treebase = "dc=ad, dc=ypg, dc=com"
get_ldap(ldap_password).search(:base => treebase, :filter => filter) do |entry|
#puts "DN: #{entry.dn}"
entry.each do |attribute, values|
return values if attribute == :member
end
end
end
def get_sam(ldap_password)
samacc = Array.new
get_ldap_users(ldap_password).entries.each{ |elem|
y = elem.to_s.split(/[,=]/)
filter = Net::LDAP::Filter.eq("cn", y[1])
treebase = "OU=Support Users and Groups,OU=CGI Support,DC=ad,DC=ypg,DC=com"
get_ldap(ldap_password).search(:base => treebase, :filter => filter, :attributes => "SamAccountName") do |entry|
samacc << entry.samaccountname
end
}
return samacc
end
end
end
事实证明,您实际上可以在 ruby 块中调用它,只需使用实际的 Chef 调用而不是资源名称,如下所示:
ruby_block 'attributes' do
only_if {File.exist?('/etc/chef/secret/yp_chefserver')}
block do
dtbg = Chef::EncryptedDataBagItem.load('yp_chefserver','ldap',"IO.read('/etc/chef/secret/yp_chefserver')")
end
end
留在这里给可能需要的人
编辑:
这是使用上面提到的代码从 AD 中提取帐户的最终函数,使用加密数据包提供密码,然后将这些结果传递给我的节点属性,所有这些都在执行阶段:
ruby_block 'attributes' do
extend YpChefserver::LDAP
only_if {File.exist?('/etc/chef/secret/yp_chefserver')}
block do
# Chef::Config[:encrypted_data_bag_secret] = '/etc/chef/secret/yp_chefserver'
dtbg = Chef::EncryptedDataBagItem.load('yp_chefserver','ldap')
node.override['yp_chefserver']['ldap_pw'] = dtbg['ldap_password']
userarray = Array.new
userarray.push("#{node['yp_chefserver']['osAdminUser']}")
get_sam("#{node['yp_chefserver']['ldap_pw']}").each { |i| userarray.push(i[0]) }
node.override['yp_chefserver']['authorized_users'] = userarray
node.override['yp_chefserver']['local_admin_pw'] = dtbg['local_admin_pw']
end
end
所以我有一点泡菜。 我有一个加密的数据包来存储 LDAP 密码。在我的节点 运行 列表中,我的一个食谱将密钥安装到我的客户端机器上。 在我有问题的食谱中,我有一个助手(在 /libraries 中)从 AD 中提取数据(使用 LDAP)。问题是,我找不到在初始编译阶段后延迟节点属性分配的方法。
以这行代码为例:
node.override['yp_chefserver']['osAdminUser'] = node['yp_chefserver']['osAdminUser'] + get_sam("#{data_bag_item('yp_chefserver', 'ldap', IO.read('/etc/chef/secret/yp_chefserver'))['ldap_password']}")
我试图通过添加由我的辅助函数 "get_sam" 返回的数组来覆盖属性,其中 returns 一个数组,但它需要 运行 在编译阶段之后,因为文件“/etc/chef/secret/yp_chefserver”在我的 运行 列表收敛之前不存在。
所以我的问题是:有没有办法在执行阶段通过 data_bag_items 分配节点属性?
我尝试过的一些事情:
ruby_block 'attribution' do
only_if { File.exist?('/etc/chef/secret/yp_chefserver')}
block do
node.override['yp_chefserver']['osAdminUser'] = node['yp_chefserver']['osAdminUser'] + get_sam("#{data_bag_item('yp_chefserver', 'ldap', IO.read('/etc/chef/secret/yp_chefserver'))['ldap_password']}")
Chef::Log.warn("content of osAdminUser : #{node['yp_chefserver']['osAdminUser']}")
end
end
这不起作用,因为自定义资源 ruby_block 没有方法 "data_bag_item"。我试过在我的 "chef_server" 自定义资源中使用惰性属性,但同样的问题。
我也试过直接在我的辅助模块中完成属性,但是由于辅助模块在exec阶段之前编译,所以当它分配变量时文件不存在。
如果有人想知道,这是有问题的辅助函数,它从 LDAP 中提取 SamAccountName 以将管理员用户分配到我的 Chef 服务器。 :
module YpChefserver
module LDAP
require 'net-ldap'
@ldap
def get_ldap(ldap_password)
if @ldap.nil?
@ldap = Net::LDAP.new :host => "ADSERVER",
:port => 389,
:auth => {
:method => :simple,
:username => "CN=USERNAME,OU=East Service Accounts,OU=System Accounts,DC=ad,DC=ypg,DC=com",
:password => "#{ldap_password}"
}
end
@ldap
end
def get_ldap_users(ldap_password)
filter = Net::LDAP::Filter.eq("cn", "DevOps")
treebase = "dc=ad, dc=ypg, dc=com"
get_ldap(ldap_password).search(:base => treebase, :filter => filter) do |entry|
#puts "DN: #{entry.dn}"
entry.each do |attribute, values|
return values if attribute == :member
end
end
end
def get_sam(ldap_password)
samacc = Array.new
get_ldap_users(ldap_password).entries.each{ |elem|
y = elem.to_s.split(/[,=]/)
filter = Net::LDAP::Filter.eq("cn", y[1])
treebase = "OU=Support Users and Groups,OU=CGI Support,DC=ad,DC=ypg,DC=com"
get_ldap(ldap_password).search(:base => treebase, :filter => filter, :attributes => "SamAccountName") do |entry|
samacc << entry.samaccountname
end
}
return samacc
end
end
end
事实证明,您实际上可以在 ruby 块中调用它,只需使用实际的 Chef 调用而不是资源名称,如下所示:
ruby_block 'attributes' do
only_if {File.exist?('/etc/chef/secret/yp_chefserver')}
block do
dtbg = Chef::EncryptedDataBagItem.load('yp_chefserver','ldap',"IO.read('/etc/chef/secret/yp_chefserver')")
end
end
留在这里给可能需要的人
编辑: 这是使用上面提到的代码从 AD 中提取帐户的最终函数,使用加密数据包提供密码,然后将这些结果传递给我的节点属性,所有这些都在执行阶段:
ruby_block 'attributes' do
extend YpChefserver::LDAP
only_if {File.exist?('/etc/chef/secret/yp_chefserver')}
block do
# Chef::Config[:encrypted_data_bag_secret] = '/etc/chef/secret/yp_chefserver'
dtbg = Chef::EncryptedDataBagItem.load('yp_chefserver','ldap')
node.override['yp_chefserver']['ldap_pw'] = dtbg['ldap_password']
userarray = Array.new
userarray.push("#{node['yp_chefserver']['osAdminUser']}")
get_sam("#{node['yp_chefserver']['ldap_pw']}").each { |i| userarray.push(i[0]) }
node.override['yp_chefserver']['authorized_users'] = userarray
node.override['yp_chefserver']['local_admin_pw'] = dtbg['local_admin_pw']
end
end