Webhooks for interface on virtual-machine #3611

Closed
opened 2025-12-29 18:30:09 +01:00 by adam · 5 comments
Owner

Originally created by @jeremmfr on GitHub (Apr 27, 2020).

Originally assigned to: @jeremystretch on GitHub.

Environment

  • Python version: 3.6.9
  • NetBox version: 2.8.1

Steps to Reproduce

  1. Disable any installed plugins by commenting out the PLUGINS setting in
    configuration.py.
  2. Add a virtual-machine
  3. Add a webhook on model device->interface to url http://localhost:9000
  4. Start webhook_receiver -> python netbox/manage.py webhook_receiver
  5. Add an interface on the virtual-machine

Expected Behavior

A virtual_machine object in data
Output on receiver :

{
     "event": "created",
     "timestamp": "2020-04-27 09:34:47.910546+00:00",
     "model": "interface",
     "username": "admin",
     "request_id": "dbdb0fd9-6ac0-4395-a900-1488182d9b4e",
     "data": {
          "id": 135088,
          "device": null,
          "virtual_machine": {
               "id": 3416,
               "url": "https://netbox.example.com/api/virtualization/virtual-machines/3416/",
               "name": "myVM"
          },
          "name": "eth1",
          "type": {
               "value": "virtual",
               "label": "Virtual",
               "id": 0
          },
          "enabled": true,
          "lag": null,
          "mtu": null,
          "mac_address": "",
          "mgmt_only": false,
          "description": "",
          "connected_endpoint_type": null,
          "connected_endpoint": null,
          "connection_status": null,
          "cable": null,
          "mode": null,
          "untagged_vlan": null,
          "tagged_vlans": [],
          "tags": [],
          "count_ipaddresses": 0
     }
}

Observed Behavior

Output on receiver :

{
     "event": "created",
     "timestamp": "2020-04-27 09:34:47.910546+00:00",
     "model": "interface",
     "username": "admin",
     "request_id": "dbdb0fd9-6ac0-4395-a900-1488182d9b4e",
     "data": {
          "id": 135088,
          "device": null,
          "name": "eth1",
          "type": {
               "value": "virtual",
               "label": "Virtual",
               "id": 0
          },
          "enabled": true,
          "lag": null,
          "mtu": null,
          "mac_address": "",
          "mgmt_only": false,
          "description": "",
          "connected_endpoint_type": null,
          "connected_endpoint": null,
          "connection_status": null,
          "cable": null,
          "mode": null,
          "untagged_vlan": null,
          "tagged_vlans": [],
          "tags": [],
          "count_ipaddresses": 0
     }
}
Originally created by @jeremmfr on GitHub (Apr 27, 2020). Originally assigned to: @jeremystretch on GitHub. ### Environment * Python version: 3.6.9 * NetBox version: 2.8.1 ### Steps to Reproduce 1. Disable any installed plugins by commenting out the `PLUGINS` setting in `configuration.py`. 2. Add a virtual-machine 3. Add a webhook on model device->interface to url http://localhost:9000 4. Start webhook_receiver -> python netbox/manage.py webhook_receiver 5. Add an interface on the virtual-machine ### Expected Behavior A `virtual_machine` object in `data` Output on receiver : ``` { "event": "created", "timestamp": "2020-04-27 09:34:47.910546+00:00", "model": "interface", "username": "admin", "request_id": "dbdb0fd9-6ac0-4395-a900-1488182d9b4e", "data": { "id": 135088, "device": null, "virtual_machine": { "id": 3416, "url": "https://netbox.example.com/api/virtualization/virtual-machines/3416/", "name": "myVM" }, "name": "eth1", "type": { "value": "virtual", "label": "Virtual", "id": 0 }, "enabled": true, "lag": null, "mtu": null, "mac_address": "", "mgmt_only": false, "description": "", "connected_endpoint_type": null, "connected_endpoint": null, "connection_status": null, "cable": null, "mode": null, "untagged_vlan": null, "tagged_vlans": [], "tags": [], "count_ipaddresses": 0 } } ``` ### Observed Behavior Output on receiver : ``` { "event": "created", "timestamp": "2020-04-27 09:34:47.910546+00:00", "model": "interface", "username": "admin", "request_id": "dbdb0fd9-6ac0-4395-a900-1488182d9b4e", "data": { "id": 135088, "device": null, "name": "eth1", "type": { "value": "virtual", "label": "Virtual", "id": 0 }, "enabled": true, "lag": null, "mtu": null, "mac_address": "", "mgmt_only": false, "description": "", "connected_endpoint_type": null, "connected_endpoint": null, "connection_status": null, "cable": null, "mode": null, "untagged_vlan": null, "tagged_vlans": [], "tags": [], "count_ipaddresses": 0 } } ```
adam added the type: bugstatus: blocked labels 2025-12-29 18:30:09 +01:00
adam closed this issue 2025-12-29 18:30:09 +01:00
Author
Owner

@jeremystretch commented on GitHub (Apr 27, 2020):

This is going to be tricky to solve with resorting to hacks. When a webhook is queued, the serializer to use is determined dynamically from the instance's class. This usually works fine, but the Interface model is unique in that we use one of two different serializers depending on whether the interface is assigned to a device or a virtual machine. We need to devise a way for inferring the correct serializer.

One option is to examine the instance's virtual_machine field: If set, we should use the VM serializer. However, the dynamic resolution needs to work with classes, not instances.

I also looked into using a proxy model to dcim.Interface, however this has some undesirable side effects, such as creating new permissions.

Ultimately, it might be best to forgo the separate serializer entirely, and simply return both the device and virtual_machine fields, however that would constitute a breaking API change.

@jeremystretch commented on GitHub (Apr 27, 2020): This is going to be tricky to solve with resorting to hacks. When a webhook is queued, the serializer to use is determined dynamically from the instance's class. This usually works fine, but the Interface model is unique in that we use one of two different serializers depending on whether the interface is assigned to a device or a virtual machine. We need to devise a way for inferring the correct serializer. One option is to examine the instance's `virtual_machine` field: If set, we should use the VM serializer. However, the dynamic resolution needs to work with classes, not instances. I also looked into using a proxy model to `dcim.Interface`, however this has some undesirable side effects, such as creating new permissions. Ultimately, it might be best to forgo the separate serializer entirely, and simply return both the `device` and `virtual_machine` fields, however that would constitute a breaking API change.
Author
Owner

@DanSheps commented on GitHub (Apr 28, 2020):

What about perhaps instead moving towards using a Polymorphic model for Device/Virtual Machine?

It would mean a couple of new deps (django-polymorphic, django-rest-polymorphic) but it might make this easier.

They are different "device" types though.

@DanSheps commented on GitHub (Apr 28, 2020): What about perhaps instead moving towards using a Polymorphic model for Device/Virtual Machine? It would mean a couple of new deps (django-polymorphic, django-rest-polymorphic) but it might make this easier. They are different "device" types though.
Author
Owner

@jeremystretch commented on GitHub (Apr 30, 2020):

We discussed this in our maintainers' meeting earlier this week, and the consensus seemed to lean toward using a single serializer for the Interface model to show both the device and virtual_machine fields. I'd consider this a breaking change though, which means it needs to be postponed until the v2.9 release.

@jeremystretch commented on GitHub (Apr 30, 2020): We discussed this in our maintainers' meeting earlier this week, and the consensus seemed to lean toward using a single serializer for the Interface model to show both the `device` and `virtual_machine` fields. I'd consider this a breaking change though, which means it needs to be postponed until the v2.9 release.
Author
Owner

@jeremystretch commented on GitHub (May 5, 2020):

Blocked by #4579

@jeremystretch commented on GitHub (May 5, 2020): Blocked by #4579
Author
Owner

@jeremystretch commented on GitHub (Jul 1, 2020):

#4721 introduces a truly separate model for virtual machine interfaces in NetBox v2.9, which will resolve this issue.

@jeremystretch commented on GitHub (Jul 1, 2020): #4721 introduces a truly separate model for virtual machine interfaces in NetBox v2.9, which will resolve this issue.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#3611