chef-infrarhelcentrify

Is there a way to iterate through node.run_state data in a Chef recipe?


Is there a way to iterate through node.run_state data? This is in a RHEL environment with Active Directory users. I have a ruby block that populates node.run_state. I have to have this run at converge time, because the overall cookbook will be used for build automation. On the very first run, the cookbook installs Centrify, then later needs to run adquery to gather user info for populating home directories with SSH keys.

On a chef-client run, I see this:

       Compiling Cookbooks...
       {}

Obviously, that's the puts running in compile time against an empty hash. At converge time, nothing happens in the loop with the 2 directory and 1 template resource.

Here is the relevant piece of the recipe:

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

Any ideas how to make this work?


Solution

  • My subconscious mind told me this morning to pull the path inside the directory resource, and THEN use lazy on it. So I have the working solution. node.run_state in the ruby_block, and lazy blocks around the requisite attributes in the subsequent resources that use node.run_state. Thanks for the feedback on this issue.