Sfoglia il codice sorgente

Fixes #18222: Include action data from event rule in webhook and custom script data

Jeremy Stretch 1 anno fa
parent
commit
10748edc3a

+ 13 - 1
docs/models/extras/eventrule.md

@@ -10,7 +10,7 @@ See the [event rules documentation](../../features/event-rules.md)  for more inf
 
 
 A unique human-friendly name.
 A unique human-friendly name.
 
 
-### Content Types
+### Object Types
 
 
 The type(s) of object in NetBox that will trigger the rule.
 The type(s) of object in NetBox that will trigger the rule.
 
 
@@ -38,3 +38,15 @@ The event types which will trigger the rule. At least one event type must be sel
 ### Conditions
 ### Conditions
 
 
 A set of [prescribed conditions](../../reference/conditions.md) against which the triggering object will be evaluated. If the conditions are defined but not met by the object, no action will be taken. An event rule that does not define any conditions will _always_ trigger.
 A set of [prescribed conditions](../../reference/conditions.md) against which the triggering object will be evaluated. If the conditions are defined but not met by the object, no action will be taken. An event rule that does not define any conditions will _always_ trigger.
+
+### Action Type
+
+The type of action to take when the rule triggers. This must be one of the following choices:
+
+* Webhook
+* Custom script
+* Notification
+
+### Action Data
+
+An optional dictionary of JSON data to pass when executing the rule. This can be useful to include additional context data, e.g. when transmitting a webhook.

+ 8 - 4
netbox/extras/events.py

@@ -90,6 +90,10 @@ def process_event_rules(event_rules, object_type, event_type, data, username=Non
         if not event_rule.eval_conditions(data):
         if not event_rule.eval_conditions(data):
             continue
             continue
 
 
+        # Compile event data
+        event_data = event_rule.action_data or {}
+        event_data.update(data)
+
         # Webhooks
         # Webhooks
         if event_rule.action_type == EventRuleActionChoices.WEBHOOK:
         if event_rule.action_type == EventRuleActionChoices.WEBHOOK:
 
 
@@ -102,7 +106,7 @@ def process_event_rules(event_rules, object_type, event_type, data, username=Non
                 "event_rule": event_rule,
                 "event_rule": event_rule,
                 "model_name": object_type.model,
                 "model_name": object_type.model,
                 "event_type": event_type,
                 "event_type": event_type,
-                "data": data,
+                "data": event_data,
                 "snapshots": snapshots,
                 "snapshots": snapshots,
                 "timestamp": timezone.now().isoformat(),
                 "timestamp": timezone.now().isoformat(),
                 "username": username,
                 "username": username,
@@ -130,7 +134,7 @@ def process_event_rules(event_rules, object_type, event_type, data, username=Non
                 instance=event_rule.action_object,
                 instance=event_rule.action_object,
                 name=script.name,
                 name=script.name,
                 user=user,
                 user=user,
-                data=data
+                data=event_data
             )
             )
 
 
         # Notification groups
         # Notification groups
@@ -138,8 +142,8 @@ def process_event_rules(event_rules, object_type, event_type, data, username=Non
             # Bulk-create notifications for all members of the notification group
             # Bulk-create notifications for all members of the notification group
             event_rule.action_object.notify(
             event_rule.action_object.notify(
                 object_type=object_type,
                 object_type=object_type,
-                object_id=data['id'],
-                object_repr=data.get('display'),
+                object_id=event_data['id'],
+                object_repr=event_data.get('display'),
                 event_type=event_type
                 event_type=event_type
             )
             )
 
 

+ 13 - 3
netbox/extras/tests/test_event_rules.py

@@ -50,21 +50,24 @@ class EventRuleTest(APITestCase):
                 event_types=[OBJECT_CREATED],
                 event_types=[OBJECT_CREATED],
                 action_type=EventRuleActionChoices.WEBHOOK,
                 action_type=EventRuleActionChoices.WEBHOOK,
                 action_object_type=webhook_type,
                 action_object_type=webhook_type,
-                action_object_id=webhooks[0].id
+                action_object_id=webhooks[0].id,
+                action_data={"foo": 1},
             ),
             ),
             EventRule(
             EventRule(
                 name='Event Rule 2',
                 name='Event Rule 2',
                 event_types=[OBJECT_UPDATED],
                 event_types=[OBJECT_UPDATED],
                 action_type=EventRuleActionChoices.WEBHOOK,
                 action_type=EventRuleActionChoices.WEBHOOK,
                 action_object_type=webhook_type,
                 action_object_type=webhook_type,
-                action_object_id=webhooks[0].id
+                action_object_id=webhooks[0].id,
+                action_data={"foo": 2},
             ),
             ),
             EventRule(
             EventRule(
                 name='Event Rule 3',
                 name='Event Rule 3',
                 event_types=[OBJECT_DELETED],
                 event_types=[OBJECT_DELETED],
                 action_type=EventRuleActionChoices.WEBHOOK,
                 action_type=EventRuleActionChoices.WEBHOOK,
                 action_object_type=webhook_type,
                 action_object_type=webhook_type,
-                action_object_id=webhooks[0].id
+                action_object_id=webhooks[0].id,
+                action_data={"foo": 3},
             ),
             ),
         ))
         ))
         for event_rule in event_rules:
         for event_rule in event_rules:
@@ -134,6 +137,7 @@ class EventRuleTest(APITestCase):
         self.assertEqual(job.kwargs['event_type'], OBJECT_CREATED)
         self.assertEqual(job.kwargs['event_type'], OBJECT_CREATED)
         self.assertEqual(job.kwargs['model_name'], 'site')
         self.assertEqual(job.kwargs['model_name'], 'site')
         self.assertEqual(job.kwargs['data']['id'], response.data['id'])
         self.assertEqual(job.kwargs['data']['id'], response.data['id'])
+        self.assertEqual(job.kwargs['data']['foo'], 1)
         self.assertEqual(len(job.kwargs['data']['tags']), len(response.data['tags']))
         self.assertEqual(len(job.kwargs['data']['tags']), len(response.data['tags']))
         self.assertEqual(job.kwargs['snapshots']['postchange']['name'], 'Site 1')
         self.assertEqual(job.kwargs['snapshots']['postchange']['name'], 'Site 1')
         self.assertEqual(job.kwargs['snapshots']['postchange']['tags'], ['Bar', 'Foo'])
         self.assertEqual(job.kwargs['snapshots']['postchange']['tags'], ['Bar', 'Foo'])
@@ -184,6 +188,7 @@ class EventRuleTest(APITestCase):
             self.assertEqual(job.kwargs['event_type'], OBJECT_CREATED)
             self.assertEqual(job.kwargs['event_type'], OBJECT_CREATED)
             self.assertEqual(job.kwargs['model_name'], 'site')
             self.assertEqual(job.kwargs['model_name'], 'site')
             self.assertEqual(job.kwargs['data']['id'], response.data[i]['id'])
             self.assertEqual(job.kwargs['data']['id'], response.data[i]['id'])
+            self.assertEqual(job.kwargs['data']['foo'], 1)
             self.assertEqual(len(job.kwargs['data']['tags']), len(response.data[i]['tags']))
             self.assertEqual(len(job.kwargs['data']['tags']), len(response.data[i]['tags']))
             self.assertEqual(job.kwargs['snapshots']['postchange']['name'], response.data[i]['name'])
             self.assertEqual(job.kwargs['snapshots']['postchange']['name'], response.data[i]['name'])
             self.assertEqual(job.kwargs['snapshots']['postchange']['tags'], ['Bar', 'Foo'])
             self.assertEqual(job.kwargs['snapshots']['postchange']['tags'], ['Bar', 'Foo'])
@@ -215,6 +220,7 @@ class EventRuleTest(APITestCase):
         self.assertEqual(job.kwargs['event_type'], OBJECT_UPDATED)
         self.assertEqual(job.kwargs['event_type'], OBJECT_UPDATED)
         self.assertEqual(job.kwargs['model_name'], 'site')
         self.assertEqual(job.kwargs['model_name'], 'site')
         self.assertEqual(job.kwargs['data']['id'], site.pk)
         self.assertEqual(job.kwargs['data']['id'], site.pk)
+        self.assertEqual(job.kwargs['data']['foo'], 2)
         self.assertEqual(len(job.kwargs['data']['tags']), len(response.data['tags']))
         self.assertEqual(len(job.kwargs['data']['tags']), len(response.data['tags']))
         self.assertEqual(job.kwargs['snapshots']['prechange']['name'], 'Site 1')
         self.assertEqual(job.kwargs['snapshots']['prechange']['name'], 'Site 1')
         self.assertEqual(job.kwargs['snapshots']['prechange']['tags'], ['Bar', 'Foo'])
         self.assertEqual(job.kwargs['snapshots']['prechange']['tags'], ['Bar', 'Foo'])
@@ -271,6 +277,7 @@ class EventRuleTest(APITestCase):
             self.assertEqual(job.kwargs['event_type'], OBJECT_UPDATED)
             self.assertEqual(job.kwargs['event_type'], OBJECT_UPDATED)
             self.assertEqual(job.kwargs['model_name'], 'site')
             self.assertEqual(job.kwargs['model_name'], 'site')
             self.assertEqual(job.kwargs['data']['id'], data[i]['id'])
             self.assertEqual(job.kwargs['data']['id'], data[i]['id'])
+            self.assertEqual(job.kwargs['data']['foo'], 2)
             self.assertEqual(len(job.kwargs['data']['tags']), len(response.data[i]['tags']))
             self.assertEqual(len(job.kwargs['data']['tags']), len(response.data[i]['tags']))
             self.assertEqual(job.kwargs['snapshots']['prechange']['name'], sites[i].name)
             self.assertEqual(job.kwargs['snapshots']['prechange']['name'], sites[i].name)
             self.assertEqual(job.kwargs['snapshots']['prechange']['tags'], ['Bar', 'Foo'])
             self.assertEqual(job.kwargs['snapshots']['prechange']['tags'], ['Bar', 'Foo'])
@@ -297,6 +304,7 @@ class EventRuleTest(APITestCase):
         self.assertEqual(job.kwargs['event_type'], OBJECT_DELETED)
         self.assertEqual(job.kwargs['event_type'], OBJECT_DELETED)
         self.assertEqual(job.kwargs['model_name'], 'site')
         self.assertEqual(job.kwargs['model_name'], 'site')
         self.assertEqual(job.kwargs['data']['id'], site.pk)
         self.assertEqual(job.kwargs['data']['id'], site.pk)
+        self.assertEqual(job.kwargs['data']['foo'], 3)
         self.assertEqual(job.kwargs['snapshots']['prechange']['name'], 'Site 1')
         self.assertEqual(job.kwargs['snapshots']['prechange']['name'], 'Site 1')
         self.assertEqual(job.kwargs['snapshots']['prechange']['tags'], ['Bar', 'Foo'])
         self.assertEqual(job.kwargs['snapshots']['prechange']['tags'], ['Bar', 'Foo'])
 
 
@@ -330,6 +338,7 @@ class EventRuleTest(APITestCase):
             self.assertEqual(job.kwargs['event_type'], OBJECT_DELETED)
             self.assertEqual(job.kwargs['event_type'], OBJECT_DELETED)
             self.assertEqual(job.kwargs['model_name'], 'site')
             self.assertEqual(job.kwargs['model_name'], 'site')
             self.assertEqual(job.kwargs['data']['id'], sites[i].pk)
             self.assertEqual(job.kwargs['data']['id'], sites[i].pk)
+            self.assertEqual(job.kwargs['data']['foo'], 3)
             self.assertEqual(job.kwargs['snapshots']['prechange']['name'], sites[i].name)
             self.assertEqual(job.kwargs['snapshots']['prechange']['name'], sites[i].name)
             self.assertEqual(job.kwargs['snapshots']['prechange']['tags'], ['Bar', 'Foo'])
             self.assertEqual(job.kwargs['snapshots']['prechange']['tags'], ['Bar', 'Foo'])
 
 
@@ -358,6 +367,7 @@ class EventRuleTest(APITestCase):
             self.assertEqual(body['username'], 'testuser')
             self.assertEqual(body['username'], 'testuser')
             self.assertEqual(body['request_id'], str(request_id))
             self.assertEqual(body['request_id'], str(request_id))
             self.assertEqual(body['data']['name'], 'Site 1')
             self.assertEqual(body['data']['name'], 'Site 1')
+            self.assertEqual(body['data']['foo'], 1)
 
 
             return HttpResponse()
             return HttpResponse()