Skip to content

Commit d24e57b

Browse files
feat(kargo): add cronjob to backup restore mongodb database
1 parent 36465af commit d24e57b

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed

charts/kargo/templates/_db-backup.tpl

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,3 +754,152 @@ spec:
754754
secret:
755755
secretName: {{ $rcloneSecret }}
756756
{{- end -}}
757+
758+
{{/*
759+
Builds a cronjob to backup and another to restore the specified mongodb database.
760+
The restore cronjob is suspended to be started manually.
761+
@param .context The caller's root scope
762+
@param .args The parameters for the backup cronjob. The template expects the following:
763+
- image The image to use to pull mongodump & mongorestore
764+
- host The host where the dabatabase is running
765+
- username The database username to use to perform the dump
766+
- password The username password
767+
- database The database to dump
768+
- remotePath The folder where the backup will be transfered (the filename is generated).
769+
- rcloneSecret The name of the secret where rclone.conf can be found
770+
- backupCron The schedule expression "0 * * * *"
771+
- restoreTimestamp The timestamp to use as restore archive
772+
*/}}
773+
{{- define "kargo.mongodb-backup-restore-db-cronjobs" -}}
774+
{{- $remotePath := include "kargo.tplvalues.render" (dict "value" .args.remotePath "context" .context) }}
775+
{{- $rcloneSecret := include "kargo.tplvalues.render" (dict "value" .args.rcloneSecret "context" .context) }}
776+
{{- $dbSecret := print "backup-restore-" .args.database }}
777+
{{- $restoreFile := print .args.database "-" .args.restoreTimestamp ".gz" }}
778+
apiVersion: v1
779+
kind: Secret
780+
metadata:
781+
name: {{ $dbSecret }}
782+
namespace: {{ .context.Release.Namespace }}
783+
type: Opaque
784+
stringData:
785+
mongo-config.yml: |-
786+
password: {{ .args.password | default "" }}
787+
uri: mongodb://{{ if hasKey .args "username" }}{{ .args.username }}@{{ end }}{{ .args.host }}/{{ .args.database }}
788+
---
789+
apiVersion: {{ .context.Capabilities.APIVersions.Has "batch/v1" | ternary "batch/v1" "batch/v1beta1" }}
790+
kind: CronJob
791+
metadata:
792+
name: backup-{{ .args.database }}-db
793+
namespace: {{ .context.Release.Namespace | quote }}
794+
spec:
795+
schedule: "{{ .args.backupCron }}"
796+
concurrencyPolicy: Forbid
797+
jobTemplate:
798+
spec:
799+
ttlSecondsAfterFinished: 3600
800+
template:
801+
spec:
802+
restartPolicy: Never
803+
initContainers:
804+
- name: db-dump
805+
image: {{ .args.image }}
806+
command:
807+
- /bin/sh
808+
args:
809+
- -c
810+
- >-
811+
TIMESTAMP=$(date +%Y%m%d-%H%M) &&
812+
BACKUP_FILE={{ .args.database }}-$TIMESTAMP.gz &&
813+
echo "Dumping {{ .args.database }} to $BACKUP_FILE ..." &&
814+
mongodump --config=/mongo-config.yml --gzip --archive=/backup/$BACKUP_FILE
815+
volumeMounts:
816+
- mountPath: /mongo-config.yml
817+
name: db-secret
818+
subPath: mongo-config.yml
819+
readOnly: true
820+
- mountPath: /backup
821+
name: db-dump-temp
822+
containers:
823+
- name: rclone-dump
824+
image: rclone/rclone
825+
command:
826+
- /bin/sh
827+
args:
828+
- -c
829+
- rclone copy /backup {{ $remotePath }} --progress --include "{{ .args.database }}-*.gz"
830+
volumeMounts:
831+
- mountPath: /backup
832+
name: db-dump-temp
833+
readOnly: true
834+
- mountPath: /config/rclone/rclone.conf
835+
name: rclone-config
836+
subPath: rclone.conf
837+
readOnly: true
838+
volumes:
839+
- name: db-dump-temp
840+
emptyDir: {}
841+
- name: db-secret
842+
secret:
843+
secretName: {{ $dbSecret }}
844+
- name: rclone-config
845+
secret:
846+
secretName: {{ $rcloneSecret }}
847+
---
848+
apiVersion: {{ .context.Capabilities.APIVersions.Has "batch/v1" | ternary "batch/v1" "batch/v1beta1" }}
849+
kind: CronJob
850+
metadata:
851+
name: restore-{{ .args.database }}-db
852+
namespace: {{ .context.Release.Namespace | quote }}
853+
spec:
854+
suspend: true
855+
schedule: "* * * * *"
856+
concurrencyPolicy: Forbid
857+
jobTemplate:
858+
spec:
859+
ttlSecondsAfterFinished: 3600
860+
template:
861+
spec:
862+
restartPolicy: Never
863+
initContainers:
864+
- name: rclone-dump
865+
image: rclone/rclone
866+
command:
867+
- /bin/sh
868+
args:
869+
- -c
870+
- rclone copy {{ $remotePath }}/{{ $restoreFile }} /restore --progress
871+
volumeMounts:
872+
- mountPath: /restore
873+
name: db-dump-temp
874+
- mountPath: /config/rclone/rclone.conf
875+
name: rclone-config
876+
subPath: rclone.conf
877+
readOnly: true
878+
containers:
879+
- name: db-restore
880+
image: {{ .args.image }}
881+
command:
882+
- /bin/sh
883+
args:
884+
- -c
885+
- >-
886+
echo "Restoring from {{ $restoreFile }} ..." &&
887+
mongorestore --drop --config=/mongo-config.yml --nsInclude="*" --gzip --archive=/restore/{{ $restoreFile }}
888+
volumeMounts:
889+
- mountPath: /mongo-config.yml
890+
name: db-secret
891+
subPath: mongo-config.yml
892+
readOnly: true
893+
- mountPath: /restore
894+
name: db-dump-temp
895+
readOnly: true
896+
volumes:
897+
- name: db-dump-temp
898+
emptyDir: {}
899+
- name: db-secret
900+
secret:
901+
secretName: {{ $dbSecret }}
902+
- name: rclone-config
903+
secret:
904+
secretName: {{ $rcloneSecret }}
905+
{{- end -}}

0 commit comments

Comments
 (0)