From cfc58a814e5e46f8ecd498763e5927a283eb1e8c Mon Sep 17 00:00:00 2001 From: Felix Delattre Date: Tue, 21 Jul 2026 16:06:19 +0200 Subject: [PATCH 1/2] fix(helm): make health path take root path into account. --- helm/README.md | 4 ++ helm/templates/_helpers.tpl | 34 ++++++++++++++ helm/templates/deployment.yaml | 6 +-- helm/tests/deployment_test.yaml | 82 +++++++++++++++++++++++++++++++++ helm/values.schema.json | 8 ++-- helm/values.yaml | 7 +-- 6 files changed, 131 insertions(+), 10 deletions(-) diff --git a/helm/README.md b/helm/README.md index 84f44af..b6d0748 100644 --- a/helm/README.md +++ b/helm/README.md @@ -7,3 +7,7 @@ For documentation, see [Kubernetes Deployment](https://developmentseed.org/stac- ```bash helm install stac-auth-proxy ./helm ``` + +## Probes and `ROOT_PATH` + +Startup, liveness, and readiness probes default `httpGet.path` to `{env.ROOT_PATH}{env.HEALTHZ_PREFIX}` (e.g. `/stac/healthz` when `ROOT_PATH=/stac`). If unset, that is `/healthz`. Set `startupProbe` / `livenessProbe` / `readinessProbe` `httpGet.path` explicitly to override. diff --git a/helm/templates/_helpers.tpl b/helm/templates/_helpers.tpl index d5137ef..22a3058 100644 --- a/helm/templates/_helpers.tpl +++ b/helm/templates/_helpers.tpl @@ -89,3 +89,37 @@ Validate autoscaling replica bounds when HPA is enabled {{- end -}} {{- end -}} {{- end -}} + +{{/* +Health endpoint path: {ROOT_PATH}{HEALTHZ_PREFIX}. +ROOT_PATH trailing slash is trimmed; HEALTHZ_PREFIX defaults to /healthz. +*/}} +{{- define "stac-auth-proxy.healthzPath" -}} +{{- $rootPath := dig "ROOT_PATH" "" .Values.env | default "" | trimSuffix "/" -}} +{{- $healthzPrefix := dig "HEALTHZ_PREFIX" "/healthz" .Values.env | default "/healthz" -}} +{{- printf "%s%s" $rootPath $healthzPrefix -}} +{{- end -}} + +{{/* +Render a probe, deriving httpGet.path from ROOT_PATH + HEALTHZ_PREFIX when unset. +Usage: include "stac-auth-proxy.probe" (dict "context" . "probe" .Values.startupProbe) +*/}} +{{- define "stac-auth-proxy.probe" -}} +{{- $result := dict -}} +{{- range $k, $v := .probe -}} +{{- if ne $k "httpGet" -}} +{{- $_ := set $result $k $v -}} +{{- end -}} +{{- end -}} +{{- if .probe.httpGet -}} +{{- $httpGet := dict -}} +{{- range $k, $v := .probe.httpGet -}} +{{- $_ := set $httpGet $k $v -}} +{{- end -}} +{{- if not (hasKey $httpGet "path") -}} +{{- $_ := set $httpGet "path" (include "stac-auth-proxy.healthzPath" .context) -}} +{{- end -}} +{{- $_ := set $result "httpGet" $httpGet -}} +{{- end -}} +{{- toYaml $result -}} +{{- end -}} diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml index 76cb380..3a9deb5 100644 --- a/helm/templates/deployment.yaml +++ b/helm/templates/deployment.yaml @@ -38,15 +38,15 @@ spec: protocol: TCP {{- with .Values.startupProbe }} startupProbe: - {{- toYaml . | nindent 12 }} + {{- include "stac-auth-proxy.probe" (dict "context" $ "probe" .) | nindent 12 }} {{- end }} {{- with .Values.livenessProbe }} livenessProbe: - {{- toYaml . | nindent 12 }} + {{- include "stac-auth-proxy.probe" (dict "context" $ "probe" .) | nindent 12 }} {{- end }} {{- with .Values.readinessProbe }} readinessProbe: - {{- toYaml . | nindent 12 }} + {{- include "stac-auth-proxy.probe" (dict "context" $ "probe" .) | nindent 12 }} {{- end }} {{- if .Values.preStopSleepSeconds }} lifecycle: diff --git a/helm/tests/deployment_test.yaml b/helm/tests/deployment_test.yaml index 8f0c7d0..4d10744 100644 --- a/helm/tests/deployment_test.yaml +++ b/helm/tests/deployment_test.yaml @@ -117,3 +117,85 @@ tests: - lengthEqual: path: spec.template.spec.containers count: 1 + + - it: should default probe paths to /healthz + set: + env.UPSTREAM_URL: "https://example.com" + env.OIDC_DISCOVERY_URL: "https://example.com/.well-known/openid-configuration" + asserts: + - equal: + path: spec.template.spec.containers[0].startupProbe.httpGet.path + value: /healthz + - equal: + path: spec.template.spec.containers[0].livenessProbe.httpGet.path + value: /healthz + - equal: + path: spec.template.spec.containers[0].readinessProbe.httpGet.path + value: /healthz + + - it: should prefix probe paths with ROOT_PATH + set: + env.UPSTREAM_URL: "https://example.com" + env.OIDC_DISCOVERY_URL: "https://example.com/.well-known/openid-configuration" + env.ROOT_PATH: /stac + asserts: + - equal: + path: spec.template.spec.containers[0].startupProbe.httpGet.path + value: /stac/healthz + - equal: + path: spec.template.spec.containers[0].livenessProbe.httpGet.path + value: /stac/healthz + - equal: + path: spec.template.spec.containers[0].readinessProbe.httpGet.path + value: /stac/healthz + + - it: should use ROOT_PATH and custom HEALTHZ_PREFIX for probe paths + set: + env.UPSTREAM_URL: "https://example.com" + env.OIDC_DISCOVERY_URL: "https://example.com/.well-known/openid-configuration" + env.ROOT_PATH: /stac + env.HEALTHZ_PREFIX: /ready + asserts: + - equal: + path: spec.template.spec.containers[0].startupProbe.httpGet.path + value: /stac/ready + - equal: + path: spec.template.spec.containers[0].livenessProbe.httpGet.path + value: /stac/ready + - equal: + path: spec.template.spec.containers[0].readinessProbe.httpGet.path + value: /stac/ready + + - it: should respect explicit probe httpGet.path over derivation + set: + env.UPSTREAM_URL: "https://example.com" + env.OIDC_DISCOVERY_URL: "https://example.com/.well-known/openid-configuration" + env.ROOT_PATH: /stac + startupProbe: + httpGet: + path: /custom-startup + port: http + periodSeconds: 2 + failureThreshold: 30 + livenessProbe: + httpGet: + path: /custom-live + port: http + periodSeconds: 60 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /custom-ready + port: http + periodSeconds: 5 + failureThreshold: 3 + asserts: + - equal: + path: spec.template.spec.containers[0].startupProbe.httpGet.path + value: /custom-startup + - equal: + path: spec.template.spec.containers[0].livenessProbe.httpGet.path + value: /custom-live + - equal: + path: spec.template.spec.containers[0].readinessProbe.httpGet.path + value: /custom-ready diff --git a/helm/values.schema.json b/helm/values.schema.json index b96727f..9ca36a2 100644 --- a/helm/values.schema.json +++ b/helm/values.schema.json @@ -67,7 +67,7 @@ }, "ROOT_PATH": { "type": "string", - "description": "Path prefix for the proxy API", + "description": "Path prefix for the proxy API. Also prefixes probe httpGet.path when those paths are unset.", "default": "" }, "OIDC_DISCOVERY_URL": { @@ -275,17 +275,17 @@ "startupProbe": { "type": "object", "additionalProperties": true, - "description": "Startup probe configuration. Disables liveness/readiness probes until startup succeeds." + "description": "Startup probe configuration. Disables liveness/readiness probes until startup succeeds. httpGet.path defaults to {ROOT_PATH}{HEALTHZ_PREFIX} when unset." }, "livenessProbe": { "type": "object", "additionalProperties": true, - "description": "Liveness probe configuration. Determines if the container should be restarted." + "description": "Liveness probe configuration. Determines if the container should be restarted. httpGet.path defaults to {ROOT_PATH}{HEALTHZ_PREFIX} when unset." }, "readinessProbe": { "type": "object", "additionalProperties": true, - "description": "Readiness probe configuration. Determines if the container should receive traffic." + "description": "Readiness probe configuration. Determines if the container should receive traffic. httpGet.path defaults to {ROOT_PATH}{HEALTHZ_PREFIX} when unset." }, "nodeSelector": { "type": "object", diff --git a/helm/values.yaml b/helm/values.yaml index c7c24c2..6b94f90 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -53,23 +53,22 @@ preStopSleepSeconds: 15 # Probes # startupProbe disables liveness/readiness checks until startup succeeds, # giving the app time to wait for upstream services (e.g. during node scaling). +# httpGet.path is derived as {ROOT_PATH}{HEALTHZ_PREFIX} when unset (default /healthz). +# Set httpGet.path explicitly to override (e.g. path: /custom-health). startupProbe: httpGet: - path: /healthz port: http periodSeconds: 2 failureThreshold: 30 # 60s total for startup livenessProbe: httpGet: - path: /healthz port: http periodSeconds: 60 failureThreshold: 3 readinessProbe: httpGet: - path: /healthz port: http periodSeconds: 5 failureThreshold: 3 @@ -146,7 +145,9 @@ env: # Optional configuration UPSTREAM_TIMEOUT: 15.0 WAIT_FOR_UPSTREAM: true + # Used with ROOT_PATH to derive probe httpGet.path when not set explicitly HEALTHZ_PREFIX: "/healthz" + # ROOT_PATH: "/stac" # If set, probes default to {ROOT_PATH}{HEALTHZ_PREFIX} OIDC_DISCOVERY_INTERNAL_URL: "http://localhost:8081/.well-known/openid-configuration" DEFAULT_PUBLIC: false PRIVATE_ENDPOINTS: | From f8782a63b8224fe0e224a4225eb6b9fe1e749d7b Mon Sep 17 00:00:00 2001 From: Felix Delattre Date: Wed, 22 Jul 2026 10:13:37 +0200 Subject: [PATCH 2/2] Small clean-ups. --- helm/templates/_helpers.tpl | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/helm/templates/_helpers.tpl b/helm/templates/_helpers.tpl index 22a3058..fa2f474 100644 --- a/helm/templates/_helpers.tpl +++ b/helm/templates/_helpers.tpl @@ -95,8 +95,8 @@ Health endpoint path: {ROOT_PATH}{HEALTHZ_PREFIX}. ROOT_PATH trailing slash is trimmed; HEALTHZ_PREFIX defaults to /healthz. */}} {{- define "stac-auth-proxy.healthzPath" -}} -{{- $rootPath := dig "ROOT_PATH" "" .Values.env | default "" | trimSuffix "/" -}} -{{- $healthzPrefix := dig "HEALTHZ_PREFIX" "/healthz" .Values.env | default "/healthz" -}} +{{- $rootPath := dig "ROOT_PATH" "" .Values.env | trimSuffix "/" -}} +{{- $healthzPrefix := dig "HEALTHZ_PREFIX" "/healthz" .Values.env -}} {{- printf "%s%s" $rootPath $healthzPrefix -}} {{- end -}} @@ -105,21 +105,9 @@ Render a probe, deriving httpGet.path from ROOT_PATH + HEALTHZ_PREFIX when unset Usage: include "stac-auth-proxy.probe" (dict "context" . "probe" .Values.startupProbe) */}} {{- define "stac-auth-proxy.probe" -}} -{{- $result := dict -}} -{{- range $k, $v := .probe -}} -{{- if ne $k "httpGet" -}} -{{- $_ := set $result $k $v -}} -{{- end -}} -{{- end -}} -{{- if .probe.httpGet -}} -{{- $httpGet := dict -}} -{{- range $k, $v := .probe.httpGet -}} -{{- $_ := set $httpGet $k $v -}} -{{- end -}} -{{- if not (hasKey $httpGet "path") -}} -{{- $_ := set $httpGet "path" (include "stac-auth-proxy.healthzPath" .context) -}} -{{- end -}} -{{- $_ := set $result "httpGet" $httpGet -}} +{{- $result := deepCopy .probe -}} +{{- if and $result.httpGet (not (hasKey $result.httpGet "path")) -}} +{{- $_ := set $result.httpGet "path" (include "stac-auth-proxy.healthzPath" .context) -}} {{- end -}} {{- toYaml $result -}} {{- end -}}