oncall-engine/engine/apps/api/serializers/paging.py

86 lines
3.4 KiB
Python
Raw Normal View History

from django.core.exceptions import ObjectDoesNotExist
from rest_framework import serializers
from apps.alerts.models import AlertGroup
from common.api_helpers.custom_fields import TeamPrimaryKeyRelatedField
from common.api_helpers.utils import CurrentTeamDefault
class UserReferenceSerializer(serializers.Serializer):
id = serializers.CharField()
important = serializers.BooleanField()
instance = serializers.HiddenField(default=None) # set in UserReferenceSerializer.validate
def validate(self, attrs):
organization = self.context["organization"]
try:
attrs["instance"] = organization.users.get(public_primary_key=attrs["id"])
except ObjectDoesNotExist:
raise serializers.ValidationError("User {} does not exist".format(attrs["id"]))
return attrs
class ScheduleReferenceSerializer(serializers.Serializer):
id = serializers.CharField()
important = serializers.BooleanField()
instance = serializers.HiddenField(default=None) # set in ScheduleReferenceSerializer.validate
def validate(self, attrs):
organization = self.context["organization"]
try:
attrs["instance"] = organization.oncall_schedules.get(public_primary_key=attrs["id"])
except ObjectDoesNotExist:
raise serializers.ValidationError("Schedule {} does not exist".format(attrs["id"]))
return attrs
class DirectPagingSerializer(serializers.Serializer):
users = UserReferenceSerializer(many=True, required=False, default=list)
schedules = ScheduleReferenceSerializer(many=True, required=False, default=list)
escalation_chain_id = serializers.CharField(required=False, default=None)
escalation_chain = serializers.HiddenField(default=None) # set in DirectPagingSerializer.validate
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)
Direct paging improvements (#2537) # What this PR does - Deprecates `/oncall` Slack command in favour of `/esalate` (direct paging) + fixes a regression bug in both commands - Unifies direct paging UX across Slack & Web UI (or at least makes an attempt to make things more similar). Kudos to @iskhakov for all the great work on this recently! - A bunch of minor changes that hopefully make direct paging more usable - TODO: documentation updates will be added in a separate PR ## Screenshots ### No issues scenario Slack: <img width="522" alt="Screenshot 2023-07-14 at 23 53 11" src="https://github.com/grafana/oncall/assets/20116910/ec15a18f-d817-4177-b1f2-6b89d79bb361"> Web UI: <img width="1172" alt="Screenshot 2023-07-14 at 23 52 25" src="https://github.com/grafana/oncall/assets/20116910/813f967c-2fdd-4868-9287-487dbfa7cea6"> ### Not configured scenario Slack: <img width="519" alt="Screenshot 2023-07-14 at 23 45 22" src="https://github.com/grafana/oncall/assets/20116910/932fa05c-81ea-42ca-be80-41b05f767d3e"> Web UI: <img width="1172" alt="Screenshot 2023-07-14 at 23 47 31" src="https://github.com/grafana/oncall/assets/20116910/6bcb07e4-2e50-4120-9fac-be8b0277e181"> ### `/oncall` deprecation warning <img width="521" alt="Screenshot 2023-07-17 at 10 31 56" src="https://github.com/grafana/oncall/assets/20116910/4ff28337-1693-4af0-81d9-9eda90099c1b"> ## Which issue(s) this PR fixes https://github.com/grafana/oncall/issues/2442 ## 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)
2023-07-17 14:21:56 +01:00
message = serializers.CharField(required=False, default=None, allow_null=True)
team = TeamPrimaryKeyRelatedField(allow_null=True, default=CurrentTeamDefault())
def validate(self, attrs):
organization = self.context["organization"]
escalation_chain_id = attrs["escalation_chain_id"]
alert_group_id = attrs["alert_group_id"]
title = attrs["title"]
message = attrs["message"]
if alert_group_id and (title or message):
raise serializers.ValidationError("alert_group_id and (title, message) are mutually exclusive")
if alert_group_id and escalation_chain_id:
raise serializers.ValidationError("escalation_chain_id is not supported for existing alert groups")
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))
if escalation_chain_id:
try:
attrs["escalation_chain"] = organization.escalation_chains.get(public_primary_key=escalation_chain_id)
except ObjectDoesNotExist:
raise serializers.ValidationError("Escalation chain {} does not exist".format(escalation_chain_id))
return attrs