La période de notification du check est affichée, elle correspond à une période de temps configurée dans l'interface de configuration.
#!/usr/bin/env python#-*-coding:utf-8-*-# Copyright (C) 2012:# Romain Forlot, rforlot@yahoo.com## This file is part of Shinken.## Shinken is free software: you can redistribute it and/or modify# it under the terms of the GNU Affero General Public License as published by# the Free Software Foundation, either version 3 of the License, or# (at your option) any later version.## Shinken is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU Affero General Public License for more details.## You should have received a copy of the GNU Affero General Public License# along with Shinken. If not, see <http://www.gnu.org/licenses/>.
import sysimport loggingimport smtplibimport base64import datetimefrom optparse import OptionParser, OptionGroupfrom email.mime.image import MIMEImagefrom email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartimport jinja2import cgi
# Global varshinken_image_dir = '/var/lib/shinken/modules/webui/htdocs/ui/assets/images'shinken_icon_dir = '/var/lib/shinken/modules/webui/htdocs/img/icons'host_states = ["UP", "DOWN", "DOWN", "UNKNOWN"]check_states = ["OK", "WARNING", "CRITICAL", "UNKNOWN"]
# Set up root loggingdef setup_logging(): log_level = logging.INFO if opts.debug: log_level = logging.DEBUG if opts.logfile: logging.basicConfig(filename=opts.logfile, level=log_level, format='%(asctime)s:%(levelname)s: %(message)s') else: logging.basicConfig(level=log_level, format='%(asctime)s:%(levelname)s: %(message)s')
mail_welcome = 'Monitoring Notification'mail_format = { 'html': MIMEMultipart() }
# Translate a comma separated list of mail recipient into a python listdef make_receivers_list(receivers): if ',' in receivers: ret = receivers.split(',') else: ret = [receivers]
return ret
# This just create mail skeleton and doesn't have any content.def create_mail(): # Fill SMTP header and body. msg = mail_format['html'] logging.debug('From: %s' % opts.sender) msg['From'] = opts.sender logging.debug('To: %s' % (opts.receivers)) msg['To'] = opts.receivers with open(opts.title_tpl) as f: text_tpl = f.read() tpl = jinja2.Template(text_tpl) subject = tpl.render(shinken_var=shinken_var) logging.debug('Subject: %s' % subject) msg['Subject'] = subject
return msg
def add_image(path, mail, cid): with open(path, 'rb') as f: image = MIMEImage(f.read(), 'jpeg', filename="%s.jpg" % cid) image.add_header('Content-ID', '<%s>' % cid) mail.attach(image)
############################################################################## Html creation lair#############################################################################
def create_html_message(msg, template): # Get url and add it in footer with open(template) as f: text_tpl = f.read() tpl = jinja2.Template(text_tpl) html_content = tpl.render(shinken_var=shinken_var, mail_welcome=mail_welcome)
# Make final string var to send and encode it to stdout encoding # avoiding decoding error.
try: html_msg = html_content.encode('utf-8') except UnicodeDecodeError: logging.debug('Content is Unicode encoded.') html_msg = html_content
logging.debug('HTML string: %s' % html_msg)
msgText = MIMEText(html_msg, 'html', 'utf-8') logging.debug('MIMEText: %s' % msgText) msg.attach(msgText) logging.debug('Mail object: %s' % msg)
return msg
if __name__ == "__main__": parser = OptionParser(description='Notify by email receivers of Shinken alerts. Message will be formatted in html and can embed customer logo. To included customer logo, just load png image named customer_logo.png in '+shinken_image_dir)
group_debug = OptionGroup(parser, 'Debugging and test options', 'Useful to debug script under shinken processes. Useful to just make a standalone test of script to see what it looks like.') group_general = OptionGroup(parser, 'General options', 'Default options to setup') group_shinken = OptionGroup(parser, 'Shinken macros to specify.', 'Used to specify usual shinken macros in notifications, if not specified then it will try to get them from environment variable. You need to enable_environment_macros in shinken.cfg if you want to used them. It isn\'t recommended to use environment macros for large environments. You \'d better use options -c and -s or -h depending on which object you\'ll notify for.')
# Debug and test options group_debug.add_option('-D', '--debug', dest='debug', default=False, action='store_true', help='Generate a test mail message') group_debug.add_option('-l', '--logfile', dest='logfile', help='Specify a log file. Default: log to stdout.')
# General options group_general.add_option('-r', '--receivers', dest='receivers', help='Mail recipients comma-separated list') group_general.add_option('-F', '--sender', dest='sender', help='Sender email address, default is system user') group_general.add_option('-S', '--SMTP', dest='smtp', default='localhost', help='Target SMTP hostname. None for just a sendmail lanch. Default: localhost') group_general.add_option('--title-tpl', dest='title_tpl', help='Mail subject template') group_general.add_option('--content-tpl', dest='content_tpl', help='Template for email body')
# Shinken options
group_debug.add_option('--with-images', dest='images', default=False, action='store_true', help='Activates logo and status images in mail. Disabled by default') group_shinken.add_option('--address', dest='address', help='Host network address') group_shinken.add_option('-n', '--notif', dest='notification', help='Notification type, PROBLEM or RECOVERY') group_shinken.add_option('-H', '--hostname', dest='hostname', help='The name of the host') group_shinken.add_option('--url', dest='url', help='The url of the web interface') group_shinken.add_option('--huuid', dest='hostuuid', help='Host UUID') group_shinken.add_option('--last-check', dest='date', help='Date and time of the check') group_shinken.add_option('--state', dest='state', help='Check or host state') group_shinken.add_option('--last-state', dest='laststate', help='Check or host previous state') group_shinken.add_option('--last-change', dest='lastchange', help='Last state change timestamp') group_shinken.add_option('--check', dest='desc', help='Check description') group_shinken.add_option('--output', dest='output', help='Check output') group_shinken.add_option('--long-output', dest='long_output', help='Check long output, if available') group_shinken.add_option('--ack-author', dest='ackauthor', help='Author of the acknowledge') group_shinken.add_option('--ack-data', dest='ackdata', help='Acknowledge comment')
# Shinken WebUI options
parser.add_option_group(group_debug) parser.add_option_group(group_general) parser.add_option_group(group_shinken)
(opts, args) = parser.parse_args()
setup_logging()
# Check and process arguments # # Retrieve and setup shinken macros that make the mail content template = opts.content_tpl shinken_var = {"Notification type": opts.notification, "Host address": opts.address, "Hostname": opts.hostname, "Check date": opts.date, "State": opts.state, "State duration": datetime.datetime.fromtimestamp(int(float(opts.lastchange))).strftime("%d/%m/%Y %H:%M:%S"), "Output": opts.output, "Long output": opts.long_output, "Check name": opts.desc, "View": "%s/static/ui/index.html#/hosts/%s" % (opts.url, opts.hostuuid), "Last state": "", "Logo": "", "Arrow": "", "State logo": "", "Title notification": opts.notification if opts.notification not in ('PROBLEM', 'RECOVERY') else opts.state, "Last state logo": "", "Acknowledge author": opts.ackauthor, "Acknowledge data": opts.ackdata }
if sys.stdin.encoding is not None: encoding = sys.stdin.encoding else: encoding = 'utf-8'
for input in shinken_var.keys(): if shinken_var[input]: shinken_var[input] = shinken_var[input].decode('string_escape').decode(encoding) shinken_var[input] = shinken_var[input].replace('\#', '#') if input not in ("Output", "Long output") and shinken_var[input]: shinken_var[input] = cgi.escape(shinken_var[input]) else: shinken_var[input] = "" print shinken_var['Long output'] shinken_var["Images enabled"] = opts.images if opts.receivers == None: logging.error('You must define at least one mail recipient using -r') sys.exit(5) else: contactemail = opts.receivers receivers = make_receivers_list(opts.receivers)
# IMAGES
if opts.images: with open(shinken_image_dir + '/logos/enterprise-black.png', 'rb') as f: shinken_var['Logo'] = base64.b64encode(f.read()) with open(shinken_icon_dir + '/arrow.png', 'rb') as f: shinken_var['Arrow'] = base64.b64encode(f.read()) if shinken_var['State'] in ('OK', 'UP'): with open(shinken_icon_dir + '/state_ok_32x32.png', 'rb') as f: shinken_var['State logo'] = base64.b64encode(f.read()) elif shinken_var['State'] == 'WARNING': with open(shinken_icon_dir + '/state_warning_32x32.png', 'rb') as f: shinken_var['State logo'] = base64.b64encode(f.read()) else: with open(shinken_icon_dir + '/state_critical_32x32.png', 'rb') as f: shinken_var['State logo'] = base64.b64encode(f.read()) if opts.laststate == '0': with open(shinken_icon_dir + '/state_ok_32x32.png', 'rb') as f: shinken_var['Last state logo'] = base64.b64encode(f.read()) elif opts.laststate == '1' and shinken_var['Check name'] : with open(shinken_icon_dir + '/state_warning_32x32.png', 'rb') as f: shinken_var['Last state logo'] = base64.b64encode(f.read()) elif opts.laststate == '3' and shinken_var['Check name'] : with open(shinken_icon_dir + '/state_unknown_32x32.png', 'rb') as f: shinken_var['Last state logo'] = base64.b64encode(f.read()) else: with open(shinken_icon_dir + '/state_critical_32x32.png', 'rb') as f: shinken_var['Last state logo'] = base64.b64encode(f.read()) else : if shinken_var['Check name']: shinken_var['Last state'] = check_states[int(opts.laststate)] else: shinken_var['Last state'] = host_states[int(opts.laststate)]
logging.debug('Create mail skeleton') mail = create_mail() logging.debug('Create mail content')
for state in ('State', 'Last state'): if shinken_var[state] in ('CRITICAL', 'DOWN'): shinken_var[state] = u"<span style='color:#dc2020;'>[CRITICAL]</span>" elif shinken_var[state] in ('OK', 'UP'): shinken_var[state] = u"<span style='color:#2a9a3d;'>[OK]</span>" elif shinken_var[state] == 'WARNING': shinken_var[state] = u"<span style='color:#e48c19;'>[WARNING]</span>"
mail = create_html_message(mail, template)
# Use SMTP or sendmail to send the mail ...
logging.debug('Connect to %s smtp server' % (opts.smtp)) smtp = smtplib.SMTP(opts.smtp) logging.debug('Send the mail') smtp.sendmail(opts.sender, receivers, mail.as_string()) logging.info("Mail sent successfully")