From a94eec4238be8bd5a4c502443205f4f581a7e17d Mon Sep 17 00:00:00 2001 From: pat-s Date: Fri, 16 May 2025 13:08:27 +0000 Subject: [PATCH] refactor: migrate ingress definition out of beta (#679) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Description of the change Redesigned ingress configuration to align better with implicit best practices. ### Benefits - Smarter defaults - More tests - Remove [deprecated API Versions](extensions/v1beta1) (e.g. `extensions/v1beta1`) and always use `networking.k8s.io/v1` ### Possible drawbacks Hopefully 🙃 none ### Applicable issues fix #674 ### Additional information - Define `ingress.annotations` via helpers - Move tests from `tests/deployment` to `tests/ingress` - Use own tests file for ingress tpl tests - Ensure defaults of `path` and `pathType` are always rendered - Set top-level default value for `ingress. pathType` - Change default of `ingress.hosts[0].paths` to `[]` to ensure proper rendering via template ### ⚠ BREAKING I think all of these changes should be backward comp with existing ingress definitions, but surely worth highlighting in the changelog of the release. ### Checklist - [x] Parameters are documented in the `values.yaml` and added to the `README.md` using [readme-generator-for-helm](https://github.com/bitnami-labs/readme-generator-for-helm) - [x] Breaking changes are documented in the `README.md` - [x] Templating unittests are added Co-authored-by: justusbunsi Co-authored-by: justusbunsi Reviewed-on: https://gitea.com/gitea/helm-gitea/pulls/679 Co-authored-by: pat-s Co-committed-by: pat-s --- README.md | 19 ++-- templates/_helpers.tpl | 14 ++- templates/gitea/ingress.yaml | 43 +++++---- .../deployment/ingress-configuration.yaml | 42 ++++----- unittests/helm/ingress/basic.yaml | 93 +++++++++++++++++++ unittests/helm/ingress/implicit-defaults.yaml | 23 +++++ unittests/helm/ingress/ingress.tpl.yaml | 45 +++++++++ unittests/helm/ingress/structured-paths.yaml | 26 ++++++ values.yaml | 18 +--- 9 files changed, 259 insertions(+), 64 deletions(-) create mode 100644 unittests/helm/ingress/basic.yaml create mode 100644 unittests/helm/ingress/implicit-defaults.yaml create mode 100644 unittests/helm/ingress/ingress.tpl.yaml create mode 100644 unittests/helm/ingress/structured-paths.yaml diff --git a/README.md b/README.md index c858f89..f85950f 100644 --- a/README.md +++ b/README.md @@ -990,16 +990,15 @@ To comply with the Gitea helm chart definition of the digest parameter, a "custo ### Ingress -| Name | Description | Value | -| ------------------------------------ | --------------------------------------------------------------------------- | ----------------- | -| `ingress.enabled` | Enable ingress | `false` | -| `ingress.className` | Ingress class name | `nil` | -| `ingress.annotations` | Ingress annotations | `{}` | -| `ingress.hosts[0].host` | Default Ingress host | `git.example.com` | -| `ingress.hosts[0].paths[0].path` | Default Ingress path | `/` | -| `ingress.hosts[0].paths[0].pathType` | Ingress path type | `Prefix` | -| `ingress.tls` | Ingress tls settings | `[]` | -| `ingress.apiVersion` | Specify APIVersion of ingress object. Mostly would only be used for argocd. | | +| Name | Description | Value | +| -------------------------------- | ------------------------------ | ----------------- | +| `ingress.enabled` | Enable ingress | `false` | +| `ingress.className` | DEPRECATED: Ingress class name | `""` | +| `ingress.pathType` | Ingress Path Type | `Prefix` | +| `ingress.annotations` | Ingress annotations | `{}` | +| `ingress.hosts[0].host` | Default Ingress host | `git.example.com` | +| `ingress.hosts[0].paths[0].path` | Default Ingress path | `/` | +| `ingress.tls` | Ingress tls settings | `[]` | ### deployment diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 01be3b9..ee9c92b 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -428,6 +428,18 @@ https {{ .Values.serviceAccount.name | default (include "gitea.fullname" .) }} {{- end -}} +{{- define "ingress.annotations" -}} + {{- if .Values.ingress.annotations }} + annotations: + {{- $tp := typeOf .Values.ingress.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.ingress.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.ingress.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + {{- define "gitea.admin.passwordMode" -}} {{- if has .Values.gitea.admin.passwordMode (tuple "keepUpdated" "initialOnlyNoReset" "initialOnlyRequireReset") -}} {{ .Values.gitea.admin.passwordMode }} @@ -456,4 +468,4 @@ https {{- define "gitea.metrics-secret-name" -}} {{ default (printf "%s-metrics-secret" (include "gitea.fullname" .)) }} -{{- end -}} \ No newline at end of file +{{- end -}} diff --git a/templates/gitea/ingress.yaml b/templates/gitea/ingress.yaml index dce7c90..f38b008 100644 --- a/templates/gitea/ingress.yaml +++ b/templates/gitea/ingress.yaml @@ -1,15 +1,7 @@ {{- if .Values.ingress.enabled -}} {{- $fullName := include "gitea.fullname" . -}} {{- $httpPort := .Values.service.http.port -}} -{{- $apiVersion := "extensions/v1beta1" -}} -{{- if .Values.ingress.apiVersion -}} -{{- $apiVersion = .Values.ingress.apiVersion -}} -{{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress" -}} -{{- $apiVersion = "networking.k8s.io/v1" }} -{{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress" -}} -{{- $apiVersion = "networking.k8s.io/v1beta1" }} -{{- end }} -apiVersion: {{ $apiVersion }} +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: {{ $fullName }} @@ -23,6 +15,8 @@ metadata: spec: {{- if .Values.ingress.className }} ingressClassName: {{ tpl .Values.ingress.className . }} +{{- else if .Values.ingress.ingressClassName }} + ingressClassName: {{ tpl .Values.ingress.ingressClassName . }} {{- end }} {{- if .Values.ingress.tls }} tls: @@ -39,21 +33,34 @@ spec: - host: {{ tpl .host $ | quote }} http: paths: + {{- if .paths }} {{- range .paths }} - - path: {{ .path }} - {{- if and .pathType (eq $apiVersion "networking.k8s.io/v1") }} - pathType: {{ .pathType }} - {{- end }} + {{- if kindIs "string" . }} + - path: {{ . }} + pathType: {{ default "Prefix" $.Values.ingress.pathType }} + backend: + service: + name: {{ $fullName }}-http + port: + number: {{ $httpPort }} + {{- else }} + - path: {{ .path | default "/" }} + pathType: {{ .pathType | default "Prefix" }} + backend: + service: + name: {{ $fullName }}-http + port: + number: {{ $httpPort }} + {{- end }} + {{- end }} + {{- else }} + - path: "/" + pathType: "Prefix" backend: - {{- if eq $apiVersion "networking.k8s.io/v1" }} service: name: {{ $fullName }}-http port: number: {{ $httpPort }} - {{- else }} - serviceName: {{ $fullName }}-http - servicePort: {{ $httpPort }} - {{- end }} {{- end }} {{- end }} {{- end }} diff --git a/unittests/helm/deployment/ingress-configuration.yaml b/unittests/helm/deployment/ingress-configuration.yaml index a6998ee..5136c1c 100644 --- a/unittests/helm/deployment/ingress-configuration.yaml +++ b/unittests/helm/deployment/ingress-configuration.yaml @@ -1,28 +1,7 @@ -suite: ingress template -release: - name: gitea-unittests - namespace: testing +suite: Test ingress tpl use templates: - templates/gitea/ingress.yaml tests: - - it: hostname using TPL - set: - global.giteaHostName: "gitea.example.com" - ingress.enabled: true - ingress.hosts[0].host: "{{ .Values.global.giteaHostName }}" - ingress.tls: - - secretName: gitea-tls - hosts: - - "{{ .Values.global.giteaHostName }}" - asserts: - - isKind: - of: Ingress - - equal: - path: spec.tls[0].hosts[0] - value: "gitea.example.com" - - equal: - path: spec.rules[0].host - value: "gitea.example.com" - it: Ingress Class using TPL set: global.ingress.className: "ingress-class" @@ -45,3 +24,22 @@ tests: - equal: path: spec.ingressClassName value: "ingress-class" + + - it: hostname using TPL + set: + global.giteaHostName: "gitea.example.com" + ingress.enabled: true + ingress.hosts[0].host: "{{ .Values.global.giteaHostName }}" + ingress.tls: + - secretName: gitea-tls + hosts: + - "{{ .Values.global.giteaHostName }}" + asserts: + - isKind: + of: Ingress + - equal: + path: spec.tls[0].hosts[0] + value: "gitea.example.com" + - equal: + path: spec.rules[0].host + value: "gitea.example.com" diff --git a/unittests/helm/ingress/basic.yaml b/unittests/helm/ingress/basic.yaml new file mode 100644 index 0000000..8cf3d87 --- /dev/null +++ b/unittests/helm/ingress/basic.yaml @@ -0,0 +1,93 @@ +suite: Test ingress.yaml +templates: + - templates/gitea/ingress.yaml +tests: + - it: should enable ingress when ingress.enabled is true + set: + ingress.enabled: true + ingress.apiVersion: networking.k8s.io/v1 + ingress.annotations: + kubernetes.io/ingress.class: nginx + ingress.className: nginx + ingress.tls: + - hosts: + - example.com + secretName: tls-secret + ingress.hosts: + - host: example.com + paths: ["/"] + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Ingress + - equal: + path: metadata.name + value: RELEASE-NAME-gitea + - matchRegex: + path: apiVersion + pattern: networking.k8s.io/v1 + - equal: + path: spec.ingressClassName + value: nginx + - equal: + path: spec.rules[0].host + value: "example.com" + - equal: + path: spec.tls[0].hosts[0] + value: "example.com" + - equal: + path: spec.tls[0].secretName + value: tls-secret + - equal: + path: metadata.annotations["kubernetes.io/ingress.class"] + value: nginx + + - it: should not create ingress when ingress.enabled is false + set: + ingress.enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: Ingress Class using TPL + set: + global.ingress.className: "ingress-class" + ingress.ingressClassName: "{{ .Values.global.ingress.className }}" + ingress.enabled: true + ingress.hosts[0].host: "some-host" + ingress.tls: + - secretName: gitea-tls + hosts: + - "some-host" + asserts: + - isKind: + of: Ingress + - equal: + path: spec.tls[0].hosts[0] + value: "some-host" + - equal: + path: spec.rules[0].host + value: "some-host" + - equal: + path: spec.ingressClassName + value: "ingress-class" + + - it: hostname using TPL + set: + global.giteaHostName: "gitea.example.com" + ingress.enabled: true + ingress.hosts[0].host: "{{ .Values.global.giteaHostName }}" + ingress.tls: + - secretName: gitea-tls + hosts: + - "{{ .Values.global.giteaHostName }}" + asserts: + - isKind: + of: Ingress + - equal: + path: spec.tls[0].hosts[0] + value: "gitea.example.com" + - equal: + path: spec.rules[0].host + value: "gitea.example.com" diff --git a/unittests/helm/ingress/implicit-defaults.yaml b/unittests/helm/ingress/implicit-defaults.yaml new file mode 100644 index 0000000..2337286 --- /dev/null +++ b/unittests/helm/ingress/implicit-defaults.yaml @@ -0,0 +1,23 @@ +suite: Test ingress with implicit path defaults +templates: + - templates/gitea/ingress.yaml +tests: + - it: should use default path and pathType when no paths are specified + set: + ingress.enabled: true + ingress.hosts: + - host: git.example.com + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Ingress + - equal: + path: spec.rules[0].host + value: "git.example.com" + - equal: + path: spec.rules[0].http.paths[0].path + value: "/" + - equal: + path: spec.rules[0].http.paths[0].pathType + value: "Prefix" diff --git a/unittests/helm/ingress/ingress.tpl.yaml b/unittests/helm/ingress/ingress.tpl.yaml new file mode 100644 index 0000000..5136c1c --- /dev/null +++ b/unittests/helm/ingress/ingress.tpl.yaml @@ -0,0 +1,45 @@ +suite: Test ingress tpl use +templates: + - templates/gitea/ingress.yaml +tests: + - it: Ingress Class using TPL + set: + global.ingress.className: "ingress-class" + ingress.className: "{{ .Values.global.ingress.className }}" + ingress.enabled: true + ingress.hosts[0].host: "some-host" + ingress.tls: + - secretName: gitea-tls + hosts: + - "some-host" + asserts: + - isKind: + of: Ingress + - equal: + path: spec.tls[0].hosts[0] + value: "some-host" + - equal: + path: spec.rules[0].host + value: "some-host" + - equal: + path: spec.ingressClassName + value: "ingress-class" + + - it: hostname using TPL + set: + global.giteaHostName: "gitea.example.com" + ingress.enabled: true + ingress.hosts[0].host: "{{ .Values.global.giteaHostName }}" + ingress.tls: + - secretName: gitea-tls + hosts: + - "{{ .Values.global.giteaHostName }}" + asserts: + - isKind: + of: Ingress + - equal: + path: spec.tls[0].hosts[0] + value: "gitea.example.com" + - equal: + path: spec.rules[0].host + value: "gitea.example.com" diff --git a/unittests/helm/ingress/structured-paths.yaml b/unittests/helm/ingress/structured-paths.yaml new file mode 100644 index 0000000..3183ac7 --- /dev/null +++ b/unittests/helm/ingress/structured-paths.yaml @@ -0,0 +1,26 @@ +suite: Test ingress with structured paths +templates: + - templates/gitea/ingress.yaml +tests: + - it: should work with structured path definitions + set: + ingress.enabled: true + ingress.hosts: + - host: git.devxy.io + paths: + - path: / + pathType: Prefix + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Ingress + - equal: + path: spec.rules[0].host + value: "git.devxy.io" + - equal: + path: spec.rules[0].http.paths[0].path + value: "/" + - equal: + path: spec.rules[0].http.paths[0].pathType + value: "Prefix" diff --git a/values.yaml b/values.yaml index 0218ddb..edb8b8e 100644 --- a/values.yaml +++ b/values.yaml @@ -157,33 +157,25 @@ service: ## @section Ingress ## @param ingress.enabled Enable ingress -## @param ingress.className Ingress class name +## @param ingress.className DEPRECATED: Ingress class name +## @param ingress.pathType Ingress Path Type ## @param ingress.annotations Ingress annotations ## @param ingress.hosts[0].host Default Ingress host ## @param ingress.hosts[0].paths[0].path Default Ingress path -## @param ingress.hosts[0].paths[0].pathType Ingress path type ## @param ingress.tls Ingress tls settings -## @extra ingress.apiVersion Specify APIVersion of ingress object. Mostly would only be used for argocd. ingress: enabled: false - # className: nginx - className: - annotations: - {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" + className: "" + pathType: Prefix + annotations: {} hosts: - host: git.example.com paths: - path: / - pathType: Prefix tls: [] # - secretName: chart-example-tls # hosts: # - git.example.com - # Mostly for argocd or any other CI that uses `helm template | kubectl apply` or similar - # If helm doesn't correctly detect your ingress API version you can set it here. - # apiVersion: networking.k8s.io/v1 ## @section deployment #