summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMicah Anderson <micah@riseup.net>2015-01-27 15:14:18 -0500
committerMicah Anderson <micah@riseup.net>2015-01-27 15:14:18 -0500
commit71123634744b9fe2ec7d6a3e38e9789fd84801e3 (patch)
tree1794e812d83facd93b3007c42632c63ddf1eb2fc /lib
parent71cb0f4c2c3bf95f62c9f189f5cef155b09a9682 (diff)
parent5863ab3901368310186790980aea2b0bf7cecb06 (diff)
Merge branch 'master' into leap
Diffstat (limited to 'lib')
-rw-r--r--lib/facter/facter_dot_d.rb8
-rw-r--r--lib/facter/root_home.rb13
-rw-r--r--lib/puppet/functions/type_of.rb17
-rw-r--r--lib/puppet/parser/functions/base64.rb12
-rw-r--r--lib/puppet/parser/functions/basename.rb34
-rw-r--r--lib/puppet/parser/functions/bool2num.rb25
-rw-r--r--lib/puppet/parser/functions/bool2str.rb27
-rw-r--r--lib/puppet/parser/functions/camelcase.rb33
-rw-r--r--lib/puppet/parser/functions/capitalize.rb3
-rw-r--r--lib/puppet/parser/functions/chomp.rb3
-rw-r--r--lib/puppet/parser/functions/chop.rb3
-rw-r--r--lib/puppet/parser/functions/concat.rb22
-rw-r--r--lib/puppet/parser/functions/deep_merge.rb44
-rw-r--r--lib/puppet/parser/functions/delete.rb29
-rw-r--r--lib/puppet/parser/functions/delete_undef_values.rb14
-rw-r--r--lib/puppet/parser/functions/delete_values.rb4
-rw-r--r--lib/puppet/parser/functions/downcase.rb3
-rw-r--r--lib/puppet/parser/functions/empty.rb3
-rw-r--r--lib/puppet/parser/functions/ensure_packages.rb25
-rw-r--r--lib/puppet/parser/functions/ensure_resource.rb3
-rw-r--r--lib/puppet/parser/functions/floor.rb7
-rw-r--r--lib/puppet/parser/functions/fqdn_rotate.rb3
-rw-r--r--lib/puppet/parser/functions/getvar.rb5
-rw-r--r--lib/puppet/parser/functions/has_interface_with.rb22
-rw-r--r--lib/puppet/parser/functions/is_bool.rb22
-rw-r--r--lib/puppet/parser/functions/is_domain_name.rb3
-rw-r--r--lib/puppet/parser/functions/is_float.rb3
-rw-r--r--lib/puppet/parser/functions/is_function_available.rb3
-rw-r--r--lib/puppet/parser/functions/is_integer.rb28
-rw-r--r--lib/puppet/parser/functions/is_numeric.rb54
-rw-r--r--lib/puppet/parser/functions/join.rb2
-rw-r--r--lib/puppet/parser/functions/lstrip.rb3
-rw-r--r--lib/puppet/parser/functions/member.rb24
-rw-r--r--lib/puppet/parser/functions/pick.rb2
-rw-r--r--lib/puppet/parser/functions/pick_default.rb35
-rw-r--r--lib/puppet/parser/functions/prefix.rb2
-rw-r--r--lib/puppet/parser/functions/private.rb29
-rw-r--r--lib/puppet/parser/functions/range.rb28
-rw-r--r--lib/puppet/parser/functions/reverse.rb3
-rw-r--r--lib/puppet/parser/functions/rstrip.rb3
-rw-r--r--lib/puppet/parser/functions/shuffle.rb3
-rw-r--r--lib/puppet/parser/functions/str2bool.rb2
-rw-r--r--lib/puppet/parser/functions/strip.rb3
-rw-r--r--lib/puppet/parser/functions/swapcase.rb3
-rw-r--r--lib/puppet/parser/functions/to_bytes.rb5
-rw-r--r--lib/puppet/parser/functions/type.rb43
-rw-r--r--lib/puppet/parser/functions/type3x.rb51
-rw-r--r--lib/puppet/parser/functions/unique.rb3
-rw-r--r--lib/puppet/parser/functions/upcase.rb3
-rw-r--r--lib/puppet/parser/functions/uriescape.rb3
-rw-r--r--lib/puppet/parser/functions/validate_absolute_path.rb61
-rw-r--r--lib/puppet/parser/functions/validate_augeas.rb2
-rw-r--r--lib/puppet/parser/functions/validate_bool.rb2
-rw-r--r--lib/puppet/parser/functions/validate_cmd.rb26
-rw-r--r--lib/puppet/parser/functions/validate_string.rb11
-rw-r--r--lib/puppet/parser/functions/values_at.rb1
-rw-r--r--lib/puppet/parser/functions/zip.rb28
-rw-r--r--lib/puppet/provider/file_line/ruby.rb41
-rw-r--r--lib/puppet/type/file_line.rb14
59 files changed, 662 insertions, 249 deletions
diff --git a/lib/facter/facter_dot_d.rb b/lib/facter/facter_dot_d.rb
index e414b20..b058437 100644
--- a/lib/facter/facter_dot_d.rb
+++ b/lib/facter/facter_dot_d.rb
@@ -15,7 +15,7 @@
class Facter::Util::DotD
require 'yaml'
- def initialize(dir="/etc/facts.d", cache_file="/tmp/facts_cache.yml")
+ def initialize(dir="/etc/facts.d", cache_file=File.join(Puppet[:libdir], "facts_dot_d.cache"))
@dir = dir
@cache_file = cache_file
@cache = nil
@@ -23,7 +23,7 @@ class Facter::Util::DotD
end
def entries
- Dir.entries(@dir).reject{|f| f =~ /^\.|\.ttl$/}.sort.map {|f| File.join(@dir, f) }
+ Dir.entries(@dir).reject { |f| f =~ /^\.|\.ttl$/ }.sort.map { |f| File.join(@dir, f) }
rescue
[]
end
@@ -40,7 +40,7 @@ class Facter::Util::DotD
def txt_parser(file)
File.readlines(file).each do |line|
- if line =~ /^(.+)=(.+)$/
+ if line =~ /^([^=]+)=(.+)$/
var = $1; val = $2
Facter.add(var) do
@@ -113,7 +113,7 @@ class Facter::Util::DotD
def cache_save!
cache = load_cache
- File.open(@cache_file, "w", 0600) {|f| f.write(YAML.dump(cache)) }
+ File.open(@cache_file, "w", 0600) { |f| f.write(YAML.dump(cache)) }
rescue
end
diff --git a/lib/facter/root_home.rb b/lib/facter/root_home.rb
index 8249f7d..b4f87ff 100644
--- a/lib/facter/root_home.rb
+++ b/lib/facter/root_home.rb
@@ -17,3 +17,16 @@ end
Facter.add(:root_home) do
setcode { Facter::Util::RootHome.get_root_home }
end
+
+Facter.add(:root_home) do
+ confine :kernel => :darwin
+ setcode do
+ str = Facter::Util::Resolution.exec("dscacheutil -q user -a name root")
+ hash = {}
+ str.split("\n").each do |pair|
+ key,value = pair.split(/:/)
+ hash[key] = value
+ end
+ hash['dir'].strip
+ end
+end
diff --git a/lib/puppet/functions/type_of.rb b/lib/puppet/functions/type_of.rb
new file mode 100644
index 0000000..02cdd4d
--- /dev/null
+++ b/lib/puppet/functions/type_of.rb
@@ -0,0 +1,17 @@
+# Returns the type when passed a value.
+#
+# @example how to compare values' types
+# # compare the types of two values
+# if type_of($first_value) != type_of($second_value) { fail("first_value and second_value are different types") }
+# @example how to compare against an abstract type
+# unless type_of($first_value) <= Numeric { fail("first_value must be Numeric") }
+# unless type_of{$first_value) <= Collection[1] { fail("first_value must be an Array or Hash, and contain at least one element") }
+#
+# See the documentation for "The Puppet Type System" for more information about types.
+# See the `assert_type()` function for flexible ways to assert the type of a value.
+#
+Puppet::Functions.create_function(:type_of) do
+ def type_of(value)
+ Puppet::Pops::Types::TypeCalculator.infer_set(value)
+ end
+end
diff --git a/lib/puppet/parser/functions/base64.rb b/lib/puppet/parser/functions/base64.rb
index d9a590a..617ba31 100644
--- a/lib/puppet/parser/functions/base64.rb
+++ b/lib/puppet/parser/functions/base64.rb
@@ -1,5 +1,5 @@
module Puppet::Parser::Functions
-
+
newfunction(:base64, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args|
Base64 encode or decode a string based on the command and the string submitted
@@ -10,9 +10,9 @@ module Puppet::Parser::Functions
$decodestring = base64('decode','dGhlc3RyaW5n')
ENDHEREDOC
-
+
require 'base64'
-
+
raise Puppet::ParseError, ("base64(): Wrong number of arguments (#{args.length}; must be = 2)") unless args.length == 2
actions = ['encode','decode']
@@ -20,18 +20,18 @@ module Puppet::Parser::Functions
unless actions.include?(args[0])
raise Puppet::ParseError, ("base64(): the first argument must be one of 'encode' or 'decode'")
end
-
+
unless args[1].is_a?(String)
raise Puppet::ParseError, ("base64(): the second argument must be a string to base64")
end
-
+
case args[0]
when 'encode'
result = Base64.encode64(args[1])
when 'decode'
result = Base64.decode64(args[1])
end
-
+
return result
end
end
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/bool2num.rb b/lib/puppet/parser/functions/bool2num.rb
index 9a07a8a..6ad6cf4 100644
--- a/lib/puppet/parser/functions/bool2num.rb
+++ b/lib/puppet/parser/functions/bool2num.rb
@@ -14,30 +14,7 @@ module Puppet::Parser::Functions
raise(Puppet::ParseError, "bool2num(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
- value = arguments[0]
- klass = value.class
-
- # We can have either true or false, or string which resembles boolean ...
- unless [FalseClass, TrueClass, String].include?(klass)
- raise(Puppet::ParseError, 'bool2num(): Requires either ' +
- 'boolean or string to work with')
- end
-
- if value.is_a?(String)
- # We consider all the yes, no, y, n and so on too ...
- value = case value
- #
- # This is how undef looks like in Puppet ...
- # We yield 0 (or false if you wish) in this case.
- #
- when /^$/, '' then false # Empty string will be false ...
- when /^(1|t|y|true|yes)$/ then true
- when /^(0|f|n|false|no)$/ then false
- when /^(undef|undefined)$/ then false # This is not likely to happen ...
- else
- raise(Puppet::ParseError, 'bool2num(): Unknown type of boolean given')
- end
- end
+ value = function_str2bool([arguments[0]])
# We have real boolean values as well ...
result = value ? 1 : 0
diff --git a/lib/puppet/parser/functions/bool2str.rb b/lib/puppet/parser/functions/bool2str.rb
new file mode 100644
index 0000000..fcd3791
--- /dev/null
+++ b/lib/puppet/parser/functions/bool2str.rb
@@ -0,0 +1,27 @@
+#
+# bool2str.rb
+#
+
+module Puppet::Parser::Functions
+ newfunction(:bool2str, :type => :rvalue, :doc => <<-EOS
+ Converts a boolean to a string.
+ Requires a single boolean as an input.
+ EOS
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "bool2str(): Wrong number of arguments " +
+ "given (#{arguments.size} for 1)") if arguments.size < 1
+
+ value = arguments[0]
+ klass = value.class
+
+ # We can have either true or false, and nothing else
+ unless [FalseClass, TrueClass].include?(klass)
+ raise(Puppet::ParseError, 'bool2str(): Requires a boolean to work with')
+ end
+
+ return value.to_s
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/lib/puppet/parser/functions/camelcase.rb b/lib/puppet/parser/functions/camelcase.rb
new file mode 100644
index 0000000..d7f43f7
--- /dev/null
+++ b/lib/puppet/parser/functions/camelcase.rb
@@ -0,0 +1,33 @@
+#
+# camelcase.rb
+#
+
+module Puppet::Parser::Functions
+ newfunction(:camelcase, :type => :rvalue, :doc => <<-EOS
+Converts the case of a string or all strings in an array to camel case.
+ EOS
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "camelcase(): Wrong number of arguments " +
+ "given (#{arguments.size} for 1)") if arguments.size < 1
+
+ value = arguments[0]
+ klass = value.class
+
+ unless [Array, String].include?(klass)
+ raise(Puppet::ParseError, 'camelcase(): Requires either ' +
+ 'array or string to work with')
+ 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.split('_').map{|e| e.capitalize}.join : i }
+ else
+ result = value.split('_').map{|e| e.capitalize}.join
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/lib/puppet/parser/functions/capitalize.rb b/lib/puppet/parser/functions/capitalize.rb
index 640d00b..98b2d16 100644
--- a/lib/puppet/parser/functions/capitalize.rb
+++ b/lib/puppet/parser/functions/capitalize.rb
@@ -13,9 +13,8 @@ module Puppet::Parser::Functions
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
- klass = value.class
- unless [Array, String].include?(klass)
+ unless value.is_a?(Array) || value.is_a?(String)
raise(Puppet::ParseError, 'capitalize(): Requires either ' +
'array or string to work with')
end
diff --git a/lib/puppet/parser/functions/chomp.rb b/lib/puppet/parser/functions/chomp.rb
index 4564a00..c55841e 100644
--- a/lib/puppet/parser/functions/chomp.rb
+++ b/lib/puppet/parser/functions/chomp.rb
@@ -14,9 +14,8 @@ module Puppet::Parser::Functions
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
- klass = value.class
- unless [Array, String].include?(klass)
+ unless value.is_a?(Array) || value.is_a?(String)
raise(Puppet::ParseError, 'chomp(): Requires either ' +
'array or string to work with')
end
diff --git a/lib/puppet/parser/functions/chop.rb b/lib/puppet/parser/functions/chop.rb
index f242af3..b24ab78 100644
--- a/lib/puppet/parser/functions/chop.rb
+++ b/lib/puppet/parser/functions/chop.rb
@@ -16,9 +16,8 @@ module Puppet::Parser::Functions
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
- klass = value.class
- unless [Array, String].include?(klass)
+ unless value.is_a?(Array) || value.is_a?(String)
raise(Puppet::ParseError, 'chop(): Requires either an ' +
'array or string to work with')
end
diff --git a/lib/puppet/parser/functions/concat.rb b/lib/puppet/parser/functions/concat.rb
index c86aa00..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 both args are arrays.
- unless a.is_a?(Array) and b.is_a?(Array)
+ # 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.concat(b)
+ result = a
+ arguments.shift
+
+ arguments.each do |x|
+ result = result + Array(x)
+ end
return result
end
diff --git a/lib/puppet/parser/functions/deep_merge.rb b/lib/puppet/parser/functions/deep_merge.rb
new file mode 100644
index 0000000..6df32e9
--- /dev/null
+++ b/lib/puppet/parser/functions/deep_merge.rb
@@ -0,0 +1,44 @@
+module Puppet::Parser::Functions
+ newfunction(:deep_merge, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args|
+ Recursively merges two or more hashes together and returns the resulting hash.
+
+ For example:
+
+ $hash1 = {'one' => 1, 'two' => 2, 'three' => { 'four' => 4 } }
+ $hash2 = {'two' => 'dos', 'three' => { 'five' => 5 } }
+ $merged_hash = deep_merge($hash1, $hash2)
+ # The resulting hash is equivalent to:
+ # $merged_hash = { 'one' => 1, 'two' => 'dos', 'three' => { 'four' => 4, 'five' => 5 } }
+
+ When there is a duplicate key that is a hash, they are recursively merged.
+ When there is a duplicate key that is not a hash, the key in the rightmost hash will "win."
+
+ ENDHEREDOC
+
+ if args.length < 2
+ raise Puppet::ParseError, ("deep_merge(): wrong number of arguments (#{args.length}; must be at least 2)")
+ end
+
+ deep_merge = Proc.new do |hash1,hash2|
+ hash1.merge(hash2) do |key,old_value,new_value|
+ if old_value.is_a?(Hash) && new_value.is_a?(Hash)
+ deep_merge.call(old_value, new_value)
+ else
+ new_value
+ end
+ end
+ end
+
+ result = Hash.new
+ args.each do |arg|
+ next if arg.is_a? String and arg.empty? # empty string is synonym for puppet's undef
+ # If the argument was not a hash, skip it.
+ unless arg.is_a?(Hash)
+ raise Puppet::ParseError, "deep_merge: unexpected argument type #{arg.class}, only expects hash arguments"
+ end
+
+ result = deep_merge.call(result, arg)
+ end
+ return( result )
+ end
+end
diff --git a/lib/puppet/parser/functions/delete.rb b/lib/puppet/parser/functions/delete.rb
index f814344..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]
- 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}.")
+ collection = arguments[0].dup
+ 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/delete_undef_values.rb b/lib/puppet/parser/functions/delete_undef_values.rb
index 4eecab2..f94d4da 100644
--- a/lib/puppet/parser/functions/delete_undef_values.rb
+++ b/lib/puppet/parser/functions/delete_undef_values.rb
@@ -3,7 +3,7 @@ module Puppet::Parser::Functions
Returns a copy of input hash or array with all undefs deleted.
*Examples:*
-
+
$hash = delete_undef_values({a=>'A', b=>'', c=>undef, d => false})
Would return: {a => 'A', b => '', d => false}
@@ -11,7 +11,7 @@ Would return: {a => 'A', b => '', d => false}
$array = delete_undef_values(['A','',undef,false])
Would return: ['A','',false]
-
+
EOS
) do |args|
@@ -19,15 +19,15 @@ Would return: ['A','',false]
"delete_undef_values(): Wrong number of arguments given " +
"(#{args.size})") if args.size < 1
- result = args[0]
+ unless args[0].is_a? Array or args[0].is_a? Hash
+ raise(Puppet::ParseError,
+ "delete_undef_values(): expected an array or hash, got #{args[0]} type #{args[0].class} ")
+ end
+ result = args[0].dup
if result.is_a?(Hash)
result.delete_if {|key, val| val.equal? :undef}
elsif result.is_a?(Array)
result.delete :undef
- else
- raise(Puppet::ParseError,
- "delete_undef_values(): Wrong argument type #{args[0].class} " +
- "for first argument")
end
result
end
diff --git a/lib/puppet/parser/functions/delete_values.rb b/lib/puppet/parser/functions/delete_values.rb
index 17b9d37..f6c8c0e 100644
--- a/lib/puppet/parser/functions/delete_values.rb
+++ b/lib/puppet/parser/functions/delete_values.rb
@@ -19,8 +19,8 @@ Would return: {'a'=>'A','c'=>'C','B'=>'D'}
if not hash.is_a?(Hash)
raise(TypeError, "delete_values(): First argument must be a Hash. " + \
- "Given an argument of class #{hash.class}.")
+ "Given an argument of class #{hash.class}.")
end
- hash.delete_if { |key, val| item == val }
+ hash.dup.delete_if { |key, val| item == val }
end
end
diff --git a/lib/puppet/parser/functions/downcase.rb b/lib/puppet/parser/functions/downcase.rb
index 4066d21..040b84f 100644
--- a/lib/puppet/parser/functions/downcase.rb
+++ b/lib/puppet/parser/functions/downcase.rb
@@ -12,9 +12,8 @@ Converts the case of a string or all strings in an array to lower case.
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
- klass = value.class
- unless [Array, String].include?(klass)
+ unless value.is_a?(Array) || value.is_a?(String)
raise(Puppet::ParseError, 'downcase(): Requires either ' +
'array or string to work with')
end
diff --git a/lib/puppet/parser/functions/empty.rb b/lib/puppet/parser/functions/empty.rb
index 80ebb86..cca620f 100644
--- a/lib/puppet/parser/functions/empty.rb
+++ b/lib/puppet/parser/functions/empty.rb
@@ -12,9 +12,8 @@ Returns true if the variable is empty.
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
- klass = value.class
- unless [Array, Hash, String].include?(klass)
+ unless value.is_a?(Array) || value.is_a?(Hash) || value.is_a?(String)
raise(Puppet::ParseError, 'empty(): Requires either ' +
'array, hash or string to work with')
end
diff --git a/lib/puppet/parser/functions/ensure_packages.rb b/lib/puppet/parser/functions/ensure_packages.rb
index 450ea02..f1da4aa 100644
--- a/lib/puppet/parser/functions/ensure_packages.rb
+++ b/lib/puppet/parser/functions/ensure_packages.rb
@@ -1,22 +1,33 @@
#
# ensure_packages.rb
#
-require 'puppet/parser/functions'
module Puppet::Parser::Functions
newfunction(:ensure_packages, :type => :statement, :doc => <<-EOS
Takes a list of packages and only installs them if they don't already exist.
+It optionally takes a hash as a second parameter that will be passed as the
+third argument to the ensure_resource() function.
EOS
) do |arguments|
- raise(Puppet::ParseError, "ensure_packages(): Wrong number of arguments " +
- "given (#{arguments.size} for 1)") if arguments.size != 1
- raise(Puppet::ParseError, "ensure_packages(): Requires array " +
- "given (#{arguments[0].class})") if !arguments[0].kind_of?(Array)
+ if arguments.size > 2 or arguments.size == 0
+ raise(Puppet::ParseError, "ensure_packages(): Wrong number of arguments " +
+ "given (#{arguments.size} for 1 or 2)")
+ elsif arguments.size == 2 and !arguments[1].is_a?(Hash)
+ raise(Puppet::ParseError, 'ensure_packages(): Requires second argument to be a Hash')
+ end
+
+ packages = Array(arguments[0])
+
+ if arguments[1]
+ defaults = { 'ensure' => 'present' }.merge(arguments[1])
+ else
+ defaults = { 'ensure' => 'present' }
+ end
Puppet::Parser::Functions.function(:ensure_resource)
- arguments[0].each { |package_name|
- function_ensure_resource(['package', package_name, {'ensure' => 'present' } ])
+ packages.each { |package_name|
+ function_ensure_resource(['package', package_name, defaults ])
}
end
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/floor.rb b/lib/puppet/parser/functions/floor.rb
index a401923..9a6f014 100644
--- a/lib/puppet/parser/functions/floor.rb
+++ b/lib/puppet/parser/functions/floor.rb
@@ -8,7 +8,12 @@ module Puppet::Parser::Functions
raise(Puppet::ParseError, "floor(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size != 1
- arg = arguments[0]
+ begin
+ arg = Float(arguments[0])
+ rescue TypeError, ArgumentError => e
+ raise(Puppet::ParseError, "floor(): Wrong argument type " +
+ "given (#{arguments[0]} for Numeric)")
+ end
raise(Puppet::ParseError, "floor(): Wrong argument type " +
"given (#{arg.class} for Numeric)") if arg.is_a?(Numeric) == false
diff --git a/lib/puppet/parser/functions/fqdn_rotate.rb b/lib/puppet/parser/functions/fqdn_rotate.rb
index 6558206..7f4d37d 100644
--- a/lib/puppet/parser/functions/fqdn_rotate.rb
+++ b/lib/puppet/parser/functions/fqdn_rotate.rb
@@ -12,10 +12,9 @@ Rotates an array a random number of times based on a nodes fqdn.
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
- klass = value.class
require 'digest/md5'
- unless [Array, String].include?(klass)
+ unless value.is_a?(Array) || value.is_a?(String)
raise(Puppet::ParseError, 'fqdn_rotate(): Requires either ' +
'array or string to work with')
end
diff --git a/lib/puppet/parser/functions/getvar.rb b/lib/puppet/parser/functions/getvar.rb
index 1621149..fb336b6 100644
--- a/lib/puppet/parser/functions/getvar.rb
+++ b/lib/puppet/parser/functions/getvar.rb
@@ -19,7 +19,10 @@ module Puppet::Parser::Functions
raise Puppet::ParseError, ("getvar(): wrong number of arguments (#{args.length}; must be 1)")
end
- self.lookupvar("#{args[0]}")
+ begin
+ self.lookupvar("#{args[0]}")
+ rescue Puppet::ParseError # Eat the exception if strict_variables = true is set
+ end
end
diff --git a/lib/puppet/parser/functions/has_interface_with.rb b/lib/puppet/parser/functions/has_interface_with.rb
index 7f150a7..3691524 100644
--- a/lib/puppet/parser/functions/has_interface_with.rb
+++ b/lib/puppet/parser/functions/has_interface_with.rb
@@ -25,7 +25,7 @@ has_interface_with("lo") => true
interfaces = lookupvar('interfaces')
# If we do not have any interfaces, then there are no requested attributes
- return false if (interfaces == :undefined)
+ return false if (interfaces == :undefined || interfaces.nil?)
interfaces = interfaces.split(',')
@@ -35,13 +35,29 @@ has_interface_with("lo") => true
kind, value = args
- if lookupvar(kind) == value
+ # Bug with 3.7.1 - 3.7.3 when using future parser throws :undefined_variable
+ # https://tickets.puppetlabs.com/browse/PUP-3597
+ factval = nil
+ catch :undefined_variable do
+ factval = lookupvar(kind)
+ end
+ if factval == value
return true
end
result = false
interfaces.each do |iface|
- if value == lookupvar("#{kind}_#{iface}")
+ iface.downcase!
+ factval = nil
+ begin
+ # Bug with 3.7.1 - 3.7.3 when using future parser throws :undefined_variable
+ # https://tickets.puppetlabs.com/browse/PUP-3597
+ catch :undefined_variable do
+ factval = lookupvar("#{kind}_#{iface}")
+ end
+ rescue Puppet::ParseError # Eat the exception if strict_variables = true is set
+ end
+ if value == factval
result = true
break
end
diff --git a/lib/puppet/parser/functions/is_bool.rb b/lib/puppet/parser/functions/is_bool.rb
new file mode 100644
index 0000000..8bbdbc8
--- /dev/null
+++ b/lib/puppet/parser/functions/is_bool.rb
@@ -0,0 +1,22 @@
+#
+# is_bool.rb
+#
+
+module Puppet::Parser::Functions
+ newfunction(:is_bool, :type => :rvalue, :doc => <<-EOS
+Returns true if the variable passed to this function is a boolean.
+ EOS
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "is_bool(): Wrong number of arguments " +
+ "given (#{arguments.size} for 1)") if arguments.size != 1
+
+ type = arguments[0]
+
+ result = type.is_a?(TrueClass) || type.is_a?(FalseClass)
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/lib/puppet/parser/functions/is_domain_name.rb b/lib/puppet/parser/functions/is_domain_name.rb
index 5826dc0..b3fee96 100644
--- a/lib/puppet/parser/functions/is_domain_name.rb
+++ b/lib/puppet/parser/functions/is_domain_name.rb
@@ -20,6 +20,9 @@ Returns true if the string passed to this function is a syntactically correct do
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/is_float.rb b/lib/puppet/parser/functions/is_float.rb
index 911f3c2..a2da943 100644
--- a/lib/puppet/parser/functions/is_float.rb
+++ b/lib/puppet/parser/functions/is_float.rb
@@ -15,6 +15,9 @@ Returns true if the variable passed to this function is a float.
value = arguments[0]
+ # Only allow Numeric or String types
+ return false unless value.is_a?(Numeric) or value.is_a?(String)
+
if value != value.to_f.to_s and !value.is_a? Float then
return false
else
diff --git a/lib/puppet/parser/functions/is_function_available.rb b/lib/puppet/parser/functions/is_function_available.rb
index 6cbd35c..6da82c8 100644
--- a/lib/puppet/parser/functions/is_function_available.rb
+++ b/lib/puppet/parser/functions/is_function_available.rb
@@ -15,6 +15,9 @@ true if the function exists, false if not.
"given #{arguments.size} for 1")
end
+ # Only allow String types
+ return false unless arguments[0].is_a?(String)
+
function = Puppet::Parser::Functions.function(arguments[0].to_sym)
function.is_a?(String) and not function.empty?
end
diff --git a/lib/puppet/parser/functions/is_integer.rb b/lib/puppet/parser/functions/is_integer.rb
index 6b29e98..c03d28d 100644
--- a/lib/puppet/parser/functions/is_integer.rb
+++ b/lib/puppet/parser/functions/is_integer.rb
@@ -4,7 +4,12 @@
module Puppet::Parser::Functions
newfunction(:is_integer, :type => :rvalue, :doc => <<-EOS
-Returns true if the variable returned to this string is an integer.
+Returns true if the variable passed to this function is an Integer or
+a decimal (base 10) integer in String form. The string may
+start with a '-' (minus). A value of '0' is allowed, but a leading '0' digit may not
+be followed by other digits as this indicates that the value is octal (base 8).
+
+If given any other argument `false` is returned.
EOS
) do |arguments|
@@ -15,12 +20,25 @@ Returns true if the variable returned to this string is an integer.
value = arguments[0]
- if value != value.to_i.to_s and !value.is_a? Fixnum then
- return false
- else
+ # Regex is taken from the lexer of puppet
+ # puppet/pops/parser/lexer.rb but modified to match also
+ # negative values and disallow numbers prefixed with multiple
+ # 0's
+ #
+ # TODO these parameter should be a constant but I'm not sure
+ # if there is no risk to declare it inside of the module
+ # Puppet::Parser::Functions
+
+ # Integer numbers like
+ # -1234568981273
+ # 47291
+ numeric = %r{^-?(?:(?:[1-9]\d*)|0)$}
+
+ if value.is_a? Integer or (value.is_a? String and value.match numeric)
return true
+ else
+ return false
end
-
end
end
diff --git a/lib/puppet/parser/functions/is_numeric.rb b/lib/puppet/parser/functions/is_numeric.rb
index abf0321..e7e1d2a 100644
--- a/lib/puppet/parser/functions/is_numeric.rb
+++ b/lib/puppet/parser/functions/is_numeric.rb
@@ -4,7 +4,23 @@
module Puppet::Parser::Functions
newfunction(:is_numeric, :type => :rvalue, :doc => <<-EOS
-Returns true if the variable passed to this function is a number.
+Returns true if the given argument is a Numeric (Integer or Float),
+or a String containing either a valid integer in decimal base 10 form, or
+a valid floating point string representation.
+
+The function recognizes only decimal (base 10) integers and float but not
+integers in hex (base 16) or octal (base 8) form.
+
+The string representation may start with a '-' (minus). If a decimal '.' is used,
+it must be followed by at least one digit.
+
+Valid examples:
+
+ 77435
+ 10e-12
+ -8475
+ 0.2343
+ -23.561e3
EOS
) do |arguments|
@@ -15,12 +31,44 @@ Returns true if the variable passed to this function is a number.
value = arguments[0]
- if value == value.to_f.to_s or value == value.to_i.to_s or value.is_a? Numeric then
+ # Regex is taken from the lexer of puppet
+ # puppet/pops/parser/lexer.rb but modified to match also
+ # negative values and disallow invalid octal numbers or
+ # numbers prefixed with multiple 0's (except in hex numbers)
+ #
+ # TODO these parameters should be constants but I'm not sure
+ # if there is no risk to declare them inside of the module
+ # Puppet::Parser::Functions
+
+ # TODO decide if this should be used
+ # HEX numbers like
+ # 0xaa230F
+ # 0X1234009C
+ # 0x0012
+ # -12FcD
+ #numeric_hex = %r{^-?0[xX][0-9A-Fa-f]+$}
+
+ # TODO decide if this should be used
+ # OCTAL numbers like
+ # 01234567
+ # -045372
+ #numeric_oct = %r{^-?0[1-7][0-7]*$}
+
+ # Integer/Float numbers like
+ # -0.1234568981273
+ # 47291
+ # 42.12345e-12
+ numeric = %r{^-?(?:(?:[1-9]\d*)|0)(?:\.\d+)?(?:[eE]-?\d+)?$}
+
+ if value.is_a? Numeric or (value.is_a? String and (
+ value.match(numeric) #or
+ # value.match(numeric_hex) or
+ # value.match(numeric_oct)
+ ))
return true
else
return false
end
-
end
end
diff --git a/lib/puppet/parser/functions/join.rb b/lib/puppet/parser/functions/join.rb
index 005a46e..6c0a6ba 100644
--- a/lib/puppet/parser/functions/join.rb
+++ b/lib/puppet/parser/functions/join.rb
@@ -4,7 +4,7 @@
module Puppet::Parser::Functions
newfunction(:join, :type => :rvalue, :doc => <<-EOS
-This function joins an array into a string using a seperator.
+This function joins an array into a string using a separator.
*Examples:*
diff --git a/lib/puppet/parser/functions/lstrip.rb b/lib/puppet/parser/functions/lstrip.rb
index 3a64de3..624e4c8 100644
--- a/lib/puppet/parser/functions/lstrip.rb
+++ b/lib/puppet/parser/functions/lstrip.rb
@@ -12,9 +12,8 @@ Strips leading spaces to the left of a string.
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
- klass = value.class
- unless [Array, String].include?(klass)
+ unless value.is_a?(Array) || value.is_a?(String)
raise(Puppet::ParseError, 'lstrip(): Requires either ' +
'array or string to work with')
end
diff --git a/lib/puppet/parser/functions/member.rb b/lib/puppet/parser/functions/member.rb
index 43d76af..88609ce 100644
--- a/lib/puppet/parser/functions/member.rb
+++ b/lib/puppet/parser/functions/member.rb
@@ -8,6 +8,7 @@
module Puppet::Parser::Functions
newfunction(:member, :type => :rvalue, :doc => <<-EOS
This function determines if a variable is a member of an array.
+The variable can be a string, fixnum, or array.
*Examples:*
@@ -15,9 +16,17 @@ This function determines if a variable is a member of an array.
Would return: true
+ member(['a', 'b', 'c'], ['a', 'b'])
+
+would return: true
+
member(['a','b'], 'c')
Would return: false
+
+ member(['a', 'b', 'c'], ['d', 'b'])
+
+would return: false
EOS
) do |arguments|
@@ -30,12 +39,21 @@ Would return: false
raise(Puppet::ParseError, 'member(): Requires array to work with')
end
- item = arguments[1]
+ unless arguments[1].is_a? String or arguments[1].is_a? Fixnum or arguments[1].is_a? Array
+ raise(Puppet::ParseError, 'member(): Item to search for must be a string, fixnum, or array')
+ end
+
+ if arguments[1].is_a? String or arguments[1].is_a? Fixnum
+ item = Array(arguments[1])
+ else
+ item = arguments[1]
+ end
+
raise(Puppet::ParseError, 'member(): You must provide item ' +
- 'to search for within array given') if item.empty?
+ 'to search for within array given') if item.respond_to?('empty?') && item.empty?
- result = array.include?(item)
+ result = (item - array).empty?
return result
end
diff --git a/lib/puppet/parser/functions/pick.rb b/lib/puppet/parser/functions/pick.rb
index cbc0300..fdd0aef 100644
--- a/lib/puppet/parser/functions/pick.rb
+++ b/lib/puppet/parser/functions/pick.rb
@@ -21,7 +21,7 @@ EOS
args.delete(:undefined)
args.delete("")
if args[0].to_s.empty? then
- fail "Must provide non empty value."
+ fail Puppet::ParseError, "pick(): must receive at least one non empty value"
else
return args[0]
end
diff --git a/lib/puppet/parser/functions/pick_default.rb b/lib/puppet/parser/functions/pick_default.rb
new file mode 100644
index 0000000..36e33ab
--- /dev/null
+++ b/lib/puppet/parser/functions/pick_default.rb
@@ -0,0 +1,35 @@
+module Puppet::Parser::Functions
+ newfunction(:pick_default, :type => :rvalue, :doc => <<-EOS
+
+This function is similar to a coalesce function in SQL in that it will return
+the first value in a list of values that is not undefined or an empty string
+(two things in Puppet that will return a boolean false value). If no value is
+found, it will return the last argument.
+
+Typically, this function is used to check for a value in the Puppet
+Dashboard/Enterprise Console, and failover to a default value like the
+following:
+
+ $real_jenkins_version = pick_default($::jenkins_version, '1.449')
+
+The value of $real_jenkins_version will first look for a top-scope variable
+called 'jenkins_version' (note that parameters set in the Puppet Dashboard/
+Enterprise Console are brought into Puppet as top-scope variables), and,
+failing that, will use a default value of 1.449.
+
+Note that, contrary to the pick() function, the pick_default does not fail if
+all arguments are empty. This allows pick_default to use an empty value as
+default.
+
+EOS
+) do |args|
+ fail "Must receive at least one argument." if args.empty?
+ default = args.last
+ args = args[0..-2].compact
+ args.delete(:undef)
+ args.delete(:undefined)
+ args.delete("")
+ args << default
+ return args[0]
+ end
+end
diff --git a/lib/puppet/parser/functions/prefix.rb b/lib/puppet/parser/functions/prefix.rb
index 62211ae..d02286a 100644
--- a/lib/puppet/parser/functions/prefix.rb
+++ b/lib/puppet/parser/functions/prefix.rb
@@ -28,7 +28,7 @@ Will return: ['pa','pb','pc']
if prefix
unless prefix.is_a?(String)
- raise Puppet::ParseError, "prefix(): expected second argument to be a String, got #{suffix.inspect}"
+ raise Puppet::ParseError, "prefix(): expected second argument to be a String, got #{prefix.inspect}"
end
end
diff --git a/lib/puppet/parser/functions/private.rb b/lib/puppet/parser/functions/private.rb
new file mode 100644
index 0000000..60210d3
--- /dev/null
+++ b/lib/puppet/parser/functions/private.rb
@@ -0,0 +1,29 @@
+#
+# private.rb
+#
+
+module Puppet::Parser::Functions
+ newfunction(:private, :doc => <<-'EOS'
+ Sets the current class or definition as private.
+ Calling the class or definition from outside the current module will fail.
+ EOS
+ ) do |args|
+
+ raise(Puppet::ParseError, "private(): Wrong number of arguments "+
+ "given (#{args.size}}) for 0 or 1)") if args.size > 1
+
+ scope = self
+ if scope.lookupvar('module_name') != scope.lookupvar('caller_module_name')
+ message = nil
+ if args[0] and args[0].is_a? String
+ message = args[0]
+ else
+ manifest_name = scope.source.name
+ manifest_type = scope.source.type
+ message = (manifest_type.to_s == 'hostclass') ? 'Class' : 'Definition'
+ message += " #{manifest_name} is private"
+ end
+ raise(Puppet::ParseError, message)
+ end
+ end
+end
diff --git a/lib/puppet/parser/functions/range.rb b/lib/puppet/parser/functions/range.rb
index 0849491..49fba21 100644
--- a/lib/puppet/parser/functions/range.rb
+++ b/lib/puppet/parser/functions/range.rb
@@ -28,7 +28,7 @@ Will return: ["a","b","c"]
Will return: ["host01", "host02", ..., "host09", "host10"]
-Passing a third argument will cause the generated range to step by that
+Passing a third argument will cause the generated range to step by that
interval, e.g.
range("0", "9", "2")
@@ -65,21 +65,21 @@ Will return: [0,2,4,6,8]
end
end
- # Check whether we have integer value if so then make it so ...
- if start.match(/^\d+$/)
- start = start.to_i
- stop = stop.to_i
- else
- start = start.to_s
- stop = stop.to_s
- end
+ # Check whether we have integer value if so then make it so ...
+ if start.to_s.match(/^\d+$/)
+ start = start.to_i
+ stop = stop.to_i
+ else
+ start = start.to_s
+ stop = stop.to_s
+ end
- range = case type
- when /^(\.\.|\-)$/ then (start .. stop)
- when /^(\.\.\.)$/ then (start ... stop) # Exclusive of last element ...
- end
+ range = case type
+ when /^(\.\.|\-)$/ then (start .. stop)
+ when /^(\.\.\.)$/ then (start ... stop) # Exclusive of last element ...
+ end
- result = range.step(step).collect { |i| i } # Get them all ... Pokemon ...
+ result = range.step(step).collect { |i| i } # Get them all ... Pokemon ...
return result
end
diff --git a/lib/puppet/parser/functions/reverse.rb b/lib/puppet/parser/functions/reverse.rb
index fe04869..7f1018f 100644
--- a/lib/puppet/parser/functions/reverse.rb
+++ b/lib/puppet/parser/functions/reverse.rb
@@ -12,9 +12,8 @@ Reverses the order of a string or array.
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
- klass = value.class
- unless [Array, String].include?(klass)
+ unless value.is_a?(Array) || value.is_a?(String)
raise(Puppet::ParseError, 'reverse(): Requires either ' +
'array or string to work with')
end
diff --git a/lib/puppet/parser/functions/rstrip.rb b/lib/puppet/parser/functions/rstrip.rb
index 29b0998..0cf8d22 100644
--- a/lib/puppet/parser/functions/rstrip.rb
+++ b/lib/puppet/parser/functions/rstrip.rb
@@ -12,9 +12,8 @@ Strips leading spaces to the right of the string.
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
- klass = value.class
- unless [Array, String].include?(klass)
+ unless value.is_a?(Array) || value.is_a?(String)
raise(Puppet::ParseError, 'rstrip(): Requires either ' +
'array or string to work with')
end
diff --git a/lib/puppet/parser/functions/shuffle.rb b/lib/puppet/parser/functions/shuffle.rb
index 18134ab..30c663d 100644
--- a/lib/puppet/parser/functions/shuffle.rb
+++ b/lib/puppet/parser/functions/shuffle.rb
@@ -12,9 +12,8 @@ Randomizes the order of a string or array elements.
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
- klass = value.class
- unless [Array, String].include?(klass)
+ unless value.is_a?(Array) || value.is_a?(String)
raise(Puppet::ParseError, 'shuffle(): Requires either ' +
'array or string to work with')
end
diff --git a/lib/puppet/parser/functions/str2bool.rb b/lib/puppet/parser/functions/str2bool.rb
index fece7a6..446732e 100644
--- a/lib/puppet/parser/functions/str2bool.rb
+++ b/lib/puppet/parser/functions/str2bool.rb
@@ -14,7 +14,7 @@ like: 0, f, n, false, no to 'false'.
"given (#{arguments.size} for 1)") if arguments.size < 1
string = arguments[0]
-
+
# If string is already Boolean, return it
if !!string == string
return string
diff --git a/lib/puppet/parser/functions/strip.rb b/lib/puppet/parser/functions/strip.rb
index 5f4630d..3fac47d 100644
--- a/lib/puppet/parser/functions/strip.rb
+++ b/lib/puppet/parser/functions/strip.rb
@@ -19,9 +19,8 @@ Would result in: "aaa"
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
- klass = value.class
- unless [Array, String].include?(klass)
+ unless value.is_a?(Array) || value.is_a?(String)
raise(Puppet::ParseError, 'strip(): Requires either ' +
'array or string to work with')
end
diff --git a/lib/puppet/parser/functions/swapcase.rb b/lib/puppet/parser/functions/swapcase.rb
index b9e6632..eb7fe13 100644
--- a/lib/puppet/parser/functions/swapcase.rb
+++ b/lib/puppet/parser/functions/swapcase.rb
@@ -18,9 +18,8 @@ Would result in: "AbCd"
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
- klass = value.class
- unless [Array, String].include?(klass)
+ unless value.is_a?(Array) || value.is_a?(String)
raise(Puppet::ParseError, 'swapcase(): Requires either ' +
'array or string to work with')
end
diff --git a/lib/puppet/parser/functions/to_bytes.rb b/lib/puppet/parser/functions/to_bytes.rb
index 8ff73d1..df490ea 100644
--- a/lib/puppet/parser/functions/to_bytes.rb
+++ b/lib/puppet/parser/functions/to_bytes.rb
@@ -2,6 +2,8 @@ module Puppet::Parser::Functions
newfunction(:to_bytes, :type => :rvalue, :doc => <<-EOS
Converts the argument into bytes, for example 4 kB becomes 4096.
Takes a single string value as an argument.
+ These conversions reflect a layperson's understanding of
+ 1 MB = 1024 KB, when in fact 1 MB = 1000 KB, and 1 MiB = 1024 KiB.
EOS
) do |arguments|
@@ -21,7 +23,8 @@ module Puppet::Parser::Functions
when 'M' then return (value*(1<<20)).to_i
when 'G' then return (value*(1<<30)).to_i
when 'T' then return (value*(1<<40)).to_i
- when 'E' then return (value*(1<<50)).to_i
+ when 'P' then return (value*(1<<50)).to_i
+ when 'E' then return (value*(1<<60)).to_i
else raise Puppet::ParseError, "to_bytes(): Unknown prefix #{prefix}"
end
end
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/unique.rb b/lib/puppet/parser/functions/unique.rb
index 8844a74..cf770f3 100644
--- a/lib/puppet/parser/functions/unique.rb
+++ b/lib/puppet/parser/functions/unique.rb
@@ -28,9 +28,8 @@ This returns:
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
- klass = value.class
- unless [Array, String].include?(klass)
+ unless value.is_a?(Array) || value.is_a?(String)
raise(Puppet::ParseError, 'unique(): Requires either ' +
'array or string to work with')
end
diff --git a/lib/puppet/parser/functions/upcase.rb b/lib/puppet/parser/functions/upcase.rb
index fe6cadc..4302b29 100644
--- a/lib/puppet/parser/functions/upcase.rb
+++ b/lib/puppet/parser/functions/upcase.rb
@@ -20,9 +20,8 @@ Will return:
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
- klass = value.class
- unless [Array, String].include?(klass)
+ unless value.is_a?(Array) || value.is_a?(String)
raise(Puppet::ParseError, 'upcase(): Requires either ' +
'array or string to work with')
end
diff --git a/lib/puppet/parser/functions/uriescape.rb b/lib/puppet/parser/functions/uriescape.rb
index 0d81de5..a486eee 100644
--- a/lib/puppet/parser/functions/uriescape.rb
+++ b/lib/puppet/parser/functions/uriescape.rb
@@ -14,9 +14,8 @@ module Puppet::Parser::Functions
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
- klass = value.class
- unless [Array, String].include?(klass)
+ unless value.is_a?(Array) || value.is_a?(String)
raise(Puppet::ParseError, 'uriescape(): Requires either ' +
'array or string to work with')
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_augeas.rb b/lib/puppet/parser/functions/validate_augeas.rb
index 154d660..4ea4fe0 100644
--- a/lib/puppet/parser/functions/validate_augeas.rb
+++ b/lib/puppet/parser/functions/validate_augeas.rb
@@ -1,3 +1,5 @@
+require 'tempfile'
+
module Puppet::Parser::Functions
newfunction(:validate_augeas, :doc => <<-'ENDHEREDOC') do |args|
Perform validation of a string using an Augeas lens
diff --git a/lib/puppet/parser/functions/validate_bool.rb b/lib/puppet/parser/functions/validate_bool.rb
index 62c1d88..59a0805 100644
--- a/lib/puppet/parser/functions/validate_bool.rb
+++ b/lib/puppet/parser/functions/validate_bool.rb
@@ -24,7 +24,7 @@ module Puppet::Parser::Functions
end
args.each do |arg|
- unless (arg.is_a?(TrueClass) || arg.is_a?(FalseClass))
+ unless function_is_bool([arg])
raise Puppet::ParseError, ("#{arg.inspect} is not a boolean. It looks to be a #{arg.class}")
end
end
diff --git a/lib/puppet/parser/functions/validate_cmd.rb b/lib/puppet/parser/functions/validate_cmd.rb
index 344a80c..5df3c60 100644
--- a/lib/puppet/parser/functions/validate_cmd.rb
+++ b/lib/puppet/parser/functions/validate_cmd.rb
@@ -1,13 +1,14 @@
require 'puppet/util/execution'
+require 'tempfile'
module Puppet::Parser::Functions
newfunction(:validate_cmd, :doc => <<-'ENDHEREDOC') do |args|
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.
@@ -16,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)")
@@ -32,14 +37,25 @@ module Puppet::Parser::Functions
tmpfile = Tempfile.new("validate_cmd")
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}"
raise Puppet::ParseError, msg
+ rescue Exception => detail
+ msg += "\n#{detail.class.name} #{detail}"
+ raise Puppet::ParseError, msg
ensure
tmpfile.unlink
end
diff --git a/lib/puppet/parser/functions/validate_string.rb b/lib/puppet/parser/functions/validate_string.rb
index e667794..c841f6a 100644
--- a/lib/puppet/parser/functions/validate_string.rb
+++ b/lib/puppet/parser/functions/validate_string.rb
@@ -13,9 +13,14 @@ module Puppet::Parser::Functions
validate_string(true)
validate_string([ 'some', 'array' ])
- $undefined = undef
- validate_string($undefined)
-
+
+ Note: validate_string(undef) will not fail in this version of the
+ functions API (incl. current and future parser). Instead, use:
+
+ if $var == undef {
+ fail('...')
+ }
+
ENDHEREDOC
unless args.length > 0 then
diff --git a/lib/puppet/parser/functions/values_at.rb b/lib/puppet/parser/functions/values_at.rb
index d3e69d9..f350f53 100644
--- a/lib/puppet/parser/functions/values_at.rb
+++ b/lib/puppet/parser/functions/values_at.rb
@@ -49,6 +49,7 @@ Would return ['a','c','d'].
indices_list = []
indices.each do |i|
+ i = i.to_s
if m = i.match(/^(\d+)(\.\.\.?|\-)(\d+)$/)
start = m[1].to_i
stop = m[3].to_i
diff --git a/lib/puppet/parser/functions/zip.rb b/lib/puppet/parser/functions/zip.rb
index 2b56e9c..3074f28 100644
--- a/lib/puppet/parser/functions/zip.rb
+++ b/lib/puppet/parser/functions/zip.rb
@@ -27,33 +27,7 @@ Would result in:
raise(Puppet::ParseError, 'zip(): Requires array to work with')
end
- flatten = arguments[2] if arguments[2]
-
- if flatten
- klass = flatten.class
-
- # We can have either true or false, or string which resembles boolean ...
- unless [FalseClass, TrueClass, String].include?(klass)
- raise(Puppet::ParseError, 'zip(): Requires either ' +
- 'boolean or string to work with')
- end
-
- if flatten.is_a?(String)
- # We consider all the yes, no, y, n and so on too ...
- flatten = case flatten
- #
- # This is how undef looks like in Puppet ...
- # We yield false in this case.
- #
- when /^$/, '' then false # Empty string will be false ...
- when /^(1|t|y|true|yes)$/ then true
- when /^(0|f|n|false|no)$/ then false
- when /^(undef|undefined)$/ then false # This is not likely to happen ...
- else
- raise(Puppet::ParseError, 'zip(): Unknown type of boolean given')
- end
- end
- end
+ flatten = function_str2bool([arguments[2]]) if arguments[2]
result = a.zip(b)
result = flatten ? result.flatten : result
diff --git a/lib/puppet/provider/file_line/ruby.rb b/lib/puppet/provider/file_line/ruby.rb
index 3cb9f6e..ae1a8b3 100644
--- a/lib/puppet/provider/file_line/ruby.rb
+++ b/lib/puppet/provider/file_line/ruby.rb
@@ -1,5 +1,4 @@
Puppet::Type.type(:file_line).provide(:ruby) do
-
def exists?
lines.find do |line|
line.chomp == resource[:line].chomp
@@ -8,9 +7,11 @@ Puppet::Type.type(:file_line).provide(:ruby) do
def create
if resource[:match]
- handle_create_with_match()
+ handle_create_with_match
+ elsif resource[:after]
+ handle_create_with_after
else
- handle_create_without_match()
+ append_line
end
end
@@ -33,7 +34,7 @@ Puppet::Type.type(:file_line).provide(:ruby) do
def handle_create_with_match()
regex = resource[:match] ? Regexp.new(resource[:match]) : nil
- match_count = lines.select { |l| regex.match(l) }.size
+ match_count = count_matches(regex)
if match_count > 1 && resource[:multiple].to_s != 'true'
raise Puppet::Error, "More than one line in file '#{resource[:path]}' matches pattern '#{resource[:match]}'"
end
@@ -48,11 +49,37 @@ Puppet::Type.type(:file_line).provide(:ruby) do
end
end
- def handle_create_without_match
- File.open(resource[:path], 'a') do |fh|
- fh.puts resource[:line]
+ def handle_create_with_after
+ regex = Regexp.new(resource[:after])
+ count = count_matches(regex)
+ case count
+ when 1 # find the line to put our line after
+ File.open(resource[:path], 'w') do |fh|
+ lines.each do |l|
+ fh.puts(l)
+ if regex.match(l) then
+ fh.puts(resource[:line])
+ end
+ end
+ end
+ when 0 # append the line to the end of the file
+ append_line
+ else
+ raise Puppet::Error, "#{count} lines match pattern '#{resource[:after]}' in file '#{resource[:path]}'. One or no line must match the pattern."
end
end
+ def count_matches(regex)
+ lines.select{|l| l.match(regex)}.size
+ end
+ ##
+ # append the line to the file.
+ #
+ # @api private
+ def append_line
+ File.open(resource[:path], 'a') do |fh|
+ fh.puts resource[:line]
+ end
+ end
end
diff --git a/lib/puppet/type/file_line.rb b/lib/puppet/type/file_line.rb
index 14946bb..df263e6 100644
--- a/lib/puppet/type/file_line.rb
+++ b/lib/puppet/type/file_line.rb
@@ -21,6 +21,9 @@ Puppet::Type.newtype(:file_line) do
In this example, Puppet will ensure both of the specified lines are
contained in the file /etc/sudoers.
+ **Autorequires:** If Puppet is managing the file that will contain the line
+ being managed, the file_line resource will autorequire that file.
+
EOT
ensurable do
@@ -42,6 +45,10 @@ Puppet::Type.newtype(:file_line) do
newvalues(true, false)
end
+ newparam(:after) do
+ desc 'An optional value used to specify the line after which we will add any new lines. (Existing lines are added in place)'
+ end
+
newparam(:line) do
desc 'The line to be appended to the file located by the path parameter.'
end
@@ -64,12 +71,5 @@ Puppet::Type.newtype(:file_line) do
unless self[:line] and self[:path]
raise(Puppet::Error, "Both line and path are required attributes")
end
-
- if (self[:match])
- unless Regexp.new(self[:match]).match(self[:line])
- raise(Puppet::Error, "When providing a 'match' parameter, the value must be a regex that matches against the value of your 'line' parameter")
- end
- end
-
end
end