Skip to content
2 changes: 1 addition & 1 deletion charts/plane-enterprise/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Meet Plane. An Enterprise software development tool to manage issue

type: application

version: 3.5.4
version: 3.5.5
appVersion: "3.1.4"

home: https://plane.so/
Expand Down
217 changes: 192 additions & 25 deletions charts/plane-enterprise/README.md

Large diffs are not rendered by default.

11 changes: 7 additions & 4 deletions charts/plane-enterprise/examples/values-openshift.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,15 @@ services:
# -----------------------------------------------------------------------------
# Ingress
# -----------------------------------------------------------------------------
# 'openshift' renders one route.openshift.io/v1 Route per path, with the HAProxy
# timeout set explicitly. This is the only OpenShift ingress path the chart offers
# — 'openshift-default' (letting the ingress-to-route controller convert a plain
# Ingress) renders nothing, because templates/ingress.yaml is gated on 'nginx'.
# controller: 'openshift' renders one route.openshift.io/v1 Route per path, with
# the HAProxy timeout set explicitly. To let OpenShift's ingress-to-route
# controller convert a plain Ingress instead, set controller: 'nginx' with
# ingressClass: 'openshift-default' — the timeout below is then not applied.
# Note controller must be set for that: with it empty, 'openshift-default'
# renders no ingress at all.
ingress:
enabled: true
controller: 'openshift'
ingressClass: 'openshift'
openshift:
# The router default is 30s, which severs /live/'s collaborative-editing
Expand Down
9 changes: 8 additions & 1 deletion charts/plane-enterprise/questions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1714,8 +1714,15 @@ questions:
type: string
default: ""
show_if: "services.rabbitmq.local_setup=true"
- variable: ingress.controller
label: "Ingress Controller Type"
description: "Which kind of ingress resource to render. Supported: 'traefik' a Traefik IngressRoute, 'openshift' one OpenShift Route per path, 'nginx' a standard networking.k8s.io/v1 Ingress using the Ingress Classname below verbatim. REQUIRED when your class name is not exactly 'nginx', 'openshift' or 'traefik*' - left empty, any other class renders no ingress at all."
type: string
default: ""
show_if: "ingress.enabled=true"
- variable: ingress.ingressClass
label: "Ingress Classname"
description: "Class name written to the standard Ingress' spec.ingressClassName. Unused by the Traefik IngressRoute and by OpenShift Routes. While Ingress Controller Type above is empty this also selects which template renders, and only 'nginx', 'openshift' and 'traefik*' are recognised."
type: string
required: true
default: "nginx"
Expand Down Expand Up @@ -1773,7 +1780,7 @@ questions:

- variable: ingress.traefik.entryPoints
label: "Traefik Entrypoints Override"
description: "Traefik entrypoints the IngressRoute binds to, e.g. 'websecure'. Leave empty to derive from the SSL settings (websecure when this chart manages a certificate, otherwise web). Required as 'websecure' when TLS is terminated by Traefik's own entrypoint. Ignored unless the ingress class is traefik."
description: "Traefik entrypoints the IngressRoute binds to, e.g. 'websecure'. Leave empty to derive from the SSL settings (websecure when this chart manages a certificate, otherwise web). Required as 'websecure' when TLS is terminated by Traefik's own entrypoint. Ignored unless the controller resolves to traefik."
type: string
default: ""
group: "Ingress"
Expand Down
35 changes: 35 additions & 0 deletions charts/plane-enterprise/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,41 @@ of the local_setup flag's value.
{{- end -}}
{{- end -}}

{{/*
Selects which ingress template renders, decoupling the controller *type* (which
resource kind to emit) from the ingress *class name* (a free-form string).
Returns "traefik" (IngressRoute), "openshift" (Route per path), "ingress"
(networking.k8s.io/v1 Ingress, i.e. ingress-nginx) or "none" (render nothing).

ingress.controller decides when set: "traefik*" -> traefik, "openshift" ->
openshift, anything else -> a standard Ingress, whatever the class name is. That
last case exists so a non-"nginx" class name can still be served, e.g.
controller "nginx" with ingressClass "nginx-new".

When ingress.controller is EMPTY the selection is the pre-3.5.5 one, exactly:
only "traefik*", "openshift" and "nginx" are recognised and any other class
returns "none", rendering no ingress. That silent no-op is kept deliberately --
widening it would make an upgrade create a <release>-ingress for operators who
are on such a class today and already run an ingress of their own. Set
ingress.controller to opt into the standard Ingress for any class name.
*/}}
{{- define "plane.ingressController" -}}
{{- $c := .Values.ingress.controller | default "" | trim | lower -}}
{{- if $c -}}
{{- if hasPrefix "traefik" $c -}}traefik
{{- else if eq $c "openshift" -}}openshift
{{- else -}}ingress
{{- end -}}
{{- else -}}
{{- $k := .Values.ingress.ingressClass | default "" -}}
{{- if hasPrefix "traefik" $k -}}traefik
{{- else if eq $k "openshift" -}}openshift
{{- else if eq $k "nginx" -}}ingress
{{- else -}}none
{{- end -}}
{{- end -}}
{{- end -}}

{{/*
Normalize the deprecated s3SecretName/s3SecretKey into the s3Secrets list format.
Returns "true" when airgapped is enabled and at least one CA secret is configured.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
{{/*
Standard networking.k8s.io/v1 Ingress. Gated on ingressClass being exactly
"nginx"; the other templates are ingress-traefik.yaml ("traefik*") and
ingress-openshift.yaml ("openshift").
Standard networking.k8s.io/v1 Ingress, for ingress-nginx. Which of the three
ingress templates renders is decided by the "plane.ingressController" helper, not
by ingressClass directly.

NOTE: any other class (alb, haproxy, contour, openshift-default, a custom
IngressClass name, ...) renders nothing at all, with no error -- despite the
README describing this template as the fallback for "any other value". That
mismatch is deliberately left as-is for now and tracked separately; do not widen
this condition without checking what else assumes the nginx-only behaviour.
The resource itself is controller-agnostic, so setting ingress.controller to
something other than traefik/openshift also renders from here -- that is how a
non-"nginx" class name such as "nginx-new" is served. Only nginx, Traefik and
OpenShift are supported configurations.
*/}}
{{- if and .Values.ingress.enabled (eq .Values.ingress.ingressClass "nginx") .Values.license.licenseDomain }}
{{- if and .Values.ingress.enabled (eq (include "plane.ingressController" .) "ingress") .Values.license.licenseDomain }}

apiVersion: networking.k8s.io/v1
kind: Ingress
Expand Down
19 changes: 10 additions & 9 deletions charts/plane-enterprise/templates/ingress-openshift.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@
================================================================================
OpenShift ingress: one route.openshift.io/v1 Route per path.
================================================================================
Rendered when ingress.ingressClass == "openshift".
Rendered when "plane.ingressController" resolves to "openshift", i.e.
ingress.controller (or, unset, ingress.ingressClass) is "openshift".

Why explicit Routes rather than a plain Ingress:

OpenShift's ingress-to-route controller can convert a networking.k8s.io/v1
Ingress into Routes. This chart does not offer that path: templates/ingress.yaml
is gated on ingressClass == "nginx", so setting "openshift-default" renders
nothing. Declaring the Routes here is also the more predictable option — the
conversion only picks up an Ingress whose class maps to the
Ingress into Routes, but declaring the Routes here is the more predictable
option — the conversion only picks up an Ingress whose class maps to the
openshift.io/ingress-to-route controller, and whether per-path HAProxy
annotations survive it varies by OCP version. Plane needs the timeout below, so
there is no guesswork this way.
there is no guesswork this way. (If you do want that path, set
ingress.controller to "nginx" with ingressClass "openshift-default" and the
standard Ingress renders instead.)

Differences from the Traefik IngressRoute this mirrors:

Expand All @@ -26,7 +27,7 @@ Differences from the Traefik IngressRoute this mirrors:
- Path-based Routes require edge or reencrypt TLS termination; they are not
supported with passthrough.
*/}}
{{- if and .Values.ingress.enabled (eq .Values.ingress.ingressClass "openshift") .Values.license.licenseDomain }}
{{- if and .Values.ingress.enabled (eq (include "plane.ingressController" .) "openshift") .Values.license.licenseDomain }}
{{- $host := .Values.license.licenseDomain }}
{{- $name := .Release.Name }}
{{- $oc := .Values.ingress.openshift | default dict }}
Expand All @@ -40,7 +41,7 @@ Differences from the Traefik IngressRoute this mirrors:
{{- fail (printf "ingress.openshift.termination must be \"edge\" or \"reencrypt\", got %q. Path-based Routes cannot use passthrough termination; see charts/plane-enterprise/README.md." $termination) }}
{{- end }}

{{/* Same path -> service mapping as templates/ingress.yaml, most specific first
{{/* Same path -> service mapping as templates/ingress-nginx.yaml, most specific first
(ordering is cosmetic here, kept aligned so the two are easy to diff). */}}
{{- $routes := list
(dict "slug" "spaces" "path" "/spaces/" "svc" (printf "%s-space" $name) "port" 3000)
Expand All @@ -64,7 +65,7 @@ Differences from the Traefik IngressRoute this mirrors:
{{- $routes = append $routes (dict "slug" "web" "path" "/" "svc" (printf "%s-web" $name) "port" 3000) }}

{{/* The bundled MinIO console and RabbitMQ management UI live on their own hosts,
matching templates/ingress.yaml. Both are gated on the corresponding
matching templates/ingress-nginx.yaml. Both are gated on the corresponding
local_setup, so neither renders in the recommended OpenShift configuration
(where the bundled datastores are off because they cannot run under an
arbitrary UID) -- they are here for a cluster that grants those workloads a
Expand Down
2 changes: 1 addition & 1 deletion charts/plane-enterprise/templates/ingress-traefik.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if and .Values.ingress.enabled (hasPrefix "traefik" .Values.ingress.ingressClass) .Values.license.licenseDomain }}
{{- if and .Values.ingress.enabled (eq (include "plane.ingressController" .) "traefik") .Values.license.licenseDomain }}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
Expand Down
2 changes: 1 addition & 1 deletion charts/plane-enterprise/templates/traefik-middleware.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if and .Values.ingress.enabled (hasPrefix "traefik" .Values.ingress.ingressClass) }}
{{- if and .Values.ingress.enabled (eq (include "plane.ingressController" .) "traefik") .Values.license.licenseDomain }}
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
Expand Down
34 changes: 24 additions & 10 deletions charts/plane-enterprise/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,30 @@ ingress:
enabled: true
minioHost: ''
rabbitmqHost: ''
# Selects which ingress template is rendered:
# 'traefik*' -> Traefik IngressRoute CRD (templates/ingress-traefik.yaml)
# 'openshift' -> OpenShift Route per path (templates/ingress-openshift.yaml)
# 'nginx' -> networking.k8s.io/v1 Ingress (templates/ingress.yaml)
# Any OTHER value renders no ingress at all -- see the note in templates/ingress.yaml.
# controller selects WHICH KIND of ingress resource is rendered, decoupled from
# the class name below. Supported: nginx, traefik and openshift. When set:
# 'traefik' -> Traefik IngressRoute CRD (templates/ingress-traefik.yaml)
# 'openshift' -> one OpenShift Route per path (templates/ingress-openshift.yaml)
# 'nginx' (or any other value)
# -> networking.k8s.io/v1 Ingress (templates/ingress-nginx.yaml),
# with ingressClass below used verbatim as spec.ingressClassName.
# Leave it empty and the legacy selection applies, unchanged: only a class of
# 'traefik*', 'openshift' or 'nginx' renders anything, and ANY OTHER class
# renders no ingress at all, silently. That is kept so upgrades never create an
# ingress where the chart previously created none.
# => Set controller when your class name is not exactly 'nginx', 'openshift' or
# 'traefik*' -- e.g. controller 'nginx' with ingressClass 'nginx-new'.
controller: ''
# ingressClass is the free-form class name written to the standard Ingress'
# spec.ingressClassName. Unused on the traefik and openshift paths, since
# neither an IngressRoute nor a Route carries a class name. It also drives the
# legacy selection above while controller is empty.
ingressClass: 'traefik'
# Annotations for the standard Ingress — e.g. to set the proxy body size limit on
# the nginx controller. ONLY rendered when ingressClass is exactly 'nginx'; they
# have no effect with traefik, and the 'openshift' Route path takes its
# annotations from ingress.openshift.route_annotations instead. Example:
# Annotations for the standard Ingress — e.g. to set the proxy body size limit
# on the nginx controller. Rendered onto the standard Ingress only; they have no
# effect with traefik (use ingress.traefik.maxRequestBodyBytes) and the openshift
# path takes its annotations from ingress.openshift.route_annotations instead.
# Example for ingress-nginx:
# - proxy-body-size: nginx equivalent of traefik's maxRequestBodyBytes (upload size limit).
# - proxy-buffer-size: size of the buffer for the response headers from upstream; bump this to avoid
# "502 upstream sent too big header" errors.
Expand All @@ -64,7 +78,7 @@ ingress:
# Set explicitly only if your Traefik install renamed the default entrypoints,
# e.g. entryPoints: ['websecure', 'web'] or ['https'].
entryPoints: []
# Only read when ingressClass is 'openshift'.
# Only read on the openshift path (see controller above).
openshift:
# HAProxy's per-route timeout. The router default is 30s, which severs
# /live/'s collaborative-editing WebSockets and /pi/'s streaming responses.
Expand Down