From d00314b7e157f8e61edee9eb7a87b415edf867da Mon Sep 17 00:00:00 2001 From: Ravishankar Date: Fri, 5 Apr 2024 21:27:48 +0530 Subject: [PATCH] Added Outgoing Web hooks to escalation policy log (#4150) # What this PR does Adds the Outgoing web hooks escalation step to the escalation plan log. ## Which issue(s) this PR closes Closes #4037 ## Checklist - [x] Unit, integration, and e2e (if applicable) tests updated - [x] Documentation added (or `pr:no public docs` PR label added if not required) - [x] Added the relevant release notes label (see labels prefixed w/ `release:`). These labels dictate how your PR will show up in the autogenerated release notes. Co-authored-by: Joey Orlando --- .../incident_log_builder.py | 10 +++++- .../alerts/tests/test_incident_log_builder.py | 34 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/engine/apps/alerts/incident_log_builder/incident_log_builder.py b/engine/apps/alerts/incident_log_builder/incident_log_builder.py index 72ba3fe9..d2d88db4 100644 --- a/engine/apps/alerts/incident_log_builder/incident_log_builder.py +++ b/engine/apps/alerts/incident_log_builder/incident_log_builder.py @@ -554,7 +554,15 @@ class IncidentLogBuilder: # notification_plan_dict structure - {timedelta: [{"user_id": user.pk, "plan_lines": []}] for timedelta, notification_plan in notification_plan_dict.items(): escalation_plan_dict.setdefault(timedelta, []).extend(notification_plan) - # TODO: should we add logic here for new webhooks? + elif escalation_policy_snapshot.step == EscalationPolicy.STEP_TRIGGER_CUSTOM_WEBHOOK: + if future_step: + custom_webhook = escalation_policy_snapshot.custom_webhook + if custom_webhook is not None: + plan_line = f'trigger outgoing webhook "{custom_webhook.name}"' + else: + plan_line = f'escalation step "{escalation_policy_snapshot.step_display}" but outgoing webhook is unspecified. Skipping' + plan = {"plan_lines": [plan_line]} + escalation_plan_dict.setdefault(timedelta, []).append(plan) elif escalation_policy_snapshot.step == EscalationPolicy.STEP_NOTIFY_IF_TIME: if future_step: if escalation_policy_snapshot.from_time is not None and escalation_policy_snapshot.to_time is not None: diff --git a/engine/apps/alerts/tests/test_incident_log_builder.py b/engine/apps/alerts/tests/test_incident_log_builder.py index 84e096b8..594399a7 100644 --- a/engine/apps/alerts/tests/test_incident_log_builder.py +++ b/engine/apps/alerts/tests/test_incident_log_builder.py @@ -37,3 +37,37 @@ def test_escalation_plan_messaging_backends( log_builder = IncidentLogBuilder(alert_group=alert_group) plan = log_builder.get_incident_escalation_plan() assert list(plan.values()) == [["send test only backend message to {}".format(user.username)]] + + +@pytest.mark.django_db +def test_escalation_plan_custom_webhooks( + make_organization_and_user, + make_escalation_chain, + make_escalation_policy, + make_custom_webhook, + make_alert_receive_channel, + make_channel_filter, + make_alert_group, +): + organization, user = make_organization_and_user() + escalation_chain = make_escalation_chain(organization=organization) + custom_webhook = make_custom_webhook(organization=organization) + make_escalation_policy( + escalation_chain=escalation_chain, + escalation_policy_step=EscalationPolicy.STEP_WAIT, + wait_delay=EscalationPolicy.FIFTEEN_MINUTES, + ) + make_escalation_policy( + escalation_chain=escalation_chain, + escalation_policy_step=EscalationPolicy.STEP_TRIGGER_CUSTOM_WEBHOOK, + custom_webhook=custom_webhook, + ) + alert_receive_channel = make_alert_receive_channel(organization=organization) + channel_filter = make_channel_filter(alert_receive_channel, escalation_chain=escalation_chain) + alert_group = make_alert_group(alert_receive_channel, channel_filter=channel_filter) + alert_group.raw_escalation_snapshot = alert_group.build_raw_escalation_snapshot() + alert_group.save() + + log_builder = IncidentLogBuilder(alert_group=alert_group) + plan = log_builder.get_incident_escalation_plan() + assert list(plan.values()) == [[f'trigger outgoing webhook "{custom_webhook.name}"']]