Compare commits

...

8 commits

9 changed files with 110 additions and 120 deletions

View file

@ -87,7 +87,6 @@
name (replace-dots-by-minus unique-name)] name (replace-dots-by-minus unique-name)]
(-> (->
(yaml/load-as-edn "website/nginx-deployment.yaml") (yaml/load-as-edn "website/nginx-deployment.yaml")
(assoc-in [:metadata :labels :app.kubernetes.part-of] name)
(assoc-in [:metadata :namespace] name) (assoc-in [:metadata :namespace] name)
(replace-all-matching-substrings-beginning-with "NAME" name) (replace-all-matching-substrings-beginning-with "NAME" name)
(cm/replace-all-matching-values-by-new-value "BUILD_CPU_REQUEST" build-cpu-request) (cm/replace-all-matching-values-by-new-value "BUILD_CPU_REQUEST" build-cpu-request)
@ -102,7 +101,6 @@
name (replace-dots-by-minus unique-name)] name (replace-dots-by-minus unique-name)]
(-> (->
(yaml/load-as-edn "website/nginx-configmap.yaml") (yaml/load-as-edn "website/nginx-configmap.yaml")
(assoc-in [:metadata :labels :app.kubernetes.part-of] name)
(assoc-in [:metadata :namespace] name) (assoc-in [:metadata :namespace] name)
(replace-all-matching-substrings-beginning-with "NAME" name) (replace-all-matching-substrings-beginning-with "NAME" name)
(#(assoc-in % (#(assoc-in %
@ -117,48 +115,24 @@
name (replace-dots-by-minus unique-name)] name (replace-dots-by-minus unique-name)]
(-> (->
(yaml/load-as-edn "website/nginx-service.yaml") (yaml/load-as-edn "website/nginx-service.yaml")
(assoc-in [:metadata :labels :app.kubernetes.part-of] name)
(assoc-in [:metadata :namespace] name) (assoc-in [:metadata :namespace] name)
(replace-all-matching-substrings-beginning-with "NAME" name)))) (replace-all-matching-substrings-beginning-with "NAME" name))))
(defn-spec generate-website-content-volume map?
[config websiteconfig?]
(let [{:keys [unique-name volume-size]} config
name (replace-dots-by-minus unique-name)]
(->
(yaml/load-as-edn "website/website-content-volume.yaml")
(assoc-in [:metadata :labels :app.kubernetes.part-of] name)
(replace-all-matching-substrings-beginning-with "NAME" name)
(cm/replace-all-matching-values-by-new-value "WEBSITESTORAGESIZE" (str volume-size "Gi")))))
(defn-spec generate-hashfile-volume map?
[config websiteconfig?]
(let [{:keys [unique-name]} config
name (replace-dots-by-minus unique-name)]
(->
(yaml/load-as-edn "website/hashfile-volume.yaml")
(assoc-in [:metadata :labels :app.kubernetes.part-of] name)
(replace-all-matching-substrings-beginning-with "NAME" name))))
(defn-spec generate-website-build-cron map? (defn-spec generate-website-build-cron map?
[config websiteconfig?] [config websiteconfig?]
(let [{:keys [unique-name build-cpu-request build-cpu-limit build-memory-request (let [{:keys [unique-name build-cpu-request build-cpu-limit build-memory-request
build-memory-limit]} config build-memory-limit]} config
name (replace-dots-by-minus unique-name)] name (replace-dots-by-minus unique-name)]
(-> (->
(yaml/load-as-edn "website/website-build-cron.yaml") (yaml/load-as-edn "website/build-cron.yaml")
(assoc-in [:metadata :labels :app.kubernetes.part-of] name) (replace-all-matching-substrings-beginning-with "NAME" name)
(replace-all-matching-substrings-beginning-with "NAME" name) (cm/replace-all-matching-values-by-new-value "BUILD_CPU_REQUEST" build-cpu-request)
(cm/replace-all-matching-values-by-new-value "BUILD_CPU_REQUEST" build-cpu-request) (cm/replace-all-matching-values-by-new-value "BUILD_CPU_LIMIT" build-cpu-limit)
(cm/replace-all-matching-values-by-new-value "BUILD_CPU_LIMIT" build-cpu-limit) (cm/replace-all-matching-values-by-new-value "BUILD_MEMORY_REQUEST" build-memory-request)
(cm/replace-all-matching-values-by-new-value "BUILD_MEMORY_REQUEST" build-memory-request) (cm/replace-all-matching-values-by-new-value "BUILD_MEMORY_LIMIT" build-memory-limit))))
(cm/replace-all-matching-values-by-new-value "BUILD_MEMORY_LIMIT" build-memory-limit))))
; TODO: Non-Secret-Parts should be config map
(defn-spec generate-website-build-secret pred/map-or-seq? (defn-spec generate-website-build-secret pred/map-or-seq?
[config websiteconfig? [config websiteconfig?
auth websiteauth?] auth websiteauth?]
@ -170,8 +144,7 @@
username]} auth username]} auth
name (replace-dots-by-minus unique-name)] name (replace-dots-by-minus unique-name)]
(-> (->
(yaml/load-as-edn "website/website-build-secret.yaml") (yaml/load-as-edn "website/build-secret.yaml")
(assoc-in [:metadata :labels :app.kubernetes.part-of] name)
(replace-all-matching-substrings-beginning-with "NAME" name) (replace-all-matching-substrings-beginning-with "NAME" name)
(cm/replace-all-matching-values-by-new-value "TOKEN" (b64/encode authtoken)) (cm/replace-all-matching-values-by-new-value "TOKEN" (b64/encode authtoken))
(cm/replace-all-matching-values-by-new-value "REPOURL" (b64/encode (cm/replace-all-matching-values-by-new-value "REPOURL" (b64/encode
@ -187,6 +160,26 @@
username)))))) username))))))
(defn-spec generate-website-content-volume map?
[config websiteconfig?]
(let [{:keys [unique-name volume-size]} config
name (replace-dots-by-minus unique-name)]
(->
(yaml/load-as-edn "website/content-pvc.yaml")
(replace-all-matching-substrings-beginning-with "NAME" name)
(cm/replace-all-matching-values-by-new-value "WEBSITESTORAGESIZE" (str volume-size "Gi")))))
; TODO: Non-Secret-Parts should be config map
(defn-spec generate-hashfile-volume map?
[config websiteconfig?]
(let [{:keys [unique-name]} config
name (replace-dots-by-minus unique-name)]
(->
(yaml/load-as-edn "website/hash-state-pvc.yaml")
(replace-all-matching-substrings-beginning-with "NAME" name))))
#?(:cljs #?(:cljs
(defmethod yaml/load-resource :website [resource-name] (defmethod yaml/load-resource :website [resource-name]
(get (inline-resources "website") resource-name))) (get (inline-resources "website") resource-name)))

View file

@ -1,7 +1,8 @@
apiVersion: batch/v1 apiVersion: batch/v1
kind: CronJob kind: CronJob
metadata: metadata:
name: NAME-build-cron name: build-cron
namespace: NAME
labels: labels:
app.kubernetes.part-of: NAME-website app.kubernetes.part-of: NAME-website
spec: spec:
@ -11,10 +12,15 @@ spec:
jobTemplate: jobTemplate:
spec: spec:
template: template:
metadata:
namespace: NAME
labels:
app: build-cron
app.kubernetes.part-of: NAME-website
spec: spec:
containers: containers:
- image: domaindrivenarchitecture/c4k-website-build - image: domaindrivenarchitecture/c4k-website-build
name: NAME-build-app name: build-cron-container
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
resources: resources:
requests: requests:
@ -26,18 +32,18 @@ spec:
command: ["/entrypoint.sh"] command: ["/entrypoint.sh"]
envFrom: envFrom:
- secretRef: - secretRef:
name: NAME-secret name: build-secret
volumeMounts: volumeMounts:
- name: content-volume - name: content-volume
mountPath: /var/www/html/website mountPath: /var/www/html/website
- name: hashfile-volume - name: hash-state-volume
mountPath: /var/hashfile.d mountPath: /var/hashfile.d
volumes: volumes:
- name: content-volume - name: content-volume
persistentVolumeClaim: persistentVolumeClaim:
claimName: NAME-content-volume claimName: content-volume
- name: hashfile-volume - name: hash-state-volume
persistentVolumeClaim: persistentVolumeClaim:
claimName: NAME-hashfile-volume claimName: hash-state-volume
restartPolicy: OnFailure restartPolicy: OnFailure

View file

@ -1,7 +1,8 @@
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: NAME-secret name: build-secret
namespace: NAME
labels: labels:
app.kubernetes.part-of: NAME-website app.kubernetes.part-of: NAME-website
data: data:

View file

@ -1,10 +1,9 @@
apiVersion: v1 apiVersion: v1
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
metadata: metadata:
name: NAME-content-volume name: content-volume
namespace: default namespace: NAME
labels: labels:
app: NAME-nginx
app.kubernetes.part-of: NAME-website app.kubernetes.part-of: NAME-website
spec: spec:
storageClassName: local-path storageClassName: local-path

View file

@ -1,10 +1,9 @@
apiVersion: v1 apiVersion: v1
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
metadata: metadata:
name: NAME-hashfile-volume name: hash-state-volume
namespace: default namespace: NAME
labels: labels:
app: NAME-nginx
app.kubernetes.part-of: NAME-website app.kubernetes.part-of: NAME-website
spec: spec:
storageClassName: local-path storageClassName: local-path

View file

@ -9,7 +9,7 @@ data:
nginx.conf: | nginx.conf: |
user nginx; user nginx;
worker_processes 3; worker_processes 3;
error_log /var/log/nginx/error.log; error_log stdout info;
pid /var/log/nginx/nginx.pid; pid /var/log/nginx/nginx.pid;
worker_rlimit_nofile 8192; worker_rlimit_nofile 8192;
events { events {
@ -21,7 +21,7 @@ data:
log_format main '$remote_addr - $remote_user [$time_local] $status' log_format main '$remote_addr - $remote_user [$time_local] $status'
'"$request" $body_bytes_sent "$http_referer"' '"$request" $body_bytes_sent "$http_referer"'
'"$http_user_agent" "$http_x_forwarded_for"'; '"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; access_log stdout main;
sendfile on; sendfile on;
tcp_nopush on; tcp_nopush on;
keepalive_timeout 65; keepalive_timeout 65;

View file

@ -46,7 +46,7 @@ spec:
command: ["/entrypoint.sh"] command: ["/entrypoint.sh"]
envFrom: envFrom:
- secretRef: - secretRef:
name: secret name: build-secret
volumeMounts: volumeMounts:
- name: content-volume - name: content-volume
mountPath: /var/www/html/website mountPath: /var/www/html/website

View file

@ -5,10 +5,10 @@ metadata:
namespace: default namespace: default
labels: labels:
app: NAME app: NAME
app.kubernetes.part-of: NAME app.kubernetes.part-of: NAME-website
spec: spec:
selector: selector:
app: NAME app: nginx
ports: ports:
- name: nginx-http - name: nginx-http
port: 80 port: 80

View file

@ -3,7 +3,6 @@
#?(:clj [clojure.test :refer [deftest is are testing run-tests]] #?(:clj [clojure.test :refer [deftest is are testing run-tests]]
:cljs [cljs.test :refer-macros [deftest is are testing run-tests]]) :cljs [cljs.test :refer-macros [deftest is are testing run-tests]])
[clojure.spec.test.alpha :as st] [clojure.spec.test.alpha :as st]
[dda.c4k-common.test-helper :as th]
[dda.c4k-website.website.website-internal :as cut])) [dda.c4k-website.website.website-internal :as cut]))
(st/instrument `cut/generate-nginx-configmap) (st/instrument `cut/generate-nginx-configmap)
@ -69,7 +68,7 @@
:forgejo-repo "none", :forgejo-repo "none",
:branchname "mablain", :branchname "mablain",
:fqdns ["test.de" "www.test.de" "test-it.de" "www.test-it.de"]}))))) :fqdns ["test.de" "www.test.de" "test-it.de" "www.test-it.de"]})))))
(is (= "user nginx;\nworker_processes 3;\nerror_log /var/log/nginx/error.log;\npid /var/log/nginx/nginx.pid;\nworker_rlimit_nofile 8192;\nevents {\n worker_connections 4096;\n}\nhttp {\n include /etc/nginx/mime.types;\n default_type application/octet-stream;\n log_format main '$remote_addr - $remote_user [$time_local] $status'\n '\"$request\" $body_bytes_sent \"$http_referer\"'\n '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n access_log /var/log/nginx/access.log main;\n sendfile on;\n tcp_nopush on;\n keepalive_timeout 65;\n server_names_hash_bucket_size 128;\n include /etc/nginx/conf.d/website.conf;\n}\n" (is (= "user nginx;\nworker_processes 3;\nerror_log stdout info;\npid /var/log/nginx/nginx.pid;\nworker_rlimit_nofile 8192;\nevents {\n worker_connections 4096;\n}\nhttp {\n include /etc/nginx/mime.types;\n default_type application/octet-stream;\n log_format main '$remote_addr - $remote_user [$time_local] $status'\n '\"$request\" $body_bytes_sent \"$http_referer\"'\n '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n access_log stdout main;\n sendfile on;\n tcp_nopush on;\n keepalive_timeout 65;\n server_names_hash_bucket_size 128;\n include /etc/nginx/conf.d/website.conf;\n}\n"
(:nginx.conf (:data (cut/generate-nginx-configmap {:issuer "staging" (:nginx.conf (:data (cut/generate-nginx-configmap {:issuer "staging"
:build-cpu-request "500m" :build-cpu-request "500m"
:build-cpu-limit "1700m" :build-cpu-limit "1700m"
@ -83,9 +82,9 @@
:fqdns ["test.de" "www.test.de" "test-it.de" "www.test-it.de"]}))))) :fqdns ["test.de" "www.test.de" "test-it.de" "www.test-it.de"]})))))
(is (= {:apiVersion "v1", (is (= {:apiVersion "v1",
:kind "ConfigMap", :kind "ConfigMap",
:metadata {:labels {:app.kubernetes.part-of "test-io"}, :metadata {:labels {:app.kubernetes.part-of "test-io-website"},
:namespace "test-io", :namespace "test-io",
:name "etc-ngingx"}} :name "etc-nginx"}}
(dissoc (cut/generate-nginx-configmap {:issuer "staging" (dissoc (cut/generate-nginx-configmap {:issuer "staging"
:build-cpu-request "500m" :build-cpu-request "500m"
:build-cpu-limit "1700m" :build-cpu-limit "1700m"
@ -99,15 +98,15 @@
:fqdns ["test.de" "www.test.de" "test-it.de" "www.test-it.de"]}) :data)))) :fqdns ["test.de" "www.test.de" "test-it.de" "www.test-it.de"]}) :data))))
(deftest should-generate-nginx-service (deftest should-generate-nginx-service
(is (= {:name-c1 "test-io", (is (= {:kind "Service",
:name-c2 "test-org", :apiVersion "v1",
:app-c1 "test-io", :metadata
:app-c2 "test-org", {:name "test-io",
:app.kubernetes.part-of-c1 "test-io", :namespace "test-io",
:app.kubernetes.part-of-c2 "test-org" :labels {:app "test-io", :app.kubernetes.part-of "test-io-website"}},
:namespace-c1 "test-io", :spec
:namespace-c2 "test-org"} {:selector {:app "nginx"}, :ports [{:name "nginx-http", :port 80}]}}
(th/map-diff (cut/generate-nginx-service {:issuer "staging" (cut/generate-nginx-service {:issuer "staging"
:build-cpu-request "500m" :build-cpu-request "500m"
:build-cpu-limit "1700m" :build-cpu-limit "1700m"
:build-memory-request "256Mi" :build-memory-request "256Mi"
@ -118,23 +117,14 @@
:forgejo-repo "none", :forgejo-repo "none",
:branchname "mablain", :branchname "mablain",
:fqdns ["test.de" "www.test.de" "test-it.de" "www.test-it.de"]}) :fqdns ["test.de" "www.test.de" "test-it.de" "www.test-it.de"]})
(cut/generate-nginx-service {:issuer "staging" )))
:build-cpu-request "500m"
:build-cpu-limit "1700m"
:build-memory-request "256Mi"
:build-memory-limit "512Mi"
:volume-size "3"
:unique-name "test.org",
:forgejo-host "gitea.evilorg",
:forgejo-repo "none",
:branchname "mablain",
:fqdns ["test.de" "www.test.de" "test-it.de" "www.test-it.de"]})))))
(deftest should-generate-website-build-cron (deftest should-generate-website-build-cron
(is (= {:apiVersion "batch/v1", (is (= {:apiVersion "batch/v1",
:kind "CronJob", :kind "CronJob",
:metadata {:name "test-io-build-cron", :metadata {:name "build-cron",
:labels {:app.kubernetes.part-of "test-io"}}, :namespace "test-io",
:labels {:app.kubernetes.part-of "test-io-website"}},
:spec :spec
{:schedule "0/7 * * * *", {:schedule "0/7 * * * *",
:successfulJobsHistoryLimit 1, :successfulJobsHistoryLimit 1,
@ -142,18 +132,22 @@
:jobTemplate :jobTemplate
{:spec {:spec
{:template {:template
{:spec {:metadata
{:namespace "test-io",
:labels
{:app "build-cron", :app.kubernetes.part-of "test-io-website"}}
:spec
{:containers {:containers
[{:image "domaindrivenarchitecture/c4k-website-build", [{:image "domaindrivenarchitecture/c4k-website-build",
:name "test-io-build-app", :name "build-cron-container",
:imagePullPolicy "IfNotPresent", :imagePullPolicy "IfNotPresent",
:resources {:requests {:cpu "500m", :memory "256Mi"}, :limits {:cpu "1700m", :memory "512Mi"}}, :resources {:requests {:cpu "500m", :memory "256Mi"}, :limits {:cpu "1700m", :memory "512Mi"}},
:command ["/entrypoint.sh"], :command ["/entrypoint.sh"],
:envFrom [{:secretRef {:name "test-io-secret"}}], :envFrom [{:secretRef {:name "build-secret"}}],
:volumeMounts [{:name "content-volume", :mountPath "/var/www/html/website"} :volumeMounts [{:name "content-volume", :mountPath "/var/www/html/website"}
{:name "hashfile-volume", :mountPath "/var/hashfile.d"}]}], {:name "hash-state-volume", :mountPath "/var/hashfile.d"}]}],
:volumes [{:name "content-volume", :persistentVolumeClaim {:claimName "test-io-content-volume"}} :volumes [{:name "content-volume", :persistentVolumeClaim {:claimName "content-volume"}}
{:name "hashfile-volume", :persistentVolumeClaim {:claimName "test-io-hashfile-volume"}}], {:name "hash-state-volume", :persistentVolumeClaim {:claimName "hash-state-volume"}}],
:restartPolicy "OnFailure"}}}}}} :restartPolicy "OnFailure"}}}}}}
(cut/generate-website-build-cron {:issuer "staging" (cut/generate-website-build-cron {:issuer "staging"
:build-cpu-request "500m" :build-cpu-request "500m"
@ -167,10 +161,13 @@
:branchname "main", :branchname "main",
:unique-name "test.io"})))) :unique-name "test.io"}))))
(deftest should-generate-website-build-secret (deftest should-generate-website-build-secret
(is (= {:apiVersion "v1", (is (= {:apiVersion "v1",
:kind "Secret", :kind "Secret",
:metadata {:name "test-io-secret", :labels {:app.kubernetes.part-of "test-io"}}, :metadata {:name "build-secret",
:namespace "test-io",
:labels {:app.kubernetes.part-of "test-io-website"}},
:data :data
{:AUTHTOKEN "YWJlZGpnYmFzZG9kag==", {:AUTHTOKEN "YWJlZGpnYmFzZG9kag==",
:GITREPOURL "aHR0cHM6Ly9naXRsYWIuZGUvYXBpL3YxL3JlcG9zL3NvbWV1c2VyL3JlcG8vYXJjaGl2ZS9tYWluLnppcA==", :GITREPOURL "aHR0cHM6Ly9naXRsYWIuZGUvYXBpL3YxL3JlcG9zL3NvbWV1c2VyL3JlcG8vYXJjaGl2ZS9tYWluLnppcA==",
@ -191,43 +188,38 @@
:username "someuser"})))) :username "someuser"}))))
(deftest should-generate-website-content-volume (deftest should-generate-website-content-volume
(is (= {:name-c1 "test-io-content-volume", (is (= {:apiVersion "v1",
:name-c2 "test-org-content-volume", :kind "PersistentVolumeClaim",
:app-c1 "test-io-nginx", :metadata
:app-c2 "test-org-nginx", {:name "content-volume",
:app.kubernetes.part-of-c1 "test-io", :namespace "test-io",
:app.kubernetes.part-of-c2 "test-org"} :labels {:app.kubernetes.part-of "test-io-website"}},
(th/map-diff (cut/generate-website-content-volume {:issuer "staging" :spec
:build-cpu-request "500m" {:storageClassName "local-path",
:build-cpu-limit "1700m" :accessModes ["ReadWriteOnce"],
:build-memory-request "256Mi" :resources {:requests {:storage "3Gi"}}}}
:build-memory-limit "512Mi" (cut/generate-website-content-volume {:issuer "staging"
:volume-size "3" :build-cpu-request "500m"
:unique-name "test.io", :build-cpu-limit "1700m"
:forgejo-host "gitea.evilorg", :build-memory-request "256Mi"
:forgejo-repo "none", :build-memory-limit "512Mi"
:branchname "mablain", :volume-size "3"
:fqdns ["test.de" "www.test.de" "test-it.de" "www.test-it.de"]}) :unique-name "test.io",
(cut/generate-website-content-volume {:issuer "staging" :forgejo-host "gitea.evilorg",
:build-cpu-request "500m" :forgejo-repo "none",
:build-cpu-limit "1700m" :branchname "mablain",
:build-memory-request "256Mi" :fqdns ["test.de" "www.test.de" "test-it.de" "www.test-it.de"]}))))
:build-memory-limit "512Mi"
:volume-size "3"
:unique-name "test.org",
:forgejo-host "gitea.evilorg",
:forgejo-repo "none",
:branchname "mablain",
:fqdns ["test.de" "www.test.de" "test-it.de" "www.test-it.de"]})))))
(deftest should-generate-hashfile-volume (deftest should-generate-hashfile-volume
(is (= {:apiVersion "v1", (is (= {:apiVersion "v1",
:kind "PersistentVolumeClaim", :kind "PersistentVolumeClaim",
:metadata :metadata
{:name "test-io-hashfile-volume", {:name "hash-state-volume",
:namespace "default", :namespace "test-io",
:labels {:app "test-io-nginx", :app.kubernetes.part-of "test-io"}}, :labels {:app.kubernetes.part-of "test-io-website"}},
:spec {:storageClassName "local-path", :accessModes ["ReadWriteOnce"], :resources {:requests {:storage "16Mi"}}}} :spec {:storageClassName "local-path",
:accessModes ["ReadWriteOnce"],
:resources {:requests {:storage "16Mi"}}}}
(cut/generate-hashfile-volume {:issuer "staging" (cut/generate-hashfile-volume {:issuer "staging"
:build-cpu-request "500m" :build-cpu-request "500m"
:build-cpu-limit "1700m" :build-cpu-limit "1700m"