Skip to content
Merged
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
6 changes: 6 additions & 0 deletions charts/cnpg-cluster/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Changelog for the 'cnpg-cluster' Helm-Chart

# v0.1.0

- Initial version
- Helm-Untittests for **CronJob**- and **Cluster**-Resources
4 changes: 4 additions & 0 deletions charts/cnpg-cluster/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v2
name: cnpg-cluster
description: Custom Helm-Chart for a CNPG-Cluster with db-dump CronJob functionality
version: 0.1.0
47 changes: 47 additions & 0 deletions charts/cnpg-cluster/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# cnpg-cluster

Custom Helm-Chart for a CNPG-Cluster with db-dump CronJob functionality

> [!IMPORTANT]
> This Helm chart assumes that the required CNPG Custom Resource Definitions (CRDs) are already installed in the target Kubernetes cluster.
> It deploys a CronJob that performs full database dumps for the configured CNPG Database.
> The dumped data is written to a Persistent Volume (PV), and your PV must be backed up using your chosen backup solution (for example, Velero with a remote S3 destination).
> The chart does not configure or guarantee the backup of the PV - this responsibility remains with the user.
> This chart is tailored to a specific CNPG backup use case. If you try to use it in your cluster, please verify that it fits your environment and requirements (including PV provisioning and backup/retention setup).

![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square)

## Values

### Backup-Cronjob specifications

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| backupCronjob.containerImage | string | `"postgres:16-alpine"` | Container-Image with 'pg_dumpall'-binary at PATH |
| backupCronjob.enabled | bool | `false` | Whether to enable backups |
| backupCronjob.persistentVolumeClaimName | string | `"cnpg-db-backup-pvc"` | Name of existing PVC where the database-dump is being stored at |
| backupCronjob.restartPolicy | string | `"OnFailure"` | Policy to restart Backup-Cronjob |
| backupCronjob.schedule | string | `"10 * * * *"` | Schedule of the Cronjob (NOTE: Align with the actual PV-Backup-Schedule) |
| backupCronjob.targetDatabaseHost | string | `"cnpg-cluster-app-rw.cnpg-system"` | Target CNPG-database Host |
| backupCronjob.targetDatabasePort | int | `5432` | Target CNPG-database Port |
| backupCronjob.timeZone | string | `"Europe/Brussels"` | Timezone of Cronjob-Schedule |

### CNPG-Cluster specifications

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| postgresCluster.annotations | object | `{}` | Annotations |
| postgresCluster.cnpgSuperUserSecretName | string | `""` | Name of the Secret for the superUser of the CNPG-Cluster |
| postgresCluster.enableSuperuserAccess | bool | `false` | Whether to allow superuser-access (NOTE: Required to be set 'true' for backups) |
| postgresCluster.imageName | string | `"ghcr.io/cloudnative-pg/postgresql:16"` | Container-Image |
| postgresCluster.imagePullPolicy | string | `"IfNotPresent"` | When to pull Container-Image |
| postgresCluster.instances | int | `1` | Number of CNPG-Cluster instances |
| postgresCluster.managedRoles | list | `[]` | Add managed Roles to database |
| postgresCluster.postgresqlParameters | object | `{}` | Additional parameters for the postgres-database |
| postgresCluster.resources | object | `{}` | Resource requests and limits |
| postgresCluster.sharedPreloadLibraries | list | `[]` | Preload additional libraries |
| postgresCluster.storageClass | string | `"local-path"` | StorageClass of requested PVC |
| postgresCluster.storageSize | string | `"10Gi"` | Storage-Size of requested PVC |

----------------------------------------------
Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2)
15 changes: 15 additions & 0 deletions charts/cnpg-cluster/README.md.gotmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{{ template "chart.header" . }}
{{ template "chart.description" . }}

> [!IMPORTANT]
> This Helm chart assumes that the required CNPG Custom Resource Definitions (CRDs) are already installed in the target Kubernetes cluster.
> It deploys a CronJob that performs full database dumps for the configured CNPG Database.
> The dumped data is written to a Persistent Volume (PV), and your PV must be backed up using your chosen backup solution (for example, Velero with a remote S3 destination).
> The chart does not configure or guarantee the backup of the PV - this responsibility remains with the user.
> This chart is tailored to a specific CNPG backup use case. If you try to use it in your cluster, please verify that it fits your environment and requirements (including PV provisioning and backup/retention setup).

{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }}

{{ template "chart.valuesSection" . }}

{{ template "helm-docs.versionFooter" . }}
85 changes: 85 additions & 0 deletions charts/cnpg-cluster/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "cnpgdb.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "cnpgdb.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "cnpgdb.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "cnpgdb.labels" -}}
helm.sh/chart: {{ include "cnpgdb.chart" . }}
{{ include "cnpgdb.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "cnpgdb.selectorLabels" -}}
app.kubernetes.io/name: {{ include "cnpgdb.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Compile all warnings into a single message, and call fail.
See e.g.: https://github.com/bitnami/charts/blob/d9f6e8974fc9c8cbc64146e1632f70476529e720/bitnami/airflow/templates/_helpers.tpl#L434
*/}}
{{- define "cnpgdb.validateValues" -}}
{{- $messages := list -}}
{{- $messages := append $messages (include "cnpgdb.validateValues.superUserAccess" .) -}}
{{- $messages := without $messages "" -}}
{{- $message := join "\n" $messages -}}

{{- if $message -}}
{{- printf "\nVALUES VALIDATION:\n%s" $message | fail -}}
{{- end -}}
{{- end -}}

{{/*
Validate values of cnpgdb - superUserAccess

> Whether `enableSuperuserAccess: true` when backup is enabled
> Whether `cnpgSuperUserSecretName` is set when `enableSuperuserAccess: true`
*/}}
{{- define "cnpgdb.validateValues.superUserAccess" -}}
{{- $postgres := .Values.postgresCluster -}}
{{- $backup := .Values.backupCronjob -}}
{{- if and $backup.enabled (not $postgres.enableSuperuserAccess) -}}
cnpgdb: enableSuperuserAccess
You have to enable external superUserAccess when enabling Backups
{{- end -}}
{{- if and $postgres.enableSuperuserAccess (not $postgres.cnpgSuperUserSecretName) -}}
cnpgdb: cnpgSuperUserSecretName
You have to provide a superUserAccess-Name when enabling superUserAccess
{{- end -}}
{{- end -}}
50 changes: 50 additions & 0 deletions charts/cnpg-cluster/templates/backup-cronjob.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{{ include "cnpgdb.validateValues" . }}
{{- $cronjob := .Values.backupCronjob -}}
{{- $postgres := .Values.postgresCluster -}}
{{- if and $cronjob.enabled $postgres.enableSuperuserAccess }}
apiVersion: batch/v1
kind: CronJob
metadata:
name: {{ include "cnpgdb.fullname" . }}-backup-dump
namespace: {{ .Release.Namespace | quote }}
spec:
schedule: "{{ $cronjob.schedule }}"
timeZone: "{{ $cronjob.timeZone }}"
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
spec:
restartPolicy: {{ $cronjob.restartPolicy }}
containers:
- name: postgres-backup
image: {{ $cronjob.containerImage }}
env:
- name: PGUSER
valueFrom:
secretKeyRef:
name: {{ $postgres.cnpgSuperUserSecretName }}
key: username
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: {{ $postgres.cnpgSuperUserSecretName }}
key: password
command:
- /bin/bash
- -c
- |
set -euo pipefail;
pg_dumpall \
-h {{ $cronjob.targetDatabaseHost }} \
-p {{ $cronjob.targetDatabasePort }} \
> /backup/cnpg-sqlbkp.sql
ls -lah /backup/cnpg-sqlbkp.sql
volumeMounts:
- name: backup-volume
mountPath: /backup
volumes:
- name: backup-volume
persistentVolumeClaim:
claimName: {{ $cronjob.persistentVolumeClaimName }}
{{- end -}}
45 changes: 45 additions & 0 deletions charts/cnpg-cluster/templates/cnpg-cluster.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{{ include "cnpgdb.validateValues" . }}
{{- $postgres := .Values.postgresCluster -}}
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: {{ include "cnpgdb.fullname" . }}
namespace: {{ .Release.Namespace | quote }}
{{- with $postgres.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
labels:
{{- include "cnpgdb.labels" . }}
spec:
instances: {{ $postgres.instances }}
storage:
size: {{ $postgres.storageSize }}
storageClass: {{ $postgres.storageClass }}
imageName: {{ $postgres.imageName }}
imagePullPolicy: {{ $postgres.imagePullPolicy }}
enableSuperuserAccess: {{ $postgres.enableSuperuserAccess }}
{{- if $postgres.cnpgSuperUserSecretName }}
superuserSecret:
name: {{ $postgres.cnpgSuperUserSecretName }}
{{- end }}
{{- if $postgres.managedRoles }}
managed:
roles:
{{- toYaml $postgres.managedRoles | nindent 6 }}
{{- end }}
{{- if or $postgres.postgresqlParameters $postgres.sharedPreloadLibraries }}
postgresql:
{{- if $postgres.postgresqlParameters }}
parameters:
{{- toYaml $postgres.postgresqlParameters | nindent 6 }}
{{- end }}
{{- if $postgres.sharedPreloadLibraries }}
shared_preload_libraries:
{{- toYaml $postgres.sharedPreloadLibraries | nindent 6 }}
{{- end }}
{{- end }}
{{- if $postgres.resources }}
resources:
{{- toYaml $postgres.resources | nindent 4 }}
{{- end }}
98 changes: 98 additions & 0 deletions charts/cnpg-cluster/tests/backup-cronjob_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#------------------------------------------------------------------------------
#
# CronJob-Unittests Test-Suite for CNPG-Cluster
#
# > https://github.com/helm-unittest/helm-unittest/blob/main/DOCUMENT.md
#
#------------------------------------------------------------------------------
#
# Test suite name to show on test result output
suite: Test CronJob
#
# The template files scope to test in this suite
# Only the selected files will be rendered
templates:
- templates/backup-cronjob.yaml
#
tests:
- it: should not render enabled CronJob with disabled superUserAccess
#
set:
backupCronjob.enabled: true
postgresCluster.enableSuperuserAccess: false
#
asserts:
- failedTemplate:
errorMessage: "VALUES VALIDATION:\ncnpgdb: enableSuperuserAccess\n You have to enable external superUserAccess when enabling Backups"

- it: should render enabled CronJob with enabled superUserAccess
#
set:
postgresCluster:
enableSuperuserAccess: true
cnpgSuperUserSecretName: "test-cnpg-superuser-secret"
backupCronjob.enabled: true
#
asserts:
- isKind:
of: CronJob

- it: should render enabled CronJob and superUserAccess with adjusted specs
#
set:
postgresCluster:
enableSuperuserAccess: true
cnpgSuperUserSecretName: "test-cnpg-superuser-secret"
backupCronjob:
enabled: true
schedule: "1337 1337 1337"
timeZone: "EARTH"
restartPolicy: OnFailure
containerImage: "postgres:1337-alpine"
persistentVolumeClaimName: "test-cronjob-backup-pvc"
targetDatabaseHost: "cnpg-db.1337-db-host"
targetDatabasePort: 1337
#
asserts:
- isKind:
of: CronJob

- equal:
path: spec.schedule
value: "1337 1337 1337"

- equal:
path: spec.timeZone
value: "EARTH"

- equal:
path: spec.jobTemplate.spec.template.spec.restartPolicy
value: "OnFailure"

- equal:
path: spec.jobTemplate.spec.template.spec.containers[0].image
value: "postgres:1337-alpine"

- equal:
path: spec.jobTemplate.spec.template.spec.containers[0].env[0].valueFrom.secretKeyRef.name
value: "test-cnpg-superuser-secret"

- equal:
path: spec.jobTemplate.spec.template.spec.containers[0].env[1].valueFrom.secretKeyRef.name
value: "test-cnpg-superuser-secret"

- equal:
path: spec.jobTemplate.spec.template.spec.containers[0].command
value:
- /bin/bash
- -c
- |
set -euo pipefail;
pg_dumpall \
-h cnpg-db.1337-db-host \
-p 1337 \
> /backup/cnpg-sqlbkp.sql
ls -lah /backup/cnpg-sqlbkp.sql



Loading