1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

14132 Add EventRule - change webhook and add in script processing to events (#14267)

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit is contained in:
Arthur Hanson
2023-11-30 13:36:33 -08:00
committed by GitHub
parent b83fcc6077
commit a38a38218b
55 changed files with 1569 additions and 589 deletions

View File

@@ -8,6 +8,7 @@ from rest_framework import status
from core.choices import ManagedFileRootPathChoices
from dcim.models import Device, DeviceRole, DeviceType, Manufacturer, Rack, Location, RackRole, Site
from extras.choices import *
from extras.models import *
from extras.reports import Report
from extras.scripts import BooleanVar, IntegerVar, Script, StringVar
@@ -32,21 +33,15 @@ class WebhookTest(APIViewTestCases.APIViewTestCase):
brief_fields = ['display', 'id', 'name', 'url']
create_data = [
{
'content_types': ['dcim.device', 'dcim.devicetype'],
'name': 'Webhook 4',
'type_create': True,
'payload_url': 'http://example.com/?4',
},
{
'content_types': ['dcim.device', 'dcim.devicetype'],
'name': 'Webhook 5',
'type_update': True,
'payload_url': 'http://example.com/?5',
},
{
'content_types': ['dcim.device', 'dcim.devicetype'],
'name': 'Webhook 6',
'type_delete': True,
'payload_url': 'http://example.com/?6',
},
]
@@ -56,29 +51,100 @@ class WebhookTest(APIViewTestCases.APIViewTestCase):
@classmethod
def setUpTestData(cls):
site_ct = ContentType.objects.get_for_model(Site)
rack_ct = ContentType.objects.get_for_model(Rack)
webhooks = (
Webhook(
name='Webhook 1',
type_create=True,
payload_url='http://example.com/?1',
),
Webhook(
name='Webhook 2',
type_update=True,
payload_url='http://example.com/?1',
),
Webhook(
name='Webhook 3',
type_delete=True,
payload_url='http://example.com/?1',
),
)
Webhook.objects.bulk_create(webhooks)
for webhook in webhooks:
webhook.content_types.add(site_ct, rack_ct)
class EventRuleTest(APIViewTestCases.APIViewTestCase):
model = EventRule
brief_fields = ['display', 'id', 'name', 'url']
bulk_update_data = {
'enabled': False,
'description': 'New description',
}
update_data = {
'name': 'Event Rule X',
'enabled': False,
'description': 'New description',
}
@classmethod
def setUpTestData(cls):
webhooks = (
Webhook(
name='Webhook 1',
payload_url='http://example.com/?1',
),
Webhook(
name='Webhook 2',
payload_url='http://example.com/?1',
),
Webhook(
name='Webhook 3',
payload_url='http://example.com/?1',
),
Webhook(
name='Webhook 4',
payload_url='http://example.com/?1',
),
Webhook(
name='Webhook 5',
payload_url='http://example.com/?1',
),
Webhook(
name='Webhook 6',
payload_url='http://example.com/?1',
),
)
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.objects.bulk_create(event_rules)
cls.create_data = [
{
'name': 'EventRule 4',
'content_types': ['dcim.device', 'dcim.devicetype'],
'type_create': True,
'action_type': EventRuleActionChoices.WEBHOOK,
'action_object_type': 'extras.webhook',
'action_object_id': webhooks[3].pk,
},
{
'name': 'EventRule 5',
'content_types': ['dcim.device', 'dcim.devicetype'],
'type_create': True,
'action_type': EventRuleActionChoices.WEBHOOK,
'action_object_type': 'extras.webhook',
'action_object_id': webhooks[4].pk,
},
{
'name': 'EventRule 6',
'content_types': ['dcim.device', 'dcim.devicetype'],
'type_create': True,
'action_type': EventRuleActionChoices.WEBHOOK,
'action_object_type': 'extras.webhook',
'action_object_id': webhooks[5].pk,
},
]
class CustomFieldTest(APIViewTestCases.APIViewTestCase):

View File

@@ -3,22 +3,22 @@ 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 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
from extras.webhooks_worker import process_webhook
from requests import Session
from rest_framework import status
from dcim.choices import SiteStatusChoices
from dcim.models import Site
from extras.choices import ObjectChangeActionChoices
from extras.models import Tag, Webhook
from extras.webhooks import enqueue_object, flush_webhooks, generate_signature, serialize_for_webhook
from extras.webhooks_worker import eval_conditions, process_webhook
from utilities.testing import APITestCase
class WebhookTest(APITestCase):
class EventRuleTest(APITestCase):
def setUp(self):
super().setUp()
@@ -35,12 +35,37 @@ class WebhookTest(APITestCase):
DUMMY_SECRET = 'LOOKATMEIMASECRETSTRING'
webhooks = Webhook.objects.bulk_create((
Webhook(name='Webhook 1', type_create=True, payload_url=DUMMY_URL, secret=DUMMY_SECRET, additional_headers='X-Foo: Bar'),
Webhook(name='Webhook 2', type_update=True, payload_url=DUMMY_URL, secret=DUMMY_SECRET),
Webhook(name='Webhook 3', type_delete=True, payload_url=DUMMY_URL, secret=DUMMY_SECRET),
Webhook(name='Webhook 1', payload_url=DUMMY_URL, secret=DUMMY_SECRET, additional_headers='X-Foo: Bar'),
Webhook(name='Webhook 2', payload_url=DUMMY_URL, secret=DUMMY_SECRET),
Webhook(name='Webhook 3', payload_url=DUMMY_URL, secret=DUMMY_SECRET),
))
for webhook in webhooks:
webhook.content_types.set([site_ct])
ct = ContentType.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_id=webhooks[0].id
),
EventRule(
name='Webhook Event 2',
type_update=True,
action_type=EventRuleActionChoices.WEBHOOK,
action_object_type=ct,
action_object_id=webhooks[0].id
),
EventRule(
name='Webhook Event 3',
type_delete=True,
action_type=EventRuleActionChoices.WEBHOOK,
action_object_type=ct,
action_object_id=webhooks[0].id
),
))
for event_rule in event_rules:
event_rule.content_types.set([site_ct])
Tag.objects.bulk_create((
Tag(name='Foo', slug='foo'),
@@ -48,7 +73,42 @@ class WebhookTest(APITestCase):
Tag(name='Baz', slug='baz'),
))
def test_enqueue_webhook_create(self):
def test_eventrule_conditions(self):
"""
Test evaluation of EventRule conditions.
"""
event_rule = EventRule(
name='Event Rule 1',
type_create=True,
type_update=True,
conditions={
'and': [
{
'attr': 'status.value',
'value': 'active',
}
]
}
)
# Create a Site to evaluate
site = Site.objects.create(name='Site 1', slug='site-1', status=SiteStatusChoices.STATUS_STAGING)
data = serialize_for_event(site)
# Evaluate the conditions (status='staging')
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(event_rule.eval_conditions(data))
def test_single_create_process_eventrule(self):
"""
Check that creating an object with an applicable EventRule queues a background task for the rule's action.
"""
# Create an object via the REST API
data = {
'name': 'Site 1',
@@ -65,10 +125,10 @@ class WebhookTest(APITestCase):
self.assertEqual(Site.objects.count(), 1)
self.assertEqual(Site.objects.first().tags.count(), 2)
# Verify that a job was queued for the object creation webhook
# 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['webhook'], Webhook.objects.get(type_create=True))
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(type_create=True))
self.assertEqual(job.kwargs['event'], ObjectChangeActionChoices.ACTION_CREATE)
self.assertEqual(job.kwargs['model_name'], 'site')
self.assertEqual(job.kwargs['data']['id'], response.data['id'])
@@ -76,7 +136,11 @@ class WebhookTest(APITestCase):
self.assertEqual(job.kwargs['snapshots']['postchange']['name'], 'Site 1')
self.assertEqual(job.kwargs['snapshots']['postchange']['tags'], ['Bar', 'Foo'])
def test_enqueue_webhook_bulk_create(self):
def test_bulk_create_process_eventrule(self):
"""
Check that bulk creating multiple objects with an applicable EventRule queues a background task for each
new object.
"""
# Create multiple objects via the REST API
data = [
{
@@ -111,10 +175,10 @@ class WebhookTest(APITestCase):
self.assertEqual(Site.objects.count(), 3)
self.assertEqual(Site.objects.first().tags.count(), 2)
# Verify that a webhook was queued for each object
# 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['webhook'], Webhook.objects.get(type_create=True))
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(type_create=True))
self.assertEqual(job.kwargs['event'], ObjectChangeActionChoices.ACTION_CREATE)
self.assertEqual(job.kwargs['model_name'], 'site')
self.assertEqual(job.kwargs['data']['id'], response.data[i]['id'])
@@ -122,7 +186,10 @@ class WebhookTest(APITestCase):
self.assertEqual(job.kwargs['snapshots']['postchange']['name'], response.data[i]['name'])
self.assertEqual(job.kwargs['snapshots']['postchange']['tags'], ['Bar', 'Foo'])
def test_enqueue_webhook_update(self):
def test_single_update_process_eventrule(self):
"""
Check that updating an object with an applicable EventRule queues a background task for the rule's action.
"""
site = Site.objects.create(name='Site 1', slug='site-1')
site.tags.set(Tag.objects.filter(name__in=['Foo', 'Bar']))
@@ -139,10 +206,10 @@ class WebhookTest(APITestCase):
response = self.client.patch(url, data, format='json', **self.header)
self.assertHttpStatus(response, status.HTTP_200_OK)
# Verify that a job was queued for the object update webhook
# 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['webhook'], Webhook.objects.get(type_update=True))
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(type_update=True))
self.assertEqual(job.kwargs['event'], ObjectChangeActionChoices.ACTION_UPDATE)
self.assertEqual(job.kwargs['model_name'], 'site')
self.assertEqual(job.kwargs['data']['id'], site.pk)
@@ -152,7 +219,11 @@ class WebhookTest(APITestCase):
self.assertEqual(job.kwargs['snapshots']['postchange']['name'], 'Site X')
self.assertEqual(job.kwargs['snapshots']['postchange']['tags'], ['Baz'])
def test_enqueue_webhook_bulk_update(self):
def test_bulk_update_process_eventrule(self):
"""
Check that bulk updating multiple objects with an applicable EventRule queues a background task for each
updated object.
"""
sites = (
Site(name='Site 1', slug='site-1'),
Site(name='Site 2', slug='site-2'),
@@ -191,10 +262,10 @@ class WebhookTest(APITestCase):
response = self.client.patch(url, data, format='json', **self.header)
self.assertHttpStatus(response, status.HTTP_200_OK)
# Verify that a job was queued for the object update webhook
# 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['webhook'], Webhook.objects.get(type_update=True))
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(type_update=True))
self.assertEqual(job.kwargs['event'], ObjectChangeActionChoices.ACTION_UPDATE)
self.assertEqual(job.kwargs['model_name'], 'site')
self.assertEqual(job.kwargs['data']['id'], data[i]['id'])
@@ -204,7 +275,10 @@ class WebhookTest(APITestCase):
self.assertEqual(job.kwargs['snapshots']['postchange']['name'], response.data[i]['name'])
self.assertEqual(job.kwargs['snapshots']['postchange']['tags'], ['Baz'])
def test_enqueue_webhook_delete(self):
def test_single_delete_process_eventrule(self):
"""
Check that deleting an object with an applicable EventRule queues a background task for the rule's action.
"""
site = Site.objects.create(name='Site 1', slug='site-1')
site.tags.set(Tag.objects.filter(name__in=['Foo', 'Bar']))
@@ -214,17 +288,21 @@ class WebhookTest(APITestCase):
response = self.client.delete(url, **self.header)
self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT)
# Verify that a job was queued for the object update webhook
# 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['webhook'], Webhook.objects.get(type_delete=True))
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(type_delete=True))
self.assertEqual(job.kwargs['event'], ObjectChangeActionChoices.ACTION_DELETE)
self.assertEqual(job.kwargs['model_name'], 'site')
self.assertEqual(job.kwargs['data']['id'], site.pk)
self.assertEqual(job.kwargs['snapshots']['prechange']['name'], 'Site 1')
self.assertEqual(job.kwargs['snapshots']['prechange']['tags'], ['Bar', 'Foo'])
def test_enqueue_webhook_bulk_delete(self):
def test_bulk_delete_process_eventrule(self):
"""
Check that bulk deleting multiple objects with an applicable EventRule queues a background task for each
deleted object.
"""
sites = (
Site(name='Site 1', slug='site-1'),
Site(name='Site 2', slug='site-2'),
@@ -243,49 +321,17 @@ class WebhookTest(APITestCase):
response = self.client.delete(url, data, format='json', **self.header)
self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT)
# Verify that a job was queued for the object update webhook
# 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['webhook'], Webhook.objects.get(type_delete=True))
self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(type_delete=True))
self.assertEqual(job.kwargs['event'], ObjectChangeActionChoices.ACTION_DELETE)
self.assertEqual(job.kwargs['model_name'], 'site')
self.assertEqual(job.kwargs['data']['id'], sites[i].pk)
self.assertEqual(job.kwargs['snapshots']['prechange']['name'], sites[i].name)
self.assertEqual(job.kwargs['snapshots']['prechange']['tags'], ['Bar', 'Foo'])
def test_webhook_conditions(self):
# Create a conditional Webhook
webhook = Webhook(
name='Conditional Webhook',
type_create=True,
type_update=True,
payload_url='http://localhost:9000/',
conditions={
'and': [
{
'attr': 'status.value',
'value': 'active',
}
]
}
)
# Create a Site to evaluate
site = Site.objects.create(name='Site 1', slug='site-1', status=SiteStatusChoices.STATUS_STAGING)
data = serialize_for_webhook(site)
# Evaluate the conditions (status='staging')
self.assertFalse(eval_conditions(webhook, data))
# Change the site's status
site.status = SiteStatusChoices.STATUS_ACTIVE
data = serialize_for_webhook(site)
# Evaluate the conditions (status='active')
self.assertTrue(eval_conditions(webhook, data))
def test_webhooks_worker(self):
request_id = uuid.uuid4()
def dummy_send(_, request, **kwargs):
@@ -293,7 +339,8 @@ class WebhookTest(APITestCase):
A dummy implementation of Session.send() to be used for testing.
Always returns a 200 HTTP response.
"""
webhook = Webhook.objects.get(type_create=True)
event = EventRule.objects.get(type_create=True)
webhook = event.action_object
signature = generate_signature(request.body, webhook.secret)
# Validate the outgoing request headers
@@ -322,7 +369,7 @@ class WebhookTest(APITestCase):
request_id=request_id,
action=ObjectChangeActionChoices.ACTION_CREATE
)
flush_webhooks(webhooks_queue)
flush_events(webhooks_queue)
# Retrieve the job from queue
job = self.queue.jobs[0]

View File

@@ -6,6 +6,7 @@ from django.contrib.contenttypes.models import ContentType
from django.test import TestCase
from circuits.models import Provider
from core.choices import ManagedFileRootPathChoices
from dcim.filtersets import SiteFilterSet
from dcim.models import DeviceRole, DeviceType, Manufacturer, Platform, Rack, Region, Site, SiteGroup
from dcim.models import Location
@@ -159,82 +160,174 @@ class WebhookTestCase(TestCase, BaseFilterSetTests):
webhooks = (
Webhook(
name='Webhook 1',
type_create=True,
type_update=False,
type_delete=False,
type_job_start=False,
type_job_end=False,
payload_url='http://example.com/?1',
enabled=True,
http_method='GET',
ssl_verification=True,
),
Webhook(
name='Webhook 2',
type_create=False,
type_update=True,
type_delete=False,
type_job_start=False,
type_job_end=False,
payload_url='http://example.com/?2',
enabled=True,
http_method='POST',
ssl_verification=True,
),
Webhook(
name='Webhook 3',
type_create=False,
type_update=False,
type_delete=True,
type_job_start=False,
type_job_end=False,
payload_url='http://example.com/?3',
enabled=False,
http_method='PATCH',
ssl_verification=False,
),
Webhook(
name='Webhook 4',
type_create=False,
type_update=False,
type_delete=False,
type_job_start=True,
type_job_end=False,
payload_url='http://example.com/?4',
enabled=False,
http_method='PATCH',
ssl_verification=False,
),
Webhook(
name='Webhook 5',
type_create=False,
type_update=False,
type_delete=False,
type_job_start=False,
type_job_end=True,
payload_url='http://example.com/?5',
enabled=False,
http_method='PATCH',
ssl_verification=False,
),
)
Webhook.objects.bulk_create(webhooks)
webhooks[0].content_types.add(content_types[0])
webhooks[1].content_types.add(content_types[1])
webhooks[2].content_types.add(content_types[2])
webhooks[3].content_types.add(content_types[3])
webhooks[4].content_types.add(content_types[4])
def test_name(self):
params = {'name': ['Webhook 1', 'Webhook 2']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_http_method(self):
params = {'http_method': ['GET', 'POST']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_ssl_verification(self):
params = {'ssl_verification': True}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
class EventRuleTestCase(TestCase, BaseFilterSetTests):
queryset = EventRule.objects.all()
filterset = EventRuleFilterSet
@classmethod
def setUpTestData(cls):
content_types = ContentType.objects.filter(
model__in=['region', 'site', 'rack', 'location', 'device']
)
webhooks = (
Webhook(
name='Webhook 1',
payload_url='http://example.com/?1',
),
Webhook(
name='Webhook 2',
payload_url='http://example.com/?2',
),
Webhook(
name='Webhook 3',
payload_url='http://example.com/?3',
),
)
Webhook.objects.bulk_create(webhooks)
scripts = (
ScriptModule(
file_root=ManagedFileRootPathChoices.SCRIPTS,
file_path='/var/tmp/script1.py'
),
ScriptModule(
file_root=ManagedFileRootPathChoices.SCRIPTS,
file_path='/var/tmp/script2.py'
),
)
ScriptModule.objects.bulk_create(scripts)
event_rules = (
EventRule(
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,
action_type=EventRuleActionChoices.WEBHOOK,
),
EventRule(
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,
action_type=EventRuleActionChoices.WEBHOOK,
),
EventRule(
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,
action_type=EventRuleActionChoices.WEBHOOK,
),
EventRule(
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,
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,
action_type=EventRuleActionChoices.SCRIPT,
),
)
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])
def test_name(self):
params = {'name': ['Event Rule 1', 'Event Rule 2']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_content_types(self):
params = {'content_types': 'dcim.region'}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
params = {'content_type_id': [ContentType.objects.get_for_model(Region).pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
def test_action_type(self):
params = {'action_type': [EventRuleActionChoices.WEBHOOK]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
params = {'action_type': [EventRuleActionChoices.SCRIPT]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_enabled(self):
params = {'enabled': True}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
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)
@@ -255,18 +348,6 @@ class WebhookTestCase(TestCase, BaseFilterSetTests):
params = {'type_job_end': True}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
def test_enabled(self):
params = {'enabled': True}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_http_method(self):
params = {'http_method': ['GET', 'POST']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_ssl_verification(self):
params = {'ssl_verification': True}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
class CustomLinkTestCase(TestCase, BaseFilterSetTests):
queryset = CustomLink.objects.all()

View File

@@ -1,4 +1,3 @@
import json
import urllib.parse
import uuid
@@ -11,7 +10,6 @@ from extras.choices import *
from extras.models import *
from utilities.testing import ViewTestCases, TestCase
User = get_user_model()
@@ -336,33 +334,26 @@ class WebhookTestCase(ViewTestCases.PrimaryObjectViewTestCase):
@classmethod
def setUpTestData(cls):
site_ct = ContentType.objects.get_for_model(Site)
webhooks = (
Webhook(name='Webhook 1', payload_url='http://example.com/?1', type_create=True, http_method='POST'),
Webhook(name='Webhook 2', payload_url='http://example.com/?2', type_create=True, http_method='POST'),
Webhook(name='Webhook 3', payload_url='http://example.com/?3', type_create=True, http_method='POST'),
Webhook(name='Webhook 1', payload_url='http://example.com/?1', http_method='POST'),
Webhook(name='Webhook 2', payload_url='http://example.com/?2', http_method='POST'),
Webhook(name='Webhook 3', payload_url='http://example.com/?3', http_method='POST'),
)
for webhook in webhooks:
webhook.save()
webhook.content_types.add(site_ct)
cls.form_data = {
'name': 'Webhook X',
'content_types': [site_ct.pk],
'type_create': False,
'type_update': True,
'type_delete': True,
'payload_url': 'http://example.com/?x',
'http_method': 'GET',
'http_content_type': 'application/foo',
'conditions': None,
}
cls.csv_data = (
"name,content_types,type_create,payload_url,http_method,http_content_type",
"Webhook 4,dcim.site,True,http://example.com/?4,GET,application/json",
"Webhook 5,dcim.site,True,http://example.com/?5,GET,application/json",
"Webhook 6,dcim.site,True,http://example.com/?6,GET,application/json",
"name,payload_url,http_method,http_content_type",
"Webhook 4,http://example.com/?4,GET,application/json",
"Webhook 5,http://example.com/?5,GET,application/json",
"Webhook 6,http://example.com/?6,GET,application/json",
)
cls.csv_update_data = (
@@ -373,11 +364,62 @@ class WebhookTestCase(ViewTestCases.PrimaryObjectViewTestCase):
)
cls.bulk_edit_data = {
'enabled': False,
'http_method': 'GET',
}
class EventRulesTestCase(ViewTestCases.PrimaryObjectViewTestCase):
model = EventRule
@classmethod
def setUpTestData(cls):
webhooks = (
Webhook(name='Webhook 1', payload_url='http://example.com/?1', http_method='POST'),
Webhook(name='Webhook 2', payload_url='http://example.com/?2', http_method='POST'),
Webhook(name='Webhook 3', payload_url='http://example.com/?3', http_method='POST'),
)
for webhook in webhooks:
webhook.save()
site_ct = ContentType.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]),
)
for event in event_rules:
event.save()
event.content_types.add(site_ct)
webhook_ct = ContentType.objects.get_for_model(Webhook)
cls.form_data = {
'name': 'Event X',
'content_types': [site_ct.pk],
'type_create': False,
'type_update': True,
'type_delete': True,
'http_method': 'GET',
'conditions': None,
'action_type': 'webhook',
'action_object_type': webhook_ct.pk,
'action_object_id': webhooks[0].pk,
'action_choice': webhooks[0]
}
cls.csv_data = (
"name,content_types,type_create,action_type,action_object",
"Webhook 4,dcim.site,True,webhook,Webhook 1",
)
cls.csv_update_data = (
"id,name",
f"{event_rules[0].pk},Event 7",
f"{event_rules[1].pk},Event 8",
f"{event_rules[2].pk},Event 9",
)
cls.bulk_edit_data = {
'type_update': True,
}