Adding some early Notifications stubs

* A basic NotificationTemplate model class with early notification type
  definitions
* Initial implementations of the Email, Slack, and Twilio Notification
  backends using the Django email backend system
* Some dependencies thereof
This commit is contained in:
Matthew Jones 2016-02-01 16:54:34 -05:00
parent 6d71fe49f2
commit 7385efef35
7 changed files with 139 additions and 0 deletions

View File

@ -17,6 +17,7 @@ from awx.main.models.schedules import * # noqa
from awx.main.models.activity_stream import * # noqa
from awx.main.models.ha import * # noqa
from awx.main.models.configuration import * # noqa
from awx.main.models.notifications import * # noqa
# Monkeypatch Django serializer to ignore django-taggit fields (which break
# the dumpdata command; see https://github.com/alex/django-taggit/issues/155).

View File

@ -0,0 +1,37 @@
# Copyright (c) 2016 Ansible, Inc.
# All Rights Reserved.
import logging
from django.db import models
from awx.main.models.base import * # noqa
from awx.main.notifications.email_backend import CustomEmailBackend
from awx.main.notifications.slack_backend import SlackBackend
from awx.main.notifications.twilio_backend import TwilioBackend
# Django-JSONField
from jsonfield import JSONField
logger = logging.getLogger('awx.main.models.notifications')
class NotificationTemplate(CommonModel):
NOTIFICATION_TYPES = [('email', _('Email'), CustomEmailBackend),
('slack', _('Slack'), SlackBackend),
('twilio', _('Twilio'), TwilioBackend)]
NOTIFICATION_TYPE_CHOICES = [(x[0], x[1]) for x in NOTIFICATION_TYPES]
CLASS_FOR_NOTIFICATION_TYPE = dict([(x[0], x[2]) for x in NOTIFICATION_TYPES])
class Meta:
app_label = 'main'
notification_type = models.CharField(
max_length = 32,
choices=NOTIFICATION_TYPE_CHOICES,
)
notification_configuration = JSONField(blank=False)
@property
def notification_class(self):
return CLASS_FOR_NOTIFICATION_TYPE[self.notification_type]

View File

View File

@ -0,0 +1,11 @@
# Copyright (c) 2016 Ansible, Inc.
# All Rights Reserved.
import logging
from django.core.mail.backends.smtp import EmailBackend
class CustomEmailBackend(EmailBackend):
init_parameters = ("host", "port", "username", "password",
"use_tls", "use_ssl")

View File

@ -0,0 +1,46 @@
# Copyright (c) 2016 Ansible, Inc.
# All Rights Reserved.
import logging
from slackclient import SlackClient
from django.core.mail.backends.base import BaseEmailBackend
logger = logging.getLogger('awx.main.notifications.slack_backend')
class SlackBackend(BaseEmailBackend):
init_parameters = ('token',)
def __init__(self, token, fail_silently=False, **kwargs):
super(SlackBackend, self).__init__(fail_silently=fail_silently)
self.token = token
self.connection = None
def open(self):
if self.connection is not None:
return False
self.connection = SlackClient(self.token)
if not self.connection.rtm_connect():
if not self.fail_silently:
raise Exception("Slack Notification Token is invalid")
return True
def close(self):
if self.connection is None:
return
self.connection = None
def send_messages(self, messages):
if self.connection is None:
self.open()
sent_messages = 0
for m in messages:
try:
self.connection.rtm_send_message(m.to, m.body)
sent_messages += 1
except Exception as e:
if not self.fail_silently:
raise
logger.error("Exception sending messages: {}".format(e))
return sent_messages

View File

@ -0,0 +1,42 @@
# Copyright (c) 2016 Ansible, Inc.
# All Rights Reserved.
import logging
from twilio.rest import TwilioRestClient
from django.core.mail.backends.base import BaseEmailBackend
logger = logging.getLogger('awx.main.notifications.twilio_backend')
class TwilioBackend(BaseEmailBackend):
init_parameters = ('account_sid', 'account_token', 'from_phone',)
def __init__(self, account_sid, account_token, from_phone, fail_silently=False, **kwargs):
super(TwilioBackend, self).__init__(fail_silently=fail_silently)
self.account_sid = account_sid
self.account_token = account_token
self.from_phone = from_phone
def send_messages(self, messages):
sent_messages = 0
try:
connection = TwilioRestClient(self.account_sid, self.account_token)
except Exception as e:
if not self.fail_silently:
raise
logger.error("Exception connecting to Twilio: {}".format(e))
for m in messages:
try:
connection.messages.create(
to=m.to,
from_=self.from_phone,
body=m.body)
sent_messages += 1
except Exception as e:
if not self.fail_silently:
raise
logger.error("Exception sending messages: {}".format(e))
return sent_messages

View File

@ -114,9 +114,11 @@ requests==2.5.1
requests-oauthlib==0.5.0
simplejson==3.6.0
six==1.9.0
slackclient==0.16
statsd==3.2.1
stevedore==1.3.0
suds==0.4
twilio==4.9.1
warlock==1.1.0
wheel==0.24.0
wsgiref==0.1.2