Puppet Class: icinga

Defined in:
modules/icinga/manifests/init.pp

Overview

Class: icinga

Sets up an icinga server, with appropriate config & plugins FIXME: A lot of code in here (init script, user setup, logrotate, and others) should probably come from the icinga deb package, and not from puppet. Investigate and potentially fix this. Note that our paging infrastructure (AQL as of 20161101) may need an update of it's sender whitelist. And don't forget to do an end-to-end test. That is submit a passive check of DOWN for a paging service and confirm people get the pages.

Parameters:

  • icinga_user (String)
  • icinga_group (String)
  • enable_notifications (Integer[0, 1]) (defaults to: 1)
  • enable_event_handlers (Integer[0, 1]) (defaults to: 1)
  • ensure_service (Enum['stopped', 'running']) (defaults to: 'running')
  • cfg_files (Array[Stdlib::Unixpath]) (defaults to: [ '/etc/nagios/puppet_hostgroups.cfg', # Backwards-compatibility '/etc/nagios/puppet_servicegroups.cfg', '/etc/nagios/nagios_host.cfg', # Locally-generated hosts (routers, pdus, et. al. -- not naggen2) '/etc/nagios/nagios_service.cfg', ])
  • cfg_dirs (Array[Stdlib::Unixpath]) (defaults to: [ '/etc/icinga/commands' ])
  • retention_file (Stdlib::Unixpath) (defaults to: '/var/cache/icinga/retention.dat')
  • max_concurrent_checks (Integer) (defaults to: 0)
  • logs_keep_days (Integer[1]) (defaults to: 780)
  • stub_contactgroups (Boolean) (defaults to: false)


11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'modules/icinga/manifests/init.pp', line 11

class icinga(
    String $icinga_user,
    String $icinga_group,
    Integer[0, 1] $enable_notifications  = 1,
    Integer[0, 1] $enable_event_handlers = 1,
    Enum['stopped', 'running'] $ensure_service = 'running',
    Array[Stdlib::Unixpath] $cfg_files = [
        '/etc/nagios/puppet_hostgroups.cfg',     # Backwards-compatibility
        '/etc/nagios/puppet_servicegroups.cfg',
        '/etc/nagios/nagios_host.cfg',           # Locally-generated hosts (routers, pdus, et. al. -- not naggen2)
        '/etc/nagios/nagios_service.cfg',
    ],
    Array[Stdlib::Unixpath] $cfg_dirs = [
        '/etc/icinga/commands'
    ],
    Stdlib::Unixpath $retention_file = '/var/cache/icinga/retention.dat',
    Integer $max_concurrent_checks = 0,
    Integer[1] $logs_keep_days = 780,
    Boolean $stub_contactgroups = false,
) {

    ensure_packages(['icinga', 'python3-yaml', 'patch', 'python3-clustershell'])

    file { $cfg_files:
      ensure => 'file',
      mode   => '0444',
      notify => Service['icinga'],
    }

    # Replaces custom icinga init script.
    file { '/etc/default/icinga':
      source  => 'puppet:///modules/icinga/default_icinga.sh',
      owner   => 'root',
      group   => 'root',
      mode    => '0644',
      require => Package['icinga']
    }

    systemd::service { 'icinga':
        ensure         => 'present',
        content        => systemd_template('icinga'),
        service_params => {
            hasstatus => false,
            restart   => '/etc/init.d/icinga reload',
        },
        require        => [
          Mount['/var/icinga-tmpfs'],
          Package['icinga'],
        ],
    }

    file { '/etc/icinga/icinga.cfg':
      content => template('icinga/icinga.cfg.erb'),
      owner   => $icinga_user,
      group   => $icinga_group,
      mode    => '0644',
      require => Package['icinga'],
      notify  => Service['icinga'],
    }

    # Clear the objects directory of sample configuration
    file { '/etc/icinga/objects':
      ensure  => 'directory',
      purge   => true,
      recurse => true,
    }

    class { '::nagios_common::contactgroups':
      source     => 'puppet:///modules/nagios_common/contactgroups.cfg',
      owner      => $icinga_user,
      group      => $icinga_group,
      config_dir => '/etc/icinga/objects',
      require    => Package['icinga'],
      notify     => Service['icinga'],
    }

    if ($stub_contactgroups) {
        if ( $::realm == 'production' ) {
            fail('Do not use $stub_contactgroups in production')
        }

        # Icinga needs all contactgroups' members to be defined. Pretend 'stub'
        # contact (defined in labs/private.git) is part of all contactgroups.
        # For testing only!
        exec { 'stub_contactgroups':
            command => '/usr/bin/sed -i "s/members.*/members stub/" /etc/icinga/objects/contactgroups.cfg',
            require => Class['Nagios_common::Contactgroups'],
        }
    }

    class { '::nagios_common::contacts':
      owner      => $icinga_user,
      group      => $icinga_group,
      config_dir => '/etc/icinga/objects',
      content    => secret('nagios/contacts.cfg'),
      require    => Package['icinga'],
      notify     => Service['icinga'],
    }

    class { [
        '::nagios_common::timeperiods',
        '::nagios_common::notification_commands',
    ] :
      owner      => $icinga_user,
      group      => $icinga_group,
      config_dir => '/etc/icinga/objects',
      require    => Package['icinga'],
      notify     => Service['icinga'],
    }

    # manages resource.cfg and does not belong in /etc/icinga/objects
    class { '::nagios_common::user_macros':
      owner   => $icinga_user,
      group   => $icinga_group,
      require => Package['icinga'],
      notify  => Service['icinga'],
    }

    file { '/etc/icinga/objects/nsca_frack.cfg':
        content => template('icinga/nsca_frack.cfg.erb'),
        owner   => $icinga_user,
        group   => $icinga_group,
        mode    => '0644',
        require => Package['icinga'],
        notify  => Service['icinga'],
    }

    $command_file='/var/lib/icinga/rw'

    file { '/var/log/icinga/icinga.log':
        ensure => 'present',
        mode   => '0644',
        owner  => $icinga_user,
        group  => $icinga_group,
    }

    # If hosts appear to be missing from the web ui, it might be
    # the permissions on this file.  Requires a restart if changed.
    file { '/var/cache/icinga/objects.cache':
        ensure => 'present',
        mode   => '0644',
        owner  => $icinga_user,
        group  => 'www-data',
        notify => Service['icinga'],
    }

    file { '/etc/icinga/cgi.cfg':
        source  => 'puppet:///modules/icinga/cgi.cfg',
        owner   => $icinga_user,
        group   => $icinga_group,
        mode    => '0644',
        require => Package['icinga'],
        notify  => Service['icinga'],
    }


    # Setup all plugins!
    class { '::icinga::plugins':
        icinga_user  => $icinga_user,
        icinga_group => $icinga_group,
        require      => Package['icinga'],
        notify       => Service['icinga'],
    }

    # Setup tmpfs for use by icinga
    file { '/var/icinga-tmpfs':
        ensure => directory,
        owner  => $icinga_user,
        group  => $icinga_group,
        mode   => '0755',
    }

    mount { '/var/icinga-tmpfs':
        ensure  => mounted,
        atboot  => true,
        fstype  => 'tmpfs',
        device  => 'none',
        options => "size=1024m,uid=${icinga_user},gid=${icinga_group},mode=755",
        require => File['/var/icinga-tmpfs'],
    }

    # Ensure periodic cleanup
    systemd::tmpfile { 'icinga-tmpfs':
        ensure  => present,
        content => 'e /var/icinga-tmpfs/ - - - 1d',
    }

    file { '/var/lib/icinga':
        ensure => directory,
        owner  => $icinga_user,
        group  => $icinga_group,
    }

    file { '/var/cache/icinga':
        ensure => directory,
        owner  => $icinga_user,
        group  => 'www-data',
    }

    # Script to purge resources for non-existent hosts
    file { '/usr/local/sbin/purge-nagios-resources.py':
        source => 'puppet:///modules/icinga/purge-nagios-resources.py',
        owner  => $icinga_user,
        group  => $icinga_group,
        mode   => '0755',
    }

    # Command folders / files to let icinga web to execute commands
    # See Debian Bug 571801
    file { $command_file:
        ensure => 'directory',
        owner  => $icinga_user,
        group  => 'www-data',
        mode   => '2710', # The sgid bit means new files inherit guid
    }

    # ensure icinga can write logs for ircecho, raid_handler etc.
    file { '/var/log/icinga':
        ensure => 'directory',
        owner  => $icinga_user,
        group  => 'adm',
        mode   => '2755',
    }

    # archive location for rotated logs, use the space in /srv/
    file { '/srv/icinga-logs':
        ensure => 'directory',
        owner  => $icinga_user,
        group  => 'adm',
        mode   => '2755',
    }

    # Complement Icinga's log archival/rotation with tmpfiles.d cleanup
    systemd::tmpfile { 'icinga-logs':
        ensure  => present,
        content => "e /srv/icinga-logs/ - - - ${logs_keep_days}d",
    }

    # Check that the icinga config is sane
    monitoring::service { 'check_icinga_config':
        description    => 'Check correctness of the icinga configuration',
        check_command  => 'check_icinga_config',
        check_interval => 10,
        notes_url      => 'https://wikitech.wikimedia.org/wiki/Icinga',
    }

    # script to manually send SMS to Icinga contacts (T82937)
    file { '/usr/local/bin/icinga-sms':
        ensure => present,
        source => 'puppet:///modules/icinga/icinga-sms.py',
        owner  => 'root',
        group  => 'root',
        mode   => '0550',
    }

    # Script to generate the contacts configuration for the Icinga meta-monitoring
    file { '/usr/local/bin/generate-check-icinga-contacts':
        ensure  => present,
        owner   => 'root',
        group   => $icinga_group,
        mode    => '0550',
        source  => 'puppet:///modules/icinga/generate_check_icinga_contacts.py',
        require => Package['python3-yaml'],
    }

    # Script to sync the contacts configuration for the Icinga meta-monitoring
    file { '/usr/local/bin/sync-check-icinga-contacts':
        ensure => present,
        owner  => 'root',
        group  => $icinga_group,
        mode   => '0550',
        source => 'puppet:///modules/icinga/sync_check_icinga_contacts.sh',
    }

    # Script to parse and query the status.dat file
    file { '/usr/local/bin/icinga-status':
        ensure  => present,
        owner   => 'root',
        group   => 'ops',
        mode    => '0550',
        source  => 'puppet:///modules/icinga/icinga_status.py',
        require => Package['python3-clustershell'],
    }

    # Purge unmanaged nagios_host and nagios_services resources
    # This will only happen for non exported resources, that is resources that
    # are declared by the icinga host itself
    resources { 'nagios_host':
        purge  => true,
        notify => Service['icinga'],
    }

    resources { 'nagios_service':
        purge  => true,
        notify => Service['icinga'],
    }

    # Applies a patch to disable autocomplete.js on search text input
    $patches_dir = '/usr/share/icinga/patches'

    file { $patches_dir:
        ensure  => 'directory'
    }

    file { "${patches_dir}/disable_autocomplete.patch":
        ensure  => 'present',
        source  => "puppet:///modules/${module_name}/disable_autocomplete.patch",
        require => File[$patches_dir]
    }

    exec { 'apply disable_autocomplete.patch':
        command => "/usr/bin/patch --forward /usr/share/icinga/htdocs/menu.html ${patches_dir}/disable_autocomplete.patch",
        unless  => "/usr/bin/patch --reverse --dry-run -f /usr/share/icinga/htdocs/menu.html ${patches_dir}/disable_autocomplete.patch",
        require => File["${patches_dir}/disable_autocomplete.patch"],
    }
}