]> gitweb.fluxo.info Git - puppet-stdlib.git/commitdiff
Add validator for any IP address
authorJaume Devesa <devvesa@gmail.com>
Thu, 19 Nov 2015 11:47:01 +0000 (12:47 +0100)
committerJaume Devesa <devvesa@gmail.com>
Mon, 30 Nov 2015 16:34:00 +0000 (17:34 +0100)
Provide a validator for IP addresses, regardless they are IPv4 or IPv6,
and its documentation.

README.markdown
lib/puppet/parser/functions/validate_ip_address.rb [new file with mode: 0644]
spec/functions/validate_ip_address_spec.rb [new file with mode: 0644]

index 9ff242cd80db82cd1c5774889c5ddd62bf913eea..526b573538586185ecb7eeeb5b66c0eb3b691367 100644 (file)
@@ -1079,6 +1079,39 @@ Validates that the first argument is an integer (or an array of integers). Abort
 
   *Type*: statement.
 
+#### `validate_ip_address`
+
+Validates that argument is an IP address, regardless of it is an IPv4 or an IPv6
+address. It validates as well IP address with netmask. It must be an String, as
+well.
+
+The following values will pass:
+
+  ~~~
+  validate_ip_address('0.0.0.0')
+  validate_ip_address('8.8.8.8')
+  validate_ip_address('127.0.0.1')
+  validate_ip_address('194.232.104.150')
+  validate_ip_address('3ffe:0505:0002::')
+  validate_ip_address('::1/64')
+  validate_ip_address('fe80::a00:27ff:fe94:44d6/64')
+  validate_ip_address('8.8.8.8/32')
+  ~~~
+
+The following values will fail, causing compilation to abort:
+
+  ~~~
+  validate_ip_address(1)
+  validate_ip_address(true)
+  validate_ip_address(0.0.0.256)
+  validate_ip_address('::1', {})
+  validate_ip_address('0.0.0.0.0')
+  validate_ip_address('3.3.3')
+  validate_ip_address('23.43.9.22/64')
+  validate_ip_address('260.2.32.43')
+  ~~~
+
+
 #### `validate_numeric`
 
 Validates that the first argument is a numeric value (or an array of numeric values). Aborts catalog compilation if any of the checks fail.
diff --git a/lib/puppet/parser/functions/validate_ip_address.rb b/lib/puppet/parser/functions/validate_ip_address.rb
new file mode 100644 (file)
index 0000000..c0baf82
--- /dev/null
@@ -0,0 +1,50 @@
+module Puppet::Parser::Functions
+
+  newfunction(:validate_ip_address, :doc => <<-ENDHEREDOC
+    Validate that all values passed are valid IP addresses,
+    regardless they are IPv4 or IPv6
+    Fail compilation if any value fails this check.
+    The following values will pass:
+    $my_ip = "1.2.3.4"
+    validate_ip_address($my_ip)
+    validate_bool("8.8.8.8", "172.16.0.1", $my_ip)
+    
+    $my_ip = "3ffe:505:2"
+    validate_ip_address(1)
+    validate_ip_address($my_ip)
+    validate_bool("fe80::baf6:b1ff:fe19:7507", $my_ip)
+   
+    The following values will fail, causing compilation to abort:
+    $some_array = [ 1, true, false, "garbage string", "3ffe:505:2" ]
+    validate_ip_address($some_array)
+    ENDHEREDOC
+  ) do |args|
+
+    require "ipaddr"
+    rescuable_exceptions = [ ArgumentError ]
+
+    if defined?(IPAddr::InvalidAddressError)
+      rescuable_exceptions << IPAddr::InvalidAddressError
+    end
+
+    unless args.length > 0 then
+      raise Puppet::ParseError, ("validate_ip_address(): wrong number of arguments (#{args.length}; must be > 0)")
+    end
+
+    args.each do |arg|
+      unless arg.is_a?(String)
+        raise Puppet::ParseError, "#{arg.inspect} is not a string."
+      end
+
+      begin
+        unless IPAddr.new(arg).ipv4? or IPAddr.new(arg).ipv6?
+          raise Puppet::ParseError, "#{arg.inspect} is not a valid IP address."
+        end
+      rescue *rescuable_exceptions
+        raise Puppet::ParseError, "#{arg.inspect} is not a valid IP address."
+      end
+    end
+
+  end
+
+end
diff --git a/spec/functions/validate_ip_address_spec.rb b/spec/functions/validate_ip_address_spec.rb
new file mode 100644 (file)
index 0000000..b56ce51
--- /dev/null
@@ -0,0 +1,46 @@
+require 'spec_helper'
+
+describe 'validate_ip_address' do
+  describe 'signature validation' do
+    it { is_expected.not_to eq(nil) }
+    it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) }
+  end
+
+  describe 'valid inputs' do
+    it { is_expected.to run.with_params('0.0.0.0') }
+    it { is_expected.to run.with_params('8.8.8.8') }
+    it { is_expected.to run.with_params('127.0.0.1') }
+    it { is_expected.to run.with_params('10.10.10.10') }
+    it { is_expected.to run.with_params('194.232.104.150') }
+    it { is_expected.to run.with_params('244.24.24.24') }
+    it { is_expected.to run.with_params('255.255.255.255') }
+    it { is_expected.to run.with_params('1.2.3.4', '5.6.7.8') }
+    it { is_expected.to run.with_params('3ffe:0505:0002::') }
+    it { is_expected.to run.with_params('3ffe:0505:0002::', '3ffe:0505:0002::2') }
+    it { is_expected.to run.with_params('::1/64') }
+    it { is_expected.to run.with_params('fe80::a00:27ff:fe94:44d6/64') }
+    context 'with netmasks' do
+      it { is_expected.to run.with_params('8.8.8.8/0') }
+      it { is_expected.to run.with_params('8.8.8.8/16') }
+      it { is_expected.to run.with_params('8.8.8.8/32') }
+      it { is_expected.to run.with_params('8.8.8.8/255.255.0.0') }
+    end
+  end
+
+  describe 'invalid inputs' do
+    it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /is not a string/) }
+    it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /is not a string/) }
+    it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /is not a string/) }
+    it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /is not a valid IP/) }
+    it { is_expected.to run.with_params('0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IP/) }
+    it { is_expected.to run.with_params('0.0.0.256').and_raise_error(Puppet::ParseError, /is not a valid IP/) }
+    it { is_expected.to run.with_params('0.0.0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IP/) }
+    it { is_expected.to run.with_params('1.2.3.4', {}).and_raise_error(Puppet::ParseError, /is not a string/) }
+    it { is_expected.to run.with_params('1.2.3.4', 1).and_raise_error(Puppet::ParseError, /is not a string/) }
+    it { is_expected.to run.with_params('1.2.3.4', true).and_raise_error(Puppet::ParseError, /is not a string/) }
+    it { is_expected.to run.with_params('1.2.3.4', 'one').and_raise_error(Puppet::ParseError, /is not a valid IP/) }
+    it { is_expected.to run.with_params('::1', {}).and_raise_error(Puppet::ParseError, /is not a string/) }
+    it { is_expected.to run.with_params('::1', true).and_raise_error(Puppet::ParseError, /is not a string/) }
+    it { is_expected.to run.with_params('::1', 'one').and_raise_error(Puppet::ParseError, /is not a valid IP/) }
+  end
+end