feat: add Gateway API support (#1073)
Add full Gateway API support for exposing Gitea via HTTPRoute, TCPRoute, BackendTLSPolicy, and ClientSettingsPolicy resources. New templates: - `httpRoute.yaml` — renders an HTTPRoute with configurable parentRefs, hostnames, and rules (defaults to PathPrefix `/`) - `tcpRoute.yaml` — renders a TCPRoute for SSH traffic - `backendTLSPolicy.yaml` — renders a BackendTLSPolicy for encrypted backend connections with required validation config - `clientSettingsPolicy.yaml` — renders an NGINX Gateway Fabric ClientSettingsPolicy to raise the request body size limit Infrastructure: - `gatewayAPI.enabled` global toggle gates all resources - Resources grouped under `gatewayAPI.core.*` and `gatewayAPI.nginx.*` - Helper templates extracted into dedicated `_*.tpl` files - Service name helpers (`gitea.service.http.name`, `gitea.service.ssh.name`) extracted into `_services.tpl`; service templates renamed to camelCase - `ROOT_URL`, `DOMAIN`, and `SSH_DOMAIN` auto-resolve from `httpRoute.hostnames[0]`; `httpRoute.tls` switches to `https` Documentation: - New `docs/gateway-api.md` with topology examples, BackendTLSPolicy setup, sectionName guidance, SSH considerations, and NGINX body size limit configuration - `.github/copilot-instructions.md` with project conventions - README parameter table auto-generated via `make readme` Tests: - Helm unit tests for all four new resource templates - Config tests for hostname/TLS resolution from Gateway API values Co-authored-by: Todd Marimon <toddmarimon@gmail.com>
This commit is contained in:
committed by
Markus Pesch
parent
5005037dbf
commit
7747a001f7
@@ -103,3 +103,56 @@ tests:
|
||||
matchRegex:
|
||||
path: stringData.server
|
||||
pattern: \nROOT_URL=https://route.example.com
|
||||
|
||||
################################################
|
||||
|
||||
- it: "[HTTPRoute enabled] uses first hostname for DOMAIN|SSH_DOMAIN|ROOT_URL"
|
||||
template: templates/gitea/config.yaml
|
||||
set:
|
||||
ingress:
|
||||
hosts: []
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
core:
|
||||
httpRoute:
|
||||
enabled: true
|
||||
hostnames:
|
||||
- gw.example.com
|
||||
parentRefs:
|
||||
- name: shared-gateway
|
||||
asserts:
|
||||
- documentIndex: 0
|
||||
matchRegex:
|
||||
path: stringData.server
|
||||
pattern: \nDOMAIN=gw.example.com
|
||||
- documentIndex: 0
|
||||
matchRegex:
|
||||
path: stringData.server
|
||||
pattern: \nSSH_DOMAIN=gw.example.com
|
||||
- documentIndex: 0
|
||||
matchRegex:
|
||||
path: stringData.server
|
||||
pattern: \nROOT_URL=http://gw.example.com
|
||||
|
||||
################################################
|
||||
|
||||
- it: "[HTTPRoute tls] switches ROOT_URL to https"
|
||||
template: templates/gitea/config.yaml
|
||||
set:
|
||||
ingress:
|
||||
hosts: []
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
core:
|
||||
httpRoute:
|
||||
enabled: true
|
||||
tls: true
|
||||
hostnames:
|
||||
- gw.example.com
|
||||
parentRefs:
|
||||
- name: shared-gateway
|
||||
asserts:
|
||||
- documentIndex: 0
|
||||
matchRegex:
|
||||
path: stringData.server
|
||||
pattern: \nROOT_URL=https://gw.example.com
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
suite: ssh-svc / http-svc template (Services configuration)
|
||||
suite: sshService / httpService template (Services configuration)
|
||||
release:
|
||||
name: gitea-unittests
|
||||
namespace: testing
|
||||
templates:
|
||||
- templates/gitea/ssh-svc.yaml
|
||||
- templates/gitea/http-svc.yaml
|
||||
- templates/gitea/sshService.yaml
|
||||
- templates/gitea/httpService.yaml
|
||||
tests:
|
||||
- it: supports adding custom labels to ssh-svc
|
||||
template: templates/gitea/ssh-svc.yaml
|
||||
- it: supports adding custom labels to sshService
|
||||
template: templates/gitea/sshService.yaml
|
||||
set:
|
||||
service:
|
||||
ssh:
|
||||
@@ -19,7 +19,7 @@ tests:
|
||||
value: "testvalue"
|
||||
|
||||
- it: keeps existing labels (ssh)
|
||||
template: templates/gitea/ssh-svc.yaml
|
||||
template: templates/gitea/sshService.yaml
|
||||
set:
|
||||
service:
|
||||
ssh:
|
||||
@@ -28,8 +28,8 @@ tests:
|
||||
- exists:
|
||||
path: metadata.labels["app"]
|
||||
|
||||
- it: supports adding custom labels to http-svc
|
||||
template: templates/gitea/http-svc.yaml
|
||||
- it: supports adding custom labels to httpService
|
||||
template: templates/gitea/httpService.yaml
|
||||
set:
|
||||
service:
|
||||
http:
|
||||
@@ -41,7 +41,7 @@ tests:
|
||||
value: "testvalue"
|
||||
|
||||
- it: keeps existing labels (http)
|
||||
template: templates/gitea/http-svc.yaml
|
||||
template: templates/gitea/httpService.yaml
|
||||
set:
|
||||
service:
|
||||
http:
|
||||
@@ -51,7 +51,7 @@ tests:
|
||||
path: metadata.labels["app"]
|
||||
|
||||
- it: render service.ssh.loadBalancerClass if set and type is LoadBalancer
|
||||
template: templates/gitea/ssh-svc.yaml
|
||||
template: templates/gitea/sshService.yaml
|
||||
set:
|
||||
service:
|
||||
ssh:
|
||||
@@ -73,7 +73,7 @@ tests:
|
||||
value: ["1.2.3.4/32", "5.6.7.8/32"]
|
||||
|
||||
- it: does not render when loadbalancer properties are set but type is not loadBalancerClass
|
||||
template: templates/gitea/http-svc.yaml
|
||||
template: templates/gitea/httpService.yaml
|
||||
set:
|
||||
service:
|
||||
http:
|
||||
@@ -92,7 +92,7 @@ tests:
|
||||
path: spec.loadBalancerSourceRanges
|
||||
|
||||
- it: does not render loadBalancerClass by default even when type is LoadBalancer
|
||||
template: templates/gitea/http-svc.yaml
|
||||
template: templates/gitea/httpService.yaml
|
||||
set:
|
||||
service:
|
||||
http:
|
||||
@@ -107,8 +107,8 @@ tests:
|
||||
|
||||
- it: both ssh and http services exist
|
||||
templates:
|
||||
- templates/gitea/ssh-svc.yaml
|
||||
- templates/gitea/http-svc.yaml
|
||||
- templates/gitea/sshService.yaml
|
||||
- templates/gitea/httpService.yaml
|
||||
asserts:
|
||||
- matchRegex:
|
||||
path: metadata.name
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
suite: Test Gateway API backendTLSPolicy.yaml
|
||||
release:
|
||||
name: gitea-unittests
|
||||
namespace: testing
|
||||
templates:
|
||||
- templates/gitea/backendTLSPolicy.yaml
|
||||
tests:
|
||||
- it: should not render when gatewayAPI.enabled is false
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: false
|
||||
core:
|
||||
backendTLSPolicy:
|
||||
enabled: true
|
||||
validation:
|
||||
hostname: git.internal
|
||||
caCertificateRefs:
|
||||
- name: gitea-ca
|
||||
group: ""
|
||||
kind: ConfigMap
|
||||
asserts:
|
||||
- hasDocuments:
|
||||
count: 0
|
||||
|
||||
- it: should not render when backendTLSPolicy.enabled is false
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
gatewayAPI.core.backendTLSPolicy.enabled: false
|
||||
asserts:
|
||||
- hasDocuments:
|
||||
count: 0
|
||||
|
||||
- it: should render a BackendTLSPolicy targeting the http Service by default
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
core:
|
||||
backendTLSPolicy:
|
||||
enabled: true
|
||||
validation:
|
||||
hostname: git.internal
|
||||
caCertificateRefs:
|
||||
- name: gitea-ca
|
||||
group: ""
|
||||
kind: ConfigMap
|
||||
asserts:
|
||||
- hasDocuments:
|
||||
count: 1
|
||||
- isKind:
|
||||
of: BackendTLSPolicy
|
||||
- equal:
|
||||
path: apiVersion
|
||||
value: gateway.networking.k8s.io/v1
|
||||
- equal:
|
||||
path: metadata.name
|
||||
value: gitea-unittests
|
||||
- equal:
|
||||
path: spec.targetRefs[0].name
|
||||
value: gitea-unittests-http
|
||||
- equal:
|
||||
path: spec.targetRefs[0].kind
|
||||
value: Service
|
||||
- equal:
|
||||
path: spec.validation.hostname
|
||||
value: git.internal
|
||||
|
||||
- it: should fail when validation is missing
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
core:
|
||||
backendTLSPolicy:
|
||||
enabled: true
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorMessage: gatewayAPI.core.backendTLSPolicy.validation is required
|
||||
|
||||
- it: should fail when validation is an empty dict
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
core:
|
||||
backendTLSPolicy:
|
||||
enabled: true
|
||||
validation: {}
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorMessage: gatewayAPI.core.backendTLSPolicy.validation is required
|
||||
@@ -0,0 +1,105 @@
|
||||
suite: Test Gateway API clientSettingsPolicy.yaml
|
||||
release:
|
||||
name: gitea-unittests
|
||||
namespace: testing
|
||||
templates:
|
||||
- templates/gitea/clientSettingsPolicy.yaml
|
||||
tests:
|
||||
- it: should not render when gatewayAPI.enabled is false
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: false
|
||||
nginx:
|
||||
clientSettingsPolicies:
|
||||
enabled: true
|
||||
body:
|
||||
maxSize: 100m
|
||||
asserts:
|
||||
- hasDocuments:
|
||||
count: 0
|
||||
|
||||
- it: should not render when clientSettingsPolicies.enabled is false
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
gatewayAPI.nginx.clientSettingsPolicies.enabled: false
|
||||
asserts:
|
||||
- hasDocuments:
|
||||
count: 0
|
||||
|
||||
- it: should render a ClientSettingsPolicy targeting the HTTPRoute by default
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
nginx:
|
||||
clientSettingsPolicies:
|
||||
enabled: true
|
||||
body:
|
||||
maxSize: 100m
|
||||
asserts:
|
||||
- hasDocuments:
|
||||
count: 1
|
||||
- isKind:
|
||||
of: ClientSettingsPolicy
|
||||
- equal:
|
||||
path: apiVersion
|
||||
value: gateway.nginx.org/v1alpha1
|
||||
- equal:
|
||||
path: metadata.name
|
||||
value: gitea-unittests
|
||||
- equal:
|
||||
path: spec.targetRef.group
|
||||
value: gateway.networking.k8s.io
|
||||
- equal:
|
||||
path: spec.targetRef.kind
|
||||
value: HTTPRoute
|
||||
- equal:
|
||||
path: spec.targetRef.name
|
||||
value: gitea-unittests
|
||||
- equal:
|
||||
path: spec.body.maxSize
|
||||
value: 100m
|
||||
|
||||
- it: should honor a custom targetRef
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
nginx:
|
||||
clientSettingsPolicies:
|
||||
enabled: true
|
||||
targetRef:
|
||||
group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
name: shared-gateway
|
||||
body:
|
||||
maxSize: 100m
|
||||
asserts:
|
||||
- equal:
|
||||
path: spec.targetRef.kind
|
||||
value: Gateway
|
||||
- equal:
|
||||
path: spec.targetRef.name
|
||||
value: shared-gateway
|
||||
|
||||
- it: should fail when body is missing
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
nginx:
|
||||
clientSettingsPolicies:
|
||||
enabled: true
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorMessage: gatewayAPI.nginx.clientSettingsPolicies.body is required
|
||||
|
||||
- it: should fail when body is an empty dict
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
nginx:
|
||||
clientSettingsPolicies:
|
||||
enabled: true
|
||||
body: {}
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorMessage: gatewayAPI.nginx.clientSettingsPolicies.body is required
|
||||
@@ -0,0 +1,117 @@
|
||||
suite: Test Gateway API httpRoute.yaml
|
||||
release:
|
||||
name: gitea-unittests
|
||||
namespace: testing
|
||||
templates:
|
||||
- templates/gitea/httpRoute.yaml
|
||||
tests:
|
||||
- it: should not render when gatewayAPI.enabled is false
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: false
|
||||
core:
|
||||
httpRoute:
|
||||
enabled: true
|
||||
hostnames:
|
||||
- git.example.com
|
||||
parentRefs:
|
||||
- name: shared-gateway
|
||||
asserts:
|
||||
- hasDocuments:
|
||||
count: 0
|
||||
|
||||
- it: should not render when httpRoute.enabled is false
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
gatewayAPI.core.httpRoute.enabled: false
|
||||
asserts:
|
||||
- hasDocuments:
|
||||
count: 0
|
||||
|
||||
- it: should render a single HTTPRoute with default rule
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
core:
|
||||
httpRoute:
|
||||
enabled: true
|
||||
annotations:
|
||||
example.io/owner: gitea
|
||||
hostnames:
|
||||
- git.example.com
|
||||
parentRefs:
|
||||
- name: shared-gateway
|
||||
namespace: gateway-system
|
||||
asserts:
|
||||
- hasDocuments:
|
||||
count: 1
|
||||
- isKind:
|
||||
of: HTTPRoute
|
||||
- equal:
|
||||
path: apiVersion
|
||||
value: gateway.networking.k8s.io/v1
|
||||
- equal:
|
||||
path: metadata.name
|
||||
value: gitea-unittests
|
||||
- equal:
|
||||
path: metadata.annotations["example.io/owner"]
|
||||
value: gitea
|
||||
- equal:
|
||||
path: spec.parentRefs[0].name
|
||||
value: shared-gateway
|
||||
- equal:
|
||||
path: spec.parentRefs[0].namespace
|
||||
value: gateway-system
|
||||
- equal:
|
||||
path: spec.hostnames[0]
|
||||
value: git.example.com
|
||||
- equal:
|
||||
path: spec.rules[0].matches[0].path.value
|
||||
value: /
|
||||
- equal:
|
||||
path: spec.rules[0].backendRefs[0].group
|
||||
value: ""
|
||||
- equal:
|
||||
path: spec.rules[0].backendRefs[0].kind
|
||||
value: Service
|
||||
- equal:
|
||||
path: spec.rules[0].backendRefs[0].name
|
||||
value: gitea-unittests-http
|
||||
- equal:
|
||||
path: spec.rules[0].backendRefs[0].port
|
||||
value: 3000
|
||||
- equal:
|
||||
path: spec.rules[0].backendRefs[0].weight
|
||||
value: 1
|
||||
|
||||
- it: should fail when parentRefs missing
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
core:
|
||||
httpRoute:
|
||||
enabled: true
|
||||
hostnames:
|
||||
- git.example.com
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorMessage: gatewayAPI.core.httpRoute.parentRefs is required
|
||||
|
||||
- it: hostname tpl rendering
|
||||
set:
|
||||
global:
|
||||
giteaHostName: gitea.tpl.example.com
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
core:
|
||||
httpRoute:
|
||||
enabled: true
|
||||
hostnames:
|
||||
- "{{ .Values.global.giteaHostName }}"
|
||||
parentRefs:
|
||||
- name: gw
|
||||
asserts:
|
||||
- equal:
|
||||
path: spec.hostnames[0]
|
||||
value: gitea.tpl.example.com
|
||||
@@ -0,0 +1,79 @@
|
||||
suite: Test Gateway API tcpRoute.yaml
|
||||
release:
|
||||
name: gitea-unittests
|
||||
namespace: testing
|
||||
templates:
|
||||
- templates/gitea/tcpRoute.yaml
|
||||
tests:
|
||||
- it: should not render when gatewayAPI.enabled is false
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: false
|
||||
core:
|
||||
tcpRoute:
|
||||
enabled: true
|
||||
parentRefs:
|
||||
- name: shared-gateway
|
||||
asserts:
|
||||
- hasDocuments:
|
||||
count: 0
|
||||
|
||||
- it: should not render when tcpRoute.enabled is false
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
gatewayAPI.core.tcpRoute.enabled: false
|
||||
asserts:
|
||||
- hasDocuments:
|
||||
count: 0
|
||||
|
||||
- it: should render a TCPRoute defaulting to the SSH service
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
core:
|
||||
tcpRoute:
|
||||
enabled: true
|
||||
parentRefs:
|
||||
- name: shared-gateway
|
||||
sectionName: ssh
|
||||
asserts:
|
||||
- hasDocuments:
|
||||
count: 1
|
||||
- isKind:
|
||||
of: TCPRoute
|
||||
- equal:
|
||||
path: apiVersion
|
||||
value: gateway.networking.k8s.io/v1alpha2
|
||||
- equal:
|
||||
path: metadata.name
|
||||
value: gitea-unittests
|
||||
- equal:
|
||||
path: spec.parentRefs[0].sectionName
|
||||
value: ssh
|
||||
- equal:
|
||||
path: spec.rules[0].backendRefs[0].group
|
||||
value: ""
|
||||
- equal:
|
||||
path: spec.rules[0].backendRefs[0].kind
|
||||
value: Service
|
||||
- equal:
|
||||
path: spec.rules[0].backendRefs[0].name
|
||||
value: gitea-unittests-ssh
|
||||
- equal:
|
||||
path: spec.rules[0].backendRefs[0].port
|
||||
value: 22
|
||||
- equal:
|
||||
path: spec.rules[0].backendRefs[0].weight
|
||||
value: 1
|
||||
|
||||
- it: should fail when parentRefs missing
|
||||
set:
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
core:
|
||||
tcpRoute:
|
||||
enabled: true
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorMessage: gatewayAPI.core.tcpRoute.parentRefs is required
|
||||
Reference in New Issue
Block a user