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