Skip to content

Commit f2f6635

Browse files
committed
Modernise fqdn_rotate function
Convert the function to the modern function API as a namespaced function and use the `networking` fact instead of legacy facts. A non-namespaced shim is also created (but marked deprecated), to preserve compatibility.
1 parent 78e07be commit f2f6635

File tree

5 files changed

+162
-92
lines changed

5 files changed

+162
-92
lines changed

REFERENCE.md

Lines changed: 79 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,7 @@ as a result.
7171
* [`floor`](#floor): Returns the largest integer less or equal to the argument.
7272
* [`fqdn_rand_string`](#fqdn_rand_string): Generates a random alphanumeric string. Combining the `$fqdn` fact and an
7373
optional seed for repeatable randomness.
74-
* [`fqdn_rotate`](#fqdn_rotate): Rotates an array or string a random number of times, combining the `$fqdn` fact
75-
and an optional seed for repeatable randomness.
74+
* [`fqdn_rotate`](#fqdn_rotate): DEPRECATED. Use the namespaced function [`stdlib::fqdn_rotate`](#stdlibfqdn_rotate) instead.
7675
* [`fqdn_uuid`](#fqdn_uuid): Returns a [RFC 4122](https://tools.ietf.org/html/rfc4122) valid version 5 UUID based
7776
on an FQDN string under the DNS namespace
7877
* [`get_module_path`](#get_module_path): Returns the absolute path of the specified module for the current
@@ -179,6 +178,7 @@ the provided regular expression.
179178
* [`stdlib::ensure`](#stdlib--ensure): function to cast ensure parameter to resource specific value
180179
* [`stdlib::extname`](#stdlib--extname): Returns the Extension (the Portion of Filename in Path starting from the
181180
last Period).
181+
* [`stdlib::fqdn_rotate`](#stdlib--fqdn_rotate): Rotates an array or string a random number of times, combining the `fqdn` fact and an optional seed for repeatable randomness.
182182
* [`stdlib::ip_in_range`](#stdlib--ip_in_range): Returns true if the ipaddress is within the given CIDRs
183183
* [`stdlib::sha256`](#stdlib--sha256): Run a SHA256 calculation against a given value.
184184
* [`stdlib::start_with`](#stdlib--start_with): Returns true if str starts with one of the prefixes given. Each of the prefixes should be a String.
@@ -2293,36 +2293,21 @@ fqdn_rand_string(10, '', 'custom seed')
22932293

22942294
### <a name="fqdn_rotate"></a>`fqdn_rotate`
22952295

2296-
Type: Ruby 3.x API
2297-
2298-
Rotates an array or string a random number of times, combining the `$fqdn` fact
2299-
and an optional seed for repeatable randomness.
2300-
2301-
#### Examples
2296+
Type: Ruby 4.x API
23022297

2303-
##### Example Usage:
2298+
DEPRECATED. Use the namespaced function [`stdlib::fqdn_rotate`](#stdlibfqdn_rotate) instead.
23042299

2305-
```puppet
2306-
fqdn_rotate(['a', 'b', 'c', 'd'])
2307-
fqdn_rotate('abcd')
2308-
fqdn_rotate([1, 2, 3], 'custom seed')
2309-
```
2310-
2311-
#### `fqdn_rotate()`
2300+
#### `fqdn_rotate(Any *$args)`
23122301

23132302
The fqdn_rotate function.
23142303

2315-
Returns: `Any` rotated array or string
2304+
Returns: `Any`
23162305

2317-
##### Examples
2306+
##### `*args`
2307+
2308+
Data type: `Any`
23182309

2319-
###### Example Usage:
23202310

2321-
```puppet
2322-
fqdn_rotate(['a', 'b', 'c', 'd'])
2323-
fqdn_rotate('abcd')
2324-
fqdn_rotate([1, 2, 3], 'custom seed')
2325-
```
23262311

23272312
### <a name="fqdn_uuid"></a>`fqdn_uuid`
23282313

@@ -4881,6 +4866,76 @@ Data type: `String`
48814866

48824867
The Filename
48834868

4869+
### <a name="stdlib--fqdn_rotate"></a>`stdlib::fqdn_rotate`
4870+
4871+
Type: Ruby 4.x API
4872+
4873+
Rotates an array or string a random number of times, combining the `fqdn` fact and an optional seed for repeatable randomness.
4874+
4875+
#### `stdlib::fqdn_rotate(String $input, Optional[Variant[Integer,String]] *$seeds)`
4876+
4877+
The stdlib::fqdn_rotate function.
4878+
4879+
Returns: `String` Returns the rotated String
4880+
4881+
##### Examples
4882+
4883+
###### Rotating a String
4884+
4885+
```puppet
4886+
stdlib::fqdn_rotate('abcd')
4887+
```
4888+
4889+
###### Using a custom seed
4890+
4891+
```puppet
4892+
stdlib::fqdn_rotate('abcd', 'custom seed')
4893+
```
4894+
4895+
##### `input`
4896+
4897+
Data type: `String`
4898+
4899+
The String you want rotated a random number of times
4900+
4901+
##### `*seeds`
4902+
4903+
Data type: `Optional[Variant[Integer,String]]`
4904+
4905+
One of more values to use as a custom seed. These will be combined with the host's FQDN
4906+
4907+
#### `stdlib::fqdn_rotate(Array $input, Optional[Variant[Integer,String]] *$seeds)`
4908+
4909+
The stdlib::fqdn_rotate function.
4910+
4911+
Returns: `Array` Returns the rotated Array
4912+
4913+
##### Examples
4914+
4915+
###### Rotating an Array
4916+
4917+
```puppet
4918+
stdlib::fqdn_rotate(['a', 'b', 'c', 'd'])
4919+
```
4920+
4921+
###### Using custom seeds
4922+
4923+
```puppet
4924+
stdlib::fqdn_rotate([1, 2, 3], 'custom', 'seed', 1)
4925+
```
4926+
4927+
##### `input`
4928+
4929+
Data type: `Array`
4930+
4931+
The Array you want rotated a random number of times
4932+
4933+
##### `*seeds`
4934+
4935+
Data type: `Optional[Variant[Integer,String]]`
4936+
4937+
One of more values to use as a custom seed. These will be combined with the host's FQDN
4938+
48844939
### <a name="stdlib--ip_in_range"></a>`stdlib::ip_in_range`
48854940

48864941
Type: Ruby 4.x API

lib/puppet/functions/fqdn_rotate.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# frozen_string_literal: true
2+
3+
# @summary DEPRECATED. Use the namespaced function [`stdlib::fqdn_rotate`](#stdlibfqdn_rotate) instead.
4+
Puppet::Functions.create_function(:fqdn_rotate) do
5+
dispatch :deprecation_gen do
6+
repeated_param 'Any', :args
7+
end
8+
def deprecation_gen(*args)
9+
call_function('deprecation', 'fqdn_rotate', 'This method is deprecated, please use stdlib::fqdn_rotate instead.')
10+
call_function('stdlib::fqdn_rotate', *args)
11+
end
12+
end
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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.split(''), seeds).join
59+
end
60+
61+
private
62+
63+
def fqdn_fact
64+
closure_scope['facts']['networking']['fqdn']
65+
end
66+
end

lib/puppet/parser/functions/fqdn_rotate.rb

Lines changed: 0 additions & 61 deletions
This file was deleted.

spec/functions/fqdn_rotate_spec.rb

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
describe 'fqdn_rotate' do
66
it { is_expected.not_to eq(nil) }
7-
it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) }
8-
it { is_expected.to run.with_params(0).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work with}) }
9-
it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work with}) }
7+
it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{expects at least 1 argument, got none}) }
8+
it { is_expected.to run.with_params(0).and_raise_error(ArgumentError, %r{parameter 'input' expects a value of type String or Array, got Integer}) }
9+
it { is_expected.to run.with_params({}).and_raise_error(ArgumentError, %r{parameter 'input' expects a value of type String or Array, got Hash}) }
1010
it { is_expected.to run.with_params('').and_return('') }
1111
it { is_expected.to run.with_params('a').and_return('a') }
1212
it { is_expected.to run.with_params('ã').and_return('ã') }
@@ -48,8 +48,6 @@
4848
end
4949

5050
it 'uses the Puppet::Util.deterministic_rand function' do
51-
skip 'Puppet::Util#deterministic_rand not available' unless Puppet::Util.respond_to?(:deterministic_rand)
52-
5351
expect(Puppet::Util).to receive(:deterministic_rand).with(44_489_829_212_339_698_569_024_999_901_561_968_770, 4)
5452
fqdn_rotate('asdf')
5553
end
@@ -68,9 +66,9 @@ def fqdn_rotate(value, args = {})
6866

6967
# workaround not being able to use let(:facts) because some tests need
7068
# multiple different hostnames in one context
71-
allow(scope).to receive(:lookupvar).with('::fqdn').and_return(host)
69+
allow(subject.func.closure_scope).to receive(:[]).with('facts').and_return({ 'networking' => { 'fqdn' => host } })
7270

7371
function_args = [value] + extra
74-
scope.function_fqdn_rotate(function_args)
72+
scope.call_function('fqdn_rotate', function_args)
7573
end
7674
end

0 commit comments

Comments
 (0)