Working on targets

This commit is contained in:
Owen
2025-11-18 13:53:04 -05:00
parent 97c707248e
commit e72e2b53aa
11 changed files with 262 additions and 427 deletions

View File

@@ -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;

View File

@@ -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
});
}
}

View File

@@ -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
)