Improved typing and quality of database/checks and database/common code

This commit is contained in:
dominicbachmann 2022-04-05 21:15:02 +02:00
parent 9fdac2741a
commit 82f7633c3a
2 changed files with 115 additions and 39 deletions

View File

@ -1,7 +1,16 @@
import { getDomain } from '$lib/common'; import { getDomain } from '$lib/common';
import { prisma } from './common'; import { prisma } from './common';
import type { Application, ServiceSecret, DestinationDocker, Secret } from '@prisma/client';
export async function isBranchAlreadyUsed({ repository, branch, id }) { export async function isBranchAlreadyUsed({
repository,
branch,
id
}: {
id: string;
repository: string;
branch: string;
}): Promise<Application> {
const application = await prisma.application.findUnique({ const application = await prisma.application.findUnique({
where: { id }, where: { id },
include: { gitSource: true } include: { gitSource: true }
@ -11,18 +20,42 @@ export async function isBranchAlreadyUsed({ repository, branch, id }) {
}); });
} }
export async function isDockerNetworkExists({ network }) { export async function isDockerNetworkExists({
network
}: {
network: string;
}): Promise<DestinationDocker> {
return await prisma.destinationDocker.findFirst({ where: { network } }); return await prisma.destinationDocker.findFirst({ where: { network } });
} }
export async function isServiceSecretExists({ id, name }) { export async function isServiceSecretExists({
id,
name
}: {
id: string;
name: string;
}): Promise<ServiceSecret> {
return await prisma.serviceSecret.findFirst({ where: { name, serviceId: id } }); return await prisma.serviceSecret.findFirst({ where: { name, serviceId: id } });
} }
export async function isSecretExists({ id, name, isPRMRSecret }) { export async function isSecretExists({
id,
name,
isPRMRSecret
}: {
id: string;
name: string;
isPRMRSecret: boolean;
}): Promise<Secret> {
return await prisma.secret.findFirst({ where: { name, applicationId: id, isPRMRSecret } }); return await prisma.secret.findFirst({ where: { name, applicationId: id, isPRMRSecret } });
} }
export async function isDomainConfigured({ id, fqdn }) { export async function isDomainConfigured({
id,
fqdn
}: {
id: string;
fqdn: string;
}): Promise<boolean> {
const domain = getDomain(fqdn); const domain = getDomain(fqdn);
const nakedDomain = domain.replace('www.', ''); const nakedDomain = domain.replace('www.', '');
const foundApp = await prisma.application.findFirst({ const foundApp = await prisma.application.findFirst({
@ -55,6 +88,5 @@ export async function isDomainConfigured({ id, fqdn }) {
}, },
select: { fqdn: true } select: { fqdn: true }
}); });
if (foundApp || foundService || coolifyFqdn) return true; return !!(foundApp || foundService || coolifyFqdn);
return false;
} }

View File

@ -2,11 +2,11 @@ import { dev } from '$app/env';
import { sentry } from '$lib/common'; import { sentry } from '$lib/common';
import * as Prisma from '@prisma/client'; import * as Prisma from '@prisma/client';
import { default as ProdPrisma } from '@prisma/client'; import { default as ProdPrisma } from '@prisma/client';
import type { PrismaClientOptions } from '@prisma/client/runtime'; import type { Database, DatabaseSettings } from '@prisma/client';
import generator from 'generate-password'; import generator from 'generate-password';
import forge from 'node-forge'; import forge from 'node-forge';
export function generatePassword(length = 24) { export function generatePassword(length = 24): string {
return generator.generate({ return generator.generate({
length, length,
numbers: true, numbers: true,
@ -26,8 +26,14 @@ export const prisma = new PrismaClient({
rejectOnNotFound: false rejectOnNotFound: false
}); });
export function ErrorHandler(e) { export function ErrorHandler(e: {
if (e! instanceof Error) { stdout?;
message?: string;
status?: number;
name?: string;
error?: string;
}): { status: number; body: { message: string; error: string } } {
if (e && e instanceof Error) {
e = new Error(e.toString()); e = new Error(e.toString());
} }
let truncatedError = e; let truncatedError = e;
@ -35,8 +41,7 @@ export function ErrorHandler(e) {
truncatedError = e.stdout; truncatedError = e.stdout;
} }
if (e.message?.includes('docker run')) { if (e.message?.includes('docker run')) {
let truncatedArray = []; const truncatedArray: string[] = truncatedError.message.split('-').filter((line) => {
truncatedArray = truncatedError.message.split('-').filter((line) => {
if (!line.startsWith('e ')) { if (!line.startsWith('e ')) {
return line; return line;
} }
@ -64,11 +69,11 @@ export function ErrorHandler(e) {
payload.body.message = 'Already exists. Choose another name.'; payload.body.message = 'Already exists. Choose another name.';
} }
} }
// console.error(e)
return payload; return payload;
} }
export async function generateSshKeyPair(): Promise<{ publicKey: string; privateKey: string }> { export async function generateSshKeyPair(): Promise<{ publicKey: string; privateKey: string }> {
return await new Promise(async (resolve, reject) => { return await new Promise((resolve, reject) => {
forge.pki.rsa.generateKeyPair({ bits: 4096, workers: -1 }, function (err, keys) { forge.pki.rsa.generateKeyPair({ bits: 4096, workers: -1 }, function (err, keys) {
if (keys) { if (keys) {
resolve({ resolve({
@ -210,35 +215,93 @@ export const supportedServiceTypesAndVersions = [
} }
]; ];
export function getVersions(type) { export function getVersions(type: string): string[] {
const found = supportedDatabaseTypesAndVersions.find((t) => t.name === type); const found = supportedDatabaseTypesAndVersions.find((t) => t.name === type);
if (found) { if (found) {
return found.versions; return found.versions;
} }
return []; return [];
} }
export function getDatabaseImage(type) {
export function getDatabaseImage(type: string): string {
const found = supportedDatabaseTypesAndVersions.find((t) => t.name === type); const found = supportedDatabaseTypesAndVersions.find((t) => t.name === type);
if (found) { if (found) {
return found.baseImage; return found.baseImage;
} }
return ''; return '';
} }
export function getServiceImage(type) {
export function getServiceImage(type: string): string {
const found = supportedServiceTypesAndVersions.find((t) => t.name === type); const found = supportedServiceTypesAndVersions.find((t) => t.name === type);
if (found) { if (found) {
return found.baseImage; return found.baseImage;
} }
return ''; return '';
} }
export function getServiceImages(type) {
export function getServiceImages(type: string): string[] {
const found = supportedServiceTypesAndVersions.find((t) => t.name === type); const found = supportedServiceTypesAndVersions.find((t) => t.name === type);
if (found) { if (found) {
return found.images; return found.images;
} }
return []; return [];
} }
export function generateDatabaseConfiguration(database) {
export function generateDatabaseConfiguration(database: Database & { settings: DatabaseSettings }):
| {
volume: string;
image: string;
ulimits: Record<string, unknown>;
privatePort: number;
environmentVariables: {
MYSQL_DATABASE: string;
MYSQL_PASSWORD: string;
MYSQL_ROOT_USER: string;
MYSQL_USER: string;
MYSQL_ROOT_PASSWORD: string;
};
}
| {
volume: string;
image: string;
ulimits: Record<string, unknown>;
privatePort: number;
environmentVariables: {
MONGODB_ROOT_USER: string;
MONGODB_ROOT_PASSWORD: string;
};
}
| {
volume: string;
image: string;
ulimits: Record<string, unknown>;
privatePort: number;
environmentVariables: {
POSTGRESQL_USERNAME: string;
POSTGRESQL_PASSWORD: string;
POSTGRESQL_DATABASE: string;
};
}
| {
volume: string;
image: string;
ulimits: Record<string, unknown>;
privatePort: number;
environmentVariables: {
REDIS_AOF_ENABLED: string;
REDIS_PASSWORD: string;
};
}
| {
volume: string;
image: string;
ulimits: Record<string, unknown>;
privatePort: number;
environmentVariables: {
COUCHDB_PASSWORD: string;
COUCHDB_USER: string;
};
} {
const { const {
id, id,
dbUser, dbUser,
@ -253,7 +316,6 @@ export function generateDatabaseConfiguration(database) {
const baseImage = getDatabaseImage(type); const baseImage = getDatabaseImage(type);
if (type === 'mysql') { if (type === 'mysql') {
return { return {
// url: `mysql://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 3306}/${defaultDatabase}`,
privatePort: 3306, privatePort: 3306,
environmentVariables: { environmentVariables: {
MYSQL_USER: dbUser, MYSQL_USER: dbUser,
@ -268,7 +330,6 @@ export function generateDatabaseConfiguration(database) {
}; };
} else if (type === 'mongodb') { } else if (type === 'mongodb') {
return { return {
// url: `mongodb://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 27017}/${defaultDatabase}`,
privatePort: 27017, privatePort: 27017,
environmentVariables: { environmentVariables: {
MONGODB_ROOT_USER: rootUser, MONGODB_ROOT_USER: rootUser,
@ -280,7 +341,6 @@ export function generateDatabaseConfiguration(database) {
}; };
} else if (type === 'postgresql') { } else if (type === 'postgresql') {
return { return {
// url: `psql://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 5432}/${defaultDatabase}`,
privatePort: 5432, privatePort: 5432,
environmentVariables: { environmentVariables: {
POSTGRESQL_PASSWORD: dbUserPassword, POSTGRESQL_PASSWORD: dbUserPassword,
@ -293,7 +353,6 @@ export function generateDatabaseConfiguration(database) {
}; };
} else if (type === 'redis') { } else if (type === 'redis') {
return { return {
// url: `redis://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 6379}/${defaultDatabase}`,
privatePort: 6379, privatePort: 6379,
environmentVariables: { environmentVariables: {
REDIS_PASSWORD: dbUserPassword, REDIS_PASSWORD: dbUserPassword,
@ -305,7 +364,6 @@ export function generateDatabaseConfiguration(database) {
}; };
} else if (type === 'couchdb') { } else if (type === 'couchdb') {
return { return {
// url: `couchdb://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 5984}/${defaultDatabase}`,
privatePort: 5984, privatePort: 5984,
environmentVariables: { environmentVariables: {
COUCHDB_PASSWORD: dbUserPassword, COUCHDB_PASSWORD: dbUserPassword,
@ -316,18 +374,4 @@ export function generateDatabaseConfiguration(database) {
ulimits: {} ulimits: {}
}; };
} }
// } else if (type === 'clickhouse') {
// return {
// url: `clickhouse://${dbUser}:${dbUserPassword}@${id}:${port}/${defaultDatabase}`,
// privatePort: 9000,
// image: `bitnami/clickhouse-server:${version}`,
// volume: `${id}-${type}-data:/var/lib/clickhouse`,
// ulimits: {
// nofile: {
// soft: 262144,
// hard: 262144
// }
// }
// }
// }
} }