mirror of
https://github.com/fosrl/pangolin.git
synced 2026-03-09 12:16:36 +00:00
Update blueprints to support new clients
This commit is contained in:
@@ -1,17 +1,23 @@
|
||||
import {
|
||||
clients,
|
||||
clientSiteResources,
|
||||
roles,
|
||||
roleSiteResources,
|
||||
SiteResource,
|
||||
siteResources,
|
||||
Transaction,
|
||||
userOrgs,
|
||||
users,
|
||||
userSiteResources
|
||||
} from "@server/db";
|
||||
import { sites } from "@server/db";
|
||||
import { eq, and } from "drizzle-orm";
|
||||
import {
|
||||
Config,
|
||||
} from "./types";
|
||||
import { eq, and, ne, inArray } from "drizzle-orm";
|
||||
import { Config } from "./types";
|
||||
import logger from "@server/logger";
|
||||
|
||||
export type ClientResourcesResults = {
|
||||
resource: SiteResource;
|
||||
newSiteResource: SiteResource;
|
||||
oldSiteResource?: SiteResource;
|
||||
}[];
|
||||
|
||||
export async function updateClientResources(
|
||||
@@ -69,17 +75,22 @@ export async function updateClientResources(
|
||||
}
|
||||
|
||||
if (existingResource) {
|
||||
if (existingResource.siteId !== site.siteId) {
|
||||
throw new Error(
|
||||
`You can not change the site of an existing client resource (${resourceNiceId}). Please delete and recreate it instead.`
|
||||
);
|
||||
}
|
||||
|
||||
// Update existing resource
|
||||
const [updatedResource] = await trx
|
||||
.update(siteResources)
|
||||
.set({
|
||||
name: resourceData.name || resourceNiceId,
|
||||
siteId: site.siteId,
|
||||
mode: "port",
|
||||
proxyPort: resourceData["proxy-port"]!,
|
||||
destination: resourceData.hostname,
|
||||
destinationPort: resourceData["internal-port"],
|
||||
protocol: resourceData.protocol
|
||||
mode: resourceData.mode,
|
||||
destination: resourceData.destination,
|
||||
enabled: true, // hardcoded for now
|
||||
// enabled: resourceData.enabled ?? true,
|
||||
alias: resourceData.alias || null
|
||||
})
|
||||
.where(
|
||||
eq(
|
||||
@@ -89,7 +100,110 @@ export async function updateClientResources(
|
||||
)
|
||||
.returning();
|
||||
|
||||
results.push({ resource: updatedResource });
|
||||
const siteResourceId = existingResource.siteResourceId;
|
||||
const orgId = existingResource.orgId;
|
||||
|
||||
await trx
|
||||
.delete(clientSiteResources)
|
||||
.where(eq(clientSiteResources.siteResourceId, siteResourceId));
|
||||
|
||||
if (resourceData.machines.length > 0) {
|
||||
// get clientIds from niceIds
|
||||
const clientsToUpdate = await trx
|
||||
.select()
|
||||
.from(clients)
|
||||
.where(
|
||||
and(
|
||||
inArray(clients.niceId, resourceData.machines),
|
||||
eq(clients.orgId, orgId)
|
||||
)
|
||||
);
|
||||
|
||||
const clientIds = clientsToUpdate.map(
|
||||
(client) => client.clientId
|
||||
);
|
||||
|
||||
await trx.insert(clientSiteResources).values(
|
||||
clientIds.map((clientId) => ({
|
||||
clientId,
|
||||
siteResourceId
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
await trx
|
||||
.delete(userSiteResources)
|
||||
.where(eq(userSiteResources.siteResourceId, siteResourceId));
|
||||
|
||||
if (resourceData.users.length > 0) {
|
||||
// get userIds from username
|
||||
const usersToUpdate = await trx
|
||||
.select()
|
||||
.from(users)
|
||||
.innerJoin(userOrgs, eq(users.userId, userOrgs.userId))
|
||||
.where(
|
||||
and(
|
||||
inArray(users.username, resourceData.users),
|
||||
eq(userOrgs.orgId, orgId)
|
||||
)
|
||||
);
|
||||
|
||||
const userIds = usersToUpdate.map((user) => user.user.userId);
|
||||
|
||||
await trx
|
||||
.insert(userSiteResources)
|
||||
.values(
|
||||
userIds.map((userId) => ({ userId, siteResourceId }))
|
||||
);
|
||||
}
|
||||
|
||||
// Get all admin role IDs for this org to exclude from deletion
|
||||
const adminRoles = await trx
|
||||
.select()
|
||||
.from(roles)
|
||||
.where(and(eq(roles.isAdmin, true), eq(roles.orgId, orgId)));
|
||||
const adminRoleIds = adminRoles.map((role) => role.roleId);
|
||||
|
||||
if (adminRoleIds.length > 0) {
|
||||
await trx.delete(roleSiteResources).where(
|
||||
and(
|
||||
eq(roleSiteResources.siteResourceId, siteResourceId),
|
||||
ne(roleSiteResources.roleId, adminRoleIds[0]) // delete all but the admin role
|
||||
)
|
||||
);
|
||||
} else {
|
||||
await trx
|
||||
.delete(roleSiteResources)
|
||||
.where(
|
||||
eq(roleSiteResources.siteResourceId, siteResourceId)
|
||||
);
|
||||
}
|
||||
|
||||
if (resourceData.roles.length > 0) {
|
||||
// Re-add specified roles but we need to get the roleIds from the role name in the array
|
||||
const rolesToUpdate = await trx
|
||||
.select()
|
||||
.from(roles)
|
||||
.where(
|
||||
and(
|
||||
eq(roles.orgId, orgId),
|
||||
inArray(roles.name, resourceData.roles)
|
||||
)
|
||||
);
|
||||
|
||||
const roleIds = rolesToUpdate.map((role) => role.roleId);
|
||||
|
||||
await trx
|
||||
.insert(roleSiteResources)
|
||||
.values(
|
||||
roleIds.map((roleId) => ({ roleId, siteResourceId }))
|
||||
);
|
||||
}
|
||||
|
||||
results.push({
|
||||
newSiteResource: updatedResource,
|
||||
oldSiteResource: existingResource
|
||||
});
|
||||
} else {
|
||||
// Create new resource
|
||||
const [newResource] = await trx
|
||||
@@ -99,19 +213,103 @@ export async function updateClientResources(
|
||||
siteId: site.siteId,
|
||||
niceId: resourceNiceId,
|
||||
name: resourceData.name || resourceNiceId,
|
||||
mode: "port",
|
||||
proxyPort: resourceData["proxy-port"]!,
|
||||
destination: resourceData.hostname,
|
||||
destinationPort: resourceData["internal-port"],
|
||||
protocol: resourceData.protocol
|
||||
mode: resourceData.mode,
|
||||
destination: resourceData.destination,
|
||||
enabled: true, // hardcoded for now
|
||||
// enabled: resourceData.enabled ?? true,
|
||||
alias: resourceData.alias || null
|
||||
})
|
||||
.returning();
|
||||
|
||||
const siteResourceId = newResource.siteResourceId;
|
||||
|
||||
const [adminRole] = await trx
|
||||
.select()
|
||||
.from(roles)
|
||||
.where(and(eq(roles.isAdmin, true), eq(roles.orgId, orgId)))
|
||||
.limit(1);
|
||||
|
||||
if (!adminRole) {
|
||||
throw new Error(`Admin role not found for org ${orgId}`);
|
||||
}
|
||||
|
||||
await trx.insert(roleSiteResources).values({
|
||||
roleId: adminRole.roleId,
|
||||
siteResourceId: siteResourceId
|
||||
});
|
||||
|
||||
if (resourceData.roles.length > 0) {
|
||||
// get roleIds from role names
|
||||
const rolesToUpdate = await trx
|
||||
.select()
|
||||
.from(roles)
|
||||
.where(
|
||||
and(
|
||||
eq(roles.orgId, orgId),
|
||||
inArray(roles.name, resourceData.roles)
|
||||
)
|
||||
);
|
||||
|
||||
const roleIds = rolesToUpdate.map((role) => role.roleId);
|
||||
|
||||
await trx
|
||||
.insert(roleSiteResources)
|
||||
.values(
|
||||
roleIds.map((roleId) => ({ roleId, siteResourceId }))
|
||||
);
|
||||
}
|
||||
|
||||
if (resourceData.users.length > 0) {
|
||||
// get userIds from username
|
||||
const usersToUpdate = await trx
|
||||
.select()
|
||||
.from(users)
|
||||
.innerJoin(userOrgs, eq(users.userId, userOrgs.userId))
|
||||
.where(
|
||||
and(
|
||||
inArray(users.username, resourceData.users),
|
||||
eq(userOrgs.orgId, orgId)
|
||||
)
|
||||
);
|
||||
|
||||
const userIds = usersToUpdate.map((user) => user.user.userId);
|
||||
|
||||
await trx
|
||||
.insert(userSiteResources)
|
||||
.values(
|
||||
userIds.map((userId) => ({ userId, siteResourceId }))
|
||||
);
|
||||
}
|
||||
|
||||
if (resourceData.machines.length > 0) {
|
||||
// get clientIds from niceIds
|
||||
const clientsToUpdate = await trx
|
||||
.select()
|
||||
.from(clients)
|
||||
.where(
|
||||
and(
|
||||
inArray(clients.niceId, resourceData.machines),
|
||||
eq(clients.orgId, orgId)
|
||||
)
|
||||
);
|
||||
|
||||
const clientIds = clientsToUpdate.map(
|
||||
(client) => client.clientId
|
||||
);
|
||||
|
||||
await trx.insert(clientSiteResources).values(
|
||||
clientIds.map((clientId) => ({
|
||||
clientId,
|
||||
siteResourceId
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
logger.info(
|
||||
`Created new client resource ${newResource.name} (${newResource.siteResourceId}) for org ${orgId}`
|
||||
);
|
||||
|
||||
results.push({ resource: newResource });
|
||||
results.push({ newSiteResource: newResource });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user