available_prefixes method doesn't allow to create prefix in Global if there are intersected prefixes in VRF #6861

Closed
opened 2025-12-29 19:46:09 +01:00 by adam · 2 comments
Owner

Originally created by @RequestSystemReboot on GitHub (Aug 23, 2022).

Originally assigned to: @jeremystretch on GitHub.

NetBox version

3.2.8

Python version

3.10

Steps to Reproduce

1. Create container 10.182.0.0/15 in Global

curl -X 'GET' \
  'https://ipam.local/api/ipam/prefixes/58204/' \
  -H 'accept: application/json' \
  -H 'Authorization: ***' \
  -H 'X-CSRFToken: ***'
{
  "id": 58204,
  "url": "https://ipam.local/api/ipam/prefixes/58204/",
  "display": "10.182.0.0/15",
  "family": {
    "value": 4,
    "label": "IPv4"
  },
  "prefix": "10.182.0.0/15",
  "site": null,
  "vrf": null,
  "tenant": null,
  "vlan": null,
  "status": {
    "value": "container",
    "label": "Container"
  },
  "role": null,
  "is_pool": false,
  "mark_utilized": false,
  "description": "",
  "tags": [],
  "custom_fields": {},
  "created": "2022-06-28T03:00:00+03:00",
  "last_updated": "2022-08-23T14:50:58.455367+03:00",
  "children": 0,
  "_depth": 1
}

2. Create VRF test

curl -X 'GET' \
  'https://ipam.local/api/ipam/vrfs/?id=80' \
  -H 'accept: application/json' \
  -H 'Authorization: ***' \
  -H 'X-CSRFToken: ***'
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 80,
      "url": "https://ipam.local/api/ipam/vrfs/80/",
      "display": "test",
      "name": "test",
      "rd": null,
      "tenant": null,
      "enforce_unique": true,
      "description": "",
      "import_targets": [],
      "export_targets": [],
      "tags": [],
      "custom_fields": {},
      "created": "2022-08-23T14:34:42.756926+03:00",
      "last_updated": "2022-08-23T14:34:42.756948+03:00",
      "ipaddress_count": 0,
      "prefix_count": 2
    }
  ]
}

3. Create container 10.182.0.0/16 in VRF test

curl -X 'GET' \
  'https://ipam.local/api/ipam/prefixes/60003/' \
  -H 'accept: application/json' \
  -H 'Authorization: ***' \
  -H 'X-CSRFToken: ***'
{
  "id": 60003,
  "url": "https://ipam.local/api/ipam/prefixes/60003/",
  "display": "10.182.0.0/16",
  "family": {
    "value": 4,
    "label": "IPv4"
  },
  "prefix": "10.182.0.0/16",
  "site": null,
  "vrf": {
    "id": 80,
    "url": "https://ipam.local/api/ipam/vrfs/80/",
    "display": "test",
    "name": "test",
    "rd": null
  },
  "tenant": null,
  "vlan": null,
  "status": {
    "value": "container",
    "label": "Container"
  },
  "role": null,
  "is_pool": false,
  "mark_utilized": false,
  "description": "I'm in VRF",
  "tags": [],
  "custom_fields": {},
  "created": "2022-08-23T14:35:15.263966+03:00",
  "last_updated": "2022-08-23T14:37:11.287683+03:00",
  "children": 0,
  "_depth": 0
}

4. Create container 10.183.0.0/16 in VRF test

curl -X 'GET' \
  'https://ipam.local/api/ipam/prefixes/60004/' \
  -H 'accept: application/json' \
  -H 'Authorization: ***' \
  -H 'X-CSRFToken: ***'
{
  "id": 60004,
  "url": "https://ipam.local/api/ipam/prefixes/60004/",
  "display": "10.183.0.0/16",
  "family": {
    "value": 4,
    "label": "IPv4"
  },
  "prefix": "10.183.0.0/16",
  "site": null,
  "vrf": {
    "id": 80,
    "url": "https://ipam.local/api/ipam/vrfs/80/",
    "display": "test",
    "name": "test",
    "rd": null
  },
  "tenant": null,
  "vlan": null,
  "status": {
    "value": "container",
    "label": "Container"
  },
  "role": null,
  "is_pool": false,
  "mark_utilized": false,
  "description": "I'm in VRF",
  "tags": [],
  "custom_fields": {},
  "created": "2022-08-23T14:35:25.692611+03:00",
  "last_updated": "2022-08-23T14:37:00.913414+03:00",
  "children": 0,
  "_depth": 0
}  

image

4. Use available_prefixes method to create a child inside 10.182.0.0/15 in Global

curl -X 'GET' \
  'https://ipam.local/api/ipam/prefixes/58204/available-prefixes/' \
  -H 'accept: application/json' \
  -H 'Authorization: ***' \
  -H 'X-CSRFToken: ***'

Response body
[]

curl -X 'POST' \
  'https://ipam.local/api/ipam/prefixes/58204/available-prefixes/' \
  -H 'accept: application/json' \
  -H 'Authorization: ***' \
  -H 'Content-Type: application/json' \
  -H 'X-CSRFToken: ***' \
  -d '{
  "prefix_length": 24
}'

Error: response status is 409
Response body

{
  "detail": "Insufficient space is available to accommodate the requested prefix size(s)"
}

Despite there is a lot of available space in 10.182.0.0/15 in Global we could not create a child.

Expected Behavior

A new prefix 10.182.0.0/24 should have been created in Global

Observed Behavior

"Insufficient space is available to accommodate the requested prefix size(s)" error was returned

But if we use strict method (POST api/ipam/prefixes/) to create a prefix we will succeed

curl -X 'POST' \
  'https://ipam.local/api/ipam/prefixes/' \
  -H 'accept: application/json' \
  -H 'Authorization: ***' \
  -H 'Content-Type: application/json' \
  -H 'X-CSRFToken: ***' \
  -d '{
  "prefix": "10.182.0.0/24",
  "status": "active",
  "custom_fields": {}
}'
{
  "id": 60006,
  "url": "https://ipam.local/api/ipam/prefixes/60006/",
  "display": "10.182.0.0/24",
  "family": {
    "value": 4,
    "label": "IPv4"
  },
  "prefix": "10.182.0.0/24",
  "site": null,
  "vrf": null,
  "tenant": null,
  "vlan": null,
  "status": {
    "value": "active",
    "label": "Active"
  },
  "role": null,
  "is_pool": false,
  "mark_utilized": false,
  "description": "",
  "tags": [],
  "custom_fields": {},
  "created": "2022-08-23T16:28:04.574840+03:00",
  "last_updated": "2022-08-23T16:28:04.574862+03:00",
  "children": 0,
  "_depth": 0
}

Unfortunately this method is not protected by advisory lock as "available-prefixes"

image

Originally created by @RequestSystemReboot on GitHub (Aug 23, 2022). Originally assigned to: @jeremystretch on GitHub. ### NetBox version 3.2.8 ### Python version 3.10 ### Steps to Reproduce **1. Create container 10.182.0.0/15 in Global** ``` curl -X 'GET' \ 'https://ipam.local/api/ipam/prefixes/58204/' \ -H 'accept: application/json' \ -H 'Authorization: ***' \ -H 'X-CSRFToken: ***' ``` ``` { "id": 58204, "url": "https://ipam.local/api/ipam/prefixes/58204/", "display": "10.182.0.0/15", "family": { "value": 4, "label": "IPv4" }, "prefix": "10.182.0.0/15", "site": null, "vrf": null, "tenant": null, "vlan": null, "status": { "value": "container", "label": "Container" }, "role": null, "is_pool": false, "mark_utilized": false, "description": "", "tags": [], "custom_fields": {}, "created": "2022-06-28T03:00:00+03:00", "last_updated": "2022-08-23T14:50:58.455367+03:00", "children": 0, "_depth": 1 } ``` **2. Create VRF test** ``` curl -X 'GET' \ 'https://ipam.local/api/ipam/vrfs/?id=80' \ -H 'accept: application/json' \ -H 'Authorization: ***' \ -H 'X-CSRFToken: ***' ``` ``` { "count": 1, "next": null, "previous": null, "results": [ { "id": 80, "url": "https://ipam.local/api/ipam/vrfs/80/", "display": "test", "name": "test", "rd": null, "tenant": null, "enforce_unique": true, "description": "", "import_targets": [], "export_targets": [], "tags": [], "custom_fields": {}, "created": "2022-08-23T14:34:42.756926+03:00", "last_updated": "2022-08-23T14:34:42.756948+03:00", "ipaddress_count": 0, "prefix_count": 2 } ] } ``` **3. Create container 10.182.0.0/16 in VRF test** ``` curl -X 'GET' \ 'https://ipam.local/api/ipam/prefixes/60003/' \ -H 'accept: application/json' \ -H 'Authorization: ***' \ -H 'X-CSRFToken: ***' ``` ``` { "id": 60003, "url": "https://ipam.local/api/ipam/prefixes/60003/", "display": "10.182.0.0/16", "family": { "value": 4, "label": "IPv4" }, "prefix": "10.182.0.0/16", "site": null, "vrf": { "id": 80, "url": "https://ipam.local/api/ipam/vrfs/80/", "display": "test", "name": "test", "rd": null }, "tenant": null, "vlan": null, "status": { "value": "container", "label": "Container" }, "role": null, "is_pool": false, "mark_utilized": false, "description": "I'm in VRF", "tags": [], "custom_fields": {}, "created": "2022-08-23T14:35:15.263966+03:00", "last_updated": "2022-08-23T14:37:11.287683+03:00", "children": 0, "_depth": 0 } ``` **4. Create container 10.183.0.0/16 in VRF test** ``` curl -X 'GET' \ 'https://ipam.local/api/ipam/prefixes/60004/' \ -H 'accept: application/json' \ -H 'Authorization: ***' \ -H 'X-CSRFToken: ***' ``` ``` { "id": 60004, "url": "https://ipam.local/api/ipam/prefixes/60004/", "display": "10.183.0.0/16", "family": { "value": 4, "label": "IPv4" }, "prefix": "10.183.0.0/16", "site": null, "vrf": { "id": 80, "url": "https://ipam.local/api/ipam/vrfs/80/", "display": "test", "name": "test", "rd": null }, "tenant": null, "vlan": null, "status": { "value": "container", "label": "Container" }, "role": null, "is_pool": false, "mark_utilized": false, "description": "I'm in VRF", "tags": [], "custom_fields": {}, "created": "2022-08-23T14:35:25.692611+03:00", "last_updated": "2022-08-23T14:37:00.913414+03:00", "children": 0, "_depth": 0 } ``` ![image](https://user-images.githubusercontent.com/91027081/186163019-b8333b1d-93b1-4807-a8ef-9ccfd459514f.png) **4. Use available_prefixes method to create a child inside 10.182.0.0/15 in Global** ``` curl -X 'GET' \ 'https://ipam.local/api/ipam/prefixes/58204/available-prefixes/' \ -H 'accept: application/json' \ -H 'Authorization: ***' \ -H 'X-CSRFToken: ***' ``` **Response body** [] ``` curl -X 'POST' \ 'https://ipam.local/api/ipam/prefixes/58204/available-prefixes/' \ -H 'accept: application/json' \ -H 'Authorization: ***' \ -H 'Content-Type: application/json' \ -H 'X-CSRFToken: ***' \ -d '{ "prefix_length": 24 }' ``` **Error: response status is 409 Response body** ``` { "detail": "Insufficient space is available to accommodate the requested prefix size(s)" } ``` Despite there is a lot of available space in 10.182.0.0/15 in Global we could not create a child. ### Expected Behavior A new prefix 10.182.0.0/24 should have been created in Global ### Observed Behavior "Insufficient space is available to accommodate the requested prefix size(s)" error was returned But if we use strict method (POST api/ipam/prefixes/) to create a prefix we will succeed ``` curl -X 'POST' \ 'https://ipam.local/api/ipam/prefixes/' \ -H 'accept: application/json' \ -H 'Authorization: ***' \ -H 'Content-Type: application/json' \ -H 'X-CSRFToken: ***' \ -d '{ "prefix": "10.182.0.0/24", "status": "active", "custom_fields": {} }' ``` ``` { "id": 60006, "url": "https://ipam.local/api/ipam/prefixes/60006/", "display": "10.182.0.0/24", "family": { "value": 4, "label": "IPv4" }, "prefix": "10.182.0.0/24", "site": null, "vrf": null, "tenant": null, "vlan": null, "status": { "value": "active", "label": "Active" }, "role": null, "is_pool": false, "mark_utilized": false, "description": "", "tags": [], "custom_fields": {}, "created": "2022-08-23T16:28:04.574840+03:00", "last_updated": "2022-08-23T16:28:04.574862+03:00", "children": 0, "_depth": 0 } ``` Unfortunately this method is not protected by advisory lock as "available-prefixes" ![image](https://user-images.githubusercontent.com/91027081/186171050-9b4f9c40-660b-4c1c-b728-70081a896813.png)
adam added the type: bugstatus: accepted labels 2025-12-29 19:46:09 +01:00
adam closed this issue 2025-12-29 19:46:09 +01:00
Author
Owner

@jeremystretch commented on GitHub (Aug 23, 2022):

Had to do a bit of digging for this one. The root issue is that the Prefix model's get_child_prefixes() method specifically includes child prefixes from any VRF for containers in the global table. This was discussed back in #1073, before the available IPs endpoint was introduced. I'm honestly not sure if that behavior is still valid, but that's a tangent of this bug.

@jeremystretch commented on GitHub (Aug 23, 2022): Had to do a bit of digging for this one. The root issue is that the Prefix model's [`get_child_prefixes()`](https://github.com/netbox-community/netbox/blob/984d8b8ee6adc6a6e1b7713a133af312d67b883d/netbox/ipam/models/ip.py#L474) method specifically includes child prefixes from _any_ VRF for containers in the global table. This was discussed back in #1073, before the available IPs endpoint was introduced. I'm honestly not sure if that behavior is still valid, but that's a tangent of this bug.
Author
Owner

@jeremystretch commented on GitHub (Aug 23, 2022):

To avoid any potentially breaking changes to the existing behavior, I'm going to work around the get_child_prefixes() method for available prefix calculations.

@jeremystretch commented on GitHub (Aug 23, 2022): To avoid any potentially breaking changes to the existing behavior, I'm going to work around the `get_child_prefixes()` method for available prefix calculations.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#6861