From 3e3a22460767d1747d6f16317b6c01ecd54c2ca8 Mon Sep 17 00:00:00 2001 From: Tomasz Kolek Date: Sun, 13 Mar 2016 15:28:44 +0100 Subject: [PATCH] Moved pagerduty webhook into its own file pagerduty.py --- zerver/views/webhooks/__init__.py | 107 ------------------------- zerver/views/webhooks/pagerduty.py | 121 +++++++++++++++++++++++++++++ zproject/urls.py | 2 +- 3 files changed, 122 insertions(+), 108 deletions(-) create mode 100644 zerver/views/webhooks/pagerduty.py diff --git a/zerver/views/webhooks/__init__.py b/zerver/views/webhooks/__init__.py index f60811cddb..e69de29bb2 100644 --- a/zerver/views/webhooks/__init__.py +++ b/zerver/views/webhooks/__init__.py @@ -1,107 +0,0 @@ -# Webhooks for external integrations. -from __future__ import absolute_import -from zerver.models import get_client -from zerver.lib.actions import check_send_message -from zerver.lib.response import json_success -from zerver.decorator import REQ, \ - has_request_variables, \ - api_key_only_webhook_view - -import pprint -import ujson - -from .github import build_commit_list_content, build_message_from_gitlog - - - - - -PAGER_DUTY_EVENT_NAMES = { - 'incident.trigger': 'triggered', - 'incident.acknowledge': 'acknowledged', - 'incident.unacknowledge': 'unacknowledged', - 'incident.resolve': 'resolved', - 'incident.assign': 'assigned', - 'incident.escalate': 'escalated', - 'incident.delegate': 'delineated', -} - -def build_pagerduty_formatdict(message): - # Normalize the message dict, after this all keys will exist. I would - # rather some strange looking messages than dropping pages. - - format_dict = {} - format_dict['action'] = PAGER_DUTY_EVENT_NAMES[message['type']] - - format_dict['incident_id'] = message['data']['incident']['id'] - format_dict['incident_num'] = message['data']['incident']['incident_number'] - format_dict['incident_url'] = message['data']['incident']['html_url'] - - format_dict['service_name'] = message['data']['incident']['service']['name'] - format_dict['service_url'] = message['data']['incident']['service']['html_url'] - - # This key can be missing on null - if message['data']['incident'].get('assigned_to_user', None): - format_dict['assigned_to_email'] = message['data']['incident']['assigned_to_user']['email'] - format_dict['assigned_to_username'] = message['data']['incident']['assigned_to_user']['email'].split('@')[0] - format_dict['assigned_to_url'] = message['data']['incident']['assigned_to_user']['html_url'] - else: - format_dict['assigned_to_email'] = 'nobody' - format_dict['assigned_to_username'] = 'nobody' - format_dict['assigned_to_url'] = '' - - # This key can be missing on null - if message['data']['incident'].get('resolved_by_user', None): - format_dict['resolved_by_email'] = message['data']['incident']['resolved_by_user']['email'] - format_dict['resolved_by_username'] = message['data']['incident']['resolved_by_user']['email'].split('@')[0] - format_dict['resolved_by_url'] = message['data']['incident']['resolved_by_user']['html_url'] - else: - format_dict['resolved_by_email'] = 'nobody' - format_dict['resolved_by_username'] = 'nobody' - format_dict['resolved_by_url'] = '' - - trigger_message = [] - trigger_subject = message['data']['incident']['trigger_summary_data'].get('subject', '') - if trigger_subject: - trigger_message.append(trigger_subject) - trigger_description = message['data']['incident']['trigger_summary_data'].get('description', '') - if trigger_description: - trigger_message.append(trigger_description) - format_dict['trigger_message'] = u'\n'.join(trigger_message) - return format_dict - - -def send_raw_pagerduty_json(user_profile, stream, message, topic): - subject = topic or 'pagerduty' - body = ( - u'Unknown pagerduty message\n' - u'``` py\n' - u'%s\n' - u'```') % (pprint.pformat(message),) - check_send_message(user_profile, get_client('ZulipPagerDutyWebhook'), 'stream', - [stream], subject, body) - - -def send_formated_pagerduty(user_profile, stream, message_type, format_dict, topic): - if message_type in ('incident.trigger', 'incident.unacknowledge'): - template = (u':imp: Incident ' - u'[{incident_num}]({incident_url}) {action} by ' - u'[{service_name}]({service_url}) and assigned to ' - u'[{assigned_to_username}@]({assigned_to_url})\n\n>{trigger_message}') - - elif message_type == 'incident.resolve' and format_dict['resolved_by_url']: - template = (u':grinning: Incident ' - u'[{incident_num}]({incident_url}) resolved by ' - u'[{resolved_by_username}@]({resolved_by_url})\n\n>{trigger_message}') - elif message_type == 'incident.resolve' and not format_dict['resolved_by_url']: - template = (u':grinning: Incident ' - u'[{incident_num}]({incident_url}) resolved\n\n>{trigger_message}') - else: - template = (u':no_good: Incident [{incident_num}]({incident_url}) ' - u'{action} by [{assigned_to_username}@]({assigned_to_url})\n\n>{trigger_message}') - - subject = topic or u'incident {incident_num}'.format(**format_dict) - body = template.format(**format_dict) - - check_send_message(user_profile, get_client('ZulipPagerDutyWebhook'), 'stream', - [stream], subject, body) diff --git a/zerver/views/webhooks/pagerduty.py b/zerver/views/webhooks/pagerduty.py new file mode 100644 index 0000000000..5ccd752f2c --- /dev/null +++ b/zerver/views/webhooks/pagerduty.py @@ -0,0 +1,121 @@ +# Webhooks for external integrations. +from __future__ import absolute_import +from zerver.models import get_client +from zerver.lib.actions import check_send_message +from zerver.lib.response import json_success +from zerver.decorator import REQ, has_request_variables, api_key_only_webhook_view + +import pprint +import ujson + + +PAGER_DUTY_EVENT_NAMES = { + 'incident.trigger': 'triggered', + 'incident.acknowledge': 'acknowledged', + 'incident.unacknowledge': 'unacknowledged', + 'incident.resolve': 'resolved', + 'incident.assign': 'assigned', + 'incident.escalate': 'escalated', + 'incident.delegate': 'delineated', +} + +def build_pagerduty_formatdict(message): + # Normalize the message dict, after this all keys will exist. I would + # rather some strange looking messages than dropping pages. + + format_dict = {} + format_dict['action'] = PAGER_DUTY_EVENT_NAMES[message['type']] + + format_dict['incident_id'] = message['data']['incident']['id'] + format_dict['incident_num'] = message['data']['incident']['incident_number'] + format_dict['incident_url'] = message['data']['incident']['html_url'] + + format_dict['service_name'] = message['data']['incident']['service']['name'] + format_dict['service_url'] = message['data']['incident']['service']['html_url'] + + # This key can be missing on null + if message['data']['incident'].get('assigned_to_user', None): + format_dict['assigned_to_email'] = message['data']['incident']['assigned_to_user']['email'] + format_dict['assigned_to_username'] = message['data']['incident']['assigned_to_user']['email'].split('@')[0] + format_dict['assigned_to_url'] = message['data']['incident']['assigned_to_user']['html_url'] + else: + format_dict['assigned_to_email'] = 'nobody' + format_dict['assigned_to_username'] = 'nobody' + format_dict['assigned_to_url'] = '' + + # This key can be missing on null + if message['data']['incident'].get('resolved_by_user', None): + format_dict['resolved_by_email'] = message['data']['incident']['resolved_by_user']['email'] + format_dict['resolved_by_username'] = message['data']['incident']['resolved_by_user']['email'].split('@')[0] + format_dict['resolved_by_url'] = message['data']['incident']['resolved_by_user']['html_url'] + else: + format_dict['resolved_by_email'] = 'nobody' + format_dict['resolved_by_username'] = 'nobody' + format_dict['resolved_by_url'] = '' + + trigger_message = [] + trigger_subject = message['data']['incident']['trigger_summary_data'].get('subject', '') + if trigger_subject: + trigger_message.append(trigger_subject) + trigger_description = message['data']['incident']['trigger_summary_data'].get('description', '') + if trigger_description: + trigger_message.append(trigger_description) + format_dict['trigger_message'] = u'\n'.join(trigger_message) + return format_dict + + +def send_raw_pagerduty_json(user_profile, stream, message, topic): + subject = topic or 'pagerduty' + body = ( + u'Unknown pagerduty message\n' + u'``` py\n' + u'%s\n' + u'```') % (pprint.pformat(message),) + check_send_message(user_profile, get_client('ZulipPagerDutyWebhook'), 'stream', + [stream], subject, body) + + +def send_formated_pagerduty(user_profile, stream, message_type, format_dict, topic): + if message_type in ('incident.trigger', 'incident.unacknowledge'): + template = (u':imp: Incident ' + u'[{incident_num}]({incident_url}) {action} by ' + u'[{service_name}]({service_url}) and assigned to ' + u'[{assigned_to_username}@]({assigned_to_url})\n\n>{trigger_message}') + + elif message_type == 'incident.resolve' and format_dict['resolved_by_url']: + template = (u':grinning: Incident ' + u'[{incident_num}]({incident_url}) resolved by ' + u'[{resolved_by_username}@]({resolved_by_url})\n\n>{trigger_message}') + elif message_type == 'incident.resolve' and not format_dict['resolved_by_url']: + template = (u':grinning: Incident ' + u'[{incident_num}]({incident_url}) resolved\n\n>{trigger_message}') + else: + template = (u':no_good: Incident [{incident_num}]({incident_url}) ' + u'{action} by [{assigned_to_username}@]({assigned_to_url})\n\n>{trigger_message}') + + subject = topic or u'incident {incident_num}'.format(**format_dict) + body = template.format(**format_dict) + + check_send_message(user_profile, get_client('ZulipPagerDutyWebhook'), 'stream', + [stream], subject, body) + + +@api_key_only_webhook_view +@has_request_variables +def api_pagerduty_webhook(request, user_profile, stream=REQ(default='pagerduty'), topic=REQ(default=None)): + payload = ujson.loads(request.body) + + for message in payload['messages']: + message_type = message['type'] + + if message_type not in PAGER_DUTY_EVENT_NAMES: + send_raw_pagerduty_json(user_profile, stream, message, topic) + + try: + format_dict = build_pagerduty_formatdict(message) + except: + send_raw_pagerduty_json(user_profile, stream, message, topic) + else: + send_formated_pagerduty(user_profile, stream, message_type, format_dict, topic) + + return json_success() diff --git a/zproject/urls.py b/zproject/urls.py index 3a80af03b5..1ef2acd815 100644 --- a/zproject/urls.py +++ b/zproject/urls.py @@ -164,7 +164,7 @@ urlpatterns += patterns('zerver.views', url(r'^api/v1/external/stash$', 'webhooks.stash.api_stash_webhook'), url(r'^api/v1/external/freshdesk$', 'webhooks.freshdesk.api_freshdesk_webhook'), url(r'^api/v1/external/zendesk$', 'webhooks.zendesk.api_zendesk_webhook'), - url(r'^api/v1/external/pagerduty$', 'webhooks.api_pagerduty_webhook'), + url(r'^api/v1/external/pagerduty$', 'webhooks.pagerduty.api_pagerduty_webhook'), url(r'^api/v1/external/travis$', 'webhooks.travis.api_travis_webhook'), url(r'^user_uploads/(?P(\d*|unk))/(?P.*)', 'get_uploaded_file'),