Merge branch 'refactor-uptodate' into 'master'

Refactoring

See merge request domaindrivenarchitecture/c4k-nextcloud!6
This commit is contained in:
Clemens Geibel 2023-03-17 14:41:52 +00:00
commit 75629ae366
23 changed files with 260 additions and 321 deletions

View file

@ -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
View 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

View file

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

View file

@ -1,4 +1,4 @@
FROM nextcloud:22
FROM nextcloud:25
# Prepare Entrypoint Script
ADD resources /tmp

View file

@ -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",

View file

@ -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"]})

View file

@ -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}}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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:

View file

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

View file

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

View file

@ -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"}))))

View file

@ -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"

View file

@ -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"

View file

@ -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"}}

View 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"

View file

@ -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"}}

View 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"