mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-27 15:26:41 +00:00
Add alias config
This commit is contained in:
@@ -1,4 +1,10 @@
|
||||
import { clientSitesAssociationsCache, db, SiteResource, Transaction } from "@server/db";
|
||||
import {
|
||||
clientSitesAssociationsCache,
|
||||
db,
|
||||
SiteResource,
|
||||
siteResources,
|
||||
Transaction
|
||||
} from "@server/db";
|
||||
import { clients, orgs, sites } from "@server/db";
|
||||
import { and, eq, isNotNull } from "drizzle-orm";
|
||||
import config from "@server/lib/config";
|
||||
@@ -281,6 +287,56 @@ export async function getNextAvailableClientSubnet(
|
||||
return subnet;
|
||||
}
|
||||
|
||||
export async function getNextAvailableAliasAddress(
|
||||
orgId: string
|
||||
): Promise<string> {
|
||||
const [org] = await db.select().from(orgs).where(eq(orgs.orgId, orgId));
|
||||
|
||||
if (!org) {
|
||||
throw new Error(`Organization with ID ${orgId} not found`);
|
||||
}
|
||||
|
||||
if (!org.subnet) {
|
||||
throw new Error(`Organization with ID ${orgId} has no subnet defined`);
|
||||
}
|
||||
|
||||
if (!org.utilitySubnet) {
|
||||
throw new Error(
|
||||
`Organization with ID ${orgId} has no utility subnet defined`
|
||||
);
|
||||
}
|
||||
|
||||
const existingAddresses = await db
|
||||
.select({
|
||||
aliasAddress: siteResources.aliasAddress
|
||||
})
|
||||
.from(siteResources)
|
||||
.where(
|
||||
and(
|
||||
isNotNull(siteResources.aliasAddress),
|
||||
eq(siteResources.orgId, orgId)
|
||||
)
|
||||
);
|
||||
|
||||
const addresses = [
|
||||
...existingAddresses.map(
|
||||
(site) => `${site.aliasAddress?.split("/")[0]}/32`
|
||||
),
|
||||
// reserve a /29 for the dns server and other stuff
|
||||
`${org.utilitySubnet.split("/")[0]}/29`
|
||||
].filter((address) => address !== null) as string[];
|
||||
|
||||
let subnet = findNextAvailableCidr(addresses, 32, org.utilitySubnet);
|
||||
if (!subnet) {
|
||||
throw new Error("No available subnets remaining in space");
|
||||
}
|
||||
|
||||
// remove the cidr
|
||||
subnet = subnet.split("/")[0];
|
||||
|
||||
return subnet;
|
||||
}
|
||||
|
||||
export async function getNextAvailableOrgSubnet(): Promise<string> {
|
||||
const existingAddresses = await db
|
||||
.select({
|
||||
@@ -303,7 +359,9 @@ export async function getNextAvailableOrgSubnet(): Promise<string> {
|
||||
return subnet;
|
||||
}
|
||||
|
||||
export function generateRemoteSubnets(allSiteResources: SiteResource[]): string[] {
|
||||
export function generateRemoteSubnets(
|
||||
allSiteResources: SiteResource[]
|
||||
): string[] {
|
||||
let remoteSubnets = allSiteResources
|
||||
.filter((sr) => {
|
||||
if (sr.mode === "cidr") return true;
|
||||
@@ -327,6 +385,18 @@ export function generateRemoteSubnets(allSiteResources: SiteResource[]): string[
|
||||
return Array.from(new Set(remoteSubnets));
|
||||
}
|
||||
|
||||
export type Alias = { alias: string | null; aliasAddress: string | null };
|
||||
|
||||
export function generateAliasConfig(allSiteResources: SiteResource[]): Alias[] {
|
||||
let aliasConfigs = allSiteResources
|
||||
.filter((sr) => sr.alias && sr.aliasAddress && sr.mode == "host")
|
||||
.map((sr) => ({
|
||||
alias: sr.alias,
|
||||
aliasAddress: sr.aliasAddress
|
||||
}));
|
||||
return aliasConfigs;
|
||||
}
|
||||
|
||||
export type SubnetProxyTarget = {
|
||||
sourcePrefix: string;
|
||||
destPrefix: string;
|
||||
@@ -372,6 +442,14 @@ export function generateSubnetProxyTargets(
|
||||
destPrefix: `${siteResource.destination}/32`
|
||||
});
|
||||
}
|
||||
|
||||
if (siteResource.alias && siteResource.aliasAddress) {
|
||||
// also push a match for the alias address
|
||||
targets.push({
|
||||
sourcePrefix: clientPrefix,
|
||||
destPrefix: `${siteResource.aliasAddress}/32`
|
||||
});
|
||||
}
|
||||
} else if (siteResource.mode == "cidr") {
|
||||
targets.push({
|
||||
sourcePrefix: clientPrefix,
|
||||
@@ -386,4 +464,4 @@ export function generateSubnetProxyTargets(
|
||||
);
|
||||
|
||||
return targets;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,14 +31,15 @@ import {
|
||||
import { sendToExitNode } from "#dynamic/lib/exitNodes";
|
||||
import logger from "@server/logger";
|
||||
import {
|
||||
generateAliasConfig,
|
||||
generateRemoteSubnets,
|
||||
generateSubnetProxyTargets,
|
||||
SubnetProxyTarget
|
||||
} from "@server/lib/ip";
|
||||
import {
|
||||
addRemoteSubnets,
|
||||
addPeerData,
|
||||
addTargets as addSubnetProxyTargets,
|
||||
removeRemoteSubnets,
|
||||
removePeerData,
|
||||
removeTargets as removeSubnetProxyTargets
|
||||
} from "@server/routers/client/targets";
|
||||
|
||||
@@ -703,10 +704,11 @@ async function handleSubnetProxyTargetUpdates(
|
||||
|
||||
for (const client of addedClients) {
|
||||
olmJobs.push(
|
||||
addRemoteSubnets(
|
||||
addPeerData(
|
||||
client.clientId,
|
||||
siteResource.siteId,
|
||||
generateRemoteSubnets([siteResource])
|
||||
generateRemoteSubnets([siteResource]),
|
||||
generateAliasConfig([siteResource])
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -738,10 +740,11 @@ async function handleSubnetProxyTargetUpdates(
|
||||
|
||||
for (const client of removedClients) {
|
||||
olmJobs.push(
|
||||
removeRemoteSubnets(
|
||||
removePeerData(
|
||||
client.clientId,
|
||||
siteResource.siteId,
|
||||
generateRemoteSubnets([siteResource])
|
||||
generateRemoteSubnets([siteResource]),
|
||||
generateAliasConfig([siteResource])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user