├── .gitignore ├── LICENSE ├── README.md └── mattermost.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .env 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 NDrive Navigation Systems S.A. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Nagios Mattermost Plugin 2 | ======================== 3 | 4 | A plugin for [Nagios](https://www.nagios.org/) and compatible software (e.g. [Icinga](https://www.icinga.org/)) to enable notifications to a [Mattermost](http://www.mattermost.org/) server. 5 | 6 | ## Plugin Usage 7 | 8 | Run `./mattermost.py --help` for full usage information. 9 | 10 | ## Mattermost Configuration 11 | 12 | 1. *Incoming Webhooks* must be enabled for your Mattermost server. Check the **Enable Incoming Webhooks** option under **Service Settings** in the *System Console*. 13 | 14 | 2. To use the optional `--username` parameter you must enable overriding of usernames from webhooks. Check the **Enable Overriding Usernames from Webhooks and Slash Commands** option under **Service Settings** in the *System Console*. 15 | 16 | 3. To use the optional `--iconurl` parameter you must enable overriding of icons from webhooks. Check the **Enable Overriding Icon from Webhooks and Slash Commands** option under **Service Settings** in the *System Console*. 17 | 18 | ## Nagios Configuration 19 | 20 | The steps below are for a Nagios 4 server but should work with minimal modifications for compatible software: 21 | 22 | 1. Copy `mattermost.py` to `/usr/local/nagios/libexec`. 23 | 24 | 2. Create an *Incoming Webhook* integration for the approriate team and note the provided URL. 25 | 26 | 3. Create the command definitions in your Nagios configuration: 27 | 28 | ``` 29 | define command { 30 | command_name notify-service-by-mattermost 31 | command_line /usr/local/nagios/libexec/mattermost.py --url [MATTERMOST-WEBHOOK-URL] \ 32 | --channel [OPTIONAL-MATTERMOST-CHANNEL] \ 33 | --notificationtype "$NOTIFICATIONTYPE$" \ 34 | --hostalias "$HOSTNAME$" \ 35 | --hostaddress "$HOSTADDRESS$" \ 36 | --servicedesc "$SERVICEDESC$" \ 37 | --servicestate "$SERVICESTATE$" \ 38 | --serviceoutput "$SERVICEOUTPUT$" 39 | } 40 | 41 | define command { 42 | command_name notify-host-by-mattermost 43 | command_line /usr/local/nagios/libexec/mattermost.py --url [MATTERMOST-WEBHOOK-URL] \ 44 | --channel [OPTIONAL-MATTERMOST-CHANNEL] \ 45 | --notificationtype "$NOTIFICATIONTYPE$" \ 46 | --hostalias "$HOSTNAME$" \ 47 | --hostaddress "$HOSTADDRESS$" \ 48 | --hoststate "$HOSTSTATE$" \ 49 | --hostoutput "$HOSTOUTPUT$" 50 | } 51 | ``` 52 | 53 | 4. Create the contact definition in your Nagios configuration: 54 | 55 | ``` 56 | define contact { 57 | contact_name mattermost 58 | alias Mattermost 59 | service_notification_period 24x7 60 | host_notification_period 24x7 61 | service_notification_options w,u,c,r 62 | host_notification_options d,r 63 | host_notification_commands notify-host-by-mattermost 64 | service_notification_commands notify-service-by-mattermost 65 | } 66 | ``` 67 | 68 | 5. Add the contact to a contact group in your Nagios configuration: 69 | 70 | ``` 71 | define contactgroup{ 72 | contactgroup_name network-admins 73 | alias Network Administrators 74 | members email, mattermost 75 | } 76 | ``` 77 | -------------------------------------------------------------------------------- /mattermost.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright (c) 2015 NDrive SA 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | import argparse 24 | import json 25 | import urllib2 26 | 27 | VERSION = "0.3.1" 28 | 29 | 30 | def parse(): 31 | parser = argparse.ArgumentParser(description='Sends alerts to Mattermost') 32 | parser.add_argument('--url', help='Incoming Webhook URL', required=True) 33 | parser.add_argument('--channel', help='Channel to notify') 34 | parser.add_argument('--username', help='Username to notify as', 35 | default='Nagios') 36 | parser.add_argument('--iconurl', help='URL of icon to use for username', 37 | default='https://slack.global.ssl.fastly.net/7bf4/img/services/nagios_128.png') # noqa 38 | parser.add_argument('--notificationtype', help='Notification Type', 39 | required=True) 40 | parser.add_argument('--hostalias', help='Host Alias', required=True) 41 | parser.add_argument('--hostaddress', help='Host Address', required=True) 42 | parser.add_argument('--hoststate', help='Host State') 43 | parser.add_argument('--hostoutput', help='Host Output') 44 | parser.add_argument('--servicedesc', help='Service Description') 45 | parser.add_argument('--servicestate', help='Service State') 46 | parser.add_argument('--serviceoutput', help='Service Output') 47 | parser.add_argument('--cgiurl', help='Link to extinfo.cgi on your Nagios instance') 48 | parser.add_argument('--version', action='version', 49 | version='% (prog)s {version}'.format(version=VERSION)) 50 | args = parser.parse_args() 51 | return args 52 | 53 | 54 | def encode_special_characters(text): 55 | text = text.replace("%", "%25") 56 | text = text.replace("&", "%26") 57 | return text 58 | 59 | 60 | def emoji(notificationtype): 61 | return { 62 | "RECOVERY": ":white_check_mark: ", 63 | "PROBLEM": ":fire: ", 64 | "DOWNTIMESTART": ":clock10: ", 65 | "DOWNTIMEEND": ":sunny: " 66 | }.get(notificationtype, "") 67 | 68 | 69 | def text(args): 70 | template_host = "__{notificationtype}__ {hostalias} is {hoststate}\n{hostoutput}" # noqa 71 | template_service = "__{notificationtype}__ {hostalias} at {hostaddress}/{servicedesc} is {servicestate}\n{serviceoutput}" # noqa 72 | if args.hoststate is not None: 73 | template_cgiurl = " [View :link:]({cgiurl}?type=1&host={hostalias})" 74 | elif args.servicestate is not None: 75 | template_cgiurl = " [View :link:]({cgiurl}?type=2&host={hostalias}&service={servicedesc})" 76 | template = template_service if args.servicestate else template_host 77 | 78 | text = emoji(args.notificationtype) + template.format(**vars(args)) 79 | if args.cgiurl is not None: 80 | # If we know the CGI url provide a clickable link to the nagios CGI 81 | text = text + template_cgiurl.format(**vars(args)) 82 | 83 | return encode_special_characters(text) 84 | 85 | 86 | def payload(args): 87 | payload = { 88 | "username": args.username, 89 | "icon_url": args.iconurl, 90 | "text": text(args) 91 | } 92 | 93 | if args.channel: 94 | payload["channel"] = args.channel 95 | 96 | data = "payload=" + json.dumps(payload) 97 | return data 98 | 99 | 100 | def request(url, data): 101 | req = urllib2.Request(url, data) 102 | response = urllib2.urlopen(req) 103 | return response.read() 104 | 105 | 106 | if __name__ == "__main__": 107 | args = parse() 108 | response = request(args.url, payload(args)) 109 | print response 110 | --------------------------------------------------------------------------------