|
2 | 2 | require 'digest/sha2'
|
3 | 3 |
|
4 | 4 | Puppet::Parser::Functions::newfunction(:fqdn_rand, :arity => -2, :type => :rvalue, :doc =>
|
5 |
| - "Usage: `fqdn_rand(MAX, [SEED])`. MAX is required and must be a positive |
6 |
| - integer; SEED is optional and may be any number or string. |
| 5 | + "Usage: `fqdn_rand(MAX, [SEED], [DOWNCASE])`. MAX is required and must be a positive |
| 6 | + integer; SEED is optional and may be any number or string; DOWNCASE is optional |
| 7 | + and should be a boolean true or false. |
7 | 8 |
|
8 | 9 | Generates a random Integer number greater than or equal to 0 and less than MAX,
|
9 | 10 | combining the `$fqdn` fact and the value of SEED for repeatable randomness.
|
10 | 11 | (That is, each node will get a different random number from this function, but
|
11 |
| - a given node's result will be the same every time unless its hostname changes.) |
| 12 | + a given node's result will be the same every time unless its hostname changes.) If |
| 13 | + DOWNCASE is true, then the `fqdn` fact will be downcased when computing the value |
| 14 | + so that the result is not sensitive to the case of the `fqdn` fact. |
12 | 15 |
|
13 | 16 | This function is usually used for spacing out runs of resource-intensive cron
|
14 | 17 | tasks that run on many nodes, which could cause a thundering herd or degrade
|
|
17 | 20 | node. (For example, `fqdn_rand(30)`, `fqdn_rand(30, 'expensive job 1')`, and
|
18 | 21 | `fqdn_rand(30, 'expensive job 2')` will produce totally different numbers.)") do |args|
|
19 | 22 | max = args.shift.to_i
|
20 |
| - |
| 23 | + initial_seed = args.shift |
| 24 | + downcase = !!args.shift |
| 25 | + |
| 26 | + fqdn = self['::fqdn'] |
| 27 | + fqdn = fqdn.downcase if downcase |
| 28 | + |
21 | 29 | # Puppet 5.4's fqdn_rand function produces a different value than earlier versions
|
22 | 30 | # for the same set of inputs.
|
23 | 31 | # This causes problems because the values are often written into service configuration files.
|
|
27 | 35 | # when running on a non-FIPS enabled platform and only using SHA256 on FIPS enabled
|
28 | 36 | # platforms.
|
29 | 37 | if Puppet::Util::Platform.fips_enabled?
|
30 |
| - seed = Digest::SHA256.hexdigest([self['::fqdn'],max,args].join(':')).hex |
| 38 | + seed = Digest::SHA256.hexdigest([fqdn,max,initial_seed].join(':')).hex |
31 | 39 | else
|
32 |
| - seed = Digest::MD5.hexdigest([self['::fqdn'],max,args].join(':')).hex |
| 40 | + seed = Digest::MD5.hexdigest([fqdn,max,initial_seed].join(':')).hex |
33 | 41 | end
|
34 | 42 |
|
35 | 43 | Puppet::Util.deterministic_rand_int(seed,max)
|
|
0 commit comments