This is an automated email from the ASF dual-hosted git repository.
jerryshao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 0e96563519 [#10866] feat(charts): Support Gateway API HTTPRoute in
Helm charts (#11308)
0e96563519 is described below
commit 0e96563519b98fbef903e833f8dafb314afa0b23
Author: somaz <[email protected]>
AuthorDate: Thu Jul 2 16:18:57 2026 +0900
[#10866] feat(charts): Support Gateway API HTTPRoute in Helm charts (#11308)
### What changes were proposed in this pull request?
Add an opt-in `ingress.type` field to the Gravitino, Iceberg REST, and
Lance REST
Helm charts. It defaults to `ingress` (renders the existing
`networking.k8s.io/v1`
Ingress, fully backward compatible). When set to `gateway`, the chart
renders a
Kubernetes Gateway API `HTTPRoute` (`gateway.networking.k8s.io/v1`)
instead of an
Ingress.
- New template `templates/httproute.yaml` in all three charts.
- Existing `templates/ingress.yaml` is now gated to skip when `type:
gateway`, so
the two resources are mutually exclusive.
- New `ingress.gateway` block (`apiVersion`, `parentRefs`) in
`values.yaml`. The
existing `hosts` / `paths` / `annotations` are reused for the HTTPRoute.
- helm-unittest coverage added for the Iceberg chart
(`httproute_test.yaml`, plus a
case asserting the Ingress is not rendered in gateway mode).
Note: `tls` and `className` are Ingress-only and are intentionally not
consumed by
HTTPRoute — Gateway API terminates TLS at the parent Gateway listener.
### Why are the changes needed?
The charts currently only support the legacy Ingress resource. The
Gateway API is
the successor to Ingress and the standard in modern Kubernetes
environments. This
lets users on a Gateway API stack expose Gravitino services without
bolting an
Ingress controller alongside their Gateway.
Fix: #10866
### Does this PR introduce _any_ user-facing change?
Yes — a new opt-in chart value `ingress.type` (default `ingress`) and an
`ingress.gateway` block. Existing installations are unaffected because
the default
preserves the current Ingress behavior.
### How was this patch tested?
- `helm unittest --with-subchart=false
dev/charts/gravitino-iceberg-rest-server`
→ 8 suites, 27 tests pass (includes the new httproute suite).
- `helm template` on all three charts: `type: gateway` renders an
HTTPRoute and no
Ingress; default/`type: ingress` renders an Ingress and no HTTPRoute.
- `helm lint` passes for the iceberg and lance charts.
---
##### Was generative AI tooling used to co-author this PR?
- [X] Yes — Claude Code (Opus 4.8)
Generated-by: Claude Code (Opus 4.8)
---
.../templates/httproute.yaml | 67 +++++++
.../templates/ingress.yaml | 2 +-
.../tests/httproute_test.yaml | 205 +++++++++++++++++++++
.../tests/ingress_test.yaml | 9 +
.../gravitino-iceberg-rest-server/values.yaml | 19 ++
.../templates/httproute.yaml | 67 +++++++
.../templates/ingress.yaml | 2 +-
.../tests/httproute_test.yaml | 154 ++++++++++++++++
.../tests/ingress_test.yaml | 9 +
dev/charts/gravitino-lance-rest-server/values.yaml | 19 ++
dev/charts/gravitino/templates/httproute.yaml | 67 +++++++
dev/charts/gravitino/templates/ingress.yaml | 4 +-
dev/charts/gravitino/tests/httproute_test.yaml | 154 ++++++++++++++++
dev/charts/gravitino/tests/ingress_test.yaml | 9 +
dev/charts/gravitino/values.yaml | 19 ++
15 files changed, 802 insertions(+), 4 deletions(-)
diff --git a/dev/charts/gravitino-iceberg-rest-server/templates/httproute.yaml
b/dev/charts/gravitino-iceberg-rest-server/templates/httproute.yaml
new file mode 100644
index 0000000000..0186127c7f
--- /dev/null
+++ b/dev/charts/gravitino-iceberg-rest-server/templates/httproute.yaml
@@ -0,0 +1,67 @@
+{{- /*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */}}
+
+{{- if and .Values.ingress.enabled (eq (.Values.ingress.type | default
"ingress") "gateway") -}}
+{{- $fullName := include "gravitino-iceberg-rest-server.fullname" . -}}
+{{- $svcPort := .Values.service.port -}}
+{{- $gateway := .Values.ingress.gateway | default dict -}}
+{{- $root := . -}}
+{{- /* Render one HTTPRoute per host so that, like the Ingress, each host only
+ matches its own paths (HTTPRoute hostnames apply to the whole resource).
*/}}
+{{- range $hostIndex, $hostEntry := .Values.ingress.hosts }}
+{{- if $hostIndex }}
+---
+{{- end }}
+apiVersion: {{ $gateway.apiVersion | default "gateway.networking.k8s.io/v1" }}
+kind: HTTPRoute
+metadata:
+ name: {{ $fullName }}{{ if $hostIndex }}-{{ $hostIndex }}{{ end }}
+ labels:
+ {{- include "gravitino-iceberg-rest-server.labels" $root | nindent 4 }}
+ {{- with $root.Values.ingress.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ {{- with $gateway.parentRefs }}
+ parentRefs:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ {{- if $hostEntry.host }}
+ hostnames:
+ - {{ $hostEntry.host | quote }}
+ {{- end }}
+ rules:
+ {{- range $hostEntry.paths }}
+ {{- $pathType := .pathType | default "Prefix" }}
+ {{- if or (eq $pathType "Prefix") (eq $pathType "PathPrefix") (eq
$pathType "ImplementationSpecific") }}
+ {{- $pathType = "PathPrefix" }}
+ {{- else if ne $pathType "Exact" }}
+ {{- fail (printf "ingress.hosts[].paths[].pathType %q is not supported
when ingress.type is \"gateway\"; use Exact, Prefix, or ImplementationSpecific"
$pathType) }}
+ {{- end }}
+ - matches:
+ - path:
+ type: {{ $pathType }}
+ value: {{ .path | quote }}
+ backendRefs:
+ - name: {{ $fullName }}
+ port: {{ $svcPort }}
+ {{- end }}
+{{- end }}
+{{- end }}
diff --git a/dev/charts/gravitino-iceberg-rest-server/templates/ingress.yaml
b/dev/charts/gravitino-iceberg-rest-server/templates/ingress.yaml
index 67cd365fba..337ca2809e 100644
--- a/dev/charts/gravitino-iceberg-rest-server/templates/ingress.yaml
+++ b/dev/charts/gravitino-iceberg-rest-server/templates/ingress.yaml
@@ -17,7 +17,7 @@
under the License.
*/}}
-{{- if .Values.ingress.enabled -}}
+{{- if and .Values.ingress.enabled (ne (.Values.ingress.type | default
"ingress") "gateway") -}}
{{- $fullName := include "gravitino-iceberg-rest-server.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0"
.Capabilities.KubeVersion.GitVersion)) }}
diff --git a/dev/charts/gravitino-iceberg-rest-server/tests/httproute_test.yaml
b/dev/charts/gravitino-iceberg-rest-server/tests/httproute_test.yaml
new file mode 100644
index 0000000000..ea370bbde2
--- /dev/null
+++ b/dev/charts/gravitino-iceberg-rest-server/tests/httproute_test.yaml
@@ -0,0 +1,205 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+suite: test gravitino iceberg rest server httproute
+templates:
+ - httproute.yaml
+tests:
+ - it: does not render httproute by default
+ asserts:
+ - hasDocuments:
+ count: 0
+
+ - it: does not render httproute when type is the default ingress
+ set:
+ ingress:
+ enabled: true
+ type: ingress
+ asserts:
+ - hasDocuments:
+ count: 0
+
+ - it: renders a Gateway API HTTPRoute when type is gateway
+ release:
+ name: iceberg-rest
+ set:
+ ingress:
+ enabled: true
+ type: gateway
+ annotations:
+ example.com/route: "true"
+ hosts:
+ - host: iceberg-rest.example.com
+ paths:
+ - path: /iceberg
+ pathType: Prefix
+ - path: /exact
+ pathType: Exact
+ gateway:
+ parentRefs:
+ - name: external
+ namespace: gateway-system
+ sectionName: https
+ asserts:
+ - isAPIVersion:
+ of: gateway.networking.k8s.io/v1
+ - isKind:
+ of: HTTPRoute
+ - equal:
+ path: metadata.name
+ value: iceberg-rest-gravitino-iceberg-rest-server-helm
+ - equal:
+ path: metadata.annotations["example.com/route"]
+ value: "true"
+ - equal:
+ path: spec.parentRefs[0].name
+ value: external
+ - equal:
+ path: spec.parentRefs[0].namespace
+ value: gateway-system
+ - equal:
+ path: spec.parentRefs[0].sectionName
+ value: https
+ - contains:
+ path: spec.hostnames
+ content: iceberg-rest.example.com
+ - equal:
+ path: spec.rules[0].matches[0].path.type
+ value: PathPrefix
+ - equal:
+ path: spec.rules[0].matches[0].path.value
+ value: /iceberg
+ - equal:
+ path: spec.rules[1].matches[0].path.type
+ value: Exact
+ - equal:
+ path: spec.rules[1].matches[0].path.value
+ value: /exact
+ - equal:
+ path: spec.rules[0].backendRefs[0].name
+ value: iceberg-rest-gravitino-iceberg-rest-server-helm
+ - equal:
+ path: spec.rules[0].backendRefs[0].port
+ value: 9001
+
+ - it: maps ImplementationSpecific pathType to PathPrefix in gateway mode
+ set:
+ ingress:
+ enabled: true
+ type: gateway
+ hosts:
+ - host: iceberg-rest.example.com
+ paths:
+ - path: /
+ pathType: ImplementationSpecific
+ gateway:
+ parentRefs:
+ - name: external
+ asserts:
+ - equal:
+ path: spec.rules[0].matches[0].path.type
+ value: PathPrefix
+ - equal:
+ path: spec.rules[0].matches[0].path.value
+ value: /
+
+ - it: defaults pathType to PathPrefix when unset in gateway mode
+ set:
+ ingress:
+ enabled: true
+ type: gateway
+ hosts:
+ - host: iceberg-rest.example.com
+ paths:
+ - path: /api
+ gateway:
+ parentRefs:
+ - name: external
+ asserts:
+ - equal:
+ path: spec.rules[0].matches[0].path.type
+ value: PathPrefix
+
+ - it: fails rendering on an unsupported pathType in gateway mode
+ set:
+ ingress:
+ enabled: true
+ type: gateway
+ hosts:
+ - host: iceberg-rest.example.com
+ paths:
+ - path: /re
+ pathType: RegularExpression
+ gateway:
+ parentRefs:
+ - name: external
+ asserts:
+ - failedTemplate:
+ errorMessage: 'ingress.hosts[].paths[].pathType "RegularExpression"
is not supported when ingress.type is "gateway"; use Exact, Prefix, or
ImplementationSpecific'
+
+ - it: renders one HTTPRoute per host so paths stay scoped to their host
+ release:
+ name: iceberg-rest
+ set:
+ ingress:
+ enabled: true
+ type: gateway
+ hosts:
+ - host: a.example.com
+ paths:
+ - path: /a
+ pathType: Prefix
+ - host: b.example.com
+ paths:
+ - path: /b
+ pathType: Prefix
+ gateway:
+ parentRefs:
+ - name: external
+ asserts:
+ - hasDocuments:
+ count: 2
+ - equal:
+ path: metadata.name
+ value: iceberg-rest-gravitino-iceberg-rest-server-helm
+ documentIndex: 0
+ - contains:
+ path: spec.hostnames
+ content: a.example.com
+ documentIndex: 0
+ - notContains:
+ path: spec.hostnames
+ content: b.example.com
+ documentIndex: 0
+ - equal:
+ path: spec.rules[0].matches[0].path.value
+ value: /a
+ documentIndex: 0
+ - equal:
+ path: metadata.name
+ value: iceberg-rest-gravitino-iceberg-rest-server-helm-1
+ documentIndex: 1
+ - contains:
+ path: spec.hostnames
+ content: b.example.com
+ documentIndex: 1
+ - equal:
+ path: spec.rules[0].matches[0].path.value
+ value: /b
+ documentIndex: 1
diff --git a/dev/charts/gravitino-iceberg-rest-server/tests/ingress_test.yaml
b/dev/charts/gravitino-iceberg-rest-server/tests/ingress_test.yaml
index 6e091c7eba..09d9a91f5a 100644
--- a/dev/charts/gravitino-iceberg-rest-server/tests/ingress_test.yaml
+++ b/dev/charts/gravitino-iceberg-rest-server/tests/ingress_test.yaml
@@ -26,6 +26,15 @@ tests:
- hasDocuments:
count: 0
+ - it: does not render ingress when type is gateway
+ set:
+ ingress:
+ enabled: true
+ type: gateway
+ asserts:
+ - hasDocuments:
+ count: 0
+
- it: renders networking v1 ingress for supported Kubernetes versions
release:
name: iceberg-rest
diff --git a/dev/charts/gravitino-iceberg-rest-server/values.yaml
b/dev/charts/gravitino-iceberg-rest-server/values.yaml
index 6570d7d728..6e0df95823 100644
--- a/dev/charts/gravitino-iceberg-rest-server/values.yaml
+++ b/dev/charts/gravitino-iceberg-rest-server/values.yaml
@@ -323,6 +323,10 @@ extraVolumeMounts:
ingress:
enabled: false
+ # Resource type to render when ingress is enabled.
+ # "ingress" renders a Kubernetes Ingress (apiVersion selected by cluster
version; default, backward compatible).
+ # "gateway" renders a Gateway API gateway.networking.k8s.io HTTPRoute
instead.
+ type: ingress
className: "nginx"
annotations: {}
# kubernetes.io/ingress.class: nginx
@@ -339,6 +343,21 @@ ingress:
# - secretName: chart-gravitino-tls
# hosts:
# - chart-gravitino.local
+ # Gateway API (HTTPRoute) settings. Used only when type is "gateway".
+ # hosts (above) become the HTTPRoute hostnames and rule paths; annotations
are reused.
+ # In gateway mode each path's pathType is mapped to a Gateway API match type:
+ # Exact -> Exact
+ # Prefix -> PathPrefix
+ # ImplementationSpecific -> PathPrefix (Gateway API has no equivalent;
treated as a prefix match)
+ # Any other value fails template rendering (RegularExpression is not
supported).
+ gateway:
+ # Only gateway.networking.k8s.io/v1 (the GA version) is supported and
tested.
+ apiVersion: gateway.networking.k8s.io/v1
+ # Parent Gateway(s) this HTTPRoute attaches to.
+ parentRefs: []
+ # - name: gateway
+ # namespace: gateway-system
+ # sectionName: http
nodeSelector: {}
diff --git a/dev/charts/gravitino-lance-rest-server/templates/httproute.yaml
b/dev/charts/gravitino-lance-rest-server/templates/httproute.yaml
new file mode 100644
index 0000000000..92eac5279d
--- /dev/null
+++ b/dev/charts/gravitino-lance-rest-server/templates/httproute.yaml
@@ -0,0 +1,67 @@
+{{- /*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */}}
+
+{{- if and .Values.ingress.enabled (eq (.Values.ingress.type | default
"ingress") "gateway") -}}
+{{- $fullName := include "gravitino-lance-rest-server.fullname" . -}}
+{{- $svcPort := .Values.service.port -}}
+{{- $gateway := .Values.ingress.gateway | default dict -}}
+{{- $root := . -}}
+{{- /* Render one HTTPRoute per host so that, like the Ingress, each host only
+ matches its own paths (HTTPRoute hostnames apply to the whole resource).
*/}}
+{{- range $hostIndex, $hostEntry := .Values.ingress.hosts }}
+{{- if $hostIndex }}
+---
+{{- end }}
+apiVersion: {{ $gateway.apiVersion | default "gateway.networking.k8s.io/v1" }}
+kind: HTTPRoute
+metadata:
+ name: {{ $fullName }}{{ if $hostIndex }}-{{ $hostIndex }}{{ end }}
+ labels:
+ {{- include "gravitino-lance-rest-server.labels" $root | nindent 4 }}
+ {{- with $root.Values.ingress.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ {{- with $gateway.parentRefs }}
+ parentRefs:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ {{- if $hostEntry.host }}
+ hostnames:
+ - {{ $hostEntry.host | quote }}
+ {{- end }}
+ rules:
+ {{- range $hostEntry.paths }}
+ {{- $pathType := .pathType | default "Prefix" }}
+ {{- if or (eq $pathType "Prefix") (eq $pathType "PathPrefix") (eq
$pathType "ImplementationSpecific") }}
+ {{- $pathType = "PathPrefix" }}
+ {{- else if ne $pathType "Exact" }}
+ {{- fail (printf "ingress.hosts[].paths[].pathType %q is not supported
when ingress.type is \"gateway\"; use Exact, Prefix, or ImplementationSpecific"
$pathType) }}
+ {{- end }}
+ - matches:
+ - path:
+ type: {{ $pathType }}
+ value: {{ .path | quote }}
+ backendRefs:
+ - name: {{ $fullName }}
+ port: {{ $svcPort }}
+ {{- end }}
+{{- end }}
+{{- end }}
diff --git a/dev/charts/gravitino-lance-rest-server/templates/ingress.yaml
b/dev/charts/gravitino-lance-rest-server/templates/ingress.yaml
index b33c646256..cb6d1292fe 100644
--- a/dev/charts/gravitino-lance-rest-server/templates/ingress.yaml
+++ b/dev/charts/gravitino-lance-rest-server/templates/ingress.yaml
@@ -17,7 +17,7 @@
under the License.
*/}}
-{{- if .Values.ingress.enabled -}}
+{{- if and .Values.ingress.enabled (ne (.Values.ingress.type | default
"ingress") "gateway") -}}
{{- $fullName := include "gravitino-lance-rest-server.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0"
.Capabilities.KubeVersion.GitVersion)) }}
diff --git a/dev/charts/gravitino-lance-rest-server/tests/httproute_test.yaml
b/dev/charts/gravitino-lance-rest-server/tests/httproute_test.yaml
new file mode 100644
index 0000000000..f426aecb15
--- /dev/null
+++ b/dev/charts/gravitino-lance-rest-server/tests/httproute_test.yaml
@@ -0,0 +1,154 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+suite: test gravitino lance rest server httproute
+templates:
+ - httproute.yaml
+tests:
+ - it: does not render httproute by default
+ asserts:
+ - hasDocuments:
+ count: 0
+
+ - it: does not render httproute when type is the default ingress
+ set:
+ ingress:
+ enabled: true
+ type: ingress
+ asserts:
+ - hasDocuments:
+ count: 0
+
+ - it: renders a Gateway API HTTPRoute when type is gateway
+ release:
+ name: lance-rest
+ set:
+ ingress:
+ enabled: true
+ type: gateway
+ annotations:
+ example.com/route: "true"
+ hosts:
+ - host: lance-rest.example.com
+ paths:
+ - path: /lance
+ pathType: Prefix
+ - path: /exact
+ pathType: Exact
+ gateway:
+ parentRefs:
+ - name: external
+ namespace: gateway-system
+ sectionName: https
+ asserts:
+ - isAPIVersion:
+ of: gateway.networking.k8s.io/v1
+ - isKind:
+ of: HTTPRoute
+ - equal:
+ path: metadata.name
+ value: lance-rest-gravitino-lance-rest-server-helm
+ - equal:
+ path: metadata.annotations["example.com/route"]
+ value: "true"
+ - equal:
+ path: spec.parentRefs[0].name
+ value: external
+ - equal:
+ path: spec.parentRefs[0].namespace
+ value: gateway-system
+ - equal:
+ path: spec.parentRefs[0].sectionName
+ value: https
+ - contains:
+ path: spec.hostnames
+ content: lance-rest.example.com
+ - equal:
+ path: spec.rules[0].matches[0].path.type
+ value: PathPrefix
+ - equal:
+ path: spec.rules[0].matches[0].path.value
+ value: /lance
+ - equal:
+ path: spec.rules[1].matches[0].path.type
+ value: Exact
+ - equal:
+ path: spec.rules[1].matches[0].path.value
+ value: /exact
+ - equal:
+ path: spec.rules[0].backendRefs[0].name
+ value: lance-rest-gravitino-lance-rest-server-helm
+ - equal:
+ path: spec.rules[0].backendRefs[0].port
+ value: 9101
+
+ - it: maps ImplementationSpecific pathType to PathPrefix in gateway mode
+ set:
+ ingress:
+ enabled: true
+ type: gateway
+ hosts:
+ - host: lance-rest.example.com
+ paths:
+ - path: /
+ pathType: ImplementationSpecific
+ gateway:
+ parentRefs:
+ - name: external
+ asserts:
+ - equal:
+ path: spec.rules[0].matches[0].path.type
+ value: PathPrefix
+ - equal:
+ path: spec.rules[0].matches[0].path.value
+ value: /
+
+ - it: defaults pathType to PathPrefix when unset in gateway mode
+ set:
+ ingress:
+ enabled: true
+ type: gateway
+ hosts:
+ - host: lance-rest.example.com
+ paths:
+ - path: /api
+ gateway:
+ parentRefs:
+ - name: external
+ asserts:
+ - equal:
+ path: spec.rules[0].matches[0].path.type
+ value: PathPrefix
+
+ - it: fails rendering on an unsupported pathType in gateway mode
+ set:
+ ingress:
+ enabled: true
+ type: gateway
+ hosts:
+ - host: lance-rest.example.com
+ paths:
+ - path: /re
+ pathType: RegularExpression
+ gateway:
+ parentRefs:
+ - name: external
+ asserts:
+ - failedTemplate:
+ errorMessage: 'ingress.hosts[].paths[].pathType "RegularExpression"
is not supported when ingress.type is "gateway"; use Exact, Prefix, or
ImplementationSpecific'
diff --git a/dev/charts/gravitino-lance-rest-server/tests/ingress_test.yaml
b/dev/charts/gravitino-lance-rest-server/tests/ingress_test.yaml
index 6afcde56a9..672aaaa3a0 100644
--- a/dev/charts/gravitino-lance-rest-server/tests/ingress_test.yaml
+++ b/dev/charts/gravitino-lance-rest-server/tests/ingress_test.yaml
@@ -26,6 +26,15 @@ tests:
- hasDocuments:
count: 0
+ - it: does not render ingress when type is gateway
+ set:
+ ingress:
+ enabled: true
+ type: gateway
+ asserts:
+ - hasDocuments:
+ count: 0
+
- it: renders networking v1 ingress for supported Kubernetes versions
release:
name: lance-rest
diff --git a/dev/charts/gravitino-lance-rest-server/values.yaml
b/dev/charts/gravitino-lance-rest-server/values.yaml
index 2c254b349b..a097d52021 100644
--- a/dev/charts/gravitino-lance-rest-server/values.yaml
+++ b/dev/charts/gravitino-lance-rest-server/values.yaml
@@ -140,6 +140,10 @@ readinessProbe:
ingress:
enabled: false
+ # Resource type to render when ingress is enabled.
+ # "ingress" renders a Kubernetes Ingress (apiVersion selected by cluster
version; default, backward compatible).
+ # "gateway" renders a Gateway API gateway.networking.k8s.io HTTPRoute
instead.
+ type: ingress
className: "nginx"
annotations: {}
# kubernetes.io/ingress.class: nginx
@@ -153,6 +157,21 @@ ingress:
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
+ # Gateway API (HTTPRoute) settings. Used only when type is "gateway".
+ # hosts (above) become the HTTPRoute hostnames and rule paths; annotations
are reused.
+ # In gateway mode each path's pathType is mapped to a Gateway API match type:
+ # Exact -> Exact
+ # Prefix -> PathPrefix
+ # ImplementationSpecific -> PathPrefix (Gateway API has no equivalent;
treated as a prefix match)
+ # Any other value fails template rendering (RegularExpression is not
supported).
+ gateway:
+ # Only gateway.networking.k8s.io/v1 (the GA version) is supported and
tested.
+ apiVersion: gateway.networking.k8s.io/v1
+ # Parent Gateway(s) this HTTPRoute attaches to.
+ parentRefs: []
+ # - name: gateway
+ # namespace: gateway-system
+ # sectionName: http
## PodDisruptionBudget settings
podDisruptionBudget:
diff --git a/dev/charts/gravitino/templates/httproute.yaml
b/dev/charts/gravitino/templates/httproute.yaml
new file mode 100644
index 0000000000..ed79e5639a
--- /dev/null
+++ b/dev/charts/gravitino/templates/httproute.yaml
@@ -0,0 +1,67 @@
+{{- /*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */}}
+
+{{- if and .Values.ingress.enabled (eq (.Values.ingress.type | default
"ingress") "gateway") -}}
+{{- $fullName := include "gravitino.fullname" . -}}
+{{- $svcPort := .Values.service.port -}}
+{{- $gateway := .Values.ingress.gateway | default dict -}}
+{{- $root := . -}}
+{{- /* Render one HTTPRoute per host so that, like the Ingress, each host only
+ matches its own paths (HTTPRoute hostnames apply to the whole resource).
*/}}
+{{- range $hostIndex, $hostEntry := .Values.ingress.hosts }}
+{{- if $hostIndex }}
+---
+{{- end }}
+apiVersion: {{ $gateway.apiVersion | default "gateway.networking.k8s.io/v1" }}
+kind: HTTPRoute
+metadata:
+ name: {{ $fullName }}{{ if $hostIndex }}-{{ $hostIndex }}{{ end }}
+ labels:
+ {{- include "gravitino.labels" $root | nindent 4 }}
+ {{- with $root.Values.ingress.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ {{- with $gateway.parentRefs }}
+ parentRefs:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ {{- if $hostEntry.host }}
+ hostnames:
+ - {{ $hostEntry.host | quote }}
+ {{- end }}
+ rules:
+ {{- range $hostEntry.paths }}
+ {{- $pathType := .pathType | default "Prefix" }}
+ {{- if or (eq $pathType "Prefix") (eq $pathType "PathPrefix") (eq
$pathType "ImplementationSpecific") }}
+ {{- $pathType = "PathPrefix" }}
+ {{- else if ne $pathType "Exact" }}
+ {{- fail (printf "ingress.hosts[].paths[].pathType %q is not supported
when ingress.type is \"gateway\"; use Exact, Prefix, or ImplementationSpecific"
$pathType) }}
+ {{- end }}
+ - matches:
+ - path:
+ type: {{ $pathType }}
+ value: {{ .path | quote }}
+ backendRefs:
+ - name: {{ $fullName }}
+ port: {{ $svcPort }}
+ {{- end }}
+{{- end }}
+{{- end }}
diff --git a/dev/charts/gravitino/templates/ingress.yaml
b/dev/charts/gravitino/templates/ingress.yaml
index 64252ee814..f40947b3d0 100644
--- a/dev/charts/gravitino/templates/ingress.yaml
+++ b/dev/charts/gravitino/templates/ingress.yaml
@@ -6,7 +6,7 @@
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
@@ -17,7 +17,7 @@
under the License.
*/}}
- {{- if .Values.ingress.enabled -}}
+{{- if and .Values.ingress.enabled (ne (.Values.ingress.type | default
"ingress") "gateway") -}}
{{- $fullName := include "gravitino.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0"
.Capabilities.KubeVersion.GitVersion)) }}
diff --git a/dev/charts/gravitino/tests/httproute_test.yaml
b/dev/charts/gravitino/tests/httproute_test.yaml
new file mode 100644
index 0000000000..baadc31c80
--- /dev/null
+++ b/dev/charts/gravitino/tests/httproute_test.yaml
@@ -0,0 +1,154 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+suite: test gravitino httproute
+templates:
+ - httproute.yaml
+tests:
+ - it: does not render httproute by default
+ asserts:
+ - hasDocuments:
+ count: 0
+
+ - it: does not render httproute when type is the default ingress
+ set:
+ ingress:
+ enabled: true
+ type: ingress
+ asserts:
+ - hasDocuments:
+ count: 0
+
+ - it: renders a Gateway API HTTPRoute when type is gateway
+ release:
+ name: gravitino
+ set:
+ ingress:
+ enabled: true
+ type: gateway
+ annotations:
+ example.com/route: "true"
+ hosts:
+ - host: gravitino.example.com
+ paths:
+ - path: /gravitino
+ pathType: Prefix
+ - path: /exact
+ pathType: Exact
+ gateway:
+ parentRefs:
+ - name: external
+ namespace: gateway-system
+ sectionName: https
+ asserts:
+ - isAPIVersion:
+ of: gateway.networking.k8s.io/v1
+ - isKind:
+ of: HTTPRoute
+ - equal:
+ path: metadata.name
+ value: gravitino-gravitino-helm
+ - equal:
+ path: metadata.annotations["example.com/route"]
+ value: "true"
+ - equal:
+ path: spec.parentRefs[0].name
+ value: external
+ - equal:
+ path: spec.parentRefs[0].namespace
+ value: gateway-system
+ - equal:
+ path: spec.parentRefs[0].sectionName
+ value: https
+ - contains:
+ path: spec.hostnames
+ content: gravitino.example.com
+ - equal:
+ path: spec.rules[0].matches[0].path.type
+ value: PathPrefix
+ - equal:
+ path: spec.rules[0].matches[0].path.value
+ value: /gravitino
+ - equal:
+ path: spec.rules[1].matches[0].path.type
+ value: Exact
+ - equal:
+ path: spec.rules[1].matches[0].path.value
+ value: /exact
+ - equal:
+ path: spec.rules[0].backendRefs[0].name
+ value: gravitino-gravitino-helm
+ - equal:
+ path: spec.rules[0].backendRefs[0].port
+ value: 8090
+
+ - it: maps ImplementationSpecific pathType to PathPrefix in gateway mode
+ set:
+ ingress:
+ enabled: true
+ type: gateway
+ hosts:
+ - host: gravitino.example.com
+ paths:
+ - path: /
+ pathType: ImplementationSpecific
+ gateway:
+ parentRefs:
+ - name: external
+ asserts:
+ - equal:
+ path: spec.rules[0].matches[0].path.type
+ value: PathPrefix
+ - equal:
+ path: spec.rules[0].matches[0].path.value
+ value: /
+
+ - it: defaults pathType to PathPrefix when unset in gateway mode
+ set:
+ ingress:
+ enabled: true
+ type: gateway
+ hosts:
+ - host: gravitino.example.com
+ paths:
+ - path: /api
+ gateway:
+ parentRefs:
+ - name: external
+ asserts:
+ - equal:
+ path: spec.rules[0].matches[0].path.type
+ value: PathPrefix
+
+ - it: fails rendering on an unsupported pathType in gateway mode
+ set:
+ ingress:
+ enabled: true
+ type: gateway
+ hosts:
+ - host: gravitino.example.com
+ paths:
+ - path: /re
+ pathType: RegularExpression
+ gateway:
+ parentRefs:
+ - name: external
+ asserts:
+ - failedTemplate:
+ errorMessage: 'ingress.hosts[].paths[].pathType "RegularExpression"
is not supported when ingress.type is "gateway"; use Exact, Prefix, or
ImplementationSpecific'
diff --git a/dev/charts/gravitino/tests/ingress_test.yaml
b/dev/charts/gravitino/tests/ingress_test.yaml
index 6591cf535c..5c577877bc 100644
--- a/dev/charts/gravitino/tests/ingress_test.yaml
+++ b/dev/charts/gravitino/tests/ingress_test.yaml
@@ -26,6 +26,15 @@ tests:
- hasDocuments:
count: 0
+ - it: does not render ingress when type is gateway
+ set:
+ ingress:
+ enabled: true
+ type: gateway
+ asserts:
+ - hasDocuments:
+ count: 0
+
- it: renders networking v1 ingress for supported Kubernetes versions
release:
name: gravitino
diff --git a/dev/charts/gravitino/values.yaml b/dev/charts/gravitino/values.yaml
index fb14537b66..b2796bc09f 100644
--- a/dev/charts/gravitino/values.yaml
+++ b/dev/charts/gravitino/values.yaml
@@ -514,6 +514,10 @@ extraExposePorts:
ingress:
enabled: false
+ # Resource type to render when ingress is enabled.
+ # "ingress" renders a Kubernetes Ingress (apiVersion selected by cluster
version; default, backward compatible).
+ # "gateway" renders a Gateway API gateway.networking.k8s.io HTTPRoute
instead.
+ type: ingress
className: "nginx"
annotations: {}
# kubernetes.io/tls-acme: "true"
@@ -526,6 +530,21 @@ ingress:
# - secretName: chart-gravitino-tls
# hosts:
# - chart-gravitino.local
+ # Gateway API (HTTPRoute) settings. Used only when type is "gateway".
+ # hosts (above) become the HTTPRoute hostnames and rule paths; annotations
are reused.
+ # In gateway mode each path's pathType is mapped to a Gateway API match type:
+ # Exact -> Exact
+ # Prefix -> PathPrefix
+ # ImplementationSpecific -> PathPrefix (Gateway API has no equivalent;
treated as a prefix match)
+ # Any other value fails template rendering (RegularExpression is not
supported).
+ gateway:
+ # Only gateway.networking.k8s.io/v1 (the GA version) is supported and
tested.
+ apiVersion: gateway.networking.k8s.io/v1
+ # Parent Gateway(s) this HTTPRoute attaches to.
+ parentRefs: []
+ # - name: gateway
+ # namespace: gateway-system
+ # sectionName: http
## Deployment annotations
##