-
Notifications
You must be signed in to change notification settings - Fork 296
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove template editor from Slack #1847
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,9 @@ | ||
import json | ||
|
||
from django.apps import apps | ||
from django.db import transaction | ||
from jinja2 import TemplateSyntaxError | ||
from rest_framework.response import Response | ||
|
||
from apps.api.permissions import RBACPermission | ||
from apps.slack.scenarios import scenario_step | ||
from common.insight_log import EntityEvent, write_resource_insight_log | ||
from common.jinja_templater import jinja_template_env | ||
|
||
from .step_mixins import CheckAlertIsUnarchivedMixin, IncidentActionsAccessControlMixin | ||
|
||
|
@@ -21,7 +16,6 @@ class OpenAlertAppearanceDialogStep( | |
|
||
def process_scenario(self, slack_user_identity, slack_team_identity, payload): | ||
AlertGroup = apps.get_model("alerts", "AlertGroup") | ||
AlertReceiveChannel = apps.get_model("alerts", "AlertReceiveChannel") | ||
|
||
try: | ||
message_ts = payload["message_ts"] | ||
|
@@ -45,148 +39,17 @@ def process_scenario(self, slack_user_identity, slack_team_identity, payload): | |
"message_ts": message_ts, | ||
} | ||
|
||
integration = alert_group.channel.integration | ||
|
||
PAYLOAD_TEXT_SIZE = 3000 | ||
raw_request_data = json.dumps(alert_group.alerts.first().raw_request_data, sort_keys=True, indent=4) | ||
|
||
# This is a special case for amazon sns notifications in str format CHEKED | ||
if ( | ||
hasattr(AlertReceiveChannel, "INTEGRATION_AMAZON_SNS") | ||
and alert_group.channel.integration == AlertReceiveChannel.INTEGRATION_AMAZON_SNS | ||
and raw_request_data == "{}" | ||
): | ||
raw_request_data = alert_group.alerts.first().message | ||
|
||
raw_request_data_chunks = [ | ||
raw_request_data[i : i + PAYLOAD_TEXT_SIZE] for i in range(0, len(raw_request_data), PAYLOAD_TEXT_SIZE) | ||
] | ||
for idx, chunk in enumerate(raw_request_data_chunks): | ||
block = { | ||
"type": "input", | ||
"block_id": f"payload_{idx}", | ||
"label": { | ||
"type": "plain_text", | ||
"text": f"Payload (Part {idx + 1}):" if len(raw_request_data_chunks) > 1 else "Payload (Readonly)", | ||
}, | ||
"element": { | ||
"type": "plain_text_input", | ||
"placeholder": { | ||
"type": "plain_text", | ||
"text": "Payload of the current alert", | ||
}, | ||
"action_id": UpdateAppearanceStep.routing_uid(), | ||
"multiline": True, | ||
alert_receive_channel = alert_group.channel | ||
blocks = [ | ||
{ | ||
"type": "section", | ||
"text": { | ||
"type": "mrkdwn", | ||
"text": f":point_right: Click <{alert_receive_channel.web_link}|here> to open Integrations settings, edit Slack templates and return here", | ||
}, | ||
"optional": True, | ||
"hint": {"type": "plain_text", "text": "This is example payload of the first alert of the group"}, | ||
} | ||
block["element"]["initial_value"] = chunk | ||
blocks.append(block) | ||
blocks.append({"type": "divider"}) | ||
|
||
for notification_channel in ["slack", "web", "sms", "phone_call", "telegram"]: | ||
blocks.append( | ||
{ | ||
"type": "header", | ||
"text": { | ||
"type": "plain_text", | ||
"text": f"{notification_channel.replace('_', ' ').title()} Templates", | ||
"emoji": True, | ||
}, | ||
} | ||
) | ||
for templatizable_attr in ["title", "message", "image_url"]: | ||
try: | ||
attr = getattr(alert_group.channel, f"{notification_channel}_{templatizable_attr}_template") | ||
except AttributeError: | ||
continue | ||
block = { | ||
"type": "input", | ||
"block_id": f"{notification_channel}_{templatizable_attr}_template", | ||
"label": { | ||
"type": "plain_text", | ||
"text": f"{notification_channel.capitalize()} {templatizable_attr}:", | ||
}, | ||
"element": { | ||
"type": "plain_text_input", | ||
"placeholder": {"type": "plain_text", "text": f"{{{{ payload.{templatizable_attr} }}}}"}, | ||
"action_id": UpdateAppearanceStep.routing_uid(), | ||
"multiline": True, | ||
}, | ||
"optional": True, | ||
"hint": { | ||
"type": "plain_text", | ||
"text": "Jinja2 template", | ||
}, | ||
} | ||
if attr is not None: | ||
block["element"]["initial_value"] = attr | ||
else: | ||
default_values = getattr( | ||
AlertReceiveChannel, | ||
f"INTEGRATION_TO_DEFAULT_{notification_channel.upper()}_{templatizable_attr.upper()}_TEMPLATE", | ||
None, | ||
) | ||
if default_values is not None: | ||
default_value = default_values.get(integration) | ||
if default_value is not None: | ||
block["element"]["initial_value"] = default_value | ||
blocks.append(block) | ||
blocks.append({"type": "divider"}) | ||
|
||
common_templates_meta_data = { | ||
"source_link": {"placeholder": "{{ payload.link_to_upstream_details }}", "hint": "Jinja2 template."}, | ||
"grouping_id": {"placeholder": "{{ payload.uid }}", "hint": "Jinja2 template"}, | ||
"resolve_condition": { | ||
"placeholder": '{{ 1 if payload.state == "OK" else 0 }}', | ||
"hint": "This Jinja2 template should output one of the following values: ok, true, 1 (case insensitive)", | ||
}, | ||
"acknowledge_condition": { | ||
"placeholder": '{{ 1 if payload.state == "OK" else 0 }}', | ||
"hint": "This Jinja2 template should output one of the following values: ok, true, 1 (case insensitive)", | ||
}, | ||
} | ||
|
||
for common_template in common_templates_meta_data.keys(): | ||
try: | ||
attr = getattr(alert_group.channel, f"{common_template}_template") | ||
except AttributeError: | ||
continue | ||
|
||
block = { | ||
"type": "input", | ||
"block_id": f"{common_template}_template", | ||
"label": { | ||
"type": "plain_text", | ||
"text": f"{common_template.capitalize().replace('_', ' ')}:", | ||
}, | ||
"element": { | ||
"type": "plain_text_input", | ||
"placeholder": { | ||
"type": "plain_text", | ||
"text": common_templates_meta_data[common_template]["placeholder"], | ||
}, | ||
"action_id": UpdateAppearanceStep.routing_uid(), | ||
"multiline": True, | ||
}, | ||
"optional": True, | ||
"hint": { | ||
"type": "plain_text", | ||
"text": common_templates_meta_data[common_template]["hint"], | ||
}, | ||
} | ||
if attr is not None: | ||
block["element"]["initial_value"] = attr | ||
else: | ||
default_values = getattr( | ||
AlertReceiveChannel, f"INTEGRATION_TO_DEFAULT_{common_template.upper()}_TEMPLATE", None | ||
) | ||
if default_values is not None: | ||
default_value = default_values.get(integration) | ||
if default_value: | ||
block["element"]["initial_value"] = default_value | ||
blocks.append(block) | ||
{"type": "section", "text": {"type": "mrkdwn", "text": "Once changed Refresh the alert group"}}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really need refresh alert group? We don't have this for msteams and telegram There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't want to silently remove the button, so keeping this for transition period and then decide |
||
] | ||
|
||
view = { | ||
"callback_id": UpdateAppearanceStep.routing_uid(), | ||
|
@@ -198,7 +61,7 @@ def process_scenario(self, slack_user_identity, slack_team_identity, payload): | |
}, | ||
"submit": { | ||
"type": "plain_text", | ||
"text": "Submit", | ||
"text": "Refresh alert group", | ||
}, | ||
"private_metadata": json.dumps(private_metadata), | ||
} | ||
|
@@ -213,101 +76,11 @@ def process_scenario(self, slack_user_identity, slack_team_identity, payload): | |
class UpdateAppearanceStep(scenario_step.ScenarioStep): | ||
def process_scenario(self, slack_user_identity, slack_team_identity, payload): | ||
AlertGroup = apps.get_model("alerts", "AlertGroup") | ||
AlertReceiveChannel = apps.get_model("alerts", "AlertReceiveChannel") | ||
|
||
private_metadata = json.loads(payload["view"]["private_metadata"]) | ||
alert_group_pk = private_metadata["alert_group_pk"] | ||
payload_values = payload["view"]["state"]["values"] | ||
|
||
with transaction.atomic(): | ||
alert_group = AlertGroup.all_objects.filter(pk=alert_group_pk).select_for_update().get() | ||
integration = alert_group.channel.integration | ||
alert_receive_channel = alert_group.channel | ||
prev_state = alert_receive_channel.insight_logs_serialized | ||
|
||
for templatizable_attr in ["title", "message", "image_url"]: | ||
for notification_channel in ["slack", "web", "sms", "phone_call", "telegram"]: | ||
attr_name = f"{notification_channel}_{templatizable_attr}_template" | ||
try: | ||
old_value = getattr(alert_receive_channel, attr_name) | ||
except AttributeError: | ||
continue | ||
new_value = payload_values[attr_name][self.routing_uid()].get("value") | ||
|
||
if new_value is None and old_value is not None: | ||
setattr(alert_receive_channel, attr_name, None) | ||
alert_receive_channel.save() | ||
elif new_value is not None: | ||
default_values = getattr( | ||
AlertReceiveChannel, | ||
f"INTEGRATION_TO_DEFAULT_{notification_channel.upper()}_{templatizable_attr.upper()}_TEMPLATE", | ||
None, | ||
) | ||
if default_values is not None: | ||
default_value = default_values.get(integration) | ||
|
||
try: | ||
if default_value is None or new_value.strip() != default_value.strip(): | ||
jinja_template_env.from_string(new_value) | ||
setattr(alert_receive_channel, attr_name, new_value) | ||
alert_receive_channel.save() | ||
elif default_value is not None and new_value.strip() == default_value.strip(): | ||
new_value = None | ||
setattr(alert_receive_channel, attr_name, new_value) | ||
alert_receive_channel.save() | ||
except TemplateSyntaxError: | ||
return Response( | ||
{"response_action": "errors", "errors": {attr_name: "Template has incorrect format"}}, | ||
headers={"content-type": "application/json"}, | ||
) | ||
|
||
common_templates = ["source_link", "grouping_id", "resolve_condition", "acknowledge_condition"] | ||
for common_template in common_templates: | ||
attr_name = f"{common_template}_template" | ||
try: | ||
old_value = getattr(alert_receive_channel, attr_name) | ||
except AttributeError: | ||
continue | ||
new_value = payload_values[attr_name][self.routing_uid()].get("value") | ||
|
||
if new_value is None and old_value is not None: | ||
setattr(alert_receive_channel, attr_name, None) | ||
alert_receive_channel.save() | ||
alert_group.save() | ||
elif new_value is not None: | ||
default_values = getattr( | ||
AlertReceiveChannel, f"INTEGRATION_TO_DEFAULT_{common_template.upper()}_TEMPLATE", None | ||
) | ||
if default_values is not None: | ||
default_value = default_values.get(integration) | ||
|
||
try: | ||
if default_value is None or new_value.strip() != default_value.strip(): | ||
jinja_template_env.from_string(new_value) | ||
setattr(alert_receive_channel, attr_name, new_value) | ||
alert_receive_channel.save() | ||
alert_group.save() | ||
elif default_value is not None and new_value.strip() == default_value.strip(): | ||
new_value = None | ||
setattr(alert_receive_channel, attr_name, new_value) | ||
alert_receive_channel.save() | ||
alert_group.save() | ||
except TemplateSyntaxError: | ||
return Response( | ||
{"response_action": "errors", "errors": {common_template: "Template has incorrect format"}}, | ||
headers={"content-type": "application/json"}, | ||
) | ||
|
||
new_state = alert_receive_channel.insight_logs_serialized | ||
|
||
if new_state != prev_state: | ||
write_resource_insight_log( | ||
instance=alert_receive_channel, | ||
author=slack_user_identity.get_user(alert_receive_channel.organization), | ||
event=EntityEvent.UPDATED, | ||
prev_state=prev_state, | ||
new_state=new_state, | ||
) | ||
alert_group = AlertGroup.all_objects.get(pk=alert_group_pk) | ||
|
||
attachments = alert_group.render_slack_attachments() | ||
blocks = alert_group.render_slack_blocks() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Maybe use a button with a URL as shown in Slack docs to redirect to the web UI? A button with URL seems to be more appropriate for this use case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the next version we’ll have 3 urls to 3 templates