2022-02-10 15:47:44 +01:00
|
|
|
import { decrypt, encrypt } from '$lib/crypto';
|
2022-02-11 21:14:47 +01:00
|
|
|
import { asyncExecShell, getEngine } from '$lib/common';
|
2022-02-10 15:47:44 +01:00
|
|
|
|
2022-04-05 20:48:33 +02:00
|
|
|
import { removeDestinationDocker } from '$lib/common';
|
2022-02-10 15:47:44 +01:00
|
|
|
import { prisma } from './common';
|
|
|
|
|
2022-04-05 20:48:33 +02:00
|
|
|
import type {
|
|
|
|
DestinationDocker,
|
|
|
|
GitSource,
|
|
|
|
Secret,
|
|
|
|
ApplicationSettings,
|
|
|
|
Application,
|
|
|
|
ApplicationPersistentStorage
|
|
|
|
} from '@prisma/client';
|
|
|
|
|
|
|
|
export async function listApplications(teamId: string): Promise<Application[]> {
|
2022-02-10 15:47:44 +01:00
|
|
|
return await prisma.application.findMany({ where: { teams: { some: { id: teamId } } } });
|
|
|
|
}
|
|
|
|
|
2022-04-05 20:48:33 +02: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 } }
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-04-05 20:48:33 +02:00
|
|
|
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 } });
|
2022-03-19 15:06:25 +01:00
|
|
|
await prisma.build.deleteMany({ where: { applicationId: id } });
|
2022-02-10 15:47:44 +01:00
|
|
|
await prisma.secret.deleteMany({ where: { applicationId: id } });
|
2022-03-23 10:25:32 +01:00
|
|
|
await prisma.applicationPersistentStorage.deleteMany({ where: { applicationId: id } });
|
2022-02-10 15:47:44 +01:00
|
|
|
await prisma.application.deleteMany({ where: { id, teams: { some: { id: teamId } } } });
|
|
|
|
}
|
|
|
|
|
2022-04-05 20:48:33 +02: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 {
|
2022-04-05 20:48:33 +02:00
|
|
|
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
|
|
|
}
|
|
|
|
});
|
2022-03-19 15:04:52 +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-02-14 09:28:37 +01:00
|
|
|
|
2022-04-05 20:48:33 +02:00
|
|
|
export async function getApplication({
|
|
|
|
id,
|
|
|
|
teamId
|
|
|
|
}: {
|
|
|
|
id: string;
|
|
|
|
teamId: string;
|
|
|
|
}): Promise<
|
|
|
|
Application & {
|
|
|
|
destinationDocker: DestinationDocker;
|
|
|
|
settings: ApplicationSettings;
|
|
|
|
gitSource: GitSource;
|
|
|
|
secrets: Secret[];
|
|
|
|
persistentStorage: ApplicationPersistentStorage[];
|
|
|
|
}
|
|
|
|
> {
|
|
|
|
const body = await prisma.application.findFirst({
|
2022-02-10 15:47:44 +01:00
|
|
|
where: { id, teams: { some: { id: teamId } } },
|
|
|
|
include: {
|
|
|
|
destinationDocker: true,
|
|
|
|
settings: true,
|
|
|
|
gitSource: { include: { githubApp: true, gitlabApp: true } },
|
2022-03-20 23:51:50 +01:00
|
|
|
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;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return { ...body };
|
|
|
|
}
|
|
|
|
|
2022-03-11 22:36:21 +01:00
|
|
|
export async function configureGitRepository({
|
|
|
|
id,
|
|
|
|
repository,
|
|
|
|
branch,
|
|
|
|
projectId,
|
|
|
|
webhookToken,
|
|
|
|
autodeploy
|
2022-04-05 20:48:33 +02:00
|
|
|
}: {
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2022-04-05 20:48:33 +02: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-05 20:48:33 +02:00
|
|
|
}: {
|
|
|
|
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;
|
|
|
|
}): 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-02-10 15:47:44 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-04-05 20:48:33 +02: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;
|
|
|
|
}
|
2022-04-05 20:48:33 +02:00
|
|
|
|
|
|
|
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 }
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-04-05 20:48:33 +02:00
|
|
|
export async function getPersistentStorage(id: string): Promise<ApplicationPersistentStorage[]> {
|
2022-03-20 23:51:50 +01:00
|
|
|
return await prisma.applicationPersistentStorage.findMany({ where: { applicationId: id } });
|
|
|
|
}
|