repositories:
firewall: "git://github.com/puppetlabs/puppetlabs-firewall.git"
stdlib: "git://github.com/puppetlabs/puppetlabs-stdlib.git"
+ postgresql: "git://github.com/puppetlabs/puppetlabs-postgresql.git"
symlinks:
mailman3: "#{source_dir}"
$core_manage_firewall = $mailman3::params::core_manage_firewall,
$core_override_options = {},
$core_override_allowed_hosts = {},
+ $db_tag = $mailman3::params::core_db_tag,
) inherits mailman3::params {
# Make sure parameters are properly formatted
validate_bool($install_core)
+ validate_string($db_tag)
validate_string($core_version)
validate_bool($core_manage_database)
validate_bool($core_manage_firewall)
core_manage_firewall => $core_manage_firewall,
core_options => $core_options,
core_allowed_hosts => $core_allowed_hosts,
+ db_tag => $db_tag,
}
Anchor['mailman3::core::begin'] ->
# Copyright 2015 Josh Farwell, unless otherwise noted.
#
class mailman3::core::config (
+ $core_allowed_hosts,
$core_manage_database,
$core_manage_firewall,
$core_options,
- $core_allowed_hosts,
+ $db_tag,
) {
+ validate_string($db_tag)
validate_bool($core_manage_database)
validate_bool($core_manage_firewall)
validate_hash($core_options)
core_options => $core_options,
}
}
+
+ if ($core_manage_database) {
+ class { 'mailman3::core::config::db':
+ core_manage_database => $core_manage_database,
+ core_options => $core_options,
+ db_tag => $db_tag,
+ }
+ }
+
}
--- /dev/null
+# == Class: mailman3::core::config::db
+#
+# Full description of class mailman3 here.
+#
+# === Parameters
+#
+# Document parameters here.
+#
+# [*sample_parameter*]
+# Explanation of what this parameter affects and what it defaults to.
+# e.g. "Specify one or more upstream ntp servers as an array."
+#
+# === Variables
+#
+# Here you should define a list of variables that this module would require.
+#
+# [*sample_variable*]
+# Explanation of how this variable affects the function of this class and if
+# it has a default. e.g. "The parameter enc_ntp_servers must be set by the
+# External Node Classifier as a comma separated list of hostnames." (Note,
+# global variables should be avoided in favor of class parameters as
+# of Puppet 2.6.)
+#
+# === Examples
+#
+# class { 'mailman3':
+# servers => [ 'pool.ntp.org', 'ntp.local.company.com' ],
+# }
+#
+# === Authors
+#
+# Josh Farwell <jfarwell@linuxfoundation.org>
+#
+# === Copyright
+#
+# Copyright 2015 Josh Farwell, unless otherwise noted.
+#
+class mailman3::core::config::db (
+ $core_manage_database,
+ $core_options,
+ $db_tag,
+) {
+ validate_string($db_tag)
+ validate_bool($core_manage_database)
+ validate_hash($core_options)
+
+ if has_key($core_options, 'database') {
+
+ validate_hash($core_options['database'])
+
+ # string manipulation to parse our options from SQLAlchemy URL
+ unless has_key($core_options['database'], 'url') {
+ fail 'Database hash has no url'
+ }
+
+ validate_re($core_options['database']['url'], '^*://*')
+
+ $db_url_arr = split($core_options['database']['url'], '://')
+ $db_type = $db_url_arr[0]
+
+ case $db_type {
+ /^sqlite/: {
+ $db_path = $db_url_arr[1]
+
+ class { 'mailman3::db::sqlite':
+ manage_database => $core_manage_database,
+ db_path => $db_path
+ }
+ }
+
+ /^mysql/: {
+ fail 'MySQL is not officially supported by Mailman 3 at this time.'
+
+ #$db_options_arr = split($db_url_arr[1], '[:@/]')
+
+ #$db_options = {
+ #'username' => $db_options_arr[0],
+ #'password' => $db_options_arr[1],
+ #'hostname' => $db_options_arr[2],
+ #'database' => $db_options_arr[3],
+ #}
+
+ #class { '::mailman3::db::mysql':
+ #db_tag => $db_tag,
+ #manage_database => $core_manage_database,
+ #options => $core_options,
+ #}
+ }
+ /^postgres/: {
+ $db_database_arr = split($db_url_arr[1], '/')
+ $db_options_arr = split($db_url_arr[1], '[:@/]')
+
+ $db_options = {
+ 'username' => $db_options_arr[0],
+ 'password' => $db_options_arr[1],
+ 'hostname' => $db_options_arr[2],
+ 'database' => $db_options_arr[3],
+ }
+
+ class { 'mailman3::db::postgres':
+ db_tag => $db_tag,
+ manage_database => $core_manage_database,
+ db_options => $db_options,
+ }
+ }
+ default: { }
+ }
+ }
+}
--- /dev/null
+# == Class: mailman3
+#
+# Full description of class mailman3 here.
+#
+# === Parameters
+#
+# Document parameters here.
+#
+# [*sample_parameter*]
+# Explanation of what this parameter affects and what it defaults to.
+# e.g. "Specify one or more upstream ntp servers as an array."
+#
+# === Variables
+#
+# Here you should define a list of variables that this module would require.
+#
+# [*sample_variable*]
+# Explanation of how this variable affects the function of this class and if
+# it has a default. e.g. "The parameter enc_ntp_servers must be set by the
+# External Node Classifier as a comma separated list of hostnames." (Note,
+# global variables should be avoided in favor of class parameters as
+# of Puppet 2.6.)
+#
+# === Examples
+#
+# class { 'mailman3':
+# servers => [ 'pool.ntp.org', 'ntp.local.company.com' ],
+# }
+#
+# === Authors
+#
+# Josh Farwell <jfarwell@linuxfoundation.org>
+#
+# === Copyright
+#
+# Copyright 2015 Josh Farwell, unless otherwise noted.
+#
+class mailman3::db::postgres (
+ $db_options,
+ $db_tag,
+ $manage_database,
+) {
+ validate_string($db_tag)
+ validate_bool($manage_database)
+ validate_hash($db_options)
+
+ if ($manage_database) {
+
+ validate_string($db_options['username'])
+ validate_string($db_options['password'])
+ validate_string($db_options['hostname'])
+ validate_string($db_options['database'])
+
+ $username = $db_options['username']
+ $password = $db_options['password']
+ $hostname = $db_options['hostname']
+ $database = $db_options['database']
+
+ # export postgresql database configuration
+
+ @@postgresql::server::db { "$::{database}_$::{fdqn}":
+ dbname => $database,
+ grant => 'ALL',
+ owner => $username,
+ password => $password,
+ tag => $db_tag,
+ user => $username,
+ }
+ }
+}
--- /dev/null
+# == Class: mailman3::db::sqlite
+#
+# Full description of class mailman3 here.
+#
+# === Parameters
+#
+# Document parameters here.
+#
+# [*sample_parameter*]
+# Explanation of what this parameter affects and what it defaults to.
+# e.g. "Specify one or more upstream ntp servers as an array."
+#
+# === Variables
+#
+# Here you should define a list of variables that this module would require.
+#
+# [*sample_variable*]
+# Explanation of how this variable affects the function of this class and if
+# it has a default. e.g. "The parameter enc_ntp_servers must be set by the
+# External Node Classifier as a comma separated list of hostnames." (Note,
+# global variables should be avoided in favor of class parameters as
+# of Puppet 2.6.)
+#
+# === Examples
+#
+# class { 'mailman3':
+# servers => [ 'pool.ntp.org', 'ntp.local.company.com' ],
+# }
+#
+# === Authors
+#
+# Josh Farwell <jfarwell@linuxfoundation.org>
+#
+# === Copyright
+#
+# Copyright 2015 Josh Farwell, unless otherwise noted.
+#
+class mailman3::db::sqlite (
+ $db_path,
+ $manage_database,
+) {
+ validate_bool($manage_database)
+
+ if ($manage_database) {
+ # TODO: extract containing directory from sqlite db path and ensure
+ # that it exists and the mailman3 user can read and write there.
+ validate_string($db_path)
+ }
+}
$rest_admin_pass = 'restpass'
# Mailman Core values
+ $core_db_tag = 'mailman3-core'
$core_layout = 'fhs'
$core_bin_dir = '/usr/libexec/mailman3'
$core_var_dir = '/var/lib/mailman3'
$core_site_owner = 'root@localhost'
$core_version = 'installed' # could also be 3.0.0
- # Mailman Core default options
+ # Mailman Core default options hashes
$core_default_allowed_hosts = {
'rest' => ['0.0.0.0'],
'lmtp' => ['0.0.0.0'],
--- /dev/null
+require 'spec_helper'
+
+describe 'mailman3::core::config::db', :type => :class do
+
+ # since we have no defaults params, should fail
+ context 'with defaults for all parameters' do
+ let (:params) {{}}
+
+ it do
+ expect {
+ should compile
+ }.to raise_error(RSpec::Expectations::ExpectationNotMetError,
+ /Must pass /)
+ end
+ end
+
+
+ # with defaults from params.pp
+ context 'with assumed default parameters' do
+ let (:params) { {
+ 'db_tag' => 'mailman3-core',
+ 'core_manage_database' => true,
+ 'core_options' => {},
+ } }
+
+ # defaults should do nothing because the application takes
+ # care of it. This is the only class defined in the manifest.
+ it { is_expected.to_not contain_class('mailman3::db::postgres') }
+ end
+
+
+ context 'with management flag set to false' do
+ let (:params) {{
+ 'db_tag' => '',
+ 'core_manage_database' => false,
+ 'core_options' => {}
+ }}
+
+ it { is_expected.to_not contain_class('mailman3::db::postgres') }
+ end
+
+
+ context 'with a MySQL URL in options' do
+ let (:params) {{
+ 'db_tag' => 'testtag',
+ 'core_manage_database' => true,
+ 'core_options' => {
+ 'database' => {
+ 'url' => 'mysql://test:test@test/test',
+ }
+ }
+ }}
+
+ it do
+ expect {
+ should compile
+ }.to raise_error(
+ /MySQL is not officially supported/)
+ end
+ end
+
+
+ context 'with a SQLite URL in options' do
+ let (:params) {{
+ 'db_tag' => 'testtag',
+ 'core_manage_database' => true,
+ 'core_options' => {
+ 'database' => {
+ 'url' => 'sqlite:///path/to/database.db',
+ },
+ },
+ }}
+
+ it { is_expected.to_not contain_class('mailman3::db::postgres') }
+ it { is_expected.to contain_class('mailman3::db::sqlite').with(
+ 'manage_database' => true,
+ 'db_path' => '/path/to/database.db',
+ ) }
+
+ end
+
+
+ context 'with a PostgreSQL URL in options' do
+ let (:params) { {
+ 'db_tag' => 'test',
+ 'core_manage_database' => true,
+ 'core_options' => {
+ 'database' => {
+ 'url' => 'postgres://myuser:mypassword@mypghost/mailman',
+ },
+ },
+ } }
+
+ it { is_expected.to contain_class('mailman3::db::postgres').with(
+ 'db_tag' => 'test',
+ 'manage_database' => true,
+ 'db_options' => {
+ 'username' => 'myuser',
+ 'password' => 'mypassword',
+ 'hostname' => 'mypghost',
+ 'database' => 'mailman',
+ }, ) }
+ end
+
+ context 'with a malformed database URL' do
+ let (:params) { {
+ 'db_tag' => 'test',
+ 'core_manage_database' => true,
+ 'core_options' => {
+ 'database' => {
+ 'url' => 'garbage string with garbage',
+ },
+ },
+ } }
+
+ it do
+ expect {
+ should compile
+ }.to raise_error(/does not match /)
+ end
+
+ end
+
+ context 'with a database hash but no url value' do
+ let (:params) { {
+ 'db_tag' => 'test',
+ 'core_manage_database' => true,
+ 'core_options' => {
+ 'database' => {},
+ },
+ } }
+
+ it do
+ expect {
+ should compile
+ }.to raise_error(/Database hash has no url/)
+ end
+ end
+
+end
context 'with assumed default parameters' do
let (:params) {
{
+ 'db_tag' => 'testtag',
'core_allowed_hosts' => {
'rest' => ['0.0.0.0'],
'lmtp' => ['0.0.0.0'],
context 'with user defined parameters' do
let (:params) {
{
+ 'db_tag' => 'testtag',
'core_allowed_hosts' => {
'rest' => ['10.0.0.1'],
'lmtp' => ['10.0.0.1'],
let (:params) {
{
+ 'db_tag' => 'testtag',
'core_manage_database' => false,
'core_manage_firewall' => false,
'core_allowed_hosts' => {},
--- /dev/null
+require 'spec_helper'
+
+describe 'mailman3::db::postgres', :type => :class do
+
+ # known good parameters
+ let(:params) {
+ {
+ 'db_tag' => 'testtag',
+ 'manage_database' => true,
+ 'db_options' => {
+ 'username' => 'testuser',
+ 'password' => 'testpass',
+ 'hostname' => 'localhost',
+ 'database' => 'testdb',
+ }
+ }
+ }
+
+ context 'with defaults for all parameters' do
+ let(:params) {{}}
+
+ it do
+ expect {
+ should compile
+ }.to raise_error(RSpec::Expectations::ExpectationNotMetError,
+ /Must pass/)
+ end
+ end
+
+ context 'with known good parameters' do
+ it { is_expected.to contain_class('mailman3::db::postgres') }
+
+ # we unfortunately can't test for exported resources.
+ #it { is_expected.to contain_class('postgresql::server::db') }
+ end
+end
+
+
--- /dev/null
+require 'spec_helper'
+
+describe 'mailman3::db::sqlite', :type => :class do
+
+ # known good parameters
+ let(:params) {
+ {
+ 'manage_database' => true,
+ 'db_path' => '/path/to/database.db',
+ }
+ }
+
+ context 'with defaults for all parameters' do
+ let(:params) {{}}
+
+ it do
+ expect {
+ should compile
+ }.to raise_error(RSpec::Expectations::ExpectationNotMetError,
+ /Must pass/)
+ end
+ end
+
+ context 'with known good parameters' do
+ it { is_expected.to contain_class('mailman3::db::sqlite') }
+
+ # when TODO for this class is complete it will need to test for a file resource
+ #it { is_expected.to contain_file('sqlite_dir') }
+ end
+
+ context 'with management flag set to false' do
+ let(:params) {
+ {
+ 'manage_database' => false,
+ 'db_path' => '/path/to/database.db',
+ }
+ }
+
+ it { is_expected.to contain_class('mailman3::db::sqlite') }
+
+ # when TODO for this class is complete it wil need to test that a file resource is not present.
+ #it { is_expected.to_not contain_file('sqlite_dir') }
+ end
+end
+
+