feat(common): rework and update cnpg code (#509)

**Description**
This PR aims to rework and update cnpg code to expose more features of
CNPG to our users.
Primarily a big change would be the support of more backup and restore
options.

- add some missing options for both cluster and pooler
- seperates cluster and pooler sections
- add labels/annotions for pooler and cluster seperatly as well as
cnpg-wide labels-annotations
- Simplify storage logic
- Disable metrics by default

**⚙️ Type of change**

- [x] ⚙️ Feature/App addition
- [x] 🪛 Bugfix
- [x] ⚠️ Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [x] 🔃 Refactor of current code

**🧪 How Has This Been Tested?**
<!--
Please describe the tests that you ran to verify your changes. Provide
instructions so we can reproduce. Please also list any relevant details
for your test configuration
-->

**📃 Notes:**

It will be very loosely inspired by the work done here, mostly because
it gives some nice values.yaml structure on how to deal with the many
backup options:
https://github.com/cloudnative-pg/charts/pull/106

It's going to be flagged as "breaking", because of the shear scope and
the fact it would likely also include a change in standard operating
procedures when it comes to backup-and-restore for our users.

**✔️ Checklist:**

- [ ] ⚖️ My code follows the style guidelines of this project
- [ ] 👀 I have performed a self-review of my own code
- [ ] #️⃣ I have commented my code, particularly in hard-to-understand
areas
- [ ] 📄 I have made corresponding changes to the documentation
- [ ] ⚠️ My changes generate no new warnings
- [ ] 🧪 I have added tests to this description that prove my fix is
effective or that my feature works
- [ ] ⬆️ I increased versions for any altered app according to semantic
versioning

** App addition**

If this PR is an app addition please make sure you have done the
following.

- [ ] 🪞 I have opened a PR on
[truecharts/containers](https://github.com/truecharts/containers) adding
the container to TrueCharts mirror repo.
- [ ] 🖼️ I have added an icon in the Chart's root directory called
`icon.png`

---

_Please don't blindly check all the boxes. Read them and only check
those that apply.
Those checkboxes are there for the reviewer to see what is this all
about and
the status of this PR with a quick glance._

---------

Co-authored-by: Stavros kois <s.kois@outlook.com>
Co-authored-by: Stavros Kois <47820033+stavros-k@users.noreply.github.com>
This commit is contained in:
Kjeld Schouten
2023-12-04 01:49:27 +01:00
committed by GitHub
parent 71995a44be
commit 47daa5c813
67 changed files with 5250 additions and 314 deletions

View File

@@ -1,3 +1,5 @@
words:
- cnpg
- netshoot
- tailscale
- Velero
- velero

View File

@@ -3,7 +3,7 @@ appVersion: ""
dependencies:
- name: common
repository: file://../common
version: ~15.3.0
version: ~16.0.0
deprecated: false
description: Helper chart to test different use cases of the common library
home: https://github.com/truecharts/apps/tree/master/charts/library/common-test

View File

@@ -0,0 +1,242 @@
suite: cnpg backup metadata test
templates:
- common.yaml
chart:
appVersion: &appVer v9.9.9
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should pass with cnpg manualBackups backup created with labels and annotations
set:
operator:
verify:
enabled: false
label1: label1
label2: global_label2
label3: label3
annotation1: annotation1
annotation2: global_annotation2
annotation3: annotation3
global:
labels:
g_label1: global_label1
g_label2: "{{ .Values.label2 }}"
annotations:
g_annotation1: global_annotation1
g_annotation2: "{{ .Values.annotation2 }}"
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
labels:
label1: "{{ .Values.label1 }}"
label2: label2
annotations:
annotation1: "{{ .Values.annotation1 }}"
annotation2: annotation2
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
labels:
label5: label5
annotations:
annotation5: annotation5
manualBackups:
- name: today
labels:
label3: "{{ .Values.label3 }}"
label4: label4
annotations:
annotation3: "{{ .Values.annotation3 }}"
annotation4: annotation4
asserts:
- documentIndex: &backupDoc 0
isKind:
of: Backup
- documentIndex: *backupDoc
equal:
path: metadata.annotations
value:
annotation1: annotation1
annotation2: annotation2
annotation3: annotation3
annotation4: annotation4
annotation5: annotation5
g_annotation1: global_annotation1
g_annotation2: global_annotation2
- documentIndex: *backupDoc
equal:
path: metadata.labels
value:
app: common-test-1.0.0
release: test-release-name
helm-revision: "0"
helm.sh/chart: common-test-1.0.0
app.kubernetes.io/name: common-test
app.kubernetes.io/instance: test-release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/version: *appVer
cnpg.io/cluster: test-release-name-common-test-cnpg-my-pg
g_label1: global_label1
g_label2: global_label2
label1: label1
label2: label2
label3: label3
label4: label4
label5: label5
- documentIndex: *backupDoc
equal:
path: metadata.namespace
value: test-release-namespace
- it: should pass with cnpg manualBackups backup created with namespace
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
namespace: some-namespace
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
manualBackups:
- name: today
asserts:
- documentIndex: *backupDoc
equal:
path: metadata.namespace
value: some-namespace
- it: should pass with cnpg manualBackups backup created with object namespace from tpl
set:
operator:
verify:
enabled: false
key: some-namespace
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
namespace: "{{ .Values.key }}"
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
manualBackups:
- name: today
asserts:
- documentIndex: *backupDoc
equal:
path: metadata.namespace
value: some-namespace
- it: should pass with cnpg manualBackups backup created with namespace from global with tpl
set:
operator:
verify:
enabled: false
key: global-namespace
global:
namespace: "{{ .Values.key }}"
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
manualBackups:
- name: today
asserts:
- documentIndex: *backupDoc
equal:
path: metadata.namespace
value: global-namespace
- it: should pass with cnpg manualBackups backup created with namespace from root with tpl
set:
operator:
verify:
enabled: false
key: local-namespace
namespace: "{{ .Values.key }}"
global:
namespace: global-namespace
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
manualBackups:
- name: today
asserts:
- documentIndex: *backupDoc
equal:
path: metadata.namespace
value: local-namespace
- it: should pass with cnpg manualBackups backup created with namespace in TrueNAS SCALE
set:
operator:
verify:
enabled: false
global:
ixChartContext:
iAmNotEmpty: true
storageClassName: some-storage-class
namespace: ix-namespace
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
manualBackups:
- name: today
asserts:
- documentIndex: *backupDoc
equal:
path: metadata.namespace
value: ix-namespace

View File

@@ -0,0 +1,62 @@
suite: cnpg backup name test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should generate correct name
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
manualBackups:
- name: today
my-pg2:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
manualBackups:
- name: other
asserts:
- documentIndex: &backupDoc 0
isKind:
of: Backup
- documentIndex: *backupDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *backupDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-backup-today
- documentIndex: &otherbackupDoc 3
isKind:
of: Backup
- documentIndex: *otherbackupDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *otherbackupDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg2-backup-other

View File

@@ -0,0 +1,123 @@
suite: cnpg backup provider secret spec test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should create secret for azure provider with connection string
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
manualBackups:
- name: today
asserts:
- documentIndex: &secretDoc 3
isKind:
of: Secret
- documentIndex: *secretDoc
isAPIVersion:
of: v1
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-provider-backup-azure-creds
- documentIndex: *secretDoc
equal:
path: stringData
value:
CONNECTION_STRING: some-connection-string
STORAGE_ACCOUNT: ""
STORAGE_KEY: ""
STORAGE_SAS_TOKEN: ""
- it: should create secret for google provider with application credentials
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: google
destinationPath: some-path
google:
applicationCredentials: some-credentials
manualBackups:
- name: today
asserts:
- documentIndex: *secretDoc
isKind:
of: Secret
- documentIndex: *secretDoc
isAPIVersion:
of: v1
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-provider-backup-google-creds
- documentIndex: *secretDoc
equal:
path: stringData
value:
APPLICATION_CREDENTIALS: some-credentials
- it: should create secret for s3 provider with application credentials
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: s3
destinationPath: some-path
endpointURL: some-url
s3:
secretKey: some-secret-key
accessKey: some-access-key
manualBackups:
- name: today
asserts:
- documentIndex: *secretDoc
isKind:
of: Secret
- documentIndex: *secretDoc
isAPIVersion:
of: v1
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds
- documentIndex: *secretDoc
equal:
path: stringData
value:
ACCESS_SECRET_KEY: some-secret-key
ACCESS_KEY_ID: some-access-key

View File

@@ -0,0 +1,156 @@
suite: cnpg backup provider validation test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should fail with invalid provider
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
backups:
enabled: true
provider: invalid
manualBackups:
- name: today
asserts:
- failedTemplate:
errorMessage: CNPG Backup - Expected [backups.provider] to be one of [azure, s3, google], but got [invalid]
- it: should fail with missing "provider" object
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
backups:
enabled: true
provider: azure
manualBackups:
- name: today
asserts:
- failedTemplate:
errorMessage: CNPG Backup - Expected [backups.azure] to be defined when [backups.provider] is set to [azure]
- it: should fail with missing storageAccount or connectionString with azure provider
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
backups:
enabled: true
provider: azure
azure:
storageKey: test
manualBackups:
- name: today
asserts:
- failedTemplate:
errorMessage: CNPG Backup - Expected [backups.azure.storageAccount] OR [backups.azure.connectionString] to be defined and non-empty when provider is set to [azure]
- it: should fail with missing storageKey or storageSasToken with azure provider
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
backups:
enabled: true
provider: azure
azure:
storageAccount: test
manualBackups:
- name: today
asserts:
- failedTemplate:
errorMessage: CNPG Backup - Expected [backups.azure.storageKey] OR [backups.azure.storageSasToken] to be defined and non-empty when provider is set to [azure]
- it: should fail with both storageKey and storageSasToken defined with azure provider
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
backups:
enabled: true
provider: azure
azure:
storageAccount: test
storageKey: test
storageSasToken: test
manualBackups:
- name: today
asserts:
- failedTemplate:
errorMessage: CNPG Backup - Expected only one of [backups.azure.storageKey, backups.azure.storageSasToken] to be defined and non-empty when provider is set to [azure]
- it: should fail with applicationCredentials missing with google provider
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
backups:
enabled: true
provider: google
google:
gkeEnvironment: false
manualBackups:
- name: today
asserts:
- failedTemplate:
errorMessage: CNPG Backup - Expected [backups.google.applicationCredentials] to be defined and non-empty when provider is set to [google]
- it: should fail with accessKey missing with s3 provider
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
backups:
enabled: true
provider: s3
s3:
secretKey: test
manualBackups:
- name: today
asserts:
- failedTemplate:
errorMessage: CNPG Backup - Expected [backups.s3.accessKey] to be defined and non-empty when provider is set to [s3]
- it: should fail with secretKey missing with s3 provider
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
backups:
enabled: true
provider: s3
s3:
accessKey: test
manualBackups:
- name: today
asserts:
- failedTemplate:
errorMessage: CNPG Backup - Expected [backups.s3.secretKey] to be defined and non-empty when provider is set to [s3]

View File

@@ -0,0 +1,61 @@
suite: cnpg backup spec test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should generate correct spec
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
manualBackups:
- name: today
- name: before-upgrade
asserts:
- documentIndex: &cnpgDoc 0
isKind:
of: Backup
- documentIndex: *cnpgDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *cnpgDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-backup-today
- documentIndex: *cnpgDoc
equal:
path: spec
value:
cluster:
name: test-release-name-common-test-cnpg-my-pg
- documentIndex: &otherCnpgDoc 1
isKind:
of: Backup
- documentIndex: *otherCnpgDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *otherCnpgDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-backup-before-upgrade
- documentIndex: *otherCnpgDoc
equal:
path: spec
value:
cluster:
name: test-release-name-common-test-cnpg-my-pg

View File

@@ -0,0 +1,44 @@
suite: cnpg backup validation test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should fail without name in manualBackups backup
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
backups:
enabled: true
provider: azure
azure:
connectionString: some-connection-string
manualBackups:
- name:
asserts:
- failedTemplate:
errorMessage: CNPG Backup - Expected non-empty [name] in [backups.manualBackups] entry
- it: should fail with invalid name in manualBackups backup
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
backups:
enabled: true
provider: azure
azure:
connectionString: some-connection-string
manualBackups:
- name: _invalid
asserts:
- failedTemplate:
errorMessage: Name [test-release-name-common-test-cnpg-my-pg-backup-_invalid] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 253 characters.

View File

@@ -0,0 +1,223 @@
suite: cnpg cluster backup spec test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should generate correct spec with backups (azure)
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
asserts:
- documentIndex: &secretDoc 2
isKind:
of: Secret
- documentIndex: *secretDoc
isAPIVersion:
of: v1
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-provider-backup-azure-creds
- documentIndex: *secretDoc
equal:
path: stringData
value:
CONNECTION_STRING: some-connection-string
STORAGE_ACCOUNT: ""
STORAGE_KEY: ""
STORAGE_SAS_TOKEN: ""
- documentIndex: &clusterDoc 1
isKind:
of: Cluster
- documentIndex: *clusterDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *clusterDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
backup:
target: primary
retentionPolicy: 10d
barmanObjectStore:
wal:
compression: gzip
encryption: AES256
data:
compression: gzip
encryption: AES256
jobs: 2
endpointURL: null
destinationPath: some-path
azureCredentials:
connectionString:
key: CONNECTION_STRING
name: test-release-name-common-test-cnpg-my-pg-provider-backup-azure-creds
storageAccount:
key: STORAGE_ACCOUNT
name: test-release-name-common-test-cnpg-my-pg-provider-backup-azure-creds
storageKey:
key: STORAGE_KEY
name: test-release-name-common-test-cnpg-my-pg-provider-backup-azure-creds
storageSasToken:
key: STORAGE_SAS_TOKEN
name: test-release-name-common-test-cnpg-my-pg-provider-backup-azure-creds
- it: should generate correct spec with backups (google)
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: google
destinationPath: some-path
google:
applicationCredentials: some-credentials
asserts:
- documentIndex: &secretDoc 2
isKind:
of: Secret
- documentIndex: *secretDoc
isAPIVersion:
of: v1
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-provider-backup-google-creds
- documentIndex: *secretDoc
equal:
path: stringData
value:
APPLICATION_CREDENTIALS: some-credentials
- documentIndex: &clusterDoc 1
isKind:
of: Cluster
- documentIndex: *clusterDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *clusterDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
backup:
target: primary
retentionPolicy: 10d
barmanObjectStore:
wal:
compression: gzip
encryption: AES256
data:
compression: gzip
encryption: AES256
jobs: 2
endpointURL: null
destinationPath: some-path
googleCredentials:
gkeEnvironment: false
applicationCredentials:
key: APPLICATION_CREDENTIALS
name: test-release-name-common-test-cnpg-my-pg-provider-backup-google-creds
- it: should generate correct spec with backups (s3)
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: s3
destinationPath: some-path
endpointURL: some-url
s3:
accessKey: some-access-key
secretKey: some-secret-key
asserts:
- documentIndex: &secretDoc 2
isKind:
of: Secret
- documentIndex: *secretDoc
isAPIVersion:
of: v1
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds
- documentIndex: *secretDoc
equal:
path: stringData
value:
ACCESS_KEY_ID: some-access-key
ACCESS_SECRET_KEY: some-secret-key
- documentIndex: &clusterDoc 1
isKind:
of: Cluster
- documentIndex: *clusterDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *clusterDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
backup:
target: primary
retentionPolicy: 10d
barmanObjectStore:
wal:
compression: gzip
encryption: AES256
data:
compression: gzip
encryption: AES256
jobs: 2
endpointURL: some-url
destinationPath: some-path
s3Credentials:
accessKeyId:
key: ACCESS_KEY_ID
name: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds
secretAccessKey:
key: ACCESS_SECRET_KEY
name: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds

View File

@@ -0,0 +1,178 @@
suite: cnpg cluster metadata test
templates:
- common.yaml
chart:
appVersion: &appVer v9.9.9
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should pass with cnpg created with labels and annotations
set:
operator:
verify:
enabled: false
label1: label1
label2: global_label2
label3: label3
annotation1: annotation1
annotation2: global_annotation2
annotation3: annotation3
global:
labels:
g_label1: global_label1
g_label2: "{{ .Values.label2 }}"
annotations:
g_annotation1: global_annotation1
g_annotation2: "{{ .Values.annotation2 }}"
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
labels:
label1: "{{ .Values.label1 }}"
label2: label2
annotations:
annotation1: "{{ .Values.annotation1 }}"
annotation2: annotation2
cluster:
labels:
label3: "{{ .Values.label3 }}"
annotations:
annotation3: "{{ .Values.annotation3 }}"
asserts:
- documentIndex: &clusterDoc 1
isKind:
of: Cluster
- documentIndex: *clusterDoc
isSubset:
path: metadata.annotations
content:
annotation1: annotation1
annotation2: annotation2
annotation3: annotation3
g_annotation1: global_annotation1
g_annotation2: global_annotation2
cnpg.io/hibernation: "off"
- documentIndex: *clusterDoc
matchRegex:
path: metadata.annotations.rollme
pattern: ^[a-zA-Z0-9]{5}$
- documentIndex: *clusterDoc
equal:
path: metadata.labels
value:
app: common-test-1.0.0
release: test-release-name
helm-revision: "0"
helm.sh/chart: common-test-1.0.0
app.kubernetes.io/name: common-test
app.kubernetes.io/instance: test-release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/version: *appVer
cnpg.io/reload: "on"
g_label1: global_label1
g_label2: global_label2
label1: label1
label2: label2
label3: label3
- documentIndex: *clusterDoc
equal:
path: metadata.namespace
value: test-release-namespace
- it: should pass with cnpg created with namespace
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
namespace: some-namespace
asserts:
- documentIndex: *clusterDoc
equal:
path: metadata.namespace
value: some-namespace
- it: should pass with cnpg created with object namespace from tpl
set:
operator:
verify:
enabled: false
key: some-namespace
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
namespace: "{{ .Values.key }}"
asserts:
- documentIndex: *clusterDoc
equal:
path: metadata.namespace
value: some-namespace
- it: should pass with cnpg created with namespace from global with tpl
set:
operator:
verify:
enabled: false
key: global-namespace
global:
namespace: "{{ .Values.key }}"
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
asserts:
- documentIndex: *clusterDoc
equal:
path: metadata.namespace
value: global-namespace
- it: should pass with cnpg created with namespace from root with tpl
set:
operator:
verify:
enabled: false
key: local-namespace
namespace: "{{ .Values.key }}"
global:
namespace: global-namespace
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
asserts:
- documentIndex: *clusterDoc
equal:
path: metadata.namespace
value: local-namespace
- it: should pass with cnpg created with namespace in TrueNAS SCALE
set:
operator:
verify:
enabled: false
global:
ixChartContext:
iAmNotEmpty: true
storageClassName: some-storage-class
namespace: ix-namespace
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
asserts:
- documentIndex: *clusterDoc
equal:
path: metadata.namespace
value: ix-namespace

View File

@@ -0,0 +1,42 @@
suite: cnpg cluster name test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should generate correct name
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
my-pg2:
enabled: true
user: test-user
database: test-db
asserts:
- documentIndex: &clusterDoc 1
isKind:
of: Cluster
- documentIndex: *clusterDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *clusterDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg
- documentIndex: &otherclusterDoc 3
isKind:
of: Cluster
- documentIndex: *otherclusterDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *otherclusterDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg2

View File

@@ -0,0 +1,532 @@
suite: cnpg cluster recovery spec test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should generate correct spec with recovery/backup
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: backup
backupName: some-backup-name
asserts:
- documentIndex: &clusterDoc 1
isKind:
of: Cluster
- documentIndex: *clusterDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *clusterDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg
- documentIndex: *clusterDoc
equal:
path: spec
value:
enableSuperuserAccess: true
primaryUpdateStrategy: unsupervised
primaryUpdateMethod: switchover
logLevel: info
instances: 2
nodeMaintenanceWindow:
reusePVC: true
inProgress: false
resources:
limits:
cpu: 4000m
memory: 8Gi
requests:
cpu: 10m
memory: 50Mi
storage:
pvcTemplate:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
walStorage:
pvcTemplate:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
bootstrap:
recovery:
secret:
name: test-release-name-common-test-cnpg-my-pg-user
owner: test-user
database: test-db
backup:
name: some-backup-name
- it: should generate correct spec with recovery/objectStore (google)
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: object_store
provider: google
google:
applicationCredentials: some-credentials
bucket: some-bucket
path: some-path
pitrTarget:
time: "2021-01-01T00:00:00Z"
asserts:
- documentIndex: &secretDoc 2
isKind:
of: Secret
- documentIndex: *secretDoc
isAPIVersion:
of: v1
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-provider-recovery-google-creds
- documentIndex: *secretDoc
equal:
path: stringData
value:
APPLICATION_CREDENTIALS: some-credentials
- documentIndex: &clusterDoc 1
isKind:
of: Cluster
- documentIndex: *clusterDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *clusterDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
bootstrap:
recovery:
secret:
name: test-release-name-common-test-cnpg-my-pg-user
owner: test-user
database: test-db
source: objectStoreRecoveryCluster
recoveryTarget:
targetTime: "2021-01-01T00:00:00Z"
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
externalClusters:
- name: objectStoreRecoveryCluster
barmanObjectStore:
destinationPath: gs://some-bucket/some-path
endpointURL: null
googleCredentials:
applicationCredentials:
key: APPLICATION_CREDENTIALS
name: test-release-name-common-test-cnpg-my-pg-provider-recovery-google-creds
gkeEnvironment: false
- it: should generate correct spec with recovery/objectStore (google - destinationPath)
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: object_store
provider: google
destinationPath: gs://some-bucket
google:
applicationCredentials: some-credentials
pitrTarget:
time: "2021-01-01T00:00:00Z"
asserts:
- documentIndex: &secretDoc 2
isKind:
of: Secret
- documentIndex: *secretDoc
isAPIVersion:
of: v1
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-provider-recovery-google-creds
- documentIndex: *secretDoc
equal:
path: stringData
value:
APPLICATION_CREDENTIALS: some-credentials
- documentIndex: &clusterDoc 1
isKind:
of: Cluster
- documentIndex: *clusterDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *clusterDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
bootstrap:
recovery:
secret:
name: test-release-name-common-test-cnpg-my-pg-user
owner: test-user
database: test-db
source: objectStoreRecoveryCluster
recoveryTarget:
targetTime: "2021-01-01T00:00:00Z"
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
externalClusters:
- name: objectStoreRecoveryCluster
barmanObjectStore:
destinationPath: gs://some-bucket
endpointURL: null
googleCredentials:
applicationCredentials:
key: APPLICATION_CREDENTIALS
name: test-release-name-common-test-cnpg-my-pg-provider-recovery-google-creds
gkeEnvironment: false
- it: should generate correct spec with recovery/objectStore (s3)
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: object_store
provider: s3
s3:
accessKey: some-access-key
secretKey: some-secret-key
bucket: some-bucket
path: some-path
region: some-region
asserts:
- documentIndex: &secretDoc 2
isKind:
of: Secret
- documentIndex: *secretDoc
isAPIVersion:
of: v1
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds
- documentIndex: *secretDoc
equal:
path: stringData
value:
ACCESS_KEY_ID: some-access-key
ACCESS_SECRET_KEY: some-secret-key
- documentIndex: &clusterDoc 1
isKind:
of: Cluster
- documentIndex: *clusterDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *clusterDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
bootstrap:
recovery:
secret:
name: test-release-name-common-test-cnpg-my-pg-user
owner: test-user
database: test-db
source: objectStoreRecoveryCluster
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
externalClusters:
- name: objectStoreRecoveryCluster
barmanObjectStore:
destinationPath: s3://some-bucket/some-path
endpointURL: https://s3.some-region.amazonaws.com
s3Credentials:
accessKeyId:
key: ACCESS_KEY_ID
name: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds
secretAccessKey:
key: ACCESS_SECRET_KEY
name: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds
- it: should generate correct spec with recovery/objectStore (s3 - destinationPath/endpointURL)
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: object_store
provider: s3
destinationPath: s3://some-bucket
endpointURL: some-endpoint-url
s3:
accessKey: some-access-key
secretKey: some-secret-key
asserts:
- documentIndex: &secretDoc 2
isKind:
of: Secret
- documentIndex: *secretDoc
isAPIVersion:
of: v1
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds
- documentIndex: *secretDoc
equal:
path: stringData
value:
ACCESS_KEY_ID: some-access-key
ACCESS_SECRET_KEY: some-secret-key
- documentIndex: &clusterDoc 1
isKind:
of: Cluster
- documentIndex: *clusterDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *clusterDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
bootstrap:
recovery:
secret:
name: test-release-name-common-test-cnpg-my-pg-user
owner: test-user
database: test-db
source: objectStoreRecoveryCluster
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
externalClusters:
- name: objectStoreRecoveryCluster
barmanObjectStore:
destinationPath: s3://some-bucket
endpointURL: some-endpoint-url
s3Credentials:
accessKeyId:
key: ACCESS_KEY_ID
name: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds
secretAccessKey:
key: ACCESS_SECRET_KEY
name: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds
- it: should generate correct spec with recovery/objectStore (azure)
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: object_store
provider: azure
azure:
connectionString: some-connection-string
storageAccount: some-storage-account
serviceName: some-service-name
containerName: some-container-name
path: some-path
asserts:
- documentIndex: &secretDoc 2
isKind:
of: Secret
- documentIndex: *secretDoc
isAPIVersion:
of: v1
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-provider-recovery-azure-creds
- documentIndex: *secretDoc
equal:
path: stringData
value:
CONNECTION_STRING: some-connection-string
STORAGE_ACCOUNT: some-storage-account
STORAGE_KEY: ""
STORAGE_SAS_TOKEN: ""
- documentIndex: &clusterDoc 1
isKind:
of: Cluster
- documentIndex: *clusterDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *clusterDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
bootstrap:
recovery:
secret:
name: test-release-name-common-test-cnpg-my-pg-user
owner: test-user
database: test-db
source: objectStoreRecoveryCluster
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
externalClusters:
- name: objectStoreRecoveryCluster
barmanObjectStore:
destinationPath: https://some-storage-account.some-service-name.core.windows.net/some-container-name/some-path
endpointURL: null
azureCredentials:
connectionString:
key: CONNECTION_STRING
name: test-release-name-common-test-cnpg-my-pg-provider-recovery-azure-creds
storageAccount:
key: STORAGE_ACCOUNT
name: test-release-name-common-test-cnpg-my-pg-provider-recovery-azure-creds
storageKey:
key: STORAGE_KEY
name: test-release-name-common-test-cnpg-my-pg-provider-recovery-azure-creds
storageSasToken:
key: STORAGE_SAS_TOKEN
name: test-release-name-common-test-cnpg-my-pg-provider-recovery-azure-creds
- it: should generate correct spec with recovery/objectStore (azure - destinationPath)
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: object_store
provider: azure
destinationPath: https://some-storage-account.some-service-name.core.windows.net/some-container-name
azure:
connectionString: some-connection-string
asserts:
- documentIndex: &secretDoc 2
isKind:
of: Secret
- documentIndex: *secretDoc
isAPIVersion:
of: v1
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-provider-recovery-azure-creds
- documentIndex: *secretDoc
equal:
path: stringData
value:
CONNECTION_STRING: some-connection-string
STORAGE_ACCOUNT: ""
STORAGE_KEY: ""
STORAGE_SAS_TOKEN: ""
- documentIndex: &clusterDoc 1
isKind:
of: Cluster
- documentIndex: *clusterDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *clusterDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
bootstrap:
recovery:
secret:
name: test-release-name-common-test-cnpg-my-pg-user
owner: test-user
database: test-db
source: objectStoreRecoveryCluster
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
externalClusters:
- name: objectStoreRecoveryCluster
barmanObjectStore:
destinationPath: https://some-storage-account.some-service-name.core.windows.net/some-container-name
endpointURL: null
azureCredentials:
connectionString:
key: CONNECTION_STRING
name: test-release-name-common-test-cnpg-my-pg-provider-recovery-azure-creds
storageAccount:
key: STORAGE_ACCOUNT
name: test-release-name-common-test-cnpg-my-pg-provider-recovery-azure-creds
storageKey:
key: STORAGE_KEY
name: test-release-name-common-test-cnpg-my-pg-provider-recovery-azure-creds
storageSasToken:
key: STORAGE_SAS_TOKEN
name: test-release-name-common-test-cnpg-my-pg-provider-recovery-azure-creds

View File

@@ -0,0 +1,370 @@
suite: cnpg cluster spec test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should generate correct spec
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
asserts:
- documentIndex: &clusterDoc 1
isKind:
of: Cluster
- documentIndex: *clusterDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *clusterDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg
- documentIndex: *clusterDoc
equal:
path: spec
value:
enableSuperuserAccess: true
primaryUpdateStrategy: unsupervised
primaryUpdateMethod: switchover
logLevel: info
instances: 2
nodeMaintenanceWindow:
reusePVC: true
inProgress: false
resources:
limits:
cpu: 4000m
memory: 8Gi
requests:
cpu: 10m
memory: 50Mi
storage:
pvcTemplate:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
walStorage:
pvcTemplate:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
bootstrap:
initdb:
secret:
name: test-release-name-common-test-cnpg-my-pg-user
database: test-db
owner: test-user
dataChecksums: false
- it: should override options
set:
operator:
verify:
enabled: false
ext1: some-extension
ext2: some-other-extension
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
cluster:
enableSuperuserAccess: false
primaryUpdateStrategy: supervised
primaryUpdateMethod: restart
logLevel: debug
instances: 3
initdb:
dataChecksums: true
encoding: some-encoding
localeCollate: some-locale
localeCtype: some-locale
walSegmentSize: 16
postInitApplicationSQL:
- CREATE EXTENSION IF NOT EXISTS {{ .Values.ext1 }};
- CREATE EXTENSION IF NOT EXISTS {{ .Values.ext2 }};
postInitSQL:
- CREATE EXTENSION IF NOT EXISTS {{ .Values.ext1 }}1;
- CREATE EXTENSION IF NOT EXISTS {{ .Values.ext2 }}2;
postInitTemplateSQL:
- CREATE EXTENSION IF NOT EXISTS {{ .Values.ext1 }}1;
- CREATE EXTENSION IF NOT EXISTS {{ .Values.ext2 }}2;
nodeMaintenanceWindow:
reusePVC: false
inProgress: true
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 20m
memory: 100Mi
storage:
size: 200Gi
accessModes:
- ReadWriteMany
walStorage:
size: 200Gi
accessModes:
- ReadWriteMany
asserts:
- documentIndex: *clusterDoc
isKind:
of: Cluster
- documentIndex: *clusterDoc
equal:
path: spec
value:
enableSuperuserAccess: false
primaryUpdateStrategy: supervised
primaryUpdateMethod: restart
logLevel: debug
instances: 3
nodeMaintenanceWindow:
reusePVC: false
inProgress: true
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 20m
memory: 100Mi
storage:
pvcTemplate:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 200Gi
walStorage:
pvcTemplate:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 200Gi
bootstrap:
initdb:
secret:
name: test-release-name-common-test-cnpg-my-pg-user
database: test-db
owner: test-user
dataChecksums: true
encoding: some-encoding
localeCollate: some-locale
localeCtype: some-locale
walSegmentSize: 16
postInitApplicationSQL:
- CREATE EXTENSION IF NOT EXISTS some-extension;
- CREATE EXTENSION IF NOT EXISTS some-other-extension;
postInitSQL:
- CREATE EXTENSION IF NOT EXISTS some-extension1;
- CREATE EXTENSION IF NOT EXISTS some-other-extension2;
postInitTemplateSQL:
- CREATE EXTENSION IF NOT EXISTS some-extension1;
- CREATE EXTENSION IF NOT EXISTS some-other-extension2;
- it: should override resources from top level
set:
operator:
verify:
enabled: false
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 20m
memory: 100Mi
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
asserts:
- documentIndex: *clusterDoc
isKind:
of: Cluster
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 20m
memory: 100Mi
- it: should pass with custom-conf
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: app
database: app
cluster:
postgresql:
key1: value1
key2: '{{ printf "test-tpl" }}'
preloadLibraries:
- pg_stat_statements
- pg_cron
asserts:
- documentIndex: *clusterDoc
isKind:
of: Cluster
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
postgresql:
parameters:
key1: value1
key2: test-tpl
shared_preload_libraries:
- pg_stat_statements
- pg_cron
- it: should pass with timescaledb
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: app
database: app
type: timescaledb
cluster:
initdb:
postInitApplicationSQL:
- CREATE EXTENSION IF NOT EXISTS some-extension;
postgresql:
key1: value1
key2: '{{ printf "test-tpl" }}'
preloadLibraries:
- pg_stat_statements
- pg_cron
asserts:
- documentIndex: *clusterDoc
isKind:
of: Cluster
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
postgresql:
parameters:
key1: value1
key2: test-tpl
shared_preload_libraries:
- pg_stat_statements
- pg_cron
- timescaledb
bootstrap:
initdb:
secret:
name: test-release-name-common-test-cnpg-my-pg-user
database: app
owner: app
dataChecksums: false
postInitApplicationSQL:
- CREATE EXTENSION IF NOT EXISTS some-extension;
- CREATE EXTENSION IF NOT EXISTS timescaledb;
- it: should pass with enabled monitoring
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: app
database: app
type: timescaledb
monitoring:
enablePodMonitor: true
asserts:
- documentIndex: *clusterDoc
isKind:
of: Cluster
- documentIndex: *clusterDoc
equal:
path: spec.monitoring
value:
enablePodMonitor: true
disableDefaultQueries: false
- it: should pass with override monitoring
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: app
database: app
type: timescaledb
monitoring:
enablePodMonitor: true
disableDefaultQueries: true
customQueries:
- name: test-query
query: test-query
metrics:
- a-gauge:
usage: GAUGE
description: test-metric
- a-counter:
usage: COUNTER
description: test-metric
- name: test-query2
query: test-query2
metrics:
- a-gauge:
usage: GAUGE
description: test-metric
- a-counter:
usage: COUNTER
description: test-metric
- name: test-query3
query: test-query3
expandObjectName: false
key: test-key
asserts:
- documentIndex: *clusterDoc
isKind:
of: Cluster
- documentIndex: *clusterDoc
equal:
path: spec.monitoring
value:
enablePodMonitor: true
disableDefaultQueries: true
customQueriesConfigMap:
- name: test-release-name-common-test-cnpg-my-pg-test-query
key: custom-queries
- name: test-release-name-common-test-cnpg-my-pg-test-query2
key: custom-queries
- name: test-query3
key: test-key

View File

@@ -0,0 +1,558 @@
suite: cnpg cluster validation test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should fail without user
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
database: test-db
asserts:
- failedTemplate:
errorMessage: CNPG - Expected a non-empty [user] key
- it: should fail without database
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
asserts:
- failedTemplate:
errorMessage: CNPG - Expected a non-empty [database] key
- it: should fail with invalid version
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
version: invalid
asserts:
- failedTemplate:
errorMessage: CNPG - Expected [version] to be one of [legacy], but got [invalid]
- it: should fail with hibernate not a bool
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
hibernate: invalid
asserts:
- failedTemplate:
errorMessage: CNPG - Expected [hibernate] to be a boolean, but got [string]
- it: should fail with invalid mode
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: invalid
asserts:
- failedTemplate:
errorMessage: CNPG Cluster - Expected [mode] to be one of [standalone, replica, recovery], but got [invalid]
- it: should fail with invalid type
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
type: invalid
asserts:
- failedTemplate:
errorMessage: CNPG Cluster - Expected [type] to be one of [postgresql, postgis, timescaledb], but got [invalid]
- it: should fail with invalid log level
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
cluster:
logLevel: invalid
asserts:
- failedTemplate:
errorMessage: CNPG Cluster - Expected [cluster.logLevel] to be one of [error, warning, info, debug, trace], but got [invalid]
- it: should fail with invalid primaryUpdateStrategy
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
cluster:
primaryUpdateStrategy: invalid
asserts:
- failedTemplate:
errorMessage: CNPG Cluster - Expected [cluster.primaryUpdateStrategy] to be one of [supervised, unsupervised], but got [invalid]
- it: should fail with invalid primaryUpdateMethod
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
cluster:
primaryUpdateMethod: invalid
asserts:
- failedTemplate:
errorMessage: CNPG Cluster - Expected [cluster.primaryUpdateMethod] to be one of [switchover, restart], but got [invalid]
- it: should fail with invalid walSegmentSize
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
cluster:
initdb:
walSegmentSize: invalid
asserts:
- failedTemplate:
errorMessage: CNPG Cluster - Expected [cluster.initdb.walSegmentSize] to be an integer, but got [string]
- it: should fail with too large walSegmentSize
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
cluster:
initdb:
walSegmentSize: 1025
asserts:
- failedTemplate:
errorMessage: CNPG Cluster - Expected [cluster.initdb.walSegmentSize] to be between 1 and 1024, but got [1025]
- it: should fail without recovery object when mode is recovery
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
asserts:
- failedTemplate:
errorMessage: CNPG Recovery - Expected a non-empty [recovery] key
- it: should fail with invalid recovery method
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: invalid
asserts:
- failedTemplate:
errorMessage: CNPG Recovery - Expected [recovery.method] to be one of [backup, object_store, pg_basebackup], but got [invalid]
- it: should fail without backupName on recovery method backup
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: backup
asserts:
- failedTemplate:
errorMessage: CNPG Recovery - Expected a non-empty [recovery.backupName] key
- it: should fail with invalid provider on recovery method object_store
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: object_store
provider: invalid
asserts:
- failedTemplate:
errorMessage: CNPG Recovery - Expected [recovery.provider] to be one of [azure, s3, google], but got [invalid]
- it: should fail with missing "provider" key on recovery method object_store
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: object_store
provider: google
asserts:
- failedTemplate:
errorMessage: CNPG Recovery - Expected [recovery.google] to be defined when [recovery.provider] is set to [google]
- it: should fail with missing destinationPath and google bucket on recovery method object_store
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: object_store
provider: google
google:
applicationCredentials: some-credentials
asserts:
- failedTemplate:
errorMessage: CNPG Recovery - You need to specify [recovery.google.bucket] or [recovery.destinationPath]
- it: should fail with missing destinationPath and s3 bucket on recovery method object_store
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: object_store
provider: s3
s3:
accessKey: some-access-key
secretKey: some-secret-key
asserts:
- failedTemplate:
errorMessage: CNPG Recovery - You need to specify [recovery.s3.bucket] or [recovery.destinationPath]
- it: should fail with missing endpointURL and s3 region on recovery method object_store
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: object_store
provider: s3
s3:
accessKey: some-access-key
secretKey: some-secret-key
bucket: some-bucket
asserts:
- failedTemplate:
errorMessage: CNPG Recovery - You need to specify [recovery.s3.region] or [recovery.endpointURL]
- it: should fail with missing destinationPath and azure storageAccount on recovery method object_store
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: object_store
provider: azure
azure:
connectionString: some-connection-string
asserts:
- failedTemplate:
errorMessage: CNPG Recovery - You need to specify [recovery.azure.storageAccount] or [recovery.destinationPath]
- it: should fail with missing destinationPath and azure serviceName on recovery method object_store
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: object_store
provider: azure
azure:
connectionString: some-connection-string
storageAccount: some-storage-account
asserts:
- failedTemplate:
errorMessage: CNPG Recovery - You need to specify [recovery.azure.serviceName] or [recovery.destinationPath]
- it: should fail with missing destinationPath and azure containerName on recovery method object_store
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
mode: recovery
recovery:
method: object_store
provider: azure
azure:
connectionString: some-connection-string
storageAccount: some-storage-account
serviceName: some-service-name
asserts:
- failedTemplate:
errorMessage: CNPG Recovery - You need to specify [recovery.azure.containerName] or [recovery.destinationPath]
- it: should fail with invalid target when backups are enabled
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
provider: azure
azure:
connectionString: some-connection-string
target: invalid
asserts:
- failedTemplate:
errorMessage: CNPG Backup - Expected [backups.target] to be one of [primary, prefer-standby], but got [invalid]
- it: should fail with invalid retentionPolicy when backups are enabled
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
provider: azure
azure:
connectionString: some-connection-string
target: primary
retentionPolicy: invalid
asserts:
- failedTemplate:
errorMessage: CNPG Backup - Expected [backups.retentionPolicy] to match regex [^[1-9][0-9]*[dwm]$], got [invalid]
- it: should fail with missing destinationPath and google bucket on backups
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
provider: google
target: primary
retentionPolicy: 1d
google:
applicationCredentials: some-credentials
asserts:
- failedTemplate:
errorMessage: CNPG Backup - You need to specify [backups.google.bucket] or [backups.destinationPath]
- it: should fail with missing destinationPath and s3 bucket on backups
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
provider: s3
target: primary
retentionPolicy: 1d
s3:
accessKey: some-access-key
secretKey: some-secret-key
asserts:
- failedTemplate:
errorMessage: CNPG Backup - You need to specify [backups.s3.bucket] or [backups.destinationPath]
- it: should fail with missing endpointURL and s3 region on backups
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
provider: s3
target: primary
retentionPolicy: 1d
s3:
accessKey: some-access-key
secretKey: some-secret-key
bucket: some-bucket
asserts:
- failedTemplate:
errorMessage: CNPG Backup - You need to specify [backups.s3.region] or [backups.endpointURL]
- it: should fail with missing destinationPath and azure storageAccount on backups
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
provider: azure
target: primary
retentionPolicy: 1d
azure:
connectionString: some-connection-string
asserts:
- failedTemplate:
errorMessage: CNPG Backup - You need to specify [backups.azure.storageAccount] or [backups.destinationPath]
- it: should fail with missing destinationPath and azure serviceName on backups
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
provider: azure
target: primary
retentionPolicy: 1d
azure:
connectionString: some-connection-string
storageAccount: some-storage-account
asserts:
- failedTemplate:
errorMessage: CNPG Backup - You need to specify [backups.azure.serviceName] or [backups.destinationPath]
- it: should fail with missing destinationPath and azure containerName on backups
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
provider: azure
target: primary
retentionPolicy: 1d
azure:
connectionString: some-connection-string
storageAccount: some-storage-account
serviceName: some-service-name
asserts:
- failedTemplate:
errorMessage: CNPG Backup - You need to specify [backups.azure.containerName] or [backups.destinationPath]

View File

@@ -0,0 +1,151 @@
suite: cnpg credentials test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should generate correct secret
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
asserts:
- documentIndex: &secretDoc 3
isKind:
of: Secret
- documentIndex: *secretDoc
isAPIVersion:
of: v1
- documentIndex: *secretDoc
equal:
path: type
value: kubernetes.io/basic-auth
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-user
- documentIndex: *secretDoc
equal:
path: stringData.username
value: test-user
- documentIndex: *secretDoc
matchRegex:
path: stringData.password
pattern: ^[a-zA-Z0-9]{62}$
- documentIndex: &secretDoc 2
isKind:
of: Secret
- documentIndex: *secretDoc
isAPIVersion:
of: v1
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-urls
- documentIndex: *secretDoc
isSubset:
path: stringData
content:
porthost: test-release-name-common-test-cnpg-my-pg-rw:5432
host: test-release-name-common-test-cnpg-my-pg-rw
jdbc: jdbc:postgresql://test-release-name-common-test-cnpg-my-pg-rw:5432/test-db
- documentIndex: *secretDoc
matchRegex:
path: stringData.std
pattern: postgresql://test-user:[a-zA-Z0-9]{62}@test-release-name-common-test-cnpg-my-pg-rw:5432/test-db
- documentIndex: *secretDoc
matchRegex:
path: stringData.nossl
pattern: postgresql://test-user:[a-zA-Z0-9]{62}@test-release-name-common-test-cnpg-my-pg-rw:5432/test-db\?sslmode=disable
- it: should generate correct secret with ro pooler
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
pooler:
createRO: true
asserts:
- documentIndex: &secretDoc 3
isKind:
of: Secret
- documentIndex: *secretDoc
isAPIVersion:
of: v1
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-urls
- documentIndex: *secretDoc
isSubset:
path: stringData
content:
porthost: test-release-name-common-test-cnpg-my-pg-rw:5432
host: test-release-name-common-test-cnpg-my-pg-rw
jdbc: jdbc:postgresql://test-release-name-common-test-cnpg-my-pg-rw:5432/test-db
hostRO: test-release-name-common-test-cnpg-my-pg-ro
jdbcRO: jdbc:postgresql://test-release-name-common-test-cnpg-my-pg-ro:5432/test-db
porthostRO: test-release-name-common-test-cnpg-my-pg-ro:5432
- documentIndex: *secretDoc
matchRegex:
path: stringData.std
pattern: postgresql://test-user:[a-zA-Z0-9]{62}@test-release-name-common-test-cnpg-my-pg-rw:5432/test-db
- documentIndex: *secretDoc
matchRegex:
path: stringData.nossl
pattern: postgresql://test-user:[a-zA-Z0-9]{62}@test-release-name-common-test-cnpg-my-pg-rw:5432/test-db\?sslmode=disable
- documentIndex: *secretDoc
matchRegex:
path: stringData.stdRO
pattern: postgresql://test-user:[a-zA-Z0-9]{62}@test-release-name-common-test-cnpg-my-pg-ro:5432/test-db
- documentIndex: *secretDoc
matchRegex:
path: stringData.nosslRO
pattern: postgresql://test-user:[a-zA-Z0-9]{62}@test-release-name-common-test-cnpg-my-pg-ro:5432/test-db\?sslmode=disable
- it: should generate correct secret with password set
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
password: test-password
asserts:
- documentIndex: &secretDoc 3
isKind:
of: Secret
- documentIndex: *secretDoc
isAPIVersion:
of: v1
- documentIndex: *secretDoc
equal:
path: type
value: kubernetes.io/basic-auth
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-user
- documentIndex: *secretDoc
equal:
path: stringData.username
value: test-user
- documentIndex: *secretDoc
equal:
path: stringData.password
value: test-password

View File

@@ -1,35 +0,0 @@
suite: cnpg custom conf test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should pass with custom-conf
set:
operator:
verify:
enabled: false
cnpg:
main:
enabled: true
primary: true
user: app
database: app
postgresql:
key1: value1
key2: '{{ printf "test-tpl" }}'
asserts:
- documentIndex: &clusterDoc 0
isKind:
of: Cluster
- documentIndex: *clusterDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
postgresql:
key1: value1
key2: test-tpl

View File

@@ -0,0 +1,178 @@
suite: cnpg pooler metadata test
templates:
- common.yaml
chart:
appVersion: &appVer v9.9.9
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should pass with cnpg pooler created with labels and annotations
set:
operator:
verify:
enabled: false
label1: label1
label2: global_label2
label3: label3
annotation1: annotation1
annotation2: global_annotation2
annotation3: annotation3
global:
labels:
g_label1: global_label1
g_label2: "{{ .Values.label2 }}"
annotations:
g_annotation1: global_annotation1
g_annotation2: "{{ .Values.annotation2 }}"
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
labels:
label1: "{{ .Values.label1 }}"
label2: label2
annotations:
annotation1: "{{ .Values.annotation1 }}"
annotation2: annotation2
pooler:
labels:
label3: "{{ .Values.label3 }}"
annotations:
annotation3: "{{ .Values.annotation3 }}"
asserts:
- documentIndex: &poolerDoc 0
isKind:
of: Pooler
- documentIndex: *poolerDoc
isSubset:
path: metadata.annotations
content:
annotation1: annotation1
annotation2: annotation2
annotation3: annotation3
g_annotation1: global_annotation1
g_annotation2: global_annotation2
cnpg.io/hibernation: "off"
- documentIndex: *poolerDoc
matchRegex:
path: metadata.annotations.rollme
pattern: '^[0-9a-zA-Z]{5}$'
- documentIndex: *poolerDoc
equal:
path: metadata.labels
value:
app: common-test-1.0.0
release: test-release-name
helm-revision: "0"
helm.sh/chart: common-test-1.0.0
app.kubernetes.io/name: common-test
app.kubernetes.io/instance: test-release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/version: *appVer
cnpg.io/reload: "on"
g_label1: global_label1
g_label2: global_label2
label1: label1
label2: label2
label3: label3
- documentIndex: *poolerDoc
equal:
path: metadata.namespace
value: test-release-namespace
- it: should pass with cnpg pooler created with namespace
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
namespace: some-namespace
asserts:
- documentIndex: *poolerDoc
equal:
path: metadata.namespace
value: some-namespace
- it: should pass with cnpg pooler created with object namespace from tpl
set:
operator:
verify:
enabled: false
key: some-namespace
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
namespace: "{{ .Values.key }}"
asserts:
- documentIndex: *poolerDoc
equal:
path: metadata.namespace
value: some-namespace
- it: should pass with cnpg pooler created with namespace from global with tpl
set:
operator:
verify:
enabled: false
key: global-namespace
global:
namespace: "{{ .Values.key }}"
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
asserts:
- documentIndex: *poolerDoc
equal:
path: metadata.namespace
value: global-namespace
- it: should pass with cnpg pooler created with namespace from root with tpl
set:
operator:
verify:
enabled: false
key: local-namespace
namespace: "{{ .Values.key }}"
global:
namespace: global-namespace
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
asserts:
- documentIndex: *poolerDoc
equal:
path: metadata.namespace
value: local-namespace
- it: should pass with cnpg pooler created with namespace in TrueNAS SCALE
set:
operator:
verify:
enabled: false
global:
ixChartContext:
iAmNotEmpty: true
storageClassName: some-storage-class
namespace: ix-namespace
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
asserts:
- documentIndex: *poolerDoc
equal:
path: metadata.namespace
value: ix-namespace

View File

@@ -0,0 +1,54 @@
suite: cnpg pooler name test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should generate correct name
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
my-pg2:
enabled: true
user: test-user
database: test-db
pooler:
createRO: true
asserts:
- documentIndex: &poolerDoc 0
isKind:
of: Pooler
- documentIndex: *poolerDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *poolerDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-pooler-rw
- documentIndex: &otherpoolerDoc 2
isKind:
of: Pooler
- documentIndex: *otherpoolerDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *otherpoolerDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg2-pooler-rw
- documentIndex: &otherpoolerDoc 3
isKind:
of: Pooler
- documentIndex: *otherpoolerDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *otherpoolerDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg2-pooler-ro

View File

@@ -0,0 +1,96 @@
suite: cnpg pooler spec test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should generate correct spec
set:
param: someValue
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
my-pg2:
enabled: true
user: test-user
database: test-db
pooler:
createRO: true
poolMode: transaction
instances: 1
parameters:
some: value
someOther: "{{ .Values.param }}"
asserts:
- documentIndex: &poolerDoc 0
isKind:
of: Pooler
- documentIndex: *poolerDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *poolerDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-pooler-rw
- documentIndex: *poolerDoc
equal:
path: spec
value:
cluster:
name: test-release-name-common-test-cnpg-my-pg
instances: 2
type: rw
pgbouncer:
poolMode: session
- documentIndex: &otherpoolerDoc 2
isKind:
of: Pooler
- documentIndex: *otherpoolerDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *otherpoolerDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg2-pooler-rw
- documentIndex: *otherpoolerDoc
equal:
path: spec
value:
cluster:
name: test-release-name-common-test-cnpg-my-pg2
instances: 1
type: rw
pgbouncer:
poolMode: transaction
parameters:
some: value
someOther: someValue
- documentIndex: &otherpoolerDoc 3
isKind:
of: Pooler
- documentIndex: *otherpoolerDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *otherpoolerDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg2-pooler-ro
- documentIndex: *otherpoolerDoc
equal:
path: spec
value:
cluster:
name: test-release-name-common-test-cnpg-my-pg2
instances: 1
type: ro
pgbouncer:
poolMode: transaction
parameters:
some: value
someOther: someValue

View File

@@ -0,0 +1,22 @@
suite: cnpg pooler validation test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should fail with invalid poolMode
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
pooler:
poolMode: invalid
asserts:
- failedTemplate:
errorMessage: CNPG Pooler - Expected [poolMode] to be one of [session, transaction], but got [invalid]

View File

@@ -0,0 +1,33 @@
suite: cnpg recovery configmap test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should create configmap with recovery string when forceRecovery is enabled
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
forceRecovery: true
user: test-user
database: test-db
asserts:
- documentIndex: &configMapDoc 2
isKind:
of: ConfigMap
- documentIndex: *configMapDoc
isAPIVersion:
of: v1
- documentIndex: *configMapDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-recovery-string
- documentIndex: *configMapDoc
matchRegex:
path: data.recovery-string
pattern: ^[a-zA-Z0-9]{5}$

View File

@@ -0,0 +1,254 @@
suite: cnpg scheduled backup metadata test
templates:
- common.yaml
chart:
appVersion: &appVer v9.9.9
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should pass with cnpg scheduledBackup backup created with labels and annotations
set:
operator:
verify:
enabled: false
label1: label1
label2: global_label2
label3: label3
annotation1: annotation1
annotation2: global_annotation2
annotation3: annotation3
global:
labels:
g_label1: global_label1
g_label2: "{{ .Values.label2 }}"
annotations:
g_annotation1: global_annotation1
g_annotation2: "{{ .Values.annotation2 }}"
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
labels:
label1: "{{ .Values.label1 }}"
label2: label2
annotations:
annotation1: "{{ .Values.annotation1 }}"
annotation2: annotation2
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
labels:
label5: label5
annotations:
annotation5: annotation5
scheduledBackups:
- name: daily
schedule: "0 0 * * *"
backupOwnerReference: self
labels:
label3: "{{ .Values.label3 }}"
label4: label4
annotations:
annotation3: "{{ .Values.annotation3 }}"
annotation4: annotation4
asserts:
- documentIndex: &backupDoc 0
isKind:
of: ScheduledBackup
- documentIndex: *backupDoc
equal:
path: metadata.annotations
value:
annotation1: annotation1
annotation2: annotation2
annotation3: annotation3
annotation4: annotation4
annotation5: annotation5
g_annotation1: global_annotation1
g_annotation2: global_annotation2
- documentIndex: *backupDoc
equal:
path: metadata.labels
value:
app: common-test-1.0.0
release: test-release-name
helm-revision: "0"
helm.sh/chart: common-test-1.0.0
app.kubernetes.io/name: common-test
app.kubernetes.io/instance: test-release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/version: *appVer
cnpg.io/cluster: test-release-name-common-test-cnpg-my-pg
g_label1: global_label1
g_label2: global_label2
label1: label1
label2: label2
label3: label3
label4: label4
label5: label5
- documentIndex: *backupDoc
equal:
path: metadata.namespace
value: test-release-namespace
- it: should pass with cnpg scheduledBackup backup created with namespace
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
namespace: some-namespace
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
scheduledBackups:
- name: daily
schedule: "0 0 * * *"
backupOwnerReference: self
asserts:
- documentIndex: *backupDoc
equal:
path: metadata.namespace
value: some-namespace
- it: should pass with cnpg scheduledBackup backup created with object namespace from tpl
set:
operator:
verify:
enabled: false
key: some-namespace
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
namespace: "{{ .Values.key }}"
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
scheduledBackups:
- name: daily
schedule: "0 0 * * *"
backupOwnerReference: self
asserts:
- documentIndex: *backupDoc
equal:
path: metadata.namespace
value: some-namespace
- it: should pass with cnpg scheduledBackup backup created with namespace from global with tpl
set:
operator:
verify:
enabled: false
key: global-namespace
global:
namespace: "{{ .Values.key }}"
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
scheduledBackups:
- name: daily
schedule: "0 0 * * *"
backupOwnerReference: self
asserts:
- documentIndex: *backupDoc
equal:
path: metadata.namespace
value: global-namespace
- it: should pass with cnpg scheduledBackup backup created with namespace from root with tpl
set:
operator:
verify:
enabled: false
key: local-namespace
namespace: "{{ .Values.key }}"
global:
namespace: global-namespace
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
scheduledBackups:
- name: daily
schedule: "0 0 * * *"
backupOwnerReference: self
asserts:
- documentIndex: *backupDoc
equal:
path: metadata.namespace
value: local-namespace
- it: should pass with cnpg scheduledBackup backup created with namespace in TrueNAS SCALE
set:
operator:
verify:
enabled: false
global:
ixChartContext:
iAmNotEmpty: true
storageClassName: some-storage-class
namespace: ix-namespace
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
scheduledBackups:
- name: daily
schedule: "0 0 * * *"
backupOwnerReference: self
asserts:
- documentIndex: *backupDoc
equal:
path: metadata.namespace
value: ix-namespace

View File

@@ -0,0 +1,66 @@
suite: cnpg scheduled backup name test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should generate correct name
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
scheduledBackups:
- name: daily
schedule: "0 0 * * *"
backupOwnerReference: self
my-pg2:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
scheduledBackups:
- name: weekly
schedule: "0 0 * * 0"
backupOwnerReference: self
asserts:
- documentIndex: &backupDoc 0
isKind:
of: ScheduledBackup
- documentIndex: *backupDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *backupDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-sched-backup-daily
- documentIndex: &otherbackupDoc 3
isKind:
of: ScheduledBackup
- documentIndex: *otherbackupDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *otherbackupDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg2-sched-backup-weekly

View File

@@ -0,0 +1,74 @@
suite: cnpg scheduled backup spec test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should generate correct spec
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
scheduledBackups:
- name: daily
schedule: "0 0 * * *"
suspend: true
- name: weekly
schedule: "0 0 * * 0"
immediate: true
backupOwnerReference: cluster
asserts:
- documentIndex: &cnpgDoc 0
isKind:
of: ScheduledBackup
- documentIndex: *cnpgDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *cnpgDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-sched-backup-daily
- documentIndex: *cnpgDoc
equal:
path: spec
value:
schedule: "0 0 * * *"
backupOwnerReference: none
suspend: true
immediate: false
cluster:
name: test-release-name-common-test-cnpg-my-pg
- documentIndex: &otherCnpgDoc 1
isKind:
of: ScheduledBackup
- documentIndex: *otherCnpgDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *otherCnpgDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg-sched-backup-weekly
- documentIndex: *otherCnpgDoc
equal:
path: spec
value:
schedule: "0 0 * * 0"
backupOwnerReference: cluster
suspend: false
immediate: true
cluster:
name: test-release-name-common-test-cnpg-my-pg

View File

@@ -0,0 +1,161 @@
suite: cnpg scheduled backup stop test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should pass with hibernate
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
hibernate: true
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
scheduledBackups:
- name: daily
schedule: "0 0 * * *"
suspend: false
backupOwnerReference: self
asserts:
- documentIndex: &backupDoc 0
isKind:
of: ScheduledBackup
- documentIndex: *backupDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *backupDoc
equal:
path: spec.suspend
value: true
- it: should set suspend on stopAll
set:
operator:
verify:
enabled: false
global:
stopAll: true
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
hibernate: false
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
scheduledBackups:
- name: daily
schedule: "0 0 * * *"
suspend: false
backupOwnerReference: self
asserts:
- documentIndex: &backupDoc 0
isKind:
of: ScheduledBackup
- documentIndex: *backupDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *backupDoc
equal:
path: spec.suspend
value: true
- it: should set suspend on ixChartContext - isStopped (true)
set:
operator:
verify:
enabled: false
global:
namespace: ix-something
ixChartContext:
storageClassName: some-storage-class
isStopped: true
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
hibernate: false
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
scheduledBackups:
- name: daily
schedule: "0 0 * * *"
suspend: false
backupOwnerReference: self
asserts:
- documentIndex: &backupDoc 0
isKind:
of: ScheduledBackup
- documentIndex: *backupDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *backupDoc
equal:
path: spec.suspend
value: true
- it: should not suspend on ixChartContext - isStopped (false)
set:
operator:
verify:
enabled: false
global:
namespace: ix-something
ixChartContext:
storageClassName: some-storage-class
isStopped: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
hibernate: false
backups:
enabled: true
target: primary
retentionPolicy: 10d
provider: azure
destinationPath: some-path
azure:
connectionString: some-connection-string
scheduledBackups:
- name: daily
schedule: "0 0 * * *"
backupOwnerReference: self
asserts:
- documentIndex: &backupDoc 0
isKind:
of: ScheduledBackup
- documentIndex: *backupDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *backupDoc
equal:
path: spec.suspend
value: false

View File

@@ -0,0 +1,142 @@
suite: cnpg scheduled backup validation test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should fail without name in scheduledBackups backup
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
provider: azure
azure:
connectionString: some-connection-string
scheduledBackups:
- name:
asserts:
- failedTemplate:
errorMessage: CNPG Scheduled Backup - Expected non-empty [name] in [backups.scheduledBackups] entry
- it: should fail without schedule in scheduledBackups backup
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
provider: azure
azure:
connectionString: some-connection-string
scheduledBackups:
- name: daily
asserts:
- failedTemplate:
errorMessage: CNPG Scheduled Backup - Expected non-empty [schedule] in [backups.scheduledBackups] entry
- it: should fail with invalid backupOwnerReference in scheduledBackups backup
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
provider: azure
azure:
connectionString: some-connection-string
scheduledBackups:
- name: daily
schedule: "0 0 * * *"
backupOwnerReference: invalid
asserts:
- failedTemplate:
errorMessage: CNPG Scheduled Backup - Expected [backupOwnerReference] in [backups.scheduledBackups] entry to be one of [none, self, cluster], but got [invalid]
- it: should fail with invalid name in scheduledBackups backup
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
provider: azure
azure:
connectionString: some-connection-string
scheduledBackups:
- name: _invalid
schedule: "0 0 * * *"
backupOwnerReference: self
asserts:
- failedTemplate:
errorMessage: Name [test-release-name-common-test-cnpg-my-pg-sched-backup-_invalid] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 253 characters.
- it: should fail with suspend not a bool in scheduledBackups backup
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
provider: azure
azure:
connectionString: some-connection-string
scheduledBackups:
- name: _invalid
schedule: "0 0 * * *"
backupOwnerReference: self
suspend: invalid
asserts:
- failedTemplate:
errorMessage: CNPG Scheduled Backup - Expected [suspend] in [backups.scheduledBackups] entry to be a boolean, but got [string]
- it: should fail with immediate not a bool in scheduledBackups backup
set:
operator:
verify:
enabled: false
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
backups:
enabled: true
provider: azure
azure:
connectionString: some-connection-string
scheduledBackups:
- name: _invalid
schedule: "0 0 * * *"
backupOwnerReference: self
immediate: invalid
asserts:
- failedTemplate:
errorMessage: CNPG Scheduled Backup - Expected [immediate] in [backups.scheduledBackups] entry to be a boolean, but got [string]

View File

@@ -11,15 +11,14 @@ tests:
verify:
enabled: false
cnpg:
main:
mypg:
enabled: true
primary: true
user: app
database: app
instances: 2
hibernate: true
asserts:
- documentIndex: &clusterDoc 0
- documentIndex: &clusterDoc 1
isKind:
of: Cluster
- documentIndex: *clusterDoc
@@ -30,7 +29,7 @@ tests:
path: metadata.annotations
content:
cnpg.io/hibernation: "on"
- documentIndex: &poolerDoc 1
- documentIndex: &poolerDoc 0
isKind:
of: Pooler
- documentIndex: *poolerDoc
@@ -50,15 +49,14 @@ tests:
global:
stopAll: true
cnpg:
main:
mypg:
enabled: true
primary: true
user: app
database: app
hibernate: false
instances: 2
asserts:
- documentIndex: &clusterDoc 0
- documentIndex: *clusterDoc
isKind:
of: Cluster
- documentIndex: *clusterDoc
@@ -69,7 +67,7 @@ tests:
path: metadata.annotations
content:
cnpg.io/hibernation: "on"
- documentIndex: &poolerDoc 1
- documentIndex: *poolerDoc
isKind:
of: Pooler
- documentIndex: *poolerDoc
@@ -92,15 +90,14 @@ tests:
storageClassName: some-storage-class
isStopped: true
cnpg:
main:
mypg:
enabled: true
primary: true
user: app
database: app
hibernate: false
instances: 2
asserts:
- documentIndex: &clusterDoc 0
- documentIndex: *clusterDoc
isKind:
of: Cluster
- documentIndex: *clusterDoc
@@ -111,7 +108,7 @@ tests:
path: metadata.annotations
content:
cnpg.io/hibernation: "on"
- documentIndex: &poolerDoc 1
- documentIndex: *poolerDoc
isKind:
of: Pooler
- documentIndex: *poolerDoc
@@ -134,15 +131,14 @@ tests:
storageClassName: some-storage-class
isStopped: false
cnpg:
main:
mypg:
enabled: true
primary: true
user: app
database: app
hibernate: false
instances: 2
asserts:
- documentIndex: &clusterDoc 0
- documentIndex: *clusterDoc
isKind:
of: Cluster
- documentIndex: *clusterDoc
@@ -153,7 +149,7 @@ tests:
path: metadata.annotations
content:
cnpg.io/hibernation: "off"
- documentIndex: &poolerDoc 1
- documentIndex: *poolerDoc
isKind:
of: Pooler
- documentIndex: *poolerDoc

View File

@@ -108,7 +108,7 @@ tests:
podSpec: {}
asserts:
- failedTemplate:
errorMessage: Expected <restartPolicy to be [Always] for [Deployment] but got [Never]
errorMessage: Expected [restartPolicy] to be [Always] for [Deployment] but got [Never]
- it: should fail with restartPolicy to Never on DaemonSet
set:
@@ -122,7 +122,7 @@ tests:
podSpec: {}
asserts:
- failedTemplate:
errorMessage: Expected <restartPolicy to be [Always] for [DaemonSet] but got [Never]
errorMessage: Expected [restartPolicy] to be [Always] for [DaemonSet] but got [Never]
- it: should fail with restartPolicy to Never on StatefulSet
set:
@@ -136,7 +136,7 @@ tests:
podSpec: {}
asserts:
- failedTemplate:
errorMessage: Expected <restartPolicy to be [Always] for [StatefulSet] but got [Never]
errorMessage: Expected [restartPolicy] to be [Always] for [StatefulSet] but got [Never]
- it: should fail with restartPolicy to invalid on global
set:
@@ -150,7 +150,7 @@ tests:
podSpec: {}
asserts:
- failedTemplate:
errorMessage: Expected <restartPolicy to be one of [Never, Always, OnFailure] but got [invalid]
errorMessage: Expected [restartPolicy] to be one of [Never, Always, OnFailure] but got [invalid]
- it: should fail with restartPolicy to invalid-policy on pod
set:
@@ -165,4 +165,4 @@ tests:
restartPolicy: invalid-policy
asserts:
- failedTemplate:
errorMessage: Expected <restartPolicy to be one of [Never, Always, OnFailure] but got [invalid-policy]
errorMessage: Expected [restartPolicy] to be one of [Never, Always, OnFailure] but got [invalid-policy]

View File

@@ -15,4 +15,4 @@ maintainers:
name: common
sources: null
type: library
version: 15.3.4
version: 16.0.0

View File

@@ -1,69 +0,0 @@
{{- define "tc.v1.common.class.cnpg.cluster" -}}
{{- $values := .Values.cnpg -}}
{{- if hasKey . "ObjectValues" -}}
{{- with .ObjectValues.cnpg -}}
{{- $values = . -}}
{{- end -}}
{{- end -}}
{{- $cnpgClusterName := $values.name -}}
{{- $cnpgClusterLabels := $values.labels -}}
{{- $cnpgClusterAnnotations := $values.annotations -}}
{{- $hibernation := "off" -}}
{{- if or $values.hibernate (include "tc.v1.common.lib.util.stopAll" $) -}}
{{- $hibernation = "on" -}}
{{- end }}
---
apiVersion: {{ include "tc.v1.common.capabilities.cnpg.cluster.apiVersion" $ }}
kind: Cluster
metadata:
name: {{ $cnpgClusterName }}
namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }}
{{- $labels := (mustMerge ($cnpgClusterLabels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $ | fromYaml)) }}
labels:
cnpg.io/reload: "on"
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" $labels) | trim) }}
{{- . | nindent 4 }}
{{- end }}
{{- $annotations := (mustMerge ($cnpgClusterAnnotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $ | fromYaml)) }}
annotations:
cnpg.io/hibernation: {{ $hibernation | quote }}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" $annotations) | trim) }}
{{- . | nindent 4 }}
{{- end }}
spec:
instances: {{ $values.instances | default 2 }}
bootstrap:
initdb:
database: {{ $values.database | default "app" }}
owner: {{ $values.user | default "app" }}
secret:
name: {{ $cnpgClusterName }}-user
primaryUpdateStrategy: {{ $values.primaryUpdateStrategy | default "unsupervised" }}
storage:
pvcTemplate:
{{- include "tc.v1.common.lib.storage.pvc.spec" (dict "rootCtx" $ "objectData" $values.storage) | trim | nindent 6 }}
walStorage:
pvcTemplate:
{{- include "tc.v1.common.lib.storage.pvc.spec" (dict "rootCtx" $ "objectData" $values.walStorage) | trim | nindent 6 }}
monitoring:
enablePodMonitor: {{ $values.monitoring.enablePodMonitor | default true }}
nodeMaintenanceWindow:
inProgress: false
reusePVC: true
{{- with (include "tc.v1.common.lib.container.resources" (dict "rootCtx" $ "objectData" $values) | trim) }}
resources:
{{- . | nindent 4 }}
{{- end }}
postgresql:
{{- tpl ( $values.postgresql | toYaml ) $ | nindent 4 }}
{{- end -}}

View File

@@ -1,35 +0,0 @@
{{- define "tc.v1.common.class.cnpg.pooler" -}}
{{- $values := .Values.cnpg -}}
{{- if hasKey . "ObjectValues" -}}
{{- with .ObjectValues.cnpg -}}
{{- $values = . -}}
{{- end -}}
{{- end -}}
{{- $cnpgClusterName := $values.name -}}
{{- $cnpgName := $values.cnpgName -}}
{{- $cnpgPoolerName := $values.poolerName -}}
{{- $cnpgClusterLabels := $values.labels -}}
{{- $cnpgClusterAnnotations := $values.annotations -}}
{{- $instances := $values.pooler.instances | default 2 -}}
{{- if or $values.hibernate (include "tc.v1.common.lib.util.stopAll" $) -}}
{{- $instances = 0 -}}
{{- end }}
---
apiVersion: {{ include "tc.v1.common.capabilities.cnpg.pooler.apiVersion" $ }}
kind: Pooler
metadata:
name: {{ printf "%v-%v" $cnpgClusterName $values.pooler.type }}
namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }}
spec:
cluster:
name: {{ $cnpgClusterName }}
instances: {{ $instances }}
type: {{ $values.pooler.type }}
pgbouncer:
poolMode: session
parameters:
max_client_conn: "1000"
default_pool_size: "10"
{{- end -}}

View File

@@ -0,0 +1,40 @@
{{- define "tc.v1.common.class.cnpg.backup" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{/* Naming */}}
{{- $backupName := printf "%v-backup-%v" $objectData.name $objectData.backupName -}}
{{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $backupName "length" 253) -}}
{{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "CNPG Backup") -}}
{{/* Metadata */}}
{{- $objLabels := $objectData.labels | default dict -}}
{{- $globalBackupLabels := $objectData.backups.labels | default dict -}}
{{- $backupLabels := $objectData.backupLabels | default dict -}}
{{- $backupLabels = mustMerge $backupLabels $objLabels $globalBackupLabels -}}
{{- $objAnnotations := $objectData.annotations | default dict -}}
{{- $globalBackupAnnotations := $objectData.backups.annotations | default dict -}}
{{- $backupAnnotations := $objectData.backupAnnotations | default dict -}}
{{- $backupAnnotations = mustMerge $backupAnnotations $objAnnotations $globalBackupAnnotations }}
---
apiVersion: postgresql.cnpg.io/v1
kind: Backup
metadata:
name: {{ $backupName }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "CNPG Backup") }}
labels:
cnpg.io/cluster: {{ $objectData.clusterName }}
{{- $labels := (mustMerge $backupLabels (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge $backupAnnotations (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
cluster:
name: {{ $objectData.clusterName }}
{{- end -}}

View File

@@ -0,0 +1,212 @@
{{- define "tc.v1.common.class.cnpg.cluster" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $rootCtx -}}
{{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectData.clusterName "length" 253) -}}
{{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "CNPG Cluster") -}}
{{/* Initialize variables */}}
{{- $hibernation := "off" -}}
{{- $instances := 2 -}}
{{- $mode := "standalone" -}}
{{- $enableMonitoring := false -}}
{{- $disableDefaultQueries := false -}}
{{- $customQueries := list -}}
{{- $enableSuperUser := true -}}
{{- $inProgress := false -}}
{{- $reusePVC := true -}}
{{- $preloadLibraries := list -}}
{{- $walSize := $rootCtx.Values.fallbackDefaults.vctSize -}}
{{- $size := $rootCtx.Values.fallbackDefaults.vctSize -}}
{{- $primaryUpdateStrategy := "unsupervised" -}}
{{- $primaryUpdateMethod := "switchover" -}}
{{- $logLevel := "info" -}}
{{/* Make sure keys exist before try to access any sub keys */}}
{{- if not (hasKey $objectData "cluster") -}}
{{- $_ := set $objectData "cluster" dict -}}
{{- end -}}
{{- if not (hasKey $objectData "monitoring") -}}
{{- $_ := set $objectData "monitoring" dict -}}
{{- end -}}
{{- if not (hasKey $objectData "backups") -}}
{{- $_ := set $objectData "backups" dict -}}
{{- end -}}
{{- if not (hasKey $objectData.cluster "storage") -}}
{{- $_ := set $objectData.cluster "storage" dict -}}
{{- end -}}
{{- if not (hasKey $objectData.cluster "walStorage") -}}
{{- $_ := set $objectData.cluster "walStorage" dict -}}
{{- end -}}
{{/* Metadata */}}
{{- $objLabels := $objectData.labels | default dict -}}
{{- $clusterLabels := $objectData.cluster.labels | default dict -}}
{{- $clusterLabels = mustMerge $clusterLabels $objLabels -}}
{{- $objAnnotations := $objectData.annotations | default dict -}}
{{- $clusterAnnotations := $objectData.cluster.annotations | default dict -}}
{{- $clusterAnnotations = mustMerge $clusterAnnotations $objAnnotations -}}
{{- with $objectData.cluster.instances -}}
{{- $instances = . -}}
{{- end -}}
{{/* Stop All */}}
{{- if or $objectData.hibernate (include "tc.v1.common.lib.util.stopAll" $rootCtx) -}}
{{- $hibernation = "on" -}}
{{- $instances = 0 -}}
{{- end -}}
{{/* General */}}
{{- with $objectData.mode -}}
{{- $mode = . -}}
{{- end -}}
{{- with $objectData.cluster.primaryUpdateStrategy -}}
{{- $primaryUpdateStrategy = . -}}
{{- end -}}
{{- with $objectData.cluster.primaryUpdateMethod -}}
{{- $primaryUpdateMethod = . -}}
{{- end -}}
{{- with $objectData.cluster.logLevel -}}
{{- $logLevel = . -}}
{{- end -}}
{{/* Monitoring */}}
{{- with $objectData.monitoring -}}
{{- if (kindIs "bool" .enablePodMonitor) -}}
{{- $enableMonitoring = .enablePodMonitor -}}
{{- end -}}
{{- if (kindIs "bool" .disableDefaultQueries) -}}
{{- $disableDefaultQueries = .disableDefaultQueries -}}
{{- end -}}
{{- with .customQueries -}}
{{- $customQueries = . -}}
{{- end -}}
{{- end -}}
{{/* Superuser */}}
{{- if (kindIs "bool" $objectData.cluster.enableSuperuserAccess) -}}
{{- $enableSuperUser = $objectData.cluster.enableSuperuserAccess -}}
{{- end -}}
{{/* Node Maintenance Window */}}
{{- if or $rootCtx.Values.global.ixChartContext $objectData.cluster.singleNode -}}
{{- $inProgress = true -}}
{{- $reusePVC = true -}}
{{- end -}}
{{- with $objectData.cluster.nodeMaintenanceWindow -}}
{{- if (kindIs "bool" .inProgress) -}}
{{ $inProgress = .inProgress -}}
{{- end -}}
{{- if (kindIs "bool" .reusePVC) -}}
{{ $reusePVC = .reusePVC -}}
{{- end -}}
{{- end -}}
{{/* Preload Libraries */}}
{{- if (kindIs "slice" $objectData.cluster.preloadLibraries) -}}
{{- $preloadLibraries = $objectData.cluster.preloadLibraries -}}
{{- end -}}
{{- if eq $objectData.type "timescaledb" -}}
{{- $preloadLibraries = mustAppend $preloadLibraries "timescaledb" -}}
{{- end -}}
{{/* Storage */}}
{{- with $objectData.cluster.storage.size -}}
{{- $size = . -}}
{{- end -}}
{{- with $objectData.cluster.walStorage.size -}}
{{- $walSize = . -}}
{{- end }}
---
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: {{ $objectData.clusterName }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "CNPG Cluster") }}
labels:
cnpg.io/reload: "on"
{{- $labels := (mustMerge $clusterLabels (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
{{- . | nindent 4 }}
{{- end }}
annotations:
rollme: {{ randAlphaNum 5 | quote }}
cnpg.io/hibernation: {{ $hibernation | quote }}
{{- $annotations := (mustMerge $clusterAnnotations (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
{{- . | nindent 4 }}
{{- end }}
spec:
enableSuperuserAccess: {{ $enableSuperUser }}
primaryUpdateStrategy: {{ $primaryUpdateStrategy }}
primaryUpdateMethod: {{ $primaryUpdateMethod }}
logLevel: {{ $logLevel }}
instances: {{ $instances }}
{{- if or $objectData.cluster.postgresql $preloadLibraries }}
postgresql:
{{- with $objectData.cluster.postgresql }}
parameters:
{{- range $k, $v := . }}
{{ $k }}: {{ tpl $v $rootCtx | quote }}
{{- end -}}
{{- end -}}
{{- with $preloadLibraries }}
shared_preload_libraries:
{{- range $lib := (. | uniq) }}
- {{ $lib | quote }}
{{- end -}}
{{- end -}}
{{- end }}
nodeMaintenanceWindow:
inProgress: {{ $inProgress }}
reusePVC: {{ $reusePVC }}
{{- with (include "tc.v1.common.lib.container.resources" (dict "rootCtx" $rootCtx "objectData" $objectData.cluster) | trim) }}
resources:
{{- . | nindent 4 }}
{{- end }}
storage:
pvcTemplate:
{{- $_ := set $objectData.cluster.storage "size" $size -}}
{{- include "tc.v1.common.lib.storage.pvc.spec" (dict "rootCtx" $rootCtx "objectData" $objectData.cluster.storage) | trim | nindent 6 }}
walStorage:
pvcTemplate:
{{- $_ := set $objectData.cluster.walStorage "size" $walSize -}}
{{- include "tc.v1.common.lib.storage.pvc.spec" (dict "rootCtx" $rootCtx "objectData" $objectData.cluster.walStorage) | trim | nindent 6 }}
{{- if $enableMonitoring }}
monitoring:
enablePodMonitor: {{ $enableMonitoring }}
disableDefaultQueries: {{ $disableDefaultQueries }}
{{- if $customQueries }}
customQueriesConfigMap:
{{- range $q := $customQueries }}
{{- $name := $q.name -}}
{{- $expandName := (include "tc.v1.common.lib.util.expandName" (dict
"rootCtx" $rootCtx "objectData" $q
"name" $q.name "caller" "CNPG Cluster"
"key" "monitoring.customQueries")) -}}
{{- if eq $expandName "true" -}}
{{- $name = (printf "%s-cnpg-%s-%s" $fullname $objectData.shortName $q.name) -}}
{{- end }}
- name: {{ $name }}
key: {{ $q.key | default "custom-queries" }}
{{- end -}}
{{- end -}}
{{- end }}
bootstrap:
{{- if eq $mode "standalone" -}}
{{- include "tc.v1.common.lib.cnpg.cluster.bootstrap.standalone" (dict "rootCtx" $rootCtx "objectData" $objectData) | nindent 4 -}}
{{- else if eq $mode "recovery" -}}
{{- include "tc.v1.common.lib.cnpg.cluster.bootstrap.recovery" (dict "objectData" $objectData) | nindent 4 -}}
{{- include "tc.v1.common.lib.cnpg.cluster.bootstrap.recovery.externalCluster" (dict "rootCtx" $rootCtx "objectData" $objectData) | nindent 2 -}}
{{- end -}}
{{- if $objectData.backups.enabled }}
{{- include "tc.v1.common.lib.cnpg.cluster.backup" (dict "rootCtx" $rootCtx "objectData" $objectData) | nindent 2 -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,59 @@
{{- define "tc.v1.common.class.cnpg.pooler" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{/* Naming */}}
{{- $poolerName := printf "%s-pooler-%s" $objectData.name $objectData.pooler.type -}}
{{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $poolerName "length" 253) -}}
{{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "CNPG Pooler") -}}
{{/* Metadata */}}
{{- $objLabels := $objectData.labels | default dict -}}
{{- $poolerLabels := $objectData.pooler.labels | default dict -}}
{{- $poolerLabels = mustMerge $poolerLabels $objLabels -}}
{{- $objAnnotations := $objectData.annotations | default dict -}}
{{- $poolerAnnotations := $objectData.pooler.annotations | default dict -}}
{{- $poolerAnnotations = mustMerge $poolerAnnotations $objAnnotations -}}
{{/* Stop All */}}
{{- $instances := $objectData.pooler.instances | default 2 -}}
{{- $hibernation := "off" -}}
{{- if or $objectData.hibernate (include "tc.v1.common.lib.util.stopAll" $rootCtx) -}}
{{- $instances = 0 -}}
{{- $hibernation = "on" -}}
{{- end }}
---
apiVersion: postgresql.cnpg.io/v1
kind: Pooler
metadata:
name: {{ $poolerName }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "CNPG Pooler") }}
labels:
cnpg.io/reload: "on"
{{- $labels := (mustMerge $poolerLabels (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
{{- . | nindent 4 }}
{{- end }}
annotations:
rollme: {{ randAlphaNum 5 | quote }}
cnpg.io/hibernation: {{ $hibernation | quote }}
{{- $annotations := (mustMerge $poolerAnnotations (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
{{- . | nindent 4 }}
{{- end }}
spec:
cluster:
name: {{ $objectData.clusterName }}
instances: {{ $instances }}
type: {{ $objectData.pooler.type }}
pgbouncer:
poolMode: {{ $objectData.pooler.poolMode | default "session" }}
{{/* https://cloudnative-pg.io/documentation/1.15/connection_pooling/#pgbouncer-configuration-options */}}
{{- with $objectData.pooler.parameters }}
parameters:
{{- range $key, $value := . }}
{{ $key }}: {{ tpl $value $rootCtx | quote }}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,57 @@
{{- define "tc.v1.common.class.cnpg.scheduledbackup" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{/* Naming */}}
{{- $backupName := printf "%v-sched-backup-%v" $objectData.name $objectData.backupName -}}
{{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $backupName "length" 253) -}}
{{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "CNPG Scheduled Backup") -}}
{{/* Metadata */}}
{{- $objLabels := $objectData.labels | default dict -}}
{{- $globalBackupLabels := $objectData.backups.labels | default dict -}}
{{- $backupLabels := $objectData.backupLabels | default dict -}}
{{- $backupLabels = mustMerge $backupLabels $objLabels $globalBackupLabels -}}
{{- $objAnnotations := $objectData.annotations | default dict -}}
{{- $globalBackupAnnotations := $objectData.backups.annotations | default dict -}}
{{- $backupAnnotations := $objectData.backupAnnotations | default dict -}}
{{- $backupAnnotations = mustMerge $backupAnnotations $objAnnotations $globalBackupAnnotations -}}
{{/* Data */}}
{{- $suspend := false -}}
{{- if (hasKey $objectData.schedData "suspend") -}}
{{- $suspend = $objectData.schedData.suspend -}}
{{- end -}}
{{- if or $objectData.hibernate (include "tc.v1.common.lib.util.stopAll" $rootCtx) -}}
{{- $suspend = true -}}
{{- end -}}
{{- $immediate := false -}}
{{- if (hasKey $objectData.schedData "immediate") -}}
{{- $immediate = $objectData.schedData.immediate -}}
{{- end }}
---
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
name: {{ $backupName }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "CNPG Scheduled Backup") }}
labels:
cnpg.io/cluster: {{ $objectData.clusterName }}
{{- $labels := (mustMerge $backupLabels (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge $backupAnnotations (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
schedule: {{ $objectData.schedData.schedule }}
backupOwnerReference: {{ $objectData.schedData.backupOwnerReference | default "none" }}
suspend: {{ $suspend }}
immediate: {{ $immediate }}
cluster:
name: {{ $objectData.clusterName }}
{{- end -}}

View File

@@ -32,13 +32,3 @@
{{- define "tc.v1.common.capabilities.cert-manager.certificate.apiVersion" -}}
{{- print "cert-manager.io/v1" -}}
{{- end -}}
{{/* Return the appropriate apiVersion for Cert-Manager certificates */}}
{{- define "tc.v1.common.capabilities.cnpg.cluster.apiVersion" -}}
{{- print "postgresql.cnpg.io/v1" -}}
{{- end -}}
{{/* Return the appropriate apiVersion for Cert-Manager certificates */}}
{{- define "tc.v1.common.capabilities.cnpg.pooler.apiVersion" -}}
{{- print "postgresql.cnpg.io/v1" -}}
{{- end -}}

View File

@@ -0,0 +1,20 @@
{{- define "tc.v1.common.lib.cnpg.clusterName" -}}
{{- $objectData := .objectData -}}
{{- if not $objectData.version -}}
{{- $_ := set $objectData "version" "legacy" -}}
{{- end -}}
{{- $clusterName := $objectData.name -}}
{{/* Append version to the cluster name if available */}}
{{- if ne $objectData.version "legacy" -}}
{{- $clusterName = printf "%s-%v" $objectData.name $objectData.version -}}
{{- end -}}
{{/* Append the recovery string to the cluster name if available */}}
{{- if $objectData.recValue -}}
{{- $clusterName = printf "%s-%s" $clusterName $objectData.recValue -}}
{{- end -}}
{{- $clusterName -}}
{{- end -}}

View File

@@ -0,0 +1,84 @@
{{- define "tc.v1.common.lib.cnpg.db.credentials.secrets" -}}
{{- $objectData := .objectData -}}
{{- $cnpg := .cnpg -}}
{{- $rootCtx := .rootCtx -}}
{{- $dbPass := $objectData.password -}}
{{- $creds := (dict
"std" (printf "postgresql://%v:%v@%v-rw:5432/%v" $objectData.user $dbPass $objectData.name $objectData.database)
"nossl" (printf "postgresql://%v:%v@%v-rw:5432/%v?sslmode=disable" $objectData.user $dbPass $objectData.name $objectData.database)
"porthost" (printf "%s-rw:5432" $objectData.name)
"host" (printf "%s-rw" $objectData.name)
"jdbc" (printf "jdbc:postgresql://%v-rw:5432/%v" $objectData.name $objectData.database)
) -}}
{{- $credsRO := dict -}}
{{- if $objectData.pooler.createRO -}}
{{- $credsRO = (dict
"std" (printf "postgresql://%v:%v@%v-ro:5432/%v" $objectData.user $dbPass $objectData.name $objectData.database)
"nossl" (printf "postgresql://%v:%v@%v-ro:5432/%v?sslmode=disable" $objectData.user $dbPass $objectData.name $objectData.database)
"porthost" (printf "%s-ro:5432" $objectData.name)
"host" (printf "%s-ro" $objectData.name)
"jdbc" (printf "jdbc:postgresql://%v-ro:5432/%v" $objectData.name $objectData.database)
) -}}
{{- end -}}
{{- with (include "tc.v1.common.lib.cnpg.secret.user" (dict "user" $objectData.user "pass" $dbPass) | fromYaml) -}}
{{- $_ := set $rootCtx.Values.secret (printf "cnpg-%s-user" $objectData.shortName) . -}}
{{- end -}}
{{- with (include "tc.v1.common.lib.cnpg.secret.urls" (dict "creds" $creds "credsRO" $credsRO) | fromYaml) -}}
{{- $_ := set $rootCtx.Values.secret (printf "cnpg-%s-urls" $objectData.shortName) . -}}
{{- end -}}
{{/* We need to mutate the actual (cnpg) values here not the copy */}}
{{- if not (hasKey $cnpg "creds") -}}
{{- $_ := set $cnpg "creds" dict -}}
{{- end -}}
{{- $_ := set $cnpg.creds "password" $dbPass -}}
{{- $_ := set $cnpg.creds "std" $creds.std -}}
{{- $_ := set $cnpg.creds "nossl" $creds.nossl -}}
{{- $_ := set $cnpg.creds "porthost" $creds.porthost -}}
{{- $_ := set $cnpg.creds "host" $creds.host -}}
{{- $_ := set $cnpg.creds "jdbc" $creds.jdbc -}}
{{- if $objectData.pooler.createRO -}}
{{- $_ := set $cnpg.creds "stdRO" $credsRO.std -}}
{{- $_ := set $cnpg.creds "nosslRO" $credsRO.nossl -}}
{{- $_ := set $cnpg.creds "porthostRO" $credsRO.porthost -}}
{{- $_ := set $cnpg.creds "hostRO" $credsRO.host -}}
{{- $_ := set $cnpg.creds "jdbcRO" $credsRO.jdbc -}}
{{- end -}}
{{- end -}}
{{- define "tc.v1.common.lib.cnpg.secret.urls" -}}
{{- $creds := .creds -}}
{{- $credsRO := .credsRO }}
enabled: true
data:
std: {{ $creds.std }}
nossl: {{ $creds.nossl }}
porthost: {{ $creds.porthost }}
host: {{ $creds.host }}
jdbc: {{ $creds.jdbc }}
{{- if $credsRO }}
stdRO: {{ $credsRO.std }}
nosslRO: {{ $credsRO.nossl }}
porthostRO: {{ $credsRO.porthost }}
hostRO: {{ $credsRO.host }}
jdbcRO: {{ $credsRO.jdbc }}
{{- end -}}
{{- end -}}
{{- define "tc.v1.common.lib.cnpg.secret.user" -}}
{{- $user := .user -}}
{{- $pass := .pass }}
enabled: true
type: kubernetes.io/basic-auth
data:
username: {{ $user }}
password: {{ $pass }}
{{- end -}}

View File

@@ -1,9 +1,10 @@
{{- define "tc.v1.common.lib.cnpg.metrics.pooler" -}}
{{- $poolerName := .poolerName }}
enabled: true
type: "podmonitor"
type: podmonitor
selector:
matchLabels:
cnpg.io/poolerName: {{ .poolerName }}
cnpg.io/poolerName: {{ $poolerName }}
endpoints:
- port: metrics
{{- end }}
- port: metrics
{{- end -}}

View File

@@ -0,0 +1,7 @@
{{- define "tc.v1.common.lib.cnpg.configmap.recoverystring" -}}
{{- $recoveryString := .recoveryString -}}
{{- $recoveryKey := .recoveryKey -}}
enabled: true
data:
{{ $recoveryKey }}: {{ $recoveryString }}
{{- end -}}

View File

@@ -1,14 +0,0 @@
{{- define "tc.v1.common.lib.cnpg.secret.urls" -}}
{{- $std := .std }}
{{- $nossl := .nossl }}
{{- $porthost := .porthost }}
{{- $host := .host }}
{{- $jdbc := .jdbc }}
enabled: true
data:
std: {{ $std }}
nossl: {{ $nossl }}
porthost: {{ $porthost }}
host: {{ $host }}
jdbc: {{ $jdbc }}
{{- end -}}

View File

@@ -1,9 +0,0 @@
{{- define "tc.v1.common.lib.cnpg.secret.user" -}}
{{- $dbPass := .dbPass }}
{{- $values := .values -}}
enabled: true
type: kubernetes.io/basic-auth
data:
username: {{ $values.user }}
password: {{ $dbPass }}
{{- end -}}

View File

@@ -0,0 +1,14 @@
{{- define "tc.v1.common.lib.cnpg.spawner.backups" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- range $backup := $objectData.backups.manualBackups -}}
{{- $_ := set $objectData "backupName" $backup.name -}}
{{- $_ := set $objectData "backupLabels" $backup.labels -}}
{{- $_ := set $objectData "backupAnnotations" $backup.annotations -}}
{{- include "tc.v1.common.lib.cnpg.backup.validation" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
{{- include "tc.v1.common.class.cnpg.backup" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,7 @@
{{- define "tc.v1.common.lib.cnpg.backup.validation" -}}
{{- $objectData := .objectData -}}
{{- if not $objectData.backupName -}}
{{- fail "CNPG Backup - Expected non-empty [name] in [backups.manualBackups] entry" -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,49 @@
{{- define "tc.v1.common.lib.cnpg.cluster.barmanObjectStoreConfig.azure" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $type := .type -}}
{{- $data := .data -}}
{{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $rootCtx -}}
{{- $secretName := (printf "%s-cnpg-%s-provider-%s-azure-creds" $fullname $objectData.shortName $type) -}}
{{- $endpointURL := "" -}}
{{- $destinationPath := "" -}}
{{- $k := "" -}}
{{- if eq $type "recovery" -}}
{{- $endpointURL = $objectData.recovery.endpointURL -}}
{{- $destinationPath = $objectData.recovery.destinationPath -}}
{{- $k = "recovery" -}}
{{- else if eq $type "backup" -}}
{{- $endpointURL = $objectData.backups.endpointURL -}}
{{- $destinationPath = $objectData.backups.destinationPath -}}
{{- $k = "backups" -}}
{{- end -}}
{{- if not $destinationPath -}}
{{- if not $data.storageAccount -}}
{{- fail (printf "CNPG %s - You need to specify [%s.azure.storageAccount] or [%s.destinationPath]" ($type | camelcase) $k $k) -}}
{{- end -}}
{{- if not $data.serviceName -}}
{{- fail (printf "CNPG %s - You need to specify [%s.azure.serviceName] or [%s.destinationPath]" ($type | camelcase) $k $k) -}}
{{- end -}}
{{- if not $data.containerName -}}
{{- fail (printf "CNPG %s - You need to specify [%s.azure.containerName] or [%s.destinationPath]" ($type | camelcase) $k $k) -}}
{{- end -}}
{{- $destinationPath = (printf "https://%s.%s.core.windows.net/%s/%s" $data.storageAccount $data.serviceName $data.containerName (($data.path | default "/") | trimSuffix "/")) -}}
{{- end }}
endpointURL: {{ $endpointURL }}
destinationPath: {{ $destinationPath }}
azureCredentials:
connectionString:
name: {{ $secretName }}
key: CONNECTION_STRING
storageAccount:
name: {{ $secretName }}
key: STORAGE_ACCOUNT
storageKey:
name: {{ $secretName }}
key: STORAGE_KEY
storageSasToken:
name: {{ $secretName }}
key: STORAGE_SAS_TOKEN
{{- end -}}

View File

@@ -0,0 +1,40 @@
{{- define "tc.v1.common.lib.cnpg.cluster.barmanObjectStoreConfig.google" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $type := .type -}}
{{- $data := .data -}}
{{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $rootCtx -}}
{{- $secretName := (printf "%s-cnpg-%s-provider-%s-google-creds" $fullname $objectData.shortName $type) -}}
{{- $gkeEnv := false -}}
{{- if (kindIs "bool" $data.gkeEnvionment) -}}
{{- $gkeEnv = $data.gkeEnvionment -}}
{{- end -}}
{{- $endpointURL := "" -}}
{{- $destinationPath := "" -}}
{{- $k := "" -}}
{{- if eq $type "recovery" -}}
{{- $endpointURL = $objectData.recovery.endpointURL -}}
{{- $destinationPath = $objectData.recovery.destinationPath -}}
{{- $k = "recovery" -}}
{{- else if eq $type "backup" -}}
{{- $endpointURL = $objectData.backups.endpointURL -}}
{{- $destinationPath = $objectData.backups.destinationPath -}}
{{- $k = "backups" -}}
{{- end -}}
{{- if not $destinationPath -}}
{{- if not $data.bucket -}}
{{- fail (printf "CNPG %s - You need to specify [%s.google.bucket] or [%s.destinationPath]" ($type | camelcase) $k $k) -}}
{{- end -}}
{{- $destinationPath = (printf "gs://%s/%s" $data.bucket (($data.path | default "/") | trimSuffix "/")) -}}
{{- end }}
endpointURL: {{ $endpointURL }}
destinationPath: {{ $destinationPath }}
googleCredentials:
gkeEnvironment: {{ $gkeEnv }}
applicationCredentials:
name: {{ $secretName }}
key: APPLICATION_CREDENTIALS
{{- end -}}

View File

@@ -0,0 +1,43 @@
{{- define "tc.v1.common.lib.cnpg.cluster.barmanObjectStoreConfig.s3" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $type := .type -}}
{{- $data := .data -}}
{{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $rootCtx -}}
{{- $secretName := (printf "%s-cnpg-%s-provider-%s-s3-creds" $fullname $objectData.shortName $type) -}}
{{- $endpointURL := "" -}}
{{- $destinationPath := "" -}}
{{- $k := "" -}}
{{- if eq $type "recovery" -}}
{{- $endpointURL = $objectData.recovery.endpointURL -}}
{{- $destinationPath = $objectData.recovery.destinationPath -}}
{{- $k = "recovery" -}}
{{- else if eq $type "backup" -}}
{{- $endpointURL = $objectData.backups.endpointURL -}}
{{- $destinationPath = $objectData.backups.destinationPath -}}
{{- $k = "backups" -}}
{{- end -}}
{{- if not $destinationPath -}}
{{- if not $data.bucket -}}
{{- fail (printf "CNPG %s - You need to specify [%s.s3.bucket] or [%s.destinationPath]" ($type | camelcase) $k $k) -}}
{{- end -}}
{{- $destinationPath = (printf "s3://%s/%s" $data.bucket (($data.path | default "/") | trimSuffix "/")) -}}
{{- end -}}
{{- if not $endpointURL -}}
{{- if not $data.region -}}
{{- fail (printf "CNPG %s - You need to specify [%s.s3.region] or [%s.endpointURL]" ($type | camelcase) $k $k) -}}
{{- end -}}
{{- $endpointURL = (printf "https://s3.%s.amazonaws.com" $data.region) -}}
{{- end }}
endpointURL: {{ $endpointURL }}
destinationPath: {{ $destinationPath }}
s3Credentials:
accessKeyId:
name: {{ $secretName }}
key: ACCESS_KEY_ID
secretAccessKey:
name: {{ $secretName }}
key: ACCESS_SECRET_KEY
{{- end -}}

View File

@@ -0,0 +1,19 @@
{{- define "tc.v1.common.lib.cnpg.cluster.backup" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
backup:
target: {{ $objectData.backups.target }}
retentionPolicy: {{ $objectData.backups.retentionPolicy }}
barmanObjectStore:
wal:
compression: gzip
encryption: AES256
data:
compression: gzip
encryption: AES256
jobs: {{ $objectData.backups.jobs | default 2 }}
{{- $provider := $objectData.backups.provider -}}
{{/* Fetch provider data */}}
{{- $data := (get $objectData.backups $provider) -}}
{{- include (printf "tc.v1.common.lib.cnpg.cluster.barmanObjectStoreConfig.%s" $provider) (dict "rootCtx" $rootCtx "objectData" $objectData "data" $data "type" "backup") | nindent 4 -}}
{{- end -}}

View File

@@ -0,0 +1,21 @@
{{/* Recovery Template, called when mode is recovery */}}
{{- define "tc.v1.common.lib.cnpg.cluster.bootstrap.recovery" }}
{{- $objectData := .objectData -}}
recovery:
secret:
name: {{ printf "%s-user" $objectData.clusterName }}
database: {{ $objectData.database }}
owner: {{ $objectData.user }}
{{- if eq $objectData.recovery.method "backup" }}
backup:
name: {{ $objectData.recovery.backupName }}
{{- else if eq $objectData.recovery.method "object_store" }}
source: objectStoreRecoveryCluster
{{- end -}}
{{- if $objectData.recovery.pitrTarget -}}
{{- with $objectData.recovery.pitrTarget.time }}
recoveryTarget:
targetTime: {{ . | quote }}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,16 @@
{{/* Recovery from externalClusters Template, called when mode is recovery */}}
{{- define "tc.v1.common.lib.cnpg.cluster.bootstrap.recovery.externalCluster" }}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- if eq $objectData.recovery.method "object_store" }}
externalClusters:
- name: objectStoreRecoveryCluster
barmanObjectStore:
{{- $provider := $objectData.recovery.provider -}}
{{/* Fetch provider data */}}
{{- $data := (get $objectData.recovery $provider) -}}
{{- include (printf "tc.v1.common.lib.cnpg.cluster.barmanObjectStoreConfig.%s" $provider) (dict "rootCtx" $rootCtx "objectData" $objectData "data" $data "type" "recovery") | nindent 6 -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,72 @@
{{- define "tc.v1.common.lib.cnpg.cluster.bootstrap.standalone" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $initdb := dict -}}
{{- $postInitSQL := list -}}
{{- $postInitTemplateSQL := list -}}
{{- $postInitApplicationSQL := list -}}
{{- $dataChecksums := false -}}
{{- if not (hasKey $objectData.cluster "initdb") -}}
{{- $_ := set $objectData.cluster "initdb" dict -}}
{{- end -}}
{{- if $objectData.cluster.initdb -}}
{{- $postInitApplicationSQL = $objectData.cluster.initdb.postInitApplicationSQL | default list -}}
{{- $postInitSQL = $objectData.cluster.initdb.postInitSQL | default list -}}
{{- $postInitTemplateSQL = $objectData.cluster.initdb.postInitTemplateSQL | default list -}}
{{- end -}}
{{- if (kindIs "bool" $objectData.cluster.initdb.dataChecksums) -}}
{{- $dataChecksums = $objectData.cluster.initdb.dataChecksums -}}
{{- end -}}
{{/* PostInitApplicationSQL */}}
{{- if eq $objectData.type "timescaledb" -}}
{{- $postInitApplicationSQL = concat $postInitApplicationSQL (list
"CREATE EXTENSION IF NOT EXISTS timescaledb;") -}}
{{- end -}}
{{- if eq $objectData.type "postgis" -}}
{{- $postInitApplicationSQL = concat $postInitApplicationSQL (list
"CREATE EXTENSION IF NOT EXISTS postgis;"
"CREATE EXTENSION IF NOT EXISTS postgis_topology;"
"CREATE EXTENSION IF NOT EXISTS fuzzystrmatch;"
"CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder;") -}}
{{- end }}
initdb:
secret:
name: {{ printf "%s-user" $objectData.clusterName }}
database: {{ $objectData.database }}
owner: {{ $objectData.user }}
dataChecksums: {{ $dataChecksums }}
{{- with $objectData.cluster.initdb.encoding }}
encoding: {{ . }}
{{- end -}}
{{- with $objectData.cluster.initdb.localeCollate }}
localeCollate: {{ . }}
{{- end -}}
{{- with $objectData.cluster.initdb.localeCtype }}
localeCtype: {{ . }}
{{- end -}}
{{- with $objectData.cluster.initdb.walSegmentSize }}
walSegmentSize: {{ . }}
{{- end -}}
{{- if $postInitApplicationSQL }}
postInitApplicationSQL:
{{- range $v := $postInitApplicationSQL }}
- {{ tpl $v $rootCtx | quote }}
{{- end -}}
{{- end -}}
{{- if $postInitSQL }}
postInitSQL:
{{- range $v := $postInitSQL }}
- {{ tpl $v $rootCtx | quote }}
{{- end -}}
{{- end -}}
{{- if $postInitTemplateSQL }}
postInitTemplateSQL:
{{- range $v := $postInitTemplateSQL }}
- {{ tpl $v $rootCtx | quote }}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,102 @@
{{- define "tc.v1.common.lib.cnpg.cluster.validation" -}}
{{- $objectData := .objectData -}}
{{- $requiredKeys := (list "database" "user") -}}
{{- range $key := $requiredKeys -}}
{{- if not (get $objectData $key) -}}
{{- fail (printf "CNPG - Expected a non-empty [%s] key" $key) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData "version") -}}
{{- $validVersions := (list "legacy") -}}
{{- if not (mustHas $objectData.version $validVersions) -}}
{{- fail (printf "CNPG - Expected [version] to be one of [%s], but got [%s]" (join ", " $validVersions) $objectData.version) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData "hibernate") -}}
{{- if not (kindIs "bool" $objectData.hibernate) -}}
{{- fail (printf "CNPG - Expected [hibernate] to be a boolean, but got [%s]" (kindOf $objectData.hibernate)) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData "mode") -}}
{{- $validModes := (list "standalone" "replica" "recovery") -}}
{{- if not (mustHas $objectData.mode $validModes) -}}
{{- fail (printf "CNPG Cluster - Expected [mode] to be one of [%s], but got [%s]" (join ", " $validModes) $objectData.mode) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData "type") -}}
{{- $validTypes := (list "postgresql" "postgis" "timescaledb") -}}
{{- if not (mustHas $objectData.type $validTypes) -}}
{{- fail (printf "CNPG Cluster - Expected [type] to be one of [%s], but got [%s]" (join ", " $validTypes) $objectData.type) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData "cluster") -}}
{{- if (hasKey $objectData.cluster "logLevel") -}}
{{- $validLevels := (list "error" "warning" "info" "debug" "trace") -}}
{{- if not (mustHas $objectData.cluster.logLevel $validLevels) -}}
{{- fail (printf "CNPG Cluster - Expected [cluster.logLevel] to be one of [%s], but got [%s]" (join ", " $validLevels) $objectData.cluster.logLevel) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData.cluster "primaryUpdateStrategy") -}}
{{- $validStrategies := (list "supervised" "unsupervised") -}}
{{- if not (mustHas $objectData.cluster.primaryUpdateStrategy $validStrategies) -}}
{{- fail (printf "CNPG Cluster - Expected [cluster.primaryUpdateStrategy] to be one of [%s], but got [%s]" (join ", " $validStrategies) $objectData.cluster.primaryUpdateStrategy) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData.cluster "primaryUpdateMethod") -}}
{{- $validMethods := (list "switchover" "restart") -}}
{{- if not (mustHas $objectData.cluster.primaryUpdateMethod $validMethods) -}}
{{- fail (printf "CNPG Cluster - Expected [cluster.primaryUpdateMethod] to be one of [%s], but got [%s]" (join ", " $validMethods) $objectData.cluster.primaryUpdateMethod) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData.cluster "initdb") -}}
{{- with $objectData.cluster.initdb.walSegmentSize -}}
{{- if not (mustHas (kindOf .) (list "int" "int64" "float64")) -}}
{{- fail (printf "CNPG Cluster - Expected [cluster.initdb.walSegmentSize] to be an integer, but got [%s]" (kindOf .)) -}}
{{- end -}}
{{- if or (lt (. | int) 1) (gt (. | int) 1024) -}}
{{- fail (printf "CNPG Cluster - Expected [cluster.initdb.walSegmentSize] to be between 1 and 1024, but got [%d]" (. | int)) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if eq $objectData.mode "recovery" -}}
{{- if not $objectData.recovery -}}
{{- fail "CNPG Recovery - Expected a non-empty [recovery] key" -}}
{{- end -}}
{{- $validMethods := (list "backup" "object_store" "pg_basebackup") -}}
{{- if not (mustHas $objectData.recovery.method $validMethods) -}}
{{- fail (printf "CNPG Recovery - Expected [recovery.method] to be one of [%s], but got [%s]" (join ", " $validMethods) $objectData.recovery.method) -}}
{{- end -}}
{{- if eq $objectData.recovery.method "backup" -}}
{{- if not $objectData.recovery.backupName -}}
{{- fail "CNPG Recovery - Expected a non-empty [recovery.backupName] key" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData "backups") -}}
{{- if $objectData.backups.enabled -}}
{{- $validTargets := (list "primary" "prefer-standby") -}}
{{- if not (mustHas $objectData.backups.target $validTargets) -}}
{{- fail (printf "CNPG Backup - Expected [backups.target] to be one of [%s], but got [%s]" (join ", " $validTargets) $objectData.backups.target) -}}
{{- end -}}
{{- $regexPolicy := "^[1-9][0-9]*[dwm]$" -}} {{/* Copied from upstream */}}
{{- if not (mustRegexMatch $regexPolicy $objectData.backups.retentionPolicy) -}}
{{- fail (printf "CNPG Backup - Expected [backups.retentionPolicy] to match regex [%s], got [%s]" $regexPolicy $objectData.backups.retentionPolicy) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,41 @@
{{- define "tc.v1.common.lib.cnpg.spawner.pooler" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- if not (hasKey $objectData "pooler") -}}
{{- $_ := set $objectData "pooler" dict -}}
{{- end -}}
{{- $monitoring := false -}}
{{- if (hasKey $objectData "monitoring") -}}
{{- if (kindIs "bool" $objectData.monitoring.enablePodMonitor) -}}
{{- $monitoring := $objectData.monitoring.enablePodMonitor -}}
{{- end -}}
{{- end -}}
{{- $_ := set $objectData.pooler "type" "rw" -}}
{{/* Validate Pooler */}}
{{- include "tc.v1.common.lib.cnpg.pooler.validation" (dict "objectData" $objectData) -}}
{{/* Create the RW Pooler object */}}
{{- include "tc.v1.common.class.cnpg.pooler" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
{{- if $monitoring -}} {{/* TODO: Unit tests for Pooler Metrics */}}
{{- $poolerMetrics := include "tc.v1.common.lib.cnpg.metrics.pooler" (dict "poolerName" (printf "%s-rw" $objectData.name)) | fromYaml -}}
{{- $_ := set $.Values.metrics (printf "cnpg-%s-rw" $objectData.shortName) $poolerMetrics -}}
{{- end -}}
{{- if $objectData.pooler.createRO -}}
{{- $_ := set $objectData.pooler "type" "ro" -}}
{{/* Validate Pooler */}}
{{- include "tc.v1.common.lib.cnpg.pooler.validation" (dict "objectData" $objectData) -}}
{{/* Create the RO Pooler object */}}
{{- include "tc.v1.common.class.cnpg.pooler" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
{{- if $monitoring -}} {{/* TODO: Unit tests for Pooler Metrics */}}
{{- $poolerMetrics := include "tc.v1.common.lib.cnpg.metrics.pooler" (dict "poolerName" (printf "%s-rw" $objectData.name)) | fromYaml -}}
{{- $_ := set $.Values.metrics (printf "cnpg-%s-ro" $objectData.shortName) $poolerMetrics -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,15 @@
{{- define "tc.v1.common.lib.cnpg.pooler.validation" -}}
{{- $objectData := .objectData -}}
{{- $validTypes := (list "rw" "ro") -}}
{{- if not (mustHas $objectData.pooler.type $validTypes) -}}
{{- fail (printf "CNPG Pooler - Expected [type] to be one one of [%s], but got [%s]" (join ", " $validTypes) $objectData.pooler.type) -}}
{{- end -}}
{{- $validPgModes := (list "session" "transaction") -}}
{{- if $objectData.pooler.poolMode -}}
{{- if not (mustHas $objectData.pooler.poolMode $validPgModes) -}}
{{- fail (printf "CNPG Pooler - Expected [poolMode] to be one of [%s], but got [%s]" (join ", " $validPgModes) $objectData.pooler.poolMode) -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,27 @@
{{- define "tc.v1.common.lib.cnpg.provider.azure.secret" -}}
{{- $creds := .creds }}
enabled: true
data:
CONNECTION_STRING: {{ $creds.connectionString | default "" | quote }}
STORAGE_ACCOUNT: {{ $creds.storageAccount | default "" | quote }}
STORAGE_KEY: {{ $creds.storageKey | default "" | quote }}
STORAGE_SAS_TOKEN: {{ $creds.storageSasToken | default "" | quote }}
{{- end -}}
{{- define "tc.v1.common.lib.cnpg.provider.azure.validation" -}}
{{- $creds := .creds -}}
{{- if and (not $creds.storageAccount) (not $creds.connectionString) -}}
{{- fail "CNPG Backup - Expected [backups.azure.storageAccount] OR [backups.azure.connectionString] to be defined and non-empty when provider is set to [azure]" -}}
{{- end -}}
{{- if not $creds.connectionString -}}
{{- if and (not $creds.storageKey) (not $creds.storageSasToken) -}}
{{- fail "CNPG Backup - Expected [backups.azure.storageKey] OR [backups.azure.storageSasToken] to be defined and non-empty when provider is set to [azure]" -}}
{{- end -}}
{{- if and $creds.storageKey $creds.storageSasToken -}}
{{- fail "CNPG Backup - Expected only one of [backups.azure.storageKey, backups.azure.storageSasToken] to be defined and non-empty when provider is set to [azure]" -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,14 @@
{{- define "tc.v1.common.lib.cnpg.provider.backupValidation" -}}
{{- $objectData := .objectData -}}
{{- $provider := $objectData.backups.provider -}}
{{- include "tc.v1.common.lib.cnpg.provider.validation" (dict
"objectData" $objectData
"key" "backups" "caller" "CNPG Backup"
"provider" $provider) -}}
{{- if not (get $objectData.backups $provider) -}}
{{- fail (printf "CNPG Backup - Expected [backups.%s] to be defined when [backups.provider] is set to [%s]" $provider $provider) -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,14 @@
{{- define "tc.v1.common.lib.cnpg.provider.google.secret" -}}
{{- $creds := .creds }}
enabled: true
data:
APPLICATION_CREDENTIALS: {{ $creds.applicationCredentials | default "" | quote }}
{{- end -}}
{{- define "tc.v1.common.lib.cnpg.provider.google.validation" -}}
{{- $creds := .creds -}}
{{- if not $creds.applicationCredentials -}}
{{- fail "CNPG Backup - Expected [backups.google.applicationCredentials] to be defined and non-empty when provider is set to [google]" -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,28 @@
{{- define "tc.v1.common.lib.cnpg.provider.secret.spawner" -}}
{{- $objectData := .objectData -}}
{{- $rootCtx := .rootCtx -}}
{{- $type := .type -}}
{{- if not $type -}}
{{- fail "CNPG Provider Secret Spawner - No [type] was given" -}}
{{- end -}}
{{- $provider := "" -}}
{{- $creds := dict -}}
{{- if eq $type "backup" -}}
{{- include "tc.v1.common.lib.cnpg.provider.backupValidation" (dict "objectData" $objectData) -}}
{{- $provider = $objectData.backups.provider -}}
{{/* Get the creds defined in backup.$provider */}}
{{- $creds = (get $objectData.backups $provider) -}}
{{- else if eq $type "recovery" -}}
{{- include "tc.v1.common.lib.cnpg.provider.recoveryValidation" (dict "objectData" $objectData) -}}
{{- $provider = $objectData.recovery.provider -}}
{{/* Get the creds defined in recovery.$provider */}}
{{- $creds = (get $objectData.recovery $provider) -}}
{{- end -}}
{{- include (printf "tc.v1.common.lib.cnpg.provider.%s.validation" $provider) (dict "objectData" $objectData "creds" $creds) -}}
{{- with (include (printf "tc.v1.common.lib.cnpg.provider.%s.secret" $provider) (dict "creds" $creds) | fromYaml) -}}
{{- $_ := set $rootCtx.Values.secret (printf "cnpg-%s-provider-%s-%s-creds" $objectData.shortName $type $provider) . -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,14 @@
{{- define "tc.v1.common.lib.cnpg.provider.recoveryValidation" -}}
{{- $objectData := .objectData -}}
{{- $provider := $objectData.recovery.provider -}}
{{- include "tc.v1.common.lib.cnpg.provider.validation" (dict
"objectData" $objectData
"key" "recovery" "caller" "CNPG Recovery"
"provider" $provider) -}}
{{- if not (get $objectData.recovery $provider) -}}
{{- fail (printf "CNPG Recovery - Expected [recovery.%s] to be defined when [recovery.provider] is set to [%s]" $provider $provider) -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,19 @@
{{- define "tc.v1.common.lib.cnpg.provider.s3.secret" -}}
{{- $creds := .creds }}
enabled: true
data:
ACCESS_KEY_ID: {{ $creds.accessKey | default "" | quote }}
ACCESS_SECRET_KEY: {{ $creds.secretKey | default "" | quote }}
{{- end -}}
{{- define "tc.v1.common.lib.cnpg.provider.s3.validation" -}}
{{- $creds := .creds -}}
{{- if not $creds.secretKey -}}
{{- fail "CNPG Backup - Expected [backups.s3.secretKey] to be defined and non-empty when provider is set to [s3]" -}}
{{- end -}}
{{- if not $creds.accessKey -}}
{{- fail "CNPG Backup - Expected [backups.s3.accessKey] to be defined and non-empty when provider is set to [s3]" -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,11 @@
{{- define "tc.v1.common.lib.cnpg.provider.validation" -}}
{{- $objectData := .objectData -}}
{{- $key := .key -}}
{{- $caller := .caller -}}
{{- $provider := .provider -}}
{{- $validProviders := (list "azure" "s3" "google") -}}
{{- if not (mustHas $provider $validProviders) -}}
{{- fail (printf "%s - Expected [%s.provider] to be one of [%s], but got [%s]" $caller $key (join ", " $validProviders) $provider) -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,18 @@
{{- define "tc.v1.common.lib.cnpg.spawner.scheduledBackups" -}}
{{- $objectData := .objectData -}}
{{- $rootCtx := .rootCtx -}}
{{- range $schedBackup := $objectData.backups.scheduledBackups -}}
{{- $_ := set $objectData "backupName" $schedBackup.name -}}
{{- $_ := set $objectData "backupLabels" $schedBackup.labels -}}
{{- $_ := set $objectData "backupAnnotations" $schedBackup.annotations -}}
{{/* Make a copy of the objectData */}}
{{- $newObjectData := mustDeepCopy $objectData -}}
{{/* Add the scheduled backup data */}}
{{- $_ := set $newObjectData "schedData" $schedBackup -}}
{{- include "tc.v1.common.lib.cnpg.scheduledBackup.validation" (dict "objectData" $newObjectData) }}
{{- include "tc.v1.common.class.cnpg.scheduledbackup" (dict "rootCtx" $rootCtx "objectData" $newObjectData) -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,30 @@
{{- define "tc.v1.common.lib.cnpg.scheduledBackup.validation" -}}
{{- $objectData := .objectData -}}
{{- if not $objectData.backupName -}}
{{- fail "CNPG Scheduled Backup - Expected non-empty [name] in [backups.scheduledBackups] entry" -}}
{{- end -}}
{{- if not $objectData.schedData.schedule -}}
{{- fail "CNPG Scheduled Backup - Expected non-empty [schedule] in [backups.scheduledBackups] entry" -}}
{{- end -}}
{{- if (hasKey $objectData.schedData "backupOwnerReference") -}}
{{- $validOwnerRefs := (list "none" "self" "cluster") -}}
{{- if not (mustHas $objectData.schedData.backupOwnerReference $validOwnerRefs) -}}
{{- fail (printf "CNPG Scheduled Backup - Expected [backupOwnerReference] in [backups.scheduledBackups] entry to be one of [%s], but got [%s] " (join ", " $validOwnerRefs) $objectData.schedData.backupOwnerReference) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData.schedData "immediate") -}}
{{- if not (kindIs "bool" $objectData.schedData.immediate) -}}
{{- fail (printf "CNPG Scheduled Backup - Expected [immediate] in [backups.scheduledBackups] entry to be a boolean, but got [%s]" (kindOf $objectData.schedData.immediate)) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData.schedData "suspend") -}}
{{- if not (kindIs "bool" $objectData.schedData.suspend) -}}
{{- fail (printf "CNPG Scheduled Backup - Expected [suspend] in [backups.scheduledBackups] entry to be a boolean, but got [%s]" (kindOf $objectData.schedData.suspend)) -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -22,12 +22,12 @@ objectData: The object data to be used to render the Pod.
{{- $policies := (list "Never" "Always" "OnFailure") -}}
{{- if not (mustHas $policy $policies) -}}
{{- fail (printf "Expected <restartPolicy to be one of [%s] but got [%s]" (join ", " $policies) $policy) -}}
{{- fail (printf "Expected [restartPolicy] to be one of [%s] but got [%s]" (join ", " $policies) $policy) -}}
{{- end -}}
{{- $types := (list "Deployment" "DaemonSet" "StatefulSet") -}}
{{- if and (ne "Always" $policy) (mustHas $objectData.type $types) -}}
{{- fail (printf "Expected <restartPolicy to be [Always] for [%s] but got [%s]" $objectData.type $policy) -}}
{{- fail (printf "Expected [restartPolicy] to be [Always] for [%s] but got [%s]" $objectData.type $policy) -}}
{{- end -}}
{{- $policy -}}

View File

@@ -8,7 +8,7 @@
{{- $certValues := $cert -}}
{{- $certName := $fullname -}}
{{/* set defaults */}}
{{/* set defaults */}} {{/* FIXME: the primary template does not exist */}}
{{- if and (not $certValues.nameOverride) (ne $name (include "tc.v1.common.lib.util.cert.primary" $)) -}}
{{- $_ := set $certValues "nameOverride" $name -}}
{{- end -}}

View File

@@ -1,102 +1,100 @@
{{/* Renders the cnpg objects required by the chart */}}
{{- define "tc.v1.common.spawner.cnpg" -}}
{{/* Generate named cnpges as required */}}
{{- range $name, $cnpg := $.Values.cnpg }}
{{- $enabled := false -}}
{{- if hasKey $cnpg "enabled" -}}
{{- if not (kindIs "invalid" $cnpg.enabled) -}}
{{- $enabled = $cnpg.enabled -}}
{{- else -}}
{{- fail (printf "cnpg - Expected the defined key [enabled] in [cnpg.%s] to not be empty" $name) -}}
{{- end -}}
{{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $ -}}
{{- range $name, $cnpg := $.Values.cnpg -}}
{{- $enabled := (include "tc.v1.common.lib.util.enabled" (dict
"rootCtx" $ "objectData" $cnpg
"name" $name "caller" "CNPG"
"key" "cnpg")) -}}
{{/* Create a copy */}}
{{- $objectData := mustDeepCopy $cnpg -}}
{{- $objectName := printf "%s-cnpg-%s" $fullname $name -}}
{{/* Set the name */}}
{{- $_ := set $objectData "name" $objectName -}}
{{/* Short name is the one that defined on the chart*/}}
{{- $_ := set $objectData "shortName" $name -}}
{{/* Set the cluster name */}}
{{- $_ := set $objectData "clusterName" (include "tc.v1.common.lib.cnpg.clusterName" (dict "objectData" $objectData)) -}}
{{/* Handle recovery string */}}
{{- $recoveryValue := "" -}}
{{- $recoveryKey := "recovery-string" -}}
{{- $recoveryConfigMapName := printf "cnpg-%s-%s" $objectData.shortName $recoveryKey -}}
{{/* If there are previous configmap, fetch value */}}
{{- with (lookup "v1" "ConfigMap" $.Release.Namespace $recoveryConfigMapName) -}}
{{- $recoveryValue = (index .data $recoveryKey) -}}
{{- end -}}
{{- if kindIs "string" $enabled -}}
{{- $enabled = tpl $enabled $ -}}
{{/* After tpl it becomes a string, not a bool */}}
{{- if eq $enabled "true" -}}
{{- $enabled = true -}}
{{- else if eq $enabled "false" -}}
{{- $enabled = false -}}
{{- end -}}
{{/* If forced recovery is requested... */}}
{{- if $objectData.forceRecovery -}}
{{- $recoveryValue = randAlphaNum 5 -}}
{{- end -}}
{{/* Recreate the configmap if there is a recovery value */}}
{{- if $recoveryValue -}}
{{- $_ := set $objectData "recoveryValue" $recoveryValue -}}
{{- $recConfig := include "tc.v1.common.lib.cnpg.configmap.recoverystring" (dict "recoveryString" $recoveryValue "recoveryKey" $recoveryKey) | fromYaml -}}
{{- $_ := set $.Values.configmap $recoveryConfigMapName $recConfig -}}
{{- end -}}
{{- $cnpgValues := $cnpg }}
{{- $cnpgName := include "tc.v1.common.lib.chart.names.fullname" $ }}
{{- $_ := set $cnpgValues "shortName" $name }}
{{- if eq $enabled "true" -}}
{{/* set defaults */}}
{{- $_ := set $cnpgValues "nameOverride" ( printf "cnpg-%v" $name ) }}
{{/* Handle Backups/ScheduledBackups */}}
{{- if and (hasKey $objectData "backups") $objectData.backups.enabled -}}
{{- $cnpgName := printf "%v-%v" $cnpgName $cnpgValues.nameOverride }}
{{/* Create Backups */}}
{{- include "tc.v1.common.lib.cnpg.spawner.backups" (dict "rootCtx" $ "objectData" $objectData) -}}
{{- $_ := set $cnpgValues "name" $cnpgName }}
{{/* Create ScheduledBackups */}}
{{- include "tc.v1.common.lib.cnpg.spawner.scheduledBackups" (dict "rootCtx" $ "objectData" $objectData) -}}
{{- if $enabled -}}
{{- $_ := set $ "ObjectValues" (dict "cnpg" $cnpgValues) }}
{{- include "tc.v1.common.class.cnpg.cluster" $ }}
{{/* Create secret for backup store */}}
{{- include "tc.v1.common.lib.cnpg.provider.secret.spawner" (dict "rootCtx" $ "objectData" $objectData "type" "backup") -}}
{{- end -}}
{{- $_ := set $cnpgValues.pooler "type" "rw" }}
{{- if not $cnpgValues.acceptRO }}
{{- include "tc.v1.common.class.cnpg.pooler" $ }}
{{- else }}
{{- include "tc.v1.common.class.cnpg.pooler" $ }}
{{- $_ := set $cnpgValues.pooler "type" "ro" }}
{{- include "tc.v1.common.class.cnpg.pooler" $ }}
{{- end }}
{{/* Handle Pooler(s) */}}
{{- include "tc.v1.common.lib.cnpg.spawner.pooler" (dict "rootCtx" $ "objectData" $objectData) -}}
{{- end }}
{{/* Handle Cluster */}}
{{/* Validate Cluster */}}
{{- include "tc.v1.common.lib.cnpg.cluster.validation" (dict "objectData" $objectData) -}}
{{- if and (eq $objectData.mode "recovery") (eq $objectData.recovery.method "object_store") -}}
{{/* Create secret for recovery store */}}
{{- include "tc.v1.common.lib.cnpg.provider.secret.spawner" (dict "rootCtx" $ "objectData" $objectData "type" "recovery") -}}
{{- end -}}
{{- $dbPass := "" }}
{{- $dbprevious := lookup "v1" "Secret" $.Release.Namespace ( printf "%s-user" $cnpgValues.name ) }}
{{- if or $enabled $dbprevious -}}
{{/* Inject the required secrets */}}
{{/* Create the Cluster object */}}
{{- include "tc.v1.common.class.cnpg.cluster" (dict "rootCtx" $ "objectData" $objectData) -}}
{{- if $dbprevious }}
{{- $dbPass = ( index $dbprevious.data "password" ) | b64dec }}
{{- else }}
{{- $dbPass = $cnpgValues.password | default ( randAlphaNum 62 ) }}
{{- end }}
{{/* TODO: Create configmaps for cluster.monitoring.customQueries */}}
{{- end -}}
{{- $std := ( ( printf "postgresql://%v:%v@%v-rw:5432/%v" $cnpgValues.user $dbPass $cnpgValues.name $cnpgValues.database ) | quote ) }}
{{- $nossl := ( ( printf "postgresql://%v:%v@%v-rw:5432/%v?sslmode=disable" $cnpgValues.user $dbPass $cnpgValues.name $cnpgValues.database ) | quote ) }}
{{- $porthost := ( ( printf "%s-rw:5432" $cnpgValues.name ) | quote ) }}
{{- $host := ( ( printf "%s-rw" $cnpgValues.name ) | quote ) }}
{{- $jdbc := ( ( printf "jdbc:postgresql://%v-rw:5432/%v" $cnpgValues.name $cnpgValues.database ) | quote ) }}
{{/* Fetch db pass from Secret */}}
{{- $dbPass := "" -}}
{{- with (lookup "v1" "Secret" $.Release.Namespace (printf "%s-user" $objectData.name)) -}}
{{- $dbPass = (index .data "password") | b64dec -}}
{{- end -}}
{{- $userSecret := include "tc.v1.common.lib.cnpg.secret.user" (dict "values" $cnpgValues "dbPass" $dbPass ) | fromYaml }}
{{- if $userSecret }}
{{- $_ := set $.Values.secret ( printf "cnpg-%s-user" $cnpgValues.shortName ) $userSecret }}
{{- end }}
{{/* Either enebled or if there was a dbpass fetched. Required to keep the generated password around */}}
{{- if or (eq $enabled "true") $dbPass -}}
{{/* If enabled or dbPass fetched from secret, recreate the secret */}}
{{- if not $dbPass -}}
{{/* Use provided password or fallback to generating new password */}}
{{- $dbPass = $objectData.password | default (randAlphaNum 62) -}}
{{- end -}}
{{/* Set password back to password field */}}
{{- $_ := set $objectData "password" $dbPass -}}
{{- $urlSecret := include "tc.v1.common.lib.cnpg.secret.urls" (dict "std" $std "nossl" $nossl "porthost" $porthost "host" $host "jdbc" $jdbc) | fromYaml }}
{{- if $urlSecret }}
{{- $_ := set $.Values.secret ( printf "cnpg-%s-urls" $cnpgValues.shortName ) $urlSecret }}
{{- end }}
{{/* Handle DB Credentials Secret, will also inject creds to cnpg.creds */}}
{{- include "tc.v1.common.lib.cnpg.db.credentials.secrets" (dict "rootCtx" $ "cnpg" $cnpg "objectData" $objectData) -}}
{{- end -}}
{{- $_ := set $cnpgValues.creds "password" ( $dbPass | quote ) }}
{{- $_ := set $cnpgValues.creds "std" $std }}
{{- $_ := set $cnpgValues.creds "nossl" $nossl }}
{{- $_ := set $cnpgValues.creds "porthost" $porthost }}
{{- $_ := set $cnpgValues.creds "host" $host }}
{{- $_ := set $cnpgValues.creds "jdbc" $jdbc }}
{{- if $cnpgValues.monitoring }}
{{- if $cnpgValues.monitoring.enablePodMonitor }}
{{- $poolermetrics := include "tc.v1.common.lib.cnpg.metrics.pooler" (dict "poolerName" ( printf "%s-rw" $cnpgValues.name) ) | fromYaml }}
{{- $_ := set $.Values.metrics ( printf "cnpg-%s-rw" $cnpgValues.shortName ) $poolermetrics }}
{{- if $cnpgValues.acceptRO }}
{{- $poolermetricsRO := include "tc.v1.common.lib.cnpg.metrics.pooler" (dict "poolerName" ( printf "%s-ro" $cnpgValues.name) ) | fromYaml }}
{{- $_ := set $.Values.metrics ( printf "cnpg-%s-ro" $cnpgValues.shortName ) $poolermetricsRO }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end -}}
{{- end -}}

View File

@@ -1022,9 +1022,9 @@ addons:
env: {}
##
# This section contains some-preconfig for frequently used dependencies
##
##########################################################################
# This section contains some pre-config for frequently used dependencies #
##########################################################################
cnpg:
main:
@@ -1032,46 +1032,242 @@ cnpg:
primary: true
# -- Puts the cnpg cluster in hibernation mode
hibernate: false
# -- number of instances for both postgres and pgbouncer
instances: 2
# Additional Labels and annotations for all cnpg objects
labels: {}
annotations: {}
# -- Destroys the current cluster to forge a new cluster or recovery operation
# ABSOLUTELY DESTRUCTIVE
forceRecovery: false
# Type of the CNPG database. Available types:
# * `postgresql`
# * `postgis`
# * `timescaledb`
type: postgresql
# Version of Postgresql to use, changes cluster naming scheme
# * `legacy`
# TODO: allow for selecting other versions
version: legacy
# Cluster mode of operation. Available modes:
# * `standalone` - default mode. Creates new or updates an existing CNPG cluster.
# * `replica` - Creates a replica cluster from an existing CNPG cluster. # TODO
# * `recovery` - Same as standalone but creates a cluster from a backup, object store or via pg_basebackup.
mode: standalone
# Database details
database: "app"
user: "app"
# password:
# superUserPassword:
# -- change to supervised to disable unsupervised updates
# Example of rolling update strategy:
# - unsupervised: automated update of the primary once all
# replicas have been upgraded (default)
# - supervised: requires manual supervision to perform
# the switchover of the primary
primaryUpdateStrategy: unsupervised
# -- enable to create extra pgbouncer for readonly access
acceptRO: false
# # -- storage size for the data pvc's
# # Follows the same spec as .Values.Persistence type=PVC
# storage:
# size: "256Gi"
# # -- storage size for the wal pvc's
# # Follows the same spec as .Values.Persistence type=PVC
# walStorage:
# size: "256Gi"
# -- Gets scaled to 0 if hibernation is true
pooler:
password: ""
# Database cluster configuration
cluster:
# Additional Labels and annotations for cnpg cluster
labels: {}
annotations: {}
# Number of instances
instances: 2
# set to true on single-node clusters to allow PVCs to be kept on instance restart
singleNode: false
# # -- storage size for the data pvc's
# # Follows the same spec as .Values.Persistence type=PVC
# storage:
# size: "256Gi"
# # -- storage size for the wal pvc's
# # Follows the same spec as .Values.Persistence type=PVC
# walStorage:
# size: "256Gi"
# -- Gets scaled to 0 if hibernation is true
## See .Values.resources for more info
# resources:
# 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).
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)
# Example of rolling update strategy:
# - unsupervised: automated update of the primary once all
# replicas have been upgraded (default)
# - supervised: requires manual supervision to perform
# the switchover of the primary
# -- change to supervised to disable unsupervised updates
primaryUpdateStrategy: unsupervised
# The instances' log level, one of the following values: error, warning, info (default), debug, trace
logLevel: info
# The configuration for the CA and related certificates
# See: https://cloudnative-pg.io/documentation/current/api_reference/#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: true
# Configuration of the PostgreSQL server
# See: https://cloudnative-pg.io/documentation/current/api_reference/#PostgresConfiguration
postgresql:
# 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/api_reference/#bootstrapinitdb
initdb: {}
# postInitSQL:
# - CREATE EXTENSION IF NOT EXISTS vector;
# postInitApplicationSQL:
# - CREATE EXTENSION IF NOT EXISTS someextension;
# -- set to enable prometheus metrics
monitoring:
enablePodMonitor: true
enablePodMonitor: false
disableDefaultQueries: false
customQueries: []
# - name: "pg_cache_hit_ratio"
# expandObjectName: true
# key: "custom-key" (defaults to "custom-queries")
# 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 database"
# - ratio:
# usage: GAUGE
# description: "Cache hit ratio"
# Recovery settings if the chosen mode is `recovery`.
recovery:
##
# Backup Recovery Method
# 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.
# * `object_store` - Recovers a CNPG cluster from a barman object store (PITR supported).
# * `pg_basebackup` - Recovers a CNPG cluster viaa streaming replication protocol. Useful if you want to
# migrate databases to CloudNativePG, even from outside Kubernetes. # TODO
method: backup
## Point in time recovery target. Specify one of the following:
pitrTarget:
time: "" # Time in RFC3339 format
# Name of the backup to recover from. Required if method is `backup`.
backupName: ""
# Object Store Recovery Method
clusterName: ""
# Overrides the provider specific default endpoint. Defaults to:
# S3: https://s3.<region>.amazonaws.com"
endpointURL: "" # Leave empty if using the default S3 endpoint
# Overrides the provider specific default path. Defaults to:
# S3: s3://<bucket><path>
# Azure: https://<storageAccount>.<serviceName>.core.windows.net/<clusterName><path>
# Google: gs://<bucket><path>
destinationPath: ""
provider: s3 # One of s3, azure, google
s3:
region: ""
bucket: ""
path: "/"
accessKey: ""
secretKey: ""
azure:
path: "/"
connectionString: ""
storageAccount: ""
storageKey: ""
storageSasToken: ""
containerName: ""
serviceName: blob
inheritFromAzureAD: false
google:
path: "/"
bucket: ""
gkeEnvironment: false
applicationCredentials: ""
# Database cluster backup configuration
backups:
enabled: false # You need to configure backups manually, so backups are disabled by default.
# Overrides the provider specific default endpoint. Defaults to:
# S3: https://s3.<region>.amazonaws.com"
endpointURL: "" # Leave empty if using the default S3 endpoint
# Overrides the provider specific default path. Defaults to:
# S3: s3://<bucket><path>
# Azure: https://<storageAccount>.<serviceName>.core.windows.net/<clusterName><path>
# Google: gs://<bucket><path>
destinationPath: ""
provider: s3
s3:
region: ""
bucket: ""
path: "/"
accessKey: ""
secretKey: ""
azure:
path: "/"
connectionString: ""
storageAccount: ""
storageKey: ""
storageSasToken: ""
containerName: ""
serviceName: blob
inheritFromAzureAD: false
google:
path: "/"
bucket: ""
gkeEnvironment: false
applicationCredentials: ""
scheduledBackups: []
# - name: daily-backup # Daily at midnight
# schedule: "0 0 0 * * *" # Daily at midnight
# backupOwnerReference: self
# immediate: false
# suspend: false
retentionPolicy: "30d"
# - Manual list of backups
manualBackups: []
# - name: today
# labels: {}
# annotations: {}
# - name: beforeUpgrade
# labels: {}
# annotations: {}
# Database cluster PgBouncer configuration
pooler:
# -- enable to create extra pgbouncer for readonly access
createRO: false
poolMode: session
# -- Gets scaled to 0 if hibernation is true
instances: 2
# parameters:
# max_client_conn: "1000"
# default_pool_size: "25"
labels: {}
annotations: {}
# -- contains credentials and urls output by generator
creds: {}
# -- contains postgresql settings
# ref: https://cloudnative-pg.io/documentation/1.19/postgresql_conf/#the-postgresql-section
postgresql: {}
# -- Redis dependency configuration
# @default -- See below
redis:
enabled: false
# -- can be used to make an easy accessable note which URLS to use to access the DB.
# -- can be used to make an easy accessible note which URLS to use to access the DB.
creds: {}
manifestManager:
enabled: false