Skip to content

Commit

Permalink
Fixes #18222: Include action data from event rule in webhook and cust…
Browse files Browse the repository at this point in the history
…om script data
  • Loading branch information
jeremystretch committed Dec 27, 2024
1 parent 1691713 commit d667644
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 8 deletions.
14 changes: 13 additions & 1 deletion docs/models/extras/eventrule.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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.
12 changes: 8 additions & 4 deletions netbox/extras/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -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,
Expand Down Expand Up @@ -130,16 +134,16 @@ 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
elif event_rule.action_type == EventRuleActionChoices.NOTIFICATION:
# 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
)

Expand Down
16 changes: 13 additions & 3 deletions netbox/extras/tests/test_event_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,24 @@ def setUpTestData(cls):
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:
Expand Down Expand Up @@ -134,6 +137,7 @@ def test_single_create_process_eventrule(self):
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'])
Expand Down Expand Up @@ -184,6 +188,7 @@ def test_bulk_create_process_eventrule(self):
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'])
Expand Down Expand Up @@ -215,6 +220,7 @@ def test_single_update_process_eventrule(self):
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'])
Expand Down Expand Up @@ -271,6 +277,7 @@ def test_bulk_update_process_eventrule(self):
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'])
Expand All @@ -297,6 +304,7 @@ def test_single_delete_process_eventrule(self):
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'])

Expand Down Expand Up @@ -330,6 +338,7 @@ def test_bulk_delete_process_eventrule(self):
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'])

Expand Down Expand Up @@ -358,6 +367,7 @@ def dummy_send(_, request, **kwargs):
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()

Expand Down

0 comments on commit d667644

Please sign in to comment.