diff options
Diffstat (limited to 'lib/puppet/parser/functions')
-rw-r--r-- | lib/puppet/parser/functions/basename.rb | 34 | ||||
-rw-r--r-- | lib/puppet/parser/functions/ceiling.rb | 25 | ||||
-rw-r--r-- | lib/puppet/parser/functions/concat.rb | 18 | ||||
-rw-r--r-- | lib/puppet/parser/functions/delete.rb | 27 | ||||
-rw-r--r-- | lib/puppet/parser/functions/ensure_resource.rb | 3 | ||||
-rw-r--r-- | lib/puppet/parser/functions/fqdn_rotate.rb | 16 | ||||
-rw-r--r-- | lib/puppet/parser/functions/is_domain_name.rb | 8 | ||||
-rw-r--r-- | lib/puppet/parser/functions/prefix.rb | 23 | ||||
-rw-r--r-- | lib/puppet/parser/functions/type.rb | 43 | ||||
-rw-r--r-- | lib/puppet/parser/functions/type3x.rb | 51 | ||||
-rw-r--r-- | lib/puppet/parser/functions/upcase.rb | 17 | ||||
-rw-r--r-- | lib/puppet/parser/functions/uriescape.rb | 2 | ||||
-rw-r--r-- | lib/puppet/parser/functions/validate_absolute_path.rb | 61 | ||||
-rw-r--r-- | lib/puppet/parser/functions/validate_cmd.rb | 21 |
14 files changed, 242 insertions, 107 deletions
diff --git a/lib/puppet/parser/functions/basename.rb b/lib/puppet/parser/functions/basename.rb new file mode 100644 index 0000000..f7e4438 --- /dev/null +++ b/lib/puppet/parser/functions/basename.rb @@ -0,0 +1,34 @@ +module Puppet::Parser::Functions + newfunction(:basename, :type => :rvalue, :doc => <<-EOS + Strips directory (and optional suffix) from a filename + EOS + ) do |arguments| + + if arguments.size < 1 then + raise(Puppet::ParseError, "basename(): No arguments given") + elsif arguments.size > 2 then + raise(Puppet::ParseError, "basename(): Too many arguments given (#{arguments.size})") + else + + unless arguments[0].is_a?(String) + raise(Puppet::ParseError, 'basename(): Requires string as first argument') + end + + if arguments.size == 1 then + rv = File.basename(arguments[0]) + elsif arguments.size == 2 then + + unless arguments[1].is_a?(String) + raise(Puppet::ParseError, 'basename(): Requires string as second argument') + end + + rv = File.basename(arguments[0], arguments[1]) + end + + end + + return rv + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/ceiling.rb b/lib/puppet/parser/functions/ceiling.rb new file mode 100644 index 0000000..5f3b10b --- /dev/null +++ b/lib/puppet/parser/functions/ceiling.rb @@ -0,0 +1,25 @@ +module Puppet::Parser::Functions + newfunction(:ceiling, :type => :rvalue, :doc => <<-EOS + Returns the smallest integer greater or equal to the argument. + Takes a single numeric value as an argument. + EOS + ) do |arguments| + + raise(Puppet::ParseError, "ceiling(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size != 1 + + begin + arg = Float(arguments[0]) + rescue TypeError, ArgumentError => e + raise(Puppet::ParseError, "ceiling(): Wrong argument type " + + "given (#{arguments[0]} for Numeric)") + end + + raise(Puppet::ParseError, "ceiling(): Wrong argument type " + + "given (#{arg.class} for Numeric)") if arg.is_a?(Numeric) == false + + arg.ceil + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/concat.rb b/lib/puppet/parser/functions/concat.rb index 0d35b07..618e62d 100644 --- a/lib/puppet/parser/functions/concat.rb +++ b/lib/puppet/parser/functions/concat.rb @@ -4,31 +4,35 @@ module Puppet::Parser::Functions newfunction(:concat, :type => :rvalue, :doc => <<-EOS -Appends the contents of array 2 onto array 1. +Appends the contents of multiple arrays into array 1. *Example:* - concat(['1','2','3'],['4','5','6']) + concat(['1','2','3'],['4','5','6'],['7','8','9']) Would result in: - ['1','2','3','4','5','6'] + ['1','2','3','4','5','6','7','8','9'] EOS ) do |arguments| - # Check that 2 arguments have been given ... + # Check that more than 2 arguments have been given ... raise(Puppet::ParseError, "concat(): Wrong number of arguments " + - "given (#{arguments.size} for 2)") if arguments.size != 2 + "given (#{arguments.size} for < 2)") if arguments.size < 2 a = arguments[0] - b = arguments[1] # Check that the first parameter is an array unless a.is_a?(Array) raise(Puppet::ParseError, 'concat(): Requires array to work with') end - result = a + Array(b) + result = a + arguments.shift + + arguments.each do |x| + result = result + Array(x) + end return result end diff --git a/lib/puppet/parser/functions/delete.rb b/lib/puppet/parser/functions/delete.rb index d03a293..f548b44 100644 --- a/lib/puppet/parser/functions/delete.rb +++ b/lib/puppet/parser/functions/delete.rb @@ -17,27 +17,30 @@ string, or key from a hash. delete({'a'=>1,'b'=>2,'c'=>3}, 'b') Would return: {'a'=>1,'c'=>3} + delete({'a'=>1,'b'=>2,'c'=>3}, ['b','c']) + Would return: {'a'=>1} + delete('abracadabra', 'bra') Would return: 'acada' - EOS + EOS ) do |arguments| if (arguments.size != 2) then raise(Puppet::ParseError, "delete(): Wrong number of arguments "+ - "given #{arguments.size} for 2.") + "given #{arguments.size} for 2.") end collection = arguments[0].dup - item = arguments[1] - - case collection - when Array, Hash - collection.delete item - when String - collection.gsub! item, '' - else - raise(TypeError, "delete(): First argument must be an Array, " + - "String, or Hash. Given an argument of class #{collection.class}.") + Array(arguments[1]).each do |item| + case collection + when Array, Hash + collection.delete item + when String + collection.gsub! item, '' + else + raise(TypeError, "delete(): First argument must be an Array, " + + "String, or Hash. Given an argument of class #{collection.class}.") + end end collection end diff --git a/lib/puppet/parser/functions/ensure_resource.rb b/lib/puppet/parser/functions/ensure_resource.rb index 05e5593..1ba6a44 100644 --- a/lib/puppet/parser/functions/ensure_resource.rb +++ b/lib/puppet/parser/functions/ensure_resource.rb @@ -36,8 +36,9 @@ ENDOFDOC items.each do |item| Puppet::Parser::Functions.function(:defined_with_params) if function_defined_with_params(["#{type}[#{item}]", params]) - Puppet.debug("Resource #{type}[#{item}] not created because it already exists") + Puppet.debug("Resource #{type}[#{item}] with params #{params} not created because it already exists") else + Puppet.debug("Create new resource #{type}[#{item}] with params #{params}") Puppet::Parser::Functions.function(:create_resources) function_create_resources([type.capitalize, { item => params }]) end diff --git a/lib/puppet/parser/functions/fqdn_rotate.rb b/lib/puppet/parser/functions/fqdn_rotate.rb index 7f4d37d..cf22d36 100644 --- a/lib/puppet/parser/functions/fqdn_rotate.rb +++ b/lib/puppet/parser/functions/fqdn_rotate.rb @@ -31,8 +31,20 @@ Rotates an array a random number of times based on a nodes fqdn. elements = result.size - srand(Digest::MD5.hexdigest([lookupvar('::fqdn'),arguments].join(':')).hex) - rand(elements).times { + seed = Digest::MD5.hexdigest([lookupvar('::fqdn'),arguments].join(':')).hex + # deterministic_rand() was added in Puppet 3.2.0; reimplement if necessary + if Puppet::Util.respond_to?(:deterministic_rand) + offset = Puppet::Util.deterministic_rand(seed, elements).to_i + else + if defined?(Random) == 'constant' && Random.class == Class + offset = Random.new(seed).rand(elements) + else + srand(seed) + offset = rand(elements) + srand() + end + end + offset.times { result.push result.shift } diff --git a/lib/puppet/parser/functions/is_domain_name.rb b/lib/puppet/parser/functions/is_domain_name.rb index b3fee96..2860ded 100644 --- a/lib/puppet/parser/functions/is_domain_name.rb +++ b/lib/puppet/parser/functions/is_domain_name.rb @@ -13,16 +13,16 @@ Returns true if the string passed to this function is a syntactically correct do "given #{arguments.size} for 1") end - domain = arguments[0] + # Only allow string types + return false unless arguments[0].is_a?(String) + + domain = arguments[0].dup # Limits (rfc1035, 3.1) domain_max_length=255 label_min_length=1 label_max_length=63 - # Only allow string types - return false unless domain.is_a?(String) - # Allow ".", it is the top level domain return true if domain == '.' diff --git a/lib/puppet/parser/functions/prefix.rb b/lib/puppet/parser/functions/prefix.rb index d02286a..ac1c58a 100644 --- a/lib/puppet/parser/functions/prefix.rb +++ b/lib/puppet/parser/functions/prefix.rb @@ -4,7 +4,7 @@ module Puppet::Parser::Functions newfunction(:prefix, :type => :rvalue, :doc => <<-EOS -This function applies a prefix to all elements in an array. +This function applies a prefix to all elements in an array or a hash. *Examples:* @@ -18,10 +18,10 @@ Will return: ['pa','pb','pc'] raise(Puppet::ParseError, "prefix(): Wrong number of arguments " + "given (#{arguments.size} for 1)") if arguments.size < 1 - array = arguments[0] + enumerable = arguments[0] - unless array.is_a?(Array) - raise Puppet::ParseError, "prefix(): expected first argument to be an Array, got #{array.inspect}" + unless enumerable.is_a?(Array) or enumerable.is_a?(Hash) + raise Puppet::ParseError, "prefix(): expected first argument to be an Array or a Hash, got #{enumerable.inspect}" end prefix = arguments[1] if arguments[1] @@ -32,10 +32,17 @@ Will return: ['pa','pb','pc'] end end - # Turn everything into string same as join would do ... - result = array.collect do |i| - i = i.to_s - prefix ? prefix + i : i + if enumerable.is_a?(Array) + # Turn everything into string same as join would do ... + result = enumerable.collect do |i| + i = i.to_s + prefix ? prefix + i : i + end + else + result = Hash[enumerable.map do |k,v| + k = k.to_s + [ prefix ? prefix + k : k, v ] + end] end return result diff --git a/lib/puppet/parser/functions/type.rb b/lib/puppet/parser/functions/type.rb index 8d85f11..016529b 100644 --- a/lib/puppet/parser/functions/type.rb +++ b/lib/puppet/parser/functions/type.rb @@ -4,46 +4,15 @@ module Puppet::Parser::Functions newfunction(:type, :type => :rvalue, :doc => <<-EOS -Returns the type when passed a variable. Type can be one of: - -* string -* array -* hash -* float -* integer -* boolean + DEPRECATED: This function will cease to function on Puppet 4; please use type3x() before upgrading to puppet 4 for backwards-compatibility, or migrate to the new parser's typing system. EOS - ) do |arguments| - - raise(Puppet::ParseError, "type(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - value = arguments[0] - - klass = value.class - - if not [TrueClass, FalseClass, Array, Bignum, Fixnum, Float, Hash, String].include?(klass) - raise(Puppet::ParseError, 'type(): Unknown type') - end - - klass = klass.to_s # Ugly ... + ) do |args| - # We note that Integer is the parent to Bignum and Fixnum ... - result = case klass - when /^(?:Big|Fix)num$/ then 'integer' - when /^(?:True|False)Class$/ then 'boolean' - else klass + warning("type() DEPRECATED: This function will cease to function on Puppet 4; please use type3x() before upgrading to puppet 4 for backwards-compatibility, or migrate to the new parser's typing system.") + if ! Puppet::Parser::Functions.autoloader.loaded?(:type3x) + Puppet::Parser::Functions.autoloader.load(:type3x) end - - if result == "String" then - if value == value.to_i.to_s then - result = "Integer" - elsif value == value.to_f.to_s then - result = "Float" - end - end - - return result.downcase + function_type3x(args + [false]) end end diff --git a/lib/puppet/parser/functions/type3x.rb b/lib/puppet/parser/functions/type3x.rb new file mode 100644 index 0000000..0800b4a --- /dev/null +++ b/lib/puppet/parser/functions/type3x.rb @@ -0,0 +1,51 @@ +# +# type3x.rb +# + +module Puppet::Parser::Functions + newfunction(:type3x, :type => :rvalue, :doc => <<-EOS +DEPRECATED: This function will be removed when puppet 3 support is dropped; please migrate to the new parser's typing system. + +Returns the type when passed a value. Type can be one of: + +* string +* array +* hash +* float +* integer +* boolean + EOS + ) do |args| + raise(Puppet::ParseError, "type3x(): Wrong number of arguments " + + "given (#{args.size} for 1)") if args.size < 1 + + value = args[0] + + klass = value.class + + if not [TrueClass, FalseClass, Array, Bignum, Fixnum, Float, Hash, String].include?(klass) + raise(Puppet::ParseError, 'type3x(): Unknown type') + end + + klass = klass.to_s # Ugly ... + + # We note that Integer is the parent to Bignum and Fixnum ... + result = case klass + when /^(?:Big|Fix)num$/ then 'integer' + when /^(?:True|False)Class$/ then 'boolean' + else klass + end + + if result == "String" then + if value == value.to_i.to_s then + result = "Integer" + elsif value == value.to_f.to_s then + result = "Float" + end + end + + return result.downcase + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/upcase.rb b/lib/puppet/parser/functions/upcase.rb index 4302b29..0226a88 100644 --- a/lib/puppet/parser/functions/upcase.rb +++ b/lib/puppet/parser/functions/upcase.rb @@ -13,22 +13,27 @@ Converts a string or an array of strings to uppercase. Will return: ASDF - EOS + EOS ) do |arguments| raise(Puppet::ParseError, "upcase(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 + "given (#{arguments.size} for 1)") if arguments.size != 1 value = arguments[0] - unless value.is_a?(Array) || value.is_a?(String) - raise(Puppet::ParseError, 'upcase(): Requires either ' + - 'array or string to work with') + unless value.is_a?(Array) || value.is_a?(Hash) || value.respond_to?(:upcase) + raise(Puppet::ParseError, 'upcase(): Requires an ' + + 'array, hash or object that responds to upcase in order to work') end if value.is_a?(Array) # Numbers in Puppet are often string-encoded which is troublesome ... - result = value.collect { |i| i.is_a?(String) ? i.upcase : i } + result = value.collect { |i| function_upcase([i]) } + elsif value.is_a?(Hash) + result = {} + value.each_pair do |k, v| + result[function_upcase([k])] = function_upcase([v]) + end else result = value.upcase end diff --git a/lib/puppet/parser/functions/uriescape.rb b/lib/puppet/parser/functions/uriescape.rb index a486eee..45bbed2 100644 --- a/lib/puppet/parser/functions/uriescape.rb +++ b/lib/puppet/parser/functions/uriescape.rb @@ -22,7 +22,7 @@ module Puppet::Parser::Functions if value.is_a?(Array) # Numbers in Puppet are often string-encoded which is troublesome ... - result = value.collect { |i| i.is_a?(String) ? URI.escape(i,unsafe) : i } + result = value.collect { |i| i.is_a?(String) ? URI.escape(i) : i } else result = URI.escape(value) end diff --git a/lib/puppet/parser/functions/validate_absolute_path.rb b/lib/puppet/parser/functions/validate_absolute_path.rb index fe27974..b696680 100644 --- a/lib/puppet/parser/functions/validate_absolute_path.rb +++ b/lib/puppet/parser/functions/validate_absolute_path.rb @@ -5,15 +5,20 @@ module Puppet::Parser::Functions The following values will pass: - $my_path = "C:/Program Files (x86)/Puppet Labs/Puppet" + $my_path = 'C:/Program Files (x86)/Puppet Labs/Puppet' validate_absolute_path($my_path) - $my_path2 = "/var/lib/puppet" + $my_path2 = '/var/lib/puppet' validate_absolute_path($my_path2) - + $my_path3 = ['C:/Program Files (x86)/Puppet Labs/Puppet','C:/Program Files/Puppet Labs/Puppet'] + validate_absolute_path($my_path3) + $my_path4 = ['/var/lib/puppet','/usr/share/puppet'] + validate_absolute_path($my_path4) The following values will fail, causing compilation to abort: validate_absolute_path(true) + validate_absolute_path('../var/lib/puppet') + validate_absolute_path('var/lib/puppet') validate_absolute_path([ 'var/lib/puppet', '/var/foo' ]) validate_absolute_path([ '/var/lib/puppet', 'var/foo' ]) $undefined = undef @@ -28,28 +33,36 @@ module Puppet::Parser::Functions end args.each do |arg| - # This logic was borrowed from - # [lib/puppet/file_serving/base.rb](https://github.com/puppetlabs/puppet/blob/master/lib/puppet/file_serving/base.rb) - - # Puppet 2.7 and beyond will have Puppet::Util.absolute_path? Fall back to a back-ported implementation otherwise. - if Puppet::Util.respond_to?(:absolute_path?) then - unless Puppet::Util.absolute_path?(arg, :posix) or Puppet::Util.absolute_path?(arg, :windows) - raise Puppet::ParseError, ("#{arg.inspect} is not an absolute path.") + # put arg to candidate var to be able to replace it + candidates = arg + # if arg is just a string with a path to test, convert it to an array + # to avoid test code duplication + unless arg.is_a?(Array) then + candidates = Array.new(1,arg) + end + # iterate over all pathes within the candidates array + candidates.each do |path| + # This logic was borrowed from + # [lib/puppet/file_serving/base.rb](https://github.com/puppetlabs/puppet/blob/master/lib/puppet/file_serving/base.rb) + # Puppet 2.7 and beyond will have Puppet::Util.absolute_path? Fall back to a back-ported implementation otherwise. + if Puppet::Util.respond_to?(:absolute_path?) then + unless Puppet::Util.absolute_path?(path, :posix) or Puppet::Util.absolute_path?(path, :windows) + raise Puppet::ParseError, ("#{path.inspect} is not an absolute path.") + end + else + # This code back-ported from 2.7.x's lib/puppet/util.rb Puppet::Util.absolute_path? + # Determine in a platform-specific way whether a path is absolute. This + # defaults to the local platform if none is specified. + # Escape once for the string literal, and once for the regex. + slash = '[\\\\/]' + name = '[^\\\\/]+' + regexes = { + :windows => %r!^(([A-Z]:#{slash})|(#{slash}#{slash}#{name}#{slash}#{name})|(#{slash}#{slash}\?#{slash}#{name}))!i, + :posix => %r!^/!, + } + rval = (!!(path =~ regexes[:posix])) || (!!(path =~ regexes[:windows])) + rval or raise Puppet::ParseError, ("#{path.inspect} is not an absolute path.") end - else - # This code back-ported from 2.7.x's lib/puppet/util.rb Puppet::Util.absolute_path? - # Determine in a platform-specific way whether a path is absolute. This - # defaults to the local platform if none is specified. - # Escape once for the string literal, and once for the regex. - slash = '[\\\\/]' - name = '[^\\\\/]+' - regexes = { - :windows => %r!^(([A-Z]:#{slash})|(#{slash}#{slash}#{name}#{slash}#{name})|(#{slash}#{slash}\?#{slash}#{name}))!i, - :posix => %r!^/!, - } - - rval = (!!(arg =~ regexes[:posix])) || (!!(arg =~ regexes[:windows])) - rval or raise Puppet::ParseError, ("#{arg.inspect} is not an absolute path.") end end end diff --git a/lib/puppet/parser/functions/validate_cmd.rb b/lib/puppet/parser/functions/validate_cmd.rb index c6136a5..5df3c60 100644 --- a/lib/puppet/parser/functions/validate_cmd.rb +++ b/lib/puppet/parser/functions/validate_cmd.rb @@ -6,9 +6,9 @@ module Puppet::Parser::Functions Perform validation of a string with an external command. The first argument of this function should be a string to test, and the second argument should be a path to a test command - taking a file as last argument. If the command, launched against - a tempfile containing the passed string, returns a non-null value, - compilation will abort with a parse error. + taking a % as a placeholder for the file path (will default to the end). + If the command, launched against a tempfile containing the passed string, + returns a non-null value, compilation will abort with a parse error. If a third argument is specified, this will be the error message raised and seen by the user. @@ -17,8 +17,12 @@ module Puppet::Parser::Functions Example: + # Defaults to end of path validate_cmd($sudoerscontent, '/usr/sbin/visudo -c -f', 'Visudo failed to validate sudoers content') + # % as file location + validate_cmd($haproxycontent, '/usr/sbin/haproxy -f % -c', 'Haproxy failed to validate config content') + ENDHEREDOC if (args.length < 2) or (args.length > 3) then raise Puppet::ParseError, ("validate_cmd(): wrong number of arguments (#{args.length}; must be 2 or 3)") @@ -34,10 +38,17 @@ module Puppet::Parser::Functions begin tmpfile.write(content) tmpfile.close + + if checkscript =~ /\s%(\s|$)/ + check_with_correct_location = checkscript.gsub(/%/,tmpfile.path) + else + check_with_correct_location = "#{checkscript} #{tmpfile.path}" + end + if Puppet::Util::Execution.respond_to?('execute') - Puppet::Util::Execution.execute("#{checkscript} #{tmpfile.path}") + Puppet::Util::Execution.execute(check_with_correct_location) else - Puppet::Util.execute("#{checkscript} #{tmpfile.path}") + Puppet::Util.execute(check_with_correct_location) end rescue Puppet::ExecutionFailure => detail msg += "\n#{detail}" |