Skip to content
Merged
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
100 changes: 100 additions & 0 deletions charts/eoapi/templates/_helpers/networking.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
{{/*
Return JSON array of enabled ingress services with resolved path, backend, and rewrite metadata.
Browser remains on the main ingress; skipStripPrefix excludes it from Traefik strip-prefix only.
*/}}
{{- define "eoapi.enabledIngressServices" -}}
{{- $root := . -}}
{{- $entries := list
(dict "key" "stac" "usesAuthProxy" true)
(dict "key" "raster")
(dict "key" "vector")
(dict "key" "multidim")
(dict "key" "browser" "defaultPath" "/browser" "hasOwnPort" true "skipStripPrefix" true)
(dict "key" "mockOidcServer" "actualName" "mock-oidc-server" "hasOwnPort" true)
-}}
{{- $resolved := list -}}
{{- range $entries }}
{{- $entry := . -}}
{{- $service := ternary (index $root.Values "testing" "mockOidcServer") (index $root.Values $entry.key) (eq $entry.key "mockOidcServer") -}}
{{- $ingress := (($service | default dict).ingress) | default dict -}}
{{- if and $service $service.enabled (or (not $service.ingress) $service.ingress.enabled) }}
{{- $path := $ingress.path | default $entry.defaultPath -}}
{{- $useAuthProxy := and $entry.usesAuthProxy (index $root.Values "stac-auth-proxy" "enabled") -}}
{{/* nginxStrip: NGINX rewrite path shape; stripPrefix: Traefik middleware (matches main, includes "/") */}}
{{- $nginxStrip := and (ne $path "/") (not $useAuthProxy) -}}
{{- $stripPrefix := and (not $entry.skipStripPrefix) (not $useAuthProxy) -}}
{{- $serviceName := $entry.actualName | default $entry.key -}}
{{- $port := $root.Values.service.port -}}
{{- if $entry.hasOwnPort }}
{{- $port = (($service.service).port | default 8080) }}
{{- end }}
{{- $resolved = append $resolved (dict "path" $path "serviceName" $serviceName "port" $port "useAuthProxy" $useAuthProxy "stripPath" $nginxStrip "stripPrefix" $stripPrefix) -}}
{{- end }}
{{- end }}
{{- toJson $resolved -}}
{{- end -}}

{{/*
Return true when at least one ingress service or doc server is enabled.
*/}}
{{- define "eoapi.hasEnabledService" -}}
{{- if or (include "eoapi.enabledIngressServices" . | fromJsonArray) .Values.docServer.enabled -}}true{{- end -}}
{{- end -}}

{{/*
Generate ingress path rules for enabled services and doc server.
*/}}
{{- define "eoapi.ingressPaths" -}}
{{- $root := . -}}
{{- $isNginx := eq $root.Values.ingress.className "nginx" -}}
{{- range include "eoapi.enabledIngressServices" $root | fromJsonArray }}
- pathType: {{ if and $isNginx .stripPath }}ImplementationSpecific{{ else }}Prefix{{ end }}
path: {{ .path }}{{ if and $isNginx .stripPath }}(/|$)(.*){{ end }}
backend:
service:
{{- if .useAuthProxy }}
name: {{ $root.Release.Name }}-stac-auth-proxy
{{- else }}
name: {{ $root.Release.Name }}-{{ .serviceName }}
{{- end }}
port:
number: {{ .port }}
{{- end }}
{{- if $root.Values.docServer.enabled }}
- pathType: Prefix
path: "/{{ $root.Values.ingress.rootPath | default "" }}"
backend:
service:
name: {{ $root.Release.Name }}-doc-server
port:
number: 80
{{- end }}
{{- end -}}

{{/*
Return JSON array of path prefixes for Traefik strip-prefix middleware.
*/}}
{{- define "eoapi.traefikStripPrefixes" -}}
{{- $prefixes := list -}}
{{- range include "eoapi.enabledIngressServices" . | fromJsonArray }}
{{- if and .stripPrefix .path }}
{{- $prefixes = append $prefixes .path }}
{{- end }}
{{- end }}
{{- toJson $prefixes -}}
{{- end -}}

{{/*
Return the configured browser ingress path without trailing slash.
*/}}
{{- define "eoapi.browserIngressPath" -}}
{{- trimSuffix "/" ((((.Values.browser).ingress).path) | default "/browser") | default "/" -}}
{{- end -}}

{{/*
Return true when the Traefik bare-path redirect middleware is needed.
*/}}
{{- define "eoapi.browserRedirectEnabled" -}}
{{- $browser := .Values.browser -}}
{{- if and $browser $browser.enabled (or (not $browser.ingress) $browser.ingress.enabled) -}}true{{- end -}}
{{- end -}}
92 changes: 9 additions & 83 deletions charts/eoapi/templates/networking/ingress.yaml
Original file line number Diff line number Diff line change
@@ -1,96 +1,22 @@
{{/*
Helper template for generating ingress paths
*/}}
{{- define "eoapi.ingressPaths" -}}
{{- $isNginx := eq .Values.ingress.className "nginx" -}}
{{- $root := . -}}

{{/* Service list with metadata for special cases - preserves order */}}
{{- $services := list
(dict "key" "stac" "usesAuthProxy" true)
(dict "key" "raster")
(dict "key" "vector")
(dict "key" "multidim")
(dict "key" "browser" "defaultPath" "/browser" "hasOwnPort" true)
(dict "key" "mockOidcServer" "actualName" "mock-oidc-server" "hasOwnPort" true "config" .Values.testing.mockOidcServer)
-}}

{{- range $services }}
{{- $service := .config | default (index $root.Values .key) }}
{{- if and $service $service.enabled (or (not $service.ingress) $service.ingress.enabled) }}
{{- $path := $service.ingress.path | default .defaultPath }}
{{- $useAuthProxy := and .usesAuthProxy (index $root.Values "stac-auth-proxy" "enabled") }}
{{- $stripPath := and (ne $path "/") (not $useAuthProxy) }}
{{- $serviceName := .actualName | default .key }}
{{- $port := $root.Values.service.port }}
{{- if .hasOwnPort }}
{{- if $service.service }}
{{- $port = $service.service.port | default 8080 }}
{{- else }}
{{- $port = 8080 }}
{{- end }}
{{- end }}
- pathType: {{ if and $isNginx $stripPath }}ImplementationSpecific{{ else }}Prefix{{ end }}
path: {{ $path }}{{ if and $isNginx $stripPath }}(/|$)(.*){{ end }}
backend:
service:
{{- if $useAuthProxy }}
name: {{ $root.Release.Name }}-stac-auth-proxy
{{- else }}
name: {{ $root.Release.Name }}-{{ $serviceName }}
{{- end }}
port:
number: {{ $port }}
{{- end }}
{{- end }}

{{- if .Values.docServer.enabled }}
- pathType: Prefix
path: "/{{ .Values.ingress.rootPath | default "" }}"
backend:
service:
name: {{ .Release.Name }}-doc-server
port:
number: 80
{{- end }}
{{- end }}

{{- define "eoapi.hasEnabledService" -}}
{{- $keys := list "stac" "raster" "vector" "multidim" "browser" -}}
{{- $hasService := false -}}
{{- range $keys }}
{{- $s := index $.Values . }}
{{- if and $s $s.enabled (or (not $s.ingress) $s.ingress.enabled) }}
{{- $hasService = true -}}
{{- end }}
{{- end }}
{{- if and $.Values.testing.mockOidcServer $.Values.testing.mockOidcServer.enabled (or (not $.Values.testing.mockOidcServer.ingress) $.Values.testing.mockOidcServer.ingress.enabled) }}
{{- $hasService = true -}}
{{- end }}
{{- or $hasService .Values.docServer.enabled -}}
{{- end }}

{{- if and .Values.ingress.enabled (include "eoapi.hasEnabledService" . | trim | eq "true") }}
{{- $ingressAnnotations := .Values.ingress.annotations | default dict }}
{{- $annotations := dict }}
{{- if and (eq .Values.ingress.className "traefik") .Values.ingress.entrypoints }}
{{- $_ := set $annotations "traefik.ingress.kubernetes.io/router.entrypoints" (.Values.ingress.entrypoints | toString) }}
{{- end }}
{{- $annotations = mergeOverwrite $annotations $ingressAnnotations }}
{{- $annotations := dict -}}
{{- if and (eq .Values.ingress.className "traefik") .Values.ingress.entrypoints -}}
{{- $_ := set $annotations "traefik.ingress.kubernetes.io/router.entrypoints" (.Values.ingress.entrypoints | toString) -}}
{{- end -}}
{{- $annotations = mergeOverwrite $annotations (.Values.ingress.annotations | default dict) -}}
{{- if eq .Values.ingress.className "nginx" }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/rewrite-target" "/$2" }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/use-regex" "true" }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/rewrite-target" "/$2" -}}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/use-regex" "true" -}}
{{- end }}
{{- if eq .Values.ingress.className "traefik" }}
{{- /* strip-prefix always; also chain the browser bare-path redirect when the browser ingress is on.
Keep this condition in sync with the redirect Middleware in traefik-middleware.yaml. */}}
{{- $mwPrefix := printf "%s-%s" .Release.Namespace .Release.Name }}
{{- $middlewares := list (printf "%s-strip-prefix-middleware@kubernetescrd" $mwPrefix) }}
{{- $browser := .Values.browser }}
{{- if and $browser $browser.enabled (or (not $browser.ingress) $browser.ingress.enabled) }}
{{- if include "eoapi.browserRedirectEnabled" . | trim }}
{{- $middlewares = append $middlewares (printf "%s-browser-redirect-middleware@kubernetescrd" $mwPrefix) }}
{{- end }}
{{- $_ := set $annotations "traefik.ingress.kubernetes.io/router.middlewares" (join "," $middlewares) }}
{{- $_ := set $annotations "traefik.ingress.kubernetes.io/router.middlewares" (join "," $middlewares) -}}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }}
apiVersion: networking.k8s.io/v1
Expand Down
29 changes: 3 additions & 26 deletions charts/eoapi/templates/networking/traefik-middleware.yaml
Original file line number Diff line number Diff line change
@@ -1,27 +1,5 @@
{{- if and .Values.ingress.enabled (eq .Values.ingress.className "traefik") }}
{{- $services := list
(dict "key" "stac" "usesAuthProxy" true)
(dict "key" "raster")
(dict "key" "vector")
(dict "key" "multidim")
(dict "key" "browser" "defaultPath" "/browser" "skipStripPrefix" true)
(dict "key" "mockOidcServer" "config" .Values.testing.mockOidcServer)
-}}
{{- $prefixes := list -}}

{{- range $services }}
{{- $service := .config | default (index $.Values .key) }}
{{- if and $service $service.enabled (or (not $service.ingress) $service.ingress.enabled) }}
{{- $stripPath := not (or .skipStripPrefix (and .usesAuthProxy (index $.Values "stac-auth-proxy" "enabled"))) }}
{{- if $stripPath }}
{{- $path := $service.ingress.path | default .defaultPath }}
{{- if $path }}
{{- $prefixes = append $prefixes $path }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

{{- $prefixes := include "eoapi.traefikStripPrefixes" . | fromJsonArray -}}
{{- if $prefixes }}
apiVersion: traefik.io/v1alpha1
kind: Middleware
Expand All @@ -40,9 +18,8 @@ spec:
{{- /* Bare browser path 404s (pathPrefix is baked into the image) and Traefik has no
append-slash, so redirect the exact bare path to its trailing-slash form.
Keep this condition in sync with the router annotation in ingress.yaml. */}}
{{- $browser := .Values.browser }}
{{- if and $browser $browser.enabled (or (not $browser.ingress) $browser.ingress.enabled) }}
{{- $browserPath := trimSuffix "/" ($browser.ingress.path | default "/browser") }}
{{- if include "eoapi.browserRedirectEnabled" . | trim }}
{{- $browserPath := include "eoapi.browserIngressPath" . }}
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
Expand Down
1 change: 1 addition & 0 deletions charts/eoapi/tests/browser_redirect_test.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
suite: browser bare-path redirect middleware
templates:
- templates/_helpers/networking.tpl
- templates/networking/traefik-middleware.yaml
- templates/networking/ingress.yaml
set:
Expand Down
Loading