131 lines
4.6 KiB
Python
131 lines
4.6 KiB
Python
|
|
from apps.alerts.incident_appearance.renderers.base_renderer import AlertBaseRenderer, AlertGroupBaseRenderer
|
||
|
|
from apps.alerts.incident_appearance.templaters.alert_templater import AlertTemplater
|
||
|
|
from apps.alerts.models import Alert, AlertGroup
|
||
|
|
from apps.mattermost.events.types import EventAction
|
||
|
|
from apps.mattermost.utils import MattermostEventAuthenticator
|
||
|
|
from common.api_helpers.utils import create_engine_url
|
||
|
|
from common.utils import is_string_with_visible_characters, str_or_backup
|
||
|
|
|
||
|
|
|
||
|
|
class MattermostMessageRenderer:
|
||
|
|
def __init__(self, alert_group: AlertGroup):
|
||
|
|
self.alert_group = alert_group
|
||
|
|
|
||
|
|
def render_alert_group_message(self):
|
||
|
|
attachments = AlertGroupMattermostRenderer(self.alert_group).render_alert_group_attachments()
|
||
|
|
return {"props": {"attachments": attachments}}
|
||
|
|
|
||
|
|
|
||
|
|
class AlertMattermostTemplater(AlertTemplater):
|
||
|
|
RENDER_FOR_MATTERMOST = "mattermost"
|
||
|
|
|
||
|
|
def _render_for(self) -> str:
|
||
|
|
return self.RENDER_FOR_MATTERMOST
|
||
|
|
|
||
|
|
|
||
|
|
class AlertMattermostRenderer(AlertBaseRenderer):
|
||
|
|
def __init__(self, alert: Alert):
|
||
|
|
super().__init__(alert)
|
||
|
|
self.channel = alert.group.channel
|
||
|
|
|
||
|
|
@property
|
||
|
|
def templater_class(self):
|
||
|
|
return AlertMattermostTemplater
|
||
|
|
|
||
|
|
def render_alert_attachments(self):
|
||
|
|
attachments = []
|
||
|
|
title = str_or_backup(self.templated_alert.title, "Alert")
|
||
|
|
message = ""
|
||
|
|
if is_string_with_visible_characters(self.templated_alert.message):
|
||
|
|
message = self.templated_alert.message
|
||
|
|
attachments.append(
|
||
|
|
{
|
||
|
|
"fallback": "{}: {}".format(self.channel.get_integration_display(), self.alert.title),
|
||
|
|
"title": title,
|
||
|
|
"title_link": self.templated_alert.source_link,
|
||
|
|
"text": message,
|
||
|
|
"image_url": self.templated_alert.image_url,
|
||
|
|
}
|
||
|
|
)
|
||
|
|
return attachments
|
||
|
|
|
||
|
|
|
||
|
|
class AlertGroupMattermostRenderer(AlertGroupBaseRenderer):
|
||
|
|
def __init__(self, alert_group: AlertGroup):
|
||
|
|
super().__init__(alert_group)
|
||
|
|
|
||
|
|
self.alert_renderer = self.alert_renderer_class(self.alert_group.alerts.last())
|
||
|
|
|
||
|
|
@property
|
||
|
|
def alert_renderer_class(self):
|
||
|
|
return AlertMattermostRenderer
|
||
|
|
|
||
|
|
def render_alert_group_attachments(self):
|
||
|
|
attachments = self.alert_renderer.render_alert_attachments()
|
||
|
|
alert_group = self.alert_group
|
||
|
|
|
||
|
|
if alert_group.resolved:
|
||
|
|
attachments.append(
|
||
|
|
{
|
||
|
|
"fallback": "Resolved...",
|
||
|
|
"text": alert_group.get_resolve_text(),
|
||
|
|
}
|
||
|
|
)
|
||
|
|
elif alert_group.acknowledged:
|
||
|
|
attachments.append(
|
||
|
|
{
|
||
|
|
"fallback": "Acknowledged...",
|
||
|
|
"text": alert_group.get_acknowledge_text(),
|
||
|
|
}
|
||
|
|
)
|
||
|
|
|
||
|
|
# append buttons to the initial attachment
|
||
|
|
attachments[0]["actions"] = self._get_buttons_attachments()
|
||
|
|
|
||
|
|
return self._set_attachments_color(attachments)
|
||
|
|
|
||
|
|
def _get_buttons_attachments(self):
|
||
|
|
actions = []
|
||
|
|
|
||
|
|
def _make_actions(id, name, token):
|
||
|
|
return {
|
||
|
|
"id": id,
|
||
|
|
"name": name,
|
||
|
|
"integration": {
|
||
|
|
"url": create_engine_url("api/internal/v1/mattermost/event/"),
|
||
|
|
"context": {
|
||
|
|
"action": id,
|
||
|
|
"alert": self.alert_group.public_primary_key,
|
||
|
|
"token": token,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
token = MattermostEventAuthenticator.create_token(organization=self.alert_group.channel.organization)
|
||
|
|
if not self.alert_group.resolved:
|
||
|
|
if self.alert_group.acknowledged:
|
||
|
|
actions.append(_make_actions(EventAction.UNACKNOWLEDGE.value, "Unacknowledge", token))
|
||
|
|
else:
|
||
|
|
actions.append(_make_actions(EventAction.ACKNOWLEDGE.value, "Acknowledge", token))
|
||
|
|
|
||
|
|
if self.alert_group.resolved:
|
||
|
|
actions.append(_make_actions(EventAction.UNRESOLVE.value, "Unresolve", token))
|
||
|
|
else:
|
||
|
|
actions.append(_make_actions(EventAction.RESOLVE.value, "Resolve", token))
|
||
|
|
|
||
|
|
return actions
|
||
|
|
|
||
|
|
def _set_attachments_color(self, attachments):
|
||
|
|
color = "#a30200" # danger
|
||
|
|
if self.alert_group.silenced:
|
||
|
|
color = "#dddddd" # slack-grey
|
||
|
|
if self.alert_group.acknowledged:
|
||
|
|
color = "#daa038" # warning
|
||
|
|
if self.alert_group.resolved:
|
||
|
|
color = "#2eb886" # good
|
||
|
|
|
||
|
|
for attachment in attachments:
|
||
|
|
attachment["color"] = color
|
||
|
|
|
||
|
|
return attachments
|