# What this PR does - Add a new column, `grafana_incident_id`, to the `AlertGroup` model. For now this is really just needed to determine if the Alert Group was created, via a Direct Page, that originated from Grafana Incident. - I understand that these IDs may be cluster specific. For now we will not need to make OnCall backend -> Incident API calls. Should we need to start doing this we will likely need to start syncing the Incident plugin's provisioned API url into the `organization` in OnCall, such that we make the API call to the right Incident backend. - Add two new optional request body parameters to `POST /direct_paging`, `source_url` and `grafana_incident_id` - `source_url` - will easily allow Grafana Incident to specify the URL to the Incident and have this populate the "Source" button - `grafana_incident_id` - Grafana Incident can specify this such that we have a link back to Incident (+ we know that the Alert Group was generated from Incident) - Hide the "Declare Incident" button in the UI if the Alert Group was generated from Grafana Incident ## 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)
70 lines
2.6 KiB
Python
70 lines
2.6 KiB
Python
import typing
|
|
|
|
from django.core.exceptions import ObjectDoesNotExist
|
|
from rest_framework import serializers
|
|
|
|
from apps.alerts.models import AlertGroup
|
|
from apps.user_management.models import Organization
|
|
from common.api_helpers.custom_fields import TeamPrimaryKeyRelatedField
|
|
from common.api_helpers.utils import CurrentTeamDefault
|
|
|
|
|
|
class SerializerContext(typing.TypedDict):
|
|
organization: Organization
|
|
|
|
|
|
class UserReferenceSerializer(serializers.Serializer):
|
|
context: SerializerContext
|
|
|
|
id = serializers.CharField()
|
|
important = serializers.BooleanField()
|
|
instance = serializers.HiddenField(default=None) # set in UserReferenceSerializer.validate
|
|
|
|
def validate(self, attrs):
|
|
id = attrs["id"]
|
|
organization = self.context["organization"]
|
|
|
|
try:
|
|
attrs["instance"] = organization.users.get(public_primary_key=id)
|
|
except ObjectDoesNotExist:
|
|
raise serializers.ValidationError(f"User {id} does not exist")
|
|
|
|
return attrs
|
|
|
|
|
|
class DirectPagingSerializer(serializers.Serializer):
|
|
context: SerializerContext
|
|
|
|
users = UserReferenceSerializer(many=True, required=False, default=list)
|
|
team = TeamPrimaryKeyRelatedField(allow_null=True, default=CurrentTeamDefault())
|
|
|
|
alert_group_id = serializers.CharField(required=False, default=None)
|
|
alert_group = serializers.HiddenField(default=None) # set in DirectPagingSerializer.validate
|
|
|
|
title = serializers.CharField(required=False, default=None)
|
|
message = serializers.CharField(required=False, default=None, allow_null=True)
|
|
source_url = serializers.URLField(required=False, default=None, allow_null=True)
|
|
grafana_incident_id = serializers.CharField(required=False, default=None, allow_null=True)
|
|
|
|
def validate(self, attrs):
|
|
organization = self.context["organization"]
|
|
alert_group_id = attrs["alert_group_id"]
|
|
title = attrs["title"]
|
|
message = attrs["message"]
|
|
source_url = attrs["source_url"]
|
|
grafana_incident_id = attrs["grafana_incident_id"]
|
|
|
|
if alert_group_id and (title or message or source_url or grafana_incident_id):
|
|
raise serializers.ValidationError(
|
|
"alert_group_id and (title, message, source_url, grafana_incident_id) are mutually exclusive"
|
|
)
|
|
|
|
if alert_group_id:
|
|
try:
|
|
attrs["alert_group"] = AlertGroup.objects.get(
|
|
public_primary_key=alert_group_id, channel__organization=organization
|
|
)
|
|
except ObjectDoesNotExist:
|
|
raise serializers.ValidationError("Alert group {} does not exist".format(alert_group_id))
|
|
|
|
return attrs
|