ext/extlookup.rb in puppet-0.25.5 vs ext/extlookup.rb in puppet-2.6.0

- old
+ new

@@ -1,12 +1,12 @@ -# Puppet External Data Sources +# Puppet External Data Sources # # This is a parser function to read data from external files, this version # uses CSV files but the concept can easily be adjust for databases, yaml # or any other queryable data source. # -# The object of this is to make it obvious when it's being used, rather than +# The object of this is to make it obvious when it's being used, rather than # magically loading data in when an module is loaded I prefer to look at the code # and see statements like: # # $snmp_contact = extlookup("snmp_contact") # @@ -32,11 +32,11 @@ # The array tells the code how to resolve values, first it will try to find it in # web1.myclient.com.csv then in domain_myclient.com.csv and finally in common.csv # # Now create the following data files in /etc/puppet/manifests/extdata # -# domain_myclient.com.csv: +# domain_myclient.com.csv: # snmp_contact,John Doe <john@myclient.com> # root_contact,support@%{domain} # client_trusted_ips,192.168.1.130,192.168.10.0/24 # # common.csv: @@ -46,21 +46,21 @@ # Now you can replace the case statement with the simple single line to achieve # the exact same outcome: # # $snmp_contact = extlookup("snmp_contact") # -# The obove code shows some other features, you can use any fact or variable that +# The obove code shows some other features, you can use any fact or variable that # is in scope by simply using %{varname} in your data files, you can return arrays # by just having multiple values in the csv after the initial variable name. # # In the event that a variable is nowhere to be found a critical error will be raised # that will prevent your manifest from compiling, this is to avoid accidentally putting # in empty values etc. You can however specify a default value: # # $ntp_servers = extlookup("ntp_servers", "1.${country}.pool.ntp.org") -# -# In this case it will default to "1.${country}.pool.ntp.org" if nothing is defined in +# +# In this case it will default to "1.${country}.pool.ntp.org" if nothing is defined in # any data file. # # You can also specify an additional data file to search first before any others at use # time, for example: # @@ -72,112 +72,110 @@ # by $extlookup_precedence if it's not found anywhere it will default to "present", this kind # of use case makes puppet a lot nicer for managing large amounts of packages since you do not # need to edit a load of manifests to do simple things like adjust a desired version number. # # For more information on installing and writing your own custom functions see: -# http://puppetlabs.com/trac/puppet/wiki/WritingYourOwnFunctions +# http://docs.puppetlabs.com/guides/custom_functions.html # # For further help contact Volcane on #puppet require 'csv' - + module Puppet::Parser::Functions - newfunction(:extlookup, :type => :rvalue) do |args| - key = args[0] - default = "_ExtUNSET_" - datafile = "_ExtUNSET_" + newfunction(:extlookup, :type => :rvalue) do |args| + key = args[0] + default = "_ExtUNSET_" + datafile = "_ExtUNSET_" - default = args[1] if args[1] - datafile = args[2] if args[2] + default = args[1] if args[1] + datafile = args[2] if args[2] - extlookup_datadir = lookupvar('extlookup_datadir') - extlookup_precedence = Array.new + extlookup_datadir = lookupvar('extlookup_datadir') + extlookup_precedence = Array.new - # precedence values can have variables embedded in them - # in the form %{fqdn}, you could for example do - # - # $extlookup_precedence = ["hosts/%{fqdn}", "common"] - # - # this will result in /path/to/extdata/hosts/your.box.com.csv - # being searched. - # - # we parse the precedence here because the best place to specify - # it would be in site.pp but site.pp is only evaluated at startup - # so $fqdn etc would have no meaning there, this way it gets evaluated - # each run and has access to the right variables for that run - lookupvar('extlookup_precedence').each do |prec| - while prec =~ /%\{(.+?)\}/ - prec.gsub!(/%\{#{$1}\}/, lookupvar($1)) - end + # precedence values can have variables embedded in them + # in the form %{fqdn}, you could for example do + # + # $extlookup_precedence = ["hosts/%{fqdn}", "common"] + # + # this will result in /path/to/extdata/hosts/your.box.com.csv + # being searched. + # + # we parse the precedence here because the best place to specify + # it would be in site.pp but site.pp is only evaluated at startup + # so $fqdn etc would have no meaning there, this way it gets evaluated + # each run and has access to the right variables for that run + lookupvar('extlookup_precedence').each do |prec| + while prec =~ /%\{(.+?)\}/ + prec.gsub!(/%\{#{$1}\}/, lookupvar($1)) + end - extlookup_precedence << prec - end - + extlookup_precedence << prec + end - datafiles = Array.new - # if we got a custom data file, put it first in the array of search files - if datafile != "" - if File.exists?(extlookup_datadir + "/#{datafile}.csv") - datafiles << extlookup_datadir + "/#{datafile}.csv" - end - end + datafiles = Array.new - extlookup_precedence.each do |d| - datafiles << extlookup_datadir + "/#{d}.csv" - end + # if we got a custom data file, put it first in the array of search files + if datafile != "" + datafiles << extlookup_datadir + "/#{datafile}.csv" if File.exists?(extlookup_datadir + "/#{datafile}.csv") + end - desired = "_ExtUNSET_" + extlookup_precedence.each do |d| + datafiles << extlookup_datadir + "/#{d}.csv" + end - datafiles.each do |file| - parser.watch_file(file) if File.exists?(file) + desired = "_ExtUNSET_" - if desired == "_ExtUNSET_" - if File.exists?(file) - result = CSV.read(file).find_all do |r| - r[0] == key - end - + datafiles.each do |file| + parser.watch_file(file) if File.exists?(file) - # return just the single result if theres just one, - # else take all the fields in the csv and build an array - if result.length > 0 - if result[0].length == 2 - val = result[0][1].to_s - - # parse %{}'s in the CSV into local variables using lookupvar() - while val =~ /%\{(.+?)\}/ - val.gsub!(/%\{#{$1}\}/, lookupvar($1)) - end + if desired == "_ExtUNSET_" + if File.exists?(file) + result = CSV.read(file).find_all do |r| + r[0] == key + end - desired = val - elsif result[0].length > 1 - length = result[0].length - cells = result[0][1,length] - - # Individual cells in a CSV result are a weird data type and throws - # puppets yaml parsing, so just map it all to plain old strings - desired = cells.map do |c| - # parse %{}'s in the CSV into local variables using lookupvar() - while c =~ /%\{(.+?)\}/ - c.gsub!(/%\{#{$1}\}/, lookupvar($1)) - end - c.to_s - end - end - end + # return just the single result if theres just one, + # else take all the fields in the csv and build an array + if result.length > 0 + if result[0].length == 2 + val = result[0][1].to_s + + # parse %{}'s in the CSV into local variables using lookupvar() + while val =~ /%\{(.+?)\}/ + val.gsub!(/%\{#{$1}\}/, lookupvar($1)) + end + + desired = val + elsif result[0].length > 1 + length = result[0].length + cells = result[0][1,length] + + # Individual cells in a CSV result are a weird data type and throws + # puppets yaml parsing, so just map it all to plain old strings + desired = cells.map do |c| + # parse %{}'s in the CSV into local variables using lookupvar() + while c =~ /%\{(.+?)\}/ + c.gsub!(/%\{#{$1}\}/, lookupvar($1)) end + + c.to_s + end end + end end + end + end - # don't accidently return nil's and such rather throw a parse error - if desired == "_ExtUNSET_" && default == "_ExtUNSET_" - raise Puppet::ParseError, "No match found for '#{key}' in any data file during extlookup()" - else - desired = default if desired == "_ExtUNSET_" - end - - desired + # don't accidently return nil's and such rather throw a parse error + if desired == "_ExtUNSET_" && default == "_ExtUNSET_" + raise Puppet::ParseError, "No match found for '#{key}' in any data file during extlookup()" + else + desired = default if desired == "_ExtUNSET_" end + + desired + end end # vi:tabstop=4:expandtab:ai