Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
RequestSystemReboot opened this issue Aug 23, 2022 · 2 comments · Fixed by #10114
Assignees
Labels
status: accepted This issue has been accepted for implementation type: bug A confirmed report of unexpected behavior in the application

Comments

@RequestSystemReboot
Copy link

RequestSystemReboot commented Aug 23, 2022

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

@RequestSystemReboot RequestSystemReboot added the type: bug A confirmed report of unexpected behavior in the application label Aug 23, 2022
@jeremystretch jeremystretch added the status: accepted This issue has been accepted for implementation label Aug 23, 2022
@jeremystretch jeremystretch self-assigned this Aug 23, 2022
@jeremystretch jeremystretch added status: under review Further discussion is needed to determine this issue's scope and/or implementation and removed status: accepted This issue has been accepted for implementation labels Aug 23, 2022
@jeremystretch
Copy link
Member

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 jeremystretch added status: accepted This issue has been accepted for implementation and removed status: under review Further discussion is needed to determine this issue's scope and/or implementation labels Aug 23, 2022
@jeremystretch
Copy link
Member

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 added a commit that referenced this issue Aug 23, 2022
Fixes #10109: Fix available prefixes calculation for container prefixes in the global table
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 22, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
status: accepted This issue has been accepted for implementation type: bug A confirmed report of unexpected behavior in the application
Projects
None yet
2 participants