MultipleObjectsReturned: get() returned more than one Aggregate #41

Closed
opened 2025-12-29 15:30:27 +01:00 by adam · 1 comment
Owner

Originally created by @candlerb on GitHub (Jun 28, 2016).

Netbox 66a16dd0 under Ubuntu 14.04

What I did was:

  • Create a device with interface 1.2.3.4/24
  • Create an aggregate 1.2.3.0/24
  • Create a prefix 1.2.3.0/24
  • Create an aggregate 1.0.0.0/8

When I browse to the outer aggregate http://x.x.x.x:8000/ipam/aggregates/2/ (1.0.0.0/8) it shows the "child prefixes" inside it, including 1.2.3.0/24 "active". But when I click on this, which takes me to http://x.x.x.x:8000/ipam/prefixes/1/, I get a 500 "Server error"

No error is shown in the console output apart from:

[28/Jun/2016 09:35:28] "GET /ipam/prefixes/1/ HTTP/1.1" 500 1026

But after setting DEBUG = True in configuration.py, I get this:

Internal Server Error: /ipam/prefixes/1/
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 149, in get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 147, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/opt/netbox/netbox/ipam/views.py", line 273, in prefix
    aggregate = Aggregate.objects.get(prefix__net_contains_or_equals=str(prefix.prefix))
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py", line 122, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 391, in get
    (self.model._meta.object_name, num)
MultipleObjectsReturned: get() returned more than one Aggregate -- it returned 2!

Possibly the problem is that I can't have both an aggregate and a prefix which are the same (but then Netbox should stop me getting into this situation in the first place?)

Issue 2: I tried to delete the aggregate 1.2.3.0/24, but what it actually did was to delete the prefix! Then I deleted the aggregate, then recreated the prefix, and it was OK.

Issue 3: given that I still have an aggregate 1.0.0.0/8 it now doesn't allow me to create an aggregate 1.2.3.0/24 again: it says "1.2.3.0/24 is already covered by an existing aggregate (1.0.0.0/8)"

This may be true, but if one aggregate is not allowed to contain another aggregate, this needs to be enforced in the opposite direction too (i.e. it allowed me to create aggregate 1.0.0.0/8 after creating aggregate 1.2.3.0/24, but not the other way round)

This leads onto:

Issue 4: it should be made clearer in the documentation about whether aggregates can be nested, and/or prefixes can be nested.

Based on experimentation, it looks like prefixes can be nested, but aggregates cannot / should not, correct?

For example: I may have 192.0.0.0/22 from my registry, but I divide that up to 192.0.0.0/24 for data centre 1 and 192.0.1.0/24 for data centre 2, and then from within those ranges I allocate subnets for each data centre. So I believe the correct approach in Netbox is to create an aggregate 192.0.0.0/22, prefixes 192.0.0.0/24 and 192.0.1.0/24, and child prefixes within those prefixes to represent the actual subnets on router interfaces - is that right?

Originally created by @candlerb on GitHub (Jun 28, 2016). Netbox 66a16dd0 under Ubuntu 14.04 What I did was: - Create a device with interface 1.2.3.4/24 - Create an aggregate 1.2.3.0/24 - Create a prefix 1.2.3.0/24 - Create an aggregate 1.0.0.0/8 When I browse to the outer aggregate http://x.x.x.x:8000/ipam/aggregates/2/ (1.0.0.0/8) it shows the "child prefixes" inside it, including 1.2.3.0/24 "active". But when I click on this, which takes me to http://x.x.x.x:8000/ipam/prefixes/1/, I get a 500 "Server error" No error is shown in the console output apart from: ``` [28/Jun/2016 09:35:28] "GET /ipam/prefixes/1/ HTTP/1.1" 500 1026 ``` But after setting `DEBUG = True` in configuration.py, I get this: ``` Internal Server Error: /ipam/prefixes/1/ Traceback (most recent call last): File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 149, in get_response response = self.process_exception_by_middleware(e, request) File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 147, in get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/opt/netbox/netbox/ipam/views.py", line 273, in prefix aggregate = Aggregate.objects.get(prefix__net_contains_or_equals=str(prefix.prefix)) File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py", line 122, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 391, in get (self.model._meta.object_name, num) MultipleObjectsReturned: get() returned more than one Aggregate -- it returned 2! ``` Possibly the problem is that I can't have both an aggregate and a prefix which are the same (but then Netbox should stop me getting into this situation in the first place?) Issue 2: I tried to delete the aggregate 1.2.3.0/24, but what it actually did was to delete the prefix! Then I deleted the aggregate, then recreated the prefix, and it was OK. Issue 3: given that I still have an aggregate 1.0.0.0/8 it now doesn't allow me to create an aggregate 1.2.3.0/24 again: it says "1.2.3.0/24 is already covered by an existing aggregate (1.0.0.0/8)" This may be true, but if one aggregate is not allowed to contain another aggregate, this needs to be enforced in the opposite direction too (i.e. it allowed me to create aggregate 1.0.0.0/8 _after_ creating aggregate 1.2.3.0/24, but not the other way round) This leads onto: Issue 4: it should be made clearer in the [documentation](https://github.com/digitalocean/netbox/blob/develop/docs/ipam.md) about whether aggregates can be nested, and/or prefixes can be nested. Based on experimentation, it looks like prefixes can be nested, but aggregates cannot / should not, correct? For example: I may have 192.0.0.0/22 from my registry, but I divide that up to 192.0.0.0/24 for data centre 1 and 192.0.1.0/24 for data centre 2, and then from within those ranges I allocate subnets for each data centre. So I believe the correct approach in Netbox is to create an aggregate 192.0.0.0/22, prefixes 192.0.0.0/24 and 192.0.1.0/24, and child prefixes within those prefixes to represent the actual subnets on router interfaces - is that right?
adam added the type: bug label 2025-12-29 15:30:27 +01:00
adam closed this issue 2025-12-29 15:30:27 +01:00
Author
Owner

@jeremystretch commented on GitHub (Jun 28, 2016):

Aggregates represent the top level of the IP hierarchy; they don't nest within one another. You should not have been able to create an aggregate which overlaps with another.

It looks like it was possible because you created a more-specific aggregate first, and then one which covers it. The validation code currently only checks for the reverse scenario.

@jeremystretch commented on GitHub (Jun 28, 2016): Aggregates represent the top level of the IP hierarchy; they don't nest within one another. You should not have been able to create an aggregate which overlaps with another. It looks like it was possible because you created a more-specific aggregate first, and then one which covers it. The validation code currently only checks for the reverse scenario.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#41