瀏覽代碼

Add `site_block_size` and migration for beta.3

Owen Schwartz 6 月之前
父節點
當前提交
38544cc2d6

+ 1 - 0
config/config.example.yml

@@ -22,6 +22,7 @@ gerbil:
     start_port: 51820
     base_endpoint: localhost
     block_size: 16
+    site_block_size: 29
     subnet_group: 10.0.0.0/8
     use_subdomain: true
 

+ 1 - 0
install/fs/config.yml

@@ -24,6 +24,7 @@ gerbil:
     base_endpoint: {{.Domain}}
     use_subdomain: false
     block_size: 16
+    site_block_size: 29
     subnet_group: 10.0.0.0/8
 
 rate_limits:

+ 0 - 4
package.json

@@ -1,10 +1,6 @@
 {
     "name": "@fosrl/pangolin",
-<<<<<<< HEAD
-    "version": "1.0.0-beta.2",
-=======
     "version": "1.0.0-beta.3",
->>>>>>> c3d19454f7f5c5546a7efb47c23fc040dbbf94d2
     "private": true,
     "type": "module",
     "description": "Tunneled Reverse Proxy Management Server with Identity and Access Control and Dashboard UI",

+ 2 - 15
server/lib/config.ts

@@ -3,15 +3,7 @@ import yaml from "js-yaml";
 import path from "path";
 import { z } from "zod";
 import { fromError } from "zod-validation-error";
-<<<<<<< HEAD
 import { __DIRNAME, APP_PATH, configFilePath1, configFilePath2 } from "@server/lib/consts";
-=======
-import {
-    __DIRNAME,
-    configFilePath1,
-    configFilePath2
-} from "@server/lib/consts";
->>>>>>> c3d19454f7f5c5546a7efb47c23fc040dbbf94d2
 import { loadAppVersion } from "@server/lib/loadAppVersion";
 import { passwordSchema } from "@server/auth/passwordSchema";
 
@@ -19,15 +11,9 @@ const portSchema = z.number().positive().gt(0).lte(65535);
 const hostnameSchema = z
     .string()
     .regex(
-<<<<<<< HEAD
         /^(?!-)[a-zA-Z0-9-]{1,63}(?<!-)(\.[a-zA-Z]{2,})*$/,
         "Invalid hostname. Must be a valid hostname like 'localhost' or 'test.example.com'."
     );
-=======
-        /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)+([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$/
-    )
-    .or(z.literal("localhost"));
->>>>>>> c3d19454f7f5c5546a7efb47c23fc040dbbf94d2
 
 const environmentSchema = z.object({
     app: z.object({
@@ -59,7 +45,8 @@ const environmentSchema = z.object({
         base_endpoint: z.string().transform((url) => url.toLowerCase()),
         use_subdomain: z.boolean(),
         subnet_group: z.string(),
-        block_size: z.number().positive().gt(0)
+        block_size: z.number().positive().gt(0),
+        site_block_size: z.number().positive().gt(0)
     }),
     rate_limits: z.object({
         global: z.object({

+ 4 - 3
server/routers/site/pickSiteDefaults.ts

@@ -8,6 +8,7 @@ import createHttpError from "http-errors";
 import logger from "@server/logger";
 import { findNextAvailableCidr } from "@server/lib/ip";
 import { generateId } from "@server/auth/sessions/app";
+import config from "@server/lib/config";
 
 export type PickSiteDefaultsResponse = {
     exitNodeId: number;
@@ -51,9 +52,9 @@ export async function pickSiteDefaults(
 
         // TODO: we need to lock this subnet for some time so someone else does not take it
         let subnets = sitesQuery.map((site) => site.subnet);
-        // exclude the exit node address by replacing after the / with a /28
-        subnets.push(exitNode.address.replace(/\/\d+$/, "/29"));
-        const newSubnet = findNextAvailableCidr(subnets, 29, exitNode.address);
+        // exclude the exit node address by replacing after the / with a site block size
+        subnets.push(exitNode.address.replace(/\/\d+$/, `/${config.getRawConfig().gerbil.site_block_size}`));
+        const newSubnet = findNextAvailableCidr(subnets, config.getRawConfig().gerbil.site_block_size, exitNode.address);
         if (!newSubnet) {
             return next(
                 createHttpError(

+ 3 - 1
server/setup/migrations.ts

@@ -8,6 +8,7 @@ import { __DIRNAME } from "@server/lib/consts";
 import { loadAppVersion } from "@server/lib/loadAppVersion";
 import m1 from "./scripts/1.0.0-beta1";
 import m2 from "./scripts/1.0.0-beta2";
+import m3 from "./scripts/1.0.0-beta3";
 
 // THIS CANNOT IMPORT ANYTHING FROM THE SERVER
 // EXCEPT FOR THE DATABASE AND THE SCHEMA
@@ -15,7 +16,8 @@ import m2 from "./scripts/1.0.0-beta2";
 // Define the migration list with versions and their corresponding functions
 const migrations = [
     { version: "1.0.0-beta.1", run: m1 },
-    { version: "1.0.0-beta.2", run: m2 }
+    { version: "1.0.0-beta.2", run: m2 },
+    { version: "1.0.0-beta.3", run: m3 }
     // Add new migrations here as they are created
 ] as const;
 

+ 42 - 0
server/setup/scripts/1.0.0-beta3.ts

@@ -0,0 +1,42 @@
+import { configFilePath1, configFilePath2 } from "@server/lib/consts";
+import fs from "fs";
+import yaml from "js-yaml";
+
+export default async function migration() {
+    console.log("Running setup script 1.0.0-beta.3...");
+
+    // Determine which config file exists
+    const filePaths = [configFilePath1, configFilePath2];
+    let filePath = "";
+    for (const path of filePaths) {
+        if (fs.existsSync(path)) {
+            filePath = path;
+            break;
+        }
+    }
+
+    if (!filePath) {
+        throw new Error(
+            `No config file found (expected config.yml or config.yaml).`
+        );
+    }
+
+    // Read and parse the YAML file
+    let rawConfig: any;
+    const fileContents = fs.readFileSync(filePath, "utf8");
+    rawConfig = yaml.load(fileContents);
+
+    // Validate the structure
+    if (!rawConfig.gerbil) {
+        throw new Error(`Invalid config file: gerbil is missing.`);
+    }
+
+    // Update the config
+    rawConfig.gerbil.site_block_size = 29;
+
+    // Write the updated YAML back to the file
+    const updatedYaml = yaml.dump(rawConfig);
+    fs.writeFileSync(filePath, updatedYaml, "utf8");
+
+    console.log("Done.");
+}