Назначение атрибута задержки шеф-повара через пакет данных

#ruby #chef-infra #databags

#ruby #chef-инфра #пакеты данных

Вопрос:

Итак, у меня небольшая проблема. У меня есть зашифрованный пакет данных для хранения паролей 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, файл не существует, когда он присваивает переменную.

Вот вспомогательная функция, о которой идет речь, если кому-то интересно, она извлекает sAMAccountName из LDAP для назначения пользователей-администраторов на мой сервер 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
  

Ответ №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