From 1252a4b49144c69a394efe960d26abd09f4cd82e Mon Sep 17 00:00:00 2001 From: erik Date: Thu, 8 Sep 2022 15:04:17 +0200 Subject: [PATCH] Project skeleton --- .gitignore | 28 +++ .gitlab-ci.yml | 116 ++++++++++ LICENSE | 201 ++++++++++++++++++ doc/Releasing.md | 14 ++ doc/tryItOut.png | Bin 0 -> 101516 bytes package.json | 33 +++ project.clj | 46 ++++ public/index.html | 17 ++ src/main/clj/dda/c4k_gitea/uberjar.clj | 9 + src/main/cljc/dda/c4k_gitea/core.cljc | 29 +++ src/main/cljc/dda/c4k_gitea/gitea.cljc | 138 ++++++++++++ src/main/cljs/dda/c4k_gitea/browser.cljs | 125 +++++++++++ src/main/resources/gitea/certificate.yaml | 15 ++ src/main/resources/gitea/datavolume.yaml | 15 ++ src/main/resources/gitea/ingress.yaml | 24 +++ src/main/resources/gitea/nginx-configmap.yaml | 56 +++++ .../resources/gitea/nginx-deployment.yaml | 36 ++++ .../gitea/website-server-service.yaml | 16 ++ src/main/resources/logback.xml | 50 +++++ src/test/cljc/dda/c4k_gitea/website_test.cljc | 73 +++++++ 20 files changed, 1041 insertions(+) create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 LICENSE create mode 100644 doc/Releasing.md create mode 100644 doc/tryItOut.png create mode 100644 package.json create mode 100644 project.clj create mode 100644 public/index.html create mode 100644 src/main/clj/dda/c4k_gitea/uberjar.clj create mode 100644 src/main/cljc/dda/c4k_gitea/core.cljc create mode 100644 src/main/cljc/dda/c4k_gitea/gitea.cljc create mode 100644 src/main/cljs/dda/c4k_gitea/browser.cljs create mode 100644 src/main/resources/gitea/certificate.yaml create mode 100644 src/main/resources/gitea/datavolume.yaml create mode 100644 src/main/resources/gitea/ingress.yaml create mode 100644 src/main/resources/gitea/nginx-configmap.yaml create mode 100644 src/main/resources/gitea/nginx-deployment.yaml create mode 100644 src/main/resources/gitea/website-server-service.yaml create mode 100644 src/main/resources/logback.xml create mode 100644 src/test/cljc/dda/c4k_gitea/website_test.cljc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ab17090 --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +.clj-kondo/ +.lsp/ + +# pybuilder +.pybuilder/ +__pycache__/ + +# lein +target/ +.lein-repl-history +.lein-failures +pom.* + +# cljs +.shadow-cljs +.nrepl-* +package-lock.json +node_modules/ +public/js/ + +# ide +.calva + +*.iml +.idea/ + +auth.edn +config.edn diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..0d7852f --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,116 @@ +stages: + - build_and_test + - package + - security + - upload + - image + +services: + - docker:19.03.12-dind + +.cljs-job: &cljs + image: domaindrivenarchitecture/shadow-cljs + cache: + key: ${CI_COMMIT_REF_SLUG} + paths: + - node_modules/ + - .shadow-cljs/ + - .m2 + before_script: + - echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc + - npm install + +.clj-uploadjob: &clj + image: domaindrivenarchitecture/lein + cache: + key: ${CI_COMMIT_REF_SLUG} + paths: + - .m2 + before_script: + - mkdir -p /root/.lein + - echo "{:auth {:repository-auth {#\"clojars\" {:username \"${CLOJARS_USER}\" :password \"${CLOJARS_TOKEN_DOMAINDRIVENARCHITECTURE}\" }}}}" > ~/.lein/profiles.clj + +test-cljs: + <<: *cljs + stage: build_and_test + script: + - shadow-cljs compile test + - node target/node-tests.js + +test-clj: + <<: *clj + stage: build_and_test + script: + - lein test + +test-schema: + <<: *clj + stage: build_and_test + script: + - lein uberjar + - java -jar target/uberjar/c4k-website-standalone.jar valid-config.edn valid-auth.edn | kubeconform --kubernetes-version 1.19.0 --strict --skip Certificate - + artifacts: + paths: + - target/uberjar + +report-frontend: + <<: *cljs + stage: package + script: + - mkdir -p target/frontend-build + - shadow-cljs run shadow.cljs.build-report frontend target/frontend-build/build-report.html + artifacts: + paths: + - target/frontend-build/build-report.html + +package-frontend: + <<: *cljs + stage: package + script: + - mkdir -p target/frontend-build + - shadow-cljs release frontend + - cp public/js/main.js target/frontend-build/c4k-website.js + - sha256sum target/frontend-build/c4k-website.js > target/frontend-build/c4k-website.js.sha256 + - sha512sum target/frontend-build/c4k-website.js > target/frontend-build/c4k-website.js.sha512 + artifacts: + paths: + - target/frontend-build + +package-uberjar: + <<: *clj + stage: package + script: + - lein uberjar + - sha256sum target/uberjar/c4k-website-standalone.jar > target/uberjar/c4k-website-standalone.jar.sha256 + - sha512sum target/uberjar/c4k-website-standalone.jar > target/uberjar/c4k-website-standalone.jar.sha512 + artifacts: + paths: + - target/uberjar + +upload-clj-release: + <<: *clj + stage: upload + rules: + - if: '$CI_COMMIT_TAG != null' + script: + - lein deploy + +release: + image: registry.gitlab.com/gitlab-org/release-cli:latest + stage: upload + rules: + - if: '$CI_COMMIT_TAG != null' + artifacts: + paths: + - target/uberjar + - target/frontend-build + script: + - apk --no-cache add curl + - | + release-cli create --name "Release $CI_COMMIT_TAG" --tag-name $CI_COMMIT_TAG \ + --assets-link "{\"name\":\"c4k-website-standalone.jar\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-website/-/jobs/${CI_JOB_ID}/artifacts/file/target/uberjar/c4k-website-standalone.jar\"}" \ + --assets-link "{\"name\":\"c4k-website-standalone.jar.sha256\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-website/-/jobs/${CI_JOB_ID}/artifacts/file/target/uberjar/c4k-website-standalone.jar.sha256\"}" \ + --assets-link "{\"name\":\"c4k-website-standalone.jar.sha512\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-website/-/jobs/${CI_JOB_ID}/artifacts/file/target/uberjar/c4k-website-standalone.jar.sha512\"}" \ + --assets-link "{\"name\":\"c4k-website.js\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-website/-/jobs/${CI_JOB_ID}/artifacts/file/target/frontend-build/c4k-website.js\"}" \ + --assets-link "{\"name\":\"c4k-website.js.sha256\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-website/-/jobs/${CI_JOB_ID}/artifacts/file/target/frontend-build/c4k-website.js.sha256\"}" \ + --assets-link "{\"name\":\"c4k-website.js.sha512\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-website/-/jobs/${CI_JOB_ID}/artifacts/file/target/frontend-build/c4k-website.js.sha512\"}" \ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/doc/Releasing.md b/doc/Releasing.md new file mode 100644 index 0000000..e3aa755 --- /dev/null +++ b/doc/Releasing.md @@ -0,0 +1,14 @@ +# stable release (should be done from master) + +``` +#adjust [version] +vi package.json + +lein release +git push --follow-tags + +# bump version - increase version and add -SNAPSHOT +vi package.json +git commit -am "version bump" +git push +``` \ No newline at end of file diff --git a/doc/tryItOut.png b/doc/tryItOut.png new file mode 100644 index 0000000000000000000000000000000000000000..02396e1948e5f4f10861c50e1c5ee2ac24b3d61c GIT binary patch literal 101516 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¥`u7hi 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 literal 0 HcmV?d00001 diff --git a/package.json b/package.json new file mode 100644 index 0000000..3245952 --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "name": "c4k-website", + "description": "Generate c4k yaml for a website deployment.", + "author": "meissa GmbH", + "version": "0.1.1-SNAPSHOT", + "homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-website#readme", + "repository": "https://www.npmjs.com/package/c4k-website", + "license": "APACHE2", + "main": "c4k-website.js", + "bin": { + "c4k-website": "./c4k-website.js" + }, + "keywords": [ + "cljs", + "website", + "k8s", + "c4k", + "deployment", + "yaml", + "convention4kubernetes" + ], + "bugs": { + "url": "https://gitlab.com/domaindrivenarchitecture/c4k-website/issues" + }, + "dependencies": { + "js-base64": "^3.6.1", + "js-yaml": "^4.0.0" + }, + "devDependencies": { + "shadow-cljs": "^2.11.18", + "source-map-support": "^0.5.19" + } +} \ No newline at end of file diff --git a/project.clj b/project.clj new file mode 100644 index 0000000..734fabc --- /dev/null +++ b/project.clj @@ -0,0 +1,46 @@ +(defproject org.domaindrivenarchitecture/c4k-website "0.1.1-SNAPSHOT" + :description "website 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.10.3"] + [org.clojure/tools.reader "1.3.6"] + [org.domaindrivenarchitecture/c4k-common-clj "3.0.1"] + [hickory "0.7.1"]] + :target-path "target/%s/" + :source-paths ["src/main/cljc" + "src/main/clj"] + :resource-paths ["src/main/resources"] + :repositories [["snapshots" :clojars] + ["releases" :clojars]] + :deploy-repositories [["snapshots" {:sign-releases false :url "https://clojars.org/repo"}] + ["releases" {:sign-releases false :url "https://clojars.org/repo"}]] + :profiles {:test {:test-paths ["src/test/cljc"] + :resource-paths ["src/test/resources"] + :dependencies [[dda/data-test "0.1.1"]]} + :dev {:plugins [[lein-shell "0.5.0"]]} + :uberjar {:aot :all + :main dda.c4k-website.uberjar + :uberjar-name "c4k-website-standalone.jar" + :dependencies [[org.clojure/tools.cli "1.0.206"] + [ch.qos.logback/logback-classic "1.3.0-alpha4" + :exclusions [com.sun.mail/javax.mail]] + [org.slf4j/jcl-over-slf4j "2.0.0-alpha1"]]}} + :release-tasks [["test"] + ["vcs" "assert-committed"] + ["change" "version" "leiningen.release/bump-version" "release"] + ["vcs" "commit"] + ["vcs" "tag" "v" "--no-sign"] + ["change" "version" "leiningen.release/bump-version"]] + :aliases {"native" ["shell" + "native-image" + "--report-unsupported-elements-at-runtime" + "--initialize-at-build-time" + "-jar" "target/uberjar/c4k-website-standalone.jar" + "-H:ResourceConfigurationFiles=graalvm-resource-config.json" + "-H:Log=registerResource" + "-H:Name=target/graalvm/${:name}"] + "inst" ["shell" + "sh" + "-c" + "lein uberjar && sudo install -m=755 target/uberjar/c4k-website-standalone.jar /usr/local/bin/c4k-website-standalone.jar"]}) diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..99ea0c9 --- /dev/null +++ b/public/index.html @@ -0,0 +1,17 @@ + + + + + + c4k-website + + + + + + +
+ + + + \ No newline at end of file diff --git a/src/main/clj/dda/c4k_gitea/uberjar.clj b/src/main/clj/dda/c4k_gitea/uberjar.clj new file mode 100644 index 0000000..eb2b794 --- /dev/null +++ b/src/main/clj/dda/c4k_gitea/uberjar.clj @@ -0,0 +1,9 @@ +(ns dda.c4k-website.uberjar + (:gen-class) + (:require + [dda.c4k-website.core :as core] + [dda.c4k-website.website :as website] + [dda.c4k-common.uberjar :as uberjar])) + +(defn -main [& cmd-args] + (uberjar/main-common "c4k-website" website/config? website/auth? website/config-defaults core/k8s-objects cmd-args)) diff --git a/src/main/cljc/dda/c4k_gitea/core.cljc b/src/main/cljc/dda/c4k_gitea/core.cljc new file mode 100644 index 0000000..974eddd --- /dev/null +++ b/src/main/cljc/dda/c4k_gitea/core.cljc @@ -0,0 +1,29 @@ +(ns dda.c4k-website.core + (:require + [dda.c4k-common.yaml :as yaml] + [dda.c4k-common.common :as cm] + [dda.c4k-website.website :as website] + [dda.c4k-common.postgres :as postgres])) + +(defn k8s-objects [config] + (let [storage-class (if (contains? config :postgres-data-volume-path) :manual :local-path)] + (cm/concat-vec + (map yaml/to-string + (filter #(not (nil? %)) + [(postgres/generate-config {:postgres-size :2gb :db-name "website"}) + (postgres/generate-secret config) + (when (contains? config :postgres-data-volume-path) + (postgres/generate-persistent-volume (select-keys config [:postgres-data-volume-path :pv-storage-size-gb]))) + (postgres/generate-pvc {:pv-storage-size-gb 5 + :pvc-storage-class-name storage-class}) + (postgres/generate-deployment {:postgres-image "postgres:14" + :postgres-size :2gb}) + (postgres/generate-service) + (website/generate-deployment) + (website/generate-service) + (website/generate-service-ssh) + (website/generate-data-volume config) + (website/generate-appini-env config) + (website/generate-secrets config) + (website/generate-ingress config) + (website/generate-certificate config)]))))) diff --git a/src/main/cljc/dda/c4k_gitea/gitea.cljc b/src/main/cljc/dda/c4k_gitea/gitea.cljc new file mode 100644 index 0000000..71dc246 --- /dev/null +++ b/src/main/cljc/dda/c4k_gitea/gitea.cljc @@ -0,0 +1,138 @@ +(ns dda.c4k-website.website + (:require + [clojure.spec.alpha :as s] + [clojure.string :as st] + #?(: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 pred] + [dda.c4k-common.postgres :as postgres])) + +(defn domain-list? + [input] + (or + (st/blank? input) + (pred/string-of-separated-by? pred/fqdn-string? #"," input))) + +(s/def ::default-app-name string?) +(s/def ::fqdn pred/fqdn-string?) +(s/def ::mailer-from pred/bash-env-string?) +(s/def ::mailer-host-port pred/host-and-port-string?) +(s/def ::service-domain-whitelist domain-list?) +(s/def ::service-noreply-address string?) +(s/def ::mailer-user pred/bash-env-string?) +(s/def ::mailer-pw pred/bash-env-string?) +(s/def ::issuer pred/letsencrypt-issuer?) +(s/def ::volume-total-storage-size (partial pred/int-gt-n? 5)) + +(def config-defaults {:issuer "staging"}) + +(def config? (s/keys :req-un [::fqdn + ::mailer-from + ::mailer-host-port + ::service-noreply-address] + :opt-un [::issuer + ::default-app-name + ::service-domain-whitelist])) + +(def auth? (s/keys :req-un [::postgres/postgres-db-user ::postgres/postgres-db-password ::mailer-user ::mailer-pw])) + +(def vol? (s/keys :req-un [::volume-total-storage-size])) + +(defn data-storage-by-volume-size + [total] + total) + + +#?(:cljs + (defmethod yaml/load-resource :website [resource-name] + (case resource-name + "website/appini-env-configmap.yaml" (rc/inline "website/appini-env-configmap.yaml") + "website/deployment.yaml" (rc/inline "website/deployment.yaml") + "website/certificate.yaml" (rc/inline "website/certificate.yaml") + "website/ingress.yaml" (rc/inline "website/ingress.yaml") + "website/secrets.yaml" (rc/inline "website/secrets.yaml") + "website/service.yaml" (rc/inline "website/service.yaml") + "website/service-ssh.yaml" (rc/inline "website/service-ssh.yaml") + "website/datavolume.yaml" (rc/inline "website/datavolume.yaml") + (throw (js/Error. "Undefined Resource!"))))) + +#?(:cljs + (defmethod yaml/load-as-edn :website [resource-name] + (yaml/from-string (yaml/load-resource resource-name)))) + +(defn-spec generate-appini-env pred/map-or-seq? + [config config?] + (let [{:keys [default-app-name + fqdn + mailer-from + mailer-host-port + service-domain-whitelist + service-noreply-address] + :or {default-app-name "website instance" + service-domain-whitelist fqdn}} + config] + (-> + (yaml/load-as-edn "website/appini-env-configmap.yaml") + (cm/replace-all-matching-values-by-new-value "APPNAME" default-app-name) + (cm/replace-all-matching-values-by-new-value "FQDN" fqdn) + (cm/replace-all-matching-values-by-new-value "URL" (str "https://" fqdn)) + (cm/replace-all-matching-values-by-new-value "FROM" mailer-from) + (cm/replace-all-matching-values-by-new-value "HOSTANDPORT" mailer-host-port) + (cm/replace-all-matching-values-by-new-value "WHITELISTDOMAINS" service-domain-whitelist) + (cm/replace-all-matching-values-by-new-value "NOREPLY" service-noreply-address)))) + +(defn-spec generate-secrets pred/map-or-seq? + [auth auth?] + (let [{:keys [postgres-db-user + postgres-db-password + mailer-user + mailer-pw]} auth] + (-> + (yaml/load-as-edn "website/secrets.yaml") + (cm/replace-all-matching-values-by-new-value "DBUSER" (b64/encode postgres-db-user)) + (cm/replace-all-matching-values-by-new-value "DBPW" (b64/encode postgres-db-password)) + (cm/replace-all-matching-values-by-new-value "MAILERUSER" (b64/encode mailer-user)) + (cm/replace-all-matching-values-by-new-value "MAILERPW" (b64/encode mailer-pw))))) + +(defn-spec generate-ingress pred/map-or-seq? + [config config?] + (let [{:keys [fqdn issuer]} config] + (-> + (yaml/load-as-edn "website/ingress.yaml") + (cm/replace-all-matching-values-by-new-value "FQDN" fqdn)))) + +(defn-spec generate-certificate pred/map-or-seq? + [config config?] + (let [{:keys [fqdn issuer] + :or {issuer "staging"}} config + letsencrypt-issuer (name issuer)] + (-> + (yaml/load-as-edn "website/certificate.yaml") + (assoc-in [:spec :issuerRef :name] letsencrypt-issuer) + (cm/replace-all-matching-values-by-new-value "FQDN" fqdn)))) + +(defn-spec generate-data-volume pred/map-or-seq? + [config vol?] + (let [{:keys [volume-total-storage-size]} config + data-storage-size (data-storage-by-volume-size volume-total-storage-size)] + (-> + (yaml/load-as-edn "website/datavolume.yaml") + (cm/replace-all-matching-values-by-new-value "DATASTORAGESIZE" (str (str data-storage-size) "Gi"))))) + +(defn-spec generate-deployment pred/map-or-seq? + [] + (yaml/load-as-edn "website/deployment.yaml")) + +(defn-spec generate-service pred/map-or-seq? + [] + (yaml/load-as-edn "website/service.yaml")) + +(defn-spec generate-service-ssh pred/map-or-seq? + [] + (yaml/load-as-edn "website/service-ssh.yaml")) diff --git a/src/main/cljs/dda/c4k_gitea/browser.cljs b/src/main/cljs/dda/c4k_gitea/browser.cljs new file mode 100644 index 0000000..79ce286 --- /dev/null +++ b/src/main/cljs/dda/c4k_gitea/browser.cljs @@ -0,0 +1,125 @@ +(ns dda.c4k-website.browser + (:require + [clojure.string :as st] + [clojure.tools.reader.edn :as edn] + [dda.c4k-website.core :as core] + [dda.c4k-website.website :as website] + [dda.c4k-common.browser :as br] + [dda.c4k-common.postgres :as pgc] + [dda.c4k-common.common :as cm])) + +(defn generate-group + [name + content] + [{:type :element + :tag :div + :attrs {:class "rounded border border-3 m-3 p-2"} + :content [{:type :element + :tag :b + :attrs {:style "z-index: 1; position: relative; top: -1.3rem;"} + :content name} + {:type :element + :tag :fieldset + :content content}]}]) + +(defn generate-content [] + (cm/concat-vec + [(assoc + (br/generate-needs-validation) :content + (cm/concat-vec + (generate-group + "domain" + (cm/concat-vec + (br/generate-input-field "fqdn" "Your fqdn:" "repo.test.de") + (br/generate-input-field "mailer-from" "Your mailer email address:" "test@test.de") + (br/generate-input-field "mailer-host-port" "Your mailer host with port:" "test.de:123") + (br/generate-input-field "service-noreply-address" "Your noreply domain:" "test.de") + (br/generate-input-field "issuer" "(Optional) Your issuer prod/staging:" "") + (br/generate-input-field "app-name" "(Optional) Your app name:" "") + (br/generate-input-field "domain-whitelist" "(Optional) Domain whitelist for registration email-addresses:" ""))) + (generate-group + "provider" + (cm/concat-vec + (br/generate-input-field "volume-total-storage-size" "Your website volume-total-storage-size:" "20") + (br/generate-input-field "postgres-data-volume-path" "(Optional) Your postgres-data-volume-path if Persistent Volumes are not generated by an Operator:" ""))) + (generate-group + "credentials" + (br/generate-text-area + "auth" "Your auth.edn:" + "{:postgres-db-user \"website\" + :postgres-db-password \"website-db-password\" + :mailer-user \"test@test.de\" + :mailer-pw \"mail-test-password\"}" + "5")) + [(br/generate-br)] + (br/generate-button "generate-button" "Generate c4k yaml")))] + (br/generate-output "c4k-website-output" "Your c4k deployment.yaml:" "25"))) + +(defn generate-content-div + [] + {:type :element + :tag :div + :content + (generate-content)}) + +(defn config-from-document [] + (let [postgres-data-volume-path (br/get-content-from-element "postgres-data-volume-path" :optional true) + issuer (br/get-content-from-element "issuer" :optional true) + app-name (br/get-content-from-element "app-name" :optional true) + domain-whitelist (br/get-content-from-element "domain-whitelist" :optional true)] + (merge + {:fqdn (br/get-content-from-element "fqdn") + :mailer-from (br/get-content-from-element "mailer-from") + :mailer-host-port (br/get-content-from-element "mailer-host-port") + :service-noreply-address (br/get-content-from-element "service-noreply-address") + :volume-total-storage-size (br/get-content-from-element "volume-total-storage-size" :deserializer js/parseInt)} + (when (not (st/blank? postgres-data-volume-path)) + {:postgres-data-volume-path postgres-data-volume-path}) + (when (not (st/blank? issuer)) + {:issuer issuer}) + (when (not (st/blank? app-name)) + {:default-app-name app-name}) + (when (not (st/blank? domain-whitelist)) + {:service-domain-whitelist domain-whitelist}) + ))) + +(defn validate-all! [] + (br/validate! "fqdn" ::website/fqdn) + (br/validate! "mailer-from" ::website/mailer-from) + (br/validate! "mailer-host-port" ::website/mailer-host-port) + (br/validate! "service-noreply-address" ::website/service-noreply-address) + (br/validate! "issuer" ::website/issuer :optional true) + (br/validate! "app-name" ::website/default-app-name :optional true) + (br/validate! "domain-whitelist" ::website/service-domain-whitelist :optional true) + (br/validate! "postgres-data-volume-path" ::pgc/postgres-data-volume-path :optional true) + (br/validate! "volume-total-storage-size" ::website/volume-total-storage-size :deserializer js/parseInt) + (br/validate! "auth" website/auth? :deserializer edn/read-string) + (br/set-form-validated!)) + +(defn add-validate-listener [name] + (-> (br/get-element-by-id name) + (.addEventListener "blur" #(do (validate-all!))))) + + +(defn init [] + (br/append-hickory (generate-content-div)) + (-> js/document + (.getElementById "generate-button") + (.addEventListener "click" + #(do (validate-all!) + (-> (cm/generate-common + (config-from-document) + (br/get-content-from-element "auth" :deserializer edn/read-string) + website/config-defaults + core/k8s-objects) + (br/set-output!))))) + (add-validate-listener "fqdn") + (add-validate-listener "mailer-from") + (add-validate-listener "mailer-host-port") + (add-validate-listener "service-noreply-address") + (add-validate-listener "app-name") + (add-validate-listener "domain-whitelist") + (add-validate-listener "postgres-data-volume-path") + (add-validate-listener "volume-total-storage-size") + (add-validate-listener "issuer") + (add-validate-listener "auth")) \ No newline at end of file diff --git a/src/main/resources/gitea/certificate.yaml b/src/main/resources/gitea/certificate.yaml new file mode 100644 index 0000000..a9dacca --- /dev/null +++ b/src/main/resources/gitea/certificate.yaml @@ -0,0 +1,15 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: website-cert + namespace: default +spec: + secretName: website-cert + commonName: FQDN + duration: 2160h # 90d + renewBefore: 360h # 15d + dnsNames: + - FQDN + issuerRef: + name: staging + kind: ClusterIssuer \ No newline at end of file diff --git a/src/main/resources/gitea/datavolume.yaml b/src/main/resources/gitea/datavolume.yaml new file mode 100644 index 0000000..7be576e --- /dev/null +++ b/src/main/resources/gitea/datavolume.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: website-data-pvc + namespace: default + labels: + app: website +spec: + storageClassName: local-path + accessModes: + - ReadWriteOnce + resources: + requests: + storage: DATASTORAGESIZE + \ No newline at end of file diff --git a/src/main/resources/gitea/ingress.yaml b/src/main/resources/gitea/ingress.yaml new file mode 100644 index 0000000..f7aed60 --- /dev/null +++ b/src/main/resources/gitea/ingress.yaml @@ -0,0 +1,24 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress-website + namespace: default + annotations: + ingress.kubernetes.io/ssl-redirect: "true" + traefik.ingress.kubernetes.io/router.middlewares: default-redirect-https@kubernetescrd +spec: + tls: + - hosts: + - FQDN + secretName: website-cert + rules: + - host: FQDN + http: + paths: + - pathType: Prefix + path: "/" + backend: + service: + name: website-service + port: + number: 3000 diff --git a/src/main/resources/gitea/nginx-configmap.yaml b/src/main/resources/gitea/nginx-configmap.yaml new file mode 100644 index 0000000..49c58ab --- /dev/null +++ b/src/main/resources/gitea/nginx-configmap.yaml @@ -0,0 +1,56 @@ +# ToDo: +# content-pfad für nginx server definieren +# sinnvolle security policies konfigurieren + +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-env + namespace: default +data: + nginx.conv: | + user nginx; + worker_processes 3; + error_log /var/log/nginx/error.log; + events { + worker_connections 10240; + } + http { + log_format main + 'remote_addr:$remote_addr\t' + 'time_local:$time_local\t' + 'method:$request_method\t' + 'uri:$request_uri\t' + 'host:$host\t' + 'status:$status\t' + 'bytes_sent:$body_bytes_sent\t' + 'referer:$http_referer\t' + 'useragent:$http_user_agent\t' + 'forwardedfor:$http_x_forwarded_for\t' + 'request_time:$request_time'; + access_log /var/log/nginx/access.log main; + server { + listen 80; + server_name _; + location / { + root html; + index index.html index.htm; + } + } + include /etc/nginx/virtualhost/virtualhost.conf; + } + virtualhost.conf: | + upstream app { + server localhost:8080; + keepalive 1024; + } + server { + listen 80 default_server; + root /usr/local/app; + access_log /var/log/nginx/app.access_log main; + error_log /var/log/nginx/app.error_log; + location / { + proxy_pass http://app/; + proxy_http_version 1.1; + } + } diff --git a/src/main/resources/gitea/nginx-deployment.yaml b/src/main/resources/gitea/nginx-deployment.yaml new file mode 100644 index 0000000..29db5ce --- /dev/null +++ b/src/main/resources/gitea/nginx-deployment.yaml @@ -0,0 +1,36 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx + namespace: default + labels: + app: nginx +spec: + replicas: 1 + selector: + matchLabels: + app: nginx + template: + metadata: + name: nginx + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:latest + imagePullPolicy: IfNotPresent + ports: + - containerPort: 80 + protocol: TCP + envFrom: + - configMapRef: + name: nginx-env + volumeMounts: + - name: website-data-volume + mountPath: "/data" + volumes: + - name: website-data-volume + persistentVolumeClaim: + claimName: website-data-pvc + diff --git a/src/main/resources/gitea/website-server-service.yaml b/src/main/resources/gitea/website-server-service.yaml new file mode 100644 index 0000000..0425f79 --- /dev/null +++ b/src/main/resources/gitea/website-server-service.yaml @@ -0,0 +1,16 @@ +kind: Service +apiVersion: v1 +metadata: + name: website-server-service + namespace: default + annotations: + metallb.universe.tf/allow-shared-ip: "shared-ip-service-group" +spec: + type: LoadBalancer + selector: + app: website-server + ports: + - port: 80 + targetPort: 80 + protocol: TCP + diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..8985f2b --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,50 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + INFO + + + + + logs/pallet.log + + logs/old/pallet.%d{yyyy-MM-dd}.log + 3 + + + %date %level [%thread] %logger{10} %msg%n + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/cljc/dda/c4k_gitea/website_test.cljc b/src/test/cljc/dda/c4k_gitea/website_test.cljc new file mode 100644 index 0000000..c1485ad --- /dev/null +++ b/src/test/cljc/dda/c4k_gitea/website_test.cljc @@ -0,0 +1,73 @@ +(ns dda.c4k-website.website-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-common.test-helper :as th] + [dda.c4k-common.base64 :as b64] + [dda.c4k-website.website :as cut])) + +(st/instrument `cut/generate-appini-env) +(st/instrument `cut/generate-ingress) +(st/instrument `cut/generate-secrets) + +(deftest should-generate-appini-env + (is (= {:APP_NAME-c1 "", + :APP_NAME-c2 "test website", + :website__mailer__FROM-c1 "", + :website__mailer__FROM-c2 "test@test.com", + :website__mailer__HOST-c1 "m.t.de:123", + :website__mailer__HOST-c2 "mail.test.com:123", + :website__server__DOMAIN-c1 "test.de", + :website__server__DOMAIN-c2 "test.com", + :website__server__ROOT_URL-c1 "https://test.de", + :website__server__ROOT_URL-c2 "https://test.com", + :website__server__SSH_DOMAIN-c1 "test.de", + :website__server__SSH_DOMAIN-c2 "test.com", + :website__service__EMAIL_DOMAIN_WHITELIST-c1 "adb.de", + :website__service__EMAIL_DOMAIN_WHITELIST-c2 "test.com,test.net", + :website__service__NO_REPLY_ADDRESS-c1 "", + :website__service__NO_REPLY_ADDRESS-c2 "noreply@test.com"} + (th/map-diff (cut/generate-appini-env {:default-app-name "" + :fqdn "test.de" + :mailer-from "" + :mailer-host-port "m.t.de:123" + :service-domain-whitelist "adb.de" + :service-noreply-address "" + }) + (cut/generate-appini-env {:default-app-name "test website" + :fqdn "test.com" + :mailer-from "test@test.com" + :mailer-host-port "mail.test.com:123" + :service-domain-whitelist "test.com,test.net" + :service-noreply-address "noreply@test.com" + }))))) + +(deftest should-generate-certificate + (is (= {:name-c2 "prod", :name-c1 "staging"} + (th/map-diff (cut/generate-certificate {}) + (cut/generate-certificate {:issuer "prod"}))))) + +(deftest should-generate-secret + (is (= {:website__database__USER-c1 "", + :website__database__USER-c2 (b64/encode "pg-user"), + :website__database__PASSWD-c1 "", + :website__database__PASSWD-c2 (b64/encode "pg-pw"), + :website__mailer__USER-c1 "", + :website__mailer__USER-c2 (b64/encode "maileruser"), + :website__mailer__PASSWD-c1 "", + :website__mailer__PASSWD-c2 (b64/encode "mailerpw")} + (th/map-diff (cut/generate-secrets {:postgres-db-user "" + :postgres-db-password "" + :mailer-user "" + :mailer-pw ""}) + (cut/generate-secrets {:postgres-db-user "pg-user" + :postgres-db-password "pg-pw" + :mailer-user "maileruser" + :mailer-pw "mailerpw"}))))) + +(deftest should-generate-data-volume + (is (= {:storage-c1 "1Gi", + :storage-c2 "15Gi"} + (th/map-diff (cut/generate-data-volume {:volume-total-storage-size 1}) + (cut/generate-data-volume {:volume-total-storage-size 15}))))) \ No newline at end of file