dont show policy on tcp/udp resources

This commit is contained in:
miloschwartz
2026-06-09 15:56:24 -07:00
parent fb6f5b3953
commit 1aa6e3511f
4 changed files with 170 additions and 132 deletions

View File

@@ -280,7 +280,7 @@
"back": "Back",
"cancel": "Cancel",
"resourceConfig": "Configuration Snippets",
"resourceConfigDescription": "Copy and paste these configuration snippets to set up the TCP/UDP resource",
"resourceConfigDescription": "Copy and paste these configuration snippets to set up the TCP/UDP resource.",
"resourceAddEntrypoints": "Traefik: Add Entrypoints",
"resourceExposePorts": "Gerbil: Expose Ports in Docker Compose",
"resourceLearnRaw": "Learn how to configure TCP/UDP resources",
@@ -1844,9 +1844,9 @@
"accountSetupSuccess": "Account setup completed! Welcome to Pangolin!",
"documentation": "Documentation",
"saveAllSettings": "Save All Settings",
"saveResourceTargets": "Save Targets",
"saveResourceTargets": "Save Settings",
"saveResourceHttp": "Save Settings",
"saveProxyProtocol": "Save Proxy protocol settings",
"saveProxyProtocol": "Save Settings",
"settingsUpdated": "Settings updated",
"settingsUpdatedDescription": "Settings updated successfully",
"settingsErrorUpdate": "Failed to update settings",
@@ -2972,9 +2972,10 @@
"enableProxyProtocol": "Enable Proxy Protocol",
"proxyProtocolInfo": "Preserve client IP addresses for TCP backends",
"proxyProtocolVersion": "Proxy Protocol Version",
"version1": " Version 1 (Recommended)",
"version1": "Version 1 (Recommended)",
"version2": "Version 2",
"versionDescription": "Version 1 is text-based and widely supported. Version 2 is binary and more efficient but less compatible. Make sure servers transport is added to dynamic config.",
"version1Description": "Text-based and widely supported. Make sure servers transport is added to dynamic config.",
"version2Description": "Binary and more efficient but less compatible. Make sure servers transport is added to dynamic config.",
"warning": "Warning",
"proxyProtocolWarning": "The backend application must be configured to accept Proxy Protocol connections. If your backend doesn't support Proxy Protocol, enabling this will break all connections so only enable this if you know what you're doing. Make sure to configure your backend to trust Proxy Protocol headers from Traefik.",
"restarting": "Restarting...",

View File

@@ -153,7 +153,10 @@ export default function GeneralForm() {
let resourcePolicyId: number | null | undefined;
if (showResourcePolicy) {
if (
showResourcePolicy &&
!["tcp", "udp"].includes(resource.mode)
) {
resourcePolicyId = selectedSharedPolicyId;
}
@@ -473,7 +476,10 @@ export default function GeneralForm() {
</div>
</SettingsFormCell>
)}
{showResourcePolicy && (
{showResourcePolicy &&
!["tcp", "udp"].includes(
resource.mode
) && (
<>
<SettingsFormCell span="full">
<SettingsSubsectionHeader>

View File

@@ -1,28 +1,27 @@
"use client";
import { Button } from "@/components/ui/button";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue
} from "@/components/ui/select";
import {
SettingsContainer,
SettingsFormCell,
SettingsFormGrid,
SettingsSection,
SettingsSectionBody,
SettingsSectionDescription,
SettingsSectionFooter,
SettingsSectionForm,
SettingsSectionHeader,
SettingsSectionTitle
} from "@app/components/Settings";
import { SwitchInput } from "@app/components/SwitchInput";
import {
StrategyOption,
StrategySelect
} from "@app/components/StrategySelect";
import { Alert, AlertDescription } from "@app/components/ui/alert";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
@@ -49,6 +48,7 @@ import { useRouter } from "next/navigation";
import {
use,
useActionState,
useMemo
} from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";
@@ -131,6 +131,22 @@ function ProxyResourceProtocolForm({
const router = useRouter();
const proxyProtocolVersionOptions = useMemo(
(): StrategyOption<"1" | "2">[] => [
{
id: "1",
title: t("version1"),
description: t("version1Description")
},
{
id: "2",
title: t("version2"),
description: t("version2Description")
}
],
[t]
);
const [, formAction, isSubmitting] = useActionState(
saveProtocolSettings,
null
@@ -187,105 +203,118 @@ function ProxyResourceProtocolForm({
</SettingsSectionDescription>
</SettingsSectionHeader>
<SettingsSectionBody>
<SettingsSectionForm>
<SettingsSectionForm variant="half">
<Form {...proxySettingsForm}>
<form
action={formAction}
className="space-y-4"
id="proxy-protocol-settings-form"
>
<FormField
control={proxySettingsForm.control}
name="proxyProtocol"
render={({ field }) => (
<FormItem>
<FormControl>
<SwitchInput
id="proxy-protocol-toggle"
label={t("enableProxyProtocol")}
description={t(
"proxyProtocolInfo"
)}
defaultChecked={
field.value || false
}
onCheckedChange={(val) => {
field.onChange(val);
}}
/>
</FormControl>
</FormItem>
)}
/>
{proxySettingsForm.watch("proxyProtocol") && (
<>
<SettingsFormGrid>
<SettingsFormCell span="full">
<FormField
control={proxySettingsForm.control}
name="proxyProtocolVersion"
name="proxyProtocol"
render={({ field }) => (
<FormItem>
<FormLabel>
{t("proxyProtocolVersion")}
</FormLabel>
<FormControl>
<Select
value={String(
field.value || 1
<SwitchInput
id="proxy-protocol-toggle"
label={t(
"enableProxyProtocol"
)}
onValueChange={(
value
) =>
field.onChange(
parseInt(
value,
10
)
)
description={t(
"proxyProtocolInfo"
)}
defaultChecked={
field.value || false
}
>
<SelectTrigger>
<SelectValue placeholder="Select version" />
</SelectTrigger>
<SelectContent>
<SelectItem value="1">
{t("version1")}
</SelectItem>
<SelectItem value="2">
{t("version2")}
</SelectItem>
</SelectContent>
</Select>
onCheckedChange={(
val
) => {
field.onChange(val);
}}
/>
</FormControl>
<FormDescription>
{t("versionDescription")}
</FormDescription>
</FormItem>
)}
/>
</SettingsFormCell>
<Alert>
<AlertTriangle className="h-4 w-4" />
<AlertDescription>
<strong>{t("warning")}:</strong>{" "}
{t("proxyProtocolWarning")}
</AlertDescription>
</Alert>
</>
)}
{proxySettingsForm.watch("proxyProtocol") && (
<>
<SettingsFormCell span="full">
<Alert className="[&>svg]:self-start">
<AlertTriangle className="h-4 w-4" />
<AlertDescription>
<strong>
{t("warning")}:
</strong>{" "}
{t("proxyProtocolWarning")}
</AlertDescription>
</Alert>
</SettingsFormCell>
<SettingsFormCell span="full">
<FormField
control={
proxySettingsForm.control
}
name="proxyProtocolVersion"
render={({ field }) => (
<FormItem>
<FormLabel>
{t(
"proxyProtocolVersion"
)}
</FormLabel>
<FormControl>
<StrategySelect<
"1" | "2"
>
value={
field.value ===
2
? "2"
: "1"
}
options={
proxyProtocolVersionOptions
}
onChange={(
value
) =>
field.onChange(
parseInt(
value,
10
)
)
}
cols={2}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</SettingsFormCell>
</>
)}
</SettingsFormGrid>
</form>
</Form>
</SettingsSectionForm>
<form action={formAction} className="flex justify-end">
<Button
disabled={isSubmitting}
loading={isSubmitting}
type="submit"
>
{t("saveProxyProtocol")}
</Button>
</form>
</SettingsSectionBody>
<SettingsSectionFooter>
<Button
disabled={isSubmitting}
loading={isSubmitting}
type="submit"
form="proxy-protocol-settings-form"
>
{t("saveProxyProtocol")}
</Button>
</SettingsSectionFooter>
</SettingsSection>
);
}

View File

@@ -73,13 +73,8 @@ import {
ProxyResourceTargetsForm
} from "@app/app/[orgId]/settings/resources/public/ProxyResourceTargetsForm";
import { AxiosResponse } from "axios";
import {
ChevronsUpDown,
ExternalLink,
SquareArrowOutUpRight
} from "lucide-react";
import { ChevronsUpDown, ExternalLink } from "lucide-react";
import { useTranslations } from "next-intl";
import Link from "next/link";
import { useParams, useRouter } from "next/navigation";
import { toASCII } from "punycode";
import {
@@ -1446,54 +1441,61 @@ export default function Page() {
{t("resourceConfig")}
</SettingsSectionTitle>
<SettingsSectionDescription>
{t("resourceConfigDescription")}
{t("resourceConfigDescription")}{" "}
<a
href="https://docs.pangolin.net/manage/resources/public/raw-resources"
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline inline-flex items-center gap-1"
>
{t("learnMore")}
<ExternalLink className="size-3.5 shrink-0" />
</a>
</SettingsSectionDescription>
</SettingsSectionHeader>
<SettingsSectionBody>
<div className="space-y-6">
<div className="space-y-4">
<h3 className="text-lg font-semibold">
{t("resourceAddEntrypoints")}
</h3>
<p className="text-sm text-muted-foreground">
{t(
"resourceAddEntrypointsEditFile"
)}
</p>
<SettingsFormGrid>
<SettingsFormCell span="full">
<SettingsSubsectionHeader>
<SettingsSubsectionTitle>
{t("resourceAddEntrypoints")}
</SettingsSubsectionTitle>
<SettingsSubsectionDescription>
{t(
"resourceAddEntrypointsEditFile"
)}
</SettingsSubsectionDescription>
</SettingsSubsectionHeader>
</SettingsFormCell>
<SettingsFormCell span="full">
<CopyTextBox
text={`entryPoints:
${tcpUdpForm.getValues("protocol")}-${tcpUdpForm.getValues("proxyPort")}:
address: ":${tcpUdpForm.getValues("proxyPort")}/${tcpUdpForm.getValues("protocol")}"`}
wrapText={false}
/>
</div>
</SettingsFormCell>
<div className="space-y-4">
<h3 className="text-lg font-semibold">
{t("resourceExposePorts")}
</h3>
<p className="text-sm text-muted-foreground">
{t(
"resourceExposePortsEditFile"
)}
</p>
<SettingsFormCell span="full">
<SettingsSubsectionHeader>
<SettingsSubsectionTitle>
{t("resourceExposePorts")}
</SettingsSubsectionTitle>
<SettingsSubsectionDescription>
{t(
"resourceExposePortsEditFile"
)}
</SettingsSubsectionDescription>
</SettingsSubsectionHeader>
</SettingsFormCell>
<SettingsFormCell span="full">
<CopyTextBox
text={`ports:
- ${tcpUdpForm.getValues("proxyPort")}:${tcpUdpForm.getValues("proxyPort")}${tcpUdpForm.getValues("protocol") === "tcp" ? "" : "/" + tcpUdpForm.getValues("protocol")}`}
wrapText={false}
/>
</div>
<Link
className="text-sm text-primary flex items-center gap-1"
href="https://docs.pangolin.net/manage/resources/public/raw-resources"
target="_blank"
rel="noopener noreferrer"
>
<span>{t("resourceLearnRaw")}</span>
<SquareArrowOutUpRight size={14} />
</Link>
</div>
</SettingsFormCell>
</SettingsFormGrid>
</SettingsSectionBody>
</SettingsSection>