Puppet Class: sympa

Defined in:
manifests/init.pp

Summary

Install and configure Sympa mailing list manager

Overview

Install and configure Sympa mailing list manager

Examples:

include sympa

Parameters:

  • manage_user (Boolean) (defaults to: true)

    if true this puppet module manage user account settings.

  • user (String[1]) (defaults to: 'sympa')

    User account name

  • group (String[1]) (defaults to: 'sympa')

    User account group name.

  • manage_database (Boolean) (defaults to: true)

    If true this module manage postgreSQL server and database backend.

  • db_host (String[1]) (defaults to: 'localhost')

    Address of the database server with TCP connection (5432 is used as port).

  • db_name (String[1]) (defaults to: 'sympa')

    Name of used database.

  • db_user (String[1]) (defaults to: 'sympa')

    User for the database connection.

  • db_password (Variant[String[1], Sensitive[String[1]]]) (defaults to: 'changeme')

    Password for the database connection.

  • prefix_path (Stdlib::Absolutepath) (defaults to: '/home/sympa')

    Install Sympa files in this path.

  • sysconf_dir (String[1]) (defaults to: 'etc')

    Configuration dir under prefix_path

  • aliases_file (String[1]) (defaults to: 'sympa_aliases')

    Aliases file to store Sympa mail aliases, under sysconfig_dir

  • release (String[1]) (defaults to: '6.2.76')

    Installed release number of Sympa.

  • listdomain (Stdlib::Fqdn) (defaults to: 'listes.example.org')

    Primary mail domain name. Web interface for Sympa mailing list manager, can be joined at $listdomain

  • listmaster (Array[Stdlib::Email]) (defaults to: ['listmaster@example.org'])

    Email addresses of listmasters

  • lang (Enum['fr']) (defaults to: 'fr')

    Supported language

  • topics (Sympa::Topics) (defaults to: {})

    Defines topics (categories) of the mailing lists.

  • dkim_feature (Boolean) (defaults to: false)

    If true, Sympa may verify DKIM signatures of incoming messages and/or insert DKIM signature to outgoing messages.

  • dkim_selector (String[1]) (defaults to: 'lists-sympa')

    Selector for DNS lookup of DKIM public key.

  • dkim_signature_apply_on (Array[String[1]]) (defaults to: ['any'])

    It controls in which case messages must be signed using DKIM

  • dkim_private_key (Optional[String[1]]) (defaults to: undef)

    RSA private key used by DKIM, must contain a PEM encoded private key

  • dmarc_protection (Boolean) (defaults to: false)

    If true, enable some dmarc protections

  • dmarc_protection_mode (Array[String[1]]) (defaults to: ['all'])
  • dmarc_protection_phrase (String[1]) (defaults to: 'name_via_list')

    This is the format to be used for the sender name part of the new From header field.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'manifests/init.pp', line 33

class sympa (
  Boolean $manage_user = true,
  String[1] $user = 'sympa',
  String[1] $group = 'sympa',
  Boolean $manage_database = true,
  String[1] $db_host = 'localhost',
  String[1] $db_name = 'sympa',
  String[1] $db_user = 'sympa',
  Variant[String[1], Sensitive[String[1]]] $db_password = 'changeme',
  Stdlib::Absolutepath $prefix_path = '/home/sympa',
  String[1] $sysconf_dir = 'etc',
  String[1] $aliases_file = 'sympa_aliases',
  String[1] $release = '6.2.76',
  Stdlib::Fqdn $listdomain = 'listes.example.org',
  Array[Stdlib::Email] $listmaster = ['listmaster@example.org'],
  Enum['fr'] $lang = 'fr',
  Sympa::Topics $topics = {},
  Boolean $dkim_feature = false,
  String[1] $dkim_selector = 'lists-sympa',
  Optional[String[1]] $dkim_private_key = undef,
  Array[String[1]] $dkim_signature_apply_on = ['any'],
  Boolean $dmarc_protection = false,
  Array[String[1]] $dmarc_protection_mode = ['all'],
  String[1] $dmarc_protection_phrase = 'name_via_list',
) {
  $_required = [
    'debconf-utils',
    'cpanminus',
    'gcc',
    'libssl-dev',
    'autoconf',
    'automake',
    'gettext',
    'mhonarc',
    'perl',
    'libxml-libxml-perl',
    'libmime-lite-html-perl',
    'libdatetime-timezone-perl',
  ]

  $_configure_array = [
    '--enable-fhs',
    "--prefix=${sympa::prefix_path}",
    "--sysconfdir=${sympa::prefix_path}/${sympa::sysconf_dir}",
    "--with-confdir=${sympa::prefix_path}/${sympa::sysconf_dir}",
    "--with-user=${sympa::user}",
    "--with-group=${sympa::group}",
    "--with-aliases_file=${sympa::prefix_path}/${sympa::sysconf_dir}/${sympa::aliases_file}",
    '--without-initdir',
  ]

  $_configure_opts = join($_configure_array, ' ')

  if $sympa::manage_user {
    class { 'accounts':
      user_list => {
        $sympa::user => {
          comment    => 'Sympa Mailing List',
          group      => $sympa::group,
          shell      => '/usr/sbin/nologin',
          managehome => true,
          home       => $sympa::prefix_path,
          home_mode  => '0701',
        },
      },
    }

    Class['accounts'] -> File["${sympa::prefix_path}/sympa"]
    Class['accounts'] -> Exec['autoreconf']
    Class['accounts'] -> Exec['configure']
    Class['accounts'] -> Exec['make']
  }
  if $sympa::manage_database {
    include postgresql::server

    postgresql::server::db { $sympa::db_name:
      user     => $sympa::db_user,
      password => postgresql::postgresql_password($sympa::db_user, $sympa::db_password),
    }

    package { 'libdbd-pg-perl':
      ensure  => present,
      require => Class['Postgresql::Server'],
    }

    Postgresql::Server::Db[$sympa::db_name] -> File["${sympa::prefix_path}/${sympa::sysconf_dir}/sympa.conf"]
  }

  archive { "sympa-${sympa::release}.tar.gz":
    path         => "/tmp/sympa-${sympa::release}.tar.gz",
    source       => "https://github.com/sympa-community/sympa/archive/refs/tags/${sympa::release}.tar.gz",
    user         => $sympa::user,
    extract      => true,
    extract_path => $sympa::prefix_path,
    creates      => "${sympa::prefix_path}/sympa-${sympa::release}",
    cleanup      => true,
  }
  -> file { "${sympa::prefix_path}/sympa":
    ensure => link,
    owner  => $user,
    target => "${sympa::prefix_path}/sympa-${sympa::release}",
  }
  -> package { $_required:
    ensure => present,
  }
  -> exec { 'cpanm --installdeps':
    command     => '/usr/bin/cpanm --installdeps --with-recommends .',
    cwd         => "${sympa::prefix_path}/sympa-${sympa::release}",
    environment => ['HOME=/root'],
    user        => 'root',
    timeout     => 1200,
    creates     => [
      '/usr/local/share/perl/5.34.0/Mail/DKIM/Algorithm/Base.pm',
      '/usr/local/share/perl/5.34.0/Crypt/OpenSSL/Guess.pm',
      '/usr/local/share/perl/5.34.0/Net/DNS/Resolver/Base.pm',
    ],
    subscribe   => [
      Archive["sympa-${sympa::release}.tar.gz"],
      File["${sympa::prefix_path}/sympa"],
    ],
  }
  -> exec { 'autoreconf':
    command     => '/usr/bin/autoreconf -i',
    cwd         => "${sympa::prefix_path}/sympa-${sympa::release}",
    environment => ["HOME=${sympa::prefix_path}"],
    user        => $sympa::user,
    creates     => "${sympa::prefix_path}/sympa-${sympa::release}/configure",
  }
  -> exec { 'configure':
    command     => "/usr/bin/make distclean; ${sympa::prefix_path}/sympa/configure ${_configure_opts}",
    path        => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
    cwd         => "${sympa::prefix_path}/sympa-${sympa::release}",
    environment => ["HOME=${sympa::prefix_path}"],
    user        => $sympa::user,
    creates     => "${sympa::prefix_path}/sympa-${sympa::release}/config.status",
  }
  ~> exec { 'make':
    command     => '/usr/bin/make',
    cwd         => "${sympa::prefix_path}/sympa-${sympa::release}",
    environment => ["HOME=${sympa::prefix_path}"],
    user        => $sympa::user,
    creates     => "${sympa::prefix_path}/sympa-${sympa::release}/service/logrotate",
  }
  ~> exec { 'make install':
    command     => '/usr/bin/make install',
    cwd         => "${sympa::prefix_path}/sympa-${sympa::release}",
    environment => ["HOME=${sympa::prefix_path}"],
    user        => $sympa::user,
    creates     => [
      "${sympa::prefix_path}/etc",
      "${sympa::prefix_path}/var",
      "${sympa::prefix_path}/sbin",
    ],
  }
  -> exec { 'locale-gen fr_FR.UTF-8':
    command => 'locale-gen fr_FR.UTF-8',
    path    => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
    user    => 'root',
    unless  => 'debconf-get-selections | grep -qP "^locales\s+locales/locales_to_be_generated\s+multiselect\s+.*fr_FR.UTF-8 UTF-8"',
  }
  -> exec { 'debconf-set-selections locales locales/locales_to_be_generated':
    command => 'echo "locales locales/locales_to_be_generated multiselect en_US.UTF-8 UTF-8, fr_FR.UTF-8 UTF-8" | debconf-set-selections',
    path    => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
    user    => 'root',
    unless  => 'debconf-get-selections | grep -qP "^locales\s+locales/locales_to_be_generated\s+multiselect\s+.*fr_FR.UTF-8 UTF-8"',
  }
  -> file { "${sympa::prefix_path}/${sympa::sysconf_dir}/sympa.conf":
    ensure  => file,
    mode    => '0600',
    owner   => $sympa::user,
    group   => $sympa::group,
    content => epp('sympa/sympa.conf.epp'),
    notify  => [
      Service['sympa.service'],
      Service['wwsympa.service'],
    ],
  }

  if $dkim_feature {
    if !$dkim_private_key {
      fail('With dkim_feature true, dkim_private_key is mandatory.')
    }

    $_dkim_directories = [
      "${sympa::prefix_path}/${sympa::sysconf_dir}/dkim",
      "${sympa::prefix_path}/${sympa::sysconf_dir}/dkim/${sympa::listdomain}",
    ]

    file { $_dkim_directories:
      ensure  => directory,
      mode    => '0700',
      owner   => $sympa::user,
      group   => $sympa::group,
      require => File["${sympa::prefix_path}/${sympa::sysconf_dir}/sympa.conf"],
    }
    -> file { "${sympa::prefix_path}/${sympa::sysconf_dir}/dkim/${sympa::listdomain}/${sympa::dkim_selector}.key":
      ensure  => file,
      mode    => '0600',
      owner   => $sympa::user,
      group   => $sympa::group,
      content => epp('sympa/dkim_priv.key.epp'),
      notify  => Service['sympa.service'],
    }
  }

  if $sympa::topics.type == Undef {
    # topics are undefined so Sympa defaults are used
    file { "${sympa::prefix_path}/${sympa::sysconf_dir}/topics.conf":
      ensure => 'absent',
    }
  } else {
    file { "${sympa::prefix_path}/${sympa::sysconf_dir}/topics.conf":
      ensure  => file,
      mode    => '0755',
      owner   => $sympa::user,
      group   => $sympa::group,
      content => epp('sympa/topics.conf.epp'),
      require => File["${sympa::prefix_path}/${sympa::sysconf_dir}/sympa.conf"],
    }
  }

  [
    'sympa.service',
    'sympa-archive.service',
    'sympa-bounce.service',
    'sympa-outgoing.service',
    'sympa-task.service',
    'wwsympa.socket',
    'wwsympa.service',
  ].each | String $_unit | {
    systemd::unit_file { $_unit:
      enable  => true,
      active  => true,
      content => epp("sympa/${_unit}.epp"),
      require => [
        File["${sympa::prefix_path}/${sympa::sysconf_dir}/sympa.conf"],
        Exec['locale-gen fr_FR.UTF-8'],
      ],
    }
  }
}