I await Luke''s node settings implementation with interest. At the
moment however, I have this sort of ugliness:
$site = $hostname ? {
fred => "opsera",
barney => "bedrock",
default => "unknown site",
...
}
So I''ve knocked up this little function to use CSV files instead. Now
I can just do:
$site = lookup_csv("sites.csv",$hostname,"site")
where sites.csv is:
hostname,site,ip
fred,opsera,192.168.1.1
barney,bedrock,10.0.0.1
This is much nicer IMO - in particular I only need to change a .csv
file. That file is likely to be exported from a spreadsheet which
makes life even easier (later versions could just read the spreadsheet).
Beware: this is _definitely_ v0.1 - I''ve only done a couple of days of
Ruby so it''s more proof of concept than a final version - it''s
also
only been tested for 5mins. Even so I thought it might be useful.
I thought about adding it to the wiki, but thought I should check here
first.
# lookup items from a CSV file
# v0.1 - 2007/06/06
# Adrian Bridgett, Opsera Ltd.
# file in the format of:
# colname1, colname2, colname3,... (must be first line)
# key1, value2, value3,...
# key2, value4, value5
#
# lookup_csv(filename,key1,colname3) will then return value3
#
# TODO:
# proper CSV parsing (e.g. quoting)
# regexp on the value?
# return a supplied default if row not found?
# add Excel and Openoffice support
module Puppet::Parser::Functions
newfunction(:lookup_csv, :type => :rvalue) do |args|
filename = args[0]
key = args[1]
column = args[2]
File.open(filename) do |file|
# find which column we are after
colnum = file.gets.chomp.split(/,/).index(column)
return nil if colnum == nil
# find row
file.each_line { |line|
row = line.chomp.split(/,/)
if (row[0] == key)
return row[colnum]
end
}
end
# no match found
return nil
end
end
Adrian
On Wed, Jun 6, 2007 at 10:02:05 +0100 (+0100), wrote:> Beware: this is _definitely_ v0.1 - I''ve only done a couple of days of > Ruby so it''s more proof of concept than a final version - it''s also > only been tested for 5mins. Even so I thought it might be useful.And obviously not very well. v0.2 actually works (no guarantee, the quality of coding can go down as well as up, yada yada) ... # lookup items from a CSV file # v0.2 - 2007/06/06 # Adrian Bridgett, Opsera Ltd. # file in the format of: # colname1, colname2, colname3,... (must be first line) # key1, value2, value3,... # key2, value4, value5 # # lookup_csv(filename,key1,colname3) will then return value3 # # TODO: # proper CSV parsing (e.g. quoting) # regexp on the value? # return a supplied default if row not found? # add Excel and Openoffice support module Puppet::Parser::Functions newfunction(:lookup_csv, :type => :rvalue) do |args| filename = args[0] key = args[1] column = args[2] rc = nil File.open(filename) do |file| # find which column we are after colnum = file.gets.chomp.split(/,/).index(column) break if colnum == nil # find row file.each_line { |line| row = line.chomp.split(/,/) if (row[0] == key) rc = row[colnum] break end } end return rc end end Adrian
v0.3 (probably last one for a little while)
This uses FasterCSV to do parsing and supports arrays in the CSV when
they are specified like this: "[foo,bar]".
# lookup items from a CSV file
# v0.3 - 2007/06/06
# Adrian Bridgett, Opsera Ltd.
# file in the format of:
# colname1, colname2, colname3,... (must be first line)
# key1, value2, value3,...
# key2, value4, value5
#
# lookup_csv(filename,key1,colname3) will then return value3
#
# TODO:
# regexp on the key?
# return a supplied default if row not found?
# add Excel and Openoffice support
# Changelog
# v0.3 - use FasterCSV, arrays supported
# v0.2 - bugfixed (return in middle of loop)
# v0.1 - initial version
require "faster_csv"
module Puppet::Parser::Functions
newfunction(:lookup_csv, :type => :rvalue) do |args|
filename = args[0]
key = args[1]
column = args[2]
rc = nil
FasterCSV::open(filename) do |csv_file|
# find which column we are after
colnum = csv_file.readline.index(column)
break if colnum == nil
# find matching line
csv_file.each { |line|
if (line[0] == key)
rc = line[colnum]
if (rc =~ /^\[(.*)\]$/)
rc = $1.split(/,/)
end
break
end
}
end
return rc
end
end
Adrian