Fix api call

This commit is contained in:
Owen
2025-12-20 21:14:48 -05:00
parent 6a5939599c
commit af4f85a081
2 changed files with 137 additions and 159 deletions

View File

@@ -321,130 +321,49 @@ export async function getTraefikConfig(
config_output.http.services = {};
}
const availableServers = (targets as TargetWithSite[]).filter(
(target: TargetWithSite) => {
if (!target.enabled) return false;
const additionalMiddlewares =
config.getRawConfig().traefik.additional_middlewares || [];
const anySitesOnline = (targets as TargetWithSite[]).some(
(t: TargetWithSite) => t.site.online
);
if (anySitesOnline && !target.site.online) return false;
const routerMiddlewares = [
badgerMiddlewareName,
...additionalMiddlewares
];
if (target.site.type === "local" || target.site.type === "wireguard") {
return target.ip && target.port && target.method;
} else if (target.site.type === "newt") {
return target.internalPort && target.method && target.site.subnet;
}
return false;
}
);
let rule = `Host(\`${fullDomain}\`)`;
const hasHealthyServers = availableServers.length > 0;
let showMaintenancePage = false;
if (resource.maintenanceModeEnabled) {
if (resource.maintenanceModeType === "forced") {
showMaintenancePage = true;
logger.debug(
`Resource ${resource.name} (${fullDomain}) is in FORCED maintenance mode`
);
} else if (resource.maintenanceModeType === "automatic") {
showMaintenancePage = !hasHealthyServers;
if (showMaintenancePage) {
logger.warn(
`Resource ${resource.name} (${fullDomain}) has no healthy servers - showing maintenance page (AUTOMATIC mode)`
);
}
}
}
if (showMaintenancePage) {
const maintenanceServiceName = `${key}-maintenance-service`;
const maintenanceRouterName = `${key}-maintenance-router`;
const rewriteMiddlewareName = `${key}-maintenance-rewrite`;
const entrypointHttp = config.getRawConfig().traefik.http_entrypoint;
const entrypointHttps = config.getRawConfig().traefik.https_entrypoint;
const fullDomain = resource.fullDomain;
const domainParts = fullDomain.split(".");
const wildCard = resource.subdomain
? `*.${domainParts.slice(1).join(".")}`
: fullDomain;
const tls = {
certResolver: resource.domainCertResolver?.trim() ||
config.getRawConfig().traefik.cert_resolver,
...(config.getRawConfig().traefik.prefer_wildcard_cert
? { domains: [{ main: wildCard }] }
: {})
};
const maintenancePort = config.getRawConfig().server.next_port;
const maintenanceHost = config.getRawConfig().server.internal_hostname;
config_output.http.services[maintenanceServiceName] = {
loadBalancer: {
servers: [{ url: `http://${maintenanceHost}:${maintenancePort}` }],
passHostHeader: true
}
};
// middleware to rewrite path to /maintenance-screen
if (!config_output.http.middlewares) {
config_output.http.middlewares = {};
}
config_output.http.middlewares[rewriteMiddlewareName] = {
replacePathRegex: {
regex: "^/(.*)",
replacement: "/maintenance-screen"
}
};
const rule = `Host(\`${fullDomain}\`)`;
console.log('DEBUG: Generated rule:', rule); // Should show: Host(`pangolin.pallavi.fosrl.io`)
config_output.http.routers[maintenanceRouterName] = {
entryPoints: [resource.ssl ? entrypointHttps : entrypointHttp],
service: maintenanceServiceName,
middlewares: [rewriteMiddlewareName],
rule: rule,
priority: 2000,
...(resource.ssl ? { tls } : {})
};
if (resource.ssl) {
config_output.http.routers[`${maintenanceRouterName}-redirect`] = {
entryPoints: [entrypointHttp],
middlewares: [redirectHttpsMiddlewareName, rewriteMiddlewareName],
service: maintenanceServiceName,
rule: rule,
priority: 2000
};
}
logger.info(`Maintenance mode active for ${fullDomain}`);
continue;
}
const domainParts = fullDomain.split(".");
let wildCard;
if (domainParts.length <= 2) {
wildCard = `*.${domainParts.join(".")}`;
// priority logic
let priority: number;
if (resource.priority && resource.priority != 100) {
priority = resource.priority;
} else {
wildCard = `*.${domainParts.slice(1).join(".")}`;
priority = 100;
if (resource.path && resource.pathMatchType) {
priority += 10;
if (resource.pathMatchType === "exact") {
priority += 5;
} else if (resource.pathMatchType === "prefix") {
priority += 3;
} else if (resource.pathMatchType === "regex") {
priority += 2;
}
if (resource.path === "/") {
priority = 1; // lowest for catch-all
}
}
}
if (!resource.subdomain) {
wildCard = resource.fullDomain;
if (resource.ssl) {
config_output.http.routers![routerName + "-redirect"] = {
entryPoints: [
config.getRawConfig().traefik.http_entrypoint
],
middlewares: [redirectHttpsMiddlewareName],
service: serviceName,
rule: rule,
priority: priority
};
}
const configDomain = config.getDomain(resource.domainId);
let tls = {};
if (!privateConfig.getRawPrivateConfig().flags.use_pangolin_dns) {
const domainParts = fullDomain.split(".");
@@ -510,13 +429,101 @@ export async function getTraefikConfig(
}
}
const additionalMiddlewares =
config.getRawConfig().traefik.additional_middlewares || [];
const availableServers = (targets as TargetWithSite[]).filter(
(target: TargetWithSite) => {
if (!target.enabled) return false;
const routerMiddlewares = [
badgerMiddlewareName,
...additionalMiddlewares
];
const anySitesOnline = (targets as TargetWithSite[]).some(
(t: TargetWithSite) => t.site.online
);
if (anySitesOnline && !target.site.online) return false;
if (target.site.type === "local" || target.site.type === "wireguard") {
return target.ip && target.port && target.method;
} else if (target.site.type === "newt") {
return target.internalPort && target.method && target.site.subnet;
}
return false;
}
);
const hasHealthyServers = availableServers.length > 0;
let showMaintenancePage = false;
if (resource.maintenanceModeEnabled) {
if (resource.maintenanceModeType === "forced") {
showMaintenancePage = true;
// logger.debug(
// `Resource ${resource.name} (${fullDomain}) is in FORCED maintenance mode`
// );
} else if (resource.maintenanceModeType === "automatic") {
showMaintenancePage = !hasHealthyServers;
if (showMaintenancePage) {
logger.warn(
`Resource ${resource.name} (${fullDomain}) has no healthy servers - showing maintenance page (AUTOMATIC mode)`
);
}
}
}
if (showMaintenancePage) {
const maintenanceServiceName = `${key}-maintenance-service`;
const maintenanceRouterName = `${key}-maintenance-router`;
const rewriteMiddlewareName = `${key}-maintenance-rewrite`;
const entrypointHttp = config.getRawConfig().traefik.http_entrypoint;
const entrypointHttps = config.getRawConfig().traefik.https_entrypoint;
const fullDomain = resource.fullDomain;
const domainParts = fullDomain.split(".");
const wildCard = resource.subdomain
? `*.${domainParts.slice(1).join(".")}`
: fullDomain;
const maintenancePort = config.getRawConfig().server.next_port;
const maintenanceHost = config.getRawConfig().server.internal_hostname;
config_output.http.services[maintenanceServiceName] = {
loadBalancer: {
servers: [{ url: `http://${maintenanceHost}:${maintenancePort}` }],
passHostHeader: true
}
};
// middleware to rewrite path to /maintenance-screen
if (!config_output.http.middlewares) {
config_output.http.middlewares = {};
}
config_output.http.middlewares[rewriteMiddlewareName] = {
replacePathRegex: {
regex: "^/(.*)",
replacement: "/maintenance-screen"
}
};
config_output.http.routers[maintenanceRouterName] = {
entryPoints: [resource.ssl ? entrypointHttps : entrypointHttp],
service: maintenanceServiceName,
middlewares: [rewriteMiddlewareName],
rule: rule,
priority: 2000,
...(resource.ssl ? { tls } : {})
};
// Router to allow Next.js assets to load without rewrite
config_output.http.routers[`${maintenanceRouterName}-assets`] = {
entryPoints: [resource.ssl ? entrypointHttps : entrypointHttp],
service: maintenanceServiceName,
rule: `Host(\`${fullDomain}\`) && (PathPrefix(\`/_next\`) || PathRegexp(\`^/__nextjs*\`))`,
priority: 2001,
...(resource.ssl ? { tls } : {})
};
// logger.info(`Maintenance mode active for ${fullDomain}`);
continue;
}
// Handle path rewriting middleware
if (
@@ -608,29 +615,6 @@ export async function getTraefikConfig(
}
}
let rule = `Host(\`${fullDomain}\`)`;
// priority logic
let priority: number;
if (resource.priority && resource.priority != 100) {
priority = resource.priority;
} else {
priority = 100;
if (resource.path && resource.pathMatchType) {
priority += 10;
if (resource.pathMatchType === "exact") {
priority += 5;
} else if (resource.pathMatchType === "prefix") {
priority += 3;
} else if (resource.pathMatchType === "regex") {
priority += 2;
}
if (resource.path === "/") {
priority = 1; // lowest for catch-all
}
}
}
if (resource.path && resource.pathMatchType) {
//priority += 1;
// add path to rule based on match type
@@ -661,18 +645,6 @@ export async function getTraefikConfig(
...(resource.ssl ? { tls } : {})
};
if (resource.ssl) {
config_output.http.routers![routerName + "-redirect"] = {
entryPoints: [
config.getRawConfig().traefik.http_entrypoint
],
middlewares: [redirectHttpsMiddlewareName],
service: serviceName,
rule: rule,
priority: priority
};
}
config_output.http.services![serviceName] = {
loadBalancer: {
servers: (() => {

View File

@@ -1,3 +1,4 @@
import { Metadata } from "next";
import { headers } from "next/headers";
import { priv } from "@app/lib/api";
import { GetMaintenanceInfoResponse } from "@server/routers/resource/types";
@@ -10,9 +11,14 @@ import {
} from "@app/components/ui/card";
import { Alert, AlertTitle, AlertDescription } from "@app/components/ui/alert";
import { Clock } from "lucide-react";
import { AxiosResponse } from "axios";
export const dynamic = "force-dynamic";
export const metadata: Metadata = {
title: "Maintenance"
};
export default async function MaintenanceScreen() {
const t = await getTranslations();
@@ -25,12 +31,12 @@ export default async function MaintenanceScreen() {
const host = headersList.get("host") || "";
const hostname = host.split(":")[0];
const res = await priv.get<GetMaintenanceInfoResponse>(
const res = await priv.get<AxiosResponse<GetMaintenanceInfoResponse>>(
`/maintenance/info?fullDomain=${encodeURIComponent(hostname)}`
);
if (res && res.status === 200) {
const maintenanceInfo = res.data;
const maintenanceInfo = res.data.data;
title = maintenanceInfo?.maintenanceTitle || title;
message = maintenanceInfo?.maintenanceMessage || message;
estimatedTime = maintenanceInfo?.maintenanceEstimatedTime || null;