Create gateway resources in blueprints

This commit is contained in:
Owen
2026-09-24 09:49:09 -04:00
parent 3378125f8e
commit 118120c9ce
2 changed files with 41 additions and 19 deletions
+36 -16
View File
@@ -259,6 +259,11 @@ export async function updatePrivateResources(
}
const isInference = resourceData.mode === "inference";
const isGateway = resourceData.mode === "gateway";
// gateway resources always route the whole subnet with everything open
const effectiveDestination = isGateway
? "0.0.0.0/0"
: resourceData.destination;
// Update existing resource
const [updatedResource] = await trx
@@ -268,23 +273,28 @@ export async function updatePrivateResources(
mode: resourceData.mode,
ssl: resourceSsl,
scheme: resourceData.scheme,
destination: resourceData.destination,
destination: effectiveDestination,
destinationPort: resourceData["destination-port"],
enabled: resourceEnabled,
alias: resourceData.alias || null,
disableIcmp:
resourceData["disable-icmp"] ||
(resourceData.mode == "http" || isInference
? true
: false), // default to true for http/inference resources, otherwise false
disableIcmp: isGateway
? false // gateway always allows icmp
: resourceData["disable-icmp"] ||
(resourceData.mode == "http" || isInference
? true
: false), // default to true for http/inference resources, otherwise false
tcpPortRangeString:
resourceData.mode == "http" || isInference
? "443,80"
: resourceData["tcp-ports"],
: isGateway
? "*"
: resourceData["tcp-ports"],
udpPortRangeString:
resourceData.mode == "http" || isInference
? ""
: resourceData["udp-ports"],
: isGateway
? "*"
: resourceData["udp-ports"],
fullDomain: resourceData["full-domain"] || null,
subdomain: domainInfo ? domainInfo.subdomain : null,
domainId: domainInfo ? domainInfo.domainId : null,
@@ -529,6 +539,11 @@ export async function updatePrivateResources(
}
const isInference = resourceData.mode === "inference";
const isGateway = resourceData.mode === "gateway";
// gateway resources always route the whole subnet with everything open
const effectiveDestination = isGateway
? "0.0.0.0/0"
: resourceData.destination;
let domainInfo:
| { subdomain: string | null; domainId: string }
@@ -590,24 +605,29 @@ export async function updatePrivateResources(
mode: resourceData.mode,
ssl: resourceSsl,
scheme: resourceData.scheme,
destination: resourceData.destination,
destination: effectiveDestination,
destinationPort: resourceData["destination-port"],
enabled: resourceEnabled,
alias: resourceData.alias || null,
aliasAddress: aliasAddress,
disableIcmp:
resourceData["disable-icmp"] ||
(resourceData.mode == "http" || isInference
? true
: false), // default to true for http/inference resources, otherwise false
disableIcmp: isGateway
? false // gateway always allows icmp
: resourceData["disable-icmp"] ||
(resourceData.mode == "http" || isInference
? true
: false), // default to true for http/inference resources, otherwise false
tcpPortRangeString:
resourceData.mode == "http" || isInference
? "443,80"
: resourceData["tcp-ports"],
: isGateway
? "*"
: resourceData["tcp-ports"],
udpPortRangeString:
resourceData.mode == "http" || isInference
? ""
: resourceData["udp-ports"],
: isGateway
? "*"
: resourceData["udp-ports"],
fullDomain: resourceData["full-domain"] || null,
subdomain: domainInfo ? domainInfo.subdomain : null,
domainId: domainInfo ? domainInfo.domainId : null,
+5 -3
View File
@@ -612,7 +612,7 @@ export function isTargetsOnlyResource(resource: any): boolean {
export const PrivateResourceSchema = z
.object({
name: z.string().min(1).max(255),
mode: z.enum(["host", "cidr", "http", "ssh", "inference"]),
mode: z.enum(["host", "cidr", "http", "ssh", "inference", "gateway"]),
site: z.string().optional(), // DEPRECATED IN FAVOR OF sites
sites: z.array(z.string()).optional().default([]),
// protocol: z.enum(["tcp", "udp"]).optional(),
@@ -652,13 +652,15 @@ export const PrivateResourceSchema = z
})
.refine(
(data) => {
// destination is optional only for ssh+native or inference; required for everything else
// destination is optional only for ssh+native, inference, or gateway
// (gateway always routes the whole subnet, so destination is ignored); required for everything else
const isNativeSSH =
data.mode === "ssh" &&
(data["auth-daemon"] === undefined ||
data["auth-daemon"].mode === "native");
if (
data.mode !== "inference" &&
data.mode !== "gateway" &&
!isNativeSSH &&
!data.destination
) {
@@ -669,7 +671,7 @@ export const PrivateResourceSchema = z
{
path: ["destination"],
message:
"destination is required unless mode is 'ssh' with auth-daemon mode 'native', or mode is 'inference'"
"destination is required unless mode is 'ssh' with auth-daemon mode 'native', 'inference', or 'gateway'"
}
)
.refine(