Skip to content

Commit ca7633c

Browse files
committed
Merge pull request #158 from wfarr/validate_ip
[#20862] Add functions to validate ipv4 and ipv6 addresses
2 parents 928c131 + e0fd729 commit ca7633c

4 files changed

Lines changed: 228 additions & 0 deletions

File tree

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
module Puppet::Parser::Functions
2+
3+
newfunction(:validate_ipv4_address, :doc => <<-ENDHEREDOC
4+
Validate that all values passed are valid IPv4 addresses.
5+
Fail compilation if any value fails this check.
6+
7+
The following values will pass:
8+
9+
$my_ip = "1.2.3.4"
10+
validate_ipv4_address($my_ip)
11+
validate_bool("8.8.8.8", "172.16.0.1", $my_ip)
12+
13+
The following values will fail, causing compilation to abort:
14+
15+
$some_array = [ 1, true, false, "garbage string", "3ffe:505:2" ]
16+
validate_ipv4_address($some_array)
17+
18+
ENDHEREDOC
19+
) do |args|
20+
21+
require "ipaddr"
22+
rescuable_exceptions = [ ArgumentError ]
23+
24+
if defined?(IPAddr::InvalidAddressError)
25+
rescuable_exceptions << IPAddr::InvalidAddressError
26+
end
27+
28+
unless args.length > 0 then
29+
raise Puppet::ParseError, ("validate_ipv4_address(): wrong number of arguments (#{args.length}; must be > 0)")
30+
end
31+
32+
args.each do |arg|
33+
unless arg.is_a?(String)
34+
raise Puppet::ParseError, "#{arg.inspect} is not a string."
35+
end
36+
37+
begin
38+
unless IPAddr.new(arg).ipv4?
39+
raise Puppet::ParseError, "#{arg.inspect} is not a valid IPv4 address."
40+
end
41+
rescue *rescuable_exceptions
42+
raise Puppet::ParseError, "#{arg.inspect} is not a valid IPv4 address."
43+
end
44+
end
45+
46+
end
47+
48+
end
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
module Puppet::Parser::Functions
2+
3+
newfunction(:validate_ipv6_address, :doc => <<-ENDHEREDOC
4+
Validate that all values passed are valid IPv6 addresses.
5+
Fail compilation if any value fails this check.
6+
7+
The following values will pass:
8+
9+
$my_ip = "3ffe:505:2"
10+
validate_ipv6_address(1)
11+
validate_ipv6_address($my_ip)
12+
validate_bool("fe80::baf6:b1ff:fe19:7507", $my_ip)
13+
14+
The following values will fail, causing compilation to abort:
15+
16+
$some_array = [ true, false, "garbage string", "1.2.3.4" ]
17+
validate_ipv6_address($some_array)
18+
19+
ENDHEREDOC
20+
) do |args|
21+
22+
require "ipaddr"
23+
rescuable_exceptions = [ ArgumentError ]
24+
25+
if defined?(IPAddr::InvalidAddressError)
26+
rescuable_exceptions << IPAddr::InvalidAddressError
27+
end
28+
29+
unless args.length > 0 then
30+
raise Puppet::ParseError, ("validate_ipv6_address(): wrong number of arguments (#{args.length}; must be > 0)")
31+
end
32+
33+
args.each do |arg|
34+
unless arg.is_a?(String)
35+
raise Puppet::ParseError, "#{arg.inspect} is not a string."
36+
end
37+
38+
begin
39+
unless IPAddr.new(arg).ipv6?
40+
raise Puppet::ParseError, "#{arg.inspect} is not a valid IPv6 address."
41+
end
42+
rescue *rescuable_exceptions
43+
raise Puppet::ParseError, "#{arg.inspect} is not a valid IPv6 address."
44+
end
45+
end
46+
47+
end
48+
49+
end
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#! /usr/bin/env/ruby -S rspec
2+
3+
require "spec_helper"
4+
5+
describe Puppet::Parser::Functions.function(:validate_ipv4_address) do
6+
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
7+
8+
describe "when calling validate_ipv4_address from puppet" do
9+
describe "when given IPv4 address strings" do
10+
it "should compile with one argument" do
11+
Puppet[:code] = "validate_ipv4_address('1.2.3.4')"
12+
scope.compiler.compile
13+
end
14+
15+
it "should compile with multiple arguments" do
16+
Puppet[:code] = "validate_ipv4_address('1.2.3.4', '5.6.7.8')"
17+
scope.compiler.compile
18+
end
19+
end
20+
21+
describe "when given an IPv6 address" do
22+
it "should not compile" do
23+
Puppet[:code] = "validate_ipv4_address('3ffe:505')"
24+
expect {
25+
scope.compiler.compile
26+
}.to raise_error(Puppet::ParseError, /not a valid IPv4 address/)
27+
end
28+
end
29+
30+
describe "when given other strings" do
31+
it "should not compile" do
32+
Puppet[:code] = "validate_ipv4_address('hello', 'world')"
33+
expect {
34+
scope.compiler.compile
35+
}.to raise_error(Puppet::ParseError, /not a valid IPv4 address/)
36+
end
37+
end
38+
39+
describe "when given numbers" do
40+
it "should not compile" do
41+
Puppet[:code] = "validate_ipv4_address(1, 2)"
42+
expect {
43+
scope.compiler.compile
44+
}.to raise_error(Puppet::ParseError, /is not a valid IPv4 address/)
45+
end
46+
end
47+
48+
describe "when given booleans" do
49+
it "should not compile" do
50+
Puppet[:code] = "validate_ipv4_address(true, false)"
51+
expect {
52+
scope.compiler.compile
53+
}.to raise_error(Puppet::ParseError, /is not a string/)
54+
end
55+
end
56+
57+
it "should not compile when no arguments are passed" do
58+
Puppet[:code] = "validate_ipv4_address()"
59+
expect {
60+
scope.compiler.compile
61+
}.to raise_error(Puppet::ParseError, /wrong number of arguments/)
62+
end
63+
end
64+
end
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#! /usr/bin/env/ruby -S rspec
2+
3+
require "spec_helper"
4+
5+
describe Puppet::Parser::Functions.function(:validate_ipv6_address) do
6+
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
7+
8+
describe "when calling validate_ipv6_address from puppet" do
9+
describe "when given IPv6 address strings" do
10+
it "should compile with one argument" do
11+
Puppet[:code] = "validate_ipv6_address('3ffe:0505:0002::')"
12+
scope.compiler.compile
13+
end
14+
15+
it "should compile with multiple arguments" do
16+
Puppet[:code] = "validate_ipv6_address('3ffe:0505:0002::', '3ffe:0505:0001::')"
17+
scope.compiler.compile
18+
end
19+
end
20+
21+
describe "when given an ipv4 address" do
22+
it "should not compile" do
23+
Puppet[:code] = "validate_ipv6_address('1.2.3.4')"
24+
expect {
25+
scope.compiler.compile
26+
}.to raise_error(Puppet::ParseError, /not a valid IPv6 address/)
27+
end
28+
end
29+
30+
describe "when given other strings" do
31+
it "should not compile" do
32+
Puppet[:code] = "validate_ipv6_address('hello', 'world')"
33+
expect {
34+
scope.compiler.compile
35+
}.to raise_error(Puppet::ParseError, /not a valid IPv6 address/)
36+
end
37+
end
38+
39+
# 1.8.7 is EOL'd and also absolutely insane about ipv6
40+
unless RUBY_VERSION == '1.8.7'
41+
describe "when given numbers" do
42+
it "should not compile" do
43+
Puppet[:code] = "validate_ipv6_address(1, 2)"
44+
expect {
45+
scope.compiler.compile
46+
}.to raise_error(Puppet::ParseError, /not a valid IPv6 address/)
47+
end
48+
end
49+
end
50+
51+
describe "when given booleans" do
52+
it "should not compile" do
53+
Puppet[:code] = "validate_ipv6_address(true, false)"
54+
expect {
55+
scope.compiler.compile
56+
}.to raise_error(Puppet::ParseError, /is not a string/)
57+
end
58+
end
59+
60+
it "should not compile when no arguments are passed" do
61+
Puppet[:code] = "validate_ipv6_address()"
62+
expect {
63+
scope.compiler.compile
64+
}.to raise_error(Puppet::ParseError, /wrong number of arguments/)
65+
end
66+
end
67+
end

0 commit comments

Comments
 (0)