diff --git a/packages/core/platform/tests/apps_load_balancer_class_wiring_test.yaml b/packages/core/platform/tests/apps_load_balancer_class_wiring_test.yaml new file mode 100644 index 000000000..34d04c8c1 --- /dev/null +++ b/packages/core/platform/tests/apps_load_balancer_class_wiring_test.yaml @@ -0,0 +1,29 @@ +suite: apps.yaml publishing.loadBalancerClass → _cluster wiring +templates: + - templates/apps.yaml + +release: + name: cozy-platform + namespace: cozy-system + +# publishing.loadBalancerClass selects which LoadBalancer controller handles the +# host ingress Service. It reaches the host ingress-nginx through +# _cluster.load-balancer-class in the cozystack-values Secret (the same path +# expose-external-ips and proxy-protocol travel). These assertions pin that the +# value lands in the Secret; without them the host ingress would silently never +# see the configured loadBalancerClass. + +tests: + - it: writes an empty load-balancer-class by default + asserts: + - matchRegex: + path: stringData["values.yaml"] + pattern: '(?m)^\s*load-balancer-class:\s*""' + + - it: writes the load-balancer-class when publishing.loadBalancerClass is set + set: + publishing.loadBalancerClass: metallb.io/metallb + asserts: + - matchRegex: + path: stringData["values.yaml"] + pattern: '(?m)^\s*load-balancer-class:\s*"metallb\.io/metallb"' diff --git a/packages/extra/ingress/templates/nginx-ingress.yaml b/packages/extra/ingress/templates/nginx-ingress.yaml index b09ec2ea2..1276b9c4a 100644 --- a/packages/extra/ingress/templates/nginx-ingress.yaml +++ b/packages/extra/ingress/templates/nginx-ingress.yaml @@ -82,8 +82,12 @@ spec: {{- else }} type: LoadBalancer externalTrafficPolicy: Local - {{- with $loadBalancerClass }} - loadBalancerClass: {{ . }} + {{- /* loadBalancerClass is a host-publishing setting: apply it only to + the external-facing ingress (the namespace named by expose-ingress), + host-scoped like expose-external-ips and proxy-protocol above. + Tenant ingress Services keep the cluster's default LB controller. */}} + {{- if and $loadBalancerClass (eq $exposeIngress .Release.Namespace) }} + loadBalancerClass: {{ $loadBalancerClass }} {{- end }} {{- end }} {{- if or .Values.whitelist .Values.cloudflareProxy $proxyProtocol }} diff --git a/packages/extra/ingress/tests/load_balancer_class_test.yaml b/packages/extra/ingress/tests/load_balancer_class_test.yaml new file mode 100644 index 000000000..0dd92ddb7 --- /dev/null +++ b/packages/extra/ingress/tests/load_balancer_class_test.yaml @@ -0,0 +1,69 @@ +suite: ingress loadBalancerClass wiring +templates: + - templates/nginx-ingress.yaml +release: + name: ingress + +# publishing.loadBalancerClass is a host-publishing setting carried in +# _cluster.load-balancer-class. It must land on the external-facing (host) +# ingress Service only — host-scoped like expose-external-ips and +# proxy-protocol. These assertions pin that scope: a tenant ingress must NOT +# inherit the host's loadBalancerClass, or its Service would be claimed by an +# LB controller the tenant never asked for. +tests: + - it: sets loadBalancerClass on the host ingress LoadBalancer Service + set: + _cluster: + expose-ingress: tenant-root + load-balancer-class: metallb.io/metallb + release: + namespace: tenant-root + asserts: + - equal: + path: spec.values.ingress-nginx.controller.service.type + value: LoadBalancer + - equal: + path: spec.values.ingress-nginx.controller.service.loadBalancerClass + value: metallb.io/metallb + + - it: does not leak the host loadBalancerClass onto a tenant ingress + set: + _cluster: + expose-ingress: tenant-root + load-balancer-class: metallb.io/metallb + release: + namespace: tenant-foo + asserts: + - equal: + path: spec.values.ingress-nginx.controller.service.type + value: LoadBalancer + - notExists: + path: spec.values.ingress-nginx.controller.service.loadBalancerClass + + - it: keeps the externalIPs path untouched by loadBalancerClass + set: + _cluster: + expose-ingress: tenant-root + expose-external-ips: 203.0.113.10 + load-balancer-class: metallb.io/metallb + release: + namespace: tenant-root + asserts: + - equal: + path: spec.values.ingress-nginx.controller.service.type + value: ClusterIP + - notExists: + path: spec.values.ingress-nginx.controller.service.loadBalancerClass + + - it: omits loadBalancerClass on the host ingress when none is configured + set: + _cluster: + expose-ingress: tenant-root + release: + namespace: tenant-root + asserts: + - equal: + path: spec.values.ingress-nginx.controller.service.type + value: LoadBalancer + - notExists: + path: spec.values.ingress-nginx.controller.service.loadBalancerClass