Enable event rules to target notification groups

This commit is contained in:
Jeremy Stretch 2024-07-04 15:05:48 -04:00
parent 8c0693fb36
commit 71860ba985
3 changed files with 38 additions and 18 deletions

View File

@ -18,18 +18,15 @@ from utilities.api import get_serializer_for_model
from utilities.rqworker import get_rq_retry from utilities.rqworker import get_rq_retry
from utilities.serialization import serialize_object from utilities.serialization import serialize_object
from .choices import EventRuleActionChoices from .choices import EventRuleActionChoices
from .constants import EVENT_CREATE, EVENT_DELETE, EVENT_UPDATE
from .models import EventRule from .models import EventRule
logger = logging.getLogger('netbox.events_processor') logger = logging.getLogger('netbox.events_processor')
EVENT_OBJECT_CREATED = 'object_created'
EVENT_OBJECT_UPDATED = 'object_updated'
EVENT_OBJECT_DELETED = 'object_deleted'
# Register event types # Register event types
Event(name=EVENT_OBJECT_CREATED, text=_('Object created')).register() Event(name=EVENT_CREATE, text=_('Object created')).register()
Event(name=EVENT_OBJECT_UPDATED, text=_('Object updated')).register() Event(name=EVENT_UPDATE, text=_('Object updated')).register()
Event(name=EVENT_OBJECT_DELETED, text=_('Object deleted')).register() Event(name=EVENT_DELETE, text=_('Object deleted')).register()
def serialize_for_event(instance): def serialize_for_event(instance):
@ -88,7 +85,7 @@ def enqueue_object(queue, instance, user, request_id, action):
} }
def process_event_rules(event_rules, model_name, event, data, username=None, snapshots=None, request_id=None): def process_event_rules(event_rules, object_type, event, data, username=None, snapshots=None, request_id=None):
if username: if username:
user = get_user_model().objects.get(username=username) user = get_user_model().objects.get(username=username)
else: else:
@ -110,7 +107,7 @@ def process_event_rules(event_rules, model_name, event, data, username=None, sna
# Compile the task parameters # Compile the task parameters
params = { params = {
"event_rule": event_rule, "event_rule": event_rule,
"model_name": model_name, "model_name": object_type.model,
"event": event, "event": event,
"data": data, "data": data,
"snapshots": snapshots, "snapshots": snapshots,
@ -143,10 +140,14 @@ def process_event_rules(event_rules, model_name, event, data, username=None, sna
data=data data=data
) )
# Notifications # Notification groups
elif event_rule.action_type == EventRuleActionChoices.NOTIFICATION: elif event_rule.action_type == EventRuleActionChoices.NOTIFICATION:
# TODO: Create notifications # Bulk-create notifications for all members of the notification group
pass event_rule.action_object.notify(
object_type=object_type,
object_id=data['id'],
event_name=event
)
else: else:
raise ValueError(_("Unknown action type for an event rule: {action_type}").format( raise ValueError(_("Unknown action type for an event rule: {action_type}").format(
@ -182,7 +183,7 @@ def process_event_queue(events):
event_rules = events_cache[action_flag][content_type] event_rules = events_cache[action_flag][content_type]
process_event_rules( process_event_rules(
event_rules, content_type.model, data['event'], data['data'], data['username'], event_rules, content_type, data['event'], data['data'], data['username'],
snapshots=data['snapshots'], request_id=data['request_id'] snapshots=data['snapshots'], request_id=data['request_id']
) )

View File

@ -11,6 +11,7 @@ from core.models import ObjectType
from extras.querysets import NotificationQuerySet from extras.querysets import NotificationQuerySet
from netbox.models import ChangeLoggedModel from netbox.models import ChangeLoggedModel
from netbox.registry import registry from netbox.registry import registry
from users.models import User
from utilities.querysets import RestrictedQuerySet from utilities.querysets import RestrictedQuerySet
__all__ = ( __all__ = (
@ -135,6 +136,24 @@ class NotificationGroup(ChangeLoggedModel):
def get_absolute_url(self): def get_absolute_url(self):
return reverse('extras:notificationgroup', args=[self.pk]) return reverse('extras:notificationgroup', args=[self.pk])
@cached_property
def members(self):
"""
Return all Users who belong to this notification group.
"""
return self.users.union(
User.objects.filter(groups__in=self.groups.all())
).order_by('username')
def notify(self, **kwargs):
"""
Bulk-create Notifications for all members of this group.
"""
Notification.objects.bulk_create([
Notification(user=member, **kwargs)
for member in self.members
])
class Subscription(models.Model): class Subscription(models.Model):
""" """

View File

@ -12,7 +12,7 @@ from django_prometheus.models import model_deletes, model_inserts, model_updates
from core.choices import ObjectChangeActionChoices from core.choices import ObjectChangeActionChoices
from core.models import ObjectChange, ObjectType from core.models import ObjectChange, ObjectType
from core.signals import job_end, job_start from core.signals import job_end, job_start
from extras.constants import EVENT_JOB_END, EVENT_JOB_START from extras.constants import EVENT_JOB_END, EVENT_JOB_START, EVENT_UPDATE
from extras.events import process_event_rules from extras.events import process_event_rules
from extras.models import EventRule, Notification, Subscription from extras.models import EventRule, Notification, Subscription
from netbox.config import get_config from netbox.config import get_config
@ -21,7 +21,7 @@ from netbox.models.features import ChangeLoggingMixin
from netbox.registry import registry from netbox.registry import registry
from netbox.signals import post_clean from netbox.signals import post_clean
from utilities.exceptions import AbortRequest from utilities.exceptions import AbortRequest
from .events import EVENT_OBJECT_UPDATED, enqueue_object from .events import enqueue_object
from .models import CustomField, TaggedItem from .models import CustomField, TaggedItem
from .validators import CustomValidator from .validators import CustomValidator
@ -271,7 +271,7 @@ def process_job_start_event_rules(sender, **kwargs):
""" """
event_rules = EventRule.objects.filter(type_job_start=True, enabled=True, object_types=sender.object_type) event_rules = EventRule.objects.filter(type_job_start=True, enabled=True, object_types=sender.object_type)
username = sender.user.username if sender.user else None username = sender.user.username if sender.user else None
process_event_rules(event_rules, sender.object_type.model, EVENT_JOB_START, sender.data, username) process_event_rules(event_rules, sender.object_type, EVENT_JOB_START, sender.data, username)
@receiver(job_end) @receiver(job_end)
@ -281,7 +281,7 @@ def process_job_end_event_rules(sender, **kwargs):
""" """
event_rules = EventRule.objects.filter(type_job_end=True, enabled=True, object_types=sender.object_type) event_rules = EventRule.objects.filter(type_job_end=True, enabled=True, object_types=sender.object_type)
username = sender.user.username if sender.user else None username = sender.user.username if sender.user else None
process_event_rules(event_rules, sender.object_type.model, EVENT_JOB_END, sender.data, username) process_event_rules(event_rules, sender.object_type, EVENT_JOB_END, sender.data, username)
# #
@ -309,7 +309,7 @@ def notify_object_changed(sender, instance, created, raw, **kwargs):
Notification( Notification(
user_id=sub['user'], user_id=sub['user'],
object=instance, object=instance,
event_name=EVENT_OBJECT_UPDATED event_name=EVENT_UPDATE
) )
for sub in subscriptions for sub in subscriptions
] ]