mirror of
https://github.com/fosrl/pangolin.git
synced 2025-08-21 09:48:39 +02:00
Also allow local traefikConfig
This commit is contained in:
parent
8c8a981452
commit
fbefcfedb9
4 changed files with 253 additions and 148 deletions
78
server/lib/remoteCertificates/certificates.ts
Normal file
78
server/lib/remoteCertificates/certificates.ts
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
import axios from "axios";
|
||||||
|
import { tokenManager } from "../tokenManager";
|
||||||
|
import logger from "@server/logger";
|
||||||
|
import config from "../config";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get valid certificates for the specified domains
|
||||||
|
*/
|
||||||
|
export async function getValidCertificatesForDomainsHybrid(domains: Set<string>): Promise<
|
||||||
|
Array<{
|
||||||
|
id: number;
|
||||||
|
domain: string;
|
||||||
|
certFile: string | null;
|
||||||
|
keyFile: string | null;
|
||||||
|
expiresAt: Date | null;
|
||||||
|
updatedAt?: Date | null;
|
||||||
|
}>
|
||||||
|
> {
|
||||||
|
if (domains.size === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const domainArray = Array.from(domains);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get(
|
||||||
|
`${config.getRawConfig().hybrid?.endpoint}/api/v1/hybrid/certificates/domains`,
|
||||||
|
{
|
||||||
|
params: {
|
||||||
|
domains: domainArray
|
||||||
|
},
|
||||||
|
headers: (await tokenManager.getAuthHeader()).headers
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
logger.error(
|
||||||
|
`Failed to fetch certificates for domains: ${response.status} ${response.statusText}`,
|
||||||
|
{ responseData: response.data, domains: domainArray }
|
||||||
|
);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// logger.debug(
|
||||||
|
// `Successfully retrieved ${response.data.data?.length || 0} certificates for ${domainArray.length} domains`
|
||||||
|
// );
|
||||||
|
|
||||||
|
return response.data.data;
|
||||||
|
} catch (error) {
|
||||||
|
// pull data out of the axios error to log
|
||||||
|
if (axios.isAxiosError(error)) {
|
||||||
|
logger.error("Error getting certificates:", {
|
||||||
|
message: error.message,
|
||||||
|
code: error.code,
|
||||||
|
status: error.response?.status,
|
||||||
|
statusText: error.response?.statusText,
|
||||||
|
url: error.config?.url,
|
||||||
|
method: error.config?.method
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
logger.error("Error getting certificates:", error);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getValidCertificatesForDomains(domains: Set<string>): Promise<
|
||||||
|
Array<{
|
||||||
|
id: number;
|
||||||
|
domain: string;
|
||||||
|
certFile: string | null;
|
||||||
|
keyFile: string | null;
|
||||||
|
expiresAt: Date | null;
|
||||||
|
updatedAt?: Date | null;
|
||||||
|
}>
|
||||||
|
> {
|
||||||
|
return []; // stub
|
||||||
|
}
|
1
server/lib/remoteCertificates/index.ts
Normal file
1
server/lib/remoteCertificates/index.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from "./certificates";
|
|
@ -5,7 +5,16 @@ import logger from "@server/logger";
|
||||||
import * as yaml from "js-yaml";
|
import * as yaml from "js-yaml";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { db, exitNodes } from "@server/db";
|
import { db, exitNodes } from "@server/db";
|
||||||
|
import { eq } from "drizzle-orm";
|
||||||
import { tokenManager } from "./tokenManager";
|
import { tokenManager } from "./tokenManager";
|
||||||
|
import {
|
||||||
|
getCurrentExitNodeId,
|
||||||
|
getTraefikConfig
|
||||||
|
} from "@server/routers/traefik";
|
||||||
|
import {
|
||||||
|
getValidCertificatesForDomains,
|
||||||
|
getValidCertificatesForDomainsHybrid
|
||||||
|
} from "./remoteCertificates";
|
||||||
|
|
||||||
export class TraefikConfigManager {
|
export class TraefikConfigManager {
|
||||||
private intervalId: NodeJS.Timeout | null = null;
|
private intervalId: NodeJS.Timeout | null = null;
|
||||||
|
@ -14,11 +23,14 @@ export class TraefikConfigManager {
|
||||||
private timeoutId: NodeJS.Timeout | null = null;
|
private timeoutId: NodeJS.Timeout | null = null;
|
||||||
private lastCertificateFetch: Date | null = null;
|
private lastCertificateFetch: Date | null = null;
|
||||||
private lastKnownDomains = new Set<string>();
|
private lastKnownDomains = new Set<string>();
|
||||||
private lastLocalCertificateState = new Map<string, {
|
private lastLocalCertificateState = new Map<
|
||||||
|
string,
|
||||||
|
{
|
||||||
exists: boolean;
|
exists: boolean;
|
||||||
lastModified: Date | null;
|
lastModified: Date | null;
|
||||||
expiresAt: Date | null;
|
expiresAt: Date | null;
|
||||||
}>();
|
}
|
||||||
|
>();
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
|
@ -59,7 +71,9 @@ export class TraefikConfigManager {
|
||||||
|
|
||||||
// Initialize local certificate state
|
// Initialize local certificate state
|
||||||
this.lastLocalCertificateState = await this.scanLocalCertificateState();
|
this.lastLocalCertificateState = await this.scanLocalCertificateState();
|
||||||
logger.info(`Found ${this.lastLocalCertificateState.size} existing certificate directories`);
|
logger.info(
|
||||||
|
`Found ${this.lastLocalCertificateState.size} existing certificate directories`
|
||||||
|
);
|
||||||
|
|
||||||
// Run initial check
|
// Run initial check
|
||||||
await this.HandleTraefikConfig();
|
await this.HandleTraefikConfig();
|
||||||
|
@ -94,11 +108,16 @@ export class TraefikConfigManager {
|
||||||
/**
|
/**
|
||||||
* Scan local certificate directories to build current state
|
* Scan local certificate directories to build current state
|
||||||
*/
|
*/
|
||||||
private async scanLocalCertificateState(): Promise<Map<string, {
|
private async scanLocalCertificateState(): Promise<
|
||||||
|
Map<
|
||||||
|
string,
|
||||||
|
{
|
||||||
exists: boolean;
|
exists: boolean;
|
||||||
lastModified: Date | null;
|
lastModified: Date | null;
|
||||||
expiresAt: Date | null;
|
expiresAt: Date | null;
|
||||||
}>> {
|
}
|
||||||
|
>
|
||||||
|
> {
|
||||||
const state = new Map();
|
const state = new Map();
|
||||||
const certsPath = config.getRawConfig().traefik.certificates_path;
|
const certsPath = config.getRawConfig().traefik.certificates_path;
|
||||||
|
|
||||||
|
@ -127,7 +146,9 @@ export class TraefikConfigManager {
|
||||||
|
|
||||||
if (lastUpdateExists) {
|
if (lastUpdateExists) {
|
||||||
try {
|
try {
|
||||||
const lastUpdateStr = fs.readFileSync(lastUpdatePath, "utf8").trim();
|
const lastUpdateStr = fs
|
||||||
|
.readFileSync(lastUpdatePath, "utf8")
|
||||||
|
.trim();
|
||||||
lastModified = new Date(lastUpdateStr);
|
lastModified = new Date(lastUpdateStr);
|
||||||
} catch {
|
} catch {
|
||||||
// If we can't read the last update, fall back to file stats
|
// If we can't read the last update, fall back to file stats
|
||||||
|
@ -164,15 +185,20 @@ export class TraefikConfigManager {
|
||||||
|
|
||||||
// Fetch if it's been more than 24 hours (for renewals)
|
// Fetch if it's been more than 24 hours (for renewals)
|
||||||
const dayInMs = 24 * 60 * 60 * 1000;
|
const dayInMs = 24 * 60 * 60 * 1000;
|
||||||
const timeSinceLastFetch = Date.now() - this.lastCertificateFetch.getTime();
|
const timeSinceLastFetch =
|
||||||
|
Date.now() - this.lastCertificateFetch.getTime();
|
||||||
if (timeSinceLastFetch > dayInMs) {
|
if (timeSinceLastFetch > dayInMs) {
|
||||||
logger.info("Fetching certificates due to 24-hour renewal check");
|
logger.info("Fetching certificates due to 24-hour renewal check");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch if domains have changed
|
// Fetch if domains have changed
|
||||||
if (this.lastKnownDomains.size !== currentDomains.size ||
|
if (
|
||||||
!Array.from(this.lastKnownDomains).every(domain => currentDomains.has(domain))) {
|
this.lastKnownDomains.size !== currentDomains.size ||
|
||||||
|
!Array.from(this.lastKnownDomains).every((domain) =>
|
||||||
|
currentDomains.has(domain)
|
||||||
|
)
|
||||||
|
) {
|
||||||
logger.info("Fetching certificates due to domain changes");
|
logger.info("Fetching certificates due to domain changes");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -181,15 +207,21 @@ export class TraefikConfigManager {
|
||||||
for (const domain of currentDomains) {
|
for (const domain of currentDomains) {
|
||||||
const localState = this.lastLocalCertificateState.get(domain);
|
const localState = this.lastLocalCertificateState.get(domain);
|
||||||
if (!localState || !localState.exists) {
|
if (!localState || !localState.exists) {
|
||||||
logger.info(`Fetching certificates due to missing local cert for ${domain}`);
|
logger.info(
|
||||||
|
`Fetching certificates due to missing local cert for ${domain}`
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if certificate is expiring soon (within 30 days)
|
// Check if certificate is expiring soon (within 30 days)
|
||||||
if (localState.expiresAt) {
|
if (localState.expiresAt) {
|
||||||
const daysUntilExpiry = (localState.expiresAt.getTime() - Date.now()) / (1000 * 60 * 60 * 24);
|
const daysUntilExpiry =
|
||||||
|
(localState.expiresAt.getTime() - Date.now()) /
|
||||||
|
(1000 * 60 * 60 * 24);
|
||||||
if (daysUntilExpiry < 30) {
|
if (daysUntilExpiry < 30) {
|
||||||
logger.info(`Fetching certificates due to upcoming expiry for ${domain} (${Math.round(daysUntilExpiry)} days remaining)`);
|
logger.info(
|
||||||
|
`Fetching certificates due to upcoming expiry for ${domain} (${Math.round(daysUntilExpiry)} days remaining)`
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,7 +266,8 @@ export class TraefikConfigManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan current local certificate state
|
// Scan current local certificate state
|
||||||
this.lastLocalCertificateState = await this.scanLocalCertificateState();
|
this.lastLocalCertificateState =
|
||||||
|
await this.scanLocalCertificateState();
|
||||||
|
|
||||||
// Only fetch certificates if needed (domain changes, missing certs, or daily renewal check)
|
// Only fetch certificates if needed (domain changes, missing certs, or daily renewal check)
|
||||||
let validCertificates: Array<{
|
let validCertificates: Array<{
|
||||||
|
@ -248,18 +281,32 @@ export class TraefikConfigManager {
|
||||||
|
|
||||||
if (this.shouldFetchCertificates(domains)) {
|
if (this.shouldFetchCertificates(domains)) {
|
||||||
// Get valid certificates for active domains
|
// Get valid certificates for active domains
|
||||||
validCertificates = await this.getValidCertificatesForDomains(domains);
|
if (config.isHybridMode()) {
|
||||||
|
validCertificates =
|
||||||
|
await getValidCertificatesForDomainsHybrid(domains);
|
||||||
|
} else {
|
||||||
|
validCertificates =
|
||||||
|
await getValidCertificatesForDomains(domains);
|
||||||
|
}
|
||||||
this.lastCertificateFetch = new Date();
|
this.lastCertificateFetch = new Date();
|
||||||
this.lastKnownDomains = new Set(domains);
|
this.lastKnownDomains = new Set(domains);
|
||||||
|
|
||||||
logger.info(`Fetched ${validCertificates.length} certificates from remote`);
|
logger.info(
|
||||||
|
`Fetched ${validCertificates.length} certificates from remote`
|
||||||
|
);
|
||||||
|
|
||||||
// Download and decrypt new certificates
|
// Download and decrypt new certificates
|
||||||
await this.processValidCertificates(validCertificates);
|
await this.processValidCertificates(validCertificates);
|
||||||
} else {
|
} else {
|
||||||
const timeSinceLastFetch = this.lastCertificateFetch ?
|
const timeSinceLastFetch = this.lastCertificateFetch
|
||||||
Math.round((Date.now() - this.lastCertificateFetch.getTime()) / (1000 * 60)) : 0;
|
? Math.round(
|
||||||
logger.debug(`Skipping certificate fetch - no changes detected and within 24-hour window (last fetch: ${timeSinceLastFetch} minutes ago)`);
|
(Date.now() - this.lastCertificateFetch.getTime()) /
|
||||||
|
(1000 * 60)
|
||||||
|
)
|
||||||
|
: 0;
|
||||||
|
logger.debug(
|
||||||
|
`Skipping certificate fetch - no changes detected and within 24-hour window (last fetch: ${timeSinceLastFetch} minutes ago)`
|
||||||
|
);
|
||||||
|
|
||||||
// Still need to ensure config is up to date with existing certificates
|
// Still need to ensure config is up to date with existing certificates
|
||||||
await this.updateDynamicConfigFromLocalCerts(domains);
|
await this.updateDynamicConfigFromLocalCerts(domains);
|
||||||
|
@ -276,7 +323,18 @@ export class TraefikConfigManager {
|
||||||
|
|
||||||
// Send domains to SNI proxy
|
// Send domains to SNI proxy
|
||||||
try {
|
try {
|
||||||
const [exitNode] = await db.select().from(exitNodes).limit(1);
|
let exitNode;
|
||||||
|
if (config.getRawConfig().gerbil.exit_node_name) {
|
||||||
|
const exitNodeName =
|
||||||
|
config.getRawConfig().gerbil.exit_node_name!;
|
||||||
|
[exitNode] = await db
|
||||||
|
.select()
|
||||||
|
.from(exitNodes)
|
||||||
|
.where(eq(exitNodes.name, exitNodeName))
|
||||||
|
.limit(1);
|
||||||
|
} else {
|
||||||
|
[exitNode] = await db.select().from(exitNodes).limit(1);
|
||||||
|
}
|
||||||
if (exitNode) {
|
if (exitNode) {
|
||||||
try {
|
try {
|
||||||
await axios.post(
|
await axios.post(
|
||||||
|
@ -300,7 +358,9 @@ export class TraefikConfigManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.error("No exit node found. Has gerbil registered yet?");
|
logger.error(
|
||||||
|
"No exit node found. Has gerbil registered yet?"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error("Failed to post domains to SNI proxy:", err);
|
logger.error("Failed to post domains to SNI proxy:", err);
|
||||||
|
@ -320,7 +380,9 @@ export class TraefikConfigManager {
|
||||||
domains: Set<string>;
|
domains: Set<string>;
|
||||||
traefikConfig: any;
|
traefikConfig: any;
|
||||||
} | null> {
|
} | null> {
|
||||||
|
let traefikConfig;
|
||||||
try {
|
try {
|
||||||
|
if (config.isHybridMode()) {
|
||||||
const resp = await axios.get(
|
const resp = await axios.get(
|
||||||
`${config.getRawConfig().hybrid?.endpoint}/api/v1/hybrid/traefik-config`,
|
`${config.getRawConfig().hybrid?.endpoint}/api/v1/hybrid/traefik-config`,
|
||||||
await tokenManager.getAuthHeader()
|
await tokenManager.getAuthHeader()
|
||||||
|
@ -334,7 +396,15 @@ export class TraefikConfigManager {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const traefikConfig = resp.data.data;
|
traefikConfig = resp.data.data;
|
||||||
|
} else {
|
||||||
|
const currentExitNode = await getCurrentExitNodeId();
|
||||||
|
traefikConfig = await getTraefikConfig(
|
||||||
|
currentExitNode,
|
||||||
|
config.getRawConfig().traefik.site_types
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const domains = new Set<string>();
|
const domains = new Set<string>();
|
||||||
|
|
||||||
if (traefikConfig?.http?.routers) {
|
if (traefikConfig?.http?.routers) {
|
||||||
|
@ -445,8 +515,11 @@ export class TraefikConfigManager {
|
||||||
/**
|
/**
|
||||||
* Update dynamic config from existing local certificates without fetching from remote
|
* Update dynamic config from existing local certificates without fetching from remote
|
||||||
*/
|
*/
|
||||||
private async updateDynamicConfigFromLocalCerts(domains: Set<string>): Promise<void> {
|
private async updateDynamicConfigFromLocalCerts(
|
||||||
const dynamicConfigPath = config.getRawConfig().traefik.dynamic_cert_config_path;
|
domains: Set<string>
|
||||||
|
): Promise<void> {
|
||||||
|
const dynamicConfigPath =
|
||||||
|
config.getRawConfig().traefik.dynamic_cert_config_path;
|
||||||
|
|
||||||
// Load existing dynamic config if it exists, otherwise initialize
|
// Load existing dynamic config if it exists, otherwise initialize
|
||||||
let dynamicConfig: any = { tls: { certificates: [] } };
|
let dynamicConfig: any = { tls: { certificates: [] } };
|
||||||
|
@ -454,7 +527,8 @@ export class TraefikConfigManager {
|
||||||
try {
|
try {
|
||||||
const fileContent = fs.readFileSync(dynamicConfigPath, "utf8");
|
const fileContent = fs.readFileSync(dynamicConfigPath, "utf8");
|
||||||
dynamicConfig = yaml.load(fileContent) || dynamicConfig;
|
dynamicConfig = yaml.load(fileContent) || dynamicConfig;
|
||||||
if (!dynamicConfig.tls) dynamicConfig.tls = { certificates: [] };
|
if (!dynamicConfig.tls)
|
||||||
|
dynamicConfig.tls = { certificates: [] };
|
||||||
if (!Array.isArray(dynamicConfig.tls.certificates)) {
|
if (!Array.isArray(dynamicConfig.tls.certificates)) {
|
||||||
dynamicConfig.tls.certificates = [];
|
dynamicConfig.tls.certificates = [];
|
||||||
}
|
}
|
||||||
|
@ -495,67 +569,6 @@ export class TraefikConfigManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get valid certificates for the specified domains
|
|
||||||
*/
|
|
||||||
private async getValidCertificatesForDomains(domains: Set<string>): Promise<
|
|
||||||
Array<{
|
|
||||||
id: number;
|
|
||||||
domain: string;
|
|
||||||
certFile: string | null;
|
|
||||||
keyFile: string | null;
|
|
||||||
expiresAt: Date | null;
|
|
||||||
updatedAt?: Date | null;
|
|
||||||
}>
|
|
||||||
> {
|
|
||||||
if (domains.size === 0) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const domainArray = Array.from(domains);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await axios.get(
|
|
||||||
`${config.getRawConfig().hybrid?.endpoint}/api/v1/hybrid/certificates/domains`,
|
|
||||||
{
|
|
||||||
params: {
|
|
||||||
domains: domainArray
|
|
||||||
},
|
|
||||||
headers: (await tokenManager.getAuthHeader()).headers
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.status !== 200) {
|
|
||||||
logger.error(
|
|
||||||
`Failed to fetch certificates for domains: ${response.status} ${response.statusText}`,
|
|
||||||
{ responseData: response.data, domains: domainArray }
|
|
||||||
);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// logger.debug(
|
|
||||||
// `Successfully retrieved ${response.data.data?.length || 0} certificates for ${domainArray.length} domains`
|
|
||||||
// );
|
|
||||||
|
|
||||||
return response.data.data;
|
|
||||||
} catch (error) {
|
|
||||||
// pull data out of the axios error to log
|
|
||||||
if (axios.isAxiosError(error)) {
|
|
||||||
logger.error("Error getting certificates:", {
|
|
||||||
message: error.message,
|
|
||||||
code: error.code,
|
|
||||||
status: error.response?.status,
|
|
||||||
statusText: error.response?.statusText,
|
|
||||||
url: error.config?.url,
|
|
||||||
method: error.config?.method
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
logger.error("Error getting certificates:", error);
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process valid certificates - download and decrypt them
|
* Process valid certificates - download and decrypt them
|
||||||
*/
|
*/
|
|
@ -11,17 +11,10 @@ let currentExitNodeId: number;
|
||||||
const redirectHttpsMiddlewareName = "redirect-to-https";
|
const redirectHttpsMiddlewareName = "redirect-to-https";
|
||||||
const badgerMiddlewareName = "badger";
|
const badgerMiddlewareName = "badger";
|
||||||
|
|
||||||
export async function traefikConfigProvider(
|
export async function getCurrentExitNodeId(): Promise<number> {
|
||||||
_: Request,
|
|
||||||
res: Response
|
|
||||||
): Promise<any> {
|
|
||||||
try {
|
|
||||||
// First query to get resources with site and org info
|
|
||||||
// Get the current exit node name from config
|
|
||||||
if (!currentExitNodeId) {
|
if (!currentExitNodeId) {
|
||||||
if (config.getRawConfig().gerbil.exit_node_name) {
|
if (config.getRawConfig().gerbil.exit_node_name) {
|
||||||
const exitNodeName =
|
const exitNodeName = config.getRawConfig().gerbil.exit_node_name!;
|
||||||
config.getRawConfig().gerbil.exit_node_name!;
|
|
||||||
const [exitNode] = await db
|
const [exitNode] = await db
|
||||||
.select({
|
.select({
|
||||||
exitNodeId: exitNodes.exitNodeId
|
exitNodeId: exitNodes.exitNodeId
|
||||||
|
@ -44,8 +37,22 @@ export async function traefikConfigProvider(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return currentExitNodeId;
|
||||||
|
}
|
||||||
|
|
||||||
let traefikConfig = await getTraefikConfig(currentExitNodeId, config.getRawConfig().traefik.site_types);
|
export async function traefikConfigProvider(
|
||||||
|
_: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<any> {
|
||||||
|
try {
|
||||||
|
// First query to get resources with site and org info
|
||||||
|
// Get the current exit node name from config
|
||||||
|
await getCurrentExitNodeId();
|
||||||
|
|
||||||
|
let traefikConfig = await getTraefikConfig(
|
||||||
|
currentExitNodeId,
|
||||||
|
config.getRawConfig().traefik.site_types
|
||||||
|
);
|
||||||
|
|
||||||
traefikConfig.http.middlewares[badgerMiddlewareName] = {
|
traefikConfig.http.middlewares[badgerMiddlewareName] = {
|
||||||
plugin: {
|
plugin: {
|
||||||
|
@ -80,7 +87,10 @@ export async function traefikConfigProvider(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getTraefikConfig(exitNodeId: number, siteTypes: string[]): Promise<any> {
|
export async function getTraefikConfig(
|
||||||
|
exitNodeId: number,
|
||||||
|
siteTypes: string[]
|
||||||
|
): Promise<any> {
|
||||||
// Define extended target type with site information
|
// Define extended target type with site information
|
||||||
type TargetWithSite = Target & {
|
type TargetWithSite = Target & {
|
||||||
site: {
|
site: {
|
||||||
|
@ -135,7 +145,7 @@ export async function getTraefikConfig(exitNodeId: number, siteTypes: string[]):
|
||||||
eq(sites.exitNodeId, exitNodeId),
|
eq(sites.exitNodeId, exitNodeId),
|
||||||
isNull(sites.exitNodeId)
|
isNull(sites.exitNodeId)
|
||||||
),
|
),
|
||||||
inArray(sites.type, siteTypes),
|
inArray(sites.type, siteTypes)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -438,7 +448,10 @@ export async function getTraefikConfig(exitNodeId: number, siteTypes: string[]):
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (target.site.type === "newt") {
|
} else if (target.site.type === "newt") {
|
||||||
if (!target.internalPort || !target.site.subnet) {
|
if (
|
||||||
|
!target.internalPort ||
|
||||||
|
!target.site.subnet
|
||||||
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue