From 91dedbbb2473888e83ddd165bcad20e3d36454ad Mon Sep 17 00:00:00 2001 From: mikkeldamsgaard Date: Sat, 29 Aug 2026 09:05:29 +0200 Subject: [PATCH 1/2] feat(netbird)!: controller-agnostic ingressGrpc annotations; bump netbird 0.77.1, keycloak 26.7.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #134: server.ingressGrpc.annotations carried four nginx-specific annotations by default even though server.ingressGrpc.className is configurable, so they were applied verbatim to Ingresses managed by HAProxy, Traefik, and other controllers where they are meaningless. Annotations now default to {} and the nginx set remains in values.yaml as a commented example. Because ingress-nginx genuinely requires backend-protocol: GRPC (without it the controller proxies the backend as HTTP/1.1 and gRPC fails), simply dropping the defaults would silently break existing nginx users on upgrade. The chart therefore fails at template time when className contains "nginx" and that annotation is missing, listing the exact annotations to add — matching the existing fail-fast guard for ingressGrpc without TLS. Non-nginx controllers need no annotations. Version bumps, consolidating the open upstream-update issues: - netbird appVersion 0.73.2 -> 0.77.1 (covers 0.74.x-0.77.x). Upstream adds Agent Network, a rewritten desktop client, relay X-Real-Ip restricted to configured trusted proxies, and privileged-caller checks for local SSH daemon settings. No config key, env var, port, or protocol used by this chart changed; no manual DB migration. - netbird dashboard image v2.39.0 -> v2.91.0 to stay paired with server 0.77.x. Verified the dashboard env contract is unchanged: every variable the chart sets is still rendered by upstream's dashboard.env. - keycloak appVersion 26.6.3 -> 26.7.2. Fixes CVE-2026-59888/59889 and CVE-2026-9796; 26.7.2 also fixes an upgrade failure in the stateless cluster provider, which is why this goes straight to .2. No KC_* option used by this chart changed, and the options removed in 26.7.0 are not used here. Also switches the initial admin to KC_BOOTSTRAP_ADMIN_USERNAME / KC_BOOTSTRAP_ADMIN_PASSWORD; upstream deprecated KEYCLOAK_ADMIN* and logs KC-SERVICES0110 on every start. No values change — admin.username and admin.password are unchanged, only the emitted env var names. Closes #115, #116, #117, #118, #119, #120, #121, #122, #123, #124, #125, #126, #127, #128, #129, #130, #131, #132, #133, #134, #135 Co-Authored-By: Claude Opus 5 (1M context) --- CHANGELOG.md | 41 +++++++++++++++ charts/keycloak/CHANGELOG.md | 30 +++++++++++ charts/keycloak/Chart.yaml | 2 +- charts/keycloak/README.md | 10 ++-- charts/keycloak/templates/NOTES.txt | 2 +- charts/keycloak/templates/deployment.yaml | 4 +- charts/keycloak/tests/deployment_test.yaml | 10 ++-- .../keycloak/tests/serviceaccount_test.yaml | 2 +- charts/keycloak/values.yaml | 2 +- charts/netbird/Chart.yaml | 2 +- charts/netbird/README.md | 48 +++++++++-------- charts/netbird/templates/_helpers.tpl | 7 ++- .../tests/dashboard-deployment_test.yaml | 2 +- .../netbird/tests/server-configmap_test.yaml | 51 ++++++++++++++++++- .../netbird/tests/server-deployment_test.yaml | 2 +- .../tests/server-grpc-ingress_test.yaml | 36 ++++++++++++- charts/netbird/tests/serviceaccount_test.yaml | 2 +- charts/netbird/values.yaml | 24 ++++++--- 18 files changed, 227 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae094b5..8aebd00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,47 @@ and this project adheres to [Semantic Versioning](https://semver.org/). ## Unreleased +### Changed + +- **netbird**: `server.ingressGrpc.annotations` is now empty by default + instead of carrying four `nginx.ingress.kubernetes.io/*` annotations. + `server.ingressGrpc.className` is configurable, so nginx-specific keys + were applied to Ingresses managed by HAProxy, Traefik, and other + controllers where they are meaningless. The nginx annotations remain in + `values.yaml` as a commented example. Fixes #134. + + **Migration** — if you use ingress-nginx and relied on the defaults, add + them explicitly: + + ```yaml + server: + ingressGrpc: + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "GRPC" + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" + ``` + + You will not silently lose gRPC: the chart now **fails at template time** + when `ingressGrpc.className` contains `nginx` and the annotations omit + `nginx.ingress.kubernetes.io/backend-protocol`, since ingress-nginx + proxies the backend as HTTP/1.1 without it. Non-nginx controllers are + unaffected and need no annotations. +- **netbird**: Bump appVersion from 0.73.2 to 0.77.1, covering upstream + 0.74.x–0.77.x. Notable additions: Agent Network (a per-account LLM + gateway built on the existing reverse proxy, self-hosted only), a + rewritten desktop client, relay `X-Real-Ip` handling restricted to + configured trusted proxies, and privileged-caller checks for local SSH + daemon settings. No config keys, env vars, ports, or protocols used by + this chart changed, and no manual database migration is required. + See [v0.77.1 release notes](https://github.com/netbirdio/netbird/releases/tag/v0.77.1) + (#116–#132, #135). +- **netbird**: Bump dashboard image from v2.39.0 to v2.91.0 to stay paired + with server 0.77.x. The dashboard's environment contract is unchanged — + every variable the chart sets is still rendered by upstream's own + `dashboard.env` — so no values changes are required. + ## [0.6.0] — 2026-06-23 ### Added diff --git a/charts/keycloak/CHANGELOG.md b/charts/keycloak/CHANGELOG.md index d08f685..e53cb26 100644 --- a/charts/keycloak/CHANGELOG.md +++ b/charts/keycloak/CHANGELOG.md @@ -4,6 +4,36 @@ All notable changes to the Keycloak Helm chart will be documented in this file. ## Unreleased +### Changed + +- Use `KC_BOOTSTRAP_ADMIN_USERNAME` / `KC_BOOTSTRAP_ADMIN_PASSWORD` for the + initial admin instead of `KEYCLOAK_ADMIN` / `KEYCLOAK_ADMIN_PASSWORD`, + which upstream has deprecated and logs a warning for on every start + (`KC-SERVICES0110`). No values change is required — `admin.username` and + `admin.password` are unchanged; only the environment variable names the + chart emits differ. As before, these apply only when bootstrapping a + fresh database. + +### Security + +- Bump Keycloak appVersion from 26.6.3 to 26.7.2 (#115, #120, #129, #133) + - 26.7.2 fixes CVE-2026-59888 / CVE-2026-59889 (jackson-databind) and + 26.7.0 fixes CVE-2026-9796 (admin role rename TOCTOU allowing + realm-wide privilege escalation from `manage-clients`) + - 26.7.2 also fixes an upgrade failure where the stateless cluster + provider captured a null NodeInfo before `postInit` when preview + features were enabled — this is why the chart moves straight to + 26.7.2 rather than 26.7.0 + - No `KC_*` option used by this chart changed. Options removed upstream + in 26.7.0 (persistent-session batching, `token-exchange-external-internal:v2`) + are not used here, and ports, health endpoints, and the container + entrypoint are unchanged + - See upstream release notes for + [26.7.0](https://github.com/keycloak/keycloak/releases/tag/26.7.0) and + [26.7.2](https://github.com/keycloak/keycloak/releases/tag/26.7.2) + +## [26.6.3] — 2026-06-11 + ### Fixed - Set `publishNotReadyAddresses: true` on the JGroups headless service. diff --git a/charts/keycloak/Chart.yaml b/charts/keycloak/Chart.yaml index 8df3528..baeaea5 100644 --- a/charts/keycloak/Chart.yaml +++ b/charts/keycloak/Chart.yaml @@ -3,7 +3,7 @@ name: keycloak description: A Helm chart for deploying Keycloak IAM using the upstream quay.io/keycloak/keycloak image on Kubernetes type: application version: 26.6.3 -appVersion: "26.6.3" +appVersion: "26.7.2" keywords: - keycloak - iam diff --git a/charts/keycloak/README.md b/charts/keycloak/README.md index 204758b..f903a0b 100644 --- a/charts/keycloak/README.md +++ b/charts/keycloak/README.md @@ -233,11 +233,11 @@ This runs `kc.sh build` in an init container and passes `--optimized` to the mai ### Admin Credentials -| Key | Type | Default | Description | -| --------------------------- | ------ | ------------ | ----------------------------------------- | -| `admin.username` | string | `""` | Admin username (maps to `KEYCLOAK_ADMIN`) | -| `admin.password.secretName` | string | `""` | Secret containing the admin password | -| `admin.password.secretKey` | string | `"password"` | Key in the Secret | +| Key | Type | Default | Description | +| --------------------------- | ------ | ------------ | ------------------------------------------------------ | +| `admin.username` | string | `""` | Admin username (maps to `KC_BOOTSTRAP_ADMIN_USERNAME`) | +| `admin.password.secretName` | string | `""` | Secret containing the admin password | +| `admin.password.secretKey` | string | `"password"` | Key in the Secret | ### Observability diff --git a/charts/keycloak/templates/NOTES.txt b/charts/keycloak/templates/NOTES.txt index 2603683..a126aa9 100644 --- a/charts/keycloak/templates/NOTES.txt +++ b/charts/keycloak/templates/NOTES.txt @@ -47,7 +47,7 @@ Admin Credentials: IMPORTANT: The admin user is only created on the first startup of a fresh Keycloak instance. If the database already contains users, the - KEYCLOAK_ADMIN / KEYCLOAK_ADMIN_PASSWORD environment variables are + KC_BOOTSTRAP_ADMIN_USERNAME / KC_BOOTSTRAP_ADMIN_PASSWORD variables are ignored. To reset credentials on an existing instance, use the Keycloak CLI (kcadm.sh) or the Admin REST API. {{- else }} diff --git a/charts/keycloak/templates/deployment.yaml b/charts/keycloak/templates/deployment.yaml index 6515413..d073a3f 100644 --- a/charts/keycloak/templates/deployment.yaml +++ b/charts/keycloak/templates/deployment.yaml @@ -85,9 +85,9 @@ spec: {{- if or $hasAdmin $hasExternalDB .Values.extraEnvVars }} env: {{- if $hasAdmin }} - - name: KEYCLOAK_ADMIN + - name: KC_BOOTSTRAP_ADMIN_USERNAME value: {{ .Values.admin.username | quote }} - - name: KEYCLOAK_ADMIN_PASSWORD + - name: KC_BOOTSTRAP_ADMIN_PASSWORD valueFrom: secretKeyRef: name: {{ .Values.admin.password.secretName }} diff --git a/charts/keycloak/tests/deployment_test.yaml b/charts/keycloak/tests/deployment_test.yaml index 314d666..d04f99c 100644 --- a/charts/keycloak/tests/deployment_test.yaml +++ b/charts/keycloak/tests/deployment_test.yaml @@ -13,7 +13,7 @@ tests: asserts: - equal: path: spec.template.spec.containers[0].image - value: "quay.io/keycloak/keycloak:26.6.3" + value: "quay.io/keycloak/keycloak:26.7.2" - it: should use custom image tag when set set: @@ -29,7 +29,7 @@ tests: asserts: - equal: path: spec.template.spec.containers[0].image - value: "my-registry/keycloak:26.6.3" + value: "my-registry/keycloak:26.7.2" - it: should set replica count set: @@ -177,12 +177,12 @@ tests: - contains: path: spec.template.spec.containers[0].env content: - name: KEYCLOAK_ADMIN + name: KC_BOOTSTRAP_ADMIN_USERNAME value: "admin" - contains: path: spec.template.spec.containers[0].env content: - name: KEYCLOAK_ADMIN_PASSWORD + name: KC_BOOTSTRAP_ADMIN_PASSWORD valueFrom: secretKeyRef: name: admin-secret @@ -262,7 +262,7 @@ tests: asserts: - equal: path: spec.template.spec.initContainers[0].image - value: "quay.io/keycloak/keycloak:26.6.3" + value: "quay.io/keycloak/keycloak:26.7.2" - it: should set hardened securityContext on build init container set: diff --git a/charts/keycloak/tests/serviceaccount_test.yaml b/charts/keycloak/tests/serviceaccount_test.yaml index 3de3429..18914d9 100644 --- a/charts/keycloak/tests/serviceaccount_test.yaml +++ b/charts/keycloak/tests/serviceaccount_test.yaml @@ -54,4 +54,4 @@ tests: content: helm.sh/chart: keycloak-26.6.3 app.kubernetes.io/managed-by: Helm - app.kubernetes.io/version: "26.6.3" + app.kubernetes.io/version: "26.7.2" diff --git a/charts/keycloak/values.yaml b/charts/keycloak/values.yaml index 4797fda..ba6d9d4 100644 --- a/charts/keycloak/values.yaml +++ b/charts/keycloak/values.yaml @@ -109,7 +109,7 @@ features: "" # ── Admin Credentials ──────────────────────────────────────────────────── admin: - # -- Admin username (maps to KEYCLOAK_ADMIN). Leave empty to skip initial admin creation + # -- Admin username (maps to KC_BOOTSTRAP_ADMIN_USERNAME). Leave empty to skip initial admin creation username: "" # -- Admin password via Kubernetes Secret reference password: diff --git a/charts/netbird/Chart.yaml b/charts/netbird/Chart.yaml index c7c0ace..a1995dc 100644 --- a/charts/netbird/Chart.yaml +++ b/charts/netbird/Chart.yaml @@ -3,7 +3,7 @@ name: netbird description: A Helm chart for deploying NetBird VPN management, signal, dashboard, and relay services on Kubernetes type: application version: 0.6.0 -appVersion: "0.73.2" +appVersion: "0.77.1" keywords: - netbird - vpn diff --git a/charts/netbird/README.md b/charts/netbird/README.md index b5cdb3d..e2a212a 100644 --- a/charts/netbird/README.md +++ b/charts/netbird/README.md @@ -163,14 +163,20 @@ server: hosts: - netbird.example.com # ⚠ ingressGrpc requires TLS. Standard nginx-ingress cannot negotiate - # HTTP/2 cleartext (h2c), and the chart sets - # nginx.ingress.kubernetes.io/ssl-redirect: "true" by default, so - # plaintext gRPC is redirected to HTTPS and fails without a cert. + # HTTP/2 cleartext (h2c), so plaintext gRPC fails without a cert. # Enabling this block with an empty `tls:` is rejected at template time. + # ⚠ Annotations are NOT set by default — they are controller-specific and + # `className` is configurable. ingress-nginx needs the ones below; the + # chart fails fast if className is nginx and backend-protocol is missing. # For plaintext h2c, use server.grpcRoute (Gateway API) instead — see the # "Gateway API as an alternative to Ingress" section below. ingressGrpc: enabled: true + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "GRPC" + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" hosts: - host: netbird.example.com paths: @@ -796,23 +802,23 @@ instead — this disables the embedded relay and uses #### Server Ingress -| Key | Type | Default | Description | -| --------------------------------- | ------ | --------------- | ----------------------------------------------------------------------------------------------------------- | -| `server.ingress.enabled` | bool | `false` | Create HTTP ingress (API + OAuth2). Mutually exclusive with `server.httpRoute`. | -| `server.ingress.className` | string | `"nginx"` | Ingress class | -| `server.ingress.annotations` | object | `{}` | Ingress annotations | -| `server.ingress.hosts` | list | `[]` | Ingress host rules | -| `server.ingress.tls` | list | `[]` | TLS configuration | -| `server.ingressGrpc.enabled` | bool | `false` | Create gRPC ingress (Signal + Management). Mutually exclusive with `server.grpcRoute`. | -| `server.ingressGrpc.className` | string | `"nginx"` | Ingress class | -| `server.ingressGrpc.annotations` | object | see values.yaml | GRPC backend annotations | -| `server.ingressGrpc.hosts` | list | `[]` | Ingress host rules | -| `server.ingressGrpc.tls` | list | `[]` | TLS configuration | -| `server.ingressRelay.enabled` | bool | `false` | Create relay/WebSocket ingress. Mutually exclusive with `server.relayHttpRoute` and `server.relayTcpRoute`. | -| `server.ingressRelay.className` | string | `"nginx"` | Ingress class | -| `server.ingressRelay.annotations` | object | `{}` | Ingress annotations | -| `server.ingressRelay.hosts` | list | `[]` | Ingress host rules | -| `server.ingressRelay.tls` | list | `[]` | TLS configuration | +| Key | Type | Default | Description | +| --------------------------------- | ------ | --------- | ------------------------------------------------------------------------------------------------------------------------------- | +| `server.ingress.enabled` | bool | `false` | Create HTTP ingress (API + OAuth2). Mutually exclusive with `server.httpRoute`. | +| `server.ingress.className` | string | `"nginx"` | Ingress class | +| `server.ingress.annotations` | object | `{}` | Ingress annotations | +| `server.ingress.hosts` | list | `[]` | Ingress host rules | +| `server.ingress.tls` | list | `[]` | TLS configuration | +| `server.ingressGrpc.enabled` | bool | `false` | Create gRPC ingress (Signal + Management). Mutually exclusive with `server.grpcRoute`. | +| `server.ingressGrpc.className` | string | `"nginx"` | Ingress class | +| `server.ingressGrpc.annotations` | object | `{}` | Controller-specific annotations. Empty by default; ingress-nginx requires `backend-protocol: GRPC` (enforced at template time). | +| `server.ingressGrpc.hosts` | list | `[]` | Ingress host rules | +| `server.ingressGrpc.tls` | list | `[]` | TLS configuration | +| `server.ingressRelay.enabled` | bool | `false` | Create relay/WebSocket ingress. Mutually exclusive with `server.relayHttpRoute` and `server.relayTcpRoute`. | +| `server.ingressRelay.className` | string | `"nginx"` | Ingress class | +| `server.ingressRelay.annotations` | object | `{}` | Ingress annotations | +| `server.ingressRelay.hosts` | list | `[]` | Ingress host rules | +| `server.ingressRelay.tls` | list | `[]` | TLS configuration | #### Server Gateway API routes @@ -875,7 +881,7 @@ terminated at the referenced Gateway's listeners, not in these values. | ---------------------------- | ------ | ----------------------- | ---------------------------- | | `dashboard.replicaCount` | int | `1` | Number of dashboard replicas | | `dashboard.image.repository` | string | `"netbirdio/dashboard"` | Dashboard image | -| `dashboard.image.tag` | string | `"v2.39.0"` | Dashboard image tag | +| `dashboard.image.tag` | string | `"v2.91.0"` | Dashboard image tag | | `dashboard.image.pullPolicy` | string | `"IfNotPresent"` | Image pull policy | | `dashboard.imagePullSecrets` | list | `[]` | Component-level pull secrets | diff --git a/charts/netbird/templates/_helpers.tpl b/charts/netbird/templates/_helpers.tpl index c8edce6..5ee501d 100644 --- a/charts/netbird/templates/_helpers.tpl +++ b/charts/netbird/templates/_helpers.tpl @@ -157,7 +157,12 @@ create duplicate or racing rules. {{- end -}} {{- end -}} {{- if and .Values.server.ingressGrpc.enabled (not .Values.server.ingressGrpc.tls) -}} - {{- fail "server.ingressGrpc.enabled is true but server.ingressGrpc.tls is empty. gRPC over Kubernetes Ingress requires TLS: standard nginx-ingress cannot negotiate HTTP/2 cleartext (h2c) and the default `nginx.ingress.kubernetes.io/ssl-redirect: \"true\"` annotation redirects plaintext gRPC to HTTPS — without a cert, requests fail silently. Either configure server.ingressGrpc.tls, or disable server.ingressGrpc and expose gRPC via server.grpcRoute (Gateway API) with a controller that supports plaintext h2c." -}} + {{- fail "server.ingressGrpc.enabled is true but server.ingressGrpc.tls is empty. gRPC over Kubernetes Ingress requires TLS: standard nginx-ingress cannot negotiate HTTP/2 cleartext (h2c), so plaintext gRPC fails without a cert. Either configure server.ingressGrpc.tls, or disable server.ingressGrpc and expose gRPC via server.grpcRoute (Gateway API) with a controller that supports plaintext h2c." -}} +{{- end -}} +{{- if and .Values.server.ingressGrpc.enabled (contains "nginx" (toString .Values.server.ingressGrpc.className)) -}} + {{- if not (hasKey (.Values.server.ingressGrpc.annotations | default dict) "nginx.ingress.kubernetes.io/backend-protocol") -}} + {{- fail "server.ingressGrpc.className is nginx but server.ingressGrpc.annotations is missing `nginx.ingress.kubernetes.io/backend-protocol`. ingress-nginx proxies the backend as HTTP/1.1 without it, so gRPC fails. These annotations are no longer set by default (they are controller-specific and server.ingressGrpc.className is configurable). Add them to server.ingressGrpc.annotations:\n nginx.ingress.kubernetes.io/backend-protocol: \"GRPC\"\n nginx.ingress.kubernetes.io/ssl-redirect: \"true\"\n nginx.ingress.kubernetes.io/proxy-read-timeout: \"3600\"\n nginx.ingress.kubernetes.io/proxy-send-timeout: \"3600\"\nIf you are not using ingress-nginx, set server.ingressGrpc.className to your controller." -}} + {{- end -}} {{- end -}} {{- end }} diff --git a/charts/netbird/tests/dashboard-deployment_test.yaml b/charts/netbird/tests/dashboard-deployment_test.yaml index ba360d0..77c5140 100644 --- a/charts/netbird/tests/dashboard-deployment_test.yaml +++ b/charts/netbird/tests/dashboard-deployment_test.yaml @@ -13,7 +13,7 @@ tests: asserts: - equal: path: spec.template.spec.containers[0].image - value: "netbirdio/dashboard:v2.39.0" + value: "netbirdio/dashboard:v2.91.0" - it: should set replica count set: diff --git a/charts/netbird/tests/server-configmap_test.yaml b/charts/netbird/tests/server-configmap_test.yaml index f574576..f537e09 100644 --- a/charts/netbird/tests/server-configmap_test.yaml +++ b/charts/netbird/tests/server-configmap_test.yaml @@ -441,7 +441,7 @@ tests: - failedTemplate: errorPattern: "server.ingressGrpc.tls is empty" - - it: should accept ingressGrpc when TLS is configured + - it: should accept ingressGrpc when TLS and nginx annotations are configured set: server.ingressGrpc.enabled: true server.ingressGrpc.hosts: @@ -452,6 +452,55 @@ tests: - secretName: netbird-tls hosts: - netbird.example.com + server.ingressGrpc.annotations: + nginx.ingress.kubernetes.io/backend-protocol: "GRPC" + asserts: + - hasDocuments: + count: 1 + + - it: should fail when className is nginx and backend-protocol annotation is missing + set: + server.ingressGrpc.enabled: true + server.ingressGrpc.hosts: + - host: netbird.example.com + paths: + - path: /signalexchange.SignalExchange + server.ingressGrpc.tls: + - secretName: netbird-tls + hosts: + - netbird.example.com + asserts: + - failedTemplate: + errorPattern: "backend-protocol" + + - it: should fail with a clear message when nginx annotations are explicitly null + set: + server.ingressGrpc.enabled: true + server.ingressGrpc.annotations: null + server.ingressGrpc.hosts: + - host: netbird.example.com + paths: + - path: /signalexchange.SignalExchange + server.ingressGrpc.tls: + - secretName: netbird-tls + hosts: + - netbird.example.com + asserts: + - failedTemplate: + errorPattern: "backend-protocol" + + - it: should accept a non-nginx ingressGrpc controller without annotations + set: + server.ingressGrpc.enabled: true + server.ingressGrpc.className: haproxy + server.ingressGrpc.hosts: + - host: netbird.example.com + paths: + - path: /signalexchange.SignalExchange + server.ingressGrpc.tls: + - secretName: netbird-tls + hosts: + - netbird.example.com asserts: - hasDocuments: count: 1 diff --git a/charts/netbird/tests/server-deployment_test.yaml b/charts/netbird/tests/server-deployment_test.yaml index 8caf00f..795c0f1 100644 --- a/charts/netbird/tests/server-deployment_test.yaml +++ b/charts/netbird/tests/server-deployment_test.yaml @@ -13,7 +13,7 @@ tests: asserts: - equal: path: spec.template.spec.containers[0].image - value: "netbirdio/netbird-server:0.73.2" + value: "netbirdio/netbird-server:0.77.1" - it: should use custom image tag when set set: diff --git a/charts/netbird/tests/server-grpc-ingress_test.yaml b/charts/netbird/tests/server-grpc-ingress_test.yaml index b94392c..13b918c 100644 --- a/charts/netbird/tests/server-grpc-ingress_test.yaml +++ b/charts/netbird/tests/server-grpc-ingress_test.yaml @@ -21,13 +21,29 @@ tests: - isKind: of: Ingress - - it: should include default gRPC annotations + - it: should not set controller-specific annotations by default set: server.ingressGrpc.enabled: true server.ingressGrpc.hosts: - host: netbird.example.com paths: - path: /signalexchange.SignalExchange + asserts: + - notExists: + path: metadata.annotations + + - it: should render user-supplied nginx annotations verbatim + set: + server.ingressGrpc.enabled: true + server.ingressGrpc.hosts: + - host: netbird.example.com + paths: + - path: /signalexchange.SignalExchange + server.ingressGrpc.annotations: + nginx.ingress.kubernetes.io/backend-protocol: "GRPC" + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" asserts: - isSubset: path: metadata.annotations @@ -37,6 +53,24 @@ tests: nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" + - it: should render annotations for a non-nginx controller + set: + server.ingressGrpc.enabled: true + server.ingressGrpc.className: haproxy + server.ingressGrpc.hosts: + - host: netbird.example.com + paths: + - path: /signalexchange.SignalExchange + server.ingressGrpc.annotations: + haproxy.org/server-proto: "h2" + asserts: + - equal: + path: metadata.annotations["haproxy.org/server-proto"] + value: "h2" + - equal: + path: spec.ingressClassName + value: haproxy + - it: should have -grpc suffix in name set: server.ingressGrpc.enabled: true diff --git a/charts/netbird/tests/serviceaccount_test.yaml b/charts/netbird/tests/serviceaccount_test.yaml index 40b4ae2..fc7363b 100644 --- a/charts/netbird/tests/serviceaccount_test.yaml +++ b/charts/netbird/tests/serviceaccount_test.yaml @@ -64,4 +64,4 @@ tests: content: helm.sh/chart: netbird-0.6.0 app.kubernetes.io/managed-by: Helm - app.kubernetes.io/version: "0.73.2" + app.kubernetes.io/version: "0.77.1" diff --git a/charts/netbird/values.yaml b/charts/netbird/values.yaml index 333f011..f7e1dba 100644 --- a/charts/netbird/values.yaml +++ b/charts/netbird/values.yaml @@ -495,11 +495,23 @@ server: ingressGrpc: enabled: false className: "nginx" - annotations: - nginx.ingress.kubernetes.io/backend-protocol: "GRPC" - nginx.ingress.kubernetes.io/ssl-redirect: "true" - nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" - nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" + # -- Annotations are controller-agnostic (empty by default) because + # className is configurable — nginx-specific keys would be meaningless on + # HAProxy, Traefik, or any other controller. Supply the annotations your + # controller needs to carry gRPC (HTTP/2) to the backend. + # + # For ingress-nginx, these are required — without backend-protocol: GRPC + # the controller proxies gRPC as HTTP/1.1 and requests fail: + # + # annotations: + # nginx.ingress.kubernetes.io/backend-protocol: "GRPC" + # nginx.ingress.kubernetes.io/ssl-redirect: "true" + # nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" + # nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" + # + # The chart fails fast when className is nginx and backend-protocol is + # missing, so this cannot silently break a gRPC ingress. + annotations: {} hosts: [] tls: [] @@ -651,7 +663,7 @@ dashboard: image: repository: netbirdio/dashboard - tag: "v2.39.0" + tag: "v2.91.0" pullPolicy: IfNotPresent imagePullSecrets: [] From 1b3fbbe97444516d88ea499d5627ee08ed1e224e Mon Sep 17 00:00:00 2001 From: mikkeldamsgaard Date: Sat, 29 Aug 2026 09:10:16 +0200 Subject: [PATCH 2/2] ci: pin helmfmt and apply its formatting The Format Check job installed helmfmt with @latest, which is not reproducible. helmfmt v0.6.1 was published after the last green run on main and does not build: format.go:54:34: undefined: sprigStubNames so the job now fails on every PR regardless of content. Pin to v0.6.0, the newest version that builds. v0.6.0 indents template control flow differently from the v0.6.1 output currently committed, so this also reapplies formatting across 15 templates. The change is whitespace only: `helm template` output for both charts is byte-identical before and after (verified for default values, netbird with Gateway API routes enabled, and keycloak with admin credentials and 2 replicas), ignoring the auto-generated secrets that are randomised on every render by design. Kept as a separate commit so the functional changes stay reviewable. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/ci.yaml | 4 +- charts/keycloak/templates/_helpers.tpl | 50 +++++++-------- charts/keycloak/templates/deployment.yaml | 4 +- .../keycloak/templates/headless-service.yaml | 4 +- charts/keycloak/templates/service.yaml | 4 +- charts/keycloak/templates/servicemonitor.yaml | 12 ++-- charts/netbird/templates/_helpers.tpl | 64 +++++++++---------- .../templates/dashboard-httproute.yaml | 20 +++--- .../netbird/templates/server-deployment.yaml | 8 +-- .../templates/server-grpc-service.yaml | 4 +- .../netbird/templates/server-grpcroute.yaml | 28 ++++---- .../netbird/templates/server-httproute.yaml | 20 +++--- .../templates/server-relay-httproute.yaml | 28 ++++---- .../templates/server-relay-service.yaml | 4 +- .../templates/server-relay-tcproute.yaml | 26 ++++---- .../templates/server-stun-service.yaml | 4 +- 16 files changed, 143 insertions(+), 141 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c957fe0..8e81846 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -59,7 +59,9 @@ jobs: cache: false - name: Install helmfmt - run: go install github.com/digitalstudium/helmfmt@latest + # Pinned: @latest is not reproducible and v0.6.1 fails to build + # (undefined: sprigStubNames), which broke this job for every PR. + run: go install github.com/digitalstudium/helmfmt@v0.6.0 - name: Check Helm template formatting run: | diff --git a/charts/keycloak/templates/_helpers.tpl b/charts/keycloak/templates/_helpers.tpl index b016692..2681191 100644 --- a/charts/keycloak/templates/_helpers.tpl +++ b/charts/keycloak/templates/_helpers.tpl @@ -114,52 +114,52 @@ KC_HEALTH_ENABLED: {{ .Values.healthEnabled | quote }} KC_METRICS_ENABLED: {{ .Values.metrics.enabled | quote }} KC_LOG_LEVEL: {{ .Values.logLevel | quote }} KC_HTTP_ENABLED: {{ .Values.httpEnabled | quote }} -{{- if .Values.hostname }} + {{- if .Values.hostname }} KC_HOSTNAME: {{ .Values.hostname | quote }} -{{- end }} + {{- end }} KC_HOSTNAME_STRICT: {{ .Values.hostnameStrict | quote }} -{{- if .Values.hostnameAdmin }} + {{- if .Values.hostnameAdmin }} KC_HOSTNAME_ADMIN: {{ .Values.hostnameAdmin | quote }} -{{- end }} -{{- if .Values.proxyHeaders }} + {{- end }} + {{- if .Values.proxyHeaders }} KC_PROXY_HEADERS: {{ .Values.proxyHeaders | quote }} -{{- end }} -{{- if .Values.features }} + {{- end }} + {{- if .Values.features }} KC_FEATURES: {{ .Values.features | quote }} -{{- end }} -{{- if .Values.tls.enabled }} + {{- end }} + {{- if .Values.tls.enabled }} KC_HTTPS_CERTIFICATE_FILE: "/opt/keycloak/conf/tls/tls.crt" KC_HTTPS_CERTIFICATE_KEY_FILE: "/opt/keycloak/conf/tls/tls.key" -{{- end }} -{{- if eq (include "keycloak.database.isExternal" .) "true" }} + {{- end }} + {{- if eq (include "keycloak.database.isExternal" .) "true" }} KC_DB: {{ include "keycloak.database.vendor" . | quote }} KC_DB_URL_HOST: {{ .Values.database.host | quote }} KC_DB_URL_PORT: {{ include "keycloak.database.port" . | quote }} KC_DB_URL_DATABASE: {{ .Values.database.name | quote }} KC_DB_USERNAME: {{ .Values.database.user | quote }} - {{- if .Values.database.poolMinSize }} + {{- if .Values.database.poolMinSize }} KC_DB_POOL_MIN_SIZE: {{ .Values.database.poolMinSize | quote }} - {{- end }} - {{- if .Values.database.poolInitialSize }} + {{- end }} + {{- if .Values.database.poolInitialSize }} KC_DB_POOL_INITIAL_SIZE: {{ .Values.database.poolInitialSize | quote }} - {{- end }} - {{- if .Values.database.poolMaxSize }} + {{- end }} + {{- if .Values.database.poolMaxSize }} KC_DB_POOL_MAX_SIZE: {{ .Values.database.poolMaxSize | quote }} - {{- end }} - {{- if .Values.database.sslMode }} - {{- if eq .Values.database.type "postgresql" }} + {{- end }} + {{- if .Values.database.sslMode }} + {{- if eq .Values.database.type "postgresql" }} KC_DB_URL_PROPERTIES: {{ printf "?sslmode=%s" .Values.database.sslMode | quote }} + {{- end }} {{- end }} {{- end }} -{{- end }} -{{- if eq .Values.database.type "dev" }} + {{- if eq .Values.database.type "dev" }} KC_CACHE: "local" -{{- else }} + {{- else }} KC_CACHE: "ispn" KC_CACHE_STACK: {{ .Values.cache.stack | quote }} -{{- if eq .Values.cache.stack "kubernetes" }} + {{- if eq .Values.cache.stack "kubernetes" }} KC_CACHE_CONFIG_FILE: "cache-ispn.xml" JAVA_OPTS_APPEND: {{ printf "-Djgroups.dns.query=%s" (include "keycloak.headlessServiceFQDN" .) | quote }} -{{- end }} -{{- end }} + {{- end }} + {{- end }} {{- end }} diff --git a/charts/keycloak/templates/deployment.yaml b/charts/keycloak/templates/deployment.yaml index d073a3f..af0243c 100644 --- a/charts/keycloak/templates/deployment.yaml +++ b/charts/keycloak/templates/deployment.yaml @@ -43,13 +43,13 @@ spec: - configMapRef: name: {{ include "keycloak.fullname" . }}-env env: -{{- if eq (include "keycloak.database.isExternal" .) "true" }} + {{- if eq (include "keycloak.database.isExternal" .) "true" }} - name: KC_DB_PASSWORD valueFrom: secretKeyRef: name: {{ .Values.database.password.secretName }} key: {{ .Values.database.password.secretKey }} -{{- end }} + {{- end }} securityContext: runAsNonRoot: true runAsUser: 1000 diff --git a/charts/keycloak/templates/headless-service.yaml b/charts/keycloak/templates/headless-service.yaml index 35e63b7..3390e46 100644 --- a/charts/keycloak/templates/headless-service.yaml +++ b/charts/keycloak/templates/headless-service.yaml @@ -5,10 +5,10 @@ metadata: namespace: {{ .Release.Namespace }} labels: {{- include "keycloak.allLabels" . | nindent 4 }} - {{- with .Values.headlessService.annotations }} +{{- with .Values.headlessService.annotations }} annotations: {{- toYaml . | nindent 4 }} - {{- end }} +{{- end }} spec: type: ClusterIP clusterIP: None diff --git a/charts/keycloak/templates/service.yaml b/charts/keycloak/templates/service.yaml index f0b7faf..fe85369 100644 --- a/charts/keycloak/templates/service.yaml +++ b/charts/keycloak/templates/service.yaml @@ -5,10 +5,10 @@ metadata: namespace: {{ .Release.Namespace }} labels: {{- include "keycloak.allLabels" . | nindent 4 }} - {{- with .Values.service.annotations }} +{{- with .Values.service.annotations }} annotations: {{- toYaml . | nindent 4 }} - {{- end }} +{{- end }} spec: type: {{ .Values.service.type }} ports: diff --git a/charts/keycloak/templates/servicemonitor.yaml b/charts/keycloak/templates/servicemonitor.yaml index 42187fb..84e14df 100644 --- a/charts/keycloak/templates/servicemonitor.yaml +++ b/charts/keycloak/templates/servicemonitor.yaml @@ -6,9 +6,9 @@ metadata: namespace: {{ .Release.Namespace }} labels: {{- include "keycloak.allLabels" . | nindent 4 }} - {{- with .Values.metrics.serviceMonitor.labels }} + {{- with .Values.metrics.serviceMonitor.labels }} {{- toYaml . | nindent 4 }} - {{- end }} + {{- end }} spec: selector: matchLabels: @@ -16,10 +16,10 @@ spec: endpoints: - port: management path: /metrics - {{- with .Values.metrics.serviceMonitor.interval }} + {{- with .Values.metrics.serviceMonitor.interval }} interval: {{ . }} - {{- end }} - {{- with .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- with .Values.metrics.serviceMonitor.scrapeTimeout }} scrapeTimeout: {{ . }} - {{- end }} + {{- end }} {{- end }} diff --git a/charts/netbird/templates/_helpers.tpl b/charts/netbird/templates/_helpers.tpl index 5ee501d..ae412cb 100644 --- a/charts/netbird/templates/_helpers.tpl +++ b/charts/netbird/templates/_helpers.tpl @@ -120,11 +120,11 @@ Accepts hostnames, IPv4, and bracketed IPv6. Empty exposedAddress passes here to keep `helm template` usable for partial inspection). */}} {{- define "netbird.validate.exposedAddress" -}} -{{- with .Values.server.config.exposedAddress -}} - {{- if not (regexMatch `^https?://(\[[^\]]+\]|[^/:?#]+):[0-9]+([/?#].*)?$` .) -}} - {{- fail (printf "server.config.exposedAddress %q must include an explicit port (e.g. \"https://netbird.example.com:443\"). NetBird clients require the port; without it the daemon fails with \"missing port in address\"." .) -}} + {{- with .Values.server.config.exposedAddress -}} + {{- if not (regexMatch `^https?://(\[[^\]]+\]|[^/:?#]+):[0-9]+([/?#].*)?$` .) -}} + {{- fail (printf "server.config.exposedAddress %q must include an explicit port (e.g. \"https://netbird.example.com:443\"). NetBird clients require the port; without it the daemon fails with \"missing port in address\"." .) -}} + {{- end -}} {{- end -}} -{{- end -}} {{- end }} {{/* @@ -134,36 +134,36 @@ resources would otherwise claim the same paths/hostnames and silently create duplicate or racing rules. */}} {{- define "netbird.validate.routeExclusion" -}} -{{- if and .Values.server.ingress.enabled .Values.server.httpRoute.enabled -}} - {{- fail "server.ingress.enabled and server.httpRoute.enabled are mutually exclusive — pick Kubernetes Ingress or Gateway API HTTPRoute for server HTTP traffic." -}} -{{- end -}} -{{- if and .Values.server.ingressGrpc.enabled .Values.server.grpcRoute.enabled -}} - {{- fail "server.ingressGrpc.enabled and server.grpcRoute.enabled are mutually exclusive — pick Kubernetes Ingress or Gateway API GRPCRoute for server gRPC traffic." -}} -{{- end -}} -{{- if and .Values.server.ingressRelay.enabled (or .Values.server.relayHttpRoute.enabled .Values.server.relayTcpRoute.enabled) -}} - {{- fail "server.ingressRelay.enabled conflicts with server.relayHttpRoute/relayTcpRoute — pick exactly one route type for relay/WebSocket traffic." -}} -{{- end -}} -{{- if and .Values.server.relayHttpRoute.enabled .Values.server.relayTcpRoute.enabled -}} - {{- fail "server.relayHttpRoute.enabled and server.relayTcpRoute.enabled are mutually exclusive — pick HTTPRoute or TCPRoute, not both." -}} -{{- end -}} -{{- if and .Values.dashboard.ingress.enabled .Values.dashboard.httpRoute.enabled -}} - {{- fail "dashboard.ingress.enabled and dashboard.httpRoute.enabled are mutually exclusive — pick Kubernetes Ingress or Gateway API HTTPRoute for the dashboard." -}} -{{- end -}} -{{- range $path := list "server.httpRoute" "server.grpcRoute" "server.relayHttpRoute" "server.relayTcpRoute" "dashboard.httpRoute" -}} - {{- $parts := splitList "." $path -}} - {{- $block := index $.Values (index $parts 0) (index $parts 1) -}} - {{- if and $block.enabled (not $block.parentRefs) -}} - {{- fail (printf "%s.enabled is true but %s.parentRefs is empty — Gateway API routes must reference at least one Gateway." $path $path) -}} + {{- if and .Values.server.ingress.enabled .Values.server.httpRoute.enabled -}} + {{- fail "server.ingress.enabled and server.httpRoute.enabled are mutually exclusive — pick Kubernetes Ingress or Gateway API HTTPRoute for server HTTP traffic." -}} {{- end -}} -{{- end -}} -{{- if and .Values.server.ingressGrpc.enabled (not .Values.server.ingressGrpc.tls) -}} - {{- fail "server.ingressGrpc.enabled is true but server.ingressGrpc.tls is empty. gRPC over Kubernetes Ingress requires TLS: standard nginx-ingress cannot negotiate HTTP/2 cleartext (h2c), so plaintext gRPC fails without a cert. Either configure server.ingressGrpc.tls, or disable server.ingressGrpc and expose gRPC via server.grpcRoute (Gateway API) with a controller that supports plaintext h2c." -}} -{{- end -}} -{{- if and .Values.server.ingressGrpc.enabled (contains "nginx" (toString .Values.server.ingressGrpc.className)) -}} - {{- if not (hasKey (.Values.server.ingressGrpc.annotations | default dict) "nginx.ingress.kubernetes.io/backend-protocol") -}} - {{- fail "server.ingressGrpc.className is nginx but server.ingressGrpc.annotations is missing `nginx.ingress.kubernetes.io/backend-protocol`. ingress-nginx proxies the backend as HTTP/1.1 without it, so gRPC fails. These annotations are no longer set by default (they are controller-specific and server.ingressGrpc.className is configurable). Add them to server.ingressGrpc.annotations:\n nginx.ingress.kubernetes.io/backend-protocol: \"GRPC\"\n nginx.ingress.kubernetes.io/ssl-redirect: \"true\"\n nginx.ingress.kubernetes.io/proxy-read-timeout: \"3600\"\n nginx.ingress.kubernetes.io/proxy-send-timeout: \"3600\"\nIf you are not using ingress-nginx, set server.ingressGrpc.className to your controller." -}} + {{- if and .Values.server.ingressGrpc.enabled .Values.server.grpcRoute.enabled -}} + {{- fail "server.ingressGrpc.enabled and server.grpcRoute.enabled are mutually exclusive — pick Kubernetes Ingress or Gateway API GRPCRoute for server gRPC traffic." -}} + {{- end -}} + {{- if and .Values.server.ingressRelay.enabled (or .Values.server.relayHttpRoute.enabled .Values.server.relayTcpRoute.enabled) -}} + {{- fail "server.ingressRelay.enabled conflicts with server.relayHttpRoute/relayTcpRoute — pick exactly one route type for relay/WebSocket traffic." -}} + {{- end -}} + {{- if and .Values.server.relayHttpRoute.enabled .Values.server.relayTcpRoute.enabled -}} + {{- fail "server.relayHttpRoute.enabled and server.relayTcpRoute.enabled are mutually exclusive — pick HTTPRoute or TCPRoute, not both." -}} + {{- end -}} + {{- if and .Values.dashboard.ingress.enabled .Values.dashboard.httpRoute.enabled -}} + {{- fail "dashboard.ingress.enabled and dashboard.httpRoute.enabled are mutually exclusive — pick Kubernetes Ingress or Gateway API HTTPRoute for the dashboard." -}} + {{- end -}} + {{- range $path := list "server.httpRoute" "server.grpcRoute" "server.relayHttpRoute" "server.relayTcpRoute" "dashboard.httpRoute" -}} + {{- $parts := splitList "." $path -}} + {{- $block := index $.Values (index $parts 0) (index $parts 1) -}} + {{- if and $block.enabled (not $block.parentRefs) -}} + {{- fail (printf "%s.enabled is true but %s.parentRefs is empty — Gateway API routes must reference at least one Gateway." $path $path) -}} + {{- end -}} + {{- end -}} + {{- if and .Values.server.ingressGrpc.enabled (not .Values.server.ingressGrpc.tls) -}} + {{- fail "server.ingressGrpc.enabled is true but server.ingressGrpc.tls is empty. gRPC over Kubernetes Ingress requires TLS: standard nginx-ingress cannot negotiate HTTP/2 cleartext (h2c), so plaintext gRPC fails without a cert. Either configure server.ingressGrpc.tls, or disable server.ingressGrpc and expose gRPC via server.grpcRoute (Gateway API) with a controller that supports plaintext h2c." -}} + {{- end -}} + {{- if and .Values.server.ingressGrpc.enabled (contains "nginx" (toString .Values.server.ingressGrpc.className)) -}} + {{- if not (hasKey (.Values.server.ingressGrpc.annotations | default dict) "nginx.ingress.kubernetes.io/backend-protocol") -}} + {{- fail "server.ingressGrpc.className is nginx but server.ingressGrpc.annotations is missing `nginx.ingress.kubernetes.io/backend-protocol`. ingress-nginx proxies the backend as HTTP/1.1 without it, so gRPC fails. These annotations are no longer set by default (they are controller-specific and server.ingressGrpc.className is configurable). Add them to server.ingressGrpc.annotations:\n nginx.ingress.kubernetes.io/backend-protocol: \"GRPC\"\n nginx.ingress.kubernetes.io/ssl-redirect: \"true\"\n nginx.ingress.kubernetes.io/proxy-read-timeout: \"3600\"\n nginx.ingress.kubernetes.io/proxy-send-timeout: \"3600\"\nIf you are not using ingress-nginx, set server.ingressGrpc.className to your controller." -}} + {{- end -}} {{- end -}} -{{- end -}} {{- end }} {{/* diff --git a/charts/netbird/templates/dashboard-httproute.yaml b/charts/netbird/templates/dashboard-httproute.yaml index 4b198f9..d4edbc0 100644 --- a/charts/netbird/templates/dashboard-httproute.yaml +++ b/charts/netbird/templates/dashboard-httproute.yaml @@ -1,13 +1,13 @@ {{- if .Values.dashboard.httpRoute.enabled }} -{{- $serviceName := include "netbird.dashboard.fullname" . }} -{{- $rules := list }} -{{- range .Values.dashboard.httpRoute.rules }} - {{- $rule := deepCopy . }} - {{- if not (hasKey $rule "backendRefs") }} - {{- $_ := set $rule "backendRefs" (list (dict "name" $serviceName "port" 80)) }} + {{- $serviceName := include "netbird.dashboard.fullname" . }} + {{- $rules := list }} + {{- range .Values.dashboard.httpRoute.rules }} + {{- $rule := deepCopy . }} + {{- if not (hasKey $rule "backendRefs") }} + {{- $_ := set $rule "backendRefs" (list (dict "name" $serviceName "port" 80)) }} + {{- end }} + {{- $rules = append $rules $rule }} {{- end }} - {{- $rules = append $rules $rule }} -{{- end }} apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: @@ -15,9 +15,9 @@ metadata: namespace: {{ .Release.Namespace }} labels: {{- include "netbird.dashboard.labels" . | nindent 4 }} - {{- with .Values.dashboard.httpRoute.labels }} + {{- with .Values.dashboard.httpRoute.labels }} {{- toYaml . | nindent 4 }} - {{- end }} + {{- end }} {{- with .Values.dashboard.httpRoute.annotations }} annotations: {{- toYaml . | nindent 4 }} diff --git a/charts/netbird/templates/server-deployment.yaml b/charts/netbird/templates/server-deployment.yaml index ef1745d..9227389 100644 --- a/charts/netbird/templates/server-deployment.yaml +++ b/charts/netbird/templates/server-deployment.yaml @@ -41,7 +41,7 @@ spec: {{- $relayConfigured := gt (len .Values.server.config.relays.addresses) 0 }} {{- $relaySecretName := "" }} {{- if $relayConfigured }} -{{- $relaySecretName = include "netbird.server.resolveSecretName" (dict "ref" .Values.server.secrets.relaySecret "generated" $generated) }} + {{- $relaySecretName = include "netbird.server.resolveSecretName" (dict "ref" .Values.server.secrets.relaySecret "generated" $generated) }} {{- end }} {{- $isExternal := eq (include "netbird.database.isExternal" .) "true" }} {{- $patSidecar := and .Values.pat.enabled (not $isExternal) }} @@ -123,16 +123,16 @@ spec: value: "" {{- end }} {{- if $relayConfigured }} -{{- if $relaySecretName }} + {{- if $relaySecretName }} - name: RELAY_SECRET valueFrom: secretKeyRef: name: {{ $relaySecretName }} key: {{ .Values.server.secrets.relaySecret.secretKey }} -{{- else }} + {{- else }} - name: RELAY_SECRET value: "" -{{- end }} + {{- end }} {{- end }} {{- if $isExternal }} - name: DB_PASSWORD diff --git a/charts/netbird/templates/server-grpc-service.yaml b/charts/netbird/templates/server-grpc-service.yaml index acc0f73..120252d 100644 --- a/charts/netbird/templates/server-grpc-service.yaml +++ b/charts/netbird/templates/server-grpc-service.yaml @@ -17,9 +17,9 @@ spec: port: {{ .Values.server.grpcService.port }} targetPort: http protocol: TCP - {{- with .Values.server.grpcService.appProtocol }} + {{- with .Values.server.grpcService.appProtocol }} appProtocol: {{ . }} - {{- end }} + {{- end }} selector: {{- include "netbird.server.selectorLabels" . | nindent 4 }} {{- end }} diff --git a/charts/netbird/templates/server-grpcroute.yaml b/charts/netbird/templates/server-grpcroute.yaml index 984d8c0..8190e10 100644 --- a/charts/netbird/templates/server-grpcroute.yaml +++ b/charts/netbird/templates/server-grpcroute.yaml @@ -1,17 +1,17 @@ {{- if .Values.server.grpcRoute.enabled }} -{{- $serviceName := include "netbird.server.fullname" . }} -{{- $backendName := $serviceName }} -{{- if .Values.server.grpcService.enabled }} - {{- $backendName = printf "%s-grpc" $serviceName }} -{{- end }} -{{- $rules := list }} -{{- range .Values.server.grpcRoute.rules }} - {{- $rule := deepCopy . }} - {{- if not (hasKey $rule "backendRefs") }} - {{- $_ := set $rule "backendRefs" (list (dict "name" $backendName "port" 80)) }} + {{- $serviceName := include "netbird.server.fullname" . }} + {{- $backendName := $serviceName }} + {{- if .Values.server.grpcService.enabled }} + {{- $backendName = printf "%s-grpc" $serviceName }} + {{- end }} + {{- $rules := list }} + {{- range .Values.server.grpcRoute.rules }} + {{- $rule := deepCopy . }} + {{- if not (hasKey $rule "backendRefs") }} + {{- $_ := set $rule "backendRefs" (list (dict "name" $backendName "port" 80)) }} + {{- end }} + {{- $rules = append $rules $rule }} {{- end }} - {{- $rules = append $rules $rule }} -{{- end }} apiVersion: gateway.networking.k8s.io/v1 kind: GRPCRoute metadata: @@ -19,9 +19,9 @@ metadata: namespace: {{ .Release.Namespace }} labels: {{- include "netbird.server.labels" . | nindent 4 }} - {{- with .Values.server.grpcRoute.labels }} + {{- with .Values.server.grpcRoute.labels }} {{- toYaml . | nindent 4 }} - {{- end }} + {{- end }} {{- with .Values.server.grpcRoute.annotations }} annotations: {{- toYaml . | nindent 4 }} diff --git a/charts/netbird/templates/server-httproute.yaml b/charts/netbird/templates/server-httproute.yaml index 945968d..732f48b 100644 --- a/charts/netbird/templates/server-httproute.yaml +++ b/charts/netbird/templates/server-httproute.yaml @@ -1,13 +1,13 @@ {{- if .Values.server.httpRoute.enabled }} -{{- $serviceName := include "netbird.server.fullname" . }} -{{- $rules := list }} -{{- range .Values.server.httpRoute.rules }} - {{- $rule := deepCopy . }} - {{- if not (hasKey $rule "backendRefs") }} - {{- $_ := set $rule "backendRefs" (list (dict "name" $serviceName "port" 80)) }} + {{- $serviceName := include "netbird.server.fullname" . }} + {{- $rules := list }} + {{- range .Values.server.httpRoute.rules }} + {{- $rule := deepCopy . }} + {{- if not (hasKey $rule "backendRefs") }} + {{- $_ := set $rule "backendRefs" (list (dict "name" $serviceName "port" 80)) }} + {{- end }} + {{- $rules = append $rules $rule }} {{- end }} - {{- $rules = append $rules $rule }} -{{- end }} apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: @@ -15,9 +15,9 @@ metadata: namespace: {{ .Release.Namespace }} labels: {{- include "netbird.server.labels" . | nindent 4 }} - {{- with .Values.server.httpRoute.labels }} + {{- with .Values.server.httpRoute.labels }} {{- toYaml . | nindent 4 }} - {{- end }} + {{- end }} {{- with .Values.server.httpRoute.annotations }} annotations: {{- toYaml . | nindent 4 }} diff --git a/charts/netbird/templates/server-relay-httproute.yaml b/charts/netbird/templates/server-relay-httproute.yaml index bffd239..7f9975e 100644 --- a/charts/netbird/templates/server-relay-httproute.yaml +++ b/charts/netbird/templates/server-relay-httproute.yaml @@ -1,17 +1,17 @@ {{- if .Values.server.relayHttpRoute.enabled }} -{{- $serviceName := include "netbird.server.fullname" . }} -{{- $backendName := $serviceName }} -{{- if .Values.server.relayService.enabled }} - {{- $backendName = printf "%s-relay" $serviceName }} -{{- end }} -{{- $rules := list }} -{{- range .Values.server.relayHttpRoute.rules }} - {{- $rule := deepCopy . }} - {{- if not (hasKey $rule "backendRefs") }} - {{- $_ := set $rule "backendRefs" (list (dict "name" $backendName "port" 80)) }} + {{- $serviceName := include "netbird.server.fullname" . }} + {{- $backendName := $serviceName }} + {{- if .Values.server.relayService.enabled }} + {{- $backendName = printf "%s-relay" $serviceName }} + {{- end }} + {{- $rules := list }} + {{- range .Values.server.relayHttpRoute.rules }} + {{- $rule := deepCopy . }} + {{- if not (hasKey $rule "backendRefs") }} + {{- $_ := set $rule "backendRefs" (list (dict "name" $backendName "port" 80)) }} + {{- end }} + {{- $rules = append $rules $rule }} {{- end }} - {{- $rules = append $rules $rule }} -{{- end }} apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: @@ -19,9 +19,9 @@ metadata: namespace: {{ .Release.Namespace }} labels: {{- include "netbird.server.labels" . | nindent 4 }} - {{- with .Values.server.relayHttpRoute.labels }} + {{- with .Values.server.relayHttpRoute.labels }} {{- toYaml . | nindent 4 }} - {{- end }} + {{- end }} {{- with .Values.server.relayHttpRoute.annotations }} annotations: {{- toYaml . | nindent 4 }} diff --git a/charts/netbird/templates/server-relay-service.yaml b/charts/netbird/templates/server-relay-service.yaml index 77129ec..9ae49fe 100644 --- a/charts/netbird/templates/server-relay-service.yaml +++ b/charts/netbird/templates/server-relay-service.yaml @@ -17,9 +17,9 @@ spec: port: {{ .Values.server.relayService.port }} targetPort: http protocol: TCP - {{- with .Values.server.relayService.appProtocol }} + {{- with .Values.server.relayService.appProtocol }} appProtocol: {{ . }} - {{- end }} + {{- end }} selector: {{- include "netbird.server.selectorLabels" . | nindent 4 }} {{- end }} diff --git a/charts/netbird/templates/server-relay-tcproute.yaml b/charts/netbird/templates/server-relay-tcproute.yaml index 8bff12f..70b8ed0 100644 --- a/charts/netbird/templates/server-relay-tcproute.yaml +++ b/charts/netbird/templates/server-relay-tcproute.yaml @@ -1,16 +1,16 @@ {{- if .Values.server.relayTcpRoute.enabled }} -{{- $serviceName := include "netbird.server.fullname" . }} -{{- $rules := list }} -{{- range .Values.server.relayTcpRoute.rules }} - {{- $rule := deepCopy . }} - {{- if not (hasKey $rule "backendRefs") }} - {{- $_ := set $rule "backendRefs" (list (dict "name" $serviceName "port" 80)) }} + {{- $serviceName := include "netbird.server.fullname" . }} + {{- $rules := list }} + {{- range .Values.server.relayTcpRoute.rules }} + {{- $rule := deepCopy . }} + {{- if not (hasKey $rule "backendRefs") }} + {{- $_ := set $rule "backendRefs" (list (dict "name" $serviceName "port" 80)) }} + {{- end }} + {{- $rules = append $rules $rule }} + {{- end }} + {{- if not $rules }} + {{- $rules = list (dict "backendRefs" (list (dict "name" $serviceName "port" 80))) }} {{- end }} - {{- $rules = append $rules $rule }} -{{- end }} -{{- if not $rules }} - {{- $rules = list (dict "backendRefs" (list (dict "name" $serviceName "port" 80))) }} -{{- end }} apiVersion: gateway.networking.k8s.io/v1alpha2 kind: TCPRoute metadata: @@ -18,9 +18,9 @@ metadata: namespace: {{ .Release.Namespace }} labels: {{- include "netbird.server.labels" . | nindent 4 }} - {{- with .Values.server.relayTcpRoute.labels }} + {{- with .Values.server.relayTcpRoute.labels }} {{- toYaml . | nindent 4 }} - {{- end }} + {{- end }} {{- with .Values.server.relayTcpRoute.annotations }} annotations: {{- toYaml . | nindent 4 }} diff --git a/charts/netbird/templates/server-stun-service.yaml b/charts/netbird/templates/server-stun-service.yaml index feb3af8..df1e66b 100644 --- a/charts/netbird/templates/server-stun-service.yaml +++ b/charts/netbird/templates/server-stun-service.yaml @@ -16,9 +16,9 @@ spec: port: {{ .Values.server.stunService.port }} targetPort: stun protocol: UDP - {{- if and (eq .Values.server.stunService.type "NodePort") (not (kindIs "invalid" .Values.server.stunService.nodePort)) }} +{{- if and (eq .Values.server.stunService.type "NodePort") (not (kindIs "invalid" .Values.server.stunService.nodePort)) }} nodePort: {{ .Values.server.stunService.nodePort }} - {{- end }} +{{- end }} selector: {{- include "netbird.server.selectorLabels" . | nindent 4 }}