From 14165fabed1e00eba64552fd5897c88ef9d6a581 Mon Sep 17 00:00:00 2001 From: Alexey Lazarev Date: Thu, 16 Jun 2022 17:52:29 +0400 Subject: [PATCH 1/4] feat(helm): add security context for init container for ex istio using 1337 for init containers --- helm/oncall/templates/_helpers.tpl | 4 +++- helm/oncall/values.yaml | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/helm/oncall/templates/_helpers.tpl b/helm/oncall/templates/_helpers.tpl index bf137b40ee..18bcee4204 100644 --- a/helm/oncall/templates/_helpers.tpl +++ b/helm/oncall/templates/_helpers.tpl @@ -85,6 +85,8 @@ Create the name of the service account to use image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} command: ['sh', '-c', "until (python manage.py migrate --check); do echo Waiting for database migrations; sleep 2; done"] + securityContext: + {{ toYaml .Values.init.securityContext| nindent 4}} env: {{- include "snippet.oncall.env" . | nindent 12 }} {{- include "snippet.mysql.env" . | nindent 12 }} @@ -93,4 +95,4 @@ Create the name of the service account to use {{- if .Values.env }} {{- toYaml .Values.env | nindent 12 }} {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/helm/oncall/values.yaml b/helm/oncall/values.yaml index 6c78171826..4f67379cc5 100644 --- a/helm/oncall/values.yaml +++ b/helm/oncall/values.yaml @@ -160,3 +160,15 @@ securityContext: {} # readOnlyRootFilesystem: true # runAsNonRoot: true # runAsUser: 1000 + +init: + securityContext: {} + # allowPrivilegeEscalation: false + # capabilities: + # drop: + # - ALL + # privileged: false + # readOnlyRootFilesystem: true + # runAsGroup: 1337 + # runAsNonRoot: true + # runAsUser: 1337 From b14d105478a830e5554f7a877a9635241b4dd695 Mon Sep 17 00:00:00 2001 From: Alexey Lazarev Date: Thu, 16 Jun 2022 17:52:42 +0400 Subject: [PATCH 2/4] fix(helm): add enabled logic for ingress and issuers --- helm/oncall/templates/cert-issuer.yaml | 2 +- helm/oncall/templates/ingress-regular.yaml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/helm/oncall/templates/cert-issuer.yaml b/helm/oncall/templates/cert-issuer.yaml index 60c2b6906d..8b1716f344 100644 --- a/helm/oncall/templates/cert-issuer.yaml +++ b/helm/oncall/templates/cert-issuer.yaml @@ -1,4 +1,4 @@ -{{- if (index .Values "cert-manager") }} +{{- if (index .Values "cert-manager").enabled }} apiVersion: cert-manager.io/v1 kind: Issuer metadata: diff --git a/helm/oncall/templates/ingress-regular.yaml b/helm/oncall/templates/ingress-regular.yaml index 31c4e36717..dc2f82c765 100644 --- a/helm/oncall/templates/ingress-regular.yaml +++ b/helm/oncall/templates/ingress-regular.yaml @@ -38,6 +38,7 @@ spec: name: {{ include "oncall.engine.fullname" . }} port: number: 8080 + {{ if .Values.grafana.enabled }} - path: /grafana pathType: Prefix backend: @@ -45,4 +46,5 @@ spec: name: {{ include "oncall.grafana.fullname" . }} port: number: 80 + {{- end }} {{- end }} From c8964188e76be49d5a8761849a6761cc2fface65 Mon Sep 17 00:00:00 2001 From: Vadim Stepanov Date: Tue, 28 Jun 2022 09:11:19 +0100 Subject: [PATCH 3/4] Allow Telegram DMs without channel connection (#142) * allow posting DM messages to Telegram without connecting a channel * fix get_channel_for_alert_group, add tests * add docs on usage without channel connection --- .../chat-options/configure-telegram.md | 2 + engine/apps/alerts/models/alert_group.py | 8 --- engine/apps/alerts/tasks/notify_user.py | 19 +----- .../user_notification_policy_log_record.py | 3 +- .../telegram/alert_group_representative.py | 21 ------ .../telegram/models/connectors/channel.py | 3 + .../telegram/tests/test_channel_connector.py | 66 +++++++++++++++++++ 7 files changed, 74 insertions(+), 48 deletions(-) create mode 100644 engine/apps/telegram/tests/test_channel_connector.py diff --git a/docs/sources/chat-options/configure-telegram.md b/docs/sources/chat-options/configure-telegram.md index 30c220e951..e119aff4f1 100644 --- a/docs/sources/chat-options/configure-telegram.md +++ b/docs/sources/chat-options/configure-telegram.md @@ -20,6 +20,8 @@ You can use Telegram to deliver alert group notifications to a dedicated channel Each alert group notification is assigned a dedicated discussion. Users can perform notification actions (acknowledge, resolve, silence), create reports, and discuss alerts in the comments section of the discussions. +In case an integration route is not configured to use a Telegram channel, users will receive messages with alert group contents, logs and actions in their DMs. + ## Connect to Telegram Connect your organization's Telegram account to your Grafana OnCall instance by following the instructions provided in OnCall. You can use the following steps as a reference. diff --git a/engine/apps/alerts/models/alert_group.py b/engine/apps/alerts/models/alert_group.py index 72e93ebc65..16b2d19bcf 100644 --- a/engine/apps/alerts/models/alert_group.py +++ b/engine/apps/alerts/models/alert_group.py @@ -1557,14 +1557,6 @@ def notify_in_slack_enabled(self): else: return True - @property - def notify_in_telegram_enabled(self): - channel_filter = self.channel_filter_with_respect_to_escalation_snapshot - if channel_filter is not None: - return channel_filter.notify_in_telegram - else: - return True - @property def is_presented_in_slack(self): return self.slack_message and self.channel.organization.slack_team_identity diff --git a/engine/apps/alerts/tasks/notify_user.py b/engine/apps/alerts/tasks/notify_user.py index b3a998b4d3..ea462a2f97 100644 --- a/engine/apps/alerts/tasks/notify_user.py +++ b/engine/apps/alerts/tasks/notify_user.py @@ -162,10 +162,6 @@ def notify_user_task( user_to_be_notified_in_slack = ( notification_policy.notify_by == UserNotificationPolicy.NotificationChannel.SLACK ) - user_to_be_notified_in_telegram = ( - notification_policy.notify_by == UserNotificationPolicy.NotificationChannel.TELEGRAM - ) - if user_to_be_notified_in_slack and alert_group.notify_in_slack_enabled is False: log_record = UserNotificationPolicyLogRecord( author=user, @@ -178,18 +174,6 @@ def notify_user_task( notification_channel=notification_policy.notify_by, notification_error_code=UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_POSTING_TO_SLACK_IS_DISABLED, ) - elif user_to_be_notified_in_telegram and alert_group.notify_in_telegram_enabled is False: - log_record = UserNotificationPolicyLogRecord( - author=user, - type=UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_FAILED, - notification_policy=notification_policy, - alert_group=alert_group, - reason=reason, - slack_prevent_posting=prevent_posting_to_thread, - notification_step=notification_policy.step, - notification_channel=notification_policy.notify_by, - notification_error_code=UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_POSTING_TO_TELEGRAM_IS_DISABLED, - ) else: log_record = UserNotificationPolicyLogRecord( author=user, @@ -292,8 +276,7 @@ def perform_notification(log_record_pk): ) elif notification_channel == UserNotificationPolicy.NotificationChannel.TELEGRAM: - if alert_group.notify_in_telegram_enabled is True: - TelegramToUserConnector.notify_user(user, alert_group, notification_policy) + TelegramToUserConnector.notify_user(user, alert_group, notification_policy) # TODO: restore email notifications # elif notification_channel == UserNotificationPolicy.NotificationChannel.EMAIL: diff --git a/engine/apps/base/models/user_notification_policy_log_record.py b/engine/apps/base/models/user_notification_policy_log_record.py index 2cfc3b0a11..d8afed2db9 100644 --- a/engine/apps/base/models/user_notification_policy_log_record.py +++ b/engine/apps/base/models/user_notification_policy_log_record.py @@ -59,7 +59,7 @@ class UserNotificationPolicyLogRecord(models.Model): ERROR_NOTIFICATION_MAIL_DELIVERY_FAILED, ERROR_NOTIFICATION_TELEGRAM_BOT_IS_DELETED, ERROR_NOTIFICATION_POSTING_TO_SLACK_IS_DISABLED, - ERROR_NOTIFICATION_POSTING_TO_TELEGRAM_IS_DISABLED, + ERROR_NOTIFICATION_POSTING_TO_TELEGRAM_IS_DISABLED, # deprecated ERROR_NOTIFICATION_IN_SLACK, ERROR_NOTIFICATION_IN_SLACK_TOKEN_ERROR, ERROR_NOTIFICATION_IN_SLACK_USER_NOT_IN_SLACK, @@ -213,6 +213,7 @@ def render_log_line_action(self, for_slack=False, substitute_author_with_tag=Fal self.notification_error_code == UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_POSTING_TO_TELEGRAM_IS_DISABLED ): + # deprecated result += f"failed to notify {user_verbal} in Telegram, because the incident is not posted to Telegram (reason: Telegram is disabled for the route)" elif ( self.notification_error_code diff --git a/engine/apps/telegram/alert_group_representative.py b/engine/apps/telegram/alert_group_representative.py index 355e3a2fb3..156a0afdd7 100644 --- a/engine/apps/telegram/alert_group_representative.py +++ b/engine/apps/telegram/alert_group_representative.py @@ -66,11 +66,6 @@ def on_alert_group_update_log_report(cls, **kwargs): if not isinstance(alert_group, AlertGroup): alert_group = AlertGroup.all_objects.get(pk=alert_group) - # telegram notification is disabled for channel filter - if alert_group.notify_in_telegram_enabled is False: - logger.debug(f"Skipping alert group with id {alert_group.pk} since notify_in_telegram is disabled") - return - messages_to_edit = alert_group.telegram_messages.filter( message_type__in=( TelegramMessage.LOG_MESSAGE, @@ -90,13 +85,6 @@ def on_alert_group_action_triggered(cls, **kwargs): if not isinstance(log_record, AlertGroupLogRecord): log_record = AlertGroupLogRecord.objects.get(pk=log_record) - # telegram notification is disabled for channel filter - if log_record.alert_group.notify_in_telegram_enabled is False: - logger.debug( - f"Skipping alert group with id {log_record.alert_group.pk} since notify_in_telegram is disabled" - ) - return - instance = cls(log_record) if instance.is_applicable(): handler = instance.get_handler() @@ -104,16 +92,7 @@ def on_alert_group_action_triggered(cls, **kwargs): @staticmethod def on_create_alert(**kwargs): - Alert = apps.get_model("alerts", "Alert") - alert_pk = kwargs["alert"] - alert = Alert.objects.get(pk=alert_pk) - - # telegram notification is disabled for channel filter - if alert.group.notify_in_telegram_enabled is False: - logger.debug(f"Skipping alert with id {alert.pk} since notify_in_telegram is disabled") - return - on_create_alert_telegram_representative_async.apply_async((alert_pk,)) def get_handler(self): diff --git a/engine/apps/telegram/models/connectors/channel.py b/engine/apps/telegram/models/connectors/channel.py index a24508a67b..c21e76c9fe 100644 --- a/engine/apps/telegram/models/connectors/channel.py +++ b/engine/apps/telegram/models/connectors/channel.py @@ -82,6 +82,9 @@ def get_channel_for_alert_group(cls, alert_group: AlertGroup) -> Optional["Teleg if alert_group.channel_filter is None: return default_channel + if not alert_group.channel_filter.notify_in_telegram: + return None + return alert_group.channel_filter.telegram_channel or default_channel def make_channel_default(self, author): diff --git a/engine/apps/telegram/tests/test_channel_connector.py b/engine/apps/telegram/tests/test_channel_connector.py new file mode 100644 index 0000000000..1969557032 --- /dev/null +++ b/engine/apps/telegram/tests/test_channel_connector.py @@ -0,0 +1,66 @@ +import pytest + +from apps.telegram.models import TelegramMessage, TelegramToOrganizationConnector + + +@pytest.mark.django_db +def test_get_channel_for_alert_group( + make_organization, make_alert_receive_channel, make_channel_filter, make_alert_group, make_telegram_channel +): + organization = make_organization() + + make_telegram_channel(organization, is_default_channel=True) + telegram_channel = make_telegram_channel(organization) + + alert_receive_channel = make_alert_receive_channel(organization) + channel_filter = make_channel_filter( + alert_receive_channel, notify_in_telegram=True, telegram_channel=telegram_channel + ) + + alert_group = make_alert_group(alert_receive_channel, channel_filter=channel_filter) + + channel = TelegramToOrganizationConnector.get_channel_for_alert_group(alert_group) + assert channel is telegram_channel + + +@pytest.mark.django_db +def test_get_channel_telegram_disabled_for_route( + make_organization, make_alert_receive_channel, make_channel_filter, make_alert_group, make_telegram_channel +): + organization = make_organization() + + telegram_channel = make_telegram_channel(organization) + + alert_receive_channel = make_alert_receive_channel(organization) + channel_filter = make_channel_filter( + alert_receive_channel, notify_in_telegram=False, telegram_channel=telegram_channel + ) + + alert_group = make_alert_group(alert_receive_channel, channel_filter=channel_filter) + + channel = TelegramToOrganizationConnector.get_channel_for_alert_group(alert_group) + assert channel is None + + +@pytest.mark.django_db +def test_get_channel_for_alert_group_dm_messages_exist( + make_organization, + make_alert_receive_channel, + make_channel_filter, + make_alert_group, + make_telegram_channel, + make_telegram_message, +): + organization = make_organization() + + telegram_channel = make_telegram_channel(organization) + alert_receive_channel = make_alert_receive_channel(organization) + channel_filter = make_channel_filter( + alert_receive_channel, notify_in_telegram=True, telegram_channel=telegram_channel + ) + + alert_group = make_alert_group(alert_receive_channel, channel_filter=channel_filter) + make_telegram_message(alert_group=alert_group, message_type=TelegramMessage.PERSONAL_MESSAGE) + + channel = TelegramToOrganizationConnector.get_channel_for_alert_group(alert_group) + assert channel is None From 57117614e603c83c762af2ab8895e39f9d889932 Mon Sep 17 00:00:00 2001 From: Matias Bordese Date: Tue, 28 Jun 2022 16:02:37 -0300 Subject: [PATCH 4/4] Update changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b189025b15..e55bb4d175 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Change Log +## 1.0.4 (2022-06-28) +- Allow Telegram DMs without channel connection. + ## 1.0.3 (2022-06-27) - Fix users public api endpoint. Now it returns users with all roles. - Fix redundant notifications about gaps in schedules. @@ -16,4 +19,4 @@ ## 0.0.71 (2022-06-06) -- Initial Commit Release \ No newline at end of file +- Initial Commit Release