lasthourcloud/src/lib/database/applications.ts

355 lines
9.0 KiB
TypeScript
Raw Normal View History

2022-02-10 15:47:44 +01:00
import { decrypt, encrypt } from '$lib/crypto';
import { asyncExecShell, getEngine } from '$lib/common';
2022-02-10 15:47:44 +01:00
import { removeDestinationDocker } from '$lib/common';
2022-02-10 15:47:44 +01:00
import { prisma } from './common';
import type {
DestinationDocker,
GitSource,
Secret,
ApplicationSettings,
Application,
ApplicationPersistentStorage
} from '@prisma/client';
2022-04-26 14:51:08 +02:00
import { setDefaultBaseImage } from '$lib/buildPacks/common';
export async function listApplications(teamId: string): Promise<Application[]> {
2022-04-06 15:55:17 +02:00
if (teamId === '0') {
return await prisma.application.findMany({ include: { teams: true } });
}
return await prisma.application.findMany({
where: { teams: { some: { id: teamId } } },
include: { teams: true }
});
2022-02-10 15:47:44 +01:00
}
export async function newApplication({
name,
teamId
}: {
name: string;
teamId: string;
}): Promise<Application> {
2022-02-10 15:47:44 +01:00
return await prisma.application.create({
data: {
name,
teams: { connect: { id: teamId } },
settings: { create: { debug: false, previews: false } }
}
});
}
export async function removeApplication({
id,
teamId
}: {
id: string;
teamId: string;
}): Promise<void> {
const { destinationDockerId, destinationDocker } = await prisma.application.findUnique({
2022-02-10 15:47:44 +01:00
where: { id },
include: { destinationDocker: true }
});
if (destinationDockerId) {
const host = getEngine(destinationDocker.engine);
const { stdout: containers } = await asyncExecShell(
`DOCKER_HOST=${host} docker ps -a --filter network=${destinationDocker.network} --filter name=${id} --format '{{json .}}'`
);
if (containers) {
const containersArray = containers.trim().split('\n');
for (const container of containersArray) {
const containerObj = JSON.parse(container);
const id = containerObj.ID;
await removeDestinationDocker({ id, engine: destinationDocker.engine });
}
}
}
await prisma.applicationSettings.deleteMany({ where: { application: { id } } });
await prisma.buildLog.deleteMany({ where: { applicationId: id } });
await prisma.build.deleteMany({ where: { applicationId: id } });
2022-02-10 15:47:44 +01:00
await prisma.secret.deleteMany({ where: { applicationId: id } });
await prisma.applicationPersistentStorage.deleteMany({ where: { applicationId: id } });
2022-04-08 10:35:16 +02:00
if (teamId === '0') {
await prisma.application.deleteMany({ where: { id } });
} else {
await prisma.application.deleteMany({ where: { id, teams: { some: { id: teamId } } } });
}
2022-02-10 15:47:44 +01:00
}
export async function getApplicationWebhook({
projectId,
branch
}: {
projectId: number;
branch: string;
}): Promise<
Application & {
destinationDocker: DestinationDocker;
settings: ApplicationSettings;
gitSource: GitSource;
secrets: Secret[];
persistentStorage: ApplicationPersistentStorage[];
}
> {
2022-02-10 15:47:44 +01:00
try {
const application = await prisma.application.findFirst({
2022-03-11 22:36:21 +01:00
where: { projectId, branch, settings: { autodeploy: true } },
2022-02-10 15:47:44 +01:00
include: {
destinationDocker: true,
settings: true,
gitSource: { include: { githubApp: true, gitlabApp: true } },
2022-03-30 09:28:45 +02:00
secrets: true,
persistentStorage: true
2022-02-10 15:47:44 +01:00
}
});
if (!application) {
return null;
}
2022-03-15 17:22:28 +01:00
if (application?.gitSource?.githubApp?.clientSecret) {
2022-03-11 22:48:55 +01:00
application.gitSource.githubApp.clientSecret = decrypt(
application.gitSource.githubApp.clientSecret
);
}
2022-03-15 17:22:28 +01:00
if (application?.gitSource?.githubApp?.webhookSecret) {
2022-03-11 22:48:55 +01:00
application.gitSource.githubApp.webhookSecret = decrypt(
application.gitSource.githubApp.webhookSecret
);
}
2022-03-15 17:22:28 +01:00
if (application?.gitSource?.githubApp?.privateKey) {
2022-03-11 22:48:55 +01:00
application.gitSource.githubApp.privateKey = decrypt(
application.gitSource.githubApp.privateKey
);
}
if (application?.gitSource?.gitlabApp?.appSecret) {
application.gitSource.gitlabApp.appSecret = decrypt(
application.gitSource.gitlabApp.appSecret
);
}
if (application?.gitSource?.gitlabApp?.webhookToken) {
application.gitSource.gitlabApp.webhookToken = decrypt(
application.gitSource.gitlabApp.webhookToken
);
}
if (application?.secrets.length > 0) {
application.secrets = application.secrets.map((s) => {
s.value = decrypt(s.value);
return s;
});
2022-02-10 15:47:44 +01:00
}
2022-03-11 22:48:55 +01:00
return { ...application };
2022-02-10 15:47:44 +01:00
} catch (e) {
throw { status: 404, body: { message: e.message } };
}
}
2022-04-07 01:03:13 +02:00
export async function getApplication({ id, teamId }: { id: string; teamId: string }): Promise<
Application & {
destinationDocker: DestinationDocker;
settings: ApplicationSettings;
gitSource: GitSource;
secrets: Secret[];
persistentStorage: ApplicationPersistentStorage[];
}
> {
2022-04-07 01:03:13 +02:00
let body;
2022-04-06 15:55:17 +02:00
if (teamId === '0') {
body = await prisma.application.findFirst({
where: { id },
include: {
destinationDocker: true,
settings: true,
gitSource: { include: { githubApp: true, gitlabApp: true } },
secrets: true,
persistentStorage: true
}
});
} else {
body = await prisma.application.findFirst({
where: { id, teams: { some: { id: teamId } } },
include: {
destinationDocker: true,
settings: true,
gitSource: { include: { githubApp: true, gitlabApp: true } },
secrets: true,
persistentStorage: true
}
});
}
2022-02-10 15:47:44 +01:00
2022-03-01 15:30:39 +01:00
if (body?.gitSource?.githubApp?.clientSecret) {
2022-02-10 15:47:44 +01:00
body.gitSource.githubApp.clientSecret = decrypt(body.gitSource.githubApp.clientSecret);
}
2022-03-01 15:30:39 +01:00
if (body?.gitSource?.githubApp?.webhookSecret) {
2022-02-10 15:47:44 +01:00
body.gitSource.githubApp.webhookSecret = decrypt(body.gitSource.githubApp.webhookSecret);
}
2022-03-01 15:30:39 +01:00
if (body?.gitSource?.githubApp?.privateKey) {
2022-02-10 15:47:44 +01:00
body.gitSource.githubApp.privateKey = decrypt(body.gitSource.githubApp.privateKey);
}
if (body?.gitSource?.gitlabApp?.appSecret) {
body.gitSource.gitlabApp.appSecret = decrypt(body.gitSource.gitlabApp.appSecret);
}
if (body?.secrets.length > 0) {
body.secrets = body.secrets.map((s) => {
s.value = decrypt(s.value);
return s;
});
}
2022-04-26 14:51:08 +02:00
const { baseImage, baseBuildImage, baseBuildImages, baseImages } = setDefaultBaseImage(
body.buildPack
);
2022-04-25 23:44:06 +02:00
// Set default build images
if (!body.baseImage) {
2022-04-26 14:51:08 +02:00
body.baseImage = baseImage;
2022-04-25 23:44:06 +02:00
}
2022-04-26 14:51:08 +02:00
if (!body.baseBuildImage) {
body.baseBuildImage = baseBuildImage;
}
return { ...body, baseBuildImages, baseImages };
2022-02-10 15:47:44 +01:00
}
2022-03-11 22:36:21 +01:00
export async function configureGitRepository({
id,
repository,
branch,
projectId,
webhookToken,
autodeploy
}: {
id: string;
repository: string;
branch: string;
projectId: number;
webhookToken: string;
autodeploy: boolean;
}): Promise<void> {
2022-02-10 15:47:44 +01:00
if (webhookToken) {
const encryptedWebhookToken = encrypt(webhookToken);
2022-03-11 22:36:21 +01:00
await prisma.application.update({
2022-02-10 15:47:44 +01:00
where: { id },
data: {
repository,
branch,
projectId,
2022-03-11 22:36:21 +01:00
gitSource: { update: { gitlabApp: { update: { webhookToken: encryptedWebhookToken } } } },
settings: { update: { autodeploy } }
2022-02-10 15:47:44 +01:00
}
});
} else {
2022-03-11 22:36:21 +01:00
await prisma.application.update({
2022-02-10 15:47:44 +01:00
where: { id },
2022-03-11 22:36:21 +01:00
data: { repository, branch, projectId, settings: { update: { autodeploy } } }
2022-02-10 15:47:44 +01:00
});
}
2022-03-11 22:36:21 +01:00
if (!autodeploy) {
const applications = await prisma.application.findMany({ where: { branch, projectId } });
for (const application of applications) {
await prisma.applicationSettings.updateMany({
where: { applicationId: application.id },
data: { autodeploy: false }
});
}
}
2022-02-10 15:47:44 +01:00
}
export async function configureBuildPack({
id,
buildPack
}: Pick<Application, 'id' | 'buildPack'>): Promise<Application> {
2022-02-10 15:47:44 +01:00
return await prisma.application.update({ where: { id }, data: { buildPack } });
}
export async function configureApplication({
id,
buildPack,
name,
fqdn,
port,
installCommand,
buildCommand,
startCommand,
baseDirectory,
2022-04-02 16:22:51 +02:00
publishDirectory,
pythonWSGI,
pythonModule,
pythonVariable,
2022-04-20 22:23:25 +02:00
dockerFileLocation,
denoMainFile,
2022-04-25 23:44:06 +02:00
denoOptions,
2022-04-26 14:51:08 +02:00
baseImage,
baseBuildImage
}: {
id: string;
buildPack: string;
name: string;
fqdn: string;
port: number;
installCommand: string;
buildCommand: string;
startCommand: string;
baseDirectory: string;
publishDirectory: string;
pythonWSGI: string;
pythonModule: string;
pythonVariable: string;
dockerFileLocation: string;
2022-04-20 22:23:25 +02:00
denoMainFile: string;
denoOptions: string;
2022-04-25 23:44:06 +02:00
baseImage: string;
2022-04-26 14:51:08 +02:00
baseBuildImage: string;
}): Promise<Application> {
2022-02-10 15:47:44 +01:00
return await prisma.application.update({
where: { id },
data: {
2022-04-02 16:22:51 +02:00
name,
2022-02-10 15:47:44 +01:00
buildPack,
fqdn,
port,
installCommand,
buildCommand,
startCommand,
baseDirectory,
publishDirectory,
2022-04-02 16:22:51 +02:00
pythonWSGI,
pythonModule,
pythonVariable,
2022-04-20 22:23:25 +02:00
dockerFileLocation,
denoMainFile,
2022-04-25 23:44:06 +02:00
denoOptions,
2022-04-26 14:51:08 +02:00
baseImage,
baseBuildImage
2022-02-10 15:47:44 +01:00
}
});
}
export async function checkDoubleBranch(branch: string, projectId: number): Promise<boolean> {
2022-03-11 22:36:21 +01:00
const applications = await prisma.application.findMany({ where: { branch, projectId } });
return applications.length > 1;
}
export async function setApplicationSettings({
id,
debug,
previews,
dualCerts,
autodeploy
}: {
id: string;
debug: boolean;
previews: boolean;
dualCerts: boolean;
autodeploy: boolean;
}): Promise<Application & { destinationDocker: DestinationDocker }> {
2022-02-10 15:47:44 +01:00
return await prisma.application.update({
where: { id },
2022-03-11 22:36:21 +01:00
data: { settings: { update: { debug, previews, dualCerts, autodeploy } } },
2022-02-10 15:47:44 +01:00
include: { destinationDocker: true }
});
}
export async function getPersistentStorage(id: string): Promise<ApplicationPersistentStorage[]> {
2022-03-20 23:51:50 +01:00
return await prisma.applicationPersistentStorage.findMany({ where: { applicationId: id } });
}