-
Notifications
You must be signed in to change notification settings - Fork 296
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4683 from grafana/dev
v1.8.5
- Loading branch information
Showing
82 changed files
with
2,275 additions
and
506 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
engine/apps/alerts/migrations/0052_alter_channelfilter_filtering_term_type.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Generated by Django 4.2.11 on 2024-07-04 20:20 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('alerts', '0051_remove_escalationpolicy_custom_button_trigger'), | ||
] | ||
|
||
operations = [ | ||
migrations.AlterField( | ||
model_name='channelfilter', | ||
name='filtering_term_type', | ||
field=models.IntegerField(choices=[(0, 'regex'), (1, 'jinja2'), (2, 'labels')], default=0), | ||
), | ||
] |
18 changes: 18 additions & 0 deletions
18
engine/apps/alerts/migrations/0053_channelfilter_filtering_labels.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Generated by Django 4.2.11 on 2024-07-08 18:20 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('alerts', '0052_alter_channelfilter_filtering_term_type'), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name='channelfilter', | ||
name='filtering_labels', | ||
field=models.JSONField(default=None, null=True), | ||
), | ||
] |
45 changes: 45 additions & 0 deletions
45
engine/apps/alerts/migrations/0054_usernotificationbundle_bundlednotification_and_more.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Generated by Django 4.2.10 on 2024-06-20 11:00 | ||
|
||
import apps.base.models.user_notification_policy | ||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('base', '0005_drop_unused_dynamic_settings'), | ||
('user_management', '0022_alter_team_unique_together'), | ||
('alerts', '0053_channelfilter_filtering_labels'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='UserNotificationBundle', | ||
fields=[ | ||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('important', models.BooleanField()), | ||
('notification_channel', models.PositiveSmallIntegerField(default=None, null=True, validators=[apps.base.models.user_notification_policy.validate_channel_choice])), | ||
('last_notified_at', models.DateTimeField(default=None, null=True)), | ||
('notification_task_id', models.CharField(default=None, max_length=100, null=True)), | ||
('eta', models.DateTimeField(default=None, null=True)), | ||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notification_bundles', to='user_management.user')), | ||
], | ||
), | ||
migrations.CreateModel( | ||
name='BundledNotification', | ||
fields=[ | ||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('created_at', models.DateTimeField(auto_now_add=True)), | ||
('bundle_uuid', models.CharField(db_index=True, default=None, max_length=100, null=True)), | ||
('alert_group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='alerts.alertgroup')), | ||
('alert_receive_channel', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='alerts.alertreceivechannel')), | ||
('notification_bundle', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notifications', to='alerts.usernotificationbundle')), | ||
('notification_policy', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='base.usernotificationpolicy')), | ||
], | ||
), | ||
migrations.AddConstraint( | ||
model_name='usernotificationbundle', | ||
constraint=models.UniqueConstraint(fields=('user', 'important', 'notification_channel'), name='unique_user_notification_bundle'), | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import datetime | ||
import typing | ||
|
||
from django.db import models | ||
from django.utils import timezone | ||
|
||
from apps.alerts.constants import BUNDLED_NOTIFICATION_DELAY_SECONDS | ||
from apps.base.models import UserNotificationPolicy | ||
from apps.base.models.user_notification_policy import validate_channel_choice | ||
|
||
if typing.TYPE_CHECKING: | ||
from django.db.models.manager import RelatedManager | ||
|
||
from apps.alerts.models import AlertGroup, AlertReceiveChannel | ||
from apps.user_management.models import User | ||
|
||
|
||
class UserNotificationBundle(models.Model): | ||
user: "User" | ||
notifications: "RelatedManager['BundledNotification']" | ||
|
||
NOTIFICATION_CHANNELS_TO_BUNDLE = [ | ||
UserNotificationPolicy.NotificationChannel.SMS, | ||
] | ||
|
||
user = models.ForeignKey("user_management.User", on_delete=models.CASCADE, related_name="notification_bundles") | ||
important = models.BooleanField() | ||
notification_channel = models.PositiveSmallIntegerField( | ||
validators=[validate_channel_choice], null=True, default=None | ||
) | ||
last_notified_at = models.DateTimeField(default=None, null=True) | ||
notification_task_id = models.CharField(max_length=100, null=True, default=None) | ||
# estimated time of arrival for scheduled send_bundled_notification task | ||
eta = models.DateTimeField(default=None, null=True) | ||
|
||
class Meta: | ||
constraints = [ | ||
models.UniqueConstraint( | ||
fields=["user", "important", "notification_channel"], name="unique_user_notification_bundle" | ||
) | ||
] | ||
|
||
def notified_recently(self) -> bool: | ||
return ( | ||
timezone.now() - self.last_notified_at < timezone.timedelta(seconds=BUNDLED_NOTIFICATION_DELAY_SECONDS) | ||
if self.last_notified_at | ||
else False | ||
) | ||
|
||
def eta_is_valid(self) -> bool: | ||
""" | ||
`eta` shows eta of scheduled send_bundled_notification task and should never be less than the current time | ||
(with a 1 minute buffer provided). | ||
`eta` is None means that there is no scheduled task. | ||
""" | ||
if not self.eta or self.eta + timezone.timedelta(minutes=1) >= timezone.now(): | ||
return True | ||
return False | ||
|
||
def get_notification_eta(self) -> datetime.datetime: | ||
last_notified = self.last_notified_at if self.last_notified_at else timezone.now() | ||
return last_notified + timezone.timedelta(seconds=BUNDLED_NOTIFICATION_DELAY_SECONDS) | ||
|
||
def append_notification(self, alert_group: "AlertGroup", notification_policy: "UserNotificationPolicy"): | ||
self.notifications.create( | ||
alert_group=alert_group, notification_policy=notification_policy, alert_receive_channel=alert_group.channel | ||
) | ||
|
||
@classmethod | ||
def notification_is_bundleable(cls, notification_channel): | ||
return notification_channel in cls.NOTIFICATION_CHANNELS_TO_BUNDLE | ||
|
||
|
||
class BundledNotification(models.Model): | ||
alert_group: "AlertGroup" | ||
alert_receive_channel: "AlertReceiveChannel" | ||
notification_policy: typing.Optional["UserNotificationPolicy"] | ||
notification_bundle: "UserNotificationBundle" | ||
|
||
alert_group = models.ForeignKey("alerts.AlertGroup", on_delete=models.CASCADE) | ||
alert_receive_channel = models.ForeignKey("alerts.AlertReceiveChannel", on_delete=models.CASCADE) | ||
notification_policy = models.ForeignKey("base.UserNotificationPolicy", on_delete=models.SET_NULL, null=True) | ||
notification_bundle = models.ForeignKey( | ||
UserNotificationBundle, on_delete=models.CASCADE, related_name="notifications" | ||
) | ||
created_at = models.DateTimeField(auto_now_add=True) | ||
bundle_uuid = models.CharField(max_length=100, null=True, default=None, db_index=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.