--- /dev/null
+module Puppet::Parser::Functions
+ newfunction(:generate_password, :type => :rvalue, :doc => <<-EOS
+Returns a semi-random string based on a seed and a value. Will always generate the same value with the same entry.
+Prototype:
+ generate_password(length, seed_file, password_key)
+EOS
+) do |*arguments|
+ arguments = arguments.shift if arguments.first.is_a?(Array)
+
+ raise Puppet::ParseError, "generate_password(): Wrong number of arguments " +
+ "given (#{arguments.size} for 3)" if arguments.size != 3
+
+ size = arguments.shift
+ seed_file = arguments.shift
+ password_key = arguments.shift
+
+ unless size.class.ancestors.include?(Numeric) or size.is_a?(String)
+ raise Puppet::ParseError, 'generate_password(): Requires a numeric first argument'
+ end
+
+ size = size.to_i
+
+ set = ('a' .. 'z').to_a + ('A' .. 'Z').to_a + ('0' .. '9').to_a
+
+ key = "#{File.open(seed_file).read}:#{password_key}"
+
+ size.times.collect do |i|
+ set[OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), key, i.to_s).to_i(16) % set.size]
+ end.join
+end
+end