From e2653d7c874d0489264b4ca423f8ee2c4bc8addd Mon Sep 17 00:00:00 2001 From: Pratapa Lakshmi Date: Mon, 16 Feb 2026 14:16:42 +0530 Subject: [PATCH 1/3] Implement Traefik ingress support in Plane-EE Helm chart - Updated values.yaml to switch ingressClass from 'nginx' to 'traefik-external'. - Added new ingress-traefik.yaml template for Traefik IngressRoute configuration. - Introduced traefik-middleware.yaml for request body size limiting middleware. - Modified existing ingress.yaml to conditionally render based on the selected ingressClass. --- .../templates/ingress-traefik.yaml | 84 +++++++++++++++++++ .../plane-enterprise/templates/ingress.yaml | 2 +- .../templates/traefik-middleware.yaml | 11 +++ charts/plane-enterprise/values.yaml | 3 +- 4 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 charts/plane-enterprise/templates/ingress-traefik.yaml create mode 100644 charts/plane-enterprise/templates/traefik-middleware.yaml diff --git a/charts/plane-enterprise/templates/ingress-traefik.yaml b/charts/plane-enterprise/templates/ingress-traefik.yaml new file mode 100644 index 0000000..52366f9 --- /dev/null +++ b/charts/plane-enterprise/templates/ingress-traefik.yaml @@ -0,0 +1,84 @@ +{{- if and .Values.ingress.enabled (eq .Values.ingress.ingressClass "traefik-external") .Values.license.licenseDomain }} + +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: {{ .Release.Name }}-ingress + namespace: {{ .Release.Namespace }} +spec: + entryPoints: + - websecure + + routes: + + # IMPORTANT: specific paths FIRST + + - match: Host(`{{ .Values.license.licenseDomain }}`) && PathPrefix(`/spaces/`) + kind: Rule + services: + - name: {{ .Release.Name }}-space + port: 3000 + + - match: Host(`{{ .Values.license.licenseDomain }}`) && PathPrefix(`/god-mode/`) + kind: Rule + services: + - name: {{ .Release.Name }}-admin + port: 3000 + + - match: Host(`{{ .Values.license.licenseDomain }}`) && PathPrefix(`/api/`) + kind: Rule + services: + - name: {{ .Release.Name }}-api + port: 8000 + + - match: Host(`{{ .Values.license.licenseDomain }}`) && PathPrefix(`/auth/`) + kind: Rule + services: + - name: {{ .Release.Name }}-api + port: 8000 + + - match: Host(`{{ .Values.license.licenseDomain }}`) && PathPrefix(`/graphql/`) + kind: Rule + services: + - name: {{ .Release.Name }}-api + port: 8000 + + - match: Host(`{{ .Values.license.licenseDomain }}`) && PathPrefix(`/marketplace/`) + kind: Rule + services: + - name: {{ .Release.Name }}-api + port: 8000 + + - match: Host(`{{ .Values.license.licenseDomain }}`) && PathPrefix(`/live/`) + kind: Rule + services: + - name: {{ .Release.Name }}-live + port: 3000 + + - match: Host(`{{ .Values.license.licenseDomain }}`) && PathPrefix(`/silo/`) + kind: Rule + services: + - name: {{ .Release.Name }}-silo + port: 3000 + + {{- if and .Values.services.minio.local_setup .Values.env.docstore_bucket }} + - match: Host(`{{ .Values.license.licenseDomain }}`) && PathPrefix(`/{{ .Values.env.docstore_bucket }}`) + kind: Rule + services: + - name: {{ .Release.Name }}-minio + port: 9000 + {{- end }} + + # LAST: catch all + - match: Host(`{{ .Values.license.licenseDomain }}`) && PathPrefix(`/`) + kind: Rule + middlewares: + - name: {{ .Release.Name }}-body-limit + services: + - name: {{ .Release.Name }}-web + port: 3000 + + tls: + secretName: {{ default (printf "%s-ssl-cert" .Release.Name) .Values.ssl.tls_secret_name }} + +{{- end }} \ No newline at end of file diff --git a/charts/plane-enterprise/templates/ingress.yaml b/charts/plane-enterprise/templates/ingress.yaml index 2225f0f..8895922 100644 --- a/charts/plane-enterprise/templates/ingress.yaml +++ b/charts/plane-enterprise/templates/ingress.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.ingress.enabled .Values.license.licenseDomain }} +{{- if and .Values.ingress.enabled (eq .Values.ingress.ingressClass "nginx") .Values.license.licenseDomain }} apiVersion: networking.k8s.io/v1 kind: Ingress diff --git a/charts/plane-enterprise/templates/traefik-middleware.yaml b/charts/plane-enterprise/templates/traefik-middleware.yaml new file mode 100644 index 0000000..1736fc6 --- /dev/null +++ b/charts/plane-enterprise/templates/traefik-middleware.yaml @@ -0,0 +1,11 @@ +{{- if and .Values.ingress.enabled (eq .Values.ingress.ingressClass "traefik-external") }} +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: {{ .Release.Name }}-body-limit + namespace: {{ .Release.Namespace }} +spec: + buffering: + maxRequestBodyBytes: 5242880 + +{{- end }} diff --git a/charts/plane-enterprise/values.yaml b/charts/plane-enterprise/values.yaml index ed7ddf4..abdc8b8 100644 --- a/charts/plane-enterprise/values.yaml +++ b/charts/plane-enterprise/values.yaml @@ -25,8 +25,9 @@ ingress: enabled: true minioHost: '' rabbitmqHost: '' - ingressClass: 'nginx' + # ingressClass: 'nginx' ingress_annotations: { "nginx.ingress.kubernetes.io/proxy-body-size": "5m" } + ingressClass: 'traefik-external' ssl: tls_secret_name: '' # If you have a custom TLS secret name From c526cee4f5519e2414d082fa49b09bc6467b24ee Mon Sep 17 00:00:00 2001 From: Pratapa Lakshmi Date: Mon, 16 Feb 2026 14:27:58 +0530 Subject: [PATCH 2/3] Update ingress configuration to switch from 'traefik-external' to 'traefik' in Plane-EE Helm chart - Modified values.yaml to set ingressClass to 'nginx' and commented out 'traefik'. - Updated ingress-traefik.yaml and traefik-middleware.yaml templates to reflect the new ingressClass condition. --- charts/plane-enterprise/templates/ingress-traefik.yaml | 2 +- charts/plane-enterprise/templates/traefik-middleware.yaml | 2 +- charts/plane-enterprise/values.yaml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/charts/plane-enterprise/templates/ingress-traefik.yaml b/charts/plane-enterprise/templates/ingress-traefik.yaml index 52366f9..f150bed 100644 --- a/charts/plane-enterprise/templates/ingress-traefik.yaml +++ b/charts/plane-enterprise/templates/ingress-traefik.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.ingress.enabled (eq .Values.ingress.ingressClass "traefik-external") .Values.license.licenseDomain }} +{{- if and .Values.ingress.enabled (eq .Values.ingress.ingressClass "traefik") .Values.license.licenseDomain }} apiVersion: traefik.io/v1alpha1 kind: IngressRoute diff --git a/charts/plane-enterprise/templates/traefik-middleware.yaml b/charts/plane-enterprise/templates/traefik-middleware.yaml index 1736fc6..ecc76bb 100644 --- a/charts/plane-enterprise/templates/traefik-middleware.yaml +++ b/charts/plane-enterprise/templates/traefik-middleware.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.ingress.enabled (eq .Values.ingress.ingressClass "traefik-external") }} +{{- if and .Values.ingress.enabled (eq .Values.ingress.ingressClass "traefik") }} apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: diff --git a/charts/plane-enterprise/values.yaml b/charts/plane-enterprise/values.yaml index abdc8b8..a7934f3 100644 --- a/charts/plane-enterprise/values.yaml +++ b/charts/plane-enterprise/values.yaml @@ -25,9 +25,9 @@ ingress: enabled: true minioHost: '' rabbitmqHost: '' - # ingressClass: 'nginx' + ingressClass: 'nginx' ingress_annotations: { "nginx.ingress.kubernetes.io/proxy-body-size": "5m" } - ingressClass: 'traefik-external' + # ingressClass: 'traefik' ssl: tls_secret_name: '' # If you have a custom TLS secret name From f4ab03cd0a0e895db0b6d6642fa251c7ddc956cb Mon Sep 17 00:00:00 2001 From: Pratapa Lakshmi Date: Mon, 16 Feb 2026 16:22:07 +0530 Subject: [PATCH 3/3] Add Traefik RBAC configuration for secret access in Plane-EE Helm chart - Introduced a new traefik-rbac.yaml template to define Role and RoleBinding for Traefik. - This configuration allows the Traefik controller to read secrets in the namespace, essential for loading TLS certificates referenced in IngressRoute. - The RBAC settings are conditionally applied based on the ingress configuration in values.yaml. --- .../templates/traefik-rbac.yaml | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 charts/plane-enterprise/templates/traefik-rbac.yaml diff --git a/charts/plane-enterprise/templates/traefik-rbac.yaml b/charts/plane-enterprise/templates/traefik-rbac.yaml new file mode 100644 index 0000000..4ccaab0 --- /dev/null +++ b/charts/plane-enterprise/templates/traefik-rbac.yaml @@ -0,0 +1,38 @@ +{{- $traefik := .Values.ingress.traefik | default dict }} +{{- if and .Values.ingress.enabled (eq .Values.ingress.ingressClass "traefik") ($traefik.createSecretReadRBAC) }} +# Role: allows reading secrets in this namespace (for TLS certs used by IngressRoute). +# RoleBinding: grants the Traefik controller's service account that permission. +# Required so Traefik can load the TLS certificate referenced in the IngressRoute. +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ .Release.Name }}-traefik-secret-reader + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: plane-enterprise + app.kubernetes.io/component: traefik-rbac + app.kubernetes.io/managed-by: helm +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ .Release.Name }}-traefik-secret-reader + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: plane-enterprise + app.kubernetes.io/component: traefik-rbac + app.kubernetes.io/managed-by: helm +subjects: +- kind: ServiceAccount + name: {{ $traefik.serviceAccountName | default "traefik" }} + namespace: {{ $traefik.serviceAccountNamespace | default "traefik" }} +roleRef: + kind: Role + name: {{ .Release.Name }}-traefik-secret-reader + apiGroup: rbac.authorization.k8s.io +{{- end }}