1 | #
|
---|
2 | # fqdn_rotate.rb
|
---|
3 | #
|
---|
4 |
|
---|
5 | Puppet::Parser::Functions.newfunction(
|
---|
6 | :fqdn_rotate,
|
---|
7 | :type => :rvalue,
|
---|
8 | :doc => "Usage: `fqdn_rotate(VALUE, [SEED])`. VALUE is required and
|
---|
9 | must be an array or a string. SEED is optional and may be any number
|
---|
10 | or string.
|
---|
11 |
|
---|
12 | Rotates VALUE a random number of times, combining the `$fqdn` fact and
|
---|
13 | the value of SEED for repeatable randomness. (That is, each node will
|
---|
14 | get a different random rotation from this function, but a given node's
|
---|
15 | result will be the same every time unless its hostname changes.) Adding
|
---|
16 | a SEED can be useful if you need more than one unrelated rotation.") do |args|
|
---|
17 |
|
---|
18 | raise(Puppet::ParseError, "fqdn_rotate(): Wrong number of arguments " +
|
---|
19 | "given (#{args.size} for 1)") if args.size < 1
|
---|
20 |
|
---|
21 | value = args.shift
|
---|
22 | require 'digest/md5'
|
---|
23 |
|
---|
24 | unless value.is_a?(Array) || value.is_a?(String)
|
---|
25 | raise(Puppet::ParseError, 'fqdn_rotate(): Requires either ' +
|
---|
26 | 'array or string to work with')
|
---|
27 | end
|
---|
28 |
|
---|
29 | result = value.clone
|
---|
30 |
|
---|
31 | string = value.is_a?(String) ? true : false
|
---|
32 |
|
---|
33 | # Check whether it makes sense to rotate ...
|
---|
34 | return result if result.size <= 1
|
---|
35 |
|
---|
36 | # We turn any string value into an array to be able to rotate ...
|
---|
37 | result = string ? result.split('') : result
|
---|
38 |
|
---|
39 | elements = result.size
|
---|
40 |
|
---|
41 | seed = Digest::MD5.hexdigest([lookupvar('::fqdn'),args].join(':')).hex
|
---|
42 | # deterministic_rand() was added in Puppet 3.2.0; reimplement if necessary
|
---|
43 | if Puppet::Util.respond_to?(:deterministic_rand)
|
---|
44 | offset = Puppet::Util.deterministic_rand(seed, elements).to_i
|
---|
45 | else
|
---|
46 | if defined?(Random) == 'constant' && Random.class == Class
|
---|
47 | offset = Random.new(seed).rand(elements)
|
---|
48 | else
|
---|
49 | old_seed = srand(seed)
|
---|
50 | offset = rand(elements)
|
---|
51 | srand(old_seed)
|
---|
52 | end
|
---|
53 | end
|
---|
54 | offset.times {
|
---|
55 | result.push result.shift
|
---|
56 | }
|
---|
57 |
|
---|
58 | result = string ? result.join : result
|
---|
59 |
|
---|
60 | return result
|
---|
61 | end
|
---|
62 |
|
---|
63 | # vim: set ts=2 sw=2 et :
|
---|