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: 1.6.5
version: 1.6.6
appVersion: "1.17.0"

home: https://plane.so/
Expand Down
19 changes: 9 additions & 10 deletions charts/plane-enterprise/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,10 @@

### Air-gapped Settings

| Setting | Default | Required | Description |
| ---------------------- | :-----: | :------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| airgapped.enabled | false | No | Specifies the airgapped mode the Plane API runs in. |
| airgapped.s3SecretName | "" | No | Name of the Secret that contains the CA certificate (.crt). The Secret must include a data key whose filename matches the basename of `airgapped.s3SecretKey`. Used to override S3’s CA when `airgapped.enabled=true`. Applying this secret looks like: `kubectl -n plane create secret generic plane-s3-ca \ --from-file=s3-custom-ca.crt=/path/to/your/ca.crt` |
| airgapped.s3SecretKey | "" | No | Key name of the secret to load the Custom Root CA from `airgapped.s3SecretName` |
| Setting | Default | Required | Description |
|-----------------------|:-------:| :------: |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| airgapped.enabled | false | No | Specifies the airgapped mode the Plane API runs in. |
| airgapped.s3Secrets | [] | No | List of Kubernetes Secrets containing CA certificates to install. Each item in the list must contain a `name` (the Secret name) and a `key` (the file key inside the Secret). Applying a secret looks like: `kubectl -n plane create secret generic plane-s3-ca \ --from-file=s3-custom-ca.crt=/path/to/your/ca.crt` |
Comment on lines 99 to +104
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Documentation for new s3Secrets structure is clear but lacks breaking change warning.

The table update and kubectl example are helpful. However, the documentation does not explicitly highlight that this is a breaking change from the old s3SecretName/s3SecretKey fields. Users upgrading from older versions will have deployment failures if they don't update their values.

Add a prominent "Breaking Changes" section in the README (before the configuration tables) noting:

  • Old fields airgapped.s3SecretName and airgapped.s3SecretKey have been removed
  • Migration required: convert to the new airgapped.s3Secrets[] list structure
  • Example migration path for users

Alternatively, ensure this is clearly documented in release notes/CHANGELOG.

🤖 Prompt for AI Agents
In charts/plane-enterprise/README.md around lines 99 to 104, the new
airgapped.s3Secrets[] documentation does not warn that this is a breaking change
from the old airgapped.s3SecretName/airgapped.s3SecretKey fields; add a
prominent "Breaking Changes" section before the configuration tables that states
the old fields were removed, instructs users to migrate to the new
airgapped.s3Secrets[] list structure, and include a concise example showing how
to convert a single s3SecretName/s3SecretKey pair into the new list format plus
a note that failing to migrate will cause deployments to fail; alternatively,
reference and link to the exact release notes/CHANGELOG entry where the
migration steps are documented.


### Postgres

Expand Down Expand Up @@ -184,7 +183,7 @@
| env.aws_access_key | | | External `S3` (or compatible) storage service provides `access key` for the application to connect and do the necessary upload/download operations. To be provided when `services.minio.local_setup=false` |
| env.aws_secret_access_key | | | External `S3` (or compatible) storage service provides `secret access key` for the application to connect and do the necessary upload/download operations. To be provided when `services.minio.local_setup=false` |
| env.aws_region | | | External `S3` (or compatible) storage service providers creates any buckets in user selected region. This is also shared with the user as `region` for the application to connect and do the necessary upload/download operations. To be provided when `services.minio.local_setup=false` |
| env.aws_s3_endpoint_url | | | External `S3` (or compatible) storage service providers shares a `endpoint_url` for the integration purpose for the application to connect and do the necessary upload/download operations. To be provided when `services.minio.local_setup=false` |
| env.aws_s3_endpoint_url | | | External `S3` (or compatible) storage service providers shares a `endpoint_url` for the integration purpose for the application to connect and do the necessary upload/download operations. To be provided when `services.minio.local_setup=false` |
| env.use_storage_proxy | false | | When set to `true`, all S3 (or compatible) file GET requests from the browser are proxied through Plane's API service instead of accessing the S3 endpoint directly. Enable this if your storage endpoint is not accessible publicly or you want to control/download access through the API. Default is `false`. |
### Web Deployment
Expand Down Expand Up @@ -317,9 +316,9 @@
| services.silo.assign_cluster_ip | false | | Set it to `true` if you want to assign `ClusterIP` to the service |
| services.silo.nodeSelector | {} | | This key allows you to set the node selector for the deployment of `silo`. This is useful when you want to run the deployment on specific nodes in your Kubernetes cluster. |
| services.silo.tolerations | [] | | This key allows you to set the tolerations for the deployment of `silo`. This is useful when you want to run the deployment on nodes with specific taints in your Kubernetes cluster. |
| services.silo.affinity | {} | | This key allows you to set the affinity rules for the deployment of `silo`. This is useful when you want to control how pods are scheduled on nodes in your Kubernetes cluster. |
| services.silo.affinity | {} | | This key allows you to set the affinity rules for the deployment of `silo`. This is useful when you want to control how pods are scheduled on nodes in your Kubernetes cluster. |
| services.silo.labels | {} | | Custom labels to add to the silo deployment |
| services.silo.annotations | {} | | Custom annotations to add to the silo deployment |
| services.silo.annotations | {} | | Custom annotations to add to the silo deployment |
| services.silo.connectors.slack.enabled | false | | Slack Integration |
| services.silo.connectors.slack.client_id | "" | required if `services.silo.connectors.slack.enabled` is `true` | Slack Client ID |
| services.silo.connectors.slack.client_secret | "" | required if `services.silo.connectors.slack.enabled` is `true` | Slack Client Secret |
Expand All @@ -337,11 +336,11 @@
| env.silo_envs.request_interval | 400 | | Request interval for Silo |
| env.silo_envs.sentry_dsn | | | Sentry DSN |
| env.silo_envs.sentry_environment | | | Sentry Environment |
| env.silo_envs.sentry_traces_sample_rate | | | Sentry Traces Sample Rate |
| env.silo_envs.sentry_traces_sample_rate | | | Sentry Traces Sample Rate |
| env.silo_envs.hmac_secret_key | <random-32-bit-string> | | HMAC Secret Key |
| env.silo_envs.aes_secret_key | "dsOdt7YrvxsTIFJ37pOaEVvLxN8KGBCr" | | AES Secret Key |
### Worker Deployment
| Setting | Default | Required | Description |
Expand Down
4 changes: 2 additions & 2 deletions charts/plane-enterprise/questions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@ questions:
group: "License Setup"
show_subquestion_if: true
subquestions:
- variable: airgapped.s3SecretName
- variable: airgapped.s3Secrets[0].name
label: "S3 Secret Name"
type: string
default: ""
- variable: airgapped.s3SecretKey
- variable: airgapped.s3Secrets[0].key
label: "S3 Secret Key"
type: string
default: ""
Expand Down
6 changes: 3 additions & 3 deletions charts/plane-enterprise/templates/config-secrets/app-env.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ stringData:
AMQP_URL: ""
{{ end }}

{{- if and .Values.airgapped.enabled .Values.airgapped.s3SecretName .Values.airgapped.s3SecretKey }}
AWS_CA_BUNDLE: "/s3-custom-ca/{{ .Values.airgapped.s3SecretKey }}"
{{- if and .Values.airgapped.enabled .Values.airgapped.s3Secrets }}
AWS_CA_BUNDLE: "/etc/ssl/certs/ca-certificates.crt"
{{- end }}

{{- end }}
Expand Down Expand Up @@ -78,4 +78,4 @@ data:
CORS_ALLOWED_ORIGINS: "http://{{ .Values.license.licenseDomain }},https://{{ .Values.license.licenseDomain }},{{ .Values.env.cors_allowed_origins }}"
{{- else}}
CORS_ALLOWED_ORIGINS: "http://{{ .Values.license.licenseDomain }},https://{{ .Values.license.licenseDomain }}"
{{- end }}
{{- end }}
44 changes: 24 additions & 20 deletions charts/plane-enterprise/templates/workloads/api.deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,18 @@ spec:
annotations:
timestamp: {{ now | quote }}
spec:
{{- if and .Values.airgapped.enabled .Values.airgapped.s3SecretName .Values.airgapped.s3SecretKey }}
{{- if and .Values.airgapped.enabled .Values.airgapped.s3Secrets }}
volumes:
- name: s3-custom-ca
secret:
secretName: {{ .Values.airgapped.s3SecretName }}
items:
- key: {{ .Values.airgapped.s3SecretKey }}
path: {{ .Values.airgapped.s3SecretKey }}
projected:
sources:
{{- range .Values.airgapped.s3Secrets }}
- secret:
name: {{ .name }}
items:
- key: {{ .key }}
path: {{ .key }}
{{- end }}
{{- end }}
containers:
- name: {{ .Release.Name }}-api
Expand All @@ -62,7 +66,7 @@ spec:
limits:
memory: {{ .Values.services.api.memoryLimit | default "1000Mi" | quote }}
cpu: {{ .Values.services.api.cpuLimit | default "500m" | quote}}
{{- if and .Values.airgapped.enabled .Values.airgapped.s3SecretName .Values.airgapped.s3SecretKey }}
{{- if and .Values.airgapped.enabled .Values.airgapped.s3Secrets }}
volumeMounts:
- name: s3-custom-ca
mountPath: /s3-custom-ca
Expand All @@ -73,26 +77,26 @@ spec:
- -c
- |
set -e
{{- if and .Values.airgapped.enabled .Values.airgapped.s3SecretName }}

{{- if and .Values.airgapped.enabled .Values.airgapped.s3Secrets }}
echo "Installing custom CA certificates..."

# Ensure ca-certificates directory exists
mkdir -p /usr/local/share/ca-certificates
# Install custom S3 CA if available
S3_CERT_FILE="{{ .Values.airgapped.s3SecretKey }}"
if [ -f "/s3-custom-ca/$S3_CERT_FILE" ]; then
echo "Installing S3 custom CA certificate..."
cp "/s3-custom-ca/$S3_CERT_FILE" "/usr/local/share/ca-certificates/$S3_CERT_FILE"

# Install custom S3 CA certs if available
if [ "$(ls -A /s3-custom-ca)" ]; then
echo "Found certificates in /s3-custom-ca. Installing..."
# Copy all files from the mount to the system folder
cp /s3-custom-ca/* /usr/local/share/ca-certificates/
# Update CA certificates
update-ca-certificates
echo "CA certificates installed successfully"
else
echo "No custom S3 CA certificate found, skipping..."
fi
{{- end }}

# Start the API
exec ./bin/docker-entrypoint-api-ee.sh
envFrom:
Expand All @@ -111,9 +115,9 @@ spec:
optional: false
{{- end }}

{{- if or .Values.extraEnv (and .Values.airgapped.enabled .Values.airgapped.s3SecretName .Values.airgapped.s3SecretKey) }}
{{- if or .Values.extraEnv (and .Values.airgapped.enabled .Values.airgapped.s3Secrets) }}
env:
{{- if and .Values.airgapped.enabled .Values.airgapped.s3SecretName .Values.airgapped.s3SecretKey }}
{{- if and .Values.airgapped.enabled .Values.airgapped.s3Secrets }}
- name: SSL_CERT_FILE
value: "/etc/ssl/certs/ca-certificates.crt"
- name: SSL_CERT_DIR
Expand All @@ -140,4 +144,4 @@ spec:
{{- include "plane.podScheduling" .Values.services.api }}
serviceAccount: {{ .Release.Name }}-srv-account
serviceAccountName: {{ .Release.Name }}-srv-account
---
---
42 changes: 23 additions & 19 deletions charts/plane-enterprise/templates/workloads/worker.deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,18 @@ spec:
annotations:
timestamp: {{ now | quote }}
spec:
{{- if and .Values.airgapped.enabled .Values.airgapped.s3SecretName .Values.airgapped.s3SecretKey }}
{{- if and .Values.airgapped.enabled .Values.airgapped.s3Secrets }}
volumes:
- name: s3-custom-ca
secret:
secretName: {{ .Values.airgapped.s3SecretName }}
items:
- key: {{ .Values.airgapped.s3SecretKey }}
path: {{ .Values.airgapped.s3SecretKey }}
projected:
sources:
{{- range .Values.airgapped.s3Secrets }}
- secret:
name: {{ .name }}
items:
- key: {{ .key }}
path: {{ .key }}
{{- end }}
{{- end }}
containers:
- name: {{ .Release.Name }}-worker
Expand All @@ -39,7 +43,7 @@ spec:
limits:
memory: {{ .Values.services.worker.memoryLimit | default "1000Mi" | quote }}
cpu: {{ .Values.services.worker.cpuLimit | default "500m" | quote}}
{{- if and .Values.airgapped.enabled .Values.airgapped.s3SecretName .Values.airgapped.s3SecretKey }}
{{- if and .Values.airgapped.enabled .Values.airgapped.s3Secrets }}
volumeMounts:
- name: s3-custom-ca
mountPath: /s3-custom-ca
Expand All @@ -50,26 +54,26 @@ spec:
- -c
- |
set -e
{{- if and .Values.airgapped.enabled .Values.airgapped.s3SecretName .Values.airgapped.s3SecretKey }}

{{- if and .Values.airgapped.enabled .Values.airgapped.s3Secrets }}
echo "Installing custom CA certificates..."

# Ensure ca-certificates directory exists
mkdir -p /usr/local/share/ca-certificates

# Install custom S3 CA if available
S3_CERT_FILE="{{ .Values.airgapped.s3SecretKey }}"
if [ -f "/s3-custom-ca/$S3_CERT_FILE" ]; then
echo "Installing S3 custom CA certificate..."
cp "/s3-custom-ca/$S3_CERT_FILE" "/usr/local/share/ca-certificates/$S3_CERT_FILE"
if [ "$(ls -A /s3-custom-ca)" ]; then
echo "Found certificates in /s3-custom-ca. Installing..."
# Copy all files from the mount to the system folder
cp /s3-custom-ca/* /usr/local/share/ca-certificates/
# Update CA certificates
update-ca-certificates
echo "CA certificates installed successfully"
else
echo "No custom S3 CA certificate found, skipping..."
fi
{{- end }}

# Start the worker
exec ./bin/docker-entrypoint-worker.sh
envFrom:
Expand All @@ -88,9 +92,9 @@ spec:
optional: false
{{- end }}

{{- if or .Values.extraEnv (and .Values.airgapped.enabled .Values.airgapped.s3SecretName .Values.airgapped.s3SecretKey) }}
{{- if or .Values.extraEnv (and .Values.airgapped.enabled .Values.airgapped.s3Secrets) }}
env:
{{- if and .Values.airgapped.enabled .Values.airgapped.s3SecretName .Values.airgapped.s3SecretKey }}
{{- if and .Values.airgapped.enabled .Values.airgapped.s3Secrets }}
- name: SSL_CERT_FILE
value: "/etc/ssl/certs/ca-certificates.crt"
- name: SSL_CERT_DIR
Expand All @@ -108,4 +112,4 @@ spec:
{{- include "plane.podScheduling" .Values.services.worker }}
serviceAccount: {{ .Release.Name }}-srv-account
serviceAccountName: {{ .Release.Name }}-srv-account
---
---
3 changes: 1 addition & 2 deletions charts/plane-enterprise/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ airgapped:
# mount the CA bundle into the API pod by passing it in as an environment
# variable. Should be the full path to the CA bundle file, e.g.
#
s3SecretName: ""
s3SecretKey: ""
s3Secrets: []

ingress:
enabled: true
Expand Down