← Back to team overview

nagios-charmers team mailing list archive

[Merge] ~aggkolaitis/nagios-charm:extra_contacts into nagios-charm:master

 

Aggelos Kolaitis has proposed merging ~aggkolaitis/nagios-charm:extra_contacts into nagios-charm:master.

Commit message:
Added new configuration option extra_contacts

Requested reviews:
  Canonical IS Reviewers (canonical-is-reviewers)
  Nagios Charm developers (nagios-charmers)

For more details, see:
https://code.launchpad.net/~aggkolaitis/nagios-charm/+git/nagios-charm/+merge/374074

Implemented a new configuration option named `extra_contacts`, which allows us to define extra Nagios administrator contacts. This is useful because it enables integrating Nagios notifications with new platforms (e.g. RocketChat, Slack).

LP: 1827006
-- 
Your team Nagios Charm developers is requested to review the proposed merge of ~aggkolaitis/nagios-charm:extra_contacts into nagios-charm:master.
diff --git a/README.md b/README.md
index a71ef83..81cfce5 100644
--- a/README.md
+++ b/README.md
@@ -73,9 +73,11 @@ Will get you the public IP of the web interface.
 
 - `password` - Password to use for administrative access instead of a generated password.
 
+- `extra_contacts` - List of extra administrator contacts to configure. Useful for integrating with external notification services (e.g. Slack, RocketChat)
+
 ### SSL Configuration
 
-- `ssl` - Determinant configuration for enabling SSL. Valid options are "on", "off", "only". The "only" option disables HTTP traffic on Apache in favor of HTTPS. This setting may cause unexpected behavior with existing nagios charm deployments. 
+- `ssl` - Determinant configuration for enabling SSL. Valid options are "on", "off", "only". The "only" option disables HTTP traffic on Apache in favor of HTTPS. This setting may cause unexpected behavior with existing nagios charm deployments.
 
 - `ssl_cert` - Base64 encoded SSL certificate. Deploys to configured ssl_domain certificate name as `/etc/ssl/certs/{ssl_domain}.pem`.   If left blank, the certificate and key will be autogenerated as self-signed.
 
@@ -104,7 +106,7 @@ If you purchased keys from a certificate authority:
 
 #### Web Interface username/password
 
-Login: nagiosadmin  
+Login: nagiosadmin
 Password: see below
 
 To fetch the Nagios Administrative password you have to retrieve them from
diff --git a/config.yaml b/config.yaml
index 4ce0f18..88d03b8 100644
--- a/config.yaml
+++ b/config.yaml
@@ -105,7 +105,7 @@ options:
         type: string
         default: pageroot@localhost
         description: |
-            Email address used for the admin pager, used by $ADMINPAGER$ in 
+            Email address used for the admin pager, used by $ADMINPAGER$ in
             notification commands.
     enable_pagerduty:
         type: boolean
@@ -168,7 +168,7 @@ options:
         type: string
         description: |
             A string to pass to the Nagios load monitoring command.  Default is
-            to report warning at 5.0, 4.0 and 3.0 averages, critical at 10.0, 
+            to report warning at 5.0, 4.0 and 3.0 averages, critical at 10.0,
             6.0 and 4.0.
     pagerduty_notification_levels:
         default: u,c,r
@@ -206,4 +206,21 @@ options:
             u - Unknown
             w - Warning
             o - OK
-
+    extra_contacts:
+        default: ''
+        type: string
+        description: |
+            Define extra contacts for Nagios. They will be appended in the
+            default administrators contact group. This is useful for adding
+            notification integrations with external services.
+            Contacts are passed as a YAML array, and must have a contact name,
+            a command to be executed for host notifications and a command to
+            be executed for service notifications. These commands may use all
+            relevant Nagios macros ($HOSTNAME$, $SERVICENAME$, etc). Refer to
+            the Nagios documentation for more information.
+            Only [A-Za-z0-9_-] contact names are valid. Be careful with
+            commands, since they are not sanitized.
+            Example
+            - name: contact_name_1
+              host: /custom/command/for/host $HOSTNAME$
+              service: /custom/command/for/service $SERVICENAME$
diff --git a/hooks/templates/contacts-cfg.tmpl b/hooks/templates/contacts-cfg.tmpl
index 24a1372..c937874 100644
--- a/hooks/templates/contacts-cfg.tmpl
+++ b/hooks/templates/contacts-cfg.tmpl
@@ -31,6 +31,39 @@ define contact{
         }
 
 
+###############################################################################
+###############################################################################
+#
+# EXTRA CONTACTS
+#
+###############################################################################
+###############################################################################
+
+{% for contact in extra_contacts %}
+
+define contact{
+        contact_name                    {{ contact.name }}
+        alias                           {{ contact.name }}
+        service_notification_period     24x7
+        host_notification_period        24x7
+        service_notification_options    w,u,c,r
+        host_notification_options       d,r
+        service_notification_commands   notify-service-by-{{ contact.name }}
+        host_notification_commands      notify-host-by-{{ contact.name }}
+        }
+
+
+define command {
+        command_name                    notify-service-by-{{ contact.name }}
+        command_line                    {{ contact.service }}
+}
+
+define command {
+        command_name                    notify-host-by-{{ contact.name }}
+        command_line                    {{ contact.host }}
+}
+
+{% endfor %}
 
 ###############################################################################
 ###############################################################################
@@ -46,6 +79,5 @@ define contact{
 define contactgroup{
         contactgroup_name       admins
         alias                   Nagios Administrators
-        members                 root{% if enable_pagerduty -%}, pagerduty{% endif %}
+        members                 root{% if enable_pagerduty -%}, pagerduty{% endif %}{% for contact in extra_contacts %}, {{ contact.name }}{% endfor %}
         }
-
diff --git a/hooks/upgrade-charm b/hooks/upgrade-charm
index 19e736c..94eaaa2 100755
--- a/hooks/upgrade-charm
+++ b/hooks/upgrade-charm
@@ -12,6 +12,7 @@ import stat
 import errno
 import shutil
 import subprocess
+import yaml
 from charmhelpers.contrib import ssl
 from charmhelpers.core import hookenv, host
 from charmhelpers import fetch
@@ -52,6 +53,53 @@ def warn_legacy_relations():
                 "WARNING")
 
 
+# Parses a list of extra Nagios contacts from a YAML string
+# Does basic sanitization only
+def get_extra_contacts(yaml_string, log=False):
+    # Final result
+    extra_contacts = []
+
+    # Valid characters for contact names
+    valid_name_chars = (
+        'abcdefghijklmnopqrstuvwxyz'
+        'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+        '0123456789_-'
+    )
+
+    try:
+        extra_contacts_raw = yaml.load(yaml_string, Loader=yaml.Loader) or []
+        if not isinstance(extra_contacts_raw, list):
+            raise ValueError('not a list')
+
+        required_fields = ['name', 'host', 'service']
+        for contact in extra_contacts_raw:
+            if {'name', 'host', 'service'} > set(contact.keys()):
+                if log:
+                    hookenv.log(
+                        'Contact {} is missing fields.'.format(contact))
+                continue
+
+            if not (set(contact['name']) < set(valid_name_chars)):
+                if log:
+                    hookenv.log(
+                        'Contact name {} is illegal'.format(contact['name']))
+                continue
+
+            if '\n' in (contact['host'] + contact['service']):
+                if log:
+                    hookenv.log('Line breaks not allowed in commands')
+                continue
+
+            extra_contacts.append(contact)
+
+    except ValueError as e:
+        if log:
+            hookenv.log(
+                'Invalid "extra_contacts" configuration: {}'.format(e))
+
+    return extra_contacts
+
+
 # If the charm has extra configuration provided, write that to the
 # proper nagios3 configuration file, otherwise remove the config
 def write_extra_config():
@@ -160,9 +208,14 @@ def enable_pagerduty_config():
         if os.path.isfile(pagerduty_cron):
             os.remove(pagerduty_cron)
 
+    # Parse extra_contacts
+    extra_contacts = get_extra_contacts(
+        hookenv.config('extra_contacts'), log=True)
+
     # Update contacts for admin
     template_values = {'enable_pagerduty': enable_pagerduty,
-                       'admin_email': hookenv.config('admin_email')}
+                       'admin_email': hookenv.config('admin_email'),
+                       'extra_contacts': extra_contacts}
 
     with open('hooks/templates/contacts-cfg.tmpl', 'r') as f:
         templateDef = f.read()

References