Rename EventRule.content_types to object_types & use ObjectType proxy

This commit is contained in:
Jeremy Stretch 2024-03-01 15:31:03 -05:00
parent ba514aceac
commit e51d71d7e6
15 changed files with 71 additions and 58 deletions

View File

@ -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',
]

View File

@ -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]

View File

@ -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
)

View File

@ -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'
)

View File

@ -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')

View File

@ -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'
)

View File

@ -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

View File

@ -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'),
),
]

View File

@ -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.")
)

View File

@ -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',
)

View File

@ -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',

View File

@ -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'),

View File

@ -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):

View File

@ -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",
)

View File

@ -26,9 +26,9 @@
<div class="card">
<h5 class="card-header">{% trans "Object Types" %}</h5>
<table class="table table-hover attr-table">
{% for ct in object.content_types.all %}
{% for object_type in object.object_types.all %}
<tr>
<td>{{ ct }}</td>
<td>{{ object_type }}</td>
</tr>
{% endfor %}
</table>