diff --git a/lib/puppet/functions/validate_domain_name.rb b/lib/puppet/functions/validate_domain_name.rb new file mode 100644 index 000000000..c2833043f --- /dev/null +++ b/lib/puppet/functions/validate_domain_name.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +# @summary +# Validate that all values passed are syntactically correct domain names. +# Fail compilation if any value fails this check. +Puppet::Functions.create_function(:validate_domain_name) do + # @param values A domain name or an array of domain names to check + # + # @return [Undef] + # passes when the given values are syntactically correct domain names or raise an error when they are not and fails compilation + # + # @example Passing examples + # $my_domain_name = 'server.domain.tld' + # validate_domain_name($my_domain_name) + # validate_domain_name('domain.tld', 'puppet.com', $my_domain_name) + # validate_domain_name('www.example.2com') + # + # @example Failing examples (causing compilation to abort) + # validate_domain_name(1) + # validate_domain_name(true) + # validate_domain_name('invalid domain') + # validate_domain_name('-foo.example.com') + dispatch :validate_domain_name do + repeated_param 'Variant[Stdlib::Fqdn, Stdlib::Dns::Zone]', :values + end + + def validate_domain_name(*_values); end +end diff --git a/lib/puppet/parser/functions/validate_domain_name.rb b/lib/puppet/parser/functions/validate_domain_name.rb deleted file mode 100644 index 0ed576f16..000000000 --- a/lib/puppet/parser/functions/validate_domain_name.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -# -# validate_domain_name.rb -# -module Puppet::Parser::Functions - newfunction(:validate_domain_name, doc: <<-DOC - @summary - Validate that all values passed are syntactically correct domain names. - Fail compilation if any value fails this check. - - @return - passes when the given values are syntactically correct domain names or raise an error when they are not and fails compilation - - @example **Usage** - - The following values will pass: - - $my_domain_name = 'server.domain.tld' - validate_domain_name($my_domain_name) - validate_domain_name('domain.tld', 'puppet.com', $my_domain_name) - - The following values will fail, causing compilation to abort: - - validate_domain_name(1) - validate_domain_name(true) - validate_domain_name('invalid domain') - validate_domain_name('-foo.example.com') - validate_domain_name('www.example.2com') - DOC - ) do |args| - rescuable_exceptions = [ArgumentError] - - if args.empty? - raise Puppet::ParseError, "validate_domain_name(): wrong number of arguments (#{args.length}; must be > 0)" - end - - args.each do |arg| - raise Puppet::ParseError, "#{arg.inspect} is not a string." unless arg.is_a?(String) - - begin - raise Puppet::ParseError, "#{arg.inspect} is not a syntactically correct domain name" unless function_is_domain_name([arg]) - rescue *rescuable_exceptions - raise Puppet::ParseError, "#{arg.inspect} is not a syntactically correct domain name" - end - end - end -end diff --git a/spec/functions/validate_domain_name_spec.rb b/spec/functions/validate_domain_name_spec.rb index f48d31ab5..78aea8218 100644 --- a/spec/functions/validate_domain_name_spec.rb +++ b/spec/functions/validate_domain_name_spec.rb @@ -5,7 +5,6 @@ describe 'validate_domain_name' do describe 'signature validation' do it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } end describe 'valid inputs' do @@ -15,23 +14,23 @@ it { is_expected.to run.with_params('2foo.example.com', '2foo.example.com.') } it { is_expected.to run.with_params('www.2foo.example.com', 'www.2foo.example.com.') } it { is_expected.to run.with_params('domain.tld', 'puppet.com') } + it { is_expected.to run.with_params('www.example.2com') } + it { is_expected.to run.with_params('10.10.10.10.10') } end describe 'invalid inputs' do - it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, %r{is not a string}) } - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, %r{is not a string}) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, %r{is not a string}) } - it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, %r{is not a string}) } + it { is_expected.to run.with_params([]).and_raise_error(ArgumentError, %r{got Array}) } + it { is_expected.to run.with_params({}).and_raise_error(ArgumentError, %r{got Hash}) } + it { is_expected.to run.with_params(1).and_raise_error(ArgumentError, %r{got Integer}) } + it { is_expected.to run.with_params(true).and_raise_error(ArgumentError, %r{got Boolean}) } - it { is_expected.to run.with_params('foo.example.com', []).and_raise_error(Puppet::ParseError, %r{is not a string}) } - it { is_expected.to run.with_params('foo.example.com', {}).and_raise_error(Puppet::ParseError, %r{is not a string}) } - it { is_expected.to run.with_params('foo.example.com', 1).and_raise_error(Puppet::ParseError, %r{is not a string}) } - it { is_expected.to run.with_params('foo.example.com', true).and_raise_error(Puppet::ParseError, %r{is not a string}) } + it { is_expected.to run.with_params('foo.example.com', []).and_raise_error(ArgumentError, %r{got Array}) } + it { is_expected.to run.with_params('foo.example.com', {}).and_raise_error(ArgumentError, %r{got Hash}) } + it { is_expected.to run.with_params('foo.example.com', 1).and_raise_error(ArgumentError, %r{got Integer}) } + it { is_expected.to run.with_params('foo.example.com', true).and_raise_error(ArgumentError, %r{got Boolean}) } - it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, %r{is not a syntactically correct domain name}) } - it { is_expected.to run.with_params('invalid domain').and_raise_error(Puppet::ParseError, %r{is not a syntactically correct domain name}) } - it { is_expected.to run.with_params('-foo.example.com').and_raise_error(Puppet::ParseError, %r{is not a syntactically correct domain name}) } - it { is_expected.to run.with_params('www.example.2com').and_raise_error(Puppet::ParseError, %r{is not a syntactically correct domain name}) } - it { is_expected.to run.with_params('192.168.1.1').and_raise_error(Puppet::ParseError, %r{is not a syntactically correct domain name}) } + it { is_expected.to run.with_params('').and_raise_error(ArgumentError, %r{got ''}) } + it { is_expected.to run.with_params('invalid domain').and_raise_error(ArgumentError, %r{got 'invalid domain'}) } + it { is_expected.to run.with_params('-foo.example.com').and_raise_error(ArgumentError, %r{got '-foo\.example\.com'}) } end end diff --git a/spec/type_aliases/dns_zone_spec.rb b/spec/type_aliases/dns_zone_spec.rb new file mode 100644 index 000000000..b546a3666 --- /dev/null +++ b/spec/type_aliases/dns_zone_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Dns::Zone' do + describe 'accepts dns zones' do + [ + '.', + 'com.', + 'example.com.', + '10.10.10.10.10.', + 'xn--5ea.pf.', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + true, + false, + '', + 'iAmAString', + {}, + { 'key' => 'value' }, + { 1 => 2 }, + :undef, + 3, + 'www..com.', + '127.0.0.1', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/fqdn_spec.rb b/spec/type_aliases/fqdn_spec.rb index 09ed393bb..f7d526ee7 100644 --- a/spec/type_aliases/fqdn_spec.rb +++ b/spec/type_aliases/fqdn_spec.rb @@ -4,7 +4,12 @@ describe 'Stdlib::Fqdn' do describe 'valid handling' do - ['example', 'example.com', 'www.example.com'].each do |value| + [ + 'example', + 'example.com', + 'www.example.com', + '10.10.10.10.10', + ].each do |value| describe value.inspect do it { is_expected.to allow_value(value) } end diff --git a/spec/type_aliases/host_spec.rb b/spec/type_aliases/host_spec.rb index cfd23ee26..6cfd3d94b 100644 --- a/spec/type_aliases/host_spec.rb +++ b/spec/type_aliases/host_spec.rb @@ -4,8 +4,19 @@ describe 'Stdlib::Host' do describe 'valid handling' do - ['example', 'example.com', 'www.example.com', '2001:0db8:85a3:0000:0000:8a2e:0370:7334', 'fa76:8765:34ac:0823:ab76:eee9:0987:1111', '2001:0db8::1', '224.0.0.0', '255.255.255.255', - '0.0.0.0', '192.88.99.0'].each do |value| + [ + 'example', + 'example.com', + 'www.example.com', + '2001:0db8:85a3:0000:0000:8a2e:0370:7334', + 'fa76:8765:34ac:0823:ab76:eee9:0987:1111', + '2001:0db8::1', + '224.0.0.0', + '255.255.255.255', + '0.0.0.0', + '192.88.99.0', + '10.10.10.10.10', + ].each do |value| describe value.inspect do it { is_expected.to allow_value(value) } end diff --git a/types/dns/zone.pp b/types/dns/zone.pp new file mode 100644 index 000000000..bdd3220db --- /dev/null +++ b/types/dns/zone.pp @@ -0,0 +1,2 @@ +# @summary Validate a DNS zone name +type Stdlib::Dns::Zone = Pattern[/\A((([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)+|\.)\z/]