Compare commits

...

4 Commits

Author SHA1 Message Date
56d7b063bd change helpers
All checks were successful
release-charts-postgres-cluster / release (push) Successful in 39s
2025-05-13 20:29:07 -05:00
1ca985edc7 rebase this chart on cnpg provided chart
All checks were successful
release-charts-postgres-cluster / release (push) Successful in 18s
2025-05-13 00:14:16 -05:00
47d7604aac change repo
All checks were successful
release-charts-cloudflared / release (push) Successful in 15s
2025-05-01 22:14:19 -05:00
ecf6e80a20 update image
Some checks failed
release-charts-cloudflared / release (push) Failing after 7s
2025-05-01 22:06:54 -05:00
34 changed files with 1338 additions and 355 deletions

View File

@@ -1,18 +1,18 @@
apiVersion: v2
name: cloudflared
version: 1.14.5
version: 1.14.7
description: Cloudflared Tunnel
keywords:
- cloudflare
- tunnel
sources:
- https://github.com/cloudflare/cloudflared
- https://github.com/bjw-s/helm-charts/tree/main/charts/library/common
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/library/common
maintainers:
- name: alexlebens
dependencies:
- name: common
repository: https://bjw-s.github.io/helm-charts/
repository: https://bjw-s-labs.github.io/helm-charts/
version: 3.7.3
icon: https://avatars.githubusercontent.com/u/314135?s=48&v=4
appVersion: "2025.4.0"
appVersion: "2025.4.2"

View File

@@ -1,6 +1,6 @@
# cloudflared
![Version: 1.14.5](https://img.shields.io/badge/Version-1.14.5-informational?style=flat-square) ![AppVersion: 2025.4.0](https://img.shields.io/badge/AppVersion-2025.4.0-informational?style=flat-square)
![Version: 1.14.7](https://img.shields.io/badge/Version-1.14.7-informational?style=flat-square) ![AppVersion: 2025.4.2](https://img.shields.io/badge/AppVersion-2025.4.2-informational?style=flat-square)
Cloudflared Tunnel
@@ -13,13 +13,13 @@ Cloudflared Tunnel
## Source Code
* <https://github.com/cloudflare/cloudflared>
* <https://github.com/bjw-s/helm-charts/tree/main/charts/library/common>
* <https://github.com/bjw-s-labs/helm-charts/tree/main/charts/library/common>
## Requirements
| Repository | Name | Version |
|------------|------|---------|
| https://bjw-s.github.io/helm-charts/ | common | 3.7.3 |
| https://bjw-s-labs.github.io/helm-charts/ | common | 3.7.3 |
## Values
@@ -27,7 +27,7 @@ Cloudflared Tunnel
|-----|------|---------|-------------|
| existingSecretKey | string | `"cf-tunnel-token"` | Name of key that contains the token in the existingSecret |
| existingSecretName | string | `"cloudflared-secret"` | Name of existing secret that contains Cloudflare token |
| image | object | `{"pullPolicy":"IfNotPresent","repository":"cloudflare/cloudflared","tag":"2025.4.0"}` | Default image |
| image | object | `{"pullPolicy":"IfNotPresent","repository":"cloudflare/cloudflared","tag":"2025.4.2"}` | Default image |
| name | string | `"cloudflared"` | Name override of release |
| resources | object | `{"requests":{"cpu":"10m","memory":"128Mi"}}` | Default resources |

View File

@@ -10,7 +10,7 @@ existingSecretKey: cf-tunnel-token
# -- Default image
image:
repository: cloudflare/cloudflared
tag: "2025.4.0"
tag: "2025.4.2"
pullPolicy: IfNotPresent
# -- Default resources

View File

@@ -1,13 +1,14 @@
apiVersion: v2
name: postgres-cluster
version: 4.2.1
description: Chart for cloudnative-pg cluster
version: 5.0.1
description: Cloudnative-pg Cluster
keywords:
- database
- postgres
sources:
- https://github.com/cloudnative-pg/cloudnative-pg
- https://github.com/cloudnative-pg/charts/tree/main/charts/cluster
maintainers:
- name: alexlebens
icon: https://avatars.githubusercontent.com/u/100373852?s=48&v=4
appVersion: v1.25.0
appVersion: v1.25.1

View File

@@ -1,8 +1,8 @@
# postgres-cluster
![Version: 4.2.1](https://img.shields.io/badge/Version-4.2.1-informational?style=flat-square) ![AppVersion: v1.25.0](https://img.shields.io/badge/AppVersion-v1.25.0-informational?style=flat-square)
![Version: 5.0.1](https://img.shields.io/badge/Version-5.0.1-informational?style=flat-square) ![AppVersion: v1.25.1](https://img.shields.io/badge/AppVersion-v1.25.1-informational?style=flat-square)
Chart for cloudnative-pg cluster
Cloudnative-pg Cluster
## Maintainers
@@ -13,70 +13,124 @@ Chart for cloudnative-pg cluster
## Source Code
* <https://github.com/cloudnative-pg/cloudnative-pg>
* <https://github.com/cloudnative-pg/charts/tree/main/charts/cluster>
## Values
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| backup | object | `{"backupIndex":1,"backupName":"","data":{"compression":"snappy","encryption":"","jobs":1},"destinationPath":"","enabled":false,"endpointCA":{"create":false,"key":"","name":""},"endpointCredentials":"","endpointURL":"","retentionPolicy":"30d","scheduledBackups":[{"backupOwnerReference":"self","method":"barmanObjectStore","name":"daily-backup","schedule":"0 0 */3 * *"}],"wal":{"compression":"snappy","encryption":"","maxParallel":1}}` | Backup settings |
| backup.backupIndex | int | `1` | Generate external cluster name, creates: postgresql-{{ .Release.Name }}-cluster-backup-index-{{ .Values.backups.backupIndex }}" |
| backup.backupName | string | `""` | Name of the backup cluster in the object store, defaults to "cluster.name" |
| backup.backupName | string | `""` | Override ame of the backup cluster in the object store, defaults to "cluster.name" |
| backup.data.compression | string | `"snappy"` | Data compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. |
| backup.data.encryption | string | `""` | Whether to instruct the storage provider to encrypt data files. One of `` (use the storage container default), `AES256` or `aws:kms`. |
| backup.data.jobs | int | `1` | Number of data files to be archived or restored in parallel. |
| backup.destinationPath | string | `""` | S3 path starting with "s3://" |
| backup.enabled | bool | `false` | |
| backup.endpointCA | string | `""` | Specifies secret that contains a CA bundle to validate a privately signed certificate, should contain the key ca-bundle.crt |
| backup.destinationPath | string | `""` | Overrides the provider specific default path. Defaults to: S3: s3://<bucket><path> Azure: https://<storageAccount>.<serviceName>.core.windows.net/<containerName><path> Google: gs://<bucket><path> |
| backup.enabled | bool | `false` | You need to configure backups manually, so backups are disabled by default. |
| backup.endpointCA | object | `{"create":false,"key":"","name":""}` | Specifies a CA bundle to validate a privately signed certificate. |
| backup.endpointCA.create | bool | `false` | Creates a secret with the given value if true, otherwise uses an existing secret. |
| backup.endpointCredentials | string | `""` | Specifies secret that contains S3 credentials, should contain the keys ACCESS_KEY_ID and ACCESS_SECRET_KEY |
| backup.endpointURL | string | `""` | S3 endpoint starting with "https://" |
| backup.historyTags.backupRetentionPolicy | string | `""` | |
| backup.retentionPolicy | string | `"7d"` | Retention policy for backups |
| backup.schedule | string | `"0 0 */3 * *"` | Scheduled backup in cron format |
| backup.tags | object | `{"backupRetentionPolicy":""}` | Tags to add to backups. Add in key value beneath the type. |
| backup.endpointURL | string | `""` | Overrides the provider specific default endpoint. Defaults to: S3: https://s3.<region>.amazonaws.com" |
| backup.retentionPolicy | string | `"30d"` | Retention policy for backups |
| backup.scheduledBackups[0].backupOwnerReference | string | `"self"` | Backup owner reference |
| backup.scheduledBackups[0].method | string | `"barmanObjectStore"` | Backup method, can be `barmanObjectStore` (default) or `volumeSnapshot` |
| backup.scheduledBackups[0].name | string | `"daily-backup"` | Scheduled backup name |
| backup.scheduledBackups[0].schedule | string | `"0 0 */3 * *"` | Schedule in cron format |
| backup.wal | object | `{"compression":"snappy","encryption":"","maxParallel":1}` | Storage |
| backup.wal.compression | string | `"snappy"` | WAL compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. |
| backup.wal.encryption | string | `""` | Whether to instruct the storage provider to encrypt WAL files. One of `` (use the storage container default), `AES256` or `aws:kms`. |
| backup.wal.maxParallel | int | `1` | Number of WAL files to be archived or restored in parallel. |
| bootstrap | object | `{"initdb":{}}` | Bootstrap 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 |
| bootstrap.initdb | object | `{}` | Example values database: app owner: app secret: "" # Name of the secret containing the initial credentials for the owner of the user database. If empty a new secret will be created from scratch postInitApplicationSQL: - CREATE TABLE IF NOT EXISTS example; |
| cluster.additionalLabels | object | `{}` | |
| cluster.affinity | object | `{"enablePodAntiAffinity":true,"topologyKey":"kubernetes.io/hostname"}` | See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-AffinityConfiguration |
| cluster.annotations | object | `{}` | |
| cluster.enableSuperuserAccess | bool | `false` | Create secret containing credentials of superuser |
| cluster.image | object | `{"pullPolicy":"IfNotPresent","repository":"ghcr.io/cloudnative-pg/postgresql","tag":"17.4-3-bullseye"}` | Default image |
| cluster.instances | int | `3` | |
| cluster.logLevel | string | `"info"` | |
| cluster.monitoring | object | `{"enabled":false,"podMonitor":{"enabled":true},"prometheusRule":{"enableDefaultRules":true,"enabled":false,"excludeRules":[]}}` | Enable default monitoring and alert rules |
| cluster.postgresGID | int | `26` | |
| cluster.postgresUID | int | `26` | The UID and GID of the postgres user inside the image |
| cluster.postgresql | object | `{"parameters":{"hot_standby_feedback":"on","max_slot_wal_keep_size":"2000MB","shared_buffers":"128MB"},"shared_preload_libraries":[]}` | Parameters to be set for the database itself See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-PostgresConfiguration |
| cluster.primaryUpdateMethod | string | `"switchover"` | Method to follow to upgrade the primary server during a rolling update procedure, after all replicas have been successfully updated. It can be switchover (default) or in-place (restart). |
| cluster | object | `{"additionalLabels":{},"affinity":{"enablePodAntiAffinity":true,"topologyKey":"kubernetes.io/hostname"},"annotations":{},"certificates":{},"enablePDB":true,"enableSuperuserAccess":false,"image":{"repository":"ghcr.io/cloudnative-pg/postgresql","tag":"17.4-3-bullseye"},"imageCatalogRef":{},"imagePullPolicy":"IfNotPresent","imagePullSecrets":[],"initdb":{},"instances":3,"logLevel":"info","monitoring":{"customQueries":[],"customQueriesSecret":[],"disableDefaultQueries":false,"enabled":false,"podMonitor":{"enabled":true,"metricRelabelings":[],"relabelings":[]},"prometheusRule":{"enabled":false,"excludeRules":[]}},"postgresGID":-1,"postgresUID":-1,"postgresql":{"ldap":{},"parameters":{"hot_standby_feedback":"on","max_slot_wal_keep_size":"2000MB","shared_buffers":"128MB"},"pg_hba":[],"pg_ident":[],"shared_preload_libraries":[],"synchronous":{}},"primaryUpdateMethod":"switchover","primaryUpdateStrategy":"unsupervised","priorityClassName":"","resources":{"limits":{"hugepages-2Mi":"256Mi"},"requests":{"cpu":"100m","memory":"256Mi"}},"roles":[],"serviceAccountTemplate":{},"services":{},"storage":{"size":"10Gi","storageClass":""},"superuserSecret":"","walStorage":{"enabled":true,"size":"2Gi","storageClass":""}}` | Cluster settings |
| cluster.affinity | object | `{"enablePodAntiAffinity":true,"topologyKey":"kubernetes.io/hostname"}` | Affinity/Anti-affinity rules for Pods. See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-AffinityConfiguration |
| cluster.certificates | object | `{}` | The configuration for the CA and related certificates. See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-CertificatesConfiguration |
| 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 | `false` | 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.image | object | `{"repository":"ghcr.io/cloudnative-pg/postgresql","tag":"17.4-3-bullseye"}` | Default image |
| cluster.imageCatalogRef | object | `{}` | Reference to `ImageCatalog` of `ClusterImageCatalog`, if specified takes precedence over `cluster.imageName` |
| 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 | `{}` | Bootstrap 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 |
| cluster.logLevel | string | `"info"` | The instances' log level, one of the following values: error, warning, info (default), debug, trace |
| cluster.monitoring | object | `{"customQueries":[],"customQueriesSecret":[],"disableDefaultQueries":false,"enabled":false,"podMonitor":{"enabled":true,"metricRelabelings":[],"relabelings":[]},"prometheusRule":{"enabled":false,"excludeRules":[]}}` | Enable default monitoring and alert rules |
| cluster.monitoring.customQueries | list | `[]` | Custom Prometheus metrics Will be stored in the ConfigMap |
| cluster.monitoring.customQueriesSecret | list | `[]` | The list of secrets containing the custom queries |
| cluster.monitoring.disableDefaultQueries | bool | `false` | Whether the default queries should be injected. Set it to true if you don't want to inject default queries into the cluster. |
| cluster.monitoring.enabled | bool | `false` | Whether to enable monitoring |
| cluster.monitoring.podMonitor.enabled | bool | `true` | Whether to enable the PodMonitor |
| cluster.monitoring.podMonitor.metricRelabelings | list | `[]` | The list of metric relabelings for the PodMonitor. Applied to samples before ingestion. |
| cluster.monitoring.podMonitor.relabelings | list | `[]` | The list of relabelings for the PodMonitor. Applied to samples before scraping. |
| cluster.monitoring.prometheusRule.enabled | bool | `false` | Whether to enable the PrometheusRule automated alerts |
| cluster.monitoring.prometheusRule.excludeRules | list | `[]` | Exclude specified rules |
| cluster.postgresUID | int | `-1` | The UID and GID of the postgres user inside the image, defaults to 26 |
| cluster.postgresql | object | `{"ldap":{},"parameters":{"hot_standby_feedback":"on","max_slot_wal_keep_size":"2000MB","shared_buffers":"128MB"},"pg_hba":[],"pg_ident":[],"shared_preload_libraries":[],"synchronous":{}}` | Parameters to be set for the database itself See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-PostgresConfiguration |
| cluster.postgresql.ldap | object | `{}` | PostgreSQL LDAP configuration (see https://cloudnative-pg.io/documentation/current/postgresql_conf/#ldap-configuration) |
| cluster.postgresql.parameters | object | `{"hot_standby_feedback":"on","max_slot_wal_keep_size":"2000MB","shared_buffers":"128MB"}` | PostgreSQL configuration options (postgresql.conf) |
| cluster.postgresql.pg_hba | list | `[]` | PostgreSQL Host Based Authentication rules (lines to be appended to the pg_hba.conf file) |
| cluster.postgresql.pg_ident | list | `[]` | PostgreSQL User Name Maps rules (lines to be appended to the pg_ident.conf file) |
| cluster.postgresql.shared_preload_libraries | list | `[]` | Lists of shared preload libraries to add to the default ones |
| cluster.postgresql.synchronous | object | `{}` | Quorum-based Synchronous Replication |
| cluster.primaryUpdateMethod | string | `"switchover"` | Method to follow to upgrade the primary server during a rolling update procedure, after all replicas have been successfully updated. It can be switchover (default) or restart. |
| cluster.primaryUpdateStrategy | string | `"unsupervised"` | Strategy to follow to upgrade the primary server during a rolling update procedure, after all replicas have been successfully updated: it can be automated (unsupervised - default) or manual (supervised) |
| cluster.priorityClassName | string | `""` | |
| cluster.resources | object | `{"limits":{"cpu":"1","hugepages-2Mi":"256Mi"},"requests":{"cpu":"100m","memory":"256Mi"}}` | Default resources |
| cluster.storage.size | string | `"10Gi"` | |
| cluster.storage.storageClass | string | `""` | |
| cluster.walStorage | object | `{"size":"2Gi","storageClass":""}` | Default storage size |
| mode | string | `"standalone"` | Cluster mode of operation. Available modes: * `standalone` - Default mode. Creates new or updates an existing CNPG cluster. * `recovery` - Same as standalone but creates a cluster from a backup, object store or via pg_basebackup * `replica` - Create database as a replica from another CNPG cluster |
| cluster.resources | object | `{"limits":{"hugepages-2Mi":"256Mi"},"requests":{"cpu":"100m","memory":"256Mi"}}` | Resources requirements of every generated Pod. 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/ |
| cluster.roles | list | `[]` | 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/ |
| cluster.serviceAccountTemplate | object | `{}` | Configure the metadata of the generated service account |
| cluster.services | object | `{}` | Customization of service definitions. Please refer to https://cloudnative-pg.io/documentation/current/service_management/ |
| cluster.storage | object | `{"size":"10Gi","storageClass":""}` | Default storage size |
| imageCatalog.create | bool | `false` | Whether to provision an image catalog. If imageCatalog.images is empty this option will be ignored. |
| imageCatalog.images | list | `[]` | List of images to be provisioned in an image catalog. |
| mode | string | `"standalone"` | Cluster mode of operation. Available modes: * `standalone` - Default mode. Creates new or updates an existing CNPG cluster. * `recovery` - Same as standalone but creates a cluster from a backup, object store or via pg_basebackup |
| nameOverride | string | `""` | Override the name of the cluster |
| recovery | object | `{"data":{"compression":"snappy","encryption":"","jobs":1},"destinationPath":"","endpointCA":"","endpointCredentials":"","endpointURL":"","pitrTarget":{"time":""},"recoveryIndex":1,"recoveryInstanceName":"","recoveryServerName":"","wal":{"compression":"snappy","encryption":"","maxParallel":1}}` | Recovery settings when booting cluster from external cluster |
| recovery.data.compression | string | `"snappy"` | Data compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. |
| recovery.data.encryption | string | `""` | Whether to instruct the storage provider to encrypt data files. One of `` (use the storage container default), `AES256` or `aws:kms`. |
| recovery.data.jobs | int | `1` | Number of data files to be archived or restored in parallel. |
| recovery.endpointCA | string | `""` | Specifies secret that contains a CA bundle to validate a privately signed certificate, should contain the key ca-bundle.crt |
| recovery.endpointCredentials | string | `""` | Specifies secret that contains S3 credentials, should contain the keys ACCESS_KEY_ID and ACCESS_SECRET_KEY |
| recovery.endpointURL | string | `""` | S3 https endpoint and the s3:// path |
| recovery.pitrTarget | object | `{"time":""}` | Point in time recovery target in RFC3339 format |
| recovery.recoveryIndex | int | `1` | Generate external cluster name, uses: {{ .Release.Name }}postgresql-<major version>-cluster-backup-index-{{ .Values.recovery.recoveryIndex }} |
| recovery.recoveryInstanceName | string | `""` | Name of the recovery cluster in the object store, defaults to ".Release.Name" |
| recovery.recoveryServerName | string | `""` | Name of the recovery cluster in the object store, defaults to "cluster.name" |
| recovery.wal.compression | string | `"snappy"` | WAL compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. |
| recovery.wal.encryption | string | `""` | Whether to instruct the storage provider to encrypt WAL files. One of `` (use the storage container default), `AES256` or `aws:kms`. |
| recovery.wal.maxParallel | int | `1` | Number of WAL files to be archived or restored in parallel. |
| replica.externalCluster | object | `{"connectionParameters":{"dbname":"app","host":"postgresql","user":"app"},"password":{"key":"password","name":"postgresql"}}` | External cluster connection, password specifies a secret name and the key containing the password value |
| replica.importDatabases | list | `["app"]` | If type microservice only one database is allowed, default is app as standard in cnpg clusters |
| replica.importRoles | list | `[]` | If type microservice no roles are imported and ignored |
| replica.importType | string | `"microservice"` | See [here](https://cloudnative-pg.io/documentation/current/database_import/) for different import types * `microservice` - Single database import as expected from cnpg clusters * `monolith` - Import multiple databases and roles |
| replica.postImportApplicationSQL | list | `[]` | If import type is monolith postImportApplicationSQL is not supported and ignored |
| namespaceOverride | string | `""` | Override the namespace of the chart |
| poolers | list | `[]` | List of PgBouncer poolers |
| recovery | object | `{"backup":{"backupName":"","database":"app","owner":"","pitrTarget":{"time":""}},"import":{"databases":[],"pgDumpExtraOptions":[],"pgRestoreExtraOptions":[],"postImportApplicationSQL":[],"roles":[],"schemaOnly":false,"source":{"database":"app","host":"","passwordSecret":{"create":false,"key":"password","name":"","value":""},"port":5432,"sslCertSecret":{"key":"","name":""},"sslKeySecret":{"key":"","name":""},"sslMode":"verify-full","sslRootCertSecret":{"key":"","name":""},"username":"app"},"type":"microservice"},"method":"backup","objectStore":{"data":{"compression":"snappy","encryption":"","jobs":1},"database":"app","destinationPath":"","endpointCA":{"create":false,"key":"","name":""},"endpointCredentials":"","endpointURL":"","owner":"","pitrTarget":{"time":""},"recoveryIndex":1,"recoveryServerName":"","wal":{"compression":"snappy","encryption":"","maxParallel":1}},"pgBaseBackup":{"database":"app","owner":"","secret":"","source":{"database":"app","host":"","passwordSecret":{"create":false,"key":"password","name":"","value":""},"port":5432,"sslCertSecret":{"key":"","name":""},"sslKeySecret":{"key":"","name":""},"sslMode":"verify-full","sslRootCertSecret":{"key":"","name":""},"username":""}}}` | Recovery settings when booting cluster from external cluster |
| recovery.backup.backupName | string | `""` | Name of the backup to recover from. |
| recovery.backup.database | string | `"app"` | Name of the database used by the application. Default: `app`. |
| recovery.backup.owner | string | `""` | Name of the owner of the database in the instance to be used by applications. Defaults to the value of the `database` key. |
| recovery.backup.pitrTarget | object | `{"time":""}` | Point in time recovery target. Specify one of the following: |
| recovery.backup.pitrTarget.time | string | `""` | Time in RFC3339 format |
| recovery.import.databases | list | `[]` | Databases to import |
| recovery.import.pgDumpExtraOptions | list | `[]` | List of custom options to pass to the `pg_dump` command. IMPORTANT: Use these options with caution and at your own risk, as the operator does not validate their content. Be aware that certain options may conflict with the operator's intended functionality or design. |
| recovery.import.pgRestoreExtraOptions | list | `[]` | List of custom options to pass to the `pg_restore` command. IMPORTANT: Use these options with caution and at your own risk, as the operator does not validate their content. Be aware that certain options may conflict with the operator's intended functionality or design. |
| recovery.import.postImportApplicationSQL | list | `[]` | List of SQL queries to be executed as a superuser in the application database right after is imported. To be used with extreme care. Only available in microservice type. |
| recovery.import.roles | list | `[]` | Roles to import |
| recovery.import.schemaOnly | bool | `false` | When set to true, only the pre-data and post-data sections of pg_restore are invoked, avoiding data import. |
| recovery.import.source | object | `{"database":"app","host":"","passwordSecret":{"create":false,"key":"password","name":"","value":""},"port":5432,"sslCertSecret":{"key":"","name":""},"sslKeySecret":{"key":"","name":""},"sslMode":"verify-full","sslRootCertSecret":{"key":"","name":""},"username":"app"}` | Configuration for the source database |
| recovery.import.source.passwordSecret.create | bool | `false` | Whether to create a secret for the password |
| recovery.import.source.passwordSecret.key | string | `"password"` | The key in the secret containing the password |
| recovery.import.source.passwordSecret.name | string | `""` | Name of the secret containing the password |
| recovery.import.source.passwordSecret.value | string | `""` | The password value to use when creating the secret |
| recovery.import.type | string | `"microservice"` | One of `microservice` or `monolith.` See: https://cloudnative-pg.io/documentation/current/database_import/#how-it-works |
| recovery.method | string | `"backup"` | Available recovery methods: * `backup` - Recovers a CNPG cluster from a CNPG backup (PITR supported) Needs to be on the same cluster in the same namespace. * `objectStore` - Recovers a CNPG cluster from a barman object store (PITR supported). * `pgBaseBackup` - Recovers a CNPG cluster viaa streaming replication protocol. Useful if you want to migrate databases to CloudNativePG, even from outside Kubernetes. * `import` - Import one or more databases from an existing Postgres cluster. |
| recovery.objectStore.data.compression | string | `"snappy"` | Data compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. |
| recovery.objectStore.data.encryption | string | `""` | Whether to instruct the storage provider to encrypt data files. One of `` (use the storage container default), `AES256` or `aws:kms`. |
| recovery.objectStore.data.jobs | int | `1` | Number of data files to be archived or restored in parallel. |
| recovery.objectStore.database | string | `"app"` | Name of the database used by the application. Default: `app`. |
| recovery.objectStore.destinationPath | string | `""` | Overrides the provider specific default path. Defaults to: S3: s3://<bucket><path> Azure: https://<storageAccount>.<serviceName>.core.windows.net/<containerName><path> Google: gs://<bucket><path> |
| recovery.objectStore.endpointCA | object | `{"create":false,"key":"","name":""}` | Specifies a CA bundle to validate a privately signed certificate. |
| recovery.objectStore.endpointCA.create | bool | `false` | Creates a secret with the given value if true, otherwise uses an existing secret. |
| recovery.objectStore.endpointCredentials | string | `""` | Specifies secret that contains S3 credentials, should contain the keys ACCESS_KEY_ID and ACCESS_SECRET_KEY |
| recovery.objectStore.endpointURL | string | `""` | Overrides the provider specific default endpoint. Defaults to: S3: https://s3.<region>.amazonaws.com" Leave empty if using the default S3 endpoint |
| recovery.objectStore.owner | string | `""` | Name of the owner of the database in the instance to be used by applications. Defaults to the value of the `database` key. |
| recovery.objectStore.pitrTarget | object | `{"time":""}` | Point in time recovery target. Specify one of the following: |
| recovery.objectStore.pitrTarget.time | string | `""` | Time in RFC3339 format |
| recovery.objectStore.recoveryIndex | int | `1` | Generate external cluster name, uses: {{ .Release.Name }}postgresql-<major version>-cluster-backup-index-{{ .Values.recovery.recoveryIndex }} |
| recovery.objectStore.recoveryServerName | string | `""` | Override name of the recovery cluster in the object store, defaults to "cluster.name" |
| recovery.objectStore.wal | object | `{"compression":"snappy","encryption":"","maxParallel":1}` | Storage |
| recovery.objectStore.wal.compression | string | `"snappy"` | WAL compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. |
| recovery.objectStore.wal.encryption | string | `""` | Whether to instruct the storage provider to encrypt WAL files. One of `` (use the storage container default), `AES256` or `aws:kms`. |
| recovery.objectStore.wal.maxParallel | int | `1` | Number of WAL files to be archived or restored in parallel. |
| recovery.pgBaseBackup.database | string | `"app"` | Name of the database used by the application. Default: `app`. |
| recovery.pgBaseBackup.owner | string | `""` | Name of the owner of the database in the instance to be used by applications. Defaults to the value of the `database` key. |
| recovery.pgBaseBackup.secret | string | `""` | Name of the secret containing the initial credentials for the owner of the user database. If empty a new secret will be created from scratch |
| recovery.pgBaseBackup.source | object | `{"database":"app","host":"","passwordSecret":{"create":false,"key":"password","name":"","value":""},"port":5432,"sslCertSecret":{"key":"","name":""},"sslKeySecret":{"key":"","name":""},"sslMode":"verify-full","sslRootCertSecret":{"key":"","name":""},"username":""}` | Configuration for the source database |
| recovery.pgBaseBackup.source.passwordSecret.create | bool | `false` | Whether to create a secret for the password |
| recovery.pgBaseBackup.source.passwordSecret.key | string | `"password"` | The key in the secret containing the password |
| recovery.pgBaseBackup.source.passwordSecret.name | string | `""` | Name of the secret containing the password |
| recovery.pgBaseBackup.source.passwordSecret.value | string | `""` | The password value to use when creating the secret |
| type | string | `"postgresql"` | Type of the CNPG database. Available types: * `postgresql` * `postgis` * `timescaledb` * `tensorchord` |
| version.postgis | string | `"3.5"` | If using PostGIS, specify the version |
| version.postgresql | string | `"17"` | PostgreSQL major version to use |
| version.timescaledb | string | `"2.15"` | If using TimescaleDB, specify the version |
----------------------------------------------
Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2)

View File

@@ -0,0 +1,16 @@
{{- $alert := "CNPGClusterBackendsWaitingWarning" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Cluster a backend is waiting for longer than 5 minutes.
description: |-
Pod {{`{{`}} $labels.pod {{`}}`}}
has been waiting for longer than 5 minutes
expr: |
cnpg_backends_waiting_total > 300
for: 1m
labels:
severity: warning
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -0,0 +1,16 @@
{{- $alert := "CNPGClusterDatabaseDeadlockConflictsWarning" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Cluster has over 10 deadlock conflicts.
description: |-
There are over 10 deadlock conflicts in
{{`{{`}} $labels.pod {{`}}`}}
expr: |
cnpg_pg_stat_database_deadlocks > 10
for: 1m
labels:
severity: warning
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -0,0 +1,26 @@
{{- $alert := "CNPGClusterHACritical" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Cluster has no standby replicas!
description: |-
CloudNativePG Cluster "{{ .labels.job }}" has no ready standby replicas. Your cluster at a severe
risk of data loss and downtime if the primary instance fails.
The primary instance is still online and able to serve queries, although connections to the `-ro` endpoint
will fail. The `-r` endpoint os operating at reduced capacity and all traffic is being served by the main.
This can happen during a normal fail-over or automated minor version upgrades in a cluster with 2 or less
instances. The replaced instance may need some time to catch-up with the cluster primary instance.
This alarm will be always trigger if your cluster is configured to run with only 1 instance. In this
case you may want to silence it.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterHACritical.md
expr: |
max by (job) (cnpg_pg_replication_streaming_replicas{namespace="{{ .namespace }}"} - cnpg_pg_replication_is_wal_receiver_up{namespace="{{ .namespace }}"}) < 1
for: 5m
labels:
severity: critical
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -0,0 +1,24 @@
{{- $alert := "CNPGClusterHAWarning" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Cluster less than 2 standby replicas.
description: |-
CloudNativePG Cluster "{{ .labels.job }}" has only {{ .value }} standby replicas, putting
your cluster at risk if another instance fails. The cluster is still able to operate normally, although
the `-ro` and `-r` endpoints operate at reduced capacity.
This can happen during a normal fail-over or automated minor version upgrades. The replaced instance may
need some time to catch-up with the cluster primary instance.
This alarm will be constantly triggered if your cluster is configured to run with less than 3 instances.
In this case you may want to silence it.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterHAWarning.md
expr: |
max by (job) (cnpg_pg_replication_streaming_replicas{namespace="{{ .namespace }}"} - cnpg_pg_replication_is_wal_receiver_up{namespace="{{ .namespace }}"}) < 2
for: 5m
labels:
severity: warning
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -0,0 +1,17 @@
{{- $alert := "CNPGClusterHighConnectionsCritical" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Instance maximum number of connections critical!
description: |-
CloudNativePG Cluster "{{ .namespace }}/{{ .cluster }}" instance {{ .labels.pod }} is using {{ .value }}% of
the maximum number of connections.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterHighConnectionsCritical.md
expr: |
sum by (pod) (cnpg_backends_total{namespace="{{ .namespace }}", pod=~"{{ .podSelector }}"}) / max by (pod) (cnpg_pg_settings_setting{name="max_connections", namespace="{{ .namespace }}", pod=~"{{ .podSelector }}"}) * 100 > 95
for: 5m
labels:
severity: critical
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -0,0 +1,17 @@
{{- $alert := "CNPGClusterHighConnectionsWarning" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Instance is approaching the maximum number of connections.
description: |-
CloudNativePG Cluster "{{ .namespace }}/{{ .cluster }}" instance {{ .labels.pod }} is using {{ .value }}% of
the maximum number of connections.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterHighConnectionsWarning.md
expr: |
sum by (pod) (cnpg_backends_total{namespace="{{ .namespace }}", pod=~"{{ .podSelector }}"}) / max by (pod) (cnpg_pg_settings_setting{name="max_connections", namespace="{{ .namespace }}", pod=~"{{ .podSelector }}"}) * 100 > 80
for: 5m
labels:
severity: warning
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -0,0 +1,19 @@
{{- $alert := "CNPGClusterHighReplicationLag" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Cluster high replication lag
description: |-
CloudNativePG Cluster "{{ .namespace }}/{{ .cluster }}" is experiencing a high replication lag of
{{ .value }}ms.
High replication lag indicates network issues, busy instances, slow queries or suboptimal configuration.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterHighReplicationLag.md
expr: |
max(cnpg_pg_replication_lag{namespace="{{ .namespace }}",pod=~"{{ .podSelector }}"}) * 1000 > 1000
for: 5m
labels:
severity: warning
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -0,0 +1,19 @@
{{- $alert := "CNPGClusterInstancesOnSameNode" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Cluster instances are located on the same node.
description: |-
CloudNativePG Cluster "{{ .namespace }}/{{ .cluster }}" has {{ .value }}
instances on the same node {{ .labels.node }}.
A failure or scheduled downtime of a single node will lead to a potential service disruption and/or data loss.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterInstancesOnSameNode.md
expr: |
count by (node) (kube_pod_info{namespace="{{ .namespace }}", pod=~"{{ .podSelector }}"}) > 1
for: 5m
labels:
severity: warning
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -0,0 +1,15 @@
{{- $alert := "CNPGClusterLastFailedArchiveTimeWarning" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Cluster last time archiving failed.
description: |-
Archiving failed for {{`{{`}} $labels.pod {{`}}`}}
expr: |
(cnpg_pg_stat_archiver_last_failed_time - cnpg_pg_stat_archiver_last_archived_time) > 1
for: 1m
labels:
severity: warning
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -0,0 +1,16 @@
{{- $alert := "CNPGClusterLongRunningTransactionWarning" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Cluster query is taking longer than 5 minutes.
description: |-
CloudNativePG Cluster Pod {{`{{`}} $labels.pod {{`}}`}}
is taking more than 5 minutes (300 seconds) for a query.
expr: |-
cnpg_backends_max_tx_duration_seconds > 300
for: 1m
labels:
severity: warning
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -0,0 +1,24 @@
{{- $alert := "CNPGClusterLowDiskSpaceCritical" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Instance is running out of disk space!
description: |-
CloudNativePG Cluster "{{ .namespace }}/{{ .cluster }}" is running extremely low on disk space. Check attached PVCs!
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterLowDiskSpaceCritical.md
expr: |
max(max by(persistentvolumeclaim) (1 - kubelet_volume_stats_available_bytes{namespace="{{ .namespace }}", persistentvolumeclaim=~"{{ .podSelector }}"} / kubelet_volume_stats_capacity_bytes{namespace="{{ .namespace }}", persistentvolumeclaim=~"{{ .podSelector }}"})) > 0.9 OR
max(max by(persistentvolumeclaim) (1 - kubelet_volume_stats_available_bytes{namespace="{{ .namespace }}", persistentvolumeclaim=~"{{ .podSelector }}-wal"} / kubelet_volume_stats_capacity_bytes{namespace="{{ .namespace }}", persistentvolumeclaim=~"{{ .podSelector }}-wal"})) > 0.9 OR
max(sum by (namespace,persistentvolumeclaim) (kubelet_volume_stats_used_bytes{namespace="{{ .namespace }}", persistentvolumeclaim=~"{{ .podSelector }}-tbs.*"})
/
sum by (namespace,persistentvolumeclaim) (kubelet_volume_stats_capacity_bytes{namespace="{{ .namespace }}", persistentvolumeclaim=~"{{ .podSelector }}-tbs.*"})
*
on(namespace, persistentvolumeclaim) group_left(volume)
kube_pod_spec_volumes_persistentvolumeclaims_info{pod=~"{{ .podSelector }}"}
) > 0.9
for: 5m
labels:
severity: critical
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -0,0 +1,24 @@
{{- $alert := "CNPGClusterLowDiskSpaceWarning" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Instance is running out of disk space.
description: |-
CloudNativePG Cluster "{{ .namespace }}/{{ .cluster }}" is running low on disk space. Check attached PVCs.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterLowDiskSpaceWarning.md
expr: |
max(max by(persistentvolumeclaim) (1 - kubelet_volume_stats_available_bytes{namespace="{{ .namespace }}", persistentvolumeclaim=~"{{ .podSelector }}"} / kubelet_volume_stats_capacity_bytes{namespace="{{ .namespace }}", persistentvolumeclaim=~"{{ .podSelector }}"})) > 0.7 OR
max(max by(persistentvolumeclaim) (1 - kubelet_volume_stats_available_bytes{namespace="{{ .namespace }}", persistentvolumeclaim=~"{{ .podSelector }}-wal"} / kubelet_volume_stats_capacity_bytes{namespace="{{ .namespace }}", persistentvolumeclaim=~"{{ .podSelector }}-wal"})) > 0.7 OR
max(sum by (namespace,persistentvolumeclaim) (kubelet_volume_stats_used_bytes{namespace="{{ .namespace }}", persistentvolumeclaim=~"{{ .podSelector }}-tbs.*"})
/
sum by (namespace,persistentvolumeclaim) (kubelet_volume_stats_capacity_bytes{namespace="{{ .namespace }}", persistentvolumeclaim=~"{{ .podSelector }}-tbs.*"})
*
on(namespace, persistentvolumeclaim) group_left(volume)
kube_pod_spec_volumes_persistentvolumeclaims_info{pod=~"{{ .podSelector }}"}
) > 0.7
for: 5m
labels:
severity: warning
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -0,0 +1,19 @@
{{- $alert := "CNPGClusterOffline" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Cluster has no running instances!
description: |-
CloudNativePG Cluster "{{ .namespace }}/{{ .cluster }}" has no ready instances.
Having an offline cluster means your applications will not be able to access the database, leading to
potential service disruption and/or data loss.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterOffline.md
expr: |
(count(cnpg_collector_up{namespace="{{ .namespace }}",pod=~"{{ .podSelector }}"}) OR on() vector(0)) == 0
for: 5m
labels:
severity: critical
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -0,0 +1,16 @@
{{- $alert := "CNPGClusterPGDatabaseXidAgeWarning" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Cluster has a number of transactions from the frozen XID to the current one.
description: |-
Over 300,000,000 transactions from frozen xid
on pod {{`{{`}} $labels.pod {{`}}`}}
expr: |
cnpg_pg_database_xid_age > 300000000
for: 1m
labels:
severity: warning
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -0,0 +1,15 @@
{{- $alert := "CNPGClusterPGReplicationWarning" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Cluster standby is lagging behind the primary.
description: |-
Standby is lagging behind by over 300 seconds (5 minutes)
expr: |
cnpg_pg_replication_lag > 300
for: 1m
labels:
severity: warning
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -0,0 +1,16 @@
{{- $alert := "CNPGClusterReplicaFailingReplicationWarning" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Cluster has a replica is failing to replicate.
description: |-
Replica {{`{{`}} $labels.pod {{`}}`}}
is failing to replicate
expr: |
cnpg_pg_replication_in_recovery > cnpg_pg_replication_is_wal_receiver_up
for: 1m
labels:
severity: warning
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -0,0 +1,18 @@
{{- $alert := "CNPGClusterZoneSpreadWarning" -}}
{{- if not (has $alert .excludeRules) -}}
alert: {{ $alert }}
annotations:
summary: CNPG Cluster instances in the same zone.
description: |-
CloudNativePG Cluster "{{ .namespace }}/{{ .cluster }}" has instances in the same availability zone.
A disaster in one availability zone will lead to a potential service disruption and/or data loss.
runbook_url: https://github.com/cloudnative-pg/charts/blob/main/charts/cluster/docs/runbooks/CNPGClusterZoneSpreadWarning.md
expr: |
{{ .Values.cluster.instances }} > count(count by (label_topology_kubernetes_io_zone) (kube_pod_info{namespace="{{ .namespace }}", pod=~"{{ .podSelector }}"} * on(node,instance) group_left(label_topology_kubernetes_io_zone) kube_node_labels)) < 3
for: 5m
labels:
severity: warning
namespace: {{ .namespace }}
cnpg_cluster: {{ .cluster }}
{{- end -}}

View File

@@ -7,18 +7,22 @@ backup:
endpointURL: {{ .Values.backup.endpointURL }}
{{- if .Values.backup.endpointCA }}
endpointCA:
name: {{ .Values.backup.endpointCA }}
key: ca-bundle.crt
name: {{ .Values.backup.endpointCA.name }}
key: {{ .Values.backup.endpointCA.key }}
{{- end }}
serverName: "{{ include "cluster.name" . }}-backup-{{ .Values.backup.backupIndex }}"
tags:
{{- with .Values.backup.tags }}
{{- . | toYaml | nindent 6 }}
serverName: "{{ include "cluster.backupName" . }}-backup-{{ .Values.backup.backupIndex }}"
wal:
compression: {{ .Values.backup.wal.compression }}
{{- with .Values.backup.wal.encryption}}
encryption: {{ . }}
{{- end }}
historyTags:
{{- with .Values.backup.historyTags }}
{{- . | toYaml | nindent 6 }}
maxParallel: {{ .Values.backup.wal.maxParallel }}
data:
compression: {{ .Values.backup.data.compression }}
{{- with .Values.backup.data.encryption }}
encryption: {{ . }}
{{- end }}
jobs: {{ .Values.backup.data.jobs }}
s3Credentials:
accessKeyId:
name: {{ include "cluster.backupCredentials" . }}
@@ -26,25 +30,5 @@ backup:
secretAccessKey:
name: {{ include "cluster.backupCredentials" . }}
key: ACCESS_SECRET_KEY
wal:
{{- if .Values.backup.wal.compression }}
compression: {{ .Values.backup.wal.compression }}
{{- end }}
{{- if .Values.backup.wal.encryption }}
encryption: {{ .Values.backup.wal.encryption }}
{{- end }}
{{- if .Values.backup.wal.maxParallel }}
maxParallel: {{ .Values.backup.wal.maxParallel }}
{{- end }}
data:
{{- if .Values.backup.data.compression }}
compression: {{ .Values.backup.data.compression }}
{{- end }}
{{- if .Values.backup.data.encryption }}
encryption: {{ .Values.backup.data.encryption }}
{{- end }}
{{- if .Values.backup.data.jobs }}
jobs: {{ .Values.backup.data.jobs }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -1,16 +1,20 @@
{{- define "cluster.bootstrap" -}}
bootstrap:
{{- if eq .Values.mode "standalone" }}
bootstrap:
initdb:
{{- with .Values.bootstrap.initdb }}
{{- with (omit . "postInitApplicationSQL") }}
{{- with .Values.cluster.initdb }}
{{- with (omit . "postInitApplicationSQL" "owner" "import") }}
{{- . | toYaml | nindent 4 }}
{{- end }}
{{- end }}
{{- if .Values.cluster.initdb.owner }}
owner: {{ tpl .Values.cluster.initdb.owner . }}
{{- end }}
{{- if eq .Values.type "tensorchord" }}
dataChecksums: true
{{- end }}
{{- if or (eq .Values.type "postgis") (eq .Values.type "timescaledb") (eq .Values.type "tensorchord") (.Values.bootstrap.initdb.postInitApplicationSQL) }}
{{- if or (eq .Values.type "postgis") (eq .Values.type "timescaledb") (eq .Values.type "tensorchord") (.Values.cluster.initdb.postInitApplicationSQL) }}
postInitApplicationSQL:
{{- if eq .Values.type "postgis" }}
- CREATE EXTENSION IF NOT EXISTS postgis;
@@ -29,65 +33,117 @@ bootstrap:
- GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA vectors TO "app";
- GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "app";
{{- end }}
{{- with .Values.bootstrap.initdb }}
{{- with .Values.cluster.initdb }}
{{- range .postInitApplicationSQL }}
{{- printf "- %s" . | nindent 6 }}
{{- end -}}
{{- end }}
{{- end }}
{{- else if eq .Values.mode "recovery" -}}
bootstrap:
{{- if eq .Values.recovery.method "pgBaseBackup" }}
pg_basebackup:
source: pgBaseBackupSource
{{ with .Values.recovery.pgBaseBackup.database }}
database: {{ . }}
{{- end }}
{{- else if eq .Values.mode "replica" }}
{{ with .Values.recovery.pgBaseBackup.owner }}
owner: {{ . }}
{{- end }}
{{ with .Values.recovery.pgBaseBackup.secret }}
secret:
{{- toYaml . | nindent 6 }}
{{- end }}
externalClusters:
{{- include "cluster.externalSourceCluster" (list "pgBaseBackupSource" .Values.recovery.pgBaseBackup.source) | nindent 2 }}
{{- else if eq .Values.recovery.method "import" }}
initdb:
{{- with .Values.cluster.initdb }}
{{- with (omit . "owner" "import" "postInitApplicationSQL") }}
{{- . | toYaml | nindent 4 }}
{{- end }}
{{- end }}
{{- if .Values.cluster.initdb.owner }}
owner: {{ tpl .Values.cluster.initdb.owner . }}
{{- end }}
import:
type: {{ .Values.replica.importType }}
source:
externalCluster: importSource
type: {{ .Values.recovery.import.type }}
databases:
{{- if and (gt (len .Values.replica.importDatabases) 1) (eq .Values.replica.importType "microservice") }}
{{- if and (gt (len .Values.recovery.import.databases) 1) (eq .Values.recovery.import.type "microservice") }}
{{ fail "Too many databases in import type of microservice!" }}
{{- else}}
{{- with .Values.replica.importDatabases }}
{{- with .Values.recovery.import.databases }}
{{- . | toYaml | nindent 8 }}
{{- end }}
{{- end }}
{{- if eq .Values.replica.importType "monolith" }}
{{- if eq .Values.recovery.import.type "monolith" }}
roles:
{{- with .Values.replica.importRoles }}
{{- . | toYaml | nindent 8 }}
{{- end }}
{{- end }}
{{- if and (.Values.replica.postImportApplicationSQL) (eq .Values.replica.importType "microservice") }}
{{- if and (.Values.recovery.import.postImportApplicationSQL) (eq .Values.recovery.import.type "microservice") }}
postImportApplicationSQL:
{{- with .Values.replica.postImportApplicationSQL }}
{{- with .Values.recovery.import.postImportApplicationSQL }}
{{- . | toYaml | nindent 8 }}
{{- end }}
{{- end }}
source:
externalCluster: "{{ include "cluster.name" . }}-cluster"
{{- with .Values.bootstrap.initdb }}
{{- with (omit . "postInitApplicationSQL") }}
{{- . | toYaml | nindent 4 }}
schemaOnly: {{ .Values.recovery.import.schemaOnly }}
{{ with .Values.recovery.import.pgDumpExtraOptions }}
pgDumpExtraOptions:
{{- . | toYaml | nindent 8 }}
{{- end }}
{{ with .Values.recovery.import.pgRestoreExtraOptions }}
pgRestoreExtraOptions:
{{- . | toYaml | nindent 8 }}
{{- end }}
externalClusters:
- name: "{{ include "cluster.name" . }}-cluster"
{{- with .Values.replica.externalCluster }}
{{- . | toYaml | nindent 4 }}
{{- end }}
{{- else if eq .Values.mode "recovery" }}
{{- include "cluster.externalSourceCluster" (list "importSource" .Values.recovery.import.source) | nindent 2 }}
{{- else if eq .Values.mode "backup" }}
recovery:
{{- with .Values.recovery.pitrTarget.time }}
{{- with .Values.recovery.backup.pitrTarget.time }}
recoveryTarget:
targetTime: {{ . }}
{{- end }}
{{ with .Values.recovery.backup.database }}
database: {{ . }}
{{- end }}
{{ with .Values.recovery.backup.owner }}
owner: {{ . }}
{{- end }}
backup:
name: {{ .Values.recovery.backup.backupName }}
{{- else if eq .Values.mode "objectStore" }}
recovery:
{{- with .Values.recovery.objectStore.pitrTarget.time }}
recoveryTarget:
targetTime: {{ . }}
{{- end }}
{{ with .Values.recovery.objectStore.database }}
database: {{ . }}
{{- end }}
{{ with .Values.recovery.objectStore.owner }}
owner: {{ . }}
{{- end }}
source: {{ include "cluster.recoveryServerName" . }}
externalClusters:
- name: {{ include "cluster.recoveryServerName" . }}
barmanObjectStore:
serverName: {{ include "cluster.recoveryServerName" . }}
destinationPath: {{ .Values.recovery.destinationPath }}
endpointURL: {{ .Values.recovery.endpointURL }}
{{- with .Values.recovery.endpointCA }}
endpointURL: {{ .Values.recovery.objectStore.endpointURL }}
destinationPath: {{ .Values.recovery.objectStore.destinationPath }}
{{- if .Values.recovery.objectStore.endpointCA }}
endpointCA:
name: {{ . }}
key: ca-bundle.crt
name: {{ .Values.recovery.objectStore.endpointCA.name }}
key: {{ .Values.recovery.objectStore.endpointCA.key }}
{{- end }}
s3Credentials:
accessKeyId:
@@ -97,26 +153,24 @@ externalClusters:
name: {{ include "cluster.recoveryCredentials" . }}
key: ACCESS_SECRET_KEY
wal:
{{- if .Values.recovery.wal.compression }}
compression: {{ .Values.recovery.wal.compression }}
{{- end }}
{{- if .Values.recovery.wal.encryption }}
encryption: {{ .Values.recovery.wal.encryption }}
{{- end }}
{{- if .Values.recovery.wal.maxParallel }}
maxParallel: {{ .Values.recovery.wal.maxParallel }}
compression: {{ .Values.recovery.objectStore.wal.compression }}
{{- with .Values.recovery.objectStore.wal.encryption}}
encryption: {{ . }}
{{- end }}
maxParallel: {{ .Values.recovery.objectStore.wal.maxParallel }}
data:
{{- if .Values.recovery.data.compression }}
compression: {{ .Values.recovery.data.compression }}
{{- end }}
{{- if .Values.recovery.data.encryption }}
encryption: {{ .Values.recovery.data.encryption }}
{{- end }}
{{- if .Values.recovery.data.jobs }}
jobs: {{ .Values.recovery.data.jobs }}
compression: {{ .Values.recovery.objectStore.data.compression }}
{{- with .Values.recovery.objectStore.data.encryption }}
encryption: {{ . }}
{{- end }}
jobs: {{ .Values.recovery.objectStore.data.jobs }}
{{- else }}
{{ fail "Invalid recovery mode!" }}
{{- end }}
{{- else }}
{{ fail "Invalid cluster mode!" }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,12 @@
{{- define "cluster.color-error" }}
{{- printf "\033[0;31m%s\033[0m" . -}}
{{- end }}
{{- define "cluster.color-ok" }}
{{- printf "\033[0;32m%s\033[0m" . -}}
{{- end }}
{{- define "cluster.color-warning" }}
{{- printf "\033[0;33m%s\033[0m" . -}}
{{- end }}
{{- define "cluster.color-info" }}
{{- printf "\033[0;34m%s\033[0m" . -}}
{{- end }}

View File

@@ -0,0 +1,33 @@
{{- define "cluster.externalSourceCluster" -}}
{{- $name := first . -}}
{{- $config := last . -}}
- name: {{ first . }}
connectionParameters:
host: {{ $config.host | quote }}
port: {{ $config.port | quote }}
user: {{ $config.username | quote }}
{{- with $config.database }}
dbname: {{ . | quote }}
{{- end }}
sslmode: {{ $config.sslMode | quote }}
{{- if $config.passwordSecret.name }}
password:
name: {{ $config.passwordSecret.name }}
key: {{ $config.passwordSecret.key }}
{{- end }}
{{- if $config.sslKeySecret.name }}
sslKey:
name: {{ $config.sslKeySecret.name }}
key: {{ $config.sslKeySecret.key }}
{{- end }}
{{- if $config.sslCertSecret.name }}
sslCert:
name: {{ $config.sslCertSecret.name }}
key: {{ $config.sslCertSecret.key }}
{{- end }}
{{- if $config.sslRootCertSecret.name }}
sslRootCert:
name: {{ $config.sslRootCertSecret.name }}
key: {{ $config.sslRootCertSecret.key }}
{{- end }}
{{- end }}

View File

@@ -37,6 +37,67 @@ app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: cloudnative-pg
{{- end }}
{{/*
Allow the release namespace to be overridden for multi-namespace deployments in combined charts
*/}}
{{- define "cluster.namespace" -}}
{{- if .Values.namespaceOverride -}}
{{- .Values.namespaceOverride -}}
{{- else -}}
{{- .Release.Namespace -}}
{{- end -}}
{{- end -}}
{{/*
Whether we need to use TimescaleDB defaults
*/}}
{{- define "cluster.useTimescaleDBDefaults" -}}
{{ and (eq .Values.type "timescaledb") .Values.imageCatalog.create (empty .Values.cluster.imageCatalogRef.name) (empty .Values.imageCatalog.images) (empty .Values.cluster.imageName) }}
{{- end -}}
{{/*
Cluster Image Name
If a custom imageName is available, use it, otherwise use the defaults based on the .Values.type
*/}}
{{- define "cluster.imageName" -}}
{{- if .Values.cluster.image.repository -}}
{{- printf "%s:%s" .Values.cluster.image.repository .Values.cluster.image.tag -}}
{{- else if eq .Values.type "postgresql" -}}
{{- printf "ghcr.io/cloudnative-pg/postgresql:%s" .Values.version.postgresql -}}
{{- else if eq .Values.type "postgis" -}}
{{- printf "ghcr.io/cloudnative-pg/postgis:%s-%s" .Values.version.postgresql .Values.version.postgis -}}
{{- else -}}
{{ fail "Invalid cluster type!" }}
{{- end }}
{{- end -}}
{{/*
Cluster Image
If imageCatalogRef defined, use it, otherwise calculate ordinary imageName.
*/}}
{{- define "cluster.image" }}
{{- if .Values.cluster.imageCatalogRef.name }}
imageCatalogRef:
apiGroup: postgresql.cnpg.io
{{- toYaml .Values.cluster.imageCatalogRef | nindent 2 }}
major: {{ include "cluster.postgresqlMajor" . }}
{{- else if and .Values.imageCatalog.create (not (empty .Values.imageCatalog.images )) }}
imageCatalogRef:
apiGroup: postgresql.cnpg.io
kind: ImageCatalog
name: {{ include "cluster.name" . }}
major: {{ include "cluster.postgresqlMajor" . }}
{{- else if eq (include "cluster.useTimescaleDBDefaults" .) "true" -}}
imageCatalogRef:
apiGroup: postgresql.cnpg.io
kind: ImageCatalog
name: {{ include "cluster.name" . }}-timescaledb-ha
major: {{ include "cluster.postgresqlMajor" . }}
{{- else }}
imageName: {{ include "cluster.imageName" . }}
{{- end }}
{{- end }}
{{/*
Generate name for object store credentials
*/}}
@@ -56,6 +117,32 @@ Generate name for object store credentials
{{- end }}
{{- end }}
{{/*
Postgres UID
*/}}
{{- define "cluster.postgresUID" -}}
{{- if ge (int .Values.cluster.postgresUID) 0 -}}
{{- .Values.cluster.postgresUID }}
{{- else if and (eq (include "cluster.useTimescaleDBDefaults" .) "true") (eq .Values.type "timescaledb") -}}
{{- 1000 -}}
{{- else -}}
{{- 26 -}}
{{- end -}}
{{- end -}}
{{/*
Postgres GID
*/}}
{{- define "cluster.postgresGID" -}}
{{- if ge (int .Values.cluster.postgresGID) 0 -}}
{{- .Values.cluster.postgresGID }}
{{- else if and (eq (include "cluster.useTimescaleDBDefaults" .) "true") (eq .Values.type "timescaledb") -}}
{{- 1000 -}}
{{- else -}}
{{- 26 -}}
{{- end -}}
{{- end -}}
{{/*
Generate backup server name
*/}}
@@ -67,7 +154,6 @@ Generate backup server name
{{- end }}
{{- end }}
{{/*
Generate recovery server name
*/}}
@@ -78,14 +164,3 @@ Generate recovery server name
{{- printf "%s-backup-%s" (include "cluster.name" .) (toString .Values.recovery.recoveryIndex) | trunc 63 | trimSuffix "-" -}}
{{- end }}
{{- end }}
{{/*
Generate recovery instance name
*/}}
{{- define "cluster.recoveryInstanceName" -}}
{{- if .Values.recovery.recoveryInstanceName -}}
{{- .Values.recovery.recoveryInstanceName -}}
{{- else -}}
{{ include "cluster.name" . }}
{{- end }}
{{- end }}

View File

@@ -2,7 +2,7 @@ apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: {{ include "cluster.name" . }}-cluster
namespace: {{ .Release.Namespace }}
namespace: {{ include "cluster.namespace" . }}
{{- with .Values.cluster.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
@@ -14,17 +14,27 @@ metadata:
{{- end }}
spec:
instances: {{ .Values.cluster.instances }}
{{- include "cluster.image" . | nindent 2 }}
imageName: "{{ .Values.cluster.image.repository }}:{{ .Values.cluster.image.tag }}"
imagePullPolicy: {{ .Values.cluster.image.pullPolicy }}
postgresUID: {{ .Values.cluster.postgresUID }}
postgresGID: {{ .Values.cluster.postgresGID }}
enableSuperuserAccess: {{ .Values.cluster.enableSuperuserAccess }}
walStorage:
size: {{ .Values.cluster.walStorage.size }}
storageClass: {{ .Values.cluster.walStorage.storageClass }}
imagePullPolicy: {{ .Values.cluster.image.imagePullPolicy }}
{{- with .Values.cluster.image.imagePullSecrets }}
imagePullSecrets:
{{- . | toYaml | nindent 4 }}
{{- end }}
postgresUID: {{ include "cluster.postgresUID" . }}
postgresGID: {{ include "cluster.postgresGID" . }}
storage:
size: {{ .Values.cluster.storage.size }}
{{- if not (empty .Values.cluster.storage.storageClass) }}
storageClass: {{ .Values.cluster.storage.storageClass }}
{{- end }}
{{- if .Values.cluster.walStorage.enabled }}
walStorage:
size: {{ .Values.cluster.walStorage.size }}
{{- if not (empty .Values.cluster.walStorage.storageClass) }}
storageClass: {{ .Values.cluster.walStorage.storageClass }}
{{- end }}
{{- end }}
{{- with .Values.cluster.resources }}
resources:
{{- toYaml . | nindent 4 }}
@@ -36,30 +46,98 @@ spec:
{{- if .Values.cluster.priorityClassName }}
priorityClassName: {{ .Values.cluster.priorityClassName }}
{{- end }}
primaryUpdateMethod: {{ .Values.cluster.primaryUpdateMethod }}
primaryUpdateStrategy: {{ .Values.cluster.primaryUpdateStrategy }}
logLevel: {{ .Values.cluster.logLevel }}
{{- with .Values.cluster.certificates }}
certificates:
{{- toYaml . | nindent 4 }}
{{ end }}
enableSuperuserAccess: {{ .Values.cluster.enableSuperuserAccess }}
{{- with .Values.cluster.superuserSecret }}
superuserSecret:
name: {{ . }}
{{ end }}
enablePDB: {{ .Values.cluster.enablePDB }}
postgresql:
{{- if eq .Values.type "timescaledb" }}
{{- if or (eq .Values.type "timescaledb") (eq .Values.type "tensorchord") (not (empty .Values.cluster.postgresql.shared_preload_libraries)) }}
shared_preload_libraries:
{{- if eq .Values.type "timescaledb" }}
- timescaledb
{{- end }}
{{- if eq .Values.type "tensorchord" }}
shared_preload_libraries:
- vectors.so
enableAlterSystem: true
{{- end }}
{{- with .Values.cluster.postgresql.shared_preload_libraries }}
shared_preload_libraries:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- end }}
{{- with .Values.cluster.postgresql.pg_hba }}
pg_hba:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- with .Values.cluster.postgresql.pg_ident }}
pg_ident:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- with .Values.cluster.postgresql.ldap }}
ldap:
{{- toYaml . | nindent 6 }}
{{- end}}
{{- with .Values.cluster.postgresql.synchronous }}
synchronous:
{{- toYaml . | nindent 6 }}
{{ end }}
{{- with .Values.cluster.postgresql.parameters }}
parameters:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- if not (and (empty .Values.cluster.roles) (empty .Values.cluster.services)) }}
managed:
{{- with .Values.cluster.services }}
services:
{{- toYaml . | nindent 6 }}
{{ end }}
{{- with .Values.cluster.roles }}
roles:
{{- toYaml . | nindent 6 }}
{{ end }}
{{- end }}
{{- with .Values.cluster.serviceAccountTemplate }}
serviceAccountTemplate:
{{- toYaml . | nindent 4 }}
{{- end }}
monitoring:
enablePodMonitor: {{ and .Values.cluster.monitoring.enabled .Values.cluster.monitoring.podMonitor.enabled }}
disableDefaultQueries: {{ .Values.cluster.monitoring.disableDefaultQueries }}
{{- if not (empty .Values.cluster.monitoring.customQueries) }}
customQueriesConfigMap:
- name: {{ include "cluster.name" . }}-monitoring
key: custom-queries
{{- end }}
{{- if not (empty .Values.cluster.monitoring.customQueriesSecret) }}
{{- with .Values.cluster.monitoring.customQueriesSecret }}
customQueriesSecret:
{{- toYaml . | nindent 6 }}
{{ end }}
{{- end }}
{{- if not (empty .Values.cluster.monitoring.podMonitor.relabelings) }}
{{- with .Values.cluster.monitoring.podMonitor.relabelings }}
podMonitorRelabelings:
{{- toYaml . | nindent 6 }}
{{ end }}
{{- end }}
{{- if not (empty .Values.cluster.monitoring.podMonitor.metricRelabelings) }}
{{- with .Values.cluster.monitoring.podMonitor.metricRelabelings }}
podMonitorMetricRelabelings:
{{- toYaml . | nindent 6 }}
{{ end }}
{{- end }}
{{ include "cluster.bootstrap" . | nindent 2 }}
{{ include "cluster.backup" . | nindent 2 }}

View File

@@ -0,0 +1,21 @@
{{- if not (empty .Values.cluster.monitoring.customQueries) }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "cluster.name" . }}-monitoring
namespace: {{ include "cluster.namespace" . }}
labels:
cnpg.io/reload: ""
{{- include "cluster.labels" . | nindent 4 }}
{{- with .Values.cluster.additionalLabels }}
{{ toYaml . | nindent 4 }}
{{- end }}
data:
custom-queries: |
{{- range .Values.cluster.monitoring.customQueries }}
{{ .name }}:
query: {{ .query | quote }}
metrics:
{{- .metrics | toYaml | nindent 8 }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,18 @@
{{ if and .Values.imageCatalog.create (not (empty .Values.imageCatalog.images )) }}
apiVersion: postgresql.cnpg.io/v1
kind: ImageCatalog
metadata:
name: {{ include "cluster.name" . }}-image-catalog
namespace: {{ include "cluster.namespace" . }}
labels:
{{- include "cluster.labels" . | nindent 4 }}
{{- with .Values.cluster.additionalLabels }}
{{ toYaml . | nindent 4 }}
{{- end }}
spec:
images:
{{- range $image := .Values.imageCatalog.images }}
- image: {{ $image.image }}
major: {{ $image.major }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,54 @@
{{- range .Values.poolers }}
---
apiVersion: postgresql.cnpg.io/v1
kind: Pooler
metadata:
name: {{ include "cluster.name" $ }}-pooler-{{ .name }}
namespace: {{ include "cluster.namespace" $ }}
labels:
{{- include "cluster.labels" . | nindent 4 }}
{{- with .Values.cluster.additionalLabels }}
{{ toYaml . | nindent 4 }}
{{- end }}
spec:
cluster:
name: {{ include "cluster.name" $ }}
instances: {{ .instances }}
type: {{ default "rw" .type }}
pgbouncer:
poolMode: {{ default "session" .poolMode }}
{{- with .authQuerySecret }}
authQuerySecret:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- with .authQuery }}
authQuery:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- with .parameters }}
parameters:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- with .pg_hba }}
pg_hba:
{{- toYaml . | nindent 6 }}
{{- end }}
{{ with .monitoring }}
monitoring:
{{- if not (empty .podMonitor) }}
enablePodMonitor: {{ and .enabled .podMonitor.enabled }}
{{- with .podMonitor.relabelings }}
podMonitorRelabelings:
{{- toYaml . | nindent 6 }}
{{ end }}
{{- with .podMonitor.metricRelabelings }}
podMonitorMetricRelabelings:
{{- toYaml . | nindent 6 }}
{{ end }}
{{- end }}
{{- end }}
{{- with .template }}
template:
{{- . | toYaml | nindent 4 }}
{{- end }}
{{- end }}

View File

@@ -3,7 +3,7 @@ apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: {{ include "cluster.name" . }}-alert-rules
namespace: {{ .Release.Namespace }}
namespace: {{ include "cluster.namespace" . }}
labels:
{{- include "cluster.labels" . | nindent 4 }}
{{- with .Values.cluster.additionalLabels }}
@@ -26,72 +26,5 @@ spec:
{{- with $tpl }}
- {{ $tpl }}
{{- end -}}
{{- end -}}
{{- if .Values.cluster.monitoring.prometheusRule.enableDefaultRules }}
- name: cloudnative-pg/default-rules
rules:
- alert: LongRunningTransaction
annotations:
description: Pod {{`{{`}} $labels.pod {{`}}`}} is taking more than 5 minutes (300 seconds) for a query.
summary: A query is taking longer than 5 minutes.
expr: |-
cnpg_backends_max_tx_duration_seconds > 300
for: 1m
labels:
severity: warning
- alert: BackendsWaiting
annotations:
description: Pod {{`{{`}} $labels.pod {{`}}`}} has been waiting for longer than 5 minutes
summary: If a backend is waiting for longer than 5 minutes
expr: |-
cnpg_backends_waiting_total > 300
for: 1m
labels:
severity: warning
- alert: PGDatabaseXidAge
annotations:
description: Over 300,000,000 transactions from frozen xid on pod {{`{{`}} $labels.pod {{`}}`}}
summary: Number of transactions from the frozen XID to the current one
expr: |-
cnpg_pg_database_xid_age > 300000000
for: 1m
labels:
severity: warning
- alert: PGReplication
annotations:
description: Standby is lagging behind by over 300 seconds (5 minutes)
summary: The standby is lagging behind the primary
expr: |-
cnpg_pg_replication_lag > 300
for: 1m
labels:
severity: warning
- alert: LastFailedArchiveTime
annotations:
description: Archiving failed for {{`{{`}} $labels.pod {{`}}`}}
summary: Checks the last time archiving failed. Will be < 0 when it has not failed.
expr: |-
(cnpg_pg_stat_archiver_last_failed_time - cnpg_pg_stat_archiver_last_archived_time) > 1
for: 1m
labels:
severity: warning
- alert: DatabaseDeadlockConflicts
annotations:
description: There are over 10 deadlock conflicts in {{`{{`}} $labels.pod {{`}}`}}
summary: Checks the number of database conflicts
expr: |-
cnpg_pg_stat_database_deadlocks > 10
for: 1m
labels:
severity: warning
- alert: ReplicaFailingReplication
annotations:
description: Replica {{`{{`}} $labels.pod {{`}}`}} is failing to replicate
summary: Checks if the replica is failing to replicate
expr: |-
cnpg_pg_replication_in_recovery > cnpg_pg_replication_is_wal_receiver_up
for: 1m
labels:
severity: warning
{{- end }}
{{ end }}

View File

@@ -1,9 +1,12 @@
{{ if .Values.backup.enabled }}
{{ $context := . -}}
{{ range .Values.backup.scheduledBackups -}}
---
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
name: {{ include "cluster.name" . }}-scheduled-backup
namespace: {{ .Release.Namespace }}
name: {{ include "cluster.name" $context }}-{{ .name }}-scheduled-backup
namespace: {{ include "cluster.namespace" $ }}
labels:
{{- include "cluster.labels" . | nindent 4 }}
{{- with .Values.cluster.additionalLabels }}
@@ -11,8 +14,9 @@ metadata:
{{- end }}
spec:
immediate: true
schedule: {{ .Values.backup.schedule }}
backupOwnerReference: self
schedule: {{ .schedule | quote }}
backupOwnerReference: {{ .backupOwnerReference }}
cluster:
name: {{ include "cluster.name" . }}-cluster
name: {{ include "cluster.name" $context }}
{{ end -}}
{{ end }}

View File

@@ -1,6 +1,9 @@
# -- Override the name of the cluster
nameOverride: ""
# -- Override the namespace of the chart
namespaceOverride: ""
# -- Type of the CNPG database. Available types:
# * `postgresql`
# * `postgis`
@@ -8,12 +11,33 @@ nameOverride: ""
# * `tensorchord`
type: postgresql
imageCatalog:
# -- Whether to provision an image catalog. If imageCatalog.images is empty this option will be ignored.
create: false
# -- List of images to be provisioned in an image catalog.
images: []
# - image: ghcr.io/your_repo/your_image:your_tag
# major: 16
version:
# -- PostgreSQL major version to use
postgresql: "17"
# -- If using TimescaleDB, specify the version
timescaledb: "2.15"
# -- If using PostGIS, specify the version
postgis: "3.5"
# -- Cluster mode of operation. Available modes:
# * `standalone` - Default mode. Creates new or updates an existing CNPG cluster.
# * `recovery` - Same as standalone but creates a cluster from a backup, object store or via pg_basebackup
# * `replica` - Create database as a replica from another CNPG cluster
mode: standalone
# -- Cluster settings
cluster:
instances: 3
@@ -21,193 +45,514 @@ cluster:
image:
repository: ghcr.io/cloudnative-pg/postgresql
tag: "17.4-3-bullseye"
pullPolicy: IfNotPresent
# -- The UID and GID of the postgres user inside the image
postgresUID: 26
postgresGID: 26
# -- Reference to `ImageCatalog` of `ClusterImageCatalog`, if specified takes precedence over `cluster.imageName`
imageCatalogRef: {}
# kind: ImageCatalog
# name: postgresql
# -- Create secret containing credentials of superuser
enableSuperuserAccess: false
# -- 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
imagePullPolicy: IfNotPresent
# -- 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
imagePullSecrets: []
# -- Default storage size
walStorage:
size: 2Gi
storageClass: ""
storage:
size: 10Gi
storageClass: ""
# -- Default resources
walStorage:
enabled: true
size: 2Gi
storageClass: ""
# -- The UID and GID of the postgres user inside the image, defaults to 26
postgresUID: -1
postgresGID: -1
# -- Customization of service definitions. Please refer to https://cloudnative-pg.io/documentation/current/service_management/
services: {}
# -- Resources requirements of every generated Pod.
# 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:
requests:
memory: 256Mi
cpu: 100m
limits:
cpu: '1'
hugepages-2Mi: 256Mi
# -- See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-AffinityConfiguration
affinity:
enablePodAntiAffinity: true
topologyKey: kubernetes.io/hostname
additionalLabels: {}
annotations: {}
priorityClassName: ""
# -- Method to follow to upgrade the primary server during a rolling update procedure, after all replicas have been
# successfully updated. It can be switchover (default) or in-place (restart).
# successfully updated. It can be switchover (default) or restart.
primaryUpdateMethod: switchover
# -- Strategy to follow to upgrade the primary server during a rolling update procedure, after all replicas have been
# successfully updated: it can be automated (unsupervised - default) or manual (supervised)
primaryUpdateStrategy: unsupervised
# -- The instances' log level, one of the following values: error, warning, info (default), debug, trace
logLevel: "info"
# -- Affinity/Anti-affinity rules for Pods.
# See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-AffinityConfiguration
affinity:
enablePodAntiAffinity: true
topologyKey: kubernetes.io/hostname
# -- The configuration for the CA and related certificates.
# See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-CertificatesConfiguration
certificates: {}
# -- 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.
enableSuperuserAccess: false
superuserSecret: ""
# -- 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
enablePDB: true
# -- 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: []
# - name: dante
# ensure: present
# comment: Dante Alighieri
# login: true
# superuser: false
# inRoles:
# - pg_monitor
# - pg_signal_backend
# -- Enable default monitoring and alert rules
monitoring:
# -- Whether to enable monitoring
enabled: false
podMonitor:
# -- Whether to enable the PodMonitor
enabled: true
# --The list of relabelings for the PodMonitor.
# Applied to samples before scraping.
relabelings: []
# -- The list of metric relabelings for the PodMonitor.
# Applied to samples before ingestion.
metricRelabelings: []
prometheusRule:
# -- Whether to enable the PrometheusRule automated alerts
enabled: false
enableDefaultRules: true
# -- Exclude specified rules
excludeRules: []
# -- Whether the default queries should be injected.
# Set it to true if you don't want to inject default queries into the cluster.
disableDefaultQueries: false
# -- Custom Prometheus metrics
# Will be stored in the ConfigMap
customQueries: []
# - name: "pg_cache_hit_ratio"
# query: "SELECT current_database() as datname, sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) as ratio FROM pg_statio_user_tables;"
# metrics:
# - datname:
# usage: "LABEL"
# description: "Name of the database"
# - ratio:
# usage: GAUGE
# description: "Cache hit ratio"
# -- The list of secrets containing the custom queries
customQueriesSecret: []
# - name: custom-queries-secret
# key: custom-queries
# -- Parameters to be set for the database itself
# See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-PostgresConfiguration
postgresql:
# -- PostgreSQL configuration options (postgresql.conf)
parameters:
shared_buffers: 128MB
max_slot_wal_keep_size: 2000MB
hot_standby_feedback: "on"
shared_preload_libraries: []
# -- Bootstrap 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
bootstrap:
# -- Example values
# database: app
# owner: app
# secret: "" # Name of the secret containing the initial credentials for the owner of the user database. If empty a new secret will be created from scratch
# postInitApplicationSQL:
# - CREATE TABLE IF NOT EXISTS example;
# -- Quorum-based Synchronous Replication
synchronous: {}
# method: any
# number: 1
# -- PostgreSQL Host Based Authentication rules (lines to be appended to the pg_hba.conf file)
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: []
# - mymap /^(.*)@mydomain\.com$ \1
# -- Lists of shared preload libraries to add to the default ones
shared_preload_libraries: []
# - pgaudit
# -- PostgreSQL LDAP configuration (see https://cloudnative-pg.io/documentation/current/postgresql_conf/#ldap-configuration)
ldap: {}
# https://cloudnative-pg.io/documentation/current/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'
# -- Bootstrap 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: {}
# database: app
# owner: "" # Defaults to the database name
# secret:
# name: "" # Name of the secret containing the initial credentials for the owner of the user database. If empty a new secret will be created from scratch
# options: []
# encoding: UTF8
# postInitSQL:
# - CREATE EXTENSION IF NOT EXISTS vector;
# postInitApplicationSQL: []
# postInitTemplateSQL: []
# -- Configure the metadata of the generated service account
serviceAccountTemplate: {}
additionalLabels: {}
annotations: {}
# -- Recovery settings when booting cluster from external cluster
recovery:
# -- Point in time recovery target in RFC3339 format
# -- Available recovery methods:
# * `backup` - Recovers a CNPG cluster from a CNPG backup (PITR supported) Needs to be on the same cluster in the same namespace.
# * `objectStore` - Recovers a CNPG cluster from a barman object store (PITR supported).
# * `pgBaseBackup` - Recovers a CNPG cluster viaa streaming replication protocol. Useful if you want to
# migrate databases to CloudNativePG, even from outside Kubernetes.
# * `import` - Import one or more databases from an existing Postgres cluster.
method: backup
# See https://cloudnative-pg.io/documentation/current/recovery/#recovery-from-a-backup-object
backup:
# -- Point in time recovery target. Specify one of the following:
pitrTarget:
# -- Time in RFC3339 format
time: ""
# -- S3 https endpoint and the s3:// path
# -- Name of the database used by the application. Default: `app`.
database: app
# -- Name of the owner of the database in the instance to be used by applications. Defaults to the value of the `database` key.
owner: ""
# -- Name of the backup to recover from.
backupName: ""
# See https://cloudnative-pg.io/documentation/current/recovery/#recovery-from-an-object-store
objectStore:
# -- Point in time recovery target. Specify one of the following:
pitrTarget:
# -- Time in RFC3339 format
time: ""
# -- Name of the database used by the application. Default: `app`.
database: app
# -- Name of the owner of the database in the instance to be used by applications. Defaults to the value of the `database` key.
owner: ""
# -- Overrides the provider specific default endpoint. Defaults to:
# S3: https://s3.<region>.amazonaws.com"
# Leave empty if using the default S3 endpoint
endpointURL: ""
# -- Overrides the provider specific default path. Defaults to:
# S3: s3://<bucket><path>
# Azure: https://<storageAccount>.<serviceName>.core.windows.net/<containerName><path>
# Google: gs://<bucket><path>
destinationPath: ""
# -- Specifies secret that contains a CA bundle to validate a privately signed certificate, should contain the key ca-bundle.crt
endpointCA: ""
# -- 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: ""
# -- Specifies secret that contains S3 credentials, should contain the keys ACCESS_KEY_ID and ACCESS_SECRET_KEY
endpointCredentials: ""
# -- Storage
wal:
# -- WAL compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`.
compression: snappy
# -- Whether to instruct the storage provider to encrypt WAL files. One of `` (use the storage container default), `AES256` or `aws:kms`.
encryption: ""
# -- 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: snappy
# -- Whether to instruct the storage provider to encrypt data files. One of `` (use the storage container default), `AES256` or `aws:kms`.
encryption: ""
# -- Number of data files to be archived or restored in parallel.
jobs: 1
# -- Generate external cluster name, uses: {{ .Release.Name }}postgresql-<major version>-cluster-backup-index-{{ .Values.recovery.recoveryIndex }}
recoveryIndex: 1
# -- Name of the recovery cluster in the object store, defaults to "cluster.name"
# -- Override name of the recovery cluster in the object store, defaults to "cluster.name"
recoveryServerName: ""
# -- Name of the recovery cluster in the object store, defaults to ".Release.Name"
recoveryInstanceName: ""
# See https://cloudnative-pg.io/documentation/current/bootstrap/#bootstrap-from-a-live-cluster-pg_basebackup
pgBaseBackup:
wal:
# -- WAL compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`.
compression: snappy
# -- Whether to instruct the storage provider to encrypt WAL files. One of `` (use the storage container default), `AES256` or `aws:kms`.
encryption: ""
# -- 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: snappy
# -- Whether to instruct the storage provider to encrypt data files. One of `` (use the storage container default), `AES256` or `aws:kms`.
encryption: ""
# -- Number of data files to be archived or restored in parallel.
jobs: 1
# -- Name of the database used by the application. Default: `app`.
database: app
replica:
# -- See [here](https://cloudnative-pg.io/documentation/current/database_import/) for different import types
# * `microservice` - Single database import as expected from cnpg clusters
# * `monolith` - Import multiple databases and roles
importType: microservice
# -- Name of the secret containing the initial credentials for the owner of the user database. If empty a new secret will be created from scratch
secret: ""
# -- If type microservice only one database is allowed, default is app as standard in cnpg clusters
importDatabases:
- app
# -- Name of the owner of the database in the instance to be used by applications. Defaults to the value of the `database` key.
owner: ""
# -- If type microservice no roles are imported and ignored
importRoles: []
# -- Configuration for the source database
source:
host: ""
port: 5432
username: ""
database: "app"
sslMode: "verify-full"
passwordSecret:
# -- If import type is monolith postImportApplicationSQL is not supported and ignored
# -- Whether to create a secret for the password
create: false
# -- Name of the secret containing the password
name: ""
# -- The key in the secret containing the password
key: "password"
# -- The password value to use when creating the secret
value: ""
sslKeySecret:
name: ""
key: ""
sslCertSecret:
name: ""
key: ""
sslRootCertSecret:
name: ""
key: ""
# See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-Import
import:
# -- One of `microservice` or `monolith.`
# See: https://cloudnative-pg.io/documentation/current/database_import/#how-it-works
type: "microservice"
# -- Databases to import
databases: []
# -- Roles to import
roles: []
# -- List of SQL queries to be executed as a superuser in the application database right after is imported.
# To be used with extreme care. Only available in microservice type.
postImportApplicationSQL: []
# -- External cluster connection, password specifies a secret name and the key containing the password value
externalCluster:
connectionParameters:
host: postgresql
user: app
dbname: app
password:
name: postgresql
key: password
# -- When set to true, only the pre-data and post-data sections of pg_restore are invoked, avoiding data import.
schemaOnly: false
# -- List of custom options to pass to the `pg_dump` command. IMPORTANT: Use these options with caution and at your
# own risk, as the operator does not validate their content. Be aware that certain options may conflict with the
# operator's intended functionality or design.
pgDumpExtraOptions: []
# -- List of custom options to pass to the `pg_restore` command. IMPORTANT: Use these options with caution and at
# your own risk, as the operator does not validate their content. Be aware that certain options may conflict with the
# operator's intended functionality or design.
pgRestoreExtraOptions: []
# -- Configuration for the source database
source:
host: ""
port: 5432
username: app
database: app
sslMode: "verify-full"
passwordSecret:
# -- Whether to create a secret for the password
create: false
# -- Name of the secret containing the password
name: ""
# -- The key in the secret containing the password
key: "password"
# -- The password value to use when creating the secret
value: ""
sslKeySecret:
name: ""
key: ""
sslCertSecret:
name: ""
key: ""
sslRootCertSecret:
name: ""
key: ""
# -- Backup settings
backup:
# -- You need to configure backups manually, so backups are disabled by default.
enabled: false
# -- S3 endpoint starting with "https://"
endpointURL: ""
# -- Overrides the provider specific default endpoint. Defaults to:
# S3: https://s3.<region>.amazonaws.com"
endpointURL: "" # Leave empty if using the default S3 endpoint
# -- S3 path starting with "s3://"
destinationPath: ""
# -- Specifies secret that contains a CA bundle to validate a privately signed certificate, should contain the key ca-bundle.crt
endpointCA: ""
# -- 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: ""
# -- Specifies secret that contains S3 credentials, should contain the keys ACCESS_KEY_ID and ACCESS_SECRET_KEY
endpointCredentials: ""
# -- Generate external cluster name, creates: postgresql-{{ .Release.Name }}-cluster-backup-index-{{ .Values.backups.backupIndex }}"
backupIndex: 1
# -- Name of the backup cluster in the object store, defaults to "cluster.name"
backupName: ""
# -- Tags to add to backups. Add in key value beneath the type.
tags:
backupRetentionPolicy: ""
historyTags:
backupRetentionPolicy: ""
# -- Overrides the provider specific default path. Defaults to:
# S3: s3://<bucket><path>
# Azure: https://<storageAccount>.<serviceName>.core.windows.net/<containerName><path>
# Google: gs://<bucket><path>
destinationPath: ""
# -- Storage
wal:
# -- WAL compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`.
compression: snappy
# -- Whether to instruct the storage provider to encrypt WAL files. One of `` (use the storage container default), `AES256` or `aws:kms`.
encryption: ""
# -- 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: snappy
# -- Whether to instruct the storage provider to encrypt data files. One of `` (use the storage container default), `AES256` or `aws:kms`.
encryption: ""
# -- Number of data files to be archived or restored in parallel.
jobs: 1
# -- Retention policy for backups
retentionPolicy: "7d"
scheduledBackups:
-
# -- Scheduled backup name
name: daily-backup
# -- Scheduled backup in cron format
# -- Schedule in cron format
schedule: "0 0 */3 * *"
# -- Backup owner reference
backupOwnerReference: self
# -- Backup method, can be `barmanObjectStore` (default) or `volumeSnapshot`
method: barmanObjectStore
# -- Retention policy for backups
retentionPolicy: "30d"
# -- Generate external cluster name, creates: postgresql-{{ .Release.Name }}-cluster-backup-index-{{ .Values.backups.backupIndex }}"
backupIndex: 1
# -- Override ame of the backup cluster in the object store, defaults to "cluster.name"
backupName: ""
# -- List of PgBouncer poolers
poolers: []
# -
# # -- Pooler name
# name: rw
# # -- PgBouncer type of service to forward traffic to.
# type: rw
# # -- PgBouncer pooling mode
# poolMode: transaction
# # -- Number of PgBouncer instances
# instances: 3
# # -- PgBouncer configuration parameters
# parameters:
# max_client_conn: "1000"
# default_pool_size: "25"
# monitoring:
# # -- Whether to enable monitoring
# enabled: false
# podMonitor:
# # -- Whether to enable the PodMonitor
# enabled: true
# # -- Custom PgBouncer deployment template.
# # Use to override image, specify resources, etc.
# template: {}
# -
# # -- Pooler name
# name: ro
# # -- PgBouncer type of service to forward traffic to.
# type: ro
# # -- PgBouncer pooling mode
# poolMode: transaction
# # -- Number of PgBouncer instances
# instances: 3
# # -- PgBouncer configuration parameters
# parameters:
# max_client_conn: "1000"
# default_pool_size: "25"
# monitoring:
# # -- Whether to enable monitoring
# enabled: false
# podMonitor:
# # -- Whether to enable the PodMonitor
# enabled: true
# # -- Custom PgBouncer deployment template.
# # Use to override image, specify resources, etc.
# template: {}