115 lines
3 KiB
Python
115 lines
3 KiB
Python
|
import logging
|
||
|
import io
|
||
|
import os.path
|
||
|
import tarfile
|
||
|
import base64
|
||
|
import json
|
||
|
|
||
|
from flask.ext.mail import Message
|
||
|
from app import mail, app
|
||
|
from data import model
|
||
|
|
||
|
logger = logging.getLogger(__name__)
|
||
|
|
||
|
class InvalidNotificationMethodException(Exception):
|
||
|
pass
|
||
|
|
||
|
class NotificationMethod(object):
|
||
|
def __init__(self):
|
||
|
pass
|
||
|
|
||
|
@classmethod
|
||
|
def method_name(cls):
|
||
|
"""
|
||
|
Particular method implemented by subclasses.
|
||
|
"""
|
||
|
raise NotImplementedError
|
||
|
|
||
|
def perform(self, notification, event_handler, notification_data):
|
||
|
"""
|
||
|
Performs the notification method.
|
||
|
|
||
|
notification: The noticication record itself.
|
||
|
event_handler: The NotificationEvent handler.
|
||
|
notification_data: The dict of notification data placed in the queue.
|
||
|
"""
|
||
|
raise NotImplementedError
|
||
|
|
||
|
@classmethod
|
||
|
def get_method(cls, methodname):
|
||
|
for subc in cls.__subclasses__():
|
||
|
if subc.method_name() == methodname:
|
||
|
return subc()
|
||
|
|
||
|
raise InvalidNotificationMethodException('Unable to find method: %s' % methodname)
|
||
|
|
||
|
|
||
|
class QuayNotificationMethod(NotificationMethod):
|
||
|
@classmethod
|
||
|
def method_name(cls):
|
||
|
return 'quay_notification'
|
||
|
|
||
|
def perform(self, notification, event_handler, notification_data):
|
||
|
repository_id = notification_data['repository_id']
|
||
|
repository = model.lookup_repository(repository_id)
|
||
|
if not repository:
|
||
|
# Probably deleted.
|
||
|
return True
|
||
|
|
||
|
model.create_notification(event_handler.event_name(),
|
||
|
repository.namespace, metadata=notification_data['event_data'])
|
||
|
return True
|
||
|
|
||
|
|
||
|
class EmailMethod(NotificationMethod):
|
||
|
@classmethod
|
||
|
def method_name(cls):
|
||
|
return 'email'
|
||
|
|
||
|
def perform(self, notification, event_handler, notification_data):
|
||
|
config_data = json.loads(notification.config_json)
|
||
|
email = config_data.get('email', '')
|
||
|
if not email:
|
||
|
return False
|
||
|
|
||
|
msg = Message(event_handler.get_summary(notification_data),
|
||
|
sender='support@quay.io',
|
||
|
recipients=[email])
|
||
|
msg.html = event_handler.get_message(notification_data)
|
||
|
|
||
|
try:
|
||
|
mail.send(msg)
|
||
|
except Exception as ex:
|
||
|
logger.exception('Email was unable to be sent: %s' % ex.message)
|
||
|
return False
|
||
|
|
||
|
return True
|
||
|
|
||
|
|
||
|
class WebhookMethod(NotificationMethod):
|
||
|
@classmethod
|
||
|
def method_name(cls):
|
||
|
return 'webhook'
|
||
|
|
||
|
def perform(self, notification, event_handler, notification_data):
|
||
|
config_data = json.loads(notification.config_json)
|
||
|
url = config_data.get('url', '')
|
||
|
if not url:
|
||
|
return False
|
||
|
|
||
|
payload = notification_data['event_data']
|
||
|
headers = {'Content-type': 'application/json'}
|
||
|
|
||
|
try:
|
||
|
resp = requests.post(url, data=json.dumps(payload), headers=headers)
|
||
|
if resp.status_code/100 != 2:
|
||
|
logger.error('%s response for webhook to url: %s' % (resp.status_code,
|
||
|
url))
|
||
|
return False
|
||
|
|
||
|
except requests.exceptions.RequestException as ex:
|
||
|
logger.exception('Webhook was unable to be sent: %s' % ex.message)
|
||
|
return False
|
||
|
|
||
|
return True
|