/api/ipam/ip-addresses/ query by virtual_machine or virtual_machine_id returns "Bad Request" #2317

Closed
opened 2025-12-29 17:24:46 +01:00 by adam · 7 comments
Owner

Originally created by @pm17788 on GitHub (Jan 29, 2019).

  • Python version: 3.5.4
  • NetBox version: 3.5.3

Steps to Reproduce

  1. https://NetBox/api/ipam/ip-addresses/?virtual_machine=fluffymonkey or https://nNetBox/api/ipam/ip-addresses/?virtual_machine_id=123

Expected Behavior

Return of:

{
    "count": 0,
    "next": null,
    "previous": null,
    "results": []
}

Observed Behavior

{
  "virtual_machine": [
    "Select a valid choice. %(value)s is not one of the available choices."
  ]
}
{
    "virtual_machine_id": [
        "Select a valid choice. %(value)s is not one of the available choices."
    ]
}
Originally created by @pm17788 on GitHub (Jan 29, 2019). * Python version: 3.5.4 * NetBox version: 3.5.3 ### Steps to Reproduce 1. https://NetBox/api/ipam/ip-addresses/?virtual_machine=fluffymonkey or https://nNetBox/api/ipam/ip-addresses/?virtual_machine_id=123 <!-- What did you expect to happen? --> ### Expected Behavior Return of: ```shell { "count": 0, "next": null, "previous": null, "results": [] } ``` <!-- What happened instead? --> ### Observed Behavior ```shell { "virtual_machine": [ "Select a valid choice. %(value)s is not one of the available choices." ] } ``` ```shell { "virtual_machine_id": [ "Select a valid choice. %(value)s is not one of the available choices." ] } ```
adam closed this issue 2025-12-29 17:24:46 +01:00
Author
Owner

@jeremystretch commented on GitHub (Jan 31, 2019):

We should fix the error string, but the response code is correct. The request is for resources which belong to an object which doesn't exist.

@jeremystretch commented on GitHub (Jan 31, 2019): We should fix the error string, but the response code is correct. The request is for resources which belong to an object which doesn't exist.
Author
Owner

@pm17788 commented on GitHub (Feb 8, 2019):

We should fix the error string, but the response code is correct. The request is for resources which belong to an object which doesn't exist.

@jeremystretch : Sorry, confused. So, if I wanted to query the API for all IP addresses "belonging" to VM named "FluffyMonkey", https://NetBox/api/ipam/ip-addresses/?virtual_machine=fluffymonkey is not the correct query? https://netbox.datto.net/api/ipam/ip-addresses/?device=fluffy_monkey works (rather, it returns a count of 0, but that's the expected behaviour)

@pm17788 commented on GitHub (Feb 8, 2019): > We should fix the error string, but the response code is correct. The request is for resources which belong to an object which doesn't exist. @jeremystretch : Sorry, confused. So, if I wanted to query the API for all IP addresses "belonging" to VM named "FluffyMonkey", https://NetBox/api/ipam/ip-addresses/?virtual_machine=fluffymonkey is not the correct query? https://netbox.datto.net/api/ipam/ip-addresses/?device=fluffy_monkey works (rather, it returns a count of 0, but that's the expected behaviour)
Author
Owner

@jeremystretch commented on GitHub (Mar 23, 2019):

There are a couple ways to handle this:

  1. Return an empty set because no device/VM with the given name was found. This can be confusing e.g. in the event of a typo in the device/VM name, because it's the same effect as specifying a valid device/VM which simply doesn't have any IP addresses assigned to it.
  2. Return an unfiltered list of all IP addresses, effectively nullifying the filter because it was passed an invalid object. While perhaps semantically correct, this is probably even more prone to confusion.
  3. Return a 400 error, indicating a bad request. IMO this is the most obvious indication that an error has been made, even if the request isn't malformed.
  4. Return a 404 error. Similar to above. Maybe more appropriate.
@jeremystretch commented on GitHub (Mar 23, 2019): There are a couple ways to handle this: 1. Return an empty set because no device/VM with the given name was found. This can be confusing e.g. in the event of a typo in the device/VM name, because it's the same effect as specifying a valid device/VM which simply doesn't have any IP addresses assigned to it. 2. Return an unfiltered list of all IP addresses, effectively nullifying the filter because it was passed an invalid object. While perhaps semantically correct, this is probably even more prone to confusion. 3. Return a 400 error, indicating a bad request. IMO this is the most obvious indication that an error has been made, even if the request isn't malformed. 4. Return a 404 error. Similar to above. Maybe more appropriate.
Author
Owner

@pm17788 commented on GitHub (Mar 23, 2019):

@jeremystretch : Sorry, very confused.

Looking at 3acc8ca3ab/netbox/ipam/api/serializers.py (L169) strongly implies that an ipaddress object has the capability to have either a nested device or virtual_machine structure. Cool! But this also makes me think that I should be able to query the API for IP address(es) associated/assigned to either a device (by name or by numeric ID), or to a virtual machine (again, either by name or numeric ID).

If I botch either the ID or the name, am I unreasonable in expecting either an empty set to be returned a-la"you asked for IPs belonging to device ID 13234. None are. Enjoy.", or "Hey, the supplied ID wasn't found at all"?

In fact, returning the empty set is what the API currently does when I query by device or device_id, but not by virtual_machine or virtual_machine_id. At a minimum, this seems inconsistent and quite confusing.

Am I misunderstanding something?

@pm17788 commented on GitHub (Mar 23, 2019): @jeremystretch : Sorry, very confused. Looking at https://github.com/digitalocean/netbox/blob/3acc8ca3ab0307487aa5d61a8c8b091900b594b2/netbox/ipam/api/serializers.py#L169 strongly implies that an `ipaddress` object has the capability to have either a nested `device` or `virtual_machine` structure. Cool! But this also makes me think that I should be able to query the API for IP address(es) associated/assigned to either a device (by name or by numeric ID), or to a virtual machine (again, either by name or numeric ID). If I botch either the ID or the name, am I unreasonable in expecting either an empty set to be returned a-la"you asked for IPs belonging to device ID 13234. None are. Enjoy.", or "Hey, the supplied ID wasn't found at all"? In fact, returning the empty set is what the API currently does when I query by `device` or `device_id`, but not by `virtual_machine` or `virtual_machine_id`. At a minimum, this seems inconsistent and quite confusing. Am I misunderstanding something?
Author
Owner

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

If I botch either the ID or the name, am I unreasonable in expecting either an empty set to be returned a-la"you asked for IPs belonging to device ID 13234. None are. Enjoy.", or "Hey, the supplied ID wasn't found at all"?

IMO we should have different behavior for querying an existing device/VM with no IPs and querying a non-existent device/VM.

In fact, returning the empty set is what the API currently does when I query by device or device_id, but not by virtual_machine or virtual_machine_id. At a minimum, this seems inconsistent and quite confusing.

Agreed. This is due to the custom filter_device() method on IPAddressFilter, which was needed to match on virtual chassis interfaces.

@jeremystretch commented on GitHub (Apr 27, 2019): > If I botch either the ID or the name, am I unreasonable in expecting either an empty set to be returned a-la"you asked for IPs belonging to device ID 13234. None are. Enjoy.", or "Hey, the supplied ID wasn't found at all"? IMO we should have different behavior for querying an existing device/VM with no IPs and querying a non-existent device/VM. > In fact, returning the empty set is what the API currently does when I query by device or device_id, but not by virtual_machine or virtual_machine_id. At a minimum, this seems inconsistent and quite confusing. Agreed. This is due to the custom `filter_device()` method on IPAddressFilter, which was needed to match on virtual chassis interfaces.
Author
Owner

@pm17788 commented on GitHub (Apr 29, 2019):

In fact, returning the empty set is what the API currently does when I query by device or device_id, but not by virtual_machine or virtual_machine_id. At a minimum, this seems inconsistent and quite confusing.

Agreed. This is due to the custom filter_device() method on IPAddressFilter, which was needed to match on virtual chassis interfaces.

Fair enough. I don't have a strong feeling on which of the two behaviours is more appropriate, it was the difference that is most confuzzling :)

@pm17788 commented on GitHub (Apr 29, 2019): > > In fact, returning the empty set is what the API currently does when I query by device or device_id, but not by virtual_machine or virtual_machine_id. At a minimum, this seems inconsistent and quite confusing. > > Agreed. This is due to the custom `filter_device()` method on IPAddressFilter, which was needed to match on virtual chassis interfaces. Fair enough. I don't have a strong feeling on which of the two behaviours is more appropriate, it was the difference that is most confuzzling :)
Author
Owner

@jeremystretch commented on GitHub (Dec 13, 2019):

Looks like this was resolved at some point and just never closed out. The API requests cited in the description work as intended now.

@jeremystretch commented on GitHub (Dec 13, 2019): Looks like this was resolved at some point and just never closed out. The API requests cited in the description work as intended now.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#2317