#!/usr/bin/env python3

import argparse
import json
import urllib.parse
import urllib.request
import sys

from icinga_slack import __version__

alert_colors = {'UNKNOWN': '#6600CC',
                'CRITICAL': '#FF0000',
                'WARNING': '#FF9900',
                'OK': '#36A64F'}


class AttachmentField(dict):
    def __init__(self, title, value, short=False):
        self['title'] = title
        self['value'] = value
        self['short'] = short


class AttachmentFieldList(list):
    def __init__(self, *args):
        for count, field in enumerate(args):
            self.append(field)


class Attachment(dict):
    def __init__(self, fallback, fields, text=None, pretext=None, color=None):
        self['fallback'] = fallback
        self['fields'] = fields
        if text:
            self['text'] = text
        if pretext:
            self['pretext'] = pretext
        if color:
            self['color'] = color


class AttachmentList(list):
    def __init__(self, *args):
        for count, attachment in enumerate(args):
            self.append(attachment)


class Message(dict):
    def __init__(self, channel, text, username, mrkdwn_in=["fields"],
                 icon_emoji=":ghost:", attachments=None):
        self['channel'] = channel
        self['text'] = text
        if mrkdwn_in:
            self['mrkdwn_in'] = mrkdwn_in
        if username:
            self['username'] = username
        if icon_emoji:
            self['icon_emoji'] = icon_emoji
        self['attachments'] = AttachmentList()

    def attach(
            self,
            message,
            host,
            level,
            action_url=None,
            notes_url=None,
            status_cgi_url=''
    ):
        fields = AttachmentFieldList()
        fields.append(AttachmentField("Message", message))
        fields.append(AttachmentField(
            "Host", "<{1}?host={0}|{0}>".format(host, status_cgi_url),
            True)
        )
        fields.append(AttachmentField("Level", level, True))
        if action_url:
            fields.append(AttachmentField("Actions URL", action_url, True))
        if notes_url:
            fields.append(AttachmentField("Notes URL", notes_url, True))
        if level in alert_colors.keys():
            color = alert_colors[level]
        else:
            color = alert_colors['UNKNOWN']
        alert_attachment = Attachment(
            fallback="    {0} on {1} is {2}".format(message, host, level),
            color=color,
            fields=fields
        )
        self['attachments'].append(alert_attachment)

    def send(self, webhook_url):
        data = urllib.parse.urlencode({"payload": json.dumps(self)})
        response = urllib.request.urlopen(
            webhook_url,
            data.encode('utf8')
        ).read()
        if response == b'ok':
            return True
        else:
            print("Error: %s" % response)
            return False


def parse_options():
    parser = argparse.ArgumentParser(
        prog="icinga_slack_webhook_notify",
        description="Send an Icinga Alert to Slack.com via a generic webhook integration"
    )
    parser.add_argument(
        '-c', '--channel',
        required=True,
        help="The channel to send the message to"
    )
    parser.add_argument(
        '-m', '--message',
        required=True,
        help="The text of the message to send"
    )
    parser.add_argument(
        '-u', '--web-hook-url',
        required=True,
        help="The webhook URL for your integration"
    )
    parser.add_argument(
        '-A', '--service-action-url',
        default=None,
        help="An optional action_url for this alert {default: None}"
    )
    parser.add_argument(
        '-H', '--host',
        default="UNKNOWN",
        help="An optional host the message relates to {default: UNKNOWN}"
    )
    parser.add_argument(
        '-L', '--level',
        choices=["OK", "WARNING", "CRITICAL", "UNKNOWN"],
        default="UNKNOWN",
        help="An optional alert level {default: UNKNOWN}"
    )
    parser.add_argument(
        '-M', '--header-message',
        default="I have received the following alert:",
        help="A header message sent before the formatted alert {default: I have received the following alert:}"
    )
    parser.add_argument(
        '-N', '--service-notes-url',
        default=None,
        help="An optional notes_url for this alert {default: None}"
    )
    parser.add_argument(
        '-S', '--status-cgi-url',
        default='https://nagios.example.com/cgi-bin/icinga/status.cgi',
        help="The URL of status.cgi for your Nagios/Icinga instance {default: https://nagios.example.com/cgi-bin/icinga/status.cgi}"
    )
    parser.add_argument(
        '-U', '--username',
        default="Icinga",
        help="Username to send the message from {default: Icinga}"
    )
    parser.add_argument(
        '-V', '--version',
        action='version',
        help="Print version information",
        version=__version__
    )

    return parser.parse_args()


def main():
    args = parse_options()
    message = Message(channel=args.c, text=args.M, username=args.U)
    message.attach(message=args.m, host=args.H, level=args.L, action_url=args.A, notes_url=args.N, status_cgi_url=args.S)
    if message.send(webhook_url=args.u):
        sys.exit(0)
    else:
        sys.exit(1)


if __name__ == "__main__":
    main()

@@ -286,16 +286,140 @@
 A64F'%7D%0A%0A
+def abbreviate_url(url):%0A    parsed_url = urllib.parse.urlparse(url)%0A%0A    return %22%3C%7B0%7D%7C%7B1%7D%3E%22.format(url, parsed_url.netloc)%0A
 %0Aclass A

Add a function to abbreviate a URL