netbox-community / netbox

The premier source of truth powering network automation. Open source under Apache 2. Public demo: https://demo.netbox.dev
http://netboxlabs.com/oss/netbox/
Apache License 2.0
15.38k stars 2.49k forks source link

Add API Endpoint for Retrieving Available Prefix for Specific Mask Length #15362

Closed talron23 closed 3 months ago

talron23 commented 4 months ago

NetBox version

v3.7.3

Feature type

Data model extension

Proposed functionality

I propose adding an API endpoint to NetBox that allows users to retrieve an available prefix for a specific mask length. Currently, the available prefixes functionality returns a list of prefixes that are nearby the root prefix. For example, for a given /11 prefix, it returns /12, /13, /14, and /15.

The new API endpoint would accept a mask length parameter and return an available prefix of that length. This would be particularly useful in automation use cases where specific prefix lengths are required.

The API endpoint /api/ipam/prefixes/{id}/available-prefixes/ should also accept as an input a prefix_length parameter, and in such case, NetBox will return a prefix with the desired prefix length.

Use case

This API endpoint would benefit NetBox users by providing a programmatic way to retrieve available prefixes for specific mask lengths. For example, in automated IP address assignment systems, users could query the API to request a specific mask length and receive an available prefix of that length, streamlining the process and ensuring efficient IP address allocation. This feature would enhance NetBox's utility in managing IP address space and improve automation workflows.

Database changes

No response

External dependencies

No response

jeremystretch commented 4 months ago

A GET request will indicate all available space, summarized as efficiently as possible, however you can specify an arbitrary prefix length (up to the size of the parent) when allocating new prefixes. For example, the below will allocate three /24s:

curl -X POST \
-H "Authorization: Token $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json; indent=4" \
http://netbox:8000/api/ipam/prefixes/1/available-prefixes/ \
--data '[{"prefix_length": 24}, {"prefix_length": 24}, {"prefix_length": 24}]'
talron23 commented 4 months ago

Thanks for the quick reply, but it still does not give us what we need for automating the IP address allocation in a single pipeline where we can then use the prefix we got through the API.

What we request is similar to #2100

For example, if we want to create an AWS VPC in Terraform and use a CIDR we are getting from NetBox, we need to be able to get the available CIDR before it is truly created. We could manage with the GET API for a list of available prefixes but it does not return a prefix with our desired prefix length.

Similar to how AWS IPAM can create a preview of an available CIDR to use for creating a VPC: https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest#vpc-cidr-from-aws-ip-address-manager-ipam We will be able to achieve the same with NetBox if there will be a GET API Endpoint for getting an available prefix per its length.

It's true we can first run the POST request to create an available prefix and then use it, but it won't help us automate it in a single pipeline. (because the aws vpc terraform module expects to know the cidr ahead of time)

jeremystretch commented 4 months ago

For example, if we want to create an AWS VPC in Terraform and use a CIDR we are getting from NetBox, we need to be able to get the available CIDR before it is truly created.

This is highly inadvisable because you are exposing a race condition: You cannot assume that a prefix available at one moment in time is still available a moment later. (This is especially dangerous when you have multiple competing consumers which all prescribe identical requirements for the "next" prefix or IP address.) The recommended approach would be to provision the new prefix first, perhaps marking its status as tentative in some manner, and then modify its attributes accordingly later in the provisioning process.

It's true we can first run the POST request to create an available prefix and then use it, but it won't help us automate it in a single pipeline.

I can't speak to the details of your specific implementation, but I can confirm that many NetBox users have had success utilizing the automated provisioning functionality in its current form.

talron23 commented 3 months ago

You cannot assume that a prefix available at one moment in time is still available a moment later.

I respect that but that is the only option to achieve our goal and similar products, like AWS IPAM can offer you a "preview" of the CIDR before it is created.

We need this functionality because of terraform behavior, as described here (https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest#vpc-cidr-from-aws-ip-address-manager-ipam), we must know the CIDR ahead of time so it means we can't do in a single "terraform apply" both provisioning the prefix and provisioning the VPC.

Currently, what we do is first provision the prefix independently and then we provision the VPC, but if we could get the available prefix via API, we could do it together.

If adding an API Endpoint for getting an Available prefix per length appears as not needed, it would be greatly appreciated if you could consider making the existing API Endpoint for getting the list of available prefixes more flexible. Currently, this API offers you a list of available prefixes - one prefix for each mask length. But then when you create such a prefix, it stops offering you prefixes at the same mask length. For example, whenever we create a /19 prefix, the API will stop sending a prefix at this length (you can see a /19 prefix is no longer offered):

image

Unfortunately, this makes this API not suitable for us as we can't rely on it as we'll be stuck if we need an available prefix at the length we already had. If we can make this API return a list of every prefix, no matter what prefixes are already inside the root prefix, it will greatly help us and make our request for an additional API endpoint not necessary.

Thanks.

jeremystretch commented 3 months ago

I'm not sure my point has landed. The workflow you're trying to achieve exposes a race condition and will break in the event two consumers compete for the same resource simultaneously. (NetBox employs database locks even for provisioning requests because this is a common problem.) The only workable solution is to provision the prefix first as I suggested above.

jeremystretch commented 3 months ago

Closing this out as the intended workflow described above does not offer sufficient justification for the implementation.