Skip to content

Commit 5ea03bb

Browse files
committed
feat(cluster): add CNPG-I plugin support and ObjectStore CRD
Signed-off-by: Bernard Gütermann <bernard.gutermann@sekops.ch>
1 parent f2711f3 commit 5ea03bb

File tree

11 files changed

+227
-3
lines changed

11 files changed

+227
-3
lines changed

charts/cluster/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ refer to the [CloudNativePG Documentation](https://cloudnative-pg.io/documentati
132132
| backups.google.bucket | string | `""` | |
133133
| backups.google.gkeEnvironment | bool | `false` | |
134134
| backups.google.path | string | `"/"` | |
135+
| backups.instanceSidecarConfiguration | object | `{}` | Instance sidecar configuration for the ObjectStore CR (plugin mode only). Useful for setting env vars required by S3-compatible storage providers. See: https://cloudnative-pg.io/plugin-barman-cloud/docs/ |
135136
| backups.provider | string | `"s3"` | One of `s3`, `azure` or `google` |
136137
| backups.retentionPolicy | string | `"30d"` | Retention policy for backups |
137138
| backups.s3.accessKey | string | `""` | |
@@ -141,7 +142,7 @@ refer to the [CloudNativePG Documentation](https://cloudnative-pg.io/documentati
141142
| backups.s3.region | string | `""` | |
142143
| backups.s3.secretKey | string | `""` | |
143144
| backups.scheduledBackups[0].backupOwnerReference | string | `"self"` | Backup owner reference |
144-
| backups.scheduledBackups[0].method | string | `"barmanObjectStore"` | Backup method, can be `barmanObjectStore` (default) or `volumeSnapshot` |
145+
| backups.scheduledBackups[0].method | string | `"barmanObjectStore"` | Backup method, can be `barmanObjectStore` (default) or `volumeSnapshot`. When the barman-cloud plugin is enabled, `barmanObjectStore` is automatically upgraded to `plugin`. Use `volumeSnapshot` to bypass the plugin. |
145146
| backups.scheduledBackups[0].name | string | `"daily-backup"` | Scheduled backup name |
146147
| backups.scheduledBackups[0].schedule | string | `"0 0 0 * * *"` | Schedule in cron format |
147148
| backups.secret.create | bool | `true` | Whether to create a secret for the backup credentials |
@@ -176,6 +177,7 @@ refer to the [CloudNativePG Documentation](https://cloudnative-pg.io/documentati
176177
| cluster.monitoring.podMonitor.relabelings | list | `[]` | The list of relabelings for the PodMonitor. Applied to samples before scraping. |
177178
| cluster.monitoring.prometheusRule.enabled | bool | `true` | Whether to enable the PrometheusRule automated alerts |
178179
| cluster.monitoring.prometheusRule.excludeRules | list | `[]` | Exclude specified rules |
180+
| cluster.plugins | list | `[]` | List of CNPG-I plugins to be loaded by the cluster. |
179181
| cluster.podSecurityContext | object | `{}` | Configure the Pod Security Context. See: https://cloudnative-pg.io/documentation/preview/security/ |
180182
| cluster.postgresGID | int | `-1` | The GID of the postgres user inside the image, defaults to 26 |
181183
| cluster.postgresUID | int | `-1` | The UID of the postgres user inside the image, defaults to 26 |

charts/cluster/templates/_backup.tpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
{{- if .Values.backups.enabled }}
33
backup:
44
target: "prefer-standby"
5+
{{- if eq (include "cluster.useBarmanCloudPlugin" .) "false" }}
56
retentionPolicy: {{ .Values.backups.retentionPolicy }}
67
barmanObjectStore:
78
wal:
@@ -19,5 +20,6 @@ backup:
1920

2021
{{- $d := dict "chartFullname" (include "cluster.fullname" .) "scope" .Values.backups "secretPrefix" "backup" }}
2122
{{- include "cluster.barmanObjectStoreConfig" $d | nindent 2 }}
23+
{{- end }}
2224
{{- end }}
2325
{{- end }}

charts/cluster/templates/_external_clusters.tpl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,20 @@ externalClusters:
1010
- name: importSource
1111
{{- include "cluster.externalSourceCluster" .Values.recovery.import.source | nindent 4 }}
1212
{{- else if eq .Values.recovery.method "object_store" }}
13+
{{- if eq (include "cluster.useBarmanCloudPlugin" .) "true" }}
14+
- name: objectStoreRecoveryCluster
15+
plugin:
16+
name: {{ include "cluster.barmanCloudPluginName" . }}
17+
parameters:
18+
barmanObjectName: {{ include "cluster.barmanCloudObjectStoreName" . }}
19+
serverName: {{ .Values.recovery.clusterName | default (include "cluster.fullname" .) }}
20+
{{- else }}
1321
- name: objectStoreRecoveryCluster
1422
barmanObjectStore:
1523
serverName: {{ .Values.recovery.clusterName }}
1624
{{- $d := dict "chartFullname" (include "cluster.fullname" .) "scope" .Values.recovery "secretPrefix" "recovery" -}}
1725
{{- include "cluster.barmanObjectStoreConfig" $d | nindent 4 }}
26+
{{- end }}
1827
{{- end }}
1928
{{- else if eq .Values.mode "replica" }}
2029
- name: originCluster

charts/cluster/templates/_helpers.tpl

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,49 @@ Postgres GID
144144
{{- 26 -}}
145145
{{- end -}}
146146
{{- end -}}
147+
148+
149+
{{/*
150+
Canonical name of the barman-cloud CNPG-I plugin.
151+
*/}}
152+
{{- define "cluster.barmanCloudPluginName" -}}
153+
barman-cloud.cloudnative-pg.io
154+
{{- end -}}
155+
156+
157+
{{/*
158+
Returns true if the barman-cloud plugin is present and not explicitly disabled.
159+
*/}}
160+
{{- define "cluster.useBarmanCloudPlugin" -}}
161+
{{- $pluginName := include "cluster.barmanCloudPluginName" . }}
162+
{{- $hasPlugin := false }}
163+
{{- if .Values.cluster.plugins }}
164+
{{- range .Values.cluster.plugins }}
165+
{{- if eq .name $pluginName }}
166+
{{- if not (eq (toString (default true .enabled)) "false") }}
167+
{{- $hasPlugin = true }}
168+
{{- end }}
169+
{{- end }}
170+
{{- end }}
171+
{{- end }}
172+
{{- $hasPlugin }}
173+
{{- end }}
174+
175+
176+
{{/*
177+
ObjectStore name for the barman-cloud plugin, auto-derived or from plugin parameters.
178+
*/}}
179+
{{- define "cluster.barmanCloudObjectStoreName" -}}
180+
{{- $pluginName := include "cluster.barmanCloudPluginName" . }}
181+
{{- $name := printf "%s-object-store" (include "cluster.fullname" .) }}
182+
{{- if .Values.cluster.plugins }}
183+
{{- range .Values.cluster.plugins }}
184+
{{- if eq .name $pluginName }}
185+
{{- if and .parameters .parameters.barmanObjectName }}
186+
{{- $name = .parameters.barmanObjectName }}
187+
{{- end }}
188+
{{- end }}
189+
{{- end }}
190+
{{- end }}
191+
{{- $name }}
192+
{{- end }}

charts/cluster/templates/cluster.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,32 @@ spec:
6767
name: {{ . }}
6868
{{ end }}
6969
enablePDB: {{ .Values.cluster.enablePDB }}
70+
{{- if .Values.cluster.plugins }}
71+
plugins:
72+
{{- range .Values.cluster.plugins }}
73+
- name: {{ .name }}
74+
{{- if hasKey . "enabled" }}
75+
enabled: {{ .enabled }}
76+
{{- end }}
77+
{{- if .isWALArchiver }}
78+
isWALArchiver: {{ .isWALArchiver }}
79+
{{- end }}
80+
{{- if and (eq .name (include "cluster.barmanCloudPluginName" $)) $.Values.backups.enabled }}
81+
parameters:
82+
barmanObjectName: {{ include "cluster.barmanCloudObjectStoreName" $ }}
83+
{{- with .parameters }}
84+
{{- range $k, $v := . }}
85+
{{- if ne $k "barmanObjectName" }}
86+
{{ $k }}: {{ $v | quote }}
87+
{{- end }}
88+
{{- end }}
89+
{{- end }}
90+
{{- else if .parameters }}
91+
parameters:
92+
{{- toYaml .parameters | nindent 8 }}
93+
{{- end }}
94+
{{- end }}
95+
{{- end }}
7096
postgresql:
7197
{{- if or (eq .Values.type "timescaledb") (not (empty .Values.cluster.postgresql.shared_preload_libraries)) }}
7298
shared_preload_libraries:
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
{{- if and .Values.backups.enabled (eq (include "cluster.useBarmanCloudPlugin" .) "true") }}
2+
apiVersion: barmancloud.cnpg.io/v1
3+
kind: ObjectStore
4+
metadata:
5+
name: {{ include "cluster.barmanCloudObjectStoreName" . }}
6+
namespace: {{ include "cluster.namespace" $ }}
7+
{{- with .Values.cluster.annotations }}
8+
annotations:
9+
{{- toYaml . | nindent 4 }}
10+
{{- end }}
11+
labels:
12+
{{- include "cluster.labels" . | nindent 4 }}
13+
{{- with .Values.cluster.additionalLabels }}
14+
{{ toYaml . | nindent 4 }}
15+
{{- end }}
16+
spec:
17+
{{- with .Values.backups.instanceSidecarConfiguration }}
18+
instanceSidecarConfiguration:
19+
{{- toYaml . | nindent 4 }}
20+
{{- end }}
21+
{{- with .Values.backups.retentionPolicy }}
22+
retentionPolicy: {{ . }}
23+
{{- end }}
24+
configuration:
25+
{{- if .Values.backups.endpointURL }}
26+
endpointURL: {{ .Values.backups.endpointURL | quote }}
27+
{{- end }}
28+
{{- if or (.Values.backups.endpointCA.create) (.Values.backups.endpointCA.name) }}
29+
endpointCA:
30+
name: {{ .Values.backups.endpointCA.name }}
31+
key: {{ .Values.backups.endpointCA.key }}
32+
{{- end }}
33+
{{- if eq .Values.backups.provider "s3" }}
34+
{{- if empty .Values.backups.endpointURL }}
35+
endpointURL: "https://s3.{{ required "You need to specify S3 region if endpointURL is not specified." .Values.backups.s3.region }}.amazonaws.com"
36+
{{- end }}
37+
destinationPath: {{ default (printf "s3://%s%s" (required "You need to specify S3 bucket." .Values.backups.s3.bucket) .Values.backups.s3.path) .Values.backups.destinationPath }}
38+
{{- $secretName := coalesce .Values.backups.secret.name (printf "%s-backup-s3-creds" (include "cluster.fullname" .)) }}
39+
s3Credentials:
40+
{{- if .Values.backups.s3.inheritFromIAMRole }}
41+
inheritFromIAMRole: true
42+
{{- else }}
43+
accessKeyId:
44+
name: {{ $secretName }}
45+
key: ACCESS_KEY_ID
46+
secretAccessKey:
47+
name: {{ $secretName }}
48+
key: ACCESS_SECRET_KEY
49+
{{- end }}
50+
{{- else if eq .Values.backups.provider "azure" }}
51+
destinationPath: {{ default (printf "https://%s.%s.core.windows.net/%s%s" (required "You need to specify Azure storageAccount." .Values.backups.azure.storageAccount) .Values.backups.azure.serviceName .Values.backups.azure.containerName .Values.backups.azure.path) .Values.backups.destinationPath }}
52+
{{- $secretName := coalesce .Values.backups.secret.name (printf "%s-backup-azure-creds" (include "cluster.fullname" .)) }}
53+
azureCredentials:
54+
{{- if .Values.backups.azure.inheritFromAzureAD }}
55+
inheritFromAzureAD: true
56+
{{- else if .Values.backups.azure.connectionString }}
57+
connectionString:
58+
name: {{ $secretName }}
59+
key: AZURE_CONNECTION_STRING
60+
{{- else }}
61+
storageAccount:
62+
name: {{ $secretName }}
63+
key: AZURE_STORAGE_ACCOUNT
64+
{{- if .Values.backups.azure.storageKey }}
65+
storageKey:
66+
name: {{ $secretName }}
67+
key: AZURE_STORAGE_KEY
68+
{{- else }}
69+
storageSasToken:
70+
name: {{ $secretName }}
71+
key: AZURE_STORAGE_SAS_TOKEN
72+
{{- end }}
73+
{{- end }}
74+
{{- else if eq .Values.backups.provider "google" }}
75+
destinationPath: {{ default (printf "gs://%s%s" (required "You need to specify Google storage bucket." .Values.backups.google.bucket) .Values.backups.google.path) .Values.backups.destinationPath }}
76+
{{- $secretName := coalesce .Values.backups.secret.name (printf "%s-backup-google-creds" (include "cluster.fullname" .)) }}
77+
googleCredentials:
78+
gkeEnvironment: {{ .Values.backups.google.gkeEnvironment }}
79+
{{- if not .Values.backups.google.gkeEnvironment }}
80+
applicationCredentials:
81+
name: {{ $secretName }}
82+
key: APPLICATION_CREDENTIALS
83+
{{- end }}
84+
{{- end }}
85+
wal:
86+
compression: {{ .Values.backups.wal.compression }}
87+
{{- if .Values.backups.wal.encryption }}
88+
encryption: {{ .Values.backups.wal.encryption }}
89+
{{- end }}
90+
maxParallel: {{ .Values.backups.wal.maxParallel }}
91+
data:
92+
compression: {{ .Values.backups.data.compression }}
93+
{{- if .Values.backups.data.encryption }}
94+
encryption: {{ .Values.backups.data.encryption }}
95+
{{- end }}
96+
jobs: {{ .Values.backups.data.jobs }}
97+
{{- end }}

charts/cluster/templates/scheduled-backups.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,15 @@ metadata:
1111
spec:
1212
immediate: true
1313
schedule: {{ .schedule | quote }}
14-
method: {{ .method }}
1514
backupOwnerReference: {{ .backupOwnerReference }}
1615
cluster:
1716
name: {{ include "cluster.fullname" $context }}
17+
{{- if and (eq (include "cluster.useBarmanCloudPlugin" $context) "true") (ne (default "" .method) "volumeSnapshot") }}
18+
method: plugin
19+
pluginConfiguration:
20+
name: {{ include "cluster.barmanCloudPluginName" $context }}
21+
{{- else }}
22+
method: {{ default "barmanObjectStore" .method }}
23+
{{- end }}
1824
{{ end -}}
1925
{{ end }}

charts/cluster/test/postgresql-cluster-configuration/01-non_default_configuration_cluster-assert.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ spec:
4949
name: supersecret-secret
5050
enableSuperuserAccess: true
5151
enablePDB: false
52+
plugins:
53+
- name: cnpg-i-plugin-example.my-org.io
54+
enabled: true
55+
parameters:
56+
key1: value1
57+
key2: value2
5258
certificates:
5359
serverCASecret: ca-secret
5460
serverTLSSecret: tls-secret

charts/cluster/test/postgresql-cluster-configuration/01-non_default_configuration_cluster.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ cluster:
8787
inRoles:
8888
- pg_monitor
8989
- pg_signal_backend
90+
plugins:
91+
- name: cnpg-i-plugin-example.my-org.io
92+
enabled: true
93+
parameters:
94+
key1: value1
95+
key2: value2
9096
postgresql:
9197
ldap:
9298
server: 'openldap.default.svc.cluster.local'

charts/cluster/values.schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@
9191
}
9292
}
9393
},
94+
"instanceSidecarConfiguration": {
95+
"type": "object"
96+
},
9497
"provider": {
9598
"type": "string"
9699
},
@@ -281,6 +284,9 @@
281284
}
282285
}
283286
},
287+
"plugins": {
288+
"type": "array"
289+
},
284290
"podSecurityContext": {
285291
"type": "object"
286292
},

0 commit comments

Comments
 (0)