fosrl.pangolin/server/routers/traefik/getTraefikConfig.ts

168 lines
5.7 KiB
TypeScript
Raw Normal View History

2024-09-28 22:50:10 -04:00
import { Request, Response } from "express";
import db from "@server/db";
import * as schema from "@server/db/schema";
import { and, eq, isNotNull } from "drizzle-orm";
2024-09-28 22:50:10 -04:00
import logger from "@server/logger";
2024-10-01 20:48:03 -04:00
import HttpCode from "@server/types/HttpCode";
2024-10-12 18:21:31 -04:00
import config from "@server/config";
2024-09-28 22:50:10 -04:00
export async function traefikConfigProvider(
_: Request,
res: Response,
): Promise<any> {
2024-09-28 22:50:10 -04:00
try {
const all = await db
.select()
.from(schema.targets)
.innerJoin(
schema.resources,
eq(schema.targets.resourceId, schema.resources.resourceId),
)
.innerJoin(
schema.orgs,
eq(schema.resources.orgId, schema.orgs.orgId),
)
.innerJoin(
schema.sites,
eq(schema.sites.siteId, schema.resources.siteId),
)
.where(
and(
eq(schema.targets.enabled, true),
isNotNull(schema.resources.subdomain),
isNotNull(schema.orgs.domain),
),
);
2024-09-28 22:50:10 -04:00
if (!all.length) {
return res.status(HttpCode.OK).json({});
}
const badgerMiddlewareName = "badger";
const redirectMiddlewareName = "redirect-to-https";
2024-09-28 22:50:10 -04:00
// const baseDomain = new URL(config.app.base_url).hostname;
const http: any = {
routers: {},
services: {},
middlewares: {
[badgerMiddlewareName]: {
plugin: {
[badgerMiddlewareName]: {
apiBaseUrl: new URL(
"/api/v1",
`http://${config.server.internal_hostname}:${config.server.internal_port}`,
).href,
resourceSessionCookieName:
config.badger.resource_session_cookie_name,
userSessionCookieName:
config.server.session_cookie_name,
sessionQueryParameter:
config.badger.session_query_parameter,
},
2024-09-29 14:37:26 -04:00
},
},
[redirectMiddlewareName]: {
redirectScheme: {
scheme: "https",
permanent: true,
},
},
2024-09-29 14:37:26 -04:00
},
2024-09-28 22:50:10 -04:00
};
for (const item of all) {
const target = item.targets;
const resource = item.resources;
const site = item.sites;
const org = item.orgs;
const routerName = `${target.targetId}-router`;
const serviceName = `${target.targetId}-service`;
2024-09-28 22:50:10 -04:00
if (!resource || !resource.subdomain) {
continue;
}
if (!org || !org.domain) {
continue;
}
const fullDomain = `${resource.subdomain}.${org.domain}`;
const domainParts = fullDomain.split(".");
let wildCard;
if (domainParts.length <= 2) {
wildCard = `*.${domainParts.join(".")}`;
} else {
wildCard = `*.${domainParts.slice(1).join(".")}`;
}
const tls = {
certResolver: config.traefik.cert_resolver,
...(config.traefik.prefer_wildcard_cert
? {
domains: [
{
2024-10-28 23:34:04 -04:00
main: wildCard,
},
],
}
: {}),
};
http.routers![routerName] = {
entryPoints: [
2024-10-28 23:34:04 -04:00
resource.ssl
? config.traefik.https_entrypoint
: config.traefik.http_entrypoint,
2024-09-28 22:50:10 -04:00
],
2024-10-28 23:34:04 -04:00
middlewares: resource.ssl ? [badgerMiddlewareName] : [],
service: serviceName,
rule: `Host(\`${fullDomain}\`)`,
2024-10-28 23:34:04 -04:00
...(resource.ssl ? { tls } : {}),
};
2024-09-28 22:50:10 -04:00
2024-10-28 23:34:04 -04:00
if (resource.ssl) {
// this is a redirect router; all it does is redirect to the https version if tls is enabled
http.routers![routerName + "-redirect"] = {
entryPoints: [config.traefik.http_entrypoint],
middlewares: [redirectMiddlewareName],
service: serviceName,
rule: `Host(\`${fullDomain}\`)`,
};
}
if (site.type === "newt") {
const ip = site.subnet.split("/")[0];
http.services![serviceName] = {
loadBalancer: {
servers: [
{
url: `${target.method}://${ip}:${target.internalPort}`,
},
],
},
};
} else if (site.type === "wireguard") {
http.services![serviceName] = {
loadBalancer: {
servers: [
{
url: `${target.method}://${target.ip}:${target.port}`,
},
],
},
};
}
}
2024-09-28 22:50:10 -04:00
return res.status(HttpCode.OK).json({ http });
} catch (e) {
logger.error(`Failed to build traefik config: ${e}`);
return res.status(HttpCode.INTERNAL_SERVER_ERROR).json({
error: "Failed to build traefik config",
});
}
2024-09-28 22:50:10 -04:00
}