From d0fb44a1b2d896b27f4f8f49c50853ae280d5e1b Mon Sep 17 00:00:00 2001 From: Nic Date: Thu, 19 Mar 2026 16:52:01 +0800 Subject: [PATCH 1/2] feat: support batch TCP/UDP port ranges in stream config Add support for port range notation and comma-separated port lists in gateway.stream.tcp and gateway.stream.udp configuration. ConfigMap passes range strings through to config.yaml where the gateway's native parsing handles them. For K8s container ports and service ports, new helper templates (gateway.expandPorts, gateway.normalizedTcpPorts, gateway.normalizedUdpPorts) expand port ranges into individual port entries since Kubernetes requires concrete port numbers. Supported formats in values.yaml: - Port range: '2000-2100' - Address with range: '127.0.0.1:2000-2100' - Comma-separated: '1881,1888,3000' - Mixed: '1881,1888,2000-2100,3000' - Object form with range: {addr: '5000-5010', tls: true} Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- charts/gateway/templates/_helpers.tpl | 93 +++++++++++++++++++ charts/gateway/templates/_pod.tpl | 24 ++--- charts/gateway/templates/configmap.yaml | 8 +- charts/gateway/templates/service-gateway.yaml | 56 ++++------- charts/gateway/values.yaml | 7 ++ 5 files changed, 130 insertions(+), 58 deletions(-) diff --git a/charts/gateway/templates/_helpers.tpl b/charts/gateway/templates/_helpers.tpl index af4dfbd..8b85559 100644 --- a/charts/gateway/templates/_helpers.tpl +++ b/charts/gateway/templates/_helpers.tpl @@ -104,3 +104,96 @@ Scheme to use while connecting etcd {{- "http" }} {{- end }} {{- end }} + +{{/* +Expand a port value (which may contain comma-separated ports and/or ranges) +into a list of individual port numbers for K8s resource definitions. +Input: a string like "1881,1888,2000-2100,3000" or "127.0.0.1:2000-2100" or "9100" +Output: JSON {"ports": [1881, 1888, 2000, 2001, ..., 2100, 3000]} +*/}} +{{- define "gateway.expandPorts" -}} +{{- $result := list -}} +{{- $s := . | toString -}} +{{- $parts := splitList "," $s -}} +{{- range $part := $parts -}} + {{- $trimmed := trim $part -}} + {{- if ne $trimmed "" -}} + {{- $portPart := splitList ":" $trimmed | last -}} + {{- if contains "-" $portPart -}} + {{- $bounds := splitList "-" $portPart -}} + {{- $start := index $bounds 0 | trim | int -}} + {{- $end := index $bounds 1 | trim | int -}} + {{- $count := add1 (sub $end $start) | int -}} + {{- range $i := until $count -}} + {{- $result = append $result (add $start $i | int) -}} + {{- end -}} + {{- else -}} + {{- $result = append $result ($portPart | trim | int) -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{- dict "ports" $result | toJson -}} +{{- end -}} + +{{/* +Normalize a TCP port list into expanded individual port entries for K8s resources. +Handles integers, strings (with ranges/commas), and map entries (with addr ranges/commas). +Input: the .tcp array from values +Output: JSON {"entries": [{"port": 9100, "nodePort": ""}, ...]} +*/}} +{{- define "gateway.normalizedTcpPorts" -}} +{{- $result := list -}} +{{- range $item := . -}} + {{- $addrStr := "" -}} + {{- $nodePort := "" -}} + {{- if kindIs "map" $item -}} + {{- $addrStr = $item.addr | toString -}} + {{- if hasKey $item "nodePort" -}} + {{- $nodePort = $item.nodePort | toString -}} + {{- end -}} + {{- else -}} + {{- $addrStr = $item | toString -}} + {{- end -}} + {{- $portPart := splitList ":" $addrStr | last -}} + {{- if or (contains "," $addrStr) (contains "-" $portPart) -}} + {{- $expanded := include "gateway.expandPorts" $addrStr | fromJson -}} + {{- range $port := $expanded.ports -}} + {{- $result = append $result (dict "port" $port "nodePort" "") -}} + {{- end -}} + {{- else -}} + {{- $result = append $result (dict "port" ($portPart | int) "nodePort" $nodePort) -}} + {{- end -}} +{{- end -}} +{{- dict "entries" $result | toJson -}} +{{- end -}} + +{{/* +Normalize a UDP port list into expanded individual port entries for K8s resources. +Input: the .udp array from values +Output: JSON {"entries": [{"port": 9200, "nodePort": ""}, ...]} +*/}} +{{- define "gateway.normalizedUdpPorts" -}} +{{- $result := list -}} +{{- range $item := . -}} + {{- $addrStr := "" -}} + {{- $nodePort := "" -}} + {{- if kindIs "map" $item -}} + {{- $addrStr = $item.addr | toString -}} + {{- if hasKey $item "nodePort" -}} + {{- $nodePort = $item.nodePort | toString -}} + {{- end -}} + {{- else -}} + {{- $addrStr = $item | toString -}} + {{- end -}} + {{- $portPart := splitList ":" $addrStr | last -}} + {{- if or (contains "," $addrStr) (contains "-" $portPart) -}} + {{- $expanded := include "gateway.expandPorts" $addrStr | fromJson -}} + {{- range $port := $expanded.ports -}} + {{- $result = append $result (dict "port" $port "nodePort" "") -}} + {{- end -}} + {{- else -}} + {{- $result = append $result (dict "port" ($portPart | int) "nodePort" $nodePort) -}} + {{- end -}} +{{- end -}} +{{- dict "entries" $result | toJson -}} +{{- end -}} diff --git a/charts/gateway/templates/_pod.tpl b/charts/gateway/templates/_pod.tpl index d887516..b7a174e 100644 --- a/charts/gateway/templates/_pod.tpl +++ b/charts/gateway/templates/_pod.tpl @@ -130,31 +130,23 @@ spec: protocol: TCP {{- end }} {{- if and .Values.gateway.stream.enabled (or (gt (len .Values.gateway.stream.tcp) 0) (gt (len .Values.gateway.stream.udp) 0)) }} - {{- with .Values.gateway.stream }} - {{- if (gt (len .tcp) 0) }} - {{- range $index, $port := .tcp }} + {{- if (gt (len .Values.gateway.stream.tcp) 0) }} + {{- $normalized := include "gateway.normalizedTcpPorts" .Values.gateway.stream.tcp | fromJson }} + {{- range $index, $entry := $normalized.entries }} - name: proxy-tcp-{{ $index | toString }} - {{- if kindIs "map" $port }} - containerPort: {{ splitList ":" ($port.addr | toString) | last }} - {{- else }} - containerPort: {{ $port }} - {{- end }} + containerPort: {{ $entry.port | int }} protocol: TCP {{- end }} {{- end }} - {{- if (gt (len .udp) 0) }} - {{- range $index, $port := .udp }} + {{- if (gt (len .Values.gateway.stream.udp) 0) }} + {{- $normalized := include "gateway.normalizedUdpPorts" .Values.gateway.stream.udp | fromJson }} + {{- range $index, $entry := $normalized.entries }} - name: proxy-udp-{{ $index | toString }} - {{- if kindIs "map" $port }} - containerPort: {{ splitList ":" ($port.addr | toString) | last }} - {{- else }} - containerPort: {{ $port }} - {{- end }} + containerPort: {{ $entry.port | int }} protocol: UDP {{- end }} {{- end }} {{- end }} - {{- end }} {{- if and .Values.deployment.fallback_cp.mode (eq .Values.deployment.fallback_cp.mode "write") }} {{- /* Disable probes when fallback_cp mode is set to write */ -}} {{- else }} diff --git a/charts/gateway/templates/configmap.yaml b/charts/gateway/templates/configmap.yaml index 5b7716b..c4562ff 100644 --- a/charts/gateway/templates/configmap.yaml +++ b/charts/gateway/templates/configmap.yaml @@ -85,10 +85,12 @@ data: tcp: # TCP proxy port list {{- range .Values.gateway.stream.tcp }} {{- if kindIs "map" . }} - - addr: {{ .addr }} + - addr: {{ .addr | quote }} {{- if hasKey . "tls" }} tls: {{ .tls }} {{- end }} + {{- else if kindIs "string" . }} + - {{ . | quote }} {{- else }} - {{ . }} {{- end }} @@ -98,7 +100,9 @@ data: udp: # UDP proxy port list {{- range .Values.gateway.stream.udp }} {{- if kindIs "map" . }} - - addr: {{ .addr }} + - addr: {{ .addr | quote }} + {{- else if kindIs "string" . }} + - {{ . | quote }} {{- else }} - {{ . }} {{- end }} diff --git a/charts/gateway/templates/service-gateway.yaml b/charts/gateway/templates/service-gateway.yaml index 04eba1a..1fde4ca 100644 --- a/charts/gateway/templates/service-gateway.yaml +++ b/charts/gateway/templates/service-gateway.yaml @@ -89,60 +89,36 @@ spec: protocol: TCP {{- end }} {{- if and .Values.gateway.stream.enabled (or (gt (len .Values.gateway.stream.tcp) 0) (gt (len .Values.gateway.stream.udp) 0)) }} - {{- with .Values.gateway.stream }} - {{- if (gt (len .tcp) 0) }} - {{- range $index, $port := .tcp }} + {{- if (gt (len .Values.gateway.stream.tcp) 0) }} + {{- $normalized := include "gateway.normalizedTcpPorts" .Values.gateway.stream.tcp | fromJson }} + {{- range $index, $entry := $normalized.entries }} - name: proxy-tcp-{{ $index | toString }} protocol: TCP - {{- if kindIs "map" $port }} - port: {{ splitList ":" ($port.addr | toString) | last }} - targetPort: {{ splitList ":" ($port.addr | toString) | last }} + port: {{ $entry.port | int }} + targetPort: {{ $entry.port | int }} {{- if eq $global.Values.gateway.type "NodePort" }} {{- if $global.Values.gateway.stream.autoAssignNodePort }} - nodePort: {{ splitList ":" ($port.addr | toString) | last }} - {{- else }} - {{- if not (empty $port.nodePort) }} - nodePort: {{ $port.nodePort }} + nodePort: {{ $entry.port | int }} + {{- else if ne ($entry.nodePort | toString) "" }} + nodePort: {{ $entry.nodePort }} {{- end }} {{- end }} - {{- end }} - {{- else }} - port: {{ $port }} - targetPort: {{ $port }} - {{- if eq $global.Values.gateway.type "NodePort" }} - {{- if $global.Values.gateway.stream.autoAssignNodePort }} - nodePort: {{ $port }} - {{- end }} - {{- end }} - {{- end }} {{- end }} {{- end }} - {{- if (gt (len .udp) 0) }} - {{- range $index, $port := .udp }} + {{- if (gt (len .Values.gateway.stream.udp) 0) }} + {{- $normalized := include "gateway.normalizedUdpPorts" .Values.gateway.stream.udp | fromJson }} + {{- range $index, $entry := $normalized.entries }} - name: proxy-udp-{{ $index | toString }} protocol: UDP - {{- if kindIs "map" $port }} - port: {{ splitList ":" ($port.addr | toString) | last }} - targetPort: {{ splitList ":" ($port.addr | toString) | last }} + port: {{ $entry.port | int }} + targetPort: {{ $entry.port | int }} {{- if eq $global.Values.gateway.type "NodePort" }} {{- if $global.Values.gateway.stream.autoAssignNodePort }} - nodePort: {{ splitList ":" ($port.addr | toString) | last }} - {{- else }} - {{- if not (empty $port.nodePort) }} - nodePort: {{ $port.nodePort }} - {{- end }} + nodePort: {{ $entry.port | int }} + {{- else if ne ($entry.nodePort | toString) "" }} + nodePort: {{ $entry.nodePort }} {{- end }} {{- end }} - {{- else }} - port: {{ $port }} - targetPort: {{ $port }} - {{- if eq $global.Values.gateway.type "NodePort" }} - {{- if $global.Values.gateway.stream.autoAssignNodePort }} - nodePort: {{ $port }} - {{- end }} - {{- end }} - {{- end }} - {{- end }} {{- end }} {{- end }} {{- end }} diff --git a/charts/gateway/values.yaml b/charts/gateway/values.yaml index 53afcbb..767790e 100644 --- a/charts/gateway/values.yaml +++ b/charts/gateway/values.yaml @@ -364,10 +364,17 @@ gateway: # - addr: 192.168.31.10:5432 # - addr: 3302 # nodePort: 31302 + # - "2000-2100" # port range (nginx native support) + # - "127.0.0.1:2000-2100" # address with port range + # - "1881,1888,2000-2100,3000" # comma-separated ports and ranges + # - addr: "5000-5010" # port range with TLS + # tls: true udp: [] # - addr: 192.168.31.10:53 # - addr: 5353 # nodePort: 31353 + # - "9300-9310" # port range + # - "9400,9401,9500-9510" # comma-separated ports and ranges # -- Using ingress access API7 Gateway service ingress: enabled: false From 1af8467537e94529f54e671ae2eff4de010a64c1 Mon Sep 17 00:00:00 2001 From: Nic Date: Fri, 20 Mar 2026 10:12:16 +0800 Subject: [PATCH 2/2] refactor: simplify port range helpers, fix reversed range - Remove comma-separated support from expandPorts helper - Handle reversed port ranges (e.g., '2100-2000') by swapping bounds - Update values.yaml examples to match gateway changes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- charts/gateway/templates/_helpers.tpl | 41 +++++++++++++-------------- charts/gateway/values.yaml | 6 ++-- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/charts/gateway/templates/_helpers.tpl b/charts/gateway/templates/_helpers.tpl index 8b85559..a5e0bd6 100644 --- a/charts/gateway/templates/_helpers.tpl +++ b/charts/gateway/templates/_helpers.tpl @@ -106,38 +106,37 @@ Scheme to use while connecting etcd {{- end }} {{/* -Expand a port value (which may contain comma-separated ports and/or ranges) -into a list of individual port numbers for K8s resource definitions. -Input: a string like "1881,1888,2000-2100,3000" or "127.0.0.1:2000-2100" or "9100" -Output: JSON {"ports": [1881, 1888, 2000, 2001, ..., 2100, 3000]} +Expand a port value (which may contain a port range) into a list of individual +port numbers for K8s resource definitions. +Input: a string like "2000-2100" or "127.0.0.1:2000-2100" or "9100" +Output: JSON {"ports": [2000, 2001, ..., 2100]} */}} {{- define "gateway.expandPorts" -}} {{- $result := list -}} {{- $s := . | toString -}} -{{- $parts := splitList "," $s -}} -{{- range $part := $parts -}} - {{- $trimmed := trim $part -}} - {{- if ne $trimmed "" -}} - {{- $portPart := splitList ":" $trimmed | last -}} - {{- if contains "-" $portPart -}} - {{- $bounds := splitList "-" $portPart -}} - {{- $start := index $bounds 0 | trim | int -}} - {{- $end := index $bounds 1 | trim | int -}} - {{- $count := add1 (sub $end $start) | int -}} - {{- range $i := until $count -}} - {{- $result = append $result (add $start $i | int) -}} - {{- end -}} - {{- else -}} - {{- $result = append $result ($portPart | trim | int) -}} - {{- end -}} +{{- $portPart := splitList ":" $s | last -}} +{{- if contains "-" $portPart -}} + {{- $bounds := splitList "-" $portPart -}} + {{- $start := index $bounds 0 | trim | int -}} + {{- $end := index $bounds 1 | trim | int -}} + {{- if gt $start $end -}} + {{- $tmp := $start -}} + {{- $start = $end -}} + {{- $end = $tmp -}} + {{- end -}} + {{- $count := add1 (sub $end $start) | int -}} + {{- range $i := until $count -}} + {{- $result = append $result (add $start $i | int) -}} {{- end -}} +{{- else -}} + {{- $result = append $result ($portPart | trim | int) -}} {{- end -}} {{- dict "ports" $result | toJson -}} {{- end -}} {{/* Normalize a TCP port list into expanded individual port entries for K8s resources. -Handles integers, strings (with ranges/commas), and map entries (with addr ranges/commas). +Handles integers, strings (with ranges), and map entries (with addr ranges). Input: the .tcp array from values Output: JSON {"entries": [{"port": 9100, "nodePort": ""}, ...]} */}} diff --git a/charts/gateway/values.yaml b/charts/gateway/values.yaml index 767790e..9b62007 100644 --- a/charts/gateway/values.yaml +++ b/charts/gateway/values.yaml @@ -365,16 +365,14 @@ gateway: # - addr: 3302 # nodePort: 31302 # - "2000-2100" # port range (nginx native support) - # - "127.0.0.1:2000-2100" # address with port range - # - "1881,1888,2000-2100,3000" # comma-separated ports and ranges - # - addr: "5000-5010" # port range with TLS + # - addr: "3000-3100" # port range in table form + # - addr: "127.0.0.1:4000-4100" # address with port range # tls: true udp: [] # - addr: 192.168.31.10:53 # - addr: 5353 # nodePort: 31353 # - "9300-9310" # port range - # - "9400,9401,9500-9510" # comma-separated ports and ranges # -- Using ingress access API7 Gateway service ingress: enabled: false