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?
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.