mirror of
https://github.com/fosrl/pangolin.git
synced 2026-01-29 06:10:47 +00:00
Get the headers into the traefik config
This commit is contained in:
@@ -31,6 +31,8 @@ def convert_and_send(file_path, url, headers):
|
||||
|
||||
# convert the parsed YAML to a JSON string
|
||||
json_payload = json.dumps(parsed_yaml)
|
||||
print("Converted JSON payload:")
|
||||
print(json_payload)
|
||||
|
||||
# Encode the JSON string to Base64
|
||||
encoded_json = base64.b64encode(json_payload.encode('utf-8')).decode('utf-8')
|
||||
|
||||
@@ -5,16 +5,19 @@ resources:
|
||||
full-domain: level1.test3.example.com
|
||||
host-header: example.com
|
||||
tls-server-name: example.com
|
||||
auth:
|
||||
pincode: 123456
|
||||
password: sadfasdfadsf
|
||||
sso-enabled: true
|
||||
sso-roles:
|
||||
- Member
|
||||
sso-users:
|
||||
- owen@fossorial.io
|
||||
whitelist-users:
|
||||
- owen@fossorial.io
|
||||
# auth:
|
||||
# pincode: 123456
|
||||
# password: sadfasdfadsf
|
||||
# sso-enabled: true
|
||||
# sso-roles:
|
||||
# - Member
|
||||
# sso-users:
|
||||
# - owen@fossorial.io
|
||||
# whitelist-users:
|
||||
# - owen@fossorial.io
|
||||
headers:
|
||||
- X-Example-Header: example-value
|
||||
- X-Another-Header: another-value
|
||||
targets:
|
||||
- site: lively-yosemite-toad
|
||||
hostname: localhost
|
||||
@@ -24,15 +27,11 @@ resources:
|
||||
hostname: localhost
|
||||
method: http
|
||||
port: 8001
|
||||
- site: glossy-plains-viscacha-rat
|
||||
hostname: localhost
|
||||
method: http
|
||||
port: 8001
|
||||
resource-nice-id2:
|
||||
name: this is other resource
|
||||
protocol: tcp
|
||||
proxy-port: 3000
|
||||
targets:
|
||||
- site: glossy-plains-viscacha-rat
|
||||
- site: lively-yosemite-toad
|
||||
hostname: localhost
|
||||
port: 3000
|
||||
@@ -96,6 +96,7 @@ export const resources = pgTable("resources", {
|
||||
skipToIdpId: integer("skipToIdpId").references(() => idp.idpId, {
|
||||
onDelete: "cascade"
|
||||
}),
|
||||
headers: text("headers"), // comma-separated list of headers to add to the request
|
||||
});
|
||||
|
||||
export const targets = pgTable("targets", {
|
||||
|
||||
@@ -107,7 +107,8 @@ export const resources = sqliteTable("resources", {
|
||||
enableProxy: integer("enableProxy", { mode: "boolean" }).default(true),
|
||||
skipToIdpId: integer("skipToIdpId").references(() => idp.idpId, {
|
||||
onDelete: "cascade"
|
||||
})
|
||||
}),
|
||||
headers: text("headers"), // comma-separated list of headers to add to the request
|
||||
});
|
||||
|
||||
export const targets = sqliteTable("targets", {
|
||||
|
||||
@@ -120,6 +120,17 @@ export async function updateResources(
|
||||
const http = resourceData.protocol == "http";
|
||||
const protocol =
|
||||
resourceData.protocol == "http" ? "tcp" : resourceData.protocol;
|
||||
const resourceEnabled = resourceData.enabled == undefined || resourceData.enabled == null ? true : resourceData.enabled;
|
||||
let headers = "";
|
||||
for (const headerObj of resourceData.headers || []) {
|
||||
for (const [key, value] of Object.entries(headerObj)) {
|
||||
headers += `${key}: ${value},`;
|
||||
}
|
||||
}
|
||||
// if there are headers, remove the trailing comma
|
||||
if (headers.endsWith(",")) {
|
||||
headers = headers.slice(0, -1);
|
||||
}
|
||||
|
||||
if (existingResource) {
|
||||
let domain;
|
||||
@@ -152,7 +163,7 @@ export async function updateResources(
|
||||
fullDomain: http ? resourceData["full-domain"] : null,
|
||||
subdomain: domain ? domain.subdomain : null,
|
||||
domainId: domain ? domain.domainId : null,
|
||||
enabled: resourceData.enabled ? true : false,
|
||||
enabled: resourceEnabled,
|
||||
sso: resourceData.auth?.["sso-enabled"] || false,
|
||||
ssl: resourceData.ssl ? true : false,
|
||||
setHostHeader: resourceData["host-header"] || null,
|
||||
@@ -161,7 +172,8 @@ export async function updateResources(
|
||||
"whitelist-users"
|
||||
]
|
||||
? resourceData.auth["whitelist-users"].length > 0
|
||||
: false
|
||||
: false,
|
||||
headers: headers || null,
|
||||
})
|
||||
.where(
|
||||
eq(resources.resourceId, existingResource.resourceId)
|
||||
@@ -379,11 +391,12 @@ export async function updateResources(
|
||||
fullDomain: http ? resourceData["full-domain"] : null,
|
||||
subdomain: domain ? domain.subdomain : null,
|
||||
domainId: domain ? domain.domainId : null,
|
||||
enabled: resourceData.enabled ? true : false,
|
||||
enabled: resourceEnabled,
|
||||
sso: resourceData.auth?.["sso-enabled"] || false,
|
||||
setHostHeader: resourceData["host-header"] || null,
|
||||
tlsServerName: resourceData["tls-server-name"] || null,
|
||||
ssl: resourceData.ssl ? true : false
|
||||
ssl: resourceData.ssl ? true : false,
|
||||
headers: headers || null
|
||||
})
|
||||
.returning();
|
||||
|
||||
|
||||
@@ -44,7 +44,8 @@ export const ResourceSchema = z
|
||||
targets: z.array(TargetSchema.nullable()).optional().default([]),
|
||||
auth: AuthSchema.optional(),
|
||||
"host-header": z.string().optional(),
|
||||
"tls-server-name": z.string().optional()
|
||||
"tls-server-name": z.string().optional(),
|
||||
headers: z.array(z.record(z.string(), z.string())).optional().default([]),
|
||||
})
|
||||
.refine(
|
||||
(resource) => {
|
||||
|
||||
@@ -54,7 +54,8 @@ export async function traefikConfigProvider(
|
||||
config.getRawConfig().traefik.site_types
|
||||
);
|
||||
|
||||
if (traefikConfig?.http?.middlewares) { // BECAUSE SOMETIMES THE CONFIG CAN BE EMPTY IF THERE IS NOTHING
|
||||
if (traefikConfig?.http?.middlewares) {
|
||||
// BECAUSE SOMETIMES THE CONFIG CAN BE EMPTY IF THERE IS NOTHING
|
||||
traefikConfig.http.middlewares[badgerMiddlewareName] = {
|
||||
plugin: {
|
||||
[badgerMiddlewareName]: {
|
||||
@@ -124,6 +125,7 @@ export async function getTraefikConfig(
|
||||
tlsServerName: resources.tlsServerName,
|
||||
setHostHeader: resources.setHostHeader,
|
||||
enableProxy: resources.enableProxy,
|
||||
headers: resources.headers,
|
||||
// Target fields
|
||||
targetId: targets.targetId,
|
||||
targetEnabled: targets.enabled,
|
||||
@@ -152,7 +154,7 @@ export async function getTraefikConfig(
|
||||
inArray(sites.type, siteTypes),
|
||||
config.getRawConfig().traefik.allow_raw_resources
|
||||
? isNotNull(resources.http) // ignore the http check if allow_raw_resources is true
|
||||
: eq(resources.http, true),
|
||||
: eq(resources.http, true)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -177,7 +179,8 @@ export async function getTraefikConfig(
|
||||
tlsServerName: row.tlsServerName,
|
||||
setHostHeader: row.setHostHeader,
|
||||
enableProxy: row.enableProxy,
|
||||
targets: []
|
||||
targets: [],
|
||||
headers: row.headers
|
||||
});
|
||||
}
|
||||
|
||||
@@ -296,13 +299,52 @@ export async function getTraefikConfig(
|
||||
const additionalMiddlewares =
|
||||
config.getRawConfig().traefik.additional_middlewares || [];
|
||||
|
||||
let routerMiddlewares = [
|
||||
badgerMiddlewareName,
|
||||
...additionalMiddlewares
|
||||
];
|
||||
|
||||
if (resource.headers && resource.headers.length > 0) {
|
||||
const headersMiddlewareName = `${resource.resourceId}-headers-middleware`;
|
||||
// if there are headers, parse them into an object
|
||||
let headersObj: { [key: string]: string } = {};
|
||||
const headersArr = resource.headers.split(",");
|
||||
for (const header of headersArr) {
|
||||
const [key, value] = header
|
||||
.split(":")
|
||||
.map((s: string) => s.trim());
|
||||
if (key && value) {
|
||||
headersObj[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (resource.setHostHeader) {
|
||||
headersObj["Host"] = resource.setHostHeader;
|
||||
}
|
||||
|
||||
// check if the object is not empty
|
||||
if (Object.keys(headersObj).length > 0) {
|
||||
// Add the headers middleware
|
||||
if (!config_output.http.middlewares) {
|
||||
config_output.http.middlewares = {};
|
||||
}
|
||||
config_output.http.middlewares[headersMiddlewareName] = {
|
||||
headers: {
|
||||
customRequestHeaders: headersObj
|
||||
}
|
||||
};
|
||||
|
||||
routerMiddlewares.push(headersMiddlewareName);
|
||||
}
|
||||
}
|
||||
|
||||
config_output.http.routers![routerName] = {
|
||||
entryPoints: [
|
||||
resource.ssl
|
||||
? config.getRawConfig().traefik.https_entrypoint
|
||||
: config.getRawConfig().traefik.http_entrypoint
|
||||
],
|
||||
middlewares: [badgerMiddlewareName, ...additionalMiddlewares],
|
||||
middlewares: routerMiddlewares,
|
||||
service: serviceName,
|
||||
rule: `Host(\`${fullDomain}\`)`,
|
||||
priority: 100,
|
||||
@@ -413,27 +455,6 @@ export async function getTraefikConfig(
|
||||
serviceName
|
||||
].loadBalancer.serversTransport = transportName;
|
||||
}
|
||||
|
||||
// Add the host header middleware
|
||||
if (resource.setHostHeader) {
|
||||
if (!config_output.http.middlewares) {
|
||||
config_output.http.middlewares = {};
|
||||
}
|
||||
config_output.http.middlewares[hostHeaderMiddlewareName] = {
|
||||
headers: {
|
||||
customRequestHeaders: {
|
||||
Host: resource.setHostHeader
|
||||
}
|
||||
}
|
||||
};
|
||||
if (!config_output.http.routers![routerName].middlewares) {
|
||||
config_output.http.routers![routerName].middlewares = [];
|
||||
}
|
||||
config_output.http.routers![routerName].middlewares = [
|
||||
...config_output.http.routers![routerName].middlewares,
|
||||
hostHeaderMiddlewareName
|
||||
];
|
||||
}
|
||||
} else {
|
||||
// Non-HTTP (TCP/UDP) configuration
|
||||
if (!resource.enableProxy) {
|
||||
|
||||
Reference in New Issue
Block a user