summaryrefslogtreecommitdiff
path: root/code/environments/production/modules/stdlib/lib
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2018-09-20 14:49:52 +0200
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2018-09-20 14:49:52 +0200
commit774cf89157a6c5af2566d98607a8b9aa655e33b0 (patch)
treecc7a73cb9e941b0338771653bdc301c80f2e61c7 /code/environments/production/modules/stdlib/lib
parent9513b93a992470e21e387db1451fa4fd21ffc5d6 (diff)
downloadpuppet.OvG-774cf89157a6c5af2566d98607a8b9aa655e33b0.tar.gz
puppet.OvG-774cf89157a6c5af2566d98607a8b9aa655e33b0.tar.bz2
puppet.OvG-774cf89157a6c5af2566d98607a8b9aa655e33b0.zip
Bundle puppetlabs-stdlib 4.25.1.
Diffstat (limited to 'code/environments/production/modules/stdlib/lib')
-rw-r--r--code/environments/production/modules/stdlib/lib/facter/facter_dot_d.rb194
-rw-r--r--code/environments/production/modules/stdlib/lib/facter/package_provider.rb21
-rw-r--r--code/environments/production/modules/stdlib/lib/facter/pe_version.rb61
-rw-r--r--code/environments/production/modules/stdlib/lib/facter/puppet_settings.rb42
-rw-r--r--code/environments/production/modules/stdlib/lib/facter/root_home.rb44
-rw-r--r--code/environments/production/modules/stdlib/lib/facter/service_provider.rb17
-rw-r--r--code/environments/production/modules/stdlib/lib/facter/util/puppet_settings.rb16
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/deprecation.rb32
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/fact.rb57
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/is_a.rb32
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/is_absolute_path.rb17
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/is_array.rb17
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/is_bool.rb17
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/is_float.rb17
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/is_ip_address.rb17
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/is_ipv4_address.rb17
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/is_ipv6_address.rb17
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/is_numeric.rb17
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/is_string.rb17
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/length.rb14
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/sprintf_hash.rb29
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/to_json.rb21
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/to_json_pretty.rb38
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/to_yaml.rb21
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/type_of.rb19
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/validate_absolute_path.rb18
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/validate_array.rb18
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/validate_bool.rb18
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/validate_hash.rb18
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/validate_integer.rb18
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/validate_ip_address.rb18
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/validate_ipv4_address.rb18
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/validate_ipv6_address.rb18
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/validate_legacy.rb62
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/validate_numeric.rb18
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/validate_re.rb18
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/validate_slength.rb18
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/functions/validate_string.rb18
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/abs.rb33
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/any2array.rb29
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/any2bool.rb53
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/assert_private.rb27
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/base64.rb67
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/basename.rb24
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/bool2num.rb24
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/bool2str.rb43
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/camelcase.rb31
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/capitalize.rb29
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/ceiling.rb25
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/chomp.rb31
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/chop.rb33
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/clamp.rb28
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/concat.rb39
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/convert_base.rb36
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/count.rb24
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/deep_merge.rb47
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/defined_with_params.rb57
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete.rb42
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete_at.rb45
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete_regex.rb43
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete_undef_values.rb34
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete_values.rb26
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/deprecation.rb19
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/difference.rb34
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/dig.rb15
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/dig44.rb65
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/dirname.rb24
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/dos2unix.rb15
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/downcase.rb30
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/empty.rb23
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/enclose_ipv6.rb41
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/ensure_packages.rb50
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/ensure_resource.rb46
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/ensure_resources.rb50
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/flatten.rb31
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/floor.rb25
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/fqdn_rand_string.rb35
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/fqdn_rotate.rb59
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/fqdn_uuid.rb86
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/get_module_path.rb18
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/getparam.rb36
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/getvar.rb35
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/glob.rb25
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/grep.rb30
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/has_interface_with.rb69
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/has_ip_address.rb22
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/has_ip_network.rb22
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/has_key.rb28
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/hash.rb38
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/intersection.rb31
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_absolute_path.rb54
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_array.rb21
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_bool.rb21
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_domain_name.rb51
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_email_address.rb19
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_float.rb27
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_function_available.rb24
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_hash.rb20
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_integer.rb43
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_ip_address.rb30
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_ipv4_address.rb29
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_ipv6_address.rb29
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_mac_address.rb21
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_numeric.rb74
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_string.rb28
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/join.rb39
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/join_keys_to_values.rb53
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/keys.rb24
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/load_module_metadata.rb25
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/loadjson.rb32
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/loadyaml.rb32
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/lstrip.rb29
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/max.rb23
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/member.rb57
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/merge.rb37
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/min.rb23
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/num2bool.rb41
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/parsejson.rb24
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/parseyaml.rb28
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/pick.rb27
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/pick_default.rb36
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/prefix.rb50
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/private.rb16
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/pry.rb29
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/pw_hash.rb62
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/range.rb84
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/regexpescape.rb29
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/reject.rb30
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/reverse.rb24
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/round.rb32
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/rstrip.rb28
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/seeded_rand.rb24
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/shell_escape.rb27
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/shell_join.rb29
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/shell_split.rb23
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/shuffle.rb42
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/size.rb44
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/sort.rb25
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/squeeze.rb31
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/str2bool.rb43
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/str2saltedsha512.rb30
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/strftime.rb105
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/strip.rb35
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/suffix.rb51
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/swapcase.rb36
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/time.rb48
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/to_bytes.rb33
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/try_get_value.rb56
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/type.rb18
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/type3x.rb49
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/union.rb27
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/unique.rb51
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/unix2dos.rb15
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/upcase.rb43
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/uriescape.rb32
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_absolute_path.rb54
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_array.rb36
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_augeas.rb86
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_bool.rb34
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_cmd.rb66
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_domain_name.rb42
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_email_address.rb34
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_hash.rb36
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_integer.rb137
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_ip_address.rb53
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_ipv4_address.rb51
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_ipv6_address.rb52
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_numeric.rb99
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_re.rb53
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_slength.rb71
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_string.rb42
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_x509_rsa_key_pair.rb48
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/values.rb37
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/values_at.rb89
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/parser/functions/zip.rb37
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/provider/file_line/ruby.rb171
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/type/anchor.rb46
-rw-r--r--code/environments/production/modules/stdlib/lib/puppet/type/file_line.rb192
178 files changed, 6849 insertions, 0 deletions
diff --git a/code/environments/production/modules/stdlib/lib/facter/facter_dot_d.rb b/code/environments/production/modules/stdlib/lib/facter/facter_dot_d.rb
new file mode 100644
index 0000000..5025ed9
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/facter/facter_dot_d.rb
@@ -0,0 +1,194 @@
+# A Facter plugin that loads facts from /etc/facter/facts.d
+# and /etc/puppetlabs/facter/facts.d.
+#
+# Facts can be in the form of JSON, YAML or Text files
+# and any executable that returns key=value pairs.
+#
+# In the case of scripts you can also create a file that
+# contains a cache TTL. For foo.sh store the ttl as just
+# a number in foo.sh.ttl
+#
+# The cache is stored in $libdir/facts_dot_d.cache as a mode
+# 600 file and will have the end result of not calling your
+# fact scripts more often than is needed
+class Facter::Util::DotD
+ require 'yaml'
+
+ def initialize(dir = '/etc/facts.d', cache_file = File.join(Puppet[:libdir], 'facts_dot_d.cache'))
+ @dir = dir
+ @cache_file = cache_file
+ @cache = nil
+ @types = { '.txt' => :txt, '.json' => :json, '.yaml' => :yaml }
+ end
+
+ def entries
+ Dir.entries(@dir).reject { |f| f =~ %r{^\.|\.ttl$} }.sort.map { |f| File.join(@dir, f) }
+ rescue
+ []
+ end
+
+ def fact_type(file)
+ extension = File.extname(file)
+
+ type = @types[extension] || :unknown
+
+ type = :script if type == :unknown && File.executable?(file)
+
+ type
+ end
+
+ def txt_parser(file)
+ File.readlines(file).each do |line|
+ next unless line =~ %r{^([^=]+)=(.+)$}
+ var = Regexp.last_match(1)
+ val = Regexp.last_match(2)
+
+ Facter.add(var) do
+ setcode { val }
+ end
+ end
+ rescue StandardError => e
+ Facter.warn("Failed to handle #{file} as text facts: #{e.class}: #{e}")
+ end
+
+ def json_parser(file)
+ begin
+ require 'json'
+ rescue LoadError
+ retry if require 'rubygems'
+ raise
+ end
+
+ JSON.parse(File.read(file)).each_pair do |f, v|
+ Facter.add(f) do
+ setcode { v }
+ end
+ end
+ rescue StandardError => e
+ Facter.warn("Failed to handle #{file} as json facts: #{e.class}: #{e}")
+ end
+
+ def yaml_parser(file)
+ require 'yaml'
+
+ YAML.load_file(file).each_pair do |f, v|
+ Facter.add(f) do
+ setcode { v }
+ end
+ end
+ rescue StandardError => e
+ Facter.warn("Failed to handle #{file} as yaml facts: #{e.class}: #{e}")
+ end
+
+ def script_parser(file)
+ result = cache_lookup(file)
+ ttl = cache_time(file)
+
+ if result
+ Facter.debug("Using cached data for #{file}")
+ else
+ result = Facter::Util::Resolution.exec(file)
+
+ if ttl > 0
+ Facter.debug("Updating cache for #{file}")
+ cache_store(file, result)
+ cache_save!
+ end
+ end
+
+ result.split("\n").each do |line|
+ next unless line =~ %r{^(.+)=(.+)$}
+ var = Regexp.last_match(1)
+ val = Regexp.last_match(2)
+
+ Facter.add(var) do
+ setcode { val }
+ end
+ end
+ rescue StandardError => e
+ Facter.warn("Failed to handle #{file} as script facts: #{e.class}: #{e}")
+ Facter.debug(e.backtrace.join("\n\t"))
+ end
+
+ def cache_save!
+ cache = load_cache
+ File.open(@cache_file, 'w', 0o600) { |f| f.write(YAML.dump(cache)) }
+ rescue # rubocop:disable Lint/HandleExceptions
+ end
+
+ def cache_store(file, data)
+ load_cache
+
+ @cache[file] = { :data => data, :stored => Time.now.to_i }
+ rescue # rubocop:disable Lint/HandleExceptions
+ end
+
+ def cache_lookup(file)
+ cache = load_cache
+
+ return nil if cache.empty?
+
+ ttl = cache_time(file)
+
+ return nil unless cache[file]
+ now = Time.now.to_i
+
+ return cache[file][:data] if ttl == -1
+ return cache[file][:data] if (now - cache[file][:stored]) <= ttl
+ return nil
+ rescue
+ return nil
+ end
+
+ def cache_time(file)
+ meta = file + '.ttl'
+
+ return File.read(meta).chomp.to_i
+ rescue
+ return 0
+ end
+
+ def load_cache
+ @cache ||= if File.exist?(@cache_file)
+ YAML.load_file(@cache_file)
+ else
+ {}
+ end
+
+ return @cache
+ rescue
+ @cache = {}
+ return @cache
+ end
+
+ def create
+ entries.each do |fact|
+ type = fact_type(fact)
+ parser = "#{type}_parser"
+
+ next unless respond_to?("#{type}_parser")
+ Facter.debug("Parsing #{fact} using #{parser}")
+
+ send(parser, fact)
+ end
+ end
+end
+
+mdata = Facter.version.match(%r{(\d+)\.(\d+)\.(\d+)})
+if mdata
+ (major, minor, _patch) = mdata.captures.map { |v| v.to_i }
+ if major < 2
+ # Facter 1.7 introduced external facts support directly
+ unless major == 1 && minor > 6
+ Facter::Util::DotD.new('/etc/facter/facts.d').create
+ Facter::Util::DotD.new('/etc/puppetlabs/facter/facts.d').create
+
+ # Windows has a different configuration directory that defaults to a vendor
+ # specific sub directory of the %COMMON_APPDATA% directory.
+ if Dir.const_defined? 'COMMON_APPDATA' # rubocop:disable Metrics/BlockNesting : Any attempt to alter this breaks it
+ windows_facts_dot_d = File.join(Dir::COMMON_APPDATA, 'PuppetLabs', 'facter', 'facts.d')
+ Facter::Util::DotD.new(windows_facts_dot_d).create
+ end
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/facter/package_provider.rb b/code/environments/production/modules/stdlib/lib/facter/package_provider.rb
new file mode 100644
index 0000000..0aec171
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/facter/package_provider.rb
@@ -0,0 +1,21 @@
+# Fact: package_provider
+#
+# Purpose: Returns the default provider Puppet will choose to manage packages
+# on this system
+#
+# Resolution: Instantiates a dummy package resource and return the provider
+#
+# Caveats:
+#
+require 'puppet/type'
+require 'puppet/type/package'
+
+Facter.add(:package_provider) do
+ setcode do
+ if defined? Gem && Gem::Version.new(Facter.value(:puppetversion).split(' ')[0]) >= Gem::Version.new('3.6')
+ Puppet::Type.type(:package).newpackage(:name => 'dummy', :allow_virtual => 'true')[:provider].to_s
+ else
+ Puppet::Type.type(:package).newpackage(:name => 'dummy')[:provider].to_s
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/facter/pe_version.rb b/code/environments/production/modules/stdlib/lib/facter/pe_version.rb
new file mode 100644
index 0000000..594f9dc
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/facter/pe_version.rb
@@ -0,0 +1,61 @@
+# Fact: is_pe, pe_version, pe_major_version, pe_minor_version, pe_patch_version
+#
+# Purpose: Return various facts about the PE state of the system
+#
+# Resolution: Uses a regex match against puppetversion to determine whether the
+# machine has Puppet Enterprise installed, and what version (overall, major,
+# minor, patch) is installed.
+#
+# Caveats:
+#
+Facter.add('pe_version') do
+ setcode do
+ puppet_ver = Facter.value('puppetversion')
+ if !puppet_ver.nil?
+ pe_ver = puppet_ver.match(%r{Puppet Enterprise (\d+\.\d+\.\d+)})
+ pe_ver[1] if pe_ver
+ else
+ nil
+ end
+ end
+end
+
+Facter.add('is_pe') do
+ setcode do
+ if Facter.value(:pe_version).to_s.empty?
+ false
+ else
+ true
+ end
+ end
+end
+
+Facter.add('pe_major_version') do
+ confine :is_pe => true
+ setcode do
+ pe_version = Facter.value(:pe_version)
+ if pe_version
+ pe_version.to_s.split('.')[0]
+ end
+ end
+end
+
+Facter.add('pe_minor_version') do
+ confine :is_pe => true
+ setcode do
+ pe_version = Facter.value(:pe_version)
+ if pe_version
+ pe_version.to_s.split('.')[1]
+ end
+ end
+end
+
+Facter.add('pe_patch_version') do
+ confine :is_pe => true
+ setcode do
+ pe_version = Facter.value(:pe_version)
+ if pe_version
+ pe_version.to_s.split('.')[2]
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/facter/puppet_settings.rb b/code/environments/production/modules/stdlib/lib/facter/puppet_settings.rb
new file mode 100644
index 0000000..b932189
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/facter/puppet_settings.rb
@@ -0,0 +1,42 @@
+# These facter facts return the value of the Puppet vardir and environment path
+# settings for the node running puppet or puppet agent. The intent is to
+# enable Puppet modules to automatically have insight into a place where they
+# can place variable data, or for modules running on the puppet master to know
+# where environments are stored.
+#
+# The values should be directly usable in a File resource path attribute.
+#
+begin
+ require 'facter/util/puppet_settings'
+rescue LoadError => e
+ # puppet apply does not add module lib directories to the $LOAD_PATH (See
+ # #4248). It should (in the future) but for the time being we need to be
+ # defensive which is what this rescue block is doing.
+ rb_file = File.join(File.dirname(__FILE__), 'util', 'puppet_settings.rb')
+ load rb_file if File.exist?(rb_file) || raise(e)
+end
+
+# These will be nil if Puppet is not available.
+Facter.add(:puppet_vardir) do
+ setcode do
+ Facter::Util::PuppetSettings.with_puppet do
+ Puppet[:vardir]
+ end
+ end
+end
+
+Facter.add(:puppet_environmentpath) do
+ setcode do
+ Facter::Util::PuppetSettings.with_puppet do
+ Puppet[:environmentpath]
+ end
+ end
+end
+
+Facter.add(:puppet_server) do
+ setcode do
+ Facter::Util::PuppetSettings.with_puppet do
+ Puppet[:server]
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/facter/root_home.rb b/code/environments/production/modules/stdlib/lib/facter/root_home.rb
new file mode 100644
index 0000000..d4add7b
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/facter/root_home.rb
@@ -0,0 +1,44 @@
+# A facter fact to determine the root home directory.
+# This varies on PE supported platforms and may be
+# reconfigured by the end user.
+module Facter::Util::RootHome
+ class << self
+ def returnt_root_home
+ root_ent = Facter::Util::Resolution.exec('getent passwd root')
+ # The home directory is the sixth element in the passwd entry
+ # If the platform doesn't have getent, root_ent will be nil and we should
+ # return it straight away.
+ root_ent && root_ent.split(':')[5]
+ end
+ end
+end
+
+Facter.add(:root_home) do
+ setcode { Facter::Util::RootHome.returnt_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(%r{:})
+ hash[key] = value
+ end
+ hash['dir'].strip
+ end
+end
+
+Facter.add(:root_home) do
+ confine :kernel => :aix
+ root_home = nil
+ setcode do
+ str = Facter::Util::Resolution.exec('lsuser -c -a home root')
+ str && str.split("\n").each do |line|
+ next if line =~ %r{^#}
+ root_home = line.split(%r{:})[1]
+ end
+ root_home
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/facter/service_provider.rb b/code/environments/production/modules/stdlib/lib/facter/service_provider.rb
new file mode 100644
index 0000000..a117921
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/facter/service_provider.rb
@@ -0,0 +1,17 @@
+# Fact: service_provider
+#
+# Purpose: Returns the default provider Puppet will choose to manage services
+# on this system
+#
+# Resolution: Instantiates a dummy service resource and return the provider
+#
+# Caveats:
+#
+require 'puppet/type'
+require 'puppet/type/service'
+
+Facter.add(:service_provider) do
+ setcode do
+ Puppet::Type.type(:service).newservice(:name => 'dummy')[:provider].to_s
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/facter/util/puppet_settings.rb b/code/environments/production/modules/stdlib/lib/facter/util/puppet_settings.rb
new file mode 100644
index 0000000..d12e92c
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/facter/util/puppet_settings.rb
@@ -0,0 +1,16 @@
+# A method to evaluate a Facter code block if puppet is loaded.
+module Facter::Util::PuppetSettings
+ # This method is intended to provide a convenient way to evaluate a
+ # Facter code block only if Puppet is loaded. This is to account for the
+ # situation where the fact happens to be in the load path, but Puppet is
+ # not loaded for whatever reason. Perhaps the user is simply running
+ # facter without the --puppet flag and they happen to be working in a lib
+ # directory of a module.
+ def self.with_puppet
+ Module.const_get('Puppet')
+ rescue NameError
+ nil
+ else
+ yield
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/deprecation.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/deprecation.rb
new file mode 100644
index 0000000..af6109d
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/deprecation.rb
@@ -0,0 +1,32 @@
+# Function to print deprecation warnings, Logs a warning once for a given key. The uniqueness key - can appear once.
+# The msg is the message text including any positional information that is formatted by the user/caller of the method.
+# It is affected by the puppet setting 'strict', which can be set to :error (outputs as an error message),
+# :off (no message / error is displayed) and :warning (default, outputs a warning) *Type*: String, String.
+#
+
+Puppet::Functions.create_function(:deprecation) do
+ dispatch :deprecation do
+ param 'String', :key
+ param 'String', :message
+ end
+
+ def deprecation(key, message)
+ if defined? Puppet::Pops::PuppetStack.stacktrace
+ stacktrace = Puppet::Pops::PuppetStack.stacktrace()
+ file = stacktrace[0]
+ line = stacktrace[1]
+ message = "#{message} at #{file}:#{line}"
+ end
+ # depending on configuration setting of strict
+ case Puppet.settings[:strict]
+ when :off # rubocop:disable Lint/EmptyWhen : Is required to prevent false errors
+ # do nothing
+ when :error
+ raise("deprecation. #{key}. #{message}")
+ else
+ unless ENV['STDLIB_LOG_DEPRECATIONS'] == 'false'
+ Puppet.deprecation_warning(message, key)
+ end
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/fact.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/fact.rb
new file mode 100644
index 0000000..48736ad
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/fact.rb
@@ -0,0 +1,57 @@
+# Digs into the facts hash using dot-notation
+#
+# Example usage:
+#
+# fact('osfamily')
+# fact('os.architecture')
+#
+# Array indexing:
+#
+# fact('mountpoints."/dev".options.1')
+#
+# Fact containing a "." in the name:
+#
+# fact('vmware."VRA.version"')
+#
+Puppet::Functions.create_function(:fact) do
+ dispatch :fact do
+ param 'String', :fact_name
+ end
+
+ def to_dot_syntax(array_path)
+ array_path.map { |string|
+ string.include?('.') ? %("#{string}") : string
+ }.join('.')
+ end
+
+ def fact(fact_name)
+ facts = closure_scope['facts']
+
+ # Transform the dot-notation string into an array of paths to walk. Make
+ # sure to correctly extract double-quoted values containing dots as single
+ # elements in the path.
+ path = fact_name.scan(%r{([^."]+)|(?:")([^"]+)(?:")}).map { |x| x.compact.first }
+
+ walked_path = []
+ path.reduce(facts) do |d, k|
+ return nil if d.nil? || k.nil?
+
+ if d.is_a?(Array)
+ begin
+ result = d[Integer(k)]
+ rescue ArgumentError => e # rubocop:disable Lint/UselessAssignment : Causes errors if assigment is removed.
+ Puppet.warning("fact request for #{fact_name} returning nil: '#{to_dot_syntax(walked_path)}' is an array; cannot index to '#{k}'")
+ result = nil
+ end
+ elsif d.is_a?(Hash)
+ result = d[k]
+ else
+ Puppet.warning("fact request for #{fact_name} returning nil: '#{to_dot_syntax(walked_path)}' is not a collection; cannot walk to '#{k}'")
+ result = nil
+ end
+
+ walked_path << k
+ result
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/is_a.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/is_a.rb
new file mode 100644
index 0000000..24b9744
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/is_a.rb
@@ -0,0 +1,32 @@
+# Boolean check to determine whether a variable is of a given data type. This is equivalent to the `=~` type checks.
+#
+# @example how to check a data type
+# # check a data type
+# foo = 3
+# $bar = [1,2,3]
+# $baz = 'A string!'
+#
+# if $foo.is_a(Integer) {
+# notify { 'foo!': }
+# }
+# if $bar.is_a(Array) {
+# notify { 'bar!': }
+# }
+# if $baz.is_a(String) {
+# notify { 'baz!': }
+# }
+#
+# 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(:is_a) do
+ dispatch :is_a do
+ param 'Any', :value
+ param 'Type', :type
+ end
+
+ def is_a(value, type) # rubocop:disable Style/PredicateName : Used in to many other places to rename at this time, attempting to refactor caused Rubocop to crash.
+ # See puppet's lib/puppet/pops/evaluator/evaluator_impl.rb eval_MatchExpression
+ Puppet::Pops::Types::TypeCalculator.instance?(type, value)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/is_absolute_path.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/is_absolute_path.rb
new file mode 100644
index 0000000..c9d92eb
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/is_absolute_path.rb
@@ -0,0 +1,17 @@
+Puppet::Functions.create_function(:is_absolute_path) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'is_absolute_path', 'This method is deprecated, please use match expressions with Stdlib::Compat::Absolute_Path instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.')
+ scope.send('function_is_absolute_path', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/is_array.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/is_array.rb
new file mode 100644
index 0000000..fdc60dd
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/is_array.rb
@@ -0,0 +1,17 @@
+Puppet::Functions.create_function(:is_array) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'is_array', 'This method is deprecated, please use match expressions with Stdlib::Compat::Array instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.')
+ scope.send('function_is_array', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/is_bool.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/is_bool.rb
new file mode 100644
index 0000000..1672f0a
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/is_bool.rb
@@ -0,0 +1,17 @@
+Puppet::Functions.create_function(:is_bool) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'is_bool', 'This method is deprecated, please use match expressions with Stdlib::Compat::Bool instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.')
+ scope.send('function_is_bool', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/is_float.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/is_float.rb
new file mode 100644
index 0000000..03e94d3
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/is_float.rb
@@ -0,0 +1,17 @@
+Puppet::Functions.create_function(:is_float) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'is_float', 'This method is deprecated, please use match expressions with Stdlib::Compat::Float instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.')
+ scope.send('function_is_float', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/is_ip_address.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/is_ip_address.rb
new file mode 100644
index 0000000..1ab67e7
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/is_ip_address.rb
@@ -0,0 +1,17 @@
+Puppet::Functions.create_function(:is_ip_address) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'is_ip_address', 'This method is deprecated, please use match expressions with Stdlib::Compat::Ip_address instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.')
+ scope.send('function_is_ip_address', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/is_ipv4_address.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/is_ipv4_address.rb
new file mode 100644
index 0000000..034f9ba
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/is_ipv4_address.rb
@@ -0,0 +1,17 @@
+Puppet::Functions.create_function(:is_ipv4_address) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'is_ipv4_address', 'This method is deprecated, please use match expressions with Stdlib::Compat::Ipv4 instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.')
+ scope.send('function_is_ipv4_address', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/is_ipv6_address.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/is_ipv6_address.rb
new file mode 100644
index 0000000..c8fb3ab
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/is_ipv6_address.rb
@@ -0,0 +1,17 @@
+Puppet::Functions.create_function(:is_ipv6_address) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'is_ipv4_address', 'This method is deprecated, please use match expressions with Stdlib::Compat::Ipv6 instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.')
+ scope.send('function_is_ipv6_address', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/is_numeric.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/is_numeric.rb
new file mode 100644
index 0000000..79a6bbf
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/is_numeric.rb
@@ -0,0 +1,17 @@
+Puppet::Functions.create_function(:is_numeric) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'is_numeric', 'This method is deprecated, please use match expressions with Stdlib::Compat::Numeric instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.')
+ scope.send('function_is_numeric', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/is_string.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/is_string.rb
new file mode 100644
index 0000000..a32216c
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/is_string.rb
@@ -0,0 +1,17 @@
+Puppet::Functions.create_function(:is_string) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'is_string', 'This method is deprecated, please use match expressions with Stdlib::Compat::String instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.')
+ scope.send('function_is_string', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/length.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/length.rb
new file mode 100644
index 0000000..8cd43e5
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/length.rb
@@ -0,0 +1,14 @@
+# A function to eventually replace the old size() function for stdlib - The original size function did not handle Puppets new type capabilities, so this function is a Puppet 4 compatible solution.
+Puppet::Functions.create_function(:length) do
+ dispatch :length do
+ param 'Variant[String,Array,Hash]', :value
+ end
+ def length(value)
+ if value.is_a?(String)
+ result = value.length
+ elsif value.is_a?(Array) || value.is_a?(Hash)
+ result = value.size
+ end
+ result
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/sprintf_hash.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/sprintf_hash.rb
new file mode 100644
index 0000000..2536bc9
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/sprintf_hash.rb
@@ -0,0 +1,29 @@
+# Uses sprintf with named references.
+#
+# The first parameter is format string describing how the rest of the parameters in the hash
+# should be formatted. See the documentation for the `Kernel::sprintf` function in Ruby for
+# all the details.
+#
+# In the given argument hash with parameters, all keys are converted to symbols so they work
+# with the `sprintf` function.
+#
+# @example Format a string and number
+# $output = sprintf_hash('String: %<foo>s / number converted to binary: %<number>b',
+# { 'foo' => 'a string', 'number' => 5 })
+# # $output = 'String: a string / number converted to binary: 101'
+#
+Puppet::Functions.create_function(:sprintf_hash) do
+ # @param format The format to use.
+ # @param arguments Hash with parameters.
+ # @return The formatted string.
+ dispatch :sprintf_hash do
+ param 'String', :format
+ param 'Hash', :arguments
+ # Disabled for now. This gives issues on puppet 4.7.1.
+ # return_type 'String'
+ end
+
+ def sprintf_hash(format, arguments)
+ Kernel.sprintf(format, Hash[arguments.map { |(k, v)| [k.to_sym, v] }])
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/to_json.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/to_json.rb
new file mode 100644
index 0000000..782d695
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/to_json.rb
@@ -0,0 +1,21 @@
+# Take a data structure and output it as JSON
+#
+# @example how to output JSON
+# # output json to a file
+# file { '/tmp/my.json':
+# ensure => file,
+# content => to_json($myhash),
+# }
+#
+#
+require 'json'
+
+Puppet::Functions.create_function(:to_json) do
+ dispatch :to_json do
+ param 'Any', :data
+ end
+
+ def to_json(data)
+ data.to_json
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/to_json_pretty.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/to_json_pretty.rb
new file mode 100644
index 0000000..a7a1458
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/to_json_pretty.rb
@@ -0,0 +1,38 @@
+# Take a data structure and output it as pretty JSON
+#
+# @example how to output pretty JSON
+# # output pretty json to a file
+# file { '/tmp/my.json':
+# ensure => file,
+# content => to_json_pretty($myhash),
+# }
+#
+# @example how to output pretty JSON skipping over keys with undef values
+# # output pretty JSON to a file skipping over undef values
+# file { '/tmp/my.json':
+# ensure => file,
+# content => to_json_pretty({
+# param_one => 'value',
+# param_two => undef,
+# }),
+# }
+#
+require 'json'
+
+Puppet::Functions.create_function(:to_json_pretty) do
+ dispatch :to_json_pretty do
+ param 'Variant[Hash, Array]', :data
+ optional_param 'Boolean', :skip_undef
+ end
+
+ def to_json_pretty(data, skip_undef = false)
+ if skip_undef
+ if data.is_a? Array
+ data = data.reject { |value| value.nil? }
+ elsif data.is_a? Hash
+ data = data.reject { |_, value| value.nil? }
+ end
+ end
+ JSON.pretty_generate(data) << "\n"
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/to_yaml.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/to_yaml.rb
new file mode 100644
index 0000000..fdd7370
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/to_yaml.rb
@@ -0,0 +1,21 @@
+# Take a data structure and output it as YAML
+#
+# @example how to output YAML
+# # output yaml to a file
+# file { '/tmp/my.yaml':
+# ensure => file,
+# content => to_yaml($myhash),
+# }
+#
+#
+require 'yaml'
+
+Puppet::Functions.create_function(:to_yaml) do
+ dispatch :to_yaml do
+ param 'Any', :data
+ end
+
+ def to_yaml(data)
+ data.to_yaml
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/type_of.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/type_of.rb
new file mode 100644
index 0000000..5bed6d5
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/type_of.rb
@@ -0,0 +1,19 @@
+# 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.
+#
+# The built-in type() function in puppet is generally preferred over this function
+# this function is provided for backwards compatibility.
+Puppet::Functions.create_function(:type_of) do
+ def type_of(value)
+ Puppet::Pops::Types::TypeCalculator.infer_set(value)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/validate_absolute_path.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_absolute_path.rb
new file mode 100644
index 0000000..44f600f
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_absolute_path.rb
@@ -0,0 +1,18 @@
+Puppet::Functions.create_function(:validate_absolute_path) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'validate_absolute_path', 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Absolute_Path. There is further documentation for validate_legacy function in the README.')
+ scope.send('function_validate_absolute_path', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/validate_array.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_array.rb
new file mode 100644
index 0000000..2bedd3f
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_array.rb
@@ -0,0 +1,18 @@
+Puppet::Functions.create_function(:validate_array) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'validate_array', 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Array. There is further documentation for validate_legacy function in the README.')
+ scope.send('function_validate_array', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/validate_bool.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_bool.rb
new file mode 100644
index 0000000..907eed3
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_bool.rb
@@ -0,0 +1,18 @@
+Puppet::Functions.create_function(:validate_bool) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'validate_bool', 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.')
+ scope.send('function_validate_bool', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/validate_hash.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_hash.rb
new file mode 100644
index 0000000..c6a61a4
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_hash.rb
@@ -0,0 +1,18 @@
+Puppet::Functions.create_function(:validate_hash) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'validate_hash', 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Hash. There is further documentation for validate_legacy function in the README.')
+ scope.send('function_validate_hash', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/validate_integer.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_integer.rb
new file mode 100644
index 0000000..487dcf7
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_integer.rb
@@ -0,0 +1,18 @@
+Puppet::Functions.create_function(:validate_integer) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'validate_integer', 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.')
+ scope.send('function_validate_integer', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/validate_ip_address.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_ip_address.rb
new file mode 100644
index 0000000..68e7f7f
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_ip_address.rb
@@ -0,0 +1,18 @@
+Puppet::Functions.create_function(:validate_ip_address) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'validate_ip_address', 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Ip_Address. There is further documentation for validate_legacy function in the README.')
+ scope.send('function_validate_ip_address', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/validate_ipv4_address.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_ipv4_address.rb
new file mode 100644
index 0000000..caeeaca
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_ipv4_address.rb
@@ -0,0 +1,18 @@
+Puppet::Functions.create_function(:validate_ipv4_address) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'validate_ipv4_address', 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Ipv4_Address. There is further documentation for validate_legacy function in the README.')
+ scope.send('function_validate_ipv4_address', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/validate_ipv6_address.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_ipv6_address.rb
new file mode 100644
index 0000000..c035357
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_ipv6_address.rb
@@ -0,0 +1,18 @@
+Puppet::Functions.create_function(:validate_ipv6_address) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff
+ # -c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'validate_ipv6_address', 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Ipv6_address. There is further documentation for validate_legacy function in the README.')
+ scope.send('function_validate_ipv6_address', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/validate_legacy.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_legacy.rb
new file mode 100644
index 0000000..21646ad
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_legacy.rb
@@ -0,0 +1,62 @@
+Puppet::Functions.create_function(:validate_legacy) do
+ # The function checks a value against both the target_type (new) and the previous_validation function (old).
+
+ dispatch :validate_legacy do
+ param 'Any', :scope
+ param 'Type', :target_type
+ param 'String', :function_name
+ param 'Any', :value
+ repeated_param 'Any', :args
+ end
+
+ dispatch :validate_legacy_s do
+ param 'Any', :scope
+ param 'String', :type_string
+ param 'String', :function_name
+ param 'Any', :value
+ repeated_param 'Any', :args
+ end
+
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-
+ # c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def validate_legacy_s(scope, type_string, *args)
+ t = Puppet::Pops::Types::TypeParser.new.parse(type_string, scope)
+ validate_legacy(scope, t, *args)
+ end
+
+ def validate_legacy(scope, target_type, function_name, value, *prev_args)
+ if assert_type(target_type, value)
+ if previous_validation(scope, function_name, value, *prev_args)
+ # Silently passes
+ else
+ Puppet.notice("Accepting previously invalid value for target type '#{target_type}'")
+ end
+ else
+ inferred_type = Puppet::Pops::Types::TypeCalculator.infer_set(value)
+ error_msg = Puppet::Pops::Types::TypeMismatchDescriber.new.describe_mismatch("validate_legacy(#{function_name})", target_type, inferred_type)
+ if previous_validation(scope, function_name, value, *prev_args)
+ call_function('deprecation', 'validate_legacy', error_msg)
+ else
+ call_function('fail', error_msg)
+ end
+ end
+ end
+
+ def previous_validation(scope, function_name, value, *prev_args)
+ # Call the previous validation function and catch any errors. Return true if no errors are thrown.
+
+ scope.send("function_#{function_name}".to_s, [value, *prev_args])
+ true
+ rescue Puppet::ParseError
+ false
+ end
+
+ def assert_type(type, value)
+ Puppet::Pops::Types::TypeCalculator.instance?(type, value)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/validate_numeric.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_numeric.rb
new file mode 100644
index 0000000..3adb0a8
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_numeric.rb
@@ -0,0 +1,18 @@
+Puppet::Functions.create_function(:validate_numeric) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-
+ # c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'validate_numeric', 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.')
+ scope.send('function_validate_numeric', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/validate_re.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_re.rb
new file mode 100644
index 0000000..d357aab
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_re.rb
@@ -0,0 +1,18 @@
+Puppet::Functions.create_function(:validate_re) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-
+ # c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'validate_re', 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Pattern[]. There is further documentation for validate_legacy function in the README.')
+ scope.send('function_validate_re', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/validate_slength.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_slength.rb
new file mode 100644
index 0000000..ad6f7b3
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_slength.rb
@@ -0,0 +1,18 @@
+Puppet::Functions.create_function(:validate_slength) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-
+ # c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'validate_slength', 'This method is deprecated, please use the stdlib validate_legacy function,
+ with String[]. There is further documentation for validate_legacy function in the README.')
+ scope.send('function_validate_slength', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/functions/validate_string.rb b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_string.rb
new file mode 100644
index 0000000..a908c19
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/functions/validate_string.rb
@@ -0,0 +1,18 @@
+Puppet::Functions.create_function(:validate_string) do
+ dispatch :deprecation_gen do
+ param 'Any', :scope
+ repeated_param 'Any', :args
+ end
+ # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-
+ # c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1.
+ def call(scope, *args)
+ manipulated_args = [scope] + args
+ self.class.dispatcher.dispatch(self, scope, manipulated_args)
+ end
+
+ def deprecation_gen(scope, *args)
+ call_function('deprecation', 'validate_string', 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::String. There is further documentation for validate_legacy function in the README.')
+ scope.send('function_validate_string', args)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/abs.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/abs.rb
new file mode 100644
index 0000000..84bef8c
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/abs.rb
@@ -0,0 +1,33 @@
+#
+# abs.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:abs, :type => :rvalue, :doc => <<-DOC
+ Returns the absolute value of a number, for example -34.56 becomes
+ 34.56. Takes a single integer and float value as an argument.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "abs(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ value = arguments[0]
+
+ # Numbers in Puppet are often string-encoded which is troublesome ...
+ if value.is_a?(String)
+ if value =~ %r{^-?(?:\d+)(?:\.\d+){1}$}
+ value = value.to_f
+ elsif value =~ %r{^-?\d+$}
+ value = value.to_i
+ else
+ raise(Puppet::ParseError, 'abs(): Requires float or integer to work with')
+ end
+ end
+
+ # We have numeric value to handle ...
+ result = value.abs
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/any2array.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/any2array.rb
new file mode 100644
index 0000000..510c2d5
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/any2array.rb
@@ -0,0 +1,29 @@
+#
+# any2array.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:any2array, :type => :rvalue, :doc => <<-DOC
+ This converts any object to an array containing that object. Empty argument
+ lists are converted to an empty array. Arrays are left untouched. Hashes are
+ converted to arrays of alternating keys and values.
+ DOC
+ ) do |arguments|
+
+ if arguments.empty?
+ return []
+ end
+
+ return arguments unless arguments.length == 1
+ return arguments[0] if arguments[0].is_a?(Array)
+ if arguments[0].is_a?(Hash)
+ result = []
+ arguments[0].each do |key, value|
+ result << key << value
+ end
+ return result
+ end
+ return arguments
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/any2bool.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/any2bool.rb
new file mode 100644
index 0000000..9eb634d
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/any2bool.rb
@@ -0,0 +1,53 @@
+#
+# any2bool.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:any2bool, :type => :rvalue, :doc => <<-DOC
+ This converts 'anything' to a boolean. In practise it does the following:
+
+ * Strings such as Y,y,1,T,t,TRUE,yes,'true' will return true
+ * Strings such as 0,F,f,N,n,FALSE,no,'false' will return false
+ * Booleans will just return their original value
+ * Number (or a string representation of a number) > 0 will return true, otherwise false
+ * undef will return false
+ * Anything else will return true
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "any2bool(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ # If argument is already Boolean, return it
+ if !!arguments[0] == arguments[0] # rubocop:disable Style/DoubleNegation : Could not find a better way to check if a boolean
+ return arguments[0]
+ end
+
+ arg = arguments[0]
+
+ if arg.nil?
+ return false
+ end
+
+ if arg == :undef
+ return false
+ end
+
+ valid_float = begin
+ !!Float(arg) # rubocop:disable Style/DoubleNegation : Could not find a better way to check if a boolean
+ rescue
+ false
+ end
+
+ if arg.is_a?(Numeric)
+ return function_num2bool([arguments[0]])
+ end
+
+ if arg.is_a?(String)
+ return function_num2bool([arguments[0]]) if valid_float
+ return function_str2bool([arguments[0]])
+ end
+
+ return true
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/assert_private.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/assert_private.rb
new file mode 100644
index 0000000..9cdebb9
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/assert_private.rb
@@ -0,0 +1,27 @@
+#
+# assert_private.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:assert_private, :doc => <<-DOC
+ Sets the current class or definition as private.
+ Calling the class or definition from outside the current module will fail.
+ DOC
+ ) do |args|
+
+ raise(Puppet::ParseError, "assert_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] && 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/code/environments/production/modules/stdlib/lib/puppet/parser/functions/base64.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/base64.rb
new file mode 100644
index 0000000..484c2f1
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/base64.rb
@@ -0,0 +1,67 @@
+# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085.
+module Puppet::Parser::Functions
+ newfunction(:base64, :type => :rvalue, :doc => <<-'DOC') do |args|
+ Base64 encode or decode a string based on the command and the string submitted
+
+ Usage:
+
+ $encodestring = base64('encode', 'thestring')
+ $decodestring = base64('decode', 'dGhlc3RyaW5n')
+
+ # explicitly define encode/decode method: default, strict, urlsafe
+ $method = 'default'
+ $encodestring = base64('encode', 'thestring', $method)
+ $decodestring = base64('decode', 'dGhlc3RyaW5n', $method)
+
+ DOC
+
+ require 'base64'
+
+ raise Puppet::ParseError, "base64(): Wrong number of arguments (#{args.length}; must be >= 2)" unless args.length >= 2
+
+ actions = %w[encode decode]
+
+ 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
+
+ method = %w[default strict urlsafe]
+
+ chosen_method = if args.length <= 2
+ 'default'
+ else
+ args[2]
+ end
+
+ unless method.include?(chosen_method)
+ raise Puppet::ParseError, "base64(): the third argument must be one of 'default', 'strict', or 'urlsafe'"
+ end
+
+ case args[0]
+ when 'encode'
+ case chosen_method
+ when 'default'
+ result = Base64.encode64(args[1])
+ when 'strict'
+ result = Base64.strict_encode64(args[1])
+ when 'urlsafe'
+ result = Base64.urlsafe_encode64(args[1])
+ end
+ when 'decode'
+ case chosen_method
+ when 'default'
+ result = Base64.decode64(args[1])
+ when 'strict'
+ result = Base64.strict_decode64(args[1])
+ when 'urlsafe'
+ result = Base64.urlsafe_decode64(args[1])
+ end
+ end
+
+ return result
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/basename.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/basename.rb
new file mode 100644
index 0000000..b717fa1
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/basename.rb
@@ -0,0 +1,24 @@
+#
+# basename.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:basename, :type => :rvalue, :doc => <<-DOC
+ Strips directory (and optional suffix) from a filename
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, 'basename(): No arguments given') if arguments.empty?
+ raise(Puppet::ParseError, "basename(): Too many arguments given (#{arguments.size})") if arguments.size > 2
+ raise(Puppet::ParseError, 'basename(): Requires string as first argument') unless arguments[0].is_a?(String)
+
+ rv = File.basename(arguments[0]) if arguments.size == 1
+ if arguments.size == 2
+ raise(Puppet::ParseError, 'basename(): Requires string as second argument') unless arguments[1].is_a?(String)
+ rv = File.basename(arguments[0], arguments[1])
+ end
+
+ return rv
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/bool2num.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/bool2num.rb
new file mode 100644
index 0000000..e8ad961
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/bool2num.rb
@@ -0,0 +1,24 @@
+#
+# bool2num.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:bool2num, :type => :rvalue, :doc => <<-DOC
+ Converts a boolean to a number. Converts the values:
+ false, f, 0, n, and no to 0
+ true, t, 1, y, and yes to 1
+ Requires a single boolean or string as an input.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "bool2num(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ value = function_str2bool([arguments[0]])
+
+ # We have real boolean values as well ...
+ result = value ? 1 : 0
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/bool2str.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/bool2str.rb
new file mode 100644
index 0000000..502ab2e
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/bool2str.rb
@@ -0,0 +1,43 @@
+#
+# bool2str.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:bool2str, :type => :rvalue, :doc => <<-DOC
+ Converts a boolean to a string using optionally supplied arguments. The
+ optional second and third arguments represent what true and false will be
+ converted to respectively. If only one argument is given, it will be
+ converted from a boolean to a string containing 'true' or 'false'.
+
+ *Examples:*
+
+ bool2str(true) => 'true'
+ bool2str(true, 'yes', 'no') => 'yes'
+ bool2str(false, 't', 'f') => 'f'
+
+ Requires a single boolean as an input.
+ DOC
+ ) do |arguments|
+
+ unless arguments.size == 1 || arguments.size == 3
+ raise(Puppet::ParseError, "bool2str(): Wrong number of arguments given (#{arguments.size} for 3)")
+ end
+
+ value = arguments[0]
+ true_string = arguments[1] || 'true'
+ false_string = arguments[2] || 'false'
+ 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
+
+ unless [true_string, false_string].all? { |x| x.is_a?(String) }
+ raise(Puppet::ParseError, 'bool2str(): Requires strings to convert to')
+ end
+
+ return value ? true_string : false_string
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/camelcase.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/camelcase.rb
new file mode 100644
index 0000000..fdc54a2
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/camelcase.rb
@@ -0,0 +1,31 @@
+#
+# camelcase.rb
+# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085.
+#
+module Puppet::Parser::Functions
+ newfunction(:camelcase, :type => :rvalue, :doc => <<-DOC
+ Converts the case of a string or all strings in an array to camel case.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "camelcase(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ value = arguments[0]
+ klass = value.class
+
+ unless [Array, String].include?(klass)
+ raise(Puppet::ParseError, 'camelcase(): Requires either array or string to work with')
+ end
+
+ result = if value.is_a?(Array)
+ # Numbers in Puppet are often string-encoded which is troublesome ...
+ value.map { |i| i.is_a?(String) ? i.split('_').map { |e| e.capitalize }.join : i }
+ else
+ value.split('_').map { |e| e.capitalize }.join
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/capitalize.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/capitalize.rb
new file mode 100644
index 0000000..7d7703f
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/capitalize.rb
@@ -0,0 +1,29 @@
+#
+# capitalize.rb
+# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085.
+#
+module Puppet::Parser::Functions
+ newfunction(:capitalize, :type => :rvalue, :doc => <<-DOC
+ Capitalizes the first letter of a string or array of strings.
+ Requires either a single string or an array as an input.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "capitalize(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ value = arguments[0]
+
+ unless value.is_a?(Array) || value.is_a?(String)
+ raise(Puppet::ParseError, 'capitalize(): Requires either array or string to work with')
+ end
+
+ result = if value.is_a?(Array)
+ # Numbers in Puppet are often string-encoded which is troublesome ...
+ value.map { |i| i.is_a?(String) ? i.capitalize : i }
+ else
+ value.capitalize
+ end
+
+ return result
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/ceiling.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/ceiling.rb
new file mode 100644
index 0000000..d0323a8
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/ceiling.rb
@@ -0,0 +1,25 @@
+#
+# ceiling.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:ceiling, :type => :rvalue, :doc => <<-DOC
+ Returns the smallest integer greater or equal to the argument.
+ Takes a single numeric value as an argument.
+ DOC
+ ) 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/code/environments/production/modules/stdlib/lib/puppet/parser/functions/chomp.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/chomp.rb
new file mode 100644
index 0000000..0e9cd6d
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/chomp.rb
@@ -0,0 +1,31 @@
+#
+# chomp.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:chomp, :type => :rvalue, :doc => <<-DOC
+ Removes the record separator from the end of a string or an array of
+ strings, for example `hello\n` becomes `hello`.
+ Requires a single string or array as an input.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "chomp(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ value = arguments[0]
+
+ unless value.is_a?(Array) || value.is_a?(String)
+ raise(Puppet::ParseError, 'chomp(): Requires either array or string to work with')
+ end
+
+ result = if value.is_a?(Array)
+ # Numbers in Puppet are often string-encoded which is troublesome ...
+ value.map { |i| i.is_a?(String) ? i.chomp : i }
+ else
+ value.chomp
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/chop.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/chop.rb
new file mode 100644
index 0000000..80e8964
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/chop.rb
@@ -0,0 +1,33 @@
+#
+# chop.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:chop, :type => :rvalue, :doc => <<-DOC
+ Returns a new string with the last character removed. If the string ends
+ with `\r\n`, both characters are removed. Applying chop to an empty
+ string returns an empty string. If you wish to merely remove record
+ separators then you should use the `chomp` function.
+ Requires a string or array of strings as input.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "chop(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ value = arguments[0]
+
+ unless value.is_a?(Array) || value.is_a?(String)
+ raise(Puppet::ParseError, 'chop(): Requires either an array or string to work with')
+ end
+
+ result = if value.is_a?(Array)
+ # Numbers in Puppet are often string-encoded which is troublesome ...
+ value.map { |i| i.is_a?(String) ? i.chop : i }
+ else
+ value.chop
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/clamp.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/clamp.rb
new file mode 100644
index 0000000..0aea511
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/clamp.rb
@@ -0,0 +1,28 @@
+#
+# clamp.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:clamp, :type => :rvalue, :arity => -2, :doc => <<-DOC
+ Clamps value to a range.
+ DOC
+ ) do |args|
+
+ args.flatten!
+
+ raise(Puppet::ParseError, 'clamp(): Wrong number of arguments, need three to clamp') if args.size != 3
+
+ # check values out
+ args.each do |value|
+ case [value.class]
+ when [String]
+ raise(Puppet::ParseError, "clamp(): Required explicit numeric (#{value}:String)") unless value =~ %r{^\d+$}
+ when [Hash]
+ raise(Puppet::ParseError, "clamp(): The Hash type is not allowed (#{value})")
+ end
+ end
+
+ # convert to numeric each element
+ # then sort them and get a middle value
+ args.map { |n| n.to_i }.sort[1]
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/concat.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/concat.rb
new file mode 100644
index 0000000..9a83ec1
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/concat.rb
@@ -0,0 +1,39 @@
+#
+# concat.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:concat, :type => :rvalue, :doc => <<-DOC
+ Appends the contents of multiple arrays into array 1.
+
+ *Example:*
+
+ concat(['1','2','3'],['4','5','6'],['7','8','9'])
+
+ Would result in:
+
+ ['1','2','3','4','5','6','7','8','9']
+ DOC
+ ) do |arguments|
+
+ # 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
+
+ a = arguments[0]
+
+ # 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
+ arguments.shift
+
+ arguments.each do |x|
+ result += (x.is_a?(Array) ? x : [x])
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/convert_base.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/convert_base.rb
new file mode 100644
index 0000000..6d17f85
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/convert_base.rb
@@ -0,0 +1,36 @@
+#
+# convert_base.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:convert_base, :type => :rvalue, :arity => 2, :doc => <<-'DOC') do |args|
+ Converts a given integer or base 10 string representing an integer to a specified base, as a string.
+
+ Usage:
+
+ $binary_repr = convert_base(5, 2) # $binary_repr is now set to "101"
+ $hex_repr = convert_base("254", "16") # $hex_repr is now set to "fe"
+
+ DOC
+
+ raise Puppet::ParseError, 'convert_base(): First argument must be either a string or an integer' unless args[0].is_a?(Integer) || args[0].is_a?(String)
+ raise Puppet::ParseError, 'convert_base(): Second argument must be either a string or an integer' unless args[1].is_a?(Integer) || args[1].is_a?(String)
+
+ if args[0].is_a?(String)
+ raise Puppet::ParseError, 'convert_base(): First argument must be an integer or a string corresponding to an integer in base 10' unless args[0] =~ %r{^[0-9]+$}
+ end
+
+ if args[1].is_a?(String)
+ raise Puppet::ParseError, 'convert_base(): First argument must be an integer or a string corresponding to an integer in base 10' unless args[1] =~ %r{^[0-9]+$}
+ end
+
+ number_to_convert = args[0]
+ new_base = args[1]
+
+ number_to_convert = number_to_convert.to_i
+ new_base = new_base.to_i
+
+ raise Puppet::ParseError, 'convert_base(): base must be at least 2 and must not be greater than 36' unless new_base >= 2 && new_base <= 36
+
+ return number_to_convert.to_s(new_base)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/count.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/count.rb
new file mode 100644
index 0000000..f5ac8c3
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/count.rb
@@ -0,0 +1,24 @@
+#
+# count.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:count, :type => :rvalue, :arity => -2, :doc => <<-DOC
+ Takes an array as first argument and an optional second argument.
+ Count the number of elements in array that matches second argument.
+ If called with only an array it counts the number of elements that are not nil/undef.
+ DOC
+ ) do |args|
+
+ if args.size > 2
+ raise(ArgumentError, "count(): Wrong number of arguments given #{args.size} for 1 or 2.")
+ end
+
+ collection, item = args
+
+ if item
+ collection.count item
+ else
+ collection.count { |obj| !obj.nil? && obj != :undef && obj != '' }
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/deep_merge.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/deep_merge.rb
new file mode 100644
index 0000000..dd70c61
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/deep_merge.rb
@@ -0,0 +1,47 @@
+#
+# deep_merge.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:deep_merge, :type => :rvalue, :doc => <<-'DOC') 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."
+
+ DOC
+
+ if args.length < 2
+ raise Puppet::ParseError, "deep_merge(): wrong number of arguments (#{args.length}; must be at least 2)"
+ end
+
+ deep_merge = proc 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 = {}
+ args.each do |arg|
+ next if arg.is_a?(String) && 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/code/environments/production/modules/stdlib/lib/puppet/parser/functions/defined_with_params.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/defined_with_params.rb
new file mode 100644
index 0000000..1383308
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/defined_with_params.rb
@@ -0,0 +1,57 @@
+# Test whether a given class or definition is defined
+require 'puppet/parser/functions'
+
+Puppet::Parser::Functions.newfunction(:defined_with_params,
+ :type => :rvalue,
+ :doc => <<-'DOC'
+ Takes a resource reference and an optional hash of attributes.
+
+ Returns true if a resource with the specified attributes has already been added
+ to the catalog, and false otherwise.
+
+ user { 'dan':
+ ensure => present,
+ }
+
+ if ! defined_with_params(User[dan], {'ensure' => 'present' }) {
+ user { 'dan': ensure => present, }
+ }
+DOC
+ ) do |vals|
+ reference, params = vals
+ raise(ArgumentError, 'Must specify a reference') unless reference
+ if !params || params == ''
+ params = {}
+ end
+ ret = false
+
+ if Puppet::Util::Package.versioncmp(Puppet.version, '4.6.0') >= 0
+ # Workaround for PE-20308
+ if reference.is_a?(String)
+ type_name, title = Puppet::Resource.type_and_title(reference, nil)
+ type = Puppet::Pops::Evaluator::Runtime3ResourceSupport.find_resource_type_or_class(find_global_scope, type_name.downcase)
+ elsif reference.is_a?(Puppet::Resource)
+ type = reference.resource_type
+ title = reference.title
+ else
+ raise(ArgumentError, "Reference is not understood: '#{reference.class}'")
+ end
+ # end workaround
+ else
+ type = reference.to_s
+ title = nil
+ end
+
+ resource = findresource(type, title)
+ if resource
+ matches = params.map do |key, value|
+ # eql? avoids bugs caused by monkeypatching in puppet
+ resource_is_undef = resource[key].eql?(:undef) || resource[key].nil?
+ value_is_undef = value.eql?(:undef) || value.nil?
+ (resource_is_undef && value_is_undef) || (resource[key] == value)
+ end
+ ret = params.empty? || !matches.include?(false)
+ end
+ Puppet.debug("Resource #{reference} was not determined to be defined")
+ ret
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete.rb
new file mode 100644
index 0000000..f83ff16
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete.rb
@@ -0,0 +1,42 @@
+#
+# delete.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:delete, :type => :rvalue, :doc => <<-DOC
+ Deletes all instances of a given element from an array, substring from a
+ string, or key from a hash.
+
+ *Examples:*
+
+ delete(['a','b','c','b'], 'b')
+ Would return: ['a','c']
+
+ 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'
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "delete(): Wrong number of arguments given #{arguments.size} for 2") unless arguments.size == 2
+
+ 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
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete_at.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete_at.rb
new file mode 100644
index 0000000..e40ad26
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete_at.rb
@@ -0,0 +1,45 @@
+#
+# delete_at.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:delete_at, :type => :rvalue, :doc => <<-DOC
+ Deletes a determined indexed value from an array.
+
+ *Examples:*
+
+ delete_at(['a','b','c'], 1)
+
+ Would return: ['a','c']
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "delete_at(): Wrong number of arguments given (#{arguments.size} for 2)") if arguments.size < 2
+
+ array = arguments[0]
+
+ unless array.is_a?(Array)
+ raise(Puppet::ParseError, 'delete_at(): Requires array to work with')
+ end
+
+ index = arguments[1]
+
+ if index.is_a?(String) && !index.match(%r{^\d+$})
+ raise(Puppet::ParseError, 'delete_at(): You must provide non-negative numeric index')
+ end
+
+ result = array.clone
+
+ # Numbers in Puppet are often string-encoded which is troublesome ...
+ index = index.to_i
+
+ if index > result.size - 1 # First element is at index 0 is it not?
+ raise(Puppet::ParseError, 'delete_at(): Given index exceeds size of array given')
+ end
+
+ result.delete_at(index) # We ignore the element that got deleted ...
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete_regex.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete_regex.rb
new file mode 100644
index 0000000..64cad9c
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete_regex.rb
@@ -0,0 +1,43 @@
+#
+# delete_regex.rb
+# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085.
+#
+module Puppet::Parser::Functions
+ newfunction(:delete_regex, :type => :rvalue, :doc => <<-DOC
+ deletes all instances of a given element that match a regular expression
+ from an array or key from a hash. Multiple regular expressions are assumed
+ to be matched as an OR.
+
+ *Examples:*
+
+ delete_regex(['a','b','c','b'], 'b')
+ Would return: ['a','c']
+
+ delete_regex(['a','b','c','b'], ['b', 'c'])
+ Would return: ['a']
+
+ delete_regex({'a'=>1,'b'=>2,'c'=>3}, 'b')
+ Would return: {'a'=>1,'c'=>3}
+
+ delete_regex({'a'=>1,'b'=>2,'c'=>3}, '^a$')
+ Would return: {'b'=>2,'c'=>3}
+
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "delete_regex(): Wrong number of arguments given #{arguments.size} for 2") unless arguments.size == 2
+
+ collection = arguments[0].dup
+ Array(arguments[1]).each do |item|
+ case collection
+ when Array, Hash, String
+ collection.reject! { |coll_item| (coll_item =~ %r{\b#{item}\b}) }
+ else
+ raise(TypeError, "delete_regex(): First argument must be an Array, Hash, or String. Given an argument of class #{collection.class}.")
+ end
+ end
+ collection
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete_undef_values.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete_undef_values.rb
new file mode 100644
index 0000000..af2dbc7
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete_undef_values.rb
@@ -0,0 +1,34 @@
+#
+# delete_undef_values.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:delete_undef_values, :type => :rvalue, :doc => <<-DOC
+ 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}
+
+ $array = delete_undef_values(['A','',undef,false])
+
+ Would return: ['A','',false]
+
+ DOC
+ ) do |args|
+
+ raise(Puppet::ParseError, "delete_undef_values(): Wrong number of arguments given (#{args.size})") if args.empty?
+
+ unless args[0].is_a?(Array) || 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
+ end
+ result
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete_values.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete_values.rb
new file mode 100644
index 0000000..1192766
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/delete_values.rb
@@ -0,0 +1,26 @@
+#
+# delete_values.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:delete_values, :type => :rvalue, :doc => <<-DOC
+ Deletes all instances of a given value from a hash.
+
+ *Examples:*
+
+ delete_values({'a'=>'A','b'=>'B','c'=>'C','B'=>'D'}, 'B')
+
+ Would return: {'a'=>'A','c'=>'C','B'=>'D'}
+
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "delete_values(): Wrong number of arguments given (#{arguments.size} of 2)") if arguments.size != 2
+
+ hash, item = arguments
+
+ unless hash.is_a?(Hash)
+ raise(TypeError, "delete_values(): First argument must be a Hash. Given an argument of class #{hash.class}.")
+ end
+ hash.dup.delete_if { |_key, val| item == val }
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/deprecation.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/deprecation.rb
new file mode 100644
index 0000000..01f0deb
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/deprecation.rb
@@ -0,0 +1,19 @@
+#
+# deprecation.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:deprecation, :doc => <<-DOC
+ Function to print deprecation warnings (this is the 3.X version of it), The uniqueness key - can appear once. The msg is the message text including any positional information that is formatted by the user/caller of the method.).
+DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "deprecation: Wrong number of arguments given (#{arguments.size} for 2)") unless arguments.size == 2
+
+ key = arguments[0]
+ message = arguments[1]
+
+ if ENV['STDLIB_LOG_DEPRECATIONS'] == 'true'
+ warning("deprecation. #{key}. #{message}")
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/difference.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/difference.rb
new file mode 100644
index 0000000..cfaebc9
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/difference.rb
@@ -0,0 +1,34 @@
+#
+# difference.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:difference, :type => :rvalue, :doc => <<-DOC
+ This function returns the difference between two arrays.
+ The returned array is a copy of the original array, removing any items that
+ also appear in the second array.
+
+ *Examples:*
+
+ difference(["a","b","c"],["b","c","d"])
+
+ Would return: ["a"]
+ DOC
+ ) do |arguments|
+
+ # Two arguments are required
+ raise(Puppet::ParseError, "difference(): Wrong number of arguments given (#{arguments.size} for 2)") if arguments.size != 2
+
+ first = arguments[0]
+ second = arguments[1]
+
+ unless first.is_a?(Array) && second.is_a?(Array)
+ raise(Puppet::ParseError, 'difference(): Requires 2 arrays')
+ end
+
+ result = first - second
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/dig.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/dig.rb
new file mode 100644
index 0000000..75e83aa
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/dig.rb
@@ -0,0 +1,15 @@
+#
+# dig.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:dig, :type => :rvalue, :doc => <<-DOC
+ DEPRECATED: This function has been replaced in Puppet 4.5.0, please use dig44() for backwards compatibility or use the new version.
+ DOC
+ ) do |arguments|
+ warning('dig() DEPRECATED: This function has been replaced in Puppet 4.5.0, please use dig44() for backwards compatibility or use the new version.')
+ unless Puppet::Parser::Functions.autoloader.loaded?(:dig44)
+ Puppet::Parser::Functions.autoloader.load(:dig44)
+ end
+ function_dig44(arguments)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/dig44.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/dig44.rb
new file mode 100644
index 0000000..e7e78bf
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/dig44.rb
@@ -0,0 +1,65 @@
+#
+# dig44.rb
+#
+module Puppet::Parser::Functions
+ newfunction(
+ :dig44,
+ :type => :rvalue,
+ :arity => -2,
+ :doc => <<-DOC
+ DEPRECATED: This function has been replaced in puppet 4.5.0.
+
+ Looks up into a complex structure of arrays and hashes and returns a value
+ or the default value if nothing was found.
+
+ Key can contain slashes to describe path components. The function will go down
+ the structure and try to extract the required value.
+
+ $data = {
+ 'a' => {
+ 'b' => [
+ 'b1',
+ 'b2',
+ 'b3',
+ ]
+ }
+ }
+
+ $value = dig44($data, ['a', 'b', '2'], 'not_found')
+ => $value = 'b3'
+
+ a -> first hash key
+ b -> second hash key
+ 2 -> array index starting with 0
+
+ not_found -> (optional) will be returned if there is no value or the path
+ did not match. Defaults to nil.
+
+ In addition to the required "key" argument, the function accepts a default
+ argument. It will be returned if no value was found or a path component is
+ missing. And the fourth argument can set a variable path separator.
+ DOC
+ ) do |arguments|
+ # Two arguments are required
+ raise(Puppet::ParseError, "dig44(): Wrong number of arguments given (#{arguments.size} for at least 2)") if arguments.size < 2
+
+ data, path, default = *arguments
+
+ raise(Puppet::ParseError, "dig44(): first argument must be a hash or an array, given #{data.class.name}") unless data.is_a?(Hash) || data.is_a?(Array)
+ raise(Puppet::ParseError, "dig44(): second argument must be an array, given #{path.class.name}") unless path.is_a? Array
+
+ value = path.reduce(data) do |structure, key|
+ break unless structure.is_a?(Hash) || structure.is_a?(Array)
+ if structure.is_a? Array
+ begin
+ key = Integer key
+ rescue
+ break
+ end
+ end
+ break if structure[key].nil? || structure[key] == :undef
+ structure[key]
+ end
+ value.nil? ? default : value
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/dirname.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/dirname.rb
new file mode 100644
index 0000000..a243287
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/dirname.rb
@@ -0,0 +1,24 @@
+#
+# dirname.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:dirname, :type => :rvalue, :doc => <<-DOC
+ Returns the dirname of a path.
+ DOC
+ ) do |arguments|
+
+ if arguments.empty?
+ raise(Puppet::ParseError, 'dirname(): No arguments given')
+ end
+ if arguments.size > 1
+ raise(Puppet::ParseError, "dirname(): Too many arguments given (#{arguments.size})")
+ end
+ unless arguments[0].is_a?(String)
+ raise(Puppet::ParseError, 'dirname(): Requires string as argument')
+ end
+
+ return File.dirname(arguments[0])
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/dos2unix.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/dos2unix.rb
new file mode 100644
index 0000000..32722ba
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/dos2unix.rb
@@ -0,0 +1,15 @@
+# Custom Puppet function to convert dos to unix format
+module Puppet::Parser::Functions
+ newfunction(:dos2unix, :type => :rvalue, :arity => 1, :doc => <<-DOC
+ Returns the Unix version of the given string.
+ Takes a single string argument.
+ DOC
+ ) do |arguments|
+
+ unless arguments[0].is_a?(String)
+ raise(Puppet::ParseError, 'dos2unix(): Requires string as argument')
+ end
+
+ arguments[0].gsub(%r{\r\n}, "\n")
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/downcase.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/downcase.rb
new file mode 100644
index 0000000..1661e56
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/downcase.rb
@@ -0,0 +1,30 @@
+#
+# downcase.rb
+# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085.
+#
+module Puppet::Parser::Functions
+ newfunction(:downcase, :type => :rvalue, :doc => <<-DOC
+ Converts the case of a string or all strings in an array to lower case.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "downcase(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ value = arguments[0]
+
+ unless value.is_a?(Array) || value.is_a?(String)
+ raise(Puppet::ParseError, 'downcase(): Requires either array or string to work with')
+ end
+
+ result = if value.is_a?(Array)
+ # Numbers in Puppet are often string-encoded which is troublesome ...
+ value.map { |i| i.is_a?(String) ? i.downcase : i }
+ else
+ value.downcase
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/empty.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/empty.rb
new file mode 100644
index 0000000..79c43d0
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/empty.rb
@@ -0,0 +1,23 @@
+#
+# empty.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:empty, :type => :rvalue, :doc => <<-DOC
+ Returns true if the variable is empty.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "empty(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+ value = arguments[0]
+
+ unless value.is_a?(Array) || value.is_a?(Hash) || value.is_a?(String) || value.is_a?(Numeric)
+ raise(Puppet::ParseError, 'empty(): Requires either array, hash, string or integer to work with')
+ end
+
+ return false if value.is_a?(Numeric)
+ result = value.empty?
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/enclose_ipv6.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/enclose_ipv6.rb
new file mode 100644
index 0000000..f412b01
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/enclose_ipv6.rb
@@ -0,0 +1,41 @@
+#
+# enclose_ipv6.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:enclose_ipv6, :type => :rvalue, :doc => <<-DOC
+ Takes an array of ip addresses and encloses the ipv6 addresses with square brackets.
+ DOC
+ ) do |arguments|
+
+ require 'ipaddr'
+
+ rescuable_exceptions = [ArgumentError]
+ if defined?(IPAddr::InvalidAddressError)
+ rescuable_exceptions << IPAddr::InvalidAddressError
+ end
+
+ if arguments.size != 1
+ raise(Puppet::ParseError, "enclose_ipv6(): Wrong number of arguments given #{arguments.size} for 1")
+ end
+ unless arguments[0].is_a?(String) || arguments[0].is_a?(Array)
+ raise(Puppet::ParseError, "enclose_ipv6(): Wrong argument type given #{arguments[0].class} expected String or Array")
+ end
+
+ input = [arguments[0]].flatten.compact
+ result = []
+
+ input.each do |val|
+ unless val == '*'
+ begin
+ ip = IPAddr.new(val)
+ rescue *rescuable_exceptions
+ raise(Puppet::ParseError, "enclose_ipv6(): Wrong argument given #{val} is not an ip address.")
+ end
+ val = "[#{ip}]" if ip.ipv6?
+ end
+ result << val
+ end
+
+ return result.uniq
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/ensure_packages.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/ensure_packages.rb
new file mode 100644
index 0000000..e1c4f65
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/ensure_packages.rb
@@ -0,0 +1,50 @@
+#
+# ensure_packages.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:ensure_packages, :type => :statement, :doc => <<-DOC
+ 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.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "ensure_packages(): Wrong number of arguments given (#{arguments.size} for 1 or 2)") if arguments.size > 2 || arguments.empty?
+ raise(Puppet::ParseError, 'ensure_packages(): Requires second argument to be a Hash') if arguments.size == 2 && !arguments[1].is_a?(Hash)
+
+ if arguments[0].is_a?(Hash)
+ if arguments[1]
+ defaults = { 'ensure' => 'present' }.merge(arguments[1])
+ if defaults['ensure'] == 'installed'
+ defaults['ensure'] = 'present'
+ end
+ else
+ defaults = { 'ensure' => 'present' }
+ end
+
+ Puppet::Parser::Functions.function(:ensure_resources)
+ function_ensure_resources(['package', arguments[0].dup, defaults])
+ else
+ packages = Array(arguments[0])
+
+ if arguments[1]
+ defaults = { 'ensure' => 'present' }.merge(arguments[1])
+ if defaults['ensure'] == 'installed'
+ defaults['ensure'] = 'present'
+ end
+ else
+ defaults = { 'ensure' => 'present' }
+ end
+
+ Puppet::Parser::Functions.function(:ensure_resource)
+ packages.each do |package_name|
+ raise(Puppet::ParseError, 'ensure_packages(): Empty String provided for package name') if package_name.empty?
+ unless findresource("Package[#{package_name}]")
+ function_ensure_resource(['package', package_name, defaults])
+ end
+ end
+ end
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/ensure_resource.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/ensure_resource.rb
new file mode 100644
index 0000000..d28ed9d
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/ensure_resource.rb
@@ -0,0 +1,46 @@
+# Test whether a given class or definition is defined
+require 'puppet/parser/functions'
+
+Puppet::Parser::Functions.newfunction(:ensure_resource,
+ :type => :statement,
+ :doc => <<-'DOC'
+ Takes a resource type, title, and a list of attributes that describe a
+ resource.
+
+ user { 'dan':
+ ensure => present,
+ }
+
+ This example only creates the resource if it does not already exist:
+
+ ensure_resource('user', 'dan', {'ensure' => 'present' })
+
+ If the resource already exists but does not match the specified parameters,
+ this function will attempt to recreate the resource leading to a duplicate
+ resource definition error.
+
+ An array of resources can also be passed in and each will be created with
+ the type and parameters specified if it doesn't already exist.
+
+ ensure_resource('user', ['dan','alex'], {'ensure' => 'present'})
+
+DOC
+ ) do |vals|
+ type, title, params = vals
+ raise(ArgumentError, 'Must specify a type') unless type
+ raise(ArgumentError, 'Must specify a title') unless title
+ params ||= {}
+
+ items = [title].flatten
+
+ items.each do |item|
+ Puppet::Parser::Functions.function(:defined_with_params)
+ if function_defined_with_params(["#{type}[#{item}]", params])
+ 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
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/ensure_resources.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/ensure_resources.rb
new file mode 100644
index 0000000..642247c
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/ensure_resources.rb
@@ -0,0 +1,50 @@
+require 'puppet/parser/functions'
+
+Puppet::Parser::Functions.newfunction(:ensure_resources,
+ :type => :statement,
+ :doc => <<-'DOC'
+ Takes a resource type, title (only hash), and a list of attributes that describe a
+ resource.
+
+ user { 'dan':
+ gid => 'mygroup',
+ ensure => present,
+ }
+
+ An hash of resources should be passed in and each will be created with
+ the type and parameters specified if it doesn't already exist.
+
+ ensure_resources('user', {'dan' => { gid => 'mygroup', uid => '600' } , 'alex' => { gid => 'mygroup' }}, {'ensure' => 'present'})
+
+ From Hiera Backend:
+
+ userlist:
+ dan:
+ gid: 'mygroup'
+ uid: '600'
+ alex:
+ gid: 'mygroup'
+
+ Call:
+ ensure_resources('user', hiera_hash('userlist'), {'ensure' => 'present'})
+DOC
+ ) do |vals|
+ type, title, params = vals
+ raise(ArgumentError, 'Must specify a type') unless type
+ raise(ArgumentError, 'Must specify a title') unless title
+ params ||= {}
+
+ raise(Puppet::ParseError, 'ensure_resources(): Requires second argument to be a Hash') unless title.is_a?(Hash)
+ resource_hash = title.dup
+ resources = resource_hash.keys
+
+ Puppet::Parser::Functions.function(:ensure_resource)
+ resources.each do |resource_name|
+ params_merged = if resource_hash[resource_name]
+ params.merge(resource_hash[resource_name])
+ else
+ params
+ end
+ function_ensure_resource([type, resource_name, params_merged])
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/flatten.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/flatten.rb
new file mode 100644
index 0000000..15970df
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/flatten.rb
@@ -0,0 +1,31 @@
+#
+# flatten.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:flatten, :type => :rvalue, :doc => <<-DOC
+ This function flattens any deeply nested arrays and returns a single flat array
+ as a result.
+
+ *Examples:*
+
+ flatten(['a', ['b', ['c']]])
+
+ Would return: ['a','b','c']
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "flatten(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.size != 1
+
+ array = arguments[0]
+
+ unless array.is_a?(Array)
+ raise(Puppet::ParseError, 'flatten(): Requires array to work with')
+ end
+
+ result = array.flatten
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/floor.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/floor.rb
new file mode 100644
index 0000000..9fcb048
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/floor.rb
@@ -0,0 +1,25 @@
+#
+# floor.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:floor, :type => :rvalue, :doc => <<-DOC
+ Returns the largest integer less or equal to the argument.
+ Takes a single numeric value as an argument.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "floor(): 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, "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
+
+ arg.floor
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/fqdn_rand_string.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/fqdn_rand_string.rb
new file mode 100644
index 0000000..ee45236
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/fqdn_rand_string.rb
@@ -0,0 +1,35 @@
+Puppet::Parser::Functions.newfunction(
+ :fqdn_rand_string,
+ :arity => -2,
+ :type => :rvalue,
+ :doc => "Usage: `fqdn_rand_string(LENGTH, [CHARSET], [SEED])`. LENGTH is
+ required and must be a positive integer. CHARSET is optional and may be
+ `undef` or a string. SEED is optional and may be any number or string.
+
+ Generates a random string LENGTH characters long using the character set
+ provided by CHARSET, combining the `$fqdn` fact and the value of SEED for
+ repeatable randomness. (That is, each node will get a different random
+ string from this function, but a given node's result will be the same every
+ time unless its hostname changes.) Adding a SEED can be useful if you need
+ more than one unrelated string. CHARSET will default to alphanumeric if
+ `undef` or an empty string.",
+) do |args|
+ raise(ArgumentError, 'fqdn_rand_string(): wrong number of arguments (0 for 1)') if args.empty?
+ Puppet::Parser::Functions.function('is_integer')
+ raise(ArgumentError, 'fqdn_rand_string(): first argument must be a positive integer') unless function_is_integer([args[0]]) && args[0].to_i > 0
+ raise(ArgumentError, 'fqdn_rand_string(): second argument must be undef or a string') unless args[1].nil? || args[1].is_a?(String)
+
+ Puppet::Parser::Functions.function('fqdn_rand')
+
+ length = args.shift.to_i
+ charset = args.shift.to_s.chars.to_a
+
+ charset = (0..9).map { |i| i.to_s } + ('A'..'Z').to_a + ('a'..'z').to_a if charset.empty?
+
+ rand_string = ''
+ for current in 1..length # rubocop:disable Style/For : An each loop would not work correctly in this circumstance
+ rand_string << charset[function_fqdn_rand([charset.size, (args + [current.to_s]).join(':')]).to_i]
+ end
+
+ rand_string
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/fqdn_rotate.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/fqdn_rotate.rb
new file mode 100644
index 0000000..879e44b
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/fqdn_rotate.rb
@@ -0,0 +1,59 @@
+#
+# fqdn_rotate.rb
+#
+Puppet::Parser::Functions.newfunction(
+ :fqdn_rotate,
+ :type => :rvalue,
+ :doc => "Usage: `fqdn_rotate(VALUE, [SEED])`. VALUE is required and
+ must be an array or a string. SEED is optional and may be any number
+ or string.
+
+ Rotates VALUE a random number of times, combining the `$fqdn` fact and
+ the value of SEED for repeatable randomness. (That is, each node will
+ get a different random rotation from this function, but a given node's
+ result will be the same every time unless its hostname changes.) Adding
+ a SEED can be useful if you need more than one unrelated rotation.",
+) do |args|
+
+ raise(Puppet::ParseError, "fqdn_rotate(): Wrong number of arguments given (#{args.size} for 1)") if args.empty?
+
+ value = args.shift
+ require 'digest/md5'
+
+ unless value.is_a?(Array) || value.is_a?(String)
+ raise(Puppet::ParseError, 'fqdn_rotate(): Requires either array or string to work with')
+ end
+
+ result = value.clone
+
+ string = value.is_a?(String) ? true : false
+
+ # Check whether it makes sense to rotate ...
+ return result if result.size <= 1
+
+ # We turn any string value into an array to be able to rotate ...
+ result = string ? result.split('') : result
+
+ elements = result.size
+
+ seed = Digest::MD5.hexdigest([lookupvar('::fqdn'), args].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
+ return offset = Random.new(seed).rand(elements) if defined?(Random) == 'constant' && Random.class == Class
+
+ old_seed = srand(seed)
+ offset = rand(elements)
+ srand(old_seed)
+ end
+ offset.times do
+ result.push result.shift
+ end
+
+ result = string ? result.join : result
+
+ return result
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/fqdn_uuid.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/fqdn_uuid.rb
new file mode 100644
index 0000000..5080e8e
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/fqdn_uuid.rb
@@ -0,0 +1,86 @@
+require 'digest/sha1'
+#
+# fqdn_uuid.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:fqdn_uuid, :type => :rvalue, :doc => <<-DOC) do |args|
+ Creates a UUID based on a given string, assumed to be the FQDN
+
+ For example, to generate a UUID based on the FQDN of a system:
+
+ Usage:
+
+ $uuid = fqdn_uuid($::fqdn)
+
+ The generated UUID will be the same for the given hostname
+
+ The resulting UUID is returned on the form:
+
+ 1d839dea-5e10-5243-88eb-e66815bd7d5c
+
+ (u.e. without any curly braces.)
+
+ The generated UUID is a version 5 UUID with the V5 DNS namespace:
+
+ 6ba7b810-9dad-11d1-80b4-00c04fd430c8
+
+ This only supports a the V5 SHA-1 hash, using the DNS namespace.
+
+ Please consult http://www.ietf.org/rfc/rfc4122.txt for the details on
+ UUID generation and example implementation.
+
+ No verification is present at the moment as whether the domain name given
+ is in fact a correct fully-qualified domain name. Therefore any arbitrary
+ string and/or alpha-numeric value can subside for a domain name.
+ DOC
+
+ raise(ArgumentError, 'fqdn_uuid: No arguments given') if args.empty?
+ raise(ArgumentError, "fqdn_uuid: Too many arguments given (#{args.length})") unless args.length == 1
+ fqdn = args[0]
+
+ # Code lovingly taken from
+ # https://github.com/puppetlabs/marionette-collective/blob/master/lib/mcollective/ssl.rb
+
+ # This is the UUID version 5 type DNS name space which is as follows:
+ #
+ # 6ba7b810-9dad-11d1-80b4-00c04fd430c8
+ #
+ uuid_name_space_dns = [0x6b,
+ 0xa7,
+ 0xb8,
+ 0x10,
+ 0x9d,
+ 0xad,
+ 0x11,
+ 0xd1,
+ 0x80,
+ 0xb4,
+ 0x00,
+ 0xc0,
+ 0x4f,
+ 0xd4,
+ 0x30,
+ 0xc8].map { |b| b.chr }.join
+
+ sha1 = Digest::SHA1.new
+ sha1.update(uuid_name_space_dns)
+ sha1.update(fqdn)
+
+ # first 16 bytes..
+ bytes = sha1.digest[0, 16].bytes.to_a
+
+ # version 5 adjustments
+ bytes[6] &= 0x0f
+ bytes[6] |= 0x50
+
+ # variant is DCE 1.1
+ bytes[8] &= 0x3f
+ bytes[8] |= 0x80
+
+ bytes = [4, 2, 2, 2, 6].map do |i|
+ bytes.slice!(0, i).pack('C*').unpack('H*')
+ end
+
+ bytes.join('-')
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/get_module_path.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/get_module_path.rb
new file mode 100644
index 0000000..3a95b71
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/get_module_path.rb
@@ -0,0 +1,18 @@
+#
+# get_module_path.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:get_module_path, :type => :rvalue, :doc => <<-DOC
+ Returns the absolute path of the specified module for the current
+ environment.
+
+ Example:
+ $module_path = get_module_path('stdlib')
+ DOC
+ ) do |args|
+ raise(Puppet::ParseError, 'get_module_path(): Wrong number of arguments, expects one') unless args.size == 1
+ module_path = Puppet::Module.find(args[0], compiler.environment.to_s)
+ raise(Puppet::ParseError, "Could not find module #{args[0]} in environment #{compiler.environment}") unless module_path
+ module_path.path
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/getparam.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/getparam.rb
new file mode 100644
index 0000000..d73650b
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/getparam.rb
@@ -0,0 +1,36 @@
+# Test whether a given class or definition is defined
+require 'puppet/parser/functions'
+
+Puppet::Parser::Functions.newfunction(:getparam,
+ :type => :rvalue,
+ :doc => <<-'DOC'
+ Takes a resource reference and name of the parameter and
+ returns value of resource's parameter.
+
+ *Examples:*
+
+ define example_resource($param) {
+ }
+
+ example_resource { "example_resource_instance":
+ param => "param_value"
+ }
+
+ getparam(Example_resource["example_resource_instance"], "param")
+
+ Would return: param_value
+ DOC
+ ) do |vals|
+ reference, param = vals
+ raise(ArgumentError, 'Must specify a reference') unless reference
+ raise(ArgumentError, 'Must specify name of a parameter') unless param && param.instance_of?(String)
+
+ return '' if param.empty?
+
+ resource = findresource(reference.to_s)
+ if resource
+ return resource[param] unless resource[param].nil?
+ end
+
+ return ''
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/getvar.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/getvar.rb
new file mode 100644
index 0000000..f464467
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/getvar.rb
@@ -0,0 +1,35 @@
+#
+# getvar.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:getvar, :type => :rvalue, :doc => <<-'DOC') do |args|
+ Lookup a variable in a remote namespace.
+
+ For example:
+
+ $foo = getvar('site::data::foo')
+ # Equivalent to $foo = $site::data::foo
+
+ This is useful if the namespace itself is stored in a string:
+
+ $datalocation = 'site::data'
+ $bar = getvar("${datalocation}::bar")
+ # Equivalent to $bar = $site::data::bar
+ DOC
+
+ unless args.length == 1
+ raise Puppet::ParseError, "getvar(): wrong number of arguments (#{args.length}; must be 1)"
+ end
+
+ begin
+ result = nil
+ catch(:undefined_variable) do
+ result = lookupvar((args[0]).to_s)
+ end
+
+ # avoid relying on incosistent behaviour around ruby return values from catch
+ result
+ rescue Puppet::ParseError # rubocop:disable Lint/HandleExceptions : Eat the exception if strict_variables = true is set
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/glob.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/glob.rb
new file mode 100644
index 0000000..e9d35b2
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/glob.rb
@@ -0,0 +1,25 @@
+#
+# glob.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:glob, :type => :rvalue, :doc => <<-'DOC'
+ Returns an Array of file entries of a directory or an Array of directories.
+ Uses same patterns as Dir#glob
+ DOC
+ ) do |arguments|
+
+ unless arguments.size == 1
+ raise(Puppet::ParseError, 'glob(): Wrong number of arguments given ' \
+ "(#{arguments.size} for 1)")
+ end
+
+ pattern = arguments[0]
+
+ unless pattern.is_a?(String) || pattern.is_a?(Array)
+ raise(Puppet::ParseError, 'glob(): Requires either array or string ' \
+ 'to work')
+ end
+
+ Dir.glob(pattern)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/grep.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/grep.rb
new file mode 100644
index 0000000..030c14a
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/grep.rb
@@ -0,0 +1,30 @@
+#
+# grep.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:grep, :type => :rvalue, :doc => <<-DOC
+ This function searches through an array and returns any elements that match
+ the provided regular expression.
+
+ *Examples:*
+
+ grep(['aaa','bbb','ccc','aaaddd'], 'aaa')
+
+ Would return:
+
+ ['aaa','aaaddd']
+ DOC
+ ) do |arguments|
+
+ if arguments.size != 2
+ raise(Puppet::ParseError, "grep(): Wrong number of arguments given #{arguments.size} for 2")
+ end
+
+ a = arguments[0]
+ pattern = Regexp.new(arguments[1])
+
+ a.grep(pattern)
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/has_interface_with.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/has_interface_with.rb
new file mode 100644
index 0000000..44005d0
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/has_interface_with.rb
@@ -0,0 +1,69 @@
+#
+# has_interface_with
+#
+module Puppet::Parser::Functions
+ newfunction(:has_interface_with, :type => :rvalue, :doc => <<-DOC
+ Returns boolean based on kind and value:
+ * macaddress
+ * netmask
+ * ipaddress
+ * network
+
+ has_interface_with("macaddress", "x:x:x:x:x:x")
+ has_interface_with("ipaddress", "127.0.0.1") => true
+ etc.
+
+ If no "kind" is given, then the presence of the interface is checked:
+ has_interface_with("lo") => true
+ DOC
+ ) do |args|
+
+ raise(Puppet::ParseError, "has_interface_with(): Wrong number of arguments given (#{args.size} for 1 or 2)") if args.empty? || args.size > 2
+
+ interfaces = lookupvar('interfaces')
+
+ # If we do not have any interfaces, then there are no requested attributes
+ return false if interfaces == :undefined || interfaces.nil?
+
+ interfaces = interfaces.split(',')
+
+ if args.size == 1
+ return interfaces.member?(args[0])
+ end
+
+ kind, value = args
+
+ # Bug with 3.7.1 - 3.7.3 when using future parser throws :undefined_variable
+ # https://tickets.puppetlabs.com/browse/PUP-3597
+ factval = nil
+ begin
+ catch :undefined_variable do
+ factval = lookupvar(kind)
+ end
+ rescue Puppet::ParseError # rubocop:disable Lint/HandleExceptions : Eat the exception if strict_variables = true is set
+ end
+ if factval == value
+ return true
+ end
+
+ result = false
+ interfaces.each do |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 # rubocop:disable Lint/HandleExceptions : Eat the exception if strict_variables = true is set
+ end
+ if value == factval
+ result = true
+ break
+ end
+ end
+
+ result
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/has_ip_address.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/has_ip_address.rb
new file mode 100644
index 0000000..5f14ee2
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/has_ip_address.rb
@@ -0,0 +1,22 @@
+#
+# has_ip_address
+#
+module Puppet::Parser::Functions
+ newfunction(:has_ip_address, :type => :rvalue, :doc => <<-DOC
+ Returns true if the client has the requested IP address on some interface.
+
+ This function iterates through the 'interfaces' fact and checks the
+ 'ipaddress_IFACE' facts, performing a simple string comparison.
+ DOC
+ ) do |args|
+
+ raise(Puppet::ParseError, "has_ip_address(): Wrong number of arguments given (#{args.size} for 1)") if args.size != 1
+
+ Puppet::Parser::Functions.autoloader.load(:has_interface_with) \
+ unless Puppet::Parser::Functions.autoloader.loaded?(:has_interface_with)
+
+ function_has_interface_with(['ipaddress', args[0]])
+ end
+end
+
+# vim:sts=2 sw=2
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/has_ip_network.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/has_ip_network.rb
new file mode 100644
index 0000000..65f2789
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/has_ip_network.rb
@@ -0,0 +1,22 @@
+#
+# has_ip_network
+#
+module Puppet::Parser::Functions
+ newfunction(:has_ip_network, :type => :rvalue, :doc => <<-DOC
+ Returns true if the client has an IP address within the requested network.
+
+ This function iterates through the 'interfaces' fact and checks the
+ 'network_IFACE' facts, performing a simple string comparision.
+ DOC
+ ) do |args|
+
+ raise(Puppet::ParseError, "has_ip_network(): Wrong number of arguments given (#{args.size} for 1)") if args.size != 1
+
+ Puppet::Parser::Functions.autoloader.load(:has_interface_with) \
+ unless Puppet::Parser::Functions.autoloader.loaded?(:has_interface_with)
+
+ function_has_interface_with(['network', args[0]])
+ end
+end
+
+# vim:sts=2 sw=2
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/has_key.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/has_key.rb
new file mode 100644
index 0000000..53b8c74
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/has_key.rb
@@ -0,0 +1,28 @@
+#
+# has_key.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:has_key, :type => :rvalue, :doc => <<-'DOC') do |args|
+ Determine if a hash has a certain key value.
+
+ Example:
+
+ $my_hash = {'key_one' => 'value_one'}
+ if has_key($my_hash, 'key_two') {
+ notice('we will not reach here')
+ }
+ if has_key($my_hash, 'key_one') {
+ notice('this will be printed')
+ }
+
+ DOC
+
+ unless args.length == 2
+ raise Puppet::ParseError, "has_key(): wrong number of arguments (#{args.length}; must be 2)"
+ end
+ unless args[0].is_a?(Hash)
+ raise Puppet::ParseError, "has_key(): expects the first argument to be a hash, got #{args[0].inspect} which is of type #{args[0].class}"
+ end
+ args[0].key?(args[1])
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/hash.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/hash.rb
new file mode 100644
index 0000000..f6644db
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/hash.rb
@@ -0,0 +1,38 @@
+#
+# hash.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:hash, :type => :rvalue, :doc => <<-DOC
+ This function converts an array into a hash.
+
+ *Examples:*
+
+ hash(['a',1,'b',2,'c',3])
+
+ Would return: {'a'=>1,'b'=>2,'c'=>3}
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "hash(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ array = arguments[0]
+
+ unless array.is_a?(Array)
+ raise(Puppet::ParseError, 'hash(): Requires array to work with')
+ end
+
+ result = {}
+
+ begin
+ # This is to make it compatible with older version of Ruby ...
+ array = array.flatten
+ result = Hash[*array]
+ rescue StandardError
+ raise(Puppet::ParseError, 'hash(): Unable to compute hash from array given')
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/intersection.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/intersection.rb
new file mode 100644
index 0000000..0c16722
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/intersection.rb
@@ -0,0 +1,31 @@
+#
+# intersection.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:intersection, :type => :rvalue, :doc => <<-DOC
+ This function returns an array of the intersection of two.
+
+ *Examples:*
+
+ intersection(["a","b","c"],["b","c","d"]) # returns ["b","c"]
+ intersection(["a","b","c"],[1,2,3,4]) # returns [] (true, when evaluated as a Boolean)
+ DOC
+ ) do |arguments|
+
+ # Two arguments are required
+ raise(Puppet::ParseError, "intersection(): Wrong number of arguments given (#{arguments.size} for 2)") if arguments.size != 2
+
+ first = arguments[0]
+ second = arguments[1]
+
+ unless first.is_a?(Array) && second.is_a?(Array)
+ raise(Puppet::ParseError, 'intersection(): Requires 2 arrays')
+ end
+
+ result = first & second
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_absolute_path.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_absolute_path.rb
new file mode 100644
index 0000000..06e9465
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_absolute_path.rb
@@ -0,0 +1,54 @@
+#
+# is_absolute_path.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:is_absolute_path, :type => :rvalue, :arity => 1, :doc => <<-'DOC') do |args|
+ Returns boolean true if the string represents an absolute path in the filesystem. This function works
+ for windows and unix style paths.
+
+ The following values will return true:
+
+ $my_path = 'C:/Program Files (x86)/Puppet Labs/Puppet'
+ is_absolute_path($my_path)
+ $my_path2 = '/var/lib/puppet'
+ is_absolute_path($my_path2)
+ $my_path3 = ['C:/Program Files (x86)/Puppet Labs/Puppet']
+ is_absolute_path($my_path3)
+ $my_path4 = ['/var/lib/puppet']
+ is_absolute_path($my_path4)
+
+ The following values will return false:
+
+ is_absolute_path(true)
+ is_absolute_path('../var/lib/puppet')
+ is_absolute_path('var/lib/puppet')
+ $undefined = undef
+ is_absolute_path($undefined)
+
+ DOC
+ function_deprecation([:is_absolute_path, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Absolute_path. There is further documentation for validate_legacy function in the README.'])
+ require 'puppet/util'
+
+ path = args[0]
+ # 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?)
+ value = (Puppet::Util.absolute_path?(path, :posix) || Puppet::Util.absolute_path?(path, :windows))
+ 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{^/},
+ }
+ value = !!(path =~ regexes[:posix]) || !!(path =~ regexes[:windows]) # rubocop:disable Style/DoubleNegation : No alternative known
+ end
+ value
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_array.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_array.rb
new file mode 100644
index 0000000..620f4f7
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_array.rb
@@ -0,0 +1,21 @@
+#
+# is_array.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:is_array, :type => :rvalue, :doc => <<-DOC
+ Returns true if the variable passed to this function is an array.
+ DOC
+ ) do |arguments|
+
+ function_deprecation([:is_array, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Array. There is further documentation for validate_legacy function in the README.'])
+
+ raise(Puppet::ParseError, "is_array(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ type = arguments[0]
+
+ result = type.is_a?(Array)
+
+ return result
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_bool.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_bool.rb
new file mode 100644
index 0000000..d0e0026
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_bool.rb
@@ -0,0 +1,21 @@
+#
+# is_bool.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:is_bool, :type => :rvalue, :doc => <<-DOC
+ Returns true if the variable passed to this function is a boolean.
+ DOC
+ ) do |arguments|
+
+ function_deprecation([:is_bool, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.'])
+
+ 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
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_domain_name.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_domain_name.rb
new file mode 100644
index 0000000..d80689a
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_domain_name.rb
@@ -0,0 +1,51 @@
+#
+# is_domain_name.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:is_domain_name, :type => :rvalue, :doc => <<-DOC
+ Returns true if the string passed to this function is a syntactically correct domain name.
+ DOC
+ ) do |arguments|
+
+ if arguments.size != 1
+ raise(Puppet::ParseError, "is_domain_name(): Wrong number of arguments given #{arguments.size} for 1")
+ end
+
+ # 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
+
+ # Allow ".", it is the top level domain
+ return true if domain == '.'
+
+ # Remove the final dot, if present.
+ domain.chomp!('.')
+
+ # Check the whole domain
+ return false if domain.empty?
+ return false if domain.length > domain_max_length
+
+ # The top level domain must be alphabetic if there are multiple labels.
+ # See rfc1123, 2.1
+ return false if domain.include?('.') && !%r{\.[A-Za-z]+$}.match(domain)
+
+ # Check each label in the domain
+ labels = domain.split('.')
+ vlabels = labels.each do |label|
+ break if label.length < label_min_length
+ break if label.length > label_max_length
+ break if label[-1..-1] == '-'
+ break if label[0..0] == '-'
+ break unless %r{^[a-z\d-]+$}i =~ label
+ end
+ return vlabels == labels
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_email_address.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_email_address.rb
new file mode 100644
index 0000000..f656468
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_email_address.rb
@@ -0,0 +1,19 @@
+#
+# is_email_address.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:is_email_address, :type => :rvalue, :doc => <<-DOC
+ Returns true if the string passed to this function is a valid email address.
+ DOC
+ ) do |arguments|
+ if arguments.size != 1
+ raise(Puppet::ParseError, "is_email_address(): Wrong number of arguments given #{arguments.size} for 1")
+ end
+
+ # Taken from http://emailregex.com/ (simpler regex)
+ valid_email_regex = %r{\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z}
+ return (arguments[0] =~ valid_email_regex) == 0 # rubocop:disable Style/NumericPredicate : Changing to '.zero?' breaks the code
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_float.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_float.rb
new file mode 100644
index 0000000..89994d2
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_float.rb
@@ -0,0 +1,27 @@
+#
+# is_float.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:is_float, :type => :rvalue, :doc => <<-DOC
+ Returns true if the variable passed to this function is a float.
+ DOC
+ ) do |arguments|
+
+ function_deprecation([:is_float, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Float. There is further documentation for validate_legacy function in the README.'])
+
+ if arguments.size != 1
+ raise(Puppet::ParseError, "is_float(): Wrong number of arguments given #{arguments.size} for 1")
+ end
+
+ value = arguments[0]
+
+ # Only allow Numeric or String types
+ return false unless value.is_a?(Numeric) || value.is_a?(String)
+
+ return false if value != value.to_f.to_s && !value.is_a?(Float)
+ return true
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_function_available.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_function_available.rb
new file mode 100644
index 0000000..e02aa53
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_function_available.rb
@@ -0,0 +1,24 @@
+#
+# is_function_available.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:is_function_available, :type => :rvalue, :doc => <<-DOC
+ This function accepts a string as an argument, determines whether the
+ Puppet runtime has access to a function by that name. It returns a
+ true if the function exists, false if not.
+ DOC
+ ) do |arguments|
+
+ if arguments.size != 1
+ raise(Puppet::ParseError, "is_function_available?(): Wrong number of arguments 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) && !function.empty?
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_hash.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_hash.rb
new file mode 100644
index 0000000..dc03653
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_hash.rb
@@ -0,0 +1,20 @@
+#
+# is_hash.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:is_hash, :type => :rvalue, :doc => <<-DOC
+ Returns true if the variable passed to this function is a hash.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "is_hash(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.size != 1
+
+ type = arguments[0]
+
+ result = type.is_a?(Hash)
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_integer.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_integer.rb
new file mode 100644
index 0000000..7444cac
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_integer.rb
@@ -0,0 +1,43 @@
+#
+# is_integer.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:is_integer, :type => :rvalue, :doc => <<-DOC
+ 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.
+ DOC
+ ) do |arguments|
+
+ function_deprecation([:is_integer, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.'])
+
+ if arguments.size != 1
+ raise(Puppet::ParseError, "is_integer(): Wrong number of arguments given #{arguments.size} for 1")
+ end
+
+ value = arguments[0]
+
+ # 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)$}
+
+ return true if value.is_a?(Integer) || (value.is_a?(String) && value.match(numeric))
+ return false
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_ip_address.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_ip_address.rb
new file mode 100644
index 0000000..6ce993a
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_ip_address.rb
@@ -0,0 +1,30 @@
+#
+# is_ip_address.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:is_ip_address, :type => :rvalue, :doc => <<-DOC
+ Returns true if the string passed to this function is a valid IP address.
+ DOC
+ ) do |arguments|
+
+ require 'ipaddr'
+
+ function_deprecation([:is_ip_address, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Ip_address. There is further documentation for validate_legacy function in the README.'])
+
+ if arguments.size != 1
+ raise(Puppet::ParseError, "is_ip_address(): Wrong number of arguments given #{arguments.size} for 1")
+ end
+
+ begin
+ ip = IPAddr.new(arguments[0])
+ rescue ArgumentError
+ return false
+ end
+
+ return true if ip.ipv4? || ip.ipv6?
+ return false
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_ipv4_address.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_ipv4_address.rb
new file mode 100644
index 0000000..7f2241b
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_ipv4_address.rb
@@ -0,0 +1,29 @@
+#
+# is_ipv4_address.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:is_ipv4_address, :type => :rvalue, :doc => <<-DOC
+ Returns true if the string passed to this function is a valid IPv4 address.
+ DOC
+ ) do |arguments|
+
+ require 'ipaddr'
+
+ function_deprecation([:is_ipv4_address, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Ipv4. There is further documentation for validate_legacy function in the README.'])
+
+ if arguments.size != 1
+ raise(Puppet::ParseError, "is_ipv4_address(): Wrong number of arguments given #{arguments.size} for 1")
+ end
+
+ begin
+ ip = IPAddr.new(arguments[0])
+ rescue ArgumentError
+ return false
+ end
+
+ return ip.ipv4?
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_ipv6_address.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_ipv6_address.rb
new file mode 100644
index 0000000..35be026
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_ipv6_address.rb
@@ -0,0 +1,29 @@
+#
+# is_ipv6_address.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:is_ipv6_address, :type => :rvalue, :doc => <<-DOC
+ Returns true if the string passed to this function is a valid IPv6 address.
+ DOC
+ ) do |arguments|
+
+ function_deprecation([:is_ipv6_address, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Ipv6. There is further documentation for validate_legacy function in the README.'])
+
+ require 'ipaddr'
+
+ if arguments.size != 1
+ raise(Puppet::ParseError, "is_ipv6_address(): Wrong number of arguments given #{arguments.size} for 1")
+ end
+
+ begin
+ ip = IPAddr.new(arguments[0])
+ rescue ArgumentError
+ return false
+ end
+
+ return ip.ipv6?
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_mac_address.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_mac_address.rb
new file mode 100644
index 0000000..83a5ba2
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_mac_address.rb
@@ -0,0 +1,21 @@
+#
+# is_mac_address.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:is_mac_address, :type => :rvalue, :doc => <<-DOC
+ Returns true if the string passed to this function is a valid mac address.
+ DOC
+ ) do |arguments|
+
+ if arguments.size != 1
+ raise(Puppet::ParseError, "is_mac_address(): Wrong number of arguments given #{arguments.size} for 1")
+ end
+
+ mac = arguments[0]
+
+ return true if %r{^[a-f0-9]{1,2}(:[a-f0-9]{1,2}){5}$}i =~ mac
+ return false
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_numeric.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_numeric.rb
new file mode 100644
index 0000000..e127705
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_numeric.rb
@@ -0,0 +1,74 @@
+#
+# is_numeric.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:is_numeric, :type => :rvalue, :doc => <<-DOC
+ 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
+ DOC
+ ) do |arguments|
+
+ function_deprecation([:is_numeric, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.'])
+
+ if arguments.size != 1
+ raise(Puppet::ParseError, "is_numeric(): Wrong number of arguments given #{arguments.size} for 1")
+ end
+
+ value = arguments[0]
+
+ # 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) || (value.is_a?(String) &&
+ value.match(numeric) # or
+ # value.match(numeric_hex) or
+ # value.match(numeric_oct)
+ )
+ return true
+ else
+ return false
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_string.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_string.rb
new file mode 100644
index 0000000..f7b1b14
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/is_string.rb
@@ -0,0 +1,28 @@
+#
+# is_string.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:is_string, :type => :rvalue, :doc => <<-DOC
+ Returns true if the variable passed to this function is a string.
+ DOC
+ ) do |arguments|
+
+ function_deprecation([:is_string, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::String. There is further documentation for validate_legacy function in the README.'])
+
+ raise(Puppet::ParseError, "is_string(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ type = arguments[0]
+
+ # when called through the v4 API shim, undef gets translated to nil
+ result = type.is_a?(String) || type.nil?
+
+ if result && (type == type.to_f.to_s || type == type.to_i.to_s)
+ return false
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/join.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/join.rb
new file mode 100644
index 0000000..bcb97b7
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/join.rb
@@ -0,0 +1,39 @@
+#
+# join.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:join, :type => :rvalue, :doc => <<-DOC
+ This function joins an array into a string using a separator.
+
+ *Examples:*
+
+ join(['a','b','c'], ",")
+
+ Would result in: "a,b,c"
+ DOC
+ ) do |arguments|
+
+ # Technically we support two arguments but only first is mandatory ...
+ raise(Puppet::ParseError, "join(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ array = arguments[0]
+
+ unless array.is_a?(Array)
+ raise(Puppet::ParseError, 'join(): Requires array to work with')
+ end
+
+ suffix = arguments[1] if arguments[1]
+
+ if suffix
+ unless suffix.is_a?(String)
+ raise(Puppet::ParseError, 'join(): Requires string to work with')
+ end
+ end
+
+ result = suffix ? array.join(suffix) : array.join
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/join_keys_to_values.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/join_keys_to_values.rb
new file mode 100644
index 0000000..3232fa8
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/join_keys_to_values.rb
@@ -0,0 +1,53 @@
+#
+# join.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:join_keys_to_values, :type => :rvalue, :doc => <<-DOC
+ This function joins each key of a hash to that key's corresponding value with a
+ separator. Keys are cast to strings. If values are arrays, multiple keys
+ are added for each element. The return value is an array in
+ which each element is one joined key/value pair.
+
+ *Examples:*
+
+ join_keys_to_values({'a'=>1,'b'=>2}, " is ")
+
+ Would result in: ["a is 1","b is 2"]
+
+ join_keys_to_values({'a'=>1,'b'=>[2,3]}, " is ")
+
+ Would result in: ["a is 1","b is 2","b is 3"]
+ DOC
+ ) do |arguments|
+
+ # Validate the number of arguments.
+ if arguments.size != 2
+ raise(Puppet::ParseError, "join_keys_to_values(): Takes exactly two arguments, but #{arguments.size} given.")
+ end
+
+ # Validate the first argument.
+ hash = arguments[0]
+ unless hash.is_a?(Hash)
+ raise(TypeError, "join_keys_to_values(): The first argument must be a hash, but a #{hash.class} was given.")
+ end
+
+ # Validate the second argument.
+ separator = arguments[1]
+ unless separator.is_a?(String)
+ raise(TypeError, "join_keys_to_values(): The second argument must be a string, but a #{separator.class} was given.")
+ end
+
+ # Join the keys to their values.
+ hash.map { |k, v|
+ if v.is_a?(Array)
+ v.map { |va| String(k) + separator + String(va) }
+ elsif String(v) == 'undef'
+ String(k)
+ else
+ String(k) + separator + String(v)
+ end
+ }.flatten
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/keys.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/keys.rb
new file mode 100644
index 0000000..0ecd48f
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/keys.rb
@@ -0,0 +1,24 @@
+#
+# keys.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:keys, :type => :rvalue, :doc => <<-DOC
+ Returns the keys of a hash as an array.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "keys(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ hash = arguments[0]
+
+ unless hash.is_a?(Hash)
+ raise(Puppet::ParseError, 'keys(): Requires hash to work with')
+ end
+
+ result = hash.keys
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/load_module_metadata.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/load_module_metadata.rb
new file mode 100644
index 0000000..f9a39de
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/load_module_metadata.rb
@@ -0,0 +1,25 @@
+#
+# load_module_metadata.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:load_module_metadata, :type => :rvalue, :doc => <<-DOC
+ This function loads the metadata of a given module.
+ DOC
+ ) do |args|
+ raise(Puppet::ParseError, 'load_module_metadata(): Wrong number of arguments, expects one or two') unless [1, 2].include?(args.size)
+ mod = args[0]
+ allow_empty_metadata = args[1]
+ module_path = function_get_module_path([mod])
+ metadata_json = File.join(module_path, 'metadata.json')
+
+ metadata_exists = File.exists?(metadata_json) # rubocop:disable Lint/DeprecatedClassMethods : Changing to .exist? breaks the code
+ if metadata_exists
+ metadata = PSON.load(File.read(metadata_json))
+ else
+ metadata = {}
+ raise(Puppet::ParseError, "load_module_metadata(): No metadata.json file for module #{mod}") unless allow_empty_metadata
+ end
+
+ return metadata
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/loadjson.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/loadjson.rb
new file mode 100644
index 0000000..9a1d54f
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/loadjson.rb
@@ -0,0 +1,32 @@
+#
+# loadjson.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:loadjson, :type => :rvalue, :arity => -2, :doc => <<-'DOC') do |args|
+ Load a JSON file containing an array, string, or hash, and return the data
+ in the corresponding native data type.
+ The second parameter is the default value. It will be returned if the file
+ was not found or could not be parsed.
+
+ For example:
+
+ $myhash = loadjson('/etc/puppet/data/myhash.json')
+ $myhash = loadjson('no-file.json', {'default' => 'value'})
+ DOC
+
+ raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless args.length >= 1
+
+ if File.exists?(args[0]) # rubocop:disable Lint/DeprecatedClassMethods : Changing to .exist? breaks the code
+ begin
+ content = File.read(args[0])
+ PSON.load(content) || args[1]
+ rescue StandardError => e
+ raise e unless args[1]
+ args[1]
+ end
+ else
+ warning("Can't load '#{args[0]}' File does not exist!")
+ args[1]
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/loadyaml.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/loadyaml.rb
new file mode 100644
index 0000000..a8c9e62
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/loadyaml.rb
@@ -0,0 +1,32 @@
+#
+# loadyaml.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:loadyaml, :type => :rvalue, :arity => -2, :doc => <<-'DOC') do |args|
+ Load a YAML file containing an array, string, or hash, and return the data
+ in the corresponding native data type.
+ The second parameter is the default value. It will be returned if the file
+ was not found or could not be parsed.
+
+ For example:
+
+ $myhash = loadyaml('/etc/puppet/data/myhash.yaml')
+ $myhash = loadyaml('no-file.yaml', {'default' => 'value'})
+ DOC
+
+ raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless args.length >= 1
+ require 'yaml'
+
+ if File.exists?(args[0]) # rubocop:disable Lint/DeprecatedClassMethods : Changing to .exist? breaks the code
+ begin
+ YAML.load_file(args[0]) || args[1]
+ rescue StandardError => e
+ raise e unless args[1]
+ args[1]
+ end
+ else
+ warning("Can't load '#{args[0]}' File does not exist!")
+ args[1]
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/lstrip.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/lstrip.rb
new file mode 100644
index 0000000..f5b9a58
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/lstrip.rb
@@ -0,0 +1,29 @@
+#
+# lstrip.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:lstrip, :type => :rvalue, :doc => <<-DOC
+ Strips leading spaces to the left of a string.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "lstrip(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ value = arguments[0]
+
+ unless value.is_a?(Array) || value.is_a?(String)
+ raise(Puppet::ParseError, 'lstrip(): Requires either array or string to work with')
+ end
+
+ result = if value.is_a?(Array)
+ # Numbers in Puppet are often string-encoded which is troublesome ...
+ value.map { |i| i.is_a?(String) ? i.lstrip : i }
+ else
+ value.lstrip
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/max.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/max.rb
new file mode 100644
index 0000000..21c5245
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/max.rb
@@ -0,0 +1,23 @@
+#
+# max.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:max, :type => :rvalue, :doc => <<-DOC
+ Returns the highest value of all arguments.
+ Requires at least one argument.
+ DOC
+ ) do |args|
+
+ raise(Puppet::ParseError, 'max(): Wrong number of arguments need at least one') if args.empty?
+
+ # Sometimes we get numbers as numerics and sometimes as strings.
+ # We try to compare them as numbers when possible
+ return args.max do |a, b|
+ if a.to_s =~ %r{\A-?\d+(.\d+)?\z} && b.to_s =~ %r{\A-?\d+(.\d+)?\z}
+ a.to_f <=> b.to_f
+ else
+ a.to_s <=> b.to_s
+ end
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/member.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/member.rb
new file mode 100644
index 0000000..9261080
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/member.rb
@@ -0,0 +1,57 @@
+# TODO(Krzysztof Wilczynski): We need to add support for regular expression ...
+# TODO(Krzysztof Wilczynski): Support for strings and hashes too ...
+#
+# member.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:member, :type => :rvalue, :doc => <<-DOC
+ This function determines if a variable is a member of an array.
+ The variable can be a string, fixnum, or array.
+
+ *Examples:*
+
+ member(['a','b'], 'b')
+
+ 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
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "member(): Wrong number of arguments given (#{arguments.size} for 2)") if arguments.size < 2
+
+ array = arguments[0]
+
+ unless array.is_a?(Array)
+ raise(Puppet::ParseError, 'member(): Requires array to work with')
+ end
+
+ unless arguments[1].is_a?(String) || arguments[1].is_a?(Integer) || arguments[1].is_a?(Array)
+ raise(Puppet::ParseError, 'member(): Item to search for must be a string, fixnum, or array')
+ end
+
+ item = if arguments[1].is_a?(String) || arguments[1].is_a?(Integer)
+ [arguments[1]]
+ else
+ arguments[1]
+ end
+
+ raise(Puppet::ParseError, 'member(): You must provide item to search for within array given') if item.respond_to?('empty?') && item.empty?
+
+ result = (item - array).empty?
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/merge.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/merge.rb
new file mode 100644
index 0000000..25ebc79
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/merge.rb
@@ -0,0 +1,37 @@
+#
+# merge.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:merge, :type => :rvalue, :doc => <<-'DOC') do |args|
+ Merges two or more hashes together and returns the resulting hash.
+
+ For example:
+
+ $hash1 = {'one' => 1, 'two', => 2}
+ $hash2 = {'two' => 'dos', 'three', => 'tres'}
+ $merged_hash = merge($hash1, $hash2)
+ # The resulting hash is equivalent to:
+ # $merged_hash = {'one' => 1, 'two' => 'dos', 'three' => 'tres'}
+
+ When there is a duplicate key, the key in the rightmost hash will "win."
+
+ DOC
+
+ if args.length < 2
+ raise Puppet::ParseError, "merge(): wrong number of arguments (#{args.length}; must be at least 2)"
+ end
+
+ # The hash we accumulate into
+ accumulator = {}
+ # Merge into the accumulator hash
+ args.each do |arg|
+ next if arg.is_a?(String) && arg.empty? # empty string is synonym for puppet's undef
+ unless arg.is_a?(Hash)
+ raise Puppet::ParseError, "merge: unexpected argument type #{arg.class}, only expects hash arguments"
+ end
+ accumulator.merge!(arg)
+ end
+ # Return the fully merged hash
+ accumulator
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/min.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/min.rb
new file mode 100644
index 0000000..985ec56
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/min.rb
@@ -0,0 +1,23 @@
+#
+# min.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:min, :type => :rvalue, :doc => <<-DOC
+ Returns the lowest value of all arguments.
+ Requires at least one argument.
+ DOC
+ ) do |args|
+
+ raise(Puppet::ParseError, 'min(): Wrong number of arguments need at least one') if args.empty?
+
+ # Sometimes we get numbers as numerics and sometimes as strings.
+ # We try to compare them as numbers when possible
+ return args.min do |a, b|
+ if a.to_s =~ %r{\A^-?\d+(.\d+)?\z} && b.to_s =~ %r{\A-?\d+(.\d+)?\z}
+ a.to_f <=> b.to_f
+ else
+ a.to_s <=> b.to_s
+ end
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/num2bool.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/num2bool.rb
new file mode 100644
index 0000000..0957c56
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/num2bool.rb
@@ -0,0 +1,41 @@
+#
+# num2bool.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:num2bool, :type => :rvalue, :doc => <<-DOC
+ This function converts a number or a string representation of a number into a
+ true boolean. Zero or anything non-numeric becomes false. Numbers higher then 0
+ become true.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "num2bool(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.size != 1
+
+ number = arguments[0]
+
+ case number
+ when Numeric # rubocop:disable Lint/EmptyWhen : Required for the module to work
+ # Yay, it's a number
+ when String
+ begin
+ number = Float(number)
+ rescue ArgumentError => ex
+ raise(Puppet::ParseError, "num2bool(): '#{number}' does not look like a number: #{ex.message}")
+ end
+ else
+ begin
+ number = number.to_s
+ rescue NoMethodError => ex
+ raise(Puppet::ParseError, "num2bool(): Unable to parse argument: #{ex.message}")
+ end
+ end
+
+ # Truncate Floats
+ number = number.to_i
+
+ # Return true for any positive number and false otherwise
+ return number > 0
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/parsejson.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/parsejson.rb
new file mode 100644
index 0000000..4cc43e6
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/parsejson.rb
@@ -0,0 +1,24 @@
+#
+# parsejson.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:parsejson, :type => :rvalue, :doc => <<-DOC
+ This function accepts JSON as a string and converts it into the correct
+ Puppet structure.
+
+ The optional second argument can be used to pass a default value that will
+ be returned if the parsing of YAML string have failed.
+ DOC
+ ) do |arguments|
+ raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless arguments.length >= 1
+
+ begin
+ PSON.load(arguments[0]) || arguments[1]
+ rescue StandardError => e
+ raise e unless arguments[1]
+ arguments[1]
+ end
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/parseyaml.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/parseyaml.rb
new file mode 100644
index 0000000..7f857ca
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/parseyaml.rb
@@ -0,0 +1,28 @@
+#
+# parseyaml.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:parseyaml, :type => :rvalue, :doc => <<-DOC
+ This function accepts YAML as a string and converts it into the correct
+ Puppet structure.
+
+ The optional second argument can be used to pass a default value that will
+ be returned if the parsing of YAML string have failed.
+ DOC
+ ) do |arguments|
+ raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless arguments.length >= 1
+ require 'yaml'
+
+ begin
+ YAML.load(arguments[0]) || arguments[1] # rubocop:disable Security/YAMLLoad : using YAML.safe_load causes the code to break
+ # in ruby 1.9.3 Psych::SyntaxError is a RuntimeException
+ # this still needs to catch that and work also on rubies that
+ # do not have Psych available.
+ rescue StandardError, Psych::SyntaxError => e # rubocop:disable Lint/ShadowedException : See above
+ raise e unless arguments[1]
+ arguments[1]
+ end
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/pick.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/pick.rb
new file mode 100644
index 0000000..300e164
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/pick.rb
@@ -0,0 +1,27 @@
+#
+# pick.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:pick, :type => :rvalue, :doc => <<-DOC
+ 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). 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($::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.
+DOC
+ ) do |args|
+ args = args.compact
+ args.delete(:undef)
+ args.delete(:undefined)
+ args.delete('')
+ raise Puppet::ParseError, 'pick(): must receive at least one non empty value' if args[0].to_s.empty?
+ return args[0]
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/pick_default.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/pick_default.rb
new file mode 100644
index 0000000..29aaef2
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/pick_default.rb
@@ -0,0 +1,36 @@
+#
+# pick_default.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:pick_default, :type => :rvalue, :doc => <<-DOC
+ 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.
+DOC
+ ) do |args|
+ raise '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/code/environments/production/modules/stdlib/lib/puppet/parser/functions/prefix.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/prefix.rb
new file mode 100644
index 0000000..7490a18
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/prefix.rb
@@ -0,0 +1,50 @@
+#
+# prefix.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:prefix, :type => :rvalue, :doc => <<-DOC
+ This function applies a prefix to all elements in an array or a hash.
+
+ *Examples:*
+
+ prefix(['a','b','c'], 'p')
+
+ Will return: ['pa','pb','pc']
+ DOC
+ ) do |arguments|
+
+ # Technically we support two arguments but only first is mandatory ...
+ raise(Puppet::ParseError, "prefix(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ enumerable = arguments[0]
+
+ unless enumerable.is_a?(Array) || 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]
+
+ if prefix
+ unless prefix.is_a?(String)
+ raise Puppet::ParseError, "prefix(): expected second argument to be a String, got #{prefix.inspect}"
+ end
+ end
+
+ result = if enumerable.is_a?(Array)
+ # Turn everything into string same as join would do ...
+ enumerable.map do |i|
+ i = i.to_s
+ prefix ? prefix + i : i
+ end
+ else
+ Hash[enumerable.map do |k, v|
+ k = k.to_s
+ [prefix ? prefix + k : k, v]
+ end]
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/private.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/private.rb
new file mode 100644
index 0000000..5e0b7c5
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/private.rb
@@ -0,0 +1,16 @@
+#
+# private.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:private, :doc => <<-'DOC'
+ DEPRECATED: Sets the current class or definition as private.
+ Calling the class or definition from outside the current module will fail.
+ DOC
+ ) do |args|
+ warning("private() DEPRECATED: This function will cease to function on Puppet 4; please use assert_private() before upgrading to puppet 4 for backwards-compatibility, or migrate to the new parser's typing system.") # rubocop:disable Metrics/LineLength : Cannot shorten this line
+ unless Puppet::Parser::Functions.autoloader.loaded?(:assert_private)
+ Puppet::Parser::Functions.autoloader.load(:assert_private)
+ end
+ function_assert_private([(args[0] unless args.empty?)])
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/pry.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/pry.rb
new file mode 100644
index 0000000..17b3bc7
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/pry.rb
@@ -0,0 +1,29 @@
+#
+# pry.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:pry, :type => :statement, :doc => <<-DOC
+ This function invokes a pry debugging session in the current scope object. This is useful for debugging manifest code at specific points during a compilation.
+
+ *Examples:*
+
+ pry()
+ DOC
+ ) do |arguments|
+ begin
+ require 'pry'
+ rescue LoadError
+ raise(Puppet::Error, "pry(): Requires the 'pry' rubygem to use, but it was not found")
+ end
+ #
+ ## Run `catalog` to see the contents currently compiling catalog
+ ## Run `cd catalog` and `ls` to see catalog methods and instance variables
+ ## Run `@resource_table` to see the current catalog resource table
+ #
+ if $stdout.isatty
+ binding.pry # rubocop:disable Lint/Debugger
+ else
+ Puppet.warning 'pry(): cowardly refusing to start the debugger on a daemonized master'
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/pw_hash.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/pw_hash.rb
new file mode 100644
index 0000000..eaf1d74
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/pw_hash.rb
@@ -0,0 +1,62 @@
+# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085.
+Puppet::Parser::Functions.newfunction(
+ :pw_hash,
+ :type => :rvalue,
+ :arity => 3,
+ :doc => "Hashes a password using the crypt function. Provides a hash
+ usable on most POSIX systems.
+
+ The first argument to this function is the password to hash. If it is
+ undef or an empty string, this function returns undef.
+
+ The second argument to this function is which type of hash to use. It
+ will be converted into the appropriate crypt(3) hash specifier. Valid
+ hash types are:
+
+ |Hash type |Specifier|
+ |---------------------|---------|
+ |MD5 |1 |
+ |SHA-256 |5 |
+ |SHA-512 (recommended)|6 |
+
+ The third argument to this function is the salt to use.
+
+ Note: this uses the Puppet Master's implementation of crypt(3). If your
+ environment contains several different operating systems, ensure that they
+ are compatible before using this function.",
+) do |args|
+ raise ArgumentError, "pw_hash(): wrong number of arguments (#{args.size} for 3)" if args.size != 3
+ args.map! do |arg|
+ if (defined? Puppet::Pops::Types::PSensitiveType::Sensitive) && (arg.is_a? Puppet::Pops::Types::PSensitiveType::Sensitive)
+ arg.unwrap
+ else
+ arg
+ end
+ end
+ raise ArgumentError, 'pw_hash(): first argument must be a string' unless args[0].is_a?(String) || args[0].nil?
+ raise ArgumentError, 'pw_hash(): second argument must be a string' unless args[1].is_a? String
+ hashes = { 'md5' => '1',
+ 'sha-256' => '5',
+ 'sha-512' => '6' }
+ hash_type = hashes[args[1].downcase]
+ raise ArgumentError, "pw_hash(): #{args[1]} is not a valid hash type" if hash_type.nil?
+ raise ArgumentError, 'pw_hash(): third argument must be a string' unless args[2].is_a? String
+ raise ArgumentError, 'pw_hash(): third argument must not be empty' if args[2].empty?
+ raise ArgumentError, 'pw_hash(): characters in salt must be in the set [a-zA-Z0-9./]' unless args[2] =~ %r{\A[a-zA-Z0-9./]+\z}
+
+ password = args[0]
+ return nil if password.nil? || password.empty?
+
+ salt = "$#{hash_type}$#{args[2]}"
+
+ # handle weak implementations of String#crypt
+ if 'test'.crypt('$1$1') != '$1$1$Bp8CU9Oujr9SSEw53WV6G.'
+ # JRuby < 1.7.17
+ # MS Windows and other systems that don't support enhanced salts
+ raise Puppet::ParseError, 'system does not support enhanced salts' unless RUBY_PLATFORM == 'java'
+ # puppetserver bundles Apache Commons Codec
+ org.apache.commons.codec.digest.Crypt.crypt(password.to_java_bytes, salt)
+ else
+ password.crypt(salt)
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/range.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/range.rb
new file mode 100644
index 0000000..3e5cc44
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/range.rb
@@ -0,0 +1,84 @@
+#
+# range.rb
+#
+# TODO(Krzysztof Wilczynski): We probably need to approach numeric values differently ...
+module Puppet::Parser::Functions
+ newfunction(:range, :type => :rvalue, :doc => <<-DOC
+ When given range in the form of (start, stop) it will extrapolate a range as
+ an array.
+
+ *Examples:*
+
+ range("0", "9")
+
+ Will return: [0,1,2,3,4,5,6,7,8,9]
+
+ range("00", "09")
+
+ Will return: [0,1,2,3,4,5,6,7,8,9] (Zero padded strings are converted to
+ integers automatically)
+
+ range("a", "c")
+
+ Will return: ["a","b","c"]
+
+ range("host01", "host10")
+ Will return: ["host01", "host02", ..., "host09", "host10"]
+ NB Be explicit in including trailing zeros. Otherwise the underlying ruby function will fail.
+
+ Passing a third argument will cause the generated range to step by that
+ interval, e.g.
+
+ range("0", "9", "2")
+
+ Will return: [0,2,4,6,8]
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, 'range(): Wrong number of arguments given (0 for 1)') if arguments.empty?
+
+ if arguments.size > 1
+ start = arguments[0]
+ stop = arguments[1]
+ step = arguments[2].nil? ? 1 : arguments[2].to_i.abs
+
+ type = '..' # Use the simplest type of Range available in Ruby
+
+ else # arguments.size == 1
+ value = arguments[0]
+
+ m = value.match(%r{^(\w+)(\.\.\.?|\-)(\w+)$})
+ if m
+ start = m[1]
+ stop = m[3]
+
+ type = m[2]
+ step = 1
+ elsif value =~ %r{^.+$}
+ raise(Puppet::ParseError, "range(): Unable to compute range from the value: #{value}")
+ else
+ raise(Puppet::ParseError, "range(): Unknown range format: #{value}")
+ end
+ end
+
+ # If we were given an integer, ensure we work with one
+ if start.to_s =~ %r{^\d+$}
+ start = start.to_i
+ stop = stop.to_i
+ else
+ start = start.to_s
+ stop = stop.to_s
+ end
+
+ range = case type
+ when %r{^(..|-)$} then (start..stop)
+ when '...' then (start...stop) # Exclusive of last element
+ end
+
+ result = range.step(step).to_a
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/regexpescape.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/regexpescape.rb
new file mode 100644
index 0000000..647d865
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/regexpescape.rb
@@ -0,0 +1,29 @@
+#
+# regexpescape.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:regexpescape, :type => :rvalue, :doc => <<-DOC
+ Regexp escape a string or array of strings.
+ Requires either a single string or an array as an input.
+ DOC
+ ) do |arguments| # rubocop:disable Layout/ClosingParenthesisIndentation
+ raise(Puppet::ParseError, "regexpescape(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ value = arguments[0]
+
+ unless value.is_a?(Array) || value.is_a?(String)
+ raise(Puppet::ParseError, 'regexpescape(): Requires either array or string to work with')
+ end
+
+ result = if value.is_a?(Array)
+ # Numbers in Puppet are often string-encoded which is troublesome ...
+ value.map { |i| i.is_a?(String) ? Regexp.escape(i) : i }
+ else
+ Regexp.escape(value)
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/reject.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/reject.rb
new file mode 100644
index 0000000..be2f017
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/reject.rb
@@ -0,0 +1,30 @@
+#
+# reject.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:reject, :type => :rvalue, :doc => <<-DOC) do |args|
+ This function searches through an array and rejects all elements that match
+ the provided regular expression.
+
+ *Examples:*
+
+ reject(['aaa','bbb','ccc','aaaddd'], 'aaa')
+
+ Would return:
+
+ ['bbb','ccc']
+DOC
+
+ if args.size != 2
+ raise Puppet::ParseError,
+ "reject(): Wrong number of arguments given #{args.size} for 2"
+ end
+
+ ary = args[0]
+ pattern = Regexp.new(args[1])
+
+ ary.reject { |e| e =~ pattern }
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/reverse.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/reverse.rb
new file mode 100644
index 0000000..ea911ec
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/reverse.rb
@@ -0,0 +1,24 @@
+#
+# reverse.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:reverse, :type => :rvalue, :doc => <<-DOC
+ Reverses the order of a string or array.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "reverse(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ value = arguments[0]
+
+ unless value.is_a?(Array) || value.is_a?(String)
+ raise(Puppet::ParseError, 'reverse(): Requires either array or string to work with')
+ end
+
+ result = value.reverse
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/round.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/round.rb
new file mode 100644
index 0000000..b4f2c2b
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/round.rb
@@ -0,0 +1,32 @@
+#
+# round.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:round, :type => :rvalue, :doc => <<-DOC
+ Rounds a number to the nearest integer
+
+ *Examples:*
+
+ round(2.9)
+
+ returns: 3
+
+ round(2.4)
+
+ returns: 2
+
+ DOC
+ ) do |args|
+
+ raise Puppet::ParseError, "round(): Wrong number of arguments given #{args.size} for 1" if args.size != 1
+ raise Puppet::ParseError, "round(): Expected a Numeric, got #{args[0].class}" unless args[0].is_a? Numeric
+
+ value = args[0]
+
+ if value >= 0
+ Integer(value + 0.5)
+ else
+ Integer(value - 0.5)
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/rstrip.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/rstrip.rb
new file mode 100644
index 0000000..3e04b27
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/rstrip.rb
@@ -0,0 +1,28 @@
+#
+# rstrip.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:rstrip, :type => :rvalue, :doc => <<-DOC
+ Strips leading spaces to the right of the string.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "rstrip(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ value = arguments[0]
+
+ unless value.is_a?(Array) || value.is_a?(String)
+ raise(Puppet::ParseError, 'rstrip(): Requires either array or string to work with')
+ end
+
+ result = if value.is_a?(Array)
+ value.map { |i| i.is_a?(String) ? i.rstrip : i }
+ else
+ value.rstrip
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/seeded_rand.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/seeded_rand.rb
new file mode 100644
index 0000000..0120b87
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/seeded_rand.rb
@@ -0,0 +1,24 @@
+#
+# seeded_rand.rb
+#
+Puppet::Parser::Functions.newfunction(
+ :seeded_rand,
+ :arity => 2,
+ :type => :rvalue,
+ :doc => <<-DOC
+ Usage: `seeded_rand(MAX, SEED)`. MAX must be a positive integer; SEED is any string.
+
+ Generates a random whole number greater than or equal to 0 and less
+ than MAX, using the value of SEED for repeatable randomness. If SEED
+ starts with "$fqdn:", this is behaves the same as `fqdn_rand`.
+DOC
+) do |args|
+ require 'digest/md5'
+
+ raise(ArgumentError, 'seeded_rand(): first argument must be a positive integer') unless function_is_integer([args[0]]) && args[0].to_i > 0
+ raise(ArgumentError, 'seeded_rand(): second argument must be a string') unless args[1].is_a? String
+
+ max = args[0].to_i
+ seed = Digest::MD5.hexdigest(args[1]).hex
+ Puppet::Util.deterministic_rand(seed, max)
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/shell_escape.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/shell_escape.rb
new file mode 100644
index 0000000..96fea20
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/shell_escape.rb
@@ -0,0 +1,27 @@
+require 'shellwords'
+#
+# shell_escape.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:shell_escape, :type => :rvalue, :doc => <<-DOC
+ Escapes a string so that it can be safely used in a Bourne shell command line.
+
+ Note that the resulting string should be used unquoted and is not intended for use in double quotes nor in single
+ quotes.
+
+ This function behaves the same as ruby's Shellwords.shellescape() function.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "shell_escape(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.size != 1
+
+ # explicit conversion to string is required for ruby 1.9
+ string = arguments[0].to_s
+
+ result = Shellwords.shellescape(string)
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/shell_join.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/shell_join.rb
new file mode 100644
index 0000000..0a037c1
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/shell_join.rb
@@ -0,0 +1,29 @@
+
+require 'shellwords'
+#
+# shell_join.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:shell_join, :type => :rvalue, :doc => <<-DOC
+ Builds a command line string from the given array of strings. Each array item is escaped for Bourne shell. All items are
+ then joined together, with a single space in between.
+
+ This function behaves the same as ruby's Shellwords.shelljoin() function
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "shell_join(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.size != 1
+
+ array = arguments[0]
+
+ raise Puppet::ParseError, "First argument is not an Array: #{array.inspect}" unless array.is_a?(Array)
+
+ # explicit conversion to string is required for ruby 1.9
+ array = array.map { |item| item.to_s }
+ result = Shellwords.shelljoin(array)
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/shell_split.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/shell_split.rb
new file mode 100644
index 0000000..9dcf958
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/shell_split.rb
@@ -0,0 +1,23 @@
+require 'shellwords'
+#
+# shell_split.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:shell_split, :type => :rvalue, :doc => <<-DOC
+ Splits a string into an array of tokens in the same way the Bourne shell does.
+
+ This function behaves the same as ruby's Shellwords.shellsplit() function
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "shell_split(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.size != 1
+
+ string = arguments[0].to_s
+
+ result = Shellwords.shellsplit(string)
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/shuffle.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/shuffle.rb
new file mode 100644
index 0000000..5e6d93b
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/shuffle.rb
@@ -0,0 +1,42 @@
+#
+# shuffle.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:shuffle, :type => :rvalue, :doc => <<-DOC
+ Randomizes the order of a string or array elements.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "shuffle(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ value = arguments[0]
+
+ unless value.is_a?(Array) || value.is_a?(String)
+ raise(Puppet::ParseError, 'shuffle(): Requires either array or string to work with')
+ end
+
+ result = value.clone
+
+ string = value.is_a?(String) ? true : false
+
+ # Check whether it makes sense to shuffle ...
+ return result if result.size <= 1
+
+ # We turn any string value into an array to be able to shuffle ...
+ result = string ? result.split('') : result
+
+ elements = result.size
+
+ # Simple implementation of Fisher–Yates in-place shuffle ...
+ elements.times do |i|
+ j = rand(elements - i) + i
+ result[j], result[i] = result[i], result[j]
+ end
+
+ result = string ? result.join : result
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/size.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/size.rb
new file mode 100644
index 0000000..27f9614
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/size.rb
@@ -0,0 +1,44 @@
+#
+# size.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:size, :type => :rvalue, :doc => <<-DOC
+ Returns the number of elements in a string, an array or a hash
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "size(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ item = arguments[0]
+
+ function_deprecation([:size, 'This method is going to be deprecated, please use the stdlib length function.'])
+
+ if item.is_a?(String)
+
+ begin
+ #
+ # Check whether your item is a numeric value or not ...
+ # This will take care about positive and/or negative numbers
+ # for both integer and floating-point values ...
+ #
+ # Please note that Puppet has no notion of hexadecimal
+ # nor octal numbers for its DSL at this point in time ...
+ #
+ Float(item)
+
+ raise(Puppet::ParseError, 'size(): Requires either string, array or hash to work with')
+ rescue ArgumentError
+ result = item.size
+ end
+
+ elsif item.is_a?(Array) || item.is_a?(Hash)
+ result = item.size
+ else
+ raise(Puppet::ParseError, 'size(): Unknown type given')
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/sort.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/sort.rb
new file mode 100644
index 0000000..f0b4a14
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/sort.rb
@@ -0,0 +1,25 @@
+#
+# sort.rb
+# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085.
+#
+module Puppet::Parser::Functions
+ newfunction(:sort, :type => :rvalue, :doc => <<-DOC
+ Sorts strings and arrays lexically.
+ DOC
+ ) do |arguments|
+
+ if arguments.size != 1
+ raise(Puppet::ParseError, "sort(): Wrong number of arguments given #{arguments.size} for 1")
+ end
+
+ value = arguments[0]
+
+ if value.is_a?(Array)
+ value.sort
+ elsif value.is_a?(String)
+ value.split('').sort.join('')
+ end
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/squeeze.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/squeeze.rb
new file mode 100644
index 0000000..eaa1404
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/squeeze.rb
@@ -0,0 +1,31 @@
+#
+# squeeze.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:squeeze, :type => :rvalue, :doc => <<-DOC
+ Returns a new string where runs of the same character that occur in this set are replaced by a single character.
+ DOC
+ ) do |arguments|
+
+ if (arguments.size != 2) && (arguments.size != 1)
+ raise(Puppet::ParseError, "squeeze(): Wrong number of arguments given #{arguments.size} for 2 or 1")
+ end
+
+ item = arguments[0]
+ squeezeval = arguments[1]
+
+ if item.is_a?(Array)
+ if squeezeval
+ item.map { |i| i.squeeze(squeezeval) }
+ else
+ item.map { |i| i.squeeze }
+ end
+ elsif squeezeval
+ item.squeeze(squeezeval)
+ else
+ item.squeeze
+ end
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/str2bool.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/str2bool.rb
new file mode 100644
index 0000000..95c260c
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/str2bool.rb
@@ -0,0 +1,43 @@
+#
+# str2bool.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:str2bool, :type => :rvalue, :doc => <<-DOC
+ This converts a string to a boolean. This attempt to convert strings that
+ contain things like: Y,y, 1, T,t, TRUE,true to 'true' and strings that contain things
+ like: 0, F,f, N,n, false, FALSE, no to 'false'.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "str2bool(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ string = arguments[0]
+
+ # If string is already Boolean, return it
+ if !!string == string # rubocop:disable Style/DoubleNegation : No viable alternative
+ return string
+ end
+
+ unless string.is_a?(String)
+ raise(Puppet::ParseError, 'str2bool(): Requires string to work with')
+ end
+
+ # We consider all the yes, no, y, n and so on too ...
+ result = case string
+ #
+ # This is how undef looks like in Puppet ...
+ # We yield false in this case.
+ #
+ when %r{^$}, '' then false # Empty string will be false ...
+ when %r{^(1|t|y|true|yes)$}i then true
+ when %r{^(0|f|n|false|no)$}i then false
+ when %r{^(undef|undefined)$} then false # This is not likely to happen ...
+ else
+ raise(Puppet::ParseError, 'str2bool(): Unknown type of boolean given')
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/str2saltedsha512.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/str2saltedsha512.rb
new file mode 100644
index 0000000..4d62008
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/str2saltedsha512.rb
@@ -0,0 +1,30 @@
+#
+# str2saltedsha512.rb
+# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085.
+#
+module Puppet::Parser::Functions
+ newfunction(:str2saltedsha512, :type => :rvalue, :doc => <<-DOC
+ This converts a string to a salted-SHA512 password hash (which is used for
+ OS X versions >= 10.7). Given any simple string, you will get a hex version
+ of a salted-SHA512 password hash that can be inserted into your Puppet
+ manifests as a valid password attribute.
+ DOC
+ ) do |arguments|
+ require 'digest/sha2'
+
+ raise(Puppet::ParseError, "str2saltedsha512(): Wrong number of arguments passed (#{arguments.size} but we require 1)") if arguments.size != 1
+
+ password = arguments[0]
+
+ unless password.is_a?(String)
+ raise(Puppet::ParseError, "str2saltedsha512(): Requires a String argument, you passed: #{password.class}")
+ end
+
+ seedint = rand(2**31 - 1)
+ seedstring = Array(seedint).pack('L')
+ saltedpass = Digest::SHA512.digest(seedstring + password)
+ (seedstring + saltedpass).unpack('H*')[0]
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/strftime.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/strftime.rb
new file mode 100644
index 0000000..53cf749
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/strftime.rb
@@ -0,0 +1,105 @@
+#
+# strftime.rb
+# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085.
+#
+module Puppet::Parser::Functions
+ newfunction(:strftime, :type => :rvalue, :doc => <<-DOC
+ This function returns formatted time.
+
+ *Examples:*
+
+ To return the time since epoch:
+
+ strftime("%s")
+
+ To return the date:
+
+ strftime("%Y-%m-%d")
+
+ *Format meaning:*
+
+ %a - The abbreviated weekday name (``Sun'')
+ %A - The full weekday name (``Sunday'')
+ %b - The abbreviated month name (``Jan'')
+ %B - The full month name (``January'')
+ %c - The preferred local date and time representation
+ %C - Century (20 in 2009)
+ %d - Day of the month (01..31)
+ %D - Date (%m/%d/%y)
+ %e - Day of the month, blank-padded ( 1..31)
+ %F - Equivalent to %Y-%m-%d (the ISO 8601 date format)
+ %h - Equivalent to %b
+ %H - Hour of the day, 24-hour clock (00..23)
+ %I - Hour of the day, 12-hour clock (01..12)
+ %j - Day of the year (001..366)
+ %k - hour, 24-hour clock, blank-padded ( 0..23)
+ %l - hour, 12-hour clock, blank-padded ( 0..12)
+ %L - Millisecond of the second (000..999)
+ %m - Month of the year (01..12)
+ %M - Minute of the hour (00..59)
+ %n - Newline (\n)
+ %N - Fractional seconds digits, default is 9 digits (nanosecond)
+ %3N millisecond (3 digits)
+ %6N microsecond (6 digits)
+ %9N nanosecond (9 digits)
+ %p - Meridian indicator (``AM'' or ``PM'')
+ %P - Meridian indicator (``am'' or ``pm'')
+ %r - time, 12-hour (same as %I:%M:%S %p)
+ %R - time, 24-hour (%H:%M)
+ %s - Number of seconds since 1970-01-01 00:00:00 UTC.
+ %S - Second of the minute (00..60)
+ %t - Tab character (\t)
+ %T - time, 24-hour (%H:%M:%S)
+ %u - Day of the week as a decimal, Monday being 1. (1..7)
+ %U - Week number of the current year,
+ starting with the first Sunday as the first
+ day of the first week (00..53)
+ %v - VMS date (%e-%b-%Y)
+ %V - Week number of year according to ISO 8601 (01..53)
+ %W - Week number of the current year,
+ starting with the first Monday as the first
+ day of the first week (00..53)
+ %w - Day of the week (Sunday is 0, 0..6)
+ %x - Preferred representation for the date alone, no time
+ %X - Preferred representation for the time alone, no date
+ %y - Year without a century (00..99)
+ %Y - Year with century
+ %z - Time zone as hour offset from UTC (e.g. +0900)
+ %Z - Time zone name
+ %% - Literal ``%'' character
+ DOC
+ ) do |arguments|
+
+ # Technically we support two arguments but only first is mandatory ...
+ raise(Puppet::ParseError, "strftime(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ format = arguments[0]
+
+ raise(Puppet::ParseError, 'strftime(): You must provide format for evaluation') if format.empty?
+
+ # The Time Zone argument is optional ...
+ time_zone = arguments[1] if arguments[1]
+
+ time = Time.new
+
+ # There is probably a better way to handle Time Zone ...
+ if time_zone && !time_zone.empty?
+ original_zone = ENV['TZ']
+
+ local_time = time.clone
+ local_time = local_time.utc
+
+ ENV['TZ'] = time_zone
+
+ time = local_time.localtime
+
+ ENV['TZ'] = original_zone
+ end
+
+ result = time.strftime(format)
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/strip.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/strip.rb
new file mode 100644
index 0000000..6a147cd
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/strip.rb
@@ -0,0 +1,35 @@
+#
+# strip.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:strip, :type => :rvalue, :doc => <<-DOC
+ This function removes leading and trailing whitespace from a string or from
+ every string inside an array.
+
+ *Examples:*
+
+ strip(" aaa ")
+
+ Would result in: "aaa"
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "strip(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ value = arguments[0]
+
+ unless value.is_a?(Array) || value.is_a?(String)
+ raise(Puppet::ParseError, 'strip(): Requires either array or string to work with')
+ end
+
+ result = if value.is_a?(Array)
+ value.map { |i| i.is_a?(String) ? i.strip : i }
+ else
+ value.strip
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/suffix.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/suffix.rb
new file mode 100644
index 0000000..407cd53
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/suffix.rb
@@ -0,0 +1,51 @@
+#
+# suffix.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:suffix, :type => :rvalue, :doc => <<-DOC
+ This function applies a suffix to all elements in an array, or to the keys
+ in a hash.
+
+ *Examples:*
+
+ suffix(['a','b','c'], 'p')
+
+ Will return: ['ap','bp','cp']
+ DOC
+ ) do |arguments|
+
+ # Technically we support two arguments but only first is mandatory ...
+ raise(Puppet::ParseError, "suffix(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ enumerable = arguments[0]
+
+ unless enumerable.is_a?(Array) || enumerable.is_a?(Hash)
+ raise Puppet::ParseError, "suffix(): expected first argument to be an Array or a Hash, got #{enumerable.inspect}"
+ end
+
+ suffix = arguments[1] if arguments[1]
+
+ if suffix
+ unless suffix.is_a? String
+ raise Puppet::ParseError, "suffix(): expected second argument to be a String, got #{suffix.inspect}"
+ end
+ end
+
+ result = if enumerable.is_a?(Array)
+ # Turn everything into string same as join would do ...
+ enumerable.map do |i|
+ i = i.to_s
+ suffix ? i + suffix : i
+ end
+ else
+ Hash[enumerable.map do |k, v|
+ k = k.to_s
+ [suffix ? k + suffix : k, v]
+ end]
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/swapcase.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/swapcase.rb
new file mode 100644
index 0000000..e8a5d9a
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/swapcase.rb
@@ -0,0 +1,36 @@
+#
+# swapcase.rb
+# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085.
+#
+module Puppet::Parser::Functions
+ newfunction(:swapcase, :type => :rvalue, :doc => <<-DOC
+ This function will swap the existing case of a string.
+
+ *Examples:*
+
+ swapcase("aBcD")
+
+ Would result in: "AbCd"
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "swapcase(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ value = arguments[0]
+
+ unless value.is_a?(Array) || value.is_a?(String)
+ raise(Puppet::ParseError, 'swapcase(): Requires either array or string to work with')
+ end
+
+ result = if value.is_a?(Array)
+ # Numbers in Puppet are often string-encoded which is troublesome ...
+ value.map { |i| i.is_a?(String) ? i.swapcase : i }
+ else
+ value.swapcase
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/time.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/time.rb
new file mode 100644
index 0000000..021a483
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/time.rb
@@ -0,0 +1,48 @@
+#
+# time.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:time, :type => :rvalue, :doc => <<-DOC
+ This function will return the current time since epoch as an integer.
+
+ *Examples:*
+
+ time()
+
+ Will return something like: 1311972653
+ DOC
+ ) do |arguments|
+
+ # The Time Zone argument is optional ...
+ time_zone = arguments[0] if arguments[0]
+
+ if !arguments.empty? && (arguments.size != 1)
+ raise(Puppet::ParseError, "time(): Wrong number of arguments given #{arguments.size} for 0 or 1")
+ end
+
+ time = Time.new
+
+ # There is probably a better way to handle Time Zone ...
+ if time_zone && !time_zone.empty?
+ original_zone = ENV['TZ']
+
+ local_time = time.clone
+ local_time = local_time.utc
+
+ ENV['TZ'] = time_zone
+
+ result = local_time.localtime.strftime('%s')
+
+ ENV['TZ'] = original_zone
+ else
+ result = time.localtime.strftime('%s')
+ end
+
+ # Calling Time#to_i on a receiver changes it. Trust me I am the Doctor.
+ result = result.to_i
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/to_bytes.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/to_bytes.rb
new file mode 100644
index 0000000..bff24b0
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/to_bytes.rb
@@ -0,0 +1,33 @@
+#
+# to_bytes.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:to_bytes, :type => :rvalue, :doc => <<-DOC
+ 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.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "to_bytes(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.size != 1
+
+ arg = arguments[0]
+
+ return arg if arg.is_a? Numeric
+
+ value, prefix = *%r{([0-9.e+-]*)\s*([^bB]?)}.match(arg)[1, 2]
+
+ value = value.to_f
+ case prefix
+ when '' then return value.to_i
+ when 'k' then return (value * (1 << 10)).to_i
+ 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 '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
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/try_get_value.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/try_get_value.rb
new file mode 100644
index 0000000..34f9476
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/try_get_value.rb
@@ -0,0 +1,56 @@
+#
+# try_get_value.rb
+#
+module Puppet::Parser::Functions
+ newfunction(
+ :try_get_value,
+ :type => :rvalue,
+ :arity => -2,
+ :doc => <<-DOC
+ DEPRECATED: this function is deprecated, please use dig() instead.
+
+ Looks up into a complex structure of arrays and hashes and returns a value
+ or the default value if nothing was found.
+
+ Key can contain slashes to describe path components. The function will go down
+ the structure and try to extract the required value.
+
+ $data = {
+ 'a' => {
+ 'b' => [
+ 'b1',
+ 'b2',
+ 'b3',
+ ]
+ }
+ }
+
+ $value = try_get_value($data, 'a/b/2', 'not_found', '/')
+ => $value = 'b3'
+
+ a -> first hash key
+ b -> second hash key
+ 2 -> array index starting with 0
+
+ not_found -> (optional) will be returned if there is no value or the path did not match. Defaults to nil.
+ / -> (optional) path delimiter. Defaults to '/'.
+
+ In addition to the required "key" argument, "try_get_value" accepts default
+ argument. It will be returned if no value was found or a path component is
+ missing. And the fourth argument can set a variable path separator.
+ DOC
+ ) do |args|
+ warning('try_get_value() DEPRECATED: this function is deprecated, please use dig() instead.')
+ data = args[0]
+ path = args[1] || ''
+ default = args[2]
+
+ if !(data.is_a?(Hash) || data.is_a?(Array)) || path == ''
+ return default || data
+ end
+
+ separator = args[3] || '/'
+ path = path.split(separator).map { |key| (key =~ %r{^\d+$}) ? key.to_i : key }
+ function_dig([data, path, default])
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/type.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/type.rb
new file mode 100644
index 0000000..d9d841b
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/type.rb
@@ -0,0 +1,18 @@
+#
+# type.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:type, :type => :rvalue, :doc => <<-DOC
+ 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.
+ DOC
+ ) do |args|
+
+ 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.") # rubocop:disable Metrics/LineLength : Cannot reduce line length
+ unless Puppet::Parser::Functions.autoloader.loaded?(:type3x)
+ Puppet::Parser::Functions.autoloader.load(:type3x)
+ end
+ function_type3x(args)
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/type3x.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/type3x.rb
new file mode 100644
index 0000000..f5b46aa
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/type3x.rb
@@ -0,0 +1,49 @@
+#
+# type3x.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:type3x, :type => :rvalue, :doc => <<-DOC
+ 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
+ DOC
+ ) do |args|
+ raise(Puppet::ParseError, "type3x(): Wrong number of arguments given (#{args.size} for 1)") unless args.size == 1
+
+ value = args[0]
+
+ klass = value.class
+
+ unless [TrueClass, FalseClass, Array, Bignum, Fixnum, Float, Hash, String].include?(klass) # rubocop:disable Lint/UnifiedInteger
+ 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 %r{^(?:Big|Fix)num$} then 'integer'
+ when %r{^(?:True|False)Class$} then 'boolean'
+ else klass
+ end
+
+ if result == 'String'
+ if value == value.to_i.to_s
+ result = 'Integer'
+ elsif value == value.to_f.to_s
+ result = 'Float'
+ end
+ end
+
+ return result.downcase
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/union.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/union.rb
new file mode 100644
index 0000000..ed57bc5
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/union.rb
@@ -0,0 +1,27 @@
+#
+# union.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:union, :type => :rvalue, :doc => <<-DOC
+ This function returns a union of two or more arrays.
+
+ *Examples:*
+
+ union(["a","b","c"],["b","c","d"])
+
+ Would return: ["a","b","c","d"]
+ DOC
+ ) do |arguments|
+
+ # Check that 2 or more arguments have been given ...
+ raise(Puppet::ParseError, "union(): Wrong number of arguments given (#{arguments.size} for < 2)") if arguments.size < 2
+
+ arguments.each do |argument|
+ raise(Puppet::ParseError, 'union(): Every parameter must be an array') unless argument.is_a?(Array)
+ end
+
+ arguments.reduce(:|)
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/unique.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/unique.rb
new file mode 100644
index 0000000..301f6a4
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/unique.rb
@@ -0,0 +1,51 @@
+#
+# unique.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:unique, :type => :rvalue, :doc => <<-DOC
+ This function will remove duplicates from strings and arrays.
+
+ *Examples:*
+
+ unique("aabbcc")
+
+ Will return:
+
+ abc
+
+ You can also use this with arrays:
+
+ unique(["a","a","b","b","c","c"])
+
+ This returns:
+
+ ["a","b","c"]
+ DOC
+ ) do |arguments|
+
+ if Puppet::Util::Package.versioncmp(Puppet.version, '5.0.0') >= 0
+ function_deprecation([:unique, 'This method is deprecated, please use the core puppet unique function. There is further documentation for the function in the release notes of Puppet 5.0.'])
+ end
+
+ raise(Puppet::ParseError, "unique(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ value = arguments[0]
+
+ unless value.is_a?(Array) || value.is_a?(String)
+ raise(Puppet::ParseError, 'unique(): Requires either array or string to work with')
+ end
+
+ result = value.clone
+
+ string = value.is_a?(String) ? true : false
+
+ # We turn any string value into an array to be able to shuffle ...
+ result = string ? result.split('') : result
+ result = result.uniq # Remove duplicates ...
+ result = string ? result.join : result
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/unix2dos.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/unix2dos.rb
new file mode 100644
index 0000000..8123797
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/unix2dos.rb
@@ -0,0 +1,15 @@
+# Custom Puppet function to convert unix to dos format
+module Puppet::Parser::Functions
+ newfunction(:unix2dos, :type => :rvalue, :arity => 1, :doc => <<-DOC
+ Returns the DOS version of the given string.
+ Takes a single string argument.
+ DOC
+ ) do |arguments|
+
+ unless arguments[0].is_a?(String)
+ raise(Puppet::ParseError, 'unix2dos(): Requires string as argument')
+ end
+
+ arguments[0].gsub(%r{\r*\n}, "\r\n")
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/upcase.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/upcase.rb
new file mode 100644
index 0000000..42e6114
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/upcase.rb
@@ -0,0 +1,43 @@
+#
+# upcase.rb
+# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085.
+#
+module Puppet::Parser::Functions
+ newfunction(:upcase, :type => :rvalue, :doc => <<-DOC
+ Converts a string or an array of strings to uppercase.
+
+ *Examples:*
+
+ upcase("abcd")
+
+ Will return:
+
+ ABCD
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "upcase(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.size != 1
+
+ value = arguments[0]
+
+ 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.map { |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
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/uriescape.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/uriescape.rb
new file mode 100644
index 0000000..8bcd586
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/uriescape.rb
@@ -0,0 +1,32 @@
+require 'uri'
+#
+# uriescape.rb
+# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085.
+#
+module Puppet::Parser::Functions
+ newfunction(:uriescape, :type => :rvalue, :doc => <<-DOC
+ Urlencodes a string or array of strings.
+ Requires either a single string or an array as an input.
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "uriescape(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ value = arguments[0]
+
+ unless value.is_a?(Array) || value.is_a?(String)
+ raise(Puppet::ParseError, 'uriescape(): Requires either array or string to work with')
+ end
+
+ result = if value.is_a?(Array)
+ # Numbers in Puppet are often string-encoded which is troublesome ...
+ value.map { |i| i.is_a?(String) ? URI.escape(i) : i }
+ else
+ URI.escape(value)
+ end
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_absolute_path.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_absolute_path.rb
new file mode 100644
index 0000000..0db10c3
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_absolute_path.rb
@@ -0,0 +1,54 @@
+#
+# validate_absolute_path.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_absolute_path, :doc => <<-'DOC') do |args|
+ Validate the string represents an absolute path in the filesystem. This function works
+ for windows and unix style paths.
+
+ The following values will pass:
+
+ $my_path = 'C:/Program Files (x86)/Puppet Labs/Puppet'
+ validate_absolute_path($my_path)
+ $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
+ validate_absolute_path($undefined)
+
+ DOC
+
+ require 'puppet/util'
+
+ if args.empty?
+ raise Puppet::ParseError, "validate_absolute_path(): wrong number of arguments (#{args.length}; must be > 0)"
+ end
+
+ args.each do |arg|
+ # 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)
+ candidates = Array.new(1, arg)
+ end
+ # iterate over all paths within the candidates array
+ candidates.each do |path|
+ unless function_is_absolute_path([path])
+ raise Puppet::ParseError, "#{path.inspect} is not an absolute path."
+ end
+ end
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_array.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_array.rb
new file mode 100644
index 0000000..1120ce8
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_array.rb
@@ -0,0 +1,36 @@
+#
+# validate_array.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_array, :doc => <<-'DOC') do |args|
+ Validate that all passed values are array data structures. Abort catalog
+ compilation if any value fails this check.
+
+ The following values will pass:
+
+ $my_array = [ 'one', 'two' ]
+ validate_array($my_array)
+
+ The following values will fail, causing compilation to abort:
+
+ validate_array(true)
+ validate_array('some_string')
+ $undefined = undef
+ validate_array($undefined)
+
+ DOC
+
+ function_deprecation([:validate_array, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Array. There is further documentation for validate_legacy function in the README.'])
+
+ if args.empty?
+ raise Puppet::ParseError, "validate_array(): wrong number of arguments (#{args.length}; must be > 0)"
+ end
+
+ args.each do |arg|
+ unless arg.is_a?(Array)
+ raise Puppet::ParseError, "#{arg.inspect} is not an Array. It looks to be a #{arg.class}"
+ end
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_augeas.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_augeas.rb
new file mode 100644
index 0000000..97f3127
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_augeas.rb
@@ -0,0 +1,86 @@
+require 'tempfile'
+
+#
+# validate_augaes.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_augeas, :doc => <<-'DOC') do |args|
+ Perform validation of a string using an Augeas lens
+ The first argument of this function should be a string to
+ test, and the second argument should be the name of the Augeas lens to use.
+ If Augeas fails to parse the string with the lens, the compilation will
+ abort with a parse error.
+
+ A third argument can be specified, listing paths which should
+ not be found in the file. The `$file` variable points to the location
+ of the temporary file being tested in the Augeas tree.
+
+ For example, if you want to make sure your passwd content never contains
+ a user `foo`, you could write:
+
+ validate_augeas($passwdcontent, 'Passwd.lns', ['$file/foo'])
+
+ Or if you wanted to ensure that no users used the '/bin/barsh' shell,
+ you could use:
+
+ validate_augeas($passwdcontent, 'Passwd.lns', ['$file/*[shell="/bin/barsh"]']
+
+ If a fourth argument is specified, this will be the error message raised and
+ seen by the user.
+
+ A helpful error message can be returned like this:
+
+ validate_augeas($sudoerscontent, 'Sudoers.lns', [], 'Failed to validate sudoers content with Augeas')
+
+ DOC
+ unless Puppet.features.augeas?
+ raise Puppet::ParseError, 'validate_augeas(): this function requires the augeas feature. See http://docs.puppetlabs.com/guides/augeas.html#pre-requisites for how to activate it.'
+ end
+
+ if (args.length < 2) || (args.length > 4)
+ raise Puppet::ParseError, "validate_augeas(): wrong number of arguments (#{args.length}; must be 2, 3, or 4)"
+ end
+
+ msg = args[3] || "validate_augeas(): Failed to validate content against #{args[1].inspect}"
+
+ require 'augeas'
+ aug = Augeas.open(nil, nil, Augeas::NO_MODL_AUTOLOAD)
+ begin
+ content = args[0]
+
+ # Test content in a temporary file
+ tmpfile = Tempfile.new('validate_augeas')
+ begin
+ tmpfile.write(content)
+ ensure
+ tmpfile.close
+ end
+
+ # Check for syntax
+ lens = args[1]
+ aug.transform(
+ :lens => lens,
+ :name => 'Validate_augeas',
+ :incl => tmpfile.path,
+ )
+ aug.load!
+
+ unless aug.match("/augeas/files#{tmpfile.path}//error").empty?
+ error = aug.get("/augeas/files#{tmpfile.path}//error/message")
+ msg += " with error: #{error}"
+ raise Puppet::ParseError, msg
+ end
+
+ # Launch unit tests
+ tests = args[2] || []
+ aug.defvar('file', "/files#{tmpfile.path}")
+ tests.each do |t|
+ msg += " testing path #{t}"
+ raise Puppet::ParseError, msg unless aug.match(t).empty?
+ end
+ ensure
+ aug.close
+ tmpfile.unlink
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_bool.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_bool.rb
new file mode 100644
index 0000000..d3bf3d0
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_bool.rb
@@ -0,0 +1,34 @@
+#
+# validate_bool.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_bool, :doc => <<-'DOC') do |args|
+ Validate that all passed values are either true or false. Abort catalog
+ compilation if any value fails this check.
+
+ The following values will pass:
+
+ $iamtrue = true
+ validate_bool(true)
+ validate_bool(true, true, false, $iamtrue)
+
+ The following values will fail, causing compilation to abort:
+
+ $some_array = [ true ]
+ validate_bool("false")
+ validate_bool("true")
+ validate_bool($some_array)
+
+ DOC
+
+ if args.empty?
+ raise Puppet::ParseError, "validate_bool(): wrong number of arguments (#{args.length}; must be > 0)"
+ end
+
+ args.each do |arg|
+ unless function_is_bool([arg])
+ raise Puppet::ParseError, "#{arg.inspect} is not a boolean. It looks to be a #{arg.class}"
+ end
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_cmd.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_cmd.rb
new file mode 100644
index 0000000..dbea604
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_cmd.rb
@@ -0,0 +1,66 @@
+require 'puppet/util/execution'
+require 'tempfile'
+
+#
+# validate_cmd.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_cmd, :doc => <<-'DOC') 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 % 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.
+
+ A helpful error message can be returned like this:
+
+ 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')
+
+ DOC
+ if (args.length < 2) || (args.length > 3)
+ raise Puppet::ParseError, "validate_cmd(): wrong number of arguments (#{args.length}; must be 2 or 3)"
+ end
+
+ msg = args[2] || "validate_cmd(): failed to validate content with command #{args[1].inspect}"
+
+ content = args[0]
+ checkscript = args[1]
+
+ # Test content in a temporary file
+ tmpfile = Tempfile.new('validate_cmd')
+ begin
+ tmpfile.write(content)
+ tmpfile.close
+
+ check_with_correct_location = if checkscript =~ %r{\s%(\s|$)}
+ checkscript.gsub(%r{%}, tmpfile.path)
+ else
+ "#{checkscript} #{tmpfile.path}"
+ end
+
+ if Puppet::Util::Execution.respond_to?('execute')
+ Puppet::Util::Execution.execute(check_with_correct_location)
+ else
+ Puppet::Util.execute(check_with_correct_location)
+ end
+ rescue Puppet::ExecutionFailure => detail
+ msg += "\n#{detail}"
+ raise Puppet::ParseError, msg
+ rescue StandardError => detail
+ msg += "\n#{detail.class.name} #{detail}"
+ raise Puppet::ParseError, msg
+ ensure
+ tmpfile.unlink
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_domain_name.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_domain_name.rb
new file mode 100644
index 0000000..c479dfb
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_domain_name.rb
@@ -0,0 +1,42 @@
+#
+# validate_domain_name.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_domain_name, :doc => <<-DOC
+ Validate that all values passed are syntactically correct domain names.
+ Fail compilation if any value fails this check.
+
+ The following values will pass:
+
+ $my_domain_name = 'server.domain.tld'
+ validate_domain_name($my_domain_name)
+ validate_domain_name('domain.tld', 'puppet.com', $my_domain_name)
+
+ The following values will fail, causing compilation to abort:
+
+ validate_domain_name(1)
+ validate_domain_name(true)
+ validate_domain_name('invalid domain')
+ validate_domain_name('-foo.example.com')
+ validate_domain_name('www.example.2com')
+
+ DOC
+ ) do |args|
+
+ rescuable_exceptions = [ArgumentError]
+
+ if args.empty?
+ raise Puppet::ParseError, "validate_domain_name(): wrong number of arguments (#{args.length}; must be > 0)"
+ end
+
+ args.each do |arg|
+ raise Puppet::ParseError, "#{arg.inspect} is not a string." unless arg.is_a?(String)
+
+ begin
+ raise Puppet::ParseError, "#{arg.inspect} is not a syntactically correct domain name" unless function_is_domain_name([arg])
+ rescue *rescuable_exceptions
+ raise Puppet::ParseError, "#{arg.inspect} is not a syntactically correct domain name"
+ end
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_email_address.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_email_address.rb
new file mode 100644
index 0000000..a039f51
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_email_address.rb
@@ -0,0 +1,34 @@
+#
+# validate_email_address.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_email_address, :doc => <<-DOC
+ Validate that all values passed are valid email addresses.
+ Fail compilation if any value fails this check.
+ The following values will pass:
+ $my_email = "waldo@gmail.com"
+ validate_email_address($my_email)
+ validate_email_address("bob@gmail.com", "alice@gmail.com", $my_email)
+
+ The following values will fail, causing compilation to abort:
+ $some_array = [ 'bad_email@/d/efdf.com' ]
+ validate_email_address($some_array)
+ DOC
+ ) do |args|
+ rescuable_exceptions = [ArgumentError]
+
+ if args.empty?
+ raise Puppet::ParseError, "validate_email_address(): wrong number of arguments (#{args.length}; must be > 0)"
+ end
+
+ args.each do |arg|
+ raise Puppet::ParseError, "#{arg.inspect} is not a string." unless arg.is_a?(String)
+
+ begin
+ raise Puppet::ParseError, "#{arg.inspect} is not a valid email address" unless function_is_email_address([arg])
+ rescue *rescuable_exceptions
+ raise Puppet::ParseError, "#{arg.inspect} is not a valid email address"
+ end
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_hash.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_hash.rb
new file mode 100644
index 0000000..0460cf3
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_hash.rb
@@ -0,0 +1,36 @@
+#
+# validate_hash.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_hash, :doc => <<-'DOC') do |args|
+ Validate that all passed values are hash data structures. Abort catalog
+ compilation if any value fails this check.
+
+ The following values will pass:
+
+ $my_hash = { 'one' => 'two' }
+ validate_hash($my_hash)
+
+ The following values will fail, causing compilation to abort:
+
+ validate_hash(true)
+ validate_hash('some_string')
+ $undefined = undef
+ validate_hash($undefined)
+
+ DOC
+
+ function_deprecation([:validate_hash, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Hash. There is further documentation for validate_legacy function in the README.'])
+
+ if args.empty?
+ raise Puppet::ParseError, "validate_hash(): wrong number of arguments (#{args.length}; must be > 0)"
+ end
+
+ args.each do |arg|
+ unless arg.is_a?(Hash)
+ raise Puppet::ParseError, "#{arg.inspect} is not a Hash. It looks to be a #{arg.class}"
+ end
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_integer.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_integer.rb
new file mode 100644
index 0000000..fc50bdc
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_integer.rb
@@ -0,0 +1,137 @@
+#
+# validate_interger.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_integer, :doc => <<-'DOC') do |args|
+ Validate that the first argument is an integer (or an array of integers). Abort catalog compilation if any of the checks fail.
+
+ The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max.
+
+ The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min.
+ If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check
+ if (all elements of) the first argument are greater or equal to the given minimum.
+
+ It will fail if the first argument is not an integer or array of integers, and if arg 2 and arg 3 are not convertable to an integer.
+
+ The following values will pass:
+
+ validate_integer(1)
+ validate_integer(1, 2)
+ validate_integer(1, 1)
+ validate_integer(1, 2, 0)
+ validate_integer(2, 2, 2)
+ validate_integer(2, '', 0)
+ validate_integer(2, undef, 0)
+ $foo = undef
+ validate_integer(2, $foo, 0)
+ validate_integer([1,2,3,4,5], 6)
+ validate_integer([1,2,3,4,5], 6, 0)
+
+ Plus all of the above, but any combination of values passed as strings ('1' or "1").
+ Plus all of the above, but with (correct) combinations of negative integer values.
+
+ The following values will not:
+
+ validate_integer(true)
+ validate_integer(false)
+ validate_integer(7.0)
+ validate_integer({ 1 => 2 })
+ $foo = undef
+ validate_integer($foo)
+ validate_integer($foobaridontexist)
+
+ validate_integer(1, 0)
+ validate_integer(1, true)
+ validate_integer(1, '')
+ validate_integer(1, undef)
+ validate_integer(1, , 0)
+ validate_integer(1, 2, 3)
+ validate_integer(1, 3, 2)
+ validate_integer(1, 3, true)
+
+ Plus all of the above, but any combination of values passed as strings ('false' or "false").
+ Plus all of the above, but with incorrect combinations of negative integer values.
+ Plus all of the above, but with non-integer items in arrays or maximum / minimum argument.
+
+ DOC
+
+ function_deprecation([:validate_integer, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.'])
+
+ # tell the user we need at least one, and optionally up to two other parameters
+ raise Puppet::ParseError, "validate_integer(): Wrong number of arguments; must be 1, 2 or 3, got #{args.length}" unless !args.empty? && args.length < 4
+
+ input, max, min = *args
+
+ # check maximum parameter
+ if args.length > 1
+ max = max.to_s
+ # allow max to be empty (or undefined) if we have a minimum set
+ if args.length > 2 && max == ''
+ max = nil
+ else
+ begin
+ max = Integer(max)
+ rescue TypeError, ArgumentError
+ raise Puppet::ParseError, "validate_integer(): Expected second argument to be unset or an Integer, got #{max}:#{max.class}"
+ end
+ end
+ else
+ max = nil
+ end
+
+ # check minimum parameter
+ if args.length > 2
+ begin
+ min = Integer(min.to_s)
+ rescue TypeError, ArgumentError
+ raise Puppet::ParseError, "validate_integer(): Expected third argument to be unset or an Integer, got #{min}:#{min.class}"
+ end
+ else
+ min = nil
+ end
+
+ # ensure that min < max
+ if min && max && min > max
+ raise Puppet::ParseError, "validate_integer(): Expected second argument to be larger than third argument, got #{max} < #{min}"
+ end
+
+ # create lamba validator function
+ validator = ->(num) do
+ # check input < max
+ if max && num > max
+ raise Puppet::ParseError, "validate_integer(): Expected #{input.inspect} to be smaller or equal to #{max}, got #{input.inspect}."
+ end
+ # check input > min (this will only be checked if no exception has been raised before)
+ if min && num < min
+ raise Puppet::ParseError, "validate_integer(): Expected #{input.inspect} to be greater or equal to #{min}, got #{input.inspect}."
+ end
+ end
+
+ # if this is an array, handle it.
+ case input
+ when Array
+ # check every element of the array
+ input.each_with_index do |arg, pos|
+ begin
+ raise TypeError if arg.is_a?(Hash)
+ arg = Integer(arg.to_s)
+ validator.call(arg)
+ rescue TypeError, ArgumentError
+ raise Puppet::ParseError, "validate_integer(): Expected element at array position #{pos} to be an Integer, got #{arg.class}"
+ end
+ end
+ # for the sake of compatibility with ruby 1.8, we need extra handling of hashes
+ when Hash
+ raise Puppet::ParseError, "validate_integer(): Expected first argument to be an Integer or Array, got #{input.class}"
+ # check the input. this will also fail any stuff other than pure, shiny integers
+ else
+ begin
+ input = Integer(input.to_s)
+ validator.call(input)
+ rescue TypeError, ArgumentError
+ raise Puppet::ParseError, "validate_integer(): Expected first argument to be an Integer or Array, got #{input.class}"
+ end
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_ip_address.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_ip_address.rb
new file mode 100644
index 0000000..af835ad
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_ip_address.rb
@@ -0,0 +1,53 @@
+#
+# validate_ip_address.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_ip_address, :doc => <<-DOC
+ Validate that all values passed are valid IP addresses,
+ regardless they are IPv4 or IPv6
+ Fail compilation if any value fails this check.
+ The following values will pass:
+ $my_ip = "1.2.3.4"
+ validate_ip_address($my_ip)
+ validate_ip_address("8.8.8.8", "172.16.0.1", $my_ip)
+
+ $my_ip = "3ffe:505:2"
+ validate_ip_address(1)
+ validate_ip_address($my_ip)
+ validate_ip_address("fe80::baf6:b1ff:fe19:7507", $my_ip)
+
+ The following values will fail, causing compilation to abort:
+ $some_array = [ 1, true, false, "garbage string", "3ffe:505:2" ]
+ validate_ip_address($some_array)
+ DOC
+ ) do |args|
+
+ require 'ipaddr'
+ rescuable_exceptions = [ArgumentError]
+
+ function_deprecation([:validate_ip_address, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Ip_address. There is further documentation for validate_legacy function in the README.'])
+
+ if defined?(IPAddr::InvalidAddressError)
+ rescuable_exceptions << IPAddr::InvalidAddressError
+ end
+
+ if args.empty?
+ raise Puppet::ParseError, "validate_ip_address(): wrong number of arguments (#{args.length}; must be > 0)"
+ end
+
+ args.each do |arg|
+ unless arg.is_a?(String)
+ raise Puppet::ParseError, "#{arg.inspect} is not a string."
+ end
+
+ begin
+ unless IPAddr.new(arg).ipv4? || IPAddr.new(arg).ipv6?
+ raise Puppet::ParseError, "#{arg.inspect} is not a valid IP address."
+ end
+ rescue *rescuable_exceptions
+ raise Puppet::ParseError, "#{arg.inspect} is not a valid IP address."
+ end
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_ipv4_address.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_ipv4_address.rb
new file mode 100644
index 0000000..1ac303f
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_ipv4_address.rb
@@ -0,0 +1,51 @@
+#
+# validate_ipv4_address.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_ipv4_address, :doc => <<-DOC
+ Validate that all values passed are valid IPv4 addresses.
+ Fail compilation if any value fails this check.
+
+ The following values will pass:
+
+ $my_ip = "1.2.3.4"
+ validate_ipv4_address($my_ip)
+ validate_ipv4_address("8.8.8.8", "172.16.0.1", $my_ip)
+
+ The following values will fail, causing compilation to abort:
+
+ $some_array = [ 1, true, false, "garbage string", "3ffe:505:2" ]
+ validate_ipv4_address($some_array)
+
+ DOC
+ ) do |args|
+
+ function_deprecation([:validate_ipv4_address, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Ipv4. There is further documentation for validate_legacy function in the README.'])
+
+ require 'ipaddr'
+ rescuable_exceptions = [ArgumentError]
+
+ if defined?(IPAddr::InvalidAddressError)
+ rescuable_exceptions << IPAddr::InvalidAddressError
+ end
+
+ if args.empty?
+ raise Puppet::ParseError, "validate_ipv4_address(): wrong number of arguments (#{args.length}; must be > 0)"
+ end
+
+ args.each do |arg|
+ unless arg.is_a?(String)
+ raise Puppet::ParseError, "#{arg.inspect} is not a string."
+ end
+
+ begin
+ unless IPAddr.new(arg).ipv4?
+ raise Puppet::ParseError, "#{arg.inspect} is not a valid IPv4 address."
+ end
+ rescue *rescuable_exceptions
+ raise Puppet::ParseError, "#{arg.inspect} is not a valid IPv4 address."
+ end
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_ipv6_address.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_ipv6_address.rb
new file mode 100644
index 0000000..88c133c
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_ipv6_address.rb
@@ -0,0 +1,52 @@
+#
+# validate_ipv7_address.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_ipv6_address, :doc => <<-DOC
+ Validate that all values passed are valid IPv6 addresses.
+ Fail compilation if any value fails this check.
+
+ The following values will pass:
+
+ $my_ip = "3ffe:505:2"
+ validate_ipv6_address(1)
+ validate_ipv6_address($my_ip)
+ validate_bool("fe80::baf6:b1ff:fe19:7507", $my_ip)
+
+ The following values will fail, causing compilation to abort:
+
+ $some_array = [ true, false, "garbage string", "1.2.3.4" ]
+ validate_ipv6_address($some_array)
+
+ DOC
+ ) do |args|
+
+ function_deprecation([:validate_ipv6_address, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Ipv6. There is further documentation for validate_legacy function in the README.'])
+
+ require 'ipaddr'
+ rescuable_exceptions = [ArgumentError]
+
+ if defined?(IPAddr::InvalidAddressError)
+ rescuable_exceptions << IPAddr::InvalidAddressError
+ end
+
+ if args.empty?
+ raise Puppet::ParseError, "validate_ipv6_address(): wrong number of arguments (#{args.length}; must be > 0)"
+ end
+
+ args.each do |arg|
+ unless arg.is_a?(String)
+ raise Puppet::ParseError, "#{arg.inspect} is not a string."
+ end
+
+ begin
+ unless IPAddr.new(arg).ipv6?
+ raise Puppet::ParseError, "#{arg.inspect} is not a valid IPv6 address."
+ end
+ rescue *rescuable_exceptions
+ raise Puppet::ParseError, "#{arg.inspect} is not a valid IPv6 address."
+ end
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_numeric.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_numeric.rb
new file mode 100644
index 0000000..803e6f0
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_numeric.rb
@@ -0,0 +1,99 @@
+#
+# validate_numeric.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_numeric, :doc => <<-'DOC') do |args|
+ Validate that the first argument is a numeric value (or an array of numeric values). Abort catalog compilation if any of the checks fail.
+
+ The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max.
+
+ The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min.
+ If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check
+ if (all elements of) the first argument are greater or equal to the given minimum.
+
+ It will fail if the first argument is not a numeric (Integer or Float) or array of numerics, and if arg 2 and arg 3 are not convertable to a numeric.
+
+ For passing and failing usage, see `validate_integer()`. It is all the same for validate_numeric, yet now floating point values are allowed, too.
+
+ DOC
+
+ function_deprecation([:validate_numeric, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.'])
+
+ # tell the user we need at least one, and optionally up to two other parameters
+ raise Puppet::ParseError, "validate_numeric(): Wrong number of arguments; must be 1, 2 or 3, got #{args.length}" unless !args.empty? && args.length < 4
+
+ input, max, min = *args
+
+ # check maximum parameter
+ if args.length > 1
+ max = max.to_s
+ # allow max to be empty (or undefined) if we have a minimum set
+ if args.length > 2 && max == ''
+ max = nil
+ else
+ begin
+ max = Float(max)
+ rescue TypeError, ArgumentError
+ raise Puppet::ParseError, "validate_numeric(): Expected second argument to be unset or a Numeric, got #{max}:#{max.class}"
+ end
+ end
+ else
+ max = nil
+ end
+
+ # check minimum parameter
+ if args.length > 2
+ begin
+ min = Float(min.to_s)
+ rescue TypeError, ArgumentError
+ raise Puppet::ParseError, "validate_numeric(): Expected third argument to be unset or a Numeric, got #{min}:#{min.class}"
+ end
+ else
+ min = nil
+ end
+
+ # ensure that min < max
+ if min && max && min > max
+ raise Puppet::ParseError, "validate_numeric(): Expected second argument to be larger than third argument, got #{max} < #{min}"
+ end
+
+ # create lamba validator function
+ validator = ->(num) do
+ # check input < max
+ if max && num > max
+ raise Puppet::ParseError, "validate_numeric(): Expected #{input.inspect} to be smaller or equal to #{max}, got #{input.inspect}."
+ end
+ # check input > min (this will only be checked if no exception has been raised before)
+ if min && num < min
+ raise Puppet::ParseError, "validate_numeric(): Expected #{input.inspect} to be greater or equal to #{min}, got #{input.inspect}."
+ end
+ end
+
+ # if this is an array, handle it.
+ case input
+ when Array
+ # check every element of the array
+ input.each_with_index do |arg, pos|
+ begin
+ raise TypeError if arg.is_a?(Hash)
+ arg = Float(arg.to_s)
+ validator.call(arg)
+ rescue TypeError, ArgumentError
+ raise Puppet::ParseError, "validate_numeric(): Expected element at array position #{pos} to be a Numeric, got #{arg.class}"
+ end
+ end
+ # for the sake of compatibility with ruby 1.8, we need extra handling of hashes
+ when Hash
+ raise Puppet::ParseError, "validate_integer(): Expected first argument to be a Numeric or Array, got #{input.class}"
+ # check the input. this will also fail any stuff other than pure, shiny integers
+ else
+ begin
+ input = Float(input.to_s)
+ validator.call(input)
+ rescue TypeError, ArgumentError
+ raise Puppet::ParseError, "validate_numeric(): Expected first argument to be a Numeric or Array, got #{input.class}"
+ end
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_re.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_re.rb
new file mode 100644
index 0000000..88f23fc
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_re.rb
@@ -0,0 +1,53 @@
+#
+# validate.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_re, :doc => <<-'DOC') do |args|
+ Perform simple validation of a string against one or more regular
+ expressions. The first argument of this function should be a string to
+ test, and the second argument should be a stringified regular expression
+ (without the // delimiters) or an array of regular expressions. If none
+ of the regular expressions match the string passed in, 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.
+
+ The following strings will validate against the regular expressions:
+
+ validate_re('one', '^one$')
+ validate_re('one', [ '^one', '^two' ])
+
+ The following strings will fail to validate, causing compilation to abort:
+
+ validate_re('one', [ '^two', '^three' ])
+
+ A helpful error message can be returned like this:
+
+ validate_re($::puppetversion, '^2.7', 'The $puppetversion fact value does not match 2.7')
+
+ Note: Compilation will also abort, if the first argument is not a String. Always use
+ quotes to force stringification:
+
+ validate_re("${::operatingsystemmajrelease}", '^[57]$')
+
+ DOC
+
+ function_deprecation([:validate_re, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::Re. There is further documentation for validate_legacy function in the README.'])
+
+ if (args.length < 2) || (args.length > 3)
+ raise Puppet::ParseError, "validate_re(): wrong number of arguments (#{args.length}; must be 2 or 3)"
+ end
+
+ raise Puppet::ParseError, "validate_re(): input needs to be a String, not a #{args[0].class}" unless args[0].is_a? String
+
+ msg = args[2] || "validate_re(): #{args[0].inspect} does not match #{args[1].inspect}"
+
+ # We're using a flattened array here because we can't call String#any? in
+ # Ruby 1.9 like we can in Ruby 1.8
+ raise Puppet::ParseError, msg unless [args[1]].flatten.any? do |re_str|
+ args[0] =~ Regexp.compile(re_str)
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_slength.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_slength.rb
new file mode 100644
index 0000000..db5010e
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_slength.rb
@@ -0,0 +1,71 @@
+#
+# validate_slength.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_slength, :doc => <<-'DOC') do |args|
+ Validate that the first argument is a string (or an array of strings), and
+ less/equal to than the length of the second argument. An optional third
+ parameter can be given the minimum length. It fails if the first
+ argument is not a string or array of strings, and if arg 2 and arg 3 are
+ not convertable to a number.
+
+ The following values will pass:
+
+ validate_slength("discombobulate",17)
+ validate_slength(["discombobulate","moo"],17)
+ validate_slength(["discombobulate","moo"],17,3)
+
+ The following valueis will not:
+
+ validate_slength("discombobulate",1)
+ validate_slength(["discombobulate","thermometer"],5)
+ validate_slength(["discombobulate","moo"],17,10)
+
+ DOC
+
+ function_deprecation([:validate_slength, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with String[]. There is further documentation for validate_legacy function in the README.'])
+
+ raise Puppet::ParseError, "validate_slength(): Wrong number of arguments (#{args.length}; must be 2 or 3)" unless args.length == 2 || args.length == 3
+
+ input, max_length, min_length = *args
+
+ begin
+ max_length = Integer(max_length)
+ raise ArgumentError if max_length <= 0
+ rescue ArgumentError, TypeError
+ raise Puppet::ParseError, "validate_slength(): Expected second argument to be a positive Numeric, got #{max_length}:#{max_length.class}"
+ end
+
+ if min_length
+ begin
+ min_length = Integer(min_length)
+ raise ArgumentError if min_length < 0
+ rescue ArgumentError, TypeError
+ raise Puppet::ParseError, "validate_slength(): Expected third argument to be unset or a positive Numeric, got #{min_length}:#{min_length.class}"
+ end
+ else
+ min_length = 0
+ end
+
+ raise Puppet::ParseError, 'validate_slength(): Expected second argument to be equal to or larger than third argument' unless max_length >= min_length
+
+ validator = ->(str) do
+ unless str.length <= max_length && str.length >= min_length
+ raise Puppet::ParseError, "validate_slength(): Expected length of #{input.inspect} to be between #{min_length} and #{max_length}, was #{input.length}"
+ end
+ end
+
+ case input
+ when String
+ validator.call(input)
+ when Array
+ input.each_with_index do |arg, pos|
+ raise Puppet::ParseError, "validate_slength(): Expected element at array position #{pos} to be a String, got #{arg.class}" unless arg.is_a? String
+ validator.call(arg)
+ end
+ else
+ raise Puppet::ParseError, "validate_slength(): Expected first argument to be a String or Array, got #{input.class}"
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_string.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_string.rb
new file mode 100644
index 0000000..c2847b6
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_string.rb
@@ -0,0 +1,42 @@
+#
+# validate_String.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_string, :doc => <<-'DOC') do |args|
+ Validate that all passed values are string data structures. Abort catalog
+ compilation if any value fails this check.
+
+ The following values will pass:
+
+ $my_string = "one two"
+ validate_string($my_string, 'three')
+
+ The following values will fail, causing compilation to abort:
+
+ validate_string(true)
+ validate_string([ 'some', 'array' ])
+
+ 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('...')
+ }
+
+ DOC
+
+ function_deprecation([:validate_string, 'This method is deprecated, please use the stdlib validate_legacy function,
+ with Stdlib::Compat::String. There is further documentation for validate_legacy function in the README.'])
+
+ if args.empty?
+ raise Puppet::ParseError, "validate_string(): wrong number of arguments (#{args.length}; must be > 0)"
+ end
+
+ args.each do |arg|
+ # when called through the v4 API shim, undef gets translated to nil
+ unless arg.is_a?(String) || arg.nil?
+ raise Puppet::ParseError, "#{arg.inspect} is not a string. It looks to be a #{arg.class}"
+ end
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_x509_rsa_key_pair.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_x509_rsa_key_pair.rb
new file mode 100644
index 0000000..ea69dc4
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/validate_x509_rsa_key_pair.rb
@@ -0,0 +1,48 @@
+#
+# validate_x509_rsa_key_pair.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:validate_x509_rsa_key_pair, :doc => <<-DOC
+ Validates a PEM-formatted X.509 certificate and RSA private key using
+ OpenSSL. Verifies that the certficate's signature was created from the
+ supplied key.
+
+ Fail compilation if any value fails this check.
+
+ validate_x509_rsa_key_pair($cert, $key)
+
+ DOC
+ ) do |args|
+
+ require 'openssl'
+
+ NUM_ARGS = 2 unless defined? NUM_ARGS
+
+ unless args.length == NUM_ARGS
+ raise Puppet::ParseError,
+ "validate_x509_rsa_key_pair(): wrong number of arguments (#{args.length}; must be #{NUM_ARGS})"
+ end
+
+ args.each do |arg|
+ unless arg.is_a?(String)
+ raise Puppet::ParseError, "#{arg.inspect} is not a string."
+ end
+ end
+
+ begin
+ cert = OpenSSL::X509::Certificate.new(args[0])
+ rescue OpenSSL::X509::CertificateError => e
+ raise Puppet::ParseError, "Not a valid x509 certificate: #{e}"
+ end
+
+ begin
+ key = OpenSSL::PKey::RSA.new(args[1])
+ rescue OpenSSL::PKey::RSAError => e
+ raise Puppet::ParseError, "Not a valid RSA key: #{e}"
+ end
+
+ unless cert.verify(key)
+ raise Puppet::ParseError, 'Certificate signature does not match supplied key'
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/values.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/values.rb
new file mode 100644
index 0000000..168da84
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/values.rb
@@ -0,0 +1,37 @@
+#
+# values.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:values, :type => :rvalue, :doc => <<-DOC
+ When given a hash this function will return the values of that hash.
+
+ *Examples:*
+
+ $hash = {
+ 'a' => 1,
+ 'b' => 2,
+ 'c' => 3,
+ }
+ values($hash)
+
+ This example would return:
+
+ [1,2,3]
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "values(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty?
+
+ hash = arguments[0]
+
+ unless hash.is_a?(Hash)
+ raise(Puppet::ParseError, 'values(): Requires hash to work with')
+ end
+
+ result = hash.values
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/values_at.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/values_at.rb
new file mode 100644
index 0000000..2e07552
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/values_at.rb
@@ -0,0 +1,89 @@
+#
+# values_at.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:values_at, :type => :rvalue, :doc => <<-DOC
+ Finds value inside an array based on location.
+
+ The first argument is the array you want to analyze, and the second element can
+ be a combination of:
+
+ * A single numeric index
+ * A range in the form of 'start-stop' (eg. 4-9)
+ * An array combining the above
+
+ *Examples*:
+
+ values_at(['a','b','c'], 2)
+
+ Would return ['c'].
+
+ values_at(['a','b','c'], ["0-1"])
+
+ Would return ['a','b'].
+
+ values_at(['a','b','c','d','e'], [0, "2-3"])
+
+ Would return ['a','c','d'].
+ DOC
+ ) do |arguments|
+
+ raise(Puppet::ParseError, "values_at(): Wrong number of arguments given (#{arguments.size} for 2)") if arguments.size < 2
+
+ array = arguments.shift
+
+ unless array.is_a?(Array)
+ raise(Puppet::ParseError, 'values_at(): Requires array to work with')
+ end
+
+ indices = [arguments.shift].flatten # Get them all ... Pokemon ...
+
+ if !indices || indices.empty?
+ raise(Puppet::ParseError, 'values_at(): You must provide at least one positive index to collect')
+ end
+
+ indices_list = []
+
+ indices.each do |i|
+ i = i.to_s
+ m = i.match(%r{^(\d+)(\.\.\.?|\-)(\d+)$})
+ if m
+ start = m[1].to_i
+ stop = m[3].to_i
+
+ type = m[2]
+
+ raise(Puppet::ParseError, 'values_at(): Stop index in given indices range is smaller than the start index') if start > stop
+ raise(Puppet::ParseError, 'values_at(): Stop index in given indices range exceeds array size') if stop > array.size - 1 # First element is at index 0 is it not?
+
+ range = case type
+ when %r{^(\.\.|\-)$} then (start..stop)
+ when %r{^(\.\.\.)$} then (start...stop) # Exclusive of last element ...
+ end
+
+ range.each { |i| indices_list << i.to_i } # rubocop:disable Lint/ShadowingOuterLocalVariable : Value is meant to be shadowed
+ else
+ # Only positive numbers allowed in this case ...
+ unless i =~ %r{^\d+$}
+ raise(Puppet::ParseError, 'values_at(): Unknown format of given index')
+ end
+
+ # In Puppet numbers are often string-encoded ...
+ i = i.to_i
+
+ if i > array.size - 1 # Same story. First element is at index 0 ...
+ raise(Puppet::ParseError, 'values_at(): Given index exceeds array size')
+ end
+
+ indices_list << i
+ end
+ end
+
+ # We remove nil values as they make no sense in Puppet DSL ...
+ result = indices_list.map { |i| array[i] }.compact
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/parser/functions/zip.rb b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/zip.rb
new file mode 100644
index 0000000..87a89f8
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/parser/functions/zip.rb
@@ -0,0 +1,37 @@
+#
+# zip.rb
+#
+module Puppet::Parser::Functions
+ newfunction(:zip, :type => :rvalue, :doc => <<-DOC
+ Takes one element from first array and merges corresponding elements from second array. This generates a sequence of n-element arrays, where n is one more than the count of arguments.
+
+ *Example:*
+
+ zip(['1','2','3'],['4','5','6'])
+
+ Would result in:
+
+ ["1", "4"], ["2", "5"], ["3", "6"]
+ DOC
+ ) do |arguments|
+
+ # Technically we support three arguments but only first is mandatory ...
+ raise(Puppet::ParseError, "zip(): Wrong number of arguments given (#{arguments.size} for 2)") if arguments.size < 2
+
+ a = arguments[0]
+ b = arguments[1]
+
+ unless a.is_a?(Array) && b.is_a?(Array)
+ raise(Puppet::ParseError, 'zip(): Requires array to work with')
+ end
+
+ flatten = function_str2bool([arguments[2]]) if arguments[2]
+
+ result = a.zip(b)
+ result = flatten ? result.flatten : result
+
+ return result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
diff --git a/code/environments/production/modules/stdlib/lib/puppet/provider/file_line/ruby.rb b/code/environments/production/modules/stdlib/lib/puppet/provider/file_line/ruby.rb
new file mode 100644
index 0000000..8423300
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/provider/file_line/ruby.rb
@@ -0,0 +1,171 @@
+Puppet::Type.type(:file_line).provide(:ruby) do
+ def exists?
+ found = false
+ lines_count = 0
+ lines.each do |line|
+ found = line.chomp == resource[:line]
+ if found
+ lines_count += 1
+ end
+ end
+ return found = lines_count > 0 if resource[:match].nil?
+
+ match_count = count_matches(new_match_regex)
+ found = if resource[:ensure] == :present
+ if match_count.zero?
+ if lines_count.zero? && resource[:append_on_no_match].to_s == 'false'
+ true # lies, but gets the job done
+ elsif lines_count.zero? && resource[:append_on_no_match].to_s != 'false'
+ false
+ else
+ true
+ end
+ elsif resource[:replace_all_matches_not_matching_line].to_s == 'true'
+ false # maybe lies, but knows there's still work to do
+ elsif lines_count.zero?
+ resource[:replace].to_s == 'false'
+ else
+ true
+ end
+ elsif match_count.zero?
+ if lines_count.zero?
+ false
+ else
+ true
+ end
+ elsif lines_count.zero?
+ resource[:match_for_absence].to_s == 'true'
+ else
+ true
+ end
+ end
+
+ def create
+ return if resource[:replace].to_s != 'true' && count_matches(new_match_regex) > 0
+ if resource[:match]
+ handle_create_with_match
+ elsif resource[:after]
+ handle_create_with_after
+ else
+ handle_append_line
+ end
+ end
+
+ def destroy
+ if resource[:match_for_absence].to_s == 'true' && resource[:match]
+ handle_destroy_with_match
+ else
+ handle_destroy_line
+ end
+ end
+
+ private
+
+ def lines
+ # If this type is ever used with very large files, we should
+ # write this in a different way, using a temp
+ # file; for now assuming that this type is only used on
+ # small-ish config files that can fit into memory without
+ # too much trouble.
+
+ @lines ||= File.readlines(resource[:path], :encoding => resource[:encoding])
+ rescue TypeError => _e
+ # Ruby 1.8 doesn't support open_args
+ @lines ||= File.readlines(resource[:path])
+ end
+
+ def new_after_regex
+ resource[:after] ? Regexp.new(resource[:after]) : nil
+ end
+
+ def new_match_regex
+ resource[:match] ? Regexp.new(resource[:match]) : nil
+ end
+
+ def count_matches(regex)
+ lines.select { |line|
+ if resource[:replace_all_matches_not_matching_line].to_s == 'true'
+ line.match(regex) unless line.chomp == resource[:line]
+ else
+ line.match(regex)
+ end
+ }.size
+ end
+
+ def handle_create_with_match
+ after_regex = new_after_regex
+ match_regex = new_match_regex
+ match_count = count_matches(new_match_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
+
+ File.open(resource[:path], 'w') do |fh|
+ lines.each do |line|
+ fh.puts(match_regex.match(line) ? resource[:line] : line)
+ next unless match_count.zero? && after_regex
+ if after_regex.match(line)
+ fh.puts(resource[:line])
+ match_count += 1 # Increment match_count to indicate that the new line has been inserted.
+ end
+ end
+
+ if match_count.zero?
+ fh.puts(resource[:line])
+ end
+ end
+ end
+
+ def handle_create_with_after
+ after_regex = new_after_regex
+ after_count = count_matches(after_regex)
+
+ if after_count > 1 && resource[:multiple].to_s != 'true'
+ raise Puppet::Error, "#{after_count} lines match pattern '#{resource[:after]}' in file '#{resource[:path]}'. One or no line must match the pattern."
+ end
+
+ File.open(resource[:path], 'w') do |fh|
+ lines.each do |line|
+ fh.puts(line)
+ if after_regex.match(line)
+ fh.puts(resource[:line])
+ end
+ end
+
+ if after_count.zero?
+ fh.puts(resource[:line])
+ end
+ end
+ end
+
+ def handle_destroy_with_match
+ match_regex = new_match_regex
+ match_count = count_matches(match_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
+
+ local_lines = lines
+ File.open(resource[:path], 'w') do |fh|
+ fh.write(local_lines.reject { |line| match_regex.match(line) }.join(''))
+ end
+ end
+
+ def handle_destroy_line
+ local_lines = lines
+ File.open(resource[:path], 'w') do |fh|
+ fh.write(local_lines.reject { |line| line.chomp == resource[:line] }.join(''))
+ end
+ end
+
+ def handle_append_line
+ local_lines = lines
+ File.open(resource[:path], 'w') do |fh|
+ local_lines.each do |line|
+ fh.puts(line)
+ end
+ fh.puts(resource[:line])
+ end
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/type/anchor.rb b/code/environments/production/modules/stdlib/lib/puppet/type/anchor.rb
new file mode 100644
index 0000000..60cfa64
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/type/anchor.rb
@@ -0,0 +1,46 @@
+Puppet::Type.newtype(:anchor) do
+ desc <<-'DESCRIPTION'
+ A simple resource type intended to be used as an anchor in a composite class.
+
+ In Puppet 2.6, when a class declares another class, the resources in the
+ interior class are not contained by the exterior class. This interacts badly
+ with the pattern of composing complex modules from smaller classes, as it
+ makes it impossible for end users to specify order relationships between the
+ exterior class and other modules.
+
+ The anchor type lets you work around this. By sandwiching any interior
+ classes between two no-op resources that _are_ contained by the exterior
+ class, you can ensure that all resources in the module are contained.
+
+ class ntp {
+ # These classes will have the correct order relationship with each
+ # other. However, without anchors, they won't have any order
+ # relationship to Class['ntp'].
+ class { 'ntp::package': }
+ -> class { 'ntp::config': }
+ -> class { 'ntp::service': }
+
+ # These two resources "anchor" the composed classes within the ntp
+ # class.
+ anchor { 'ntp::begin': } -> Class['ntp::package']
+ Class['ntp::service'] -> anchor { 'ntp::end': }
+ }
+
+ This allows the end user of the ntp module to establish require and before
+ relationships with Class['ntp']:
+
+ class { 'ntp': } -> class { 'mcollective': }
+ class { 'mcollective': } -> class { 'ntp': }
+
+ DESCRIPTION
+
+ newparam :name do
+ desc 'The name of the anchor resource.'
+ end
+
+ def refresh
+ # We don't do anything with them, but we need this to
+ # show that we are "refresh aware" and not break the
+ # chain of propagation.
+ end
+end
diff --git a/code/environments/production/modules/stdlib/lib/puppet/type/file_line.rb b/code/environments/production/modules/stdlib/lib/puppet/type/file_line.rb
new file mode 100644
index 0000000..14650fe
--- /dev/null
+++ b/code/environments/production/modules/stdlib/lib/puppet/type/file_line.rb
@@ -0,0 +1,192 @@
+Puppet::Type.newtype(:file_line) do
+ desc <<-DOC
+ Ensures that a given line is contained within a file. The implementation
+ matches the full line, including whitespace at the beginning and end. If
+ the line is not contained in the given file, Puppet will append the line to
+ the end of the file to ensure the desired state. Multiple resources may
+ be declared to manage multiple lines in the same file.
+
+ Example:
+
+ file_line { 'sudo_rule':
+ path => '/etc/sudoers',
+ line => '%sudo ALL=(ALL) ALL',
+ }
+
+ file_line { 'sudo_rule_nopw':
+ path => '/etc/sudoers',
+ line => '%sudonopw ALL=(ALL) NOPASSWD: ALL',
+ }
+
+ In this example, Puppet will ensure both of the specified lines are
+ contained in the file /etc/sudoers.
+
+ Match Example:
+
+ file_line { 'bashrc_proxy':
+ ensure => present,
+ path => '/etc/bashrc',
+ line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128',
+ match => '^export\ HTTP_PROXY\=',
+ }
+
+ In this code example match will look for a line beginning with export
+ followed by HTTP_PROXY and replace it with the value in line.
+
+ Examples With `ensure => absent`:
+
+ This type has two behaviors when `ensure => absent` is set.
+
+ One possibility is to set `match => ...` and `match_for_absence => true`,
+ as in the following example:
+
+ file_line { 'bashrc_proxy':
+ ensure => absent,
+ path => '/etc/bashrc',
+ match => '^export\ HTTP_PROXY\=',
+ match_for_absence => true,
+ }
+
+ In this code example match will look for a line beginning with export
+ followed by HTTP_PROXY and delete it. If multiple lines match, an
+ error will be raised unless the `multiple => true` parameter is set.
+
+ Note that the `line => ...` parameter would be accepted BUT IGNORED in
+ the above example.
+
+ The second way of using `ensure => absent` is to specify a `line => ...`,
+ and no match:
+
+ file_line { 'bashrc_proxy':
+ ensure => absent,
+ path => '/etc/bashrc',
+ line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128',
+ }
+
+ Note that when ensuring lines are absent this way, the default behavior
+ this time is to always remove all lines matching, and this behavior
+ can't be disabled.
+
+ Encoding example:
+
+ file_line { "XScreenSaver":
+ ensure => present,
+ path => '/root/XScreenSaver',
+ line => "*lock: 10:00:00",
+ match => '^*lock:',
+ encoding => "iso-8859-1",
+ }
+
+ Files with special characters that are not valid UTF-8 will give the
+ error message "invalid byte sequence in UTF-8". In this case, determine
+ the correct file encoding and specify the correct encoding using the
+ encoding attribute, the value of which needs to be a valid Ruby character
+ encoding.
+
+ **Autorequires:** If Puppet is managing the file that will contain the line
+ being managed, the file_line resource will autorequire that file.
+ DOC
+
+ ensurable do
+ defaultvalues
+ defaultto :present
+ end
+
+ newparam(:name, :namevar => true) do
+ desc 'An arbitrary name used as the identity of the resource.'
+ end
+
+ newparam(:match) do
+ desc 'An optional ruby regular expression to run against existing lines in the file.' \
+ ' If a match is found, we replace that line rather than adding a new line.' \
+ ' A regex comparison is performed against the line value and if it does not' \
+ ' match an exception will be raised.'
+ end
+
+ newparam(:match_for_absence) do
+ desc 'An optional value to determine if match should be applied when ensure => absent.' \
+ ' If set to true and match is set, the line that matches match will be deleted.' \
+ ' If set to false (the default), match is ignored when ensure => absent.' \
+ ' When `ensure => present`, match_for_absence is ignored.'
+ newvalues(true, false)
+ defaultto false
+ end
+
+ newparam(:multiple) do
+ desc 'An optional value to determine if match can change multiple lines.' \
+ ' If set to false, an exception will be raised if more than one line matches'
+ 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)' \
+ ' This is also takes a regex.'
+ end
+
+ # The line property never changes; the type only ever performs a create() or
+ # destroy(). line is a property in order to allow it to correctly handle
+ # Sensitive type values. Because it is a property which will never change,
+ # it should never be considered out of sync.
+ newproperty(:line) do
+ desc 'The line to be appended to the file or used to replace matches found by the match attribute.'
+
+ def retrieve
+ @resource[:line]
+ end
+ end
+
+ newparam(:path) do
+ desc 'The file Puppet will ensure contains the line specified by the line parameter.'
+ validate do |value|
+ unless Puppet::Util.absolute_path?(value)
+ raise Puppet::Error, "File paths must be fully qualified, not '#{value}'"
+ end
+ end
+ end
+
+ newparam(:replace) do
+ desc 'If true, replace line that matches. If false, do not write line if a match is found'
+ newvalues(true, false)
+ defaultto true
+ end
+
+ newparam(:replace_all_matches_not_matching_line) do
+ desc 'Configures the behavior of replacing all lines in a file which match the `match` parameter regular expression, regardless of whether the specified line is already present in the file.'
+
+ newvalues(true, false)
+ defaultto false
+ end
+
+ newparam(:encoding) do
+ desc 'For files that are not UTF-8 encoded, specify encoding such as iso-8859-1'
+ defaultto 'UTF-8'
+ end
+
+ newparam(:append_on_no_match) do
+ desc 'If true, append line if match is not found. If false, do not append line if a match is not found'
+ newvalues(true, false)
+ defaultto true
+ end
+
+ # Autorequire the file resource if it's being managed
+ autorequire(:file) do
+ self[:path]
+ end
+
+ validate do
+ if self[:replace_all_matches_not_matching_line].to_s == 'true' && self[:multiple].to_s == 'false'
+ raise(Puppet::Error, 'multiple must be true when replace_all_matches_not_matching_line is true')
+ end
+ if self[:replace_all_matches_not_matching_line].to_s == 'true' && self[:replace].to_s == 'false'
+ raise(Puppet::Error, 'replace must be true when replace_all_matches_not_matching_line is true')
+ end
+ unless self[:line]
+ unless (self[:ensure].to_s == 'absent') && (self[:match_for_absence].to_s == 'true') && self[:match]
+ raise(Puppet::Error, 'line is a required attribute')
+ end
+ end
+ unless self[:path]
+ raise(Puppet::Error, 'path is a required attribute')
+ end
+ end
+end