diff --git a/infrastructure/backup/image/Dockerfile b/infrastructure/backup/image/Dockerfile index 87344ab..a6436eb 100644 --- a/infrastructure/backup/image/Dockerfile +++ b/infrastructure/backup/image/Dockerfile @@ -5,6 +5,7 @@ ADD resources /tmp/ RUN /tmp/install.sh ADD local/ /usr/local/lib/dda-backup RUN init-bb.bb -#ADD resources2 /tmp/ -#RUN install -m 0700 -o root -g root /tmp/test.bb /usr/local/bin/ -#RUN test.bb +# ADD resources2 /tmp/ +# RUN install -m 0700 -o root -g root /tmp/test.bb /usr/local/bin/ +# RUN install -m 0700 -o root -g root /tmp/check.bb /usr/local/bin/ +# RUN test.bb diff --git a/infrastructure/backup/image/resources2/change-password.bb b/infrastructure/backup/image/resources2/change-password.bb index c2c89d7..ab0d700 100755 --- a/infrastructure/backup/image/resources2/change-password.bb +++ b/infrastructure/backup/image/resources2/change-password.bb @@ -3,7 +3,8 @@ (require '[dda.backup.cred-rot :as cr]) (def restic-repo {:password-file "/restic-pwd" - :restic-repository "/restic-repo"}) + :restic-repository "/restic-repo" + :debug true}) (def file-config (merge restic-repo {:backup-path "files" :files ["/test-backup"] @@ -12,7 +13,7 @@ (def cred-config (merge file-config {:restic-repository "/restic-repo/files" :new-password-config {:new-password-file "/new-pw" - :valid-from "2024-12-12 00:00:00"}})) + :valid-from "2024-12-17 00:00:00"}})) (def dry-run {:dry-run true :debug true}) diff --git a/infrastructure/backup/image/resources2/check.bb b/infrastructure/backup/image/resources2/check.bb new file mode 100755 index 0000000..183feec --- /dev/null +++ b/infrastructure/backup/image/resources2/check.bb @@ -0,0 +1,23 @@ +#!/usr/bin/env bb + +(require '[dda.backup.restic :as rc]) + +(def restic-repo {:password-file "/restic-pwd" + :restic-repository "/restic-repo" + :debug true}) + +(def file-config (merge restic-repo {:backup-path "files" + :files ["/test-backup"] + :restore-target-directory "/test-restore"})) + +(def cred-config (merge file-config {:new-password-file "new-pw"})) + + +(def dry-run {:dry-run true :debug true}) + +(defn restic-repo-check + [] + (println "restic-repo-check") + (println (rc/check file-config))) + +(restic-repo-check) \ No newline at end of file diff --git a/infrastructure/backup/image/resources2/test.bb b/infrastructure/backup/image/resources2/test.bb index fd4c043..fb0a550 100755 --- a/infrastructure/backup/image/resources2/test.bb +++ b/infrastructure/backup/image/resources2/test.bb @@ -1,82 +1,57 @@ #!/usr/bin/env bb (require '[babashka.tasks :as tasks] - '[dda.backup.core :as bc] - '[dda.backup.cred-rot :as cr] '[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 restic-repo {:password-file "/restic-pwd" + :new-password-file "/new-restic-pwd" + :restic-repository "/restic-repo" + :debug true}) (def file-config (merge restic-repo {:backup-path "files" :files ["/test-backup"] :restore-target-directory "/test-restore"})) - -(def db-config (merge restic-repo {:backup-path "db" - :pg-db "mydb" - :pg-user "user" - :pg-password "password"})) - -(def cred-config (merge file-config - {:restic-repository "/restic-repo/files" - :new-password-config {:new-password-file "new-pw" - :valid-from "2024-12-12 00:00:00"}})) - - (def dry-run {:dry-run true :debug true}) (defn prepare! [] (spit "/tmp/file_password" "file-password") - (spit "/restic-pwd" "ThePassword") - (spit "/new-pw" "newPassword") + (spit "/restic-pwd" "oldPassword") + (spit "/new-restic-pwd" "newPassword") (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)) - -(defn check-env-or-file - [] - (println "check-env-or-file") - (println (bc/env-or-file "FILE_PASSWORD")) - (println (bc/env-or-file "ENV_PASSWORD"))) + (tasks/shell "mkdir" "-p" "/test-restore")) (defn restic-repo-init! [] (println "restic-repo-init!") - (rc/init! file-config) - (rc/init! (merge db-config dry-run))) + (rc/init! file-config)) (defn restic-backup! [] (println "restic-backup!") - (bak/backup-file! file-config) - (bak/backup-db! (merge db-config dry-run))) + (bak/backup-file! file-config)) (defn list-snapshots! [] (println "list-snapshots!") - (rc/list-snapshots! file-config) - (rc/list-snapshots! (merge db-config dry-run))) + (rc/list-snapshots! file-config)) (defn restic-restore! [] (println "restic-restore!") - (rs/restore-file! file-config) - (pg/drop-create-db! (merge db-config dry-run)) - (rs/restore-db! (merge db-config dry-run))) + (rs/restore-file! file-config)) (defn change-password! [] (println "change-password!") - (cr/change-password! cred-config)) + (rc/change-password! file-config)) (prepare!) diff --git a/infrastructure/backup/test/resources/test.bb b/infrastructure/backup/test/resources/test.bb index 0e3c983..a129154 100755 --- a/infrastructure/backup/test/resources/test.bb +++ b/infrastructure/backup/test/resources/test.bb @@ -2,39 +2,33 @@ (require '[babashka.tasks :as tasks] '[dda.backup.core :as bc] - '[dda.backup.cred-rot :as cr] '[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 restic-repo {:password-file "/restic-pwd" + :new-password-file "/new-restic-pwd" + :restic-repository "/restic-repo" + :debug true}) (def file-config (merge restic-repo {:backup-path "files" :files ["/test-backup"] :restore-target-directory "/test-restore"})) - (def db-config (merge restic-repo {:backup-path "db" :pg-db "mydb" :pg-user "user" :pg-password "password"})) -(def cred-config (merge file-config - {:restic-repository "/restic-repo/files" - :new-password-config {:new-password-file "new-pw" - :valid-from "2024-12-12 00:00:00"}})) - - (def dry-run {:dry-run true :debug true}) (defn prepare! [] (spit "/tmp/file_password" "file-password") - (spit "/restic-pwd" "ThePassword") - (spit "/new-pw" "newPassword") + (spit "/restic-pwd" "oldPassword") + (spit "/new-restic-pwd" "newPassword") (tasks/shell "mkdir" "-p" "/test-backup") (spit "/test-backup/file" "I was here") @@ -43,41 +37,40 @@ (defn check-env-or-file [] - (println "check-env-or-file") + (println "\ncheck-env-or-file") (println (bc/env-or-file "FILE_PASSWORD")) (println (bc/env-or-file "ENV_PASSWORD"))) (defn restic-repo-init! [] - (println "restic-repo-init!") + (println "\nrestic-repo-init!") (rc/init! file-config) (rc/init! (merge db-config dry-run))) (defn restic-backup! [] - (println "restic-backup!") + (println "\nrestic-backup!") (bak/backup-file! file-config) (bak/backup-db! (merge db-config dry-run))) (defn list-snapshots! [] - (println "list-snapshots!") + (println "\nlist-snapshots!") (rc/list-snapshots! file-config) (rc/list-snapshots! (merge db-config dry-run))) (defn restic-restore! [] - (println "restic-restore!") + (println "\nrestic-restore!") (rs/restore-file! file-config) (pg/drop-create-db! (merge db-config dry-run)) (rs/restore-db! (merge db-config dry-run))) (defn change-password! [] - (println "change-password!") - (cr/change-password! cred-config)) - + (println "\nchange-password!") + (rc/change-password! file-config)) (prepare!) (check-env-or-file) @@ -86,3 +79,6 @@ (list-snapshots!) (restic-restore!) (change-password!) +(restic-backup!) +(list-snapshots!) +(restic-restore!) diff --git a/src/dda/backup/backup.clj b/src/dda/backup/backup.clj index 13d5e2d..5facd07 100644 --- a/src/dda/backup/backup.clj +++ b/src/dda/backup/backup.clj @@ -26,25 +26,31 @@ (s/merge ::pg/pg-config ::restic/restic-config)) +(defn- config-w-defaults + [config] + (if (restic/use-new-password? config) + (merge default config {:password-file (:new-password-file config)}) + (merge default config))) + (defn-spec backup-file! nil? [config ::backup-file-config] - (let [config-w-defaults (merge default config)] - (restic/unlock! config-w-defaults) + (let [config-2-use (config-w-defaults config)] + (restic/unlock! config-2-use) (i/execute! - (domain/backup-files-command config-w-defaults) - config-w-defaults) - (restic/forget! config-w-defaults))) + (domain/backup-files-command config-2-use) + config-2-use) + (restic/forget! config-2-use))) (defn-spec backup-db-roles! nil? [config ::pg-role-dump-config] - (let [config-w-defaults (merge default config)] - (restic/unlock! config-w-defaults) - (i/execute! (domain/backup-role-command config-w-defaults) config-w-defaults) - (restic/forget! config-w-defaults))) + (let [config-2-use (config-w-defaults config)] + (restic/unlock! config-2-use) + (i/execute! (domain/backup-role-command config-2-use) config-2-use) + (restic/forget! config-2-use))) (defn-spec backup-db! nil? [config ::pg-db-dump-config] - (let [config-w-defaults (merge default config)] - (restic/unlock! config-w-defaults) - (i/execute! (domain/backup-db-command config-w-defaults) config-w-defaults) - (restic/forget! config-w-defaults))) \ No newline at end of file + (let [config-2-use (config-w-defaults config)] + (restic/unlock! config-2-use) + (i/execute! (domain/backup-db-command config-2-use) config-2-use) + (restic/forget! config-2-use))) \ No newline at end of file diff --git a/src/dda/backup/cred_rot.clj b/src/dda/backup/cred_rot.clj deleted file mode 100644 index a5729b6..0000000 --- a/src/dda/backup/cred_rot.clj +++ /dev/null @@ -1,72 +0,0 @@ -(ns dda.backup.cred-rot - (:require - [orchestra.core :refer [defn-spec]] - [clojure.spec.alpha :as s] - [dda.backup.cred-rot.domain :as domain] - [dda.backup.infrastructure :as i] - [cljc.java-time.instant :as inst] - [cljc.java-time.local-date :as ld])) - -(s/def ::replace-until domain/timestamp?) -(s/def ::new-password-file string?) -(s/def ::new-password-config (s/keys :req-un [::new-password-file ::replace-until])) - -(s/def ::cred-rot - (s/keys :req-un [] - :opt-un [::new-password-config])) - -; Refer to "docs/CredentialRotation.md" for specifics -(defn-spec list-passwords! string? - [config ::cred-rot] - (i/execute-out! (domain/list-passwords-command config) config)) - -(defn-spec change-password-step! ::domain/set-password-action - [config ::cred-rot] - (when-some [new-password-config (:new-password-config config)] - (let [initial-passwords-list (domain/parse-response (list-passwords! config)) - action (domain/set-new-password-action - (ld/now) - initial-passwords-list - config)] - (cond - (= action :wait-for-new-pwd) - (println "nothing to do.") - (= action :change-pwd) - (i/execute! (domain/change-password-command config) config) - (= action :new-pwd-change-finished) - (println "pw-change sucessfull") - (= action :no-pwd-change-needed) - (println "nothing to do.") - :else - (throw (Exception. (str action))) - ) - (println initial-passwords-list) - (println action) - (println (list-passwords! config)) - action - ))) - -(defn-spec change-password! nil? - [config ::cred-rot] - (while (let [action (change-password-step! config) ] - (and (not= :no-pwd-change-needed action) - (not= :wait-for-new-pwd action))) - (println "call step") - )) - - -(defn-spec set-new-password-old! nil? - [config ::cred-rot] - (let [{:keys [new-password-file replace-until]} (:new-password-config config) - replace-until-date (ld/parse "2024-10-19 13:16:54" domain/timestamp-formatter)] - (if (not (nil? new-password-file)) - (let [parsed-passwords (domain/parse-response (list-passwords! config))] - (println (str "add-new-password: relace until " replace-until)) - (cond - (> 0 (compare - (:created (last parsed-passwords)) - replace-until-date)) - (do (println "add-new-password: set new pw") - (i/execute! (domain/add-password-command config) config)) - :else (println (str "else " (inst/now))))) - (println "add-new-password: there was no new pw configured")))) diff --git a/src/dda/backup/cred_rot/domain.clj b/src/dda/backup/cred_rot/domain.clj deleted file mode 100644 index 5ac8224..0000000 --- a/src/dda/backup/cred_rot/domain.clj +++ /dev/null @@ -1,111 +0,0 @@ -(ns dda.backup.cred-rot.domain - (:require - [orchestra.core :refer [defn-spec]] - [clojure.spec.alpha :as s] - [clojure.string :as str] - [dda.backup.core.domain :as cd] - [dda.backup.restic.domain :as rd] - [cheshire.core :as cc] - [cljc.java-time.local-date :as ld] - [cljc.java-time.format.date-time-formatter :as df])) - -(s/def ::new-password-file string?) -(s/def ::config (s/keys :req-un [::rd/restic-repository - ::rd/password-file] - :opt-un [::rd/certificate-file - ::new-password-file])) - -(def lowercase-numeric #"[a-z0-9]+") -(def alphanumeric #"[a-zA-Z0-9]+") -; true | false -(s/def ::current boolean?) -; 521e0760 -(s/def ::id (s/and string? #(re-matches lowercase-numeric %))) -; root -(s/def ::userName #(re-matches alphanumeric %)) -; backup-restore-65bd9b6ff5-z69sn -(s/def ::hostName (fn [in] (every? #(re-matches lowercase-numeric %) (str/split in #"-")))) -; "2024-10-18 13:08:16" -(def timestamp-formatter (df/of-pattern "yyyy-MM-dd HH:mm:ss")) -(defn timestamp-string? [in] - (try - (ld/parse in timestamp-formatter) - true - (catch Exception _ false))) -(def timestamp? any?) - -(s/def ::created timestamp?) - -(s/def ::entry (s/keys :opt-un [] - :req-un [::current ::id ::userName ::hostName ::created])) -(s/def ::response (s/coll-of ::entry)) - -(s/def ::set-password-action #{:error-parse-password :error-undefined - :wait-for-new-pwd :change-pwd :pwd-change-finished :no-pwd-change-needed}) - -(s/def ::valid-from timestamp-string?) -(s/def ::new-password-file string?) -(s/def ::new-password-config (s/keys :req-un [::new-password-file ::valid-from])) - -(s/def ::cred-rot - (s/keys :req-un [] - :opt-un [::new-password-config])) - -; Refer to "docs/CredentialRotation.md" for specifics -(defn-spec base-command ::cd/command - [config ::config - command ::cd/command] - (let [{:keys [restic-repository password-file - certificate-file new-password-file]} config] - (into - [] - (concat ["restic" "-r" restic-repository] - (cond - (some? certificate-file) - ["--cacert" certificate-file] - (some? password-file) - ["--password-file" password-file] - :else - []) - command)))) - -(defn-spec list-passwords-command ::cd/command - [config ::config] - (base-command config ["key" "list" "--json"])) - -(defn-spec change-password-command ::cd/command - [config ::config] - (let [{:keys [new-password-file]} (:new-password-config config)] - [(base-command config ["--new-password-file" new-password-file "key" "passwd"])])) - -(defn-spec parse-response ::response - [response string?] - (->> (cc/parse-string response true) - (map #(merge % {:created (ld/parse (:created %) timestamp-formatter)})) - (sort-by :created) - )) - -(defn-spec set-new-password-action ::set-password-action - [current-date timestamp? - parsed-response ::response - config ::cred-rot] - (if-let [new-password-config (:new-password-config config)] - (let [valid-from (:valid-from new-password-config) - valid-from-date (ld/parse valid-from timestamp-formatter)] - (cond - (> 1 (count parsed-response)) - :error-parse-password - (> 0 (compare current-date valid-from-date)) - :wait-for-new-pwd - (and (<= 0 (compare current-date valid-from-date)) - (= 1 (count parsed-response)) - (> 0 (compare (:created (last parsed-response)) valid-from-date))) - :change-pwd - (and (<= 0 (compare current-date valid-from-date)) - (= 1 (count parsed-response)) - (<= 0 (compare (:created (last parsed-response)) valid-from-date)) - (:current (last parsed-response))) - :pwd-change-finished - :else - :error-undefined)) - :no-pwd-change-needed)) diff --git a/src/dda/backup/infrastructure.clj b/src/dda/backup/infrastructure.clj index a0b8b89..15a3b45 100644 --- a/src/dda/backup/infrastructure.clj +++ b/src/dda/backup/infrastructure.clj @@ -3,16 +3,6 @@ [babashka.tasks :as t] [dda.backup.core.domain :as core])) -(defn-spec execute! nil? - [commands ::core/commands - config ::core/execution] - (let [{:keys [dry-run debug]} config] - (doseq [c commands] - (when debug - (println c)) - (when-not dry-run - (apply t/shell c))))) - (defn-spec execute-out! string? [command ::core/command config ::core/execution] @@ -20,4 +10,22 @@ (when debug (println command)) (when-not dry-run - (:out (t/shell {:out :string} (clojure.string/join " " command)))))) \ No newline at end of file + (:out (t/shell {:out :string :err :string} (clojure.string/join " " command)))))) + +(defn-spec execute-single! string? + [command ::core/command + config ::core/execution] + (let [{:keys [dry-run debug]} config] + (when debug + (println command)) + (when-not dry-run + (:out (t/shell {:err :string} (clojure.string/join " " command)))))) + + +(defn-spec execute! nil? + [commands ::core/commands + config ::core/execution] + (let [{:keys [dry-run debug]} config] + (doseq [c commands] + (when-not dry-run + (execute-single! c config))))) \ No newline at end of file diff --git a/src/dda/backup/restic.clj b/src/dda/backup/restic.clj index 419a7ce..3da74cb 100644 --- a/src/dda/backup/restic.clj +++ b/src/dda/backup/restic.clj @@ -12,39 +12,77 @@ :months-to-keep 12})) (s/def ::restic-config - (s/merge ::core/execution + (s/merge ::core/execution (s/keys :req-un [::domain/restic-repository ::domain/backup-path] :opt-un [::domain/certificate-file ::domain/password-file + ::domain/new-password-file ::domain/days-to-keep ::domain/months-to-keep]))) -(defn-spec initalized? boolean? +(s/def ::check-result #{:initialized :wrong-password :not-initialized :error}) + +(defn-spec check ::check-result [restic-config ::restic-config] (let [config-w-defaults (merge core/default restic-config)] (try (i/execute! (domain/check-repo-command config-w-defaults) config-w-defaults) - true - (catch Exception e false)))) + :initialized + (catch Exception e + (let [data (ex-data e) + parsed-error (domain/parse-check-error (get-in data [:proc :err]))] + (cond + (= parsed-error :not-initialized) :not-initialized + (= parsed-error :wrong-password) :wrong-password + :default :error)))))) + +(defn-spec use-new-password? boolean? + "deprecated" + [restic-config ::restic-config] + (if (contains? restic-config :new-password-file) + (= :initialized (check (merge restic-config {:password-file (:new-password-file restic-config)}))) + false)) + +(defn- config-w-defaults + [restic-config] + (if (use-new-password? restic-config) + (merge default restic-config {:password-file (:new-password-file restic-config)}) + (merge default restic-config))) + +(defn-spec initalized? boolean? + "deprecated" + [restic-config ::restic-config] + (let [config-2-use (config-w-defaults restic-config)] + (= :initialized (check config-2-use)))) (defn-spec init! nil? [restic-config ::restic-config] - (let [config-w-defaults (merge core/default restic-config)] - (when (not (initalized? config-w-defaults)) - (i/execute! (domain/init-repo-command config-w-defaults) config-w-defaults)))) + (let [config-2-use (config-w-defaults restic-config)] + (when (= :not-initialized (check config-2-use)) + (i/execute! (domain/init-repo-command config-2-use) config-2-use)))) (defn-spec unlock! nil? [restic-config ::restic-config] - (let [config-w-defaults (merge core/default restic-config)] - (i/execute! (domain/unlock-repo-command config-w-defaults) config-w-defaults))) + (let [config-2-use (config-w-defaults restic-config)] + (i/execute! (domain/unlock-repo-command config-2-use) config-2-use))) (defn-spec forget! nil? [restic-config ::restic-config] - (let [config-w-defaults (merge core/default restic-config)] - (i/execute! (domain/forget-command config-w-defaults) config-w-defaults))) + (let [config-2-use (config-w-defaults restic-config)] + (i/execute! (domain/forget-command config-2-use) config-2-use))) (defn-spec list-snapshots! nil? [restic-config ::restic-config] - (let [config-w-defaults (merge core/default restic-config)] - (i/execute! (domain/list-snapshot-command config-w-defaults) config-w-defaults))) + (let [config-2-use (config-w-defaults restic-config)] + (i/execute! (domain/list-snapshot-command config-2-use) config-2-use))) + +(defn-spec change-password! nil? + [restic-config ::restic-config] + (when (contains? restic-config :new-password-file) + (let [config-2-use (merge core/default restic-config)] + (when (= :initialized (check config-2-use)) + (do + (i/execute! (domain/change-password-command config-2-use) config-2-use) + (when-not (= :wrong-password (check config-2-use)) + (throw (Exception. "password-change did not work!")))))))) diff --git a/src/dda/backup/restic/domain.clj b/src/dda/backup/restic/domain.clj index d06ae11..10594e5 100644 --- a/src/dda/backup/restic/domain.clj +++ b/src/dda/backup/restic/domain.clj @@ -6,24 +6,28 @@ (s/def ::certificate-file string?) (s/def ::password-file string?) +(s/def ::new-password-file string?) (s/def ::restic-repository string?) (s/def ::backup-path string?) (s/def ::days-to-keep pos?) (s/def ::months-to-keep pos?) (s/def ::restic-config - (s/keys :req-un [::restic-repository - ::backup-path - ::days-to-keep + (s/keys :req-un [::restic-repository + ::backup-path + ::days-to-keep ::months-to-keep] - :opt-un [::certificate-file - ::password-file + :opt-un [::certificate-file + ::password-file + ::new-password-file ::cd/execution-directory])) +(s/def ::check-error #{:not-initialized :wrong-password :no-password :unknown}) + (defn-spec repo-command ::cd/command [config ::restic-config command ::cd/command] - (let [{:keys [certificate-file password-file execution-directory + (let [{:keys [certificate-file password-file execution-directory restic-repository backup-path]} config] (into [] @@ -60,7 +64,23 @@ (defn-spec forget-command ::cd/commands [config ::restic-config] (let [{:keys [days-to-keep months-to-keep]} config] - [(repo-command config ["forget" "--group-by" "" + [(repo-command config ["forget" "--group-by" "''" "--keep-last" "1" "--keep-daily" (str days-to-keep) - "--keep-monthly" (str months-to-keep) "--prune"])])) \ No newline at end of file + "--keep-monthly" (str months-to-keep) "--prune"])])) + +(defn-spec change-password-command ::cd/command + [config ::restic-config] + (if (contains? config :new-password-file) + (let [{:keys [new-password-file]} config] + [(repo-command config ["--new-password-file" new-password-file + "key" "passwd"])]) + (throw (Exception. "change-password: new password required")))) + +(defn-spec parse-check-error ::check-error + [error string?] + (cond + (clojure.string/includes? error "Fatal: unable to open config file") :not-initialized + (clojure.string/includes? error "Fatal: wrong password or no key found") :wrong-password + (clojure.string/includes? error "Resolving password failed") :no-password + :default :unknown)) diff --git a/src/dda/backup/restore.clj b/src/dda/backup/restore.clj index 63054e3..57a5988 100644 --- a/src/dda/backup/restore.clj +++ b/src/dda/backup/restore.clj @@ -20,19 +20,26 @@ (s/merge ::pg/pg-config (s/keys :req-un [::domain/snapshot-id]))) +(defn- config-w-defaults + [config] + (if (restic/use-new-password? config) + (merge default config {:password-file (:new-password-file config)}) + (merge default config))) + + (defn-spec restore-file! nil? [config ::restore-file-config] - (let [config-w-defaults (merge default config)] - (restic/unlock! config-w-defaults) + (let [config-2-use (config-w-defaults config)] + (restic/unlock! config-2-use) (i/execute! - (domain/restore-dir-command config-w-defaults) - config-w-defaults))) + (domain/restore-dir-command config-2-use) + config-2-use))) (defn-spec restore-db! nil? [config ::restore-db-config] - (let [config-w-defaults (merge default config)] - (restic/unlock! config-w-defaults) - (i/execute! (domain/restore-db-command config-w-defaults) config-w-defaults))) + (let [config-2-use (config-w-defaults config)] + (restic/unlock! config-2-use) + (i/execute! (domain/restore-db-command config-2-use) config-2-use))) ;; function restore-roles() { diff --git a/test/dda/backup/cred_rot/domain_test.clj b/test/dda/backup/cred_rot/domain_test.clj deleted file mode 100644 index 48222f9..0000000 --- a/test/dda/backup/cred_rot/domain_test.clj +++ /dev/null @@ -1,106 +0,0 @@ -(ns dda.backup.cred-rot.domain-test - (:require - [clojure.test :refer [deftest is]] - [clojure.spec.alpha :as s] - [clojure.spec.test.alpha :as st] - [cljc.java-time.local-date :as ld] - [dda.backup.cred-rot.domain :as cut])) - -(deftest test-spec-id - (is (s/valid? ::cut/id "521e0760")) - (is (s/valid? ::cut/id "test")) - (is (s/valid? ::cut/id "123456")) - (is (not (s/valid? ::cut/id "ROOT"))) - (is (not (s/valid? ::cut/id "Test!")))) - -(deftest test-spec-username - (is (s/valid? ::cut/userName "521e0760")) - (is (s/valid? ::cut/userName "Testuser")) - (is (s/valid? ::cut/userName "root")) - (is (s/valid? ::cut/userName "ROOT")) - (is (not (s/valid? ::cut/userName "test-user")))) - -(deftest test-spec-hostName - (let [valid #(s/valid? ::cut/hostName %)] - (is (valid "test-some-combination-2")) - (is (valid "backup-restore-65bd9b6ff5-z69sn")))) - -(deftest test-spec-timestamp - (let [valid #(s/valid? cut/timestamp-string? %)] - (is (valid "2024-10-18 13:08:16")) - (is (valid "2032-09-01 12:56:59")) - (is (not (valid "2024-13-5 13:08:16"))) - (is (not (valid "2024-6-42 13:08:16"))) - (is (not (valid "test"))))) - -(deftest test-parse-response - (is (= - (ld/parse "2024-10-19 13:16:54" cut/timestamp-formatter) - (:created - (first - (cut/parse-response "[ - { - \"current\": false, - \"id\": \"521e0760\", - \"userName\": \"root\", - \"hostName\": \"backup-restore-65bd9b6ff5-z69sn\", - \"created\": \"2024-11-18 13:08:16\" - }, - { - \"current\": true, - \"id\": \"b67161fb\", - \"userName\": \"root\", - \"hostName\": \"backup-restore-65bd9b6ff5-z69sn\", - \"created\": \"2024-10-19 13:16:54\" - } -]")))))) - -(deftest test-set-new-password-action - (is (= :error-parse-password - (cut/set-new-password-action - (ld/parse "2024-10-19 13:16:54" cut/timestamp-formatter) - [] - {:new-password-config {:new-password-file "new-pw-file" - :valid-from "2024-11-29 12:00:16"}}))) - (is (= :wait-for-new-pwd - (cut/set-new-password-action - (ld/parse "2024-10-19 13:16:54" cut/timestamp-formatter) - [{:current true - :id "a1" - :userName "root" - :hostName "host" - :created (ld/parse "2023-01-01 00:00:00" cut/timestamp-formatter)}] - {:new-password-config {:new-password-file "new-pw-file" - :valid-from "2024-11-29 12:00:16"}}))) - (is (= :change-pwd - (cut/set-new-password-action - (ld/parse "2024-11-29 13:16:54" cut/timestamp-formatter) - [{:current true - :id "a1" - :userName "root" - :hostName "host" - :created (ld/parse "2023-01-01 00:00:00" cut/timestamp-formatter)}] - {:new-password-config {:new-password-file "new-pw-file" - :valid-from "2024-11-29 12:00:16"}}))) - - (is (= :pwd-change-finished - (cut/set-new-password-action - (ld/parse "2024-11-29 13:16:55" cut/timestamp-formatter) - [{:current true - :id "a2" - :userName "root" - :hostName "host" - :created (ld/parse "2024-11-29 13:16:54" cut/timestamp-formatter)}] - {:new-password-config {:new-password-file "new-pw-file" - :valid-from "2024-11-29 12:00:16"}}))) - - (is (= :no-pwd-change-needed - (cut/set-new-password-action - (ld/parse "2024-11-29 13:16:55" cut/timestamp-formatter) - [{:current true - :id "a2" - :userName "root" - :hostName "host" - :created (ld/parse "2024-11-29 13:16:54" cut/timestamp-formatter)}] - {}))) - ) \ No newline at end of file diff --git a/test/dda/backup/restic/domain_test.clj b/test/dda/backup/restic/domain_test.clj index d4e7a4f..44453c6 100644 --- a/test/dda/backup/restic/domain_test.clj +++ b/test/dda/backup/restic/domain_test.clj @@ -64,9 +64,34 @@ (deftest should-calculate-forget-command (is (= [["restic" "-r" "repo/dir" "-v" "forget" - "--group-by" "" "--keep-last" "1" + "--group-by" "''" "--keep-last" "1" "--keep-daily" "39" "--keep-monthly" "3" "--prune"]] (cut/forget-command {:restic-repository "repo" :backup-path "dir" :days-to-keep 39 - :months-to-keep 3})))) \ No newline at end of file + :months-to-keep 3})))) + +(deftest should-calculate-change-password-command + (is (= [["restic" + "-r" + "repo/dir" + "-v" + "--new-password-file" + "/new-pwd" + "key" + "passwd"]] + (cut/change-password-command {:restic-repository "repo" + :new-password-file "/new-pwd" + :backup-path "dir" + :days-to-keep 39 + :months-to-keep 3})))) + +(deftest should-parse-check-error + (is (= :not-initialized + (cut/parse-check-error "Fatal: unable to open config file: stat /restic-repo/files/config: no such file or directory\nIs there a repository at the following location?\n/restic-repo/files" ) + )) + (is (= :wrong-password + (cut/parse-check-error "Fatal: wrong password or no key found\n"))) + (is (= :no-password + (cut/parse-check-error "Resolving password failed: Fatal: /restic-pwd does not exist\n"))) + )