|
| 1 | +# frozen_string_literal: true |
| 2 | + |
| 3 | +# @summary Rotates an array or string a random number of times, combining the `fqdn` fact and an optional seed for repeatable randomness. |
| 4 | +Puppet::Functions.create_function(:'stdlib::fqdn_rotate') do |
| 5 | + # @param input |
| 6 | + # The String you want rotated a random number of times |
| 7 | + # @param seeds |
| 8 | + # One of more values to use as a custom seed. These will be combined with the host's FQDN |
| 9 | + # |
| 10 | + # @return [String] Returns the rotated String |
| 11 | + # |
| 12 | + # @example Rotating a String |
| 13 | + # stdlib::fqdn_rotate('abcd') |
| 14 | + # @example Using a custom seed |
| 15 | + # stdlib::fqdn_rotate('abcd', 'custom seed') |
| 16 | + dispatch :fqdn_rotate_string do |
| 17 | + param 'String', :input |
| 18 | + optional_repeated_param 'Variant[Integer,String]', :seeds |
| 19 | + return_type 'String' |
| 20 | + end |
| 21 | + |
| 22 | + # @param input |
| 23 | + # The Array you want rotated a random number of times |
| 24 | + # @param seeds |
| 25 | + # One of more values to use as a custom seed. These will be combined with the host's FQDN |
| 26 | + # |
| 27 | + # @return [String] Returns the rotated Array |
| 28 | + # |
| 29 | + # @example Rotating an Array |
| 30 | + # stdlib::fqdn_rotate(['a', 'b', 'c', 'd']) |
| 31 | + # @example Using custom seeds |
| 32 | + # stdlib::fqdn_rotate([1, 2, 3], 'custom', 'seed', 1) |
| 33 | + dispatch :fqdn_rotate_array do |
| 34 | + param 'Array', :input |
| 35 | + optional_repeated_param 'Variant[Integer,String]', :seeds |
| 36 | + return_type 'Array' |
| 37 | + end |
| 38 | + |
| 39 | + def fqdn_rotate_array(input, *seeds) |
| 40 | + # Check whether it makes sense to rotate ... |
| 41 | + return input if input.size <= 1 |
| 42 | + |
| 43 | + result = input.clone |
| 44 | + |
| 45 | + require 'digest/md5' |
| 46 | + seed = Digest::MD5.hexdigest([fqdn_fact, seeds].join(':')).hex |
| 47 | + |
| 48 | + offset = Puppet::Util.deterministic_rand(seed, result.size).to_i |
| 49 | + |
| 50 | + offset.times do |
| 51 | + result.push result.shift |
| 52 | + end |
| 53 | + |
| 54 | + result |
| 55 | + end |
| 56 | + |
| 57 | + def fqdn_rotate_string(input, *seeds) |
| 58 | + fqdn_rotate_array(input.chars, seeds).join |
| 59 | + end |
| 60 | + |
| 61 | + private |
| 62 | + |
| 63 | + def fqdn_fact |
| 64 | + closure_scope['facts']['networking']['fqdn'] |
| 65 | + end |
| 66 | +end |
0 commit comments