def extend_context(context): if context.get('PARAMETER_2'): context["PARAMETER_URL_PREFIX"] = context["PARAMETER_2"] context["LINKEDHOSTNAME"] = utils.format_link('<a href="%s">%s</a>', utils.host_url_from_context(context), context["HOSTNAME"]) context["LINKEDSERVICEDESC"] = utils.format_link('<a href="%s">%s</a>', utils.service_url_from_context(context), context.get("SERVICEDESC", '')) event_template_txt, event_template_html = event_templates(context["NOTIFICATIONTYPE"]) context["EVENT_TXT"] = utils.substitute_context( event_template_txt.replace("@", context["WHAT"]), context) context["EVENT_HTML"] = utils.substitute_context( event_template_html.replace("@", context["WHAT"]), context) if "HOSTOUTPUT" in context: context["HOSTOUTPUT_HTML"] = utils.format_plugin_output(context["HOSTOUTPUT"]) if context["WHAT"] == "SERVICE": context["SERVICEOUTPUT_HTML"] = utils.format_plugin_output(context["SERVICEOUTPUT"]) long_serviceoutput = context["LONGSERVICEOUTPUT"]\ .replace('\\n', '<br>')\ .replace('\n', '<br>') context["LONGSERVICEOUTPUT_HTML"] = utils.format_plugin_output(long_serviceoutput) # Compute the subject of the mail if context['WHAT'] == 'HOST': tmpl = context.get('PARAMETER_HOST_SUBJECT') or TMPL_HOST_SUBJECT context['SUBJECT'] = utils.substitute_context(tmpl, context) else: tmpl = context.get('PARAMETER_SERVICE_SUBJECT') or TMPL_SERVICE_SUBJECT context['SUBJECT'] = utils.substitute_context(tmpl, context)
def construct_content( context: dict[str, str], is_bulk: bool = False, notification_number: int = 1) -> tuple[str, str, AttachmentList]: # A list of optional information is configurable via the parameter "elements" # (new configuration style) # Note: The value PARAMETER_ELEMENTSS is NO TYPO. # Have a look at the function events.py:add_to_event_context(..) if "PARAMETER_ELEMENTSS" in context: elements = context["PARAMETER_ELEMENTSS"].split() else: elements = ["perfdata", "graph", "abstime", "address", "longoutput"] if is_bulk and "graph" in elements: notifications_with_graphs = context[ "PARAMETER_NOTIFICATIONS_WITH_GRAPHS"] if notification_number > int(notifications_with_graphs): elements.remove("graph") # Prepare the mail contents template_txt, template_html = body_templates( context["WHAT"].lower(), "ALERTHANDLEROUTPUT" in context, elements, BODY_ELEMENTS, ) content_txt = utils.substitute_context(template_txt, context) content_html = utils.substitute_context(template_html, context) attachments: AttachmentList = [] if "graph" in elements and "ALERTHANDLEROUTPUT" not in context: # Add Checkmk graphs try: attachments, graph_code = render_performance_graphs( context, is_bulk) content_html += graph_code except Exception as e: sys.stderr.write( "Failed to add graphs to mail. Continue without them. (%s)\n" % e) extra_html_section = "" if "PARAMETER_INSERT_HTML_SECTION" in context: extra_html_section = context["PARAMETER_INSERT_HTML_SECTION"] content_html = ( utils.substitute_context(tmpl_head_html(extra_html_section), context) + content_html + utils.substitute_context(TMPL_FOOT_HTML, context)) return content_txt, content_html, attachments
def get_subject(context): s = context["HOSTNAME"] if context["WHAT"] != "HOST": s += "/" + context["SERVICEDESC"] s += " " notification_type = context["NOTIFICATIONTYPE"] if notification_type in ["PROBLEM", "RECOVERY"]: s += u"$PREVIOUS@HARDSHORTSTATE$ \u2192 $@SHORTSTATE$" elif notification_type.startswith("FLAP"): if "START" in notification_type: s += "Started Flapping" else: s += "Stopped Flapping ($@SHORTSTATE$)" elif notification_type.startswith("DOWNTIME"): what = notification_type[8:].title() s += "Downtime " + what + " ($@SHORTSTATE$)" elif notification_type == "ACKNOWLEDGEMENT": s += "Acknowledged ($@SHORTSTATE$)" elif notification_type == "CUSTOM": s += "Custom Notification ($@SHORTSTATE$)" else: s += notification_type return utils.substitute_context(s.replace("@", context["WHAT"]), context)
def extend_context(context: dict[str, str]) -> None: if context.get("PARAMETER_2"): context["PARAMETER_URL_PREFIX"] = context["PARAMETER_2"] context["LINKEDHOSTNAME"] = utils.format_link( '<a href="%s">%s</a>', utils.host_url_from_context(context), context["HOSTNAME"]) context["LINKEDSERVICEDESC"] = utils.format_link( '<a href="%s">%s</a>', utils.service_url_from_context(context), context.get("SERVICEDESC", ""), ) event_template_txt, event_template_html = event_templates( context["NOTIFICATIONTYPE"]) context["EVENT_TXT"] = utils.substitute_context( event_template_txt.replace("@", context["WHAT"]), context) context["EVENT_HTML"] = utils.substitute_context( event_template_html.replace("@", context["WHAT"]), context) if "HOSTOUTPUT" in context: context["HOSTOUTPUT_HTML"] = utils.format_plugin_output( context["HOSTOUTPUT"]) if context["WHAT"] == "SERVICE": context["SERVICEOUTPUT_HTML"] = utils.format_plugin_output( context["SERVICEOUTPUT"]) long_serviceoutput = (context["LONGSERVICEOUTPUT"].replace( "\\n", "<br>").replace("\n", "<br>")) context["LONGSERVICEOUTPUT_HTML"] = utils.format_plugin_output( long_serviceoutput) # Compute the subject of the mail if context["WHAT"] == "HOST": tmpl = context.get("PARAMETER_HOST_SUBJECT") or TMPL_HOST_SUBJECT context["SUBJECT"] = utils.substitute_context(tmpl, context) else: tmpl = context.get("PARAMETER_SERVICE_SUBJECT") or TMPL_SERVICE_SUBJECT context["SUBJECT"] = utils.substitute_context(tmpl, context)
def construct_content(context): # A list of optional information is configurable via the parameter "elements" # (new configuration style) # Note: The value PARAMETER_ELEMENTSS is NO TYPO. # Have a look at the function events.py:add_to_event_context(..) if "PARAMETER_ELEMENTSS" in context: elements = context["PARAMETER_ELEMENTSS"].split() else: elements = ["perfdata", "graph", "abstime", "address", "longoutput"] # Prepare the mail contents template_txt, template_html = body_templates( context['WHAT'].lower(), "ALERTHANDLEROUTPUT" in context, elements, BODY_ELEMENTS, ) content_txt = utils.substitute_context(template_txt, context) content_html = utils.substitute_context(template_html, context) attachments = [] if "graph" in elements and not "ALERTHANDLEROUTPUT" in context: # Add PNP or Check_MK graph try: attachments, graph_code = render_performance_graphs(context) content_html += graph_code except Exception as e: sys.stderr.write( "Failed to add graphs to mail. Continue without them. (%s)\n" % e) extra_html_section = "" if "PARAMETER_INSERT_HTML_SECTION" in context: extra_html_section = context['PARAMETER_INSERT_HTML_SECTION'] content_html = utils.substitute_context(tmpl_head_html(extra_html_section), context) + \ content_html + \ utils.substitute_context(TMPL_FOOT_HTML, context) return content_txt, content_html, attachments
def render_elements(context, elements): what = context['WHAT'].lower() is_alert_handler = "ALERTHANDLEROUTPUT" in context even = "even" tmpl_txt = "" tmpl_html = "" for name, whence, forced, nottype, title, txt, html in body_elements: if nottype == "alerthandler" and not is_alert_handler: continue if nottype not in ("alerthandler", "all") and is_alert_handler: continue if (whence == "both" or whence == what) and \ (forced or (name in elements)): tmpl_txt += "%-20s %s\n" % (title + ":", txt) tmpl_html += '<tr class="%s0"><td class=left>%s</td><td>%s</td></tr>' % (even, title, html) even = 'odd' if even == 'even' else 'even' return utils.substitute_context(tmpl_txt, context), \ utils.substitute_context(tmpl_html, context)
def get_text(context): s = "" s += "$@OUTPUT$" if "PARAMETER_URL_PREFIX" in context: utils.extend_context_with_link_urls(context, '<a href="%s">%s</a>') s += " <i>Link: </i>" s += context["LINKEDHOSTNAME"] if context["WHAT"] != "HOST": s += context["LINKEDSERVICEDESC"] return utils.substitute_context(s.replace("@", context["WHAT"]), context)
def get_text(context): s = "" s += "$@OUTPUT$" if "PARAMETER_URL_PREFIX" in context: s += " <i>Link: </i>" s += utils.format_link('<a href="%s">%s</a>', utils.host_url_from_context(context), context["HOSTNAME"]) if context["WHAT"] != "HOST": s += utils.format_link('<a href="%s">%s</a>', utils.service_url_from_context(context), context["SERVICEDESC"]) return utils.substitute_context(s.replace("@", context["WHAT"]), context)
def main(): context = utils.collect_context() priority = u'P3' # type: Optional[Text] teams_list = [] tags_list = None action_list = None if 'PARAMETER_PASSWORD' not in context: sys.stderr.write("API key not set\n") return 2 key = retrieve_from_passwordstore(context['PARAMETER_PASSWORD']) note_created = 'Alert created by Check_MK' or context.get( 'PARAMETER_NOTE_CREATED') note_closed = 'Alert closed by Check_MK' or context.get( 'PARAMETER_NOTE_CLOSED') priority = context.get('PARAMETER_PRIORITY') alert_source = context.get('PARAMETER_SOURCE') owner = context.get('PARAMETER_OWNER') entity_value = context.get('PARAMETER_ENTITY') host_url = context.get("PARAMETER_URL") if context.get('PARAMETER_TAGSS'): tags_list = None or context.get('PARAMETER_TAGSS', u'').split(" ") if context.get('PARAMETER_ACTIONSS'): action_list = None or context.get('PARAMETER_ACTIONSS', u'').split(" ") if context.get('PARAMETER_TEAMSS'): for team in context['PARAMETER_TEAMSS'].split(" "): teams_list.append(TeamRecipient(name=str(team), type='team')) if context['WHAT'] == 'HOST': tmpl_host_msg = "Check_MK: $HOSTNAME$ - $HOSTSHORTSTATE$" tmpl_host_desc = """Host: $HOSTNAME$ Event: $EVENT_TXT$ Output: $HOSTOUTPUT$ Perfdata: $HOSTPERFDATA$ $LONGHOSTOUTPUT$ """ desc = context.get('PARAMETER_HOST_DESC') or tmpl_host_desc msg = context.get('PARAMETER_HOST_MSG') or tmpl_host_msg alias = 'HOST_PROBLEM_ID: %s' % context['HOSTPROBLEMID'] ack_author = context['HOSTACKAUTHOR'] ack_comment = context['HOSTACKCOMMENT'] else: tmpl_svc_msg = 'Check_MK: $HOSTNAME$/$SERVICEDESC$ $SERVICESHORTSTATE$' tmpl_svc_desc = """Host: $HOSTNAME$ Service: $SERVICEDESC$ Event: $EVENT_TXT$ Output: $SERVICEOUTPUT$ Perfdata: $SERVICEPERFDATA$ $LONGSERVICEOUTPUT$ """ desc = context.get('PARAMETER_SVC_DESC') or tmpl_svc_desc msg = context.get('PARAMETER_SVC_MSG') or tmpl_svc_msg alias = 'SVC_PROBLEM_ID: %s' % context['SERVICEPROBLEMID'] ack_author = context['SERVICEACKAUTHOR'] ack_comment = context['SERVICEACKCOMMENT'] desc = utils.substitute_context(desc, context) msg = utils.substitute_context(msg, context) if context['NOTIFICATIONTYPE'] == 'PROBLEM': handle_alert_creation( key, note_created, action_list, desc, alert_source, msg, priority, teams_list, tags_list, alias, owner, entity_value, host_url, ) elif context['NOTIFICATIONTYPE'] == 'RECOVERY': handle_alert_deletion(key, owner, alias, alert_source, note_closed, host_url) elif context['NOTIFICATIONTYPE'] == 'ACKNOWLEDGEMENT': handle_alert_ack(key, ack_author, ack_comment, alias, alert_source, host_url) else: sys.stdout.write( six.ensure_str('Notification type %s not supported\n' % (context['NOTIFICATIONTYPE']))) return 0
def construct_content(context): # A list of optional information is configurable via the parameter "elements" # (new configuration style) # Note: The value PARAMETER_ELEMENTSS is NO TYPO. # Have a look at the function events.py:add_to_event_context(..) if "PARAMETER_ELEMENTSS" in context: elements = context["PARAMETER_ELEMENTSS"].split() else: elements = ["perfdata", "graph", "abstime", "address", "longoutput"] # If argument 2 is given (old style) or the parameter url_prefix is set (new style), # we know the base url to the installation and can add # links to hosts and services. ubercomfortable! if context.get('PARAMETER_2'): context["PARAMETER_URL_PREFIX"] = context["PARAMETER_2"] utils.extend_context_with_link_urls(context, '<a href="%s">%s</a>') # Create a notification summary in a new context variable # Note: This code could maybe move to cmk --notify in order to # make it available every in all notification scripts # We have the following types of notifications: # - Alerts OK -> CRIT # NOTIFICATIONTYPE is "PROBLEM" or "RECOVERY" # - Flapping Started, Ended # NOTIFICATIONTYPE is "FLAPPINGSTART" or "FLAPPINGSTOP" # - Downtimes Started, Ended, Cancelled # NOTIFICATIONTYPE is "DOWNTIMESTART", "DOWNTIMECANCELLED", or "DOWNTIMEEND" # - Acknowledgements # NOTIFICATIONTYPE is "ACKNOWLEDGEMENT" # - Custom notifications # NOTIFICATIONTYPE is "CUSTOM" html_info = "" html_state = '<span class="state$@STATE$">$@STATE$</span>' notification_type = context["NOTIFICATIONTYPE"] if notification_type in ["PROBLEM", "RECOVERY"]: txt_info = "$PREVIOUS@HARDSHORTSTATE$ -> $@SHORTSTATE$" html_info = '<span class="state$PREVIOUS@HARDSTATE$">$PREVIOUS@HARDSTATE$</span> → ' + \ html_state elif notification_type.startswith("FLAP"): if "START" in notification_type: txt_info = "Started Flapping" else: txt_info = "Stopped Flapping ($@SHORTSTATE$)" html_info = "Stopped Flapping (while " + html_state + ")" elif notification_type.startswith("DOWNTIME"): what = notification_type[8:].title() txt_info = "Downtime " + what + " ($@SHORTSTATE$)" html_info = "Downtime " + what + " (while " + html_state + ")" elif notification_type == "ACKNOWLEDGEMENT": txt_info = "Acknowledged ($@SHORTSTATE$)" html_info = "Acknowledged (while " + html_state + ")" elif notification_type == "CUSTOM": txt_info = "Custom Notification ($@SHORTSTATE$)" html_info = "Custom Notification (while " + html_state + ")" else: txt_info = notification_type # Should never happen if not html_info: html_info = txt_info txt_info = utils.substitute_context(txt_info.replace("@", context["WHAT"]), context) context["EVENT_TXT"] = txt_info # Add HTML formated plugin output html_info = utils.substitute_context(html_info.replace("@", context["WHAT"]), context) context["EVENT_HTML"] = html_info if "HOSTOUTPUT" in context: context["HOSTOUTPUT_HTML"] = utils.format_plugin_output(context["HOSTOUTPUT"]) if context["WHAT"] == "SERVICE": context["SERVICEOUTPUT_HTML"] = utils.format_plugin_output(context["SERVICEOUTPUT"]) long_serviceoutput = context["LONGSERVICEOUTPUT"]\ .replace('\\n', '<br>')\ .replace('\n', '<br>') context["LONGSERVICEOUTPUT_HTML"] = utils.format_plugin_output(long_serviceoutput) attachments = [] # Compute the subject of the mail if context['WHAT'] == 'HOST': tmpl = context.get('PARAMETER_HOST_SUBJECT') or tmpl_host_subject context['SUBJECT'] = utils.substitute_context(tmpl, context) else: tmpl = context.get('PARAMETER_SERVICE_SUBJECT') or tmpl_service_subject context['SUBJECT'] = utils.substitute_context(tmpl, context) # Prepare the mail contents content_txt, content_html = render_elements(context, elements) if "graph" in elements and not "ALERTHANDLEROUTPUT" in context: # Add PNP or Check_MK graph try: attachments, graph_code = render_performance_graphs(context) content_html += graph_code except Exception as e: sys.stderr.write("Failed to add graphs to mail. Continue without them. (%s)\n" % e) extra_html_section = "" if "PARAMETER_INSERT_HTML_SECTION" in context: extra_html_section = context['PARAMETER_INSERT_HTML_SECTION'] content_html = utils.substitute_context(tmpl_head_html(extra_html_section), context) + \ content_html + \ utils.substitute_context(tmpl_foot_html, context) return content_txt, content_html, attachments
def main() -> int: context = utils.collect_context() if 'PARAMETER_PASSWORD' not in context: sys.stderr.write("API key not set\n") return 2 api_key = retrieve_from_passwordstore(context['PARAMETER_PASSWORD']) note_created = context.get('PARAMETER_NOTE_CREATED') or 'Alert created by Check_MK' note_closed = context.get('PARAMETER_NOTE_CLOSED') or 'Alert closed by Check_MK' priority = context.get('PARAMETER_PRIORITY', 'P3') entity_value = context.get('PARAMETER_ENTITY', '') alert_source: Optional[str] = context.get('PARAMETER_SOURCE') owner: Optional[str] = context.get('PARAMETER_OWNER') host_url: Optional[str] = context.get("PARAMETER_URL") proxy_url: Optional[str] = context.get("PARAMETER_PROXY_URL") tags_list: List[str] = [] if context.get('PARAMETER_TAGSS'): tags_list = context.get('PARAMETER_TAGSS', u'').split(" ") actions_list: List[str] = [] if context.get('PARAMETER_ACTIONSS'): actions_list = context.get('PARAMETER_ACTIONSS', u'').split(" ") teams_list: List[Optional[Dict[str, str]]] = [] if context.get('PARAMETER_TEAMSS'): for team in context['PARAMETER_TEAMSS'].split(" "): teams_list.append({'name': str(team), 'type': 'team'}) if context['WHAT'] == 'HOST': tmpl_host_msg: str = "Check_MK: $HOSTNAME$ - $HOSTSHORTSTATE$" tmpl_host_desc: str = """Host: $HOSTNAME$ Event: $EVENT_TXT$ Output: $HOSTOUTPUT$ Perfdata: $HOSTPERFDATA$ $LONGHOSTOUTPUT$ """ desc = context.get('PARAMETER_HOST_DESC') or tmpl_host_desc msg = context.get('PARAMETER_HOST_MSG') or tmpl_host_msg alias = 'HOST_PROBLEM_ID: %s' % context['HOSTPROBLEMID'] ack_author = context['HOSTACKAUTHOR'] ack_comment = context['HOSTACKCOMMENT'] else: tmpl_svc_msg = 'Check_MK: $HOSTNAME$/$SERVICEDESC$ $SERVICESHORTSTATE$' tmpl_svc_desc = """Host: $HOSTNAME$ Service: $SERVICEDESC$ Event: $EVENT_TXT$ Output: $SERVICEOUTPUT$ Perfdata: $SERVICEPERFDATA$ $LONGSERVICEOUTPUT$ """ desc = context.get('PARAMETER_SVC_DESC') or tmpl_svc_desc msg = context.get('PARAMETER_SVC_MSG') or tmpl_svc_msg alias = 'SVC_PROBLEM_ID: %s' % context['SERVICEPROBLEMID'] ack_author = context['SERVICEACKAUTHOR'] ack_comment = context['SERVICEACKCOMMENT'] desc = utils.substitute_context(desc, context) msg = utils.substitute_context(msg, context) connector = Connector(api_key, host_url, proxy_url) if context['NOTIFICATIONTYPE'] == 'PROBLEM': return connector.handle_alert_creation( note_created, actions_list, desc, msg, priority, teams_list, tags_list, entity_value, alert_source, alias, owner, ) if context['NOTIFICATIONTYPE'] == 'RECOVERY': return connector.handle_alert_deletion(note_closed, owner, alias, alert_source) if context['NOTIFICATIONTYPE'] == 'ACKNOWLEDGEMENT': return connector.handle_alert_ack(ack_author, ack_comment, alias, alert_source) sys.stdout.write( ensure_str('Notification type %s not supported\n' % (context['NOTIFICATIONTYPE']))) return 0
def main(): context = utils.collect_context() timeout = 10 urgency = 3 impact = 3 ack_state = 0 dtstart_state = 0 dtend_state = 0 for necessary in [ 'PARAMETER_URL', 'PARAMETER_USERNAME', 'PARAMETER_PASSWORD', 'PARAMETER_CALLER' ]: if necessary not in context: sys.stderr.write("%s not set\n" % necessary) return 2 hostname = context['HOSTNAME'] url = context['PARAMETER_URL'] user = context['PARAMETER_USERNAME'] pwd = retrieve_from_passwordstore(context['PARAMETER_PASSWORD']) caller = context['PARAMETER_CALLER'] if 'PARAMETER_TIMEOUT' in context: timeout = float(context['PARAMETER_TIMEOUT']) if 'PARAMETER_URGENCY' in context: urgency = PRIORITY_STATES[context['PARAMETER_URGENCY']] if 'PARAMETER_IMPACT' in context: impact = PRIORITY_STATES[context['PARAMETER_IMPACT']] if 'PARAMETER_ACK_STATE_START' in context: ack_state = COMMAND_STATES[context['PARAMETER_ACK_STATE_START']] if 'PARAMETER_DT_STATE_START' in context: dtstart_state = COMMAND_STATES[context['PARAMETER_DT_STATE_START']] if 'PARAMETER_DT_STATE_END' in context: dtend_state = COMMAND_STATES[context['PARAMETER_DT_STATE_END']] if context['WHAT'] == 'HOST': tmpl_host_short_desc = 'Check_MK: $HOSTNAME$ - $HOSTSHORTSTATE$' tmpl_host_desc = """Host: $HOSTNAME$ Event: $EVENT_TXT$ Output: $HOSTOUTPUT$ Perfdata: $HOSTPERFDATA$ $LONGHOSTOUTPUT$ """ short_desc = context.get( 'PARAMETER_HOST_SHORT_DESC') or tmpl_host_short_desc desc = context.get('PARAMETER_HOST_DESC') or tmpl_host_desc problem_id = context['HOSTPROBLEMID'] ack_author = context['HOSTACKAUTHOR'] ack_comment = context['HOSTACKCOMMENT'] servicename = context['HOSTOUTPUT'] else: tmpl_svc_short_desc = 'Check_MK: $HOSTNAME$/$SERVICEDESC$ $SERVICESHORTSTATE$' tmpl_svc_desc = """Host: $HOSTNAME$ Service: $SERVICEDESC$ Event: $EVENT_TXT$ Output: $SERVICEOUTPUT$ Perfdata: $SERVICEPERFDATA$ $LONGSERVICEOUTPUT$ """ short_desc = context.get( 'PARAMETER_SVC_SHORT_DESC') or tmpl_svc_short_desc servicename = context['SERVICEDESC'] desc = context.get('PARAMETER_SVC_DESC') or tmpl_svc_desc problem_id = context['SERVICEPROBLEMID'] ack_author = context['SERVICEACKAUTHOR'] ack_comment = context['SERVICEACKCOMMENT'] short_desc = utils.substitute_context(short_desc, context) desc = utils.substitute_context(desc, context) if context['NOTIFICATIONTYPE'] == 'PROBLEM': handle_problem(url, user, pwd, short_desc, desc, hostname, servicename, problem_id, caller, urgency, impact, timeout) elif context['NOTIFICATIONTYPE'] == 'RECOVERY': handle_recovery(problem_id, url, user, pwd, desc, caller, timeout) elif context['NOTIFICATIONTYPE'] == 'ACKNOWLEDGEMENT': handle_ack(problem_id, url, user, pwd, ack_comment, ack_author, ack_state, caller, timeout) elif context['NOTIFICATIONTYPE'] == 'DOWNTIMESTART': desc = """Downtime was set. User: $NOTIFICATIONAUTHOR$ Comment: $NOTIFICATIONCOMMENT$ """ desc = utils.substitute_context(desc, context) handle_downtime(problem_id, url, user, pwd, desc, "start", dtstart_state, caller, timeout) elif context['NOTIFICATIONTYPE'] == 'DOWNTIMECANCELLED': desc = """Downtime expired. """ handle_downtime(problem_id, url, user, pwd, desc, "end", dtend_state, caller, timeout) else: sys.stdout.write("Noticication type %s not supported\n" % (context['NOTIFICATIONTYPE'])) return 0
def main(): context = utils.collect_context() tmpl_host_summary = 'Check_MK: $HOSTNAME$ - $HOSTSHORTSTATE$' tmpl_service_summary = 'Check_MK: $HOSTNAME$/$SERVICEDESC$ $SERVICESHORTSTATE$' tmpl_label = 'monitoring' for necessary in [ 'PARAMETER_URL', 'PARAMETER_USERNAME', 'PARAMETER_PASSWORD', 'PARAMETER_HOST_CUSTOMID', 'PARAMETER_SERVICE_CUSTOMID' ]: if necessary not in context: sys.stderr.write("%s not set" % necessary) return 2 if "PARAMETER_IGNORE_SSL" in context: sys.stdout.write( "Unverified HTTPS request warnings are ignored. Use with caution.\n" ) jira = JIRA(server=context['PARAMETER_URL'], basic_auth=(context['PARAMETER_USERNAME'], context['PARAMETER_PASSWORD']), options={'verify': False}) else: jira = JIRA(server=context['PARAMETER_URL'], basic_auth=(context['PARAMETER_USERNAME'], context['PARAMETER_PASSWORD'])) if context['WHAT'] == 'HOST': summary = context.get('PARAMETER_HOST_SUMMARY') or tmpl_host_summary svc_desc = context['HOSTOUTPUT'] custom_field = int(context['PARAMETER_HOST_CUSTOMID']) custom_field_value = int(context['HOSTPROBLEMID']) else: summary = context.get( 'PARAMETER_SERVICE_SUMMARY') or tmpl_service_summary svc_desc = context['SERVICEOUTPUT'] custom_field = int(context['PARAMETER_SERVICE_CUSTOMID']) custom_field_value = int(context['SERVICEPROBLEMID']) context['SUBJECT'] = utils.substitute_context(summary, context) label = context.get('PARAMETER_LABEL') or tmpl_label newissue = { u'labels': [label], u'summary': context['SUBJECT'], u'description': svc_desc, } if 'PARAMETER_PROJECT' in context: newissue[u'project'] = {u'id': context['PARAMETER_PROJECT']} if 'CONTACT_JIRAPROJECT' in context: newissue[u'project'] = {u'id': context['CONTACT_JIRAPROJECT']} if 'PARAMETER_ISSUETYPE' in context: newissue[u'issuetype'] = {u'id': context['PARAMETER_ISSUETYPE']} if 'CONTACT_JIRAISSUETYPE' in context: newissue[u'issuetype'] = {u'id': context['CONTACT_JIRAISSUETYPE']} if 'PARAMETER_PRIORITY' in context: newissue[u'priority'] = {u'id': context['PARAMETER_PRIORITY']} if 'CONTACT_JIRAPRIORITY' in context: newissue[u'priority'] = {u'id': context['CONTACT_JIRAPRIORITY']} if 'project' not in newissue: sys.stderr.write("No JIRA project ID set, discarding notification") return 2 if 'issuetype' not in newissue: sys.stderr.write("No JIRA issue type ID set") return 2 try: custom_field_exists = jira.search_issues( "cf[%d]=%d" % (custom_field, custom_field_value)) except JIRAError, err: sys.stderr.write( 'Unable to query custom field search, JIRA response code %s, %s' % (err.status_code, err.text)) return 2
def main() -> int: context = utils.collect_context() if "PARAMETER_PASSWORD" not in context: sys.stderr.write("API key not set\n") return 2 api_key = retrieve_from_passwordstore(context["PARAMETER_PASSWORD"]) note_created = context.get( "PARAMETER_NOTE_CREATED") or "Alert created by Check_MK" note_closed = context.get( "PARAMETER_NOTE_CLOSED") or "Alert closed by Check_MK" priority = context.get("PARAMETER_PRIORITY", "P3") entity_value = context.get("PARAMETER_ENTITY", "") alert_source: Optional[str] = context.get("PARAMETER_SOURCE") owner: Optional[str] = context.get("PARAMETER_OWNER") host_url: Optional[str] = context.get("PARAMETER_URL") proxy_url: Optional[str] = context.get("PARAMETER_PROXY_URL") tags_list: List[str] = [] if context.get("PARAMETER_TAGSS"): tags_list = context.get("PARAMETER_TAGSS", "").split(" ") actions_list: List[str] = [] if context.get("PARAMETER_ACTIONSS"): actions_list = context.get("PARAMETER_ACTIONSS", "").split(" ") teams_list: List[Optional[Dict[str, str]]] = [] if context.get("PARAMETER_TEAMSS"): for team in context["PARAMETER_TEAMSS"].split(" "): teams_list.append({"name": str(team), "type": "team"}) if context["WHAT"] == "HOST": tmpl_host_msg: str = "Check_MK: $HOSTNAME$ - $HOSTSHORTSTATE$" tmpl_host_desc: str = """Host: $HOSTNAME$ Event: $EVENT_TXT$ Output: $HOSTOUTPUT$ Perfdata: $HOSTPERFDATA$ $LONGHOSTOUTPUT$ """ desc = context.get("PARAMETER_HOST_DESC") or tmpl_host_desc msg = context.get("PARAMETER_HOST_MSG") or tmpl_host_msg alias = "HOST_PROBLEM_ID: %s" % context["HOSTPROBLEMID"] ack_author = context["HOSTACKAUTHOR"] ack_comment = context["HOSTACKCOMMENT"] else: tmpl_svc_msg = "Check_MK: $HOSTNAME$/$SERVICEDESC$ $SERVICESHORTSTATE$" tmpl_svc_desc = """Host: $HOSTNAME$ Service: $SERVICEDESC$ Event: $EVENT_TXT$ Output: $SERVICEOUTPUT$ Perfdata: $SERVICEPERFDATA$ $LONGSERVICEOUTPUT$ """ desc = context.get("PARAMETER_SVC_DESC") or tmpl_svc_desc msg = context.get("PARAMETER_SVC_MSG") or tmpl_svc_msg alias = "SVC_PROBLEM_ID: %s" % context["SERVICEPROBLEMID"] ack_author = context["SERVICEACKAUTHOR"] ack_comment = context["SERVICEACKCOMMENT"] desc = utils.substitute_context(desc, context) msg = utils.substitute_context(msg, context) connector = Connector(api_key, host_url, proxy_url) if context["NOTIFICATIONTYPE"] == "PROBLEM": return connector.handle_alert_creation( note_created, actions_list, desc, msg, priority, teams_list, tags_list, entity_value, alert_source, alias, owner, ) if context["NOTIFICATIONTYPE"] == "RECOVERY": return connector.handle_alert_deletion(note_closed, owner, alias, alert_source) if context["NOTIFICATIONTYPE"] == "ACKNOWLEDGEMENT": return connector.handle_alert_ack(ack_author, ack_comment, alias, alert_source) sys.stdout.write("Notification type %s not supported\n" % (context["NOTIFICATIONTYPE"])) return 0
def main(): context = utils.collect_context() tmpl_host_summary = 'Check_MK: $HOSTNAME$ - $HOSTSHORTSTATE$' tmpl_service_summary = 'Check_MK: $HOSTNAME$/$SERVICEDESC$ $SERVICESHORTSTATE$' tmpl_label = 'monitoring' for necessary in [ 'PARAMETER_URL', 'PARAMETER_USERNAME', 'PARAMETER_PASSWORD', 'PARAMETER_HOST_CUSTOMID', 'PARAMETER_SERVICE_CUSTOMID' ]: if necessary not in context: sys.stderr.write("%s not set" % necessary) return 2 if "PARAMETER_IGNORE_SSL" in context: sys.stdout.write( "Unverified HTTPS request warnings are ignored. Use with caution.\n" ) jira = JIRA(server=context['PARAMETER_URL'], basic_auth=(context['PARAMETER_USERNAME'], context['PARAMETER_PASSWORD']), options={'verify': False}) else: jira = JIRA(server=context['PARAMETER_URL'], basic_auth=(context['PARAMETER_USERNAME'], context['PARAMETER_PASSWORD'])) if context['WHAT'] == 'HOST': summary = context.get('PARAMETER_HOST_SUMMARY') or tmpl_host_summary svc_desc = context['HOSTOUTPUT'] custom_field = int(context['PARAMETER_HOST_CUSTOMID']) custom_field_value = int(context['HOSTPROBLEMID']) else: summary = context.get( 'PARAMETER_SERVICE_SUMMARY') or tmpl_service_summary svc_desc = context['SERVICEOUTPUT'] custom_field = int(context['PARAMETER_SERVICE_CUSTOMID']) custom_field_value = int(context['SERVICEPROBLEMID']) context['SUBJECT'] = utils.substitute_context(summary, context) label = context.get('PARAMETER_LABEL') or tmpl_label newissue = { u'labels': [label], u'summary': context['SUBJECT'], u'description': svc_desc, } if 'PARAMETER_PROJECT' in context: newissue[u'project'] = {u'id': context['PARAMETER_PROJECT']} if 'CONTACT_JIRAPROJECT' in context: newissue[u'project'] = {u'id': context['CONTACT_JIRAPROJECT']} if 'PARAMETER_ISSUETYPE' in context: newissue[u'issuetype'] = {u'id': context['PARAMETER_ISSUETYPE']} if 'CONTACT_JIRAISSUETYPE' in context: newissue[u'issuetype'] = {u'id': context['CONTACT_JIRAISSUETYPE']} if 'PARAMETER_PRIORITY' in context: newissue[u'priority'] = {u'id': context['PARAMETER_PRIORITY']} if 'CONTACT_JIRAPRIORITY' in context: newissue[u'priority'] = {u'id': context['CONTACT_JIRAPRIORITY']} if 'project' not in newissue: sys.stderr.write("No JIRA project ID set, discarding notification") return 2 if 'issuetype' not in newissue: sys.stderr.write("No JIRA issue type ID set") return 2 try: custom_field_exists = jira.search_issues( "cf[%d]=%d" % (custom_field, custom_field_value)) except JIRAError as err: sys.stderr.write( 'Unable to query custom field search, JIRA response code %s, %s' % (err.status_code, err.text)) return 2 if not custom_field_exists: newissue[u'customfield_%d' % custom_field] = custom_field_value if context['NOTIFICATIONTYPE'] == 'PROBLEM': try: issue = jira.create_issue(fields=newissue) except JIRAError as err: sys.stderr.write( 'Unable to create issue, JIRA response code %s, %s' % (err.status_code, err.text)) return 2 sys.stdout.write('Created %s\n' % issue.permalink()) if 'PARAMETER_MONITORING' in context: if context['PARAMETER_MONITORING'].endswith('/'): # remove trailing slash context['PARAMETER_MONITORING'] = context[ 'PARAMETER_MONITORING'][:-1] if context['WHAT'] == 'SERVICE': url = context['PARAMETER_MONITORING'] + context['SERVICEURL'] else: url = context['PARAMETER_MONITORING'] + context['HOSTURL'] try: rl = jira.add_simple_link(issue, { 'url': url, 'title': 'Monitoring' }) except JIRAError as err: sys.stderr.write( 'Unable to create link in issue, JIRA response code %s, %s\n' % (err.status_code, err.text)) return 2 sys.stdout.write('Created JIRA simple link: %s' % rl) if context['NOTIFICATIONTYPE'] == 'RECOVERY' and custom_field_exists: if "PARAMETER_RESOLUTION" not in context: sys.stderr.write( "Ticket resolution not enabled in wato rule. Don't send a resolution to jira\n" ) return 0 else: resolution = None if 'PARAMETER_RESOLUTION' in context: resolution = context['PARAMETER_RESOLUTION'] if 'CONTACT_JIRARESOLUTION' in context: resolution = context['CONTACT_JIRARESOLUTION'] if resolution is None: sys.stderr.write("No JIRA resolution ID set") return 2 for issue in custom_field_exists: try: jira.transition_issue(issue, resolution, comment=newissue['description']) sys.stdout.write('Resolved %s' % issue.permalink()) except JIRAError as err: sys.stderr.write( 'Unable to resolve %s, JIRA response code %s, %s' % (issue.permalink(), err.status_code, err.text)) return 2
def test_substitute_context(context, template, result): assert result == utils.substitute_context(template, context)
def construct_content(context): # Create a notification summary in a new context variable # Note: This code could maybe move to cmk --notify in order to # make it available every in all notification scripts # We have the following types of notifications: # - Alerts OK -> CRIT # NOTIFICATIONTYPE is "PROBLEM" or "RECOVERY" # - Flapping Started, Ended # NOTIFICATIONTYPE is "FLAPPINGSTART" or "FLAPPINGSTOP" # - Downtimes Started, Ended, Cancelled # NOTIFICATIONTYPE is "DOWNTIMESTART", "DOWNTIMECANCELLED", or "DOWNTIMEEND" # - Acknowledgements # NOTIFICATIONTYPE is "ACKNOWLEDGEMENT" # - Custom notifications # NOTIFICATIONTYPE is "CUSTOM" notification_type = context["NOTIFICATIONTYPE"] if notification_type in ["PROBLEM", "RECOVERY"]: txt_info = "$PREVIOUS@HARDSHORTSTATE$ -> $@SHORTSTATE$" elif notification_type.startswith("FLAP"): if "START" in notification_type: txt_info = "Started Flapping" else: txt_info = "Stopped Flapping ($@SHORTSTATE$)" elif notification_type.startswith("DOWNTIME"): what = notification_type[8:].title() txt_info = "Downtime " + what + " ($@SHORTSTATE$)" elif notification_type == "ACKNOWLEDGEMENT": txt_info = "Acknowledged ($@SHORTSTATE$)" elif notification_type == "CUSTOM": txt_info = "Custom Notification ($@SHORTSTATE$)" else: txt_info = notification_type # Should neven happen txt_info = utils.substitute_context(txt_info.replace("@", context["WHAT"]), context) context["EVENT_TXT"] = txt_info # Prepare the mail contents if "PARAMETER_COMMON_BODY" in context: tmpl_body = context['PARAMETER_COMMON_BODY'] else: tmpl_body = tmpl_common_body if "ALERTHANDLERNAME" in context: my_tmpl_host_body = tmpl_alerthandler_host_body my_tmpl_service_body = tmpl_alerthandler_service_body else: my_tmpl_host_body = tmpl_host_body my_tmpl_service_body = tmpl_service_body # Compute the subject and body of the mail if context['WHAT'] == 'HOST': tmpl = context.get('PARAMETER_HOST_SUBJECT') or tmpl_host_subject if "PARAMETER_HOST_BODY" in context: tmpl_body += context["PARAMETER_HOST_BODY"] else: tmpl_body += my_tmpl_host_body else: tmpl = context.get('PARAMETER_SERVICE_SUBJECT') or tmpl_service_subject if "PARAMETER_SERVICE_BODY" in context: tmpl_body += context["PARAMETER_SERVICE_BODY"] else: tmpl_body += my_tmpl_service_body context['SUBJECT'] = utils.substitute_context(tmpl, context) body = utils.substitute_context(tmpl_body, context) return body