diff --git a/lib/puppet/parser/functions/is_service_default.rb b/lib/puppet/functions/is_service_default.rb
similarity index 60%
rename from lib/puppet/parser/functions/is_service_default.rb
rename to lib/puppet/functions/is_service_default.rb
index 9af9148b..a016a603 100644
--- a/lib/puppet/parser/functions/is_service_default.rb
+++ b/lib/puppet/functions/is_service_default.rb
@@ -1,22 +1,15 @@
-#
-# is_service_default.rb
-#
 # This function can be used to check if a variable is set to the default value
 # of '<SERVICE DEFAULT>'
 #
 # For reference:
 # http://lists.openstack.org/pipermail/openstack-dev/2015-July/069823.html
 # https://github.com/openstack/puppet-openstacklib/commit/3b85306d042292713d0fd89fa508e0a0fbf99671
-#
-module Puppet::Parser::Functions
-  newfunction(:is_service_default, :type => :rvalue, :doc => <<-EOS
-Returns true if the variable passed to this function is '<SERVICE DEFAULT>'
-  EOS
-  ) do |arguments|
+Puppet::Functions.create_function(:is_service_default) do
+  def is_service_default(*args)
     raise(Puppet::ParseError, "is_service_default(): Wrong number of arguments" +
-          "given (#{arguments.size} for 1)") if arguments.size != 1
+          "given (#{args.size} for 1)") if args.size != 1
 
-    value = arguments[0]
+    value = args[0]
 
     unless value.is_a?(String)
       return false
diff --git a/lib/puppet/functions/normalize_ip_for_uri.rb b/lib/puppet/functions/normalize_ip_for_uri.rb
new file mode 100644
index 00000000..3713b078
--- /dev/null
+++ b/lib/puppet/functions/normalize_ip_for_uri.rb
@@ -0,0 +1,36 @@
+# Add brackets if the argument is an IPv6 address.
+# Returns the argument untouched otherwise.
+#
+# CAUTION: this code "fails" when the user is passing
+# an IPv6 address with the port in it without the
+# brackets: 2001::1:8080, to specify address 2001::1
+# and port 8080.  This code will change it to
+# [2001::1:8080] as it's a valid ip address.  This
+# shouldn't be an issue in most cases.
+#
+# If an array is given, each member will be normalized to
+# a valid IPv6 address with brackets when needed.
+Puppet::Functions.create_function(:normalize_ip_for_uri) do
+  def normalize_ip_for_uri(*args)
+    require 'ipaddr'
+
+    result = []
+    args = args[0] if args[0].kind_of?(Array)
+    args = [args] unless args.kind_of?(Array)
+    args.each do |ip|
+      begin
+        if IPAddr.new(ip).ipv6?
+          unless ip.match(/\[.+\]/)
+            Puppet.debug("IP #{ip} is changed to [#{ip}]")
+            ip = "[#{ip}]"
+          end
+        end
+      rescue ArgumentError
+        # ignore it
+      end
+      result << ip
+    end
+    return result[0] if args.size == 1
+    result
+  end
+end
diff --git a/lib/puppet/functions/os_database_connection.rb b/lib/puppet/functions/os_database_connection.rb
new file mode 100644
index 00000000..f63c70b1
--- /dev/null
+++ b/lib/puppet/functions/os_database_connection.rb
@@ -0,0 +1,75 @@
+Puppet::Functions.create_function(:os_database_connection) do
+  def os_database_connection(*args)
+    require 'uri'
+
+    if (args.size != 1) then
+      raise(Puppet::ParseError, "os_database_connection(): Wrong number of arguments " +
+        "given (#{args.size} for 1)")
+    end
+
+    v = args[0]
+    klass = v.class
+
+    unless klass == Hash
+      raise(Puppet::ParseError, "os_database_connection(): Requires an hash, got #{klass}")
+    end
+
+    v.keys.each do |key|
+      klass = (key == 'extra') ? Hash : String
+      unless (v[key].class == klass) or (v[key] == :undef)
+        raise(Puppet::ParseError, "os_database_connection(): #{key} should be a #{klass}")
+      end
+    end
+
+    parts = {}
+
+    unless v.include?('dialect')
+      raise(Puppet::ParseError, 'os_database_connection(): dialect is required')
+    end
+
+    if v.include?('host')
+      parts[:host] = v['host']
+    end
+
+    unless v.include?('database')
+      raise(Puppet::ParseError, 'os_database_connection(): database is required')
+    end
+
+    if v.include?('port')
+      if v.include?('host')
+        parts[:port] = v['port'].to_i
+      else
+        raise(Puppet::ParseError, 'os_database_connection(): host is required with port')
+      end
+    end
+
+    if v.include?('username') and (v['username'] != :undef) and (v['username'].to_s != '')
+      parts[:userinfo] = URI.escape(v['username'])
+      if v.include?('password') and (v['password'] != :undef) and (v['password'].to_s != '')
+        parts[:userinfo] += ":#{URI.escape(v['password'])}"
+      end
+    end
+
+    # support previous charset option on the function. Setting charset will
+    # override charset if passed in via the extra parameters
+    if v.include?('charset')
+      if v.include?('extra')
+        v['extra'].merge!({ 'charset' => v['charset'] })
+      else
+        v['extra'] = { 'charset' => v['charset'] }
+      end
+    end
+
+    parts[:query] = v['extra'].map{ |k,v| "#{k}=#{v}" }.join('&') if v.include?('extra')
+
+    parts[:scheme] = v['dialect']
+
+    if v.include?('host')
+      parts[:path] = "/#{v['database']}"
+    else
+      parts[:path] = "///#{v['database']}"
+    end
+
+    URI::Generic.build(parts).to_s
+  end
+end
diff --git a/lib/puppet/functions/os_transport_url.rb b/lib/puppet/functions/os_transport_url.rb
new file mode 100644
index 00000000..b8f90b03
--- /dev/null
+++ b/lib/puppet/functions/os_transport_url.rb
@@ -0,0 +1,189 @@
+# This function builds a os_transport_url string from a hash of parameters.
+#
+# Valid hash parameteres:
+#  * transport - (string) type of transport, 'rabbit' or 'amqp'
+#  * host - (string) single host
+#  * hosts - (array) array of hosts to use
+#  * port - (string | integer) port to connect to
+#  * username - (string) connection username
+#  * password - (string) connection password
+#  * virtual_host - (string) virtual host to connect to
+#  * ssl - (string) is the connection ssl or not ('1' or '0'). overrides the ssl
+#    key in the query parameter
+#  * query - (hash) hash of key,value pairs used to create a query string for
+#    the transport_url.
+#
+# Only 'transport' and either 'host' or 'hosts' are required keys for the
+# parameters hash.
+#
+# The url format that will be generated:
+# transport://user:pass@host:port[,userN:passN@hostN:portN]/virtual_host?query
+#
+# NOTE: ipv6 addresses will automatically be bracketed for the URI using the
+# normalize_ip_for_uri function.
+#
+# Single Host Example:
+# os_transport_url({
+#   'transport'    => 'rabbit',
+#   'host'         => '1.1.1.1',
+#   'port'         => '5672',
+#   'username'     => 'username',
+#   'password'     => 'password',
+#   'virtual_host' => 'virtual_host',
+#   'ssl'          => '1',
+#   'query'        => { 'key' => 'value' },
+# })
+#
+# Generates:
+# rabbit://username:password@1.1.1.1:5672/virtual_host?key=value&ssl=1
+#
+# Multiple Hosts Example:
+# os_transport_url({
+#   'transport'    => 'rabbit',
+#   'hosts'        => [ '1.1.1.1', '2.2.2.2' ],
+#   'port'         => '5672',
+#   'username'     => 'username',
+#   'password'     => 'password',
+#   'virtual_host' => 'virtual_host',
+#   'query'        => { 'key' => 'value' },
+# })
+#
+# Generates:
+# rabbit://username:password@1.1.1.1:5672,username:password@2.2.2.2:5672/virtual_host?key=value
+Puppet::Functions.create_function(:os_transport_url) do
+  # TODO(tobias-urdin): Rework and remove this.
+  # Taken straight from stdlib v5.1.0 module.
+  def _str2bool(string)
+    if !!string == string
+      return string
+    end
+    unless string.is_a?(String)
+      raise(Puppet::ParseError, 'str2bool(): Requires string to work with')
+    end
+    result = case string
+             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, 'os_transport_url _str2bool(): Unknown type of boolean given')
+             end
+    return result
+  end
+
+  # TODO(tobias-urdin): Rework and remove this.
+  # Taken straight from stdlib v5.1.0 module.
+  def _bool2num(val)
+    value = _str2bool(val)
+    result = value ? 1 : 0
+    return result
+  end
+
+  def os_transport_url(*args)
+    require 'uri'
+
+    unless args.size == 1
+      raise(ArgumentError, 'os_transport_url(): Wrong number of arguments')
+    end
+
+    v = args[0]
+    klass = v.class
+
+    unless klass == Hash
+      raise(Puppet::ParseError, "os_transport_url(): Requires an hash, got #{klass}")
+    end
+
+    # type checking for the parameter hash
+    v.keys.each do |key|
+      v[key] = v[key].to_s if key == 'port'
+      klass = (key == 'hosts') ? Array : String
+      klass = (key == 'query') ? Hash : klass
+      unless (v[key].class == klass) or (v[key] == :undef)
+        raise(Puppet::ParseError, "os_transport_url(): #{key} should be a #{klass}")
+      end
+    end
+
+    # defaults
+    parts = {
+      :transport => 'rabbit',
+      :hostinfo  => 'localhost',
+      :path      => '/',
+    }
+
+    unless v.include?('transport')
+      raise(Puppet::ParseError, 'os_transport_url(): transport is required')
+    end
+
+    unless v.include?('host') or v.include?('hosts')
+      raise(Puppet::ParseError, 'os_transport_url(): host or hosts is required')
+    end
+
+    if v.include?('host') and v.include?('hosts')
+      raise(Puppet::ParseError, 'os_transport_url(): cannot use both host and hosts.')
+    end
+
+    parts[:transport] = v['transport']
+
+    if v.include?('username') and (v['username'] != :undef) and (v['username'].to_s != '')
+      parts[:userinfo] = URI.escape(v['username'])
+      if v.include?('password') and (v['password'] != :undef) and (v['password'].to_s != '')
+        parts[:userinfo] += ":#{URI.escape(v['password'])}"
+      end
+    end
+
+    if v.include?('host')
+      host = call_function('normalize_ip_for_uri', v['host'])
+      host += ":#{v['port'].to_s}" if v.include?('port')
+      if parts.include?(:userinfo)
+        parts[:hostinfo] = "#{parts[:userinfo]}@#{host}"
+      else
+        parts[:hostinfo] = "#{host}"
+      end
+    end
+
+    if v.include?('hosts')
+      hosts = call_function('normalize_ip_for_uri', v['hosts'])
+      # normalize_ip_for_uri may return a string, so check that we still have an
+      # array
+      hosts = [hosts] if hosts.kind_of?(String)
+      hosts = hosts.map{ |h| "#{h}:#{v['port'].to_s}" } if v.include?('port')
+      if parts.include?(:userinfo)
+        parts[:hostinfo] = hosts.map { |h| "#{parts[:userinfo]}@#{h}" }.join(',')
+      else
+        parts[:hostinfo] = hosts.join(',')
+      end
+    end
+
+    parts[:path] = "/#{v['virtual_host']}" if v.include?('virtual_host')
+
+    # support previous ssl option on the function. Setting ssl will
+    # override ssl if passed in via the query parameters
+    if v.include?('ssl')
+      # ssl can be passed in as a query paramter but should be 0/1. See
+      # http://docs.celeryproject.org/projects/kombu/en/latest/userguide/connections.html#urls
+      # so we rely on _str2bool and _bool2num to ensure it's in the
+      # format
+      # TODO(tobias-urdin): Rework this to using proper data types and not the
+      # legacy puppet functions that is copied into this function statement.
+      # We need to do this right now because it fails testing if we call the
+      # str2bool or bool2num legacy functions using call_function.
+      ssl_str = _str2bool(v['ssl'])
+      ssl_val = _bool2num(v['ssl'])
+      if v.include?('query')
+        v['query'].merge!({ 'ssl' => ssl_val })
+      else
+        v['query'] = { 'ssl' => ssl_val }
+      end
+    end
+
+    parts[:query] = v['query'].map{ |k,val| "#{k}=#{val}" }.join('&') if v.include?('query')
+
+    url_parts = []
+    url_parts << parts[:transport]
+    url_parts << '://'
+    url_parts << parts[:hostinfo]
+    url_parts << parts[:path]
+    url_parts << '?' << parts[:query] if parts.include?(:query)
+    url_parts.join()
+  end
+end
diff --git a/lib/puppet/parser/functions/normalize_ip_for_uri.rb b/lib/puppet/parser/functions/normalize_ip_for_uri.rb
deleted file mode 100644
index 92dead9a..00000000
--- a/lib/puppet/parser/functions/normalize_ip_for_uri.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-require 'ipaddr'
-
-module Puppet::Parser::Functions
-  newfunction(:normalize_ip_for_uri,
-              :type => :rvalue,
-              :doc => <<-EOD
-    Add brackets if the argument is an IPv6 address.
-    Returns the argument untouched otherwise.
-    CAUTION: this code "fails" when the user is passing
-    an IPv6 address with the port in it without the
-    brackets: 2001::1:8080, to specify address 2001::1
-    and port 8080.  This code will change it to
-    [2001::1:8080] as it's a valid ip address.  This
-    shouldn't be an issue in most cases.
-    If an array is given, each member will be normalized to
-    a valid IPv6 address with brackets when needed.
-    EOD
-    ) do |args|
-    result = []
-    args = args[0] if args[0].kind_of?(Array)
-    args.each do |ip|
-      begin
-        if IPAddr.new(ip).ipv6?
-          unless ip.match(/\[.+\]/)
-            Puppet.debug("IP #{ip} is changed to [#{ip}]")
-            ip = "[#{ip}]"
-          end
-        end
-      rescue ArgumentError
-        # ignore it
-      end
-      result << ip
-    end
-    return result[0] if args.size == 1
-    result
-  end
-end
diff --git a/lib/puppet/parser/functions/os_database_connection.rb b/lib/puppet/parser/functions/os_database_connection.rb
deleted file mode 100644
index 4cc428d9..00000000
--- a/lib/puppet/parser/functions/os_database_connection.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-require 'puppet/parser/functions'
-
-Puppet::Parser::Functions.newfunction(:os_database_connection,
-                                      :type => :rvalue,
-                                      :doc => <<-EOS
-This function builds a os_database_connection string from various parameters.
-EOS
-) do |arguments|
-
-  require 'uri'
-
-  if (arguments.size != 1) then
-    raise(Puppet::ParseError, "os_database_connection(): Wrong number of arguments " +
-      "given (#{arguments.size} for 1)")
-  end
-
-  v = arguments[0]
-  klass = v.class
-
-  unless klass == Hash
-    raise(Puppet::ParseError, "os_database_connection(): Requires an hash, got #{klass}")
-  end
-
-  v.keys.each do |key|
-    klass = (key == 'extra') ? Hash : String
-    unless (v[key].class == klass) or (v[key] == :undef)
-      raise(Puppet::ParseError, "os_database_connection(): #{key} should be a #{klass}")
-    end
-  end
-
-  parts = {}
-
-  unless v.include?('dialect')
-    raise(Puppet::ParseError, 'os_database_connection(): dialect is required')
-  end
-
-  if v.include?('host')
-    parts[:host] = v['host']
-  end
-
-  unless v.include?('database')
-    raise(Puppet::ParseError, 'os_database_connection(): database is required')
-  end
-
-  if v.include?('port')
-    if v.include?('host')
-      parts[:port] = v['port'].to_i
-    else
-      raise(Puppet::ParseError, 'os_database_connection(): host is required with port')
-    end
-  end
-
-  if v.include?('username') and (v['username'] != :undef) and (v['username'].to_s != '')
-    parts[:userinfo] = URI.escape(v['username'])
-    if v.include?('password') and (v['password'] != :undef) and (v['password'].to_s != '')
-      parts[:userinfo] += ":#{URI.escape(v['password'])}"
-    end
-  end
-
-  # support previous charset option on the function. Setting charset will
-  # override charset if passed in via the extra parameters
-  if v.include?('charset')
-    if v.include?('extra')
-      v['extra'].merge!({ 'charset' => v['charset'] })
-    else
-      v['extra'] = { 'charset' => v['charset'] }
-    end
-  end
-
-  parts[:query] = v['extra'].map{ |k,v| "#{k}=#{v}" }.join('&') if v.include?('extra')
-
-  parts[:scheme] = v['dialect']
-
-  if v.include?('host')
-    parts[:path] = "/#{v['database']}"
-  else
-    parts[:path] = "///#{v['database']}"
-  end
-
-  URI::Generic.build(parts).to_s
-end
diff --git a/lib/puppet/parser/functions/os_transport_url.rb b/lib/puppet/parser/functions/os_transport_url.rb
deleted file mode 100644
index 7c611a91..00000000
--- a/lib/puppet/parser/functions/os_transport_url.rb
+++ /dev/null
@@ -1,157 +0,0 @@
-require 'puppet/parser/functions'
-
-Puppet::Parser::Functions.newfunction(:os_transport_url,
-                                      :type  => :rvalue,
-                                      :arity => 1,
-                                      :doc   => <<-EOS
-This function builds a os_transport_url string from a hash of parameters.
-
-Valid hash parameteres:
- * transport - (string) type of transport, 'rabbit' or 'amqp'
- * host - (string) single host
- * hosts - (array) array of hosts to use
- * port - (string | integer) port to connect to
- * username - (string) connection username
- * password - (string) connection password
- * virtual_host - (string) virtual host to connect to
- * ssl - (string) is the connection ssl or not ('1' or '0'). overrides the ssl
-   key in the query parameter
- * query - (hash) hash of key,value pairs used to create a query string for
-   the transport_url.
-
-Only 'transport' and either 'host' or 'hosts' are required keys for the
-parameters hash.
-
-The url format that will be generated:
-transport://user:pass@host:port[,userN:passN@hostN:portN]/virtual_host?query
-
-NOTE: ipv6 addresses will automatically be bracketed for the URI using the
-normalize_ip_for_uri function.
-
-Single Host Example:
-os_transport_url({
-  'transport'    => 'rabbit',
-  'host'         => '1.1.1.1',
-  'port'         => '5672',
-  'username'     => 'username',
-  'password'     => 'password',
-  'virtual_host' => 'virtual_host',
-  'ssl'          => '1',
-  'query'        => { 'key' => 'value' },
-})
-Generates:
-rabbit://username:password@1.1.1.1:5672/virtual_host?key=value&ssl=1
-
-Multiple Hosts Example:
-os_transport_url({
-  'transport'    => 'rabbit',
-  'hosts'        => [ '1.1.1.1', '2.2.2.2' ],
-  'port'         => '5672',
-  'username'     => 'username',
-  'password'     => 'password',
-  'virtual_host' => 'virtual_host',
-  'query'        => { 'key' => 'value' },
-})
-Generates:
-rabbit://username:password@1.1.1.1:5672,username:password@2.2.2.2:5672/virtual_host?key=value
-EOS
-) do |arguments|
-
-  require 'uri'
-
-  v = arguments[0]
-  klass = v.class
-
-  unless klass == Hash
-    raise(Puppet::ParseError, "os_transport_url(): Requires an hash, got #{klass}")
-  end
-
-  # type checking for the parameter hash
-  v.keys.each do |key|
-    v[key] = v[key].to_s if key == 'port'
-    klass = (key == 'hosts') ? Array : String
-    klass = (key == 'query') ? Hash : klass
-    unless (v[key].class == klass) or (v[key] == :undef)
-      raise(Puppet::ParseError, "os_transport_url(): #{key} should be a #{klass}")
-    end
-  end
-
-  # defaults
-  parts = {
-    :transport => 'rabbit',
-    :hostinfo  => 'localhost',
-    :path      => '/',
-  }
-
-  unless v.include?('transport')
-    raise(Puppet::ParseError, 'os_transport_url(): transport is required')
-  end
-
-  unless v.include?('host') or v.include?('hosts')
-    raise(Puppet::ParseError, 'os_transport_url(): host or hosts is required')
-  end
-
-  if v.include?('host') and v.include?('hosts')
-    raise(Puppet::ParseError, 'os_transport_url(): cannot use both host and hosts.')
-  end
-
-  parts[:transport] = v['transport']
-
-  if v.include?('username') and (v['username'] != :undef) and (v['username'].to_s != '')
-    parts[:userinfo] = URI.escape(v['username'])
-    if v.include?('password') and (v['password'] != :undef) and (v['password'].to_s != '')
-      parts[:userinfo] += ":#{URI.escape(v['password'])}"
-    end
-  end
-
-  if v.include?('host')
-    host = function_normalize_ip_for_uri([v['host']])
-    host += ":#{v['port'].to_s}" if v.include?('port')
-    if parts.include?(:userinfo)
-      parts[:hostinfo] = "#{parts[:userinfo]}@#{host}"
-    else
-      parts[:hostinfo] = "#{host}"
-    end
-  end
-
-  if v.include?('hosts')
-    hosts = function_normalize_ip_for_uri([v['hosts']])
-    # normalize_ip_for_uri may return a string, so check that we still have an
-    # array
-    hosts = [hosts] if hosts.kind_of?(String)
-    hosts = hosts.map{ |h| "#{h}:#{v['port'].to_s}" } if v.include?('port')
-    if parts.include?(:userinfo)
-      parts[:hostinfo] = hosts.map { |h| "#{parts[:userinfo]}@#{h}" }.join(',')
-    else
-      parts[:hostinfo] = hosts.join(',')
-    end
-  end
-
-  parts[:path] = "/#{v['virtual_host']}" if v.include?('virtual_host')
-
-  # support previous ssl option on the function. Setting ssl will
-  # override ssl if passed in via the query parameters
-  if v.include?('ssl')
-    # ssl can be passed in as a query paramter but should be 0/1. See
-    # http://docs.celeryproject.org/projects/kombu/en/latest/userguide/connections.html#urls
-    # so we rely on the stdlib str2bool and bool2num to ensure it's in the
-    # format
-    ssl_val = function_bool2num([function_str2bool([v['ssl']])])
-    if v.include?('query')
-      v['query'].merge!({ 'ssl' => ssl_val })
-    else
-      v['query'] = { 'ssl' => ssl_val }
-    end
-  end
-
-  parts[:query] = v['query'].map{ |k,val| "#{k}=#{val}" }.join('&') if v.include?('query')
-
-
-  url_parts = []
-  url_parts << parts[:transport]
-  url_parts << '://'
-  url_parts << parts[:hostinfo]
-  url_parts << parts[:path]
-  url_parts << '?' << parts[:query] if parts.include?(:query)
-  url_parts.join()
-end