From 9f39ec03283bcb47eae7530dd621a1acb6f60367 Mon Sep 17 00:00:00 2001
From: Adar Nimrod <nimrod@shore.co.il>
Date: Mon, 25 Apr 2022 21:56:08 +0300
Subject: [PATCH] Backup refactor.

- Change from a single backup that's overwritten everytime to a
  multiple, dated backups.
- Save the last 30 days of backups.
- Save backups under the host's /var/backups instead of a Docker volume.
  Easier to backup.
- Add a restore script so that at least I would have some idea on how to
  restore this backup. Last thing I want to do when I need this backup
is to try and figure out how to restore it.
---
 crond/crontab      |  1 +
 docker-compose.yml |  5 +----
 slapd/Dockerfile   |  1 +
 slapd/backup       | 14 ++++++++++++--
 slapd/restore      | 25 +++++++++++++++++++++++++
 5 files changed, 40 insertions(+), 6 deletions(-)
 create mode 100755 slapd/restore

diff --git a/crond/crontab b/crond/crontab
index 6f7374e..fb2522e 100644
--- a/crond/crontab
+++ b/crond/crontab
@@ -1 +1,2 @@
 @weekly docker exec ldap_ldap_1 backup || wget --spider https://notify.shore.co.il/send?message=LDAP%20backup%20failed.
+@daily docker exec ldap_ldap_1 find /var/backups/ldap -atime +30 -delete
diff --git a/docker-compose.yml b/docker-compose.yml
index 595c91a..2886773 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -37,7 +37,7 @@ services:
     volumes:
       - _run_slapd:/run/slapd
       - ldap:/var/lib/ldap
-      - backup_ldap:/var/backups/ldap
+      - /var/backups/ldap:/var/backups/ldap
       - /var/ssl/dhparams:/var/ssl/dhparams:ro
 
   ldap-account-manager:
@@ -68,9 +68,6 @@ volumes:
   _run_slapd:
     name: run_slapd
   ldap:
-  backup_ldap:
-    labels:
-      snapshot: 'true'
 
 networks:
   default:
diff --git a/slapd/Dockerfile b/slapd/Dockerfile
index 118c59e..508aade 100644
--- a/slapd/Dockerfile
+++ b/slapd/Dockerfile
@@ -30,6 +30,7 @@ COPY --chown=root:root config.ldif /usr/share/slapd/
 COPY --chown=root:root skel.ldif /usr/share/slapd/
 COPY --chown=root:root entrypoint /usr/local/sbin/
 COPY --chown=root:root backup /usr/local/sbin/
+COPY --chown=root:root restore /usr/local/sbin/
 EXPOSE 389 636
 VOLUME [ "/var/lib/ldap" ]
 VOLUME [ "/run/slapd" ]
diff --git a/slapd/backup b/slapd/backup
index 9fe1ab2..dd6748f 100755
--- a/slapd/backup
+++ b/slapd/backup
@@ -1,11 +1,21 @@
 #!/bin/sh
 set -eux
 
+cleanup () {
+    rm -rf "$tempdir"
+}
+
 alias slapcat='slapcat -vF /var/lib/ldap/config'
 
-slapcat -n0 -l /var/backups/ldap/config.ldif
+now="$(date --utc --iso-8601=seconds)"
+trap 'cleanup' INT QUIT EXIT TERM
+tempdir="$(mktemp -d)"
+
+slapcat -n0 -l "$tempdir/config.ldif"
 
 for dn in $(ldapsearch -Y EXTERNAL -LLL -s base -b '' o namingContexts | sed -n '/namingContexts/ s/namingContexts: //gp')
 do
-    slapcat -b "$dn" -l "/var/backups/ldap/$dn.ldif"
+    slapcat -b "$dn" -l "$tempdir/$dn.ldif"
 done
+
+tar -zcf "/var/backups/ldap/$now.ldif" -C "$tempdir" .
diff --git a/slapd/restore b/slapd/restore
new file mode 100755
index 0000000..bcf29ef
--- /dev/null
+++ b/slapd/restore
@@ -0,0 +1,25 @@
+#!/bin/sh
+set -eux
+
+cleanup () {
+    rm -rf "$tempdir"
+}
+
+alias slapadd='slapadd -vF /var/lib/ldap/config'
+
+src="$1"
+
+trap 'cleanup' INT QUIT EXIT TERM
+
+tempdir="$(mktemp -d)"
+
+tar -xzf "$src" -C "$tempdir"
+
+slapadd -c -n0 -l "$tempdir/config.ldif"
+
+# shellcheck disable=SC2044
+for file in $(find "$tempdir" -type f -name '*.ldif' \! -name config.ldif -printf '%f\n')
+do
+    dn="${file%.ldif}"
+    slapadd -c -b "$dn" -l "$tempdir/$file"
+done
-- 
GitLab