Есть ли способ перебрать данные node.run_state в рецепте Chef?

Есть ли способ перебрать данные node.run_state? Это в среде RHEL с пользователями Active Directory. У меня есть рубиновый блок, который заполняет node.run_state. Мне нужно запустить этот запуск во время схождения, потому что общая кулинарная книга будет использоваться для автоматизации сборки. При первом запуске поваренная книга устанавливает Centrify, а затем необходимо запустить adquery для сбора пользовательской информации для заполнения домашних каталогов ключами SSH.

При запуске chef-client я вижу следующее:

       Compiling Cookbooks...
       {}

Очевидно, что во время компиляции выполняется put для пустого хэша. Во время схождения ничего не происходит в цикле с 2 каталогами и 1 ресурсом шаблона.

Вот соответствующая часть рецепта:

ruby_block 'set uid, gid, and homedir for users' do
  block do
    base_attr['ssh_keys'].each do |user, pubkeys|
  # next unless Dir.exist?(homedir)
      node.run_state[user] = {}
      puts "Checking user #{user}..."
      if local_users.key?(user)
        node.run_state[user]['homedir'] = local_users[user]['homedir']
        node.run_state[user]['uid'] = local_users[user]['uid'].to_i
        node.run_state[user]['gid'] = local_users[user]['gid'].to_i
      elsif centrify_users.key?(user)
        node.run_state[user]['homedir'] = centrify_users[user]['homedir']
        node.run_state[user]['uid'] = centrify_users[user]['uid'].to_i
        node.run_state[user]['gid'] = centrify_users[user]['gid'].to_i
      else
        puts "user #{user} not found."
        # Place holder values.
        node.run_state[user]['homedir'] = "/tmp/#{user}"
        node.run_state[user]['uid'] = 0
        node.run_state[user]['gid'] = 0
      end
    end
  end
end
  # Dir.exist? guard should bypass compile-time error.
  # "name is a required property"
  # next unless Dir.exist?(homedir)
puts node.run_state
node.run_state.each do |user|
  directory node.run_state[user]['homedir'] do
    owner node.run_state[user]['uid']
    group node.run_state[user]['gid']
    mode '0700'
  end

  directory "#{node.run_state[user]['homedir']}/.ssh" do
    owner node.run_state[user]['uid']
    group node.run_state[user]['gid']
    mode '0700'
  end

  template "#{node.run_state[user]['homedir']}/.ssh/authorized_keys" do
    owner node.run_state[user]['uid']
    group node.run_state[user]['gid']
    mode '0600'
    source 'authorized_keys.erb'
    variables(
      sshkeys: base_attr['ssh_keys'][user]
    )
  end
end

Есть идеи, как это сделать?

3 ответа

Решение

Мое подсознание сказало мне сегодня утром вытащить путь внутри ресурса каталога, а ЗАТЕМ использовать его лениво. Итак, у меня есть рабочее решение. node.run_state в ruby_block и ленивые блоки вокруг необходимых атрибутов в последующих ресурсах, использующих node.run_state. Спасибо за отзыв по этой проблеме.

Добавьте ленивый блок {} вокруг node.run_state, где вы его используете. Итак, в вашем каталоге и шаблоне ресурса. lazy {} гарантирует, что ресурс оценивается на этапе выполнения запуска Chef Infra Client (в отличие от этапа компиляции). Вы можете узнать больше о ленивом блоке здесь

Как вы устанавливаете node.run_stateна этапе выполнения вам также необходимо прочитать его на этапе выполнения. В настоящее время вашnode.run_state.each пропускается, потому что, как вы правильно заметили, node.run_state пусто.

Итак, вам нужно переместить это node.run_state.eachисполнение в фазу исполнения. Одна из возможностей - создатьruby_block и переместите туда свой цикл, к сожалению, вы не можете использовать там методы ресурсов, как в рецепте, но вы можете использовать классы ресурсов напрямую:

ruby_block 'Create ssh authorized keys' do
  block do
    node.run_state.each do |user|
      d = Chef::Resource::Directory.new(node.run_state[user]['homedir'], run_context)
      d.owner node.run_state[user]['uid']
      d.group node.run_state[user]['gid']
      d.mode '0700'
      d.run_action :create

      d = Chef::Resource::Directory.new("#{node.run_state[user]['homedir']}/.ssh", run_context)
      d.owner node.run_state[user]['uid']
      d.group node.run_state[user]['gid']
      d.mode '0700'
      d.run_action :create

      t = Chef::Resource::Template.new("#{node.run_state[user]['homedir']}/.ssh/authorized_keys", run_context)
      t.owner node.run_state[user]['uid']
      t.group node.run_state[user]['gid']
      t.mode '0600'
      t.source 'authorized_keys.erb'
      t.variables(sshkeys: base_attr['ssh_keys'][user])
      t.run_action :create
    end
  end
end
Другие вопросы по тегам