diff --git a/README.md b/README.md index 37f6354..bdfe5df 100644 --- a/README.md +++ b/README.md @@ -1026,6 +1026,19 @@ To comply with the Gitea helm chart definition of the digest parameter, a "custo | `ingress.hosts[0].paths[0].path` | Default Ingress path | `/` | | `ingress.tls` | Ingress tls settings | `[]` | +### Gateway + +| Name | Description | Value | +| --------------------------------------------- | ---------------------------------------------------------------- | --------------------- | +| `gateway.httpRoute.enabled` | Enable HTTPRoute | `false` | +| `gateway.httpRoute.annotations` | HTTPRoute annotations | `{}` | +| `gateway.httpRoute.hostnames` | HTTPRoute hostnames | `["git.example.com"]` | +| `gateway.httpRoute.parentRefs[0].name` | HTTPRoute Gateway name | `traefik` | +| `gateway.httpRoute.parentRefs[0].sectionName` | HTTPRoute Gateway section name | `https` | +| `gateway.httpRoute.parentRefs[0].kind` | HTTPRoute Gateway kind | `Gateway` | +| `gateway.httpRoute.pathType` | HTTPRoute path match type (PathPrefix, Exact, RegularExpression) | `PathPrefix` | +| `gateway.httpRoute.paths[0].path` | Default HTTPRoute path | `/` | + ### deployment | Name | Description | Value | diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index f993b95..5514c8b 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -471,3 +471,12 @@ https {{- define "gitea.metrics-secret-name" -}} {{ default (printf "%s-metrics-secret" (include "gitea.fullname" .)) }} {{- end -}} + +{{/* +Validate that Ingress and Gateway HTTPRoute are not enabled at the same time +*/}} +{{- define "gitea.validate-ingress-gateway-conflict" -}} +{{- if and ((.Values.ingress).enabled) (((.Values.gateway).httpRoute).enabled) -}} +{{- fail "You cannot enable both Ingress and HTTPRoute at the same time" -}} +{{- end -}} +{{- end -}} \ No newline at end of file diff --git a/templates/gitea/httproute.yaml b/templates/gitea/httproute.yaml new file mode 100644 index 0000000..993e83c --- /dev/null +++ b/templates/gitea/httproute.yaml @@ -0,0 +1,79 @@ +{{- include "gitea.validate-ingress-gateway-conflict" . }} +{{- if .Values.gateway.httpRoute.enabled -}} +{{- $fullName := include "gitea.fullname" . -}} +{{- $httpPort := .Values.service.http.port -}} +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: {{ $fullName }} + namespace: {{ .Values.namespace | default .Release.Namespace }} + labels: + {{- include "gitea.labels" . | nindent 4 }} + annotations: + {{- range $key, $value := .Values.gateway.httpRoute.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +spec: + hostnames: + {{- range .Values.gateway.httpRoute.hostnames }} + - {{ tpl . $ | quote }} + {{- end }} + parentRefs: + {{- range .Values.gateway.httpRoute.parentRefs }} + - name: {{ .name | quote }} + {{- if .namespace }} + namespace: {{ .namespace | quote }} + {{- end }} + {{- if .kind }} + kind: {{ .kind | quote }} + {{- end }} + {{- if .group }} + group: {{ .group | quote }} + {{- end }} + {{- if .sectionName }} + sectionName: {{ .sectionName | quote }} + {{- end }} + {{- if .port }} + port: {{ .port }} + {{- end }} + {{- end }} + rules: + {{- if .Values.gateway.httpRoute.paths }} + {{- range .Values.gateway.httpRoute.paths }} + {{- if kindIs "string" . }} + - matches: + - path: + type: {{ default "PathPrefix" $.Values.gateway.httpRoute.pathType }} + value: {{ . }} + backendRefs: + - group: "" + kind: Service + name: {{ $fullName }}-http + namespace: {{ $.Values.namespace | default $.Release.Namespace }} + port: {{ $httpPort }} + {{- else }} + - matches: + - path: + type: {{ .pathType | default "PathPrefix" }} + value: {{ .path | default "/" }} + backendRefs: + - group: "" + kind: Service + name: {{ $fullName }}-http + namespace: {{ $.Values.namespace | default $.Release.Namespace }} + port: {{ $httpPort }} + {{- end }} + {{- end }} + {{- else }} + - matches: + - path: + type: PathPrefix + value: "/" + backendRefs: + - group: "" + kind: Service + name: {{ $fullName }}-http + namespace: {{ .Values.namespace | default .Release.Namespace }} + port: {{ $httpPort }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/gitea/ingress.yaml b/templates/gitea/ingress.yaml index 9312ffb..0056b1e 100644 --- a/templates/gitea/ingress.yaml +++ b/templates/gitea/ingress.yaml @@ -1,3 +1,4 @@ +{{- include "gitea.validate-ingress-gateway-conflict" . }} {{- if .Values.ingress.enabled -}} {{- $fullName := include "gitea.fullname" . -}} {{- $httpPort := .Values.service.http.port -}} diff --git a/unittests/helm/httproute/basic.yaml b/unittests/helm/httproute/basic.yaml new file mode 100644 index 0000000..9daddd4 --- /dev/null +++ b/unittests/helm/httproute/basic.yaml @@ -0,0 +1,74 @@ +suite: Test httproute.yaml +templates: + - templates/gitea/httproute.yaml +tests: + - it: should enable httproute when gateway.httpRoute.enabled is true + set: + gateway.httpRoute.enabled: true + gateway.httpRoute.annotations: + some-annotation: some-value + gateway.httpRoute.hostnames: + - example.com + gateway.httpRoute.parentRefs: + - name: traefik + sectionName: https + kind: Gateway + gateway.httpRoute.paths: + - path: / + asserts: + - hasDocuments: + count: 1 + - isKind: + of: HTTPRoute + - isAPIVersion: + of: gateway.networking.k8s.io/v1 + - equal: + path: metadata.name + value: RELEASE-NAME-gitea + - equal: + path: metadata.annotations["some-annotation"] + value: some-value + - equal: + path: spec.hostnames[0] + value: "example.com" + - equal: + path: spec.parentRefs[0].name + value: "traefik" + - equal: + path: spec.parentRefs[0].kind + value: "Gateway" + - equal: + path: spec.parentRefs[0].sectionName + value: "https" + - equal: + path: spec.rules[0].matches[0].path.type + value: "PathPrefix" + - equal: + path: spec.rules[0].matches[0].path.value + value: "/" + - equal: + path: spec.rules[0].backendRefs[0].name + value: "RELEASE-NAME-gitea-http" + - equal: + path: spec.rules[0].backendRefs[0].port + value: 3000 + + - it: should not create httproute when gateway.httpRoute.enabled is false + set: + gateway.httpRoute.enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: hostname using TPL + set: + global.giteaHostName: "gitea.example.com" + gateway.httpRoute.enabled: true + gateway.httpRoute.hostnames: + - "{{ .Values.global.giteaHostName }}" + asserts: + - isKind: + of: HTTPRoute + - equal: + path: spec.hostnames[0] + value: "gitea.example.com" diff --git a/unittests/helm/httproute/implicit-defaults.yaml b/unittests/helm/httproute/implicit-defaults.yaml new file mode 100644 index 0000000..6bed4b6 --- /dev/null +++ b/unittests/helm/httproute/implicit-defaults.yaml @@ -0,0 +1,19 @@ +suite: Test httproute with implicit path defaults +templates: + - templates/gitea/httproute.yaml +tests: + - it: should use default path and pathType when no paths are specified + set: + gateway.httpRoute.enabled: true + gateway.httpRoute.paths: [] + asserts: + - hasDocuments: + count: 1 + - isKind: + of: HTTPRoute + - equal: + path: spec.rules[0].matches[0].path.type + value: "PathPrefix" + - equal: + path: spec.rules[0].matches[0].path.value + value: "/" diff --git a/unittests/helm/httproute/structured-paths.yaml b/unittests/helm/httproute/structured-paths.yaml new file mode 100644 index 0000000..9dbe600 --- /dev/null +++ b/unittests/helm/httproute/structured-paths.yaml @@ -0,0 +1,56 @@ +suite: Test httproute with structured paths +templates: + - templates/gitea/httproute.yaml +tests: + - it: should work with a plain string path + set: + gateway.httpRoute.enabled: true + gateway.httpRoute.paths: + - / + asserts: + - hasDocuments: + count: 1 + - isKind: + of: HTTPRoute + - equal: + path: spec.rules[0].matches[0].path.type + value: "PathPrefix" + - equal: + path: spec.rules[0].matches[0].path.value + value: "/" + + - it: should work with structured path definitions and per-path pathType + set: + gateway.httpRoute.enabled: true + gateway.httpRoute.paths: + - path: / + - path: /foo + pathType: Exact + asserts: + - hasDocuments: + count: 1 + - isKind: + of: HTTPRoute + - equal: + path: spec.rules[0].matches[0].path.type + value: "PathPrefix" + - equal: + path: spec.rules[0].matches[0].path.value + value: "/" + - equal: + path: spec.rules[1].matches[0].path.type + value: "Exact" + - equal: + path: spec.rules[1].matches[0].path.value + value: "/foo" + + - it: should allow overriding the default pathType + set: + gateway.httpRoute.enabled: true + gateway.httpRoute.pathType: Exact + gateway.httpRoute.paths: + - / + asserts: + - equal: + path: spec.rules[0].matches[0].path.type + value: "Exact" diff --git a/unittests/helm/values-conflicting-checks.yaml b/unittests/helm/values-conflicting-checks.yaml index a1ba969..a1dd94a 100644 --- a/unittests/helm/values-conflicting-checks.yaml +++ b/unittests/helm/values-conflicting-checks.yaml @@ -12,3 +12,14 @@ tests: asserts: - failedTemplate: errorMessage: valkey and valkey-cluster cannot be enabled at the same time. Please only choose one. + + - it: fails when trying to enable ingress and gateway httpRoute at the same time + set: + ingress: + enabled: true + gateway: + httpRoute: + enabled: true + asserts: + - failedTemplate: + errorMessage: You cannot enable both Ingress and HTTPRoute at the same time diff --git a/values.yaml b/values.yaml index 107e623..4f9560c 100644 --- a/values.yaml +++ b/values.yaml @@ -177,6 +177,30 @@ ingress: # hosts: # - git.example.com +## @section Gateway +## @param gateway.httpRoute.enabled Enable HTTPRoute +## @param gateway.httpRoute.annotations HTTPRoute annotations +## @param gateway.httpRoute.hostnames HTTPRoute hostnames +## @param gateway.httpRoute.parentRefs[0].name HTTPRoute Gateway name +## @param gateway.httpRoute.parentRefs[0].sectionName HTTPRoute Gateway section name +## @param gateway.httpRoute.parentRefs[0].kind HTTPRoute Gateway kind +## @param gateway.httpRoute.pathType HTTPRoute path match type (PathPrefix, Exact, RegularExpression) +## @param gateway.httpRoute.paths[0].path Default HTTPRoute path +gateway: + httpRoute: + enabled: false + annotations: {} + hostnames: + - git.example.com + parentRefs: + - name: traefik + sectionName: https + kind: Gateway + pathType: PathPrefix + paths: + - path: / + + ## @section deployment # ## @param resources Kubernetes resources