mirror of
https://github.com/ansible/awx.git
synced 2026-01-12 02:19:58 -03:30
Merge pull request #103 from ragingpastry/add-mattermost-notification
Add mattermost notification
This commit is contained in:
commit
4657f29df9
@ -157,7 +157,7 @@ class Migration(migrations.Migration):
|
||||
('status', models.CharField(default=b'pending', max_length=20, editable=False, choices=[(b'pending', 'Pending'), (b'successful', 'Successful'), (b'failed', 'Failed')])),
|
||||
('error', models.TextField(default=b'', editable=False, blank=True)),
|
||||
('notifications_sent', models.IntegerField(default=0, editable=False)),
|
||||
('notification_type', models.CharField(max_length=32, choices=[(b'email', 'Email'), (b'slack', 'Slack'), (b'twilio', 'Twilio'), (b'pagerduty', 'Pagerduty'), (b'hipchat', 'HipChat'), (b'webhook', 'Webhook'), (b'irc', 'IRC')])),
|
||||
('notification_type', models.CharField(max_length=32, choices=[(b'email', 'Email'), (b'slack', 'Slack'), (b'twilio', 'Twilio'), (b'pagerduty', 'Pagerduty'), (b'hipchat', 'HipChat'), (b'webhook', 'Webhook'), (b'mattermost', 'Mattermost'), (b'irc', 'IRC')])),
|
||||
('recipients', models.TextField(default=b'', editable=False, blank=True)),
|
||||
('subject', models.TextField(default=b'', editable=False, blank=True)),
|
||||
('body', jsonfield.fields.JSONField(default=dict, blank=True)),
|
||||
@ -174,7 +174,7 @@ class Migration(migrations.Migration):
|
||||
('modified', models.DateTimeField(default=None, editable=False)),
|
||||
('description', models.TextField(default=b'', blank=True)),
|
||||
('name', models.CharField(unique=True, max_length=512)),
|
||||
('notification_type', models.CharField(max_length=32, choices=[(b'email', 'Email'), (b'slack', 'Slack'), (b'twilio', 'Twilio'), (b'pagerduty', 'Pagerduty'), (b'hipchat', 'HipChat'), (b'webhook', 'Webhook'), (b'irc', 'IRC')])),
|
||||
('notification_type', models.CharField(max_length=32, choices=[(b'email', 'Email'), (b'slack', 'Slack'), (b'twilio', 'Twilio'), (b'pagerduty', 'Pagerduty'), (b'hipchat', 'HipChat'), (b'webhook', 'Webhook'), (b'mattermost', 'Mattermost'), (b'irc', 'IRC')])),
|
||||
('notification_configuration', jsonfield.fields.JSONField(default=dict)),
|
||||
('created_by', models.ForeignKey(related_name="{u'class': 'notificationtemplate', u'app_label': 'main'}(class)s_created+", on_delete=django.db.models.deletion.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
|
||||
('modified_by', models.ForeignKey(related_name="{u'class': 'notificationtemplate', u'app_label': 'main'}(class)s_modified+", on_delete=django.db.models.deletion.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
|
||||
|
||||
@ -12,6 +12,7 @@ from awx.main.notifications.slack_backend import SlackBackend
|
||||
from awx.main.notifications.twilio_backend import TwilioBackend
|
||||
from awx.main.notifications.pagerduty_backend import PagerDutyBackend
|
||||
from awx.main.notifications.hipchat_backend import HipChatBackend
|
||||
from awx.main.notifications.mattermost_backend import MattermostBackend
|
||||
from awx.main.notifications.webhook_backend import WebhookBackend
|
||||
from awx.main.notifications.irc_backend import IrcBackend
|
||||
|
||||
@ -25,6 +26,7 @@ NOTIFICATION_TYPES = [('email', _('Email'), CustomEmailBackend),
|
||||
('twilio', _('Twilio'), TwilioBackend),
|
||||
('pagerduty', _('Pagerduty'), PagerDutyBackend),
|
||||
('hipchat', _('HipChat'), HipChatBackend),
|
||||
('mattermost', _('Mattermost'), MattermostBackend),
|
||||
('webhook', _('Webhook'), WebhookBackend),
|
||||
('irc', _('IRC'), IrcBackend)]
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ from awx.main.notifications.twilio_backend import TwilioBackend
|
||||
from awx.main.notifications.pagerduty_backend import PagerDutyBackend
|
||||
from awx.main.notifications.hipchat_backend import HipChatBackend
|
||||
from awx.main.notifications.webhook_backend import WebhookBackend
|
||||
from awx.main.notifications.mattermost_backend import MattermostBackend
|
||||
from awx.main.notifications.irc_backend import IrcBackend
|
||||
from awx.main.fields import JSONField
|
||||
|
||||
@ -36,6 +37,7 @@ class NotificationTemplate(CommonModelNameNotUnique):
|
||||
('pagerduty', _('Pagerduty'), PagerDutyBackend),
|
||||
('hipchat', _('HipChat'), HipChatBackend),
|
||||
('webhook', _('Webhook'), WebhookBackend),
|
||||
('mattermost', _('Mattermost'), MattermostBackend),
|
||||
('irc', _('IRC'), IrcBackend)]
|
||||
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])
|
||||
|
||||
52
awx/main/notifications/mattermost_backend.py
Normal file
52
awx/main/notifications/mattermost_backend.py
Normal file
@ -0,0 +1,52 @@
|
||||
# Copyright (c) 2016 Ansible, Inc.
|
||||
# All Rights Reserved.
|
||||
|
||||
import logging
|
||||
import requests
|
||||
import json
|
||||
|
||||
from django.utils.encoding import smart_text
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from awx.main.notifications.base import AWXBaseEmailBackend
|
||||
|
||||
logger = logging.getLogger('awx.main.notifications.mattermost_backend')
|
||||
|
||||
|
||||
class MattermostBackend(AWXBaseEmailBackend):
|
||||
|
||||
init_parameters = {"mattermost_url": {"label": "Target URL", "type": "string"},
|
||||
"mattermost_no_verify_ssl": {"label": "Verify SSL", "type": "bool"}}
|
||||
recipient_parameter = "mattermost_url"
|
||||
sender_parameter = None
|
||||
|
||||
def __init__(self, mattermost_no_verify_ssl=False, mattermost_channel=None, mattermost_username=None,
|
||||
mattermost_icon_url=None, fail_silently=False, **kwargs):
|
||||
super(MattermostBackend, self).__init__(fail_silently=fail_silently)
|
||||
self.mattermost_channel = mattermost_channel
|
||||
self.mattermost_username = mattermost_username
|
||||
self.mattermost_icon_url = mattermost_icon_url
|
||||
self.mattermost_no_verify_ssl = mattermost_no_verify_ssl
|
||||
|
||||
def format_body(self, body):
|
||||
return body
|
||||
|
||||
def send_messages(self, messages):
|
||||
sent_messages = 0
|
||||
for m in messages:
|
||||
payload = {}
|
||||
for opt, optval in {'mattermost_icon_url':'icon_url',
|
||||
'mattermost_channel': 'channel', 'mattermost_username': 'username'}.iteritems():
|
||||
optvalue = getattr(self, opt)
|
||||
if optvalue is not None:
|
||||
payload[optval] = optvalue.strip()
|
||||
|
||||
payload['text'] = m.subject
|
||||
|
||||
r = requests.post("{}".format(m.recipients()[0]),
|
||||
data=json.dumps(payload), verify=(not self.mattermost_no_verify_ssl))
|
||||
if r.status_code >= 400:
|
||||
logger.error(smart_text(_("Error sending notification mattermost: {}").format(r.text)))
|
||||
if not self.fail_silently:
|
||||
raise Exception(smart_text(_("Error sending notification mattermost: {}").format(r.text)))
|
||||
sent_messages += 1
|
||||
return sent_messages
|
||||
@ -333,6 +333,45 @@ export default ['i18n', function(i18n) {
|
||||
subForm: 'typeSubForm',
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
mattermost_url: {
|
||||
label: i18n._('Target URL'),
|
||||
type: 'text',
|
||||
awRequiredWhen: {
|
||||
reqExpression: "mattermost_required",
|
||||
init: "false"
|
||||
},
|
||||
ngShow: "notification_type.value == 'mattermost' ",
|
||||
subForm: 'typeSubForm',
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
mattermost_username: {
|
||||
label: i18n._('Username'),
|
||||
type: 'text',
|
||||
ngShow: "notification_type.value == 'mattermost' ",
|
||||
subForm: 'typeSubForm',
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
mattermost_channel: {
|
||||
label: i18n._('Channel'),
|
||||
type: 'text',
|
||||
ngShow: "notification_type.value == 'mattermost' ",
|
||||
subForm: 'typeSubForm',
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
mattermost_icon_url: {
|
||||
label: i18n._('Icon URL'),
|
||||
type: 'text',
|
||||
ngShow: "notification_type.value == 'mattermost' ",
|
||||
subForm: 'typeSubForm',
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
mattermost_no_verify_ssl: {
|
||||
label: i18n._('Disable SSL Verification'),
|
||||
type: 'checkbox',
|
||||
ngShow: "notification_type.value == 'mattermost' ",
|
||||
subForm: 'typeSubForm',
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
server: {
|
||||
label: i18n._('IRC Server Address'),
|
||||
type: 'text',
|
||||
|
||||
@ -17,6 +17,7 @@ function (i18n) {
|
||||
obj.irc_required = false;
|
||||
obj.twilio_required = false;
|
||||
obj.webhook_required = false;
|
||||
obj.mattermost_required = false;
|
||||
obj.token_required = false;
|
||||
obj.port_required = false;
|
||||
obj.password_required = false;
|
||||
@ -48,6 +49,9 @@ function (i18n) {
|
||||
case 'webhook':
|
||||
obj.webhook_required = true;
|
||||
break;
|
||||
case 'mattermost':
|
||||
obj.mattermost_required = true;
|
||||
break;
|
||||
case 'pagerduty':
|
||||
obj.tokenLabel = ' ' + i18n._('API Token');
|
||||
obj.pagerduty_required = true;
|
||||
|
||||
@ -35,6 +35,7 @@ The currently defined Notification Types are:
|
||||
* Email
|
||||
* Slack
|
||||
* Hipchat
|
||||
* Mattermost
|
||||
* Pagerduty
|
||||
* Twilio
|
||||
* IRC
|
||||
@ -99,6 +100,32 @@ Hipchat allows you to create a team with limited users and message history for f
|
||||
|
||||
https://www.hipchat.com/server
|
||||
|
||||
## Mattermost
|
||||
|
||||
The mattermost notification integration uses Incoming Webhooks. A password is not required because the webhook URL itself is the secret. Webhooks must be enabled in the System Console of Mattermost. If the user wishes to allow Ansible Tower notifications to modify the Icon URL and username of the notification then they must enabled these options as well.
|
||||
|
||||
In order to enable these settings in Mattermost:
|
||||
1. First go to System Console > Integrations > Custom Integrations. Check Enable Incoming Webhooks
|
||||
2. Optionally, go to System Console > Integrations > Custom Integrations. Check "Enable integrations to override usernames" and Check "Enable integrations to override profile picture icons"
|
||||
3. Go to Main Menu > Integrations > Incoming Webhook. Click "Add Incoming Webhook"
|
||||
4. Choose a "Display Name", "Description", and Channel. This channel will be overridden if the notification uses the `channel` option
|
||||
|
||||
* `url`: The incoming webhook URL that was configured in Mattermost. Notifications will use this URL to POST.
|
||||
* `username`: Optional. The username to display for the notification.
|
||||
* `channel`: Optional. Override the channel to display the notification in. Mattermost incoming webhooks are tied to a channel by default, so if left blank then this will use the incoming webhook channel. Note, if the channel does not exist then the notification will error out.
|
||||
* `icon_url`: Optional. A URL pointing to an icon to use for the notification.
|
||||
|
||||
### Testing considerations
|
||||
|
||||
* Make sure all options behave as expected
|
||||
* Test that all notification options are obeyed
|
||||
* Test formatting and appearance. Mattermost will use the minimal version of the notification.
|
||||
|
||||
### Test Service
|
||||
|
||||
* Utilize an existing Mattermost installation or use their docker container here: `docker run --name mattermost-preview -d --publish 8065:8065 mattermost/mattermost-preview`
|
||||
* Turn on Incoming Webhooks and optionally allow Integrations to override usernames and icons in the System Console.
|
||||
|
||||
## Pagerduty
|
||||
|
||||
Pager duty is a fairly straightforward integration. The user will create an API Key in the pagerduty system (this will be the token that is given to Tower) and then create a "Service" which will provide an "Integration Key" that will be given to Tower also. The other options of note are:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user