Filtering on both endpoints of a cable #2943

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

Originally created by @candlerb on GitHub (Oct 10, 2019).

Environment

  • Python version: 3.5.2
  • NetBox version: 2.6.6

Proposed Functionality

Netbox 2.6.6 added the ability to filter cables by site and rack.

If I filter on rack A, I get all cables where either end is in rack A. This includes cables entirely within rack A, and cables from rack A to elsewhere.

However if I filter on rack A and rack B, I get all cables where either end is in rack A, or either end is in rack B - a larger set of cables. This is not particularly useful.

What would be more useful in that situation is to show cables running between rack A and B: that is, where one end is in rack A and one end is in rack B, when 2 racks are selected.

Technically in that case I suppose it still also ought to show cables from A to A and B to B. I think that would add noise, and make it less useful. (*)

This can be generalised: if I select racks A, B and C, then show all cables where both ends are in the set (A,B,C) - that is, it would show cables from A to B, A to C, B to C. (Arguable about A-A, B-B, C-C).

(*) Maybe that's a separate feature though: show all cables from A to A, and show all cables from A to (not A).

For sites, I think this becomes even more important. "Show me all cables where one end is in site A" is not all that useful. "Show me all cables which run from site A to another site" is more useful, as is "show me all cables entirely within site A". Ditto for racks.

Use Case

Filtering to see backbone / inter-rack cables; finding patch panels linking two racks.

Database Changes

None

External Dependencies

None

Originally created by @candlerb on GitHub (Oct 10, 2019). ### Environment * Python version: 3.5.2 * NetBox version: 2.6.6 ### Proposed Functionality Netbox 2.6.6 added the ability to filter cables by site and rack. If I filter on rack A, I get all cables where either end is in rack A. This includes cables entirely within rack A, and cables from rack A to elsewhere. However if I filter on rack A and rack B, I get all cables where either end is in rack A, _or_ either end is in rack B - a larger set of cables. This is not particularly useful. What would be more useful in that situation is to show cables running between rack A and B: that is, where one end is in rack A *and* one end is in rack B, when 2 racks are selected. Technically in that case I suppose it still also ought to show cables from A to A and B to B. I think that would add noise, and make it less useful. (*) This can be generalised: if I select racks A, B and C, then show all cables where both ends are in the set (A,B,C) - that is, it would show cables from A to B, A to C, B to C. (Arguable about A-A, B-B, C-C). (*) Maybe that's a separate feature though: show all cables from A to A, and show all cables from A to (not A). For sites, I think this becomes even more important. "Show me all cables where one end is in site A" is not all that useful. "Show me all cables which run from site A to another site" is more useful, as is "show me all cables entirely within site A". Ditto for racks. ### Use Case Filtering to see backbone / inter-rack cables; finding patch panels linking two racks. ### Database Changes None ### External Dependencies None
adam added the type: featurestatus: needs ownerpending closure labels 2025-12-29 18:23:47 +01:00
adam closed this issue 2025-12-29 18:23:47 +01:00
Author
Owner

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

I'm a little confused. What are you proposing the results would be for each of the following queries?

  • GET /api/dcim/cables/?site=A
  • GET /api/dcim/cables/?site=A&site=B
@jeremystretch commented on GitHub (Oct 23, 2019): I'm a little confused. What are you proposing the results would be for each of the following queries? * `GET /api/dcim/cables/?site=A` * `GET /api/dcim/cables/?site=A&site=B`
Author
Owner

@candlerb commented on GitHub (Oct 28, 2019):

From the point of the GUI, I think the most useful behaviour would be:

  • Single site selected: cable is within site
  • Multiple sites selected: cable is between sites

Translating to the API, this becomes:

  • GET /api/dcim/cables/?site=A: cables where both ends are in site A
  • GET /api/dcim/cables/?site=A&site=B: cables where one end is in site (A or B) and the other end is in site (A or B), but different sites - i.e. A to B only
  • GET /api/dcim/cables/?site=A&site=B&site=C: cables where one end is in site (A or B or C) and the other end is in site (A or B or C), but different sites (i.e. A-B, A-C, B-C)

Unfortunately this is not backwards-compatible, plus you lose the existing query capability ("cables where one end is in site A and I don't care whether the other end is in site A or not").

However, you can keep the current behaviour if you require the same site to be selected multiple times to get the new behaviour:

  • GET /api/dcim/cables/?site=A: cables with one end in site A, other end don't care (as today)
  • GET /api/dcim/cables/?site=A&site=A: cables where both ends are in site A
  • ... rest as above

That's awkward to implement as multi-select widget in the GUI - although the GUI doesn't currently allow multi-select for sites anyway. Otherwise it's a relatively minor change.

Other approaches add more complexity, using sentinel values or query options.

Sentinel values might look like this (these can be options in a multi-select widget):

  • GET /api/dcim/cables/?site=A: cables with one end in site A, other end don't care
  • GET /api/dcim/cables/?site=A&site=<same>: cables where both ends are in site A
  • GET /api/dcim/cables/?site=A&site=<other>: cables where one end is in site A and the other is in a different site
  • GET /api/dcim/cables/?site=A&site=B&site=<same>: cables where one end is in site (A or B) and the other end is in the same site
  • GET /api/dcim/cables/?site=A&site=B&site=<other>: cables where one end is in site (A or B) and the other end is in site (A or B), but different sites - i.e. A to B only
  • GET /api/dcim/cables/?site=<same>: all cables which are internal to any site
  • GET /api/dcim/cables/?site=<other>: all cables which are between any two sites

Query options are similar, but avoid special-case values. They might look like this:

  • GET /api/dcim/cables/?site=A: cables from A to anywhere (as today)
  • GET /api/dcim/cables/?site=A&same=site: cables from A to A only
  • GET /api/dcim/cables/?site=A&different=site: cables from A to a different site
  • GET /api/dcim/cables/?site=A&site=B&same=site: cables from A to A or B to B only
  • GET /api/dcim/cables/?site=A&site=B&different=site: cables from A to B only
  • GET /api/dcim/cables/?same=site: all cables which are internal to any site
  • GET /api/dcim/cables/?different=site: all cables which are between any two sites

Query options seem cleaner, and this approach is useful even without multi-select widgets for site/rack/device in the GUI.


Discussion:

I note that Netbox treats most repeated params as "or", with the exception of ManyToMany fields like tags, where it treats them as "and". This is because an object can have multiple tags. I would argue that cables also fall into the latter category, because one cable has two terminations, and hence two sites (and two racks, two devices).

Thinking about devices, the following might be useful:

  • GET /api/dcim/cables/?device_id=123&device_id=456: cables between those two devices (rather than all cables into both devices)

But the following is probably not what you want:

  • GET /api/dcim/cables/?device_id=123: cables from this device to itself??

In that case, what you want is "cables from this device to anywhere" - which is how it works today, and is contrary to the initial proposal I made for sites.

That is a stronger argument for keeping the current behaviour when only a single parameter is provided.

Sentinel values would work here though:

  • GET /api/dcim/cables/?device_id=123&device_id=<same>: cables from this device to itself
  • GET /api/dcim/cables/?device_id=123&device_id=<other>: cables from this device to another device

Or query options:

  • GET /api/dcim/cables/?device_id=123&same=device: cables from this device to itself
  • GET /api/dcim/cables/?device_id=123&different=device: cables from this device to another device
  • GET /api/dcim/cables/?device_id=123&different=rack&same=site: cables from this device to other racks in the same site

(Query options probably more useful, since the GUI only allows you to enter a single device name today)


Regarding the limitations of multi-select widgets, where you can't select the same item twice, another approach I considered would be to have two selection widgets, in which case it becomes something completely different:

  • GET /api/dcim/cables/?site=A&site2=B

"site" and "site2" would represent the A and B terminations but either way round.

This gives:

  • GET /api/dcim/cables/?site=A: cables where where one end is in site A, other can be any
  • GET /api/dcim/cables/?site=A&site2=A: cables where both ends are in site A
  • GET /api/dcim/cables/?site=A&site2=B: cables between site A and site B
  • GET /api/dcim/cables/?site=A&site=B&site2=C&site2=D: cables between (site A or B) and (site C or D)

It is still difficult to do "cables from site A to any other site" without listing all other sites in site2, unless you introduce a sentinel value again:

  • GET /api/dcim/cables/?site=A&site2=<other>: cables from site A to any other site
@candlerb commented on GitHub (Oct 28, 2019): From the point of the GUI, I think the most useful behaviour would be: * Single site selected: cable is within site * Multiple sites selected: cable is between sites Translating to the API, this becomes: * `GET /api/dcim/cables/?site=A`: cables where both ends are in site A * `GET /api/dcim/cables/?site=A&site=B`: cables where one end is in site (A or B) and the other end is in site (A or B), but different sites - i.e. A to B only * `GET /api/dcim/cables/?site=A&site=B&site=C`: cables where one end is in site (A or B or C) and the other end is in site (A or B or C), but different sites (i.e. A-B, A-C, B-C) Unfortunately this is not backwards-compatible, plus you lose the existing query capability ("cables where one end is in site A and I don't care whether the other end is in site A or not"). However, you can keep the current behaviour if you require the same site to be selected multiple times to get the new behaviour: * `GET /api/dcim/cables/?site=A`: cables with one end in site A, other end don't care (as today) * `GET /api/dcim/cables/?site=A&site=A`: cables where both ends are in site A * ... rest as above That's awkward to implement as multi-select widget in the GUI - although the GUI doesn't currently allow multi-select for sites anyway. Otherwise it's a relatively minor change. Other approaches add more complexity, using sentinel values or query options. Sentinel values might look like this (these can be options in a multi-select widget): * `GET /api/dcim/cables/?site=A`: cables with one end in site A, other end don't care * `GET /api/dcim/cables/?site=A&site=<same>`: cables where both ends are in site A * `GET /api/dcim/cables/?site=A&site=<other>`: cables where one end is in site A and the other is in a different site * `GET /api/dcim/cables/?site=A&site=B&site=<same>`: cables where one end is in site (A or B) and the other end is in the same site * `GET /api/dcim/cables/?site=A&site=B&site=<other>`: cables where one end is in site (A or B) and the other end is in site (A or B), but different sites - i.e. A to B only * `GET /api/dcim/cables/?site=<same>`: all cables which are internal to any site * `GET /api/dcim/cables/?site=<other>`: all cables which are between any two sites Query options are similar, but avoid special-case values. They might look like this: * `GET /api/dcim/cables/?site=A`: cables from A to anywhere (as today) * `GET /api/dcim/cables/?site=A&same=site`: cables from A to A only * `GET /api/dcim/cables/?site=A&different=site`: cables from A to a different site * `GET /api/dcim/cables/?site=A&site=B&same=site`: cables from A to A or B to B only * `GET /api/dcim/cables/?site=A&site=B&different=site`: cables from A to B only * `GET /api/dcim/cables/?same=site`: all cables which are internal to any site * `GET /api/dcim/cables/?different=site`: all cables which are between any two sites Query options seem cleaner, and this approach is useful even without multi-select widgets for site/rack/device in the GUI. ----- Discussion: I note that Netbox treats most repeated params as "or", with the exception of ManyToMany fields like tags, where it treats them as "and". This is because an object can have multiple tags. I would argue that cables also fall into the latter category, because one cable has two terminations, and hence two sites (and two racks, two devices). Thinking about devices, the following might be useful: * `GET /api/dcim/cables/?device_id=123&device_id=456`: cables between those two devices (rather than all cables into both devices) But the following is probably *not* what you want: * `GET /api/dcim/cables/?device_id=123`: cables from this device to itself?? In that case, what you want is "cables from this device to anywhere" - which is how it works today, and is contrary to the initial proposal I made for sites. That is a stronger argument for keeping the current behaviour when only a single parameter is provided. Sentinel values would work here though: * `GET /api/dcim/cables/?device_id=123&device_id=<same>`: cables from this device to itself * `GET /api/dcim/cables/?device_id=123&device_id=<other>`: cables from this device to another device Or query options: * `GET /api/dcim/cables/?device_id=123&same=device`: cables from this device to itself * `GET /api/dcim/cables/?device_id=123&different=device`: cables from this device to another device * `GET /api/dcim/cables/?device_id=123&different=rack&same=site`: cables from this device to other racks in the same site (Query options probably more useful, since the GUI only allows you to enter a single device name today) ----- Regarding the limitations of multi-select widgets, where you can't select the same item twice, another approach I considered would be to have two selection widgets, in which case it becomes something completely different: * `GET /api/dcim/cables/?site=A&site2=B` "site" and "site2" would represent the A and B terminations but either way round. This gives: * `GET /api/dcim/cables/?site=A`: cables where where one end is in site A, other can be any * `GET /api/dcim/cables/?site=A&site2=A`: cables where both ends are in site A * `GET /api/dcim/cables/?site=A&site2=B`: cables between site A and site B * `GET /api/dcim/cables/?site=A&site=B&site2=C&site2=D`: cables between (site A or B) and (site C or D) It is still difficult to do "cables from site A to any other site" without listing all other sites in site2, unless you introduce a sentinel value again: * `GET /api/dcim/cables/?site=A&site2=<other>`: cables from site A to any other site
Author
Owner

@candlerb commented on GitHub (Oct 28, 2019):

Let me reformulate into a simple proposal:

  1. If a single value is given for a query parameter, either end of the cable must match.

  2. If multiple values are given for the same query parameter, both ends of the cable must match any of the provided values.

  3. For rule (2), the two ends must also match different values from the set of provided values, unless only one unique query value was provided (e.g. site=A&site=A)

Rule 1: ... WHERE a.x = 'foo' OR b.x = 'foo'
Rule 2/3: (single unique value): ... WHERE a.x = 'foo' AND b.x = 'foo'
Rule 2/3: (multiple values): ... WHERE a.x IN ('foo', 'bar') AND b.x IN ('foo', 'bar') AND a.x != b.x


Optional bonus rule: a blank value matches anything. In that case, site=A&site=B&site= means that one end must be in site A or B, and the other end must be in any other site (not the same site, because of rule (3))

Rule 4: ... WHERE (a.x IN ('foo', 'bar') OR b.x IN ('foo', 'bar')) AND a.x != b.x

@candlerb commented on GitHub (Oct 28, 2019): Let me reformulate into a simple proposal: 1. If a single value is given for a query parameter, *either* end of the cable must match. 2. If multiple values are given for the same query parameter, *both* ends of the cable must match any of the provided values. 3. For rule (2), the two ends must also match *different* values from the set of provided values, unless only one unique query value was provided (e.g. `site=A&site=A`) Rule 1: `... WHERE a.x = 'foo' OR b.x = 'foo'` Rule 2/3: (single unique value): `... WHERE a.x = 'foo' AND b.x = 'foo'` Rule 2/3: (multiple values): `... WHERE a.x IN ('foo', 'bar') AND b.x IN ('foo', 'bar') AND a.x != b.x` ----- Optional bonus rule: a blank value matches anything. In that case, `site=A&site=B&site=` means that one end must be in site A or B, and the other end must be in any other site (not the same site, because of rule (3)) Rule 4: `... WHERE (a.x IN ('foo', 'bar') OR b.x IN ('foo', 'bar')) AND a.x != b.x`
Author
Owner

@stale[bot] commented on GitHub (Sep 7, 2020):

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. Please see our contributing guide.

@stale[bot] commented on GitHub (Sep 7, 2020): This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. Please see our [contributing guide](https://github.com/netbox-community/netbox/blob/develop/CONTRIBUTING.md).
Author
Owner

@stale[bot] commented on GitHub (Sep 23, 2020):

This issue has been automatically closed due to lack of activity. In an effort to reduce noise, please do not comment any further. Note that the core maintainers may elect to reopen this issue at a later date if deemed necessary.

@stale[bot] commented on GitHub (Sep 23, 2020): This issue has been automatically closed due to lack of activity. In an effort to reduce noise, please do not comment any further. Note that the core maintainers may elect to reopen this issue at a later date if deemed necessary.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#2943