From fd0ff2880da8c2f7d26b63a5c744f3a96639a714 Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Mon, 13 Jan 2025 16:04:12 +0100
Subject: [PATCH] infra work

---
 doc/BackupAndRestore.md                       | 68 ++++++++++++++-----
 infrastructure/backup/image/Dockerfile        |  3 +-
 .../backup/image/resources/backup.bb          | 33 +++------
 .../backup/image/resources/bb-backup.edn      |  1 +
 infrastructure/backup/image/resources/bb.edn  |  2 +-
 .../backup/image/resources/change-password.bb | 24 +++++++
 .../backup/image/resources/install.bb         |  3 +
 .../backup/image/resources/list-snapshots.bb  | 18 ++---
 .../backup/image/resources/restore.bb         | 32 ++++-----
 infrastructure/backup/image/resources/wait.bb | 18 ++---
 infrastructure/backup/test/Dockerfile         |  2 +-
 infrastructure/backup/test/resources/bb.edn   |  1 +
 .../backup/test/resources/file_password       |  1 +
 .../backup/test/resources/new_file_password   |  1 +
 infrastructure/backup/test/resources/test.bb  | 63 +++++++++--------
 15 files changed, 150 insertions(+), 120 deletions(-)
 create mode 100755 infrastructure/backup/image/resources/change-password.bb
 create mode 100644 infrastructure/backup/test/resources/file_password
 create mode 100644 infrastructure/backup/test/resources/new_file_password

diff --git a/doc/BackupAndRestore.md b/doc/BackupAndRestore.md
index 50b9658..62d91b4 100644
--- a/doc/BackupAndRestore.md
+++ b/doc/BackupAndRestore.md
@@ -7,35 +7,67 @@
 * Forgejo stores files in `/data/gitea` and `/data/git/repositories`, these files are backed up. 
 * The postgres db is also backed up
 
-## Manual init the restic repository for the first time
+## Manual backup
 
-1. apply backup-and-restore pod:   
-   `kubectl -n forgejo scale deployment backup-restore --replicas=1`
-2. exec into pod and execute restore pod (press tab to get your exact pod name)   
-   `kubectl -n forgejo exec -it backup-restore-... -- /usr/local/bin/init.bb`
-3. remove backup-and-restore pod:   
-   `kubectl -n forgejo scale deployment backup-restore --replicas=0`
-
-
-## Manual backup the restic repository for the first time
-
-1. apply backup-and-restore pod:   
+1. Scale down forgejo deployment:   
+   `kubectl -n forgejo scale deployment forgejo --replicas=0`
+2. apply backup-and-restore pod:   
   `kubectl -n forgejo scale deployment backup-restore --replicas=1`
-2. exec into pod and execute backup pod (press tab to get your exact pod name)   
+3. exec into pod and execute backup pod (press tab to get your exact pod name)   
    `kubectl -n forgejo exec -it backup-restore-... -- /usr/local/bin/backup.bb`
-3. remove backup-and-restore pod:   
+4. remove backup-and-restore pod:   
    `kubectl -n forgejo scale deployment backup-restore --replicas=0`
-
+5. Scale up forgejo deployment:   
+   `kubectl -n forgejo scale deployment forgejo --replicas=1`
 
 ## Manual restore
 
-1. apply backup-and-restore pod:   
-  `kubectl -n forgejo scale deployment backup-restore --replicas=1`
-2. Scale down forgejo deployment:
+1. Scale down forgejo deployment:
    `kubectl -n forgejo scale deployment forgejo --replicas=0`
+2. apply backup-and-restore pod:   
+  `kubectl -n forgejo scale deployment backup-restore --replicas=1`
 3. exec into pod and execute restore pod (press tab to get your exact pod name)   
    `kubectl -n forgejo exec -it backup-restore-... -- /usr/local/bin/restore.bb`
 4. Start forgejo again:
    `kubectl -n forgejo scale deployment forgejo --replicas=1`
 5. remove backup-and-restore pod:   
    `kubectl -n forgejo scale deployment backup-restore --replicas=0`
+
+## Change Password
+
+1. Check restic-new-password env is set in backup deployment   
+   ```
+   kind: Deployment
+   metadata:
+     name: backup-restore
+   spec:
+       spec:
+         containers:
+         - name: backup-app
+           env:
+           - name: RESTIC_NEW_PASSWORD_FILE
+             value: /var/run/secrets/backup-secrets/restic-new-password
+   ```
+2. Add restic-new-password to secret   
+   ```
+   kind: Secret
+   metadata:
+     name: backup-secret
+   data:
+     restic-password: old
+     restic-new-password: new
+   ```
+3. Scale backup-restore deployment up:   
+   `kubectl -n nextcloud scale deployment backup-restore --replicas=1`
+4. exec into pod and execute restore pod   
+   `kubectl -n nextcloud exec -it backup-restore -- change-password.bb`
+5. Scale backup-restore deployment down:   
+  `kubectl -n nextcloud scale deployment backup-restore --replicas=0`
+6. Replace restic-password with restic-new-password in secret   
+   ```
+   kind: Secret
+   metadata:
+     name: backup-secret
+   data:
+     restic-password: new
+   ```
diff --git a/infrastructure/backup/image/Dockerfile b/infrastructure/backup/image/Dockerfile
index 47e2d41..59a99c5 100644
--- a/infrastructure/backup/image/Dockerfile
+++ b/infrastructure/backup/image/Dockerfile
@@ -1,4 +1,5 @@
-FROM domaindrivenarchitecture/dda-backup:latest
+FROM domaindrivenarchitecture/dda-backup:5.3.0
 
 ADD resources /tmp
 RUN /tmp/install.bb
+RUN init.bb
diff --git a/infrastructure/backup/image/resources/backup.bb b/infrastructure/backup/image/resources/backup.bb
index ce54f71..6509399 100755
--- a/infrastructure/backup/image/resources/backup.bb
+++ b/infrastructure/backup/image/resources/backup.bb
@@ -2,44 +2,27 @@
 
 (require
  '[dda.backup.core :as bc]
+ '[dda.backup.config :as cfg]
  '[dda.backup.restic :as rc]
  '[dda.backup.postgresql :as pg]
  '[dda.backup.backup :as bak])
 
-(def restic-repo {:password-file (bc/env-or-file "RESTIC_PASSWORD_FILE")
-                  :restic-repository (bc/env-or-file "RESTIC_REPOSITORY")})
-
-(def file-config (merge restic-repo {:backup-path "files"
-                                     :execution-directory "/var/backups/"
-                                     :files ["gitea/" "git/repositories/"]}))
-
-
-(def db-config (merge restic-repo {:backup-path "pg-database"
-                                   :pg-host (bc/env-or-file "POSTGRES_SERVICE")
-                                   :pg-port (bc/env-or-file "POSTGRES_PORT")
-                                   :pg-db (bc/env-or-file "POSTGRES_DB")
-                                   :pg-user (bc/env-or-file "POSTGRES_USER")
-                                   :pg-password (bc/env-or-file "POSTGRES_PASSWORD")}))
-
-(def aws-config {:aws-access-key-id (bc/env-or-file "AWS_ACCESS_KEY_ID")
-                 :aws-secret-access-key (bc/env-or-file "AWS_SECRET_ACCESS_KEY")})
-
-(def dry-run {:dry-run true :debug true})
+(def config (cfg/read-config "/usr/local/bin/config.edn"))
 
 (defn prepare!
   []
-  (bc/create-aws-credentials! aws-config)
-  (pg/create-pg-pass! db-config))
+  (bc/create-aws-credentials! (:aws-config config))
+  (pg/create-pg-pass! (:db-config config)))
 
 (defn restic-repo-init!
   []
-  (rc/init! file-config)
-  (rc/init! db-config))
+  (rc/init! (:file-config config))
+  (rc/init! (:db-config config)))
 
 (defn restic-backup!
   []
-  (bak/backup-file! file-config)
-  (bak/backup-db! db-config))
+  (bak/backup-file! (:file-config config))
+  (bak/backup-db! (:db-config config)))
 
 (prepare!)
 (restic-repo-init!)
diff --git a/infrastructure/backup/image/resources/bb-backup.edn b/infrastructure/backup/image/resources/bb-backup.edn
index 1a7297a..11e9d9c 100644
--- a/infrastructure/backup/image/resources/bb-backup.edn
+++ b/infrastructure/backup/image/resources/bb-backup.edn
@@ -1,3 +1,4 @@
 {:deps {org.clojure/spec.alpha {:mvn/version "0.4.233"}
         orchestra/orchestra {:mvn/version "2021.01.01-1"}
+        aero/aero {:mvn/version "1.1.6"}
         org.domaindrivenarchitecture/dda-backup {:local/root "/usr/local/lib/dda-backup"}}}
diff --git a/infrastructure/backup/image/resources/bb.edn b/infrastructure/backup/image/resources/bb.edn
index 1c6458c..da7e0df 100644
--- a/infrastructure/backup/image/resources/bb.edn
+++ b/infrastructure/backup/image/resources/bb.edn
@@ -1,3 +1,3 @@
 {:deps {org.clojure/spec.alpha {:mvn/version "0.4.233"}
         orchestra/orchestra {:mvn/version "2021.01.01-1"}
-        org.domaindrivenarchitecture/dda-build {:mvn/version "0.1.1-SNAPSHOT"}}}
+        org.domaindrivenarchitecture/dda-build {:mvn/version "0.2.0"}}}
diff --git a/infrastructure/backup/image/resources/change-password.bb b/infrastructure/backup/image/resources/change-password.bb
new file mode 100755
index 0000000..3f26735
--- /dev/null
+++ b/infrastructure/backup/image/resources/change-password.bb
@@ -0,0 +1,24 @@
+#!/usr/bin/env bb
+(require
+ '[dda.backup.core :as bc]
+ '[dda.backup.config :as cfg]
+ '[dda.backup.restic :as rc])
+
+(def config (cfg/read-config "/usr/local/bin/config.edn"))
+
+(def file-pw-change-config (merge (:file-config config)
+                                  {:new-password-file (bc/env-or-file "RESTIC_NEW_PASSWORD_FILE")}))
+(def db-pw-change-config (merge (:db-config config) 
+                                {:new-password-file (bc/env-or-file "RESTIC_NEW_PASSWORD_FILE")}))
+
+(defn prepare!
+  []
+  (bc/create-aws-credentials! (:aws-config config)))
+
+(defn change-password!
+  []
+  (rc/change-password! file-pw-change-config)
+  (rc/change-password! db-pw-change-config))
+
+(prepare!)
+(change-password!)
diff --git a/infrastructure/backup/image/resources/install.bb b/infrastructure/backup/image/resources/install.bb
index 3ec49fb..3f96494 100755
--- a/infrastructure/backup/image/resources/install.bb
+++ b/infrastructure/backup/image/resources/install.bb
@@ -7,8 +7,11 @@
 
 (ub/upgrade-system!)
 (in/install! "bb-backup.edn" :target-name "bb.edn" :mod "0400")
+(in/install! "config.edn" :mod "0440")
+(in/install! "init.bb")
 (in/install! "backup.bb")
 (in/install! "restore.bb")
 (in/install! "list-snapshots.bb")
+(in/install! "change-password.bb")
 (in/install! "wait.bb")
 (ub/cleanup-container!)
\ No newline at end of file
diff --git a/infrastructure/backup/image/resources/list-snapshots.bb b/infrastructure/backup/image/resources/list-snapshots.bb
index 349db38..f7f86bf 100755
--- a/infrastructure/backup/image/resources/list-snapshots.bb
+++ b/infrastructure/backup/image/resources/list-snapshots.bb
@@ -2,27 +2,19 @@
 
 (require
  '[dda.backup.core :as bc]
+ '[dda.backup.config :as cfg]
  '[dda.backup.restic :as rc])
 
-(def restic-repo {:password-file (bc/env-or-file "RESTIC_PASSWORD_FILE")
-                  :restic-repository (bc/env-or-file "RESTIC_REPOSITORY")})
-
-(def file-config (merge restic-repo {:backup-path "files"}))
-
-
-(def db-config (merge restic-repo {:backup-path "pg-database"}))
-
-(def aws-config {:aws-access-key-id (bc/env-or-file "AWS_ACCESS_KEY_ID")
-                 :aws-secret-access-key (bc/env-or-file "AWS_SECRET_ACCESS_KEY")})
+(def config (cfg/read-config "/usr/local/bin/config.edn"))
 
 (defn prepare!
   []
-  (bc/create-aws-credentials! aws-config))
+  (bc/create-aws-credentials! (:aws-config config)))
 
 (defn list-snapshots!
   []
-  (rc/list-snapshots! file-config)
-  (rc/list-snapshots! db-config))
+  (rc/list-snapshots! (:file-config config))
+  (rc/list-snapshots! (:db-config config)))
 
 (prepare!)
 (list-snapshots!)
diff --git a/infrastructure/backup/image/resources/restore.bb b/infrastructure/backup/image/resources/restore.bb
index c8a9cd1..6b790ae 100755
--- a/infrastructure/backup/image/resources/restore.bb
+++ b/infrastructure/backup/image/resources/restore.bb
@@ -2,34 +2,28 @@
 
 (require '[babashka.tasks :as tasks]
          '[dda.backup.core :as bc]
+         '[dda.backup.config :as cfg]
          '[dda.backup.postgresql :as pg]
          '[dda.backup.restore :as rs])
 
-(def restic-repo {:password-file (bc/env-or-file "RESTIC_PASSWORD_FILE")
-                  :restic-repository (bc/env-or-file "RESTIC_REPOSITORY")})
+(def config (cfg/read-config "/usr/local/bin/config.edn"))
 
-(def file-config (merge restic-repo {:backup-path "files"
-                                     :restore-target-directory "/var/backups/restore"
-                                     :snapshot-id "latest"}))
+(def file-config (merge
+                  (:restic-repo config)
+                  {:backup-path "files"
+                   :restore-target-directory "/var/backups/restore"
+                   :snapshot-id "latest"}))
 
+(def db-config (merge (:db-config config)
+                      {:snapshot-id "latest"}))
 
-(def db-config (merge restic-repo {:backup-path "pg-database"
-                                   :pg-host (bc/env-or-file "POSTGRES_SERVICE")
-                                   :pg-port (bc/env-or-file "POSTGRES_PORT")
-                                   :pg-db (bc/env-or-file "POSTGRES_DB")
-                                   :pg-user (bc/env-or-file "POSTGRES_USER")
-                                   :pg-password (bc/env-or-file "POSTGRES_PASSWORD")
-                                   :snapshot-id "latest"}))
-
-(def aws-config {:aws-access-key-id (bc/env-or-file "AWS_ACCESS_KEY_ID")
-                 :aws-secret-access-key (bc/env-or-file "AWS_SECRET_ACCESS_KEY")})
 
 (def dry-run {:dry-run true :debug true})
 
 (defn prepare!
   []
-  (pg/create-pg-pass! db-config)
-  (bc/create-aws-credentials! aws-config))
+  (bc/create-aws-credentials! (:aws-config config))
+  (pg/create-pg-pass! db-config))
 
 (defn restic-restore!
   []
@@ -39,8 +33,8 @@
   (tasks/shell ["mv" "/var/backups/restore/gitea" "/var/backups/"])
   (tasks/shell ["mv" "/var/backups/restore/git/repositories" "/var/backups/git/"])
   (tasks/shell ["chown" "-R" "1000:1000" "/var/backups"])
-  (pg/drop-create-db! (merge db-config {:debug true}))
-  (rs/restore-db! (merge db-config {:debug true})))
+  (pg/drop-create-db! db-config)
+  (rs/restore-db! db-config))
 
 (prepare!)
 (restic-restore!)
diff --git a/infrastructure/backup/image/resources/wait.bb b/infrastructure/backup/image/resources/wait.bb
index 2bb9e3f..bd0ecd9 100755
--- a/infrastructure/backup/image/resources/wait.bb
+++ b/infrastructure/backup/image/resources/wait.bb
@@ -1,27 +1,19 @@
 #!/usr/bin/env bb
-
 (require
  '[dda.backup.core :as bc]
+ '[dda.backup.config :as cfg]
  '[dda.backup.postgresql :as pg])
 
-
-(def restic-repo {:password-file (bc/env-or-file "RESTIC_PASSWORD_FILE")
-                  :restic-repository (bc/env-or-file "RESTIC_REPOSITORY")})
-
-(def db-config (merge restic-repo {:backup-path "pg-database"
-                                   :pg-host (bc/env-or-file "POSTGRES_SERVICE")
-                                   :pg-port (bc/env-or-file "POSTGRES_PORT")
-                                   :pg-db (bc/env-or-file "POSTGRES_DB")
-                                   :pg-user (bc/env-or-file "POSTGRES_USER")
-                                   :pg-password (bc/env-or-file "POSTGRES_PASSWORD")}))
+(def config (cfg/read-config "/usr/local/bin/config.edn"))
 
 (defn prepare!
   []
-  (pg/create-pg-pass! db-config))
+  (bc/create-aws-credentials! (:aws-config config))
+  (pg/create-pg-pass! (:db-config config)))
 
 (defn wait! []
   (while true
     (Thread/sleep 1000)))
 
 (prepare!)
-(wait!)
\ No newline at end of file
+(wait!)
diff --git a/infrastructure/backup/test/Dockerfile b/infrastructure/backup/test/Dockerfile
index 91b7719..d05cd5a 100644
--- a/infrastructure/backup/test/Dockerfile
+++ b/infrastructure/backup/test/Dockerfile
@@ -1,4 +1,4 @@
 FROM c4k-forgejo-backup:latest
 
 ADD resources /tmp/
-RUN ENV_PASSWORD=env-password FILE_PASSWORD_FILE=/tmp/file_password /tmp/test.bb
+RUN RESTIC_PASSWORD_FILE=/tmp/file_password RESTIC_NEW_PASSWORD_FILE=/tmp/new_file_password RESTIC_REPOSITORY=/tmp/restic-repo POSTGRES_SERVICE=dummy POSTGRES_PORT=dummy POSTGRES_DB=dummy POSTGRES_USER=dummy POSTGRES_PASSWORD=dummy AWS_ACCESS_KEY_ID=dummy AWS_SECRET_ACCESS_KEY=dummy /tmp/test.bb
diff --git a/infrastructure/backup/test/resources/bb.edn b/infrastructure/backup/test/resources/bb.edn
index 1a7297a..11e9d9c 100644
--- a/infrastructure/backup/test/resources/bb.edn
+++ b/infrastructure/backup/test/resources/bb.edn
@@ -1,3 +1,4 @@
 {:deps {org.clojure/spec.alpha {:mvn/version "0.4.233"}
         orchestra/orchestra {:mvn/version "2021.01.01-1"}
+        aero/aero {:mvn/version "1.1.6"}
         org.domaindrivenarchitecture/dda-backup {:local/root "/usr/local/lib/dda-backup"}}}
diff --git a/infrastructure/backup/test/resources/file_password b/infrastructure/backup/test/resources/file_password
new file mode 100644
index 0000000..f0890e1
--- /dev/null
+++ b/infrastructure/backup/test/resources/file_password
@@ -0,0 +1 @@
+oldPassword
\ No newline at end of file
diff --git a/infrastructure/backup/test/resources/new_file_password b/infrastructure/backup/test/resources/new_file_password
new file mode 100644
index 0000000..d97747c
--- /dev/null
+++ b/infrastructure/backup/test/resources/new_file_password
@@ -0,0 +1 @@
+newPassword
\ No newline at end of file
diff --git a/infrastructure/backup/test/resources/test.bb b/infrastructure/backup/test/resources/test.bb
index 5ac0474..db59380 100755
--- a/infrastructure/backup/test/resources/test.bb
+++ b/infrastructure/backup/test/resources/test.bb
@@ -2,61 +2,66 @@
 
 (require '[babashka.tasks :as tasks]
          '[dda.backup.core :as bc]
+         '[dda.backup.config :as cfg]
          '[dda.backup.restic :as rc]
          '[dda.backup.postgresql :as pg]
          '[dda.backup.backup :as bak]
          '[dda.backup.restore :as rs])
 
-(def restic-repo {:password-file "restic-pwd"
-                  :restic-repository "restic-repo"})
+(def config (cfg/read-config "/usr/local/bin/config.edn"))
 
-(def file-config (merge restic-repo {:backup-path "files"
-                                     :files ["test-backup"]
-                                     :restore-target-directory "test-restore"}))
+(def file-pw-change-config (merge (:file-config config)
+                                  {:new-password-file (bc/env-or-file "RESTIC_NEW_PASSWORD_FILE")}))
 
-
-(def db-config (merge restic-repo {:backup-path "db"
-                                   :pg-db "mydb"
-                                   :pg-user "user"
-                                   :pg-password "password"}))
-
-(def dry-run {:dry-run true :debug true})
+(def file-restore-config (merge
+                          (:restic-repo config)
+                          {:backup-path "files"
+                           :restore-target-directory "/var/backups/restore"
+                           :snapshot-id "latest"}))
 
 (defn prepare!
   []
-  (spit "/tmp/file_password" "file-password")
-  (println (bc/env-or-file "FILE_PASSWORD"))
-  (println (bc/env-or-file "ENV_PASSWORD"))
-  (spit "restic-pwd" "ThePassword")
-  (tasks/shell "mkdir" "-p" "test-backup")
-  (spit "test-backup/file" "I was here")
-  (tasks/shell "mkdir" "-p" "test-restore")
-  (pg/create-pg-pass! db-config))
+  (tasks/shell "mkdir" "-p" "/tmp/restic-repo")
+  (tasks/shell "mkdir" "-p" "/var/backups/gitea")
+  (tasks/shell "mkdir" "-p" "/var/backups/git/repositories")
+  (spit "/var/backups/gitea/file" "I was here")
+  (tasks/shell "mkdir" "-p" "test-restore"))
 
 (defn restic-repo-init!
   []
-  (rc/init! file-config)
-  (rc/init! (merge db-config dry-run)))
+  (rc/init! (:file-config config))
+  (rc/init! (merge (:db-config config)
+                   (:dry-run config))))
 
 (defn restic-backup!
   []
-  (bak/backup-file! file-config)
-  (bak/backup-db! (merge db-config dry-run)))
+  (bak/backup-file! (:file-config config))
+  (bak/backup-db! (merge (:db-config config)
+                         (:dry-run config))))
 
 (defn list-snapshots!
   []
-  (rc/list-snapshots! file-config)
-  (rc/list-snapshots! (merge db-config dry-run)))
+  (rc/list-snapshots! (:file-config config))
+  (rc/list-snapshots! (merge (:db-config config)
+                             (:dry-run config))))
 
 
 (defn restic-restore!
   []
-  (rs/restore-file! file-config)
-  (pg/drop-create-db! (merge db-config dry-run))
-  (rs/restore-db! (merge db-config dry-run)))
+  (pg/drop-create-db! (merge (:db-config config)
+                             (:dry-run config)))
+  (rs/restore-db! (merge (:db-config config)
+                         (:dry-run config)))
+  (rs/restore-file! file-restore-config))
+
+(defn change-password!
+  []
+  (println "change-password!")
+  (rc/change-password! file-pw-change-config))
 
 (prepare!)
 (restic-repo-init!)
 (restic-backup!)
 (list-snapshots!)
 (restic-restore!)
+(change-password!)