Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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: 2.6.2
version: 2.6.3
appVersion: "2.6.3"

home: https://plane.so/
Expand Down
48 changes: 35 additions & 13 deletions charts/plane-enterprise/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,42 @@ If you plan to use Traefik as your ingress controller, install it before deployi

## Migrating the Ingress Controller

The chart selects between two ingress templates based on `ingress.ingressClass`:
The chart renders one of two ingress templates. **Which one** is chosen by the
*controller type* — kept separate from the *class name* so atypical class names
(e.g. `nginx-new`) work without changing template selection.

| `ingressClass` value | Template rendered | Resource kind |
| ------------------------------ | -------------------------------- | ---------------------------------- |
| `traefik` (or starts with it) | `templates/ingress-traefik.yaml` | `traefik.io/v1alpha1 IngressRoute` |
| Any other value (e.g. `nginx`) | `templates/ingress.yaml` | `networking.k8s.io/v1 Ingress` |
`ingress.controller` selects the resource kind:

The default value is `"traefik"`. If you are switching to a standard ingress controller such as nginx, follow the migration steps below.
| `ingress.controller` value | Template rendered | Resource kind |
| ------------------------------------- | -------------------------------- | ---------------------------------- |
| `traefik` | `templates/ingress-traefik.yaml` | `traefik.io/v1alpha1 IngressRoute` |
| Any other value (`nginx`, `f5`, ...) | `templates/ingress.yaml` | `networking.k8s.io/v1 Ingress` |

> The standard `Ingress` path covers **any** standard Kubernetes ingress controller —
> ingress-nginx, F5 NGINX, HAProxy, etc. The value is just a selector; it is not
> written anywhere. The actual class name comes from `ingress.ingressClass`
> (`spec.ingressClassName`), which can be any string your controller exposes.

If `ingress.controller` is left empty, the controller is **auto-detected** from
`ingress.ingressClass` for backward compatibility: a value starting with `traefik`
selects Traefik, anything else selects the standard `Ingress`. Set
`ingress.controller` explicitly to use a non-`nginx` class name like `nginx-new`
(which previously was silently dropped).

The default is a Traefik `IngressRoute` (`ingressClass: traefik`, controller
auto-detected). If you are switching to a standard ingress controller, follow the
migration steps below.

### Switching from Traefik to a standard Ingress controller (e.g. nginx)

1. **Install your target ingress controller** if it is not already running.

2. **Update `ingress.ingressClass`** in your `values.yaml`:
2. **Set `ingress.controller` and `ingress.ingressClass`** in your `values.yaml`:

```yaml
ingress:
ingressClass: "nginx" # or whichever class your controller exposes
controller: "nginx" # selects the standard Ingress template (any value but "traefik")
ingressClass: "nginx" # spec.ingressClassName — whichever class your controller exposes (e.g. "nginx-new")
```

3. **Run `helm upgrade`**:
Expand All @@ -69,11 +87,12 @@ The default value is `"traefik"`. If you are switching to a standard ingress con

1. **Install Traefik** with CRD support enabled (see [Installing Traefik Ingress Controller](#installing-traefik-ingress-controller-optional) above).

2. **Update `ingress.ingressClass`**:
2. **Set `ingress.controller`**:

```yaml
ingress:
ingressClass: "traefik"
controller: "traefik"
ingressClass: "traefik" # unused by the IngressRoute, kept for clarity
```

3. **Run `helm upgrade`**. The old `Ingress` resource is orphaned — delete it:
Expand All @@ -87,9 +106,10 @@ The default value is `"traefik"`. If you are switching to a standard ingress con
| Value | Default | Effect |
| ------------------------------------- | ---------- | ----------------------------------------------------------------------------------------- |
| `ingress.enabled` | `true` | Master switch — set to `false` to render neither template. |
| `ingress.ingressClass` | `traefik` | Selects which template is active (see table above). |
| `ingress.controller` | `''` | Selects the resource kind: `traefik` → IngressRoute, anything else → standard `Ingress`. Empty = auto-detect from `ingressClass`. |
| `ingress.ingressClass` | `traefik` | Free-form `spec.ingressClassName` on the standard `Ingress`. Also drives auto-detection when `controller` is empty. Unused by Traefik. |
| `ingress.traefik.maxRequestBodyBytes` | `20971520` | Max request body size for Traefik's buffering middleware. Ignored when not using Traefik. |
| `ingress.ingress_annotations` | `{}` | Standard `Ingress` annotations. Ignored when `ingressClass` starts with `traefik`. |
| `ingress.ingress_annotations` | `{}` | Standard `Ingress` annotations (e.g. cert-manager). Rendered only on the standard `Ingress`; ignored when `controller` resolves to `traefik`. |

## Installing Plane

Expand Down Expand Up @@ -158,6 +178,7 @@ The default value is `"traefik"`. If you are switching to a standard ingress con
- `planeVersion: v2.6.3 <or the last released version>`
- `license.licenseDomain: <The domain you have specified to host Plane>`
- `ingress.enabled: <true | false>`
- `ingress.controller: <traefik | nginx | ... — leave empty to auto-detect from ingressClass>`
- `ingress.ingressClass: <traefik or any other ingress class configured in your cluster>`
- `env.storageClass: <default storage class configured in your cluster>`

Expand Down Expand Up @@ -760,7 +781,8 @@ Note: When the email service is enabled, the cert-issuer will be automatically c
| ingress.enabled | true | | Ingress setup in kubernetes is a common practice to expose application to the intended audience. Set it to `false` if you are using external ingress providers like `Cloudflare` |
| ingress.minioHost | | | Based on above configuration, if you want to expose the `minio` web console to set of users, use this key to set the `host` mapping or leave it as `EMPTY` to not expose interface. |
| ingress.rabbitmqHost | | | Based on above configuration, if you want to expose the `rabbitmq` web console to set of users, use this key to set the `host` mapping or leave it as `EMPTY` to not expose interface. |
| ingress.ingressClass | nginx | Yes | Kubernetes cluster setup comes with various options of `ingressClass`. Based on your setup, set this value to the right one (eg. nginx, traefik, etc). Leave it to default in case you are using external ingress provider. |
| ingress.controller | | | Selects the ingress resource kind: `traefik` renders a Traefik `IngressRoute`; any other value (`nginx`, `f5`, `haproxy`, ...) renders a standard `Ingress`. Leave empty to auto-detect from `ingressClass`. Set explicitly for atypical class names (e.g. `nginx-new`). |
| ingress.ingressClass | traefik | Yes | Free-form class name written to the standard `Ingress` `spec.ingressClassName` (eg. nginx, traefik, nginx-new, etc). When `controller` is empty it also drives auto-detection. Unused by the Traefik `IngressRoute`. |
| ingress.ingress_annotations | `{ "nginx.ingress.kubernetes.io/proxy-body-size": "5m" }` | | Ingress controllers comes with various configuration options which can be passed as annotations. Setting this value lets you change the default value to user required. |
| ssl.createIssuer | false | | Kubernets cluster setup supports creating `issuer` type resource. After deployment, this is step towards creating secure access to the ingress url. Issuer is required for you generate SSL certifiate. Kubernetes can be configured to use any of the certificate authority to generate SSL (depending on CertManager configuration). Set it to `true` to create the issuer. Applicable only when `ingress.enabled=true` |
| ssl.issuer | http | | CertManager configuration allows user to create issuers using `http` or any of the other DNS Providers like `cloudflare`, `digitalocean`, etc. As of now Plane supports `http`, `cloudflare`, `digitalocean` |
Expand Down
2 changes: 1 addition & 1 deletion charts/plane-enterprise/questions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1420,7 +1420,7 @@ questions:
label: "Ingress Classname"
type: string
required: true
default: "nginx"
default: "traefik"
show_if: "ingress.enabled=true"

- variable: ssl.createIssuer
Expand Down
30 changes: 30 additions & 0 deletions charts/plane-enterprise/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,36 @@ 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 one of:
- "traefik" -> templates/ingress-traefik.yaml emits a traefik.io/v1alpha1 IngressRoute
- "ingress" -> templates/ingress.yaml emits a networking.k8s.io/v1 Ingress
(nginx, F5 NGINX, HAProxy, or any other standard controller)

Resolution order:
1. If ingress.controller is set explicitly, it wins. Only the literal value
"traefik" selects the IngressRoute path; any other value (e.g. "nginx",
"f5", "haproxy") selects the standard Ingress path. This lets atypical
class names like "nginx-new" be used without affecting template selection.
2. Otherwise (legacy behavior) the choice is inferred from ingress.ingressClass:
a value starting with "traefik" selects Traefik, anything else selects the
standard Ingress. Set ingress.controller to override the inference (e.g. a
standard Ingress whose ingressClassName happens to start with "traefik").
*/}}
{{- define "plane.ingressController" -}}
{{- $c := .Values.ingress.controller | default "" | lower | trim -}}
{{- if $c -}}
{{- if eq $c "traefik" -}}traefik{{- else -}}ingress{{- end -}}
{{- else if hasPrefix "traefik" (.Values.ingress.ingressClass | default "" | lower) -}}
traefik
{{- else -}}
ingress
{{- 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
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
6 changes: 3 additions & 3 deletions charts/plane-enterprise/templates/ingress.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{{- 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
metadata:
namespace: {{ .Release.Namespace }}
name: {{ .Release.Name }}-ingress
{{- if gt (len .Values.ingress.ingress_annotations) 0 }}
{{- with .Values.ingress.ingress_annotations }}
annotations:
{{- range $key, $value := .Values.ingress.ingress_annotations }}
{{- range $key, $value := . }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- end }}
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") }}
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
Expand Down
18 changes: 15 additions & 3 deletions charts/plane-enterprise/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,22 @@ ingress:
enabled: true
minioHost: ''
rabbitmqHost: ''
# controller selects WHICH KIND of ingress resource the chart renders, decoupled
# from the class name below. Only the literal value "traefik" emits a Traefik
# IngressRoute CRD; any other value ("nginx", "f5", "haproxy", ...) emits a standard
# networking.k8s.io/v1 Ingress. Leave empty to auto-detect from ingressClass
# (a value starting with "traefik" -> Traefik, otherwise standard Ingress).
# Set this explicitly when your ingressClass is an atypical name (e.g. "nginx-new").
controller: ''
# ingressClass is the free-form class name written to the standard Ingress'
# spec.ingressClassName. It no longer constrains which template renders (use
# controller above for that). With controller="traefik" it is unused, since an
# IngressRoute has no class name.
ingressClass: 'traefik'
# If using nginx ingress controller, set this to 'nginx' and add the appropriate annotations to set the proxy body size limit.
# These annotations are ONLY rendered when ingressClass is 'nginx' (the nginx Ingress template is gated on
# ingressClass == "nginx"); they have no effect with traefik. Example:
# For standard Ingress controllers (controller != "traefik") set the proxy body
# size / buffer annotations here. These are rendered onto the standard Ingress
# only; they have no effect with Traefik (use ingress.traefik.maxRequestBodyBytes).
# Example for ingress-nginx:
Comment thread
coderabbitai[bot] marked this conversation as resolved.
# - 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 Down