From ee570e299419344b5f675a9de25c85ea456ad5de Mon Sep 17 00:00:00 2001 From: Yury Bushmelev Date: Sun, 31 Mar 2024 18:31:38 +0300 Subject: [PATCH] Add `extlib::compare_ip()` function This function is to be used with the built-in `sort()` function. --- REFERENCE.md | 45 +++++++++++++++++++++++ lib/puppet/functions/extlib/compare_ip.rb | 23 ++++++++++++ spec/functions/extlib/compare_ip_spec.rb | 21 +++++++++++ 3 files changed, 89 insertions(+) create mode 100644 lib/puppet/functions/extlib/compare_ip.rb create mode 100644 spec/functions/extlib/compare_ip_spec.rb diff --git a/REFERENCE.md b/REFERENCE.md index dbd58a9..b76ecf1 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -9,6 +9,7 @@ * [`extlib::cache_data`](#extlib--cache_data): Retrieves data from a cache file, or creates it with supplied data if the file doesn't exist * [`extlib::cidr_to_netmask`](#extlib--cidr_to_netmask): Converts an CIDR address of the form 192.168.0.1/24 into its netmask. * [`extlib::cidr_to_network`](#extlib--cidr_to_network): Converts a CIDR address of the form 2001:DB8::/32 or 192.0.2.0/24 into their network address (also known as net address) +* [`extlib::compare_ip`](#extlib--compare_ip): A function that compares two IP addresses. To be used with the built-in sort() function. * [`extlib::default_content`](#extlib--default_content): Takes an optional content and an optional template name and returns the contents of a file. * [`extlib::dir_clean`](#extlib--dir_clean): Take a path and normalise it to its Unix form. * [`extlib::dir_split`](#extlib--dir_split): Splits the given directory or directories into individual paths. @@ -172,6 +173,50 @@ Data type: `Variant[Stdlib::IP::Address::V4::CIDR,Stdlib::IP::Address::V6::CIDR] IPv6 or IPv4 address in CIDR notation +### `extlib::compare_ip` + +Type: Ruby 4.x API + +A function that compares two IP addresses. To be used with the built-in sort() +function. + +#### Examples + +##### Sorting the array of IP addresses + +```puppet +$ip_addresses = ['10.1.1.1', '10.10.1.1', '10.2.1.1'] +$ip_addresses.sort |$a, $b| { extlib::compare_ip($a, $b) } +``` + +#### `extlib::compare_ip(Stdlib::IP::Address $left, Stdlib::IP::Address $right)` + +A function that compares two IP addresses. To be used with the built-in sort() +function. + +Returns: `Integer[-1,1]` -1, 0 or 1 if left value is lesser, equal or greater than right value + +##### Examples + +###### Sorting the array of IP addresses + +```puppet +$ip_addresses = ['10.1.1.1', '10.10.1.1', '10.2.1.1'] +$ip_addresses.sort |$a, $b| { extlib::compare_ip($a, $b) } +``` + +##### `left` + +Data type: `Stdlib::IP::Address` + +Left value + +##### `right` + +Data type: `Stdlib::IP::Address` + +Right value + ### `extlib::default_content` Type: Ruby 4.x API diff --git a/lib/puppet/functions/extlib/compare_ip.rb b/lib/puppet/functions/extlib/compare_ip.rb new file mode 100644 index 0000000..702df52 --- /dev/null +++ b/lib/puppet/functions/extlib/compare_ip.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'ipaddr' + +# A function that compares two IP addresses. To be used with the built-in sort() +# function. +Puppet::Functions.create_function(:'extlib::compare_ip') do + # @param left Left value + # @param right Right value + # @return -1, 0 or 1 if left value is lesser, equal or greater than right value + # @example Sorting the array of IP addresses + # $ip_addresses = ['10.1.1.1', '10.10.1.1', '10.2.1.1'] + # $ip_addresses.sort |$a, $b| { extlib::compare_ip($a, $b) } + dispatch :compare_ip do + param 'Stdlib::IP::Address', :left + param 'Stdlib::IP::Address', :right + return_type 'Integer[-1,1]' + end + + def compare_ip(left, right) + IPAddr.new(left).to_i <=> IPAddr.new(right).to_i + end +end diff --git a/spec/functions/extlib/compare_ip_spec.rb b/spec/functions/extlib/compare_ip_spec.rb new file mode 100644 index 0000000..8a288f7 --- /dev/null +++ b/spec/functions/extlib/compare_ip_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'extlib::compare_ip' do + it 'exists' do + is_expected.not_to be_nil + end + + it { is_expected.to run.with_params('10.1.1.1', '10.2.1.1').and_return(-1) } + it { is_expected.to run.with_params('10.2.1.1', '10.2.1.1').and_return(0) } + it { is_expected.to run.with_params('10.10.1.1', '10.2.1.1').and_return(1) } + + it { is_expected.to run.with_params('fe80::1', 'fe80::2').and_return(-1) } + it { is_expected.to run.with_params('fe80::2', 'fe80::2').and_return(0) } + it { is_expected.to run.with_params('fe80::10', 'fe80::2').and_return(1) } + + it { is_expected.to run.with_params('0::ffff:fffe', '255.255.255.255').and_return(-1) } + it { is_expected.to run.with_params('0::ffff:ffff', '255.255.255.255').and_return(0) } + it { is_expected.to run.with_params('0::1:0:0', '255.255.255.255').and_return(1) } +end