通过数据包分配厨师延迟属性

时间:2019-03-21 16:47:01

标签: ruby chef databags

所以我有点泡菜。 我有一个加密的数据袋来存储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”返回的数组来覆盖属性,该函数返回一个数组,但是由于文件“ / 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以便将管理员用户分配给我的厨师服务器。 :

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

1 个答案:

答案 0 :(得分:1)

事实证明,您实际上可以在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