mirror of
https://github.com/we-promise/sure.git
synced 2026-04-07 14:31:25 +00:00
Helm chart: render CNPG spec.backup + method inference for volume snapshots (and support spec.plugins) (#504)
* Add backup rendering logic and tests for CNPG Cluster CR - Implemented logic in `cnpg-cluster.yaml` to render `.spec.backup` based on `cnpg.cluster.backup` values. - Introduced validation for required fields and unsupported keys (e.g., `ttl`, `volumeSnapshot.enabled`) to avoid CRD warnings. - Added Helm unit tests to validate backup rendering for various scenarios: missing/invalid fields, inferred `method`, and unsupported keys. - Updated `README.md` and `values.yaml` with examples and documentation for backup configuration options. * Add plugin rendering logic and tests for CNPG Cluster CR - Implemented logic in `cnpg-cluster.yaml` to render `.spec.plugins` based on `cnpg.cluster.plugins` values. - Added Helm unit tests to validate plugin rendering scenarios: unset plugins and configured plugin values. - Updated `values.yaml` with examples and documentation for configuring CNPG plugins. * Update chart to v1.0.1 with CNPG backup and plugin enhancements - Add rendering logic for `Cluster.spec.backup`, inferring `method: volumeSnapshot` when applicable and validating required fields. - Add support for `Cluster.spec.plugins`, enabling barman-cloud plugin and WAL archiver configuration. - Strip unsupported keys (e.g., `backup.ttl`, `volumeSnapshot.enabled`) to prevent CRD warnings. - Update examples and documentation in `README.md` and `values.yaml`. * Keep Helm chart on same major version as app? * Versioning with monorepo * MD is tricky --------- Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com> Co-authored-by: Juan José Mata <jjmata@jjmata.com>
This commit is contained in:
12
charts/sure/CHANGELOG.md
Normal file
12
charts/sure/CHANGELOG.md
Normal file
@@ -0,0 +1,12 @@
|
||||
### 0.0.0
|
||||
|
||||
- First (nightly/test) releases via <https://we-promise.github.io/sure/index.yaml>
|
||||
|
||||
### 0.6.5
|
||||
|
||||
- First version/release that aligns versions with monorepo
|
||||
- CNPG: render `Cluster.spec.backup` from `cnpg.cluster.backup`.
|
||||
- If `backup.method` is omitted and `backup.volumeSnapshot` is present, the chart will infer `method: volumeSnapshot`.
|
||||
- For snapshot backups, `backup.volumeSnapshot.className` is required (template fails early if missing).
|
||||
- Example-only keys like `backup.ttl` and `backup.volumeSnapshot.enabled` are stripped to avoid CRD warnings.
|
||||
- CNPG: render `Cluster.spec.plugins` from `cnpg.cluster.plugins` (enables barman-cloud plugin / WAL archiver configuration).
|
||||
@@ -2,7 +2,7 @@ apiVersion: v2
|
||||
name: sure
|
||||
description: Official Helm chart for deploying the Sure Rails app (web + Sidekiq) on Kubernetes with optional HA PostgreSQL (CloudNativePG) and Redis.
|
||||
type: application
|
||||
version: 1.0.0
|
||||
version: 0.6.5
|
||||
appVersion: "0.6.5"
|
||||
|
||||
kubeVersion: ">=1.25.0-0"
|
||||
|
||||
@@ -144,6 +144,11 @@ cnpg:
|
||||
storage:
|
||||
size: 20Gi
|
||||
storageClassName: longhorn
|
||||
# Optional: enable CNPG volume snapshot backups (requires a VolumeSnapshotClass)
|
||||
backup:
|
||||
method: volumeSnapshot
|
||||
volumeSnapshot:
|
||||
className: longhorn
|
||||
# Synchronous replication for stronger durability
|
||||
minSyncReplicas: 1
|
||||
maxSyncReplicas: 2
|
||||
@@ -187,6 +192,26 @@ simplefin:
|
||||
- The chart configures credentials via `spec.bootstrap.initdb.secret` rather than `managed.roles`. The operator expects the referenced Secret to contain `username` and `password` keys (configurable via values).
|
||||
- This chart generates the application DB Secret when `cnpg.cluster.secret.enabled=true` using the keys defined at `cnpg.cluster.secret.usernameKey` (default `username`) and `cnpg.cluster.secret.passwordKey` (default `password`). If you use an existing Secret (`cnpg.cluster.existingSecret`), ensure it contains these keys. The Cluster CR references the Secret by name and maps the keys accordingly.
|
||||
- If the CNPG operator is already installed cluster‑wide, you may set `cnpg.enabled=false` and keep `cnpg.cluster.enabled=true`. The chart will still render the `Cluster` CR and compute the in‑cluster `DATABASE_URL`.
|
||||
- For backups, CNPG requires `spec.backup.method` to be explicit (for example `volumeSnapshot` or `barmanObjectStore`). This chart will infer `method: volumeSnapshot` if a `backup.volumeSnapshot` block is present.
|
||||
- For snapshot backups, `backup.volumeSnapshot.className` must be set (the chart will fail the render if it is missing).
|
||||
- The CNPG `spec.backup` schema does not support keys like `ttl` or `volumeSnapshot.enabled`; this chart strips those keys to avoid CRD warnings.
|
||||
- Unknown `backup.method` values are passed through and left for CNPG to validate.
|
||||
|
||||
Example (barman-cloud plugin for WAL archiving + snapshot backups):
|
||||
|
||||
```yaml
|
||||
cnpg:
|
||||
cluster:
|
||||
plugins:
|
||||
- name: barman-cloud.cloudnative-pg.io
|
||||
isWALArchiver: true
|
||||
parameters:
|
||||
barmanObjectName: minio-backups # references an ObjectStore CR
|
||||
backup:
|
||||
method: volumeSnapshot
|
||||
volumeSnapshot:
|
||||
className: longhorn
|
||||
```
|
||||
|
||||
Additional default hardening:
|
||||
|
||||
|
||||
@@ -15,9 +15,53 @@ spec:
|
||||
{{- end }}
|
||||
storage:
|
||||
size: {{ .Values.cnpg.cluster.storage.size | default "10Gi" }}
|
||||
{{- if .Values.cnpg.cluster.storage.storageClassName }}
|
||||
{{ if .Values.cnpg.cluster.storage.storageClassName }}
|
||||
storageClass: {{ .Values.cnpg.cluster.storage.storageClassName }}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
{{ with .Values.cnpg.cluster.backup }}
|
||||
{{- $backup := deepCopy . }}
|
||||
{{- /* CNPG `spec.backup` does not support these historical/example keys */ -}}
|
||||
{{- $_ := unset $backup "ttl" -}}
|
||||
{{- if and (hasKey $backup "volumeSnapshot") (kindIs "map" $backup.volumeSnapshot) -}}
|
||||
{{- $_ := unset $backup.volumeSnapshot "enabled" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- $method := (get $backup "method") -}}
|
||||
{{- if not $method -}}
|
||||
{{- if hasKey $backup "volumeSnapshot" -}}
|
||||
{{- $_ := set $backup "method" "volumeSnapshot" -}}
|
||||
{{- $method = "volumeSnapshot" -}}
|
||||
{{- else if hasKey $backup "barmanObjectStore" -}}
|
||||
{{- $_ := set $backup "method" "barmanObjectStore" -}}
|
||||
{{- $method = "barmanObjectStore" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if not $method -}}
|
||||
{{- fail "cnpg.cluster.backup is set but no backup method could be inferred. Set cnpg.cluster.backup.method explicitly (e.g. volumeSnapshot or barmanObjectStore)." -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if and (eq $method "volumeSnapshot") (not (hasKey $backup "volumeSnapshot")) -}}
|
||||
{{- fail "cnpg.cluster.backup.method=volumeSnapshot requires cnpg.cluster.backup.volumeSnapshot to be set" -}}
|
||||
{{- end -}}
|
||||
{{- if and (eq $method "barmanObjectStore") (not (hasKey $backup "barmanObjectStore")) -}}
|
||||
{{- fail "cnpg.cluster.backup.method=barmanObjectStore requires cnpg.cluster.backup.barmanObjectStore to be set" -}}
|
||||
{{- end -}}
|
||||
{{- if eq $method "volumeSnapshot" -}}
|
||||
{{- if kindIs "map" $backup.volumeSnapshot -}}
|
||||
{{- $_ := required "cnpg.cluster.backup.volumeSnapshot.className is required for volumeSnapshot backups" $backup.volumeSnapshot.className -}}
|
||||
{{- else -}}
|
||||
{{- fail "cnpg.cluster.backup.volumeSnapshot must be a map/object" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
backup:
|
||||
{{- toYaml $backup | nindent 4 }}
|
||||
{{- end }}
|
||||
{{ with .Values.cnpg.cluster.plugins }}
|
||||
plugins:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{ end }}
|
||||
{{- with .Values.cnpg.cluster.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
|
||||
73
charts/sure/tests/cnpg-backup_test.yaml
Normal file
73
charts/sure/tests/cnpg-backup_test.yaml
Normal file
@@ -0,0 +1,73 @@
|
||||
suite: CNPG Cluster backup rendering
|
||||
templates:
|
||||
- templates/cnpg-cluster.yaml
|
||||
|
||||
tests:
|
||||
- it: renders no spec.backup when cnpg.cluster.backup is unset
|
||||
set:
|
||||
cnpg:
|
||||
cluster:
|
||||
enabled: true
|
||||
asserts:
|
||||
- notExists:
|
||||
path: spec.backup
|
||||
|
||||
- it: defaults method to volumeSnapshot when volumeSnapshot is present
|
||||
set:
|
||||
cnpg:
|
||||
cluster:
|
||||
enabled: true
|
||||
backup:
|
||||
volumeSnapshot:
|
||||
className: longhorn
|
||||
asserts:
|
||||
- equal:
|
||||
path: spec.backup.method
|
||||
value: volumeSnapshot
|
||||
- equal:
|
||||
path: spec.backup.volumeSnapshot.className
|
||||
value: longhorn
|
||||
|
||||
- it: strips unsupported keys (ttl and volumeSnapshot.enabled)
|
||||
set:
|
||||
cnpg:
|
||||
cluster:
|
||||
enabled: true
|
||||
backup:
|
||||
method: volumeSnapshot
|
||||
ttl: 168h
|
||||
volumeSnapshot:
|
||||
enabled: true
|
||||
className: longhorn
|
||||
asserts:
|
||||
- equal:
|
||||
path: spec.backup.method
|
||||
value: volumeSnapshot
|
||||
- notExists:
|
||||
path: spec.backup.ttl
|
||||
- notExists:
|
||||
path: spec.backup.volumeSnapshot.enabled
|
||||
|
||||
- it: fails when volumeSnapshot backups are enabled without className
|
||||
set:
|
||||
cnpg:
|
||||
cluster:
|
||||
enabled: true
|
||||
backup:
|
||||
method: volumeSnapshot
|
||||
volumeSnapshot: {}
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorMessage: cnpg.cluster.backup.volumeSnapshot.className is required for volumeSnapshot backups
|
||||
|
||||
- it: renders unknown backup method as-is (CNPG will validate)
|
||||
set:
|
||||
cnpg:
|
||||
cluster:
|
||||
enabled: true
|
||||
backup:
|
||||
method: madeUpMethod
|
||||
asserts:
|
||||
- equal:
|
||||
path: spec.backup.method
|
||||
value: madeUpMethod
|
||||
34
charts/sure/tests/cnpg-plugins_test.yaml
Normal file
34
charts/sure/tests/cnpg-plugins_test.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
suite: CNPG Cluster plugins rendering
|
||||
templates:
|
||||
- templates/cnpg-cluster.yaml
|
||||
|
||||
tests:
|
||||
- it: renders no spec.plugins when cnpg.cluster.plugins is unset
|
||||
set:
|
||||
cnpg:
|
||||
cluster:
|
||||
enabled: true
|
||||
asserts:
|
||||
- notExists:
|
||||
path: spec.plugins
|
||||
|
||||
- it: renders spec.plugins when cnpg.cluster.plugins is set
|
||||
set:
|
||||
cnpg:
|
||||
cluster:
|
||||
enabled: true
|
||||
plugins:
|
||||
- name: barman-cloud.cloudnative-pg.io
|
||||
isWALArchiver: true
|
||||
parameters:
|
||||
barmanObjectName: minio-backups
|
||||
asserts:
|
||||
- equal:
|
||||
path: spec.plugins[0].name
|
||||
value: barman-cloud.cloudnative-pg.io
|
||||
- equal:
|
||||
path: spec.plugins[0].isWALArchiver
|
||||
value: true
|
||||
- equal:
|
||||
path: spec.plugins[0].parameters.barmanObjectName
|
||||
value: minio-backups
|
||||
@@ -65,6 +65,53 @@ cnpg:
|
||||
storage:
|
||||
size: 10Gi
|
||||
storageClassName: ""
|
||||
# Optional CNPG backup configuration (rendered as `.spec.backup` on the Cluster CR)
|
||||
# Example (CNPG volume snapshots):
|
||||
# backup:
|
||||
# method: volumeSnapshot
|
||||
# volumeSnapshot:
|
||||
# className: longhorn
|
||||
#
|
||||
# Example (CNPG barmanObjectStore backups):
|
||||
# backup:
|
||||
# method: barmanObjectStore
|
||||
# barmanObjectStore:
|
||||
# destinationPath: s3://my-bucket/cnpg
|
||||
# endpointURL: https://s3.us-east-1.amazonaws.com
|
||||
# s3Credentials:
|
||||
# accessKeyId:
|
||||
# name: my-s3-creds
|
||||
# key: ACCESS_KEY_ID
|
||||
# secretAccessKey:
|
||||
# name: my-s3-creds
|
||||
# key: SECRET_ACCESS_KEY
|
||||
#
|
||||
# NOTE:
|
||||
# - The CNPG Cluster `spec.backup` schema does not support `enabled` or `ttl` keys.
|
||||
# If you add them, this chart will ignore them to avoid CRD warnings.
|
||||
# - This chart only hard-validates required fields for supported methods; unknown `method` values
|
||||
# are passed through for CNPG to validate.
|
||||
backup: {}
|
||||
|
||||
# Optional CNPG plugin configuration (rendered as `.spec.plugins` on the Cluster CR)
|
||||
# Example (barman-cloud plugin as WAL archiver):
|
||||
# plugins:
|
||||
# - name: barman-cloud.cloudnative-pg.io
|
||||
# isWALArchiver: true
|
||||
# parameters:
|
||||
# barmanObjectName: minio-backups
|
||||
#
|
||||
# Example (complete setup: WAL archiving via barman-cloud plugin + snapshot backups):
|
||||
# plugins:
|
||||
# - name: barman-cloud.cloudnative-pg.io
|
||||
# isWALArchiver: true
|
||||
# parameters:
|
||||
# barmanObjectName: minio-backups # references an ObjectStore CR
|
||||
# backup:
|
||||
# method: volumeSnapshot
|
||||
# volumeSnapshot:
|
||||
# className: longhorn
|
||||
plugins: []
|
||||
# auth config for application user
|
||||
appUser: sure
|
||||
appDatabase: sure
|
||||
|
||||
Reference in New Issue
Block a user