diff --git a/.github/workflows/tests-cluster-chainsaw.yaml b/.github/workflows/tests-cluster-chainsaw.yaml index a7f37533f..bd318c2ba 100644 --- a/.github/workflows/tests-cluster-chainsaw.yaml +++ b/.github/workflows/tests-cluster-chainsaw.yaml @@ -37,6 +37,15 @@ jobs: - name: Setup kind uses: ./.github/actions/setup-kind + - name: Install VolumeSnapShot CRDs + run: | + kubectl apply -f \ + https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/release-5.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml + kubectl apply -f \ + https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/release-5.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml + kubectl apply -f \ + https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/release-5.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml + - name: Deploy the operator uses: ./.github/actions/deploy-operator diff --git a/charts/cloudnative-pg/README.md b/charts/cloudnative-pg/README.md index c45573d5a..de164e0c5 100644 --- a/charts/cloudnative-pg/README.md +++ b/charts/cloudnative-pg/README.md @@ -80,3 +80,5 @@ CloudNativePG Operator Helm Chart | updateStrategy | object | `{}` | Update strategy for the operator. ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy For example: type: RollingUpdate rollingUpdate: maxSurge: 25% maxUnavailable: 25% | | webhook | object | `{"livenessProbe":{"initialDelaySeconds":3},"mutating":{"create":true,"failurePolicy":"Fail"},"port":9443,"readinessProbe":{"initialDelaySeconds":3},"startupProbe":{"failureThreshold":6,"periodSeconds":5},"validating":{"create":true,"failurePolicy":"Fail"}}` | The webhook configuration. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/charts/cluster/Chart.yaml b/charts/cluster/Chart.yaml index 6e1aa275b..5bc7a4e20 100644 --- a/charts/cluster/Chart.yaml +++ b/charts/cluster/Chart.yaml @@ -18,7 +18,7 @@ name: cluster description: Deploys and manages a CloudNativePG cluster and its associated resources. icon: https://raw.githubusercontent.com/cloudnative-pg/artwork/main/cloudnativepg-logo.svg type: application -version: 0.2.1 +version: 0.2.2 sources: - https://github.com/cloudnative-pg/charts keywords: diff --git a/charts/cluster/README.md b/charts/cluster/README.md index 864867c57..abc60b727 100644 --- a/charts/cluster/README.md +++ b/charts/cluster/README.md @@ -1,6 +1,6 @@ # cluster -![Version: 0.2.1](https://img.shields.io/badge/Version-0.2.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) +![Version: 0.2.2](https://img.shields.io/badge/Version-0.2.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) > **Warning** > ### This chart is under active development. @@ -73,6 +73,8 @@ The chart has three modes of operation. These are configured via the `mode` para ### Backup configuration +#### Barman Object Store + CNPG implements disaster recovery via [Barman](https://pgbarman.org/). The following section configures the barman object store where backups will be stored. Barman performs backups of the cluster filesystem base backup and WALs. Both are stored in the specified location. The backup provider is configured via the `backups.provider` parameter. The following @@ -93,9 +95,29 @@ backups: backupOwnerReference: self ``` -Each backup adapter takes it's own set of parameters, listed in the [Configuration options](#Configuration-options) section -below. Refer to the table for the full list of parameters and place the configuration under the appropriate key: `backup.s3`, -`backup.azure`, or `backup.google`. +Each backup adapter takes its own set of parameters, listed in the [Configuration options](#Configuration-options) section +below. Refer to the table for the full list of parameters and place the configuration under the appropriate key: `backup.barmanObjectStore.s3`, +`backup.barmanObjectStore.azure`, or `backup.barmanObjectStore.google`. + +#### Volume Snapshots + +You can also configure backup using Volume Snapshots. See the [example](.examples/volumesnapshot.yml) to learn how to do that. + +Volume snapshots can be used as a backup method by setting the `backups.method` parameter to `volumeSnapshot`. The following parameters can be configured: +* `backups.volumeSnapshot.className` - Snapshot Class to be used for PG_DATA PersistentVolumeClaim. +* `backups.volumeSnapshot.walClassName` - Snapshot Class to be used for the PG_WAL PersistentVolumeClaim. +* `backups.volumeSnapshot.tablespaceClassName` - Snapshot Class to be used for the tablespaces. Defaults to the PGDATA Snapshot Class, if set. +* `backups.volumeSnapshot.snapshotOwnerReference` - Type of owner reference the snapshot should have. Available options are `none`, `cluster`, and `backup`. +* `backups.volumeSnapshot.online` - Define if the backup shall be online or offline. +* `backups.volumeSnapshot.onlineConfiguration` - Configuration for online backups, including `waitForArchive` and `immediateCheckpoint`. + +#### Plugin Backups + +Another backup option are plugin backups. See the [example](.examples/pluginbackup.yml) to learn how to do that. + +Plugin backups can be used by setting the `backups.method` parameter to `plugin`. The following parameters can be configured: +* `backups.pluginConfiguration.name` - Name of the plugin to use. +* `backups.pluginConfiguration.parameters` - Configuration parameters for the plugin. Recovery -------- @@ -112,43 +134,43 @@ refer to the [CloudNativePG Documentation](https://cloudnative-pg.io/documentat | Key | Type | Default | Description | |-----|------|---------|-------------| -| backups.azure.connectionString | string | `""` | | -| backups.azure.containerName | string | `""` | | -| backups.azure.inheritFromAzureAD | bool | `false` | | -| backups.azure.path | string | `"/"` | | -| backups.azure.serviceName | string | `"blob"` | | -| backups.azure.storageAccount | string | `""` | | -| backups.azure.storageKey | string | `""` | | -| backups.azure.storageSasToken | string | `""` | | -| backups.data.compression | string | `"gzip"` | Data compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. | -| backups.data.encryption | string | `"AES256"` | Whether to instruct the storage provider to encrypt data files. One of `` (use the storage container default), `AES256` or `aws:kms`. | -| backups.data.jobs | int | `2` | Number of data files to be archived or restored in parallel. | -| backups.destinationPath | string | `""` | Overrides the provider specific default path. Defaults to: S3: s3:// Azure: https://..core.windows.net/ Google: gs:// | +| backups.barmanObjectStore | object | `{"azure":{"connectionString":"","containerName":"","inheritFromAzureAD":false,"path":"/","serviceName":"blob","storageAccount":"","storageKey":"","storageSasToken":""},"data":{"compression":"gzip","encryption":"AES256","jobs":2},"destinationPath":"","endpointCA":{"create":false,"key":"","name":"","value":""},"endpointURL":"","google":{"applicationCredentials":"","bucket":"","gkeEnvironment":false,"path":"/"},"provider":"s3","s3":{"accessKey":"","bucket":"","inheritFromIAMRole":false,"path":"/","region":"","secretKey":""},"secret":{"create":true,"name":""},"wal":{"compression":"gzip","encryption":"AES256","maxParallel":1}}` | Configuration for method barmanObjectStore | +| backups.barmanObjectStore.data.compression | string | `"gzip"` | Data compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. | +| backups.barmanObjectStore.data.encryption | string | `"AES256"` | Whether to instruct the storage provider to encrypt data files. One of `` (use the storage container default), `AES256` or `aws:kms`. | +| backups.barmanObjectStore.data.jobs | int | `2` | Number of data files to be archived or restored in parallel. | +| backups.barmanObjectStore.destinationPath | string | `""` | Overrides the provider specific default path. Defaults to: S3: s3:// Azure: https://..core.windows.net/ Google: gs:// | +| backups.barmanObjectStore.endpointCA | object | `{"create":false,"key":"","name":"","value":""}` | Specifies a CA bundle to validate a privately signed certificate. | +| backups.barmanObjectStore.endpointCA.create | bool | `false` | Creates a secret with the given value if true, otherwise uses an existing secret. | +| backups.barmanObjectStore.endpointURL | string | `""` | Overrides the provider specific default endpoint. Defaults to: S3: https://s3..amazonaws.com" Leave empty if using the default S3 endpoint | +| backups.barmanObjectStore.provider | string | `"s3"` | One of `s3`, `azure` or `google` | +| backups.barmanObjectStore.s3.inheritFromIAMRole | bool | `false` | Use the role based authentication without providing explicitly the keys | +| backups.barmanObjectStore.secret.create | bool | `true` | Whether to create a secret for the backup credentials | +| backups.barmanObjectStore.secret.name | string | `""` | Name of the backup credentials secret | +| backups.barmanObjectStore.wal.compression | string | `"gzip"` | WAL compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. | +| backups.barmanObjectStore.wal.encryption | string | `"AES256"` | Whether to instruct the storage provider to encrypt WAL files. One of `` (use the storage container default), `AES256` or `aws:kms`. | +| backups.barmanObjectStore.wal.maxParallel | int | `1` | Number of WAL files to be archived or restored in parallel. | | backups.enabled | bool | `false` | You need to configure backups manually, so backups are disabled by default. | -| backups.endpointCA | object | `{"create":false,"key":"","name":"","value":""}` | Specifies a CA bundle to validate a privately signed certificate. | -| backups.endpointCA.create | bool | `false` | Creates a secret with the given value if true, otherwise uses an existing secret. | -| backups.endpointURL | string | `""` | Overrides the provider specific default endpoint. Defaults to: S3: https://s3..amazonaws.com" | -| backups.google.applicationCredentials | string | `""` | | -| backups.google.bucket | string | `""` | | -| backups.google.gkeEnvironment | bool | `false` | | -| backups.google.path | string | `"/"` | | -| backups.provider | string | `"s3"` | One of `s3`, `azure` or `google` | +| backups.method | string | `"barmanObjectStore"` | The backup method to be used, possible options are `barmanObjectStore`, `volumeSnapshot` or `plugin` | +| backups.pluginConfiguration | object | `{"name":"","parameters":{}}` | Configuration for method plugin | +| backups.pluginConfiguration.name | string | `""` | Name of the plugin to use | +| backups.pluginConfiguration.parameters | object | `{}` | Configuration for the plugin | | backups.retentionPolicy | string | `"30d"` | Retention policy for backups | -| backups.s3.accessKey | string | `""` | | -| backups.s3.bucket | string | `""` | | -| backups.s3.inheritFromIAMRole | bool | `false` | Use the role based authentication without providing explicitly the keys | -| backups.s3.path | string | `"/"` | | -| backups.s3.region | string | `""` | | -| backups.s3.secretKey | string | `""` | | | backups.scheduledBackups[0].backupOwnerReference | string | `"self"` | Backup owner reference | -| backups.scheduledBackups[0].method | string | `"barmanObjectStore"` | Backup method, can be `barmanObjectStore` (default) or `volumeSnapshot` | +| backups.scheduledBackups[0].method | string | `"barmanObjectStore"` | Backup method, can be `barmanObjectStore` (default) or `volumeSnapshot` or `plugin` | | backups.scheduledBackups[0].name | string | `"daily-backup"` | Scheduled backup name | | backups.scheduledBackups[0].schedule | string | `"0 0 0 * * *"` | Schedule in cron format | -| backups.secret.create | bool | `true` | Whether to create a secret for the backup credentials | -| backups.secret.name | string | `""` | Name of the backup credentials secret | -| backups.wal.compression | string | `"gzip"` | WAL compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. | -| backups.wal.encryption | string | `"AES256"` | Whether to instruct the storage provider to encrypt WAL files. One of `` (use the storage container default), `AES256` or `aws:kms`. | -| backups.wal.maxParallel | int | `1` | Number of WAL files to be archived or restored in parallel. | +| backups.target | string | `"prefer-standby"` | The policy to decide which instance should perform this backup. Available options are empty string, `primary` and `prefer-standby` | +| backups.volumeSnapshot | object | `{"annotations":{},"className":"","labels":{},"online":true,"onlineConfiguration":{"immediateCheckpoint":false,"waitForArchive":true},"snapshotOwnerReference":"backup","tablespaceClassName":{},"walClassName":""}` | Define volume snapshot configuration | +| backups.volumeSnapshot.annotations | object | `{}` | Key-value pairs that will be added to .metadata.annotations snapshot resources | +| backups.volumeSnapshot.className | string | `""` | Snapshot Class to be used for PG_DATA PersistentVolumeClaim | +| backups.volumeSnapshot.labels | object | `{}` | Key-value pairs that will be added to .metadata.labels snapshot resources. | +| backups.volumeSnapshot.online | bool | `true` | Define if the backup shall be online or offline | +| backups.volumeSnapshot.onlineConfiguration | object | `{"immediateCheckpoint":false,"waitForArchive":true}` | Configuration for method volumeSnapshot | +| backups.volumeSnapshot.onlineConfiguration.immediateCheckpoint | bool | `false` | If set to true, an immediate checkpoint will be used, meaning PostgreSQL will complete the checkpoint as soon as possible | +| backups.volumeSnapshot.onlineConfiguration.waitForArchive | bool | `true` | If false, the function will return immediately after the backup is completed, without waiting for WAL to be archived | +| backups.volumeSnapshot.snapshotOwnerReference | string | `"backup"` | Type of owner reference the snapshot should have. Available options are `none`, `cluster` and `backup` | +| backups.volumeSnapshot.tablespaceClassName | object | `{}` | Snapshot Class to be used for the tablespaces. defaults to the PGDATA Snapshot Class, if set | +| backups.volumeSnapshot.walClassName | string | `""` | Snapshot Class to be used for the PG_WAL PersistentVolumeClaim | | cluster.additionalLabels | object | `{}` | | | cluster.affinity | object | `{"topologyKey":"topology.kubernetes.io/zone"}` | Affinity/Anti-affinity rules for Pods. See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-AffinityConfiguration | | cluster.annotations | object | `{}` | | @@ -156,7 +178,7 @@ refer to the [CloudNativePG Documentation](https://cloudnative-pg.io/documentat | cluster.enablePDB | bool | `true` | Allow to disable PDB, mainly useful for upgrade of single-instance clusters or development purposes See: https://cloudnative-pg.io/documentation/current/kubernetes_upgrade/#pod-disruption-budgets | | cluster.enableSuperuserAccess | bool | `true` | When this option is enabled, the operator will use the SuperuserSecret to update the postgres user password. If the secret is not present, the operator will automatically create one. When this option is disabled, the operator will ignore the SuperuserSecret content, delete it when automatically created, and then blank the password of the postgres user by setting it to NULL. | | cluster.imageCatalogRef | object | `{}` | Reference to `ImageCatalog` of `ClusterImageCatalog`, if specified takes precedence over `cluster.imageName` | -| cluster.imageName | string | `""` | Name of the container image, supporting both tags (:) and digests for deterministic and repeatable deployments: :@sha256: | +| cluster.imageName | string | `""` | Name of the container image, supporting both tags (:) and digests for deterministic and repeatable deployments: :@sha256: Default value depends on type (postgresql/postgis/timescaledb) | | cluster.imagePullPolicy | string | `"IfNotPresent"` | Image pull policy. One of Always, Never or IfNotPresent. If not defined, it defaults to IfNotPresent. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images | | cluster.imagePullSecrets | list | `[]` | The list of pull secrets to be used to pull the images. See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-LocalObjectReference | | cluster.initdb | object | `{}` | BootstrapInitDB is the configuration of the bootstrap process when initdb is used. See: https://cloudnative-pg.io/documentation/current/bootstrap/ See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-bootstrapinitdb | @@ -207,7 +229,7 @@ refer to the [CloudNativePG Documentation](https://cloudnative-pg.io/documentat | recovery.azure.storageAccount | string | `""` | | | recovery.azure.storageKey | string | `""` | | | recovery.azure.storageSasToken | string | `""` | | -| recovery.backupName | string | `""` | Backup Recovery Method | +| recovery.backupName | string | `""` | Backup Recovery Method Name of the backup to recover from. Required if method is `backup`. | | recovery.clusterName | string | `""` | The original cluster name when used in backups. Also known as serverName. | | recovery.destinationPath | string | `""` | Overrides the provider specific default path. Defaults to: S3: s3:// Azure: https://..core.windows.net/ Google: gs:// | | recovery.endpointCA | object | `{"create":false,"key":"","name":"","value":""}` | Specifies a CA bundle to validate a privately signed certificate. | @@ -305,3 +327,5 @@ TODO * IAM Role for S3 Service Account * Automatic provisioning of a Alert Manager configuration +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/charts/cluster/README.md.gotmpl b/charts/cluster/README.md.gotmpl index 1ca7bebaa..cdae9532e 100644 --- a/charts/cluster/README.md.gotmpl +++ b/charts/cluster/README.md.gotmpl @@ -81,6 +81,8 @@ The chart has three modes of operation. These are configured via the `mode` para ### Backup configuration +#### Barman Object Store + CNPG implements disaster recovery via [Barman](https://pgbarman.org/). The following section configures the barman object store where backups will be stored. Barman performs backups of the cluster filesystem base backup and WALs. Both are stored in the specified location. The backup provider is configured via the `backups.provider` parameter. The following @@ -101,10 +103,29 @@ backups: backupOwnerReference: self ``` -Each backup adapter takes it's own set of parameters, listed in the [Configuration options](#Configuration-options) section -below. Refer to the table for the full list of parameters and place the configuration under the appropriate key: `backup.s3`, -`backup.azure`, or `backup.google`. +Each backup adapter takes its own set of parameters, listed in the [Configuration options](#Configuration-options) section +below. Refer to the table for the full list of parameters and place the configuration under the appropriate key: `backup.barmanObjectStore.s3`, +`backup.barmanObjectStore.azure`, or `backup.barmanObjectStore.google`. + +#### Volume Snapshots + +You can also configure backup using Volume Snapshots. See the [example](.examples/volumesnapshot.yml) to learn how to do that. + +Volume snapshots can be used as a backup method by setting the `backups.method` parameter to `volumeSnapshot`. The following parameters can be configured: +* `backups.volumeSnapshot.className` - Snapshot Class to be used for PG_DATA PersistentVolumeClaim. +* `backups.volumeSnapshot.walClassName` - Snapshot Class to be used for the PG_WAL PersistentVolumeClaim. +* `backups.volumeSnapshot.tablespaceClassName` - Snapshot Class to be used for the tablespaces. Defaults to the PGDATA Snapshot Class, if set. +* `backups.volumeSnapshot.snapshotOwnerReference` - Type of owner reference the snapshot should have. Available options are `none`, `cluster`, and `backup`. +* `backups.volumeSnapshot.online` - Define if the backup shall be online or offline. +* `backups.volumeSnapshot.onlineConfiguration` - Configuration for online backups, including `waitForArchive` and `immediateCheckpoint`. + +#### Plugin Backups + +Another backup option are plugin backups. See the [example](.examples/pluginbackup.yml) to learn how to do that. +Plugin backups can be used by setting the `backups.method` parameter to `plugin`. The following parameters can be configured: +* `backups.pluginConfiguration.name` - Name of the plugin to use. +* `backups.pluginConfiguration.parameters` - Configuration parameters for the plugin. Recovery -------- diff --git a/charts/cluster/examples/pluginbackup.yml b/charts/cluster/examples/pluginbackup.yml new file mode 100644 index 000000000..0c76323a1 --- /dev/null +++ b/charts/cluster/examples/pluginbackup.yml @@ -0,0 +1,14 @@ +type: postgresql +mode: standalone +version: + postgresql: "16" +cluster: + instances: 1 +backups: + enabled: true + method: plugin + pluginConfiguration: + name: testplugin + parameters: + param1: value1 + param2: value2 diff --git a/charts/cluster/examples/recovery-backup.yaml b/charts/cluster/examples/recovery-backup.yaml index c478e7a9e..c3a599a45 100644 --- a/charts/cluster/examples/recovery-backup.yaml +++ b/charts/cluster/examples/recovery-backup.yaml @@ -9,15 +9,17 @@ cluster: instances: 1 backups: - provider: s3 - s3: - region: "eu-west-1" - bucket: "db-backups" - path: "/v1-restore" - accessKey: "AWS_S3_ACCESS_KEY" - secretKey: "AWS_S3_SECRET_KEY" - scheduledBackups: - - name: daily-backup # Daily at midnight - schedule: "0 0 0 * * *" # Daily at midnight - backupOwnerReference: self - retentionPolicy: "30d" \ No newline at end of file + enabled: true + barmanObjectStore: + provider: s3 + s3: + region: "eu-west-1" + bucket: "db-backups" + path: "/v1-restore" + accessKey: "AWS_S3_ACCESS_KEY" + secretKey: "AWS_S3_SECRET_KEY" + scheduledBackups: + - name: daily-backup # Daily at midnight + schedule: "0 0 0 * * *" # Daily at midnight + backupOwnerReference: self + retentionPolicy: "30d" diff --git a/charts/cluster/examples/recovery-object_store.yaml b/charts/cluster/examples/recovery-object_store.yaml index 060f5328d..061b966b5 100644 --- a/charts/cluster/examples/recovery-object_store.yaml +++ b/charts/cluster/examples/recovery-object_store.yaml @@ -16,16 +16,18 @@ cluster: instances: 1 backups: - endpointURL: "https://cm-db-chart-test.ams3.digitaloceanspaces.com" - provider: s3 - s3: - region: "eu-west-1" - bucket: "db-backups" - path: "/v1-restore" - accessKey: "AWS_S3_ACCESS_KEY" - secretKey: "AWS_S3_SECRET_KEY" - scheduledBackups: - - name: daily-backup # Daily at midnight - schedule: "0 0 0 * * *" # Daily at midnight - backupOwnerReference: self - retentionPolicy: "30d" + enabled: true + barmanObjectStore: + endpointURL: "https://cm-db-chart-test.ams3.digitaloceanspaces.com" + provider: s3 + s3: + region: "eu-west-1" + bucket: "db-backups" + path: "/v1-restore" + accessKey: "AWS_S3_ACCESS_KEY" + secretKey: "AWS_S3_SECRET_KEY" + scheduledBackups: + - name: daily-backup # Daily at midnight + schedule: "0 0 0 * * *" # Daily at midnight + backupOwnerReference: self + retentionPolicy: "30d" diff --git a/charts/cluster/examples/standalone-s3.yaml b/charts/cluster/examples/standalone-s3.yaml index 44a4bb104..8e77ffca6 100644 --- a/charts/cluster/examples/standalone-s3.yaml +++ b/charts/cluster/examples/standalone-s3.yaml @@ -6,15 +6,16 @@ cluster: backups: enabled: true - provider: s3 - s3: - region: "eu-west-1" - bucket: "db-backups" - path: "/v1" - accessKey: "AWS_S3_ACCESS_KEY" - secretKey: "AWS_S3_SECRET_KEY" - scheduledBackups: - - name: daily-backup # Daily at midnight - schedule: "0 0 0 * * *" # Daily at midnight - backupOwnerReference: self - retentionPolicy: "30d" + barmanObjectStore: + provider: s3 + s3: + region: "eu-west-1" + bucket: "db-backups" + path: "/v1" + accessKey: "AWS_S3_ACCESS_KEY" + secretKey: "AWS_S3_SECRET_KEY" + scheduledBackups: + - name: daily-backup # Daily at midnight + schedule: "0 0 0 * * *" # Daily at midnight + backupOwnerReference: self + retentionPolicy: "30d" diff --git a/charts/cluster/examples/volumesnapshot.yml b/charts/cluster/examples/volumesnapshot.yml new file mode 100644 index 000000000..bbd80e0e7 --- /dev/null +++ b/charts/cluster/examples/volumesnapshot.yml @@ -0,0 +1,22 @@ +type: postgresql +mode: standalone +version: + postgresql: "16" +cluster: + instances: 1 +backups: + enabled: true + method: volumeSnapshot + volumeSnapshot: + labels: + testlabel: abc + annotations: + testannotation: def + className: snapclass + snapshotOwnerReference: backup + online: true + scheduledBackups: + - name: daily-backup + schedule: "0 0 0 * * *" + backupOwnerReference: self + method: volumeSnapshot diff --git a/charts/cluster/templates/NOTES.txt b/charts/cluster/templates/NOTES.txt index 5e96a74ea..4c17def12 100644 --- a/charts/cluster/templates/NOTES.txt +++ b/charts/cluster/templates/NOTES.txt @@ -82,7 +82,10 @@ Configuration │ Instances │ {{ include (printf "%s%s" "cluster.color-" $redundancyColor) (printf "%-56s" (toString .Values.cluster.instances)) }} │ │ Backups │ {{ include (printf "%s%s" "cluster.color-" (ternary "ok" "error" .Values.backups.enabled)) (printf "%-56s" (ternary "Enabled" "Disabled" .Values.backups.enabled)) }} │ {{- if .Values.backups.enabled }} -│ Backup Provider │ {{ printf "%-56s" (title .Values.backups.provider) }} │ +| Backup Method | {{ printf "%-56s" .Values.backups.method }} | +{{- if eq .Values.backups.method "barmanObjectStore" }} +│ Backup Provider │ {{ printf "%-56s" (title .Values.backups.barmanObjectStore.provider) }} │ +{{- end }} │ Scheduled Backups │ {{ printf "%-56s" $scheduledBackups }} │ {{- end }} │ Storage │ {{ printf "%-56s" .Values.cluster.storage.size }} │ diff --git a/charts/cluster/templates/_backup.tpl b/charts/cluster/templates/_backup.tpl index 8059618c4..93412c4e2 100644 --- a/charts/cluster/templates/_backup.tpl +++ b/charts/cluster/templates/_backup.tpl @@ -1,19 +1,42 @@ {{- define "cluster.backup" -}} {{- if .Values.backups.enabled }} backup: - target: "prefer-standby" + target: {{ .Values.backups.target }} retentionPolicy: {{ .Values.backups.retentionPolicy }} + {{- if eq .Values.backups.method "plugin" }} + pluginConfiguration: + name: {{ .Values.backups.pluginConfiguration.name }} + parameters: + {{ .Values.backups.pluginConfiguration.parameters | toYaml | nindent 6 }} + {{- end }} + {{- if eq .Values.backups.method "volumeSnapshot" }} + volumeSnapshot: + labels: + {{ .Values.backups.volumeSnapshot.labels | toYaml | nindent 6 }} + annotations: + {{ .Values.backups.volumeSnapshot.annotations | toYaml | nindent 6 }} + className: {{ .Values.backups.volumeSnapshot.className }} + walClassName: {{ .Values.backups.volumeSnapshot.walClassName }} + tablespaceClassName: + {{ .Values.backups.volumeSnapshot.tablespaceClassName | toYaml | nindent 6 }} + snapshotOwnerReference: {{ .Values.backups.volumeSnapshot.snapshotOwnerReference }} + online: {{ .Values.backups.volumeSnapshot.online }} + onlineConfiguration: + waitForArchive: {{ .Values.backups.volumeSnapshot.onlineConfiguration.waitForArchive }} + immediateCheckpoint: {{ .Values.backups.volumeSnapshot.onlineConfiguration.immediateCheckpoint }} + {{- end }} + {{- if eq .Values.backups.method "barmanObjectStore" }} barmanObjectStore: wal: - compression: {{ .Values.backups.wal.compression }} - encryption: {{ .Values.backups.wal.encryption }} - maxParallel: {{ .Values.backups.wal.maxParallel }} + compression: {{ .Values.backups.barmanObjectStore.wal.compression }} + encryption: {{ .Values.backups.barmanObjectStore.wal.encryption }} + maxParallel: {{ .Values.backups.barmanObjectStore.wal.maxParallel }} data: - compression: {{ .Values.backups.data.compression }} - encryption: {{ .Values.backups.data.encryption }} - jobs: {{ .Values.backups.data.jobs }} - - {{- $d := dict "chartFullname" (include "cluster.fullname" .) "scope" .Values.backups "secretPrefix" "backup" }} + compression: {{ .Values.backups.barmanObjectStore.data.compression }} + encryption: {{ .Values.backups.barmanObjectStore.data.encryption }} + jobs: {{ .Values.backups.barmanObjectStore.data.jobs }} + {{- $d := dict "chartFullname" (include "cluster.fullname" .) "scope" .Values.backups.barmanObjectStore "secretPrefix" "backup" }} {{- include "cluster.barmanObjectStoreConfig" $d | nindent 2 }} + {{- end }} {{- end }} {{- end }} diff --git a/charts/cluster/templates/backup-azure-creds.yaml b/charts/cluster/templates/backup-azure-creds.yaml index 7d384ea1b..c199de339 100644 --- a/charts/cluster/templates/backup-azure-creds.yaml +++ b/charts/cluster/templates/backup-azure-creds.yaml @@ -1,12 +1,12 @@ -{{- if and .Values.backups.enabled (eq .Values.backups.provider "azure") .Values.backups.secret.create }} +{{- if and .Values.backups.enabled (eq .Values.backups.method "barmanObjectStore") (eq .Values.backups.barmanObjectStore.provider "azure") .Values.backups.barmanObjectStore.secret.create }} apiVersion: v1 kind: Secret metadata: - name: {{ default (printf "%s-backup-azure-creds" (include "cluster.fullname" .)) .Values.backups.secret.name }} + name: {{ default (printf "%s-backup-azure-creds" (include "cluster.fullname" .)) .Values.backups.barmanObjectStore.secret.name }} namespace: {{ include "cluster.namespace" . }} data: - AZURE_CONNECTION_STRING: {{ .Values.backups.azure.connectionString | b64enc | quote }} - AZURE_STORAGE_ACCOUNT: {{ .Values.backups.azure.storageAccount | b64enc | quote }} - AZURE_STORAGE_KEY: {{ .Values.backups.azure.storageKey | b64enc | quote }} - AZURE_STORAGE_SAS_TOKEN: {{ .Values.backups.azure.storageSasToken | b64enc | quote }} + AZURE_CONNECTION_STRING: {{ .Values.backups.barmanObjectStore.azure.connectionString | b64enc | quote }} + AZURE_STORAGE_ACCOUNT: {{ .Values.backups.barmanObjectStore.azure.storageAccount | b64enc | quote }} + AZURE_STORAGE_KEY: {{ .Values.backups.barmanObjectStore.azure.storageKey | b64enc | quote }} + AZURE_STORAGE_SAS_TOKEN: {{ .Values.backups.barmanObjectStore.azure.storageSasToken | b64enc | quote }} {{- end }} diff --git a/charts/cluster/templates/backup-google-creds.yaml b/charts/cluster/templates/backup-google-creds.yaml index 1b1f52fb4..e997a2cbe 100644 --- a/charts/cluster/templates/backup-google-creds.yaml +++ b/charts/cluster/templates/backup-google-creds.yaml @@ -1,9 +1,9 @@ -{{- if and .Values.backups.enabled (eq .Values.backups.provider "google") .Values.backups.secret.create }} +{{- if and .Values.backups.enabled (eq .Values.backups.method "barmanObjectStore") (eq .Values.backups.barmanObjectStore.provider "google") .Values.backups.barmanObjectStore.secret.create }} apiVersion: v1 kind: Secret metadata: - name: {{ default (printf "%s-backup-google-creds" (include "cluster.fullname" .)) .Values.backups.secret.name }} + name: {{ default (printf "%s-backup-google-creds" (include "cluster.fullname" .)) .Values.backups.barmanObjectStore.secret.name }} namespace: {{ include "cluster.namespace" . }} data: - APPLICATION_CREDENTIALS: {{ .Values.backups.google.applicationCredentials | b64enc | quote }} + APPLICATION_CREDENTIALS: {{ .Values.backups.barmanObjectStore.google.applicationCredentials | b64enc | quote }} {{- end }} diff --git a/charts/cluster/templates/backup-s3-creds.yaml b/charts/cluster/templates/backup-s3-creds.yaml index 558573295..b262460bd 100644 --- a/charts/cluster/templates/backup-s3-creds.yaml +++ b/charts/cluster/templates/backup-s3-creds.yaml @@ -1,10 +1,10 @@ -{{- if and .Values.backups.enabled (eq .Values.backups.provider "s3") (not .Values.backups.s3.inheritFromIAMRole) .Values.backups.secret.create }} +{{- if and .Values.backups.enabled (eq .Values.backups.method "barmanObjectStore") (eq .Values.backups.barmanObjectStore.provider "s3") (not .Values.backups.barmanObjectStore.s3.inheritFromIAMRole) .Values.backups.barmanObjectStore.secret.create }} apiVersion: v1 kind: Secret metadata: - name: {{ default (printf "%s-backup-s3-creds" (include "cluster.fullname" .)) .Values.backups.secret.name }} + name: {{ default (printf "%s-backup-s3-creds" (include "cluster.fullname" .)) .Values.backups.barmanObjectStore.secret.name }} namespace: {{ include "cluster.namespace" . }} data: - ACCESS_KEY_ID: {{ required ".Values.backups.s3.accessKey is required, but not specified." .Values.backups.s3.accessKey | b64enc | quote }} - ACCESS_SECRET_KEY: {{ required ".Values.backups.s3.secretKey is required, but not specified." .Values.backups.s3.secretKey | b64enc | quote }} + ACCESS_KEY_ID: {{ required ".Values.backups.barmanObjectStore.s3.accessKey is required, but not specified." .Values.backups.barmanObjectStore.s3.accessKey | b64enc | quote }} + ACCESS_SECRET_KEY: {{ required ".Values.backups.barmanObjectStore.s3.secretKey is required, but not specified." .Values.backups.barmanObjectStore.s3.secretKey | b64enc | quote }} {{- end }} diff --git a/charts/cluster/templates/ca-bundle.yaml b/charts/cluster/templates/ca-bundle.yaml index 8f46f5af6..51e47faf6 100644 --- a/charts/cluster/templates/ca-bundle.yaml +++ b/charts/cluster/templates/ca-bundle.yaml @@ -1,10 +1,10 @@ -{{- if .Values.backups.endpointCA.create }} +{{- if .Values.backups.barmanObjectStore.endpointCA.create }} apiVersion: v1 kind: Secret metadata: - name: {{ .Values.backups.endpointCA.name | default (printf "%s-ca-bundle" (include "cluster.fullname" .)) | quote }} + name: {{ .Values.backups.barmanObjectStore.endpointCA.name | default (printf "%s-ca-bundle" (include "cluster.fullname" .)) | quote }} namespace: {{ include "cluster.namespace" . }} data: - {{ .Values.backups.endpointCA.key | default "ca-bundle.crt" | quote }}: {{ .Values.backups.endpointCA.value }} + {{ .Values.backups.barmanObjectStore.endpointCA.key | default "ca-bundle.crt" | quote }}: {{ .Values.backups.barmanObjectStore.endpointCA.value }} {{- end }} diff --git a/charts/cluster/test/postgresql-minio-backup-restore/01-standalone_cluster.yaml b/charts/cluster/test/postgresql-minio-backup-restore/01-standalone_cluster.yaml index 7db3fe9af..baaf9a2db 100644 --- a/charts/cluster/test/postgresql-minio-backup-restore/01-standalone_cluster.yaml +++ b/charts/cluster/test/postgresql-minio-backup-restore/01-standalone_cluster.yaml @@ -8,20 +8,21 @@ cluster: backups: enabled: true - provider: s3 - endpointURL: "https://minio.minio.svc.cluster.local" - endpointCA: - name: kube-root-ca.crt - key: ca.crt - wal: - encryption: "" - data: - encryption: "" - s3: - bucket: "mybucket" - path: "/postgresql-minio-backup-restore/v1" - accessKey: "minio" - secretKey: "minio123" - region: "local" - scheduledBackups: [] - retentionPolicy: "30d" + barmanObjectStore: + provider: s3 + endpointURL: "https://minio.minio.svc.cluster.local" + endpointCA: + name: kube-root-ca.crt + key: ca.crt + wal: + encryption: "" + data: + encryption: "" + s3: + bucket: "mybucket" + path: "/postgresql-minio-backup-restore/v1" + accessKey: "minio" + secretKey: "minio123" + region: "local" + scheduledBackups: [] + retentionPolicy: "30d" diff --git a/charts/cluster/test/postgresql-minio-backup-restore/05-recovery_backup_cluster.yaml b/charts/cluster/test/postgresql-minio-backup-restore/05-recovery_backup_cluster.yaml index c2731b3bf..9a3552fa8 100644 --- a/charts/cluster/test/postgresql-minio-backup-restore/05-recovery_backup_cluster.yaml +++ b/charts/cluster/test/postgresql-minio-backup-restore/05-recovery_backup_cluster.yaml @@ -29,20 +29,21 @@ recovery: backups: enabled: true - provider: s3 - endpointURL: "https://minio.minio.svc.cluster.local" - endpointCA: - name: kube-root-ca.crt - key: ca.crt - wal: - encryption: "" - data: - encryption: "" - s3: - bucket: "mybucket" - path: "/postgresql-minio-backup-restore/v2" - accessKey: "minio" - secretKey: "minio123" - region: "local" - scheduledBackups: [] - retentionPolicy: "30d" + barmanObjectStore: + provider: s3 + endpointURL: "https://minio.minio.svc.cluster.local" + endpointCA: + name: kube-root-ca.crt + key: ca.crt + wal: + encryption: "" + data: + encryption: "" + s3: + bucket: "mybucket" + path: "/postgresql-minio-backup-restore/v2" + accessKey: "minio" + secretKey: "minio123" + region: "local" + scheduledBackups: [] + retentionPolicy: "30d" diff --git a/charts/cluster/test/postgresql-minio-backup-restore/07-recovery_object_store_cluster.yaml b/charts/cluster/test/postgresql-minio-backup-restore/07-recovery_object_store_cluster.yaml index 7f059e394..a74e04954 100644 --- a/charts/cluster/test/postgresql-minio-backup-restore/07-recovery_object_store_cluster.yaml +++ b/charts/cluster/test/postgresql-minio-backup-restore/07-recovery_object_store_cluster.yaml @@ -29,20 +29,21 @@ recovery: backups: enabled: true - provider: s3 - endpointURL: "https://minio.minio.svc.cluster.local" - endpointCA: - name: kube-root-ca.crt - key: ca.crt - wal: - encryption: "" - data: - encryption: "" - s3: - bucket: "mybucket" - path: "/postgresql-minio-backup-restore/v2" - accessKey: "minio" - secretKey: "minio123" - region: "local" - scheduledBackups: [] - retentionPolicy: "30d" + barmanObjectStore: + provider: s3 + endpointURL: "https://minio.minio.svc.cluster.local" + endpointCA: + name: kube-root-ca.crt + key: ca.crt + wal: + encryption: "" + data: + encryption: "" + s3: + bucket: "mybucket" + path: "/postgresql-minio-backup-restore/v2" + accessKey: "minio" + secretKey: "minio123" + region: "local" + scheduledBackups: [] + retentionPolicy: "30d" diff --git a/charts/cluster/test/postgresql-minio-backup-restore/09-recovery_backup_pitr_cluster.yaml b/charts/cluster/test/postgresql-minio-backup-restore/09-recovery_backup_pitr_cluster.yaml index c2731b3bf..9a3552fa8 100644 --- a/charts/cluster/test/postgresql-minio-backup-restore/09-recovery_backup_pitr_cluster.yaml +++ b/charts/cluster/test/postgresql-minio-backup-restore/09-recovery_backup_pitr_cluster.yaml @@ -29,20 +29,21 @@ recovery: backups: enabled: true - provider: s3 - endpointURL: "https://minio.minio.svc.cluster.local" - endpointCA: - name: kube-root-ca.crt - key: ca.crt - wal: - encryption: "" - data: - encryption: "" - s3: - bucket: "mybucket" - path: "/postgresql-minio-backup-restore/v2" - accessKey: "minio" - secretKey: "minio123" - region: "local" - scheduledBackups: [] - retentionPolicy: "30d" + barmanObjectStore: + provider: s3 + endpointURL: "https://minio.minio.svc.cluster.local" + endpointCA: + name: kube-root-ca.crt + key: ca.crt + wal: + encryption: "" + data: + encryption: "" + s3: + bucket: "mybucket" + path: "/postgresql-minio-backup-restore/v2" + accessKey: "minio" + secretKey: "minio123" + region: "local" + scheduledBackups: [] + retentionPolicy: "30d" diff --git a/charts/cluster/test/scheduledbackups/01-scheduledbackups_cluster.yaml b/charts/cluster/test/scheduledbackups/01-scheduledbackups_cluster.yaml index c5ea25be6..34b3c2b27 100644 --- a/charts/cluster/test/scheduledbackups/01-scheduledbackups_cluster.yaml +++ b/charts/cluster/test/scheduledbackups/01-scheduledbackups_cluster.yaml @@ -8,22 +8,23 @@ cluster: backups: enabled: true - provider: s3 - endpointURL: "https://minio.minio.svc.cluster.local" - endpointCA: - name: kube-root-ca.crt - key: ca.crt - wal: - encryption: "" - data: - encryption: "" - s3: - bucket: "mybucket" - path: "/scheduledbackups/v1" - accessKey: "minio" - secretKey: "minio123" - region: "local" - retentionPolicy: "30d" + barmanObjectStore: + provider: s3 + endpointURL: "https://minio.minio.svc.cluster.local" + endpointCA: + name: kube-root-ca.crt + key: ca.crt + wal: + encryption: "" + data: + encryption: "" + s3: + bucket: "mybucket" + path: "/scheduledbackups/v1" + accessKey: "minio" + secretKey: "minio123" + region: "local" + retentionPolicy: "30d" scheduledBackups: - name: daily-backup schedule: "0 0 0 * * *" @@ -33,4 +34,3 @@ backups: schedule: "0 0 0 * * 1" backupOwnerReference: self method: barmanObjectStore - diff --git a/charts/cluster/test/timescale-minio-backup-restore/01-timescale_cluster.yaml b/charts/cluster/test/timescale-minio-backup-restore/01-timescale_cluster.yaml index f84117fe0..fa752cc89 100644 --- a/charts/cluster/test/timescale-minio-backup-restore/01-timescale_cluster.yaml +++ b/charts/cluster/test/timescale-minio-backup-restore/01-timescale_cluster.yaml @@ -8,21 +8,21 @@ cluster: backups: enabled: true - - provider: s3 - endpointURL: "https://minio.minio.svc.cluster.local" - endpointCA: - name: kube-root-ca.crt - key: ca.crt - wal: - encryption: "" - data: - encryption: "" - s3: - bucket: "mybucket" - path: "/timescale/v1" - accessKey: "minio" - secretKey: "minio123" - region: "local" - scheduledBackups: [] - retentionPolicy: "30d" + barmanObjectStore: + provider: s3 + endpointURL: "https://minio.minio.svc.cluster.local" + endpointCA: + name: kube-root-ca.crt + key: ca.crt + wal: + encryption: "" + data: + encryption: "" + s3: + bucket: "mybucket" + path: "/timescale/v1" + accessKey: "minio" + secretKey: "minio123" + region: "local" + scheduledBackups: [] + retentionPolicy: "30d" diff --git a/charts/cluster/test/timescale-minio-backup-restore/07-recovery_backup_pitr_cluster.yaml b/charts/cluster/test/timescale-minio-backup-restore/07-recovery_backup_pitr_cluster.yaml index 7e9c38f55..1621875a8 100644 --- a/charts/cluster/test/timescale-minio-backup-restore/07-recovery_backup_pitr_cluster.yaml +++ b/charts/cluster/test/timescale-minio-backup-restore/07-recovery_backup_pitr_cluster.yaml @@ -29,20 +29,21 @@ recovery: backups: enabled: true - provider: s3 - endpointURL: "https://minio.minio.svc.cluster.local" - endpointCA: - name: kube-root-ca.crt - key: ca.crt - wal: - encryption: "" - data: - encryption: "" - s3: - bucket: "mybucket" - path: "/timescale/v2" - accessKey: "minio" - secretKey: "minio123" - region: "local" - scheduledBackups: [] - retentionPolicy: "30d" + barmanObjectStore: + provider: s3 + endpointURL: "https://minio.minio.svc.cluster.local" + endpointCA: + name: kube-root-ca.crt + key: ca.crt + wal: + encryption: "" + data: + encryption: "" + s3: + bucket: "mybucket" + path: "/timescale/v2" + accessKey: "minio" + secretKey: "minio123" + region: "local" + scheduledBackups: [] + retentionPolicy: "30d" diff --git a/charts/cluster/test/volumesnapshot/01-non_default_configuration_cluster-assert.yaml b/charts/cluster/test/volumesnapshot/01-non_default_configuration_cluster-assert.yaml new file mode 100644 index 000000000..1f733ad2f --- /dev/null +++ b/charts/cluster/test/volumesnapshot/01-non_default_configuration_cluster-assert.yaml @@ -0,0 +1,183 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: non-default-configuration-cluster + annotations: + foo: bar + labels: + foo: bar +spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: In + values: + - node1 + - node2 + podAntiAffinityType: preferred + topologyKey: kubernetes.io/hostname + backup: + retentionPolicy: 30d + target: prefer-standby + volumeSnapshot: + annotations: + annotationA: valueA + annotationB: valueB + className: testClass + labels: + labelA: valueA + labelB: valueB + online: false + onlineConfiguration: + immediateCheckpoint: true + waitForArchive: false + snapshotOwnerReference: cluster + walClassName: testWalClass + bootstrap: + initdb: + database: mydb + encoding: UTF8 + localeCType: C + localeCollate: C + owner: dante + postInitApplicationSQL: + - CREATE TABLE mytable (id serial PRIMARY KEY, name VARCHAR(255)); + postInitSQL: + - CREATE TABLE mytable (id serial PRIMARY KEY, name VARCHAR(255)); + postInitTemplateSQL: + - CREATE TABLE mytable (id serial PRIMARY KEY, name VARCHAR(255)); + secret: + name: mydb-secret + certificates: + clientCASecret: client-ca-secret + replicationTLSSecret: replication-tls-secret + serverCASecret: ca-secret + serverTLSSecret: tls-secret + enablePDB: false + enableSuperuserAccess: true + failoverDelay: 0 + imageName: ghcr.io/cloudnative-pg/crazycustomimage:99.99 + imagePullPolicy: Always + imagePullSecrets: + - name: image-pull-secret + instances: 2 + logLevel: warning + managed: + roles: + - comment: Dante Alighieri + connectionLimit: -1 + ensure: present + inRoles: + - pg_monitor + - pg_signal_backend + inherit: true + login: true + name: dante + services: + additional: + - selectorType: rw + serviceTemplate: + metadata: + annotations: + test-annotation: "true" + labels: + test-label: "true" + name: test-lb + spec: + type: LoadBalancer + updateStrategy: patch + maxSyncReplicas: 0 + minSyncReplicas: 0 + monitoring: + customQueriesConfigMap: + - key: queries + name: cnpg-default-monitoring + disableDefaultQueries: false + enablePodMonitor: false + postgresGID: 1002 + postgresUID: 1001 + postgresql: + ldap: + bindSearchAuth: + baseDN: ou=org,dc=example,dc=com + bindDN: cn=admin,dc=example,dc=com + bindPassword: + key: data + name: ldapBindPassword + searchAttribute: uid + server: openldap.default.svc.cluster.local + parameters: + archive_mode: "on" + archive_timeout: 5min + dynamic_shared_memory_type: posix + full_page_writes: "on" + log_destination: csvlog + log_directory: /controller/log + log_filename: postgres + log_rotation_age: "0" + log_rotation_size: "0" + log_truncate_on_rotation: "false" + logging_collector: "on" + max_connections: "42" + max_parallel_workers: "32" + max_replication_slots: "32" + max_worker_processes: "32" + shared_memory_type: mmap + shared_preload_libraries: "" + ssl_max_protocol_version: TLSv1.3 + ssl_min_protocol_version: TLSv1.3 + wal_keep_size: 512MB + wal_level: logical + wal_log_hints: "on" + wal_receiver_timeout: 5s + wal_sender_timeout: 5s + pg_hba: + - host all 1.2.3.4/32 trust + pg_ident: + - mymap /^(.*)@mydomain\.com$ \1 + shared_preload_libraries: + - pgaudit + syncReplicaElectionConstraint: + enabled: false + synchronous: + dataDurability: required + method: any + number: 1 + primaryUpdateMethod: restart + primaryUpdateStrategy: supervised + priorityClassName: mega-high + replicationSlots: + highAvailability: + enabled: true + slotPrefix: _cnpg_ + synchronizeReplicas: + enabled: true + updateInterval: 30 + resources: + limits: + cpu: 100m + memory: 256Mi + requests: + cpu: 100m + memory: 256Mi + serviceAccountTemplate: + metadata: + annotations: + my-annotation: my-service-account + smartShutdownTimeout: 180 + startDelay: 3600 + stopDelay: 1800 + storage: + resizeInUseVolumes: true + size: 256Mi + storageClass: standard + superuserSecret: + name: supersecret-secret + switchoverDelay: 3600 + walStorage: + resizeInUseVolumes: true + size: 256Mi + storageClass: standard diff --git a/charts/cluster/test/volumesnapshot/01-non_default_configuration_cluster.yaml b/charts/cluster/test/volumesnapshot/01-non_default_configuration_cluster.yaml new file mode 100644 index 000000000..c9212270f --- /dev/null +++ b/charts/cluster/test/volumesnapshot/01-non_default_configuration_cluster.yaml @@ -0,0 +1,129 @@ +type: postgresql +mode: standalone +cluster: + instances: 2 + imageName: ghcr.io/cloudnative-pg/crazycustomimage:99.99 + imagePullPolicy: Always + imagePullSecrets: + - name: "image-pull-secret" + storage: + size: 256Mi + storageClass: standard + walStorage: + enabled: true + size: 256Mi + storageClass: standard + postgresUID: 1001 + postgresGID: 1002 + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 100m + memory: 256Mi + priorityClassName: mega-high + primaryUpdateMethod: restart + primaryUpdateStrategy: supervised + logLevel: warning + affinity: + topologyKey: kubernetes.io/hostname + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: In + values: + - node1 + - node2 + certificates: + serverCASecret: ca-secret + serverTLSSecret: tls-secret + replicationTLSSecret: replication-tls-secret + clientCASecret: client-ca-secret + enableSuperuserAccess: true + superuserSecret: supersecret-secret + enablePDB: false + services: + additional: + - selectorType: rw + serviceTemplate: + metadata: + name: "test-lb" + labels: + test-label: "true" + annotations: + test-annotation: "true" + spec: + type: LoadBalancer + roles: + - name: dante + ensure: present + comment: Dante Alighieri + login: true + inRoles: + - pg_monitor + - pg_signal_backend + postgresql: + ldap: + server: "openldap.default.svc.cluster.local" + bindSearchAuth: + baseDN: "ou=org,dc=example,dc=com" + bindDN: "cn=admin,dc=example,dc=com" + bindPassword: + name: "ldapBindPassword" + key: "data" + searchAttribute: "uid" + parameters: + max_connections: "42" + pg_hba: + - host all 1.2.3.4/32 trust + pg_ident: + - mymap /^(.*)@mydomain\.com$ \1 + shared_preload_libraries: + - pgaudit + synchronous: + method: any + number: 1 + initdb: + database: mydb + owner: dante + secret: + name: mydb-secret + postInitApplicationSQL: + - CREATE TABLE mytable (id serial PRIMARY KEY, name VARCHAR(255)); + postInitTemplateSQL: + - CREATE TABLE mytable (id serial PRIMARY KEY, name VARCHAR(255)); + postInitSQL: + - CREATE TABLE mytable (id serial PRIMARY KEY, name VARCHAR(255)); + additionalLabels: + foo: bar + annotations: + foo: bar + serviceAccountTemplate: + metadata: + annotations: + my-annotation: my-service-account +backups: + enabled: true + method: volumeSnapshot + volumeSnapshot: + labels: + labelA: valueA + labelB: valueB + annotations: + annotationA: valueA + annotationB: valueB + className: testClass + walClassName: testWalClass + snapshotOwnerReference: cluster + online: false + onlineConfiguration: + waitForArchive: false + immediateCheckpoint: true + scheduledBackups: + - name: daily-backup + schedule: "0 0 0 * * *" + backupOwnerReference: self + method: volumeSnapshot diff --git a/charts/cluster/test/volumesnapshot/chainsaw-test.yaml b/charts/cluster/test/volumesnapshot/chainsaw-test.yaml new file mode 100644 index 000000000..b02b4900d --- /dev/null +++ b/charts/cluster/test/volumesnapshot/chainsaw-test.yaml @@ -0,0 +1,30 @@ +## +# This is a test that verifies that non-default configuration options are correctly propagated to the CNPG cluster. +# P.S. This test is not designed to have a good running configuration, it is designed to test the configuration propagation! +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: postgresql-cluster-configuration +spec: + timeouts: + apply: 1s + assert: 5s + cleanup: 30s + steps: + - name: Install the non-default configuration cluster + try: + - script: + content: | + helm upgrade \ + --install \ + --namespace $NAMESPACE \ + --values ./01-non_default_configuration_cluster.yaml \ + --wait \ + non-default-configuration ../../ + - assert: + file: ./01-non_default_configuration_cluster-assert.yaml + - name: Cleanup + try: + - script: + content: | + helm uninstall --namespace $NAMESPACE non-default-configuration diff --git a/charts/cluster/values.yaml b/charts/cluster/values.yaml index 978ab476e..1741f9fe0 100644 --- a/charts/cluster/values.yaml +++ b/charts/cluster/values.yaml @@ -44,7 +44,8 @@ recovery: ## # -- Backup Recovery Method - backupName: "" # Name of the backup to recover from. Required if method is `backup`. + # Name of the backup to recover from. Required if method is `backup`. + backupName: "" ## # -- The original cluster name when used in backups. Also known as serverName. @@ -175,17 +176,18 @@ recovery: name: "" key: "" - cluster: # -- Number of instances instances: 3 # -- Name of the container image, supporting both tags (:) and digests for deterministic and repeatable deployments: # :@sha256: - imageName: "" # Default value depends on type (postgresql/postgis/timescaledb) + # Default value depends on type (postgresql/postgis/timescaledb) + imageName: "" # -- Reference to `ImageCatalog` of `ClusterImageCatalog`, if specified takes precedence over `cluster.imageName` - imageCatalogRef: {} + imageCatalogRef: + {} # kind: ImageCatalog # name: postgresql @@ -219,7 +221,8 @@ cluster: # Please refer to https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ for more information. # We strongly advise you use the same setting for limits and requests so that your cluster pods are given a Guaranteed QoS. # See: https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/ - resources: {} + resources: + {} # limits: # cpu: 2000m # memory: 8Gi @@ -263,7 +266,8 @@ cluster: # -- This feature enables declarative management of existing roles, as well as the creation of new roles if they are not # already present in the database. # See: https://cloudnative-pg.io/documentation/current/declarative_role_management/ - roles: [] + roles: + [] # - name: dante # ensure: present # comment: Dante Alighieri @@ -289,7 +293,8 @@ cluster: # -- Whether to enable the PrometheusRule automated alerts enabled: true # -- Exclude specified rules - excludeRules: [] + excludeRules: + [] # - CNPGClusterZoneSpreadWarning # -- Whether the default queries should be injected. # Set it to true if you don't want to inject default queries into the cluster. @@ -313,38 +318,44 @@ cluster: postgresql: # -- PostgreSQL configuration options (postgresql.conf) - parameters: {} + parameters: + {} # max_connections: 300 # -- Quorum-based Synchronous Replication - synchronous: {} - # method: any - # number: 1 + synchronous: + {} + # method: any + # number: 1 # -- PostgreSQL Host Based Authentication rules (lines to be appended to the pg_hba.conf file) - pg_hba: [] + pg_hba: + [] # - host all all 10.244.0.0/16 md5 # -- PostgreSQL User Name Maps rules (lines to be appended to the pg_ident.conf file) - pg_ident: [] + pg_ident: + [] # - mymap /^(.*)@mydomain\.com$ \1 # -- Lists of shared preload libraries to add to the default ones - shared_preload_libraries: [] + shared_preload_libraries: + [] # - pgaudit # -- PostgreSQL LDAP configuration (see https://cloudnative-pg.io/documentation/current/postgresql_conf/#ldap-configuration) - ldap: {} + ldap: + {} # https://cloudnative-pg.io/documentation/1.24/postgresql_conf/#ldap-configuration # server: 'openldap.default.svc.cluster.local' # bindSearchAuth: - # baseDN: 'ou=org,dc=example,dc=com' - # bindDN: 'cn=admin,dc=example,dc=com' - # bindPassword: - # name: 'ldapBindPassword' - # key: 'data' - # searchAttribute: 'uid' - + # baseDN: 'ou=org,dc=example,dc=com' + # bindDN: 'cn=admin,dc=example,dc=com' + # bindPassword: + # name: 'ldapBindPassword' + # key: 'data' + # searchAttribute: 'uid' # -- BootstrapInitDB is the configuration of the bootstrap process when initdb is used. # See: https://cloudnative-pg.io/documentation/current/bootstrap/ # See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-bootstrapinitdb - initdb: {} + initdb: + {} # database: app # owner: "" # Defaults to the database name # secret: @@ -362,96 +373,135 @@ cluster: additionalLabels: {} annotations: {} - backups: # -- You need to configure backups manually, so backups are disabled by default. enabled: false - # -- Overrides the provider specific default endpoint. Defaults to: - # S3: https://s3..amazonaws.com" - endpointURL: "" # Leave empty if using the default S3 endpoint - # -- Specifies a CA bundle to validate a privately signed certificate. - endpointCA: - # -- Creates a secret with the given value if true, otherwise uses an existing secret. - create: false - name: "" - key: "" - value: "" + # -- The backup method to be used, possible options are `barmanObjectStore`, `volumeSnapshot` or `plugin` + method: barmanObjectStore - # -- Overrides the provider specific default path. Defaults to: - # S3: s3:// - # Azure: https://..core.windows.net/ - # Google: gs:// - destinationPath: "" - # -- One of `s3`, `azure` or `google` - provider: s3 - s3: - region: "" - bucket: "" - path: "/" - accessKey: "" - secretKey: "" - # -- Use the role based authentication without providing explicitly the keys - inheritFromIAMRole: false - azure: - path: "/" - connectionString: "" - storageAccount: "" - storageKey: "" - storageSasToken: "" - containerName: "" - serviceName: blob - inheritFromAzureAD: false - google: - path: "/" - bucket: "" - gkeEnvironment: false - applicationCredentials: "" - secret: - # -- Whether to create a secret for the backup credentials - create: true - # -- Name of the backup credentials secret + # -- Retention policy for backups + retentionPolicy: "30d" + + # -- The policy to decide which instance should perform this backup. Available options are empty string, `primary` and `prefer-standby` + target: "prefer-standby" + + # -- Configuration for method plugin + pluginConfiguration: + # -- Name of the plugin to use name: "" + # -- Configuration for the plugin + parameters: {} - wal: - # -- WAL compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. - compression: gzip - # -- Whether to instruct the storage provider to encrypt WAL files. One of `` (use the storage container default), `AES256` or `aws:kms`. - encryption: AES256 - # -- Number of WAL files to be archived or restored in parallel. - maxParallel: 1 - data: - # -- Data compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. - compression: gzip - # -- Whether to instruct the storage provider to encrypt data files. One of `` (use the storage container default), `AES256` or `aws:kms`. - encryption: AES256 - # -- Number of data files to be archived or restored in parallel. - jobs: 2 + # -- Define volume snapshot configuration + volumeSnapshot: + # -- Key-value pairs that will be added to .metadata.labels snapshot resources. + labels: {} + # -- Key-value pairs that will be added to .metadata.annotations snapshot resources + annotations: {} + # -- Snapshot Class to be used for PG_DATA PersistentVolumeClaim + className: "" + # -- Snapshot Class to be used for the PG_WAL PersistentVolumeClaim + walClassName: "" + # -- Snapshot Class to be used for the tablespaces. defaults to the PGDATA Snapshot Class, if set + tablespaceClassName: {} + # -- Type of owner reference the snapshot should have. Available options are `none`, `cluster` and `backup` + snapshotOwnerReference: backup + # -- Define if the backup shall be online or offline + online: true + # -- Configuration for method volumeSnapshot + onlineConfiguration: + # -- If false, the function will return immediately after the backup is completed, without waiting for WAL to be archived + waitForArchive: true + # -- If set to true, an immediate checkpoint will be used, meaning PostgreSQL will complete the checkpoint as soon as possible + immediateCheckpoint: false + + # -- Configuration for method barmanObjectStore + barmanObjectStore: + # -- Overrides the provider specific default endpoint. Defaults to: + # S3: https://s3..amazonaws.com" + # Leave empty if using the default S3 endpoint + endpointURL: "" + # -- Specifies a CA bundle to validate a privately signed certificate. + endpointCA: + # -- Creates a secret with the given value if true, otherwise uses an existing secret. + create: false + name: "" + key: "" + value: "" + + # -- Overrides the provider specific default path. Defaults to: + # S3: s3:// + # Azure: https://..core.windows.net/ + # Google: gs:// + destinationPath: "" + # -- One of `s3`, `azure` or `google` + provider: s3 + s3: + region: "" + bucket: "" + path: "/" + accessKey: "" + secretKey: "" + # -- Use the role based authentication without providing explicitly the keys + inheritFromIAMRole: false + azure: + path: "/" + connectionString: "" + storageAccount: "" + storageKey: "" + storageSasToken: "" + containerName: "" + serviceName: blob + inheritFromAzureAD: false + google: + path: "/" + bucket: "" + gkeEnvironment: false + applicationCredentials: "" + secret: + # -- Whether to create a secret for the backup credentials + create: true + # -- Name of the backup credentials secret + name: "" + + wal: + # -- WAL compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. + compression: gzip + # -- Whether to instruct the storage provider to encrypt WAL files. One of `` (use the storage container default), `AES256` or `aws:kms`. + encryption: AES256 + # -- Number of WAL files to be archived or restored in parallel. + maxParallel: 1 + data: + # -- Data compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. + compression: gzip + # -- Whether to instruct the storage provider to encrypt data files. One of `` (use the storage container default), `AES256` or `aws:kms`. + encryption: AES256 + # -- Number of data files to be archived or restored in parallel. + jobs: 2 scheduledBackups: - - - # -- Scheduled backup name + - # -- Scheduled backup name name: daily-backup # -- Schedule in cron format schedule: "0 0 0 * * *" # -- Backup owner reference backupOwnerReference: self - # -- Backup method, can be `barmanObjectStore` (default) or `volumeSnapshot` + # -- Backup method, can be `barmanObjectStore` (default) or `volumeSnapshot` or `plugin` method: barmanObjectStore - # -- Retention policy for backups - retentionPolicy: "30d" - imageCatalog: # -- Whether to provision an image catalog. If imageCatalog.images is empty this option will be ignored. create: true # -- List of images to be provisioned in an image catalog. - images: [] + images: + [] # - image: ghcr.io/your_repo/your_image:your_tag # major: 16 # -- List of PgBouncer poolers -poolers: [] +poolers: + [] # - # # -- Pooler name # name: rw