diff --git a/prisma/migrations/20220220141136_public_portrange/migration.sql b/prisma/migrations/20220220141136_public_portrange/migration.sql new file mode 100644 index 000000000..6423e9761 --- /dev/null +++ b/prisma/migrations/20220220141136_public_portrange/migration.sql @@ -0,0 +1,20 @@ +-- RedefineTables +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_Setting" ( + "id" TEXT NOT NULL PRIMARY KEY, + "fqdn" TEXT, + "isRegistrationEnabled" BOOLEAN NOT NULL DEFAULT false, + "dualCerts" BOOLEAN NOT NULL DEFAULT false, + "minPort" INTEGER NOT NULL DEFAULT 9000, + "maxPort" INTEGER NOT NULL DEFAULT 9100, + "proxyPassword" TEXT NOT NULL, + "proxyUser" TEXT NOT NULL, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL +); +INSERT INTO "new_Setting" ("createdAt", "dualCerts", "fqdn", "id", "isRegistrationEnabled", "proxyPassword", "proxyUser", "updatedAt") SELECT "createdAt", "dualCerts", "fqdn", "id", "isRegistrationEnabled", "proxyPassword", "proxyUser", "updatedAt" FROM "Setting"; +DROP TABLE "Setting"; +ALTER TABLE "new_Setting" RENAME TO "Setting"; +CREATE UNIQUE INDEX "Setting_fqdn_key" ON "Setting"("fqdn"); +PRAGMA foreign_key_check; +PRAGMA foreign_keys=ON; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 7599602fb..fefc32561 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -12,6 +12,8 @@ model Setting { fqdn String? @unique isRegistrationEnabled Boolean @default(false) dualCerts Boolean @default(false) + minPort Int @default(9000) + maxPort Int @default(9100) proxyPassword String proxyUser String createdAt DateTime @default(now()) diff --git a/src/lib/database/databases.ts b/src/lib/database/databases.ts index b38c38882..be5ddacd3 100644 --- a/src/lib/database/databases.ts +++ b/src/lib/database/databases.ts @@ -1,9 +1,9 @@ import { decrypt, encrypt } from '$lib/crypto'; -import { dockerInstance } from '$lib/docker'; +import * as db from '$lib/database'; import cuid from 'cuid'; import { generatePassword } from '.'; import { prisma, ErrorHandler } from './common'; -import getPort from 'get-port'; +import getPort, { portNumbers } from 'get-port'; import { asyncExecShell, getEngine, removeContainer } from '$lib/common'; export async function listDatabases(teamId) { @@ -16,24 +16,9 @@ export async function newDatabase({ name, teamId }) { const rootUserPassword = encrypt(generatePassword()); const defaultDatabase = cuid(); - let publicPort = await getPort(); - let i = 0; - - do { - const usedPorts = await prisma.database.findMany({ where: { publicPort } }); - if (usedPorts.length === 0) break; - publicPort = await getPort(); - i++; - } while (i < 10); - if (i === 9) { - throw { - error: 'No free port found!? Is it possible?' - }; - } return await prisma.database.create({ data: { name, - publicPort, defaultDatabase, dbUser, dbUserPassword, diff --git a/src/lib/letsencrypt.ts b/src/lib/letsencrypt.ts index dc4c9d6f7..d70de1812 100644 --- a/src/lib/letsencrypt.ts +++ b/src/lib/letsencrypt.ts @@ -3,23 +3,24 @@ import { forceSSLOffApplication, forceSSLOnApplication } from '$lib/haproxy'; import { asyncExecShell, getEngine } from './common'; import * as db from '$lib/database'; import cuid from 'cuid'; -import getPort from 'get-port'; +import getPort, { portNumbers } from 'get-port'; export async function letsEncrypt({ domain, isCoolify = false, id = null }) { try { + const data = await db.prisma.setting.findFirst(); + const { minPort, maxPort } = data; + const nakedDomain = domain.replace('www.', ''); const wwwDomain = `www.${nakedDomain}`; const randomCuid = cuid(); - const randomPort = 9080; + const randomPort = await getPort({ port: portNumbers(minPort, maxPort) }); let host; let dualCerts = false; if (isCoolify) { - const data = await db.prisma.setting.findFirst(); dualCerts = data.dualCerts; host = 'unix:///var/run/docker.sock'; } else { - // Check Application const applicationData = await db.prisma.application.findUnique({ where: { id }, include: { destinationDocker: true, settings: true } diff --git a/src/routes/databases/[id]/_Databases/_Databases.svelte b/src/routes/databases/[id]/_Databases/_Databases.svelte index 83c15a496..9b233c8c8 100644 --- a/src/routes/databases/[id]/_Databases/_Databases.svelte +++ b/src/routes/databases/[id]/_Databases/_Databases.svelte @@ -56,9 +56,11 @@ appendOnly = !appendOnly; } try { - await post(`/databases/${id}/settings.json`, { isPublic, appendOnly }); + const { publicPort } = await post(`/databases/${id}/settings.json`, { isPublic, appendOnly }); + if (isPublic) { + database.publicPort = publicPort; + } databaseUrl = generateUrl(); - return; } catch ({ error }) { return errorNotification(error); } @@ -135,7 +137,7 @@
{ const { status, body, teamId } = await getUserDetails(event); if (status === 401) return { status, body }; const { id } = event.params; + const data = await db.prisma.setting.findFirst(); + const { minPort, maxPort } = data; + const { isPublic, appendOnly = true } = await event.request.json(); + const publicPort = await getPort({ port: portNumbers(minPort, maxPort) }); try { await db.setDatabase({ id, isPublic, appendOnly }); const database = await db.getDatabase({ id, teamId }); - const { destinationDockerId, destinationDocker, publicPort } = database; + const { destinationDockerId, destinationDocker, publicPort: oldPublicPort } = database; const { privatePort } = generateDatabaseConfiguration(database); if (destinationDockerId) { if (isPublic) { + await db.prisma.database.update({ where: { id }, data: { publicPort } }); await startTcpProxy(destinationDocker, id, publicPort, privatePort); } else { - await stopTcpHttpProxy(destinationDocker, publicPort); + await db.prisma.database.update({ where: { id }, data: { publicPort: null } }); + await stopTcpHttpProxy(destinationDocker, oldPublicPort); } } - return { - status: 201 + status: 201, + body: { + publicPort + } }; } catch (error) { return ErrorHandler(error); diff --git a/src/routes/databases/[id]/stop.json.ts b/src/routes/databases/[id]/stop.json.ts index c09927658..6bd4f4c19 100644 --- a/src/routes/databases/[id]/stop.json.ts +++ b/src/routes/databases/[id]/stop.json.ts @@ -15,6 +15,7 @@ export const post: RequestHandler = async (event) => { const everStarted = await stopDatabase(database); if (everStarted) await stopTcpHttpProxy(database.destinationDocker, database.publicPort); await db.setDatabase({ id, isPublic: false }); + await db.prisma.database.update({ where: { id }, data: { publicPort: null } }); return { status: 200