diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py index fe66e2035..32b708fcc 100644 --- a/netbox/extras/api/serializers.py +++ b/netbox/extras/api/serializers.py @@ -59,7 +59,7 @@ __all__ = ( class EventRuleSerializer(NetBoxModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='extras-api:eventrule-detail') - content_types = ContentTypeField( + object_types = ContentTypeField( queryset=ObjectType.objects.with_feature('event_rules'), many=True ) @@ -72,7 +72,7 @@ class EventRuleSerializer(NetBoxModelSerializer): class Meta: model = EventRule fields = [ - 'id', 'url', 'display', 'content_types', 'name', 'type_create', 'type_update', 'type_delete', + 'id', 'url', 'display', 'object_types', 'name', 'type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end', 'enabled', 'conditions', 'action_type', 'action_object_type', 'action_object_id', 'action_object', 'description', 'custom_fields', 'tags', 'created', 'last_updated', ] diff --git a/netbox/extras/events.py b/netbox/extras/events.py index e7706ea9f..0ee4cffa8 100644 --- a/netbox/extras/events.py +++ b/netbox/extras/events.py @@ -155,7 +155,7 @@ def process_event_queue(events): if content_type not in events_cache[action_flag]: events_cache[action_flag][content_type] = EventRule.objects.filter( **{action_flag: True}, - content_types=content_type, + object_types=content_type, enabled=True ) event_rules = events_cache[action_flag][content_type] diff --git a/netbox/extras/filtersets.py b/netbox/extras/filtersets.py index dd378075a..d03d134be 100644 --- a/netbox/extras/filtersets.py +++ b/netbox/extras/filtersets.py @@ -89,10 +89,10 @@ class EventRuleFilterSet(NetBoxModelFilterSet): method='search', label=_('Search'), ) - content_type_id = MultiValueNumberFilter( - field_name='content_types__id' + object_types_id = MultiValueNumberFilter( + field_name='object_types__id' ) - content_types = ContentTypeFilter() + object_types = ContentTypeFilter() action_type = django_filters.MultipleChoiceFilter( choices=EventRuleActionChoices ) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index abe35e30c..cbb7b4e44 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -173,8 +173,8 @@ class WebhookImportForm(NetBoxModelImportForm): class EventRuleImportForm(NetBoxModelImportForm): - content_types = CSVMultipleContentTypeField( - label=_('Content types'), + object_types = CSVMultipleContentTypeField( + label=_('Object types'), queryset=ObjectType.objects.with_feature('event_rules'), help_text=_("One or more assigned object types") ) @@ -187,7 +187,7 @@ class EventRuleImportForm(NetBoxModelImportForm): class Meta: model = EventRule fields = ( - 'name', 'description', 'enabled', 'conditions', 'content_types', 'type_create', 'type_update', + 'name', 'description', 'enabled', 'conditions', 'object_types', 'type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end', 'action_type', 'action_object', 'comments', 'tags' ) diff --git a/netbox/extras/forms/filtersets.py b/netbox/extras/forms/filtersets.py index 208f28725..f19695f57 100644 --- a/netbox/extras/forms/filtersets.py +++ b/netbox/extras/forms/filtersets.py @@ -250,10 +250,10 @@ class EventRuleFilterForm(NetBoxModelFilterSetForm): fieldsets = ( (None, ('q', 'filter_id', 'tag')), - (_('Attributes'), ('content_type_id', 'action_type', 'enabled')), + (_('Attributes'), ('object_types_id', 'action_type', 'enabled')), (_('Events'), ('type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end')), ) - content_type_id = ContentTypeMultipleChoiceField( + object_types_id = ContentTypeMultipleChoiceField( queryset=ObjectType.objects.with_feature('event_rules'), required=False, label=_('Object type') diff --git a/netbox/extras/forms/model_forms.py b/netbox/extras/forms/model_forms.py index 70f533013..9423e35e2 100644 --- a/netbox/extras/forms/model_forms.py +++ b/netbox/extras/forms/model_forms.py @@ -248,8 +248,8 @@ class WebhookForm(NetBoxModelForm): class EventRuleForm(NetBoxModelForm): - content_types = ContentTypeMultipleChoiceField( - label=_('Content types'), + object_types = ContentTypeMultipleChoiceField( + label=_('Object types'), queryset=ObjectType.objects.with_feature('event_rules'), ) action_choice = forms.ChoiceField( @@ -266,7 +266,7 @@ class EventRuleForm(NetBoxModelForm): ) fieldsets = ( - (_('Event Rule'), ('name', 'description', 'content_types', 'enabled', 'tags')), + (_('Event Rule'), ('name', 'description', 'object_types', 'enabled', 'tags')), (_('Events'), ('type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end')), (_('Conditions'), ('conditions',)), (_('Action'), ( @@ -277,7 +277,7 @@ class EventRuleForm(NetBoxModelForm): class Meta: model = EventRule fields = ( - 'content_types', 'name', 'description', 'type_create', 'type_update', 'type_delete', 'type_job_start', + 'object_types', 'name', 'description', 'type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end', 'enabled', 'conditions', 'action_type', 'action_object_type', 'action_object_id', 'action_data', 'comments', 'tags' ) diff --git a/netbox/extras/graphql/types.py b/netbox/extras/graphql/types.py index e4cfd4be7..15ef76b6b 100644 --- a/netbox/extras/graphql/types.py +++ b/netbox/extras/graphql/types.py @@ -59,6 +59,14 @@ class CustomLinkType(ObjectType): filterset_class = filtersets.CustomLinkFilterSet +class EventRuleType(OrganizationalObjectType): + + class Meta: + model = models.EventRule + exclude = ('object_types',) + filterset_class = filtersets.EventRuleFilterSet + + class ExportTemplateType(ObjectType): class Meta: @@ -112,11 +120,3 @@ class WebhookType(OrganizationalObjectType): class Meta: model = models.Webhook filterset_class = filtersets.WebhookFilterSet - - -class EventRuleType(OrganizationalObjectType): - - class Meta: - model = models.EventRule - exclude = ('content_types', ) - filterset_class = filtersets.EventRuleFilterSet diff --git a/netbox/extras/migrations/0111_rename_content_types.py b/netbox/extras/migrations/0111_rename_content_types.py index dc3ec9fe6..f44b01e34 100644 --- a/netbox/extras/migrations/0111_rename_content_types.py +++ b/netbox/extras/migrations/0111_rename_content_types.py @@ -38,4 +38,16 @@ class Migration(migrations.Migration): name='object_types', field=models.ManyToManyField(related_name='custom_links', to='core.objecttype'), ), + + # Event rules + migrations.RenameField( + model_name='eventrule', + old_name='content_types', + new_name='object_types', + ), + migrations.AlterField( + model_name='eventrule', + name='object_types', + field=models.ManyToManyField(related_name='event_rules', to='core.objecttype'), + ), ] diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index 7439546fb..bfc11b7c5 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -43,9 +43,9 @@ class EventRule(CustomFieldsMixin, ExportTemplatesMixin, TagsMixin, ChangeLogged specific type of object is created, modified, or deleted. The action to be taken might entail transmitting a webhook or executing a custom script. """ - content_types = models.ManyToManyField( - to='contenttypes.ContentType', - related_name='eventrules', + object_types = models.ManyToManyField( + to='core.ObjectType', + related_name='event_rules', verbose_name=_('object types'), help_text=_("The object(s) to which this rule applies.") ) diff --git a/netbox/extras/tables/tables.py b/netbox/extras/tables/tables.py index 7adbae178..7775916b9 100644 --- a/netbox/extras/tables/tables.py +++ b/netbox/extras/tables/tables.py @@ -281,8 +281,8 @@ class EventRuleTable(NetBoxTable): linkify=True, verbose_name=_('Object'), ) - content_types = columns.ContentTypesColumn( - verbose_name=_('Content Types'), + object_types = columns.ContentTypesColumn( + verbose_name=_('Object Types'), ) enabled = columns.BooleanColumn( verbose_name=_('Enabled'), @@ -309,7 +309,7 @@ class EventRuleTable(NetBoxTable): class Meta(NetBoxTable.Meta): model = EventRule fields = ( - 'pk', 'id', 'name', 'enabled', 'description', 'action_type', 'action_object', 'content_types', + 'pk', 'id', 'name', 'enabled', 'description', 'action_type', 'action_object', 'object_types', 'type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end', 'tags', 'created', 'last_updated', ) diff --git a/netbox/extras/tests/test_api.py b/netbox/extras/tests/test_api.py index ae592b528..7bed486a0 100644 --- a/netbox/extras/tests/test_api.py +++ b/netbox/extras/tests/test_api.py @@ -122,7 +122,7 @@ class EventRuleTest(APIViewTestCases.APIViewTestCase): cls.create_data = [ { 'name': 'EventRule 4', - 'content_types': ['dcim.device', 'dcim.devicetype'], + 'object_types': ['dcim.device', 'dcim.devicetype'], 'type_create': True, 'action_type': EventRuleActionChoices.WEBHOOK, 'action_object_type': 'extras.webhook', @@ -130,7 +130,7 @@ class EventRuleTest(APIViewTestCases.APIViewTestCase): }, { 'name': 'EventRule 5', - 'content_types': ['dcim.device', 'dcim.devicetype'], + 'object_types': ['dcim.device', 'dcim.devicetype'], 'type_create': True, 'action_type': EventRuleActionChoices.WEBHOOK, 'action_object_type': 'extras.webhook', @@ -138,7 +138,7 @@ class EventRuleTest(APIViewTestCases.APIViewTestCase): }, { 'name': 'EventRule 6', - 'content_types': ['dcim.device', 'dcim.devicetype'], + 'object_types': ['dcim.device', 'dcim.devicetype'], 'type_create': True, 'action_type': EventRuleActionChoices.WEBHOOK, 'action_object_type': 'extras.webhook', diff --git a/netbox/extras/tests/test_event_rules.py b/netbox/extras/tests/test_event_rules.py index 549c33478..8cea2078a 100644 --- a/netbox/extras/tests/test_event_rules.py +++ b/netbox/extras/tests/test_event_rules.py @@ -3,17 +3,18 @@ import uuid from unittest.mock import patch import django_rq -from dcim.choices import SiteStatusChoices -from dcim.models import Site -from django.contrib.contenttypes.models import ContentType from django.http import HttpResponse from django.urls import reverse +from requests import Session +from rest_framework import status + +from core.models import ObjectType +from dcim.choices import SiteStatusChoices +from dcim.models import Site from extras.choices import EventRuleActionChoices, ObjectChangeActionChoices from extras.events import enqueue_object, flush_events, serialize_for_event from extras.models import EventRule, Tag, Webhook from extras.webhooks import generate_signature, send_webhook -from requests import Session -from rest_framework import status from utilities.testing import APITestCase @@ -29,7 +30,7 @@ class EventRuleTest(APITestCase): @classmethod def setUpTestData(cls): - site_ct = ContentType.objects.get_for_model(Site) + site_type = ObjectType.objects.get_for_model(Site) DUMMY_URL = 'http://localhost:9000/' DUMMY_SECRET = 'LOOKATMEIMASECRETSTRING' @@ -39,32 +40,32 @@ class EventRuleTest(APITestCase): Webhook(name='Webhook 3', payload_url=DUMMY_URL, secret=DUMMY_SECRET), )) - ct = ContentType.objects.get(app_label='extras', model='webhook') + webhook_type = ObjectType.objects.get(app_label='extras', model='webhook') event_rules = EventRule.objects.bulk_create(( EventRule( name='Webhook Event 1', type_create=True, action_type=EventRuleActionChoices.WEBHOOK, - action_object_type=ct, + action_object_type=webhook_type, action_object_id=webhooks[0].id ), EventRule( name='Webhook Event 2', type_update=True, action_type=EventRuleActionChoices.WEBHOOK, - action_object_type=ct, + action_object_type=webhook_type, action_object_id=webhooks[0].id ), EventRule( name='Webhook Event 3', type_delete=True, action_type=EventRuleActionChoices.WEBHOOK, - action_object_type=ct, + action_object_type=webhook_type, action_object_id=webhooks[0].id ), )) for event_rule in event_rules: - event_rule.content_types.set([site_ct]) + event_rule.object_types.set([site_type]) Tag.objects.bulk_create(( Tag(name='Foo', slug='foo'), diff --git a/netbox/extras/tests/test_filtersets.py b/netbox/extras/tests/test_filtersets.py index a23e11288..43ee605fb 100644 --- a/netbox/extras/tests/test_filtersets.py +++ b/netbox/extras/tests/test_filtersets.py @@ -241,7 +241,7 @@ class EventRuleTestCase(TestCase, BaseFilterSetTests): @classmethod def setUpTestData(cls): - content_types = ContentType.objects.filter( + object_types = ObjectType.objects.filter( model__in=['region', 'site', 'rack', 'location', 'device'] ) @@ -334,11 +334,11 @@ class EventRuleTestCase(TestCase, BaseFilterSetTests): ), ) EventRule.objects.bulk_create(event_rules) - event_rules[0].content_types.add(content_types[0]) - event_rules[1].content_types.add(content_types[1]) - event_rules[2].content_types.add(content_types[2]) - event_rules[3].content_types.add(content_types[3]) - event_rules[4].content_types.add(content_types[4]) + event_rules[0].object_types.add(object_types[0]) + event_rules[1].object_types.add(object_types[1]) + event_rules[2].object_types.add(object_types[2]) + event_rules[3].object_types.add(object_types[3]) + event_rules[4].object_types.add(object_types[4]) def test_q(self): params = {'q': 'foobar1'} @@ -352,10 +352,10 @@ class EventRuleTestCase(TestCase, BaseFilterSetTests): params = {'description': ['foobar1', 'foobar2']} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - def test_content_types(self): - params = {'content_types': 'dcim.region'} + def test_object_types(self): + params = {'object_types': 'dcim.region'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) - params = {'content_type_id': [ContentType.objects.get_for_model(Region).pk]} + params = {'object_types_id': [ContentType.objects.get_for_model(Region).pk]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) def test_action_type(self): diff --git a/netbox/extras/tests/test_views.py b/netbox/extras/tests/test_views.py index 890cd59de..ba7cd0818 100644 --- a/netbox/extras/tests/test_views.py +++ b/netbox/extras/tests/test_views.py @@ -397,7 +397,7 @@ class EventRulesTestCase(ViewTestCases.PrimaryObjectViewTestCase): for webhook in webhooks: webhook.save() - site_ct = ContentType.objects.get_for_model(Site) + site_type = ObjectType.objects.get_for_model(Site) event_rules = ( EventRule(name='EventRule 1', type_create=True, action_object=webhooks[0]), EventRule(name='EventRule 2', type_create=True, action_object=webhooks[1]), @@ -405,12 +405,12 @@ class EventRulesTestCase(ViewTestCases.PrimaryObjectViewTestCase): ) for event in event_rules: event.save() - event.content_types.add(site_ct) + event.object_types.add(site_type) webhook_ct = ContentType.objects.get_for_model(Webhook) cls.form_data = { 'name': 'Event X', - 'content_types': [site_ct.pk], + 'object_types': [site_type.pk], 'type_create': False, 'type_update': True, 'type_delete': True, @@ -423,7 +423,7 @@ class EventRulesTestCase(ViewTestCases.PrimaryObjectViewTestCase): } cls.csv_data = ( - "name,content_types,type_create,action_type,action_object", + "name,object_types,type_create,action_type,action_object", "Webhook 4,dcim.site,True,webhook,Webhook 1", ) diff --git a/netbox/templates/extras/eventrule.html b/netbox/templates/extras/eventrule.html index d3c483819..844fbf9c6 100644 --- a/netbox/templates/extras/eventrule.html +++ b/netbox/templates/extras/eventrule.html @@ -26,9 +26,9 @@
{{ ct }} | +{{ object_type }} |