Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions deploy/helm/openshell/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,36 @@ Validate chart values that Helm would otherwise accept silently.
{{- if and (eq $workloadKind "statefulset") (gt $replicaCount 1) (not (get $workload "allowMultiReplicaStatefulSet" | default false)) -}}
{{- fail "replicaCount > 1 with workload.kind=statefulset requires workload.allowMultiReplicaStatefulSet=true; use workload.kind=deployment for external database-backed multi-replica gateways." -}}
{{- end -}}
{{- $servicePortValue := toString .Values.service.port -}}
{{- $healthPortValue := toString .Values.service.healthPort -}}
{{- $metricsPortValue := toString (default 0 .Values.service.metricsPort) -}}
{{- if not (regexMatch `^-?[0-9]+$` $servicePortValue) -}}
{{- fail "service.port must be an integer." -}}
{{- end -}}
{{- if not (regexMatch `^-?[0-9]+$` $healthPortValue) -}}
{{- fail "service.healthPort must be an integer." -}}
{{- end -}}
{{- if not (regexMatch `^-?[0-9]+$` $metricsPortValue) -}}
{{- fail "service.metricsPort must be an integer." -}}
{{- end -}}
{{- $servicePort := int $servicePortValue -}}
{{- $healthPort := int $healthPortValue -}}
{{- $metricsPort := int $metricsPortValue -}}
{{- if or (lt $servicePort 1) (gt $servicePort 65535) -}}
{{- fail "service.port must be between 1 and 65535." -}}
{{- end -}}
{{- if or (lt $healthPort 1) (gt $healthPort 65535) -}}
{{- fail "service.healthPort must be between 1 and 65535 because gateway probes require it." -}}
{{- end -}}
{{- if eq $servicePort $healthPort -}}
{{- fail "service.port and service.healthPort must be different." -}}
{{- end -}}
{{- if and (ne $metricsPort 0) (or (lt $metricsPort 1) (gt $metricsPort 65535)) -}}
{{- fail "service.metricsPort must be 0 (disabled) or between 1 and 65535." -}}
{{- end -}}
{{- if and (ne $metricsPort 0) (or (eq $metricsPort $servicePort) (eq $metricsPort $healthPort)) -}}
{{- fail "service.metricsPort must differ from service.port and service.healthPort." -}}
{{- end -}}
{{- $workspaceMode := .Values.server.drivers.kubernetes.workspaceMode | default "shared" -}}
{{- if not (has $workspaceMode (list "shared" "managed" "operator")) -}}
{{- fail "server.drivers.kubernetes.workspaceMode must be one of: shared, managed, operator." -}}
Expand Down
129 changes: 129 additions & 0 deletions deploy/helm/openshell/tests/gateway_ports_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

suite: gateway listener port validation
templates:
- templates/gateway-config.yaml
- templates/statefulset.yaml

tests:
- it: rejects primary gateway port 0
template: templates/statefulset.yaml
set:
service.port: 0
asserts:
- failedTemplate:
errorPattern: "service.port must be between 1 and 65535"

- it: rejects a primary gateway listener above the valid port range
template: templates/statefulset.yaml
set:
service.port: 65536
asserts:
- failedTemplate:
errorPattern: "service.port must be between 1 and 65535"

- it: rejects a disabled health listener because probes require it
template: templates/statefulset.yaml
set:
service.healthPort: 0
asserts:
- failedTemplate:
errorPattern: "service.healthPort must be between 1 and 65535 because gateway probes require it"

- it: rejects a health listener above the valid port range
template: templates/statefulset.yaml
set:
service.healthPort: 65536
asserts:
- failedTemplate:
errorPattern: "service.healthPort must be between 1 and 65535 because gateway probes require it"

- it: rejects a health listener that collides with the primary listener
template: templates/statefulset.yaml
set:
service.healthPort: 8080
asserts:
- failedTemplate:
errorPattern: "service.port and service.healthPort must be different"

- it: rejects a metrics listener that collides with the primary listener
template: templates/statefulset.yaml
set:
service.metricsPort: 8080
asserts:
- failedTemplate:
errorPattern: "service.metricsPort must differ from service.port and service.healthPort"

- it: rejects a metrics listener that collides with the health listener
template: templates/statefulset.yaml
set:
service.metricsPort: 8081
asserts:
- failedTemplate:
errorPattern: "service.metricsPort must differ from service.port and service.healthPort"

- it: rejects a negative metrics listener port
template: templates/statefulset.yaml
set:
service.metricsPort: -1
asserts:
- failedTemplate:
errorPattern: "service.metricsPort must be 0 \\(disabled\\) or between 1 and 65535"

- it: rejects a boolean primary port
template: templates/statefulset.yaml
set:
service.port: true
asserts:
- failedTemplate:
errorPattern: "service.port must be an integer"

- it: rejects a boolean health port
template: templates/statefulset.yaml
set:
service.healthPort: true
asserts:
- failedTemplate:
errorPattern: "service.healthPort must be an integer"

- it: rejects a boolean metrics port
template: templates/statefulset.yaml
set:
service.metricsPort: true
asserts:
- failedTemplate:
errorPattern: "service.metricsPort must be an integer"

- it: rejects a fractional metrics port
template: templates/statefulset.yaml
set:
service.metricsPort: 9090.5
asserts:
- failedTemplate:
errorPattern: "service.metricsPort must be an integer"

- it: rejects a metrics listener above the valid port range
template: templates/statefulset.yaml
set:
service.metricsPort: 65536
asserts:
- failedTemplate:
errorPattern: "service.metricsPort must be 0 \\(disabled\\) or between 1 and 65535"

- it: accepts boundary ports with metrics disabled
template: templates/gateway-config.yaml
set:
service.port: 1
service.healthPort: 65535
service.metricsPort: 0
asserts:
- matchRegex:
path: data["gateway.toml"]
pattern: '(?m)^bind_address\s*=\s*"0\.0\.0\.0:1"$'
- matchRegex:
path: data["gateway.toml"]
pattern: '(?m)^health_bind_address\s*=\s*"0\.0\.0\.0:65535"$'
- notMatchRegex:
path: data["gateway.toml"]
pattern: '(?m)^metrics_bind_address\s*='
Loading