Working on refactoring

This commit is contained in:
Owen
2026-03-19 12:10:04 -07:00
parent d8b511b198
commit 7cbe3d42a1
5 changed files with 156 additions and 75 deletions

View File

@@ -121,8 +121,8 @@ export async function applyBlueprint({
for (const result of clientResourcesResults) {
if (
result.oldSiteResource &&
result.oldSiteResource.siteId !=
result.newSiteResource.siteId
JSON.stringify(result.newSites?.sort()) !==
JSON.stringify(result.oldSites?.sort())
) {
// query existing associations
const existingRoleIds = await trx
@@ -222,13 +222,15 @@ export async function applyBlueprint({
trx
);
} else {
const [newSite] = await trx
let good = true;
for (const newSite of result.newSites) {
const [site] = await trx
.select()
.from(sites)
.innerJoin(newts, eq(sites.siteId, newts.siteId))
.where(
and(
eq(sites.siteId, result.newSiteResource.siteId),
eq(sites.siteId, newSite.siteId),
eq(sites.orgId, orgId),
eq(sites.type, "newt"),
isNotNull(sites.pubKey)
@@ -236,24 +238,30 @@ export async function applyBlueprint({
)
.limit(1);
if (!newSite) {
if (!site) {
logger.debug(
`No newt site found for client resource ${result.newSiteResource.siteResourceId}, skipping target update`
`No newt sites found for client resource ${result.newSiteResource.siteResourceId}, skipping target update`
);
continue;
good = false;
break;
}
logger.debug(
`Updating client resource ${result.newSiteResource.siteResourceId} on site ${newSite.sites.siteId}`
`Updating client resource ${result.newSiteResource.siteResourceId} on site ${newSite.siteId}`
);
}
if (!good) {
continue;
}
await handleMessagingForUpdatedSiteResource(
result.oldSiteResource,
result.newSiteResource,
{
siteId: newSite.sites.siteId,
orgId: newSite.sites.orgId
},
result.newSites.map((site) => ({
siteId: site.siteId,
orgId: result.newSiteResource.orgId
})),
trx
);
}

View File

@@ -3,8 +3,10 @@ import {
clientSiteResources,
roles,
roleSiteResources,
Site,
SiteResource,
siteResources,
siteSiteResources,
Transaction,
userOrgs,
users,
@@ -19,6 +21,8 @@ import { getNextAvailableAliasAddress } from "../ip";
export type ClientResourcesResults = {
newSiteResource: SiteResource;
oldSiteResource?: SiteResource;
newSites: { siteId: number }[];
oldSites: { siteId: number }[];
}[];
export async function updateClientResources(
@@ -43,12 +47,26 @@ export async function updateClientResources(
)
.limit(1);
const existingSiteIds = await trx
.select({ siteId: sites.siteId })
.from(siteSiteResources)
.where(
and(
eq(
siteSiteResources.siteResourceId,
existingResource.siteResourceId
)
)
);
let allSites: { siteId: number }[] = [];
if (resourceData.site) {
let siteSingle;
const resourceSiteId = resourceData.site;
let site;
if (resourceSiteId) {
// Look up site by niceId
[site] = await trx
[siteSingle] = await trx
.select({ siteId: sites.siteId })
.from(sites)
.where(
@@ -60,20 +78,45 @@ export async function updateClientResources(
.limit(1);
} else if (siteId) {
// Use the provided siteId directly, but verify it belongs to the org
[site] = await trx
[siteSingle] = await trx
.select({ siteId: sites.siteId })
.from(sites)
.where(and(eq(sites.siteId, siteId), eq(sites.orgId, orgId)))
.where(
and(eq(sites.siteId, siteId), eq(sites.orgId, orgId))
)
.limit(1);
} else {
throw new Error(`Target site is required`);
}
if (!site) {
if (!siteSingle) {
throw new Error(
`Site not found: ${resourceSiteId} in org ${orgId}`
);
}
allSites.push(siteSingle);
}
if (resourceData.sites) {
for (const siteNiceId of resourceData.sites) {
const [site] = await trx
.select({ siteId: sites.siteId })
.from(sites)
.where(
and(
eq(sites.niceId, siteNiceId),
eq(sites.orgId, orgId)
)
)
.limit(1);
if (!site) {
throw new Error(
`Site not found: ${siteId} in org ${orgId}`
);
}
allSites.push(site);
}
}
if (existingResource) {
// Update existing resource
@@ -81,7 +124,6 @@ export async function updateClientResources(
.update(siteResources)
.set({
name: resourceData.name || resourceNiceId,
siteId: site.siteId,
mode: resourceData.mode,
destination: resourceData.destination,
enabled: true, // hardcoded for now
@@ -102,6 +144,17 @@ export async function updateClientResources(
const siteResourceId = existingResource.siteResourceId;
const orgId = existingResource.orgId;
await trx
.delete(siteSiteResources)
.where(eq(siteSiteResources.siteResourceId, siteResourceId));
for (const site of allSites) {
await trx.insert(siteSiteResources).values({
siteId: site.siteId,
siteResourceId: siteResourceId
});
}
await trx
.delete(clientSiteResources)
.where(eq(clientSiteResources.siteResourceId, siteResourceId));
@@ -204,7 +257,9 @@ export async function updateClientResources(
results.push({
newSiteResource: updatedResource,
oldSiteResource: existingResource
oldSiteResource: existingResource,
newSites: allSites,
oldSites: existingSiteIds
});
} else {
let aliasAddress: string | null = null;
@@ -218,7 +273,6 @@ export async function updateClientResources(
.insert(siteResources)
.values({
orgId: orgId,
siteId: site.siteId,
niceId: resourceNiceId,
name: resourceData.name || resourceNiceId,
mode: resourceData.mode,
@@ -235,6 +289,13 @@ export async function updateClientResources(
const siteResourceId = newResource.siteResourceId;
for (const site of allSites) {
await trx.insert(siteSiteResources).values({
siteId: site.siteId,
siteResourceId: siteResourceId
});
}
const [adminRole] = await trx
.select()
.from(roles)
@@ -324,7 +385,11 @@ export async function updateClientResources(
`Created new client resource ${newResource.name} (${newResource.siteResourceId}) for org ${orgId}`
);
results.push({ newSiteResource: newResource });
results.push({
newSiteResource: newResource,
newSites: allSites,
oldSites: existingSiteIds
});
}
}

View File

@@ -312,7 +312,8 @@ export const ClientResourceSchema = z
.object({
name: z.string().min(1).max(255),
mode: z.enum(["host", "cidr"]),
site: z.string(),
site: z.string(), // DEPRECATED IN FAVOR OF sites
sites: z.array(z.string()).optional().default([]),
// protocol: z.enum(["tcp", "udp"]).optional(),
// proxyPort: z.int().positive().optional(),
// destinationPort: z.int().positive().optional(),

View File

@@ -366,18 +366,23 @@ export async function createSiteResource(
);
}
// Not sure what this is doing??
// const [newt] = await trx
// .select()
// .from(newts)
// .where(eq(newts.siteId, site.siteId))
// .limit(1);
for (const siteToAssign of sitesToAssign) {
const [newt] = await trx
.select()
.from(newts)
.where(eq(newts.siteId, siteToAssign.siteId))
.limit(1);
if (!newt) {
return next(
createHttpError(
HttpCode.NOT_FOUND,
`Newt not found for site ${siteToAssign.siteId}`
)
);
}
}
// if (!newt) {
// return next(
// createHttpError(HttpCode.NOT_FOUND, "Newt not found")
// );
// }
await rebuildClientAssociationsFromSiteResource(
newSiteResource,

View File

@@ -1,4 +1,4 @@
import { db, SiteResource, siteResources, sites } from "@server/db";
import { db, SiteResource, siteResources, sites, siteSiteResources } from "@server/db";
import response from "@server/lib/response";
import logger from "@server/logger";
import { OpenAPITags, registry } from "@server/openApi";
@@ -73,9 +73,9 @@ const listAllSiteResourcesByOrgQuerySchema = z.object({
export type ListAllSiteResourcesByOrgResponse = PaginatedResponse<{
siteResources: (SiteResource & {
siteName: string;
siteNiceId: string;
siteAddress: string | null;
siteNames: string[];
siteNiceIds: string[];
siteAddresses: (string | null)[];
})[];
}>;
@@ -83,7 +83,6 @@ function querySiteResourcesBase() {
return db
.select({
siteResourceId: siteResources.siteResourceId,
siteId: siteResources.siteId,
orgId: siteResources.orgId,
niceId: siteResources.niceId,
name: siteResources.name,
@@ -100,14 +99,17 @@ function querySiteResourcesBase() {
disableIcmp: siteResources.disableIcmp,
authDaemonMode: siteResources.authDaemonMode,
authDaemonPort: siteResources.authDaemonPort,
siteName: sites.name,
siteNiceId: sites.niceId,
siteAddress: sites.address
siteNames: sql<string[]>`array_agg(${sites.name})`,
siteNiceIds: sql<string[]>`array_agg(${sites.niceId})`,
siteAddresses: sql<(string | null)[]>`array_agg(${sites.address})`
})
.from(siteResources)
.innerJoin(sites, eq(siteResources.siteId, sites.siteId));
.innerJoin(siteSiteResources, eq(siteResources.siteResourceId, siteSiteResources.siteResourceId))
.innerJoin(sites, eq(siteSiteResources.siteId, sites.siteId))
.groupBy(siteResources.siteResourceId);
}
registry.registerPath({
method: "get",
path: "/org/{orgId}/site-resources",