diff --git a/engine/apps/alerts/signals.py b/engine/apps/alerts/signals.py index 1b4652aa..30f54803 100644 --- a/engine/apps/alerts/signals.py +++ b/engine/apps/alerts/signals.py @@ -20,6 +20,12 @@ alert_group_created_signal = django.dispatch.Signal( ] ) +alert_group_escalation_snapshot_built = django.dispatch.Signal( + providing_args=[ + "alert_group", + ] +) + # Signal to rerender alert group in all connected integrations (Slack, Telegram) when its state is changed alert_group_action_triggered_signal = django.dispatch.Signal( providing_args=[ diff --git a/engine/apps/alerts/tasks/distribute_alert.py b/engine/apps/alerts/tasks/distribute_alert.py index 87469ff9..0d532772 100644 --- a/engine/apps/alerts/tasks/distribute_alert.py +++ b/engine/apps/alerts/tasks/distribute_alert.py @@ -2,7 +2,7 @@ from django.apps import apps from django.conf import settings from apps.alerts.constants import TASK_DELAY_SECONDS -from apps.alerts.signals import alert_create_signal +from apps.alerts.signals import alert_create_signal, alert_group_escalation_snapshot_built from common.custom_celery_tasks import shared_dedicated_queue_retry_task from .task_logger import task_logger @@ -26,6 +26,7 @@ def distribute_alert(alert_id): if alert.is_the_first_alert_in_group: alert_group = AlertGroup.all_objects.filter(pk=alert.group_id).get() alert_group.start_escalation_if_needed(countdown=TASK_DELAY_SECONDS) + alert_group_escalation_snapshot_built.send(sender=distribute_alert, alert_group=alert_group) updated_rows = Alert.objects.filter(pk=alert_id, delivered=True).update(delivered=True) if updated_rows != 1: diff --git a/engine/apps/webhooks/listeners.py b/engine/apps/webhooks/listeners.py index 31c83637..4f8e5fc7 100644 --- a/engine/apps/webhooks/listeners.py +++ b/engine/apps/webhooks/listeners.py @@ -8,13 +8,8 @@ logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) -def on_alert_created(**kwargs): - Alert = apps.get_model("alerts", "Alert") - alert_pk = kwargs["alert"] - alert = Alert.objects.get(pk=alert_pk) - - if alert.is_the_first_alert_in_group: - alert_group_created.apply_async((alert.group_id,)) +def on_alert_group_created(**kwargs): + alert_group_created.apply_async((kwargs["alert_group"].id,)) def on_action_triggered(**kwargs): diff --git a/engine/apps/webhooks/signals.py b/engine/apps/webhooks/signals.py index 68d2559c..35c259c1 100644 --- a/engine/apps/webhooks/signals.py +++ b/engine/apps/webhooks/signals.py @@ -1,6 +1,6 @@ -from apps.alerts.signals import alert_create_signal, alert_group_action_triggered_signal +from apps.alerts.signals import alert_group_action_triggered_signal, alert_group_escalation_snapshot_built -from .listeners import on_action_triggered, on_alert_created +from .listeners import on_action_triggered, on_alert_group_created -alert_create_signal.connect(on_alert_created) +alert_group_escalation_snapshot_built.connect(on_alert_group_created) alert_group_action_triggered_signal.connect(on_action_triggered) diff --git a/engine/apps/webhooks/tests/test_trigger_webhook.py b/engine/apps/webhooks/tests/test_trigger_webhook.py index 7d948e75..eaae6f95 100644 --- a/engine/apps/webhooks/tests/test_trigger_webhook.py +++ b/engine/apps/webhooks/tests/test_trigger_webhook.py @@ -316,6 +316,7 @@ def test_execute_webhook_ok_forward_all( "alert_group": IncidentSerializer(alert_group).data, "alert_group_id": alert_group.public_primary_key, "alert_payload": "", + "users_to_be_notified": [], } expected_call = call( "https://something/{}/".format(alert_group.public_primary_key), diff --git a/engine/apps/webhooks/utils.py b/engine/apps/webhooks/utils.py index 4dedae92..30d768a5 100644 --- a/engine/apps/webhooks/utils.py +++ b/engine/apps/webhooks/utils.py @@ -8,6 +8,7 @@ from django.apps import apps from django.conf import settings from apps.base.utils import live_settings +from apps.schedules.ical_utils import list_users_to_notify_from_ical from common.jinja_templater import apply_jinja_template @@ -124,6 +125,30 @@ def _serialize_event_user(user): } +def _extract_users_from_escalation_snapshot(escalation_snapshot): + from apps.alerts.models import EscalationPolicy + + users = [] + if escalation_snapshot: + for policy_snapshot in escalation_snapshot.escalation_policies_snapshots: + if policy_snapshot.step in [ + EscalationPolicy.STEP_NOTIFY, + EscalationPolicy.STEP_NOTIFY_IMPORTANT, + EscalationPolicy.STEP_NOTIFY_MULTIPLE_USERS, + EscalationPolicy.STEP_NOTIFY_MULTIPLE_USERS_IMPORTANT, + ]: + for user in policy_snapshot.notify_to_users_queue: + users.append(_serialize_event_user(user)) + elif policy_snapshot.step in [ + EscalationPolicy.STEP_NOTIFY_SCHEDULE, + EscalationPolicy.STEP_NOTIFY_SCHEDULE_IMPORTANT, + ]: + if policy_snapshot.notify_schedule: + for user in list_users_to_notify_from_ical(policy_snapshot.notify_schedule): + users.append(_serialize_event_user(user)) + return list({u["id"]: u for u in users}.values()) + + def serialize_event(event, alert_group, user, responses=None): from apps.public_api.serializers import IncidentSerializer @@ -148,6 +173,7 @@ def serialize_event(event, alert_group, user, responses=None): _serialize_event_user(user) for user in set(notification.author for notification in alert_group.sent_notifications) ], + "users_to_be_notified": _extract_users_from_escalation_snapshot(alert_group.escalation_snapshot), } if responses: data["responses"] = responses