diff --git a/charts/postgres-cluster/Chart.yaml b/charts/postgres-cluster/Chart.yaml index 66eb5ae..8ce4b1f 100644 --- a/charts/postgres-cluster/Chart.yaml +++ b/charts/postgres-cluster/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: postgres-cluster -version: 7.1.4 +version: 7.2.0 description: Cloudnative-pg Cluster keywords: - database diff --git a/charts/postgres-cluster/README.md b/charts/postgres-cluster/README.md index 2417dff..ea94d60 100644 --- a/charts/postgres-cluster/README.md +++ b/charts/postgres-cluster/README.md @@ -1,6 +1,6 @@ # postgres-cluster -![Version: 7.1.4](https://img.shields.io/badge/Version-7.1.4-informational?style=flat-square) ![AppVersion: v1.28.0](https://img.shields.io/badge/AppVersion-v1.28.0-informational?style=flat-square) +![Version: 7.2.0](https://img.shields.io/badge/Version-7.2.0-informational?style=flat-square) ![AppVersion: v1.28.0](https://img.shields.io/badge/AppVersion-v1.28.0-informational?style=flat-square) Cloudnative-pg Cluster @@ -59,11 +59,12 @@ Cloudnative-pg Cluster | cluster.services | object | `{}` | Customization of service definitions. Please refer to https://cloudnative-pg.io/documentation/current/service_management/ | | cluster.storage | object | `{"size":"10Gi","storageClass":""}` | Default storage size | | databases | list | `[]` | Database management configuration | +| kubernetesClusterName | string | `"cl01tl"` | Kubernetes cluster name | | mode | string | `"standalone"` | Cluster mode of operation. Available modes: * `standalone` - Default mode. Creates new or updates an existing CNPG cluster. * `recovery` - Same as standalone but creates a cluster from a backup, object store or via pg_basebackup | | nameOverride | string | `""` | Override the name of the cluster | | namespaceOverride | string | `""` | Override the namespace of the chart | | poolers | list | `[]` | List of PgBouncer poolers | -| recovery | object | `{"backup":{"backupName":"","database":"app","owner":"","pitrTarget":{"time":""}},"import":{"databases":[],"pgDumpExtraOptions":[],"pgRestoreExtraOptions":[],"postImportApplicationSQL":[],"roles":[],"schemaOnly":false,"source":{"database":"app","host":"","passwordSecret":{"create":false,"key":"password","name":"","value":""},"port":5432,"sslCertSecret":{"key":"","name":""},"sslKeySecret":{"key":"","name":""},"sslMode":"verify-full","sslRootCertSecret":{"key":"","name":""},"username":"app"},"type":"microservice"},"method":"backup","objectStore":{"clusterName":"","data":{"compression":"snappy","encryption":"","jobs":1},"database":"app","destinationPath":"","endpointCA":{"create":false,"key":"","name":""},"endpointCredentials":"","endpointURL":"https://nyc3.digitaloceanspaces.com","index":1,"name":"recovery","owner":"","pitrTarget":{"time":""},"wal":{"compression":"snappy","encryption":"","maxParallel":1}},"pgBaseBackup":{"database":"app","owner":"","secret":"","source":{"database":"app","host":"","passwordSecret":{"create":false,"key":"password","name":"","value":""},"port":5432,"sslCertSecret":{"key":"","name":""},"sslKeySecret":{"key":"","name":""},"sslMode":"disable","sslRootCertSecret":{"key":"","name":""},"username":""}}}` | Recovery settings when booting cluster from external cluster | +| recovery | object | `{"backup":{"backupName":"","database":"app","owner":"","pitrTarget":{"time":""}},"import":{"databases":[],"pgDumpExtraOptions":[],"pgRestoreExtraOptions":[],"postImportApplicationSQL":[],"roles":[],"schemaOnly":false,"source":{"database":"app","host":"","passwordSecret":{"create":false,"key":"password","name":"","value":""},"port":5432,"sslCertSecret":{"key":"","name":""},"sslKeySecret":{"key":"","name":""},"sslMode":"verify-full","sslRootCertSecret":{"key":"","name":""},"username":"app"},"type":"microservice"},"method":"backup","objectStore":{"clusterName":"","data":{"compression":"snappy","encryption":"","jobs":1},"database":"app","destinationBucket":"postgres-backups","destinationPathOverride":"","endpointCA":{"create":false,"key":"","name":""},"endpointCredentials":"","endpointCredentialsIncludeRegion":true,"endpointURL":"http://garage-main.garage:3900","externalSecret":{"credentialPath":"/garage/home-infra/postgres-backups","enabled":true},"index":1,"owner":"","pitrTarget":{"time":""},"wal":{"compression":"snappy","encryption":"","maxParallel":1}},"pgBaseBackup":{"database":"app","owner":"","secret":"","source":{"database":"app","host":"","passwordSecret":{"create":false,"key":"password","name":"","value":""},"port":5432,"sslCertSecret":{"key":"","name":""},"sslKeySecret":{"key":"","name":""},"sslMode":"disable","sslRootCertSecret":{"key":"","name":""},"username":""}}}` | Recovery settings when booting cluster from external cluster | | recovery.backup.backupName | string | `""` | Name of the backup to recover from. | | recovery.backup.database | string | `"app"` | Name of the database used by the application. Default: `app`. | | recovery.backup.owner | string | `""` | Name of the owner of the database in the instance to be used by applications. Defaults to the value of the `database` key. | @@ -87,13 +88,15 @@ Cloudnative-pg Cluster | recovery.objectStore.data.encryption | string | `""` | Whether to instruct the storage provider to encrypt data files. One of `` (use the storage container default), `AES256` or `aws:kms`. | | recovery.objectStore.data.jobs | int | `1` | Number of data files to be archived or restored in parallel. | | recovery.objectStore.database | string | `"app"` | Name of the database used by the application. Default: `app`. | -| recovery.objectStore.destinationPath | string | `""` | Overrides the provider specific default path. Defaults to: S3: s3:// Azure: https://..core.windows.net/ Google: gs:// | +| recovery.objectStore.destinationBucket | string | `"postgres-backups"` | Desitination bucket | +| recovery.objectStore.destinationPathOverride | string | `""` | Overrides the provider specific default path. Defaults to: S3: s3:// Azure: https://..core.windows.net/ Google: gs:// | | recovery.objectStore.endpointCA | object | `{"create":false,"key":"","name":""}` | Specifies a CA bundle to validate a privately signed certificate. | | recovery.objectStore.endpointCA.create | bool | `false` | Creates a secret with the given value if true, otherwise uses an existing secret. | -| recovery.objectStore.endpointCredentials | string | `""` | Specifies secret that contains S3 credentials, should contain the keys ACCESS_KEY_ID and ACCESS_SECRET_KEY | -| recovery.objectStore.endpointURL | string | `"https://nyc3.digitaloceanspaces.com"` | Overrides the provider specific default endpoint. Defaults to: S3: https://s3..amazonaws.com" Leave empty if using the default S3 endpoint | +| recovery.objectStore.endpointCredentials | string | `""` | Defaults to -recovery-secret for the existing secret | +| recovery.objectStore.endpointCredentialsIncludeRegion | bool | `true` | If the S3 endpoint require the ACCESS_REGION variable set in credentials | +| recovery.objectStore.endpointURL | string | `"http://garage-main.garage:3900"` | Overrides the provider specific default endpoint. Defaults to: S3: https://s3..amazonaws.com" Leave empty if using the default S3 endpoint | +| recovery.objectStore.externalSecret | object | `{"credentialPath":"/garage/home-infra/postgres-backups","enabled":true}` | Use generated External Secrets, credentialPath points at path in cluster store that contains the keys ACCESS_KEY_ID and ACCESS_SECRET_KEY | | recovery.objectStore.index | int | `1` | Generate external cluster name, uses: {{ .Release.Name }}-postgresql--backup-index-{{ index }} | -| recovery.objectStore.name | string | `"recovery"` | Object store backup name | | recovery.objectStore.owner | string | `""` | Name of the owner of the database in the instance to be used by applications. Defaults to the value of the `database` key. | | recovery.objectStore.pitrTarget | object | `{"time":""}` | Point in time recovery target. Specify one of the following: | | recovery.objectStore.pitrTarget.time | string | `""` | Time in RFC3339 format | diff --git a/charts/postgres-cluster/templates/_helpers.tpl b/charts/postgres-cluster/templates/_helpers.tpl index b5fa3d2..bc8c210 100644 --- a/charts/postgres-cluster/templates/_helpers.tpl +++ b/charts/postgres-cluster/templates/_helpers.tpl @@ -83,3 +83,25 @@ Generate recovery server name {{- printf "%s-backup-%s" (include "cluster.name" .) (toString .Values.recovery.objectStore.index) | trunc 63 | trimSuffix "-" -}} {{- end }} {{- end }} + +{{/* +Generate recovery destination path +*/}} +{{- define "cluster.recoveryDestinationPath" -}} + {{- if .Values.recovery.objectStore.destinationPathOverride -}} + {{- .Values.recovery.objectStore.destinationPathOverride -}} + {{- else -}} + {{- printf "s3://%s/%s/%s/%s" (.Values.recovery.objectStore.destinationBucket) (.Values.kubernetesClusterName) (include "cluster.namespace" .) (include "cluster.name" .) | trunc 63 | trimSuffix "-" -}} + {{- end }} +{{- end }} + +{{/* +Generate recovery credentials name +*/}} +{{- define "cluster.recoverySecretName" -}} + {{- if and (.Values.recovery.objectStore.endpointCredentials) (not .Values.recovery.objectStore.externalSecret.enabled) }} + {{- .Values.recovery.objectStore.endpointCredentials | trunc 63 | trimSuffix "-" }} + {{- else -}} + {{- printf "%s-recovery-secret" (include "cluster.name" .) -}} + {{- end }} +{{- end }} diff --git a/charts/postgres-cluster/templates/external-secret.yaml b/charts/postgres-cluster/templates/external-secret.yaml new file mode 100644 index 0000000..1c6312a --- /dev/null +++ b/charts/postgres-cluster/templates/external-secret.yaml @@ -0,0 +1,40 @@ +{{- if and (eq .Values.recovery.method "objectStore") (.Values.recovery.objectStore.externalSecret.enabled) }} +--- +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: {{ include "cluster.recoverySecretName" . }} + namespace: {{ include "cluster.namespace" . }} + labels: + {{- include "cluster.labels" . | nindent 4 }} + app.kubernetes.io/name: {{ include "cluster.recoverySecretName" . }} + {{- with .Values.cluster.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: ACCESS_REGION + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: {{ .Values.recovery.objectStore.externalSecret.credentialPath | required "External Secret Credential local path is required" }} + metadataPolicy: None + property: ACCESS_REGION + - secretKey: ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: {{ .Values.recovery.objectStore.externalSecret.credentialPath | required "External Secret Credential local path is required" }} + metadataPolicy: None + property: ACCESS_KEY_ID + - secretKey: ACCESS_SECRET_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: {{ .Values.recovery.objectStore.externalSecret.credentialPath | required "External Secret Credential local path is required" }} + metadataPolicy: None + property: ACCESS_SECRET_KEY +{{- end }} diff --git a/charts/postgres-cluster/templates/object-store.yaml b/charts/postgres-cluster/templates/object-store.yaml index 98be893..3ca034d 100644 --- a/charts/postgres-cluster/templates/object-store.yaml +++ b/charts/postgres-cluster/templates/object-store.yaml @@ -9,6 +9,10 @@ metadata: namespace: {{ include "cluster.namespace" $context }} labels: {{- include "cluster.labels" $context | nindent 4 }} + app.kubernetes.io/name: "{{ include "cluster.name" $context }}-{{ .name }}-backup" + {{- with .Values.cluster.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} spec: retentionPolicy: {{ .retentionPolicy | default "30d" }} configuration: @@ -55,13 +59,17 @@ spec: apiVersion: barmancloud.cnpg.io/v1 kind: ObjectStore metadata: - name: "{{ include "cluster.name" . }}-{{ .Values.recovery.objectStore.name }}" + name: "{{ include "cluster.name" . }}-recovery" namespace: {{ include "cluster.namespace" . }} labels: {{- include "cluster.labels" . | nindent 4 }} + app.kubernetes.io/name: "{{ include "cluster.name" . }}-recovery" + {{- with .Values.cluster.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} spec: configuration: - destinationPath: {{ .Values.recovery.objectStore.destinationPath }} + destinationPath: {{ include "cluster.recoveryDestinationPath" . }} endpointURL: {{ .Values.recovery.objectStore.endpointURL }} {{- if .Values.recovery.objectStore.endpointCA.name }} endpointCA: @@ -82,9 +90,14 @@ spec: jobs: {{ .Values.recovery.objectStore.data.jobs }} s3Credentials: accessKeyId: - name: {{ .Values.recovery.objectStore.endpointCredentials | default (printf "%s-cluster-backup-secret" (include "cluster.name" .) | trunc 63 | trimSuffix "-") }} + name: {{ include "cluster.recoverySecretName" . }} key: ACCESS_KEY_ID secretAccessKey: - name: {{ .Values.recovery.objectStore.endpointCredentials | default (printf "%s-cluster-backup-secret" (include "cluster.name" .) | trunc 63 | trimSuffix "-") }} + name: {{ include "cluster.recoverySecretName" . }} key: ACCESS_SECRET_KEY + {{- if .Values.recovery.objectStore.endpointCredentialsIncludeRegion }} + region: + name: {{ include "cluster.recoverySecretName" . }} + key: ACCESS_REGION + {{- end }} {{ end }} diff --git a/charts/postgres-cluster/values.yaml b/charts/postgres-cluster/values.yaml index 8b925cb..d18e366 100644 --- a/charts/postgres-cluster/values.yaml +++ b/charts/postgres-cluster/values.yaml @@ -4,6 +4,9 @@ nameOverride: "" # -- Override the namespace of the chart namespaceOverride: "" +# -- Kubernetes cluster name +kubernetesClusterName: cl01tl + # -- Type of the CNPG database. Available types: # * `postgresql` type: postgresql @@ -259,19 +262,19 @@ recovery: # -- Name of the owner of the database in the instance to be used by applications. Defaults to the value of the `database` key. owner: "" - # -- Object store backup name - name: recovery + # -- Desitination bucket + destinationBucket: postgres-backups # -- Overrides the provider specific default path. Defaults to: # S3: s3:// # Azure: https://..core.windows.net/ # Google: gs:// - destinationPath: "" + destinationPathOverride: "" # -- Overrides the provider specific default endpoint. Defaults to: # S3: https://s3..amazonaws.com" # Leave empty if using the default S3 endpoint - endpointURL: "https://nyc3.digitaloceanspaces.com" + endpointURL: "http://garage-main.garage:3900" # -- Specifies a CA bundle to validate a privately signed certificate. endpointCA: @@ -287,9 +290,18 @@ recovery: # -- Override the name of the backup cluster, defaults to "cluster.name" clusterName: "" + # -- Use generated External Secrets, credentialPath points at path in cluster store that contains the keys ACCESS_KEY_ID and ACCESS_SECRET_KEY + externalSecret: + enabled: true + credentialPath: /garage/home-infra/postgres-backups + # -- Specifies secret that contains S3 credentials, should contain the keys ACCESS_KEY_ID and ACCESS_SECRET_KEY + # -- Defaults to -recovery-secret for the existing secret endpointCredentials: "" + # -- If the S3 endpoint require the ACCESS_REGION variable set in credentials + endpointCredentialsIncludeRegion: true + # -- Storage wal: