]> gitweb.fluxo.info Git - puppet-mailalias_core.git/commitdiff
Initial mailalias import from bc8e56000fcd585d2197e1ad9e6f741bec56c174
authorMelissa Stone <melissa@puppet.com>
Fri, 13 Apr 2018 20:32:32 +0000 (13:32 -0700)
committerMelissa Stone <melissa@puppet.com>
Mon, 16 Apr 2018 23:19:30 +0000 (16:19 -0700)
acceptance/tests/resource/mailalias/create.rb [new file with mode: 0644]
acceptance/tests/resource/mailalias/destroy.rb [new file with mode: 0644]
acceptance/tests/resource/mailalias/modify.rb [new file with mode: 0644]
acceptance/tests/resource/mailalias/query.rb [new file with mode: 0644]
lib/puppet/provider/mailalias/aliases.rb [new file with mode: 0644]
lib/puppet/type/mailalias.rb [new file with mode: 0644]
spec/fixtures/integration/provider/mailalias/aliases/test1 [new file with mode: 0644]
spec/integration/provider/mailalias/aliases_spec.rb [new file with mode: 0644]
spec/unit/type/mailalias_spec.rb [new file with mode: 0644]

diff --git a/acceptance/tests/resource/mailalias/create.rb b/acceptance/tests/resource/mailalias/create.rb
new file mode 100644 (file)
index 0000000..e1d40b9
--- /dev/null
@@ -0,0 +1,32 @@
+test_name "should create an email alias"
+
+confine :except, :platform => 'windows' 
+
+tag 'audit:low',
+    'audit:refactor',  # Use block style `test_name`
+    'audit:acceptance' # Could be done at the integration (or unit) layer though
+                       # actual changing of resources could irreparably damage a
+                       # host running this, or require special permissions.
+
+name = "pl#{rand(999999).to_i}"
+agents.each do |agent|
+  teardown do
+    #(teardown) restore the alias file
+    on(agent, "mv /tmp/aliases /etc/aliases", :acceptable_exit_codes => [0,1])
+  end
+
+  #------- SETUP -------#
+  step "(setup) backup alias file"
+  on(agent, "cp /etc/aliases /tmp/aliases", :acceptable_exit_codes => [0,1])
+
+  #------- TESTS -------#
+  step "create a mailalias with puppet"
+  args = ['ensure=present',
+          'recipient="foo,bar,baz"']
+  on(agent, puppet_resource('mailalias', name, args))
+
+  step "verify the alias exists"
+  on(agent, "cat /etc/aliases")  do |res|
+    assert_match(/#{name}:.*foo,bar,baz/, res.stdout, "mailalias not in aliases file")
+  end
+end  
diff --git a/acceptance/tests/resource/mailalias/destroy.rb b/acceptance/tests/resource/mailalias/destroy.rb
new file mode 100644 (file)
index 0000000..63bc3d0
--- /dev/null
@@ -0,0 +1,41 @@
+test_name "should delete an email alias"
+
+confine :except, :platform => 'windows'
+
+tag 'audit:low',
+    'audit:refactor',  # Use block style `test_name`
+    'audit:acceptance' # Could be done at the integration (or unit) layer though
+                       # actual changing of resources could irreparably damage a
+                       # host running this, or require special permissions.
+
+name = "pl#{rand(999999).to_i}"
+agents.each do |agent|
+  teardown do
+    #(teardown) restore the alias file
+    on(agent, "mv /tmp/aliases /etc/aliases", :acceptable_exit_codes => [0,1])
+  end
+
+  #------- SETUP -------#
+  step "(setup) backup alias file"
+  on(agent, "cp /etc/aliases /tmp/aliases", :acceptable_exit_codes => [0,1])
+
+  step "(setup) create a mailalias"
+  on(agent, "echo '#{name}: foo,bar,baz' >> /etc/aliases")
+
+  step "(setup) verify the alias exists"
+  on(agent, "cat /etc/aliases")  do |res|
+    assert_match(/#{name}:.*foo,bar,baz/, res.stdout, "mailalias not in aliases file")
+  end
+
+  #------- TESTS -------#
+  step "delete the aliases database with puppet"
+  args = ['ensure=absent',
+          'recipient="foo,bar,baz"']
+  on(agent, puppet_resource('mailalias', name, args))
+
+
+  step "verify the alias is absent"
+  on(agent, "cat /etc/aliases")  do |res|
+    assert_no_match(/#{name}:.*foo,bar,baz/, res.stdout, "mailalias was not removed from aliases file")
+  end
+end  
diff --git a/acceptance/tests/resource/mailalias/modify.rb b/acceptance/tests/resource/mailalias/modify.rb
new file mode 100644 (file)
index 0000000..832043b
--- /dev/null
@@ -0,0 +1,41 @@
+test_name "should modify an email alias"
+
+confine :except, :platform => 'windows'
+
+tag 'audit:low',
+    'audit:refactor',  # Use block style `test_name`
+    'audit:acceptance' # Could be done at the integration (or unit) layer though
+                       # actual changing of resources could irreparably damage a
+                       # host running this, or require special permissions.
+
+name = "pl#{rand(999999).to_i}"
+agents.each do |agent|
+  teardown do
+    #(teardown) restore the alias file
+    on(agent, "mv /tmp/aliases /etc/aliases", :acceptable_exit_codes => [0,1])
+  end
+
+  #------- SETUP -------#
+  step "(setup) backup alias file"
+  on(agent, "cp /etc/aliases /tmp/aliases", :acceptable_exit_codes => [0,1])
+
+  step "(setup) create a mailalias"
+  on(agent, "echo '#{name}: foo,bar,baz' >> /etc/aliases")
+
+  step "(setup) verify the alias exists"
+  on(agent, "cat /etc/aliases")  do |res|
+    assert_match(/#{name}:.*foo,bar,baz/, res.stdout, "mailalias not in aliases file")
+  end
+
+  #------- TESTS -------#
+  step "modify the aliases database with puppet"
+  args = ['ensure=present',
+          'recipient="foo,bar,baz,blarvitz"']
+  on(agent, puppet_resource('mailalias', name, args))
+
+
+  step "verify the updated alias is present"
+  on(agent, "cat /etc/aliases")  do |res|
+    assert_match(/#{name}:.*foo,bar,baz,blarvitz/, res.stdout, "updated mailalias not in aliases file")
+  end
+end
diff --git a/acceptance/tests/resource/mailalias/query.rb b/acceptance/tests/resource/mailalias/query.rb
new file mode 100644 (file)
index 0000000..40e495a
--- /dev/null
@@ -0,0 +1,35 @@
+test_name "should be able to find an exisitng email alias"
+
+confine :except, :platform => 'windows'
+
+tag 'audit:low',
+    'audit:refactor',  # Use block style `test_name`
+    'audit:acceptance' # Could be done at the integration (or unit) layer though
+                       # actual changing of resources could irreparably damage a
+                       # host running this, or require special permissions.
+
+name = "pl#{rand(999999).to_i}"
+agents.each do |agent|
+  teardown do
+    #(teardown) restore the alias file
+    on(agent, "mv /tmp/aliases /etc/aliases", :acceptable_exit_codes => [0,1])
+  end
+
+  #------- SETUP -------#
+  step "(setup) backup alias file"
+  on(agent, "cp /etc/aliases /tmp/aliases", :acceptable_exit_codes => [0,1])
+
+  step "(setup) create a mailalias"
+  on(agent, "echo '#{name}: foo,bar,baz' >> /etc/aliases")
+
+  step "(setup) verify the alias exists"
+  on(agent, "cat /etc/aliases")  do |res|
+    assert_match(/#{name}:.*foo,bar,baz/, res.stdout, "mailalias not in aliases file")
+  end
+
+  #------- TESTS -------#
+  step "query for the mail alias with puppet"
+  on(agent, puppet_resource('mailalias', name)) do
+    fail_test "didn't find the scheduled_task #{name}" unless stdout.include? 'present'
+  end
+end
diff --git a/lib/puppet/provider/mailalias/aliases.rb b/lib/puppet/provider/mailalias/aliases.rb
new file mode 100644 (file)
index 0000000..038d450
--- /dev/null
@@ -0,0 +1,50 @@
+require 'puppet/provider/parsedfile'
+
+Puppet::Type.type(:mailalias).provide(
+  :aliases,
+  :parent => Puppet::Provider::ParsedFile,
+  :default_target => "/etc/aliases",
+  :filetype => :flat
+) do
+  text_line :comment, :match => /^#/
+  text_line :blank, :match => /^\s*$/
+
+  record_line :aliases, :fields => %w{name recipient}, :separator => /\s*:\s*/, :block_eval => :instance do
+    def post_parse(record)
+      if record[:recipient]
+       record[:recipient] = record[:recipient].split(/\s*,\s*/).collect { |d| d.gsub(/^['"]|['"]$/, '') }
+      end
+      record
+    end
+
+    def process(line)
+      ret = {}
+      records = line.split(':',4)
+      ret[:name] = records[0].strip
+      if records.length == 4 and records[2].strip == 'include'
+       ret[:file] = records[3].strip
+      else
+       records = line.split(':',2)
+       ret[:recipient] = records[1].strip
+      end
+      ret
+    end
+
+    def to_line(record)
+      if record[:recipient]
+       dest = record[:recipient].collect do |d|
+         # Quote aliases that have non-alpha chars
+         if d =~ /[^-+\w@.]/
+           '"%s"' % d
+         else
+           d
+         end
+       end.join(",")
+       "#{record[:name]}: #{dest}"
+      elsif record[:file]
+       "#{record[:name]}: :include: #{record[:file]}"
+      end
+    end
+  end
+end
+
diff --git a/lib/puppet/type/mailalias.rb b/lib/puppet/type/mailalias.rb
new file mode 100644 (file)
index 0000000..b5df7b8
--- /dev/null
@@ -0,0 +1,46 @@
+module Puppet
+  Type.newtype(:mailalias) do
+    @doc = "Creates an email alias in the local alias database."
+
+    ensurable
+
+    newparam(:name, :namevar => true) do
+      desc "The alias name."
+    end
+
+    newproperty(:recipient, :array_matching => :all) do
+      desc "Where email should be sent.  Multiple values
+        should be specified as an array.  The file and the
+        recipient entries are mutually exclusive."
+    end
+
+    newproperty(:file) do
+      desc "A file containing the alias's contents.  The file and the
+        recipient entries are mutually exclusive."
+
+      validate do |value|
+       unless Puppet::Util.absolute_path?(value)
+         fail Puppet::Error, _("File paths must be fully qualified, not '%{value}'") % { value: value }
+       end
+      end
+    end
+
+    newproperty(:target) do
+      desc "The file in which to store the aliases.  Only used by
+        those providers that write to disk."
+
+      defaultto { if @resource.class.defaultprovider.ancestors.include?(Puppet::Provider::ParsedFile)
+          @resource.class.defaultprovider.default_target
+        else
+          nil
+        end
+      }
+    end
+
+    validate do
+      if self[:recipient] && self[:file]
+       self.fail _("You cannot specify both a recipient and a file")
+      end
+    end
+  end
+end
diff --git a/spec/fixtures/integration/provider/mailalias/aliases/test1 b/spec/fixtures/integration/provider/mailalias/aliases/test1
new file mode 100644 (file)
index 0000000..a69be8a
--- /dev/null
@@ -0,0 +1,31 @@
+# Basic system aliases -- these MUST be present
+MAILER-DAEMON:  postmaster
+postmaster: root
+
+# General redirections for pseudo accounts
+bin:        root
+daemon:     root
+named:      root
+nobody:     root
+uucp:       root
+www:        root
+ftp-bugs:   root
+postfix:    root
+
+# Put your local aliases here.
+
+# Well-known aliases
+manager:    root
+dumper:     root
+operator:   root
+abuse:      postmaster
+
+# trap decode to catch security attacks
+decode:     root
+
+# Other tests
+anothertest: "|/path/to/rt-mailgate --queue 'another test' --action correspond --url http://my.com/"
+test: "|/path/to/rt-mailgate --queue 'test' --action correspond --url http://my.com/"
+
+# Included file
+incfile: :include: /tmp/somefile
diff --git a/spec/integration/provider/mailalias/aliases_spec.rb b/spec/integration/provider/mailalias/aliases_spec.rb
new file mode 100644 (file)
index 0000000..64cef1c
--- /dev/null
@@ -0,0 +1,10 @@
+#! /usr/bin/env ruby
+require 'spec_helper'
+require 'shared_behaviours/all_parsedfile_providers'
+
+provider_class = Puppet::Type.type(:mailalias).provider(:aliases)
+
+describe provider_class do
+  # #1560, in which we corrupt the format of complex mail aliases.
+  it_should_behave_like "all parsedfile providers", provider_class
+end
diff --git a/spec/unit/type/mailalias_spec.rb b/spec/unit/type/mailalias_spec.rb
new file mode 100644 (file)
index 0000000..eb701c6
--- /dev/null
@@ -0,0 +1,49 @@
+#! /usr/bin/env ruby
+require 'spec_helper'
+
+describe Puppet::Type.type(:mailalias) do
+  include PuppetSpec::Files
+
+  let :tmpfile_path do tmpfile('afile') end
+  let :target do tmpfile('mailalias') end
+  let :recipient_resource do
+    described_class.new(:name => "luke", :recipient => "yay", :target => target)
+  end
+
+  let :file_resource do
+    described_class.new(:name => "lukefile", :file => tmpfile_path, :target => target)
+  end
+
+  it "should be initially absent as a recipient" do
+    expect(recipient_resource.retrieve_resource[:recipient]).to eq(:absent)
+  end
+
+  it "should be initially absent as an included file" do
+    expect(file_resource.retrieve_resource[:file]).to eq(:absent)
+  end
+
+  it "should try and set the recipient when it does the sync" do
+    expect(recipient_resource.retrieve_resource[:recipient]).to eq(:absent)
+    recipient_resource.property(:recipient).expects(:set).with(["yay"])
+    recipient_resource.property(:recipient).sync
+  end
+
+  it "should try and set the included file when it does the sync" do
+    expect(file_resource.retrieve_resource[:file]).to eq(:absent)
+    file_resource.property(:file).expects(:set).with(tmpfile_path)
+    file_resource.property(:file).sync
+  end
+
+  it "should fail when file is not an absolute path" do
+    expect {
+      Puppet::Type.type(:mailalias).new(:name => 'x', :file => 'afile')
+    }.to raise_error Puppet::Error, /File paths must be fully qualified/
+  end
+
+  it "should fail when both file and recipient are specified" do
+    expect {
+      Puppet::Type.type(:mailalias).new(:name => 'x', :file => tmpfile_path,
+                                       :recipient => 'foo@example.com')
+    }.to raise_error Puppet::Error, /cannot specify both a recipient and a file/
+  end
+end