mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-07-15 02:45:23 +02:00
Merge branch 'canary' into feat/ntfy
This commit is contained in:
@@ -105,7 +105,11 @@ export const findApplicationById = async (applicationId: string) => {
|
||||
const application = await db.query.applications.findFirst({
|
||||
where: eq(applications.applicationId, applicationId),
|
||||
with: {
|
||||
project: true,
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
domains: true,
|
||||
deployments: true,
|
||||
mounts: true,
|
||||
@@ -180,7 +184,7 @@ export const deployApplication = async ({
|
||||
}) => {
|
||||
const application = await findApplicationById(applicationId);
|
||||
|
||||
const buildLink = `${await getDokployUrl()}/dashboard/project/${application.projectId}/services/application/${application.applicationId}?tab=deployments`;
|
||||
const buildLink = `${await getDokployUrl()}/dashboard/project/${application.environment.projectId}/environment/${application.environmentId}/services/application/${application.applicationId}?tab=deployments`;
|
||||
const deployment = await createDeployment({
|
||||
applicationId: applicationId,
|
||||
title: titleLog,
|
||||
@@ -227,11 +231,11 @@ export const deployApplication = async ({
|
||||
}
|
||||
|
||||
await sendBuildSuccessNotifications({
|
||||
projectName: application.project.name,
|
||||
projectName: application.environment.project.name,
|
||||
applicationName: application.name,
|
||||
applicationType: "application",
|
||||
buildLink,
|
||||
organizationId: application.project.organizationId,
|
||||
organizationId: application.environment.project.organizationId,
|
||||
domains: application.domains,
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -239,13 +243,13 @@ export const deployApplication = async ({
|
||||
await updateApplicationStatus(applicationId, "error");
|
||||
|
||||
await sendBuildErrorNotifications({
|
||||
projectName: application.project.name,
|
||||
projectName: application.environment.project.name,
|
||||
applicationName: application.name,
|
||||
applicationType: "application",
|
||||
// @ts-ignore
|
||||
errorMessage: error?.message || "Error building",
|
||||
buildLink,
|
||||
organizationId: application.project.organizationId,
|
||||
organizationId: application.environment.project.organizationId,
|
||||
});
|
||||
|
||||
throw error;
|
||||
@@ -307,7 +311,7 @@ export const deployRemoteApplication = async ({
|
||||
}) => {
|
||||
const application = await findApplicationById(applicationId);
|
||||
|
||||
const buildLink = `${await getDokployUrl()}/dashboard/project/${application.projectId}/services/application/${application.applicationId}?tab=deployments`;
|
||||
const buildLink = `${await getDokployUrl()}/dashboard/project/${application.environment.projectId}/environment/${application.environmentId}/services/application/${application.applicationId}?tab=deployments`;
|
||||
const deployment = await createDeployment({
|
||||
applicationId: applicationId,
|
||||
title: titleLog,
|
||||
@@ -363,11 +367,11 @@ export const deployRemoteApplication = async ({
|
||||
}
|
||||
|
||||
await sendBuildSuccessNotifications({
|
||||
projectName: application.project.name,
|
||||
projectName: application.environment.project.name,
|
||||
applicationName: application.name,
|
||||
applicationType: "application",
|
||||
buildLink,
|
||||
organizationId: application.project.organizationId,
|
||||
organizationId: application.environment.project.organizationId,
|
||||
domains: application.domains,
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -387,12 +391,12 @@ export const deployRemoteApplication = async ({
|
||||
await updateApplicationStatus(applicationId, "error");
|
||||
|
||||
await sendBuildErrorNotifications({
|
||||
projectName: application.project.name,
|
||||
projectName: application.environment.project.name,
|
||||
applicationName: application.name,
|
||||
applicationType: "application",
|
||||
errorMessage: `Please check the logs for details: ${errorMessage}`,
|
||||
buildLink,
|
||||
organizationId: application.project.organizationId,
|
||||
organizationId: application.environment.project.organizationId,
|
||||
});
|
||||
|
||||
throw error;
|
||||
|
||||
@@ -126,7 +126,11 @@ export const findComposeById = async (composeId: string) => {
|
||||
const result = await db.query.compose.findFirst({
|
||||
where: eq(compose.composeId, composeId),
|
||||
with: {
|
||||
project: true,
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
deployments: true,
|
||||
mounts: true,
|
||||
domains: true,
|
||||
@@ -222,7 +226,7 @@ export const deployCompose = async ({
|
||||
const compose = await findComposeById(composeId);
|
||||
|
||||
const buildLink = `${await getDokployUrl()}/dashboard/project/${
|
||||
compose.projectId
|
||||
compose.environment.projectId
|
||||
}/services/compose/${compose.composeId}?tab=deployments`;
|
||||
const deployment = await createDeploymentCompose({
|
||||
composeId: composeId,
|
||||
@@ -255,11 +259,11 @@ export const deployCompose = async ({
|
||||
});
|
||||
|
||||
await sendBuildSuccessNotifications({
|
||||
projectName: compose.project.name,
|
||||
projectName: compose.environment.project.name,
|
||||
applicationName: compose.name,
|
||||
applicationType: "compose",
|
||||
buildLink,
|
||||
organizationId: compose.project.organizationId,
|
||||
organizationId: compose.environment.project.organizationId,
|
||||
domains: compose.domains,
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -268,13 +272,13 @@ export const deployCompose = async ({
|
||||
composeStatus: "error",
|
||||
});
|
||||
await sendBuildErrorNotifications({
|
||||
projectName: compose.project.name,
|
||||
projectName: compose.environment.project.name,
|
||||
applicationName: compose.name,
|
||||
applicationType: "compose",
|
||||
// @ts-ignore
|
||||
errorMessage: error?.message || "Error building",
|
||||
buildLink,
|
||||
organizationId: compose.project.organizationId,
|
||||
organizationId: compose.environment.project.organizationId,
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
@@ -330,7 +334,7 @@ export const deployRemoteCompose = async ({
|
||||
const compose = await findComposeById(composeId);
|
||||
|
||||
const buildLink = `${await getDokployUrl()}/dashboard/project/${
|
||||
compose.projectId
|
||||
compose.environment.projectId
|
||||
}/services/compose/${compose.composeId}?tab=deployments`;
|
||||
const deployment = await createDeploymentCompose({
|
||||
composeId: composeId,
|
||||
@@ -387,11 +391,11 @@ export const deployRemoteCompose = async ({
|
||||
});
|
||||
|
||||
await sendBuildSuccessNotifications({
|
||||
projectName: compose.project.name,
|
||||
projectName: compose.environment.project.name,
|
||||
applicationName: compose.name,
|
||||
applicationType: "compose",
|
||||
buildLink,
|
||||
organizationId: compose.project.organizationId,
|
||||
organizationId: compose.environment.project.organizationId,
|
||||
domains: compose.domains,
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -410,13 +414,13 @@ export const deployRemoteCompose = async ({
|
||||
composeStatus: "error",
|
||||
});
|
||||
await sendBuildErrorNotifications({
|
||||
projectName: compose.project.name,
|
||||
projectName: compose.environment.project.name,
|
||||
applicationName: compose.name,
|
||||
applicationType: "compose",
|
||||
// @ts-ignore
|
||||
errorMessage: error?.message || "Error building",
|
||||
buildLink,
|
||||
organizationId: compose.project.organizationId,
|
||||
organizationId: compose.environment.project.organizationId,
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
|
||||
140
packages/server/src/services/environment.ts
Normal file
140
packages/server/src/services/environment.ts
Normal file
@@ -0,0 +1,140 @@
|
||||
import { db } from "@dokploy/server/db";
|
||||
import {
|
||||
type apiCreateEnvironment,
|
||||
type apiDuplicateEnvironment,
|
||||
environments,
|
||||
} from "@dokploy/server/db/schema";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { asc, eq } from "drizzle-orm";
|
||||
|
||||
export type Environment = typeof environments.$inferSelect;
|
||||
|
||||
export const createEnvironment = async (
|
||||
input: typeof apiCreateEnvironment._type,
|
||||
) => {
|
||||
const newEnvironment = await db
|
||||
.insert(environments)
|
||||
.values({
|
||||
...input,
|
||||
})
|
||||
.returning()
|
||||
.then((value) => value[0]);
|
||||
|
||||
if (!newEnvironment) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error creating the environment",
|
||||
});
|
||||
}
|
||||
|
||||
return newEnvironment;
|
||||
};
|
||||
|
||||
export const findEnvironmentById = async (environmentId: string) => {
|
||||
const environment = await db.query.environments.findFirst({
|
||||
where: eq(environments.environmentId, environmentId),
|
||||
with: {
|
||||
applications: true,
|
||||
mariadb: true,
|
||||
mongo: true,
|
||||
mysql: true,
|
||||
postgres: true,
|
||||
redis: true,
|
||||
compose: true,
|
||||
project: true,
|
||||
},
|
||||
});
|
||||
if (!environment) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
message: "Environment not found",
|
||||
});
|
||||
}
|
||||
return environment;
|
||||
};
|
||||
|
||||
export const findEnvironmentsByProjectId = async (projectId: string) => {
|
||||
const projectEnvironments = await db.query.environments.findMany({
|
||||
where: eq(environments.projectId, projectId),
|
||||
orderBy: asc(environments.createdAt),
|
||||
with: {
|
||||
applications: true,
|
||||
mariadb: true,
|
||||
mongo: true,
|
||||
mysql: true,
|
||||
postgres: true,
|
||||
redis: true,
|
||||
compose: true,
|
||||
project: true,
|
||||
},
|
||||
});
|
||||
return projectEnvironments;
|
||||
};
|
||||
|
||||
export const deleteEnvironment = async (environmentId: string) => {
|
||||
const currentEnvironment = await findEnvironmentById(environmentId);
|
||||
if (currentEnvironment.name === "production") {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "You cannot delete the production environment",
|
||||
});
|
||||
}
|
||||
const deletedEnvironment = await db
|
||||
.delete(environments)
|
||||
.where(eq(environments.environmentId, environmentId))
|
||||
.returning()
|
||||
.then((value) => value[0]);
|
||||
|
||||
return deletedEnvironment;
|
||||
};
|
||||
|
||||
export const updateEnvironmentById = async (
|
||||
environmentId: string,
|
||||
environmentData: Partial<Environment>,
|
||||
) => {
|
||||
const result = await db
|
||||
.update(environments)
|
||||
.set({
|
||||
...environmentData,
|
||||
})
|
||||
.where(eq(environments.environmentId, environmentId))
|
||||
.returning()
|
||||
.then((res) => res[0]);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export const duplicateEnvironment = async (
|
||||
input: typeof apiDuplicateEnvironment._type,
|
||||
) => {
|
||||
// Find the original environment
|
||||
const originalEnvironment = await findEnvironmentById(input.environmentId);
|
||||
|
||||
// Create a new environment with the provided name and description
|
||||
const newEnvironment = await db
|
||||
.insert(environments)
|
||||
.values({
|
||||
name: input.name,
|
||||
description: input.description || originalEnvironment.description,
|
||||
projectId: originalEnvironment.projectId,
|
||||
})
|
||||
.returning()
|
||||
.then((value) => value[0]);
|
||||
|
||||
if (!newEnvironment) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error duplicating the environment",
|
||||
});
|
||||
}
|
||||
|
||||
return newEnvironment;
|
||||
};
|
||||
|
||||
export const createProductionEnvironment = async (projectId: string) => {
|
||||
return createEnvironment({
|
||||
name: "production",
|
||||
description: "Production environment",
|
||||
projectId,
|
||||
});
|
||||
};
|
||||
@@ -56,7 +56,11 @@ export const findMariadbById = async (mariadbId: string) => {
|
||||
const result = await db.query.mariadb.findFirst({
|
||||
where: eq(mariadb.mariadbId, mariadbId),
|
||||
with: {
|
||||
project: true,
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
mounts: true,
|
||||
server: true,
|
||||
backups: {
|
||||
|
||||
@@ -53,7 +53,11 @@ export const findMongoById = async (mongoId: string) => {
|
||||
const result = await db.query.mongo.findFirst({
|
||||
where: eq(mongo.mongoId, mongoId),
|
||||
with: {
|
||||
project: true,
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
mounts: true,
|
||||
server: true,
|
||||
backups: {
|
||||
|
||||
@@ -105,13 +105,69 @@ export const findMountById = async (mountId: string) => {
|
||||
const mount = await db.query.mounts.findFirst({
|
||||
where: eq(mounts.mountId, mountId),
|
||||
with: {
|
||||
application: true,
|
||||
postgres: true,
|
||||
mariadb: true,
|
||||
mongo: true,
|
||||
mysql: true,
|
||||
redis: true,
|
||||
compose: true,
|
||||
application: {
|
||||
with: {
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
postgres: {
|
||||
with: {
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
mariadb: {
|
||||
with: {
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
mongo: {
|
||||
with: {
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
mysql: {
|
||||
with: {
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
redis: {
|
||||
with: {
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
compose: {
|
||||
with: {
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!mount) {
|
||||
@@ -123,6 +179,34 @@ export const findMountById = async (mountId: string) => {
|
||||
return mount;
|
||||
};
|
||||
|
||||
export const findMountOrganizationId = async (mountId: string) => {
|
||||
const mount = await findMountById(mountId);
|
||||
|
||||
if (mount.application) {
|
||||
return mount.application.environment.project.organizationId;
|
||||
}
|
||||
if (mount.postgres) {
|
||||
return mount.postgres.environment.project.organizationId;
|
||||
}
|
||||
if (mount.mariadb) {
|
||||
return mount.mariadb.environment.project.organizationId;
|
||||
}
|
||||
if (mount.mongo) {
|
||||
return mount.mongo.environment.project.organizationId;
|
||||
}
|
||||
if (mount.mysql) {
|
||||
return mount.mysql.environment.project.organizationId;
|
||||
}
|
||||
if (mount.redis) {
|
||||
return mount.redis.environment.project.organizationId;
|
||||
}
|
||||
|
||||
if (mount.compose) {
|
||||
return mount.compose.environment.project.organizationId;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const updateMount = async (
|
||||
mountId: string,
|
||||
mountData: Partial<Mount>,
|
||||
|
||||
@@ -56,7 +56,11 @@ export const findMySqlById = async (mysqlId: string) => {
|
||||
const result = await db.query.mysql.findFirst({
|
||||
where: eq(mysql.mysqlId, mysqlId),
|
||||
with: {
|
||||
project: true,
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
mounts: true,
|
||||
server: true,
|
||||
backups: {
|
||||
|
||||
@@ -27,6 +27,17 @@ export const createPort = async (input: typeof apiCreatePort._type) => {
|
||||
export const finPortById = async (portId: string) => {
|
||||
const result = await db.query.ports.findFirst({
|
||||
where: eq(ports.portId, portId),
|
||||
with: {
|
||||
application: {
|
||||
with: {
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!result) {
|
||||
throw new TRPCError({
|
||||
|
||||
@@ -51,7 +51,11 @@ export const findPostgresById = async (postgresId: string) => {
|
||||
const result = await db.query.postgres.findFirst({
|
||||
where: eq(postgres.postgresId, postgresId),
|
||||
with: {
|
||||
project: true,
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
mounts: true,
|
||||
server: true,
|
||||
backups: {
|
||||
|
||||
@@ -31,7 +31,11 @@ export const findPreviewDeploymentById = async (
|
||||
application: {
|
||||
with: {
|
||||
server: true,
|
||||
project: true,
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -45,37 +49,6 @@ export const findPreviewDeploymentById = async (
|
||||
return application;
|
||||
};
|
||||
|
||||
export const findApplicationByPreview = async (applicationId: string) => {
|
||||
const application = await db.query.applications.findFirst({
|
||||
with: {
|
||||
previewDeployments: {
|
||||
where: eq(previewDeployments.applicationId, applicationId),
|
||||
},
|
||||
project: true,
|
||||
domains: true,
|
||||
deployments: true,
|
||||
mounts: true,
|
||||
redirects: true,
|
||||
security: true,
|
||||
ports: true,
|
||||
registry: true,
|
||||
gitlab: true,
|
||||
github: true,
|
||||
bitbucket: true,
|
||||
gitea: true,
|
||||
server: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!application) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
message: "Application not found",
|
||||
});
|
||||
}
|
||||
return application;
|
||||
};
|
||||
|
||||
export const removePreviewDeployment = async (previewDeploymentId: string) => {
|
||||
try {
|
||||
const previewDeployment =
|
||||
@@ -163,7 +136,7 @@ export const createPreviewDeployment = async (
|
||||
const appName = `preview-${application.appName}-${generatePassword(6)}`;
|
||||
|
||||
const org = await db.query.organization.findFirst({
|
||||
where: eq(organization.id, application.project.organizationId),
|
||||
where: eq(organization.id, application.environment.project.organizationId),
|
||||
});
|
||||
const generateDomain = await generateWildcardDomain(
|
||||
application.previewWildcard || "*.traefik.me",
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from "@dokploy/server/db/schema";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { createProductionEnvironment } from "./environment";
|
||||
|
||||
export type Project = typeof projects.$inferSelect;
|
||||
|
||||
@@ -34,20 +35,31 @@ export const createProject = async (
|
||||
});
|
||||
}
|
||||
|
||||
return newProject;
|
||||
// Automatically create a production environment
|
||||
const newEnvironment = await createProductionEnvironment(
|
||||
newProject.projectId,
|
||||
);
|
||||
return {
|
||||
project: newProject,
|
||||
environment: newEnvironment,
|
||||
};
|
||||
};
|
||||
|
||||
export const findProjectById = async (projectId: string) => {
|
||||
const project = await db.query.projects.findFirst({
|
||||
where: eq(projects.projectId, projectId),
|
||||
with: {
|
||||
applications: true,
|
||||
mariadb: true,
|
||||
mongo: true,
|
||||
mysql: true,
|
||||
postgres: true,
|
||||
redis: true,
|
||||
compose: true,
|
||||
environments: {
|
||||
with: {
|
||||
applications: true,
|
||||
mariadb: true,
|
||||
mongo: true,
|
||||
mysql: true,
|
||||
postgres: true,
|
||||
redis: true,
|
||||
compose: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!project) {
|
||||
@@ -86,7 +98,7 @@ export const updateProjectById = async (
|
||||
};
|
||||
|
||||
export const validUniqueServerAppName = async (appName: string) => {
|
||||
const query = await db.query.projects.findMany({
|
||||
const query = await db.query.environments.findMany({
|
||||
with: {
|
||||
applications: {
|
||||
where: eq(applications.appName, appName),
|
||||
|
||||
@@ -52,7 +52,11 @@ export const findRedisById = async (redisId: string) => {
|
||||
const result = await db.query.redis.findFirst({
|
||||
where: eq(redis.redisId, redisId),
|
||||
with: {
|
||||
project: true,
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
mounts: true,
|
||||
server: true,
|
||||
},
|
||||
|
||||
@@ -76,9 +76,24 @@ export const createRollback = async (
|
||||
});
|
||||
};
|
||||
|
||||
const findRollbackById = async (rollbackId: string) => {
|
||||
export const findRollbackById = async (rollbackId: string) => {
|
||||
const result = await db.query.rollbacks.findFirst({
|
||||
where: eq(rollbacks.rollbackId, rollbackId),
|
||||
with: {
|
||||
deployment: {
|
||||
with: {
|
||||
application: {
|
||||
with: {
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
@@ -179,7 +194,9 @@ const rollbackApplication = async (
|
||||
image: string,
|
||||
serverId?: string | null,
|
||||
fullContext?: Application & {
|
||||
project: Project;
|
||||
environment: {
|
||||
project: Project;
|
||||
};
|
||||
mounts: Mount[];
|
||||
ports: Port[];
|
||||
},
|
||||
@@ -225,7 +242,7 @@ const rollbackApplication = async (
|
||||
const bindsMount = generateBindMounts(mounts);
|
||||
const envVariables = prepareEnvironmentVariables(
|
||||
env,
|
||||
fullContext.project.env,
|
||||
fullContext.environment.project.env,
|
||||
);
|
||||
|
||||
// For rollback, we use the provided image instead of calculating it
|
||||
|
||||
@@ -35,9 +35,29 @@ export const findScheduleById = async (scheduleId: string) => {
|
||||
const schedule = await db.query.schedules.findFirst({
|
||||
where: eq(schedules.scheduleId, scheduleId),
|
||||
with: {
|
||||
application: true,
|
||||
compose: true,
|
||||
server: true,
|
||||
application: {
|
||||
with: {
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
compose: {
|
||||
with: {
|
||||
environment: {
|
||||
with: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
server: {
|
||||
with: {
|
||||
organization: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -50,6 +70,21 @@ export const findScheduleById = async (scheduleId: string) => {
|
||||
return schedule;
|
||||
};
|
||||
|
||||
export const findScheduleOrganizationId = async (scheduleId: string) => {
|
||||
const schedule = await findScheduleById(scheduleId);
|
||||
|
||||
if (schedule?.application) {
|
||||
return schedule?.application?.environment?.project?.organizationId;
|
||||
}
|
||||
if (schedule?.compose) {
|
||||
return schedule?.compose?.environment?.project?.organizationId;
|
||||
}
|
||||
if (schedule?.server) {
|
||||
return schedule?.server?.organization?.id;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const deleteSchedule = async (scheduleId: string) => {
|
||||
const schedule = await findScheduleById(scheduleId);
|
||||
const serverId =
|
||||
|
||||
@@ -253,37 +253,36 @@ export const getDockerResourceType = async (
|
||||
resourceName: string,
|
||||
serverId?: string,
|
||||
) => {
|
||||
let result = "";
|
||||
const command = `
|
||||
RESOURCE_NAME="${resourceName}"
|
||||
if docker service inspect "$RESOURCE_NAME" &>/dev/null; then
|
||||
echo "service"
|
||||
exit 0
|
||||
fi
|
||||
try {
|
||||
let result = "";
|
||||
const command = `
|
||||
RESOURCE_NAME="${resourceName}"
|
||||
if docker service inspect "$RESOURCE_NAME" >/dev/null 2>&1; then
|
||||
echo "service"
|
||||
elif docker inspect "$RESOURCE_NAME" >/dev/null 2>&1; then
|
||||
echo "standalone"
|
||||
else
|
||||
echo "unknown"
|
||||
fi`;
|
||||
|
||||
if docker inspect "$RESOURCE_NAME" &>/dev/null; then
|
||||
echo "standalone"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "unknown"
|
||||
exit 0
|
||||
`;
|
||||
|
||||
if (serverId) {
|
||||
const { stdout } = await execAsyncRemote(serverId, command);
|
||||
result = stdout.trim();
|
||||
} else {
|
||||
const { stdout } = await execAsync(command);
|
||||
result = stdout.trim();
|
||||
if (serverId) {
|
||||
const { stdout } = await execAsyncRemote(serverId, command);
|
||||
result = stdout.trim();
|
||||
} else {
|
||||
const { stdout } = await execAsync(command);
|
||||
result = stdout.trim();
|
||||
}
|
||||
if (result === "service") {
|
||||
return "service";
|
||||
}
|
||||
if (result === "standalone") {
|
||||
return "standalone";
|
||||
}
|
||||
return "unknown";
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return "unknown";
|
||||
}
|
||||
if (result === "service") {
|
||||
return "service";
|
||||
}
|
||||
if (result === "standalone") {
|
||||
return "standalone";
|
||||
}
|
||||
return "unknown";
|
||||
};
|
||||
|
||||
export const reloadDockerResource = async (
|
||||
@@ -294,8 +293,10 @@ export const reloadDockerResource = async (
|
||||
let command = "";
|
||||
if (resourceType === "service") {
|
||||
command = `docker service update --force ${resourceName}`;
|
||||
} else {
|
||||
} else if (resourceType === "standalone") {
|
||||
command = `docker restart ${resourceName}`;
|
||||
} else {
|
||||
throw new Error("Resource type not found");
|
||||
}
|
||||
if (serverId) {
|
||||
await execAsyncRemote(serverId, command);
|
||||
@@ -312,7 +313,7 @@ export const readEnvironmentVariables = async (
|
||||
let command = "";
|
||||
if (resourceType === "service") {
|
||||
command = `docker service inspect ${resourceName} --format '{{json .Spec.TaskTemplate.ContainerSpec.Env}}'`;
|
||||
} else {
|
||||
} else if (resourceType === "standalone") {
|
||||
command = `docker container inspect ${resourceName} --format '{{json .Config.Env}}'`;
|
||||
}
|
||||
let result = "";
|
||||
@@ -339,7 +340,7 @@ export const readPorts = async (
|
||||
let command = "";
|
||||
if (resourceType === "service") {
|
||||
command = `docker service inspect ${resourceName} --format '{{json .Spec.EndpointSpec.Ports}}'`;
|
||||
} else {
|
||||
} else if (resourceType === "standalone") {
|
||||
command = `docker container inspect ${resourceName} --format '{{json .NetworkSettings.Ports}}'`;
|
||||
}
|
||||
let result = "";
|
||||
|
||||
@@ -23,6 +23,23 @@ export const addNewProject = async (
|
||||
);
|
||||
};
|
||||
|
||||
export const addNewEnvironment = async (
|
||||
userId: string,
|
||||
environmentId: string,
|
||||
organizationId: string,
|
||||
) => {
|
||||
const userR = await findMemberById(userId, organizationId);
|
||||
|
||||
await db
|
||||
.update(member)
|
||||
.set({
|
||||
accessedEnvironments: [...userR.accessedEnvironments, environmentId],
|
||||
})
|
||||
.where(
|
||||
and(eq(member.id, userR.id), eq(member.organizationId, organizationId)),
|
||||
);
|
||||
};
|
||||
|
||||
export const addNewService = async (
|
||||
userId: string,
|
||||
serviceId: string,
|
||||
@@ -131,6 +148,21 @@ export const canPerformAccessProject = async (
|
||||
return false;
|
||||
};
|
||||
|
||||
export const canPerformAccessEnvironment = async (
|
||||
userId: string,
|
||||
environmentId: string,
|
||||
organizationId: string,
|
||||
) => {
|
||||
const { accessedEnvironments } = await findMemberById(userId, organizationId);
|
||||
const haveAccessToEnvironment = accessedEnvironments.includes(environmentId);
|
||||
|
||||
if (haveAccessToEnvironment) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export const canAccessToTraefikFiles = async (
|
||||
userId: string,
|
||||
organizationId: string,
|
||||
@@ -182,6 +214,32 @@ export const checkServiceAccess = async (
|
||||
}
|
||||
};
|
||||
|
||||
export const checkEnvironmentAccess = async (
|
||||
userId: string,
|
||||
environmentId: string,
|
||||
organizationId: string,
|
||||
action = "access" as const,
|
||||
) => {
|
||||
let hasPermission = false;
|
||||
switch (action) {
|
||||
case "access":
|
||||
hasPermission = await canPerformAccessEnvironment(
|
||||
userId,
|
||||
environmentId,
|
||||
organizationId,
|
||||
);
|
||||
break;
|
||||
default:
|
||||
hasPermission = false;
|
||||
}
|
||||
if (!hasPermission) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "Permission denied",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const checkProjectAccess = async (
|
||||
authId: string,
|
||||
action: "create" | "delete" | "access",
|
||||
|
||||
Reference in New Issue
Block a user