mirror of
https://github.com/fosrl/pangolin.git
synced 2026-08-15 08:49:59 +02:00
Allow overlapping domains on public inference resources
This commit is contained in:
@@ -306,6 +306,7 @@ export async function updatePublicResources(
|
|||||||
existingResource.resourceId,
|
existingResource.resourceId,
|
||||||
resourceData["full-domain"]!,
|
resourceData["full-domain"]!,
|
||||||
orgId,
|
orgId,
|
||||||
|
resourceData.mode === "inference",
|
||||||
trx
|
trx
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1098,6 +1099,7 @@ export async function updatePublicResources(
|
|||||||
undefined,
|
undefined,
|
||||||
resourceData["full-domain"]!,
|
resourceData["full-domain"]!,
|
||||||
orgId,
|
orgId,
|
||||||
|
resourceData.mode === "inference",
|
||||||
trx
|
trx
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -2113,6 +2115,7 @@ export async function getDomain(
|
|||||||
resourceId: number | undefined,
|
resourceId: number | undefined,
|
||||||
fullDomain: string,
|
fullDomain: string,
|
||||||
orgId: string,
|
orgId: string,
|
||||||
|
isInference: boolean,
|
||||||
trx: Transaction
|
trx: Transaction
|
||||||
) {
|
) {
|
||||||
const [fullDomainExists] = await trx
|
const [fullDomainExists] = await trx
|
||||||
@@ -2122,6 +2125,14 @@ export async function getDomain(
|
|||||||
and(
|
and(
|
||||||
eq(resources.fullDomain, fullDomain),
|
eq(resources.fullDomain, fullDomain),
|
||||||
eq(resources.orgId, orgId),
|
eq(resources.orgId, orgId),
|
||||||
|
// Inference resources route through the central AI gateway
|
||||||
|
// rather than normal target-based proxying, so they're
|
||||||
|
// allowed to share a full-domain with a non-inference
|
||||||
|
// resource (and vice versa) - only conflicts within the
|
||||||
|
// same routing category are rejected.
|
||||||
|
isInference
|
||||||
|
? eq(resources.mode, "inference")
|
||||||
|
: ne(resources.mode, "inference"),
|
||||||
resourceId
|
resourceId
|
||||||
? ne(resources.resourceId, resourceId)
|
? ne(resources.resourceId, resourceId)
|
||||||
: isNotNull(resources.resourceId)
|
: isNotNull(resources.resourceId)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import {
|
|||||||
import response from "@server/lib/response";
|
import response from "@server/lib/response";
|
||||||
import HttpCode from "@server/types/HttpCode";
|
import HttpCode from "@server/types/HttpCode";
|
||||||
import createHttpError from "http-errors";
|
import createHttpError from "http-errors";
|
||||||
import { eq, and } from "drizzle-orm";
|
import { eq, and, ne } from "drizzle-orm";
|
||||||
import { fromError } from "zod-validation-error";
|
import { fromError } from "zod-validation-error";
|
||||||
import logger from "@server/logger";
|
import logger from "@server/logger";
|
||||||
import { subdomainSchema, wildcardSubdomainSchema } from "@server/lib/schemas";
|
import { subdomainSchema, wildcardSubdomainSchema } from "@server/lib/schemas";
|
||||||
@@ -484,11 +484,22 @@ async function createHttpResource(
|
|||||||
|
|
||||||
logger.debug(`Full domain: ${fullDomain}`);
|
logger.debug(`Full domain: ${fullDomain}`);
|
||||||
|
|
||||||
// make sure the full domain is unique
|
// make sure the full domain is unique. Inference resources are routed
|
||||||
|
// through the central AI gateway rather than normal target-based
|
||||||
|
// proxying, so they're allowed to share a full-domain with a
|
||||||
|
// non-inference resource (and vice versa) - only conflicts within the
|
||||||
|
// same routing category are rejected.
|
||||||
const existingResource = await db
|
const existingResource = await db
|
||||||
.select()
|
.select()
|
||||||
.from(resources)
|
.from(resources)
|
||||||
.where(eq(resources.fullDomain, fullDomain));
|
.where(
|
||||||
|
and(
|
||||||
|
eq(resources.fullDomain, fullDomain),
|
||||||
|
effectiveMode === "inference"
|
||||||
|
? eq(resources.mode, "inference")
|
||||||
|
: ne(resources.mode, "inference")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (existingResource.length > 0) {
|
if (existingResource.length > 0) {
|
||||||
return next(
|
return next(
|
||||||
|
|||||||
@@ -596,10 +596,23 @@ async function updateHttpResource(
|
|||||||
logger.debug(`Full domain: ${fullDomain}`);
|
logger.debug(`Full domain: ${fullDomain}`);
|
||||||
|
|
||||||
if (fullDomain) {
|
if (fullDomain) {
|
||||||
|
// Inference resources route through the central AI gateway
|
||||||
|
// rather than normal target-based proxying, so they're allowed
|
||||||
|
// to share a full-domain with a non-inference resource (and
|
||||||
|
// vice versa) - only conflicts within the same routing category
|
||||||
|
// are rejected. mode isn't updatable here, so `resource.mode`
|
||||||
|
// reflects the resource's actual (unchanging) routing category.
|
||||||
const [existingDomain] = await db
|
const [existingDomain] = await db
|
||||||
.select()
|
.select()
|
||||||
.from(resources)
|
.from(resources)
|
||||||
.where(eq(resources.fullDomain, fullDomain));
|
.where(
|
||||||
|
and(
|
||||||
|
eq(resources.fullDomain, fullDomain),
|
||||||
|
resource.mode === "inference"
|
||||||
|
? eq(resources.mode, "inference")
|
||||||
|
: ne(resources.mode, "inference")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
existingDomain &&
|
existingDomain &&
|
||||||
|
|||||||
@@ -55,12 +55,12 @@ const listAllSiteResourcesByOrgQuerySchema = z.strictObject({
|
|||||||
}),
|
}),
|
||||||
query: z.string().optional(),
|
query: z.string().optional(),
|
||||||
mode: z
|
mode: z
|
||||||
.enum(["host", "cidr", "http"])
|
.enum(["host", "cidr", "http", "ssh", "inference"])
|
||||||
.optional()
|
.optional()
|
||||||
.catch(undefined)
|
.catch(undefined)
|
||||||
.openapi({
|
.openapi({
|
||||||
type: "string",
|
type: "string",
|
||||||
enum: ["host", "cidr", "http"],
|
enum: ["host", "cidr", "http", "ssh", "inference"],
|
||||||
description: "Filter site resources by mode"
|
description: "Filter site resources by mode"
|
||||||
}),
|
}),
|
||||||
sort_by: z
|
sort_by: z
|
||||||
|
|||||||
Reference in New Issue
Block a user