mirror of
https://github.com/fosrl/pangolin.git
synced 2026-05-20 15:55:31 +00:00
Add locks to allocations
This commit is contained in:
@@ -6,6 +6,7 @@ import z from "zod";
|
|||||||
import logger from "@server/logger";
|
import logger from "@server/logger";
|
||||||
import semver from "semver";
|
import semver from "semver";
|
||||||
import { getValidCertificatesForDomains } from "#dynamic/lib/certificates";
|
import { getValidCertificatesForDomains } from "#dynamic/lib/certificates";
|
||||||
|
import { lockManager } from "#dynamic/lib/lock";
|
||||||
|
|
||||||
interface IPRange {
|
interface IPRange {
|
||||||
start: bigint;
|
start: bigint;
|
||||||
@@ -327,6 +328,9 @@ export async function getNextAvailableClientSubnet(
|
|||||||
orgId: string,
|
orgId: string,
|
||||||
transaction: Transaction | typeof db = db
|
transaction: Transaction | typeof db = db
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
|
return await lockManager.withLock(
|
||||||
|
`client-subnet-allocation:${orgId}`,
|
||||||
|
async () => {
|
||||||
const [org] = await transaction
|
const [org] = await transaction
|
||||||
.select()
|
.select()
|
||||||
.from(orgs)
|
.from(orgs)
|
||||||
@@ -337,7 +341,9 @@ export async function getNextAvailableClientSubnet(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!org.subnet) {
|
if (!org.subnet) {
|
||||||
throw new Error(`Organization with ID ${orgId} has no subnet defined`);
|
throw new Error(
|
||||||
|
`Organization with ID ${orgId} has no subnet defined`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const existingAddressesSites = await transaction
|
const existingAddressesSites = await transaction
|
||||||
@@ -352,7 +358,9 @@ export async function getNextAvailableClientSubnet(
|
|||||||
address: clients.subnet
|
address: clients.subnet
|
||||||
})
|
})
|
||||||
.from(clients)
|
.from(clients)
|
||||||
.where(and(isNotNull(clients.subnet), eq(clients.orgId, orgId)));
|
.where(
|
||||||
|
and(isNotNull(clients.subnet), eq(clients.orgId, orgId))
|
||||||
|
);
|
||||||
|
|
||||||
const addresses = [
|
const addresses = [
|
||||||
...existingAddressesSites.map(
|
...existingAddressesSites.map(
|
||||||
@@ -369,20 +377,30 @@ export async function getNextAvailableClientSubnet(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return subnet;
|
return subnet;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getNextAvailableAliasAddress(
|
export async function getNextAvailableAliasAddress(
|
||||||
orgId: string,
|
orgId: string,
|
||||||
trx: Transaction | typeof db = db
|
trx: Transaction | typeof db = db
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const [org] = await trx.select().from(orgs).where(eq(orgs.orgId, orgId));
|
return await lockManager.withLock(
|
||||||
|
`alias-address-allocation:${orgId}`,
|
||||||
|
async () => {
|
||||||
|
const [org] = await trx
|
||||||
|
.select()
|
||||||
|
.from(orgs)
|
||||||
|
.where(eq(orgs.orgId, orgId));
|
||||||
|
|
||||||
if (!org) {
|
if (!org) {
|
||||||
throw new Error(`Organization with ID ${orgId} not found`);
|
throw new Error(`Organization with ID ${orgId} not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!org.subnet) {
|
if (!org.subnet) {
|
||||||
throw new Error(`Organization with ID ${orgId} has no subnet defined`);
|
throw new Error(
|
||||||
|
`Organization with ID ${orgId} has no subnet defined`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!org.utilitySubnet) {
|
if (!org.utilitySubnet) {
|
||||||
@@ -411,7 +429,11 @@ export async function getNextAvailableAliasAddress(
|
|||||||
`${org.utilitySubnet.split("/")[0]}/29`
|
`${org.utilitySubnet.split("/")[0]}/29`
|
||||||
].filter((address) => address !== null) as string[];
|
].filter((address) => address !== null) as string[];
|
||||||
|
|
||||||
let subnet = findNextAvailableCidr(addresses, 32, org.utilitySubnet);
|
let subnet = findNextAvailableCidr(
|
||||||
|
addresses,
|
||||||
|
32,
|
||||||
|
org.utilitySubnet
|
||||||
|
);
|
||||||
if (!subnet) {
|
if (!subnet) {
|
||||||
throw new Error("No available subnets remaining in space");
|
throw new Error("No available subnets remaining in space");
|
||||||
}
|
}
|
||||||
@@ -420,9 +442,12 @@ export async function getNextAvailableAliasAddress(
|
|||||||
subnet = subnet.split("/")[0];
|
subnet = subnet.split("/")[0];
|
||||||
|
|
||||||
return subnet;
|
return subnet;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getNextAvailableOrgSubnet(): Promise<string> {
|
export async function getNextAvailableOrgSubnet(): Promise<string> {
|
||||||
|
return await lockManager.withLock("org-subnet-allocation", async () => {
|
||||||
const existingAddresses = await db
|
const existingAddresses = await db
|
||||||
.select({
|
.select({
|
||||||
subnet: orgs.subnet
|
subnet: orgs.subnet
|
||||||
@@ -442,6 +467,7 @@ export async function getNextAvailableOrgSubnet(): Promise<string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return subnet;
|
return subnet;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateRemoteSubnets(
|
export function generateRemoteSubnets(
|
||||||
|
|||||||
Reference in New Issue
Block a user