Puppet Module: kolab
¶
The Kolab module for Puppet allows the continued management of a Kolab Groupware environment, by defining nodes as having a certain role within the Kolab Groupware environment.
To configure the exact way an included kolab
module class behaves,
the kolab
module uses multiple parameterized classes.
Integration with Monitoring and Trending¶
Each role defined for a node participating in providing Kolab Groupware services includes specific monitoring (with Nagios) and trending (with Munin) plugins.
For Nagios, exported resources are used to allow a NOC system to aggregate the associated resources and realize them.
For Munin, the inclusion of the classes in this module allow the aggregation of graphs on the NOC server.
Module Classes (or Roles)¶
kolab::imap
A class defining virtual resources to be realized by individual sub-classes, and resources shared between all IMAP servers.
Includes the following Munin plugins:
kolab::imap::full
A full, standalone Cyrus IMAP server. Inheritskolab::imap
.
kolab::imap::backend
A Cyrus IMAP backend server, such that this server holds IMAP mailbox payload (technically, a backend can function as a frontend in a unified Cyrus IMAP Murder topology).
Inherits
kolab::imap
.
kolab::imap::frontend
A Cyrus IMAP frontend in a discrete Cyrus IMAP Murder topology.
Inherits
kolab::imap
.
kolab::imap::mupdate
A Cyrus IMAP Master Update (mupdate) server in a discrete Cyrus IMAP Murder topology.
Inherits
kolab::imap
.
kolab::ldap
kolab::mx
A generic mail exchanger.
kolab::mx::amavisd
Adds anti-spam and anti-virus to a mail exchanger.
kolab::mx::external
An Internet-facing mail exchanger.
kolab::mx::external::inbound
An Internet-facing mail exchanger for inbound traffic.
kolab::mx::external::outbound
An Internet-facing mail exchanger for outbound traffic.
kolab::mx::internal
An internal mail exchanger.
kolab::webserver
An webserver with all standard functionality included.
kolab::webserver::activesync
A webserver dedicated to providing ActiveSync for mobile device synchronization.
Merely includes
kolab::webserver::syncroton
.
kolab::webserver::chwala
A webserver dedicated to providing the Chwala file-cloud.
Inherits
kolab::webserver::common
.
kolab::webserver::common
Commonly shared resources betweenkolab::webserver
sub-classes.
kolab::webserver::freebusy
A webserver dedicated to providing Free/Busy scheduling information.
Inherits
kolab::webserver::common
.
kolab::webserver::hkccp
A webserver dedicated to the Hosted Kolab Customer Control Panel.
Inherits
kolab::webserver::common
.
kolab::webserver::irony
A webserver dediciated to providing CalDAV, CardDAV and WebDAV functionality.
Inherits
kolab::webserver::common
.
kolab::webserver::roundcubemail
A webserver dedicated to the Roundcube webmail interface.
Inherits
kolab::webserver::common
.
kolab::webserver::syncroton
A webserver dedicated to providing ActiveSync for mobile device synchronization.
Inherits
kolab::webserver::common
.
kolab::webserver::webadmin
A webserver dedicated to providing the Kolab Web Administration Panel user interface and API.
Inherits
kolab::webserver::common
.
kolab::webserver::webmail
A wrapper class to install bothkolab::webserver::roundcubemail
andkolab::webserver::chwala
.
kolab::yum
A class to maintain the YUM repository configuration for staged environments.
kolab::webserver::common
¶
This class is shared between other kolab::webserver
sub-classes, and
provides the basis for a webserver configuration.
It includes Class[“webserver”] from Puppet Module: webserver, and configures commonly used virtual resources so that each individual component can realize them, preventing collisions between duplicate definitions.
Environment Stages and Package Version Locks¶
Configuration Parameters¶
kolab::params
¶
The kolab::params
class is a class commonly shared between all nodes
participating in servicing Kolab Groupware.
imap_admin_login (cyrus-admin
)
The administrative login for Cyrus IMAP.
Todo
A separate set of credentials should be supplied for wallace, freebusy, replication and proxy for the purposes of maintaining a more well-informed audit trail.
imap_admin_password (undef
)
The password for theimap_admin_login
.
imap_enable_notify (undef
)
Enable the notifyd(8) service.
imap_enable_pop (undef
)
Enable the pop3d(8) services.
imap_enable_ptloader (undef
)
Enable the ptloader services.
imap_hostname ($fqdn
)
The hostname to use to connect to IMAP.
While this setting applies to many services including the Kolab daemon, Wallace and Roundcube webmail, should the IMAP server for each of these services need to be different, we recommend you use a split DNS horizon.
imap_port (993
)
The port to use when connecting to IMAP.
imap_scheme (imaps
)
The scheme to use. Usingimaps
translates to configuring a prefix ofssl://
where appropriate, otherwise meanstls://
.
imap_storage_partitions ([ "default" ]
)
Define one or more storage partitions.
Note
The inclusion of the “default” partition is mandatory.
Example usage:
class { "kolab::params": imap_storage_partitions => [ "default", "archive" ] }
imap_storage_meta_base_path (undef
)
Undefined by default, allows the separation of IMAP spool metadata and message payload.
If defined,
imap_storage_meta_base_path
must be set to an absolute path that exists with 0750 permissions for the cyrus user and mail group.The
kolab
module (or actually, Puppet) cannot ensure the directory exists, unless there is a guarantee that the parent directory exists – only/
is guaranteed.Example usage:
class { "kolab::params": imap_storage_meta_base_path => "/srv/imap/meta" }
imap_storage_spool_base_path (/var/spool/imap
)
Sets the root of the IMAP spool partitions.
Under the directory specified here, directories are created for each partition defined (with a mandated minimum list including
default
).Example usage:
class { "kolab::params": imap_storage_spool_base_path => "/srv/imap/spool" }results in:
File["/srv/imap/spool/default/"]
imap_configdir (/var/lib/imap/
)
The imapd.conf(5)
configdir
setting.This directory normally contains databases among which
mailboxes.db
andannotations.db
.Because of backup processes, it may be desirable to have the default spool partition and
configdir
located under the same directory hierarchy off of the same logical volume mount.Example usage:
class { "kolab::params": imap_configdir => "/srv/imap/config", imap_storage_spool_base_path => "/srv/imap/spool" }
imap_duplicate_db_path (undef
)
The
deliver.db
database file used to determine whether new message arrivals are duplicates (to be suppressed) contains a few days worth of delivery information.However, it is not critical for operations and may simply be discarded in case of a system reboot.
If performance of message delivery is more important than the suppression of duplicates (which are a rather rare occurrence), then this file may be located under a directory hierarchy mounted off of
tmpfs
.
imap_ptscache_db_path (undef
)
The
ptscache.db
database file caches information related to LDAP queries performed to find target result attributes for the process of canonification, and additional authorization information such as a user’s group memberships or roles.This database can be discarded when a node reboots, and might therefore also live in a directory hierarchy mounted off of
tmpfs
.
imap_sievedir (undef
)
Unless specifically required, keep this to a default value of${configdir}/sieve
.
imap_socket_path (/var/lib/imap/socket
)
The path to where socket files are stored.
imap_statuscache_db_path (undef
)
Thestatuscache.db
database file is undocumented.
imap_temp_path (undef
)
The absolute path to a location Cyrus IMAP can use to store temporary files.
imap_tlscache_db_path (undef
)
The
tls_sessions.db
is a database file that maintains previously negotiated TLS sessions, allowing those sessions to be resumed at a later time.This database can be discarded when a node reboots, and might therefore also live in a directory hierarchy mounted off of
tmpfs
.
kolab_version_name (kolab_14
)
The version name of the Kolab Groupware product stream to use.
Possible values include:
kolab_14
(the default)kolab_13
kolab_3_3
kolab_primary_domain ($domain
)
The primary domain for the Kolab Groupware deployment.
Corresponds to the
primary_domain
setting in the[kolab]
section of kolab.conf(5).
kolab_default_locale (en_US
)
The default locale for the environment.
Corresponds to the setting
default_locale
in the[kolab]
section of kolab.conf(5).
kolab_policy_uid (%(surname)s.lower()
)
The UID policy for Kolab.
Corresponds to the setting
policy_uid
in the[kolab]
section of kolab.conf(5).
memcache_hosts (undef
)
An array of hosts that serve memcached to be used for memcache- capable software applications unless specific memcached host addresses are defined for that service.
webclient_memcache_hosts ($kolab::params::memcache_hosts
)
An array of hosts that serve memcached to be used solely for the webmail client software.
webadmin_memcache_hosts ($kolab::params::memcache_hosts
)
An array of hosts that serve memcached to be used solely for the webadmin client software.
ldap_scheme (ldap
)
The scheme name to use to connect to LDAP, where URIs are used.
Can be either of
ldap
orldaps
.
ldap_hostname ($fqdn
)
The host address to use to connect to the LDAP service.
ldap_port (389
)
The port to use to connect to the LDAP service.
ldap_domain_base_dn (cn=kolab,cn=config
)
The base dn for domain objects.
roundcubemail_db_dsnw (mysqli://roundcube:password@localhost/roundcube
)
roundcubemail_db_dsnr (undef
)
ldap_bind_dn (cn=Directory Manager
)
The login for the administrative credentials to use when binding to LDAP.
Note
Note that you are encouraged to provide the Kolab Groupware environment with credentials lesser privileged than “cn=Directory Manager”, but that certain functionality we have to make available in a standard deployment requires the use of these superuser credentials.
ldap_bind_pw (undef
)
The password for the administrative credentials used to bind to LDAP.
ldap_root_dn (undef
)
The root DN.
ldap_service_bind_dn (undef
)
The bind DN for services, normallyuid=kolab-service,ou=Special Users,${ldap_root_dn}
ldap_service_bind_pw (undef
)
The bind password for services.
kolab_cache_sql_uri (mysql://kolab:Welcome2KolabSystems@localhost/kolab
)
The URI to a SQL location to use for caching.
kolab_webadmin_sql_uri (mysql://kolab:Welcome2KolabSystems@localhost/kolab
)
The URI to a SQL location to use for the web administration panel configuration.
roundcubemail_des_key (rcmail-!24ByteDESkey*Str
)
The DES key used by the Roundcube webmail program to encrypt session-related information.
smtp_scheme (undef
)
The scheme to use when connecting to SMTP.
smtp_hostname ($fqdn
)
The host address to use when connecting to SMTP.
smtp_port (587
)
The port to use when connecting to SMTP.
kolab::params::imap
¶
imap_storage_partitions ($kolab::params::imap_storage_partitions
)
Override the IMAP storage partitions set usingkolab::params
.
imap_storage_meta_base_path ($kolab::params::imap_storage_meta_base_path
)
Override the IMAP metadata base path set usingkolab::params
.
imap_storage_spool_base_path ($kolab::params::imap_storage_spool_base_path
)
Override the IMAP mail spool base path set usingkolab::params
.
imap_configdir ($kolab::params::imap_configdir
)
Override the
configdirectory
setting in imapd.conf(5) set usingkolab::params
.Note
So far this has not yet worked in practice.
imap_duplicate_db_path ($kolab::params::imap_duplicate_db_path
)
Override the path todeliver.db
set usingkolab::params
.
imap_ptscache_db_path ($kolab::params::imap_ptscache_db_path
)
Override the path toptscache.db
set usingkolab::params
.
imap_sievedir ($kolab::params::imap_sievedir
)
Override the Sieve directory set usingkolab::params
.
imap_socket_path ($kolab::params::imap_socket_path
)
Override the directory used to store socket files set usingkolab::params
.
imap_statuscache_db_path ($kolab::params::imap_statuscache_db_path
)
imap_temp_path ($kolab::params::imap_temp_path
)
imap_tlscache_db_path ($kolab::params::imap_tlscache_db_path
)
Todo
- Add a setting
imap_proc_path
. - Add a setting
webadmin_api_memcache_hosts
- Add a setting
hkccp_memcache_hosts
Using the Kolab Module¶
We strongly encourage you wrap the individual kolab
module classes
with some of your own, in order to share certain configuration
information between multiple nodes, but not share all information with
all of them, and in order to allow divergence (in terms of development).
In the simplest form, going with all defaults, the class structure you might want to use looks as follows:
You might wonder why the green parts (yours) need to be so large, so lets look under the hood and apply some differentiation between IMAP frontends and backends.
Suppose that, for example, both types of IMAP servers require a
different configdir
setting in imapd.conf(5).
The kolab::params
class is already configured by the parameterized
inclusion of example_org_kolab::common
, the class you use to share
settings between all nodes related to Kolab Groupware services.
The frontend-, backend- and mupdate-specific classes would need to
break the inheritance of the common class, and each instantiate
kolab::params
themselves, individually. Because your other
functional components would still use the common class, this duplicates
instantiating kolab::params
times 4, for 3 environments each.
Therefore each example_org_kolab::imap
sub-class is to instantiate a
parameterized sub-class of kolab::params
, called
kolab::params::imap
. This sub-class inherits kolab::params
, so
that you still have to configure those settings only once, but allow you
to configure some additional, IMAP-server specific settings.
The same picture as before now looks a little bit more complex:
Add to this picture the following considerations:
A deployment does not necessarily consist of homogeneous operating systems and operating system versions.
Some systems may run CentOS 6, others RHEL 6, and perhaps yet some others RHEL 7.
Even if this is not the day-to-day, each deployment will transition, sooner or later, therefore creating a hybrid environment (or worse).
A deployment is not necessarily comprised of systems all running the exact same Kolab Enterprise version. Some systems may happily continue to run a functional component based on Kolab Enterprise 13, while perhaps the web- or IMAP servers have moved on to run Kolab Enterprise 14.
Again even if this is not the day-to-day, each deployment will transition, sooner or later.
The reproducibility of a system you have in production today, whether for the purposes of recovery or capacity increase, depends on your ability to not only produce a system, but have that system be maintained using the exact same package versions as the other systems in production.
While Puppet is intended to describe the desired state of individual
nodes, and the desired state of so many nodes across and even within
deployments may differ so much, the picture of the internals of the
kolab
module look yet again a little different from the previous
diagram:
Example example_org_kolab
Class¶
In this example class, we re-iterate how it is built up, and why.
First, the bare bones of it all:
# The module class wrapper.
class example_org_kolab {
# The common class, that includes some basic configuration
# information shared across all (most) Kolab nodes.
class common inherits example_org_kolab { }
# A container class for all things IMAP.
class imap inherits common {
}
}
Next, we populate some of the information (not all of the relevant information, for that see later on):
class example_org_kolab {
class common inherits example_org_kolab {
class { "kolab::params":
imap_admin_login => "cyrus-admin",
imap_admin_password => "password"
}
}
class imap inherits common {
include kolab::imap::full
}
}
This gives us a base structure so that a node manifest might look as follows:
node 'imap.example.org' {
include example_org_kolab::imap
}
The structure allows us to distinguish certain parameter values between environments:
class example_org_kolab {
class common inherits example_org_kolab {
case $environment {
"development": {
class { "kolab::params":
imap_admin_login => "cyrus-admin",
imap_admin_password => "password",
(...)
}
}
"testing": {
class { "kolab::params":
imap_admin_login => "cyrus-admin",
imap_admin_password => "anotherpassword",
(...)
}
}
"production": {
class { "kolab::params":
imap_admin_login => "cyrus-admin",
imap_admin_password => "verysecretpassword",
(...)
}
}
}
}
class imap inherits common {
include kolab::imap::full
}
}
Or, alternatively:
class example_org_kolab {
class common inherits example_org_kolab {
class { "kolab::params":
imap_admin_login => "cyrus-admin",
imap_admin_password => $environment ? {
"development" => "password",
"testing" => "anotherpassword",
"production" => "verysecretpassword"
}
}
}
class imap inherits common {
include kolab::imap::full
}
}
However, there are reasons to do it the way it was done the first time around:
- Instead of defining
Class['kolab::params']
, include a class that comes from a file external toexample_org_kolab
class definition (and hide the actual value from prying eyes). - Not all environment stages need to contain all values for all parameters.
Sub-classing example_org_kolab
further, to wrap individual more
specific roles might give you something like this:
class example_org_kolab {
class common inherits example_org_kolab {
case $environment {
"development": {
class { 'kolab::params':
imap_admin_login => "cyrus-admin",
imap_admin_password => "somepass",
ldap_domain_base_dn => "ou=Domains,dc=example,dc=org",
imap_enable_notify => undef,
imap_enable_pop => true,
imap_enable_ptloader => true,
imap_hostname => "imap.example.org",
imap_port => 993,
imap_scheme => "imaps",
imap_socket_path => "/var/lib/imap/socket",
kolab_cache_sql_uri => "mysql://kolab:somepass@mysql-write.example.org/kolab_cache",
ldap_bind_dn => "cn=Directory Manager",
ldap_bind_pw => "somepass",
ldap_hostname => "ldap.example.org",
ldap_port => 389,
ldap_root_dn => "dc=example,dc=org",
ldap_service_bind_dn => "uid=kolab-service,ou=Special Users,dc=example,dc=org",
ldap_service_bind_pw => "somepass",
memcache_hosts => [ 'memc.example.org:11211' ],
roundcubemail_db_dsnw => "mysqli://roundcube:somepass@mysql-write.example.org/roundcube",
roundcubemail_db_dsnr => "mysqli://roundcube:somepass@mysql-read.example.org/roundcube",
roundcubemail_des_key => "somestringthatis24chars.",
smtp_hostname => "smtp.example.org",
smtp_port => 587
}
}
"testing": {
(...)
}
"production": {
(...)
}
}
}
class imap inherits common {
class backend inherits imap {
class { "kolab::params::imap":
imap_configdir => "/srv/imap/config",
imap_duplicate_db_path => "/var/tmp/cyrus-imapd/deliver.db",
imap_ptscache_db_path => "/var/tmp/cyrus-imapd/ptscache.db",
imap_sievedir => "/srv/imap/config/sieve/",
imap_socket_path => "/srv/imap/config/socket",
imap_statuscache_db_path => "/var/tmp/cyrus-imapd/statuscache.db",
imap_storage_partitions => [ "default", "archive" ],
imap_storage_meta_base_path => "/srv/imap/meta",
imap_storage_spool_base_path => "/srv/imap/spool",
imap_temp_path => "/var/tmp/cyrus-imapd/",
imap_tlscache_db_path => "/var/tmp/cyrus-imapd/tls_sessions.db"
}
file { "/srv/imap/":
ensure => directory
}
file { [
"/srv/imap/config/",
"/srv/imap/meta/",
"/srv/imap/spool/"
]:
ensure => directory,
owner => "cyrus",
group => "mail",
mode => 750,
require => Mount["/srv/imap"],
notify => [
Exec["_usr_lib_cyrus-imapd_mkimap"],
Service["cyrus-imapd"]
]
}
file { "/srv/imap/config/proc/":
ensure => "/var/tmp/cyrus-imapd/proc/",
force => true,
links => manage,
noop => false,
require => File["/var/tmp/cyrus-imapd/proc/"],
notify => Service["cyrus-imapd"]
}
file { "/var/tmp/cyrus-imapd/":
ensure => directory,
owner => "cyrus",
group => "mail",
mode => 750,
noop => false,
notify => Service["cyrus-imapd"]
}
file { "/var/tmp/cyrus-imapd/proc/":
ensure => directory,
owner => "cyrus",
group => "mail",
mode => 750,
noop => false,
require => Mount["/var/tmp/cyrus-imapd"],
notify => Service["cyrus-imapd"]
}
mount { "/srv/imap":
atboot => true,
device => "/dev/vg_imap/lv_imap",
options => "defaults",
fstype => "ext4",
remounts => true,
ensure => mounted,
noop => false,
require => File["/srv/imap/"],
notify => Service["cyrus-imapd"]
}
mount { "/var/tmp/cyrus-imapd":
atboot => true,
device => "tmpfs",
options => "defaults",
fstype => "tmpfs",
remounts => true,
ensure => mounted,
noop => false,
require => File["/var/tmp/cyrus-imapd/"],
notify => Service["cyrus-imapd"]
}
include kolab::imap::backend
}
}
node 'imapb01.example.org' {
include example_org_kolab::imap::backend
}