Send email alert by script deriving recipient from message field

Script Arguments:

--${event.fields.Category} --${event.fields.ControllerID} --${event.fields.Description} --${event.fields.Event} --${event.fields.EventID} --${event.fields.Severity} --${event.fields.source} --${event.fields.timestamp}

For my purposes, it’s not required to pass any event or backlog fields to the script. Just using script arguments as above.

#!/usr/bin/env python3

import getopt, smtplib, sys

from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

def body_html(evnt_fields):
    table = "background-color:#f9f9f9;border:none;line-height:1.2;width:100%"
    td_odd = "text-align:right;padding-right:20;width:150px"
    td_even = "padding-left:20"
    th = "background-color:#e6e6e6;line-height:1.5"
    try:
        rv = f"""\
    <html>
        <head></head>
        <body>
            <br />
            <table cellpadding="10" cellspacing="0" style="{table}"><tbody>
	        <tr><th colspan="2" style="{th}"><b>Notification about HDD event on host {evnt_fields['source']}<br />{evnt_fields['Event']}</b></th></tr>
                <tr><td style="{td_odd}">Timestamp</td><td style="{td_even}">{evnt_fields['timestamp']}</td></tr>
    	        <tr><td style="{td_odd}">Event</td><td style="{td_even}">[ID{evnt_fields['EventID']}] {evnt_fields['Event']}</td></tr>
    	        <tr><td style="{td_odd}">Severity</td><td style="{td_even}">{evnt_fields['Severity']}</td></tr>
    	        <tr><td style="{td_odd}">Category</td><td style="{td_even}">{evnt_fields['Category']}</td></tr>
	        <tr><td style="{td_odd}">Controller ID</td><td style="{td_even}">{evnt_fields['ControllerID']}</td></tr>
	        <tr><td style="{td_odd}">Full Message</td><td style="{td_even}">{evnt_fields['Description']}</td></tr>
            </tbody></table>
            <br />
        </body>
    </html>"""
    except KeyError:
        pass

    return rv

def body_plain(evnt_fields):
    try:
        rv = f"""

--------------------------------------------------------------------------------------------------------------------------
    Notification about HDD event on host {evnt_fields['source']}
--------------------------------------------------------------------------------------------------------------------------

        Timestamp: {evnt_fields['timestamp']}

        Event: [ID{evnt_fields['EventID']}] {evnt_fields['Event']}
        Severity: {evnt_fields['Severity']}
        Category: {evnt_fields['Category']}

        Controller ID: {evnt_fields['ControllerID']}

        Full Message: {evnt_fields['Description']}

--------------------------------------------------------------------------------------------------------------------------

"""
    except KeyError:
        pass

    return rv

def parse_cmdline_params(argv):
    longopts = ['Category=',
                'ControllerID=',
                'Description=',
                'Event=',
                'EventID=',
                'Office=',
                'Severity=',
                'source=',
                'timestamp=']
    try:
        opts, args = getopt.getopt(args=argv,
                                   shortopts="",
                                   longopts=longopts)
    except getopt.GetoptError:
        sys.exit(2)

    rv = {}
    for opt, arg in opts:
        rv.setdefault(opt[2:], arg)
    return rv

def trigger_email(evnt_fields, relay="localhost"):
    try:
        subject = f"HDD {evnt_fields['Severity']} Event on Host {evnt_fields['source']}"
        msgfrom = f"{evnt_fields['Office'].lower()}_hdd_issue@maildomain.com"
        msgrcpt = f"{evnt_fields['Office'].lower()}_admins@maildomain.com"
    except KeyError:
        sys.exit(3)

    msg = MIMEMultipart("alternative")
    msg['Subject'] = subject
    msg['From'] = msgfrom
    msg['To'] = msgrcpt
    msg.attach(MIMEText(body_plain(evnt_fields), "plain"))
    msg.attach(MIMEText(body_html(evnt_fields), "html"))

    try:
        with smtplib.SMTP(relay) as srv:
            srv.send_message(msg)
    except Exception:
        sys.exit(4)

def main(argv):
    evnt_fields = parse_cmdline_params(argv)
    trigger_email(evnt_fields)
    sys.exit(0)

if __name__ == "__main__":
    main(sys.argv[1:])
2 Likes

Extended example:

  • script now reports back errors and notes about successfully sent emails as GELF message to Graylog using python module graypy

  • minor changes

#!/usr/bin/env python3

import getopt
import graypy
import logging
import smtplib
import sys

from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

gelf_logger = 0

def body_html(evnt_fields):
    table = "background-color:#f9f9f9;border:none;line-height:1.2;width:100%"
    td_odd = "text-align:right;padding-right:20;width:150px"
    td_even = "padding-left:20"
    th = "background-color:#e6e6e6;line-height:1.5"
    try:
        rv = f"""\
    <html>
        <head></head>
        <body>
            <br />
            <table cellpadding="10" cellspacing="0" style="{table}"><tbody>
	        <tr><th colspan="2" style="{th};font-weight:bold">Notification about HDD event on host {evnt_fields['source']}</th>
                <th colspan="2" style="{th};font-weight:normal">{evnt_fields['Event']}</th></tr>
                <tr><td style="{td_odd}">Timestamp</td><td style="{td_even}">{evnt_fields['timestamp']}</td></tr>
    	        <tr><td style="{td_odd}">Event</td><td style="{td_even}">[ID{evnt_fields['EventID']}] {evnt_fields['Event']}</td></tr>
                <tr><td style="{td_odd}">Object</td><td style="{td_even}">{evnt_fields['EventOn']}</td></tr>
    	        <tr><td style="{td_odd}">Severity</td><td style="{td_even}">{evnt_fields['Severity']}</td></tr>
    	        <tr><td style="{td_odd}">Category</td><td style="{td_even}">{evnt_fields['Category']}</td></tr>
	        <tr><td style="{td_odd}">Full Message</td><td style="{td_even}">{evnt_fields['Description']}</td></tr>
            </tbody></table>
            <br />
        </body>
    </html>"""
    except KeyError:
        gelf_logger.debug("Exception KeyError in body_html()", exc_info=1)
        sys.exit(10)

    return rv

def body_plain(evnt_fields):
    try:
        rv = f"""

--------------------------------------------------------------------------------------------------------------------------
    Notification about HDD event on host {evnt_fields['source']}
--------------------------------------------------------------------------------------------------------------------------

        Timestamp: {evnt_fields['timestamp']}

        Event: [ID{evnt_fields['EventID']}] {evnt_fields['Event']}
        Object: {evnt_fields['EventOn']}
        Severity: {evnt_fields['Severity']}
        Category: {evnt_fields['Category']}

        Full Message: {evnt_fields['Description']}

--------------------------------------------------------------------------------------------------------------------------

"""
    except KeyError:
        gelf_logger.debug("Exception KeyError in body_plain()", exc_info=1)
        sys.exit(11)

    return rv

def init_logging():
    global gelf_logger
    handler = graypy.GELFTCPHandler("graylog-servername", port)
    gelf_logger = logging.getLogger("Log_to_Graylog")
    gelf_logger.setLevel(logging.DEBUG)
    gelf_logger.addHandler(handler)

def parse_cmdline_params(argv):
    longopts = ['Category=',
                'Description=',
                'Event=',
                'EventID=',
                'EventOn=',
                'Office=',
                'Severity=',
                'source=',
                'timestamp=']
    argvc = []
    for arg in argv:
        argvc.append(arg.replace("\"", ""))
    try:
        opts, args = getopt.getopt(args=argvc,
                                   shortopts="",
                                   longopts=longopts)
    except getopt.GetoptError:
        gelf_logger("Exception getopt.Getopt in parse_cmdline_params()", exc_info=1)
        sys.exit(12)

    rv = {}
    for opt, arg in opts:
        rv.setdefault(opt[2:], arg)
    return rv

def trigger_email(evnt_fields, relay="mailgateway"):
    try:
        subject = f"HDD {evnt_fields['Severity']} Event on Host {evnt_fields['source']}"
        msgfrom = evnt_fields['Office'] + "_hdd_issue@example.com"

        if evnt_fields['Office'] in ("xxx", "xxxidc"):
            msgrcpt = "xxx_admins@example.com"
        else:
            msgrcpt = evnt_fields['Office'] + "_admins@example.com, xxx_admins@example.com"
            if evnt_fields['Office'] == "xxx2":
                msgrcpt = msgrcpt + ", xxx2_admins@example.com"
    except KeyError:
        gelf_logger.debug("Exception KeyError in trigger_email()", exc_info=1)
        sys.exit(13)

    msg = MIMEMultipart("alternative")
    msg['Subject'] = subject
    msg['From'] = msgfrom
    msg['To'] = msgrcpt
    msg.attach(MIMEText(body_plain(evnt_fields), "plain"))
    msg.attach(MIMEText(body_html(evnt_fields), "html"))

    try:
        with smtplib.SMTP(relay) as srv:
            srv.send_message(msg)
    except Exception:
        gelf_logger.debug("Exception in trigger_email()", exc_info=1)
        sys.exit(14)

    return subject, msgrcpt

def main(argv):
    init_logging()
    evnt_fields = parse_cmdline_params(argv)
    subject, msgrcpt = trigger_email(evnt_fields)
    gelf_logger.debug(f"Sucessfully sent email alert with subject {subject} to {msgrcpt}.")
    sys.exit(0)

if __name__ == "__main__":
    main(sys.argv[1:])
2 Likes