1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3#
4# This file is largely copied from the Nagios module included in the
5# Func project. Original copyright follows:
6#
7# func-nagios - Schedule downtime and enables/disable notifications
8# Copyright 2011, Red Hat, Inc.
9# Tim Bielawa <tbielawa@redhat.com>
10# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
11
12from __future__ import absolute_import, division, print_function
13__metaclass__ = type
14
15
16ANSIBLE_METADATA = {'metadata_version': '1.1',
17                    'status': ['preview'],
18                    'supported_by': 'community'}
19
20
21DOCUMENTATION = '''
22---
23module: nagios
24short_description: Perform common tasks in Nagios related to downtime and notifications.
25description:
26  - "The C(nagios) module has two basic functions: scheduling downtime and toggling alerts for services or hosts."
27  - All actions require the I(host) parameter to be given explicitly. In playbooks you can use the C({{inventory_hostname}}) variable to refer
28    to the host the playbook is currently running on.
29  - You can specify multiple services at once by separating them with commas, .e.g., C(services=httpd,nfs,puppet).
30  - When specifying what service to handle there is a special service value, I(host), which will handle alerts/downtime for the I(host itself),
31    e.g., C(service=host). This keyword may not be given with other services at the same time.
32    I(Setting alerts/downtime for a host does not affect alerts/downtime for any of the services running on it.) To schedule downtime for all
33    services on particular host use keyword "all", e.g., C(service=all).
34  - When using the C(nagios) module you will need to specify your Nagios server using the C(delegate_to) parameter.
35version_added: "0.7"
36options:
37  action:
38    description:
39      - Action to take.
40      - servicegroup options were added in 2.0.
41      - delete_downtime options were added in 2.2.
42    required: true
43    choices: [ "downtime", "delete_downtime", "enable_alerts", "disable_alerts", "silence", "unsilence",
44               "silence_nagios", "unsilence_nagios", "command", "servicegroup_service_downtime",
45               "servicegroup_host_downtime" ]
46  host:
47    description:
48      - Host to operate on in Nagios.
49  cmdfile:
50    description:
51      - Path to the nagios I(command file) (FIFO pipe).
52        Only required if auto-detection fails.
53    default: auto-detected
54  author:
55    description:
56     - Author to leave downtime comments as.
57       Only usable with the C(downtime) action.
58    default: Ansible
59  comment:
60    version_added: "2.0"
61    description:
62     - Comment for C(downtime) action.
63    default: Scheduling downtime
64  minutes:
65    description:
66      - Minutes to schedule downtime for.
67      - Only usable with the C(downtime) action.
68    type: int
69    default: 30
70  services:
71    description:
72      - What to manage downtime/alerts for. Separate multiple services with commas.
73        C(service) is an alias for C(services).
74        B(Required) option when using the C(downtime), C(enable_alerts), and C(disable_alerts) actions.
75    aliases: [ "service" ]
76    required: true
77  servicegroup:
78    version_added: "2.0"
79    description:
80      - The Servicegroup we want to set downtimes/alerts for.
81        B(Required) option when using the C(servicegroup_service_downtime) amd C(servicegroup_host_downtime).
82  command:
83    description:
84      - The raw command to send to nagios, which
85        should not include the submitted time header or the line-feed
86        B(Required) option when using the C(command) action.
87    required: true
88
89author: "Tim Bielawa (@tbielawa)"
90'''
91
92EXAMPLES = '''
93# set 30 minutes of apache downtime
94- nagios:
95    action: downtime
96    minutes: 30
97    service: httpd
98    host: '{{ inventory_hostname }}'
99
100# schedule an hour of HOST downtime
101- nagios:
102    action: downtime
103    minutes: 60
104    service: host
105    host: '{{ inventory_hostname }}'
106
107# schedule an hour of HOST downtime, with a comment describing the reason
108- nagios:
109    action: downtime
110    minutes: 60
111    service: host
112    host: '{{ inventory_hostname }}'
113    comment: Rebuilding machine
114
115# schedule downtime for ALL services on HOST
116- nagios:
117    action: downtime
118    minutes: 45
119    service: all
120    host: '{{ inventory_hostname }}'
121
122# schedule downtime for a few services
123- nagios:
124    action: downtime
125    services: frob,foobar,qeuz
126    host: '{{ inventory_hostname }}'
127
128# set 30 minutes downtime for all services in servicegroup foo
129- nagios:
130    action: servicegroup_service_downtime
131    minutes: 30
132    servicegroup: foo
133    host: '{{ inventory_hostname }}'
134
135# set 30 minutes downtime for all host in servicegroup foo
136- nagios:
137    action: servicegroup_host_downtime
138    minutes: 30
139    servicegroup: foo
140    host: '{{ inventory_hostname }}'
141
142# delete all downtime for a given host
143- nagios:
144    action: delete_downtime
145    host: '{{ inventory_hostname }}'
146    service: all
147
148# delete all downtime for HOST with a particular comment
149- nagios:
150    action: delete_downtime
151    host: '{{ inventory_hostname }}'
152    service: host
153    comment: Planned maintenance
154
155# enable SMART disk alerts
156- nagios:
157    action: enable_alerts
158    service: smart
159    host: '{{ inventory_hostname }}'
160
161# "two services at once: disable httpd and nfs alerts"
162- nagios:
163    action: disable_alerts
164    service: httpd,nfs
165    host: '{{ inventory_hostname }}'
166
167# disable HOST alerts
168- nagios:
169    action: disable_alerts
170    service: host
171    host: '{{ inventory_hostname }}'
172
173# silence ALL alerts
174- nagios:
175    action: silence
176    host: '{{ inventory_hostname }}'
177
178# unsilence all alerts
179- nagios:
180    action: unsilence
181    host: '{{ inventory_hostname }}'
182
183# SHUT UP NAGIOS
184- nagios:
185    action: silence_nagios
186
187# ANNOY ME NAGIOS
188- nagios:
189    action: unsilence_nagios
190
191# command something
192- nagios:
193    action: command
194    command: DISABLE_FAILURE_PREDICTION
195'''
196
197import time
198import os.path
199import stat
200
201from ansible.module_utils.basic import AnsibleModule
202
203
204######################################################################
205
206def which_cmdfile():
207    locations = [
208        # rhel
209        '/etc/nagios/nagios.cfg',
210        # debian
211        '/etc/nagios3/nagios.cfg',
212        # older debian
213        '/etc/nagios2/nagios.cfg',
214        # bsd, solaris
215        '/usr/local/etc/nagios/nagios.cfg',
216        # groundwork it monitoring
217        '/usr/local/groundwork/nagios/etc/nagios.cfg',
218        # open monitoring distribution
219        '/omd/sites/oppy/tmp/nagios/nagios.cfg',
220        # ???
221        '/usr/local/nagios/etc/nagios.cfg',
222        '/usr/local/nagios/nagios.cfg',
223        '/opt/nagios/etc/nagios.cfg',
224        '/opt/nagios/nagios.cfg',
225        # icinga on debian/ubuntu
226        '/etc/icinga/icinga.cfg',
227        # icinga installed from source (default location)
228        '/usr/local/icinga/etc/icinga.cfg',
229    ]
230
231    for path in locations:
232        if os.path.exists(path):
233            for line in open(path):
234                if line.startswith('command_file'):
235                    return line.split('=')[1].strip()
236
237    return None
238
239######################################################################
240
241
242def main():
243    ACTION_CHOICES = [
244        'downtime',
245        'delete_downtime',
246        'silence',
247        'unsilence',
248        'enable_alerts',
249        'disable_alerts',
250        'silence_nagios',
251        'unsilence_nagios',
252        'command',
253        'servicegroup_host_downtime',
254        'servicegroup_service_downtime',
255    ]
256
257    module = AnsibleModule(
258        argument_spec=dict(
259            action=dict(required=True, default=None, choices=ACTION_CHOICES),
260            author=dict(default='Ansible'),
261            comment=dict(default='Scheduling downtime'),
262            host=dict(required=False, default=None),
263            servicegroup=dict(required=False, default=None),
264            minutes=dict(default=30, type='int'),
265            cmdfile=dict(default=which_cmdfile()),
266            services=dict(default=None, aliases=['service']),
267            command=dict(required=False, default=None),
268        )
269    )
270
271    action = module.params['action']
272    host = module.params['host']
273    servicegroup = module.params['servicegroup']
274    services = module.params['services']
275    cmdfile = module.params['cmdfile']
276    command = module.params['command']
277
278    ##################################################################
279    # Required args per action:
280    # downtime = (minutes, service, host)
281    # (un)silence = (host)
282    # (enable/disable)_alerts = (service, host)
283    # command = command
284    #
285    # AnsibleModule will verify most stuff, we need to verify
286    # 'service' manually.
287
288    ##################################################################
289    if action not in ['command', 'silence_nagios', 'unsilence_nagios']:
290        if not host:
291            module.fail_json(msg='no host specified for action requiring one')
292    ######################################################################
293    if action == 'downtime':
294        # Make sure there's an actual service selected
295        if not services:
296            module.fail_json(msg='no service selected to set downtime for')
297
298    ######################################################################
299    if action == 'delete_downtime':
300        # Make sure there's an actual service selected
301        if not services:
302            module.fail_json(msg='no service selected to set downtime for')
303
304    ######################################################################
305
306    if action in ['servicegroup_service_downtime', 'servicegroup_host_downtime']:
307        # Make sure there's an actual servicegroup selected
308        if not servicegroup:
309            module.fail_json(msg='no servicegroup selected to set downtime for')
310
311    ##################################################################
312    if action in ['enable_alerts', 'disable_alerts']:
313        if not services:
314            module.fail_json(msg='a service is required when setting alerts')
315
316    if action in ['command']:
317        if not command:
318            module.fail_json(msg='no command passed for command action')
319    ##################################################################
320    if not cmdfile:
321        module.fail_json(msg='unable to locate nagios.cfg')
322
323    ##################################################################
324    ansible_nagios = Nagios(module, **module.params)
325    if module.check_mode:
326        module.exit_json(changed=True)
327    else:
328        ansible_nagios.act()
329    ##################################################################
330
331
332######################################################################
333class Nagios(object):
334    """
335    Perform common tasks in Nagios related to downtime and
336    notifications.
337
338    The complete set of external commands Nagios handles is documented
339    on their website:
340
341    http://old.nagios.org/developerinfo/externalcommands/commandlist.php
342
343    Note that in the case of `schedule_svc_downtime`,
344    `enable_svc_notifications`, and `disable_svc_notifications`, the
345    service argument should be passed as a list.
346    """
347
348    def __init__(self, module, **kwargs):
349        self.module = module
350        self.action = kwargs['action']
351        self.author = kwargs['author']
352        self.comment = kwargs['comment']
353        self.host = kwargs['host']
354        self.servicegroup = kwargs['servicegroup']
355        self.minutes = kwargs['minutes']
356        self.cmdfile = kwargs['cmdfile']
357        self.command = kwargs['command']
358
359        if (kwargs['services'] is None) or (kwargs['services'] == 'host') or (kwargs['services'] == 'all'):
360            self.services = kwargs['services']
361        else:
362            self.services = kwargs['services'].split(',')
363
364        self.command_results = []
365
366    def _now(self):
367        """
368        The time in seconds since 12:00:00AM Jan 1, 1970
369        """
370
371        return int(time.time())
372
373    def _write_command(self, cmd):
374        """
375        Write the given command to the Nagios command file
376        """
377
378        if not os.path.exists(self.cmdfile):
379            self.module.fail_json(msg='nagios command file does not exist',
380                                  cmdfile=self.cmdfile)
381        if not stat.S_ISFIFO(os.stat(self.cmdfile).st_mode):
382            self.module.fail_json(msg='nagios command file is not a fifo file',
383                                  cmdfile=self.cmdfile)
384        try:
385            fp = open(self.cmdfile, 'w')
386            fp.write(cmd)
387            fp.flush()
388            fp.close()
389            self.command_results.append(cmd.strip())
390        except IOError:
391            self.module.fail_json(msg='unable to write to nagios command file',
392                                  cmdfile=self.cmdfile)
393
394    def _fmt_dt_str(self, cmd, host, duration, author=None,
395                    comment=None, start=None,
396                    svc=None, fixed=1, trigger=0):
397        """
398        Format an external-command downtime string.
399
400        cmd - Nagios command ID
401        host - Host schedule downtime on
402        duration - Minutes to schedule downtime for
403        author - Name to file the downtime as
404        comment - Reason for running this command (upgrade, reboot, etc)
405        start - Start of downtime in seconds since 12:00AM Jan 1 1970
406          Default is to use the entry time (now)
407        svc - Service to schedule downtime for, omit when for host downtime
408        fixed - Start now if 1, start when a problem is detected if 0
409        trigger - Optional ID of event to start downtime from. Leave as 0 for
410          fixed downtime.
411
412        Syntax: [submitted] COMMAND;<host_name>;[<service_description>]
413        <start_time>;<end_time>;<fixed>;<trigger_id>;<duration>;<author>;
414        <comment>
415        """
416
417        entry_time = self._now()
418        if start is None:
419            start = entry_time
420
421        hdr = "[%s] %s;%s;" % (entry_time, cmd, host)
422        duration_s = (duration * 60)
423        end = start + duration_s
424
425        if not author:
426            author = self.author
427
428        if not comment:
429            comment = self.comment
430
431        if svc is not None:
432            dt_args = [svc, str(start), str(end), str(fixed), str(trigger),
433                       str(duration_s), author, comment]
434        else:
435            # Downtime for a host if no svc specified
436            dt_args = [str(start), str(end), str(fixed), str(trigger),
437                       str(duration_s), author, comment]
438
439        dt_arg_str = ";".join(dt_args)
440        dt_str = hdr + dt_arg_str + "\n"
441
442        return dt_str
443
444    def _fmt_dt_del_str(self, cmd, host, svc=None, start=None, comment=None):
445        """
446        Format an external-command downtime deletion string.
447
448        cmd - Nagios command ID
449        host - Host to remove scheduled downtime from
450        comment - Reason downtime was added (upgrade, reboot, etc)
451        start - Start of downtime in seconds since 12:00AM Jan 1 1970
452        svc - Service to remove downtime for, omit to remove all downtime for the host
453
454        Syntax: [submitted] COMMAND;<host_name>;
455        [<service_desription>];[<start_time>];[<comment>]
456        """
457
458        entry_time = self._now()
459        hdr = "[%s] %s;%s;" % (entry_time, cmd, host)
460
461        if comment is None:
462            comment = self.comment
463
464        dt_del_args = []
465        if svc is not None:
466            dt_del_args.append(svc)
467        else:
468            dt_del_args.append('')
469
470        if start is not None:
471            dt_del_args.append(str(start))
472        else:
473            dt_del_args.append('')
474
475        if comment is not None:
476            dt_del_args.append(comment)
477        else:
478            dt_del_args.append('')
479
480        dt_del_arg_str = ";".join(dt_del_args)
481        dt_del_str = hdr + dt_del_arg_str + "\n"
482
483        return dt_del_str
484
485    def _fmt_notif_str(self, cmd, host=None, svc=None):
486        """
487        Format an external-command notification string.
488
489        cmd - Nagios command ID.
490        host - Host to en/disable notifications on.. A value is not required
491          for global downtime
492        svc - Service to schedule downtime for. A value is not required
493          for host downtime.
494
495        Syntax: [submitted] COMMAND;<host_name>[;<service_description>]
496        """
497
498        entry_time = self._now()
499        notif_str = "[%s] %s" % (entry_time, cmd)
500        if host is not None:
501            notif_str += ";%s" % host
502
503            if svc is not None:
504                notif_str += ";%s" % svc
505
506        notif_str += "\n"
507
508        return notif_str
509
510    def schedule_svc_downtime(self, host, services=None, minutes=30):
511        """
512        This command is used to schedule downtime for a particular
513        service.
514
515        During the specified downtime, Nagios will not send
516        notifications out about the service.
517
518        Syntax: SCHEDULE_SVC_DOWNTIME;<host_name>;<service_description>
519        <start_time>;<end_time>;<fixed>;<trigger_id>;<duration>;<author>;
520        <comment>
521        """
522
523        cmd = "SCHEDULE_SVC_DOWNTIME"
524
525        if services is None:
526            services = []
527
528        for service in services:
529            dt_cmd_str = self._fmt_dt_str(cmd, host, minutes, svc=service)
530            self._write_command(dt_cmd_str)
531
532    def schedule_host_downtime(self, host, minutes=30):
533        """
534        This command is used to schedule downtime for a particular
535        host.
536
537        During the specified downtime, Nagios will not send
538        notifications out about the host.
539
540        Syntax: SCHEDULE_HOST_DOWNTIME;<host_name>;<start_time>;<end_time>;
541        <fixed>;<trigger_id>;<duration>;<author>;<comment>
542        """
543
544        cmd = "SCHEDULE_HOST_DOWNTIME"
545        dt_cmd_str = self._fmt_dt_str(cmd, host, minutes)
546        self._write_command(dt_cmd_str)
547
548    def schedule_host_svc_downtime(self, host, minutes=30):
549        """
550        This command is used to schedule downtime for
551        all services associated with a particular host.
552
553        During the specified downtime, Nagios will not send
554        notifications out about the host.
555
556        SCHEDULE_HOST_SVC_DOWNTIME;<host_name>;<start_time>;<end_time>;
557        <fixed>;<trigger_id>;<duration>;<author>;<comment>
558        """
559
560        cmd = "SCHEDULE_HOST_SVC_DOWNTIME"
561        dt_cmd_str = self._fmt_dt_str(cmd, host, minutes)
562        self._write_command(dt_cmd_str)
563
564    def delete_host_downtime(self, host, services=None, comment=None):
565        """
566        This command is used to remove scheduled downtime for a particular
567        host.
568
569        Syntax: DEL_DOWNTIME_BY_HOST_NAME;<host_name>;
570        [<service_desription>];[<start_time>];[<comment>]
571        """
572
573        cmd = "DEL_DOWNTIME_BY_HOST_NAME"
574
575        if services is None:
576            dt_del_cmd_str = self._fmt_dt_del_str(cmd, host, comment=comment)
577            self._write_command(dt_del_cmd_str)
578        else:
579            for service in services:
580                dt_del_cmd_str = self._fmt_dt_del_str(cmd, host, svc=service, comment=comment)
581                self._write_command(dt_del_cmd_str)
582
583    def schedule_hostgroup_host_downtime(self, hostgroup, minutes=30):
584        """
585        This command is used to schedule downtime for all hosts in a
586        particular hostgroup.
587
588        During the specified downtime, Nagios will not send
589        notifications out about the hosts.
590
591        Syntax: SCHEDULE_HOSTGROUP_HOST_DOWNTIME;<hostgroup_name>;<start_time>;
592        <end_time>;<fixed>;<trigger_id>;<duration>;<author>;<comment>
593        """
594
595        cmd = "SCHEDULE_HOSTGROUP_HOST_DOWNTIME"
596        dt_cmd_str = self._fmt_dt_str(cmd, hostgroup, minutes)
597        self._write_command(dt_cmd_str)
598
599    def schedule_hostgroup_svc_downtime(self, hostgroup, minutes=30):
600        """
601        This command is used to schedule downtime for all services in
602        a particular hostgroup.
603
604        During the specified downtime, Nagios will not send
605        notifications out about the services.
606
607        Note that scheduling downtime for services does not
608        automatically schedule downtime for the hosts those services
609        are associated with.
610
611        Syntax: SCHEDULE_HOSTGROUP_SVC_DOWNTIME;<hostgroup_name>;<start_time>;
612        <end_time>;<fixed>;<trigger_id>;<duration>;<author>;<comment>
613        """
614
615        cmd = "SCHEDULE_HOSTGROUP_SVC_DOWNTIME"
616        dt_cmd_str = self._fmt_dt_str(cmd, hostgroup, minutes)
617        self._write_command(dt_cmd_str)
618
619    def schedule_servicegroup_host_downtime(self, servicegroup, minutes=30):
620        """
621        This command is used to schedule downtime for all hosts in a
622        particular servicegroup.
623
624        During the specified downtime, Nagios will not send
625        notifications out about the hosts.
626
627        Syntax: SCHEDULE_SERVICEGROUP_HOST_DOWNTIME;<servicegroup_name>;
628        <start_time>;<end_time>;<fixed>;<trigger_id>;<duration>;<author>;
629        <comment>
630        """
631
632        cmd = "SCHEDULE_SERVICEGROUP_HOST_DOWNTIME"
633        dt_cmd_str = self._fmt_dt_str(cmd, servicegroup, minutes)
634        self._write_command(dt_cmd_str)
635
636    def schedule_servicegroup_svc_downtime(self, servicegroup, minutes=30):
637        """
638        This command is used to schedule downtime for all services in
639        a particular servicegroup.
640
641        During the specified downtime, Nagios will not send
642        notifications out about the services.
643
644        Note that scheduling downtime for services does not
645        automatically schedule downtime for the hosts those services
646        are associated with.
647
648        Syntax: SCHEDULE_SERVICEGROUP_SVC_DOWNTIME;<servicegroup_name>;
649        <start_time>;<end_time>;<fixed>;<trigger_id>;<duration>;<author>;
650        <comment>
651        """
652
653        cmd = "SCHEDULE_SERVICEGROUP_SVC_DOWNTIME"
654        dt_cmd_str = self._fmt_dt_str(cmd, servicegroup, minutes)
655        self._write_command(dt_cmd_str)
656
657    def disable_host_svc_notifications(self, host):
658        """
659        This command is used to prevent notifications from being sent
660        out for all services on the specified host.
661
662        Note that this command does not disable notifications from
663        being sent out about the host.
664
665        Syntax: DISABLE_HOST_SVC_NOTIFICATIONS;<host_name>
666        """
667
668        cmd = "DISABLE_HOST_SVC_NOTIFICATIONS"
669        notif_str = self._fmt_notif_str(cmd, host)
670        self._write_command(notif_str)
671
672    def disable_host_notifications(self, host):
673        """
674        This command is used to prevent notifications from being sent
675        out for the specified host.
676
677        Note that this command does not disable notifications for
678        services associated with this host.
679
680        Syntax: DISABLE_HOST_NOTIFICATIONS;<host_name>
681        """
682
683        cmd = "DISABLE_HOST_NOTIFICATIONS"
684        notif_str = self._fmt_notif_str(cmd, host)
685        self._write_command(notif_str)
686
687    def disable_svc_notifications(self, host, services=None):
688        """
689        This command is used to prevent notifications from being sent
690        out for the specified service.
691
692        Note that this command does not disable notifications from
693        being sent out about the host.
694
695        Syntax: DISABLE_SVC_NOTIFICATIONS;<host_name>;<service_description>
696        """
697
698        cmd = "DISABLE_SVC_NOTIFICATIONS"
699
700        if services is None:
701            services = []
702
703        for service in services:
704            notif_str = self._fmt_notif_str(cmd, host, svc=service)
705            self._write_command(notif_str)
706
707    def disable_servicegroup_host_notifications(self, servicegroup):
708        """
709        This command is used to prevent notifications from being sent
710        out for all hosts in the specified servicegroup.
711
712        Note that this command does not disable notifications for
713        services associated with hosts in this service group.
714
715        Syntax: DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS;<servicegroup_name>
716        """
717
718        cmd = "DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS"
719        notif_str = self._fmt_notif_str(cmd, servicegroup)
720        self._write_command(notif_str)
721
722    def disable_servicegroup_svc_notifications(self, servicegroup):
723        """
724        This command is used to prevent notifications from being sent
725        out for all services in the specified servicegroup.
726
727        Note that this does not prevent notifications from being sent
728        out about the hosts in this servicegroup.
729
730        Syntax: DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS;<servicegroup_name>
731        """
732
733        cmd = "DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS"
734        notif_str = self._fmt_notif_str(cmd, servicegroup)
735        self._write_command(notif_str)
736
737    def disable_hostgroup_host_notifications(self, hostgroup):
738        """
739        Disables notifications for all hosts in a particular
740        hostgroup.
741
742        Note that this does not disable notifications for the services
743        associated with the hosts in the hostgroup - see the
744        DISABLE_HOSTGROUP_SVC_NOTIFICATIONS command for that.
745
746        Syntax: DISABLE_HOSTGROUP_HOST_NOTIFICATIONS;<hostgroup_name>
747        """
748
749        cmd = "DISABLE_HOSTGROUP_HOST_NOTIFICATIONS"
750        notif_str = self._fmt_notif_str(cmd, hostgroup)
751        self._write_command(notif_str)
752
753    def disable_hostgroup_svc_notifications(self, hostgroup):
754        """
755        Disables notifications for all services associated with hosts
756        in a particular hostgroup.
757
758        Note that this does not disable notifications for the hosts in
759        the hostgroup - see the DISABLE_HOSTGROUP_HOST_NOTIFICATIONS
760        command for that.
761
762        Syntax: DISABLE_HOSTGROUP_SVC_NOTIFICATIONS;<hostgroup_name>
763        """
764
765        cmd = "DISABLE_HOSTGROUP_SVC_NOTIFICATIONS"
766        notif_str = self._fmt_notif_str(cmd, hostgroup)
767        self._write_command(notif_str)
768
769    def enable_host_notifications(self, host):
770        """
771        Enables notifications for a particular host.
772
773        Note that this command does not enable notifications for
774        services associated with this host.
775
776        Syntax: ENABLE_HOST_NOTIFICATIONS;<host_name>
777        """
778
779        cmd = "ENABLE_HOST_NOTIFICATIONS"
780        notif_str = self._fmt_notif_str(cmd, host)
781        self._write_command(notif_str)
782
783    def enable_host_svc_notifications(self, host):
784        """
785        Enables notifications for all services on the specified host.
786
787        Note that this does not enable notifications for the host.
788
789        Syntax: ENABLE_HOST_SVC_NOTIFICATIONS;<host_name>
790        """
791
792        cmd = "ENABLE_HOST_SVC_NOTIFICATIONS"
793        notif_str = self._fmt_notif_str(cmd, host)
794        nagios_return = self._write_command(notif_str)
795
796        if nagios_return:
797            return notif_str
798        else:
799            return "Fail: could not write to the command file"
800
801    def enable_svc_notifications(self, host, services=None):
802        """
803        Enables notifications for a particular service.
804
805        Note that this does not enable notifications for the host.
806
807        Syntax: ENABLE_SVC_NOTIFICATIONS;<host_name>;<service_description>
808        """
809
810        cmd = "ENABLE_SVC_NOTIFICATIONS"
811
812        if services is None:
813            services = []
814
815        nagios_return = True
816        return_str_list = []
817        for service in services:
818            notif_str = self._fmt_notif_str(cmd, host, svc=service)
819            nagios_return = self._write_command(notif_str) and nagios_return
820            return_str_list.append(notif_str)
821
822        if nagios_return:
823            return return_str_list
824        else:
825            return "Fail: could not write to the command file"
826
827    def enable_hostgroup_host_notifications(self, hostgroup):
828        """
829        Enables notifications for all hosts in a particular hostgroup.
830
831        Note that this command does not enable notifications for
832        services associated with the hosts in this hostgroup.
833
834        Syntax: ENABLE_HOSTGROUP_HOST_NOTIFICATIONS;<hostgroup_name>
835        """
836
837        cmd = "ENABLE_HOSTGROUP_HOST_NOTIFICATIONS"
838        notif_str = self._fmt_notif_str(cmd, hostgroup)
839        nagios_return = self._write_command(notif_str)
840
841        if nagios_return:
842            return notif_str
843        else:
844            return "Fail: could not write to the command file"
845
846    def enable_hostgroup_svc_notifications(self, hostgroup):
847        """
848        Enables notifications for all services that are associated
849        with hosts in a particular hostgroup.
850
851        Note that this does not enable notifications for the hosts in
852        this hostgroup.
853
854        Syntax: ENABLE_HOSTGROUP_SVC_NOTIFICATIONS;<hostgroup_name>
855        """
856
857        cmd = "ENABLE_HOSTGROUP_SVC_NOTIFICATIONS"
858        notif_str = self._fmt_notif_str(cmd, hostgroup)
859        nagios_return = self._write_command(notif_str)
860
861        if nagios_return:
862            return notif_str
863        else:
864            return "Fail: could not write to the command file"
865
866    def enable_servicegroup_host_notifications(self, servicegroup):
867        """
868        Enables notifications for all hosts that have services that
869        are members of a particular servicegroup.
870
871        Note that this command does not enable notifications for
872        services associated with the hosts in this servicegroup.
873
874        Syntax: ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS;<servicegroup_name>
875        """
876
877        cmd = "ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS"
878        notif_str = self._fmt_notif_str(cmd, servicegroup)
879        nagios_return = self._write_command(notif_str)
880
881        if nagios_return:
882            return notif_str
883        else:
884            return "Fail: could not write to the command file"
885
886    def enable_servicegroup_svc_notifications(self, servicegroup):
887        """
888        Enables notifications for all services that are members of a
889        particular servicegroup.
890
891        Note that this does not enable notifications for the hosts in
892        this servicegroup.
893
894        Syntax: ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS;<servicegroup_name>
895        """
896
897        cmd = "ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS"
898        notif_str = self._fmt_notif_str(cmd, servicegroup)
899        nagios_return = self._write_command(notif_str)
900
901        if nagios_return:
902            return notif_str
903        else:
904            return "Fail: could not write to the command file"
905
906    def silence_host(self, host):
907        """
908        This command is used to prevent notifications from being sent
909        out for the host and all services on the specified host.
910
911        This is equivalent to calling disable_host_svc_notifications
912        and disable_host_notifications.
913
914        Syntax: DISABLE_HOST_SVC_NOTIFICATIONS;<host_name>
915        Syntax: DISABLE_HOST_NOTIFICATIONS;<host_name>
916        """
917
918        cmd = [
919            "DISABLE_HOST_SVC_NOTIFICATIONS",
920            "DISABLE_HOST_NOTIFICATIONS"
921        ]
922        nagios_return = True
923        return_str_list = []
924        for c in cmd:
925            notif_str = self._fmt_notif_str(c, host)
926            nagios_return = self._write_command(notif_str) and nagios_return
927            return_str_list.append(notif_str)
928
929        if nagios_return:
930            return return_str_list
931        else:
932            return "Fail: could not write to the command file"
933
934    def unsilence_host(self, host):
935        """
936        This command is used to enable notifications for the host and
937        all services on the specified host.
938
939        This is equivalent to calling enable_host_svc_notifications
940        and enable_host_notifications.
941
942        Syntax: ENABLE_HOST_SVC_NOTIFICATIONS;<host_name>
943        Syntax: ENABLE_HOST_NOTIFICATIONS;<host_name>
944        """
945
946        cmd = [
947            "ENABLE_HOST_SVC_NOTIFICATIONS",
948            "ENABLE_HOST_NOTIFICATIONS"
949        ]
950        nagios_return = True
951        return_str_list = []
952        for c in cmd:
953            notif_str = self._fmt_notif_str(c, host)
954            nagios_return = self._write_command(notif_str) and nagios_return
955            return_str_list.append(notif_str)
956
957        if nagios_return:
958            return return_str_list
959        else:
960            return "Fail: could not write to the command file"
961
962    def silence_nagios(self):
963        """
964        This command is used to disable notifications for all hosts and services
965        in nagios.
966
967        This is a 'SHUT UP, NAGIOS' command
968        """
969        cmd = 'DISABLE_NOTIFICATIONS'
970        self._write_command(self._fmt_notif_str(cmd))
971
972    def unsilence_nagios(self):
973        """
974        This command is used to enable notifications for all hosts and services
975        in nagios.
976
977        This is a 'OK, NAGIOS, GO'' command
978        """
979        cmd = 'ENABLE_NOTIFICATIONS'
980        self._write_command(self._fmt_notif_str(cmd))
981
982    def nagios_cmd(self, cmd):
983        """
984        This sends an arbitrary command to nagios
985
986        It prepends the submitted time and appends a \n
987
988        You just have to provide the properly formatted command
989        """
990
991        pre = '[%s]' % int(time.time())
992
993        post = '\n'
994        cmdstr = '%s %s%s' % (pre, cmd, post)
995        self._write_command(cmdstr)
996
997    def act(self):
998        """
999        Figure out what you want to do from ansible, and then do the
1000        needful (at the earliest).
1001        """
1002        # host or service downtime?
1003        if self.action == 'downtime':
1004            if self.services == 'host':
1005                self.schedule_host_downtime(self.host, self.minutes)
1006            elif self.services == 'all':
1007                self.schedule_host_svc_downtime(self.host, self.minutes)
1008            else:
1009                self.schedule_svc_downtime(self.host,
1010                                           services=self.services,
1011                                           minutes=self.minutes)
1012
1013        elif self.action == 'delete_downtime':
1014            if self.services == 'host':
1015                self.delete_host_downtime(self.host)
1016            elif self.services == 'all':
1017                self.delete_host_downtime(self.host, comment='')
1018            else:
1019                self.delete_host_downtime(self.host, services=self.services)
1020
1021        elif self.action == "servicegroup_host_downtime":
1022            if self.servicegroup:
1023                self.schedule_servicegroup_host_downtime(servicegroup=self.servicegroup, minutes=self.minutes)
1024        elif self.action == "servicegroup_service_downtime":
1025            if self.servicegroup:
1026                self.schedule_servicegroup_svc_downtime(servicegroup=self.servicegroup, minutes=self.minutes)
1027
1028        # toggle the host AND service alerts
1029        elif self.action == 'silence':
1030            self.silence_host(self.host)
1031
1032        elif self.action == 'unsilence':
1033            self.unsilence_host(self.host)
1034
1035        # toggle host/svc alerts
1036        elif self.action == 'enable_alerts':
1037            if self.services == 'host':
1038                self.enable_host_notifications(self.host)
1039            elif self.services == 'all':
1040                self.enable_host_svc_notifications(self.host)
1041            else:
1042                self.enable_svc_notifications(self.host,
1043                                              services=self.services)
1044
1045        elif self.action == 'disable_alerts':
1046            if self.services == 'host':
1047                self.disable_host_notifications(self.host)
1048            elif self.services == 'all':
1049                self.disable_host_svc_notifications(self.host)
1050            else:
1051                self.disable_svc_notifications(self.host,
1052                                               services=self.services)
1053        elif self.action == 'silence_nagios':
1054            self.silence_nagios()
1055
1056        elif self.action == 'unsilence_nagios':
1057            self.unsilence_nagios()
1058
1059        elif self.action == 'command':
1060            self.nagios_cmd(self.command)
1061
1062        # wtf?
1063        else:
1064            self.module.fail_json(msg="unknown action specified: '%s'" %
1065                                      self.action)
1066
1067        self.module.exit_json(nagios_commands=self.command_results,
1068                              changed=True)
1069
1070
1071if __name__ == '__main__':
1072    main()
1073