Merge branch 'refactor-uptodate' into 'master'
Refactoring See merge request domaindrivenarchitecture/c4k-nextcloud!6
This commit is contained in:
commit
c13cecab46
23 changed files with 260 additions and 321 deletions
|
@ -49,7 +49,7 @@ test-schema:
|
|||
stage: build_and_test
|
||||
script:
|
||||
- lein uberjar
|
||||
- java -jar target/uberjar/c4k-nextcloud-standalone.jar valid-config.edn valid-auth.edn | kubeconform --kubernetes-version 1.19.0 --strict --skip "Certificate,CronJob" -
|
||||
- java -jar target/uberjar/c4k-nextcloud-standalone.jar src/test/resources/nextcloud-test/valid-config.yaml src/test/resources/nextcloud-test/valid-auth.yaml | kubeconform --kubernetes-version 1.19.0 --strict --skip "Certificate,CronJob" -
|
||||
artifacts:
|
||||
paths:
|
||||
- target/uberjar
|
||||
|
|
17
doc/LiveUpgrade.md
Normal file
17
doc/LiveUpgrade.md
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Upgrade major or minor versions of nextcloud
|
||||
|
||||
## Nextcloud versions of c4k-nextcloud docker images
|
||||
|
||||
- 4.0.3: nextcloud 22
|
||||
- 5.0.0: nextcloud 23
|
||||
- 6.0.0: nextcloud 24
|
||||
- 7.0.0: nextcloud 25
|
||||
|
||||
## Uprgrading process
|
||||
|
||||
1. Change the version of the docker image in the deployment to the next major version
|
||||
- `kubectl edit deploy cloud-deployment`
|
||||
- change `image: domaindrivenarchitecture/c4k-cloud:4.0.3`
|
||||
2. Wait for the pod to finish restarting
|
||||
3. Verify the website is working and https://URL/settings/admin/overview shows the correct version
|
||||
4. Repeat until desired version is reached
|
|
@ -45,15 +45,17 @@ output "ipv4" {
|
|||
|
||||
## k8s minicluster
|
||||
|
||||
For k8s installation we use our [dda-k8s-crate](https://github.com/DomainDrivenArchitecture/dda-k8s-crate) with the following configuation:
|
||||
For k8s installation we use our [provs](https://repo.prod.meissa.de/meissa/provs) with the following configuation:
|
||||
|
||||
|
||||
```
|
||||
{:user :k8s
|
||||
:k8s {:external-ip "ip-from-above"}
|
||||
:cert-manager :letsencrypt-prod-issuer
|
||||
:persistent-dirs ["cloud", "postgres"]
|
||||
}
|
||||
postgres-db-user: "nextcloud"
|
||||
postgres-db-password: "nextcloud-db-password"
|
||||
nextcloud-admin-user: "cloudadmin"
|
||||
nextcloud-admin-password: "cloudpassword"
|
||||
aws-access-key-id: "aws-id"
|
||||
aws-secret-access-key: "aws-secret"
|
||||
restic-password: "restic-password"
|
||||
```
|
||||
|
||||
## kubectl apply c4k-nextcloud
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM nextcloud:22
|
||||
FROM nextcloud:25
|
||||
|
||||
# Prepare Entrypoint Script
|
||||
ADD resources /tmp
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "c4k-nextcloud",
|
||||
"description": "Generate c4k yaml for a nextcloud deployment.",
|
||||
"author": "meissa GmbH",
|
||||
"version": "4.0.3-SNAPSHOT",
|
||||
"version": "7.0.1-SNAPSHOT",
|
||||
"homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud#readme",
|
||||
"repository": "https://www.npmjs.com/package/c4k-nextcloud",
|
||||
"license": "APACHE2",
|
||||
|
|
13
project.clj
13
project.clj
|
@ -1,11 +1,11 @@
|
|||
(defproject org.domaindrivenarchitecture/c4k-nextcloud "4.0.4-SNAPSHOT"
|
||||
(defproject org.domaindrivenarchitecture/c4k-nextcloud "7.0.1-SNAPSHOT"
|
||||
:description "nextcloud c4k-installation package"
|
||||
: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.3.6"]
|
||||
[org.domaindrivenarchitecture/c4k-common-clj "2.0.3"]]
|
||||
[org.domaindrivenarchitecture/c4k-common-clj "6.0.1"]]
|
||||
:target-path "target/%s/"
|
||||
:source-paths ["src/main/cljc"
|
||||
"src/main/clj"]
|
||||
|
@ -39,8 +39,7 @@
|
|||
"-H:ResourceConfigurationFiles=graalvm-resource-config.json"
|
||||
"-H:Log=registerResource"
|
||||
"-H:Name=target/graalvm/${:name}"]
|
||||
"inst" ["shell" "sudo"
|
||||
"install"
|
||||
"-m=755"
|
||||
"target/uberjar/c4k-nextcloud-standalone.jar"
|
||||
"/usr/local/bin/c4k-nextcloud-standalone.jar"]})
|
||||
"inst" ["shell"
|
||||
"sh"
|
||||
"-c"
|
||||
"lein uberjar && sudo install -m=755 target/uberjar/c4k-nextcloud-standalone.jar /usr/local/bin/c4k-nextcloud-standalone.jar"]})
|
|
@ -4,7 +4,7 @@
|
|||
"src/test/cljc"
|
||||
"src/test/cljs"
|
||||
"src/test/resources"]
|
||||
:dependencies [[org.domaindrivenarchitecture/c4k-common-cljs "2.0.3"]
|
||||
:dependencies [[org.domaindrivenarchitecture/c4k-common-cljs "6.0.1"]
|
||||
[hickory "0.7.1"]]
|
||||
:builds {:frontend {:target :browser
|
||||
:modules {:main {:init-fn dda.c4k-nextcloud.browser/init}}
|
||||
|
|
|
@ -1,55 +1,15 @@
|
|||
(ns dda.c4k-nextcloud.uberjar
|
||||
(:gen-class)
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]
|
||||
[clojure.string :as cs]
|
||||
[clojure.tools.reader.edn :as edn]
|
||||
[expound.alpha :as expound]
|
||||
[dda.c4k-common.yaml :as yaml]
|
||||
[dda.c4k-nextcloud.core :as core]
|
||||
[dda.c4k-nextcloud.nextcloud :as nextcloud]))
|
||||
|
||||
(def usage
|
||||
"usage:
|
||||
|
||||
c4k-nextcloud {your configuraton file} {your authorization file}")
|
||||
|
||||
(s/def ::options (s/* #{"-h"}))
|
||||
(s/def ::filename (s/and string?
|
||||
#(not (cs/starts-with? % "-"))))
|
||||
(s/def ::cmd-args (s/cat :options ::options
|
||||
:args (s/?
|
||||
(s/cat :config ::filename
|
||||
:auth ::filename))))
|
||||
(defn invalid-args-msg
|
||||
[spec args]
|
||||
(s/explain spec args)
|
||||
(println (str "Bad commandline arguments\n" usage)))
|
||||
[dda.c4k-common.uberjar :as uberjar]
|
||||
[dda.c4k-nextcloud.nextcloud :as nextcloud]
|
||||
[dda.c4k-nextcloud.core :as core]))
|
||||
|
||||
(defn -main [& cmd-args]
|
||||
(let [parsed-args-cmd (s/conform ::cmd-args cmd-args)]
|
||||
(if (= ::s/invalid parsed-args-cmd)
|
||||
(invalid-args-msg ::cmd-args cmd-args)
|
||||
(let [{:keys [options args]} parsed-args-cmd
|
||||
{:keys [config auth]} args]
|
||||
(cond
|
||||
(some #(= "-h" %) options)
|
||||
(println usage)
|
||||
:default
|
||||
(let [config-str (slurp config)
|
||||
auth-str (slurp auth)
|
||||
config-parse-fn (if (yaml/is-yaml? config) yaml/from-string edn/read-string)
|
||||
auth-parse-fn (if (yaml/is-yaml? auth) yaml/from-string edn/read-string)
|
||||
parsed-config (config-parse-fn config-str)
|
||||
parsed-auth (auth-parse-fn auth-str)
|
||||
config-valid? (s/valid? ::core/config parsed-config)
|
||||
auth-valid? (s/valid? ::core/auth parsed-auth)]
|
||||
(if (and config-valid? auth-valid?)
|
||||
(println (core/generate parsed-config parsed-auth))
|
||||
(do
|
||||
(when (not config-valid?)
|
||||
(println
|
||||
(expound/expound-str ::core/config parsed-config {:print-specs? false})))
|
||||
(when (not auth-valid?)
|
||||
(println
|
||||
(expound/expound-str ::core/auth parsed-auth {:print-specs? false})))))))))))
|
||||
(uberjar/main-common
|
||||
"c4k-nextcloud"
|
||||
nextcloud/config?
|
||||
nextcloud/auth?
|
||||
core/config-defaults
|
||||
core/k8s-objects
|
||||
cmd-args))
|
||||
|
|
|
@ -23,14 +23,14 @@
|
|||
(defn generate-config [my-conf]
|
||||
(let [{:keys [restic-repository]} my-conf]
|
||||
(->
|
||||
(yaml/from-string (yaml/load-resource "backup/config.yaml"))
|
||||
(yaml/load-as-edn "backup/config.yaml")
|
||||
(cm/replace-key-value :restic-repository restic-repository))))
|
||||
|
||||
(defn generate-cron []
|
||||
(yaml/from-string (yaml/load-resource "backup/cron.yaml")))
|
||||
|
||||
(defn generate-backup-restore-deployment [my-conf]
|
||||
(let [backup-restore-yaml (yaml/from-string (yaml/load-resource "backup/backup-restore-deployment.yaml"))]
|
||||
(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)))
|
||||
|
@ -38,7 +38,7 @@
|
|||
(defn generate-secret [my-auth]
|
||||
(let [{:keys [aws-access-key-id aws-secret-access-key restic-password]} my-auth]
|
||||
(->
|
||||
(yaml/from-string (yaml/load-resource "backup/secret.yaml"))
|
||||
(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)))))
|
||||
|
|
|
@ -1,60 +1,44 @@
|
|||
(ns dda.c4k-nextcloud.core
|
||||
(:require
|
||||
[clojure.string :as cs]
|
||||
[clojure.spec.alpha :as s]
|
||||
#?(:clj [orchestra.core :refer [defn-spec]]
|
||||
:cljs [orchestra.core :refer-macros [defn-spec]])
|
||||
[dda.c4k-common.common :as cm]
|
||||
[dda.c4k-common.predicate :as cp]
|
||||
[dda.c4k-common.yaml :as yaml]
|
||||
[dda.c4k-common.postgres :as postgres]
|
||||
[dda.c4k-nextcloud.nextcloud :as nextcloud]
|
||||
[dda.c4k-nextcloud.backup :as backup]))
|
||||
[dda.c4k-nextcloud.backup :as backup]
|
||||
[dda.c4k-common.monitoring :as mon]))
|
||||
|
||||
(def default-storage-class :local-path)
|
||||
|
||||
(def config-defaults {:issuer "staging"})
|
||||
|
||||
(def config? (s/keys :req-un [::nextcloud/fqdn]
|
||||
:opt-un [::nextcloud/issuer
|
||||
::nextcloud/restic-repository
|
||||
::nextcloud/pv-storage-size-gb
|
||||
::nextcloud/pvc-storage-class-name]))
|
||||
|
||||
(def auth? (s/keys :req-un [::postgres/postgres-db-user ::postgres/postgres-db-password
|
||||
::nextcloud/nextcloud-admin-user ::nextcloud/nextcloud-admin-password
|
||||
::aws-access-key-id ::aws-secret-access-key
|
||||
::restic-password]))
|
||||
|
||||
(s/def ::config config?)
|
||||
(s/def ::auth auth?)
|
||||
|
||||
(defn-spec k8s-objects any?
|
||||
[config (s/merge config? auth?)]
|
||||
(defn-spec k8s-objects cp/map-or-seq?
|
||||
[config nextcloud/config?
|
||||
auth nextcloud/auth?]
|
||||
(let [nextcloud-default-storage-config {:pvc-storage-class-name default-storage-class
|
||||
:pv-storage-size-gb 200}]
|
||||
(into
|
||||
[]
|
||||
(concat [(yaml/to-string (postgres/generate-config {:postgres-size :8gb}))
|
||||
(yaml/to-string (postgres/generate-secret config))
|
||||
(yaml/to-string (postgres/generate-pvc {:pv-storage-size-gb 50
|
||||
:pvc-storage-class-name default-storage-class}))
|
||||
(yaml/to-string (postgres/generate-deployment))
|
||||
(yaml/to-string (postgres/generate-service))
|
||||
(yaml/to-string (nextcloud/generate-secret config))
|
||||
(yaml/to-string (nextcloud/generate-pvc (merge nextcloud-default-storage-config config)))
|
||||
(yaml/to-string (nextcloud/generate-deployment config))
|
||||
(yaml/to-string (nextcloud/generate-service))
|
||||
(yaml/to-string (nextcloud/generate-certificate config))
|
||||
(yaml/to-string (nextcloud/generate-ingress config))]
|
||||
(when (contains? config :restic-repository)
|
||||
[(yaml/to-string (backup/generate-config config))
|
||||
(yaml/to-string (backup/generate-secret config))
|
||||
(yaml/to-string (backup/generate-cron))
|
||||
(yaml/to-string (backup/generate-backup-restore-deployment config))])))))
|
||||
|
||||
(defn-spec generate any?
|
||||
[my-config config?
|
||||
my-auth auth?]
|
||||
(let [resulting-config (merge config-defaults my-config my-auth)]
|
||||
(cs/join
|
||||
"\n---\n"
|
||||
(k8s-objects resulting-config))))
|
||||
(map yaml/to-string
|
||||
(filter
|
||||
#(not (nil? %))
|
||||
(cm/concat-vec
|
||||
[(postgres/generate-config {:postgres-size :8gb :db-name "nextcloud"})
|
||||
(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)
|
||||
(nextcloud/generate-secret auth)
|
||||
(nextcloud/generate-pvc (merge nextcloud-default-storage-config config))
|
||||
(nextcloud/generate-deployment config)
|
||||
(nextcloud/generate-service)]
|
||||
(nextcloud/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))))))))
|
||||
|
|
|
@ -5,9 +5,12 @@
|
|||
#?(:clj [orchestra.core :refer [defn-spec]]
|
||||
:cljs [orchestra.core :refer-macros [defn-spec]])
|
||||
[dda.c4k-common.yaml :as yaml]
|
||||
[dda.c4k-common.ingress :as ing]
|
||||
[dda.c4k-common.base64 :as b64]
|
||||
[dda.c4k-common.predicate :as cp]
|
||||
[dda.c4k-common.common :as cm]))
|
||||
[dda.c4k-common.postgres :as postgres]
|
||||
[dda.c4k-common.common :as cm]
|
||||
[dda.c4k-common.monitoring :as mon]))
|
||||
|
||||
(s/def ::fqdn cp/fqdn-string?)
|
||||
(s/def ::issuer cp/letsencrypt-issuer?)
|
||||
|
@ -17,58 +20,58 @@
|
|||
(s/def ::pvc-storage-class-name cp/pvc-storage-class-name?)
|
||||
(s/def ::pv-storage-size-gb pos?)
|
||||
|
||||
(def strong-config? (s/keys :req-un [::fqdn ::issuer ::pv-storage-size-gb
|
||||
::pvc-storage-class-name]
|
||||
:opt-un [::restic-repository]))
|
||||
(def config? (s/keys :req-un [::fqdn]
|
||||
:opt-un [::issuer
|
||||
::restic-repository
|
||||
::pv-storage-size-gb
|
||||
::pvc-storage-class-name
|
||||
::mon/mon-cfg]))
|
||||
|
||||
(def auth? (s/keys :req-un [::postgres/postgres-db-user ::postgres/postgres-db-password
|
||||
::nextcloud-admin-user ::nextcloud-admin-password
|
||||
::aws-access-key-id ::aws-secret-access-key
|
||||
::restic-password]
|
||||
:opt-un [::mon/mon-auth]))
|
||||
|
||||
#?(:cljs
|
||||
(defmethod yaml/load-resource :nextcloud [resource-name]
|
||||
(case resource-name
|
||||
"nextcloud/certificate.yaml" (rc/inline "nextcloud/certificate.yaml")
|
||||
"nextcloud/deployment.yaml" (rc/inline "nextcloud/deployment.yaml")
|
||||
"nextcloud/ingress.yaml" (rc/inline "nextcloud/ingress.yaml")
|
||||
"nextcloud/pvc.yaml" (rc/inline "nextcloud/pvc.yaml")
|
||||
"nextcloud/service.yaml" (rc/inline "nextcloud/service.yaml")
|
||||
"nextcloud/secret.yaml" (rc/inline "nextcloud/secret.yaml")
|
||||
(throw (js/Error. "Undefined Resource!")))))
|
||||
|
||||
(defn generate-certificate [config]
|
||||
(let [{:keys [fqdn issuer]} config
|
||||
letsencrypt-issuer issuer]
|
||||
(->
|
||||
(yaml/from-string (yaml/load-resource "nextcloud/certificate.yaml"))
|
||||
(assoc-in [:spec :commonName] fqdn)
|
||||
(assoc-in [:spec :dnsNames] [fqdn])
|
||||
(assoc-in [:spec :issuerRef :name] letsencrypt-issuer))))
|
||||
|
||||
(defn generate-deployment [config]
|
||||
(defn-spec generate-deployment cp/map-or-seq?
|
||||
[config config?]
|
||||
(let [{:keys [fqdn]} config]
|
||||
(-> (yaml/from-string (yaml/load-resource "nextcloud/deployment.yaml"))
|
||||
(-> (yaml/load-as-edn "nextcloud/deployment.yaml")
|
||||
(cm/replace-all-matching-values-by-new-value "fqdn" fqdn))))
|
||||
|
||||
(defn generate-ingress [config]
|
||||
(let [{:keys [fqdn issuer]
|
||||
:or {issuer "staging"}} config
|
||||
letsencrypt-issuer issuer]
|
||||
(->
|
||||
(yaml/from-string (yaml/load-resource "nextcloud/ingress.yaml"))
|
||||
(assoc-in [:metadata :annotations :cert-manager.io/cluster-issuer] letsencrypt-issuer)
|
||||
(cm/replace-all-matching-values-by-new-value "fqdn" fqdn))))
|
||||
(defn-spec generate-ingress-and-cert cp/map-or-seq?
|
||||
[config config?]
|
||||
(ing/generate-ingress-and-cert
|
||||
(merge
|
||||
{:service-name "cloud-service"
|
||||
:service-port 80
|
||||
:fqdns [(:fqdn config)]}
|
||||
config)))
|
||||
|
||||
(defn-spec generate-pvc cp/map-or-seq?
|
||||
[config (s/keys :req-un [::pv-storage-size-gb ::pvc-storage-class-name])]
|
||||
(let [{:keys [pv-storage-size-gb pvc-storage-class-name]} config]
|
||||
(->
|
||||
(yaml/from-string (yaml/load-resource "nextcloud/pvc.yaml"))
|
||||
(yaml/load-as-edn "nextcloud/pvc.yaml")
|
||||
(assoc-in [:spec :resources :requests :storage] (str pv-storage-size-gb "Gi"))
|
||||
(assoc-in [:spec :storageClassName] (name pvc-storage-class-name)))))
|
||||
|
||||
(defn generate-service []
|
||||
(yaml/from-string (yaml/load-resource "nextcloud/service.yaml")))
|
||||
(yaml/load-as-edn "nextcloud/service.yaml"))
|
||||
|
||||
(defn generate-secret [config]
|
||||
(let [{:keys [nextcloud-admin-user nextcloud-admin-password]} config]
|
||||
(defn-spec generate-secret cp/map-or-seq?
|
||||
[auth auth?]
|
||||
(let [{:keys [nextcloud-admin-user nextcloud-admin-password]} auth]
|
||||
(->
|
||||
(yaml/from-string (yaml/load-resource "nextcloud/secret.yaml"))
|
||||
(yaml/load-as-edn "nextcloud/secret.yaml")
|
||||
(cm/replace-key-value :nextcloud-admin-user (b64/encode nextcloud-admin-user))
|
||||
(cm/replace-key-value :nextcloud-admin-password (b64/encode nextcloud-admin-password)))))
|
||||
|
|
|
@ -1,31 +1,42 @@
|
|||
(ns dda.c4k-nextcloud.browser
|
||||
(:require
|
||||
[clojure.tools.reader.edn :as edn]
|
||||
[dda.c4k-common.common :as cm]
|
||||
[dda.c4k-common.monitoring :as mon]
|
||||
[dda.c4k-nextcloud.core :as core]
|
||||
[dda.c4k-nextcloud.nextcloud :as nextcloud]
|
||||
[dda.c4k-common.browser :as br]
|
||||
[dda.c4k-common.postgres :as pgc]))
|
||||
|
||||
(defn generate-content
|
||||
[]
|
||||
(into [] (concat [(assoc (br/generate-needs-validation) :content
|
||||
(into [] (concat (br/generate-input-field "fqdn" "Your fqdn:" "nextcloud-neu.prod.meissa-gmbh.de")
|
||||
(br/generate-input-field "nextcloud-data-volume-path" "(Optional) Your nextcloud-data-volume-path:" "/var/nextcloud")
|
||||
(br/generate-input-field "postgres-data-volume-path" "(Optional) Your postgres-data-volume-path:" "/var/postgres")
|
||||
(br/generate-input-field "restic-repository" "(Optional) Your restic-repository:" "restic-repository")
|
||||
(br/generate-input-field "issuer" "(Optional) Your issuer prod/staging:" "")
|
||||
[(br/generate-br)]
|
||||
(br/generate-text-area "auth" "Your auth.edn:" "{:postgres-db-user \"nextcloud\"
|
||||
(defn generate-content []
|
||||
(cm/concat-vec
|
||||
[(assoc
|
||||
(br/generate-needs-validation) :content
|
||||
(cm/concat-vec
|
||||
(br/generate-group "domain"
|
||||
(cm/concat-vec (br/generate-input-field "fqdn" "Your fqdn:" "nextcloud-neu.prod.meissa-gmbh.de")
|
||||
(br/generate-input-field "issuer" "(Optional) Your issuer prod/staging:" "")
|
||||
(br/generate-input-field "pv-storage-size-gb" "(Optional) Your nextcloud storage size in GB" "8")
|
||||
(br/generate-input-field "pvc-storage-class-name" "(Optional) Your storage class type (manual / local-path):" "local-path")
|
||||
(br/generate-input-field "postgres-data-volume-path" "(Optional) Your postgres-data-volume-path:" "/var/postgres")
|
||||
(br/generate-input-field "restic-repository" "(Optional) Your restic-repository:" "restic-repository")
|
||||
(br/generate-input-field "mon-cluster-name" "(Optional) monitoring cluster name:" "keycloak")
|
||||
(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")))
|
||||
(br/generate-group "credentials"
|
||||
(br/generate-text-area "auth" "Your auth.edn:" "{:postgres-db-user \"nextcloud\"
|
||||
:postgres-db-password \"nextcloud-db-password\"
|
||||
:nextcloud-admin-password \"nextcloud-admin-password\"
|
||||
:nextcloud-admin-user \"nextcloud-admin-user\"
|
||||
:aws-access-key-id \"aws-id\"
|
||||
:aws-secret-access-key \"aws-secret\"
|
||||
:restic-password \"restic-password\"}"
|
||||
"5")
|
||||
[(br/generate-br)]
|
||||
(br/generate-button "generate-button" "Generate c4k yaml"))))]
|
||||
(br/generate-output "c4k-nextcloud-output" "Your c4k deployment.yaml:" "25"))))
|
||||
: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-nextcloud-output" "Your c4k deployment.yaml:" "25")))
|
||||
|
||||
(defn generate-content-div
|
||||
[]
|
||||
|
@ -35,29 +46,40 @@
|
|||
(generate-content)})
|
||||
|
||||
(defn config-from-document []
|
||||
(let [nextcloud-data-volume-path (br/get-content-from-element "nextcloud-data-volume-path" :optional true)
|
||||
(let [pv-storage-size-gb (br/get-content-from-element "pv-storage-size-gb" :optional true)
|
||||
pvc-storage-class-name (br/get-content-from-element "pvc-storage-class-name" :optional true)
|
||||
postgres-data-volume-path (br/get-content-from-element "postgres-data-volume-path" :optional true)
|
||||
restic-repository (br/get-content-from-element "restic-repository" :optional true)
|
||||
issuer (br/get-content-from-element "issuer" :optional true :deserializer keyword)]
|
||||
issuer (br/get-content-from-element "issuer" :optional true)
|
||||
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 (br/get-content-from-element "fqdn")}
|
||||
(when (some? nextcloud-data-volume-path)
|
||||
{:nextcloud-data-volume-path nextcloud-data-volume-path})
|
||||
(when (and (some? pv-storage-size-gb) (some? pvc-storage-class-name))
|
||||
{:pv-storage-size-gb pv-storage-size-gb :pvc-storage-class-name pvc-storage-class-name})
|
||||
(when (some? postgres-data-volume-path)
|
||||
{:postgres-data-volume-path postgres-data-volume-path})
|
||||
(when (some? restic-repository)
|
||||
{:restic-repository restic-repository})
|
||||
(when (some? 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" ::nextcloud/fqdn)
|
||||
(br/validate! "nextcloud-data-volume-path" ::nextcloud/nextcloud-data-volume-path :optional true)
|
||||
(br/validate! "pv-storage-size-gb" ::nextcloud/pv-storage-size-gb :optional true)
|
||||
(br/validate! "pvc-storage-class-name" ::nextcloud/pvc-storage-class-name :optional true)
|
||||
(br/validate! "postgres-data-volume-path" ::pgc/postgres-data-volume-path :optional true)
|
||||
(br/validate! "restic-repository" ::nextcloud/restic-repository :optional true)
|
||||
(br/validate! "issuer" ::nextcloud/issuer :optional true :deserializer keyword)
|
||||
(br/validate! "auth" core/auth? :deserializer edn/read-string)
|
||||
(br/validate! "issuer" ::nextcloud/issuer :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! "auth" nextcloud/auth? :deserializer edn/read-string)
|
||||
(br/set-validated!))
|
||||
|
||||
(defn add-validate-listener [name]
|
||||
|
@ -70,13 +92,19 @@
|
|||
(.getElementById "generate-button")
|
||||
(.addEventListener "click"
|
||||
#(do (validate-all!)
|
||||
(-> (core/generate
|
||||
(config-from-document)
|
||||
(br/get-content-from-element "auth" :deserializer edn/read-string))
|
||||
(-> (cm/generate-common
|
||||
(config-from-document)
|
||||
(br/get-content-from-element "auth" :deserializer edn/read-string)
|
||||
{}
|
||||
core/k8s-objects)
|
||||
(br/set-output!)))))
|
||||
(add-validate-listener "fqdn")
|
||||
(add-validate-listener "nextcloud-data-volume-path")
|
||||
(add-validate-listener "pv-storage-size-gb")
|
||||
(add-validate-listener "pvc-storage-class-name")
|
||||
(add-validate-listener "postgres-data-volume-path")
|
||||
(add-validate-listener "restic-repository")
|
||||
(add-validate-listener "issuer")
|
||||
(add-validate-listener "mon-cluster-name")
|
||||
(add-validate-listener "mon-cluster-stage")
|
||||
(add-validate-listener "mon-cloud-url")
|
||||
(add-validate-listener "auth"))
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: cloud-cert
|
||||
namespace: default
|
||||
spec:
|
||||
secretName: cloud-cert
|
||||
duration: 2160h # 90d
|
||||
renewBefore: 360h # 15d
|
||||
commonName: fqdn
|
||||
dnsNames:
|
||||
- fqdn
|
||||
issuerRef:
|
||||
name: staging
|
||||
kind: ClusterIssuer
|
|
@ -18,7 +18,7 @@ spec:
|
|||
redeploy: v3
|
||||
spec:
|
||||
containers:
|
||||
- image: domaindrivenarchitecture/c4k-cloud
|
||||
- image: domaindrivenarchitecture/c4k-cloud:7.0.0
|
||||
name: cloud-app
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-cloud
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-staging-issuer
|
||||
ingress.kubernetes.io/ssl-redirect: "true"
|
||||
ingress.kubernetes.io/rewrite-target: /
|
||||
ingress.kubernetes.io/proxy-body-size: "256m"
|
||||
ingress.kubernetes.io/proxy-connect-timeout: "300"
|
||||
ingress.kubernetes.io/proxy-send-timeout: "300"
|
||||
ingress.kubernetes.io/proxy-read-timeout: "300"
|
||||
namespace: default
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- fqdn
|
||||
secretName: cloud-cert
|
||||
rules:
|
||||
- host: fqdn
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: cloud-service
|
||||
port:
|
||||
number: 80
|
|
@ -1,55 +0,0 @@
|
|||
(ns dda.c4k-nextcloud.core-test
|
||||
(:require
|
||||
#?(:clj [clojure.test :refer [deftest is are testing run-tests]]
|
||||
:cljs [cljs.test :refer-macros [deftest is are testing run-tests]])
|
||||
[clojure.string :as st]
|
||||
[dda.c4k-nextcloud.core :as cut]
|
||||
))
|
||||
|
||||
(deftest should-k8s-objects
|
||||
(is (= 15
|
||||
(count (cut/k8s-objects {:fqdn "nextcloud-neu.prod.meissa-gmbh.de"
|
||||
:postgres-db-user "nextcloud"
|
||||
:postgres-db-password "nextcloud-db-password"
|
||||
:nextcloud-admin-user "cloudadmin"
|
||||
:nextcloud-admin-password "cloudpassword"
|
||||
:issuer "prod"
|
||||
:aws-access-key-id "aws-id"
|
||||
:aws-secret-access-key "aws-secret"
|
||||
:restic-password "restic-pw"
|
||||
:restic-repository "restic-repository"}))))
|
||||
(is (= 11
|
||||
(count (cut/k8s-objects {:fqdn "nextcloud-neu.prod.meissa-gmbh.de"
|
||||
:postgres-db-user "nextcloud"
|
||||
:postgres-db-password "nextcloud-db-password"
|
||||
:nextcloud-admin-user "cloudadmin"
|
||||
:nextcloud-admin-password "cloudpassword"
|
||||
:issuer "prod"
|
||||
:aws-access-key-id "aws-id"
|
||||
:aws-secret-access-key "aws-secret"
|
||||
:restic-password "restic-pw"}))))
|
||||
(is (st/includes?
|
||||
(get-in (cut/k8s-objects {:fqdn "nextcloud-neu.prod.meissa-gmbh.de"
|
||||
:postgres-db-user "nextcloud"
|
||||
:postgres-db-password "nextcloud-db-password"
|
||||
:nextcloud-admin-user "cloudadmin"
|
||||
:nextcloud-admin-password "cloudpassword"
|
||||
:issuer "prod"
|
||||
:aws-access-key-id "aws-id"
|
||||
:aws-secret-access-key "aws-secret"
|
||||
:restic-password "restic-pw"})
|
||||
[0])
|
||||
"max_connections = 700"))
|
||||
(is (st/includes?
|
||||
(get-in (cut/k8s-objects {:fqdn "nextcloud-neu.prod.meissa-gmbh.de"
|
||||
:postgres-db-user "nextcloud"
|
||||
:postgres-db-password "nextcloud-db-password"
|
||||
:nextcloud-admin-user "cloudadmin"
|
||||
:nextcloud-admin-password "cloudpassword"
|
||||
:issuer "prod"
|
||||
:aws-access-key-id "aws-id"
|
||||
:aws-secret-access-key "aws-secret"
|
||||
:restic-password "restic-pw"})
|
||||
[6])
|
||||
"storageClassName: local-path"))
|
||||
)
|
|
@ -2,8 +2,28 @@
|
|||
(:require
|
||||
#?(:clj [clojure.test :refer [deftest is are testing run-tests]]
|
||||
:cljs [cljs.test :refer-macros [deftest is are testing run-tests]])
|
||||
#?(:cljs [shadow.resource :as rc])
|
||||
[clojure.spec.alpha :as s]
|
||||
[clojure.spec.test.alpha :as st]
|
||||
[dda.c4k-common.yaml :as yaml]
|
||||
[dda.c4k-nextcloud.nextcloud :as cut]))
|
||||
|
||||
(st/instrument)
|
||||
|
||||
#?(:cljs
|
||||
(defmethod yaml/load-resource :nextcloud-test [resource-name]
|
||||
(case resource-name
|
||||
"nextcloud-test/valid-auth.yaml" (rc/inline "nextcloud-test/valid-auth.yaml")
|
||||
"nextcloud-test/valid-config.yaml" (rc/inline "nextcloud-test/valid-config.yaml")
|
||||
"nextcloud-test/invalid-auth.yaml" (rc/inline "nextcloud-test/invalid-auth.yaml")
|
||||
"nextcloud-test/invalid-config.yaml" (rc/inline "nextcloud-test/invalid-config.yaml"))))
|
||||
|
||||
(deftest validate-valid-resources
|
||||
(is (s/valid? cut/config? (yaml/load-as-edn "nextcloud-test/valid-config.yaml")))
|
||||
(is (s/valid? cut/auth? (yaml/load-as-edn "nextcloud-test/valid-auth.yaml")))
|
||||
(is (not (s/valid? cut/config? (yaml/load-as-edn "nextcloud-test/invalid-config.yaml"))))
|
||||
(is (not (s/valid? cut/auth? (yaml/load-as-edn "nextcloud-test/invalid-auth.yaml")))))
|
||||
|
||||
(deftest should-generate-secret
|
||||
(is (= {:apiVersion "v1"
|
||||
:kind "Secret"
|
||||
|
@ -12,49 +32,50 @@
|
|||
:data
|
||||
{:nextcloud-admin-user "Y2xvdWRhZG1pbg=="
|
||||
:nextcloud-admin-password "Y2xvdWRwYXNzd29yZA=="}}
|
||||
(cut/generate-secret {:nextcloud-admin-user "cloudadmin"
|
||||
(cut/generate-secret {:postgres-db-user "postgres-user"
|
||||
:postgres-db-password "postgres-password"
|
||||
:aws-access-key-id "aws-key"
|
||||
:aws-secret-access-key "aws-secret-key"
|
||||
:restic-password "restic-password"
|
||||
:nextcloud-admin-user "cloudadmin"
|
||||
:nextcloud-admin-password "cloudpassword"}))))
|
||||
|
||||
(deftest should-generate-certificate
|
||||
(is (= {:apiVersion "cert-manager.io/v1"
|
||||
:kind "Certificate"
|
||||
:metadata {:name "cloud-cert", :namespace "default"}
|
||||
:spec
|
||||
{:secretName "cloud-cert"
|
||||
:duration "2160h"
|
||||
:renewBefore "360h",
|
||||
:commonName "xx",
|
||||
:dnsNames ["xx"]
|
||||
:issuerRef
|
||||
{:name "prod", :kind "ClusterIssuer"}}}
|
||||
(cut/generate-certificate {:fqdn "xx" :issuer "prod"}))))
|
||||
|
||||
(deftest should-generate-ingress
|
||||
(is (= {:apiVersion "networking.k8s.io/v1"
|
||||
:kind "Ingress"
|
||||
:metadata
|
||||
{:name "ingress-cloud"
|
||||
:annotations
|
||||
{:cert-manager.io/cluster-issuer "staging"
|
||||
:ingress.kubernetes.io/proxy-body-size "256m"
|
||||
:ingress.kubernetes.io/ssl-redirect "true"
|
||||
:ingress.kubernetes.io/rewrite-target "/"
|
||||
:ingress.kubernetes.io/proxy-connect-timeout "300"
|
||||
:ingress.kubernetes.io/proxy-send-timeout "300"
|
||||
:ingress.kubernetes.io/proxy-read-timeout "300"}
|
||||
:namespace "default"}
|
||||
:spec
|
||||
{:tls [{:hosts ["xx"], :secretName "cloud-cert"}]
|
||||
:rules
|
||||
[{:host "xx"
|
||||
:http
|
||||
{:paths
|
||||
[{:path "/"
|
||||
:pathType "Prefix"
|
||||
:backend
|
||||
{:service
|
||||
{:name "cloud-service", :port {:number 80}}}}]}}]}}
|
||||
(cut/generate-ingress {:fqdn "xx"}))))
|
||||
(deftest should-generate-ingress-and-cert
|
||||
(is (= [{:apiVersion "cert-manager.io/v1",
|
||||
:kind "Certificate",
|
||||
:metadata
|
||||
{:name "cloud-service",
|
||||
:labels {:app.kubernetes.part-of "cloud-service"},
|
||||
:namespace "default"},
|
||||
:spec
|
||||
{:secretName "cloud-service",
|
||||
:commonName "somefqdn.de",
|
||||
:duration "2160h",
|
||||
:renewBefore "360h",
|
||||
:dnsNames ["somefqdn.de"],
|
||||
:issuerRef {:name "staging", :kind "ClusterIssuer"}}}
|
||||
{:apiVersion "networking.k8s.io/v1",
|
||||
:kind "Ingress",
|
||||
:metadata
|
||||
{:name "cloud-service",
|
||||
:namespace "default",
|
||||
:labels {:app.kubernetes.part-of "cloud-service"},
|
||||
:annotations
|
||||
{:traefik.ingress.kubernetes.io/router.entrypoints "web, websecure",
|
||||
:traefik.ingress.kubernetes.io/router.middlewares
|
||||
"default-redirect-https@kubernetescrd",
|
||||
:metallb.universe.tf/address-pool "public"}},
|
||||
:spec
|
||||
{:tls [{:hosts ["somefqdn.de"], :secretName "cloud-service"}],
|
||||
:rules
|
||||
[{:host "somefqdn.de",
|
||||
:http
|
||||
{:paths
|
||||
[{:pathType "Prefix",
|
||||
:path "/",
|
||||
:backend
|
||||
{:service {:name "cloud-service", :port {:number 80}}}}]}}]}}]
|
||||
(cut/generate-ingress-and-cert {:fqdn "somefqdn.de"}))))
|
||||
|
||||
(deftest should-generate-pvc
|
||||
(is (= {:apiVersion "v1"
|
||||
|
@ -77,7 +98,7 @@
|
|||
{:metadata {:labels {:app "cloud-app", :app.kubernetes.io/name "cloud-pod", :app.kubernetes.io/application "cloud", :redeploy "v3"}}
|
||||
:spec
|
||||
{:containers
|
||||
[{:image "domaindrivenarchitecture/c4k-cloud"
|
||||
[{:image "domaindrivenarchitecture/c4k-cloud:7.0.0"
|
||||
:name "cloud-app"
|
||||
:imagePullPolicy "IfNotPresent"
|
||||
:ports [{:containerPort 80}]
|
||||
|
@ -93,11 +114,11 @@
|
|||
[{:name "NEXTCLOUD_ADMIN_USER", :valueFrom {:secretKeyRef {:name "cloud-secret", :key "nextcloud-admin-user"}}}
|
||||
{:name "NEXTCLOUD_ADMIN_PASSWORD"
|
||||
:valueFrom {:secretKeyRef {:name "cloud-secret", :key "nextcloud-admin-password"}}}
|
||||
{:name "NEXTCLOUD_TRUSTED_DOMAINS", :value "xx"}
|
||||
{:name "NEXTCLOUD_TRUSTED_DOMAINS", :value "somefqdn.de"}
|
||||
{:name "POSTGRES_USER", :valueFrom {:secretKeyRef {:name "postgres-secret", :key "postgres-user"}}}
|
||||
{:name "POSTGRES_PASSWORD", :valueFrom {:secretKeyRef {:name "postgres-secret", :key "postgres-password"}}}
|
||||
{:name "POSTGRES_DB", :valueFrom {:configMapKeyRef {:name "postgres-config", :key "postgres-db"}}}
|
||||
{:name "POSTGRES_HOST", :value "postgresql-service:5432"}]
|
||||
:volumeMounts [{:name "cloud-data-volume", :mountPath "/var/www/html"}]}]
|
||||
:volumes [{:name "cloud-data-volume", :persistentVolumeClaim {:claimName "cloud-pvc"}}]}}}}
|
||||
(cut/generate-deployment {:fqdn "xx"}))))
|
||||
(cut/generate-deployment {:fqdn "somefqdn.de"}))))
|
|
@ -2,6 +2,6 @@ postgres-db-user: "nextcloud"
|
|||
postgres-db-password: "nextcloud-db-password"
|
||||
nextcloud-admin-user: "cloudadmin"
|
||||
nextcloud-admin-password: "cloudpassword"
|
||||
aws-access-key-id: "aws-id"
|
||||
aws-accss-key-id: "aws-id"
|
||||
aws-secret-access-key: "aws-secret"
|
||||
restic-password: "restic-password"
|
|
@ -1,5 +1,5 @@
|
|||
fqdn: "cloud.test.meissa-gmbh.de"
|
||||
issuer: "staging"
|
||||
fqdns: "cloud.test.meissa-gmbh.de"
|
||||
issuer: "none"
|
||||
nextcloud-data-volume-path: "/var/cloud"
|
||||
postgres-data-volume-path: "/var/postgres"
|
||||
restic-repository: "s3:s3.amazonaws.com/your-bucket/your-folder"
|
|
@ -4,4 +4,6 @@
|
|||
:nextcloud-admin-password "cloudpassword"
|
||||
:aws-access-key-id "aws-id"
|
||||
:aws-secret-access-key "aws-secret"
|
||||
:restic-password "restic-password"}
|
||||
:restic-password "restic-password"
|
||||
:mon-auth {:grafana-cloud-user "user"
|
||||
:grafana-cloud-password "password"}}
|
10
src/test/resources/nextcloud-test/valid-auth.yaml
Normal file
10
src/test/resources/nextcloud-test/valid-auth.yaml
Normal file
|
@ -0,0 +1,10 @@
|
|||
postgres-db-user: "nextcloud"
|
||||
postgres-db-password: "nextcloud-db-password"
|
||||
nextcloud-admin-user: "cloudadmin"
|
||||
nextcloud-admin-password: "cloudpassword"
|
||||
aws-access-key-id: "aws-id"
|
||||
aws-secret-access-key: "aws-secret"
|
||||
restic-password: "restic-password"
|
||||
mon-auth:
|
||||
grafana-cloud-user: "user"
|
||||
grafana-cloud-password: "password"
|
|
@ -2,4 +2,7 @@
|
|||
:issuer "staging"
|
||||
:nextcloud-data-volume-path "/var/cloud"
|
||||
:postgres-data-volume-path "/var/postgres"
|
||||
:restic-repository "s3:s3.amazonaws.com/your-bucket/your-folder"}
|
||||
:restic-repository "s3:s3.amazonaws.com/your-bucket/your-folder"
|
||||
:mon-cfg {:grafana-cloud-url "url-for-your-prom-remote-write-endpoint"
|
||||
:k3s-cluster-name "jitsi"
|
||||
:k3s-cluster-stage "test"}}
|
9
src/test/resources/nextcloud-test/valid-config.yaml
Normal file
9
src/test/resources/nextcloud-test/valid-config.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
fqdn: "cloud.test.meissa-gmbh.de"
|
||||
issuer: "staging"
|
||||
nextcloud-data-volume-path: "/var/cloud"
|
||||
postgres-data-volume-path: "/var/postgres"
|
||||
restic-repository: "s3:s3.amazonaws.com/your-bucket/your-folder"
|
||||
mon-cfg:
|
||||
grafana-cloud-url: "url-for-your-prom-remote-write-endpoint"
|
||||
cluster-name: "keycloak"
|
||||
cluster-stage: "test"
|
Loading…
Reference in a new issue