diff options
-rw-r--r-- | lib/puppet/parser/functions/is_email_address.rb | 21 | ||||
-rw-r--r-- | lib/puppet/parser/functions/validate_email_address.rb | 31 | ||||
-rw-r--r-- | lib/puppet/type/file_line.rb | 9 | ||||
-rwxr-xr-x | spec/functions/is_email_address_spec.rb | 14 | ||||
-rw-r--r-- | spec/functions/validate_email_address_spec.rb | 23 | ||||
-rwxr-xr-x | spec/unit/puppet/provider/file_line/ruby_spec.rb | 4 | ||||
-rwxr-xr-x | spec/unit/puppet/type/file_line_spec.rb | 7 |
7 files changed, 103 insertions, 6 deletions
diff --git a/lib/puppet/parser/functions/is_email_address.rb b/lib/puppet/parser/functions/is_email_address.rb new file mode 100644 index 0000000..ab8d075 --- /dev/null +++ b/lib/puppet/parser/functions/is_email_address.rb @@ -0,0 +1,21 @@ +# +# is_email_address.rb +# + +module Puppet::Parser::Functions + newfunction(:is_email_address, type: :rvalue, doc: <<-EOS +Returns true if the string passed to this function is a valid email address. + EOS + ) do |arguments| + if arguments.size != 1 + raise(Puppet::ParseError, 'is_email_address(): Wrong number of arguments '\ + "given #{arguments.size} for 1") + end + + # Taken from http://emailregex.com/ (simpler regex) + valid_email_regex = %r{\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z} + return (arguments[0] =~ valid_email_regex) == 0 + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/validate_email_address.rb b/lib/puppet/parser/functions/validate_email_address.rb new file mode 100644 index 0000000..63f59a7 --- /dev/null +++ b/lib/puppet/parser/functions/validate_email_address.rb @@ -0,0 +1,31 @@ +module Puppet::Parser::Functions + newfunction(:validate_email_address, doc: <<-ENDHEREDOC + Validate that all values passed are valid email addresses. + Fail compilation if any value fails this check. + The following values will pass: + $my_email = "waldo@gmail.com" + validate_email_address($my_email) + validate_email_address("bob@gmail.com", "alice@gmail.com", $my_email) + + The following values will fail, causing compilation to abort: + $some_array = [ 'bad_email@/d/efdf.com' ] + validate_email_address($some_array) + ENDHEREDOC + ) do |args| + rescuable_exceptions = [ArgumentError] + + if args.empty? + raise Puppet::ParseError, "validate_email_address(): 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 valid email address" unless function_is_email_address([arg]) + rescue *rescuable_exceptions + raise Puppet::ParseError, "#{arg.inspect} is not a valid email address" + end + end + end +end diff --git a/lib/puppet/type/file_line.rb b/lib/puppet/type/file_line.rb index 77d3be2..f2c6937 100644 --- a/lib/puppet/type/file_line.rb +++ b/lib/puppet/type/file_line.rb @@ -111,8 +111,13 @@ Puppet::Type.newtype(:file_line) do end validate do - unless self[:line] and self[:path] - raise(Puppet::Error, "Both line and path are required attributes") + unless self[:line] + unless (self[:ensure].to_s == 'absent') and (self[:match_for_absence].to_s == 'true') and self[:match] + raise(Puppet::Error, "line is a required attribute") + end + end + unless self[:path] + raise(Puppet::Error, "path is a required attribute") end end end diff --git a/spec/functions/is_email_address_spec.rb b/spec/functions/is_email_address_spec.rb new file mode 100755 index 0000000..8b7b358 --- /dev/null +++ b/spec/functions/is_email_address_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe 'is_email_address' 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) } + it { is_expected.to run.with_params([], []).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('bob@gmail.com').and_return(true) } + it { is_expected.to run.with_params('alice+puppetlabs.com@gmail.com').and_return(true) } + it { is_expected.to run.with_params('peter.parker@gmail.com').and_return(true) } + it { is_expected.to run.with_params('1.2.3@domain').and_return(false) } + it { is_expected.to run.with_params('1.2.3.4.5@').and_return(false) } + it { is_expected.to run.with_params({}).and_return(false) } + it { is_expected.to run.with_params([]).and_return(false) } +end diff --git a/spec/functions/validate_email_address_spec.rb b/spec/functions/validate_email_address_spec.rb new file mode 100644 index 0000000..7628383 --- /dev/null +++ b/spec/functions/validate_email_address_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe 'validate_email_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('bob@gmail.com') } + it { is_expected.to run.with_params('alice+puppetlabs.com@gmail.com') } + 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 email/) } + it { is_expected.to run.with_params('bob@gmail.com', {}).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('bob@gmail.com', true).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('bob@gmail.com', 'one').and_raise_error(Puppet::ParseError, /is not a valid email/) } + end +end diff --git a/spec/unit/puppet/provider/file_line/ruby_spec.rb b/spec/unit/puppet/provider/file_line/ruby_spec.rb index 23e649c..fdeaf1a 100755 --- a/spec/unit/puppet/provider/file_line/ruby_spec.rb +++ b/spec/unit/puppet/provider/file_line/ruby_spec.rb @@ -398,7 +398,7 @@ describe provider_class do expect(File.read(@tmpfile)).to eql("foo1\nfoo2\n") end - it 'should ignore the match if match_for_absense is not specified' do + it 'should ignore the match if match_for_absence is not specified' do @resource = Puppet::Type::File_line.new( { :name => 'foo', @@ -416,7 +416,7 @@ describe provider_class do expect(File.read(@tmpfile)).to eql("foo1\nfoo\n") end - it 'should ignore the match if match_for_absense is false' do + it 'should ignore the match if match_for_absence is false' do @resource = Puppet::Type::File_line.new( { :name => 'foo', diff --git a/spec/unit/puppet/type/file_line_spec.rb b/spec/unit/puppet/type/file_line_spec.rb index f1430f2..48e2670 100755 --- a/spec/unit/puppet/type/file_line_spec.rb +++ b/spec/unit/puppet/type/file_line_spec.rb @@ -41,10 +41,13 @@ describe Puppet::Type.type(:file_line) do expect { file_line[:path] = 'file' }.to raise_error(Puppet::Error, /File paths must be fully qualified/) end it 'should require that a line is specified' do - expect { Puppet::Type.type(:file_line).new(:name => 'foo', :path => '/tmp/file') }.to raise_error(Puppet::Error, /Both line and path are required attributes/) + expect { Puppet::Type.type(:file_line).new(:name => 'foo', :path => '/tmp/file') }.to raise_error(Puppet::Error, /line is a required attribute/) + end + it 'should not require that a line is specified when matching for absence' do + expect { Puppet::Type.type(:file_line).new(:name => 'foo', :path => '/tmp/file', :ensure => :absent, :match_for_absence => :true, :match => 'match') }.not_to raise_error end it 'should require that a file is specified' do - expect { Puppet::Type.type(:file_line).new(:name => 'foo', :line => 'path') }.to raise_error(Puppet::Error, /Both line and path are required attributes/) + expect { Puppet::Type.type(:file_line).new(:name => 'foo', :line => 'path') }.to raise_error(Puppet::Error, /path is a required attribute/) end it 'should default to ensure => present' do expect(file_line[:ensure]).to eq :present |