mirror of
https://github.com/fosrl/pangolin.git
synced 2026-08-15 08:49:59 +02:00
135 lines
4.0 KiB
TypeScript
135 lines
4.0 KiB
TypeScript
import { TargetWithSite } from "./types";
|
|
|
|
/**
|
|
* Build the loadBalancer.servers list for an HTTP-mode resource, preferring
|
|
* currently-online sites but falling back to all enabled/healthy targets if
|
|
* none are online yet (so there's still some feedback before sites report
|
|
* back over the receive-bandwidth endpoint).
|
|
*/
|
|
export function buildHttpLoadBalancerServers(targets: TargetWithSite[]) {
|
|
const anySitesOnline = targets.some((target) => target.site.online);
|
|
|
|
return targets
|
|
.filter((target) => {
|
|
if (!target.enabled) {
|
|
return false;
|
|
}
|
|
|
|
if (target.health == "unhealthy") {
|
|
return false;
|
|
}
|
|
|
|
// If any sites are online, exclude offline sites
|
|
if (anySitesOnline && !target.site.online) {
|
|
return false;
|
|
}
|
|
|
|
if (
|
|
target.site.type === "local" ||
|
|
target.site.type === "wireguard"
|
|
) {
|
|
if (!target.ip || !target.port || !target.method) {
|
|
return false;
|
|
}
|
|
} else if (target.site.type === "newt") {
|
|
if (
|
|
!target.internalPort ||
|
|
!target.method ||
|
|
!target.site.subnet
|
|
) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
})
|
|
.map((target) => {
|
|
if (
|
|
target.site.type === "local" ||
|
|
target.site.type === "wireguard"
|
|
) {
|
|
return {
|
|
url: `${target.method}://${target.ip}:${target.port}`
|
|
};
|
|
} else if (target.site.type === "newt") {
|
|
const ip = target.site.subnet!.split("/")[0];
|
|
return {
|
|
url: `${target.method}://${ip}:${target.internalPort}`
|
|
};
|
|
}
|
|
})
|
|
.filter(
|
|
(v, i, a) => a.findIndex((t) => t && v && t.url === v.url) === i
|
|
);
|
|
}
|
|
|
|
export function buildStickySessionCookie(ssl: boolean | null) {
|
|
return {
|
|
sticky: {
|
|
cookie: {
|
|
name: "p_sticky", // TODO: make this configurable via config.yml like other cookies
|
|
secure: ssl,
|
|
httpOnly: true
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Build the loadBalancer.servers list for a TCP/UDP-mode resource.
|
|
*/
|
|
export function buildTcpUdpLoadBalancerServers(targets: TargetWithSite[]) {
|
|
const anySitesOnline = targets.some((target) => target.site.online);
|
|
|
|
return targets
|
|
.filter((target) => {
|
|
if (!target.enabled) {
|
|
return false;
|
|
}
|
|
|
|
// If any sites are online, exclude offline sites
|
|
if (anySitesOnline && !target.site.online) {
|
|
return false;
|
|
}
|
|
|
|
if (
|
|
target.site.type === "local" ||
|
|
target.site.type === "wireguard"
|
|
) {
|
|
if (!target.ip || !target.port) {
|
|
return false;
|
|
}
|
|
} else if (target.site.type === "newt") {
|
|
if (!target.internalPort || !target.site.subnet) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
})
|
|
.map((target) => {
|
|
if (
|
|
target.site.type === "local" ||
|
|
target.site.type === "wireguard"
|
|
) {
|
|
return {
|
|
address: `${target.ip}:${target.port}`
|
|
};
|
|
} else if (target.site.type === "newt") {
|
|
const ip = target.site.subnet!.split("/")[0];
|
|
return {
|
|
address: `${ip}:${target.internalPort}`
|
|
};
|
|
}
|
|
});
|
|
}
|
|
|
|
export function buildStickySessionIp() {
|
|
return {
|
|
sticky: {
|
|
ipStrategy: {
|
|
depth: 0,
|
|
sourcePort: true
|
|
}
|
|
}
|
|
};
|
|
}
|