2022-06-03 08:09:47 -06:00
|
|
|
from datetime import timedelta
|
|
|
|
|
|
|
|
|
|
from rest_framework import serializers
|
|
|
|
|
|
2024-03-28 11:37:22 -04:00
|
|
|
from apps.alerts.models import EscalationChain, EscalationPolicy
|
Reworked declare incident escalation step (#5130)
Reworked https://github.com/grafana/oncall/pull/5047. Main update is the
switch from FK to a [M2M
relation](https://docs.google.com/document/d/1HeulqxoFShSHtInQrZNJLL5MDlHPNT50rVGaK3zZWvw/edit?disco=AAABVLjV4W8)
(which doesn't really change the original/intended behavior, besides not
needing to alter the alert group table, and it is a bit more flexible;
the extra table shouldn't introduce issues because this is used only for
tracking purposes and the information needed in the log record is
already there).
Avoid a db migration involving alert group table:
```
--
-- Create model RelatedIncident
--
CREATE TABLE `alerts_relatedincident` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `incident_id` varchar(50) NOT NULL, `created_at` datetime(6) NOT NULL, `is_active` bool NOT NULL, `channel_filter_id` bigint NULL, `organization_id` bigint NOT NULL);
CREATE TABLE `alerts_relatedincident_attached_alert_groups` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `relatedincident_id` bigint NOT NULL, `alertgroup_id` bigint NOT NULL);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincident_organization_id_incident_id_d7fc9a4f_uniq` UNIQUE (`organization_id`, `incident_id`);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincide_channel_filter_id_9556c836_fk_alerts_ch` FOREIGN KEY (`channel_filter_id`) REFERENCES `alerts_channelfilter` (`id`);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincide_organization_id_74ed6bed_fk_user_mana` FOREIGN KEY (`organization_id`) REFERENCES `user_management_organization` (`id`);
CREATE INDEX `alerts_relatedincident_incident_id_8356a799` ON `alerts_relatedincident` (`incident_id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincident_a_relatedincident_id_alert_3d683baa_uniq` UNIQUE (`relatedincident_id`, `alertgroup_id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincide_relatedincident_id_3e5e7a23_fk_alerts_re` FOREIGN KEY (`relatedincident_id`) REFERENCES `alerts_relatedincident` (`id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincide_alertgroup_id_0125deca_fk_alerts_al` FOREIGN KEY (`alertgroup_id`) REFERENCES `alerts_alertgroup` (`id`);
```
2024-10-07 16:26:10 -03:00
|
|
|
from apps.alerts.utils import is_declare_incident_step_enabled
|
2022-06-03 08:09:47 -06:00
|
|
|
from apps.schedules.models import OnCallSchedule
|
|
|
|
|
from apps.slack.models import SlackUserGroup
|
2024-02-20 10:02:23 -03:00
|
|
|
from apps.user_management.models import Team, User
|
2023-04-05 09:03:55 -03:00
|
|
|
from apps.webhooks.models import Webhook
|
2022-06-03 08:09:47 -06:00
|
|
|
from common.api_helpers.custom_fields import (
|
2024-06-03 14:06:47 +01:00
|
|
|
DurationSecondsField,
|
2022-06-03 08:09:47 -06:00
|
|
|
OrganizationFilteredPrimaryKeyRelatedField,
|
|
|
|
|
UsersFilteredByOrganizationField,
|
|
|
|
|
)
|
|
|
|
|
from common.api_helpers.mixins import EagerLoadingMixin
|
|
|
|
|
|
|
|
|
|
WAIT_DELAY = "wait_delay"
|
|
|
|
|
NOTIFY_SCHEDULE = "notify_schedule"
|
|
|
|
|
NOTIFY_TO_USERS_QUEUE = "notify_to_users_queue"
|
|
|
|
|
NOTIFY_GROUP = "notify_to_group"
|
2024-02-20 10:02:23 -03:00
|
|
|
NOTIFY_TEAM_MEMBERS = "notify_to_team_members"
|
2022-06-03 08:09:47 -06:00
|
|
|
FROM_TIME = "from_time"
|
|
|
|
|
TO_TIME = "to_time"
|
|
|
|
|
NUM_ALERTS_IN_WINDOW = "num_alerts_in_window"
|
|
|
|
|
NUM_MINUTES_IN_WINDOW = "num_minutes_in_window"
|
2023-04-05 09:03:55 -03:00
|
|
|
CUSTOM_WEBHOOK_TRIGGER = "custom_webhook"
|
Reworked declare incident escalation step (#5130)
Reworked https://github.com/grafana/oncall/pull/5047. Main update is the
switch from FK to a [M2M
relation](https://docs.google.com/document/d/1HeulqxoFShSHtInQrZNJLL5MDlHPNT50rVGaK3zZWvw/edit?disco=AAABVLjV4W8)
(which doesn't really change the original/intended behavior, besides not
needing to alter the alert group table, and it is a bit more flexible;
the extra table shouldn't introduce issues because this is used only for
tracking purposes and the information needed in the log record is
already there).
Avoid a db migration involving alert group table:
```
--
-- Create model RelatedIncident
--
CREATE TABLE `alerts_relatedincident` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `incident_id` varchar(50) NOT NULL, `created_at` datetime(6) NOT NULL, `is_active` bool NOT NULL, `channel_filter_id` bigint NULL, `organization_id` bigint NOT NULL);
CREATE TABLE `alerts_relatedincident_attached_alert_groups` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `relatedincident_id` bigint NOT NULL, `alertgroup_id` bigint NOT NULL);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincident_organization_id_incident_id_d7fc9a4f_uniq` UNIQUE (`organization_id`, `incident_id`);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincide_channel_filter_id_9556c836_fk_alerts_ch` FOREIGN KEY (`channel_filter_id`) REFERENCES `alerts_channelfilter` (`id`);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincide_organization_id_74ed6bed_fk_user_mana` FOREIGN KEY (`organization_id`) REFERENCES `user_management_organization` (`id`);
CREATE INDEX `alerts_relatedincident_incident_id_8356a799` ON `alerts_relatedincident` (`incident_id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincident_a_relatedincident_id_alert_3d683baa_uniq` UNIQUE (`relatedincident_id`, `alertgroup_id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincide_relatedincident_id_3e5e7a23_fk_alerts_re` FOREIGN KEY (`relatedincident_id`) REFERENCES `alerts_relatedincident` (`id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincide_alertgroup_id_0125deca_fk_alerts_al` FOREIGN KEY (`alertgroup_id`) REFERENCES `alerts_alertgroup` (`id`);
```
2024-10-07 16:26:10 -03:00
|
|
|
SEVERITY = "severity"
|
2022-06-03 08:09:47 -06:00
|
|
|
|
|
|
|
|
STEP_TYPE_TO_RELATED_FIELD_MAP = {
|
|
|
|
|
EscalationPolicy.STEP_WAIT: [WAIT_DELAY],
|
|
|
|
|
EscalationPolicy.STEP_NOTIFY_SCHEDULE: [NOTIFY_SCHEDULE],
|
|
|
|
|
EscalationPolicy.STEP_NOTIFY_USERS_QUEUE: [NOTIFY_TO_USERS_QUEUE],
|
|
|
|
|
EscalationPolicy.STEP_NOTIFY_MULTIPLE_USERS: [NOTIFY_TO_USERS_QUEUE],
|
|
|
|
|
EscalationPolicy.STEP_NOTIFY_GROUP: [NOTIFY_GROUP],
|
2024-02-20 10:02:23 -03:00
|
|
|
EscalationPolicy.STEP_NOTIFY_TEAM_MEMBERS: [NOTIFY_TEAM_MEMBERS],
|
2022-06-03 08:09:47 -06:00
|
|
|
EscalationPolicy.STEP_NOTIFY_IF_TIME: [FROM_TIME, TO_TIME],
|
|
|
|
|
EscalationPolicy.STEP_NOTIFY_IF_NUM_ALERTS_IN_TIME_WINDOW: [NUM_ALERTS_IN_WINDOW, NUM_MINUTES_IN_WINDOW],
|
2023-04-05 09:03:55 -03:00
|
|
|
EscalationPolicy.STEP_TRIGGER_CUSTOM_WEBHOOK: [CUSTOM_WEBHOOK_TRIGGER],
|
Reworked declare incident escalation step (#5130)
Reworked https://github.com/grafana/oncall/pull/5047. Main update is the
switch from FK to a [M2M
relation](https://docs.google.com/document/d/1HeulqxoFShSHtInQrZNJLL5MDlHPNT50rVGaK3zZWvw/edit?disco=AAABVLjV4W8)
(which doesn't really change the original/intended behavior, besides not
needing to alter the alert group table, and it is a bit more flexible;
the extra table shouldn't introduce issues because this is used only for
tracking purposes and the information needed in the log record is
already there).
Avoid a db migration involving alert group table:
```
--
-- Create model RelatedIncident
--
CREATE TABLE `alerts_relatedincident` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `incident_id` varchar(50) NOT NULL, `created_at` datetime(6) NOT NULL, `is_active` bool NOT NULL, `channel_filter_id` bigint NULL, `organization_id` bigint NOT NULL);
CREATE TABLE `alerts_relatedincident_attached_alert_groups` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `relatedincident_id` bigint NOT NULL, `alertgroup_id` bigint NOT NULL);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincident_organization_id_incident_id_d7fc9a4f_uniq` UNIQUE (`organization_id`, `incident_id`);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincide_channel_filter_id_9556c836_fk_alerts_ch` FOREIGN KEY (`channel_filter_id`) REFERENCES `alerts_channelfilter` (`id`);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincide_organization_id_74ed6bed_fk_user_mana` FOREIGN KEY (`organization_id`) REFERENCES `user_management_organization` (`id`);
CREATE INDEX `alerts_relatedincident_incident_id_8356a799` ON `alerts_relatedincident` (`incident_id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincident_a_relatedincident_id_alert_3d683baa_uniq` UNIQUE (`relatedincident_id`, `alertgroup_id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincide_relatedincident_id_3e5e7a23_fk_alerts_re` FOREIGN KEY (`relatedincident_id`) REFERENCES `alerts_relatedincident` (`id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincide_alertgroup_id_0125deca_fk_alerts_al` FOREIGN KEY (`alertgroup_id`) REFERENCES `alerts_alertgroup` (`id`);
```
2024-10-07 16:26:10 -03:00
|
|
|
EscalationPolicy.STEP_DECLARE_INCIDENT: [SEVERITY],
|
2022-06-03 08:09:47 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class EscalationPolicySerializer(EagerLoadingMixin, serializers.ModelSerializer):
|
|
|
|
|
id = serializers.CharField(read_only=True, source="public_primary_key")
|
|
|
|
|
escalation_chain = OrganizationFilteredPrimaryKeyRelatedField(queryset=EscalationChain.objects)
|
|
|
|
|
important = serializers.BooleanField(required=False)
|
|
|
|
|
|
|
|
|
|
notify_to_users_queue = UsersFilteredByOrganizationField(
|
|
|
|
|
queryset=User.objects,
|
|
|
|
|
required=False,
|
|
|
|
|
)
|
2024-06-03 14:06:47 +01:00
|
|
|
wait_delay = DurationSecondsField(
|
2022-06-03 08:09:47 -06:00
|
|
|
required=False,
|
|
|
|
|
allow_null=True,
|
2024-06-03 14:06:47 +01:00
|
|
|
min_value=timedelta(minutes=1),
|
|
|
|
|
max_value=timedelta(hours=24),
|
2022-06-03 08:09:47 -06:00
|
|
|
)
|
2024-06-03 14:06:47 +01:00
|
|
|
num_minutes_in_window = serializers.IntegerField(
|
2022-06-03 08:09:47 -06:00
|
|
|
required=False,
|
|
|
|
|
allow_null=True,
|
2024-06-03 14:06:47 +01:00
|
|
|
min_value=1, # 1 minute
|
|
|
|
|
max_value=24 * 60, # 24 hours
|
2022-06-03 08:09:47 -06:00
|
|
|
)
|
|
|
|
|
notify_schedule = OrganizationFilteredPrimaryKeyRelatedField(
|
|
|
|
|
queryset=OnCallSchedule.objects,
|
|
|
|
|
required=False,
|
|
|
|
|
allow_null=True,
|
|
|
|
|
)
|
2024-02-20 10:02:23 -03:00
|
|
|
notify_to_team_members = OrganizationFilteredPrimaryKeyRelatedField(
|
|
|
|
|
queryset=Team.objects,
|
|
|
|
|
required=False,
|
|
|
|
|
allow_null=True,
|
|
|
|
|
)
|
2022-06-03 08:09:47 -06:00
|
|
|
notify_to_group = OrganizationFilteredPrimaryKeyRelatedField(
|
|
|
|
|
queryset=SlackUserGroup.objects,
|
|
|
|
|
required=False,
|
|
|
|
|
allow_null=True,
|
|
|
|
|
filter_field="slack_team_identity__organizations",
|
|
|
|
|
)
|
2023-04-05 09:03:55 -03:00
|
|
|
custom_webhook = OrganizationFilteredPrimaryKeyRelatedField(
|
|
|
|
|
queryset=Webhook.objects,
|
|
|
|
|
required=False,
|
|
|
|
|
allow_null=True,
|
|
|
|
|
filter_field="organization",
|
|
|
|
|
)
|
Reworked declare incident escalation step (#5130)
Reworked https://github.com/grafana/oncall/pull/5047. Main update is the
switch from FK to a [M2M
relation](https://docs.google.com/document/d/1HeulqxoFShSHtInQrZNJLL5MDlHPNT50rVGaK3zZWvw/edit?disco=AAABVLjV4W8)
(which doesn't really change the original/intended behavior, besides not
needing to alter the alert group table, and it is a bit more flexible;
the extra table shouldn't introduce issues because this is used only for
tracking purposes and the information needed in the log record is
already there).
Avoid a db migration involving alert group table:
```
--
-- Create model RelatedIncident
--
CREATE TABLE `alerts_relatedincident` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `incident_id` varchar(50) NOT NULL, `created_at` datetime(6) NOT NULL, `is_active` bool NOT NULL, `channel_filter_id` bigint NULL, `organization_id` bigint NOT NULL);
CREATE TABLE `alerts_relatedincident_attached_alert_groups` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `relatedincident_id` bigint NOT NULL, `alertgroup_id` bigint NOT NULL);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincident_organization_id_incident_id_d7fc9a4f_uniq` UNIQUE (`organization_id`, `incident_id`);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincide_channel_filter_id_9556c836_fk_alerts_ch` FOREIGN KEY (`channel_filter_id`) REFERENCES `alerts_channelfilter` (`id`);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincide_organization_id_74ed6bed_fk_user_mana` FOREIGN KEY (`organization_id`) REFERENCES `user_management_organization` (`id`);
CREATE INDEX `alerts_relatedincident_incident_id_8356a799` ON `alerts_relatedincident` (`incident_id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincident_a_relatedincident_id_alert_3d683baa_uniq` UNIQUE (`relatedincident_id`, `alertgroup_id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincide_relatedincident_id_3e5e7a23_fk_alerts_re` FOREIGN KEY (`relatedincident_id`) REFERENCES `alerts_relatedincident` (`id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincide_alertgroup_id_0125deca_fk_alerts_al` FOREIGN KEY (`alertgroup_id`) REFERENCES `alerts_alertgroup` (`id`);
```
2024-10-07 16:26:10 -03:00
|
|
|
severity = serializers.CharField(required=False, allow_null=True)
|
2022-06-03 08:09:47 -06:00
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
model = EscalationPolicy
|
|
|
|
|
fields = [
|
|
|
|
|
"id",
|
|
|
|
|
"step",
|
|
|
|
|
"wait_delay",
|
|
|
|
|
"escalation_chain",
|
|
|
|
|
"notify_to_users_queue",
|
|
|
|
|
"from_time",
|
|
|
|
|
"to_time",
|
|
|
|
|
"num_alerts_in_window",
|
|
|
|
|
"num_minutes_in_window",
|
|
|
|
|
"slack_integration_required",
|
2023-04-05 09:03:55 -03:00
|
|
|
"custom_webhook",
|
2022-06-03 08:09:47 -06:00
|
|
|
"notify_schedule",
|
|
|
|
|
"notify_to_group",
|
2024-02-20 10:02:23 -03:00
|
|
|
"notify_to_team_members",
|
Reworked declare incident escalation step (#5130)
Reworked https://github.com/grafana/oncall/pull/5047. Main update is the
switch from FK to a [M2M
relation](https://docs.google.com/document/d/1HeulqxoFShSHtInQrZNJLL5MDlHPNT50rVGaK3zZWvw/edit?disco=AAABVLjV4W8)
(which doesn't really change the original/intended behavior, besides not
needing to alter the alert group table, and it is a bit more flexible;
the extra table shouldn't introduce issues because this is used only for
tracking purposes and the information needed in the log record is
already there).
Avoid a db migration involving alert group table:
```
--
-- Create model RelatedIncident
--
CREATE TABLE `alerts_relatedincident` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `incident_id` varchar(50) NOT NULL, `created_at` datetime(6) NOT NULL, `is_active` bool NOT NULL, `channel_filter_id` bigint NULL, `organization_id` bigint NOT NULL);
CREATE TABLE `alerts_relatedincident_attached_alert_groups` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `relatedincident_id` bigint NOT NULL, `alertgroup_id` bigint NOT NULL);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincident_organization_id_incident_id_d7fc9a4f_uniq` UNIQUE (`organization_id`, `incident_id`);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincide_channel_filter_id_9556c836_fk_alerts_ch` FOREIGN KEY (`channel_filter_id`) REFERENCES `alerts_channelfilter` (`id`);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincide_organization_id_74ed6bed_fk_user_mana` FOREIGN KEY (`organization_id`) REFERENCES `user_management_organization` (`id`);
CREATE INDEX `alerts_relatedincident_incident_id_8356a799` ON `alerts_relatedincident` (`incident_id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincident_a_relatedincident_id_alert_3d683baa_uniq` UNIQUE (`relatedincident_id`, `alertgroup_id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincide_relatedincident_id_3e5e7a23_fk_alerts_re` FOREIGN KEY (`relatedincident_id`) REFERENCES `alerts_relatedincident` (`id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincide_alertgroup_id_0125deca_fk_alerts_al` FOREIGN KEY (`alertgroup_id`) REFERENCES `alerts_alertgroup` (`id`);
```
2024-10-07 16:26:10 -03:00
|
|
|
"severity",
|
2022-06-03 08:09:47 -06:00
|
|
|
"important",
|
|
|
|
|
]
|
|
|
|
|
|
2023-04-05 09:03:55 -03:00
|
|
|
SELECT_RELATED = [
|
|
|
|
|
"escalation_chain",
|
|
|
|
|
"notify_schedule",
|
|
|
|
|
"notify_to_group",
|
2024-02-20 10:02:23 -03:00
|
|
|
"notify_to_team_members",
|
2023-04-05 09:03:55 -03:00
|
|
|
"custom_webhook",
|
|
|
|
|
]
|
2022-06-03 08:09:47 -06:00
|
|
|
PREFETCH_RELATED = ["notify_to_users_queue"]
|
|
|
|
|
|
|
|
|
|
def validate(self, data):
|
|
|
|
|
fields_to_check = [
|
|
|
|
|
WAIT_DELAY,
|
|
|
|
|
NOTIFY_SCHEDULE,
|
|
|
|
|
NOTIFY_TO_USERS_QUEUE,
|
2024-02-20 10:02:23 -03:00
|
|
|
NOTIFY_TEAM_MEMBERS,
|
2022-06-03 08:09:47 -06:00
|
|
|
NOTIFY_GROUP,
|
|
|
|
|
FROM_TIME,
|
|
|
|
|
TO_TIME,
|
|
|
|
|
NUM_ALERTS_IN_WINDOW,
|
|
|
|
|
NUM_MINUTES_IN_WINDOW,
|
2023-04-05 09:03:55 -03:00
|
|
|
CUSTOM_WEBHOOK_TRIGGER,
|
Reworked declare incident escalation step (#5130)
Reworked https://github.com/grafana/oncall/pull/5047. Main update is the
switch from FK to a [M2M
relation](https://docs.google.com/document/d/1HeulqxoFShSHtInQrZNJLL5MDlHPNT50rVGaK3zZWvw/edit?disco=AAABVLjV4W8)
(which doesn't really change the original/intended behavior, besides not
needing to alter the alert group table, and it is a bit more flexible;
the extra table shouldn't introduce issues because this is used only for
tracking purposes and the information needed in the log record is
already there).
Avoid a db migration involving alert group table:
```
--
-- Create model RelatedIncident
--
CREATE TABLE `alerts_relatedincident` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `incident_id` varchar(50) NOT NULL, `created_at` datetime(6) NOT NULL, `is_active` bool NOT NULL, `channel_filter_id` bigint NULL, `organization_id` bigint NOT NULL);
CREATE TABLE `alerts_relatedincident_attached_alert_groups` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `relatedincident_id` bigint NOT NULL, `alertgroup_id` bigint NOT NULL);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincident_organization_id_incident_id_d7fc9a4f_uniq` UNIQUE (`organization_id`, `incident_id`);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincide_channel_filter_id_9556c836_fk_alerts_ch` FOREIGN KEY (`channel_filter_id`) REFERENCES `alerts_channelfilter` (`id`);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincide_organization_id_74ed6bed_fk_user_mana` FOREIGN KEY (`organization_id`) REFERENCES `user_management_organization` (`id`);
CREATE INDEX `alerts_relatedincident_incident_id_8356a799` ON `alerts_relatedincident` (`incident_id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincident_a_relatedincident_id_alert_3d683baa_uniq` UNIQUE (`relatedincident_id`, `alertgroup_id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincide_relatedincident_id_3e5e7a23_fk_alerts_re` FOREIGN KEY (`relatedincident_id`) REFERENCES `alerts_relatedincident` (`id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincide_alertgroup_id_0125deca_fk_alerts_al` FOREIGN KEY (`alertgroup_id`) REFERENCES `alerts_alertgroup` (`id`);
```
2024-10-07 16:26:10 -03:00
|
|
|
SEVERITY,
|
2022-06-03 08:09:47 -06:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
step = data.get("step")
|
|
|
|
|
if step is None:
|
|
|
|
|
raise serializers.ValidationError({"step": "This field is required."})
|
|
|
|
|
|
|
|
|
|
if data.get("important") and step in EscalationPolicy.STEPS_WITH_NO_IMPORTANT_VERSION_SET:
|
|
|
|
|
raise serializers.ValidationError(f"Step {step} can't be important")
|
|
|
|
|
|
|
|
|
|
for f in STEP_TYPE_TO_RELATED_FIELD_MAP.get(step, []):
|
|
|
|
|
fields_to_check.remove(f)
|
|
|
|
|
|
|
|
|
|
for field in fields_to_check:
|
|
|
|
|
if field == NOTIFY_TO_USERS_QUEUE:
|
|
|
|
|
# notify_to_users queue is m-to-m relation so we use empty list instead of None
|
|
|
|
|
if len(data.get(field, [])) != 0:
|
|
|
|
|
raise serializers.ValidationError(f"Invalid combination if step {step} and {field}")
|
|
|
|
|
else:
|
|
|
|
|
if data.get(field, None) is not None:
|
|
|
|
|
raise serializers.ValidationError(f"Invalid combination if step {step} and {field}")
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
def validate_step(self, step_type):
|
|
|
|
|
organization = self.context["request"].user.organization
|
|
|
|
|
if step_type not in EscalationPolicy.INTERNAL_API_STEPS:
|
|
|
|
|
raise serializers.ValidationError("Invalid step value")
|
|
|
|
|
if step_type in EscalationPolicy.SLACK_INTEGRATION_REQUIRED_STEPS and organization.slack_team_identity is None:
|
|
|
|
|
raise serializers.ValidationError("Invalid escalation step type: step is Slack-specific")
|
Reworked declare incident escalation step (#5130)
Reworked https://github.com/grafana/oncall/pull/5047. Main update is the
switch from FK to a [M2M
relation](https://docs.google.com/document/d/1HeulqxoFShSHtInQrZNJLL5MDlHPNT50rVGaK3zZWvw/edit?disco=AAABVLjV4W8)
(which doesn't really change the original/intended behavior, besides not
needing to alter the alert group table, and it is a bit more flexible;
the extra table shouldn't introduce issues because this is used only for
tracking purposes and the information needed in the log record is
already there).
Avoid a db migration involving alert group table:
```
--
-- Create model RelatedIncident
--
CREATE TABLE `alerts_relatedincident` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `incident_id` varchar(50) NOT NULL, `created_at` datetime(6) NOT NULL, `is_active` bool NOT NULL, `channel_filter_id` bigint NULL, `organization_id` bigint NOT NULL);
CREATE TABLE `alerts_relatedincident_attached_alert_groups` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `relatedincident_id` bigint NOT NULL, `alertgroup_id` bigint NOT NULL);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincident_organization_id_incident_id_d7fc9a4f_uniq` UNIQUE (`organization_id`, `incident_id`);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincide_channel_filter_id_9556c836_fk_alerts_ch` FOREIGN KEY (`channel_filter_id`) REFERENCES `alerts_channelfilter` (`id`);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincide_organization_id_74ed6bed_fk_user_mana` FOREIGN KEY (`organization_id`) REFERENCES `user_management_organization` (`id`);
CREATE INDEX `alerts_relatedincident_incident_id_8356a799` ON `alerts_relatedincident` (`incident_id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincident_a_relatedincident_id_alert_3d683baa_uniq` UNIQUE (`relatedincident_id`, `alertgroup_id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincide_relatedincident_id_3e5e7a23_fk_alerts_re` FOREIGN KEY (`relatedincident_id`) REFERENCES `alerts_relatedincident` (`id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincide_alertgroup_id_0125deca_fk_alerts_al` FOREIGN KEY (`alertgroup_id`) REFERENCES `alerts_alertgroup` (`id`);
```
2024-10-07 16:26:10 -03:00
|
|
|
if step_type == EscalationPolicy.STEP_DECLARE_INCIDENT and not is_declare_incident_step_enabled(organization):
|
|
|
|
|
raise serializers.ValidationError("Invalid escalation step type: step is not enabled")
|
2022-06-03 08:09:47 -06:00
|
|
|
return step_type
|
|
|
|
|
|
|
|
|
|
def to_representation(self, instance):
|
|
|
|
|
step = instance.step
|
|
|
|
|
result = super().to_representation(instance)
|
|
|
|
|
result = EscalationPolicySerializer._get_important_field(step, result)
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def _get_important_field(step, result):
|
|
|
|
|
if step in {*EscalationPolicy.DEFAULT_STEPS_SET, *EscalationPolicy.STEPS_WITH_NO_IMPORTANT_VERSION_SET}:
|
|
|
|
|
result["important"] = False
|
|
|
|
|
elif step in EscalationPolicy.IMPORTANT_STEPS_SET:
|
|
|
|
|
result["important"] = True
|
|
|
|
|
result["step"] = EscalationPolicy.IMPORTANT_TO_DEFAULT_STEP_MAPPING[step]
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def _convert_to_important_step_if_needed(validated_data):
|
|
|
|
|
step = validated_data.get("step")
|
|
|
|
|
important = validated_data.pop("important", None)
|
|
|
|
|
|
|
|
|
|
if step in EscalationPolicy.DEFAULT_STEPS_SET and important:
|
|
|
|
|
validated_data["step"] = EscalationPolicy.DEFAULT_TO_IMPORTANT_STEP_MAPPING[step]
|
|
|
|
|
|
|
|
|
|
return validated_data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class EscalationPolicyCreateSerializer(EscalationPolicySerializer):
|
|
|
|
|
class Meta(EscalationPolicySerializer.Meta):
|
|
|
|
|
extra_kwargs = {"escalation_chain": {"required": True, "allow_null": False}}
|
|
|
|
|
|
|
|
|
|
def create(self, validated_data):
|
|
|
|
|
validated_data = EscalationPolicyCreateSerializer._convert_to_important_step_if_needed(validated_data)
|
|
|
|
|
instance = super().create(validated_data)
|
|
|
|
|
return instance
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class EscalationPolicyUpdateSerializer(EscalationPolicySerializer):
|
|
|
|
|
escalation_chain = serializers.CharField(read_only=True, source="escalation_chain.public_primary_key")
|
|
|
|
|
|
|
|
|
|
class Meta(EscalationPolicySerializer.Meta):
|
2023-07-18 18:17:53 +01:00
|
|
|
read_only_fields = ["escalation_chain"]
|
2022-06-03 08:09:47 -06:00
|
|
|
|
|
|
|
|
def update(self, instance, validated_data):
|
|
|
|
|
step = validated_data.get("step", instance.step)
|
|
|
|
|
validated_data = EscalationPolicyUpdateSerializer._drop_not_step_type_related_fields(step, validated_data)
|
|
|
|
|
validated_data = EscalationPolicyUpdateSerializer._convert_to_important_step_if_needed(validated_data)
|
|
|
|
|
return super().update(instance, validated_data)
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def _drop_not_step_type_related_fields(step, validated_data):
|
|
|
|
|
fields_to_set_none = [
|
|
|
|
|
WAIT_DELAY,
|
|
|
|
|
NOTIFY_SCHEDULE,
|
|
|
|
|
NOTIFY_TO_USERS_QUEUE,
|
|
|
|
|
NOTIFY_GROUP,
|
2024-02-20 10:02:23 -03:00
|
|
|
NOTIFY_TEAM_MEMBERS,
|
2022-06-03 08:09:47 -06:00
|
|
|
FROM_TIME,
|
|
|
|
|
TO_TIME,
|
|
|
|
|
NUM_ALERTS_IN_WINDOW,
|
|
|
|
|
NUM_MINUTES_IN_WINDOW,
|
2023-04-05 09:03:55 -03:00
|
|
|
CUSTOM_WEBHOOK_TRIGGER,
|
Reworked declare incident escalation step (#5130)
Reworked https://github.com/grafana/oncall/pull/5047. Main update is the
switch from FK to a [M2M
relation](https://docs.google.com/document/d/1HeulqxoFShSHtInQrZNJLL5MDlHPNT50rVGaK3zZWvw/edit?disco=AAABVLjV4W8)
(which doesn't really change the original/intended behavior, besides not
needing to alter the alert group table, and it is a bit more flexible;
the extra table shouldn't introduce issues because this is used only for
tracking purposes and the information needed in the log record is
already there).
Avoid a db migration involving alert group table:
```
--
-- Create model RelatedIncident
--
CREATE TABLE `alerts_relatedincident` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `incident_id` varchar(50) NOT NULL, `created_at` datetime(6) NOT NULL, `is_active` bool NOT NULL, `channel_filter_id` bigint NULL, `organization_id` bigint NOT NULL);
CREATE TABLE `alerts_relatedincident_attached_alert_groups` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `relatedincident_id` bigint NOT NULL, `alertgroup_id` bigint NOT NULL);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincident_organization_id_incident_id_d7fc9a4f_uniq` UNIQUE (`organization_id`, `incident_id`);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincide_channel_filter_id_9556c836_fk_alerts_ch` FOREIGN KEY (`channel_filter_id`) REFERENCES `alerts_channelfilter` (`id`);
ALTER TABLE `alerts_relatedincident` ADD CONSTRAINT `alerts_relatedincide_organization_id_74ed6bed_fk_user_mana` FOREIGN KEY (`organization_id`) REFERENCES `user_management_organization` (`id`);
CREATE INDEX `alerts_relatedincident_incident_id_8356a799` ON `alerts_relatedincident` (`incident_id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincident_a_relatedincident_id_alert_3d683baa_uniq` UNIQUE (`relatedincident_id`, `alertgroup_id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincide_relatedincident_id_3e5e7a23_fk_alerts_re` FOREIGN KEY (`relatedincident_id`) REFERENCES `alerts_relatedincident` (`id`);
ALTER TABLE `alerts_relatedincident_attached_alert_groups` ADD CONSTRAINT `alerts_relatedincide_alertgroup_id_0125deca_fk_alerts_al` FOREIGN KEY (`alertgroup_id`) REFERENCES `alerts_alertgroup` (`id`);
```
2024-10-07 16:26:10 -03:00
|
|
|
SEVERITY,
|
2022-06-03 08:09:47 -06:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
for f in STEP_TYPE_TO_RELATED_FIELD_MAP.get(step, []):
|
|
|
|
|
fields_to_set_none.remove(f)
|
|
|
|
|
|
|
|
|
|
for f in fields_to_set_none:
|
|
|
|
|
if f == NOTIFY_TO_USERS_QUEUE:
|
|
|
|
|
# notify_to_users queue is m-to-m relation so we use empty list instead of None
|
|
|
|
|
validated_data[f] = []
|
|
|
|
|
else:
|
|
|
|
|
validated_data[f] = None
|
|
|
|
|
|
|
|
|
|
return validated_data
|