Update stdlib and concat to 6.1.0 both
[mirror/dsa-puppet.git] / 3rdparty / modules / stdlib / lib / puppet / parser / functions / fqdn_rotate.rb
1 #
2 # fqdn_rotate.rb
3 #
4 Puppet::Parser::Functions.newfunction(
5   :fqdn_rotate,
6   :type => :rvalue,
7   :doc => <<-DOC
8   @summary
9     Rotates an array or string a random number of times, combining the `$fqdn` fact
10     and an optional seed for repeatable randomness.
11
12   @return
13     rotated array or string
14
15   @example Example Usage:
16     fqdn_rotate(['a', 'b', 'c', 'd'])
17     fqdn_rotate('abcd')
18     fqdn_rotate([1, 2, 3], 'custom seed')
19   DOC
20 ) do |args|
21
22   raise(Puppet::ParseError, "fqdn_rotate(): Wrong number of arguments given (#{args.size} for 1)") if args.empty?
23
24   value = args.shift
25   require 'digest/md5'
26
27   unless value.is_a?(Array) || value.is_a?(String)
28     raise(Puppet::ParseError, 'fqdn_rotate(): Requires either array or string to work with')
29   end
30
31   result = value.clone
32
33   string = value.is_a?(String) ? true : false
34
35   # Check whether it makes sense to rotate ...
36   return result if result.size <= 1
37
38   # We turn any string value into an array to be able to rotate ...
39   result = string ? result.split('') : result
40
41   elements = result.size
42
43   seed = Digest::MD5.hexdigest([lookupvar('::fqdn'), args].join(':')).hex
44   # deterministic_rand() was added in Puppet 3.2.0; reimplement if necessary
45   if Puppet::Util.respond_to?(:deterministic_rand)
46     offset = Puppet::Util.deterministic_rand(seed, elements).to_i
47   else
48     return offset = Random.new(seed).rand(elements) if defined?(Random) == 'constant' && Random.class == Class
49
50     old_seed = srand(seed)
51     offset = rand(elements)
52     srand(old_seed)
53   end
54   offset.times do
55     result.push result.shift
56   end
57
58   result = string ? result.join : result
59
60   return result
61 end
62
63 # vim: set ts=2 sw=2 et :