From 9201aba498a59e9c2a80ef65712a476c9f742eba Mon Sep 17 00:00:00 2001
From: Clemens <clemens.geibel@meissa-gmbh.de.de>
Date: Mon, 3 Jun 2024 10:05:22 +0200
Subject: [PATCH 01/21] make superuser creation manual

---
 README.md                                     | 8 ++++++++
 src/main/resources/taiga/back-deployment.yaml | 2 +-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 3389fb1..e858ee6 100644
--- a/README.md
+++ b/README.md
@@ -63,10 +63,18 @@ To set up you need:
 Apply this file on your cluster with `kubectl apply -f application.yaml`.  
 Done.
 
+## Setup
+
+`python manage.py createsuperuser --noinput`
+
 ## Administration
 
 You can access the administration of the taiga installation via: your.taiga.url/admin/
 
+In order to login, you first have to create a superuser.
+1. Connect to taiga-back pod: `kubectl exec -it taiga-back-deployment-... -- bash`
+2. `source /opt/venv/bin/activate && python manage.py createsuperuser --noinput`
+
 ## Backup
 
 You need some form of cloud storage like AWS buckets and the respective access credentials
diff --git a/src/main/resources/taiga/back-deployment.yaml b/src/main/resources/taiga/back-deployment.yaml
index f389e23..96b994f 100644
--- a/src/main/resources/taiga/back-deployment.yaml
+++ b/src/main/resources/taiga/back-deployment.yaml
@@ -20,7 +20,7 @@ spec:
         image: taigaio/taiga-back:latest 
         imagePullPolicy: IfNotPresent
         command: ["/bin/bash"]
-        args: ["-c", "source /opt/venv/bin/activate && CELERY_ENABLE=true python manage.py migrate && sleep 15 && python manage.py createsuperuser --noinput"]
+        args: ["-c", "source /opt/venv/bin/activate && CELERY_ENABLE=true python manage.py migrate && sleep 15"]
         ports:
         - name: http
           containerPort: 8000

From 975ea812624ee4d6b9d4fcc1eaf11251421aeed5 Mon Sep 17 00:00:00 2001
From: patdyn <erik.seiert@meissa-gmbh.de>
Date: Tue, 6 Aug 2024 13:14:51 +0200
Subject: [PATCH 02/21] [Skip-CI] Add website to contact info

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 3389fb1..c582437 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
 
 [![Clojars Project](https://img.shields.io/clojars/v/org.domaindrivenarchitecture/c4k-taiga.svg)](https://clojars.org/org.domaindrivenarchitecture/c4k-taiga) [![pipeline status](https://gitlab.com/domaindrivenarchitecture/c4k-taiga/badges/master/pipeline.svg)](https://gitlab.com/domaindrivenarchitecture/c4k-taiga/-/commits/main) 
 
-[<img src="https://domaindrivenarchitecture.org/img/delta-chat.svg" width=20 alt="DeltaChat"> chat over e-mail](mailto:buero@meissa-gmbh.de?subject=community-chat) | [<img src="https://meissa-gmbh.de/img/community/Mastodon_Logotype.svg" width=20 alt="team@social.meissa-gmbh.de"> team@social.meissa-gmbh.de](https://social.meissa-gmbh.de/@team) | [taiga & Blog](https://domaindrivenarchitecture.org)
+[<img src="https://domaindrivenarchitecture.org/img/delta-chat.svg" width=20 alt="DeltaChat"> chat over e-mail](mailto:buero@meissa-gmbh.de?subject=community-chat) | [<img src="https://meissa.de/images/parts/contact/mastodon36_hue9b2464f10b18e134322af482b9c915e_5501_filter_14705073121015236177.png" width=20 alt="M"> meissa@social.meissa-gmbh.de](https://social.meissa-gmbh.de/@meissa) | [Blog](https://domaindrivenarchitecture.org) | [Website](https://meissa.de)
 
 ## Purpose
 
@@ -90,7 +90,7 @@ For more details about our repository model see: https://repo.prod.meissa.de/mei
 
 ## License
 
-Copyright © 2022 meissa GmbH
+Copyright © 2024 meissa GmbH
 Licensed under the [Apache License, Version 2.0](LICENSE) (the "License")
 Pls. find licenses of our subcomponents [here](doc/SUBCOMPONENT_LICENSE)
 

From 278b7350d99517bd45ee37af7826f74bebcda910 Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Tue, 14 Jan 2025 10:55:48 +0100
Subject: [PATCH 03/21] update versions

---
 package.json    |  8 ++++----
 project.clj     | 10 +++++-----
 shadow-cljs.edn |  2 +-
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/package.json b/package.json
index 74abe2c..fb42886 100644
--- a/package.json
+++ b/package.json
@@ -23,11 +23,11 @@
         "url": "https://gitlab.com/domaindrivenarchitecture/c4k-taiga/issues"
     },
     "dependencies": {
-        "js-base64": "^3.7.5",
-        "js-yaml": "^4.0.0"
+        "js-base64": "^3.7.7",
+        "js-yaml": "^4.1.0"
     },
     "devDependencies": {
-        "shadow-cljs": "^2.11.18",
-        "source-map-support": "^0.5.19"
+        "shadow-cljs": "^2.28.20",
+        "source-map-support": "^0.5.21"
     }
 }
\ No newline at end of file
diff --git a/project.clj b/project.clj
index f81cafa..903f955 100644
--- a/project.clj
+++ b/project.clj
@@ -3,9 +3,9 @@
   :url "https://domaindrivenarchitecture.org"
   :license {:name "Apache License, Version 2.0"
             :url "https://www.apache.org/licenses/LICENSE-2.0.html"}
-  :dependencies [[org.clojure/clojure "1.11.1"]
-                 [org.clojure/tools.reader "1.4.0"]                 
-                 [org.domaindrivenarchitecture/c4k-common-clj "6.1.3"]
+  :dependencies [[org.clojure/clojure "1.12.0"]
+                 [org.clojure/tools.reader "1.5.0"]                 
+                 [org.domaindrivenarchitecture/c4k-common-clj "9.0.1"]
                  [hickory "0.7.1" :exclusions [viebel/codox-klipse-theme]]]
   :target-path "target/%s/"
   :source-paths ["src/main/cljc"
@@ -23,9 +23,9 @@
                        :main dda.c4k-taiga.uberjar
                        :uberjar-name "c4k-taiga-standalone.jar"
                        :dependencies [[org.clojure/tools.cli "1.1.230"]
-                                      [ch.qos.logback/logback-classic "1.5.0"
+                                      [ch.qos.logback/logback-classic "1.5.16"
                                        :exclusions [com.sun.mail/javax.mail]]
-                                      [org.slf4j/jcl-over-slf4j "2.0.12"]
+                                      [org.slf4j/jcl-over-slf4j "2.0.16"]
                                       [com.github.clj-easy/graal-build-time "1.0.5"]]}}
   :release-tasks [["test"]
                   ["vcs" "assert-committed"]
diff --git a/shadow-cljs.edn b/shadow-cljs.edn
index f9ee9c9..d247142 100644
--- a/shadow-cljs.edn
+++ b/shadow-cljs.edn
@@ -4,7 +4,7 @@
                 "src/test/cljc"
                 "src/test/cljs"
                 "src/test/resources"]
- :dependencies [[org.domaindrivenarchitecture/c4k-common-cljs "6.1.3"]
+ :dependencies [[org.domaindrivenarchitecture/c4k-common-cljs "9.0.1"]
                 [hickory "0.7.1"]]
  :builds {:frontend {:target :browser
                      :modules {:main {:init-fn dda.c4k-taiga.browser/init}}

From a9bc4c90634eff6632b2aa0b47d71fe6d2affee9 Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Tue, 14 Jan 2025 10:56:06 +0100
Subject: [PATCH 04/21] add first backup test

---
 src/main/cljc/dda/c4k_taiga/backup.cljc      | 30 +++++++++++---------
 src/main/resources/backup/config.yaml        |  1 +
 src/test/cljc/dda/c4k_taiga/backup_test.cljc | 21 ++++++++++++++
 3 files changed, 39 insertions(+), 13 deletions(-)
 create mode 100644 src/test/cljc/dda/c4k_taiga/backup_test.cljc

diff --git a/src/main/cljc/dda/c4k_taiga/backup.cljc b/src/main/cljc/dda/c4k_taiga/backup.cljc
index 3d8cba3..da77b15 100644
--- a/src/main/cljc/dda/c4k_taiga/backup.cljc
+++ b/src/main/cljc/dda/c4k_taiga/backup.cljc
@@ -1,27 +1,31 @@
 (ns dda.c4k-taiga.backup
  (:require
   [clojure.spec.alpha :as s]
-  #?(:cljs [shadow.resource :as rc])
+  #?(: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 pd]))
+  [dda.c4k-common.predicate :as p]
+  #?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]])))
 
-(s/def ::aws-access-key-id pd/bash-env-string?)
-(s/def ::aws-secret-access-key pd/bash-env-string?)
-(s/def ::restic-password pd/bash-env-string?)
-(s/def ::restic-repository pd/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 ::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 ::config (s/keys :req-un [::restic-repository]))
+
+(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]
-     (case resource-name
-       "backup/config.yaml" (rc/inline "backup/config.yaml")
-       "backup/cron.yaml" (rc/inline "backup/cron.yaml")
-       "backup/secret.yaml" (rc/inline "backup/secret.yaml")
-       "backup/backup-restore-deployment.yaml" (rc/inline "backup/backup-restore-deployment.yaml")
-       (throw (js/Error. "Undefined Resource!")))))
+     (get (inline-resources "backup") resource-name)))
 
-(defn generate-config [my-conf]
+(defn-spec generate-config p/map-or-seq?
+  [my-conf ::config]
   (let [{:keys [restic-repository]} my-conf]
     (->
      (yaml/load-as-edn "backup/config.yaml")
diff --git a/src/main/resources/backup/config.yaml b/src/main/resources/backup/config.yaml
index 36781e7..aaceaad 100644
--- a/src/main/resources/backup/config.yaml
+++ b/src/main/resources/backup/config.yaml
@@ -2,6 +2,7 @@ apiVersion: v1
 kind: ConfigMap
 metadata:
   name: backup-config
+  namespace: taiga
   labels:
     app.kubernetes.io/name: backup
     app.kubernetes.io/part-of: taiga
diff --git a/src/test/cljc/dda/c4k_taiga/backup_test.cljc b/src/test/cljc/dda/c4k_taiga/backup_test.cljc
new file mode 100644
index 0000000..47703b2
--- /dev/null
+++ b/src/test/cljc/dda/c4k_taiga/backup_test.cljc
@@ -0,0 +1,21 @@
+(ns dda.c4k-taiga.backup-test
+  (:require
+   #?(:clj [clojure.test :refer [deftest is are testing run-tests]]
+      :cljs [cljs.test :refer-macros [deftest is are testing run-tests]])
+   [clojure.spec.test.alpha :as st]
+   [dda.c4k-taiga.backup :as cut]))
+
+(st/instrument `cut/generate-secret)
+(st/instrument `cut/generate-config)
+(st/instrument `cut/generate-cron)
+
+(deftest should-generate-config
+  (is (= {:apiVersion "v1"
+          :kind "ConfigMap"
+          :metadata {:name "backup-config"
+                     :namespace "taiga"
+                     :labels {:app.kubernetes.io/name "backup"
+                              :app.kubernetes.io/part-of "taiga"}}
+          :data
+          {:restic-repository "s3:restic-repository"}}
+         (cut/generate-config {:restic-repository "s3:restic-repository"}))))
\ No newline at end of file

From 7d7526132b8386f789b42db6d43866f5bd3670ec Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Tue, 14 Jan 2025 11:04:09 +0100
Subject: [PATCH 05/21] test & namespace for backup

---
 src/main/cljc/dda/c4k_taiga/backup.cljc       | 49 ++++++++++---------
 .../backup/backup-restore-deployment.yaml     |  1 +
 src/main/resources/backup/cron.yaml           |  1 +
 src/main/resources/backup/secret.yaml         |  1 +
 src/test/cljc/dda/c4k_taiga/backup_test.cljc  | 28 ++++++++++-
 5 files changed, 56 insertions(+), 24 deletions(-)

diff --git a/src/main/cljc/dda/c4k_taiga/backup.cljc b/src/main/cljc/dda/c4k_taiga/backup.cljc
index da77b15..c934ff4 100644
--- a/src/main/cljc/dda/c4k_taiga/backup.cljc
+++ b/src/main/cljc/dda/c4k_taiga/backup.cljc
@@ -1,13 +1,13 @@
 (ns dda.c4k-taiga.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 p]
-  #?(: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 p]
+   #?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]])))
 
 (s/def ::aws-access-key-id p/bash-env-string?)
 (s/def ::aws-secret-access-key p/bash-env-string?)
@@ -31,19 +31,22 @@
      (yaml/load-as-edn "backup/config.yaml")
      (cm/replace-key-value :restic-repository restic-repository))))
 
-(defn generate-cron []
-   (yaml/load-as-edn "backup/cron.yaml"))
+(defn-spec generate-cron p/map-or-seq?
+  []
+  (yaml/load-as-edn "backup/cron.yaml"))
 
-(defn generate-backup-restore-deployment [my-conf]
-  (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)))
+(defn-spec generate-backup-restore-deployment p/map-or-seq?
+  [my-conf ::config]
+  (yaml/load-as-edn "backup/backup-restore-deployment.yaml"))
 
-(defn generate-secret [my-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)))))
+(defn-spec generate-secret p/map-or-seq?
+  [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 d4379ab..557d18c 100644
--- a/src/main/resources/backup/backup-restore-deployment.yaml
+++ b/src/main/resources/backup/backup-restore-deployment.yaml
@@ -2,6 +2,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: backup-restore
+  namespace: taiga
 spec:
   replicas: 0
   selector:
diff --git a/src/main/resources/backup/cron.yaml b/src/main/resources/backup/cron.yaml
index aafe3ee..aa4c419 100644
--- a/src/main/resources/backup/cron.yaml
+++ b/src/main/resources/backup/cron.yaml
@@ -2,6 +2,7 @@ apiVersion: batch/v1
 kind: CronJob
 metadata:
   name: taiga-backup
+  namespace: taiga
   labels:
     app.kubernetes.part-of: taiga
 spec:
diff --git a/src/main/resources/backup/secret.yaml b/src/main/resources/backup/secret.yaml
index c5809e0..7f4a98f 100644
--- a/src/main/resources/backup/secret.yaml
+++ b/src/main/resources/backup/secret.yaml
@@ -2,6 +2,7 @@ apiVersion: v1
 kind: Secret
 metadata:
   name: backup-secret
+  namespace: taiga
 type: Opaque
 data:
   aws-access-key-id: aws-access-key-id
diff --git a/src/test/cljc/dda/c4k_taiga/backup_test.cljc b/src/test/cljc/dda/c4k_taiga/backup_test.cljc
index 47703b2..9769c78 100644
--- a/src/test/cljc/dda/c4k_taiga/backup_test.cljc
+++ b/src/test/cljc/dda/c4k_taiga/backup_test.cljc
@@ -18,4 +18,30 @@
                               :app.kubernetes.io/part-of "taiga"}}
           :data
           {:restic-repository "s3:restic-repository"}}
-         (cut/generate-config {:restic-repository "s3:restic-repository"}))))
\ No newline at end of file
+         (cut/generate-config {:restic-repository "s3:restic-repository"}))))
+
+(deftest should-generate-secret
+  (is (= {:apiVersion "v1"
+          :kind "Secret"
+          :metadata {:name "backup-secret", :namespace "taiga"}
+          :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"})))
+  (is (= {:apiVersion "v1"
+          :kind "Secret"
+          :metadata {:name "backup-secret", :namespace "taiga"}
+          :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"}))))
\ No newline at end of file

From ddda23bb10118c8ab42fd036de943100a73eadf2 Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Tue, 14 Jan 2025 11:47:58 +0100
Subject: [PATCH 06/21] add namespace & speced tests to taiga

---
 src/main/cljc/dda/c4k_taiga/taiga.cljc        | 154 ++++++++----------
 .../resources/taiga/async-deployment.yaml     |   1 +
 .../taiga/async-rabbitmq-deployment.yaml      |   1 +
 .../taiga/async-rabbitmq-service.yaml         |   1 +
 src/main/resources/taiga/async-service.yaml   |   1 +
 src/main/resources/taiga/back-deployment.yaml |   1 +
 src/main/resources/taiga/back-service.yaml    |   2 +-
 src/main/resources/taiga/configmap.yaml       |   2 +-
 .../resources/taiga/events-deployment.yaml    |   1 +
 .../taiga/events-rabbitmq-deployment.yaml     |   1 +
 .../taiga/events-rabbitmq-service.yaml        |   1 +
 src/main/resources/taiga/events-service.yaml  |   2 +-
 .../resources/taiga/front-deployment.yaml     |   1 +
 src/main/resources/taiga/front-service.yaml   |   2 +-
 .../resources/taiga/gateway-configmap.yaml    |   1 +
 .../resources/taiga/gateway-deployment.yaml   |   1 +
 src/main/resources/taiga/gateway-service.yaml |   2 +-
 .../resources/taiga/protected-deployment.yaml |   1 +
 .../resources/taiga/protected-service.yaml    |   2 +-
 .../resources/taiga/pvc-taiga-media-data.yaml |   2 +-
 .../taiga/pvc-taiga-static-data.yaml          |   2 +-
 .../resources/taiga/rabbitmq-pvc-async.yaml   |   2 +-
 .../resources/taiga/rabbitmq-pvc-events.yaml  |   2 +-
 src/main/resources/taiga/secret.yaml          |   1 +
 src/test/cljc/dda/c4k_taiga/taiga_test.cljc   |  35 ++--
 25 files changed, 107 insertions(+), 115 deletions(-)

diff --git a/src/main/cljc/dda/c4k_taiga/taiga.cljc b/src/main/cljc/dda/c4k_taiga/taiga.cljc
index ba8dfb7..9dd1450 100644
--- a/src/main/cljc/dda/c4k_taiga/taiga.cljc
+++ b/src/main/cljc/dda/c4k_taiga/taiga.cljc
@@ -1,35 +1,16 @@
 (ns dda.c4k-taiga.taiga
   (:require
    [clojure.spec.alpha :as s]
-   #?(:cljs [shadow.resource :as rc])
    #?(:clj [orchestra.core :refer [defn-spec]]
       :cljs [orchestra.core :refer-macros [defn-spec]])
-   #?(:clj [clojure.edn :as edn]
-      :cljs [cljs.reader :as edn])
    [dda.c4k-common.yaml :as yaml]
-   [dda.c4k-common.common :as cm]
-   [dda.c4k-common.base64 :as b64]
-   [dda.c4k-common.predicate :as cp]
-   [dda.c4k-common.monitoring :as mon]
-   [dda.c4k-common.postgres :as postgres]
    [dda.c4k-common.ingress :as ing]
-   [clojure.string :as str]
-    #?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]])))
+   [dda.c4k-common.base64 :as b64]
+   [dda.c4k-common.predicate :as p]
+   [dda.c4k-common.common :as cm]
+   #?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]])))
 
-
-(def config-defaults {:issuer "staging"
-                      :storage-class-name "local-path"
-                      :pv-storage-size-gb "5" ;; ToDo: check sensible defaults
-                      :storage-media-size "5"
-                      :storage-static-size "5"
-                      :storage-async-rabbitmq-size "5"
-                      :storage-events-rabbitmq-size "5"
-                      :public-register-enabled "false"
-                      :enable-telemetry "false"})
-
-(s/def ::mon-cfg ::mon/mon-cfg)
-(s/def ::mon-auth ::mon/mon-auth)
-(s/def ::taiga-secret-key cp/bash-env-string?)
+(s/def ::taiga-secret-key p/bash-env-string?)
 (s/def ::mailer-user string?)
 (s/def ::mailer-pw string?)
 (s/def ::django-superuser-username string?)
@@ -39,9 +20,9 @@
 (s/def ::rabbitmq-pw string?)
 (s/def ::rabbitmq-erlang-cookie string?)
 
-(s/def ::issuer cp/letsencrypt-issuer?)
-(s/def ::fqdn cp/fqdn-string?)
-(s/def ::public-register-enabled string?) ;; ToDo maybe check for boolean string
+(s/def ::issuer p/letsencrypt-issuer?)
+(s/def ::fqdn p/fqdn-string?)
+(s/def ::public-register-enabled string?)
 (s/def ::enable-telemetry string?)
 (s/def ::storage-class-name string?)
 (s/def ::storage-media-size pos?)
@@ -49,37 +30,34 @@
 (s/def ::storage-async-rabbitmq-size pos?)
 (s/def ::storage-events-rabbitmq-size pos?)
 
-(def auth? (s/keys :req-un [::postgres/postgres-db-user 
-                            ::postgres/postgres-db-password
-                            ::taiga-secret-key
-                            ::mailer-pw
-                            ::mailer-user
-                            ::django-superuser-email
-                            ::django-superuser-password
-                            ::django-superuser-username
-                            ::rabbitmq-erlang-cookie
-                            ::rabbitmq-pw
-                            ::rabbitmq-user]
-                   :opt-un [::mon-auth]))
+(s/def ::auth (s/keys :req-un [::taiga-secret-key
+                               ::mailer-pw
+                               ::mailer-user
+                               ::django-superuser-email
+                               ::django-superuser-password
+                               ::django-superuser-username
+                               ::rabbitmq-erlang-cookie
+                               ::rabbitmq-pw
+                               ::rabbitmq-user]
+                      :opt-un [::mon-auth]))
 
-(def config? (s/keys :req-un [::fqdn]
-                     :opt-un [::issuer
-                              ::storage-class-name
-                              ::storage-media-size
-                              ::storage-static-size
-                              ::storage-async-rabbitmq-size
-                              ::storage-events-rabbitmq-size
-                              ::postgres/pv-storage-size-gb
-                              ::public-register-enabled
-                              ::enable-telemetry
-                              ::mon-cfg]))
+(s/def ::config (s/keys :req-un [::fqdn]
+                        :opt-un [::issuer
+                                 ::storage-class-name
+                                 ::storage-media-size
+                                 ::storage-static-size
+                                 ::storage-async-rabbitmq-size
+                                 ::storage-events-rabbitmq-size
+                                 ::public-register-enabled
+                                 ::enable-telemetry
+                                 ::mon-cfg]))
 
 #?(:cljs
    (defmethod yaml/load-resource :taiga [resource-name]
      (get (inline-resources "taiga") resource-name)))
 
-(defn-spec generate-ingress-and-cert cp/map-or-seq?
-  [config config?]
+(defn-spec generate-ingress-and-cert p/map-or-seq?
+  [config ::config]
   (let [{:keys [fqdn]} config]
     (ing/generate-ingress-and-cert
      (merge
@@ -88,85 +66,85 @@
        :fqdns [fqdn]}
       config))))
 
-(defn-spec generate-async-deployment cp/map-or-seq? []
+(defn-spec generate-async-deployment p/map-or-seq? []
   (yaml/load-as-edn "taiga/async-deployment.yaml"))
 
-(defn-spec generate-async-service cp/map-or-seq? []
+(defn-spec generate-async-service p/map-or-seq? []
   (yaml/load-as-edn "taiga/async-service.yaml"))
 
-(defn-spec generate-async-rabbitmq-deployment cp/map-or-seq? []
+(defn-spec generate-async-rabbitmq-deployment p/map-or-seq? []
   (yaml/load-as-edn "taiga/async-rabbitmq-deployment.yaml"))
 
-(defn-spec generate-events-rabbitmq-service cp/map-or-seq? []
+(defn-spec generate-events-rabbitmq-service p/map-or-seq? []
   (yaml/load-as-edn "taiga/events-rabbitmq-service.yaml"))
 
-(defn-spec generate-async-rabbitmq-service cp/map-or-seq? []
+(defn-spec generate-async-rabbitmq-service p/map-or-seq? []
   (yaml/load-as-edn "taiga/async-rabbitmq-service.yaml"))
 
-(defn-spec generate-back-deployment cp/map-or-seq? []
+(defn-spec generate-back-deployment p/map-or-seq? []
   (yaml/load-as-edn "taiga/back-deployment.yaml"))
 
-(defn-spec generate-back-service cp/map-or-seq? []
+(defn-spec generate-back-service p/map-or-seq? []
   (yaml/load-as-edn "taiga/back-service.yaml"))
 
-(defn-spec generate-events-rabbitmq-deployment cp/map-or-seq? []
+(defn-spec generate-events-rabbitmq-deployment p/map-or-seq? []
   (yaml/load-as-edn "taiga/events-rabbitmq-deployment.yaml"))
 
-(defn-spec generate-events-deployment cp/map-or-seq? []
+(defn-spec generate-events-deployment p/map-or-seq? []
   (yaml/load-as-edn "taiga/events-deployment.yaml"))
 
-(defn-spec generate-events-service cp/map-or-seq? []
+(defn-spec generate-events-service p/map-or-seq? []
   (yaml/load-as-edn "taiga/events-service.yaml"))
 
-(defn-spec generate-front-deployment cp/map-or-seq? []
+(defn-spec generate-front-deployment p/map-or-seq? []
   (yaml/load-as-edn "taiga/front-deployment.yaml"))
 
-(defn-spec generate-front-service cp/map-or-seq? []
+(defn-spec generate-front-service p/map-or-seq? []
   (yaml/load-as-edn "taiga/front-service.yaml"))
 
-(defn-spec generate-gateway-configmap cp/map-or-seq? []
+(defn-spec generate-gateway-configmap p/map-or-seq? []
   (yaml/load-as-edn "taiga/gateway-configmap.yaml"))
 
-(defn-spec generate-gateway-deployment cp/map-or-seq? []
+(defn-spec generate-gateway-deployment p/map-or-seq? []
   (yaml/load-as-edn "taiga/gateway-deployment.yaml"))
 
-(defn-spec generate-gateway-service cp/map-or-seq? []
+(defn-spec generate-gateway-service p/map-or-seq? []
   (yaml/load-as-edn "taiga/gateway-service.yaml"))
 
-(defn-spec generate-protected-deployment cp/map-or-seq? []
+(defn-spec generate-protected-deployment p/map-or-seq? []
   (yaml/load-as-edn "taiga/protected-deployment.yaml"))
 
-(defn-spec generate-protected-service cp/map-or-seq? []
+(defn-spec generate-protected-service p/map-or-seq? []
   (yaml/load-as-edn "taiga/protected-service.yaml"))
 
-(defn-spec generate-configmap cp/map-or-seq? 
-  [config config?]
-  (let [{:keys [fqdn enable-telemetry public-register-enabled]} (merge config-defaults config)]
-    (-> (yaml/load-as-edn "taiga/configmap.yaml")     
+(defn-spec generate-configmap p/map-or-seq?
+  [config ::config]
+  (let [{:keys [fqdn enable-telemetry public-register-enabled]} config]
+    (-> (yaml/load-as-edn "taiga/configmap.yaml")
         (cm/replace-key-value :TAIGA_SITES_DOMAIN fqdn)
         (cm/replace-key-value :TAIGA_URL (str "https://" fqdn))
         (cm/replace-key-value :TAIGA_WEBSOCKETS_URL (str "wss://" fqdn))
         (cm/replace-key-value :ENABLE_TELEMETRY enable-telemetry)
         (cm/replace-key-value :PUBLIC_REGISTER_ENABLED public-register-enabled))))
 
-(defn-spec generate-pvc-taiga-media-data cp/map-or-seq? 
-  [config config?]
-  (let [{:keys [storage-class-name storage-media-size]} (merge config-defaults config)]
+(defn-spec generate-pvc-taiga-media-data p/map-or-seq?
+  [config ::config]
+  (let [{:keys [storage-class-name storage-media-size]} config]
     (->
      (yaml/load-as-edn "taiga/pvc-taiga-media-data.yaml")
      (assoc-in [:spec :storageClassName] storage-class-name)
      (assoc-in [:spec :resources :requests :storage] (str storage-media-size "Gi")))))
 
-(defn-spec generate-pvc-taiga-static-data cp/map-or-seq?
-  [config config?]
-  (let [{:keys [storage-class-name storage-static-size]} (merge config-defaults config)]
+(defn-spec generate-pvc-taiga-static-data p/map-or-seq?
+  [config ::config]
+  (let [{:keys [storage-class-name storage-static-size]} config]
     (->
      (yaml/load-as-edn "taiga/pvc-taiga-static-data.yaml")
      (assoc-in [:spec :storageClassName] storage-class-name)
      (assoc-in [:spec :resources :requests :storage] (str storage-static-size "Gi")))))
 
-(defn-spec generate-secret cp/map-or-seq?
-  [auth auth?]
+(defn-spec generate-secret p/map-or-seq?
+  [auth ::auth]
   (let [{:keys [taiga-secret-key
                 mailer-user mailer-pw
                 rabbitmq-user rabbitmq-pw rabbitmq-erlang-cookie
@@ -183,18 +161,18 @@
      (cm/replace-key-value :DJANGO_SUPERUSER_PASSWORD (b64/encode django-superuser-password))
      (cm/replace-key-value :DJANGO_SUPERUSER_EMAIL (b64/encode django-superuser-email)))))
 
-(defn-spec generate-rabbitmq-pvc-async cp/map-or-seq? 
-  [config config?]
-  (let [{:keys [storage-class-name storage-async-rabbitmq-size]} (merge config-defaults config)]
+(defn-spec generate-rabbitmq-pvc-async p/map-or-seq?
+  [config ::config]
+  (let [{:keys [storage-class-name storage-async-rabbitmq-size]} config]
     (->
      (yaml/load-as-edn "taiga/rabbitmq-pvc-async.yaml")
      (assoc-in [:spec :storageClassName] storage-class-name)
      (assoc-in [:spec :resources :requests :storage] (str storage-async-rabbitmq-size "Gi")))))
 
-(defn-spec generate-rabbitmq-pvc-events cp/map-or-seq?
-  [config config?]
-  (let [{:keys [storage-class-name storage-events-rabbitmq-size]} (merge config-defaults config)]
-    (-> 
+(defn-spec generate-rabbitmq-pvc-events p/map-or-seq?
+  [config ::config]
+  (let [{:keys [storage-class-name storage-events-rabbitmq-size]} config]
+    (->
      (yaml/load-as-edn "taiga/rabbitmq-pvc-events.yaml")
      (assoc-in [:spec :storageClassName] storage-class-name)
      (assoc-in [:spec :resources :requests :storage] (str storage-events-rabbitmq-size "Gi")))))
diff --git a/src/main/resources/taiga/async-deployment.yaml b/src/main/resources/taiga/async-deployment.yaml
index 686ed72..cd60e05 100644
--- a/src/main/resources/taiga/async-deployment.yaml
+++ b/src/main/resources/taiga/async-deployment.yaml
@@ -2,6 +2,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: taiga-async-deployment
+  namespace: taiga
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-async
diff --git a/src/main/resources/taiga/async-rabbitmq-deployment.yaml b/src/main/resources/taiga/async-rabbitmq-deployment.yaml
index 0fab2e5..67f20c6 100644
--- a/src/main/resources/taiga/async-rabbitmq-deployment.yaml
+++ b/src/main/resources/taiga/async-rabbitmq-deployment.yaml
@@ -2,6 +2,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: taiga-async-rabbitmq-deployment
+  namespace: taiga
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-async-rabbitmq
diff --git a/src/main/resources/taiga/async-rabbitmq-service.yaml b/src/main/resources/taiga/async-rabbitmq-service.yaml
index dc8a1e1..ea541dd 100644
--- a/src/main/resources/taiga/async-rabbitmq-service.yaml
+++ b/src/main/resources/taiga/async-rabbitmq-service.yaml
@@ -2,6 +2,7 @@ kind: Service
 apiVersion: v1
 metadata:
   name: taiga-async-rabbitmq
+  namespace: taiga
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-async-rabbitmq
diff --git a/src/main/resources/taiga/async-service.yaml b/src/main/resources/taiga/async-service.yaml
index f24f84a..14a9445 100644
--- a/src/main/resources/taiga/async-service.yaml
+++ b/src/main/resources/taiga/async-service.yaml
@@ -2,6 +2,7 @@ kind: Service
 apiVersion: v1
 metadata:
   name: taiga-async
+  namespace: taiga
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-async
diff --git a/src/main/resources/taiga/back-deployment.yaml b/src/main/resources/taiga/back-deployment.yaml
index 96b994f..fc5fdf9 100644
--- a/src/main/resources/taiga/back-deployment.yaml
+++ b/src/main/resources/taiga/back-deployment.yaml
@@ -2,6 +2,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: taiga-back-deployment
+  namespace: taiga
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-back
diff --git a/src/main/resources/taiga/back-service.yaml b/src/main/resources/taiga/back-service.yaml
index b6f9d75..7004faf 100644
--- a/src/main/resources/taiga/back-service.yaml
+++ b/src/main/resources/taiga/back-service.yaml
@@ -2,10 +2,10 @@ kind: Service
 apiVersion: v1
 metadata:
   name: taiga-back
+  namespace: taiga
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-back
-  namespace: default
 spec:
   type: ClusterIP
   selector:
diff --git a/src/main/resources/taiga/configmap.yaml b/src/main/resources/taiga/configmap.yaml
index 425ac94..03fc1bd 100644
--- a/src/main/resources/taiga/configmap.yaml
+++ b/src/main/resources/taiga/configmap.yaml
@@ -2,7 +2,7 @@ apiVersion: v1
 kind: ConfigMap
 metadata:
   name: taiga-configmap
-  namespace: default
+  namespace: taiga
 data:
   # These environment variables will be used by taiga-back and taiga-async.
   # Database settings handled in deployment
diff --git a/src/main/resources/taiga/events-deployment.yaml b/src/main/resources/taiga/events-deployment.yaml
index 824f2ba..178810f 100644
--- a/src/main/resources/taiga/events-deployment.yaml
+++ b/src/main/resources/taiga/events-deployment.yaml
@@ -2,6 +2,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: taiga-events-deployment
+  namespace: taiga
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-events
diff --git a/src/main/resources/taiga/events-rabbitmq-deployment.yaml b/src/main/resources/taiga/events-rabbitmq-deployment.yaml
index bb78f80..3c52d75 100644
--- a/src/main/resources/taiga/events-rabbitmq-deployment.yaml
+++ b/src/main/resources/taiga/events-rabbitmq-deployment.yaml
@@ -2,6 +2,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: taiga-events-rabbitmq-deployment
+  namespace: taiga
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-events-rabbitmq
diff --git a/src/main/resources/taiga/events-rabbitmq-service.yaml b/src/main/resources/taiga/events-rabbitmq-service.yaml
index 2f542fc..7acc766 100644
--- a/src/main/resources/taiga/events-rabbitmq-service.yaml
+++ b/src/main/resources/taiga/events-rabbitmq-service.yaml
@@ -2,6 +2,7 @@ kind: Service
 apiVersion: v1
 metadata:
   name: taiga-events-rabbitmq
+  namespace: taiga
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-events-rabbitmq
diff --git a/src/main/resources/taiga/events-service.yaml b/src/main/resources/taiga/events-service.yaml
index 4ec0f51..d3b3ab3 100644
--- a/src/main/resources/taiga/events-service.yaml
+++ b/src/main/resources/taiga/events-service.yaml
@@ -2,10 +2,10 @@ kind: Service
 apiVersion: v1
 metadata:
   name: taiga-events
+  namespace: taiga
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-events
-  namespace: default
 spec:
   type: ClusterIP
   selector:
diff --git a/src/main/resources/taiga/front-deployment.yaml b/src/main/resources/taiga/front-deployment.yaml
index 08424d8..56574b6 100644
--- a/src/main/resources/taiga/front-deployment.yaml
+++ b/src/main/resources/taiga/front-deployment.yaml
@@ -2,6 +2,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: taiga-front-deployment
+  namespace: taiga
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-front
diff --git a/src/main/resources/taiga/front-service.yaml b/src/main/resources/taiga/front-service.yaml
index d586429..341847c 100644
--- a/src/main/resources/taiga/front-service.yaml
+++ b/src/main/resources/taiga/front-service.yaml
@@ -2,10 +2,10 @@ kind: Service
 apiVersion: v1
 metadata:
   name: taiga-front
+  namespace: taiga
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-front
-  namespace: default
 spec:
   type: ClusterIP
   selector:
diff --git a/src/main/resources/taiga/gateway-configmap.yaml b/src/main/resources/taiga/gateway-configmap.yaml
index 7ae184d..a5b1483 100644
--- a/src/main/resources/taiga/gateway-configmap.yaml
+++ b/src/main/resources/taiga/gateway-configmap.yaml
@@ -2,6 +2,7 @@ apiVersion: v1
 kind: ConfigMap
 metadata:
   name: taiga-gateway-configmap
+  namespace: taiga
 data:
   default.conf: |
     server {
diff --git a/src/main/resources/taiga/gateway-deployment.yaml b/src/main/resources/taiga/gateway-deployment.yaml
index b6c1beb..c8abe80 100644
--- a/src/main/resources/taiga/gateway-deployment.yaml
+++ b/src/main/resources/taiga/gateway-deployment.yaml
@@ -2,6 +2,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: taiga-gateway-deployment
+  namespace: taiga
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-gateway
diff --git a/src/main/resources/taiga/gateway-service.yaml b/src/main/resources/taiga/gateway-service.yaml
index 441dedf..9203edf 100644
--- a/src/main/resources/taiga/gateway-service.yaml
+++ b/src/main/resources/taiga/gateway-service.yaml
@@ -2,10 +2,10 @@ kind: Service
 apiVersion: v1
 metadata:
   name: taiga-gateway
+  namespace: taiga
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-gateway
-  namespace: default
 spec:
   type: ClusterIP
   selector:
diff --git a/src/main/resources/taiga/protected-deployment.yaml b/src/main/resources/taiga/protected-deployment.yaml
index 729de1e..01f78a7 100644
--- a/src/main/resources/taiga/protected-deployment.yaml
+++ b/src/main/resources/taiga/protected-deployment.yaml
@@ -2,6 +2,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: taiga-protected-deployment
+  namespace: taiga
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-protected
diff --git a/src/main/resources/taiga/protected-service.yaml b/src/main/resources/taiga/protected-service.yaml
index 6f448ac..3a24d1e 100644
--- a/src/main/resources/taiga/protected-service.yaml
+++ b/src/main/resources/taiga/protected-service.yaml
@@ -2,10 +2,10 @@ kind: Service
 apiVersion: v1
 metadata:
   name: taiga-protected
+  namespace: taiga
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-protected
-  namespace: default
 spec:
   type: ClusterIP
   selector:
diff --git a/src/main/resources/taiga/pvc-taiga-media-data.yaml b/src/main/resources/taiga/pvc-taiga-media-data.yaml
index 65b1867..e67748e 100644
--- a/src/main/resources/taiga/pvc-taiga-media-data.yaml
+++ b/src/main/resources/taiga/pvc-taiga-media-data.yaml
@@ -2,7 +2,7 @@ apiVersion: v1
 kind: PersistentVolumeClaim
 metadata:
   name: taiga-media-data
-  namespace: default
+  namespace: taiga
   labels:
     app: taiga
     app.kubernetes.part-of: taiga
diff --git a/src/main/resources/taiga/pvc-taiga-static-data.yaml b/src/main/resources/taiga/pvc-taiga-static-data.yaml
index 3663d24..f315d4d 100644
--- a/src/main/resources/taiga/pvc-taiga-static-data.yaml
+++ b/src/main/resources/taiga/pvc-taiga-static-data.yaml
@@ -2,7 +2,7 @@ apiVersion: v1
 kind: PersistentVolumeClaim
 metadata:
   name: taiga-static-data
-  namespace: default
+  namespace: taiga
   labels:
     app: taiga
     app.kubernetes.part-of: taiga
diff --git a/src/main/resources/taiga/rabbitmq-pvc-async.yaml b/src/main/resources/taiga/rabbitmq-pvc-async.yaml
index 52d745a..a0aa7cf 100644
--- a/src/main/resources/taiga/rabbitmq-pvc-async.yaml
+++ b/src/main/resources/taiga/rabbitmq-pvc-async.yaml
@@ -2,7 +2,7 @@ apiVersion: v1
 kind: PersistentVolumeClaim
 metadata:
   name: taiga-async-rabbitmq-data
-  namespace: default
+  namespace: taiga
   labels:
     app: taiga
     app.kubernetes.part-of: taiga
diff --git a/src/main/resources/taiga/rabbitmq-pvc-events.yaml b/src/main/resources/taiga/rabbitmq-pvc-events.yaml
index 7ce880e..0ece03d 100644
--- a/src/main/resources/taiga/rabbitmq-pvc-events.yaml
+++ b/src/main/resources/taiga/rabbitmq-pvc-events.yaml
@@ -2,7 +2,7 @@ apiVersion: v1
 kind: PersistentVolumeClaim
 metadata:
   name: taiga-events-rabbitmq-data
-  namespace: default
+  namespace: taiga
   labels:
     app: taiga
     app.kubernetes.part-of: taiga
diff --git a/src/main/resources/taiga/secret.yaml b/src/main/resources/taiga/secret.yaml
index 785444b..22dfdb2 100644
--- a/src/main/resources/taiga/secret.yaml
+++ b/src/main/resources/taiga/secret.yaml
@@ -2,6 +2,7 @@ apiVersion: v1
 kind: Secret
 metadata:
   name: taiga-secret
+  namespace: taiga
   labels:
     app.kubernetes.part-of: taiga
 data:
diff --git a/src/test/cljc/dda/c4k_taiga/taiga_test.cljc b/src/test/cljc/dda/c4k_taiga/taiga_test.cljc
index bbb1980..edda554 100644
--- a/src/test/cljc/dda/c4k_taiga/taiga_test.cljc
+++ b/src/test/cljc/dda/c4k_taiga/taiga_test.cljc
@@ -1,23 +1,26 @@
 (ns dda.c4k-taiga.taiga-test
   (:require
-   #?(:cljs [shadow.resource :as rc])
+   #?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]])
    #?(:clj [clojure.test :refer [deftest is are testing run-tests]]
       :cljs [cljs.test :refer-macros [deftest is are testing run-tests]])
-   [clojure.spec.alpha :as s]
+   [clojure.spec.test.alpha :as st]
    [dda.c4k-common.yaml :as yaml]
    [dda.c4k-taiga.taiga :as cut]))
 
+(st/instrument `cut/generate-configmap)
+(st/instrument `cut/generate-pvc-taiga-media-data)
+(st/instrument `cut/generate-rabbitmq-pvc-async)
+(st/instrument `cut/generate-rabbitmq-pvc-events)
+(st/instrument `cut/generate-secret)
+
 #?(:cljs
-   (defmethod yaml/load-resource :taiga-test [resource-name]
-     (case resource-name
-       "taiga-test/valid-config.yaml" (rc/inline "taiga-test/valid-config.yaml")
-       "taiga-test/valid-auth.yaml" (rc/inline "taiga-test/valid-auth.yaml")
-       (throw (js/Error. "Undefined Resource!")))))
+   (defmethod yaml/load-resource :nextcloud-test [resource-name]
+     (get (inline-resources "nextcloud-test") resource-name)))
 
 (deftest should-generate-configmap
   (is (= {:apiVersion "v1",
           :kind "ConfigMap",
-          :metadata {:name "taiga-configmap", :namespace "default"},
+          :metadata {:name "taiga-configmap", :namespace "taiga"},
           :data
           {:ENABLE_TELEMETRY "false",
            :TAIGA_SITES_SCHEME "https",
@@ -39,20 +42,18 @@
           :kind "PersistentVolumeClaim",
           :metadata
           {:name "taiga-media-data",
-           :namespace "default",
+           :namespace "taiga"
            :labels {:app "taiga", :app.kubernetes.part-of "taiga"}},
           :spec
           {:storageClassName "local-path",
            :accessModes ["ReadWriteOnce"],
            :resources {:requests {:storage "2Gi"}}}}
-         (cut/generate-pvc-taiga-media-data (yaml/load-as-edn "taiga-test/valid-config.yaml")))))
-
-(deftest should-generate-pvc-taiga-static-data
+         (cut/generate-pvc-taiga-media-data (yaml/load-as-edn "taiga-test/valid-config.yaml"))))
   (is (= {:apiVersion "v1",
           :kind "PersistentVolumeClaim",
           :metadata
           {:name "taiga-static-data",
-           :namespace "default",
+           :namespace "taiga"
            :labels {:app "taiga", :app.kubernetes.part-of "taiga"}},
           :spec
           {:storageClassName "local-path",
@@ -65,20 +66,20 @@
           :kind "PersistentVolumeClaim",
           :metadata
           {:name "taiga-async-rabbitmq-data",
-           :namespace "default",
+           :namespace "taiga"
            :labels {:app "taiga", :app.kubernetes.part-of "taiga"}},
           :spec
           {:storageClassName "local-path",
            :accessModes ["ReadWriteOnce"],
            :resources {:requests {:storage "4Gi"}}}}
-         (cut/generate-rabbitmq-pvc-async(yaml/load-as-edn "taiga-test/valid-config.yaml")))))
+         (cut/generate-rabbitmq-pvc-async (yaml/load-as-edn "taiga-test/valid-config.yaml")))))
 
 (deftest should-generate-rabbitmq-pvc-events
   (is (= {:apiVersion "v1",
           :kind "PersistentVolumeClaim",
           :metadata
           {:name "taiga-events-rabbitmq-data",
-           :namespace "default",
+           :namespace "taiga"
            :labels {:app "taiga", :app.kubernetes.part-of "taiga"}},
           :spec
           {:storageClassName "local-path",
@@ -90,7 +91,7 @@
   (is (= {:apiVersion "v1",
           :kind "Secret",
           :metadata
-          {:name "taiga-secret", :labels {:app.kubernetes.part-of "taiga"}},
+          {:name "taiga-secret", :namespace "taiga" :labels {:app.kubernetes.part-of "taiga"}},
           :data
           {:TAIGA_SECRET_KEY "c29tZS1rZXk=",
            :EMAIL_HOST_USER "bWFpbGVyLXVzZXI=",

From 556fc9ae58dcdf1fac122dfb01318952c6d6ca13 Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Tue, 14 Jan 2025 12:55:45 +0100
Subject: [PATCH 07/21] fix test / fix refactorings / prepare password-rotation

---
 src/main/clj/dda/c4k_taiga/uberjar.clj        |   8 +-
 src/main/cljc/dda/c4k_taiga/core.cljc         | 144 ++++++++-----
 src/main/cljs/dda/c4k_taiga/browser.cljs      | 196 ++++--------------
 .../backup/backup-restore-deployment.yaml     |   4 +-
 src/test/cljc/dda/c4k_taiga/core_test.cljc    |   9 +-
 src/test/cljc/dda/c4k_taiga/taiga_test.cljc   |   4 +-
 6 files changed, 145 insertions(+), 220 deletions(-)

diff --git a/src/main/clj/dda/c4k_taiga/uberjar.clj b/src/main/clj/dda/c4k_taiga/uberjar.clj
index ec762a5..cff656b 100644
--- a/src/main/clj/dda/c4k_taiga/uberjar.clj
+++ b/src/main/clj/dda/c4k_taiga/uberjar.clj
@@ -4,12 +4,12 @@
    [dda.c4k-common.uberjar :as uberjar]
    [dda.c4k-taiga.core :as core]))
 
-
 (defn -main [& cmd-args]
-  (uberjar/main-common
+  (uberjar/main-cm
    "c4k-taiga"
    core/config?
    core/auth?
-   core/config-defaults
-   core/k8s-objects
+   core/defaults
+   core/config-objects
+   core/auth-objects
    cmd-args))
diff --git a/src/main/cljc/dda/c4k_taiga/core.cljc b/src/main/cljc/dda/c4k_taiga/core.cljc
index 46abbf7..51b226c 100644
--- a/src/main/cljc/dda/c4k_taiga/core.cljc
+++ b/src/main/cljc/dda/c4k_taiga/core.cljc
@@ -9,57 +9,103 @@
    [dda.c4k-common.monitoring :as mon]
    [dda.c4k-taiga.taiga :as taiga]
    [dda.c4k-taiga.backup :as backup]
-   [dda.c4k-common.postgres :as postgres]))
+   [dda.c4k-common.postgres :as postgres]
+   [dda.c4k-common.namespace :as ns]))
 
-(def default-storage-class :local-path)
+(def defaults {:namespace "taiga"
+               :issuer "staging"
+               :storage-class-name "local-path"
+               :pv-storage-size-gb "5"
+               :storage-media-size "5"
+               :storage-static-size "5"
+               :storage-async-rabbitmq-size "5"
+               :storage-events-rabbitmq-size "5"
+               :public-register-enabled "false"
+               :enable-telemetry "false"})
 
-(def config? taiga/config?)
-(def auth? taiga/auth?)
+(def config? (s/merge
+              ::backup/config              
+              (s/keys :req-un [::taiga/fqdn]
+                      :opt-un [::taiga/issuer
+                               ::taiga/storage-class-name
+                               ::taiga/storage-media-size
+                               ::taiga/storage-static-size
+                               ::taiga/storage-async-rabbitmq-size
+                               ::taiga/storage-events-rabbitmq-size
+                               ::taiga/public-register-enabled
+                               ::taiga/enable-telemetry
+                               ::postgres/pv-storage-size-gb
+                               ::mon/mon-cfg])))
 
-(def config-defaults taiga/config-defaults)
+(def auth? (s/merge
+            ::backup/auth
+            (s/keys :req-un [::postgres/postgres-db-user
+                             ::postgres/postgres-db-password
+                             ::taiga/taiga-secret-key
+                             ::taiga/mailer-pw
+                             ::taiga/mailer-user
+                             ::taiga/django-superuser-email
+                             ::taiga/django-superuser-password
+                             ::taiga/django-superuser-username
+                             ::taiga/rabbitmq-erlang-cookie
+                             ::taiga/rabbitmq-pw
+                             ::taiga/rabbitmq-user
+                             ::mon/mon-auth])))
 
-(defn-spec k8s-objects cp/map-or-seq?
-  [config taiga/config?
-   auth taiga/auth?]  
+(defn-spec config-objects cp/map-or-seq?
+  [config config?]
+  (let [resolved-config (merge defaults config)
+        db-config (merge resolved-config {:postgres-size :8gb :db-name "taiga"
+                                          :pv-storage-size-gb 50})]
   (cm/concat-vec
-   (map yaml/to-string
-        (filter
-         #(not (nil? %))
-         (cm/concat-vec
-          [(postgres/generate-config {:postgres-size :8gb :db-name "taiga"})
-           (postgres/generate-secret auth)
-           (postgres/generate-pvc {:pv-storage-size-gb 50
-                                   :pvc-storage-class-name default-storage-class})
-           (postgres/generate-deployment)
-           (postgres/generate-service)
-           (taiga/generate-async-deployment)
-           (taiga/generate-async-rabbitmq-deployment)
-           (taiga/generate-async-rabbitmq-service)
-           (taiga/generate-async-service)
-           (taiga/generate-back-deployment)
-           (taiga/generate-back-service)
-           (taiga/generate-configmap config)
-           (taiga/generate-pvc-taiga-media-data config)
-           (taiga/generate-pvc-taiga-static-data config)
-           (taiga/generate-events-deployment)
-           (taiga/generate-events-rabbitmq-deployment)
-           (taiga/generate-events-rabbitmq-service)
-           (taiga/generate-events-service)
-           (taiga/generate-front-deployment)
-           (taiga/generate-front-service)
-           (taiga/generate-gateway-configmap)
-           (taiga/generate-gateway-deployment)
-           (taiga/generate-gateway-service)
-           (taiga/generate-protected-deployment)
-           (taiga/generate-protected-service)
-           (taiga/generate-rabbitmq-pvc-async config)
-           (taiga/generate-rabbitmq-pvc-events config)
-           (taiga/generate-secret auth)]
-          (taiga/generate-ingress-and-cert config)
-          (when (contains? config :restic-repository)
-            [(backup/generate-config config)
-             (backup/generate-secret auth)
-             (backup/generate-cron)
-             (backup/generate-backup-restore-deployment config)])
-          (when (:contains? config :mon-cfg)
-            (mon/generate (:mon-cfg config) (:mon-auth auth))))))))
+    (map yaml/to-string
+         (filter
+          #(not (nil? %))
+          (cm/concat-vec
+           (ns/generate resolved-config)
+           (postgres/generate-config db-config)
+           [(taiga/generate-async-deployment)
+            (taiga/generate-async-rabbitmq-deployment)
+            (taiga/generate-async-rabbitmq-service)
+            (taiga/generate-async-service)
+            (taiga/generate-back-deployment)
+            (taiga/generate-back-service)
+            (taiga/generate-configmap resolved-config)
+            (taiga/generate-pvc-taiga-media-data resolved-config)
+            (taiga/generate-pvc-taiga-static-data resolved-config)
+            (taiga/generate-events-deployment)
+            (taiga/generate-events-rabbitmq-deployment)
+            (taiga/generate-events-rabbitmq-service)
+            (taiga/generate-events-service)
+            (taiga/generate-front-deployment)
+            (taiga/generate-front-service)
+            (taiga/generate-gateway-configmap)
+            (taiga/generate-gateway-deployment)
+            (taiga/generate-gateway-service)
+            (taiga/generate-protected-deployment)
+            (taiga/generate-protected-service)
+            (taiga/generate-rabbitmq-pvc-async resolved-config)
+            (taiga/generate-rabbitmq-pvc-events resolved-config)]
+           (taiga/generate-ingress-and-cert resolved-config)
+           (when (contains? resolved-config :restic-repository)
+             [(backup/generate-config resolved-config)
+              (backup/generate-cron)
+              (backup/generate-backup-restore-deployment resolved-config)])
+           (when (:contains? resolved-config :mon-cfg)
+             (mon/generate-config))))))))
+
+(defn-spec auth-objects cp/map-or-seq?
+  [config config?
+   auth auth?]
+  (let [resolved-config (merge defaults config)]
+  (cm/concat-vec
+    (map yaml/to-string
+         (filter
+          #(not (nil? %))
+          (cm/concat-vec
+           [(postgres/generate-secret auth)
+            (taiga/generate-secret auth)]
+           (when (contains? resolved-config :restic-repository)
+             [(backup/generate-secret auth)])
+           (when (:contains? resolved-config :mon-cfg)
+             (mon/generate-auth (:mon-cfg resolved-config) (:mon-auth auth)))))))))
diff --git a/src/main/cljs/dda/c4k_taiga/browser.cljs b/src/main/cljs/dda/c4k_taiga/browser.cljs
index 911185e..343576b 100644
--- a/src/main/cljs/dda/c4k_taiga/browser.cljs
+++ b/src/main/cljs/dda/c4k_taiga/browser.cljs
@@ -1,14 +1,9 @@
 (ns dda.c4k-taiga.browser
   (:require
-   [clojure.string :as st]
    [clojure.tools.reader.edn :as edn]
-   [dda.c4k-common.monitoring :as mon]
    [dda.c4k-taiga.core :as core]
-   [dda.c4k-taiga.taiga :as taiga]
    [dda.c4k-common.common :as cm]
-   [dda.c4k-common.predicate :as cp]
-   [dda.c4k-common.browser :as br]
-   [dda.c4k-common.postgres :as postgres]))
+   [dda.c4k-common.browser :as br]))
 
 (defn generate-content []
   (cm/concat-vec
@@ -16,40 +11,33 @@
      (br/generate-needs-validation) :content
      (cm/concat-vec
       (br/generate-group
-       "domain"
-       (cm/concat-vec
-        (br/generate-input-field "fqdn" "The fully qualified domain name of your Taiga Instance:" "taiga.example.com")
-        (br/generate-input-field "issuer" "(Optional) Your issuer prod/staging:" "staging")
-        (br/generate-input-field "mon-cluster-name" "(Optional) monitoring cluster name:" "taiga")
-        (br/generate-input-field "mon-cluster-stage" "(Optional) monitoring cluster stage:" "test")
-        (br/generate-input-field "mon-cloud-url" "(Optional) grafana cloud url:" "https://prometheus-prod-01-eu-west-0.grafana.net/api/prom/push")))
+       "config"
+       (br/generate-text-area "config" "Your config.edn:" "{:fqdn \"cloud.your.domain\"
+          :issuer \"staging\"
+          :restic-repository \"s3://yourbucket/your-repo\"
+          :mon-cfg {:cluster-name \"cloud\"
+                    :cluster-stage \"test\"
+                    :cloud-url \"https://prometheus-prod-01-eu-west-0.grafana.net/api/prom/push\"}}"
+                              "5"))
       (br/generate-group
-       "options"
-       (cm/concat-vec
-        (br/generate-input-field "public-register-enabled"      "(Optional) Allow public registration?" "false")
-        (br/generate-input-field "enable-telemetry"             "(Optional) Allow anonymous collection of usage data?" "false")
-        (br/generate-input-field "pv-storage-size-gb"           "(Optional) The volume size of your postgres DB:" "5")
-        (br/generate-input-field "storage-class-name"           "(Optional) Name of storage class:" "local-path")
-        (br/generate-input-field "storage-media-size"           "(Optional) The size of your media storage:" "5")
-        (br/generate-input-field "storage-static-size"          "(Optional) The size of your static data storage:" "5")
-        (br/generate-input-field "storage-async-rabbitmq-size"  "(Optional) The size of your rabbitmq async storage:" "5")
-        (br/generate-input-field "storage-events-rabbitmq-size" "(Optional) The size of your rabbitmq events storage:" "5")))
-      (br/generate-group
-       "credentials"
-       (cm/concat-vec
-        (br/generate-input-field "postgres-db-user"          "Your postgres user:"                         "postgres")
-        (br/generate-input-field "postgres-db-password"      "Your postgres password:"                     "change-me")
-        (br/generate-input-field "mailer-user"               "Allow taiga access to a mail account:"       "mail[at]example.com")
-        (br/generate-input-field "mailer-pw"                 "Allow taiga access to a mail account:"       "change-me")
-        (br/generate-input-field "django-superuser-username" "The superusers username:"                    "admin")
-        (br/generate-input-field "django-superuser-password" "The superusers password:"                    "change-me")
-        (br/generate-input-field "django-superuser-email"    "The superusers email:"                       "mail[at]example.com")
-        (br/generate-input-field "rabbitmq-user"             "User for rabbitmq:"                          "user")
-        (br/generate-input-field "rabbitmq-pw"               "Password for the rabbitmq user:"             "change-me")
-        (br/generate-input-field "rabbitmq-erlang-cookie"    "Random hash shared among all rabbitmq pods:" "change-me")
-        (br/generate-input-field "taiga-secret-key"          "Random key shared among all taiga pods:"     "change-me")
-        (br/generate-input-field "grafana-cloud-user"        "Your grafana user name:"                     "user")
-        (br/generate-input-field "grafana-cloud-password"    "Your grafana password:"                      "change-me")))
+       "auth"
+       (br/generate-text-area "auth" "Your auth.edn:" "{:postgres-db-user \"taiga\"
+                :postgres-db-password \"db-password\"
+                :mailer-user \"mail[at]example.com\"
+                :mailer-pw \"change-me\"
+                :django-superuser-username \"admin\"
+                :django-superuser-password \"change-me\"
+                :django-superuser-email \"mail[at]example.com\"
+                :rabbitmq-user \"user\"
+                :rabbitmq-pw \"change-me\"
+                :rabbitmq-erlang-cookie \"change-me\"
+                :taiga-secret-key \"change-me\"
+                :aws-access-key-id \"aws-id\"
+                :aws-secret-access-key \"aws-secret\"
+                :restic-password \"restic-password\"}
+                :mon-auth {:grafana-cloud-user \"your-user-id\"
+                           :grafana-cloud-password \"your-cloud-password\"}"
+                              "5"))
       [(br/generate-br)]
       (br/generate-button "generate-button" "Generate c4k yaml")))]
    (br/generate-output "c4k-taiga-output" "Your c4k deployment.yaml:" "15")))
@@ -61,94 +49,9 @@
    :content
    (generate-content)})
 
-(defn auth-from-document []
-  (let [postgres-db-user          (br/get-content-from-element "postgres-db-user"          )
-        postgres-db-password      (br/get-content-from-element "postgres-db-password"      )
-        mailer-user               (br/get-content-from-element "mailer-user"               )
-        mailer-pw                 (br/get-content-from-element "mailer-pw"                 )
-        django-superuser-username (br/get-content-from-element "django-superuser-username" )
-        django-superuser-password (br/get-content-from-element "django-superuser-password" )
-        django-superuser-email    (br/get-content-from-element "django-superuser-email"    )
-        rabbitmq-user             (br/get-content-from-element "rabbitmq-user"             )
-        rabbitmq-pw               (br/get-content-from-element "rabbitmq-pw"               )
-        rabbitmq-erlang-cookie    (br/get-content-from-element "rabbitmq-erlang-cookie"    )
-        taiga-secret-key          (br/get-content-from-element "taiga-secret-key"          )
-        grafana-cloud-user        (br/get-content-from-element "grafana-cloud-user"        :optional true)
-        grafana-cloud-password    (br/get-content-from-element "grafana-cloud-password"    :optional true)]
-    (merge
-     {:postgres-db-user           postgres-db-user}
-     {:postgres-db-password       postgres-db-password}
-     {:mailer-user                mailer-user}
-     {:mailer-pw                  mailer-pw}
-     {:django-superuser-username  django-superuser-username}
-     {:django-superuser-password  django-superuser-password}
-     {:django-superuser-email     django-superuser-email}
-     {:rabbitmq-user              rabbitmq-user}
-     {:rabbitmq-pw                rabbitmq-pw}
-     {:rabbitmq-erlang-cookie     rabbitmq-erlang-cookie}
-     {:taiga-secret-key           taiga-secret-key}
-     (when (some? grafana-cloud-user)
-       {:mon-auth {:grafana-cloud-user     grafana-cloud-user
-                   :grafana-cloud-password grafana-cloud-password}}))))
-
-(defn config-from-document []
-  (let [issuer                       (br/get-content-from-element "issuer"                       :optional true)
-        fqdn                         (br/get-content-from-element "fqdn"                         :deserializer edn/read-string)
-        public-register-enabled      (br/get-content-from-element "public-register-enabled"      :deserializer edn/read-string)
-        enable-telemetry             (br/get-content-from-element "enable-telemetry"             :deserializer edn/read-string)
-        pv-storage-size-gb           (br/get-content-from-element "pv-storage-size-gb"           :deserializer edn/read-string)
-        storage-class-name           (br/get-content-from-element "storage-class-name"           :deserializer edn/read-string)
-        storage-media-size           (br/get-content-from-element "storage-media-size"           :deserializer edn/read-string)
-        storage-static-size          (br/get-content-from-element "storage-static-size"          :deserializer edn/read-string)
-        storage-async-rabbitmq-size  (br/get-content-from-element "storage-async-rabbitmq-size"  :deserializer edn/read-string)
-        storage-events-rabbitmq-size (br/get-content-from-element "storage-events-rabbitmq-size" :deserializer edn/read-string)
-        mon-cluster-name             (br/get-content-from-element "mon-cluster-name"             :optional true)
-        mon-cluster-stage            (br/get-content-from-element "mon-cluster-stage"            :optional true)
-        mon-cloud-url                (br/get-content-from-element "mon-cloud-url"                :optional true)]
-    (merge
-     {:fqdn fqdn}
-     {:public-register-enabled public-register-enabled}
-     {:enable-telemetry enable-telemetry}
-     {:pv-storage-size-gb pv-storage-size-gb}
-     {:storage-class-name storage-class-name}
-     {:storage-media-size storage-media-size}
-     {:storage-static-size storage-static-size}
-     {:storage-async-rabbitmq-size storage-async-rabbitmq-size}
-     {:storage-events-rabbitmq-size storage-events-rabbitmq-size}
-     (when (not (st/blank? issuer))
-       {:issuer issuer})
-     (when (some? mon-cluster-name)
-       {:mon-cfg {:cluster-name mon-cluster-name
-                  :cluster-stage (keyword mon-cluster-stage)
-                  :grafana-cloud-url mon-cloud-url}}))))
-
 (defn validate-all! []
-  (br/validate! "fqdn"                         ::taiga/fqdn                         )
-  (br/validate! "issuer"                       ::taiga/issuer                       :optional true)
-  (br/validate! "public-register-enabled"      ::taiga/public-register-enabled      :optional true)
-  (br/validate! "enable-telemetry"             ::taiga/enable-telemetry             :optional true)
-  (br/validate! "pv-storage-size-gb"           ::postgres/pv-storage-size-gb        :optional true)
-  (br/validate! "storage-class-name"           ::taiga/storage-class-name           :optional true)
-  (br/validate! "storage-media-size"           ::taiga/storage-media-size           :optional true)
-  (br/validate! "storage-static-size"          ::taiga/storage-static-size          :optional true)
-  (br/validate! "storage-async-rabbitmq-size"  ::taiga/storage-async-rabbitmq-size  :optional true)
-  (br/validate! "storage-events-rabbitmq-size" ::taiga/storage-events-rabbitmq-size :optional true)
-  (br/validate! "mon-cluster-name"             ::mon/cluster-name                   :optional true)
-  (br/validate! "mon-cluster-stage"            ::mon/cluster-stage                  :optional true)
-  (br/validate! "mon-cloud-url"                ::mon/grafana-cloud-url              :optional true)
-  (br/validate! "postgres-db-user"             ::postgres/postgres-db-user          )
-  (br/validate! "postgres-db-password"         ::postgres/postgres-db-password      )
-  (br/validate! "mailer-user"                  ::taiga/mailer-user                  )
-  (br/validate! "mailer-pw"                    ::taiga/mailer-pw                    )
-  (br/validate! "django-superuser-username"    ::taiga/django-superuser-username    )
-  (br/validate! "django-superuser-password"    ::taiga/django-superuser-password    )
-  (br/validate! "django-superuser-email"       ::taiga/django-superuser-email       )
-  (br/validate! "rabbitmq-user"                ::taiga/rabbitmq-user                )
-  (br/validate! "rabbitmq-pw"                  ::taiga/rabbitmq-pw                  )
-  (br/validate! "rabbitmq-erlang-cookie"       ::taiga/rabbitmq-erlang-cookie       )
-  (br/validate! "taiga-secret-key"             ::taiga/taiga-secret-key             )
-  (br/validate! "grafana-cloud-user"           ::mon/grafana-cloud-user             )
-  (br/validate! "grafana-cloud-password"       ::mon/grafana-cloud-password         )
+  (br/validate! "config" core/config? :deserializer edn/read-string)
+  (br/validate! "auth" core/auth? :deserializer edn/read-string)
   (br/set-form-validated!))
 
 (defn add-validate-listener [name]
@@ -161,35 +64,14 @@
       (.getElementById "generate-button")
       (.addEventListener "click"
                          #(do (validate-all!)
-                              (-> (cm/generate-common
-                                   (config-from-document)
-                                   (auth-from-document)
-                                   core/config-defaults
-                                   core/k8s-objects)
+                              (-> (cm/generate-cm
+                                   (br/get-content-from-element "config" :deserializer edn/read-string)
+                                    (br/get-content-from-element "auth" :deserializer edn/read-string)
+                                    core/config-defaults
+                                    core/config-objects
+                                    core/auth-objects
+                                    false
+                                    false)
                                   (br/set-output!)))))
-  (add-validate-listener "fqdn")
-  (add-validate-listener "issuer")
-  (add-validate-listener "public-register-enabled")
-  (add-validate-listener "enable-telemetry")
-  (add-validate-listener "pv-storage-size-gb")
-  (add-validate-listener "storage-class-name")
-  (add-validate-listener "storage-media-size")
-  (add-validate-listener "storage-static-size")
-  (add-validate-listener "storage-async-rabbitmq-size")
-  (add-validate-listener "storage-events-rabbitmq-size")
-  (add-validate-listener "mon-cluster-name")
-  (add-validate-listener "mon-cluster-stage")
-  (add-validate-listener "mon-cloud-url")
-  (add-validate-listener "postgres-db-user")
-  (add-validate-listener "postgres-db-password")
-  (add-validate-listener "mailer-user")
-  (add-validate-listener "mailer-pw")
-  (add-validate-listener "django-superuser-username")
-  (add-validate-listener "django-superuser-password")
-  (add-validate-listener "django-superuser-email")
-  (add-validate-listener "rabbitmq-user")
-  (add-validate-listener "rabbitmq-pw")
-  (add-validate-listener "rabbitmq-erlang-cookie")
-  (add-validate-listener "taiga-secret-key")
-  (add-validate-listener "grafana-cloud-user")
-  (add-validate-listener "grafana-cloud-password"))
+  (add-validate-listener "config")
+  (add-validate-listener "authr"))
diff --git a/src/main/resources/backup/backup-restore-deployment.yaml b/src/main/resources/backup/backup-restore-deployment.yaml
index 557d18c..550113d 100644
--- a/src/main/resources/backup/backup-restore-deployment.yaml
+++ b/src/main/resources/backup/backup-restore-deployment.yaml
@@ -57,8 +57,8 @@ spec:
               key: restic-repository
         - name: RESTIC_PASSWORD_FILE
           value: /var/run/secrets/backup-secrets/restic-password
-        - name: CERTIFICATE_FILE
-          value: ""
+        - name: RESTIC_NEW_PASSWORD_FILE
+          value: /var/run/secrets/backup-secrets/restic-new-password
         volumeMounts:
         - name: taiga-media
           mountPath: /media
diff --git a/src/test/cljc/dda/c4k_taiga/core_test.cljc b/src/test/cljc/dda/c4k_taiga/core_test.cljc
index a5de164..0913f98 100644
--- a/src/test/cljc/dda/c4k_taiga/core_test.cljc
+++ b/src/test/cljc/dda/c4k_taiga/core_test.cljc
@@ -1,6 +1,6 @@
 (ns dda.c4k-taiga.core-test
   (:require
-   #?(:cljs [shadow.resource :as rc])
+   #?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]])
    #?(:clj [clojure.test :refer [deftest is are testing run-tests]]
       :cljs [cljs.test :refer-macros [deftest is are testing run-tests]])
    [clojure.spec.alpha :as s]
@@ -8,11 +8,8 @@
    [dda.c4k-taiga.core :as cut]))
 
 #?(:cljs
-   (defmethod yaml/load-resource :website-test [resource-name]
-     (case resource-name
-       "taiga-test/valid-config.yaml" (rc/inline "taiga-test/valid-config.yaml")
-       "taiga-test/valid-auth.yaml" (rc/inline "taiga-test/valid-auth.yaml")
-       (throw (js/Error. "Undefined Resource!")))))
+   (defmethod yaml/load-resource :taiga-test [resource-name]
+     (get (inline-resources "taiga-test") resource-name)))
 
 (deftest validate-valid-resources
   (is (s/valid? cut/config? (yaml/load-as-edn "taiga-test/valid-config.yaml")))
diff --git a/src/test/cljc/dda/c4k_taiga/taiga_test.cljc b/src/test/cljc/dda/c4k_taiga/taiga_test.cljc
index edda554..08fbab4 100644
--- a/src/test/cljc/dda/c4k_taiga/taiga_test.cljc
+++ b/src/test/cljc/dda/c4k_taiga/taiga_test.cljc
@@ -14,8 +14,8 @@
 (st/instrument `cut/generate-secret)
 
 #?(:cljs
-   (defmethod yaml/load-resource :nextcloud-test [resource-name]
-     (get (inline-resources "nextcloud-test") resource-name)))
+   (defmethod yaml/load-resource :taiga-test [resource-name]
+     (get (inline-resources "taiga-test") resource-name)))
 
 (deftest should-generate-configmap
   (is (= {:apiVersion "v1",

From 77b996da46f83562317945985a33192bd2854984 Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Tue, 14 Jan 2025 15:56:37 +0100
Subject: [PATCH 08/21] introduce new backup & change-password

---
 README.md                                     |  2 +-
 doc/BackupAndRestore.md                       | 98 ++++++++++++-------
 infrastructure/backup/image/Dockerfile        |  4 +-
 .../backup/image/resources/backup.bb          | 32 ++++++
 .../backup/image/resources/backup.sh          | 17 ----
 .../backup/image/resources/bb-backup.edn      |  4 +
 infrastructure/backup/image/resources/bb.edn  |  3 +
 .../backup/image/resources/change-password.bb | 24 +++++
 .../resources/entrypoint-start-and-wait.sh    | 13 ---
 .../backup/image/resources/entrypoint.sh      | 11 ---
 infrastructure/backup/image/resources/init.bb |  3 +
 infrastructure/backup/image/resources/init.sh | 14 ---
 .../backup/image/resources/install.bb         | 18 ++++
 .../backup/image/resources/install.sh         | 21 ----
 .../backup/image/resources/list-snapshots.bb  | 20 ++++
 .../image/resources/restic-snapshots.sh       | 14 ---
 .../backup/image/resources/restore.bb         | 25 +++++
 .../backup/image/resources/restore.sh         | 29 ------
 infrastructure/backup/image/resources/wait.bb | 19 ++++
 infrastructure/backup/test/Dockerfile         |  4 +
 infrastructure/backup/test/resources/bb.edn   |  4 +
 .../backup/test/resources/file_password       |  1 +
 .../backup/test/resources/new_file_password   |  1 +
 infrastructure/backup/test/resources/test.bb  | 59 +++++++++++
 .../backup/backup-restore-deployment.yaml     |  2 +-
 src/main/resources/backup/cron.yaml           |  4 +-
 26 files changed, 286 insertions(+), 160 deletions(-)
 create mode 100755 infrastructure/backup/image/resources/backup.bb
 delete mode 100755 infrastructure/backup/image/resources/backup.sh
 create mode 100644 infrastructure/backup/image/resources/bb-backup.edn
 create mode 100644 infrastructure/backup/image/resources/bb.edn
 create mode 100755 infrastructure/backup/image/resources/change-password.bb
 delete mode 100644 infrastructure/backup/image/resources/entrypoint-start-and-wait.sh
 delete mode 100755 infrastructure/backup/image/resources/entrypoint.sh
 create mode 100755 infrastructure/backup/image/resources/init.bb
 delete mode 100755 infrastructure/backup/image/resources/init.sh
 create mode 100755 infrastructure/backup/image/resources/install.bb
 delete mode 100755 infrastructure/backup/image/resources/install.sh
 create mode 100755 infrastructure/backup/image/resources/list-snapshots.bb
 delete mode 100755 infrastructure/backup/image/resources/restic-snapshots.sh
 create mode 100755 infrastructure/backup/image/resources/restore.bb
 delete mode 100755 infrastructure/backup/image/resources/restore.sh
 create mode 100755 infrastructure/backup/image/resources/wait.bb
 create mode 100644 infrastructure/backup/test/Dockerfile
 create mode 100644 infrastructure/backup/test/resources/bb.edn
 create mode 100644 infrastructure/backup/test/resources/file_password
 create mode 100644 infrastructure/backup/test/resources/new_file_password
 create mode 100755 infrastructure/backup/test/resources/test.bb

diff --git a/README.md b/README.md
index f862dae..5dfbb17 100644
--- a/README.md
+++ b/README.md
@@ -98,7 +98,7 @@ For more details about our repository model see: https://repo.prod.meissa.de/mei
 
 ## License
 
-Copyright © 2024 meissa GmbH
+Copyright © 2024, 2025 meissa GmbH
 Licensed under the [Apache License, Version 2.0](LICENSE) (the "License")
 Pls. find licenses of our subcomponents [here](doc/SUBCOMPONENT_LICENSE)
 
diff --git a/doc/BackupAndRestore.md b/doc/BackupAndRestore.md
index a11bbe7..238ab93 100644
--- a/doc/BackupAndRestore.md
+++ b/doc/BackupAndRestore.md
@@ -7,41 +7,71 @@
 * Cloud stores files on `/var/jira`, these files are backuped. If you create a jira xml backup located in /var/jira this file will also be backed up.
 * postgres db is backed up as pgdump
 
-## Manual init the restic repository for the first time
+## Manual backup
 
-1. Scale backup-restore deployment up:   
-   `kubectl scale deployment backup-restore --replicas=1`
-1. exec into pod and execute restore pod   
-   `kubectl exec -it backup-restore -- /usr/local/bin/init.sh`
-1. Scale backup-restore deployment down:   
-  `kubectl scale deployment backup-restore --replicas=0`
-
-## Manual backup the restic repository for the first time
-
-1. Scale gateway and front deployment down:
-   `kubectl scale deployment taiga-gateway-deployment --replicas=0`
-   `kubectl scale deployment taiga-front-deployment --replicas=0`
-1. Scale backup-restore deployment up:
-   `kubectl scale deployment backup-restore --replicas=1`
-1. exec into pod and execute restore pod
-   `kubectl exec -it backup-restore -- /usr/local/bin/backup.sh`
-1. Scale backup-restore deployment down:
-   `kubectl scale deployment backup-restore --replicas=0`
-1. Scale gateway and front deployment up:
-   `kubectl scale deployment taiga-front-deployment --replicas=1`
-   `kubectl scale deployment taiga-gateway-deployment --replicas=1`
+1. Scale gateway and front deployment down:   
+   `kubectl -n taiga scale deployment taiga-gateway-deployment --replicas=0`
+   `kubectl -n taiga scale deployment taiga-front-deployment --replicas=0`
+2. Scale backup-restore deployment up:   
+   `kubectl -n taiga scale deployment backup-restore --replicas=1`
+3. exec into pod and execute restore pod   
+   `kubectl -n taiga exec -it backup-restore -- backup.bb`
+4. Scale backup-restore deployment down:   
+  `kubectl -n taiga scale deployment backup-restore --replicas=0`
+1. Scale gateway and front deployment up:   
+   `kubectl -n taiga scale deployment taiga-gateway-deployment --replicas=1`
+   `kubectl -n taiga scale deployment taiga-front-deployment --replicas=1`
 
 ## Manual restore
 
-1. Scale gateway and front deployment down:
-   `kubectl scale deployment taiga-gateway-deployment --replicas=0`
-   `kubectl scale deployment taiga-front-deployment --replicas=0`
-2. Scale backup-restore deployment up:
-   `kubectl scale deployment backup-restore --replicas=1`
-3. exec into pod and execute restore pod:
-   `kubectl exec -it backup-restore -- /usr/local/bin/restore.sh`
-4. Scale backup-restore deployment down:
-   `kubectl scale deployment backup-restore --replicas=0`
-5. Scale gateway and front deployment up:
-   `kubectl scale deployment taiga-front-deployment --replicas=1`
-   `kubectl scale deployment taiga-gateway-deployment --replicas=1`
+1. Scale gateway and front deployment down:   
+   `kubectl -n taiga scale deployment taiga-gateway-deployment --replicas=0`
+   `kubectl -n taiga scale deployment taiga-front-deployment --replicas=0`
+2. Scale backup-restore deployment up:   
+   `kubectl -n taiga scale deployment backup-restore --replicas=1`
+3. exec into pod and execute restore pod   
+   `kubectl -n taiga exec -it backup-restore -- restore.bb`
+4. Scale backup-restore deployment down:   
+  `kubectl -n taiga scale deployment backup-restore --replicas=0`
+5. Scale gateway and front deployment up:   
+   `kubectl -n taiga scale deployment taiga-gateway-deployment --replicas=1`
+   `kubectl -n taiga scale deployment taiga-front-deployment --replicas=1`
+
+## 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 taiga scale deployment backup-restore --replicas=1`
+4. exec into pod and execute restore pod   
+   `kubectl -n taiga exec -it backup-restore -- change-password.bb`
+5. Scale backup-restore deployment down:   
+  `kubectl -n taiga 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
+   ```
\ No newline at end of file
diff --git a/infrastructure/backup/image/Dockerfile b/infrastructure/backup/image/Dockerfile
index e6e11b4..9101431 100644
--- a/infrastructure/backup/image/Dockerfile
+++ b/infrastructure/backup/image/Dockerfile
@@ -1,5 +1,5 @@
-FROM domaindrivenarchitecture/dda-backup:latest
+FROM domaindrivenarchitecture/dda-backup:5.3.0
 
 # Prepare Entrypoint Script
 ADD resources /tmp
-RUN /tmp/install.sh
+RUN /tmp/install.bb
diff --git a/infrastructure/backup/image/resources/backup.bb b/infrastructure/backup/image/resources/backup.bb
new file mode 100755
index 0000000..414f64c
--- /dev/null
+++ b/infrastructure/backup/image/resources/backup.bb
@@ -0,0 +1,32 @@
+#!/usr/bin/env bb
+(require
+ '[babashka.tasks :as t]
+ '[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 config (cfg/read-config "/usr/local/bin/config.edn"))
+
+
+(defn prepare!
+  []
+  (bc/create-aws-credentials! (:aws-config config))
+  (pg/create-pg-pass! (:db-config config)))
+
+(defn restic-repo-init!
+  []
+  (rc/init! (:file-config config))
+  (rc/init! (:db-config config)))
+
+(defn restic-backup!
+  []
+  (bak/backup-file! (:file-config config))
+  (bak/backup-db! (:db-config config)))
+
+(t/shell "start-maintenance.sh")
+(prepare!)
+(restic-repo-init!)
+(restic-backup!)
+(t/shell "end-maintenance.sh")
\ No newline at end of file
diff --git a/infrastructure/backup/image/resources/backup.sh b/infrastructure/backup/image/resources/backup.sh
deleted file mode 100755
index 8278099..0000000
--- a/infrastructure/backup/image/resources/backup.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-
-function main() {
-    file_env AWS_ACCESS_KEY_ID
-    file_env AWS_SECRET_ACCESS_KEY
-    file_env RESTIC_DAYS_TO_KEEP 30
-    file_env RESTIC_MONTHS_TO_KEEP 12
-
-    backup-db-dump
-    backup-directory "/media"
-}
-
-source /usr/local/lib/functions.sh
-source /usr/local/lib/pg-functions.sh
-source /usr/local/lib/file-functions.sh
-
-main
diff --git a/infrastructure/backup/image/resources/bb-backup.edn b/infrastructure/backup/image/resources/bb-backup.edn
new file mode 100644
index 0000000..11e9d9c
--- /dev/null
+++ b/infrastructure/backup/image/resources/bb-backup.edn
@@ -0,0 +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
new file mode 100644
index 0000000..da7e0df
--- /dev/null
+++ b/infrastructure/backup/image/resources/bb.edn
@@ -0,0 +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.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/entrypoint-start-and-wait.sh b/infrastructure/backup/image/resources/entrypoint-start-and-wait.sh
deleted file mode 100644
index c6addac..0000000
--- a/infrastructure/backup/image/resources/entrypoint-start-and-wait.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash
-
-function main() {
-    create-pg-pass
-
-    while true; do
-        sleep 1m
-    done
-}
-
-source /usr/local/lib/functions.sh
-source /usr/local/lib/pg-functions.sh
-main
\ No newline at end of file
diff --git a/infrastructure/backup/image/resources/entrypoint.sh b/infrastructure/backup/image/resources/entrypoint.sh
deleted file mode 100755
index 96df4f3..0000000
--- a/infrastructure/backup/image/resources/entrypoint.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-function main() {
-    create-pg-pass
-
-	/usr/local/bin/backup.sh
-}
-
-source /usr/local/lib/functions.sh
-source /usr/local/lib/pg-functions.sh
-main
diff --git a/infrastructure/backup/image/resources/init.bb b/infrastructure/backup/image/resources/init.bb
new file mode 100755
index 0000000..af0856c
--- /dev/null
+++ b/infrastructure/backup/image/resources/init.bb
@@ -0,0 +1,3 @@
+#!/usr/bin/env bb
+
+(println "initialized")
diff --git a/infrastructure/backup/image/resources/init.sh b/infrastructure/backup/image/resources/init.sh
deleted file mode 100755
index 1f47fa5..0000000
--- a/infrastructure/backup/image/resources/init.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash
-
-function main() {
-    file_env AWS_ACCESS_KEY_ID
-    file_env AWS_SECRET_ACCESS_KEY
-
-    init-database-repo
-    init-file-repo
-}
-
-source /usr/local/lib/functions.sh
-source /usr/local/lib/pg-functions.sh
-source /usr/local/lib/file-functions.sh
-main
diff --git a/infrastructure/backup/image/resources/install.bb b/infrastructure/backup/image/resources/install.bb
new file mode 100755
index 0000000..089d104
--- /dev/null
+++ b/infrastructure/backup/image/resources/install.bb
@@ -0,0 +1,18 @@
+#!/usr/bin/env bb
+
+(require
+ '[dda.image.ubuntu :as ub]
+ '[dda.image.install :as in])
+
+(ub/upgrade-system!)
+(in/install! "bb-backup.edn" :target-name "bb.edn" :mod "0440")
+(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! "restore.bb")
+(in/install! "wait.bb")
+
+(ub/cleanup-container!)
\ No newline at end of file
diff --git a/infrastructure/backup/image/resources/install.sh b/infrastructure/backup/image/resources/install.sh
deleted file mode 100755
index f9c0484..0000000
--- a/infrastructure/backup/image/resources/install.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-
-set -exo pipefail
-
-function main()
-{
-    {
-        install -m 0700 /tmp/entrypoint.sh /
-        install -m 0700 /tmp/entrypoint-start-and-wait.sh /
-
-        install -m 0700 /tmp/init.sh /usr/local/bin/
-        install -m 0700 /tmp/backup.sh /usr/local/bin/
-        install -m 0700 /tmp/restore.sh /usr/local/bin/
-        install -m 0700 /tmp/restic-snapshots.sh /usr/local/bin/
-        
-        cleanupDocker
-    } > /dev/null
-}
-
-source /tmp/install_functions_debian.sh
-DEBIAN_FRONTEND=noninteractive DEBCONF_NOWARNINGS=yes main
diff --git a/infrastructure/backup/image/resources/list-snapshots.bb b/infrastructure/backup/image/resources/list-snapshots.bb
new file mode 100755
index 0000000..4ca7fa0
--- /dev/null
+++ b/infrastructure/backup/image/resources/list-snapshots.bb
@@ -0,0 +1,20 @@
+#!/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"))
+
+
+(defn prepare!
+  []
+  (bc/create-aws-credentials! (:aws-config config)))
+
+(defn list-snapshots!
+  []
+  (rc/list-snapshots! (:file-config config))
+  (rc/list-snapshots! (:db-config config)))
+
+(prepare!)
+(list-snapshots!)
diff --git a/infrastructure/backup/image/resources/restic-snapshots.sh b/infrastructure/backup/image/resources/restic-snapshots.sh
deleted file mode 100755
index 39909c6..0000000
--- a/infrastructure/backup/image/resources/restic-snapshots.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash
-
-function main() {
-    file_env AWS_ACCESS_KEY_ID
-    file_env AWS_SECRET_ACCESS_KEY
-
-    restic -r ${RESTIC_REPOSITORY}/files snapshots
-    restic -r ${RESTIC_REPOSITORY}/pg-database snapshots
-}
-
-source /usr/local/lib/functions.sh
-source /usr/local/lib/file-functions.sh
-
-main
diff --git a/infrastructure/backup/image/resources/restore.bb b/infrastructure/backup/image/resources/restore.bb
new file mode 100755
index 0000000..bf2ade3
--- /dev/null
+++ b/infrastructure/backup/image/resources/restore.bb
@@ -0,0 +1,25 @@
+#!/usr/bin/env bb
+(require
+ '[babashka.tasks :as t]
+ '[dda.backup.core :as bc]
+ '[dda.backup.config :as cfg]
+ '[dda.backup.postgresql :as pg]
+ '[dda.backup.restore :as rs])
+
+(def config (cfg/read-config "/usr/local/bin/config.edn"))
+
+(defn prepare!
+  []
+  (bc/create-aws-credentials! (:aws-config config))
+  (pg/create-pg-pass! (:db-config config)))
+
+(defn restic-restore!
+  []
+  (pg/drop-create-db! (:db-config config))
+  (rs/restore-db! (:db-config config))
+  (rs/restore-file! (:file-restore-config config))
+  (t/shell "mv /var/backups/restore/* /media")
+  (t/shell "chown -R 999:999 /media"))
+
+(prepare!)
+(restic-restore!)
diff --git a/infrastructure/backup/image/resources/restore.sh b/infrastructure/backup/image/resources/restore.sh
deleted file mode 100755
index b7a88dd..0000000
--- a/infrastructure/backup/image/resources/restore.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-
-function main() {
-
-    file_env AWS_ACCESS_KEY_ID
-    file_env AWS_SECRET_ACCESS_KEY
-
-    file_env POSTGRES_DB
-    file_env POSTGRES_PASSWORD
-    file_env POSTGRES_USER
-
-    # Restore latest snapshot into /var/backups/restore
-    restore-directory '/var/backups/restore'
-    
-    mv /var/backups/restore/* /media
-
-    # adjust file permissions for the taiga user
-    chown -R 999:999 /media
-
-    # Restore db
-    drop-create-db
-    restore-db
-}
-
-source /usr/local/lib/functions.sh
-source /usr/local/lib/pg-functions.sh
-source /usr/local/lib/file-functions.sh
-
-main
diff --git a/infrastructure/backup/image/resources/wait.bb b/infrastructure/backup/image/resources/wait.bb
new file mode 100755
index 0000000..bd0ecd9
--- /dev/null
+++ b/infrastructure/backup/image/resources/wait.bb
@@ -0,0 +1,19 @@
+#!/usr/bin/env bb
+(require
+ '[dda.backup.core :as bc]
+ '[dda.backup.config :as cfg]
+ '[dda.backup.postgresql :as pg])
+
+(def config (cfg/read-config "/usr/local/bin/config.edn"))
+
+(defn prepare!
+  []
+  (bc/create-aws-credentials! (:aws-config config))
+  (pg/create-pg-pass! (:db-config config)))
+
+(defn wait! []
+  (while true
+    (Thread/sleep 1000)))
+
+(prepare!)
+(wait!)
diff --git a/infrastructure/backup/test/Dockerfile b/infrastructure/backup/test/Dockerfile
new file mode 100644
index 0000000..d40e7d1
--- /dev/null
+++ b/infrastructure/backup/test/Dockerfile
@@ -0,0 +1,4 @@
+FROM c4k-taiga-backup:latest
+
+ADD resources /tmp/
+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/bb.edn b/infrastructure/backup/test/resources/bb.edn
new file mode 100644
index 0000000..11e9d9c
--- /dev/null
+++ b/infrastructure/backup/test/resources/bb.edn
@@ -0,0 +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
new file mode 100755
index 0000000..69438d0
--- /dev/null
+++ b/infrastructure/backup/test/resources/test.bb
@@ -0,0 +1,59 @@
+#!/usr/bin/env bb
+(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 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")}))
+
+(defn prepare!
+  []
+  (tasks/shell "mkdir" "-p" "/var/backups/")
+  (spit "/var/backups/file" "I was here")
+  (tasks/shell "mkdir" "-p" "/var/restore"))
+
+(defn restic-repo-init!
+  []
+  (rc/init! (:file-config config))
+  (rc/init! (merge (:db-config config)
+                   (:dry-run config))))
+
+(defn restic-backup!
+  []
+  (bak/backup-file! (:file-config config))
+  (bak/backup-db! (merge (:db-config config)
+                         (:dry-run config))))
+
+(defn list-snapshots!
+  []
+  (rc/list-snapshots! (:file-config config))
+  (rc/list-snapshots! (merge (:db-config config)
+                             (:dry-run config))))
+
+
+(defn restic-restore!
+  []
+  (pg/drop-create-db! (merge (:db-config config)
+                             (:dry-run config)))
+  (rs/restore-db! (merge (:db-config config)
+                         (:dry-run config)))
+  (rs/restore-file! (merge (:file-restore-config config)
+                           (:dry-run 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!)
diff --git a/src/main/resources/backup/backup-restore-deployment.yaml b/src/main/resources/backup/backup-restore-deployment.yaml
index 550113d..a187aad 100644
--- a/src/main/resources/backup/backup-restore-deployment.yaml
+++ b/src/main/resources/backup/backup-restore-deployment.yaml
@@ -21,7 +21,7 @@ spec:
       - image: domaindrivenarchitecture/c4k-taiga-backup
         name: backup-app
         imagePullPolicy: IfNotPresent
-        command: ["/entrypoint-start-and-wait.sh"]
+        command: ["wait.bb"]
         env:
         - name: POSTGRES_USER
           valueFrom:
diff --git a/src/main/resources/backup/cron.yaml b/src/main/resources/backup/cron.yaml
index aa4c419..a450b2e 100644
--- a/src/main/resources/backup/cron.yaml
+++ b/src/main/resources/backup/cron.yaml
@@ -17,7 +17,7 @@ spec:
           - name: backup-app
             image: domaindrivenarchitecture/c4k-taiga-backup
             imagePullPolicy: IfNotPresent
-            command: ["/entrypoint.sh"]
+            command: ["backup.bb"]
             env:
             - name: POSTGRES_USER
               valueFrom:
@@ -53,8 +53,6 @@ spec:
                   key: restic-repository
             - name: RESTIC_PASSWORD_FILE
               value: /var/run/secrets/backup-secrets/restic-password
-            - name: CERTIFICATE_FILE
-              value: ""
             volumeMounts:
             - name: taiga-media
               mountPath: /media

From 8ca5e5e9dd91cd4648a194da9c1b087f20689d98 Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Wed, 15 Jan 2025 09:28:25 +0100
Subject: [PATCH 09/21] fix some namespace problems

---
 build.py                                      |   1 +
 src/main/cljc/dda/c4k_taiga/core.cljc         | 102 +++++++++---------
 .../taiga/async-rabbitmq-service.yaml         |   2 +-
 src/main/resources/taiga/async-service.yaml   |   2 +-
 .../taiga/events-rabbitmq-service.yaml        |   2 +-
 5 files changed, 55 insertions(+), 54 deletions(-)

diff --git a/build.py b/build.py
index ba479d4..2099868 100644
--- a/build.py
+++ b/build.py
@@ -152,6 +152,7 @@ def upload_clj(project):
 
 @task
 def inst(project):
+    run("lein uberjar", shell=True, check=True)
     package_uberjar(project)
     package_native(project)
     run(
diff --git a/src/main/cljc/dda/c4k_taiga/core.cljc b/src/main/cljc/dda/c4k_taiga/core.cljc
index 51b226c..52f6aa0 100644
--- a/src/main/cljc/dda/c4k_taiga/core.cljc
+++ b/src/main/cljc/dda/c4k_taiga/core.cljc
@@ -24,7 +24,7 @@
                :enable-telemetry "false"})
 
 (def config? (s/merge
-              ::backup/config              
+              ::backup/config
               (s/keys :req-un [::taiga/fqdn]
                       :opt-un [::taiga/issuer
                                ::taiga/storage-class-name
@@ -54,58 +54,58 @@
 
 (defn-spec config-objects cp/map-or-seq?
   [config config?]
-  (let [resolved-config (merge defaults config)
-        db-config (merge resolved-config {:postgres-size :8gb :db-name "taiga"
-                                          :pv-storage-size-gb 50})]
-  (cm/concat-vec
-    (map yaml/to-string
-         (filter
-          #(not (nil? %))
-          (cm/concat-vec
-           (ns/generate resolved-config)
-           (postgres/generate-config db-config)
-           [(taiga/generate-async-deployment)
-            (taiga/generate-async-rabbitmq-deployment)
-            (taiga/generate-async-rabbitmq-service)
-            (taiga/generate-async-service)
-            (taiga/generate-back-deployment)
-            (taiga/generate-back-service)
-            (taiga/generate-configmap resolved-config)
-            (taiga/generate-pvc-taiga-media-data resolved-config)
-            (taiga/generate-pvc-taiga-static-data resolved-config)
-            (taiga/generate-events-deployment)
-            (taiga/generate-events-rabbitmq-deployment)
-            (taiga/generate-events-rabbitmq-service)
-            (taiga/generate-events-service)
-            (taiga/generate-front-deployment)
-            (taiga/generate-front-service)
-            (taiga/generate-gateway-configmap)
-            (taiga/generate-gateway-deployment)
-            (taiga/generate-gateway-service)
-            (taiga/generate-protected-deployment)
-            (taiga/generate-protected-service)
-            (taiga/generate-rabbitmq-pvc-async resolved-config)
-            (taiga/generate-rabbitmq-pvc-events resolved-config)]
-           (taiga/generate-ingress-and-cert resolved-config)
-           (when (contains? resolved-config :restic-repository)
-             [(backup/generate-config resolved-config)
-              (backup/generate-cron)
-              (backup/generate-backup-restore-deployment resolved-config)])
-           (when (:contains? resolved-config :mon-cfg)
-             (mon/generate-config))))))))
+  (let [resolved-config (merge defaults config)]
+    (cm/concat-vec
+     (map yaml/to-string
+          (filter
+           #(not (nil? %))
+           (cm/concat-vec
+            (ns/generate resolved-config)
+            (postgres/generate-config (merge resolved-config
+                                             {:postgres-size :8gb :db-name "taiga"
+                                              :pv-storage-size-gb 50}))
+            [(taiga/generate-async-deployment)
+             (taiga/generate-async-rabbitmq-deployment)
+             (taiga/generate-async-rabbitmq-service)
+             (taiga/generate-async-service)
+             (taiga/generate-back-deployment)
+             (taiga/generate-back-service)
+             (taiga/generate-configmap resolved-config)
+             (taiga/generate-pvc-taiga-media-data resolved-config)
+             (taiga/generate-pvc-taiga-static-data resolved-config)
+             (taiga/generate-events-deployment)
+             (taiga/generate-events-rabbitmq-deployment)
+             (taiga/generate-events-rabbitmq-service)
+             (taiga/generate-events-service)
+             (taiga/generate-front-deployment)
+             (taiga/generate-front-service)
+             (taiga/generate-gateway-configmap)
+             (taiga/generate-gateway-deployment)
+             (taiga/generate-gateway-service)
+             (taiga/generate-protected-deployment)
+             (taiga/generate-protected-service)
+             (taiga/generate-rabbitmq-pvc-async resolved-config)
+             (taiga/generate-rabbitmq-pvc-events resolved-config)]
+            (taiga/generate-ingress-and-cert resolved-config)
+            (when (contains? resolved-config :restic-repository)
+              [(backup/generate-config resolved-config)
+               (backup/generate-cron)
+               (backup/generate-backup-restore-deployment resolved-config)])
+            (when (:contains? resolved-config :mon-cfg)
+              (mon/generate-config))))))))
 
 (defn-spec auth-objects cp/map-or-seq?
   [config config?
    auth auth?]
   (let [resolved-config (merge defaults config)]
-  (cm/concat-vec
-    (map yaml/to-string
-         (filter
-          #(not (nil? %))
-          (cm/concat-vec
-           [(postgres/generate-secret auth)
-            (taiga/generate-secret auth)]
-           (when (contains? resolved-config :restic-repository)
-             [(backup/generate-secret auth)])
-           (when (:contains? resolved-config :mon-cfg)
-             (mon/generate-auth (:mon-cfg resolved-config) (:mon-auth auth)))))))))
+    (cm/concat-vec
+     (map yaml/to-string
+          (filter
+           #(not (nil? %))
+           (cm/concat-vec
+            (postgres/generate-auth resolved-config auth)
+            [(taiga/generate-secret auth)]            
+            (when (contains? resolved-config :restic-repository)
+              [(backup/generate-secret auth)])
+            (when (:contains? resolved-config :mon-cfg)
+              (mon/generate-auth (:mon-cfg resolved-config) (:mon-auth auth)))))))))
diff --git a/src/main/resources/taiga/async-rabbitmq-service.yaml b/src/main/resources/taiga/async-rabbitmq-service.yaml
index ea541dd..d1d86bf 100644
--- a/src/main/resources/taiga/async-rabbitmq-service.yaml
+++ b/src/main/resources/taiga/async-rabbitmq-service.yaml
@@ -6,7 +6,7 @@ metadata:
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-async-rabbitmq
-  namespace: default
+  namespace: taiga
 spec:
   type: ClusterIP
   selector:
diff --git a/src/main/resources/taiga/async-service.yaml b/src/main/resources/taiga/async-service.yaml
index 14a9445..7daea47 100644
--- a/src/main/resources/taiga/async-service.yaml
+++ b/src/main/resources/taiga/async-service.yaml
@@ -6,7 +6,7 @@ metadata:
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-async
-  namespace: default
+  namespace: taiga
 spec:
   type: ClusterIP
   selector:
diff --git a/src/main/resources/taiga/events-rabbitmq-service.yaml b/src/main/resources/taiga/events-rabbitmq-service.yaml
index 7acc766..bfc75d4 100644
--- a/src/main/resources/taiga/events-rabbitmq-service.yaml
+++ b/src/main/resources/taiga/events-rabbitmq-service.yaml
@@ -6,7 +6,7 @@ metadata:
   labels:
     app.kubernetes.part-of: c4k-taiga
     app.kubernetes.io/component: taiga-events-rabbitmq
-  namespace: default
+  namespace: taiga
 spec:
   type: ClusterIP
   selector:

From e9ba08b61bff660ef36e05cef0701d9371ee19db Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Wed, 15 Jan 2025 09:55:43 +0100
Subject: [PATCH 10/21] release: 1.2.0

---
 infrastructure/backup/build.py | 27 ++++++++++++++++-----------
 package.json                   |  2 +-
 project.clj                    |  2 +-
 3 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/infrastructure/backup/build.py b/infrastructure/backup/build.py
index 3a87c9f..0fdf5b6 100644
--- a/infrastructure/backup/build.py
+++ b/infrastructure/backup/build.py
@@ -1,14 +1,20 @@
 from os import environ
+from datetime import datetime
 from pybuilder.core import task, init
 from ddadevops import *
 
-name = "c4k-taiga-backup"
-MODULE = "docker"
+name = "c4k-taiga"
+MODULE = "backup"
 PROJECT_ROOT_PATH = "../.."
+version = "1.2.0"
 
 
 @init
 def initialize(project):
+    image_tag = version
+    if "dev" in image_tag:
+        image_tag += datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
+
     input = {
         "name": name,
         "module": MODULE,
@@ -16,9 +22,11 @@ def initialize(project):
         "project_root_path": PROJECT_ROOT_PATH,
         "build_types": ["IMAGE"],
         "mixin_types": [],
+        "image_naming": "NAME_AND_MODULE",
+        "image_tag": f"{image_tag}",
     }
 
-    project.build_depends_on("ddadevops>=4.0.0-dev")
+    project.build_depends_on("ddadevops>=4.7.0")
 
     build = DevopsImageBuild(project, input)
     build.initialize_build_dir()
@@ -29,21 +37,18 @@ def image(project):
     build = get_devops_build(project)
     build.image()
 
-
 @task
 def drun(project):
     build = get_devops_build(project)
     build.drun()
 
+@task
+def test(project):
+    build = get_devops_build(project)
+    build.test()
 
 @task
 def publish(project):
     build = get_devops_build(project)
     build.dockerhub_login()
-    build.dockerhub_publish()
-
-
-@task
-def test(project):
-    build = get_devops_build(project)
-    build.test()
+    build.dockerhub_publish()
\ No newline at end of file
diff --git a/package.json b/package.json
index fb42886..61c1eee 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
     "name": "c4k-taiga",
     "description": "Generate c4k yaml for a taiga project management deployment.",
     "author": "meissa GmbH",
-    "version": "1.1.3-SNAPSHOT",
+    "version": "1.2.0",
     "homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-taiga#readme",
     "repository": "https://www.npmjs.com/package/c4k-taiga",
     "license": "APACHE2",
diff --git a/project.clj b/project.clj
index 903f955..9bbdfb2 100644
--- a/project.clj
+++ b/project.clj
@@ -1,4 +1,4 @@
-(defproject org.domaindrivenarchitecture/c4k-taiga "1.1.3-SNAPSHOT"
+(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.0"
   :description "taiga c4k-installation package"
   :url "https://domaindrivenarchitecture.org"
   :license {:name "Apache License, Version 2.0"

From 0b7e7991ce5a998603c3b7a6b13cca8457a7fa1b Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Wed, 15 Jan 2025 09:55:43 +0100
Subject: [PATCH 11/21] bump version to: 1.2.1-SNAPSHOT

---
 infrastructure/backup/build.py | 2 +-
 package.json                   | 2 +-
 project.clj                    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/infrastructure/backup/build.py b/infrastructure/backup/build.py
index 0fdf5b6..890fcef 100644
--- a/infrastructure/backup/build.py
+++ b/infrastructure/backup/build.py
@@ -6,7 +6,7 @@ from ddadevops import *
 name = "c4k-taiga"
 MODULE = "backup"
 PROJECT_ROOT_PATH = "../.."
-version = "1.2.0"
+version = "1.2.1-dev"
 
 
 @init
diff --git a/package.json b/package.json
index 61c1eee..415605a 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
     "name": "c4k-taiga",
     "description": "Generate c4k yaml for a taiga project management deployment.",
     "author": "meissa GmbH",
-    "version": "1.2.0",
+    "version": "1.2.1-SNAPSHOT",
     "homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-taiga#readme",
     "repository": "https://www.npmjs.com/package/c4k-taiga",
     "license": "APACHE2",
diff --git a/project.clj b/project.clj
index 9bbdfb2..23fcabc 100644
--- a/project.clj
+++ b/project.clj
@@ -1,4 +1,4 @@
-(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.0"
+(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.1-SNAPSHOT"
   :description "taiga c4k-installation package"
   :url "https://domaindrivenarchitecture.org"
   :license {:name "Apache License, Version 2.0"

From 1cc181662e785015946c453278c390e0c88a1fba Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Wed, 15 Jan 2025 13:04:37 +0100
Subject: [PATCH 12/21] fix backup & restore script

---
 .gitignore                                       | 2 ++
 infrastructure/backup/image/resources/backup.bb  | 3 ---
 infrastructure/backup/image/resources/restore.bb | 1 -
 3 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/.gitignore b/.gitignore
index 33d8fb7..7fedce8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,3 +32,5 @@ config.edn
 
 build-and-move-frontend.sh
 website.yaml
+
+.envrc
diff --git a/infrastructure/backup/image/resources/backup.bb b/infrastructure/backup/image/resources/backup.bb
index 414f64c..c7f0dcc 100755
--- a/infrastructure/backup/image/resources/backup.bb
+++ b/infrastructure/backup/image/resources/backup.bb
@@ -1,6 +1,5 @@
 #!/usr/bin/env bb
 (require
- '[babashka.tasks :as t]
  '[dda.backup.core :as bc]
  '[dda.backup.config :as cfg]
  '[dda.backup.restic :as rc]
@@ -25,8 +24,6 @@
   (bak/backup-file! (:file-config config))
   (bak/backup-db! (:db-config config)))
 
-(t/shell "start-maintenance.sh")
 (prepare!)
 (restic-repo-init!)
 (restic-backup!)
-(t/shell "end-maintenance.sh")
\ No newline at end of file
diff --git a/infrastructure/backup/image/resources/restore.bb b/infrastructure/backup/image/resources/restore.bb
index bf2ade3..9dece9e 100755
--- a/infrastructure/backup/image/resources/restore.bb
+++ b/infrastructure/backup/image/resources/restore.bb
@@ -18,7 +18,6 @@
   (pg/drop-create-db! (:db-config config))
   (rs/restore-db! (:db-config config))
   (rs/restore-file! (:file-restore-config config))
-  (t/shell "mv /var/backups/restore/* /media")
   (t/shell "chown -R 999:999 /media"))
 
 (prepare!)

From 7d44d390f538ac18c9caec861406efeee45ee425 Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Wed, 15 Jan 2025 13:08:02 +0100
Subject: [PATCH 13/21] release: 1.2.1

---
 infrastructure/backup/build.py | 2 +-
 package.json                   | 2 +-
 project.clj                    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/infrastructure/backup/build.py b/infrastructure/backup/build.py
index 890fcef..8d9a888 100644
--- a/infrastructure/backup/build.py
+++ b/infrastructure/backup/build.py
@@ -6,7 +6,7 @@ from ddadevops import *
 name = "c4k-taiga"
 MODULE = "backup"
 PROJECT_ROOT_PATH = "../.."
-version = "1.2.1-dev"
+version = "1.2.1"
 
 
 @init
diff --git a/package.json b/package.json
index 415605a..e3ee23c 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
     "name": "c4k-taiga",
     "description": "Generate c4k yaml for a taiga project management deployment.",
     "author": "meissa GmbH",
-    "version": "1.2.1-SNAPSHOT",
+    "version": "1.2.1",
     "homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-taiga#readme",
     "repository": "https://www.npmjs.com/package/c4k-taiga",
     "license": "APACHE2",
diff --git a/project.clj b/project.clj
index 23fcabc..2124186 100644
--- a/project.clj
+++ b/project.clj
@@ -1,4 +1,4 @@
-(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.1-SNAPSHOT"
+(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.1"
   :description "taiga c4k-installation package"
   :url "https://domaindrivenarchitecture.org"
   :license {:name "Apache License, Version 2.0"

From 8439b20b42273ec49374776edadd52210a0edb10 Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Wed, 15 Jan 2025 13:08:03 +0100
Subject: [PATCH 14/21] bump version to: 1.2.2-SNAPSHOT

---
 infrastructure/backup/build.py | 2 +-
 package.json                   | 2 +-
 project.clj                    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/infrastructure/backup/build.py b/infrastructure/backup/build.py
index 8d9a888..ca503f9 100644
--- a/infrastructure/backup/build.py
+++ b/infrastructure/backup/build.py
@@ -6,7 +6,7 @@ from ddadevops import *
 name = "c4k-taiga"
 MODULE = "backup"
 PROJECT_ROOT_PATH = "../.."
-version = "1.2.1"
+version = "1.2.2-dev"
 
 
 @init
diff --git a/package.json b/package.json
index e3ee23c..0027665 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
     "name": "c4k-taiga",
     "description": "Generate c4k yaml for a taiga project management deployment.",
     "author": "meissa GmbH",
-    "version": "1.2.1",
+    "version": "1.2.2-SNAPSHOT",
     "homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-taiga#readme",
     "repository": "https://www.npmjs.com/package/c4k-taiga",
     "license": "APACHE2",
diff --git a/project.clj b/project.clj
index 2124186..69acdb9 100644
--- a/project.clj
+++ b/project.clj
@@ -1,4 +1,4 @@
-(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.1"
+(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.2-SNAPSHOT"
   :description "taiga c4k-installation package"
   :url "https://domaindrivenarchitecture.org"
   :license {:name "Apache License, Version 2.0"

From 2122809cb4c77b6e2b9b1dd2cd9534c14910d044 Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Fri, 17 Jan 2025 16:21:39 +0100
Subject: [PATCH 15/21] release: 1.2.2

---
 infrastructure/backup/build.py | 2 +-
 package.json                   | 2 +-
 project.clj                    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/infrastructure/backup/build.py b/infrastructure/backup/build.py
index ca503f9..5dda27a 100644
--- a/infrastructure/backup/build.py
+++ b/infrastructure/backup/build.py
@@ -6,7 +6,7 @@ from ddadevops import *
 name = "c4k-taiga"
 MODULE = "backup"
 PROJECT_ROOT_PATH = "../.."
-version = "1.2.2-dev"
+version = "1.2.2"
 
 
 @init
diff --git a/package.json b/package.json
index 0027665..d18ae84 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
     "name": "c4k-taiga",
     "description": "Generate c4k yaml for a taiga project management deployment.",
     "author": "meissa GmbH",
-    "version": "1.2.2-SNAPSHOT",
+    "version": "1.2.2",
     "homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-taiga#readme",
     "repository": "https://www.npmjs.com/package/c4k-taiga",
     "license": "APACHE2",
diff --git a/project.clj b/project.clj
index 69acdb9..a8547ad 100644
--- a/project.clj
+++ b/project.clj
@@ -1,4 +1,4 @@
-(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.2-SNAPSHOT"
+(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.2"
   :description "taiga c4k-installation package"
   :url "https://domaindrivenarchitecture.org"
   :license {:name "Apache License, Version 2.0"

From 17fe23e965559ce25bc6d4dc0dd6f73f240b1c06 Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Fri, 17 Jan 2025 16:21:39 +0100
Subject: [PATCH 16/21] bump version to: 1.2.3-SNAPSHOT

---
 infrastructure/backup/build.py | 2 +-
 package.json                   | 2 +-
 project.clj                    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/infrastructure/backup/build.py b/infrastructure/backup/build.py
index 5dda27a..dc535e4 100644
--- a/infrastructure/backup/build.py
+++ b/infrastructure/backup/build.py
@@ -6,7 +6,7 @@ from ddadevops import *
 name = "c4k-taiga"
 MODULE = "backup"
 PROJECT_ROOT_PATH = "../.."
-version = "1.2.2"
+version = "1.2.3-dev"
 
 
 @init
diff --git a/package.json b/package.json
index d18ae84..a91d301 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
     "name": "c4k-taiga",
     "description": "Generate c4k yaml for a taiga project management deployment.",
     "author": "meissa GmbH",
-    "version": "1.2.2",
+    "version": "1.2.3-SNAPSHOT",
     "homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-taiga#readme",
     "repository": "https://www.npmjs.com/package/c4k-taiga",
     "license": "APACHE2",
diff --git a/project.clj b/project.clj
index a8547ad..c374a64 100644
--- a/project.clj
+++ b/project.clj
@@ -1,4 +1,4 @@
-(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.2"
+(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.3-SNAPSHOT"
   :description "taiga c4k-installation package"
   :url "https://domaindrivenarchitecture.org"
   :license {:name "Apache License, Version 2.0"

From 860659aa6a297a4d21c3bc36d13649b27795fb7f Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Fri, 17 Jan 2025 16:26:09 +0100
Subject: [PATCH 17/21] add the missing config.edn

---
 .gitignore                                    |  3 ---
 .../backup/image/resources/config.edn         | 24 +++++++++++++++++++
 2 files changed, 24 insertions(+), 3 deletions(-)
 create mode 100644 infrastructure/backup/image/resources/config.edn

diff --git a/.gitignore b/.gitignore
index 7fedce8..07e495a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,9 +27,6 @@ public/js/
 *.iml
 .idea/
 
-auth.edn
-config.edn
-
 build-and-move-frontend.sh
 website.yaml
 
diff --git a/infrastructure/backup/image/resources/config.edn b/infrastructure/backup/image/resources/config.edn
new file mode 100644
index 0000000..ab0bf09
--- /dev/null
+++ b/infrastructure/backup/image/resources/config.edn
@@ -0,0 +1,24 @@
+{:restic-repo {:password-file #env-or-file "RESTIC_PASSWORD_FILE"
+               :restic-repository #env-or-file "RESTIC_REPOSITORY"}
+ 
+ :file-config #merge [#ref [:restic-repo]
+                      {:backup-path "files"
+                       :execution-directory "/media"
+                       :files ["."]}]
+ 
+ :file-restore-config #merge [#ref [:restic-repo]
+                              {:backup-path "files"
+                               :restore-target-directory "/media/"
+                               :clean-up-elements ["user"]}]
+ 
+ :db-config #merge [#ref [:restic-repo] {:backup-path "pg-database"
+                                         :pg-host #env-or-file "POSTGRES_SERVICE"
+                                         :pg-port #env-or-file "POSTGRES_PORT"
+                                         :pg-db #env-or-file "POSTGRES_DB"
+                                         :pg-user #env-or-file "POSTGRES_USER"
+                                         :pg-password #env-or-file "POSTGRES_PASSWORD"}]
+
+ :aws-config {:aws-access-key-id #env-or-file "AWS_ACCESS_KEY_ID"
+              :aws-secret-access-key #env-or-file "AWS_SECRET_ACCESS_KEY"}
+
+ :dry-run {:dry-run true :debug true}}
\ No newline at end of file

From 95465a364954cfeabeb865a7b1a512d76064f146 Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Fri, 17 Jan 2025 16:29:59 +0100
Subject: [PATCH 18/21] release: 1.2.3

---
 infrastructure/backup/build.py | 2 +-
 package.json                   | 2 +-
 project.clj                    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/infrastructure/backup/build.py b/infrastructure/backup/build.py
index dc535e4..71e7026 100644
--- a/infrastructure/backup/build.py
+++ b/infrastructure/backup/build.py
@@ -6,7 +6,7 @@ from ddadevops import *
 name = "c4k-taiga"
 MODULE = "backup"
 PROJECT_ROOT_PATH = "../.."
-version = "1.2.3-dev"
+version = "1.2.3"
 
 
 @init
diff --git a/package.json b/package.json
index a91d301..35c6496 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
     "name": "c4k-taiga",
     "description": "Generate c4k yaml for a taiga project management deployment.",
     "author": "meissa GmbH",
-    "version": "1.2.3-SNAPSHOT",
+    "version": "1.2.3",
     "homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-taiga#readme",
     "repository": "https://www.npmjs.com/package/c4k-taiga",
     "license": "APACHE2",
diff --git a/project.clj b/project.clj
index c374a64..a7e4fe1 100644
--- a/project.clj
+++ b/project.clj
@@ -1,4 +1,4 @@
-(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.3-SNAPSHOT"
+(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.3"
   :description "taiga c4k-installation package"
   :url "https://domaindrivenarchitecture.org"
   :license {:name "Apache License, Version 2.0"

From 2b932a8e609a27f3e048e2f243e4dc0861b7315c Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Fri, 17 Jan 2025 16:29:59 +0100
Subject: [PATCH 19/21] bump version to: 1.2.4-SNAPSHOT

---
 infrastructure/backup/build.py | 2 +-
 package.json                   | 2 +-
 project.clj                    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/infrastructure/backup/build.py b/infrastructure/backup/build.py
index 71e7026..360c600 100644
--- a/infrastructure/backup/build.py
+++ b/infrastructure/backup/build.py
@@ -6,7 +6,7 @@ from ddadevops import *
 name = "c4k-taiga"
 MODULE = "backup"
 PROJECT_ROOT_PATH = "../.."
-version = "1.2.3"
+version = "1.2.4-dev"
 
 
 @init
diff --git a/package.json b/package.json
index 35c6496..4f54e8b 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
     "name": "c4k-taiga",
     "description": "Generate c4k yaml for a taiga project management deployment.",
     "author": "meissa GmbH",
-    "version": "1.2.3",
+    "version": "1.2.4-SNAPSHOT",
     "homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-taiga#readme",
     "repository": "https://www.npmjs.com/package/c4k-taiga",
     "license": "APACHE2",
diff --git a/project.clj b/project.clj
index a7e4fe1..43162f2 100644
--- a/project.clj
+++ b/project.clj
@@ -1,4 +1,4 @@
-(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.3"
+(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.4-SNAPSHOT"
   :description "taiga c4k-installation package"
   :url "https://domaindrivenarchitecture.org"
   :license {:name "Apache License, Version 2.0"

From 46ca21c22737bb63f95b79d9f7ecf9d61c3eb434 Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Mon, 20 Jan 2025 10:05:08 +0100
Subject: [PATCH 20/21] release: 1.2.4

---
 infrastructure/backup/build.py | 2 +-
 package.json                   | 2 +-
 project.clj                    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/infrastructure/backup/build.py b/infrastructure/backup/build.py
index 360c600..96c95fd 100644
--- a/infrastructure/backup/build.py
+++ b/infrastructure/backup/build.py
@@ -6,7 +6,7 @@ from ddadevops import *
 name = "c4k-taiga"
 MODULE = "backup"
 PROJECT_ROOT_PATH = "../.."
-version = "1.2.4-dev"
+version = "1.2.4"
 
 
 @init
diff --git a/package.json b/package.json
index 4f54e8b..b5bed88 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
     "name": "c4k-taiga",
     "description": "Generate c4k yaml for a taiga project management deployment.",
     "author": "meissa GmbH",
-    "version": "1.2.4-SNAPSHOT",
+    "version": "1.2.4",
     "homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-taiga#readme",
     "repository": "https://www.npmjs.com/package/c4k-taiga",
     "license": "APACHE2",
diff --git a/project.clj b/project.clj
index 43162f2..8013d59 100644
--- a/project.clj
+++ b/project.clj
@@ -1,4 +1,4 @@
-(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.4-SNAPSHOT"
+(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.4"
   :description "taiga c4k-installation package"
   :url "https://domaindrivenarchitecture.org"
   :license {:name "Apache License, Version 2.0"

From 2bcf68760b215f6a7286891a95c52fee0479f863 Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Mon, 20 Jan 2025 10:05:09 +0100
Subject: [PATCH 21/21] bump version to: 1.2.5-SNAPSHOT

---
 infrastructure/backup/build.py | 2 +-
 package.json                   | 2 +-
 project.clj                    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/infrastructure/backup/build.py b/infrastructure/backup/build.py
index 96c95fd..24c03ce 100644
--- a/infrastructure/backup/build.py
+++ b/infrastructure/backup/build.py
@@ -6,7 +6,7 @@ from ddadevops import *
 name = "c4k-taiga"
 MODULE = "backup"
 PROJECT_ROOT_PATH = "../.."
-version = "1.2.4"
+version = "1.2.5-dev"
 
 
 @init
diff --git a/package.json b/package.json
index b5bed88..db34f53 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
     "name": "c4k-taiga",
     "description": "Generate c4k yaml for a taiga project management deployment.",
     "author": "meissa GmbH",
-    "version": "1.2.4",
+    "version": "1.2.5-SNAPSHOT",
     "homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-taiga#readme",
     "repository": "https://www.npmjs.com/package/c4k-taiga",
     "license": "APACHE2",
diff --git a/project.clj b/project.clj
index 8013d59..61aa67b 100644
--- a/project.clj
+++ b/project.clj
@@ -1,4 +1,4 @@
-(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.4"
+(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.5-SNAPSHOT"
   :description "taiga c4k-installation package"
   :url "https://domaindrivenarchitecture.org"
   :license {:name "Apache License, Version 2.0"