diff --git a/doc/tryItOut.png b/doc/tryItOut.png index 19ff34b..3ba2d3b 100644 Binary files a/doc/tryItOut.png and b/doc/tryItOut.png differ diff --git a/infrastructure/backup/image/resources/change-password.bb b/infrastructure/backup/image/resources/change-password.bb new file mode 100755 index 0000000..d8c1b82 --- /dev/null +++ b/infrastructure/backup/image/resources/change-password.bb @@ -0,0 +1,26 @@ +#!/usr/bin/env bb +(require + '[babashka.fs :as fs]) +(-> "/usr/local/bin/config.clj" fs/file load-file) + +(require + '[dda.backup.core :as bc] + '[dda.backup.restic :as rc] + '[config :as cf]) + +(def file-pw-change-config (merge cf/file-config {:new-password-file (bc/env-or-file "RESTIC_NEW_PASSWORD_FILE")})) +(def db-pw-change-config (merge cf/db-config {:new-password-file (bc/env-or-file "RESTIC_NEW_PASSWORD_FILE")})) +(def db-role-pw-change-config (merge cf/db-role-config {:new-password-file (bc/env-or-file "RESTIC_NEW_PASSWORD_FILE")})) + +(defn prepare! + [] + (bc/create-aws-credentials! cf/aws-config)) + +(defn change-password! + [] + (rc/change-password! file-pw-change-config) + (rc/change-password! db-pw-change-config) + (rc/change-password! db-role-pw-change-config)) + +(prepare!) +(change-password!) diff --git a/infrastructure/backup/test/Dockerfile b/infrastructure/backup/test/Dockerfile index ffa87cf..ce0e683 100644 --- a/infrastructure/backup/test/Dockerfile +++ b/infrastructure/backup/test/Dockerfile @@ -1,4 +1,4 @@ FROM c4k-cloud-backup:latest ADD resources /tmp/ -RUN RESTIC_PASSWORD_FILE=/tmp/file_password RESTIC_REPOSITORY=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 +RUN RESTIC_PASSWORD_FILE=/tmp/file_password RESTIC_NEW_PASSWORD_FILE=/tmp/new_file_password RESTIC_REPOSITORY=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/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 4a1a6ef..203fd27 100755 --- a/infrastructure/backup/test/resources/test.bb +++ b/infrastructure/backup/test/resources/test.bb @@ -4,12 +4,15 @@ (-> "/usr/local/bin/config.clj" fs/file load-file) (require '[babashka.tasks :as tasks] + '[dda.backup.core :as bc] '[dda.backup.restic :as rc] '[dda.backup.postgresql :as pg] '[dda.backup.backup :as bak] '[dda.backup.restore :as rs] '[config :as cf]) +(def file-pw-change-config (merge cf/file-config {:new-password-file (bc/env-or-file "RESTIC_NEW_PASSWORD_FILE")})) + (defn prepare! [] (tasks/shell "mkdir" "-p" "/var/backups/") @@ -42,8 +45,14 @@ (rs/restore-db! (merge cf/db-config cf/dry-run)) (rs/restore-file! (merge cf/file-restore-config cf/dry-run))) +(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!) diff --git a/src/main/cljc/dda/c4k_nextcloud/backup.cljc b/src/main/cljc/dda/c4k_nextcloud/backup.cljc index b2ebe44..a4223b9 100644 --- a/src/main/cljc/dda/c4k_nextcloud/backup.cljc +++ b/src/main/cljc/dda/c4k_nextcloud/backup.cljc @@ -1,13 +1,13 @@ (ns dda.c4k-nextcloud.backup - (:require - [clojure.spec.alpha :as s] - #?(:clj [orchestra.core :refer [defn-spec]] - :cljs [orchestra.core :refer-macros [defn-spec]]) - [dda.c4k-common.yaml :as yaml] - [dda.c4k-common.base64 :as b64] - [dda.c4k-common.common :as cm] - [dda.c4k-common.predicate :as cp] - #?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]]))) + (:require + [clojure.spec.alpha :as s] + #?(:clj [orchestra.core :refer [defn-spec]] + :cljs [orchestra.core :refer-macros [defn-spec]]) + [dda.c4k-common.yaml :as yaml] + [dda.c4k-common.base64 :as b64] + [dda.c4k-common.common :as cm] + [dda.c4k-common.predicate :as cp] + #?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]]))) (s/def ::aws-access-key-id cp/bash-env-string?) (s/def ::aws-secret-access-key cp/bash-env-string?) @@ -17,8 +17,8 @@ (s/def ::config (s/keys :req-un [::restic-repository])) -(s/def ::auth (s/keys :req-un [::restic-password ::aws-access-key-id ::aws-secret-access-key])) - +(s/def ::auth (s/keys :req-un [::restic-password ::aws-access-key-id ::aws-secret-access-key] + :opt-un [::restic-new-password])) #?(:cljs (defmethod yaml/load-resource :backup [resource-name] @@ -33,21 +33,20 @@ (defn-spec generate-cron map? [] - (yaml/from-string (yaml/load-resource "backup/cron.yaml"))) + (yaml/from-string (yaml/load-resource "backup/cron.yaml"))) (defn-spec generate-backup-restore-deployment map? - [my-conf ::config] - (let [backup-restore-yaml (yaml/load-as-edn "backup/backup-restore-deployment.yaml")] - (if (and (contains? my-conf :local-integration-test) - (= true (:local-integration-test my-conf))) - (cm/replace-named-value backup-restore-yaml "CERTIFICATE_FILE" "/var/run/secrets/localstack-secrets/ca.crt") - backup-restore-yaml))) + [conf ::config] + (yaml/load-as-edn "backup/backup-restore-deployment.yaml")) (defn-spec generate-secret map? - [my-auth ::auth] - (let [{:keys [aws-access-key-id aws-secret-access-key restic-password]} my-auth] - (-> - (yaml/load-as-edn "backup/secret.yaml") - (cm/replace-key-value :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 :restic-password (b64/encode restic-password))))) + [auth ::auth] + (let [{:keys [aws-access-key-id aws-secret-access-key + restic-password restic-new-password]} auth] + (as-> (yaml/load-as-edn "backup/secret.yaml") res + (cm/replace-key-value res :aws-access-key-id (b64/encode aws-access-key-id)) + (cm/replace-key-value res :aws-secret-access-key (b64/encode aws-secret-access-key)) + (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)))) diff --git a/src/main/resources/backup/backup-restore-deployment.yaml b/src/main/resources/backup/backup-restore-deployment.yaml index 7e8d0a0..1b68951 100644 --- a/src/main/resources/backup/backup-restore-deployment.yaml +++ b/src/main/resources/backup/backup-restore-deployment.yaml @@ -59,8 +59,6 @@ spec: 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 - value: "" volumeMounts: - name: cloud-data-volume mountPath: /var/backups diff --git a/src/main/resources/backup/credential-rotation.yaml b/src/main/resources/backup/credential-rotation.yaml deleted file mode 100644 index fa3c9ca..0000000 --- a/src/main/resources/backup/credential-rotation.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: rotation-credential-secret - namespace: nextcloud -type: Opaque -data: - rotation-credential: "dGVzdAo=" \ No newline at end of file diff --git a/src/main/resources/backup/cron.yaml b/src/main/resources/backup/cron.yaml index a7c1cad..d1ae3fc 100644 --- a/src/main/resources/backup/cron.yaml +++ b/src/main/resources/backup/cron.yaml @@ -53,6 +53,8 @@ spec: key: restic-repository - name: RESTIC_PASSWORD_FILE value: /var/run/secrets/backup-secrets/restic-password + - name: RESTIC_NEW_PASSWORD_FILE + value: /var/run/secrets/backup-secrets/restic-new-password volumeMounts: - name: cloud-data-volume mountPath: /var/backups diff --git a/src/main/resources/backup/secret.yaml b/src/main/resources/backup/secret.yaml index c706b1b..02a03eb 100644 --- a/src/main/resources/backup/secret.yaml +++ b/src/main/resources/backup/secret.yaml @@ -7,5 +7,4 @@ type: Opaque data: aws-access-key-id: "aws-access-key-id" aws-secret-access-key: "aws-secret-access-key" - restic-password: "restic-password" - restic-new-password: "restic-new-password" \ No newline at end of file + restic-password: "restic-password" \ No newline at end of file diff --git a/src/test/cljc/dda/c4k_nextcloud/backup_test.cljc b/src/test/cljc/dda/c4k_nextcloud/backup_test.cljc index 4f651b7..e3ca309 100644 --- a/src/test/cljc/dda/c4k_nextcloud/backup_test.cljc +++ b/src/test/cljc/dda/c4k_nextcloud/backup_test.cljc @@ -15,8 +15,25 @@ :metadata {:name "backup-secret", :namespace "nextcloud"} :type "Opaque" :data - {:aws-access-key-id "YXdzLWlk", :aws-secret-access-key "YXdzLXNlY3JldA==", :restic-password "cmVzdGljLXB3"}} - (cut/generate-secret {:aws-access-key-id "aws-id" :aws-secret-access-key "aws-secret" :restic-password "restic-pw"})))) + {:aws-access-key-id "YXdzLWlk", + :aws-secret-access-key "YXdzLXNlY3JldA==", + :restic-password "cmVzdGljLXB3"}} + (cut/generate-secret {:aws-access-key-id "aws-id" + :aws-secret-access-key "aws-secret" + :restic-password "restic-pw"}))) + (is (= {:apiVersion "v1" + :kind "Secret" + :metadata {:name "backup-secret", :namespace "nextcloud"} + :type "Opaque" + :data + {:aws-access-key-id "YXdzLWlk", + :aws-secret-access-key "YXdzLXNlY3JldA==", + :restic-password "cmVzdGljLXB3" + :restic-new-password "bmV3LXJlc3RpYy1wdw=="}} + (cut/generate-secret {:aws-access-key-id "aws-id" + :aws-secret-access-key "aws-secret" + :restic-password "restic-pw" + :restic-new-password "new-restic-pw"})))) (deftest should-generate-config (is (= {:apiVersion "v1" @@ -68,7 +85,8 @@ {:name "AWS_ACCESS_KEY_ID_FILE", :value "/var/run/secrets/backup-secrets/aws-access-key-id"} {:name "AWS_SECRET_ACCESS_KEY_FILE", :value "/var/run/secrets/backup-secrets/aws-secret-access-key"} {:name "RESTIC_REPOSITORY", :valueFrom {:configMapKeyRef {:name "backup-config", :key "restic-repository"}}} - {:name "RESTIC_PASSWORD_FILE", :value "/var/run/secrets/backup-secrets/restic-password"}] + {:name "RESTIC_PASSWORD_FILE", :value "/var/run/secrets/backup-secrets/restic-password"} + {:name "RESTIC_NEW_PASSWORD_FILE", :value "/var/run/secrets/backup-secrets/restic-new-password"}] :volumeMounts [{:name "cloud-data-volume", :mountPath "/var/backups"} {:name "backup-secret-volume", :mountPath "/var/run/secrets/backup-secrets", :readOnly true} diff --git a/src/test/resources/nextcloud-test/valid-auth.yaml b/src/test/resources/nextcloud-test/valid-auth.yaml index 6d88bf3..043a00c 100644 --- a/src/test/resources/nextcloud-test/valid-auth.yaml +++ b/src/test/resources/nextcloud-test/valid-auth.yaml @@ -5,6 +5,7 @@ nextcloud-admin-password: "cloudpassword" aws-access-key-id: "aws-id" aws-secret-access-key: "aws-secret" restic-password: "restic-password" +restic-new-password: "restic-new-password" mon-auth: grafana-cloud-user: "user" grafana-cloud-password: "password" \ No newline at end of file