Merge pull request 'password-rotation' () from password-rotation into main

Reviewed-on: 
This commit is contained in:
jem 2025-01-14 09:22:20 +00:00
commit 8898ee8def
25 changed files with 205 additions and 147 deletions

View file

@ -52,9 +52,8 @@ Mirrors are:
For more details about our repository model see: https://repo.prod.meissa.de/meissa/federate-your-repos For more details about our repository model see: https://repo.prod.meissa.de/meissa/federate-your-repos
## License ## License
Copyright © 2023, 2024 meissa GmbH Copyright © 2023, 2024, 2025 meissa GmbH
Licensed under the [Apache License, Version 2.0](LICENSE) (the "License") Licensed under the [Apache License, Version 2.0](LICENSE) (the "License")
Pls. find licenses of our subcomponents [here](doc/SUBCOMPONENT_LICENSE) Pls. find licenses of our subcomponents [here](doc/SUBCOMPONENT_LICENSE)

View file

@ -7,35 +7,67 @@
* Forgejo stores files in `/data/gitea` and `/data/git/repositories`, these files are backed up. * Forgejo stores files in `/data/gitea` and `/data/git/repositories`, these files are backed up.
* The postgres db is also 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: 1. Scale down forgejo deployment:
`kubectl -n forgejo scale deployment backup-restore --replicas=1` `kubectl -n forgejo scale deployment forgejo --replicas=0`
2. exec into pod and execute restore pod (press tab to get your exact pod name) 2. apply backup-and-restore pod:
`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:
`kubectl -n forgejo scale deployment backup-restore --replicas=1` `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` `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` `kubectl -n forgejo scale deployment backup-restore --replicas=0`
5. Scale up forgejo deployment:
`kubectl -n forgejo scale deployment forgejo --replicas=1`
## Manual restore ## Manual restore
1. apply backup-and-restore pod: 1. Scale down forgejo deployment:
`kubectl -n forgejo scale deployment backup-restore --replicas=1`
2. Scale down forgejo deployment:
`kubectl -n forgejo scale deployment forgejo --replicas=0` `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) 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` `kubectl -n forgejo exec -it backup-restore-... -- /usr/local/bin/restore.bb`
4. Start forgejo again: 4. Start forgejo again:
`kubectl -n forgejo scale deployment forgejo --replicas=1` `kubectl -n forgejo scale deployment forgejo --replicas=1`
5. remove backup-and-restore pod: 5. remove backup-and-restore pod:
`kubectl -n forgejo scale deployment backup-restore --replicas=0` `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
```

8
doc/FirstSteps.md Normal file
View file

@ -0,0 +1,8 @@
# First Steps
## Create admin user
1. exec into pod and execute restore pod (press tab to get your exact pod name)
`kubectl -n forgejo exec -it backup-restore-... -- bash`
2. create admin user
`su git -c "gitea admin user create --username [login] --password [password] -email "email"--admin"`

View file

@ -1,4 +1,5 @@
FROM domaindrivenarchitecture/dda-backup:latest FROM domaindrivenarchitecture/dda-backup:5.3.0
ADD resources /tmp ADD resources /tmp
RUN /tmp/install.bb RUN /tmp/install.bb
RUN init.bb

View file

@ -2,44 +2,27 @@
(require (require
'[dda.backup.core :as bc] '[dda.backup.core :as bc]
'[dda.backup.config :as cfg]
'[dda.backup.restic :as rc] '[dda.backup.restic :as rc]
'[dda.backup.postgresql :as pg] '[dda.backup.postgresql :as pg]
'[dda.backup.backup :as bak]) '[dda.backup.backup :as bak])
(def restic-repo {:password-file (bc/env-or-file "RESTIC_PASSWORD_FILE") (def config (cfg/read-config "/usr/local/bin/config.edn"))
: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})
(defn prepare! (defn prepare!
[] []
(bc/create-aws-credentials! aws-config) (bc/create-aws-credentials! (:aws-config config))
(pg/create-pg-pass! db-config)) (pg/create-pg-pass! (:db-config config)))
(defn restic-repo-init! (defn restic-repo-init!
[] []
(rc/init! file-config) (rc/init! (:file-config config))
(rc/init! db-config)) (rc/init! (:db-config config)))
(defn restic-backup! (defn restic-backup!
[] []
(bak/backup-file! file-config) (bak/backup-file! (:file-config config))
(bak/backup-db! db-config)) (bak/backup-db! (:db-config config)))
(prepare!) (prepare!)
(restic-repo-init!) (restic-repo-init!)

View file

@ -1,3 +1,4 @@
{:deps {org.clojure/spec.alpha {:mvn/version "0.4.233"} {:deps {org.clojure/spec.alpha {:mvn/version "0.4.233"}
orchestra/orchestra {:mvn/version "2021.01.01-1"} 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"}}} org.domaindrivenarchitecture/dda-backup {:local/root "/usr/local/lib/dda-backup"}}}

View file

@ -1,3 +1,3 @@
{:deps {org.clojure/spec.alpha {:mvn/version "0.4.233"} {:deps {org.clojure/spec.alpha {:mvn/version "0.4.233"}
orchestra/orchestra {:mvn/version "2021.01.01-1"} 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"}}}

View file

@ -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!)

View file

@ -7,8 +7,11 @@
(ub/upgrade-system!) (ub/upgrade-system!)
(in/install! "bb-backup.edn" :target-name "bb.edn" :mod "0400") (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! "backup.bb")
(in/install! "restore.bb") (in/install! "restore.bb")
(in/install! "list-snapshots.bb") (in/install! "list-snapshots.bb")
(in/install! "change-password.bb")
(in/install! "wait.bb") (in/install! "wait.bb")
(ub/cleanup-container!) (ub/cleanup-container!)

View file

@ -2,27 +2,19 @@
(require (require
'[dda.backup.core :as bc] '[dda.backup.core :as bc]
'[dda.backup.config :as cfg]
'[dda.backup.restic :as rc]) '[dda.backup.restic :as rc])
(def restic-repo {:password-file (bc/env-or-file "RESTIC_PASSWORD_FILE") (def config (cfg/read-config "/usr/local/bin/config.edn"))
: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")})
(defn prepare! (defn prepare!
[] []
(bc/create-aws-credentials! aws-config)) (bc/create-aws-credentials! (:aws-config config)))
(defn list-snapshots! (defn list-snapshots!
[] []
(rc/list-snapshots! file-config) (rc/list-snapshots! (:file-config config))
(rc/list-snapshots! db-config)) (rc/list-snapshots! (:db-config config)))
(prepare!) (prepare!)
(list-snapshots!) (list-snapshots!)

View file

@ -2,34 +2,28 @@
(require '[babashka.tasks :as tasks] (require '[babashka.tasks :as tasks]
'[dda.backup.core :as bc] '[dda.backup.core :as bc]
'[dda.backup.config :as cfg]
'[dda.backup.postgresql :as pg] '[dda.backup.postgresql :as pg]
'[dda.backup.restore :as rs]) '[dda.backup.restore :as rs])
(def restic-repo {:password-file (bc/env-or-file "RESTIC_PASSWORD_FILE") (def config (cfg/read-config "/usr/local/bin/config.edn"))
:restic-repository (bc/env-or-file "RESTIC_REPOSITORY")})
(def file-config (merge restic-repo {:backup-path "files" (def file-config (merge
:restore-target-directory "/var/backups/restore" (:restic-repo config)
:snapshot-id "latest"})) {: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}) (def dry-run {:dry-run true :debug true})
(defn prepare! (defn prepare!
[] []
(pg/create-pg-pass! db-config) (bc/create-aws-credentials! (:aws-config config))
(bc/create-aws-credentials! aws-config)) (pg/create-pg-pass! db-config))
(defn restic-restore! (defn restic-restore!
[] []
@ -39,8 +33,8 @@
(tasks/shell ["mv" "/var/backups/restore/gitea" "/var/backups/"]) (tasks/shell ["mv" "/var/backups/restore/gitea" "/var/backups/"])
(tasks/shell ["mv" "/var/backups/restore/git/repositories" "/var/backups/git/"]) (tasks/shell ["mv" "/var/backups/restore/git/repositories" "/var/backups/git/"])
(tasks/shell ["chown" "-R" "1000:1000" "/var/backups"]) (tasks/shell ["chown" "-R" "1000:1000" "/var/backups"])
(pg/drop-create-db! (merge db-config {:debug true})) (pg/drop-create-db! db-config)
(rs/restore-db! (merge db-config {:debug true}))) (rs/restore-db! db-config))
(prepare!) (prepare!)
(restic-restore!) (restic-restore!)

View file

@ -1,27 +1,19 @@
#!/usr/bin/env bb #!/usr/bin/env bb
(require (require
'[dda.backup.core :as bc] '[dda.backup.core :as bc]
'[dda.backup.config :as cfg]
'[dda.backup.postgresql :as pg]) '[dda.backup.postgresql :as pg])
(def config (cfg/read-config "/usr/local/bin/config.edn"))
(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")}))
(defn prepare! (defn prepare!
[] []
(pg/create-pg-pass! db-config)) (bc/create-aws-credentials! (:aws-config config))
(pg/create-pg-pass! (:db-config config)))
(defn wait! [] (defn wait! []
(while true (while true
(Thread/sleep 1000))) (Thread/sleep 1000)))
(prepare!) (prepare!)
(wait!) (wait!)

View file

@ -1,4 +1,4 @@
FROM c4k-forgejo-backup:latest FROM c4k-forgejo-backup:latest
ADD resources /tmp/ 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

View file

@ -1,3 +1,4 @@
{:deps {org.clojure/spec.alpha {:mvn/version "0.4.233"} {:deps {org.clojure/spec.alpha {:mvn/version "0.4.233"}
orchestra/orchestra {:mvn/version "2021.01.01-1"} 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"}}} org.domaindrivenarchitecture/dda-backup {:local/root "/usr/local/lib/dda-backup"}}}

View file

@ -0,0 +1 @@
oldPassword

View file

@ -0,0 +1 @@
newPassword

View file

@ -2,61 +2,66 @@
(require '[babashka.tasks :as tasks] (require '[babashka.tasks :as tasks]
'[dda.backup.core :as bc] '[dda.backup.core :as bc]
'[dda.backup.config :as cfg]
'[dda.backup.restic :as rc] '[dda.backup.restic :as rc]
'[dda.backup.postgresql :as pg] '[dda.backup.postgresql :as pg]
'[dda.backup.backup :as bak] '[dda.backup.backup :as bak]
'[dda.backup.restore :as rs]) '[dda.backup.restore :as rs])
(def restic-repo {:password-file "restic-pwd" (def config (cfg/read-config "/usr/local/bin/config.edn"))
:restic-repository "restic-repo"})
(def file-config (merge restic-repo {:backup-path "files" (def file-pw-change-config (merge (:file-config config)
:files ["test-backup"] {:new-password-file (bc/env-or-file "RESTIC_NEW_PASSWORD_FILE")}))
:restore-target-directory "test-restore"}))
(def file-restore-config (merge
(def db-config (merge restic-repo {:backup-path "db" (:restic-repo config)
:pg-db "mydb" {:backup-path "files"
:pg-user "user" :restore-target-directory "/var/backups/restore"
:pg-password "password"})) :snapshot-id "latest"}))
(def dry-run {:dry-run true :debug true})
(defn prepare! (defn prepare!
[] []
(spit "/tmp/file_password" "file-password") (tasks/shell "mkdir" "-p" "/tmp/restic-repo")
(println (bc/env-or-file "FILE_PASSWORD")) (tasks/shell "mkdir" "-p" "/var/backups/gitea")
(println (bc/env-or-file "ENV_PASSWORD")) (tasks/shell "mkdir" "-p" "/var/backups/git/repositories")
(spit "restic-pwd" "ThePassword") (spit "/var/backups/gitea/file" "I was here")
(tasks/shell "mkdir" "-p" "test-backup") (tasks/shell "mkdir" "-p" "test-restore"))
(spit "test-backup/file" "I was here")
(tasks/shell "mkdir" "-p" "test-restore")
(pg/create-pg-pass! db-config))
(defn restic-repo-init! (defn restic-repo-init!
[] []
(rc/init! file-config) (rc/init! (:file-config config))
(rc/init! (merge db-config dry-run))) (rc/init! (merge (:db-config config)
(:dry-run config))))
(defn restic-backup! (defn restic-backup!
[] []
(bak/backup-file! file-config) (bak/backup-file! (:file-config config))
(bak/backup-db! (merge db-config dry-run))) (bak/backup-db! (merge (:db-config config)
(:dry-run config))))
(defn list-snapshots! (defn list-snapshots!
[] []
(rc/list-snapshots! file-config) (rc/list-snapshots! (:file-config config))
(rc/list-snapshots! (merge db-config dry-run))) (rc/list-snapshots! (merge (:db-config config)
(:dry-run config))))
(defn restic-restore! (defn restic-restore!
[] []
(rs/restore-file! file-config) (pg/drop-create-db! (merge (:db-config config)
(pg/drop-create-db! (merge db-config dry-run)) (:dry-run config)))
(rs/restore-db! (merge db-config dry-run))) (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!) (prepare!)
(restic-repo-init!) (restic-repo-init!)
(restic-backup!) (restic-backup!)
(list-snapshots!) (list-snapshots!)
(restic-restore!) (restic-restore!)
(change-password!)

View file

@ -27,7 +27,7 @@
"js-yaml": "^4.0.0" "js-yaml": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {
"shadow-cljs": "^2.11.18", "shadow-cljs": "^2.28.20",
"source-map-support": "^0.5.19" "source-map-support": "^0.5.21"
} }
} }

View file

@ -3,9 +3,9 @@
:url "https://domaindrivenarchitecture.org" :url "https://domaindrivenarchitecture.org"
:license {:name "Apache License, Version 2.0" :license {:name "Apache License, Version 2.0"
:url "https://www.apache.org/licenses/LICENSE-2.0.html"} :url "https://www.apache.org/licenses/LICENSE-2.0.html"}
:dependencies [[org.clojure/clojure "1.11.4" :scope "provided"] :dependencies [[org.clojure/clojure "1.12.0" :scope "provided"]
[org.clojure/tools.reader "1.5.0"] [org.clojure/tools.reader "1.5.0"]
[org.domaindrivenarchitecture/c4k-common-clj "8.0.0"] [org.domaindrivenarchitecture/c4k-common-clj "9.0.1"]
[hickory "0.7.1" :exclusions [viebel/codox-klipse-theme]]] [hickory "0.7.1" :exclusions [viebel/codox-klipse-theme]]]
:target-path "target/%s/" :target-path "target/%s/"
:source-paths ["src/main/cljc" :source-paths ["src/main/cljc"
@ -24,7 +24,7 @@
:main dda.c4k-forgejo.uberjar :main dda.c4k-forgejo.uberjar
:uberjar-name "c4k-forgejo-standalone.jar" :uberjar-name "c4k-forgejo-standalone.jar"
:dependencies [[org.clojure/tools.cli "1.1.230"] :dependencies [[org.clojure/tools.cli "1.1.230"]
[ch.qos.logback/logback-classic "1.5.7" [ch.qos.logback/logback-classic "1.5.16"
:exclusions [com.sun.mail/javax.mail]] :exclusions [com.sun.mail/javax.mail]]
[org.slf4j/jcl-over-slf4j "2.0.16"] [org.slf4j/jcl-over-slf4j "2.0.16"]
[com.github.clj-easy/graal-build-time "1.0.5"]]}} [com.github.clj-easy/graal-build-time "1.0.5"]]}}

View file

@ -4,7 +4,7 @@
"src/test/cljc" "src/test/cljc"
"src/test/cljs" "src/test/cljs"
"src/test/resources"] "src/test/resources"]
:dependencies [[org.domaindrivenarchitecture/c4k-common-cljs "8.0.0"] :dependencies [[org.domaindrivenarchitecture/c4k-common-cljs "9.0.1"]
[hickory "0.7.1"]] [hickory "0.7.1"]]
:builds {:frontend {:target :browser :builds {:frontend {:target :browser
:modules {:main {:init-fn dda.c4k-forgejo.browser/init}} :modules {:main {:init-fn dda.c4k-forgejo.browser/init}}

View file

@ -1,17 +1,18 @@
(ns dda.c4k-forgejo.backup (ns dda.c4k-forgejo.backup
(:require (:require
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
#?(:clj [orchestra.core :refer [defn-spec]] #?(:clj [orchestra.core :refer [defn-spec]]
:cljs [orchestra.core :refer-macros [defn-spec]]) :cljs [orchestra.core :refer-macros [defn-spec]])
[dda.c4k-common.yaml :as yaml] [dda.c4k-common.yaml :as yaml]
[dda.c4k-common.base64 :as b64] [dda.c4k-common.base64 :as b64]
[dda.c4k-common.common :as cm] [dda.c4k-common.common :as cm]
[dda.c4k-common.predicate :as p] [dda.c4k-common.predicate :as p]
#?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]]))) #?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]])))
(s/def ::aws-access-key-id p/bash-env-string?) (s/def ::aws-access-key-id p/bash-env-string?)
(s/def ::aws-secret-access-key p/bash-env-string?) (s/def ::aws-secret-access-key p/bash-env-string?)
(s/def ::restic-password p/bash-env-string?) (s/def ::restic-password p/bash-env-string?)
(s/def ::restic-new-password p/bash-env-string?)
(s/def ::restic-repository p/bash-env-string?) (s/def ::restic-repository p/bash-env-string?)
(s/def ::config (s/keys :req-un [::restic-repository])) (s/def ::config (s/keys :req-un [::restic-repository]))
@ -32,17 +33,20 @@
(defn-spec generate-cron p/map-or-seq? (defn-spec generate-cron p/map-or-seq?
[] []
(yaml/from-string (yaml/load-resource "backup/cron.yaml"))) (yaml/from-string (yaml/load-resource "backup/cron.yaml")))
(defn-spec generate-backup-restore-deployment p/map-or-seq? (defn-spec generate-backup-restore-deployment p/map-or-seq?
[my-conf ::config] [my-conf ::config]
(yaml/from-string (yaml/load-resource "backup/backup-restore-deployment.yaml"))) (yaml/from-string (yaml/load-resource "backup/backup-restore-deployment.yaml")))
(defn-spec generate-secret p/map-or-seq? (defn-spec generate-secret p/map-or-seq?
[my-auth ::auth] [auth ::auth]
(let [{:keys [aws-access-key-id aws-secret-access-key restic-password]} my-auth] (let [{:keys [aws-access-key-id aws-secret-access-key
(-> restic-password restic-new-password]} auth]
(yaml/from-string (yaml/load-resource "backup/secret.yaml")) (as-> (yaml/from-string (yaml/load-resource "backup/secret.yaml")) res
(cm/replace-key-value :aws-access-key-id (b64/encode aws-access-key-id)) (cm/replace-key-value res :aws-access-key-id (b64/encode aws-access-key-id))
(cm/replace-key-value :aws-secret-access-key (b64/encode aws-secret-access-key)) (cm/replace-key-value res :aws-secret-access-key (b64/encode aws-secret-access-key))
(cm/replace-key-value :restic-password (b64/encode restic-password))))) (cm/replace-key-value res :restic-password (b64/encode restic-password))
(if (contains? auth :restic-new-password)
(assoc-in res [:data :restic-new-password] (b64/encode restic-new-password))
res))))

View file

@ -43,6 +43,7 @@
::forgejo/mailer-user ::forgejo/mailer-pw ::forgejo/mailer-user ::forgejo/mailer-pw
::backup/aws-access-key-id ::backup/aws-secret-access-key] ::backup/aws-access-key-id ::backup/aws-secret-access-key]
:opt-un [::backup/restic-password :opt-un [::backup/restic-password
::backup/restic-new-password
::mon/mon-auth])) ::mon/mon-auth]))
(defn-spec config-objects p/map-or-seq? (defn-spec config-objects p/map-or-seq?

View file

@ -57,6 +57,8 @@ spec:
key: restic-repository key: restic-repository
- name: RESTIC_PASSWORD_FILE - name: RESTIC_PASSWORD_FILE
value: /var/run/secrets/backup-secrets/restic-password value: /var/run/secrets/backup-secrets/restic-password
- name: RESTIC_NEW_PASSWORD_FILE
value: /var/run/secrets/backup-secrets/restic-new-password
- name: CERTIFICATE_FILE - name: CERTIFICATE_FILE
value: "" value: ""
volumeMounts: volumeMounts:

View file

@ -19,7 +19,20 @@
:restic-password "cmVzdGljLXB3"}} :restic-password "cmVzdGljLXB3"}}
(cut/generate-secret {:aws-access-key-id "aws-id" (cut/generate-secret {:aws-access-key-id "aws-id"
:aws-secret-access-key "aws-secret" :aws-secret-access-key "aws-secret"
:restic-password "restic-pw"})))) :restic-password "restic-pw"})))
(is (= {:apiVersion "v1",
:kind "Secret",
:metadata {:name "backup-secret", :namespace "forgejo"},
:type "Opaque",
:data
{:aws-access-key-id "YXdzLWlk",
:aws-secret-access-key "YXdzLXNlY3JldA==",
:restic-password "b2xk",
:restic-new-password "bmV3"}}
(cut/generate-secret {:aws-access-key-id "aws-id"
:aws-secret-access-key "aws-secret"
:restic-password "old"
:restic-new-password "new"}))))
(deftest should-generate-backup-config (deftest should-generate-backup-config
(testing "federated" (testing "federated"

View file

@ -4,7 +4,8 @@ mailer-user: ""
mailer-pw: "" mailer-pw: ""
aws-access-key-id: "AWS_KEY_ID" aws-access-key-id: "AWS_KEY_ID"
aws-secret-access-key: "AWS_KEY_SECRET" aws-secret-access-key: "AWS_KEY_SECRET"
restic-password: "" restic-password: "old"
restic-new-password: "new"
mon-auth: mon-auth:
grafana-cloud-user: "user" grafana-cloud-user: "user"
grafana-cloud-password: "password" grafana-cloud-password: "password"