mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-28 10:35:21 +02:00
- Introduced new test files for permission checks, including `check-permission.test.ts`, `enterprise-only-resources.test.ts`, `resolve-permissions.test.ts`, and `service-access.test.ts`. - Implemented permission checks in various components to ensure actions are gated by user permissions, including `ShowTraefikConfig`, `UpdateTraefikConfig`, `ShowVolumes`, `ShowDomains`, and others. - Enhanced the logic for displaying UI elements based on user permissions, ensuring that only authorized users can access or modify resources.
107 lines
2.7 KiB
TypeScript
107 lines
2.7 KiB
TypeScript
import {
|
|
type DockerNode,
|
|
execAsync,
|
|
execAsyncRemote,
|
|
findServerById,
|
|
getRemoteDocker,
|
|
} from "@dokploy/server";
|
|
import { TRPCError } from "@trpc/server";
|
|
import { z } from "zod";
|
|
import { audit } from "@/server/api/utils/audit";
|
|
import { getLocalServerIp } from "@/server/wss/terminal";
|
|
import { createTRPCRouter, withPermission } from "../trpc";
|
|
|
|
export const clusterRouter = createTRPCRouter({
|
|
getNodes: withPermission("server", "read")
|
|
.input(
|
|
z.object({
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.query(async ({ input }) => {
|
|
const docker = await getRemoteDocker(input.serverId);
|
|
const workers: DockerNode[] = await docker.listNodes();
|
|
return workers;
|
|
}),
|
|
|
|
removeWorker: withPermission("server", "delete")
|
|
.input(
|
|
z.object({
|
|
nodeId: z.string(),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.mutation(async ({ input, ctx }) => {
|
|
try {
|
|
const drainCommand = `docker node update --availability drain ${input.nodeId}`;
|
|
const removeCommand = `docker node rm ${input.nodeId} --force`;
|
|
|
|
if (input.serverId) {
|
|
await execAsyncRemote(input.serverId, drainCommand);
|
|
await execAsyncRemote(input.serverId, removeCommand);
|
|
} else {
|
|
await execAsync(drainCommand);
|
|
await execAsync(removeCommand);
|
|
}
|
|
await audit(ctx, {
|
|
action: "delete",
|
|
resourceType: "cluster",
|
|
resourceId: input.nodeId,
|
|
resourceName: input.nodeId,
|
|
});
|
|
return true;
|
|
} catch (error) {
|
|
throw new TRPCError({
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
message: "Error removing the node",
|
|
cause: error,
|
|
});
|
|
}
|
|
}),
|
|
|
|
addWorker: withPermission("server", "create")
|
|
.input(
|
|
z.object({
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.query(async ({ input }) => {
|
|
const docker = await getRemoteDocker(input.serverId);
|
|
const result = await docker.swarmInspect();
|
|
const docker_version = await docker.version();
|
|
|
|
let ip = await getLocalServerIp();
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
ip = server?.ipAddress;
|
|
}
|
|
|
|
return {
|
|
command: `docker swarm join --token ${result.JoinTokens.Worker} ${ip}:2377`,
|
|
version: docker_version.Version,
|
|
};
|
|
}),
|
|
|
|
addManager: withPermission("server", "create")
|
|
.input(
|
|
z.object({
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.query(async ({ input }) => {
|
|
const docker = await getRemoteDocker(input.serverId);
|
|
const result = await docker.swarmInspect();
|
|
const docker_version = await docker.version();
|
|
|
|
let ip = await getLocalServerIp();
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
ip = server?.ipAddress;
|
|
}
|
|
return {
|
|
command: `docker swarm join --token ${result.JoinTokens.Manager} ${ip}:2377`,
|
|
version: docker_version.Version,
|
|
};
|
|
}),
|
|
});
|