From b1c8163f65f0a4c8e721c86d3afbf24d8fb5abb3 Mon Sep 17 00:00:00 2001 From: Maxime Vidori Date: Tue, 16 Jun 2026 09:41:18 +0200 Subject: [PATCH] feat(charts): support topologySpreadConstraints on every deployment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an optional topologySpreadConstraints value to every chart that renders a standard Kubernetes Deployment, alongside the existing nodeSelector, tolerations, and affinity scheduling fields. The value defaults to [] and is rendered only when non-empty, so existing manifests are unchanged. Affected charts: - lago-rails (api / clock / *-worker releases) - lago-front - lago-pdf (under .gotenberg.topologySpreadConstraints) - lago-mcp-server - lago-data-api - lago-data-worker - lago-events-processor-worker Also extend tests-common/deployment/common_patterns_test.yaml so every deployment chart that consumes the shared test suite asserts that topologySpreadConstraints render through to the pod spec. lago-data-rev-rec is intentionally skipped — it renders a FlinkDeployment (Flink operator CR), not a standard Deployment, and currently exposes no scheduling fields at all. Adding spread support there is a separate change. --- charts/lago-data-api/README.md | 1 + .../lago-data-api/templates/deployment.yaml | 4 +++ charts/lago-data-api/values.yaml | 4 +++ charts/lago-data-worker/README.md | 1 + .../templates/deployment.yaml | 4 +++ charts/lago-data-worker/values.yaml | 4 +++ charts/lago-events-processor-worker/README.md | 1 + .../templates/deployment.yaml | 4 +++ .../lago-events-processor-worker/values.yaml | 4 +++ charts/lago-front/README.md | 1 + charts/lago-front/templates/deployment.yaml | 4 +++ charts/lago-front/values.yaml | 4 +++ charts/lago-mcp-server/README.md | 1 + .../lago-mcp-server/templates/deployment.yaml | 4 +++ charts/lago-mcp-server/values.yaml | 4 +++ charts/lago-pdf/README.md | 1 + charts/lago-pdf/templates/deployment.yaml | 4 +++ charts/lago-pdf/values.yaml | 4 +++ charts/lago-rails/README.md | 1 + charts/lago-rails/templates/deployment.yaml | 4 +++ charts/lago-rails/values.yaml | 4 +++ .../deployment/common_patterns_test.yaml | 34 +++++++++++++++++++ 22 files changed, 97 insertions(+) diff --git a/charts/lago-data-api/README.md b/charts/lago-data-api/README.md index d4ceb820..add751e7 100644 --- a/charts/lago-data-api/README.md +++ b/charts/lago-data-api/README.md @@ -99,6 +99,7 @@ A Helm chart for Kubernetes | nodeSelector | object | `{}` | Node selector constraints | | tolerations | list | `[]` | Pod tolerations | | affinity | object | `{}` | Pod affinity rules | +| topologySpreadConstraints | list | `[]` | Pod topology spread constraints | ### Service diff --git a/charts/lago-data-api/templates/deployment.yaml b/charts/lago-data-api/templates/deployment.yaml index 53fff596..ed59bf1f 100644 --- a/charts/lago-data-api/templates/deployment.yaml +++ b/charts/lago-data-api/templates/deployment.yaml @@ -142,6 +142,10 @@ spec: affinity: {{- toYaml . | nindent 8 }} {{- end }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} diff --git a/charts/lago-data-api/values.yaml b/charts/lago-data-api/values.yaml index bb609cc7..2e784a26 100644 --- a/charts/lago-data-api/values.yaml +++ b/charts/lago-data-api/values.yaml @@ -254,6 +254,10 @@ tolerations: [] # @section -- Pod affinity: {} +# -- Pod topology spread constraints +# @section -- Pod +topologySpreadConstraints: [] + # -- Array of extra K8s manifests to deploy # @section -- Extra Objects extraObjects: [] diff --git a/charts/lago-data-worker/README.md b/charts/lago-data-worker/README.md index a0166d61..17e4a045 100644 --- a/charts/lago-data-worker/README.md +++ b/charts/lago-data-worker/README.md @@ -117,6 +117,7 @@ A Helm chart for Kubernetes | nodeSelector | object | `{}` | Node selector constraints | | tolerations | list | `[]` | Pod tolerations | | affinity | object | `{}` | Pod affinity rules | +| topologySpreadConstraints | list | `[]` | Pod topology spread constraints | ### Autoscaling diff --git a/charts/lago-data-worker/templates/deployment.yaml b/charts/lago-data-worker/templates/deployment.yaml index 28c7f6a8..c326137d 100644 --- a/charts/lago-data-worker/templates/deployment.yaml +++ b/charts/lago-data-worker/templates/deployment.yaml @@ -132,6 +132,10 @@ spec: affinity: {{- toYaml . | nindent 8 }} {{- end }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} diff --git a/charts/lago-data-worker/values.yaml b/charts/lago-data-worker/values.yaml index a44b7113..d055cb86 100644 --- a/charts/lago-data-worker/values.yaml +++ b/charts/lago-data-worker/values.yaml @@ -206,3 +206,7 @@ tolerations: [] # -- Pod affinity rules # @section -- Pod affinity: {} + +# -- Pod topology spread constraints +# @section -- Pod +topologySpreadConstraints: [] diff --git a/charts/lago-events-processor-worker/README.md b/charts/lago-events-processor-worker/README.md index f0799a5d..3dbe1f35 100644 --- a/charts/lago-events-processor-worker/README.md +++ b/charts/lago-events-processor-worker/README.md @@ -77,6 +77,7 @@ A Helm chart for Kubernetes | nodeSelector | object | `{}` | Node selector constraints | | tolerations | list | `[]` | Pod tolerations | | affinity | object | `{}` | Pod affinity rules | +| topologySpreadConstraints | list | `[]` | Pod topology spread constraints | ### Autoscaling diff --git a/charts/lago-events-processor-worker/templates/deployment.yaml b/charts/lago-events-processor-worker/templates/deployment.yaml index b1422dc8..687af69e 100644 --- a/charts/lago-events-processor-worker/templates/deployment.yaml +++ b/charts/lago-events-processor-worker/templates/deployment.yaml @@ -130,6 +130,10 @@ spec: affinity: {{- toYaml . | nindent 8 }} {{- end }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} diff --git a/charts/lago-events-processor-worker/values.yaml b/charts/lago-events-processor-worker/values.yaml index aec51467..29dcf4a8 100644 --- a/charts/lago-events-processor-worker/values.yaml +++ b/charts/lago-events-processor-worker/values.yaml @@ -249,6 +249,10 @@ tolerations: [] # @section -- Pod affinity: {} +# -- Pod topology spread constraints +# @section -- Pod +topologySpreadConstraints: [] + # -- Array of extra K8s manifests to deploy # @section -- Extra Objects extraObjects: [] diff --git a/charts/lago-front/README.md b/charts/lago-front/README.md index 7b9fce8f..0c75bf39 100644 --- a/charts/lago-front/README.md +++ b/charts/lago-front/README.md @@ -105,6 +105,7 @@ A Helm chart for Kubernetes | nodeSelector | object | `{}` | Node selector constraints | | tolerations | list | `[]` | Pod tolerations | | affinity | object | `{}` | Pod affinity rules | +| topologySpreadConstraints | list | `[]` | Pod topology spread constraints | ### Service diff --git a/charts/lago-front/templates/deployment.yaml b/charts/lago-front/templates/deployment.yaml index 0d637cc9..98cc41a1 100644 --- a/charts/lago-front/templates/deployment.yaml +++ b/charts/lago-front/templates/deployment.yaml @@ -117,6 +117,10 @@ spec: affinity: {{- toYaml . | nindent 8 }} {{- end }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} diff --git a/charts/lago-front/values.yaml b/charts/lago-front/values.yaml index 2eac8695..2d42cf50 100644 --- a/charts/lago-front/values.yaml +++ b/charts/lago-front/values.yaml @@ -260,6 +260,10 @@ tolerations: [] # @section -- Pod affinity: {} +# -- Pod topology spread constraints +# @section -- Pod +topologySpreadConstraints: [] + # -- Array of extra K8s manifests to deploy # @section -- Extra Objects extraObjects: [] diff --git a/charts/lago-mcp-server/README.md b/charts/lago-mcp-server/README.md index 6bac185f..b82451e1 100644 --- a/charts/lago-mcp-server/README.md +++ b/charts/lago-mcp-server/README.md @@ -82,6 +82,7 @@ A Helm chart for Kubernetes | nodeSelector | object | `{}` | Node selector constraints | | tolerations | list | `[]` | Pod tolerations | | affinity | object | `{}` | Pod affinity rules | +| topologySpreadConstraints | list | `[]` | Pod topology spread constraints | ---------------------------------------------- Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/charts/lago-mcp-server/templates/deployment.yaml b/charts/lago-mcp-server/templates/deployment.yaml index db7de34d..49312983 100644 --- a/charts/lago-mcp-server/templates/deployment.yaml +++ b/charts/lago-mcp-server/templates/deployment.yaml @@ -100,6 +100,10 @@ spec: affinity: {{- toYaml . | nindent 8 }} {{- end }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} diff --git a/charts/lago-mcp-server/values.yaml b/charts/lago-mcp-server/values.yaml index 04261277..801a988a 100644 --- a/charts/lago-mcp-server/values.yaml +++ b/charts/lago-mcp-server/values.yaml @@ -142,3 +142,7 @@ tolerations: [] # -- Pod affinity rules # @section -- Pod affinity: {} + +# -- Pod topology spread constraints +# @section -- Pod +topologySpreadConstraints: [] diff --git a/charts/lago-pdf/README.md b/charts/lago-pdf/README.md index dcda044e..2753719d 100644 --- a/charts/lago-pdf/README.md +++ b/charts/lago-pdf/README.md @@ -75,6 +75,7 @@ A Helm chart for the Lago PDF stack (Gotenberg + optional Rails worker) | gotenberg.nodeSelector | object | `{}` | Node selector constraints | | gotenberg.tolerations | list | `[]` | Pod tolerations | | gotenberg.affinity | object | `{}` | Pod affinity rules | +| gotenberg.topologySpreadConstraints | list | `[]` | Pod topology spread constraints | | gotenberg.imagePullSecrets | list | `[]` | Image pull secrets for private registries | | gotenberg.nameOverride | string | `""` | Override the Gotenberg chart name | | gotenberg.fullnameOverride | string | `""` | Override the Gotenberg full release name | diff --git a/charts/lago-pdf/templates/deployment.yaml b/charts/lago-pdf/templates/deployment.yaml index de7d518d..0e31df0e 100644 --- a/charts/lago-pdf/templates/deployment.yaml +++ b/charts/lago-pdf/templates/deployment.yaml @@ -94,6 +94,10 @@ spec: affinity: {{- toYaml . | nindent 8 }} {{- end }} + {{- with .Values.gotenberg.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} {{- with .Values.gotenberg.tolerations }} tolerations: {{- toYaml . | nindent 8 }} diff --git a/charts/lago-pdf/values.yaml b/charts/lago-pdf/values.yaml index 346f13c5..1f2a4bc8 100644 --- a/charts/lago-pdf/values.yaml +++ b/charts/lago-pdf/values.yaml @@ -482,6 +482,10 @@ gotenberg: # @section -- Gotenberg affinity: {} + # -- Pod topology spread constraints + # @section -- Gotenberg + topologySpreadConstraints: [] + # -- Image pull secrets for private registries # @section -- Gotenberg imagePullSecrets: [] diff --git a/charts/lago-rails/README.md b/charts/lago-rails/README.md index 4fa69f89..296f948e 100644 --- a/charts/lago-rails/README.md +++ b/charts/lago-rails/README.md @@ -90,6 +90,7 @@ A Helm chart for Kubernetes | nodeSelector | object | `{}` | Node selector constraints | | tolerations | list | `[]` | Pod tolerations | | affinity | object | `{}` | Pod affinity rules | +| topologySpreadConstraints | list | `[]` | Pod topology spread constraints | ### Service diff --git a/charts/lago-rails/templates/deployment.yaml b/charts/lago-rails/templates/deployment.yaml index b9fafcf7..041a3311 100644 --- a/charts/lago-rails/templates/deployment.yaml +++ b/charts/lago-rails/templates/deployment.yaml @@ -357,6 +357,10 @@ spec: affinity: {{- toYaml . | nindent 8 }} {{- end }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} diff --git a/charts/lago-rails/values.yaml b/charts/lago-rails/values.yaml index 88c97087..08677f62 100644 --- a/charts/lago-rails/values.yaml +++ b/charts/lago-rails/values.yaml @@ -594,6 +594,10 @@ tolerations: [] # @section -- Pod affinity: {} +# -- Pod topology spread constraints +# @section -- Pod +topologySpreadConstraints: [] + # -- Array of extra K8s manifests to deploy # @section -- Extra Objects extraObjects: [] diff --git a/tests-common/deployment/common_patterns_test.yaml b/tests-common/deployment/common_patterns_test.yaml index eeb9b94c..e58c86ee 100644 --- a/tests-common/deployment/common_patterns_test.yaml +++ b/tests-common/deployment/common_patterns_test.yaml @@ -109,6 +109,40 @@ tests: - notExists: path: spec.template.spec.containers[0].resources + # ============================================================================ + # topologySpreadConstraints Tests + # ============================================================================ + - it: should include topologySpreadConstraints when specified + values: + - ./fixtures/required.yaml + set: + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + app.kubernetes.io/name: test-app + asserts: + - equal: + path: spec.template.spec.topologySpreadConstraints[0].maxSkew + value: 1 + - equal: + path: spec.template.spec.topologySpreadConstraints[0].topologyKey + value: kubernetes.io/hostname + - equal: + path: spec.template.spec.topologySpreadConstraints[0].whenUnsatisfiable + value: DoNotSchedule + + - it: should not include topologySpreadConstraints when empty + values: + - ./fixtures/required.yaml + set: + topologySpreadConstraints: [] + asserts: + - notExists: + path: spec.template.spec.topologySpreadConstraints + # ============================================================================ # Combined Test - All Common Patterns # ============================================================================