Присвоение атрибута Chef через сумку данных - PullRequest
1 голос
/ 21 марта 2019

Так что у меня есть немного рассола.У меня есть зашифрованный пакет данных для хранения паролей LDAP.В моем списке выполнения узлов один из моих рецептов устанавливает секретный ключ на мою клиентскую машину.В моей проблемной кулинарной книге у меня есть помощник (в / библиотеки), который извлекает данные из 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 для назначения пользователей-администраторов моему серверу шеф-повара.:

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

1 голос
/ 21 марта 2019

Оказывается, вы можете вызвать его внутри рубинового блока, просто используя реальный вызов 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
...