mirror of
https://github.com/fosrl/pangolin.git
synced 2025-07-27 22:25:58 +02:00
Fix ip picking from subnet in exclusion
This commit is contained in:
parent
fbe7e0a427
commit
4b6985718a
2 changed files with 33 additions and 14 deletions
|
@ -5,6 +5,13 @@ import { assertEquals } from "@test/assert";
|
|||
function testFindNextAvailableCidr() {
|
||||
console.log("Running findNextAvailableCidr tests...");
|
||||
|
||||
// Test 0: Basic IPv4 allocation with a subnet in the wrong range
|
||||
{
|
||||
const existing = ["100.90.130.1/30", "100.90.128.4/30"];
|
||||
const result = findNextAvailableCidr(existing, 30, "100.90.130.1/24");
|
||||
assertEquals(result, "100.90.130.4/30", "Basic IPv4 allocation failed");
|
||||
}
|
||||
|
||||
// Test 1: Basic IPv4 allocation
|
||||
{
|
||||
const existing = ["10.0.0.0/16", "10.1.0.0/16"];
|
||||
|
@ -26,6 +33,12 @@ function testFindNextAvailableCidr() {
|
|||
assertEquals(result, null, "No available space test failed");
|
||||
}
|
||||
|
||||
// Test 4: Empty existing
|
||||
{
|
||||
const existing: string[] = [];
|
||||
const result = findNextAvailableCidr(existing, 30, "10.0.0.0/8");
|
||||
assertEquals(result, "10.0.0.0/30", "Empty existing test failed");
|
||||
}
|
||||
// // Test 4: IPv6 allocation
|
||||
// {
|
||||
// const existing = ["2001:db8::/32", "2001:db8:1::/32"];
|
||||
|
|
|
@ -132,7 +132,6 @@ export function findNextAvailableCidr(
|
|||
blockSize: number,
|
||||
startCidr?: string
|
||||
): string | null {
|
||||
|
||||
if (!startCidr && existingCidrs.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
@ -151,6 +150,9 @@ export function findNextAvailableCidr(
|
|||
throw new Error('All CIDRs must be of the same IP version');
|
||||
}
|
||||
|
||||
// Extract the network part from startCidr to ensure we stay in the right subnet
|
||||
const startCidrRange = cidrToRange(startCidr);
|
||||
|
||||
// Convert existing CIDRs to ranges and sort them
|
||||
const existingRanges = existingCidrs
|
||||
.map(cidr => cidrToRange(cidr))
|
||||
|
@ -161,12 +163,13 @@ export function findNextAvailableCidr(
|
|||
const blockSizeBigInt = BigInt(1) << BigInt(maxPrefix - blockSize);
|
||||
|
||||
// Start from the beginning of the given CIDR
|
||||
let current = cidrToRange(startCidr).start;
|
||||
const maxIp = cidrToRange(startCidr).end;
|
||||
let current = startCidrRange.start;
|
||||
const maxIp = startCidrRange.end;
|
||||
|
||||
// Iterate through existing ranges
|
||||
for (let i = 0; i <= existingRanges.length; i++) {
|
||||
const nextRange = existingRanges[i];
|
||||
|
||||
// Align current to block size
|
||||
const alignedCurrent = current + ((blockSizeBigInt - (current % blockSizeBigInt)) % blockSizeBigInt);
|
||||
|
||||
|
@ -180,9 +183,12 @@ export function findNextAvailableCidr(
|
|||
return `${bigIntToIp(alignedCurrent, version)}/${blockSize}`;
|
||||
}
|
||||
|
||||
// If next range overlaps with our search space, move past it
|
||||
if (nextRange.end >= startCidrRange.start && nextRange.start <= maxIp) {
|
||||
// Move current pointer to after the current range
|
||||
current = nextRange.end + BigInt(1);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue