Skip to content

Commit 327b911

Browse files
Adding support for configurable API paths (#237)
* Add configurable ingress paths for raster, stac, vector, and multidim services * Enhance STAC API tests to verify base path for landing page, collections, and item links with custom ingress paths * Refactor ingress paths in deployment configurations to use configurable values for raster, stac, vector, and multidim services
1 parent 975a266 commit 327b911

File tree

11 files changed

+143
-16
lines changed

11 files changed

+143
-16
lines changed

.github/workflows/tests/test_stac.py

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ def test_stac_api(stac_endpoint):
1414
# Ping
1515
assert client.get(f"{stac_endpoint}/_mgmt/ping").status_code == 200
1616

17+
# Landing page
18+
resp = client.get(stac_endpoint)
19+
assert resp.status_code == 200
20+
landing = resp.json()
21+
# Verify landing page links have correct base path
22+
for link in landing["links"]:
23+
if link["href"].startswith("/"):
24+
assert link["href"].startswith(stac_endpoint.split("://")[1])
25+
1726
# viewer
1827
#assert client.get(f"{stac_endpoint}/index.html").status_code == 200
1928
assert client.get(f"{stac_endpoint}/index.html").status_code == 404
@@ -26,11 +35,21 @@ def test_stac_api(stac_endpoint):
2635
ids = [c["id"] for c in collections]
2736
assert "noaa-emergency-response" in ids
2837

38+
# Verify collection links have correct base path
39+
for collection in collections:
40+
for link in collection["links"]:
41+
if link["href"].startswith("/"):
42+
assert link["href"].startswith(stac_endpoint.split("://")[1])
43+
2944
# items
3045
resp = client.get(f"{stac_endpoint}/collections/noaa-emergency-response/items")
3146
assert resp.status_code == 200
32-
items = resp.json()["features"]
33-
assert len(items) == 10
47+
items = resp.json()
48+
# Verify item links have correct base path
49+
for feature in items["features"]:
50+
for link in feature["links"]:
51+
if link["href"].startswith("/"):
52+
assert link["href"].startswith(stac_endpoint.split("://")[1])
3453

3554
# item
3655
resp = client.get(
@@ -51,6 +70,45 @@ def test_stac_to_raster(stac_endpoint):
5170
#assert resp.status_code == 307
5271
assert resp.status_code == 404
5372

73+
def test_stac_custom_path(stac_endpoint):
74+
"""test stac with custom ingress path."""
75+
# If we're using a custom path (e.g., /api instead of /stac)
76+
base_path = stac_endpoint.split("://")[1]
77+
78+
# Landing page
79+
resp = client.get(stac_endpoint)
80+
assert resp.status_code == 200
81+
landing = resp.json()
82+
83+
# All links should use the custom path
84+
for link in landing["links"]:
85+
if link["href"].startswith("/"):
86+
assert link["href"].startswith(base_path), \
87+
f"Link {link['href']} doesn't start with {base_path}"
88+
89+
# Collections should also use the custom path
90+
resp = client.get(f"{stac_endpoint}/collections")
91+
assert resp.status_code == 200
92+
collections = resp.json()["collections"]
93+
94+
for collection in collections:
95+
for link in collection["links"]:
96+
if link["href"].startswith("/"):
97+
assert link["href"].startswith(base_path), \
98+
f"Collection link {link['href']} doesn't start with {base_path}"
99+
100+
# Test a specific item
101+
resp = client.get(f"{stac_endpoint}/collections/noaa-emergency-response/items")
102+
assert resp.status_code == 200
103+
items = resp.json()
104+
105+
# Item links should also use the custom path
106+
for feature in items["features"]:
107+
for link in feature["links"]:
108+
if link["href"].startswith("/"):
109+
assert link["href"].startswith(base_path), \
110+
f"Item link {link['href']} doesn't start with {base_path}"
111+
54112
# viewer
55113
resp = client.get(
56114
f"{stac_endpoint}/collections/noaa-emergency-response/items/20200307aC0853300w361200/viewer",

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"makefile.configureOnOpen": false
3+
}

helm-chart/eoapi/templates/services/browser/deployment.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ spec:
2020
- containerPort: 8080
2121
env:
2222
- name: SB_catalogUrl
23-
value: "/stac"
23+
value: "{{ .Values.stac.ingress.path }}"
2424
{{- end }}

helm-chart/eoapi/templates/services/ingress.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ spec:
3636
paths:
3737
{{- if and .Values.raster.enabled (or (not (hasKey .Values.raster "ingress")) .Values.raster.ingress.enabled) }}
3838
- pathType: {{ if eq .Values.ingress.className "nginx" }}ImplementationSpecific{{ else }}Prefix{{ end }}
39-
path: /raster{{ if eq .Values.ingress.className "nginx" }}(/|$)(.*){{ end }}
39+
path: {{ .Values.raster.ingress.path }}{{ if eq .Values.ingress.className "nginx" }}(/|$)(.*){{ end }}
4040
backend:
4141
service:
4242
name: raster-{{ $.Release.Name }}
@@ -46,7 +46,7 @@ spec:
4646

4747
{{- if and .Values.stac.enabled (or (not (hasKey .Values.stac "ingress")) .Values.stac.ingress.enabled) }}
4848
- pathType: {{ if eq .Values.ingress.className "nginx" }}ImplementationSpecific{{ else }}Prefix{{ end }}
49-
path: /stac{{ if eq .Values.ingress.className "nginx" }}(/|$)(.*){{ end }}
49+
path: {{ .Values.stac.ingress.path }}{{ if eq .Values.ingress.className "nginx" }}(/|$)(.*){{ end }}
5050
backend:
5151
service:
5252
name: stac-{{ $.Release.Name }}
@@ -56,7 +56,7 @@ spec:
5656

5757
{{- if and .Values.vector.enabled (or (not (hasKey .Values.vector "ingress")) .Values.vector.ingress.enabled) }}
5858
- pathType: {{ if eq .Values.ingress.className "nginx" }}ImplementationSpecific{{ else }}Prefix{{ end }}
59-
path: /vector{{ if eq .Values.ingress.className "nginx" }}(/|$)(.*){{ end }}
59+
path: {{ .Values.vector.ingress.path }}{{ if eq .Values.ingress.className "nginx" }}(/|$)(.*){{ end }}
6060
backend:
6161
service:
6262
name: vector-{{ $.Release.Name }}
@@ -66,7 +66,7 @@ spec:
6666

6767
{{- if and .Values.multidim.enabled (or (not (hasKey .Values.multidim "ingress")) .Values.multidim.ingress.enabled) }}
6868
- pathType: {{ if eq .Values.ingress.className "nginx" }}ImplementationSpecific{{ else }}Prefix{{ end }}
69-
path: /multidim{{ if eq .Values.ingress.className "nginx" }}(/|$)(.*){{ end }}
69+
path: {{ .Values.multidim.ingress.path }}{{ if eq .Values.ingress.className "nginx" }}(/|$)(.*){{ end }}
7070
backend:
7171
service:
7272
name: multidim-{{ $.Release.Name }}

helm-chart/eoapi/templates/services/multidim/deployment.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ spec:
4040
{{- if (and (.Values.ingress.className) (or (eq .Values.ingress.className "nginx") (eq .Values.ingress.className "traefik"))) }}
4141
- "--proxy-headers"
4242
- "--forwarded-allow-ips=*"
43-
- "--root-path=/multidim"
43+
- "--root-path={{ .Values.multidim.ingress.path }}"
4444
{{- end }}{{/* needed for proxies and path rewrites on NLB */}}
4545
livenessProbe:
4646
tcpSocket:

helm-chart/eoapi/templates/services/raster/deployment.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ spec:
4040
{{- if (and (.Values.ingress.className) (or (eq .Values.ingress.className "nginx") (eq .Values.ingress.className "traefik"))) }}
4141
- "--proxy-headers"
4242
- "--forwarded-allow-ips=*"
43-
- "--root-path=/raster"
43+
- "--root-path={{ .Values.raster.ingress.path }}"
4444
{{- end }}{{/* needed for proxies and path rewrites on NLB */}}
4545
livenessProbe:
4646
tcpSocket:

helm-chart/eoapi/templates/services/stac/deployment.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ spec:
4040
{{- if (and (.Values.ingress.className) (or (eq .Values.ingress.className "nginx") (eq .Values.ingress.className "traefik"))) }}
4141
- "--proxy-headers"
4242
- "--forwarded-allow-ips=*"
43-
- "--root-path=/stac"
43+
- "--root-path={{ .Values.stac.ingress.path }}"
4444
{{- end }}{{/* needed for proxies and path rewrites on NLB */}}
4545
livenessProbe:
4646
tcpSocket:

helm-chart/eoapi/templates/services/traefik-middleware.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ spec:
88
stripPrefix:
99
prefixes:
1010
{{- if .Values.raster.enabled }}
11-
- /raster
11+
- {{ .Values.raster.ingress.path }}
1212
{{- end }}
1313
{{- if .Values.stac.enabled }}
14-
- /stac
14+
- {{ .Values.stac.ingress.path }}
1515
{{- end }}
1616
{{- if .Values.vector.enabled }}
17-
- /vector
17+
- {{ .Values.vector.ingress.path }}
1818
{{- end }}
1919
{{- if .Values.multidim.enabled }}
20-
- /multidim
20+
- {{ .Values.multidim.ingress.path }}
2121
{{- end }}
2222
{{- end }}

helm-chart/eoapi/templates/services/vector/deployment.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ spec:
4040
{{- if (and (.Values.ingress.className) (or (eq .Values.ingress.className "nginx") (eq .Values.ingress.className "traefik"))) }}
4141
- "--proxy-headers"
4242
- "--forwarded-allow-ips=*"
43-
- "--root-path=/vector"
43+
- "--root-path={{ .Values.vector.ingress.path }}"
4444
{{- end }}{{/* needed for proxies and path rewrites on NLB */}}
4545
livenessProbe:
4646
tcpSocket:

helm-chart/eoapi/tests/ingress_tests.yaml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,65 @@ tests:
9191
- equal:
9292
path: spec.rules[0].http.paths[1].backend.service.name
9393
value: doc-server-RELEASE-NAME
94+
95+
- it: "custom paths for multiple services with nginx controller"
96+
set:
97+
ingress.className: "nginx"
98+
raster.enabled: true
99+
raster.ingress.path: "/titiler"
100+
stac.enabled: true
101+
stac.ingress.path: "/api"
102+
vector.enabled: true
103+
vector.ingress.path: "/features"
104+
multidim.enabled: false
105+
browser.enabled: false
106+
asserts:
107+
- isKind:
108+
of: Ingress
109+
- equal:
110+
path: spec.rules[0].http.paths[0].path
111+
value: "/titiler(/|$)(.*)"
112+
- equal:
113+
path: spec.rules[0].http.paths[1].path
114+
value: "/api(/|$)(.*)"
115+
- equal:
116+
path: spec.rules[0].http.paths[2].path
117+
value: "/features(/|$)(.*)"
118+
- equal:
119+
path: spec.rules[0].http.paths[0].pathType
120+
value: "ImplementationSpecific"
121+
- equal:
122+
path: spec.rules[0].http.paths[1].pathType
123+
value: "ImplementationSpecific"
124+
- equal:
125+
path: spec.rules[0].http.paths[2].pathType
126+
value: "ImplementationSpecific"
127+
- equal:
128+
path: metadata.annotations
129+
value:
130+
nginx.ingress.kubernetes.io/use-regex: "true"
131+
nginx.ingress.kubernetes.io/rewrite-target: /$2
132+
133+
- it: "custom paths with traefik controller"
134+
set:
135+
ingress.className: "traefik"
136+
raster.enabled: false
137+
stac.enabled: true
138+
stac.ingress.path: "/api"
139+
vector.enabled: false
140+
multidim.enabled: false
141+
browser.enabled: false
142+
asserts:
143+
- isKind:
144+
of: Ingress
145+
- equal:
146+
path: spec.rules[0].http.paths[0].path
147+
value: "/api"
148+
- equal:
149+
path: spec.rules[0].http.paths[0].pathType
150+
value: "Prefix"
151+
- equal:
152+
path: metadata.annotations
153+
value:
154+
traefik.ingress.kubernetes.io/router.entrypoints: web
155+
traefik.ingress.kubernetes.io/router.middlewares: NAMESPACE-strip-prefix-middleware-RELEASE-NAME@kubernetescrd

0 commit comments

Comments
 (0)