mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-26 23:06:37 +00:00
feat(healthcheck): add SNI input field to target healthcheck config
This commit is contained in:
@@ -516,6 +516,8 @@
|
|||||||
"targetCreatedDescription": "Target has been created successfully",
|
"targetCreatedDescription": "Target has been created successfully",
|
||||||
"targetErrorCreate": "Failed to create target",
|
"targetErrorCreate": "Failed to create target",
|
||||||
"targetErrorCreateDescription": "An error occurred while creating the target",
|
"targetErrorCreateDescription": "An error occurred while creating the target",
|
||||||
|
"tlsServerName": "TLS Server Name",
|
||||||
|
"tlsServerNameDescription": "The TLS server name to use for SNI",
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
"proxyAdditional": "Additional Proxy Settings",
|
"proxyAdditional": "Additional Proxy Settings",
|
||||||
"proxyAdditionalDescription": "Configure how your resource handles proxy settings",
|
"proxyAdditionalDescription": "Configure how your resource handles proxy settings",
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ export async function addTargets(
|
|||||||
hcUnhealthyInterval: hc.hcUnhealthyInterval, // in seconds
|
hcUnhealthyInterval: hc.hcUnhealthyInterval, // in seconds
|
||||||
hcTimeout: hc.hcTimeout, // in seconds
|
hcTimeout: hc.hcTimeout, // in seconds
|
||||||
hcHeaders: hcHeadersSend,
|
hcHeaders: hcHeadersSend,
|
||||||
hcMethod: hc.hcMethod
|
hcMethod: hc.hcMethod,
|
||||||
|
hcTlsServerName: hc.hcTlsServerName,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ const createTargetSchema = z.strictObject({
|
|||||||
hcFollowRedirects: z.boolean().optional().nullable(),
|
hcFollowRedirects: z.boolean().optional().nullable(),
|
||||||
hcMethod: z.string().min(1).optional().nullable(),
|
hcMethod: z.string().min(1).optional().nullable(),
|
||||||
hcStatus: z.int().optional().nullable(),
|
hcStatus: z.int().optional().nullable(),
|
||||||
|
hcTlsServerName: z.string().optional().nullable(),
|
||||||
path: z.string().optional().nullable(),
|
path: z.string().optional().nullable(),
|
||||||
pathMatchType: z
|
pathMatchType: z
|
||||||
.enum(["exact", "prefix", "regex"])
|
.enum(["exact", "prefix", "regex"])
|
||||||
@@ -247,7 +248,8 @@ export async function createTarget(
|
|||||||
hcFollowRedirects: targetData.hcFollowRedirects ?? null,
|
hcFollowRedirects: targetData.hcFollowRedirects ?? null,
|
||||||
hcMethod: targetData.hcMethod ?? null,
|
hcMethod: targetData.hcMethod ?? null,
|
||||||
hcStatus: targetData.hcStatus ?? null,
|
hcStatus: targetData.hcStatus ?? null,
|
||||||
hcHealth: "unknown"
|
hcHealth: "unknown",
|
||||||
|
hcTlsServerName: targetData.hcTlsServerName ?? null
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ function queryTargets(resourceId: number) {
|
|||||||
hcMethod: targetHealthCheck.hcMethod,
|
hcMethod: targetHealthCheck.hcMethod,
|
||||||
hcStatus: targetHealthCheck.hcStatus,
|
hcStatus: targetHealthCheck.hcStatus,
|
||||||
hcHealth: targetHealthCheck.hcHealth,
|
hcHealth: targetHealthCheck.hcHealth,
|
||||||
|
hcTlsServerName: targetHealthCheck.hcTlsServerName,
|
||||||
path: targets.path,
|
path: targets.path,
|
||||||
pathMatchType: targets.pathMatchType,
|
pathMatchType: targets.pathMatchType,
|
||||||
rewritePath: targets.rewritePath,
|
rewritePath: targets.rewritePath,
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ const updateTargetBodySchema = z.strictObject({
|
|||||||
hcFollowRedirects: z.boolean().optional().nullable(),
|
hcFollowRedirects: z.boolean().optional().nullable(),
|
||||||
hcMethod: z.string().min(1).optional().nullable(),
|
hcMethod: z.string().min(1).optional().nullable(),
|
||||||
hcStatus: z.int().optional().nullable(),
|
hcStatus: z.int().optional().nullable(),
|
||||||
|
hcTlsServerName: z.string().optional().nullable(),
|
||||||
path: z.string().optional().nullable(),
|
path: z.string().optional().nullable(),
|
||||||
pathMatchType: z.enum(["exact", "prefix", "regex"]).optional().nullable(),
|
pathMatchType: z.enum(["exact", "prefix", "regex"]).optional().nullable(),
|
||||||
rewritePath: z.string().optional().nullable(),
|
rewritePath: z.string().optional().nullable(),
|
||||||
@@ -217,7 +218,8 @@ export async function updateTarget(
|
|||||||
hcHeaders: hcHeaders,
|
hcHeaders: hcHeaders,
|
||||||
hcFollowRedirects: parsedBody.data.hcFollowRedirects,
|
hcFollowRedirects: parsedBody.data.hcFollowRedirects,
|
||||||
hcMethod: parsedBody.data.hcMethod,
|
hcMethod: parsedBody.data.hcMethod,
|
||||||
hcStatus: parsedBody.data.hcStatus
|
hcStatus: parsedBody.data.hcStatus,
|
||||||
|
hcTlsServerName: parsedBody.data.hcTlsServerName,
|
||||||
})
|
})
|
||||||
.where(eq(targetHealthCheck.targetId, targetId))
|
.where(eq(targetHealthCheck.targetId, targetId))
|
||||||
.returning();
|
.returning();
|
||||||
|
|||||||
@@ -464,6 +464,7 @@ export default function ReverseProxyTargets(props: {
|
|||||||
hcStatus: null,
|
hcStatus: null,
|
||||||
hcMode: null,
|
hcMode: null,
|
||||||
hcUnhealthyInterval: null,
|
hcUnhealthyInterval: null,
|
||||||
|
hcTlsServerName: null,
|
||||||
siteType: sites.length > 0 ? sites[0].type : null,
|
siteType: sites.length > 0 ? sites[0].type : null,
|
||||||
new: true,
|
new: true,
|
||||||
updated: false
|
updated: false
|
||||||
@@ -629,7 +630,8 @@ export default function ReverseProxyTargets(props: {
|
|||||||
hcHealth: "unknown",
|
hcHealth: "unknown",
|
||||||
hcStatus: null,
|
hcStatus: null,
|
||||||
hcMode: null,
|
hcMode: null,
|
||||||
hcUnhealthyInterval: null
|
hcUnhealthyInterval: null,
|
||||||
|
hcTlsServerName: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
setTargets([...targets, newTarget]);
|
setTargets([...targets, newTarget]);
|
||||||
@@ -729,7 +731,8 @@ export default function ReverseProxyTargets(props: {
|
|||||||
hcMethod: target.hcMethod || null,
|
hcMethod: target.hcMethod || null,
|
||||||
hcStatus: target.hcStatus || null,
|
hcStatus: target.hcStatus || null,
|
||||||
hcUnhealthyInterval: target.hcUnhealthyInterval || null,
|
hcUnhealthyInterval: target.hcUnhealthyInterval || null,
|
||||||
hcMode: target.hcMode || null
|
hcMode: target.hcMode || null,
|
||||||
|
hcTlsServerName: target.hcTlsServerName,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Only include path-related fields for HTTP resources
|
// Only include path-related fields for HTTP resources
|
||||||
|
|||||||
@@ -297,6 +297,7 @@ export default function Page() {
|
|||||||
hcStatus: null,
|
hcStatus: null,
|
||||||
hcMode: null,
|
hcMode: null,
|
||||||
hcUnhealthyInterval: null,
|
hcUnhealthyInterval: null,
|
||||||
|
hcTlsServerName: null,
|
||||||
siteType: sites.length > 0 ? sites[0].type : null,
|
siteType: sites.length > 0 ? sites[0].type : null,
|
||||||
new: true,
|
new: true,
|
||||||
updated: false
|
updated: false
|
||||||
@@ -454,7 +455,8 @@ export default function Page() {
|
|||||||
hcHealth: "unknown",
|
hcHealth: "unknown",
|
||||||
hcStatus: null,
|
hcStatus: null,
|
||||||
hcMode: null,
|
hcMode: null,
|
||||||
hcUnhealthyInterval: null
|
hcUnhealthyInterval: null,
|
||||||
|
hcTlsServerName: null
|
||||||
};
|
};
|
||||||
|
|
||||||
setTargets([...targets, newTarget]);
|
setTargets([...targets, newTarget]);
|
||||||
@@ -576,7 +578,8 @@ export default function Page() {
|
|||||||
target.hcFollowRedirects || null,
|
target.hcFollowRedirects || null,
|
||||||
hcStatus: target.hcStatus || null,
|
hcStatus: target.hcStatus || null,
|
||||||
hcUnhealthyInterval: target.hcUnhealthyInterval || null,
|
hcUnhealthyInterval: target.hcUnhealthyInterval || null,
|
||||||
hcMode: target.hcMode || null
|
hcMode: target.hcMode || null,
|
||||||
|
hcTlsServerName: target.hcTlsServerName
|
||||||
};
|
};
|
||||||
|
|
||||||
// Only include path-related fields for HTTP resources
|
// Only include path-related fields for HTTP resources
|
||||||
@@ -1800,7 +1803,10 @@ export default function Page() {
|
|||||||
"http",
|
"http",
|
||||||
hcUnhealthyInterval:
|
hcUnhealthyInterval:
|
||||||
selectedTargetForHealthCheck.hcUnhealthyInterval ||
|
selectedTargetForHealthCheck.hcUnhealthyInterval ||
|
||||||
30
|
30,
|
||||||
|
hcTlsServerName:
|
||||||
|
selectedTargetForHealthCheck.hcTlsServerName ||
|
||||||
|
undefined
|
||||||
}}
|
}}
|
||||||
onChanges={async (config) => {
|
onChanges={async (config) => {
|
||||||
if (selectedTargetForHealthCheck) {
|
if (selectedTargetForHealthCheck) {
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ type HealthCheckConfig = {
|
|||||||
hcFollowRedirects: boolean;
|
hcFollowRedirects: boolean;
|
||||||
hcMode: string;
|
hcMode: string;
|
||||||
hcUnhealthyInterval: number;
|
hcUnhealthyInterval: number;
|
||||||
|
hcTlsServerName: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type HealthCheckDialogProps = {
|
type HealthCheckDialogProps = {
|
||||||
@@ -93,7 +94,8 @@ export default function HealthCheckDialog({
|
|||||||
hcPort: z.number().positive().gt(0).lte(65535),
|
hcPort: z.number().positive().gt(0).lte(65535),
|
||||||
hcFollowRedirects: z.boolean(),
|
hcFollowRedirects: z.boolean(),
|
||||||
hcMode: z.string(),
|
hcMode: z.string(),
|
||||||
hcUnhealthyInterval: z.int().positive().min(5)
|
hcUnhealthyInterval: z.int().positive().min(5),
|
||||||
|
hcTlsServerName: z.string()
|
||||||
});
|
});
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof healthCheckSchema>>({
|
const form = useForm<z.infer<typeof healthCheckSchema>>({
|
||||||
@@ -129,7 +131,8 @@ export default function HealthCheckDialog({
|
|||||||
hcPort: initialConfig?.hcPort,
|
hcPort: initialConfig?.hcPort,
|
||||||
hcFollowRedirects: initialConfig?.hcFollowRedirects,
|
hcFollowRedirects: initialConfig?.hcFollowRedirects,
|
||||||
hcMode: initialConfig?.hcMode,
|
hcMode: initialConfig?.hcMode,
|
||||||
hcUnhealthyInterval: initialConfig?.hcUnhealthyInterval
|
hcUnhealthyInterval: initialConfig?.hcUnhealthyInterval,
|
||||||
|
hcTlsServerName: initialConfig?.hcTlsServerName ?? ""
|
||||||
});
|
});
|
||||||
}, [open]);
|
}, [open]);
|
||||||
|
|
||||||
@@ -531,6 +534,37 @@ export default function HealthCheckDialog({
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/*TLS Server Name (SNI)*/}
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="hcTlsServerName"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>
|
||||||
|
{t("tlsServerName")}
|
||||||
|
</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
{...field}
|
||||||
|
onChange={(e) => {
|
||||||
|
field.onChange(e);
|
||||||
|
handleFieldChange(
|
||||||
|
"hcTlsServerName",
|
||||||
|
e.target.value
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormDescription>
|
||||||
|
{t(
|
||||||
|
"tlsServerNameDescription"
|
||||||
|
)}
|
||||||
|
</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* Custom Headers */}
|
{/* Custom Headers */}
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
|||||||
Reference in New Issue
Block a user