From abb698e825926418ccf8afec5d2ffab646517b00 Mon Sep 17 00:00:00 2001 From: Rares Mardare Date: Mon, 11 Dec 2023 15:54:31 +0200 Subject: [PATCH 1/8] Unified logo with IRM, added few minor UI tweaks, bumped labels version (#3531) # What this PR does - Mostly this -> https://github.com/grafana/oncall/issues/1905 ## Which issue(s) this PR fixes ## Checklist - [ ] Unit, integration, and e2e (if applicable) tests updated - [ ] Documentation added (or `pr:no public docs` PR label added if not required) - [ ] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required) --- .../e2e-tests/integrations/heartbeat.test.ts | 3 +++ grafana-plugin/e2e-tests/utils/schedule.ts | 7 ------- grafana-plugin/package.json | 2 +- grafana-plugin/src/PluginPage.tsx | 8 +++++++- grafana-plugin/src/navbar/Header/Header.module.scss | 12 +++++++++++- grafana-plugin/src/navbar/Header/Header.tsx | 5 +++-- .../src/pages/integrations/Integrations.module.scss | 4 ++++ grafana-plugin/yarn.lock | 8 ++++---- 8 files changed, 33 insertions(+), 16 deletions(-) diff --git a/grafana-plugin/e2e-tests/integrations/heartbeat.test.ts b/grafana-plugin/e2e-tests/integrations/heartbeat.test.ts index 374ca6ae..2ba7e16e 100644 --- a/grafana-plugin/e2e-tests/integrations/heartbeat.test.ts +++ b/grafana-plugin/e2e-tests/integrations/heartbeat.test.ts @@ -7,6 +7,7 @@ const HEARTBEAT_SETTINGS_FORM_TEST_ID = 'heartbeat-settings-form'; test.describe("updating an integration's heartbeat interval works", async () => { const _openHeartbeatSettingsForm = async (page: Page) => { await page.getByTestId('integration-settings-context-menu-wrapper').getByRole('img').click(); + await page.waitForTimeout(1000); await page.getByTestId('integration-heartbeat-settings').click(); }; @@ -29,6 +30,8 @@ test.describe("updating an integration's heartbeat interval works", async () => await heartbeatSettingsForm.getByTestId('update-heartbeat').click(); + await page.waitForTimeout(1000); + await _openHeartbeatSettingsForm(page); const heartbeatIntervalValue = await heartbeatSettingsForm diff --git a/grafana-plugin/e2e-tests/utils/schedule.ts b/grafana-plugin/e2e-tests/utils/schedule.ts index 3627109a..9c5257f6 100644 --- a/grafana-plugin/e2e-tests/utils/schedule.ts +++ b/grafana-plugin/e2e-tests/utils/schedule.ts @@ -20,13 +20,6 @@ export const createOnCallSchedule = async (page: Page, scheduleName: string, use await clickButton({ page, buttonText: 'Add rotation' }); - /** - * Drag the modal such that the "Create" button will always be visible within the viewport. We cannot scroll - * on the modal itself - * https://playwright.dev/docs/input#dragging-manually - */ - await page.locator('.ReactModal__Content .drag-handler').dragTo(page.locator('.page-header__logo')); - await selectDropdownValue({ page, selectType: 'grafanaSelect', diff --git a/grafana-plugin/package.json b/grafana-plugin/package.json index 60ac20c9..33214b17 100644 --- a/grafana-plugin/package.json +++ b/grafana-plugin/package.json @@ -122,7 +122,7 @@ "@grafana/data": "^9.2.4", "@grafana/faro-web-sdk": "^1.0.0-beta4", "@grafana/faro-web-tracing": "^1.0.0-beta4", - "@grafana/labels": "~1.4.2", + "@grafana/labels": "~1.4.3", "@grafana/runtime": "9.3.0-beta1", "@grafana/ui": "^10.2.0", "@lifeomic/attempt": "^3.0.3", diff --git a/grafana-plugin/src/PluginPage.tsx b/grafana-plugin/src/PluginPage.tsx index 4497af92..5b81bdc2 100644 --- a/grafana-plugin/src/PluginPage.tsx +++ b/grafana-plugin/src/PluginPage.tsx @@ -3,8 +3,10 @@ import React from 'react'; import { PluginPageProps, PluginPage as RealPluginPage } from '@grafana/runtime'; import Header from 'navbar/Header/Header'; +import RenderConditionally from 'components/RenderConditionally/RenderConditionally'; import { pages } from 'pages'; import { isTopNavbar } from 'plugin/GrafanaPluginRootPage.helpers'; +import { DEFAULT_PAGE } from 'utils/consts'; interface AppPluginPageProps extends PluginPageProps { page?: string; @@ -14,10 +16,14 @@ export const PluginPage = (isTopNavbar() ? RealPlugin : PluginPageFallback) as R function RealPlugin(props: AppPluginPageProps): React.ReactNode { const { page } = props; + const isDefaultPage = page === DEFAULT_PAGE; return ( -
+ +
+ + {pages[page]?.text && !pages[page]?.hideTitle && (

{pages[page].text} diff --git a/grafana-plugin/src/navbar/Header/Header.module.scss b/grafana-plugin/src/navbar/Header/Header.module.scss index 78318cca..bd85bd65 100644 --- a/grafana-plugin/src/navbar/Header/Header.module.scss +++ b/grafana-plugin/src/navbar/Header/Header.module.scss @@ -4,7 +4,7 @@ .header-topnavbar { padding-top: 0; - padding-bottom: 36px; + padding-bottom: 12px; } .navbar-heading { @@ -34,6 +34,7 @@ flex-direction: row; column-gap: 8px; row-gap: 8px; + margin-left: -50px; } .irm-icon { @@ -52,3 +53,12 @@ margin-bottom: 0; } } + +.logo-container, +.page-header__img { + height: 32px; +} + +.page-header__title { + margin-bottom: 8px; +} diff --git a/grafana-plugin/src/navbar/Header/Header.tsx b/grafana-plugin/src/navbar/Header/Header.tsx index 00cae379..c7878ae5 100644 --- a/grafana-plugin/src/navbar/Header/Header.tsx +++ b/grafana-plugin/src/navbar/Header/Header.tsx @@ -23,8 +23,8 @@ const Header = observer(() => {
- - Grafana OnCall + + Grafana OnCall
{renderHeading()}
@@ -41,6 +41,7 @@ const Header = observer(() => {

Grafana OnCall

{APP_SUBTITLE}
+ Date: Mon, 11 Dec 2023 17:17:41 +0300 Subject: [PATCH 2/8] Fix schedules invalid dates issue (#3541) # What this PR does Fix schedules invalid dates issue ## Which issue(s) this PR fixes https://github.com/grafana/support-escalations/issues/8084 ## Checklist - [ ] Unit, integration, and e2e (if applicable) tests updated - [ ] Documentation added (or `pr:no public docs` PR label added if not required) - [ ] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required) --- CHANGELOG.md | 4 ++++ grafana-plugin/src/pages/schedule/Schedule.helpers.ts | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 757a953d..b521acd2 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 +### Fixed + +- Fix schedules invalid dates issue ([#support-escalations/issues/8084](https://github.com/grafana/support-escalations/issues/8084)) + ## v1.3.76 (2023-12-11) ### Fixed diff --git a/grafana-plugin/src/pages/schedule/Schedule.helpers.ts b/grafana-plugin/src/pages/schedule/Schedule.helpers.ts index d1139fb4..ddb2de77 100644 --- a/grafana-plugin/src/pages/schedule/Schedule.helpers.ts +++ b/grafana-plugin/src/pages/schedule/Schedule.helpers.ts @@ -16,10 +16,13 @@ const mondayDayOffset = { }; export const getWeekStartString = () => { - if (!config.bootData.user.weekStart || config.bootData.user.weekStart === 'browser') { + const weekStart = (config.bootData.user.weekStart || '').toLowerCase(); + + if (!weekStart || weekStart === 'browser') { return 'monday'; } - return config.bootData.user.weekStart; + + return weekStart; }; export const getNow = (tz: Timezone) => { From c667d625d8f8035c9865e11225411f768b9c89ab Mon Sep 17 00:00:00 2001 From: Joey Orlando Date: Mon, 11 Dec 2023 10:20:01 -0500 Subject: [PATCH 3/8] tiltfile - port forward mariadb to host machine --- Tiltfile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Tiltfile b/Tiltfile index eb71dad6..ec6e80ba 100644 --- a/Tiltfile +++ b/Tiltfile @@ -102,7 +102,11 @@ k8s_resource( labels=["OnCallBackend"], ) k8s_resource(workload="redis-master", labels=["OnCallDeps"]) -k8s_resource(workload="mariadb", labels=["OnCallDeps"]) +k8s_resource( + workload="mariadb", + port_forwards='3307:3306', # : + labels=["OnCallDeps"], +) # name all tilt resources after the k8s object namespace + name From 58de3f845845556782267ef303affda498d33e09 Mon Sep 17 00:00:00 2001 From: Yulya Artyukhina Date: Mon, 11 Dec 2023 17:32:15 +0100 Subject: [PATCH 4/8] Handle `Unauthorized` exception on posting alert group to telegram (#3540) ## Which issue(s) this PR fixes https://github.com/grafana/oncall-private/issues/2377 ## 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] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required) --- .../telegram/models/connectors/personal.py | 7 +++ .../telegram/tests/test_personal_connector.py | 51 ++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/engine/apps/telegram/models/connectors/personal.py b/engine/apps/telegram/models/connectors/personal.py index 8dfdc6f7..cad4fe64 100644 --- a/engine/apps/telegram/models/connectors/personal.py +++ b/engine/apps/telegram/models/connectors/personal.py @@ -167,6 +167,13 @@ class TelegramToUserConnector(models.Model): notification_policy, UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_TELEGRAM_TOKEN_ERROR, ) + elif e.message == "Forbidden: user is deactivated": + TelegramToUserConnector.create_telegram_notification_error( + alert_group, + self.user, + notification_policy, + UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_TELEGRAM_USER_IS_DEACTIVATED, + ) else: raise e diff --git a/engine/apps/telegram/tests/test_personal_connector.py b/engine/apps/telegram/tests/test_personal_connector.py index b1ea07a0..add403cb 100644 --- a/engine/apps/telegram/tests/test_personal_connector.py +++ b/engine/apps/telegram/tests/test_personal_connector.py @@ -3,7 +3,7 @@ from unittest.mock import patch import pytest from telegram import error -from apps.base.models import UserNotificationPolicy +from apps.base.models import UserNotificationPolicy, UserNotificationPolicyLogRecord from apps.telegram.client import TelegramClient from apps.telegram.models import TelegramMessage @@ -47,3 +47,52 @@ def test_personal_connector_replied_message_not_found( text="One more notification about this 👆", reply_to_message_id=telegram_message.message_id, ) + + +@pytest.mark.parametrize( + "side_effect,notification_error_code", + [ + ( + error.Unauthorized("Forbidden: bot was blocked by the user"), + UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_TELEGRAM_BOT_IS_DELETED, + ), + (error.Unauthorized("Invalid token"), UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_TELEGRAM_TOKEN_ERROR), + ( + error.Unauthorized("Forbidden: user is deactivated"), + UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_TELEGRAM_USER_IS_DEACTIVATED, + ), + ], +) +@pytest.mark.django_db +def test_personal_connector_send_link_to_channel_message_handle_exceptions( + side_effect, + notification_error_code, + make_organization_and_user, + make_telegram_user_connector, + make_user_notification_policy, + make_alert_receive_channel, + make_alert_group, +): + # set up a user with Telegram account connected + organization, user = make_organization_and_user() + user_connector = make_telegram_user_connector(user) + notification_policy = make_user_notification_policy( + user, + UserNotificationPolicy.Step.NOTIFY, + notify_by=UserNotificationPolicy.NotificationChannel.TELEGRAM, + important=False, + ) + + # create an alert group with an existing Telegram message in user's DM + alert_receive_channel = make_alert_receive_channel(organization) + alert_group = make_alert_group(alert_receive_channel) + + assert not user.personal_log_records.exists() + + with patch.object(TelegramClient, "send_message", side_effect=side_effect) as mock_send_message: + user_connector.send_link_to_channel_message(alert_group, notification_policy) + + mock_send_message.assert_called_once() + log_records = user.personal_log_records.filter(alert_group=alert_group) + assert log_records.count() == 1 + assert log_records.first().notification_error_code == notification_error_code From 16ba87bff60428c1b02f442e0692dd42eadb04e8 Mon Sep 17 00:00:00 2001 From: Joey Orlando Date: Mon, 11 Dec 2023 12:16:00 -0500 Subject: [PATCH 5/8] Don't update alert group metrics when deleting an alert group (#3544) # Which issue(s) this PR fixes Fixes https://github.com/grafana/oncall-private/issues/2376 ## Checklist - [x] Unit, integration, and e2e (if applicable) tests updated - [ ] Documentation added (or `pr:no public docs` PR label added if not required) - [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required) --- CHANGELOG.md | 1 + engine/apps/alerts/models/alert_group.py | 7 +-- .../apps/alerts/tasks/delete_alert_group.py | 2 + engine/apps/alerts/tests/test_alert_group.py | 44 +++++++++++++++++++ 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b521acd2..68fcba0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fix schedules invalid dates issue ([#support-escalations/issues/8084](https://github.com/grafana/support-escalations/issues/8084)) +- Fix issue related to updating alert group metrics when deleting an alert group via the public API by @joeyorlando ([#3544](https://github.com/grafana/oncall/pull/3544)) ## v1.3.76 (2023-12-11) diff --git a/engine/apps/alerts/models/alert_group.py b/engine/apps/alerts/models/alert_group.py index 5a891a44..54e86764 100644 --- a/engine/apps/alerts/models/alert_group.py +++ b/engine/apps/alerts/models/alert_group.py @@ -1191,8 +1191,6 @@ class AlertGroup(AlertGroupSlackRenderingMixin, EscalationSnapshotMixin, models. def delete_by_user(self, user: User): from apps.alerts.models import AlertGroupLogRecord - initial_state = self.state - self.stop_escalation() # prevent creating multiple logs # filter instead of get_or_create cause it can be multiple logs of this type due deleting error @@ -1222,10 +1220,9 @@ class AlertGroup(AlertGroupSlackRenderingMixin, EscalationSnapshotMixin, models. dependent_alerts = list(self.dependent_alert_groups.all()) self.hard_delete() - # Update alert group state metric cache - self._update_metrics(organization_id=user.organization_id, previous_state=initial_state, state=None) - for dependent_alert_group in dependent_alerts: # unattach dependent incidents + # unattach dependent incidents + for dependent_alert_group in dependent_alerts: dependent_alert_group.un_attach_by_delete() def hard_delete(self): diff --git a/engine/apps/alerts/tasks/delete_alert_group.py b/engine/apps/alerts/tasks/delete_alert_group.py index f8a1d2ae..e97ce515 100644 --- a/engine/apps/alerts/tasks/delete_alert_group.py +++ b/engine/apps/alerts/tasks/delete_alert_group.py @@ -24,6 +24,8 @@ def delete_alert_group(alert_group_pk, user_pk): logger.debug("User not found, skipping delete_alert_group") return + logger.debug(f"User {user} is deleting alert group {alert_group} (channel: {alert_group.channel})") + try: alert_group.delete_by_user(user) except SlackAPIRatelimitError as e: diff --git a/engine/apps/alerts/tests/test_alert_group.py b/engine/apps/alerts/tests/test_alert_group.py index 819b6af9..d2ba04d2 100644 --- a/engine/apps/alerts/tests/test_alert_group.py +++ b/engine/apps/alerts/tests/test_alert_group.py @@ -577,3 +577,47 @@ def test_filter_active_alert_groups( assert active_alert_groups.count() == 2 assert alert_group_active in active_alert_groups assert alert_group_active_silenced in active_alert_groups + + +@patch("apps.alerts.models.AlertGroup.hard_delete") +@patch("apps.alerts.models.AlertGroup.un_attach_by_delete") +@patch("apps.alerts.models.AlertGroup.stop_escalation") +@patch("apps.alerts.models.alert_group.alert_group_action_triggered_signal") +@pytest.mark.django_db +def test_delete_by_user( + mock_alert_group_action_triggered_signal, + _mock_stop_escalation, + _mock_un_attach_by_delete, + _mock_hard_delete, + make_organization_and_user, + make_alert_receive_channel, + make_alert_group, +): + organization, user = make_organization_and_user() + alert_receive_channel = make_alert_receive_channel(organization) + + alert_group = make_alert_group(alert_receive_channel) + + # make a few dependent alert groups + dependent_alert_groups = [make_alert_group(alert_receive_channel, root_alert_group=alert_group) for _ in range(3)] + + assert alert_group.log_records.filter(type=AlertGroupLogRecord.TYPE_DELETED).count() == 0 + + alert_group.delete_by_user(user) + + assert alert_group.log_records.filter(type=AlertGroupLogRecord.TYPE_DELETED).count() == 1 + deleted_log_record = alert_group.log_records.get(type=AlertGroupLogRecord.TYPE_DELETED) + + alert_group.stop_escalation.assert_called_once_with() + + mock_alert_group_action_triggered_signal.send.assert_called_once_with( + sender=alert_group.delete_by_user, + log_record=deleted_log_record.pk, + action_source=None, + force_sync=True, + ) + + alert_group.hard_delete.assert_called_once_with() + + for dependent_alert_group in dependent_alert_groups: + dependent_alert_group.un_attach_by_delete.assert_called_with() From 0d959a5c205d5745ca787d181032fd6499fd5b5f Mon Sep 17 00:00:00 2001 From: Stanislav Lutsenko Date: Mon, 11 Dec 2023 20:33:54 +0300 Subject: [PATCH 6/8] Fix amazon_ses inbound email ESP provider (#3509) # What this PR does Fixes django-anymail[amazon-ses] issues according to [anymail docs](https://anymail.dev/en/stable/esps/amazon_ses/) ## Which issue(s) this PR fixes [#3508](https://github.com/grafana/oncall/issues/3508) ## Checklist - [x] Unit, integration, and e2e (if applicable) tests updated - [ ] Documentation added (or `pr:no public docs` PR label added if not required) - [ ] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required) --------- Co-authored-by: Joey Orlando Co-authored-by: Joey Orlando --- CHANGELOG.md | 1 + engine/apps/email/tests/test_inbound_email.py | 53 +++++++++++++++++++ engine/requirements.txt | 1 + 3 files changed, 55 insertions(+) create mode 100644 engine/apps/email/tests/test_inbound_email.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 68fcba0d..bc407411 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix schedules invalid dates issue ([#support-escalations/issues/8084](https://github.com/grafana/support-escalations/issues/8084)) - Fix issue related to updating alert group metrics when deleting an alert group via the public API by @joeyorlando ([#3544](https://github.com/grafana/oncall/pull/3544)) +- Fix issue with `amazon_ses` inbound email ESP provider by @Lutseslav ([#3509](https://github.com/grafana/oncall/pull/3509)) ## v1.3.76 (2023-12-11) diff --git a/engine/apps/email/tests/test_inbound_email.py b/engine/apps/email/tests/test_inbound_email.py new file mode 100644 index 00000000..64a4792c --- /dev/null +++ b/engine/apps/email/tests/test_inbound_email.py @@ -0,0 +1,53 @@ +import json +import pytest +from django.urls import reverse +from rest_framework import status +from rest_framework.test import APIClient + + +@pytest.mark.django_db +def test_amazon_ses_provider_load(settings, make_organization_and_user_with_token, make_alert_receive_channel): + settings.INBOUND_EMAIL_ESP = "amazon_ses" + settings.INBOUND_EMAIL_DOMAIN = "example.com" + + dummy_channel_token = "dummy-channel-token" + + organization, _, token = make_organization_and_user_with_token() + _ = make_alert_receive_channel(organization, token=dummy_channel_token) + + recipient = f"{dummy_channel_token}@example.com" + mime = f"""From: sender@example.com + Subject: Dummy email message + To: {recipient} + Content-Type: text/plain + + Hello! + """ + + message = { + "notificationType": "Received", + "receipt": {"action": {"type": "SNS"}, "recipients": [recipient]}, + "content": mime, + } + + dummy_sns_message_id = "22b80b92-fdea-4c2c-8f9d-bdfb0c7bf324" + dummy_sns_payload = { + "Type": "Notification", + "MessageId": dummy_sns_message_id, + "TopicArn": "arn:aws:sns:us-east-1:123456789012:MyTopic", + "Subject": "My First Message", + "Message": json.dumps(message), + } + + client = APIClient() + + response = client.post( + reverse("integrations:inbound_email_webhook"), + data=json.dumps(dummy_sns_payload), + content_type="application/json", + HTTP_AUTHORIZATION=token, + HTTP_X_AMZ_SNS_MESSAGE_TYPE="Notification", + HTTP_X_AMZ_SNS_MESSAGE_ID=dummy_sns_message_id, + ) + + assert response.status_code == status.HTTP_200_OK diff --git a/engine/requirements.txt b/engine/requirements.txt index f6e987c7..b182216f 100644 --- a/engine/requirements.txt +++ b/engine/requirements.txt @@ -45,6 +45,7 @@ opentelemetry-exporter-otlp-proto-grpc==1.15.0 django-dbconn-retry==0.1.7 django-ipware==4.0.2 django-anymail==8.6 +django-amazon-ses==4.0.1 django-deprecate-fields==0.1.1 pymdown-extensions==10.0 requests==2.31.0 From 8a56b2273b65afe84d0d739244c7effd24bc36a0 Mon Sep 17 00:00:00 2001 From: Yulya Artyukhina Date: Mon, 11 Dec 2023 19:06:04 +0100 Subject: [PATCH 7/8] Fix telegram retrying task after alert group was deleted (#3546) # What this PR does ## Which issue(s) this PR fixes https://github.com/grafana/oncall-private/issues/2379 ## Checklist - [ ] Unit, integration, and e2e (if applicable) tests updated - [x] Documentation added (or `pr:no public docs` PR label added if not required) - [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required) --------- Co-authored-by: Joey Orlando --- engine/apps/email/tests/test_inbound_email.py | 1 + engine/apps/telegram/tasks.py | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/engine/apps/email/tests/test_inbound_email.py b/engine/apps/email/tests/test_inbound_email.py index 64a4792c..91951139 100644 --- a/engine/apps/email/tests/test_inbound_email.py +++ b/engine/apps/email/tests/test_inbound_email.py @@ -1,4 +1,5 @@ import json + import pytest from django.urls import reverse from rest_framework import status diff --git a/engine/apps/telegram/tasks.py b/engine/apps/telegram/tasks.py index 1c160562..f2fbabb0 100644 --- a/engine/apps/telegram/tasks.py +++ b/engine/apps/telegram/tasks.py @@ -226,8 +226,19 @@ def on_alert_group_action_triggered_async(log_record_id): from .alert_group_representative import AlertGroupTelegramRepresentative logger.info(f"AlertGroupTelegramRepresentative ACTION SIGNAL, log record {log_record_id}") - - log_record = AlertGroupLogRecord.objects.get(pk=log_record_id) + # temporary solution to handle cases when alert group and related log records were deleted + try: + log_record = AlertGroupLogRecord.objects.get(pk=log_record_id) + except AlertGroupLogRecord.DoesNotExist as e: + retries_count = on_alert_group_action_triggered_async.request.retries + if retries_count >= 10: + logger.error( + f"AlertGroupTelegramRepresentative: was not able to get AlertGroupLogRecord, probably alert group " + f"was deleted. log record {log_record_id}, retries: {retries_count}" + ) + return + else: + raise e instance = AlertGroupTelegramRepresentative(log_record) if instance.is_applicable(): From f4d3a7c7e8420f5676e9423334887bbbeed2246f Mon Sep 17 00:00:00 2001 From: Joey Orlando Date: Mon, 11 Dec 2023 14:24:44 -0500 Subject: [PATCH 8/8] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc407411..826bcc0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## v1.3.77 (2023-12-11) + ### Fixed - Fix schedules invalid dates issue ([#support-escalations/issues/8084](https://github.com/grafana/support-escalations/issues/8084))