feat: Public port range (WIP)
This commit is contained in:
parent
d3d9754277
commit
add441675d
@ -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;
|
@ -12,6 +12,8 @@ model Setting {
|
|||||||
fqdn String? @unique
|
fqdn String? @unique
|
||||||
isRegistrationEnabled Boolean @default(false)
|
isRegistrationEnabled Boolean @default(false)
|
||||||
dualCerts Boolean @default(false)
|
dualCerts Boolean @default(false)
|
||||||
|
minPort Int @default(9000)
|
||||||
|
maxPort Int @default(9100)
|
||||||
proxyPassword String
|
proxyPassword String
|
||||||
proxyUser String
|
proxyUser String
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { decrypt, encrypt } from '$lib/crypto';
|
import { decrypt, encrypt } from '$lib/crypto';
|
||||||
import { dockerInstance } from '$lib/docker';
|
import * as db from '$lib/database';
|
||||||
import cuid from 'cuid';
|
import cuid from 'cuid';
|
||||||
import { generatePassword } from '.';
|
import { generatePassword } from '.';
|
||||||
import { prisma, ErrorHandler } from './common';
|
import { prisma, ErrorHandler } from './common';
|
||||||
import getPort from 'get-port';
|
import getPort, { portNumbers } from 'get-port';
|
||||||
import { asyncExecShell, getEngine, removeContainer } from '$lib/common';
|
import { asyncExecShell, getEngine, removeContainer } from '$lib/common';
|
||||||
|
|
||||||
export async function listDatabases(teamId) {
|
export async function listDatabases(teamId) {
|
||||||
@ -16,24 +16,9 @@ export async function newDatabase({ name, teamId }) {
|
|||||||
const rootUserPassword = encrypt(generatePassword());
|
const rootUserPassword = encrypt(generatePassword());
|
||||||
const defaultDatabase = cuid();
|
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({
|
return await prisma.database.create({
|
||||||
data: {
|
data: {
|
||||||
name,
|
name,
|
||||||
publicPort,
|
|
||||||
defaultDatabase,
|
defaultDatabase,
|
||||||
dbUser,
|
dbUser,
|
||||||
dbUserPassword,
|
dbUserPassword,
|
||||||
|
@ -3,23 +3,24 @@ import { forceSSLOffApplication, forceSSLOnApplication } from '$lib/haproxy';
|
|||||||
import { asyncExecShell, getEngine } from './common';
|
import { asyncExecShell, getEngine } from './common';
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
import cuid from 'cuid';
|
import cuid from 'cuid';
|
||||||
import getPort from 'get-port';
|
import getPort, { portNumbers } from 'get-port';
|
||||||
|
|
||||||
export async function letsEncrypt({ domain, isCoolify = false, id = null }) {
|
export async function letsEncrypt({ domain, isCoolify = false, id = null }) {
|
||||||
try {
|
try {
|
||||||
|
const data = await db.prisma.setting.findFirst();
|
||||||
|
const { minPort, maxPort } = data;
|
||||||
|
|
||||||
const nakedDomain = domain.replace('www.', '');
|
const nakedDomain = domain.replace('www.', '');
|
||||||
const wwwDomain = `www.${nakedDomain}`;
|
const wwwDomain = `www.${nakedDomain}`;
|
||||||
const randomCuid = cuid();
|
const randomCuid = cuid();
|
||||||
const randomPort = 9080;
|
const randomPort = await getPort({ port: portNumbers(minPort, maxPort) });
|
||||||
|
|
||||||
let host;
|
let host;
|
||||||
let dualCerts = false;
|
let dualCerts = false;
|
||||||
if (isCoolify) {
|
if (isCoolify) {
|
||||||
const data = await db.prisma.setting.findFirst();
|
|
||||||
dualCerts = data.dualCerts;
|
dualCerts = data.dualCerts;
|
||||||
host = 'unix:///var/run/docker.sock';
|
host = 'unix:///var/run/docker.sock';
|
||||||
} else {
|
} else {
|
||||||
// Check Application
|
|
||||||
const applicationData = await db.prisma.application.findUnique({
|
const applicationData = await db.prisma.application.findUnique({
|
||||||
where: { id },
|
where: { id },
|
||||||
include: { destinationDocker: true, settings: true }
|
include: { destinationDocker: true, settings: true }
|
||||||
|
@ -56,9 +56,11 @@
|
|||||||
appendOnly = !appendOnly;
|
appendOnly = !appendOnly;
|
||||||
}
|
}
|
||||||
try {
|
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();
|
databaseUrl = generateUrl();
|
||||||
return;
|
|
||||||
} catch ({ error }) {
|
} catch ({ error }) {
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
}
|
}
|
||||||
@ -135,7 +137,7 @@
|
|||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<label for="publicPort">Port</label>
|
<label for="publicPort">Port</label>
|
||||||
<CopyPasswordField
|
<CopyPasswordField
|
||||||
placeholder="Generated automatically after start"
|
placeholder="Generated automatically after set to public"
|
||||||
id="publicPort"
|
id="publicPort"
|
||||||
readonly
|
readonly
|
||||||
disabled
|
disabled
|
||||||
|
@ -3,30 +3,39 @@ import * as db from '$lib/database';
|
|||||||
import { generateDatabaseConfiguration, ErrorHandler } from '$lib/database';
|
import { generateDatabaseConfiguration, ErrorHandler } from '$lib/database';
|
||||||
import { startTcpProxy, stopTcpHttpProxy } from '$lib/haproxy';
|
import { startTcpProxy, stopTcpHttpProxy } from '$lib/haproxy';
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
import getPort, { portNumbers } from 'get-port';
|
||||||
|
|
||||||
export const post: RequestHandler = async (event) => {
|
export const post: RequestHandler = async (event) => {
|
||||||
const { status, body, teamId } = await getUserDetails(event);
|
const { status, body, teamId } = await getUserDetails(event);
|
||||||
if (status === 401) return { status, body };
|
if (status === 401) return { status, body };
|
||||||
|
|
||||||
const { id } = event.params;
|
const { id } = event.params;
|
||||||
|
const data = await db.prisma.setting.findFirst();
|
||||||
|
const { minPort, maxPort } = data;
|
||||||
|
|
||||||
const { isPublic, appendOnly = true } = await event.request.json();
|
const { isPublic, appendOnly = true } = await event.request.json();
|
||||||
|
const publicPort = await getPort({ port: portNumbers(minPort, maxPort) });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await db.setDatabase({ id, isPublic, appendOnly });
|
await db.setDatabase({ id, isPublic, appendOnly });
|
||||||
const database = await db.getDatabase({ id, teamId });
|
const database = await db.getDatabase({ id, teamId });
|
||||||
const { destinationDockerId, destinationDocker, publicPort } = database;
|
const { destinationDockerId, destinationDocker, publicPort: oldPublicPort } = database;
|
||||||
const { privatePort } = generateDatabaseConfiguration(database);
|
const { privatePort } = generateDatabaseConfiguration(database);
|
||||||
|
|
||||||
if (destinationDockerId) {
|
if (destinationDockerId) {
|
||||||
if (isPublic) {
|
if (isPublic) {
|
||||||
|
await db.prisma.database.update({ where: { id }, data: { publicPort } });
|
||||||
await startTcpProxy(destinationDocker, id, publicPort, privatePort);
|
await startTcpProxy(destinationDocker, id, publicPort, privatePort);
|
||||||
} else {
|
} else {
|
||||||
await stopTcpHttpProxy(destinationDocker, publicPort);
|
await db.prisma.database.update({ where: { id }, data: { publicPort: null } });
|
||||||
|
await stopTcpHttpProxy(destinationDocker, oldPublicPort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: 201
|
status: 201,
|
||||||
|
body: {
|
||||||
|
publicPort
|
||||||
|
}
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return ErrorHandler(error);
|
return ErrorHandler(error);
|
||||||
|
@ -15,6 +15,7 @@ export const post: RequestHandler = async (event) => {
|
|||||||
const everStarted = await stopDatabase(database);
|
const everStarted = await stopDatabase(database);
|
||||||
if (everStarted) await stopTcpHttpProxy(database.destinationDocker, database.publicPort);
|
if (everStarted) await stopTcpHttpProxy(database.destinationDocker, database.publicPort);
|
||||||
await db.setDatabase({ id, isPublic: false });
|
await db.setDatabase({ id, isPublic: false });
|
||||||
|
await db.prisma.database.update({ where: { id }, data: { publicPort: null } });
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: 200
|
status: 200
|
||||||
|
Loading…
Reference in New Issue
Block a user