From 5dcec26308dd79a1db9f3694c8567f8e88b54be2 Mon Sep 17 00:00:00 2001
From: "James E. Blair" <jeblair@hp.com>
Date: Thu, 10 May 2012 19:19:32 +0000
Subject: [PATCH] Add initial mailman config.

Change-Id: I82cda9eb456c1ce3690eab8f558420c8a696ee25
---
 manifests/site.pp                             |  19 +--
 modules/exim/manifests/init.pp                |   4 +-
 .../exim4.conf => templates/exim4.conf.erb}   |  91 +++++++++++++-
 modules/mailman/files/apache.conf             |  73 +++++++++++
 modules/mailman/manifests/init.pp             |  44 +++++++
 modules/mailman/templates/mm_cfg.py.erb       | 114 ++++++++++++++++++
 6 files changed, 335 insertions(+), 10 deletions(-)
 rename modules/exim/{files/exim4.conf => templates/exim4.conf.erb} (91%)
 create mode 100644 modules/mailman/files/apache.conf
 create mode 100644 modules/mailman/manifests/init.pp
 create mode 100644 modules/mailman/templates/mm_cfg.py.erb

diff --git a/manifests/site.pp b/manifests/site.pp
index 07c5338c7b..596ddf6f63 100644
--- a/manifests/site.pp
+++ b/manifests/site.pp
@@ -229,13 +229,18 @@ node "lists.openstack.org" {
     iptables_public_tcp_ports => [25, 80, 465]
   }
 
-  # class { 'exim':
-  #   sysadmin => ['corvus@inaugust.com',
-  #                'mordred@inaugust.com',
-  #                'andrew@linuxjedi.co.uk',
-  #                'devananda.vdv@gmail.com',
-  # 		 'duncan@dreamhost.com']
-  # }
+  class { 'exim':
+    sysadmin => ['corvus@inaugust.com',
+                 'mordred@inaugust.com',
+                 'andrew@linuxjedi.co.uk',
+                 'devananda.vdv@gmail.com',
+  		 'duncan@dreamhost.com'],
+    mailman_domains => ['lists.openstack.org'],
+  }
+
+  class { 'mailman':
+    mailman_host => 'lists.openstack.org'
+  }
 
   realize (
     User::Virtual::Localuser["oubiwann"],
diff --git a/modules/exim/manifests/init.pp b/modules/exim/manifests/init.pp
index dc2803a548..f5f11a53a7 100644
--- a/modules/exim/manifests/init.pp
+++ b/modules/exim/manifests/init.pp
@@ -1,4 +1,4 @@
-class exim($sysadmin=[]) {
+class exim($sysadmin=[], $mailman_domains=[]) {
   package { 'exim4-base':
     ensure => present;
   }
@@ -21,7 +21,7 @@ class exim($sysadmin=[]) {
     group => 'root',
     mode => 444,
     ensure => 'present',
-    source => 'puppet:///modules/exim/exim4.conf',
+    content => template("exim/exim4.conf.erb"),
     replace => 'true',
   }
 
diff --git a/modules/exim/files/exim4.conf b/modules/exim/templates/exim4.conf.erb
similarity index 91%
rename from modules/exim/files/exim4.conf
rename to modules/exim/templates/exim4.conf.erb
index 0c3d51b000..edf7b2e266 100644
--- a/modules/exim/files/exim4.conf
+++ b/modules/exim/templates/exim4.conf.erb
@@ -288,7 +288,33 @@ timeout_frozen_after = 7d
 
 # split_spool_directory = true
 
-
+<% if mailman_domains.length > 0 -%>
+# Home dir for your Mailman installation -- aka Mailman's prefix
+# directory.
+MM_HOME=/var/lib/mailman
+#
+# User and group for Mailman, should match your --with-mail-gid
+# switch to Mailman's configure script.
+# Value is normally "mailman"
+MM_UID=list
+MM_GID=list
+#
+# Domains that your lists are in - colon separated list
+# you may wish to add these into local_domains as well
+domainlist mm_domains=<%= mailman_domains.join(":") %>
+#
+# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# These values are derived from the ones above and should not need
+# editing unless you have munged your mailman installation
+#
+# The path of the Mailman mail wrapper script
+MM_WRAP=MM_HOME/mail/mailman
+#
+# The path of the list config file (used as a required file when
+# verifying list addresses)
+MM_LISTCHK=MM_HOME/lists/${lc::$local_part}/config.pck
+<% end -%>
 
 ######################################################################
 #                       ACL CONFIGURATION                            #
@@ -484,6 +510,40 @@ acl_check_data:
 
 begin routers
 
+<% if mailman_domains.length > 0 -%>
+# Pick up on messages from our local mailman and route them via our
+# special VERP-enabled transport
+#
+mailman_verp_router:
+driver = dnslookup
+# we only consider messages sent in through loopback
+condition = ${if or{{eq{$sender_host_address}{127.0.0.1}} \
+                    {eq{$sender_host_address}{::1}}}{yes}{no}}
+# we do not do this for traffic going to the local machine
+domains = !+local_domains:!+mm_domains
+ignore_target_hosts = <; 0.0.0.0; \
+                         64.94.110.11; \
+                         127.0.0.0/8; \
+                         ::1/128;fe80::/10;fe \
+                         c0::/10;ff00::/8
+# only the un-VERPed bounce addresses are handled
+senders = "*-bounces@*"
+transport = mailman_verp_smtp
+
+mailman_router:
+  driver            = accept
+  domains           = +mm_domains
+  require_files     = MM_LISTCHK
+  local_part_suffix_optional
+  local_part_suffix = -admin     : \
+         -bounces   : -bounces+* : \
+         -confirm   : -confirm+* : \
+         -join      : -leave     : \
+         -owner     : -request   : \
+         -subscribe : -unsubscribe
+  transport         = mailman_transport
+<% end -%>
+
 # This router routes to remote hosts over SMTP by explicit IP address,
 # when an email address is given in "domain literal" form, for example,
 # <user@[192.168.35.64]>. The RFCs require this facility. However, it is
@@ -636,6 +696,35 @@ address_file:
 address_reply:
   driver = autoreply
 
+<% if mailman_domains.length > 0 -%>
+mailman_transport:
+  driver  = pipe
+  command = MM_WRAP \
+          '${if def:local_part_suffix \
+                {${sg{$local_part_suffix}{-(\\w+)(\\+.*)?}{\$1}}} \
+                {post}}' \
+          $local_part
+  current_directory = MM_HOME
+  home_directory    = MM_HOME
+  user              = MM_UID
+  group             = MM_GID
+
+# Mailman VERP envelope sender address formatting.  This seems not to use
+# quoted-printable encoding of the address, but instead just replaces the
+# '@' in the recipient address with '='.
+#
+mailman_verp_smtp:
+  driver = smtp
+# put recipient address into return_path
+  return_path = \
+    ${local_part:$return_path}+$local_part=$domain@${domain:$return_path}
+# must restrict to one recipient at a time
+  max_rcpt = 1
+# Errors-To: may carry old return_path
+  headers_remove = Errors-To
+  headers_add = Errors-To: ${return_path}
+<% end -%>
+
 ######################################################################
 #                      RETRY CONFIGURATION                           #
 ######################################################################
diff --git a/modules/mailman/files/apache.conf b/modules/mailman/files/apache.conf
new file mode 100644
index 0000000000..a7f421cc5f
--- /dev/null
+++ b/modules/mailman/files/apache.conf
@@ -0,0 +1,73 @@
+# Sample configuration for Debian mailman with Apache
+
+# We can find mailman here:
+ScriptAlias /cgi-bin/mailman/ /usr/lib/cgi-bin/mailman/
+# And the public archives:
+Alias /pipermail/ /var/lib/mailman/archives/public/
+# Logos:
+Alias /images/mailman/ /usr/share/images/mailman/
+
+# Use this if you don't want the "cgi-bin" component in your URL:
+# In case you want to access mailman through a shorter URL you should enable
+# this:
+#ScriptAlias /mailman/ /usr/lib/cgi-bin/mailman/
+# In this case you need to set the DEFAULT_URL_PATTERN in
+# /etc/mailman/mm_cfg.py to http://%s/mailman/ for the cookie
+# authentication code to work.  Note that you need to change the base
+# URL for all the already-created lists as well.
+
+<Directory /usr/lib/cgi-bin/mailman/>
+    AllowOverride None
+    Options ExecCGI
+    AddHandler cgi-script .cgi
+    Order allow,deny
+    Allow from all
+</Directory>
+<Directory /var/lib/mailman/archives/public/>
+    Options FollowSymlinks
+    AllowOverride None
+    Order allow,deny
+    Allow from all
+</Directory>
+<Directory /usr/share/images/mailman/>
+    AllowOverride None
+    Order allow,deny
+    Allow from all
+</Directory>
+
+
+## The following describes how to configure mailman on
+## a dedicated virtual host, courtesy Marco d'Itri.
+
+# Add these lines in /etc/mailman/mm_cfg.py:
+#DEFAULT_EMAIL_HOST = 'lists.example.net'
+#DEFAULT_URL_HOST = 'lists.example.net'
+#DEFAULT_URL_PATTERN = 'http://%s/'
+
+#<VirtualHost *>
+#ServerName lists.example.net
+#DocumentRoot /var/www/lists
+#ErrorLog /var/log/apache2/lists-error.log
+#CustomLog /var/log/apache2/lists-access.log combined
+#
+#<Directory /var/lib/mailman/archives/>
+#    Options FollowSymLinks
+#    AllowOverride None
+#</Directory>
+#
+#Alias /pipermail/ /var/lib/mailman/archives/public/
+#Alias /images/mailman/ /usr/share/images/mailman/
+#ScriptAlias /admin /usr/lib/cgi-bin/mailman/admin
+#ScriptAlias /admindb /usr/lib/cgi-bin/mailman/admindb
+#ScriptAlias /confirm /usr/lib/cgi-bin/mailman/confirm
+#ScriptAlias /create /usr/lib/cgi-bin/mailman/create
+#ScriptAlias /edithtml /usr/lib/cgi-bin/mailman/edithtml
+#ScriptAlias /listinfo /usr/lib/cgi-bin/mailman/listinfo
+#ScriptAlias /options /usr/lib/cgi-bin/mailman/options
+#ScriptAlias /private /usr/lib/cgi-bin/mailman/private
+#ScriptAlias /rmlist /usr/lib/cgi-bin/mailman/rmlist
+#ScriptAlias /roster /usr/lib/cgi-bin/mailman/roster
+#ScriptAlias /subscribe /usr/lib/cgi-bin/mailman/subscribe
+#ScriptAlias /mailman/ /usr/lib/cgi-bin/mailman/
+#</VirtualHost>
+
diff --git a/modules/mailman/manifests/init.pp b/modules/mailman/manifests/init.pp
new file mode 100644
index 0000000000..42b161d7f9
--- /dev/null
+++ b/modules/mailman/manifests/init.pp
@@ -0,0 +1,44 @@
+class mailman($mailman_host='') {
+
+  package { "mailman":
+    ensure => installed,
+  }
+
+  package { "apache2":
+    ensure => installed,
+  }
+
+  file { '/etc/mailman/mm_cfg.py':
+    owner => 'root',
+    group => 'root',
+    mode => 444,
+    ensure => 'present',
+    content => template('mailman/mm_cfg.py.erb'),
+    replace => 'true',
+    require => Package["mailman"]
+  }
+
+  file { '/etc/mailman/apache.conf':
+    owner => 'root',
+    group => 'root',
+    mode => 444,
+    ensure => 'present',
+    source => 'puppet:///modules/mailman/apache.conf',
+    replace => 'true',
+    require => Package["mailman"]
+  }
+
+  service { 'mailman':
+    ensure          => running,
+    hasrestart      => true,
+    subscribe       => File['/etc/mailman/mm_cfg.py'],
+    require         => Package["mailman"]
+  }
+
+  service { 'apache2':
+    ensure          => running,
+    hasrestart      => true,
+    subscribe       => File['/etc/mailman/apache.conf'],
+    require         => Package["apache2"]
+  }
+}
diff --git a/modules/mailman/templates/mm_cfg.py.erb b/modules/mailman/templates/mm_cfg.py.erb
new file mode 100644
index 0000000000..67efe63a0b
--- /dev/null
+++ b/modules/mailman/templates/mm_cfg.py.erb
@@ -0,0 +1,114 @@
+# -*- python -*-
+
+# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software 
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 USA
+
+
+"""This is the module which takes your site-specific settings.
+
+From a raw distribution it should be copied to mm_cfg.py.  If you
+already have an mm_cfg.py, be careful to add in only the new settings
+you want.  The complete set of distributed defaults, with annotation,
+are in ./Defaults.  In mm_cfg, override only those you want to
+change, after the
+
+  from Defaults import *
+
+line (see below).
+
+Note that these are just default settings - many can be overridden via the
+admin and user interfaces on a per-list or per-user basis.
+
+Note also that some of the settings are resolved against the active list
+setting by using the value as a format string against the
+list-instance-object's dictionary - see the distributed value of
+DEFAULT_MSG_FOOTER for an example."""
+
+
+#######################################################
+#    Here's where we get the distributed defaults.    #
+
+from Defaults import *
+
+##############################################################
+# Put YOUR site-specific configuration below, in mm_cfg.py . #
+# See Defaults.py for explanations of the values.            #
+
+#-------------------------------------------------------------
+# The name of the list Mailman uses to send password reminders
+# and similar. Don't change if you want mailman-owner to be
+# a valid local part.
+MAILMAN_SITE_LIST = 'mailman'
+
+#-------------------------------------------------------------
+# If you change these, you have to configure your http server
+# accordingly (Alias and ScriptAlias directives in most httpds)
+DEFAULT_URL_PATTERN = 'http://%s/cgi-bin/mailman/'
+PRIVATE_ARCHIVE_URL = '/cgi-bin/mailman/private'
+IMAGE_LOGOS         = '/images/mailman/'
+
+#-------------------------------------------------------------
+# Default domain for email addresses of newly created MLs
+DEFAULT_EMAIL_HOST = '<%= mailman_host %>'
+#-------------------------------------------------------------
+# Default host for web interface of newly created MLs
+DEFAULT_URL_HOST   = '<%= mailman_host %>'
+#-------------------------------------------------------------
+# Required when setting any of its arguments.
+add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST)
+
+#-------------------------------------------------------------
+# The default language for this server.
+DEFAULT_SERVER_LANGUAGE = 'en'
+
+#-------------------------------------------------------------
+# Iirc this was used in pre 2.1, leave it for now
+USE_ENVELOPE_SENDER    = 0              # Still used?
+
+#-------------------------------------------------------------
+# Unset send_reminders on newly created lists
+DEFAULT_SEND_REMINDERS = 0
+
+#-------------------------------------------------------------
+# Uncomment this if you configured your MTA such that it
+# automatically recognizes newly created lists.
+# (see /usr/share/doc/mailman/README.Exim4.Debian or
+# /usr/share/mailman/postfix-to-mailman.py)
+MTA=None   # Misnomer, suppresses alias output on newlist
+
+#-------------------------------------------------------------
+# Uncomment if you use Postfix virtual domains (but not
+# postfix-to-mailman.py), but be sure to see
+# /usr/share/doc/mailman/README.Debian first.
+# MTA='Postfix'
+
+#-------------------------------------------------------------
+# Uncomment if you want to filter mail with SpamAssassin. For
+# more information please visit this website:
+# http://www.jamesh.id.au/articles/mailman-spamassassin/
+# GLOBAL_PIPELINE.insert(1, 'SpamAssassin')
+
+# Note - if you're looking for something that is imported from mm_cfg, but you
+# didn't find it above, it's probably in /usr/lib/mailman/Mailman/Defaults.py.
+
+# Enable VERP, but let Exim create the VERP addresses since it's
+# more efficient.  --jeblair
+
+VERP_PASSWORD_REMINDERS      = 1
+VERP_PERSONALIZED_DELIVERIES = 1
+VERP_CONFIRMATIONS           = 1
+VERP_DELIVERY_INTERVAL       = 0