diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py index d271d18cb..f6a175b3d 100644 --- a/netbox/extras/api/serializers.py +++ b/netbox/extras/api/serializers.py @@ -67,12 +67,14 @@ class EventRuleSerializer(NetBoxModelSerializer): queryset=ContentType.objects.with_feature('webhooks'), many=True ) + action_type = ChoiceField(choices=EventRuleActionChoices) class Meta: model = EventRule fields = [ 'id', 'url', 'display', 'content_types', 'name', 'type_create', 'type_update', 'type_delete', - 'type_job_start', 'type_job_end', 'enabled', 'conditions', 'action_type', 'custom_fields', 'tags', + 'type_job_start', 'type_job_end', 'enabled', 'conditions', 'action_type', 'action_object_type' + 'action_object_id', 'action_object', 'custom_fields', 'tags', 'created', 'last_updated', ] diff --git a/netbox/extras/filtersets.py b/netbox/extras/filtersets.py index 99fe183a1..2a9f4be7d 100644 --- a/netbox/extras/filtersets.py +++ b/netbox/extras/filtersets.py @@ -69,12 +69,17 @@ class EventRuleFilterSet(NetBoxModelFilterSet): field_name='content_types__id' ) content_types = ContentTypeFilter() + action_type = django_filters.MultipleChoiceFilter( + choices=EventRuleActionChoices + ) + action_object_type = ContentTypeFilter() + action_object_id = MultiValueNumberFilter() class Meta: model = EventRule fields = [ 'id', 'name', 'type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end', 'enabled', - 'description', + 'action_type', 'description', ] def search(self, queryset, name, value): diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index 193080285..5ec79d128 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -156,8 +156,8 @@ class EventRuleImportForm(NetBoxModelImportForm): class Meta: model = EventRule fields = ( - 'name', 'description', 'enabled', 'content_types', 'type_create', 'type_update', 'type_delete', - 'type_job_start', 'type_job_end', 'comments', 'tags' + 'name', 'description', 'enabled', 'conditions', 'content_types', 'type_create', 'type_update', + 'type_delete', 'type_job_start', 'type_job_end', 'comments', 'tags' ) diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index f033ba2a0..01d057cb0 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -162,6 +162,20 @@ class EventRule(CustomFieldsMixin, ExportTemplatesMixin, TagsMixin, ChangeLogged except ValueError as e: raise ValidationError({'conditions': e}) + def eval_conditions(self, data): + """ + Test whether the given data meets the conditions of the event rule (if any). Return True + if met or no conditions are specified. + """ + if not self.conditions: + return True + + logger.debug(f'Evaluating event rule conditions: {self.conditions}') + if ConditionSet(self.conditions).eval(data): + return True + + return False + class Webhook(CustomFieldsMixin, ExportTemplatesMixin, TagsMixin, ChangeLoggedModel): """ diff --git a/netbox/extras/scripts_worker.py b/netbox/extras/scripts_worker.py index f558e21ef..d8e23b3c9 100644 --- a/netbox/extras/scripts_worker.py +++ b/netbox/extras/scripts_worker.py @@ -7,17 +7,16 @@ from django_rq import job from core.models import Job from extras.models import ScriptModule from extras.scripts import run_script -from extras.utils import eval_conditions logger = logging.getLogger('netbox.scripts_worker') @job('default') -def process_script(event_rule, model_name, event, data, timestamp, username, request_id=None, snapshots=None): +def process_script(event_rule, data, username, **kwargs): """ Run the requested script """ - if not eval_conditions(event_rule, data): + if not event_rule.eval_conditions(data): return module_id = event_rule.action_parameters.split(":")[0] diff --git a/netbox/extras/tests/test_event_rules.py b/netbox/extras/tests/test_event_rules.py index 91a99b519..990495593 100644 --- a/netbox/extras/tests/test_event_rules.py +++ b/netbox/extras/tests/test_event_rules.py @@ -14,7 +14,6 @@ from dcim.models import Site from extras.choices import ObjectChangeActionChoices from extras.models import Tag, EventRule, Webhook from extras.events import enqueue_object, flush_events, serialize_for_event -from extras.utils import eval_conditions from extras.webhooks import generate_signature from extras.webhooks_worker import process_webhook from utilities.testing import APITestCase @@ -50,7 +49,7 @@ class EventRuleTest(APITestCase): def test_event_rule_conditions(self): # Create a conditional Webhook - webhook = EventRule( + event_rule = EventRule( name='Conditional Webhook', type_create=True, type_update=True, @@ -69,11 +68,11 @@ class EventRuleTest(APITestCase): data = serialize_for_event(site) # Evaluate the conditions (status='staging') - self.assertFalse(eval_conditions(webhook, data)) + self.assertFalse(event_rule.eval_conditions(data)) # Change the site's status site.status = SiteStatusChoices.STATUS_ACTIVE data = serialize_for_event(site) # Evaluate the conditions (status='active') - self.assertTrue(eval_conditions(webhook, data)) + self.assertTrue(event_rule.eval_conditions(data)) diff --git a/netbox/extras/utils.py b/netbox/extras/utils.py index b14e33341..b95023825 100644 --- a/netbox/extras/utils.py +++ b/netbox/extras/utils.py @@ -81,21 +81,6 @@ def is_report(obj): return False -def eval_conditions(event_rule, data): - """ - Test whether the given data meets the conditions of the event rule (if any). Return True - if met or no conditions are specified. - """ - if not event_rule.conditions: - return True - - logger.debug(f'Evaluating event rule conditions: {event_rule.conditions}') - if ConditionSet(event_rule.conditions).eval(data): - return True - - return False - - def process_event_rules(event_rules, model_name, event, data, username, snapshots=None, request_id=None): rq_queue_name = get_config().QUEUE_MAPPINGS.get('webhook', RQ_QUEUE_DEFAULT) rq_queue = get_queue(rq_queue_name) diff --git a/netbox/extras/webhooks_worker.py b/netbox/extras/webhooks_worker.py index d4a9bbee1..5e3648bf9 100644 --- a/netbox/extras/webhooks_worker.py +++ b/netbox/extras/webhooks_worker.py @@ -6,7 +6,6 @@ from django_rq import job from jinja2.exceptions import TemplateError from .constants import WEBHOOK_EVENT_TYPES -from .utils import eval_conditions from .webhooks import generate_signature logger = logging.getLogger('netbox.webhooks_worker') @@ -18,7 +17,7 @@ def process_webhook(event_rule, model_name, event, data, timestamp, username, re Make a POST request to the defined Webhook """ - if not eval_conditions(event_rule, data): + if not event_rule.eval_conditions(data): return webhook = event_rule.action_object