mirror of
https://github.com/netbox-community/netbox.git
synced 2026-04-27 19:27:33 +02:00
* Initial work on #16886 * Restore GraphQL filter * Remove namespace * Add Event documentation * Use MultipleChoiceField for event_types * Fix event_types field class on EventRuleImportForm * Fix tests * Simplify event queue handling logic * Misc cleanup
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import datetime
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.urls import reverse
|
||||
from django.utils.timezone import make_aware
|
||||
@@ -13,6 +12,7 @@ from dcim.models import Device, DeviceRole, DeviceType, Manufacturer, Rack, Loca
|
||||
from extras.choices import *
|
||||
from extras.models import *
|
||||
from extras.scripts import BooleanVar, IntegerVar, Script as PythonClass, StringVar
|
||||
from netbox.events import *
|
||||
from users.models import Group, User
|
||||
from utilities.testing import APITestCase, APIViewTestCases
|
||||
|
||||
@@ -113,9 +113,9 @@ class EventRuleTest(APIViewTestCases.APIViewTestCase):
|
||||
Webhook.objects.bulk_create(webhooks)
|
||||
|
||||
event_rules = (
|
||||
EventRule(name='EventRule 1', type_create=True, action_object=webhooks[0]),
|
||||
EventRule(name='EventRule 2', type_create=True, action_object=webhooks[1]),
|
||||
EventRule(name='EventRule 3', type_create=True, action_object=webhooks[2]),
|
||||
EventRule(name='EventRule 1', event_types=[OBJECT_CREATED], action_object=webhooks[0]),
|
||||
EventRule(name='EventRule 2', event_types=[OBJECT_CREATED], action_object=webhooks[1]),
|
||||
EventRule(name='EventRule 3', event_types=[OBJECT_CREATED], action_object=webhooks[2]),
|
||||
)
|
||||
EventRule.objects.bulk_create(event_rules)
|
||||
|
||||
@@ -123,7 +123,7 @@ class EventRuleTest(APIViewTestCases.APIViewTestCase):
|
||||
{
|
||||
'name': 'EventRule 4',
|
||||
'object_types': ['dcim.device', 'dcim.devicetype'],
|
||||
'type_create': True,
|
||||
'event_types': [OBJECT_CREATED],
|
||||
'action_type': EventRuleActionChoices.WEBHOOK,
|
||||
'action_object_type': 'extras.webhook',
|
||||
'action_object_id': webhooks[3].pk,
|
||||
@@ -131,7 +131,7 @@ class EventRuleTest(APIViewTestCases.APIViewTestCase):
|
||||
{
|
||||
'name': 'EventRule 5',
|
||||
'object_types': ['dcim.device', 'dcim.devicetype'],
|
||||
'type_create': True,
|
||||
'event_types': [OBJECT_CREATED],
|
||||
'action_type': EventRuleActionChoices.WEBHOOK,
|
||||
'action_object_type': 'extras.webhook',
|
||||
'action_object_id': webhooks[4].pk,
|
||||
@@ -139,7 +139,7 @@ class EventRuleTest(APIViewTestCases.APIViewTestCase):
|
||||
{
|
||||
'name': 'EventRule 6',
|
||||
'object_types': ['dcim.device', 'dcim.devicetype'],
|
||||
'type_create': True,
|
||||
'event_types': [OBJECT_CREATED],
|
||||
'action_type': EventRuleActionChoices.WEBHOOK,
|
||||
'action_object_type': 'extras.webhook',
|
||||
'action_object_id': webhooks[5].pk,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.test import TestCase
|
||||
|
||||
from core.events import *
|
||||
from dcim.choices import SiteStatusChoices
|
||||
from dcim.models import Site
|
||||
from extras.conditions import Condition, ConditionSet
|
||||
@@ -230,8 +231,7 @@ class ConditionSetTest(TestCase):
|
||||
"""
|
||||
event_rule = EventRule(
|
||||
name='Event Rule 1',
|
||||
type_create=True,
|
||||
type_update=True,
|
||||
event_types=[OBJECT_CREATED, OBJECT_UPDATED],
|
||||
conditions={
|
||||
'attr': 'status.value',
|
||||
'value': 'active',
|
||||
@@ -251,8 +251,7 @@ class ConditionSetTest(TestCase):
|
||||
"""
|
||||
event_rule = EventRule(
|
||||
name='Event Rule 1',
|
||||
type_create=True,
|
||||
type_update=True,
|
||||
event_types=[OBJECT_CREATED, OBJECT_UPDATED],
|
||||
conditions={
|
||||
"attr": "status.value",
|
||||
"value": ["planned", "staging"],
|
||||
@@ -273,8 +272,7 @@ class ConditionSetTest(TestCase):
|
||||
"""
|
||||
event_rule = EventRule(
|
||||
name='Event Rule 1',
|
||||
type_create=True,
|
||||
type_update=True,
|
||||
event_types=[OBJECT_CREATED, OBJECT_UPDATED],
|
||||
conditions={
|
||||
"attr": "status.value",
|
||||
"value": ["planned", "staging"],
|
||||
@@ -300,8 +298,7 @@ class ConditionSetTest(TestCase):
|
||||
webhook = Webhook.objects.create(name='Webhook 100', payload_url='http://example.com/?1', http_method='POST')
|
||||
form = EventRuleForm({
|
||||
"name": "Event Rule 1",
|
||||
"type_create": True,
|
||||
"type_update": True,
|
||||
"event_types": [OBJECT_CREATED, OBJECT_UPDATED],
|
||||
"action_object_type": ct.pk,
|
||||
"action_type": "webhook",
|
||||
"action_choice": webhook.pk,
|
||||
|
||||
@@ -46,22 +46,22 @@ class EventRuleTest(APITestCase):
|
||||
webhook_type = ObjectType.objects.get(app_label='extras', model='webhook')
|
||||
event_rules = EventRule.objects.bulk_create((
|
||||
EventRule(
|
||||
name='Webhook Event 1',
|
||||
type_create=True,
|
||||
name='Event Rule 1',
|
||||
event_types=[OBJECT_CREATED],
|
||||
action_type=EventRuleActionChoices.WEBHOOK,
|
||||
action_object_type=webhook_type,
|
||||
action_object_id=webhooks[0].id
|
||||
),
|
||||
EventRule(
|
||||
name='Webhook Event 2',
|
||||
type_update=True,
|
||||
name='Event Rule 2',
|
||||
event_types=[OBJECT_UPDATED],
|
||||
action_type=EventRuleActionChoices.WEBHOOK,
|
||||
action_object_type=webhook_type,
|
||||
action_object_id=webhooks[0].id
|
||||
),
|
||||
EventRule(
|
||||
name='Webhook Event 3',
|
||||
type_delete=True,
|
||||
name='Event Rule 3',
|
||||
event_types=[OBJECT_DELETED],
|
||||
action_type=EventRuleActionChoices.WEBHOOK,
|
||||
action_object_type=webhook_type,
|
||||
action_object_id=webhooks[0].id
|
||||
@@ -82,8 +82,7 @@ class EventRuleTest(APITestCase):
|
||||
"""
|
||||
event_rule = EventRule(
|
||||
name='Event Rule 1',
|
||||
type_create=True,
|
||||
type_update=True,
|
||||
event_types=[OBJECT_CREATED, OBJECT_UPDATED],
|
||||
conditions={
|
||||
'and': [
|
||||
{
|
||||
@@ -131,7 +130,7 @@ class EventRuleTest(APITestCase):
|
||||
# Verify that a background task was queued for the new object
|
||||
self.assertEqual(self.queue.count, 1)
|
||||
job = self.queue.jobs[0]
|
||||
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(type_create=True))
|
||||
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(name='Event Rule 1'))
|
||||
self.assertEqual(job.kwargs['event_type'], OBJECT_CREATED)
|
||||
self.assertEqual(job.kwargs['model_name'], 'site')
|
||||
self.assertEqual(job.kwargs['data']['id'], response.data['id'])
|
||||
@@ -181,7 +180,7 @@ class EventRuleTest(APITestCase):
|
||||
# Verify that a background task was queued for each new object
|
||||
self.assertEqual(self.queue.count, 3)
|
||||
for i, job in enumerate(self.queue.jobs):
|
||||
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(type_create=True))
|
||||
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(name='Event Rule 1'))
|
||||
self.assertEqual(job.kwargs['event_type'], OBJECT_CREATED)
|
||||
self.assertEqual(job.kwargs['model_name'], 'site')
|
||||
self.assertEqual(job.kwargs['data']['id'], response.data[i]['id'])
|
||||
@@ -212,7 +211,7 @@ class EventRuleTest(APITestCase):
|
||||
# Verify that a background task was queued for the updated object
|
||||
self.assertEqual(self.queue.count, 1)
|
||||
job = self.queue.jobs[0]
|
||||
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(type_update=True))
|
||||
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(name='Event Rule 2'))
|
||||
self.assertEqual(job.kwargs['event_type'], OBJECT_UPDATED)
|
||||
self.assertEqual(job.kwargs['model_name'], 'site')
|
||||
self.assertEqual(job.kwargs['data']['id'], site.pk)
|
||||
@@ -268,7 +267,7 @@ class EventRuleTest(APITestCase):
|
||||
# Verify that a background task was queued for each updated object
|
||||
self.assertEqual(self.queue.count, 3)
|
||||
for i, job in enumerate(self.queue.jobs):
|
||||
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(type_update=True))
|
||||
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(name='Event Rule 2'))
|
||||
self.assertEqual(job.kwargs['event_type'], OBJECT_UPDATED)
|
||||
self.assertEqual(job.kwargs['model_name'], 'site')
|
||||
self.assertEqual(job.kwargs['data']['id'], data[i]['id'])
|
||||
@@ -294,7 +293,7 @@ class EventRuleTest(APITestCase):
|
||||
# Verify that a task was queued for the deleted object
|
||||
self.assertEqual(self.queue.count, 1)
|
||||
job = self.queue.jobs[0]
|
||||
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(type_delete=True))
|
||||
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(name='Event Rule 3'))
|
||||
self.assertEqual(job.kwargs['event_type'], OBJECT_DELETED)
|
||||
self.assertEqual(job.kwargs['model_name'], 'site')
|
||||
self.assertEqual(job.kwargs['data']['id'], site.pk)
|
||||
@@ -327,7 +326,7 @@ class EventRuleTest(APITestCase):
|
||||
# Verify that a background task was queued for each deleted object
|
||||
self.assertEqual(self.queue.count, 3)
|
||||
for i, job in enumerate(self.queue.jobs):
|
||||
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(type_delete=True))
|
||||
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(name='Event Rule 3'))
|
||||
self.assertEqual(job.kwargs['event_type'], OBJECT_DELETED)
|
||||
self.assertEqual(job.kwargs['model_name'], 'site')
|
||||
self.assertEqual(job.kwargs['data']['id'], sites[i].pk)
|
||||
@@ -342,7 +341,7 @@ class EventRuleTest(APITestCase):
|
||||
A dummy implementation of Session.send() to be used for testing.
|
||||
Always returns a 200 HTTP response.
|
||||
"""
|
||||
event = EventRule.objects.get(type_create=True)
|
||||
event = EventRule.objects.get(name='Event Rule 1')
|
||||
webhook = event.action_object
|
||||
signature = generate_signature(request.body, webhook.secret)
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ from django.test import TestCase
|
||||
|
||||
from circuits.models import Provider
|
||||
from core.choices import ManagedFileRootPathChoices, ObjectChangeActionChoices
|
||||
from core.events import *
|
||||
from core.models import ObjectChange, ObjectType
|
||||
from dcim.filtersets import SiteFilterSet
|
||||
from dcim.models import DeviceRole, DeviceType, Manufacturer, Platform, Rack, Region, Site, SiteGroup
|
||||
@@ -251,7 +252,7 @@ class WebhookTestCase(TestCase, BaseFilterSetTests):
|
||||
class EventRuleTestCase(TestCase, BaseFilterSetTests):
|
||||
queryset = EventRule.objects.all()
|
||||
filterset = EventRuleFilterSet
|
||||
ignore_fields = ('action_data', 'conditions')
|
||||
ignore_fields = ('action_data', 'conditions', 'event_types')
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
@@ -292,11 +293,7 @@ class EventRuleTestCase(TestCase, BaseFilterSetTests):
|
||||
name='Event Rule 1',
|
||||
action_object=webhooks[0],
|
||||
enabled=True,
|
||||
type_create=True,
|
||||
type_update=False,
|
||||
type_delete=False,
|
||||
type_job_start=False,
|
||||
type_job_end=False,
|
||||
event_types=[OBJECT_CREATED],
|
||||
action_type=EventRuleActionChoices.WEBHOOK,
|
||||
description='foobar1'
|
||||
),
|
||||
@@ -304,11 +301,7 @@ class EventRuleTestCase(TestCase, BaseFilterSetTests):
|
||||
name='Event Rule 2',
|
||||
action_object=webhooks[1],
|
||||
enabled=True,
|
||||
type_create=False,
|
||||
type_update=True,
|
||||
type_delete=False,
|
||||
type_job_start=False,
|
||||
type_job_end=False,
|
||||
event_types=[OBJECT_UPDATED],
|
||||
action_type=EventRuleActionChoices.WEBHOOK,
|
||||
description='foobar2'
|
||||
),
|
||||
@@ -316,11 +309,7 @@ class EventRuleTestCase(TestCase, BaseFilterSetTests):
|
||||
name='Event Rule 3',
|
||||
action_object=webhooks[2],
|
||||
enabled=False,
|
||||
type_create=False,
|
||||
type_update=False,
|
||||
type_delete=True,
|
||||
type_job_start=False,
|
||||
type_job_end=False,
|
||||
event_types=[OBJECT_DELETED],
|
||||
action_type=EventRuleActionChoices.WEBHOOK,
|
||||
description='foobar3'
|
||||
),
|
||||
@@ -328,22 +317,14 @@ class EventRuleTestCase(TestCase, BaseFilterSetTests):
|
||||
name='Event Rule 4',
|
||||
action_object=scripts[0],
|
||||
enabled=False,
|
||||
type_create=False,
|
||||
type_update=False,
|
||||
type_delete=False,
|
||||
type_job_start=True,
|
||||
type_job_end=False,
|
||||
event_types=[JOB_STARTED],
|
||||
action_type=EventRuleActionChoices.SCRIPT,
|
||||
),
|
||||
EventRule(
|
||||
name='Event Rule 5',
|
||||
action_object=scripts[1],
|
||||
enabled=False,
|
||||
type_create=False,
|
||||
type_update=False,
|
||||
type_delete=False,
|
||||
type_job_start=False,
|
||||
type_job_end=True,
|
||||
event_types=[JOB_COMPLETED],
|
||||
action_type=EventRuleActionChoices.SCRIPT,
|
||||
),
|
||||
)
|
||||
@@ -384,25 +365,9 @@ class EventRuleTestCase(TestCase, BaseFilterSetTests):
|
||||
params = {'enabled': False}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
|
||||
|
||||
def test_type_create(self):
|
||||
params = {'type_create': True}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
|
||||
|
||||
def test_type_update(self):
|
||||
params = {'type_update': True}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
|
||||
|
||||
def test_type_delete(self):
|
||||
params = {'type_delete': True}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
|
||||
|
||||
def test_type_job_start(self):
|
||||
params = {'type_job_start': True}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
|
||||
|
||||
def test_type_job_end(self):
|
||||
params = {'type_job_end': True}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
|
||||
def test_event_type(self):
|
||||
params = {'event_type': [OBJECT_CREATED, OBJECT_UPDATED]}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||
|
||||
|
||||
class CustomLinkTestCase(TestCase, ChangeLoggedFilterSetTests):
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.urls import reverse
|
||||
|
||||
from core.events import *
|
||||
from core.models import ObjectType
|
||||
from dcim.models import DeviceType, Manufacturer, Site
|
||||
from extras.choices import *
|
||||
@@ -394,9 +395,9 @@ class EventRulesTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
|
||||
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]),
|
||||
EventRule(name='EventRule 3', type_create=True, action_object=webhooks[2]),
|
||||
EventRule(name='EventRule 1', event_types=[OBJECT_CREATED], action_object=webhooks[0]),
|
||||
EventRule(name='EventRule 2', event_types=[OBJECT_CREATED], action_object=webhooks[1]),
|
||||
EventRule(name='EventRule 3', event_types=[OBJECT_CREATED], action_object=webhooks[2]),
|
||||
)
|
||||
for event in event_rules:
|
||||
event.save()
|
||||
@@ -406,9 +407,7 @@ class EventRulesTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
cls.form_data = {
|
||||
'name': 'Event X',
|
||||
'object_types': [site_type.pk],
|
||||
'type_create': False,
|
||||
'type_update': True,
|
||||
'type_delete': True,
|
||||
'event_types': [OBJECT_UPDATED, OBJECT_DELETED],
|
||||
'conditions': None,
|
||||
'action_type': 'webhook',
|
||||
'action_object_type': webhook_ct.pk,
|
||||
@@ -418,8 +417,8 @@ class EventRulesTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
}
|
||||
|
||||
cls.csv_data = (
|
||||
"name,object_types,type_create,action_type,action_object",
|
||||
"Webhook 4,dcim.site,True,webhook,Webhook 1",
|
||||
f'name,object_types,event_types,action_type,action_object',
|
||||
f'Webhook 4,dcim.site,"{OBJECT_CREATED},{OBJECT_UPDATED}",webhook,Webhook 1',
|
||||
)
|
||||
|
||||
cls.csv_update_data = (
|
||||
@@ -430,7 +429,7 @@ class EventRulesTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
)
|
||||
|
||||
cls.bulk_edit_data = {
|
||||
'type_update': True,
|
||||
'description': 'New description',
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user