mirror of
https://github.com/fosrl/pangolin.git
synced 2025-08-05 02:24:59 +02:00
use fullDomain from resources in get traefik config
This commit is contained in:
parent
92ae69ae29
commit
9320f99920
5 changed files with 143 additions and 136 deletions
|
@ -47,9 +47,7 @@ app.prepare().then(() => {
|
|||
}
|
||||
|
||||
const prefix = `/api/v1`;
|
||||
if (dev) {
|
||||
externalServer.use(logIncomingMiddleware);
|
||||
}
|
||||
externalServer.use(logIncomingMiddleware);
|
||||
externalServer.use(prefix, unauthenticated);
|
||||
externalServer.use(prefix, authenticated);
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import response from "@server/utils/response";
|
|||
import HttpCode from "@server/types/HttpCode";
|
||||
import createHttpError from "http-errors";
|
||||
import { sql, inArray } from "drizzle-orm";
|
||||
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
|
||||
import logger from "@server/logger";
|
||||
|
||||
const listOrgsSchema = z.object({
|
||||
|
@ -32,7 +31,7 @@ export type ListOrgsResponse = {
|
|||
export async function listOrgs(
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
try {
|
||||
const parsedQuery = listOrgsSchema.safeParse(req.query);
|
||||
|
@ -40,13 +39,15 @@ export async function listOrgs(
|
|||
return next(
|
||||
createHttpError(
|
||||
HttpCode.BAD_REQUEST,
|
||||
parsedQuery.error.errors.map((e) => e.message).join(", "),
|
||||
),
|
||||
parsedQuery.error.errors.map((e) => e.message).join(", ")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const { limit, offset } = parsedQuery.data;
|
||||
|
||||
logger.debug("here0")
|
||||
|
||||
// Use the userOrgs passed from the middleware
|
||||
const userOrgIds = req.userOrgIds;
|
||||
|
||||
|
@ -65,6 +66,7 @@ export async function listOrgs(
|
|||
message: "No organizations found for the user",
|
||||
status: HttpCode.OK,
|
||||
});
|
||||
logger.debug("here1")
|
||||
}
|
||||
|
||||
const organizations = await db
|
||||
|
@ -80,6 +82,8 @@ export async function listOrgs(
|
|||
.where(inArray(orgs.orgId, userOrgIds));
|
||||
const totalCount = totalCountResult[0].count;
|
||||
|
||||
logger.debug("here2")
|
||||
|
||||
return response<ListOrgsResponse>(res, {
|
||||
data: {
|
||||
orgs: organizations,
|
||||
|
@ -99,8 +103,8 @@ export async function listOrgs(
|
|||
return next(
|
||||
createHttpError(
|
||||
HttpCode.INTERNAL_SERVER_ERROR,
|
||||
"An error occurred...",
|
||||
),
|
||||
"An error occurred..."
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,100 +2,97 @@ import { Request, Response } from "express";
|
|||
import db from "@server/db";
|
||||
import * as schema from "@server/db/schema";
|
||||
import { DynamicTraefikConfig } from "./configSchema";
|
||||
import { and, like, eq, isNotNull } from "drizzle-orm";
|
||||
import { and, eq, isNotNull } from "drizzle-orm";
|
||||
import logger from "@server/logger";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
import config from "@server/config";
|
||||
|
||||
export async function traefikConfigProvider(_: Request, res: Response) {
|
||||
export async function traefikConfigProvider(
|
||||
_: Request,
|
||||
res: Response
|
||||
): Promise<any> {
|
||||
try {
|
||||
const targets = await getAllTargets();
|
||||
const traefikConfig = buildTraefikConfig(targets);
|
||||
res.status(HttpCode.OK).json(traefikConfig);
|
||||
const all = await db
|
||||
.select()
|
||||
.from(schema.targets)
|
||||
.innerJoin(
|
||||
schema.resources,
|
||||
eq(schema.targets.resourceId, schema.resources.resourceId)
|
||||
)
|
||||
.where(
|
||||
and(
|
||||
eq(schema.targets.enabled, true),
|
||||
isNotNull(schema.resources.fullDomain)
|
||||
)
|
||||
);
|
||||
|
||||
if (!all.length) {
|
||||
return { http: {} } as DynamicTraefikConfig;
|
||||
}
|
||||
|
||||
const middlewareName = "badger";
|
||||
|
||||
const baseDomain = new URL(config.app.base_url).hostname;
|
||||
|
||||
const tls = {
|
||||
certResolver: config.traefik.cert_resolver,
|
||||
...(config.traefik.prefer_wildcard_cert
|
||||
? { domains: [baseDomain, `*.${baseDomain}`] }
|
||||
: {}),
|
||||
};
|
||||
|
||||
const http: any = {
|
||||
routers: {},
|
||||
services: {},
|
||||
middlewares: {
|
||||
[middlewareName]: {
|
||||
plugin: {
|
||||
[middlewareName]: {
|
||||
apiBaseUrl: new URL(
|
||||
"/api/v1",
|
||||
`http://${config.server.internal_hostname}:${config.server.internal_port}`
|
||||
).href,
|
||||
appBaseUrl: config.app.base_url,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
for (const item of all) {
|
||||
const target = item.targets;
|
||||
const resource = item.resources;
|
||||
|
||||
const routerName = `${target.targetId}-router`;
|
||||
const serviceName = `${target.targetId}-service`;
|
||||
|
||||
http.routers![routerName] = {
|
||||
entryPoints: [
|
||||
target.ssl
|
||||
? config.traefik.https_entrypoint
|
||||
: config.traefik.http_entrypoint,
|
||||
],
|
||||
middlewares: [middlewareName],
|
||||
service: serviceName,
|
||||
rule: `Host(\`${resource.fullDomain}\`)`,
|
||||
...(target.ssl ? { tls } : {}),
|
||||
};
|
||||
|
||||
http.services![serviceName] = {
|
||||
loadBalancer: {
|
||||
servers: [
|
||||
{
|
||||
url: `${target.method}://${target.ip}:${target.port}`,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return res.status(HttpCode.OK).json({ http });
|
||||
} catch (e) {
|
||||
logger.error(`Failed to build traefik config: ${e}`);
|
||||
res.status(HttpCode.INTERNAL_SERVER_ERROR).json({
|
||||
return res.status(HttpCode.INTERNAL_SERVER_ERROR).json({
|
||||
error: "Failed to build traefik config",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function buildTraefikConfig(
|
||||
targets: schema.Target[]
|
||||
): DynamicTraefikConfig {
|
||||
if (!targets.length) {
|
||||
return { http: {} } as DynamicTraefikConfig;
|
||||
}
|
||||
|
||||
const middlewareName = "badger";
|
||||
|
||||
const baseDomain = new URL(config.app.base_url).hostname;
|
||||
|
||||
const tls = {
|
||||
certResolver: config.traefik.cert_resolver,
|
||||
...(config.traefik.prefer_wildcard_cert
|
||||
? { domains: [baseDomain, `*.${baseDomain}`] }
|
||||
: {}),
|
||||
};
|
||||
|
||||
const http: any = {
|
||||
routers: {},
|
||||
services: {},
|
||||
middlewares: {
|
||||
[middlewareName]: {
|
||||
plugin: {
|
||||
[middlewareName]: {
|
||||
apiBaseUrl: new URL(
|
||||
"/api/v1",
|
||||
`http://${config.server.internal_hostname}:${config.server.internal_port}`
|
||||
).href,
|
||||
appBaseUrl: config.app.base_url,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
for (const target of targets) {
|
||||
const routerName = `${target.targetId}-router`;
|
||||
const serviceName = `${target.targetId}-service`;
|
||||
|
||||
http.routers![routerName] = {
|
||||
entryPoints: [
|
||||
target.ssl
|
||||
? config.traefik.https_entrypoint
|
||||
: config.traefik.http_entrypoint,
|
||||
],
|
||||
middlewares: [middlewareName],
|
||||
service: serviceName,
|
||||
rule: `Host(\`${target.resourceId}\`)`, // assuming resourceId is a valid full hostname
|
||||
...(target.ssl ? { tls } : {}),
|
||||
};
|
||||
|
||||
http.services![serviceName] = {
|
||||
loadBalancer: {
|
||||
servers: [
|
||||
{ url: `${target.method}://${target.ip}:${target.port}` },
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return { http } as DynamicTraefikConfig;
|
||||
}
|
||||
|
||||
export async function getAllTargets(): Promise<schema.Target[]> {
|
||||
const all = await db
|
||||
.select()
|
||||
.from(schema.targets)
|
||||
.innerJoin(
|
||||
schema.resources,
|
||||
eq(schema.targets.resourceId, schema.resources.resourceId)
|
||||
)
|
||||
.where(
|
||||
and(
|
||||
eq(schema.targets.enabled, true),
|
||||
isNotNull(schema.resources.fullDomain)
|
||||
)
|
||||
);
|
||||
return all.map((row) => row.targets);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue