mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-17 02:16:38 +00:00
Working on targets
This commit is contained in:
@@ -6,7 +6,7 @@ import logger from "@server/logger";
|
||||
import { sites } from "@server/db";
|
||||
import { eq, and, isNotNull } from "drizzle-orm";
|
||||
import { addTargets as addProxyTargets } from "@server/routers/newt/targets";
|
||||
import { addTarget as addClientTargets } from "@server/routers/client/targets";
|
||||
import { addTargets as addClientTargets } from "@server/routers/client/targets";
|
||||
import {
|
||||
ClientResourcesResults,
|
||||
updateClientResources
|
||||
@@ -122,19 +122,17 @@ export async function applyBlueprint({
|
||||
)
|
||||
.limit(1);
|
||||
|
||||
if (site && result.resource.mode === "port" && result.resource.protocol && result.resource.proxyPort && result.resource.destinationPort) {
|
||||
logger.debug(
|
||||
`Updating client resource ${result.resource.siteResourceId} on site ${site.sites.siteId}`
|
||||
);
|
||||
logger.debug(
|
||||
`Updating client resource ${result.resource.siteResourceId} on site ${site.sites.siteId}`
|
||||
);
|
||||
|
||||
await addClientTargets(
|
||||
site.newt.newtId,
|
||||
result.resource.destination,
|
||||
result.resource.destinationPort,
|
||||
result.resource.protocol,
|
||||
result.resource.proxyPort
|
||||
);
|
||||
}
|
||||
// await addClientTargets(
|
||||
// site.newt.newtId,
|
||||
// result.resource.destination,
|
||||
// result.resource.destinationPort,
|
||||
// result.resource.protocol,
|
||||
// result.resource.proxyPort
|
||||
// );
|
||||
}
|
||||
|
||||
blueprintSucceeded = true;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { db, SiteResource } from "@server/db";
|
||||
import { clientSites, db, SiteResource, Transaction } from "@server/db";
|
||||
import { clients, orgs, sites } from "@server/db";
|
||||
import { and, eq, isNotNull } from "drizzle-orm";
|
||||
import config from "@server/lib/config";
|
||||
import z from "zod";
|
||||
import { getClientSiteResourceAccess } from "./rebuildSiteClientAssociations";
|
||||
import logger from "@server/logger";
|
||||
|
||||
interface IPRange {
|
||||
start: bigint;
|
||||
@@ -328,31 +330,47 @@ export function generateRemoteSubnetsStr(allSiteResources: SiteResource[]) {
|
||||
}
|
||||
|
||||
export type SubnetProxyTarget = {
|
||||
cidr: string;
|
||||
sourcePrefix: string;
|
||||
destPrefix: string;
|
||||
portRange?: {
|
||||
min: number;
|
||||
max: number;
|
||||
}[];
|
||||
};
|
||||
|
||||
export function generateSubnetProxyTargets(
|
||||
allSiteResources: SiteResource[]
|
||||
): SubnetProxyTarget[] {
|
||||
export async function generateSubnetProxyTargets(
|
||||
allSiteResources: SiteResource[],
|
||||
trx: Transaction | typeof db = db
|
||||
): Promise<SubnetProxyTarget[]> {
|
||||
let targets: SubnetProxyTarget[] = [];
|
||||
|
||||
for (const siteResource of allSiteResources) {
|
||||
if (siteResource.mode == "host") {
|
||||
// check if this is a valid ip
|
||||
const ipSchema = z.union([z.ipv4(), z.ipv6()]);
|
||||
if (ipSchema.safeParse(siteResource.destination).success) {
|
||||
const { mergedAllClients } =
|
||||
await getClientSiteResourceAccess(siteResource, trx);
|
||||
|
||||
if (mergedAllClients.length === 0) {
|
||||
logger.debug(`No clients have access to site resource ${siteResource.siteResourceId}, skipping target generation.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const clientSite of mergedAllClients) {
|
||||
const clientPrefix = `${clientSite.subnet.split("/")[0]}/32`;
|
||||
|
||||
if (siteResource.mode == "host") {
|
||||
// check if this is a valid ip
|
||||
const ipSchema = z.union([z.ipv4(), z.ipv6()]);
|
||||
if (ipSchema.safeParse(siteResource.destination).success) {
|
||||
targets.push({
|
||||
sourcePrefix: clientPrefix,
|
||||
destPrefix: `${siteResource.destination}/32`
|
||||
});
|
||||
}
|
||||
} else if (siteResource.mode == "cidr") {
|
||||
targets.push({
|
||||
cidr: `${siteResource.destination}/32`
|
||||
sourcePrefix: clientPrefix,
|
||||
destPrefix: siteResource.destination
|
||||
});
|
||||
}
|
||||
} else if (siteResource.mode == "cidr") {
|
||||
targets.push({
|
||||
cidr: siteResource.destination
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,24 +29,21 @@ import {
|
||||
} from "@server/routers/olm/peers";
|
||||
import { sendToExitNode } from "#dynamic/lib/exitNodes";
|
||||
import logger from "@server/logger";
|
||||
import z from "zod";
|
||||
import { generateRemoteSubnetsStr } from "@server/lib/ip";
|
||||
|
||||
export async function rebuildSiteClientAssociations(
|
||||
export async function getClientSiteResourceAccess(
|
||||
siteResource: SiteResource,
|
||||
trx: Transaction | typeof db = db
|
||||
): Promise<void> {
|
||||
const siteId = siteResource.siteId;
|
||||
|
||||
) {
|
||||
// get the site
|
||||
const [site] = await trx
|
||||
.select()
|
||||
.from(sites)
|
||||
.where(eq(sites.siteId, siteId))
|
||||
.where(eq(sites.siteId, siteResource.siteId))
|
||||
.limit(1);
|
||||
|
||||
if (!site) {
|
||||
throw new Error(`Site with ID ${siteId} not found`);
|
||||
throw new Error(`Site with ID ${siteResource.siteId} not found`);
|
||||
}
|
||||
|
||||
const roleIds = await trx
|
||||
@@ -87,27 +84,6 @@ export async function rebuildSiteClientAssociations(
|
||||
.from(clients)
|
||||
.where(inArray(clients.userId, newAllUserIds));
|
||||
|
||||
const existingClientSites = await trx
|
||||
.select({
|
||||
clientId: clientSites.clientId
|
||||
})
|
||||
.from(clientSites)
|
||||
.where(eq(clientSites.siteId, siteId));
|
||||
|
||||
const existingClientSiteIds = existingClientSites.map(
|
||||
(row) => row.clientId
|
||||
);
|
||||
|
||||
// Get full client details for existing clients (needed for sending delete messages)
|
||||
const existingClients = await trx
|
||||
.select({
|
||||
clientId: clients.clientId,
|
||||
pubKey: clients.pubKey,
|
||||
subnet: clients.subnet
|
||||
})
|
||||
.from(clients)
|
||||
.where(inArray(clients.clientId, existingClientSiteIds));
|
||||
|
||||
const allClientSiteResources = await trx // this is for if a client is directly associated with a resource instead of implicitly via a user
|
||||
.select()
|
||||
.from(clientSiteResources)
|
||||
@@ -134,6 +110,43 @@ export async function rebuildSiteClientAssociations(
|
||||
const mergedAllClients = Array.from(allClientsMap.values());
|
||||
const mergedAllClientIds = mergedAllClients.map((c) => c.clientId);
|
||||
|
||||
return {
|
||||
site,
|
||||
mergedAllClients,
|
||||
mergedAllClientIds
|
||||
};
|
||||
}
|
||||
|
||||
export async function rebuildSiteClientAssociations(
|
||||
siteResource: SiteResource,
|
||||
trx: Transaction | typeof db = db
|
||||
): Promise<void> {
|
||||
const siteId = siteResource.siteId;
|
||||
|
||||
const { site, mergedAllClients, mergedAllClientIds } =
|
||||
await getClientSiteResourceAccess(siteResource, trx);
|
||||
|
||||
const existingClientSites = await trx
|
||||
.select({
|
||||
clientId: clientSites.clientId
|
||||
})
|
||||
.from(clientSites)
|
||||
.where(eq(clientSites.siteId, siteResource.siteId));
|
||||
|
||||
const existingClientSiteIds = existingClientSites.map(
|
||||
(row) => row.clientId
|
||||
);
|
||||
|
||||
// Get full client details for existing clients (needed for sending delete messages)
|
||||
const existingClients = await trx
|
||||
.select({
|
||||
clientId: clients.clientId,
|
||||
pubKey: clients.pubKey,
|
||||
subnet: clients.subnet
|
||||
})
|
||||
.from(clients)
|
||||
.where(inArray(clients.clientId, existingClientSiteIds));
|
||||
|
||||
// ------------- calculations begin below -------------
|
||||
|
||||
const clientSitesToAdd = mergedAllClientIds.filter(
|
||||
@@ -345,7 +358,8 @@ async function handleMessagesForSiteClients(
|
||||
publicKey: site.publicKey,
|
||||
serverIP: site.address,
|
||||
serverPort: site.listenPort,
|
||||
remoteSubnets: generateRemoteSubnetsStr(allSiteResources)
|
||||
remoteSubnets:
|
||||
generateRemoteSubnetsStr(allSiteResources)
|
||||
},
|
||||
olm.olmId
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user