Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading