From 2b0abf018c4ee223ca50f043e706505c4fa87a85 Mon Sep 17 00:00:00 2001 From: Vadim Stepanov Date: Fri, 20 Jan 2023 13:29:57 +0000 Subject: [PATCH] Hide direct paging integrations (#1162) # What this PR does Hide direct paging integrations from the web UI. Related to https://github.com/grafana/oncall/issues/823 ## Checklist - [x] Tests updated - [ ] Documentation added (N/A) - [ ] `CHANGELOG.md` updated (N/A) --- .../api/serializers/alert_receive_channel.py | 3 ++- engine/apps/api/tests/test_alert_group.py | 24 ++++++++++++++++++- .../api/tests/test_alert_receive_channel.py | 16 +++++++++++++ .../apps/api/views/alert_receive_channel.py | 4 ++++ .../public_api/tests/test_integrations.py | 20 ++++++++++++++++ engine/apps/public_api/views/integrations.py | 4 ++++ .../src/pages/incident/Incident.tsx | 5 +++- 7 files changed, 73 insertions(+), 3 deletions(-) diff --git a/engine/apps/api/serializers/alert_receive_channel.py b/engine/apps/api/serializers/alert_receive_channel.py index c8df5ad3ce..0df3d11db7 100644 --- a/engine/apps/api/serializers/alert_receive_channel.py +++ b/engine/apps/api/serializers/alert_receive_channel.py @@ -169,7 +169,8 @@ class Meta: fields = ["id", "integration", "verbal_name", "deleted"] def get_deleted(self, obj): - return obj.deleted_at is not None + # Treat direct paging integrations as deleted, so integration settings are disabled on the frontend + return obj.deleted_at is not None or obj.integration == AlertReceiveChannel.INTEGRATION_DIRECT_PAGING class FilterAlertReceiveChannelSerializer(serializers.ModelSerializer): diff --git a/engine/apps/api/tests/test_alert_group.py b/engine/apps/api/tests/test_alert_group.py index 323d55a0c2..447cc647e2 100644 --- a/engine/apps/api/tests/test_alert_group.py +++ b/engine/apps/api/tests/test_alert_group.py @@ -8,7 +8,7 @@ from rest_framework.response import Response from rest_framework.test import APIClient -from apps.alerts.models import AlertGroup, AlertGroupLogRecord +from apps.alerts.models import AlertGroup, AlertGroupLogRecord, AlertReceiveChannel from apps.api.permissions import LegacyAccessControlRole alert_raw_request_data = { @@ -1585,3 +1585,25 @@ def test_alert_group_paged_users( url = reverse("api-internal:alertgroup-detail", kwargs={"pk": new_alert_group.public_primary_key}) response = client.get(url, format="json", **make_user_auth_headers(user, token)) assert response.json()["paged_users"] == [user2.short()] + + +@pytest.mark.django_db +def test_direct_paging_integration_treated_as_deleted( + make_organization_and_user_with_plugin_token, + make_alert_receive_channel, + alert_group_internal_api_setup, + make_channel_filter, + make_alert_group, + make_user_auth_headers, +): + organization, user, token = make_organization_and_user_with_plugin_token() + alert_receive_channel = make_alert_receive_channel( + organization, integration=AlertReceiveChannel.INTEGRATION_DIRECT_PAGING + ) + alert_group = make_alert_group(alert_receive_channel) + + client = APIClient() + url = reverse("api-internal:alertgroup-detail", kwargs={"pk": alert_group.public_primary_key}) + + response = client.get(url, format="json", **make_user_auth_headers(user, token)) + assert response.json()["alert_receive_channel"]["deleted"] is True diff --git a/engine/apps/api/tests/test_alert_receive_channel.py b/engine/apps/api/tests/test_alert_receive_channel.py index 2ce0734120..a886c4257a 100644 --- a/engine/apps/api/tests/test_alert_receive_channel.py +++ b/engine/apps/api/tests/test_alert_receive_channel.py @@ -668,3 +668,19 @@ def test_alert_receive_channel_counters_per_integration_permissions( response = client.get(url, format="json", **make_user_auth_headers(user, token)) assert response.status_code == expected_status + + +@pytest.mark.django_db +def test_get_alert_receive_channels_direct_paging_hidden( + make_organization_and_user_with_plugin_token, make_alert_receive_channel, make_user_auth_headers +): + organization, user, token = make_organization_and_user_with_plugin_token() + make_alert_receive_channel(user.organization, integration=AlertReceiveChannel.INTEGRATION_DIRECT_PAGING) + + client = APIClient() + url = reverse("api-internal:alert_receive_channel-list") + response = client.get(url, format="json", **make_user_auth_headers(user, token)) + + # Check no direct paging integrations in the response + assert response.status_code == status.HTTP_200_OK + assert response.json() == [] diff --git a/engine/apps/api/views/alert_receive_channel.py b/engine/apps/api/views/alert_receive_channel.py index e62599fc42..687b68df17 100644 --- a/engine/apps/api/views/alert_receive_channel.py +++ b/engine/apps/api/views/alert_receive_channel.py @@ -136,6 +136,10 @@ def get_queryset(self, eager=True): ) if eager: queryset = self.serializer_class.setup_eager_loading(queryset) + + # Hide direct paging integrations + queryset = queryset.exclude(integration=AlertReceiveChannel.INTEGRATION_DIRECT_PAGING) + return queryset @action(detail=True, methods=["post"], throttle_classes=[DemoAlertThrottler]) diff --git a/engine/apps/public_api/tests/test_integrations.py b/engine/apps/public_api/tests/test_integrations.py index 22756022ef..ac5968e7b9 100644 --- a/engine/apps/public_api/tests/test_integrations.py +++ b/engine/apps/public_api/tests/test_integrations.py @@ -3,6 +3,7 @@ from rest_framework import status from rest_framework.test import APIClient +from apps.alerts.models import AlertReceiveChannel from apps.base.tests.messaging_backend import TestOnlyBackend TEST_MESSAGING_BACKEND_FIELD = TestOnlyBackend.backend_id.lower() @@ -570,3 +571,22 @@ def test_set_default_template( response = client.put(url, data=data_for_update, format="json", HTTP_AUTHORIZATION=f"{token}") assert response.status_code == status.HTTP_200_OK assert response.data == expected_response + + +@pytest.mark.django_db +def test_get_list_integrations_direct_paging_hidden( + make_organization_and_user_with_token, + make_alert_receive_channel, + make_channel_filter, + make_integration_heartbeat, +): + organization, user, token = make_organization_and_user_with_token() + make_alert_receive_channel(organization, integration=AlertReceiveChannel.INTEGRATION_DIRECT_PAGING) + + client = APIClient() + url = reverse("api-public:integrations-list") + response = client.get(url, format="json", HTTP_AUTHORIZATION=f"{token}") + + # Check no direct paging integrations in the response + assert response.status_code == status.HTTP_200_OK + assert response.json()["results"] == [] diff --git a/engine/apps/public_api/views/integrations.py b/engine/apps/public_api/views/integrations.py index 36ef6ea33d..eac090ebdc 100644 --- a/engine/apps/public_api/views/integrations.py +++ b/engine/apps/public_api/views/integrations.py @@ -47,6 +47,10 @@ def get_queryset(self): queryset = self.filter_queryset(queryset) queryset = self.serializer_class.setup_eager_loading(queryset) queryset = queryset.annotate(alert_groups_count_annotated=Count("alert_groups", distinct=True)) + + # Hide direct paging integrations + queryset = queryset.exclude(integration=AlertReceiveChannel.INTEGRATION_DIRECT_PAGING) + return queryset def get_object(self): diff --git a/grafana-plugin/src/pages/incident/Incident.tsx b/grafana-plugin/src/pages/incident/Incident.tsx index 8ba7512438..228c2c007f 100644 --- a/grafana-plugin/src/pages/incident/Incident.tsx +++ b/grafana-plugin/src/pages/incident/Incident.tsx @@ -297,7 +297,10 @@ class IncidentPage extends React.Component - +