-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Erroneous invocations of Event Rules/Webhooks with M2M relationships #15194
Comments
Update: I created a rather simple fix for this, so if this bug gets accepted I can provide a PR. develop...peteeckel:netbox:15194-fix-duplicate-webhook-invocations |
With the patch in place, the webhook is triggered only once and correctly (same operation as above): [1] Wed, 21 Feb 2024 17:51:32 GMT 127.0.0.1 "POST / HTTP/1.1" 200 -
Host: localhost:9000
Accept-Encoding: identity
User-Agent: python-urllib3/2.1.0
Content-Type: application/json
Content-Length: 770
{
"event": "updated",
"timestamp": "2024-02-21T17:51:32.797105+00:00",
"model": "testzone",
"username": "admin",
"request_id": "df1ea10d-a772-481c-ba6e-054f612c6ec8",
"data": {
"id": 1,
"name": "zone1.example.com",
"nameservers": [
{
"id": 1,
"name": "ns1.example.com",
"url": "/api/plugins/netbox_test/test-name-servers/1/",
"display": "ns1.example.com"
}
],
"url": "/api/plugins/netbox_test/test-zones/1/",
"display": "zone1.example.com"
},
"snapshots": {
"prechange": {
"created": "2024-02-20T09:52:48.981Z",
"name": "zone1.example.com",
"nameservers": [
2,
1
],
"custom_fields": {},
"tags": []
},
"postchange": {
"created": "2024-02-20T09:52:48.981Z",
"last_updated": "2024-02-21T17:51:32.736Z",
"name": "zone1.example.com",
"nameservers": [
1
],
"custom_fields": {},
"tags": []
}
}
}
Completed request #1
------------ |
@peteeckel please go ahead and create a PR. Apologies for the delay. |
During testing I found that this is unfortunately not limited to M2M changes. Repeated |
Deployment Type
Self-hosted
Software Versions
feature
branchDescription
This is probably the most obscure issue I've filed for a long time, so I apologise up front for the difficulties in reproducing it. I did my best to minimise it, but "minimise" in that case means "bring it down to a really involved scenario with non-obvious circumstances". Nevertheless, it's a real issue and it finds one consequence in this issue for the NetBox DNS plugin.
In fact, after some analysis I could trace it down to a very specific situation: There is a problem with incorrectly created Webhooks when an M2M field is updated and the
save()
function of one of the models involved in the M2M relation causes othersave()
operations to occur aftersuper().save()
. This results in multiple invocations of a Webhook (or, in NetBox >= 4.0, an Event Rule) defined for that model, where the first invocation has wrong data.Steps to reproduce
(this is where trouble starts)
To make reprocuing the issue easier, I created a test plugin that is a very stripped down version of the NetBox DNS plugin. The code can be found on GitHub.
feature
trackpip3
install:/<netbox install path>/netbox/netbox/configuration.py
, run the migration and restart:nbshell
:update
events for thenetbox_test.TestZone
object type triggering the Webhook:zone1.example.com
by adding one or two of the defined test name servers in the GUI and watch the test listener. It's crucial that this is done in the GUI! The result should be similar to this:/<install dir>/netbox-plugin-test/netbox_test/models.py
, adding the following code to theTestZone
model class:ns2.example.com
. The resulting output of the test listener is now this:And that is the problem. Two invocations of the Webhook occur, of which the first one has the wrong data (still both
TestNameServer
entries are listed), the second one is correct.For this to occur it's not important that the object saved in the customised
save()
operation is aTestNameServer
, any NetBox object class will do. The only thing that is relevant to the issue is that anysave()
operation for a different object type occurs within thesave()
method aftersuper().save()
was invoked.Analysis
I tracked down the cause of this issue to the NetBox code in
netbox/extras/signals.py
:This code handles the queue of changes made to an object and correlates the change in the M2M relation to the change to the object itself. Unfortunately, it does that by looking at
queue[-1]
, which would actually contain the change to the object if there hadn't been asave()
operation in between caused by our customsave()
method above.As it is, the M2M change is not correlated to the object change, and so the Webhook is triggered twice, once (incorrectly) without and once with the changed M2M data in its payload.
The text was updated successfully, but these errors were encountered: