Add alert groups external URLs information to details API (#4226)
Alert groups connected to an external source will return external URLs
information, eg.
```
{
"external_urls": [
{
"integration": "C2IFSTV93NQUW",
"integration_type": "servicenow",
"external_id": "4c686e1e83d1021075feb3a6feaad3a8",
"url": "https://some.service-now.com/incident.do?sys_id=4c686e1e83d1021075feb3a6feaad3a8"
}
]
}
```
Related to https://github.com/grafana/oncall-private/issues/2615
This commit is contained in:
parent
14f9677082
commit
0989c40abb
3 changed files with 80 additions and 2 deletions
|
|
@ -22,6 +22,13 @@ logger = logging.getLogger(__name__)
|
|||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
class ExternalURL(typing.TypedDict):
|
||||
integration: str
|
||||
integration_type: str
|
||||
external_id: str
|
||||
url: str
|
||||
|
||||
|
||||
class RenderForWeb(typing.TypedDict):
|
||||
title: str
|
||||
message: str
|
||||
|
|
@ -213,6 +220,7 @@ class AlertGroupSerializer(AlertGroupListSerializer):
|
|||
alerts = serializers.SerializerMethodField("get_limited_alerts")
|
||||
last_alert_at = serializers.SerializerMethodField()
|
||||
paged_users = serializers.SerializerMethodField()
|
||||
external_urls = serializers.SerializerMethodField()
|
||||
|
||||
class Meta(AlertGroupListSerializer.Meta):
|
||||
fields = AlertGroupListSerializer.Meta.fields + [
|
||||
|
|
@ -221,6 +229,7 @@ class AlertGroupSerializer(AlertGroupListSerializer):
|
|||
"slack_permalink", # TODO: make plugin frontend use "permalinks" field to get Slack link
|
||||
"last_alert_at",
|
||||
"paged_users",
|
||||
"external_urls",
|
||||
]
|
||||
|
||||
def get_last_alert_at(self, obj: "AlertGroup") -> datetime.datetime:
|
||||
|
|
@ -242,3 +251,21 @@ class AlertGroupSerializer(AlertGroupListSerializer):
|
|||
|
||||
def get_paged_users(self, obj: "AlertGroup") -> typing.List[PagedUser]:
|
||||
return obj.get_paged_users()
|
||||
|
||||
def get_external_urls(self, obj: "AlertGroup") -> typing.List[ExternalURL]:
|
||||
external_urls = []
|
||||
external_ids = obj.external_ids.all()
|
||||
for external_id in external_ids:
|
||||
source_integration = external_id.source_alert_receive_channel
|
||||
get_url = getattr(source_integration.config, "get_url", None)
|
||||
if get_url:
|
||||
url = source_integration.config.get_url(source_integration, external_id.value)
|
||||
external_urls.append(
|
||||
{
|
||||
"integration": source_integration.public_primary_key,
|
||||
"integration_type": source_integration.integration,
|
||||
"external_id": external_id.value,
|
||||
"url": url,
|
||||
}
|
||||
)
|
||||
return external_urls
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import datetime
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
from django.core.cache import cache
|
||||
|
|
@ -10,7 +10,13 @@ from rest_framework.response import Response
|
|||
from rest_framework.test import APIClient
|
||||
|
||||
from apps.alerts.constants import ActionSource
|
||||
from apps.alerts.models import AlertGroup, AlertGroupLogRecord, ResolutionNote
|
||||
from apps.alerts.models import (
|
||||
AlertGroup,
|
||||
AlertGroupExternalID,
|
||||
AlertGroupLogRecord,
|
||||
AlertReceiveChannel,
|
||||
ResolutionNote,
|
||||
)
|
||||
from apps.alerts.paging import direct_paging
|
||||
from apps.alerts.tasks import wipe
|
||||
from apps.api.errors import AlertGroupAPIError
|
||||
|
|
@ -2243,3 +2249,42 @@ def test_alert_group_list_labels(
|
|||
assert response.json()["results"][-1]["labels"] == [
|
||||
{"key": {"id": "a", "name": "a"}, "value": {"id": "b", "name": "b"}}
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_alert_group_external_urls(
|
||||
make_organization_and_user_with_plugin_token,
|
||||
make_user_auth_headers,
|
||||
make_alert_receive_channel,
|
||||
make_alert_receive_channel_connection,
|
||||
make_alert_group,
|
||||
):
|
||||
client = APIClient()
|
||||
|
||||
integration_config = AlertReceiveChannel._config[0]
|
||||
integration_config.get_url = Mock(return_value="https://some-url")
|
||||
|
||||
organization, user, token = make_organization_and_user_with_plugin_token()
|
||||
source_alert_receive_channel = make_alert_receive_channel(organization, integration=integration_config.slug)
|
||||
alert_receive_channel = make_alert_receive_channel(organization)
|
||||
make_alert_receive_channel_connection(source_alert_receive_channel, alert_receive_channel)
|
||||
|
||||
alert_group = make_alert_group(alert_receive_channel)
|
||||
|
||||
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()["external_urls"] == []
|
||||
|
||||
# create external IDs
|
||||
external_id = AlertGroupExternalID.objects.create(
|
||||
source_alert_receive_channel=source_alert_receive_channel, alert_group=alert_group, value="test123"
|
||||
)
|
||||
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))
|
||||
expected = {
|
||||
"integration": source_alert_receive_channel.public_primary_key,
|
||||
"integration_type": source_alert_receive_channel.integration,
|
||||
"external_id": external_id.value,
|
||||
"url": "https://some-url",
|
||||
}
|
||||
assert response.json()["external_urls"] == [expected]
|
||||
|
|
|
|||
|
|
@ -1411,6 +1411,12 @@ export interface components {
|
|||
avatar_full: string;
|
||||
important: boolean;
|
||||
}[];
|
||||
readonly external_urls: {
|
||||
integration: string;
|
||||
integration_type: string;
|
||||
external_id: string;
|
||||
url: string;
|
||||
}[];
|
||||
};
|
||||
AlertGroupAttach: {
|
||||
root_alert_group_pk: string;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue