mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-18 21:55:24 +02:00
Change the audit action from "kill" to "stop" for the containerKill function to better reflect the operation being performed. This aligns the logging with the intended action and improves clarity in audit records.
302 lines
8.1 KiB
TypeScript
302 lines
8.1 KiB
TypeScript
import {
|
|
containerKill,
|
|
containerRemove,
|
|
containerRestart,
|
|
containerStart,
|
|
containerStop,
|
|
findServerById,
|
|
getConfig,
|
|
getContainers,
|
|
getContainersByAppLabel,
|
|
getContainersByAppNameMatch,
|
|
getServiceContainersByAppName,
|
|
getStackContainersByAppName,
|
|
uploadFileToContainer,
|
|
} from "@dokploy/server";
|
|
import { TRPCError } from "@trpc/server";
|
|
import { z } from "zod";
|
|
import { audit } from "@/server/api/utils/audit";
|
|
import { uploadFileToContainerSchema } from "@/utils/schema";
|
|
import { createTRPCRouter, withPermission } from "../trpc";
|
|
|
|
export const containerIdRegex = /^[a-zA-Z0-9.\-_]+$/;
|
|
|
|
export const dockerRouter = createTRPCRouter({
|
|
getContainers: withPermission("docker", "read")
|
|
.input(
|
|
z.object({
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.query(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
return await getContainers(input.serverId);
|
|
}),
|
|
|
|
restartContainer: withPermission("service", "read")
|
|
.input(
|
|
z.object({
|
|
containerId: z
|
|
.string()
|
|
.min(1)
|
|
.regex(containerIdRegex, "Invalid container id."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.mutation(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
await containerRestart(input.containerId, input.serverId);
|
|
await audit(ctx, {
|
|
action: "start",
|
|
resourceType: "docker",
|
|
resourceId: input.containerId,
|
|
resourceName: input.containerId,
|
|
});
|
|
}),
|
|
|
|
startContainer: withPermission("service", "read")
|
|
.input(
|
|
z.object({
|
|
containerId: z
|
|
.string()
|
|
.min(1)
|
|
.regex(containerIdRegex, "Invalid container id."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.mutation(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
await containerStart(input.containerId, input.serverId);
|
|
await audit(ctx, {
|
|
action: "start",
|
|
resourceType: "docker",
|
|
resourceId: input.containerId,
|
|
resourceName: input.containerId,
|
|
});
|
|
}),
|
|
|
|
stopContainer: withPermission("service", "read")
|
|
.input(
|
|
z.object({
|
|
containerId: z
|
|
.string()
|
|
.min(1)
|
|
.regex(containerIdRegex, "Invalid container id."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.mutation(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
await containerStop(input.containerId, input.serverId);
|
|
await audit(ctx, {
|
|
action: "stop",
|
|
resourceType: "docker",
|
|
resourceId: input.containerId,
|
|
resourceName: input.containerId,
|
|
});
|
|
}),
|
|
|
|
killContainer: withPermission("service", "read")
|
|
.input(
|
|
z.object({
|
|
containerId: z
|
|
.string()
|
|
.min(1)
|
|
.regex(containerIdRegex, "Invalid container id."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.mutation(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
await containerKill(input.containerId, input.serverId);
|
|
await audit(ctx, {
|
|
action: "stop",
|
|
resourceType: "docker",
|
|
resourceId: input.containerId,
|
|
resourceName: input.containerId,
|
|
});
|
|
}),
|
|
|
|
removeContainer: withPermission("docker", "read")
|
|
.input(
|
|
z.object({
|
|
containerId: z
|
|
.string()
|
|
.min(1)
|
|
.regex(containerIdRegex, "Invalid container id."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.mutation(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
await containerRemove(input.containerId, input.serverId);
|
|
await audit(ctx, {
|
|
action: "delete",
|
|
resourceType: "docker",
|
|
resourceId: input.containerId,
|
|
resourceName: input.containerId,
|
|
});
|
|
}),
|
|
|
|
getConfig: withPermission("docker", "read")
|
|
.input(
|
|
z.object({
|
|
containerId: z
|
|
.string()
|
|
.min(1)
|
|
.regex(containerIdRegex, "Invalid container id."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.query(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
return await getConfig(input.containerId, input.serverId);
|
|
}),
|
|
|
|
getContainersByAppNameMatch: withPermission("service", "read")
|
|
.input(
|
|
z.object({
|
|
appType: z.enum(["stack", "docker-compose"]).optional(),
|
|
appName: z.string().min(1).regex(containerIdRegex, "Invalid app name."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.query(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
return await getContainersByAppNameMatch(
|
|
input.appName,
|
|
input.appType,
|
|
input.serverId,
|
|
);
|
|
}),
|
|
|
|
getContainersByAppLabel: withPermission("docker", "read")
|
|
.input(
|
|
z.object({
|
|
appName: z.string().min(1).regex(containerIdRegex, "Invalid app name."),
|
|
serverId: z.string().optional(),
|
|
type: z.enum(["standalone", "swarm"]),
|
|
}),
|
|
)
|
|
.query(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
return await getContainersByAppLabel(
|
|
input.appName,
|
|
input.type,
|
|
input.serverId,
|
|
);
|
|
}),
|
|
|
|
getStackContainersByAppName: withPermission("docker", "read")
|
|
.input(
|
|
z.object({
|
|
appName: z.string().min(1).regex(containerIdRegex, "Invalid app name."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.query(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
return await getStackContainersByAppName(input.appName, input.serverId);
|
|
}),
|
|
|
|
getServiceContainersByAppName: withPermission("docker", "read")
|
|
.input(
|
|
z.object({
|
|
appName: z.string().min(1).regex(containerIdRegex, "Invalid app name."),
|
|
serverId: z.string().optional(),
|
|
}),
|
|
)
|
|
.query(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
return await getServiceContainersByAppName(input.appName, input.serverId);
|
|
}),
|
|
|
|
uploadFileToContainer: withPermission("docker", "read")
|
|
.input(uploadFileToContainerSchema)
|
|
.mutation(async ({ input, ctx }) => {
|
|
if (input.serverId) {
|
|
const server = await findServerById(input.serverId);
|
|
if (server.organizationId !== ctx.session?.activeOrganizationId) {
|
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
}
|
|
}
|
|
|
|
const file = input.file;
|
|
if (!(file instanceof File)) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Invalid file provided",
|
|
});
|
|
}
|
|
|
|
// Convert File to Buffer
|
|
const arrayBuffer = await file.arrayBuffer();
|
|
const fileBuffer = Buffer.from(arrayBuffer);
|
|
|
|
await uploadFileToContainer(
|
|
input.containerId,
|
|
fileBuffer,
|
|
file.name,
|
|
input.destinationPath,
|
|
input.serverId || null,
|
|
);
|
|
|
|
return { success: true, message: "File uploaded successfully" };
|
|
}),
|
|
});
|