diff --git a/CHANGELOG.md b/CHANGELOG.md index d17ee032bb..1e5ee2c716 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Changed + +- Remove template editor from Slack by @iskhakov ([1847](https://github.com/grafana/oncall/pull/1847)) + ### Added - Add filter descriptions to web ui by @iskhakov ([1845](https://github.com/grafana/oncall/pull/1845)) diff --git a/engine/apps/alerts/models/alert_receive_channel.py b/engine/apps/alerts/models/alert_receive_channel.py index 94db5d001f..41df3b0e53 100644 --- a/engine/apps/alerts/models/alert_receive_channel.py +++ b/engine/apps/alerts/models/alert_receive_channel.py @@ -370,7 +370,7 @@ def created_name(self): @property def web_link(self): - return urljoin(self.organization.web_link, "?page=settings") + return urljoin(self.organization.web_link, f"integrations/{self.public_primary_key}") @property def integration_url(self): diff --git a/engine/apps/slack/scenarios/alertgroup_appearance.py b/engine/apps/slack/scenarios/alertgroup_appearance.py index b3443c52d4..649f006f00 100644 --- a/engine/apps/slack/scenarios/alertgroup_appearance.py +++ b/engine/apps/slack/scenarios/alertgroup_appearance.py @@ -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"}}, + ] 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()