From 56a0968675d8ed2599bf9ae96c82b0a64f4dbb3d Mon Sep 17 00:00:00 2001 From: Marco Ebert Date: Sun, 17 Mar 2024 22:27:27 +0100 Subject: [PATCH] Chart: Add IngressClass aliases. (#11109) --- charts/ingress-nginx/README.md | 3 +- .../controller-ingressclass-aliases.yaml | 20 ++++ .../controller-ingressclass-aliases_test.yaml | 92 +++++++++++++++++++ charts/ingress-nginx/values.yaml | 7 ++ 4 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 charts/ingress-nginx/templates/controller-ingressclass-aliases.yaml create mode 100644 charts/ingress-nginx/tests/controller-ingressclass-aliases_test.yaml diff --git a/charts/ingress-nginx/README.md b/charts/ingress-nginx/README.md index faab94c2dc2..1f912ea09ef 100644 --- a/charts/ingress-nginx/README.md +++ b/charts/ingress-nginx/README.md @@ -330,7 +330,8 @@ As of version `1.26.0` of this chart, by simply not providing any clusterIP valu | controller.image.tag | string | `"v1.10.0"` | | | controller.ingressClass | string | `"nginx"` | For backwards compatibility with ingress.class annotation, use ingressClass. Algorithm is as follows, first ingressClassName is considered, if not present, controller looks for ingress.class annotation | | controller.ingressClassByName | bool | `false` | Process IngressClass per name (additionally as per spec.controller). | -| controller.ingressClassResource | object | `{"controllerValue":"k8s.io/ingress-nginx","default":false,"enabled":true,"name":"nginx","parameters":{}}` | This section refers to the creation of the IngressClass resource. IngressClasses are immutable and cannot be changed after creation. We do not support namespaced IngressClasses, yet, so a ClusterRole and a ClusterRoleBinding is required. | +| controller.ingressClassResource | object | `{"aliases":[],"controllerValue":"k8s.io/ingress-nginx","default":false,"enabled":true,"name":"nginx","parameters":{}}` | This section refers to the creation of the IngressClass resource. IngressClasses are immutable and cannot be changed after creation. We do not support namespaced IngressClasses, yet, so a ClusterRole and a ClusterRoleBinding is required. | +| controller.ingressClassResource.aliases | list | `[]` | Aliases of this IngressClass. Creates copies with identical settings but the respective alias as name. Useful for development environments with only one Ingress Controller but production-like Ingress resources. `default` gets enabled on the original IngressClass only. | | controller.ingressClassResource.controllerValue | string | `"k8s.io/ingress-nginx"` | Controller of the IngressClass. An Ingress Controller looks for IngressClasses it should reconcile by this value. This value is also being set as the `--controller-class` argument of this Ingress Controller. Ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class | | controller.ingressClassResource.default | bool | `false` | If true, Ingresses without `ingressClassName` get assigned to this IngressClass on creation. Ingress creation gets rejected if there are multiple default IngressClasses. Ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#default-ingress-class | | controller.ingressClassResource.enabled | bool | `true` | Create the IngressClass or not | diff --git a/charts/ingress-nginx/templates/controller-ingressclass-aliases.yaml b/charts/ingress-nginx/templates/controller-ingressclass-aliases.yaml new file mode 100644 index 00000000000..b4b20690ea4 --- /dev/null +++ b/charts/ingress-nginx/templates/controller-ingressclass-aliases.yaml @@ -0,0 +1,20 @@ +{{- if .Values.controller.ingressClassResource.enabled -}} +{{- range .Values.controller.ingressClassResource.aliases }} +--- +apiVersion: networking.k8s.io/v1 +kind: IngressClass +metadata: + labels: + {{- include "ingress-nginx.labels" $ | nindent 4 }} + app.kubernetes.io/component: controller + {{- with $.Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ . }} +spec: + controller: {{ $.Values.controller.ingressClassResource.controllerValue }} + {{- with $.Values.controller.ingressClassResource.parameters }} + parameters: {{ toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/ingress-nginx/tests/controller-ingressclass-aliases_test.yaml b/charts/ingress-nginx/tests/controller-ingressclass-aliases_test.yaml new file mode 100644 index 00000000000..ef0780d9c33 --- /dev/null +++ b/charts/ingress-nginx/tests/controller-ingressclass-aliases_test.yaml @@ -0,0 +1,92 @@ +suite: Controller > IngressClass > Aliases +templates: + - controller-ingressclass-aliases.yaml + +tests: + - it: should not create IngressClass aliases + asserts: + - hasDocuments: + count: 0 + + - it: should create an IngressClass alias with name "nginx-alias" if `controller.ingressClassResource.aliases` is set + set: + controller.ingressClassResource.aliases: + - nginx-alias + asserts: + - hasDocuments: + count: 1 + - isKind: + of: IngressClass + - equal: + path: metadata.name + value: nginx-alias + + - it: should create an IngressClass alias without annotation `ingressclass.kubernetes.io/is-default-class` if `controller.ingressClassResource.default` is true + set: + controller.ingressClassResource.aliases: + - nginx-alias + controller.ingressClassResource.default: true + asserts: + - hasDocuments: + count: 1 + - isKind: + of: IngressClass + - equal: + path: metadata.name + value: nginx-alias + - notExists: + path: metadata.annotations["ingressclass.kubernetes.io/is-default-class"] + + - it: should create an IngressClass alias with controller "k8s.io/ingress-nginx-internal" if `controller.ingressClassResource.controllerValue` is "k8s.io/ingress-nginx-internal" + set: + controller.ingressClassResource.aliases: + - nginx-alias + controller.ingressClassResource.controllerValue: k8s.io/ingress-nginx-internal + asserts: + - hasDocuments: + count: 1 + - isKind: + of: IngressClass + - equal: + path: metadata.name + value: nginx-alias + - equal: + path: spec.controller + value: k8s.io/ingress-nginx-internal + + - it: should create an IngressClass alias with parameters if `controller.ingressClassResource.parameters` is set + set: + controller.ingressClassResource.aliases: + - nginx-alias + controller.ingressClassResource.parameters: + apiGroup: k8s.example.com + kind: IngressParameters + name: external-lb + asserts: + - hasDocuments: + count: 1 + - isKind: + of: IngressClass + - equal: + path: metadata.name + value: nginx-alias + - equal: + path: spec.parameters + value: + apiGroup: k8s.example.com + kind: IngressParameters + name: external-lb + + - it: should create two IngressClass aliases if `controller.ingressClassResource.aliases` has two elements + set: + controller.ingressClassResource.aliases: + - nginx-alias-1 + - nginx-alias-2 + asserts: + - hasDocuments: + count: 2 + - isKind: + of: IngressClass + - matchRegex: + path: metadata.name + pattern: nginx-alias-(1|2) diff --git a/charts/ingress-nginx/values.yaml b/charts/ingress-nginx/values.yaml index 50f958562ed..5be9519dfbd 100644 --- a/charts/ingress-nginx/values.yaml +++ b/charts/ingress-nginx/values.yaml @@ -126,6 +126,13 @@ controller: # This value is also being set as the `--controller-class` argument of this Ingress Controller. # Ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class controllerValue: k8s.io/ingress-nginx + # -- Aliases of this IngressClass. Creates copies with identical settings but the respective alias as name. + # Useful for development environments with only one Ingress Controller but production-like Ingress resources. + # `default` gets enabled on the original IngressClass only. + aliases: [] + # aliases: + # - nginx-alias-1 + # - nginx-alias-2 # -- A link to a custom resource containing additional configuration for the controller. # This is optional if the controller consuming this IngressClass does not require additional parameters. # Ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class