Reputation: 809
I have a list of IP address along with me. In front of those IP I have a username. What I am trying to do is make Chef read the file having IP and username and once it encounter the IP, it should create a user of that name. But when I do I get a user but the name of the user comes out to be a number.
Here is my recipe
File.open("/tmp/users.txt", "r") do |file|
file.readlines.each_with_index do |ip,user|
if ip = node[:ipaddress]
user ip[user] do
action :create
supports :manage_home => true
comment 'Test User'
home '/home/ip[user]'
shell '/bin/bash'
password 'password'
end
end
end
my users.txt file
231.27.59.232, test1
272.27.59.15, tes2
985.54.25.22, test3
Now when I run the recipe this is what I get
Recipe: repo_update::users
* cookbook_file[/tmp/users.txt] action create (up to date)
* user[1] action create
- create user 1
* user[7] action create
- create user 7
* user[2] action create
- create user 2
Please tell me what is wrong here.
Upvotes: 0
Views: 1305
Reputation: 4223
The problem is this line:
user ip[user] do
You are calling the []
method on the ip
string. Furthermore, you're going to get a name collision between the resource user
and the block variable. Finally, you are giving each user the home of '/home/ip[user]'. You need to put the string in "
's and wrap the variable in #{
and }
Try this:
File.open("/tmp/users.txt", "r") do |file|
file.readlines.each do |line|
entries = line.split(',')
ip = entries[0].strip
username = entries[1].strip
if ip = node[:ipaddress]
user username do
action :create
supports :manage_home => true
comment 'Test User'
home "/home/#{username}"
shell '/bin/bash'
password 'password'
end
end
end
Also, reading this all from a file is a very non cheffy thing to do. Either use a databag or a hash stored in an environment variable, which also saves you from needing to loop at all:
userhash = node['my_users'][node['ipadddress']]
user userhash['username']
action :create
supports :manage_home => true
comment 'test user'
home userhash['home'] || "/home/#{userhash['username']"
shell userhash['shell'] || '/bin/bash'
password userhash['password'] || 'password'
end
Upvotes: 0
Reputation: 15784
Lots of problem here... The answer of Tejay is the way to go, I'll just try to explain why your code don't work and how to fix it so it could be of some use later :)
File.open("/tmp/users.txt", "r") do |file|
file.readlines.each_with_index do |ip,user|
puts "values are #{ip} and #{user}"
end
end
Gives:
values are 231.27.59.232, test1
and 0
values are 272.27.59.15, tes2
and 1
values are 985.54.25.22, test3
and 2
each_with_index
won't split magically your line into two part, it will just assign the last parameter the actual index in the iteration.
A fixed version of your code would be:
File.open("/tmp/users.txt", "r") do |file|
file.readlines.each do |line| # just iterate and get line
ip,myuser=line.gsub("\n",'').split(',') # set ip and myuser variable with values comma separated, using myuser to avoid conflict with the resource name. Using gsub to remove traling carriage return in user name
if ip == node[:ipaddress] # test equality, a single = will assign ip a value and always be true.
user myuser do # create the user using the variable, no need to interpolate here
action :create
supports :manage_home => true
comment 'Test User'
home "/home/#{myuser}" # use interpolation here inside double quotes (won't work in single quotes)
shell '/bin/bash'
password 'password'
end
end
end
end
Upvotes: 1