Преглед изворни кода

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

Jeremy Stretch пре 1 година
родитељ
комит
10748edc3a
3 измењених фајлова са 34 додато и 8 уклоњено
  1. 13 1
      docs/models/extras/eventrule.md
  2. 8 4
      netbox/extras/events.py
  3. 13 3
      netbox/extras/tests/test_event_rules.py

+ 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.
 
-### Content Types
+### Object Types
 
 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
 
 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):
             continue
 
+        # Compile event data
+        event_data = event_rule.action_data or {}
+        event_data.update(data)
+
         # Webhooks
         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,
                 "model_name": object_type.model,
                 "event_type": event_type,
-                "data": data,
+                "data": event_data,
                 "snapshots": snapshots,
                 "timestamp": timezone.now().isoformat(),
                 "username": username,
@@ -130,7 +134,7 @@ def process_event_rules(event_rules, object_type, event_type, data, username=Non
                 instance=event_rule.action_object,
                 name=script.name,
                 user=user,
-                data=data
+                data=event_data
             )
 
         # 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
             event_rule.action_object.notify(
                 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
             )
 

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

@@ -50,21 +50,24 @@ class EventRuleTest(APITestCase):
                 event_types=[OBJECT_CREATED],
                 action_type=EventRuleActionChoices.WEBHOOK,
                 action_object_type=webhook_type,
-                action_object_id=webhooks[0].id
+                action_object_id=webhooks[0].id,
+                action_data={"foo": 1},
             ),
             EventRule(
                 name='Event Rule 2',
                 event_types=[OBJECT_UPDATED],
                 action_type=EventRuleActionChoices.WEBHOOK,
                 action_object_type=webhook_type,
-                action_object_id=webhooks[0].id
+                action_object_id=webhooks[0].id,
+                action_data={"foo": 2},
             ),
             EventRule(
                 name='Event Rule 3',
                 event_types=[OBJECT_DELETED],
                 action_type=EventRuleActionChoices.WEBHOOK,
                 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:
@@ -134,6 +137,7 @@ class EventRuleTest(APITestCase):
         self.assertEqual(job.kwargs['event_type'], OBJECT_CREATED)
         self.assertEqual(job.kwargs['model_name'], 'site')
         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(job.kwargs['snapshots']['postchange']['name'], 'Site 1')
         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['model_name'], 'site')
             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(job.kwargs['snapshots']['postchange']['name'], response.data[i]['name'])
             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['model_name'], 'site')
         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(job.kwargs['snapshots']['prechange']['name'], 'Site 1')
         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['model_name'], 'site')
             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(job.kwargs['snapshots']['prechange']['name'], sites[i].name)
             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['model_name'], 'site')
         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']['tags'], ['Bar', 'Foo'])
 
@@ -330,6 +338,7 @@ class EventRuleTest(APITestCase):
             self.assertEqual(job.kwargs['event_type'], OBJECT_DELETED)
             self.assertEqual(job.kwargs['model_name'], 'site')
             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']['tags'], ['Bar', 'Foo'])
 
@@ -358,6 +367,7 @@ class EventRuleTest(APITestCase):
             self.assertEqual(body['username'], 'testuser')
             self.assertEqual(body['request_id'], str(request_id))
             self.assertEqual(body['data']['name'], 'Site 1')
+            self.assertEqual(body['data']['foo'], 1)
 
             return HttpResponse()