Compare commits
1 commit
main
...
config-pla
Author | SHA1 | Date | |
---|---|---|---|
bb29292291 |
85 changed files with 1356 additions and 3146 deletions
.gitignore.gitlab-ci.ymlREADME.mdbuild.py
doc
BackupAndRestore.mdDevelopment.mdReleasing.mdarchitecture.mdarchitekturbild-c4k-website.graphmlarchitekturbild-c4k-website.jpgmeissa-website-arch.pngtryItOut.png
infrastructure
out.ymlpackage.jsonproject.cljshadow-cljs.ednsrc
main
clj/dda/c4k_taiga
cljc/dda/c4k_taiga
cljs/dda/c4k_taiga
resources
backup
taiga
async-deployment.yamlasync-rabbitmq-deployment.yamlasync-rabbitmq-service.yamlasync-service.yamlback-deployment.yamlback-service.yamlconfigmap.yaml
donotapply
events-deployment.yamlevents-rabbitmq-deployment.yamlevents-rabbitmq-service.yamlevents-service.yamlfront-deployment.yamlfront-service.yamlgateway-configmap.yamlgateway-deployment.yamlgateway-service.yamlprotected-deployment.yamlprotected-service.yamlpvc-taiga-media-data.yamlpvc-taiga-static-data.yamlrabbitmq-pvc-async.yamlrabbitmq-pvc-events.yamlsecret.yamltest
cljc/dda/c4k_taiga
resources/taiga-test
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -1,5 +1,3 @@
|
||||||
.eastwood
|
|
||||||
|
|
||||||
.clj-kondo/
|
.clj-kondo/
|
||||||
.lsp/
|
.lsp/
|
||||||
|
|
||||||
|
@ -12,7 +10,6 @@ target/
|
||||||
.lein-repl-history
|
.lein-repl-history
|
||||||
.lein-failures
|
.lein-failures
|
||||||
pom.*
|
pom.*
|
||||||
reports/*
|
|
||||||
|
|
||||||
# cljs
|
# cljs
|
||||||
.shadow-cljs
|
.shadow-cljs
|
||||||
|
@ -27,7 +24,8 @@ public/js/
|
||||||
*.iml
|
*.iml
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
|
auth.edn
|
||||||
|
config.edn
|
||||||
|
|
||||||
build-and-move-frontend.sh
|
build-and-move-frontend.sh
|
||||||
website.yaml
|
website.yaml
|
||||||
|
|
||||||
.envrc
|
|
||||||
|
|
129
.gitlab-ci.yml
129
.gitlab-ci.yml
|
@ -5,18 +5,11 @@ stages:
|
||||||
- upload
|
- upload
|
||||||
- image
|
- image
|
||||||
|
|
||||||
.img: &img
|
services:
|
||||||
image: "domaindrivenarchitecture/ddadevops-dind:4.11.3"
|
- docker:dind
|
||||||
services:
|
|
||||||
- docker:dind
|
|
||||||
before_script:
|
|
||||||
- export RELEASE_ARTIFACT_TOKEN=$MEISSA_REPO_BUERO_RW
|
|
||||||
- export IMAGE_DOCKERHUB_USER=$DOCKERHUB_USER
|
|
||||||
- export IMAGE_DOCKERHUB_PASSWORD=$DOCKERHUB_PASSWORD
|
|
||||||
- export IMAGE_TAG=$CI_COMMIT_TAG
|
|
||||||
|
|
||||||
.cljs-job: &cljs
|
.cljs-job: &cljs
|
||||||
image: "domaindrivenarchitecture/ddadevops-clj-cljs:4.11.3"
|
image: "domaindrivenarchitecture/ddadevops-clj-cljs:4.10.7"
|
||||||
cache:
|
cache:
|
||||||
key: ${CI_COMMIT_REF_SLUG}
|
key: ${CI_COMMIT_REF_SLUG}
|
||||||
paths:
|
paths:
|
||||||
|
@ -24,45 +17,42 @@ stages:
|
||||||
- .shadow-cljs/
|
- .shadow-cljs/
|
||||||
- .m2
|
- .m2
|
||||||
before_script:
|
before_script:
|
||||||
- export RELEASE_ARTIFACT_TOKEN=$MEISSA_REPO_BUERO_RW
|
- export RELEASE_ARTIFACT_TOKEN=$MEISSA_REPO_BUERO_RW
|
||||||
- echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
|
- echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
|
||||||
- npm install
|
- npm install
|
||||||
|
|
||||||
.clj-job: &clj
|
.clj-uploadjob: &clj
|
||||||
image: "domaindrivenarchitecture/ddadevops-clj:4.11.3"
|
image: "domaindrivenarchitecture/ddadevops-clj-cljs:4.10.7"
|
||||||
cache:
|
cache:
|
||||||
key: ${CI_COMMIT_REF_SLUG}
|
key: ${CI_COMMIT_REF_SLUG}
|
||||||
paths:
|
paths:
|
||||||
- .m2
|
- .m2
|
||||||
before_script:
|
before_script:
|
||||||
- export RELEASE_ARTIFACT_TOKEN=$MEISSA_REPO_BUERO_RW
|
- export RELEASE_ARTIFACT_TOKEN=$MEISSA_REPO_BUERO_RW
|
||||||
- mkdir -p /root/.lein
|
- mkdir -p /root/.lein
|
||||||
- echo "{:auth {:repository-auth {#\"clojars\" {:username \"${CLOJARS_USER}\" :password \"${CLOJARS_TOKEN_DOMAINDRIVENARCHITECTURE}\" }}}}" > ~/.lein/profiles.clj
|
- echo "{:auth {:repository-auth {#\"clojars\" {:username \"${CLOJARS_USER}\" :password \"${CLOJARS_TOKEN_DOMAINDRIVENARCHITECTURE}\" }}}}" > ~/.lein/profiles.clj
|
||||||
|
|
||||||
.tag_only: &tag_only
|
|
||||||
rules:
|
|
||||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
|
||||||
when: never
|
|
||||||
- if: '$CI_COMMIT_TAG =~ /^[0-9]+\.[0-9]+\.[0-9]+$/'
|
|
||||||
|
|
||||||
test-clj:
|
|
||||||
<<: *clj
|
|
||||||
stage: build_and_test
|
|
||||||
script:
|
|
||||||
- pyb test_clj
|
|
||||||
|
|
||||||
test-cljs:
|
test-cljs:
|
||||||
<<: *cljs
|
<<: *cljs
|
||||||
stage: build_and_test
|
stage: build_and_test
|
||||||
script:
|
script:
|
||||||
- pyb test_cljs
|
- shadow-cljs compile test
|
||||||
|
- node target/node-tests.js
|
||||||
|
|
||||||
|
test-clj:
|
||||||
|
<<: *clj
|
||||||
|
stage: build_and_test
|
||||||
|
script:
|
||||||
|
- lein test
|
||||||
|
|
||||||
test-schema:
|
test-schema:
|
||||||
<<: *clj
|
<<: *clj
|
||||||
stage: build_and_test
|
stage: build_and_test
|
||||||
script:
|
script:
|
||||||
- pyb test_schema
|
- lein uberjar
|
||||||
|
- java -jar target/uberjar/c4k-taiga-standalone.jar src/test/resources/taiga-test/valid-config.yaml src/test/resources/taiga-test/valid-auth.yaml | kubeconform --kubernetes-version 1.23.0 --strict --skip Certificate -
|
||||||
artifacts:
|
artifacts:
|
||||||
|
expire_in: 1h
|
||||||
paths:
|
paths:
|
||||||
- target/uberjar
|
- target/uberjar
|
||||||
|
|
||||||
|
@ -70,8 +60,10 @@ report-frontend:
|
||||||
<<: *cljs
|
<<: *cljs
|
||||||
stage: package
|
stage: package
|
||||||
script:
|
script:
|
||||||
- pyb report_frontend
|
- mkdir -p target/frontend-build
|
||||||
|
- shadow-cljs run shadow.cljs.build-report frontend target/frontend-build/build-report.html
|
||||||
artifacts:
|
artifacts:
|
||||||
|
expire_in: 1h
|
||||||
paths:
|
paths:
|
||||||
- target/frontend-build/build-report.html
|
- target/frontend-build/build-report.html
|
||||||
|
|
||||||
|
@ -79,8 +71,13 @@ package-frontend:
|
||||||
<<: *cljs
|
<<: *cljs
|
||||||
stage: package
|
stage: package
|
||||||
script:
|
script:
|
||||||
- pyb package_frontend
|
- mkdir -p target/frontend-build
|
||||||
|
- shadow-cljs release frontend
|
||||||
|
- cp public/js/main.js target/frontend-build/c4k-taiga.js
|
||||||
|
- sha256sum target/frontend-build/c4k-taiga.js > target/frontend-build/c4k-taiga.js.sha256
|
||||||
|
- sha512sum target/frontend-build/c4k-taiga.js > target/frontend-build/c4k-taiga.js.sha512
|
||||||
artifacts:
|
artifacts:
|
||||||
|
expire_in: 1h
|
||||||
paths:
|
paths:
|
||||||
- target/frontend-build
|
- target/frontend-build
|
||||||
|
|
||||||
|
@ -88,37 +85,47 @@ package-uberjar:
|
||||||
<<: *clj
|
<<: *clj
|
||||||
stage: package
|
stage: package
|
||||||
script:
|
script:
|
||||||
- pyb package_uberjar
|
- lein uberjar
|
||||||
|
- sha256sum target/uberjar/c4k-taiga-standalone.jar > target/uberjar/c4k-taiga-standalone.jar.sha256
|
||||||
|
- sha512sum target/uberjar/c4k-taiga-standalone.jar > target/uberjar/c4k-taiga-standalone.jar.sha512
|
||||||
artifacts:
|
artifacts:
|
||||||
|
expire_in: 1h
|
||||||
|
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:
|
||||||
|
expire_in: 24h
|
||||||
paths:
|
paths:
|
||||||
- target/uberjar
|
- target/uberjar
|
||||||
|
- target/frontend-build
|
||||||
package-native:
|
|
||||||
<<: *clj
|
|
||||||
stage: package
|
|
||||||
script:
|
script:
|
||||||
- pyb package_native
|
- apk --no-cache add curl
|
||||||
artifacts:
|
- |
|
||||||
paths:
|
release-cli create --name "Release $CI_COMMIT_TAG" --tag-name $CI_COMMIT_TAG \
|
||||||
- target/graalvm
|
--assets-link "{\"name\":\"c4k-taiga-standalone.jar\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-taiga/-/jobs/${CI_JOB_ID}/artifacts/file/target/uberjar/c4k-taiga-standalone.jar\"}" \
|
||||||
|
--assets-link "{\"name\":\"c4k-taiga-standalone.jar.sha256\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-taiga/-/jobs/${CI_JOB_ID}/artifacts/file/target/uberjar/c4k-taiga-standalone.jar.sha256\"}" \
|
||||||
|
--assets-link "{\"name\":\"c4k-taiga-standalone.jar.sha512\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-taiga/-/jobs/${CI_JOB_ID}/artifacts/file/target/uberjar/c4k-taiga-standalone.jar.sha512\"}" \
|
||||||
|
--assets-link "{\"name\":\"c4k-taiga.js\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-taiga/-/jobs/${CI_JOB_ID}/artifacts/file/target/frontend-build/c4k-taiga.js\"}" \
|
||||||
|
--assets-link "{\"name\":\"c4k-taiga.js.sha256\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-taiga/-/jobs/${CI_JOB_ID}/artifacts/file/target/frontend-build/c4k-taiga.js.sha256\"}" \
|
||||||
|
--assets-link "{\"name\":\"c4k-taiga.js.sha512\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-taiga/-/jobs/${CI_JOB_ID}/artifacts/file/target/frontend-build/c4k-taiga.js.sha512\"}" \
|
||||||
|
|
||||||
release-to-clojars:
|
taiga-image-test-publish:
|
||||||
<<: *clj
|
image: domaindrivenarchitecture/devops-build:latest
|
||||||
<<: *tag_only
|
|
||||||
stage: upload
|
|
||||||
script:
|
|
||||||
- pyb upload_clj
|
|
||||||
|
|
||||||
release-to-forgejo:
|
|
||||||
<<: *clj
|
|
||||||
<<: *tag_only
|
|
||||||
stage: upload
|
|
||||||
script:
|
|
||||||
- pyb publish_artifacts
|
|
||||||
|
|
||||||
backup-image-publish:
|
|
||||||
<<: *img
|
|
||||||
<<: *tag_only
|
|
||||||
stage: image
|
stage: image
|
||||||
|
rules:
|
||||||
|
- if: '$CI_COMMIT_TAG != null'
|
||||||
script:
|
script:
|
||||||
- cd infrastructure/backup && pyb image publish
|
- cd infrastructure/c4k-taiga-build && pyb image test publish
|
162
README.md
162
README.md
|
@ -2,88 +2,116 @@
|
||||||
|
|
||||||
[](https://clojars.org/org.domaindrivenarchitecture/c4k-taiga) [](https://gitlab.com/domaindrivenarchitecture/c4k-taiga/-/commits/main)
|
[](https://clojars.org/org.domaindrivenarchitecture/c4k-taiga) [](https://gitlab.com/domaindrivenarchitecture/c4k-taiga/-/commits/main)
|
||||||
|
|
||||||
[<img src="https://domaindrivenarchitecture.org/img/delta-chat.svg" width=20 alt="DeltaChat"> chat over e-mail](mailto:buero@meissa-gmbh.de?subject=community-chat) | [<img src="https://meissa.de/images/parts/contact/mastodon36_hue9b2464f10b18e134322af482b9c915e_5501_filter_14705073121015236177.png" width=20 alt="M"> meissa@social.meissa-gmbh.de](https://social.meissa-gmbh.de/@meissa) | [Blog](https://domaindrivenarchitecture.org) | [Website](https://meissa.de)
|
[<img src="https://domaindrivenarchitecture.org/img/delta-chat.svg" width=20 alt="DeltaChat"> chat over e-mail](mailto:buero@meissa-gmbh.de?subject=community-chat) | [<img src="https://meissa-gmbh.de/img/community/Mastodon_Logotype.svg" width=20 alt="team@social.meissa-gmbh.de"> team@social.meissa-gmbh.de](https://social.meissa-gmbh.de/@team) | [taiga & Blog](https://domaindrivenarchitecture.org)
|
||||||
|
|
||||||
|
## Configuration Issues
|
||||||
|
|
||||||
|
We currently can no login even after `python manage.py createsuperuser --noinput` in the taiga-back-deployment container. What might help: https://docs.taiga.io/setup-production.html#taiga-back
|
||||||
|
|
||||||
|
Note: taiga-manage,-back und -async verwenden die gleichen docker images mit unterschiedlichen entry-points.
|
||||||
|
|
||||||
|
https://github.com/kaleidos-ventures/taiga-docker
|
||||||
|
https://community.taiga.io/t/taiga-30min-setup/170
|
||||||
|
|
||||||
|
### Steps to start and get an admin user
|
||||||
|
|
||||||
|
Philosophy: First create the superuser, then populate the DB.
|
||||||
|
https://docs.taiga.io/setup-production.html#taiga-back
|
||||||
|
https://docs.taiga.io/setup-production.html#_configure_an_admin_user
|
||||||
|
https://github.com/kaleidos-ventures/taiga-back/blob/main/docker/entrypoint.sh
|
||||||
|
|
||||||
|
In the init container we create the super user. Difference between init-container and container: CELERY_ENABLED: false
|
||||||
|
The init container gets the following command and args:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
command: ["/bin/bash"]
|
||||||
|
args: ["-c", "source /opt/venv/bin/activate && python manage.py createsuperuser --noinput"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Thus the dockerfile default entrypoint is ignored.
|
||||||
|
|
||||||
|
Problem: Login using this method is still not available with the proposed credentials.
|
||||||
|
|
||||||
|
#### Option 1: Init container, currently under test
|
||||||
|
|
||||||
|
Create an init container (celery disabled) with the python manage.py command and the taiga-manage createsuperuser args
|
||||||
|
|
||||||
|
#### Option 2: Single container
|
||||||
|
|
||||||
|
Create a single container that has celery disabled at the beginning.
|
||||||
|
Runs the following cmds:
|
||||||
|
* python manage.py taiga-manage createsuperuser
|
||||||
|
* enable celery
|
||||||
|
* execute entrypoint.sh
|
||||||
|
|
||||||
|
### HTTPS
|
||||||
|
|
||||||
|
Terminiert am ingress. Wie interagiert das mit taiga?
|
||||||
|
Eventuell wird dies hier relevant:
|
||||||
|
https://github.com/kaleidos-ventures/taiga-docker#session-cookies-in-django-admin
|
||||||
|
|
||||||
|
### Docker Compose (DC) -> Kubernetes
|
||||||
|
|
||||||
|
We implemented a deployment and service in kubernetes for each DC Service.
|
||||||
|
Configmaps and secrets were implemented, to avoid redundancy and readability also to increase security a bit.
|
||||||
|
For all volumes described in DC we implemented PVCs and volume refs.
|
||||||
|
|
||||||
|
A config.py (used for taiga-back ) was introduced for reference.
|
||||||
|
A config.json (used for taiga-front ) was introduced for reference.
|
||||||
|
NB: It might be necessary to actually map both from a config map to their respective locations in taiga-back and taiga-front. Description for that is [here](https://docs.taiga.io/setup-production.html).
|
||||||
|
A mix of both env-vars and config.py in one container is not possible.
|
||||||
|
|
||||||
|
#### depends_on
|
||||||
|
|
||||||
|
We currently assume, that it will work without explicitly defining a startup order.
|
||||||
|
|
||||||
|
#### DC Networking
|
||||||
|
|
||||||
|
https://github.com/compose-spec/compose-spec/blob/master/spec.md
|
||||||
|
|
||||||
|
The `hostname` KW sets the hostname of a container.
|
||||||
|
It should have no effect on the discoverability of the container in kubernetes.
|
||||||
|
|
||||||
|
The `networks` KW defines the networks that service containers are attached to, referencing entries under the top-level networks key.
|
||||||
|
This should be taken care of by our kubernetes installation.
|
||||||
|
|
||||||
|
#### Pod to Pod Possible Communications
|
||||||
|
|
||||||
|
Taiga containers that need to reach other taiga containers:
|
||||||
|
taiga-async -> taiga-async-rabbitmq
|
||||||
|
taiga-events -> taiga-events-rabbitmq
|
||||||
|
This is not quite clear, but probably solved with the implementation of services.
|
||||||
|
|
||||||
|
### Deployments
|
||||||
|
|
||||||
|
Separate deployments exist for each of the taiga modules:
|
||||||
|
|
||||||
|
Taiga-back reads many values in config.py from env vars as can be seen in the taiga-back [config.py](
|
||||||
|
https://github.com/kaleidos-ventures/taiga-back/blob/main/docker/config.py). These are read from configmaps and secrets in the deployment.
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
Easily generate a config for a small scale Taiga deployment. Complete with initial super user and configurable values for flexibility.
|
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
Ready for production. We are about to migrate to taiga on our own servers.
|
|
||||||
|
|
||||||
## Try out
|
## Try out
|
||||||
|
|
||||||
Click on the image to try out live in your browser:
|
|
||||||
|
|
||||||
[](https://domaindrivenarchitecture.org/pages/dda-provision/c4k-taiga/)
|
|
||||||
|
|
||||||
Your input will stay in your browser. No server interaction is required.
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
To generate your configuration:
|
You need:
|
||||||
|
|
||||||
1. Create an auth.yaml and a config.yaml
|
...
|
||||||
|
|
||||||
You can find examples in src/test/resources/taiga-test in this repository.
|
* and a kubernetes cluster provisioned by [provs]
|
||||||
Please check the ```def auth?``` and ```def config?``` definitions in src/main/cljc/dda/c4k_taiga/taiga.cljc
|
|
||||||
for required and optional values. When you plan to use the dda_backup solution, you also need the keys:
|
|
||||||
|
|
||||||
- aws-access-key-id: "AWS_KEY_ID"
|
...
|
||||||
- aws-secret-access-key: "AWS_KEY_SECRET"
|
Let c4k-taiga generate your .yaml file.
|
||||||
- restic-password: ""
|
Apply this file on your cluster with `kubectl apply -f yourApp.yaml`.
|
||||||
|
|
||||||
in your auth.yaml
|
|
||||||
|
|
||||||
and
|
|
||||||
|
|
||||||
- restic-repository: "repo-path"
|
|
||||||
|
|
||||||
in your config.yaml.
|
|
||||||
|
|
||||||
2. install jarwrapper
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo apt install jarwrapper # on debian derivatives
|
|
||||||
```
|
|
||||||
|
|
||||||
3. execute the c4k-taiga-standalone.jar
|
|
||||||
|
|
||||||
```bash
|
|
||||||
java -jar c4k-taiga-standalone.jar config.yaml auth.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
To set up you need:
|
|
||||||
|
|
||||||
* A working DNS route to the FQDN of your taiga installation
|
|
||||||
* A kubernetes cluster provisioned by [provs]
|
|
||||||
* The .yaml file generated by c4k-taiga-standalone.jar
|
|
||||||
|
|
||||||
Apply this file on your cluster with `kubectl apply -f application.yaml`.
|
|
||||||
Done.
|
Done.
|
||||||
|
|
||||||
## Setup
|
### resource requests and limits
|
||||||
|
|
||||||
`python manage.py createsuperuser --noinput`
|
You may want to adjust the resource requests and limits of the build and init containers to your specific scenario.
|
||||||
|
|
||||||
## Administration
|
|
||||||
|
|
||||||
You can access the administration of the taiga installation via: your.taiga.url/admin/
|
|
||||||
|
|
||||||
In order to login, you first have to create a superuser.
|
|
||||||
1. Connect to taiga-back pod: `kubectl exec -it taiga-back-deployment-... -- bash`
|
|
||||||
2. `source /opt/venv/bin/activate && python manage.py createsuperuser --noinput`
|
|
||||||
|
|
||||||
## Backup
|
|
||||||
|
|
||||||
You need some form of cloud storage like AWS buckets and the respective access credentials
|
|
||||||
to make the backups work correctly.
|
|
||||||
|
|
||||||
For a working backup you need to save Taiga DB & Taiga Media as described here:
|
|
||||||
https://docs.taiga.io/backup-and-restore.html
|
|
||||||
|
|
||||||
For further instruction please refer to BackupAndRestore.md in doc/ in this repository.
|
|
||||||
|
|
||||||
## Development & mirrors
|
## Development & mirrors
|
||||||
|
|
||||||
|
@ -98,7 +126,7 @@ For more details about our repository model see: https://repo.prod.meissa.de/mei
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Copyright © 2024, 2025 meissa GmbH
|
Copyright © 2022 meissa GmbH
|
||||||
Licensed under the [Apache License, Version 2.0](LICENSE) (the "License")
|
Licensed under the [Apache License, Version 2.0](LICENSE) (the "License")
|
||||||
Pls. find licenses of our subcomponents [here](doc/SUBCOMPONENT_LICENSE)
|
Pls. find licenses of our subcomponents [here](doc/SUBCOMPONENT_LICENSE)
|
||||||
|
|
||||||
|
|
234
build.py
234
build.py
|
@ -1,234 +0,0 @@
|
||||||
from os import environ
|
|
||||||
from subprocess import run
|
|
||||||
from pybuilder.core import init, task
|
|
||||||
from ddadevops import *
|
|
||||||
|
|
||||||
default_task = "dev"
|
|
||||||
base_name = "taiga"
|
|
||||||
name = 'c4k-taiga'
|
|
||||||
MODULE = 'not-used'
|
|
||||||
PROJECT_ROOT_PATH = '.'
|
|
||||||
|
|
||||||
@init
|
|
||||||
def initialize(project):
|
|
||||||
project.build_depends_on("ddadevops>=4.7.0")
|
|
||||||
|
|
||||||
input = {
|
|
||||||
"name": name,
|
|
||||||
"module": MODULE,
|
|
||||||
"stage": "notused",
|
|
||||||
"project_root_path": PROJECT_ROOT_PATH,
|
|
||||||
"build_types": [],
|
|
||||||
"mixin_types": ["RELEASE"],
|
|
||||||
"release_primary_build_file": "project.clj",
|
|
||||||
"release_secondary_build_files": [
|
|
||||||
"package.json",
|
|
||||||
"infrastructure/backup/build.py",
|
|
||||||
],
|
|
||||||
"release_artifact_server_url": "https://repo.prod.meissa.de",
|
|
||||||
"release_organisation": "meissa",
|
|
||||||
"release_repository_name": name,
|
|
||||||
"release_artifacts": [
|
|
||||||
f"target/graalvm/{name}",
|
|
||||||
f"target/uberjar/{name}-standalone.jar",
|
|
||||||
f"target/frontend-build/{name}.js",
|
|
||||||
],
|
|
||||||
"release_main_branch": "main",
|
|
||||||
}
|
|
||||||
|
|
||||||
build = ReleaseMixin(project, input)
|
|
||||||
build.initialize_build_dir()
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
|
||||||
def test(project):
|
|
||||||
test_clj(project)
|
|
||||||
test_cljs(project)
|
|
||||||
test_schema(project)
|
|
||||||
|
|
||||||
@task
|
|
||||||
def test_clj(project):
|
|
||||||
run("lein test", shell=True, check=True)
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
|
||||||
def test_cljs(project):
|
|
||||||
run("shadow-cljs compile test", shell=True, check=True)
|
|
||||||
run("node target/node-tests.js", shell=True, check=True)
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
|
||||||
def test_schema(project):
|
|
||||||
run("lein uberjar", shell=True, check=True)
|
|
||||||
run(
|
|
||||||
f"java -jar target/uberjar/{name}-standalone.jar "
|
|
||||||
+ f"src/test/resources/{base_name}-test/valid-config.yaml "
|
|
||||||
+ f"src/test/resources/{base_name}-test/valid-auth.yaml | "
|
|
||||||
+ "kubeconform --kubernetes-version 1.23.0 --strict --skip Certificate -",
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
|
||||||
def report_frontend(project):
|
|
||||||
run("mkdir -p target/frontend-build", shell=True, check=True)
|
|
||||||
run(
|
|
||||||
"shadow-cljs run shadow.cljs.build-report frontend target/frontend-build/build-report.html",
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
|
||||||
def package_frontend(project):
|
|
||||||
run("mkdir -p target/frontend-build", shell=True, check=True)
|
|
||||||
run("shadow-cljs release frontend", shell=True, check=True)
|
|
||||||
run(
|
|
||||||
f"cp public/js/main.js target/frontend-build/{name}.js",
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
)
|
|
||||||
run(
|
|
||||||
f"sha256sum target/frontend-build/{name}.js > target/frontend-build/{name}.js.sha256",
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
)
|
|
||||||
run(
|
|
||||||
f"sha512sum target/frontend-build/{name}.js > target/frontend-build/{name}.js.sha512",
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
|
||||||
def package_uberjar(project):
|
|
||||||
run(
|
|
||||||
f"sha256sum target/uberjar/{name}-standalone.jar > target/uberjar/{name}-standalone.jar.sha256",
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
)
|
|
||||||
run(
|
|
||||||
f"sha512sum target/uberjar/{name}-standalone.jar > target/uberjar/{name}-standalone.jar.sha512",
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
@task
|
|
||||||
def package_native(project):
|
|
||||||
run(
|
|
||||||
"mkdir -p target/graalvm",
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
)
|
|
||||||
run(
|
|
||||||
"native-image " +
|
|
||||||
"--native-image-info " +
|
|
||||||
"--report-unsupported-elements-at-runtime " +
|
|
||||||
"--no-server " +
|
|
||||||
"--no-fallback " +
|
|
||||||
"--features=clj_easy.graal_build_time.InitClojureClasses " +
|
|
||||||
f"-jar target/uberjar/{project.name}-standalone.jar " +
|
|
||||||
"-H:IncludeResources=.*.yaml " +
|
|
||||||
"-H:Log=registerResource:verbose " +
|
|
||||||
f"-H:Name=target/graalvm/{project.name}",
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
)
|
|
||||||
run(
|
|
||||||
f"sha256sum target/graalvm/{project.name} > target/graalvm/{project.name}.sha256",
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
)
|
|
||||||
run(
|
|
||||||
f"sha512sum target/graalvm/{project.name} > target/graalvm/{project.name}.sha512",
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
@task
|
|
||||||
def upload_clj(project):
|
|
||||||
run("lein deploy", shell=True, check=True)
|
|
||||||
|
|
||||||
@task
|
|
||||||
def inst(project):
|
|
||||||
run("lein uberjar", shell=True, check=True)
|
|
||||||
package_uberjar(project)
|
|
||||||
package_native(project)
|
|
||||||
run(
|
|
||||||
f"sudo install -m=755 target/uberjar/{project.name}-standalone.jar /usr/local/bin/{project.name}-standalone.jar",
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
)
|
|
||||||
run(
|
|
||||||
f"sudo install -m=755 target/graalvm/{project.name} /usr/local/bin/{project.name}",
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
|
||||||
def lint(project):
|
|
||||||
#run(
|
|
||||||
# "lein eastwood",
|
|
||||||
# shell=True,
|
|
||||||
# check=True,
|
|
||||||
#)
|
|
||||||
run(
|
|
||||||
"lein ancient check",
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
|
||||||
def patch(project):
|
|
||||||
linttest(project, "PATCH")
|
|
||||||
release(project)
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
|
||||||
def minor(project):
|
|
||||||
linttest(project, "MINOR")
|
|
||||||
release(project)
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
|
||||||
def major(project):
|
|
||||||
linttest(project, "MAJOR")
|
|
||||||
release(project)
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
|
||||||
def dev(project):
|
|
||||||
linttest(project, "NONE")
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
|
||||||
def prepare(project):
|
|
||||||
build = get_devops_build(project)
|
|
||||||
build.prepare_release()
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
|
||||||
def tag(project):
|
|
||||||
build = get_devops_build(project)
|
|
||||||
build.tag_bump_and_push_release()
|
|
||||||
|
|
||||||
@task
|
|
||||||
def publish_artifacts(project):
|
|
||||||
build = get_devops_build(project)
|
|
||||||
build.publish_artifacts()
|
|
||||||
|
|
||||||
def release(project):
|
|
||||||
prepare(project)
|
|
||||||
tag(project)
|
|
||||||
|
|
||||||
|
|
||||||
def linttest(project, release_type):
|
|
||||||
build = get_devops_build(project)
|
|
||||||
build.update_release_type(release_type)
|
|
||||||
test_clj(project)
|
|
||||||
test_cljs(project)
|
|
||||||
test_schema(project)
|
|
||||||
lint(project)
|
|
|
@ -1,9 +0,0 @@
|
||||||
|
|
||||||
# Backup Architecture details
|
|
||||||
|
|
||||||
Use process documented at https://repo.prod.meissa.de/meissa/dda-backup/src/branch/main/docs/Backup.md
|
|
||||||
|
|
||||||
Parameters are:
|
|
||||||
|
|
||||||
1. **deployment-name**: taiga-front-deployment, taiga-gateway-deployment
|
|
||||||
2. **deployment-namespace**: taiga
|
|
|
@ -1,107 +0,0 @@
|
||||||
# Project Setup
|
|
||||||
|
|
||||||
## clj setup
|
|
||||||
|
|
||||||
### install leiningen
|
|
||||||
```
|
|
||||||
sudo apt install leiningen
|
|
||||||
```
|
|
||||||
or manually using Instructions on https://leiningen.org/#install
|
|
||||||
|
|
||||||
### install vscode + extensions
|
|
||||||
```
|
|
||||||
sudo snap install code
|
|
||||||
```
|
|
||||||
or with packages from https://code.visualstudio.com/Download
|
|
||||||
|
|
||||||
install extension "Calva: Clojure & ClojureScript Interactive Programming"
|
|
||||||
|
|
||||||
## cljs / js-dev setup
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo apt install npm
|
|
||||||
sudo npm install -g npx
|
|
||||||
|
|
||||||
# maybe
|
|
||||||
sudo npm install -g shadow-cljs
|
|
||||||
|
|
||||||
# in project root to retrieve all dependencies
|
|
||||||
npm install --ignore-scripts
|
|
||||||
npx shadow-cljs compile test
|
|
||||||
```
|
|
||||||
|
|
||||||
### create frontend script
|
|
||||||
|
|
||||||
```
|
|
||||||
npx shadow-cljs release frontend
|
|
||||||
```
|
|
||||||
|
|
||||||
## graalvm-setup
|
|
||||||
|
|
||||||
```
|
|
||||||
curl -LO https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-21.0.2/graalvm-community-jdk-21.0.2_linux-x64_bin.tar.gz
|
|
||||||
|
|
||||||
# unpack
|
|
||||||
tar -xzf graalvm-community-jdk-21.0.2_linux-x64_bin.tar.gz
|
|
||||||
|
|
||||||
sudo mv graalvm-community-openjdk-21.0.2+13.1 /usr/lib/jvm/
|
|
||||||
sudo ln -s /usr/lib/jvm/graalvm-community-openjdk-21.0.2+13.1 /usr/lib/jvm/graalvm-21
|
|
||||||
sudo ln -s /usr/lib/jvm/graalvm-21/bin/gu /usr/local/bin
|
|
||||||
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/graalvm-21/bin/java 2
|
|
||||||
sudo update-alternatives --config java
|
|
||||||
sudo ln -s /usr/lib/jvm/graalvm-21/bin/native-image /usr/local/bin
|
|
||||||
|
|
||||||
# deps
|
|
||||||
sudo apt-get install build-essential libz-dev zlib1g-dev
|
|
||||||
|
|
||||||
# build
|
|
||||||
cd ~/repo/c4k/c4k-forgejo
|
|
||||||
lein uberjar
|
|
||||||
mkdir -p target/graalvm
|
|
||||||
lein native
|
|
||||||
|
|
||||||
# execute
|
|
||||||
./target/graalvm/c4k-cloud -h
|
|
||||||
./target/graalvm/c4k-cloud src/test/resources/valid-config.edn src/test/resources/valid-auth.edn
|
|
||||||
./target/graalvm/c4k-cloud src/test/resources/invalid-config.edn src/test/resources/invalid-auth.edn
|
|
||||||
```
|
|
||||||
|
|
||||||
## c4k-setup
|
|
||||||
### install kubectl
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo -i
|
|
||||||
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
|
|
||||||
echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" \
|
|
||||||
| tee -a /etc/apt/sources.list.d/kubernetes.list
|
|
||||||
apt update && apt install kubectl
|
|
||||||
kubectl completion bash >> /etc/bash_completion.d/kubernetes
|
|
||||||
```
|
|
||||||
|
|
||||||
### install kubeconform
|
|
||||||
|
|
||||||
```
|
|
||||||
curl -Lo /tmp/kubeconform.tar.gz https://github.com/yannh/kubeconform/releases/download/v0.4.7/kubeconform-linux-amd64.tar.gz
|
|
||||||
tar -xf /tmp/kubeconform.tar.gz
|
|
||||||
sudo cp kubeconform /usr/local/bin
|
|
||||||
```
|
|
||||||
|
|
||||||
### remote access to c4k
|
|
||||||
|
|
||||||
```
|
|
||||||
scp -r root@devops.test.meissa-gmbh.de:/home/c4k/.kube ~/
|
|
||||||
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@devops.test.meissa-gmbh.de -L 8002:localhost:8002 -L 6443:192.168.5.1:6443
|
|
||||||
|
|
||||||
# add in /etc/hosts "127.0.0.1 kubernetes"
|
|
||||||
|
|
||||||
# change in ~/.kube/config 192.168.5.1 -> kubernetes
|
|
||||||
|
|
||||||
kubectl get pods
|
|
||||||
```
|
|
||||||
|
|
||||||
### deploy cloud
|
|
||||||
|
|
||||||
```
|
|
||||||
java -jar target/uberjar/c4k-cloud-standalone.jar valid-config.edn valid-auth.edn | kubeconform --kubernetes-version 1.19.0 --strict --skip Certificate -
|
|
||||||
java -jar target/uberjar/c4k-cloud-standalone.jar valid-config.edn my-auth.edn | kubectl apply -f -
|
|
||||||
```
|
|
|
@ -1,7 +1,5 @@
|
||||||
# Release process
|
# Release process
|
||||||
|
|
||||||
(Deprecated, please refer to the build.py instead.)
|
|
||||||
|
|
||||||
## ... for testing (snapshots)
|
## ... for testing (snapshots)
|
||||||
|
|
||||||
Make sure your clojars.org credentials are correctly set in your ~/.lein/profiles.clj file.
|
Make sure your clojars.org credentials are correctly set in your ~/.lein/profiles.clj file.
|
||||||
|
|
26
doc/architecture.md
Normal file
26
doc/architecture.md
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
C4Context
|
||||||
|
title c4k-webserver
|
||||||
|
Boundary(website, "website") {
|
||||||
|
System(website_ing1, "ingress f. host meissa-gmbh.de")
|
||||||
|
System(website_ing2, "ingress f. host meissa.de")
|
||||||
|
Boundary(website_pod, "website pod"){
|
||||||
|
Boundary(aaa, "website container") {
|
||||||
|
System(ws, "webserver")
|
||||||
|
SystemDb(file_html, "static html")
|
||||||
|
Rel(ws, file_html, "file ro")
|
||||||
|
}
|
||||||
|
Boundary(aab, "cron build website") {
|
||||||
|
System(git_clone, "git clone/pull & lein ring server & copy to static html")
|
||||||
|
SystemDb(file_git, "git repo")
|
||||||
|
Rel(git_clone, file_git, "file rw")
|
||||||
|
Rel(git_clone, file_html, "file rw")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rel(website_ing1, ws, "http")
|
||||||
|
Rel(website_ing2, ws, "http")
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
[](https://mermaid.live/edit#pako:eNqNU8tugzAQ_JWVD1UqJaka5cSxSX-guSIhgxewamxkL01RxL_XQFExSdr6gtee2ccMvrDMCGQRO-wPRhN-UqzBL5KkELL9--aMqUP7gXa8eDGNFty2q_5cEq4hZt_bmD3CZUT169Q6wmrCJVIXzz3Yfy06B_kWSuMIKpTO8U1RpeVW9Dl-y7C7n2FJXjaa1EbMmgUfevys34DEOZ-DM68Nl9qLEM647NRNpFGxeT8h9JiucqkwKalSPccRJ5lBH95kvaEasgekPgBrrgjd3aHSnpZZoyFtpBJw27nFVIWkJFNGD177AIbgqW6UggdQKDVY7wmMQ_ujzNQtkIG_hgql8JmnAhZrc1eGWTtz3ijG-d-0UMRrXjfb_9zMpB0sCX7u0f6SqA6yLYC7BTAs4guwNavQVlwK_y4HW2JGJVbepshvBea8URSzWHce2tSCE74KScayKOfK4Zrxhsyp1RmLyDY4gY6SF5ZX42H3BTITMPU)
|
632
doc/architekturbild-c4k-website.graphml
Normal file
632
doc/architekturbild-c4k-website.graphml
Normal file
|
@ -0,0 +1,632 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
|
||||||
|
<!--Created by yEd 3.22-->
|
||||||
|
<key attr.name="Description" attr.type="string" for="graph" id="d0"/>
|
||||||
|
<key for="port" id="d1" yfiles.type="portgraphics"/>
|
||||||
|
<key for="port" id="d2" yfiles.type="portgeometry"/>
|
||||||
|
<key for="port" id="d3" yfiles.type="portuserdata"/>
|
||||||
|
<key attr.name="url" attr.type="string" for="node" id="d4"/>
|
||||||
|
<key attr.name="description" attr.type="string" for="node" id="d5"/>
|
||||||
|
<key for="node" id="d6" yfiles.type="nodegraphics"/>
|
||||||
|
<key for="graphml" id="d7" yfiles.type="resources"/>
|
||||||
|
<key attr.name="url" attr.type="string" for="edge" id="d8"/>
|
||||||
|
<key attr.name="description" attr.type="string" for="edge" id="d9"/>
|
||||||
|
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
|
||||||
|
<graph edgedefault="directed" id="G">
|
||||||
|
<data key="d0" xml:space="preserve"/>
|
||||||
|
<node id="n0">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="154.25" width="221.25" x="674.8125" y="-212.076171875"/>
|
||||||
|
<y:Fill color="#C0C0C0" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="free" modelPosition="anywhere" textColor="#000000" verticalTextPosition="bottom" visible="true" width="36.292236328125" x="4.0" xml:space="preserve" y="4.0">Client</y:NodeLabel>
|
||||||
|
<y:Shape type="roundrectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n1">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="514.0" width="1041.25" x="-97.5625" y="-35.638671875"/>
|
||||||
|
<y:Fill color="#3366FF" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="18" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="28.515846252441406" horizontalTextPosition="center" iconTextGap="4" modelName="free" modelPosition="anywhere" textColor="#000000" verticalTextPosition="bottom" visible="true" width="131.1511993408203" x="4.0" xml:space="preserve" y="4.0">Hetzner-Server</y:NodeLabel>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="4.0" x="518.625" y="266.69427546920065">
|
||||||
|
<y:LabelModel>
|
||||||
|
<y:SmartNodeLabelModel distance="4.0"/>
|
||||||
|
</y:LabelModel>
|
||||||
|
<y:ModelParameter>
|
||||||
|
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.022751508694942912" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
|
||||||
|
</y:ModelParameter>
|
||||||
|
</y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n2">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="426.5" width="691.75" x="-57.5" y="10.111328125"/>
|
||||||
|
<y:Fill color="#33CCCC" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="23.067916870117188" horizontalTextPosition="center" iconTextGap="4" modelName="free" modelPosition="anywhere" textColor="#000000" verticalTextPosition="bottom" visible="true" width="39.61585998535156" x="4.0" xml:space="preserve" y="4.0">Node</y:NodeLabel>
|
||||||
|
<y:Shape type="roundrectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n3">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="85.0" width="93.75" x="290.0" y="60.548828125"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="23.067916870117188" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="86.34767150878906" x="3.7011642456054688" xml:space="preserve" y="30.966041564941406">Webserver 1<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="octagon"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n4">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="98.75" width="78.75" x="128.9375" y="53.673828125"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="23.067916870117188" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="61.10578918457031" x="8.822105407714844" xml:space="preserve" y="37.841041564941406">Ingress1<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="fatarrow2"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n5">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="98.75" width="78.75" x="128.9375" y="182.423828125"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="23.067916870117188" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="61.10578918457031" x="8.822105407714844" xml:space="preserve" y="37.841041564941406">Ingress2<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="fatarrow2"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n6">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="85.0" width="93.75" x="290.0" y="189.298828125"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="23.067916870117188" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="86.34767150878906" x="3.7011642456054688" xml:space="preserve" y="30.966041564941406">Webserver 2<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="octagon"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n7">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="112.5" width="123.75" x="-47.5" y="175.548828125"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="23.067916870117188" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="53.3358154296875" x="35.20709228515625" xml:space="preserve" y="44.716041564941406">Metallb<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="octagon"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n8">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="153.75" width="148.75" x="-1048.8125" y="-1.1875"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="18" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="28.515846252441406" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="84.38749694824219" x="32.181251525878906" xml:space="preserve" y="62.6170768737793">pybuilder<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n9">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="160.0" width="148.75" x="-680.0625" y="266.25"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="18" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="28.515846252441406" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="51.15971374511719" x="48.795143127441406" xml:space="preserve" y="65.7420768737793">provs<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n10">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="160.0" width="148.75" x="-1048.8125" y="266.25"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="18" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="28.515846252441406" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="32.547821044921875" x="58.10108947753906" xml:space="preserve" y="65.7420768737793">c4k<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n11">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="153.75" width="148.75" x="-680.0625" y="-1.1875"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="18" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="28.515846252441406" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="86.96148681640625" x="30.894256591796875" xml:space="preserve" y="62.6170768737793">terraform<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n12">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="75.0" width="75.0" x="-643.1875" y="-173.138671875"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="25.792043685913086" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="37.8880615234375" x="18.55596923828125" xml:space="preserve" y="24.603978157043457">AWS<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n13">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="75.0" width="75.0" x="-331.90625" y="38.1875"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="25.792043685913086" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="63.69612121582031" x="5.651939392089844" xml:space="preserve" y="24.603978157043457">Hetzner<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n14">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="75.0" width="141.25" x="714.8125" y="-172.451171875"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="61.432403564453125" x="39.90879821777344" xml:space="preserve" y="27.327942848205566">local build<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="roundrectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n15">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="63.75" width="118.75" x="456.5" y="71.173828125"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="23.067916870117188" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="47.52583312988281" x="35.612083435058594" xml:space="preserve" y="20.341041564941406">Mount<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="111.3167724609375" x="4.0" xml:space="preserve" y="39.40588569641113">Holds website data
|
||||||
|
<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="0.5" nodeRatioX="-0.5" nodeRatioY="0.5" offsetX="4.0" offsetY="-4.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="roundrectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n16">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="63.75" width="118.75" x="456.5" y="199.923828125"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="23.067916870117188" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="47.52583312988281" x="35.612083435058594" xml:space="preserve" y="20.341041564941406">Mount<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="111.3167724609375" x="4.0" xml:space="preserve" y="39.40588569641113">Holds website data
|
||||||
|
<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="0.5" nodeRatioX="-0.5" nodeRatioY="0.5" offsetX="4.0" offsetY="-4.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="roundrectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n17">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="98.75" width="78.75" x="128.9375" y="311.173828125"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="23.067916870117188" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="15.255950927734375" x="31.747024536132812" xml:space="preserve" y="37.841041564941406">...<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="fatarrow2"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n18">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="85.0" width="93.75" x="290.0" y="318.048828125"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="23.067916870117188" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="15.255950927734375" x="39.24702453613281" xml:space="preserve" y="30.966041564941406">...<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="octagon"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n19">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="63.75" width="118.75" x="456.5" y="328.673828125"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="23.067916870117188" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="15.255950927734375" x="51.74702453613281" xml:space="preserve" y="20.341041564941406">...<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="111.3167724609375" x="4.0" xml:space="preserve" y="39.40588569641113">Holds website data
|
||||||
|
<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="0.5" nodeRatioX="-0.5" nodeRatioY="0.5" offsetX="4.0" offsetY="-4.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="roundrectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n20">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="74.375" width="255.5" x="657.6875" y="65.861328125"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="23.067916870117188" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="250.9450225830078" x="2.2774887084960938" xml:space="preserve" y="25.653541564941406">Folder in /var/www/fqdn-folder-name<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="roundrectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n21">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="74.375" width="255.5" x="657.6875" y="194.611328125"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="23.067916870117188" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="250.9450225830078" x="2.2774887084960938" xml:space="preserve" y="25.653541564941406">Folder in /var/www/fqdn-folder-name<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="roundrectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n22">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="74.375" width="255.5" x="657.6875" y="323.361328125"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="23.067916870117188" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="250.9450225830078" x="2.2774887084960938" xml:space="preserve" y="25.653541564941406">Folder in /var/www/fqdn-folder-name<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="roundrectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<edge id="e0" source="n7" target="n7">
|
||||||
|
<data key="d10">
|
||||||
|
<y:ArcEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
|
||||||
|
<y:Point x="14.375" y="231.798828125"/>
|
||||||
|
</y:Path>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:Arc height="0.0" ratio="1.0" type="fixedRatio"/>
|
||||||
|
</y:ArcEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e1" source="n7" target="n4">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e2" source="n7" target="n5">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e3" source="n4" target="n2">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e4" source="n8" target="n11">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="left" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="13" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="39.41203308105469" horizontalTextPosition="center" iconTextGap="4" modelName="free" modelPosition="anywhere" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="85.26309204101562" x="67.36845397949219" xml:space="preserve" y="10.293983459472656">out_conf.edn
|
||||||
|
out_auth.edn<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e5" source="n11" target="n9">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="left" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="13" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="39.41203308105469" horizontalTextPosition="center" iconTextGap="4" modelName="free" modelPosition="anywhere" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="40.27003479003906" x="8.364982604980469" xml:space="preserve" y="31.418983459472656">IP
|
||||||
|
FQDN<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e6" source="n11" target="n12">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
|
||||||
|
<y:Point x="-625.0275" y="-58.35633333333334"/>
|
||||||
|
</y:Path>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="left" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="13" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="21.706016540527344" horizontalTextPosition="center" iconTextGap="4" modelName="free" modelPosition="anywhere" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="65.841064453125" x="-76.92666845703047" xml:space="preserve" y="-69.5675916035971">DNS Entry<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e7" source="n11" target="n13">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
|
||||||
|
<y:Point x="-441.69499999999994" y="98.875"/>
|
||||||
|
</y:Path>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="left" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="13" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="39.41203308105469" horizontalTextPosition="center" iconTextGap="4" modelName="free" modelPosition="anywhere" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="68.63603210449219" x="65.34923394775524" xml:space="preserve" y="18.702248697916332">ssh keys
|
||||||
|
server size<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e8" source="n13" target="n1">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="left" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="13" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="57.11804962158203" horizontalTextPosition="center" iconTextGap="4" modelName="free" modelPosition="anywhere" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="108.4290771484375" x="11.446461425783014" xml:space="preserve" y="19.35144684855112">spin up server
|
||||||
|
of requested size
|
||||||
|
with ssh keys<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e9" source="n9" target="n1">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e10" source="n9" target="n1">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e11" source="n9" target="n1">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="left" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="13" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="39.41203308105469" horizontalTextPosition="center" iconTextGap="4" modelName="free" modelPosition="anywhere" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="95.46807861328125" x="124.88346069335978" xml:space="preserve" y="-5.053327657063903">k3s and
|
||||||
|
c4k application<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e12" source="n9" target="n10">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
|
||||||
|
<y:Point x="-787.3125" y="291.125"/>
|
||||||
|
</y:Path>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="left" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="13" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="39.41203308105469" horizontalTextPosition="center" iconTextGap="4" modelName="free" modelPosition="anywhere" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="85.26309204101562" x="-102.75654602050781" xml:space="preserve" y="-76.6949691772461">out_conf.edn
|
||||||
|
out_auth.edn<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e13" source="n10" target="n9">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
|
||||||
|
<y:Point x="-793.8125" y="404.125"/>
|
||||||
|
</y:Path>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="left" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="13" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="21.706016540527344" horizontalTextPosition="center" iconTextGap="4" modelName="free" modelPosition="anywhere" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="132.40110778808594" x="18.766946105956777" xml:space="preserve" y="44.647786814371784">application yaml files<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e14" source="n4" target="n3">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e15" source="n5" target="n6">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e16" source="n6" target="n2">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e17" source="n17" target="n18">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e18" source="n15" target="n3">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e19" source="n20" target="n15">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e20" source="n16" target="n6">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e21" source="n19" target="n18">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e22" source="n4" target="n2">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e23" source="n2" target="n1">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e24" source="n7" target="n17">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e25" source="n6" target="n2">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e26" source="n22" target="n19">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e27" source="n21" target="n16">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e28" source="n14" target="n20">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="left" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="free" modelPosition="anywhere" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="76.39651489257812" x="4.9553675537108575" xml:space="preserve" y="75.47775874328613">copy to
|
||||||
|
via scp/rsync<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e29" source="n13" target="n11">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
|
||||||
|
<y:Point x="-438.44499999999994" y="62.251666666666665"/>
|
||||||
|
</y:Path>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="left" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="13" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="39.41203308105469" horizontalTextPosition="center" iconTextGap="4" modelName="free" modelPosition="anywhere" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="30.31201171875" x="-116.9447558593746" xml:space="preserve" y="-49.27187929280607">IPv4
|
||||||
|
IPv6<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e30" source="n12" target="n11">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
|
||||||
|
<y:Point x="-588.3494999999999" y="-62.498333333333335"/>
|
||||||
|
</y:Path>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="left" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="13" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="21.706016540527344" horizontalTextPosition="center" iconTextGap="4" modelName="free" modelPosition="anywhere" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="54.99903869628906" x="13.953326354981414" xml:space="preserve" y="25.047580271402865">ssh keys<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
</graph>
|
||||||
|
<data key="d7">
|
||||||
|
<y:Resources/>
|
||||||
|
</data>
|
||||||
|
</graphml>
|
BIN
doc/architekturbild-c4k-website.jpg
Normal file
BIN
doc/architekturbild-c4k-website.jpg
Normal file
Binary file not shown.
After ![]() (image error) Size: 104 KiB |
BIN
doc/meissa-website-arch.png
Normal file
BIN
doc/meissa-website-arch.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 70 KiB |
BIN
doc/tryItOut.png
BIN
doc/tryItOut.png
Binary file not shown.
Before ![]() (image error) Size: 157 KiB After ![]() (image error) Size: 149 KiB ![]() ![]() |
|
@ -1,54 +0,0 @@
|
||||||
from os import environ
|
|
||||||
from datetime import datetime
|
|
||||||
from pybuilder.core import task, init
|
|
||||||
from ddadevops import *
|
|
||||||
|
|
||||||
name = "c4k-taiga"
|
|
||||||
MODULE = "backup"
|
|
||||||
PROJECT_ROOT_PATH = "../.."
|
|
||||||
version = "1.2.7-dev"
|
|
||||||
|
|
||||||
|
|
||||||
@init
|
|
||||||
def initialize(project):
|
|
||||||
image_tag = version
|
|
||||||
if "dev" in image_tag:
|
|
||||||
image_tag += datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
|
|
||||||
|
|
||||||
input = {
|
|
||||||
"name": name,
|
|
||||||
"module": MODULE,
|
|
||||||
"stage": "notused",
|
|
||||||
"project_root_path": PROJECT_ROOT_PATH,
|
|
||||||
"build_types": ["IMAGE"],
|
|
||||||
"mixin_types": [],
|
|
||||||
"image_naming": "NAME_AND_MODULE",
|
|
||||||
"image_tag": f"{image_tag}",
|
|
||||||
}
|
|
||||||
|
|
||||||
project.build_depends_on("ddadevops>=4.7.0")
|
|
||||||
|
|
||||||
build = DevopsImageBuild(project, input)
|
|
||||||
build.initialize_build_dir()
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
|
||||||
def image(project):
|
|
||||||
build = get_devops_build(project)
|
|
||||||
build.image()
|
|
||||||
|
|
||||||
@task
|
|
||||||
def drun(project):
|
|
||||||
build = get_devops_build(project)
|
|
||||||
build.drun()
|
|
||||||
|
|
||||||
@task
|
|
||||||
def test(project):
|
|
||||||
build = get_devops_build(project)
|
|
||||||
build.test()
|
|
||||||
|
|
||||||
@task
|
|
||||||
def publish(project):
|
|
||||||
build = get_devops_build(project)
|
|
||||||
build.dockerhub_login()
|
|
||||||
build.dockerhub_publish()
|
|
|
@ -1,5 +0,0 @@
|
||||||
FROM domaindrivenarchitecture/dda-backup:5.3.0
|
|
||||||
|
|
||||||
# Prepare Entrypoint Script
|
|
||||||
ADD resources /tmp
|
|
||||||
RUN /tmp/install.bb
|
|
|
@ -1,29 +0,0 @@
|
||||||
#!/usr/bin/env bb
|
|
||||||
(require
|
|
||||||
'[dda.backup.core :as bc]
|
|
||||||
'[dda.backup.config :as cfg]
|
|
||||||
'[dda.backup.restic :as rc]
|
|
||||||
'[dda.backup.postgresql :as pg]
|
|
||||||
'[dda.backup.backup :as bak])
|
|
||||||
|
|
||||||
(def config (cfg/read-config "/usr/local/bin/config.edn"))
|
|
||||||
|
|
||||||
|
|
||||||
(defn prepare!
|
|
||||||
[]
|
|
||||||
(bc/create-aws-credentials! (:aws-config config))
|
|
||||||
(pg/create-pg-pass! (:db-config config)))
|
|
||||||
|
|
||||||
(defn restic-repo-init!
|
|
||||||
[]
|
|
||||||
(rc/init! (:file-config config))
|
|
||||||
(rc/init! (:db-config config)))
|
|
||||||
|
|
||||||
(defn restic-backup!
|
|
||||||
[]
|
|
||||||
(bak/backup-file! (:file-config config))
|
|
||||||
(bak/backup-db! (:db-config config)))
|
|
||||||
|
|
||||||
(prepare!)
|
|
||||||
(restic-repo-init!)
|
|
||||||
(restic-backup!)
|
|
|
@ -1,4 +0,0 @@
|
||||||
{:deps {org.clojure/spec.alpha {:mvn/version "0.4.233"}
|
|
||||||
orchestra/orchestra {:mvn/version "2021.01.01-1"}
|
|
||||||
aero/aero {:mvn/version "1.1.6"}
|
|
||||||
org.domaindrivenarchitecture/dda-backup {:local/root "/usr/local/lib/dda-backup"}}}
|
|
|
@ -1,3 +0,0 @@
|
||||||
{:deps {org.clojure/spec.alpha {:mvn/version "0.4.233"}
|
|
||||||
orchestra/orchestra {:mvn/version "2021.01.01-1"}
|
|
||||||
org.domaindrivenarchitecture/dda-build {:mvn/version "0.2.0"}}}
|
|
|
@ -1,24 +0,0 @@
|
||||||
#!/usr/bin/env bb
|
|
||||||
(require
|
|
||||||
'[dda.backup.core :as bc]
|
|
||||||
'[dda.backup.config :as cfg]
|
|
||||||
'[dda.backup.restic :as rc])
|
|
||||||
|
|
||||||
(def config (cfg/read-config "/usr/local/bin/config.edn"))
|
|
||||||
|
|
||||||
(def file-pw-change-config (merge (:file-config config)
|
|
||||||
{:new-password-file (bc/env-or-file "RESTIC_NEW_PASSWORD_FILE")}))
|
|
||||||
(def db-pw-change-config (merge (:db-config config)
|
|
||||||
{:new-password-file (bc/env-or-file "RESTIC_NEW_PASSWORD_FILE")}))
|
|
||||||
|
|
||||||
(defn prepare!
|
|
||||||
[]
|
|
||||||
(bc/create-aws-credentials! (:aws-config config)))
|
|
||||||
|
|
||||||
(defn change-password!
|
|
||||||
[]
|
|
||||||
(rc/change-password! file-pw-change-config)
|
|
||||||
(rc/change-password! db-pw-change-config))
|
|
||||||
|
|
||||||
(prepare!)
|
|
||||||
(change-password!)
|
|
|
@ -1,24 +0,0 @@
|
||||||
{:restic-repo {:password-file #env-or-file "RESTIC_PASSWORD_FILE"
|
|
||||||
:restic-repository #env-or-file "RESTIC_REPOSITORY"}
|
|
||||||
|
|
||||||
:file-config #merge [#ref [:restic-repo]
|
|
||||||
{:backup-path "files"
|
|
||||||
:execution-directory "/media"
|
|
||||||
:files ["."]}]
|
|
||||||
|
|
||||||
:file-restore-config #merge [#ref [:restic-repo]
|
|
||||||
{:backup-path "files"
|
|
||||||
:restore-target-directory "/media/"
|
|
||||||
:clean-up-elements ["user"]}]
|
|
||||||
|
|
||||||
:db-config #merge [#ref [:restic-repo] {:backup-path "pg-database"
|
|
||||||
:pg-host #env-or-file "POSTGRES_SERVICE"
|
|
||||||
:pg-port #env-or-file "POSTGRES_PORT"
|
|
||||||
:pg-db #env-or-file "POSTGRES_DB"
|
|
||||||
:pg-user #env-or-file "POSTGRES_USER"
|
|
||||||
:pg-password #env-or-file "POSTGRES_PASSWORD"}]
|
|
||||||
|
|
||||||
:aws-config {:aws-access-key-id #env-or-file "AWS_ACCESS_KEY_ID"
|
|
||||||
:aws-secret-access-key #env-or-file "AWS_SECRET_ACCESS_KEY"}
|
|
||||||
|
|
||||||
:dry-run {:dry-run true :debug true}}
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/usr/bin/env bb
|
|
||||||
|
|
||||||
(println "initialized")
|
|
|
@ -1,18 +0,0 @@
|
||||||
#!/usr/bin/env bb
|
|
||||||
|
|
||||||
(require
|
|
||||||
'[dda.image.ubuntu :as ub]
|
|
||||||
'[dda.image.install :as in])
|
|
||||||
|
|
||||||
(ub/upgrade-system!)
|
|
||||||
(in/install! "bb-backup.edn" :target-name "bb.edn" :mod "0440")
|
|
||||||
(in/install! "config.edn" :mod "0440")
|
|
||||||
(in/install! "init.bb")
|
|
||||||
(in/install! "backup.bb")
|
|
||||||
(in/install! "restore.bb")
|
|
||||||
(in/install! "list-snapshots.bb")
|
|
||||||
(in/install! "change-password.bb")
|
|
||||||
(in/install! "restore.bb")
|
|
||||||
(in/install! "wait.bb")
|
|
||||||
|
|
||||||
(ub/cleanup-container!)
|
|
|
@ -1,20 +0,0 @@
|
||||||
#!/usr/bin/env bb
|
|
||||||
(require
|
|
||||||
'[dda.backup.core :as bc]
|
|
||||||
'[dda.backup.config :as cfg]
|
|
||||||
'[dda.backup.restic :as rc])
|
|
||||||
|
|
||||||
(def config (cfg/read-config "/usr/local/bin/config.edn"))
|
|
||||||
|
|
||||||
|
|
||||||
(defn prepare!
|
|
||||||
[]
|
|
||||||
(bc/create-aws-credentials! (:aws-config config)))
|
|
||||||
|
|
||||||
(defn list-snapshots!
|
|
||||||
[]
|
|
||||||
(rc/list-snapshots! (:file-config config))
|
|
||||||
(rc/list-snapshots! (:db-config config)))
|
|
||||||
|
|
||||||
(prepare!)
|
|
||||||
(list-snapshots!)
|
|
|
@ -1,24 +0,0 @@
|
||||||
#!/usr/bin/env bb
|
|
||||||
(require
|
|
||||||
'[babashka.tasks :as t]
|
|
||||||
'[dda.backup.core :as bc]
|
|
||||||
'[dda.backup.config :as cfg]
|
|
||||||
'[dda.backup.postgresql :as pg]
|
|
||||||
'[dda.backup.restore :as rs])
|
|
||||||
|
|
||||||
(def config (cfg/read-config "/usr/local/bin/config.edn"))
|
|
||||||
|
|
||||||
(defn prepare!
|
|
||||||
[]
|
|
||||||
(bc/create-aws-credentials! (:aws-config config))
|
|
||||||
(pg/create-pg-pass! (:db-config config)))
|
|
||||||
|
|
||||||
(defn restic-restore!
|
|
||||||
[]
|
|
||||||
(pg/drop-create-db! (:db-config config))
|
|
||||||
(rs/restore-db! (:db-config config))
|
|
||||||
(rs/restore-file! (:file-restore-config config))
|
|
||||||
(t/shell "chown -R 999:999 /media"))
|
|
||||||
|
|
||||||
(prepare!)
|
|
||||||
(restic-restore!)
|
|
|
@ -1,19 +0,0 @@
|
||||||
#!/usr/bin/env bb
|
|
||||||
(require
|
|
||||||
'[dda.backup.core :as bc]
|
|
||||||
'[dda.backup.config :as cfg]
|
|
||||||
'[dda.backup.postgresql :as pg])
|
|
||||||
|
|
||||||
(def config (cfg/read-config "/usr/local/bin/config.edn"))
|
|
||||||
|
|
||||||
(defn prepare!
|
|
||||||
[]
|
|
||||||
(bc/create-aws-credentials! (:aws-config config))
|
|
||||||
(pg/create-pg-pass! (:db-config config)))
|
|
||||||
|
|
||||||
(defn wait! []
|
|
||||||
(while true
|
|
||||||
(Thread/sleep 1000)))
|
|
||||||
|
|
||||||
(prepare!)
|
|
||||||
(wait!)
|
|
|
@ -1,4 +0,0 @@
|
||||||
FROM c4k-taiga-backup:latest
|
|
||||||
|
|
||||||
ADD resources /tmp/
|
|
||||||
RUN RESTIC_PASSWORD_FILE=/tmp/file_password RESTIC_NEW_PASSWORD_FILE=/tmp/new_file_password RESTIC_REPOSITORY=restic-repo POSTGRES_SERVICE=dummy POSTGRES_PORT=dummy POSTGRES_DB=dummy POSTGRES_USER=dummy POSTGRES_PASSWORD=dummy AWS_ACCESS_KEY_ID=dummy AWS_SECRET_ACCESS_KEY=dummy /tmp/test.bb
|
|
|
@ -1,4 +0,0 @@
|
||||||
{:deps {org.clojure/spec.alpha {:mvn/version "0.4.233"}
|
|
||||||
orchestra/orchestra {:mvn/version "2021.01.01-1"}
|
|
||||||
aero/aero {:mvn/version "1.1.6"}
|
|
||||||
org.domaindrivenarchitecture/dda-backup {:local/root "/usr/local/lib/dda-backup"}}}
|
|
|
@ -1 +0,0 @@
|
||||||
oldPassword
|
|
|
@ -1 +0,0 @@
|
||||||
newPassword
|
|
|
@ -1,59 +0,0 @@
|
||||||
#!/usr/bin/env bb
|
|
||||||
(require '[babashka.tasks :as tasks]
|
|
||||||
'[dda.backup.core :as bc]
|
|
||||||
'[dda.backup.config :as cfg]
|
|
||||||
'[dda.backup.restic :as rc]
|
|
||||||
'[dda.backup.postgresql :as pg]
|
|
||||||
'[dda.backup.backup :as bak]
|
|
||||||
'[dda.backup.restore :as rs])
|
|
||||||
|
|
||||||
(def config (cfg/read-config "/usr/local/bin/config.edn"))
|
|
||||||
|
|
||||||
(def file-pw-change-config (merge (:file-config config)
|
|
||||||
{:new-password-file (bc/env-or-file "RESTIC_NEW_PASSWORD_FILE")}))
|
|
||||||
|
|
||||||
(defn prepare!
|
|
||||||
[]
|
|
||||||
(tasks/shell "mkdir" "-p" "/var/backups/")
|
|
||||||
(spit "/var/backups/file" "I was here")
|
|
||||||
(tasks/shell "mkdir" "-p" "/var/restore"))
|
|
||||||
|
|
||||||
(defn restic-repo-init!
|
|
||||||
[]
|
|
||||||
(rc/init! (:file-config config))
|
|
||||||
(rc/init! (merge (:db-config config)
|
|
||||||
(:dry-run config))))
|
|
||||||
|
|
||||||
(defn restic-backup!
|
|
||||||
[]
|
|
||||||
(bak/backup-file! (:file-config config))
|
|
||||||
(bak/backup-db! (merge (:db-config config)
|
|
||||||
(:dry-run config))))
|
|
||||||
|
|
||||||
(defn list-snapshots!
|
|
||||||
[]
|
|
||||||
(rc/list-snapshots! (:file-config config))
|
|
||||||
(rc/list-snapshots! (merge (:db-config config)
|
|
||||||
(:dry-run config))))
|
|
||||||
|
|
||||||
|
|
||||||
(defn restic-restore!
|
|
||||||
[]
|
|
||||||
(pg/drop-create-db! (merge (:db-config config)
|
|
||||||
(:dry-run config)))
|
|
||||||
(rs/restore-db! (merge (:db-config config)
|
|
||||||
(:dry-run config)))
|
|
||||||
(rs/restore-file! (merge (:file-restore-config config)
|
|
||||||
(:dry-run config))))
|
|
||||||
|
|
||||||
(defn change-password!
|
|
||||||
[]
|
|
||||||
(println "change-password!")
|
|
||||||
(rc/change-password! file-pw-change-config))
|
|
||||||
|
|
||||||
(prepare!)
|
|
||||||
(restic-repo-init!)
|
|
||||||
(restic-backup!)
|
|
||||||
(list-snapshots!)
|
|
||||||
(restic-restore!)
|
|
||||||
(change-password!)
|
|
51
infrastructure/c4k-website-build/build.py
Normal file
51
infrastructure/c4k-website-build/build.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
from os import environ
|
||||||
|
from pybuilder.core import task, init
|
||||||
|
from ddadevops import *
|
||||||
|
import logging
|
||||||
|
|
||||||
|
name = 'c4k-website-build'
|
||||||
|
MODULE = 'docker'
|
||||||
|
PROJECT_ROOT_PATH = '../..'
|
||||||
|
|
||||||
|
class MyBuild(DevopsDockerBuild):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@init
|
||||||
|
def initialize(project):
|
||||||
|
project.build_depends_on('ddadevops>=0.12.4')
|
||||||
|
stage = 'prod'
|
||||||
|
dockerhub_user = environ.get('DOCKERHUB_USER')
|
||||||
|
if not dockerhub_user:
|
||||||
|
dockerhub_user = gopass_field_from_path('meissa/web/docker.com', 'login')
|
||||||
|
dockerhub_password = environ.get('DOCKERHUB_PASSWORD')
|
||||||
|
if not dockerhub_password:
|
||||||
|
dockerhub_password = gopass_password_from_path('meissa/web/docker.com')
|
||||||
|
tag = environ.get('CI_COMMIT_TAG')
|
||||||
|
if not tag:
|
||||||
|
tag = get_tag_from_latest_commit()
|
||||||
|
config = create_devops_docker_build_config(
|
||||||
|
stage, PROJECT_ROOT_PATH, MODULE, dockerhub_user, dockerhub_password, docker_publish_tag=tag)
|
||||||
|
build = MyBuild(project, config)
|
||||||
|
build.initialize_build_dir()
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def image(project):
|
||||||
|
build = get_devops_build(project)
|
||||||
|
build.image()
|
||||||
|
|
||||||
|
@task
|
||||||
|
def drun(project):
|
||||||
|
build = get_devops_build(project)
|
||||||
|
build.drun()
|
||||||
|
|
||||||
|
@task
|
||||||
|
def publish(project):
|
||||||
|
build = get_devops_build(project)
|
||||||
|
build.dockerhub_login()
|
||||||
|
build.dockerhub_publish()
|
||||||
|
|
||||||
|
@task
|
||||||
|
def test(project):
|
||||||
|
build = get_devops_build(project)
|
||||||
|
build.test()
|
11
infrastructure/c4k-website-build/image/Dockerfile
Normal file
11
infrastructure/c4k-website-build/image/Dockerfile
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
FROM clojure:lein
|
||||||
|
|
||||||
|
# Prepare Entrypoint Script
|
||||||
|
ADD resources /tmp
|
||||||
|
|
||||||
|
ENV BUILDDIR="/etc/website"
|
||||||
|
ENV SOURCEDIR="/etc/websitesource"
|
||||||
|
ENV WEBSITEROOT="/var/www/html/website/"
|
||||||
|
ENV HASHFILEDIR="/var/hashfile.d"
|
||||||
|
|
||||||
|
RUN /tmp/install.sh
|
36
infrastructure/c4k-website-build/image/resources/entrypoint.sh
Executable file
36
infrastructure/c4k-website-build/image/resources/entrypoint.sh
Executable file
|
@ -0,0 +1,36 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
mkdir $BUILDDIR
|
||||||
|
mkdir $SOURCEDIR
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
source /usr/local/bin/functions.sh
|
||||||
|
|
||||||
|
filename="website.zip"
|
||||||
|
hashfilename="hashfile"
|
||||||
|
|
||||||
|
echo "Check for new content"
|
||||||
|
touch $HASHFILEDIR/$hashfilename
|
||||||
|
currentHash=$( cat $HASHFILEDIR/$hashfilename )
|
||||||
|
newHash=$( get-hash-data )
|
||||||
|
|
||||||
|
if [[ $currentHash == $newHash ]]
|
||||||
|
then
|
||||||
|
echo "Nothing to do"
|
||||||
|
else
|
||||||
|
echo $currentHash > $HASHFILEDIR/$hashfilename
|
||||||
|
echo "Downloading website data"
|
||||||
|
get-website-data $filename
|
||||||
|
unzip-website-data $filename
|
||||||
|
echo "Executing Custom Scripts, if applicable"
|
||||||
|
execute-scripts-when-existing
|
||||||
|
echo "Building website"
|
||||||
|
build-website
|
||||||
|
echo "Moving files"
|
||||||
|
move-website-files-to-target
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
.git
|
||||||
|
.gitignore
|
|
@ -0,0 +1,45 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
function get-website-data() {
|
||||||
|
curl -H "Authorization: token $AUTHTOKEN" -o $SOURCEDIR/$1 $GITREPOURL
|
||||||
|
}
|
||||||
|
|
||||||
|
function get-hash-data() {
|
||||||
|
curl -s -H "Authorization: token $AUTHTOKEN" $GITCOMMITURL | jq '.sha'
|
||||||
|
}
|
||||||
|
|
||||||
|
function write-hash-data() {
|
||||||
|
echo $1 > $HASHFILEDIR/$2
|
||||||
|
}
|
||||||
|
|
||||||
|
function unzip-website-data() {
|
||||||
|
unzip $SOURCEDIR/$1 -d $BUILDDIR
|
||||||
|
}
|
||||||
|
|
||||||
|
function execute-scripts-when-existing() {
|
||||||
|
websitedir=$(ls $BUILDDIR)
|
||||||
|
if [[ -f $BUILDDIR/$websitedir/$SCRIPTFILE ]]
|
||||||
|
then
|
||||||
|
checksum="$(sha256sum $BUILDDIR/$websitedir/$SCRIPTFILE | grep -oE "^[a-z0-9]+")"
|
||||||
|
if [[ "$SHA256SUM" == "$checksum" ]]
|
||||||
|
then
|
||||||
|
chmod +x $BUILDDIR/$websitedir/$SCRIPTFILE
|
||||||
|
(cd $BUILDDIR; dir=$(ls); cd $dir; ./$SCRIPTFILE) #make sure paths defined in scriptfile are relative to $dir
|
||||||
|
else
|
||||||
|
printf "Provided SHA256 Sum does not match calculated sum. Exiting."
|
||||||
|
printf "Calculated SHA256: $checksum"
|
||||||
|
printf "Given SHA256: $SHA256SUM"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
printf "No script file provided."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function build-website() {
|
||||||
|
(cd $BUILDDIR; dir=$(ls); cd $dir; lein run;)
|
||||||
|
}
|
||||||
|
|
||||||
|
function move-website-files-to-target() {
|
||||||
|
(cd $BUILDDIR; dir=$(ls); cd $dir; rsync -ru --exclude-from "/etc/exclude.pattern" --delete resources/public/* $WEBSITEROOT;)
|
||||||
|
}
|
14
infrastructure/c4k-website-build/image/resources/install.sh
Executable file
14
infrastructure/c4k-website-build/image/resources/install.sh
Executable file
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
apt update > /dev/null;
|
||||||
|
|
||||||
|
apt install -y unzip rsync jq imagemagick
|
||||||
|
|
||||||
|
mkdir /etc/lein/
|
||||||
|
|
||||||
|
install -m 0700 /tmp/entrypoint.sh /
|
||||||
|
install -m 0700 /tmp/functions.sh /usr/local/bin/
|
||||||
|
install -m 0700 /tmp/exclude.pattern /etc/
|
||||||
|
install -m 0700 /tmp/project.clj /etc/lein/
|
||||||
|
cd /etc/lein;
|
||||||
|
lein deps;
|
11
infrastructure/c4k-website-build/image/resources/project.clj
Normal file
11
infrastructure/c4k-website-build/image/resources/project.clj
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
(defproject org.domaindrivenarchitecture/c4k-website-build "0.1.1-SNAPSHOT"
|
||||||
|
:description "website c4k-build 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.9.0"]
|
||||||
|
[dda/cryogen-bootstrap "0.1.5"]]
|
||||||
|
:plugins [[lein-ring "0.12.5"]]
|
||||||
|
:main cryogen.core
|
||||||
|
:ring {:init cryogen.server/init
|
||||||
|
:handler cryogen.server/handler})
|
11
infrastructure/c4k-website-build/test/Dockerfile
Normal file
11
infrastructure/c4k-website-build/test/Dockerfile
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
FROM c4k-website-build
|
||||||
|
|
||||||
|
RUN apt update
|
||||||
|
RUN apt -yqq --no-install-recommends --yes install curl default-jre-headless
|
||||||
|
|
||||||
|
RUN curl -L -o /tmp/serverspec.jar \
|
||||||
|
https://github.com/DomainDrivenArchitecture/dda-serverspec-crate/releases/download/2.0.0/dda-serverspec-standalone.jar
|
||||||
|
|
||||||
|
COPY serverspec.edn /tmp/serverspec.edn
|
||||||
|
|
||||||
|
RUN java -jar /tmp/serverspec.jar /tmp/serverspec.edn -v
|
4
infrastructure/c4k-website-build/test/serverspec.edn
Normal file
4
infrastructure/c4k-website-build/test/serverspec.edn
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{:file [{:path "/entrypoint.sh" :mod "700"}
|
||||||
|
{:path "/usr/local/bin/functions.sh" :mod "700"}
|
||||||
|
{:path "/etc/exclude.pattern" :mod "700"}
|
||||||
|
{:path "/etc/lein/project.clj" :mod "700"}]}
|
10
package.json
10
package.json
|
@ -2,7 +2,7 @@
|
||||||
"name": "c4k-taiga",
|
"name": "c4k-taiga",
|
||||||
"description": "Generate c4k yaml for a taiga project management deployment.",
|
"description": "Generate c4k yaml for a taiga project management deployment.",
|
||||||
"author": "meissa GmbH",
|
"author": "meissa GmbH",
|
||||||
"version": "1.2.7-SNAPSHOT",
|
"version": "0.0.1-SNAPSHOT",
|
||||||
"homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-taiga#readme",
|
"homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-taiga#readme",
|
||||||
"repository": "https://www.npmjs.com/package/c4k-taiga",
|
"repository": "https://www.npmjs.com/package/c4k-taiga",
|
||||||
"license": "APACHE2",
|
"license": "APACHE2",
|
||||||
|
@ -23,11 +23,11 @@
|
||||||
"url": "https://gitlab.com/domaindrivenarchitecture/c4k-taiga/issues"
|
"url": "https://gitlab.com/domaindrivenarchitecture/c4k-taiga/issues"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"js-base64": "^3.7.7",
|
"js-base64": "^3.7.2",
|
||||||
"js-yaml": "^4.1.0"
|
"js-yaml": "^4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"shadow-cljs": "^2.28.20",
|
"shadow-cljs": "^2.11.18",
|
||||||
"source-map-support": "^0.5.21"
|
"source-map-support": "^0.5.19"
|
||||||
}
|
}
|
||||||
}
|
}
|
29
project.clj
29
project.clj
|
@ -1,11 +1,11 @@
|
||||||
(defproject org.domaindrivenarchitecture/c4k-taiga "1.2.7-SNAPSHOT"
|
(defproject org.domaindrivenarchitecture/c4k-taiga "0.0.1-Snapshot"
|
||||||
:description "taiga c4k-installation package"
|
:description "taiga c4k-installation package"
|
||||||
:url "https://domaindrivenarchitecture.org"
|
:url "https://domaindrivenarchitecture.org"
|
||||||
:license {:name "Apache License, Version 2.0"
|
:license {:name "Apache License, Version 2.0"
|
||||||
:url "https://www.apache.org/licenses/LICENSE-2.0.html"}
|
:url "https://www.apache.org/licenses/LICENSE-2.0.html"}
|
||||||
:dependencies [[org.clojure/clojure "1.12.0"]
|
:dependencies [[org.clojure/clojure "1.11.1"]
|
||||||
[org.clojure/tools.reader "1.5.0"]
|
[org.clojure/tools.reader "1.3.7"]
|
||||||
[org.domaindrivenarchitecture/c4k-common-clj "9.0.1"]
|
[org.domaindrivenarchitecture/c4k-common-clj "6.1.2"]
|
||||||
[hickory "0.7.1" :exclusions [viebel/codox-klipse-theme]]]
|
[hickory "0.7.1" :exclusions [viebel/codox-klipse-theme]]]
|
||||||
:target-path "target/%s/"
|
:target-path "target/%s/"
|
||||||
:source-paths ["src/main/cljc"
|
:source-paths ["src/main/cljc"
|
||||||
|
@ -22,14 +22,25 @@
|
||||||
:uberjar {:aot :all
|
:uberjar {:aot :all
|
||||||
:main dda.c4k-taiga.uberjar
|
:main dda.c4k-taiga.uberjar
|
||||||
:uberjar-name "c4k-taiga-standalone.jar"
|
:uberjar-name "c4k-taiga-standalone.jar"
|
||||||
:dependencies [[org.clojure/tools.cli "1.1.230"]
|
:dependencies [[org.clojure/tools.cli "1.0.219"]
|
||||||
[ch.qos.logback/logback-classic "1.5.16"
|
[ch.qos.logback/logback-classic "1.4.14"
|
||||||
:exclusions [com.sun.mail/javax.mail]]
|
:exclusions [com.sun.mail/javax.mail]]
|
||||||
[org.slf4j/jcl-over-slf4j "2.0.16"]
|
[org.slf4j/jcl-over-slf4j "2.0.11"]]}}
|
||||||
[com.github.clj-easy/graal-build-time "1.0.5"]]}}
|
|
||||||
:release-tasks [["test"]
|
:release-tasks [["test"]
|
||||||
["vcs" "assert-committed"]
|
["vcs" "assert-committed"]
|
||||||
["change" "version" "leiningen.release/bump-version" "release"]
|
["change" "version" "leiningen.release/bump-version" "release"]
|
||||||
["vcs" "commit"]
|
["vcs" "commit"]
|
||||||
["vcs" "tag" "v" "--no-sign"]
|
["vcs" "tag" "v" "--no-sign"]
|
||||||
["change" "version" "leiningen.release/bump-version"]])
|
["change" "version" "leiningen.release/bump-version"]]
|
||||||
|
:aliases {"native" ["shell"
|
||||||
|
"native-image"
|
||||||
|
"--report-unsupported-elements-at-runtime"
|
||||||
|
"--initialize-at-build-time"
|
||||||
|
"-jar" "target/uberjar/c4k-taiga-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-taiga-standalone.jar /usr/local/bin/c4k-taiga-standalone.jar"]})
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"src/test/cljc"
|
"src/test/cljc"
|
||||||
"src/test/cljs"
|
"src/test/cljs"
|
||||||
"src/test/resources"]
|
"src/test/resources"]
|
||||||
:dependencies [[org.domaindrivenarchitecture/c4k-common-cljs "9.0.1"]
|
:dependencies [[org.domaindrivenarchitecture/c4k-common-cljs "6.0.1"]
|
||||||
[hickory "0.7.1"]]
|
[hickory "0.7.1"]]
|
||||||
:builds {:frontend {:target :browser
|
:builds {:frontend {:target :browser
|
||||||
:modules {:main {:init-fn dda.c4k-taiga.browser/init}}
|
:modules {:main {:init-fn dda.c4k-taiga.browser/init}}
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
[dda.c4k-common.uberjar :as uberjar]
|
[dda.c4k-common.uberjar :as uberjar]
|
||||||
[dda.c4k-taiga.core :as core]))
|
[dda.c4k-taiga.core :as core]))
|
||||||
|
|
||||||
|
|
||||||
(defn -main [& cmd-args]
|
(defn -main [& cmd-args]
|
||||||
(uberjar/main-cm
|
(uberjar/main-common
|
||||||
"c4k-taiga"
|
"c4k-taiga"
|
||||||
core/config?
|
core/config?
|
||||||
core/auth?
|
core/auth?
|
||||||
core/config-defaults
|
core/config-defaults
|
||||||
core/config-objects
|
core/k8s-objects
|
||||||
core/auth-objects
|
|
||||||
cmd-args))
|
cmd-args))
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
(ns dda.c4k-taiga.backup
|
|
||||||
(:require
|
|
||||||
[clojure.spec.alpha :as s]
|
|
||||||
#?(:clj [orchestra.core :refer [defn-spec]]
|
|
||||||
:cljs [orchestra.core :refer-macros [defn-spec]])
|
|
||||||
[dda.c4k-common.yaml :as yaml]
|
|
||||||
[dda.c4k-common.base64 :as b64]
|
|
||||||
[dda.c4k-common.common :as cm]
|
|
||||||
[dda.c4k-common.predicate :as p]
|
|
||||||
#?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]])))
|
|
||||||
|
|
||||||
(s/def ::aws-access-key-id p/bash-env-string?)
|
|
||||||
(s/def ::aws-secret-access-key p/bash-env-string?)
|
|
||||||
(s/def ::restic-password p/bash-env-string?)
|
|
||||||
(s/def ::restic-new-password p/bash-env-string?)
|
|
||||||
(s/def ::restic-repository p/bash-env-string?)
|
|
||||||
|
|
||||||
(s/def ::config (s/keys :req-un [::restic-repository]))
|
|
||||||
|
|
||||||
(s/def ::auth (s/keys :req-un [::restic-password ::aws-access-key-id ::aws-secret-access-key]
|
|
||||||
:opt-un [::restic-new-password]))
|
|
||||||
|
|
||||||
#?(:cljs
|
|
||||||
(defmethod yaml/load-resource :backup [resource-name]
|
|
||||||
(get (inline-resources "backup") resource-name)))
|
|
||||||
|
|
||||||
(defn-spec generate-config p/map-or-seq?
|
|
||||||
[my-conf ::config]
|
|
||||||
(let [{:keys [restic-repository]} my-conf]
|
|
||||||
(->
|
|
||||||
(yaml/load-as-edn "backup/config.yaml")
|
|
||||||
(cm/replace-key-value :restic-repository restic-repository))))
|
|
||||||
|
|
||||||
(defn-spec generate-cron p/map-or-seq?
|
|
||||||
[]
|
|
||||||
(yaml/load-as-edn "backup/cron.yaml"))
|
|
||||||
|
|
||||||
(defn-spec generate-backup-restore-deployment p/map-or-seq?
|
|
||||||
[my-conf ::config]
|
|
||||||
(yaml/load-as-edn "backup/backup-restore-deployment.yaml"))
|
|
||||||
|
|
||||||
(defn-spec generate-secret p/map-or-seq?
|
|
||||||
[auth ::auth]
|
|
||||||
(let [{:keys [aws-access-key-id aws-secret-access-key
|
|
||||||
restic-password restic-new-password]} auth]
|
|
||||||
(as-> (yaml/load-as-edn "backup/secret.yaml") res
|
|
||||||
(cm/replace-key-value res :aws-access-key-id (b64/encode aws-access-key-id))
|
|
||||||
(cm/replace-key-value res :aws-secret-access-key (b64/encode aws-secret-access-key))
|
|
||||||
(cm/replace-key-value res :restic-password (b64/encode restic-password))
|
|
||||||
(if (contains? auth :restic-new-password)
|
|
||||||
(assoc-in res [:data :restic-new-password] (b64/encode restic-new-password))
|
|
||||||
res))))
|
|
|
@ -8,104 +8,52 @@
|
||||||
[dda.c4k-common.predicate :as cp]
|
[dda.c4k-common.predicate :as cp]
|
||||||
[dda.c4k-common.monitoring :as mon]
|
[dda.c4k-common.monitoring :as mon]
|
||||||
[dda.c4k-taiga.taiga :as taiga]
|
[dda.c4k-taiga.taiga :as taiga]
|
||||||
[dda.c4k-taiga.backup :as backup]
|
[dda.c4k-common.postgres :as postgres]))
|
||||||
[dda.c4k-common.postgres :as postgres]
|
|
||||||
[dda.c4k-common.namespace :as ns]))
|
|
||||||
|
|
||||||
(def config-defaults {:namespace "taiga"
|
(def default-storage-class :local-path)
|
||||||
:issuer "staging"
|
|
||||||
:storage-class-name "local-path"
|
|
||||||
:pv-storage-size-gb "5"
|
|
||||||
:storage-media-size "5"
|
|
||||||
:storage-static-size "5"
|
|
||||||
:storage-async-rabbitmq-size "5"
|
|
||||||
:storage-events-rabbitmq-size "5"
|
|
||||||
:public-register-enabled "false"
|
|
||||||
:enable-telemetry "false"})
|
|
||||||
|
|
||||||
(def config? (s/merge
|
(def config? taiga/config?)
|
||||||
::backup/config
|
(def auth? taiga/auth?)
|
||||||
(s/keys :req-un [::taiga/fqdn]
|
|
||||||
:opt-un [::taiga/issuer
|
|
||||||
::taiga/storage-class-name
|
|
||||||
::taiga/storage-media-size
|
|
||||||
::taiga/storage-static-size
|
|
||||||
::taiga/storage-async-rabbitmq-size
|
|
||||||
::taiga/storage-events-rabbitmq-size
|
|
||||||
::taiga/public-register-enabled
|
|
||||||
::taiga/enable-telemetry
|
|
||||||
::postgres/pv-storage-size-gb
|
|
||||||
::mon/mon-cfg])))
|
|
||||||
|
|
||||||
(def auth? (s/merge
|
(def config-defaults taiga/config-defaults)
|
||||||
::backup/auth
|
|
||||||
(s/keys :req-un [::postgres/postgres-db-user
|
|
||||||
::postgres/postgres-db-password
|
|
||||||
::taiga/taiga-secret-key
|
|
||||||
::taiga/mailer-pw
|
|
||||||
::taiga/mailer-user
|
|
||||||
::taiga/django-superuser-email
|
|
||||||
::taiga/django-superuser-password
|
|
||||||
::taiga/django-superuser-username
|
|
||||||
::taiga/rabbitmq-erlang-cookie
|
|
||||||
::taiga/rabbitmq-pw
|
|
||||||
::taiga/rabbitmq-user
|
|
||||||
::mon/mon-auth])))
|
|
||||||
|
|
||||||
(defn-spec config-objects cp/map-or-seq?
|
(defn-spec k8s-objects cp/map-or-seq?
|
||||||
[config config?]
|
[config taiga/config?
|
||||||
(let [resolved-config (merge config-defaults config)]
|
auth taiga/auth?]
|
||||||
(cm/concat-vec
|
(cm/concat-vec
|
||||||
(map yaml/to-string
|
(map yaml/to-string
|
||||||
(filter
|
(filter
|
||||||
#(not (nil? %))
|
#(not (nil? %))
|
||||||
(cm/concat-vec
|
(cm/concat-vec
|
||||||
(ns/generate resolved-config)
|
[(postgres/generate-config {:postgres-size :8gb :db-name "taiga"})
|
||||||
(postgres/generate-config (merge resolved-config
|
(postgres/generate-secret auth)
|
||||||
{:postgres-size :8gb :db-name "taiga"
|
(postgres/generate-pvc {:pv-storage-size-gb 50
|
||||||
:pv-storage-size-gb 50}))
|
:pvc-storage-class-name default-storage-class})
|
||||||
[(taiga/generate-async-deployment)
|
(postgres/generate-deployment)
|
||||||
(taiga/generate-async-rabbitmq-deployment)
|
(postgres/generate-service)
|
||||||
(taiga/generate-async-rabbitmq-service)
|
(taiga/generate-async-deployment)
|
||||||
(taiga/generate-async-service)
|
(taiga/generate-async-rabbitmq-deployment)
|
||||||
(taiga/generate-back-deployment)
|
(taiga/generate-async-rabbitmq-service)
|
||||||
(taiga/generate-back-service)
|
(taiga/generate-async-service)
|
||||||
(taiga/generate-configmap resolved-config)
|
(taiga/generate-back-deployment)
|
||||||
(taiga/generate-pvc-taiga-media-data resolved-config)
|
(taiga/generate-back-service)
|
||||||
(taiga/generate-pvc-taiga-static-data resolved-config)
|
(taiga/generate-configmap config)
|
||||||
(taiga/generate-events-deployment)
|
(taiga/generate-pvc-taiga-media-data config)
|
||||||
(taiga/generate-events-rabbitmq-deployment)
|
(taiga/generate-pvc-taiga-static-data config)
|
||||||
(taiga/generate-events-rabbitmq-service)
|
(taiga/generate-events-deployment)
|
||||||
(taiga/generate-events-service)
|
(taiga/generate-events-rabbitmq-deployment)
|
||||||
(taiga/generate-front-deployment)
|
(taiga/generate-events-rabbitmq-service)
|
||||||
(taiga/generate-front-service)
|
(taiga/generate-events-service)
|
||||||
(taiga/generate-gateway-configmap)
|
(taiga/generate-front-deployment)
|
||||||
(taiga/generate-gateway-deployment)
|
(taiga/generate-front-service)
|
||||||
(taiga/generate-gateway-service)
|
(taiga/generate-gateway-configmap)
|
||||||
(taiga/generate-protected-deployment)
|
(taiga/generate-gateway-deployment)
|
||||||
(taiga/generate-protected-service)
|
(taiga/generate-gateway-service)
|
||||||
(taiga/generate-rabbitmq-pvc-async resolved-config)
|
(taiga/generate-protected-deployment)
|
||||||
(taiga/generate-rabbitmq-pvc-events resolved-config)]
|
(taiga/generate-protected-service)
|
||||||
(taiga/generate-ingress-and-cert resolved-config)
|
(taiga/generate-rabbitmq-pvc-async config)
|
||||||
(when (contains? resolved-config :restic-repository)
|
(taiga/generate-rabbitmq-pvc-events config)
|
||||||
[(backup/generate-config resolved-config)
|
(taiga/generate-secret auth)]
|
||||||
(backup/generate-cron)
|
(taiga/generate-ingress-and-cert config)
|
||||||
(backup/generate-backup-restore-deployment resolved-config)])
|
(when (:contains? config :mon-cfg)
|
||||||
(when (:contains? resolved-config :mon-cfg)
|
(mon/generate (:mon-cfg config) (:mon-auth auth))))))))
|
||||||
(mon/generate-config))))))))
|
|
||||||
|
|
||||||
(defn-spec auth-objects cp/map-or-seq?
|
|
||||||
[config config?
|
|
||||||
auth auth?]
|
|
||||||
(let [resolved-config (merge config-defaults config)]
|
|
||||||
(cm/concat-vec
|
|
||||||
(map yaml/to-string
|
|
||||||
(filter
|
|
||||||
#(not (nil? %))
|
|
||||||
(cm/concat-vec
|
|
||||||
(postgres/generate-auth resolved-config auth)
|
|
||||||
[(taiga/generate-secret auth)]
|
|
||||||
(when (contains? resolved-config :restic-repository)
|
|
||||||
[(backup/generate-secret auth)])
|
|
||||||
(when (:contains? resolved-config :mon-cfg)
|
|
||||||
(mon/generate-auth (:mon-cfg resolved-config) (:mon-auth auth)))))))))
|
|
||||||
|
|
|
@ -1,16 +1,34 @@
|
||||||
(ns dda.c4k-taiga.taiga
|
(ns dda.c4k-taiga.taiga
|
||||||
(:require
|
(:require
|
||||||
[clojure.spec.alpha :as s]
|
[clojure.spec.alpha :as s]
|
||||||
|
#?(:cljs [shadow.resource :as rc])
|
||||||
#?(:clj [orchestra.core :refer [defn-spec]]
|
#?(:clj [orchestra.core :refer [defn-spec]]
|
||||||
:cljs [orchestra.core :refer-macros [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.yaml :as yaml]
|
||||||
[dda.c4k-common.ingress :as ing]
|
|
||||||
[dda.c4k-common.base64 :as b64]
|
|
||||||
[dda.c4k-common.predicate :as p]
|
|
||||||
[dda.c4k-common.common :as cm]
|
[dda.c4k-common.common :as cm]
|
||||||
#?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]])))
|
[dda.c4k-common.base64 :as b64]
|
||||||
|
[dda.c4k-common.predicate :as cp]
|
||||||
|
[dda.c4k-common.monitoring :as mon]
|
||||||
|
[dda.c4k-common.postgres :as postgres]
|
||||||
|
[dda.c4k-common.ingress :as ing]
|
||||||
|
[clojure.string :as str]))
|
||||||
|
|
||||||
(s/def ::taiga-secret-key p/bash-env-string?)
|
|
||||||
|
(def config-defaults {:issuer "staging"
|
||||||
|
:storage-class-name "local-path"
|
||||||
|
:pv-storage-size-gb "5" ;; ToDo: check sensible defaults
|
||||||
|
:storage-media-size "5"
|
||||||
|
:storage-static-size "5"
|
||||||
|
:storage-async-rabbitmq-size "5"
|
||||||
|
:storage-events-rabbitmq-size "5"
|
||||||
|
:public-register-enabled "false"
|
||||||
|
:enable-telemetry "false"})
|
||||||
|
|
||||||
|
(s/def ::mon-cfg ::mon/mon-cfg)
|
||||||
|
(s/def ::mon-auth ::mon/mon-auth)
|
||||||
|
(s/def ::taiga-secret-key cp/bash-env-string?)
|
||||||
(s/def ::mailer-user string?)
|
(s/def ::mailer-user string?)
|
||||||
(s/def ::mailer-pw string?)
|
(s/def ::mailer-pw string?)
|
||||||
(s/def ::django-superuser-username string?)
|
(s/def ::django-superuser-username string?)
|
||||||
|
@ -20,44 +38,71 @@
|
||||||
(s/def ::rabbitmq-pw string?)
|
(s/def ::rabbitmq-pw string?)
|
||||||
(s/def ::rabbitmq-erlang-cookie string?)
|
(s/def ::rabbitmq-erlang-cookie string?)
|
||||||
|
|
||||||
(s/def ::issuer p/letsencrypt-issuer?)
|
(s/def ::issuer cp/letsencrypt-issuer?)
|
||||||
(s/def ::fqdn p/fqdn-string?)
|
(s/def ::fqdn cp/fqdn-string?)
|
||||||
(s/def ::public-register-enabled string?)
|
(s/def ::public-register-enabled string?) ;; ToDo maybe check for boolean string
|
||||||
(s/def ::enable-telemetry string?)
|
(s/def ::enable-telemetry string?)
|
||||||
(s/def ::storage-class-name string?)
|
(s/def ::storage-class-name string?)
|
||||||
(s/def ::storage-media-size pos?)
|
(s/def ::storage-media-size int?)
|
||||||
(s/def ::storage-static-size pos?)
|
(s/def ::storage-static-size int?)
|
||||||
(s/def ::storage-async-rabbitmq-size pos?)
|
(s/def ::storage-async-rabbitmq-size int?)
|
||||||
(s/def ::storage-events-rabbitmq-size pos?)
|
(s/def ::storage-events-rabbitmq-size int?)
|
||||||
|
|
||||||
(s/def ::auth (s/keys :req-un [::taiga-secret-key
|
(def auth? (s/keys :req-un [::postgres/postgres-db-user
|
||||||
::mailer-pw
|
::postgres/postgres-db-password
|
||||||
::mailer-user
|
::taiga-secret-key
|
||||||
::django-superuser-email
|
::mailer-pw
|
||||||
::django-superuser-password
|
::mailer-user
|
||||||
::django-superuser-username
|
::django-superuser-email
|
||||||
::rabbitmq-erlang-cookie
|
::django-superuser-password
|
||||||
::rabbitmq-pw
|
::django-superuser-username
|
||||||
::rabbitmq-user]
|
::rabbitmq-erlang-cookie
|
||||||
:opt-un [::mon-auth]))
|
::rabbitmq-pw
|
||||||
|
::rabbitmq-user]
|
||||||
|
:opt-un [::mon-auth]))
|
||||||
|
|
||||||
(s/def ::config (s/keys :req-un [::fqdn]
|
(def config? (s/keys :req-un [::fqdn]
|
||||||
:opt-un [::issuer
|
:opt-un [::issuer
|
||||||
::storage-class-name
|
::storage-class-name
|
||||||
::storage-media-size
|
::storage-media-size
|
||||||
::storage-static-size
|
::storage-static-size
|
||||||
::storage-async-rabbitmq-size
|
::storage-async-rabbitmq-size
|
||||||
::storage-events-rabbitmq-size
|
::storage-events-rabbitmq-size
|
||||||
::public-register-enabled
|
::pv-storage-size-gb
|
||||||
::enable-telemetry
|
::public-register-enabled
|
||||||
::mon-cfg]))
|
::enable-telemetry
|
||||||
|
::mon-cfg]))
|
||||||
|
|
||||||
#?(:cljs
|
#?(:cljs
|
||||||
(defmethod yaml/load-resource :taiga [resource-name]
|
(defmethod yaml/load-resource :taiga [resource-name]
|
||||||
(get (inline-resources "taiga") resource-name)))
|
(case resource-name
|
||||||
|
"taiga/events-rabbitmq-deployment.yaml" (rc/inline "taiga/events-rabbitmq-deployment.yaml")
|
||||||
|
"taiga/gateway-deployment.yaml" (rc/inline "taiga/gateway-deployment.yaml")
|
||||||
|
"taiga/protected-deployment.yaml" (rc/inline "taiga/protected-deployment.yaml")
|
||||||
|
"taiga/gateway-configmap.yaml" (rc/inline "taiga/gateway-configmap.yaml")
|
||||||
|
"taiga/configmap.yaml" (rc/inline "taiga/configmap.yaml")
|
||||||
|
"taiga/async-service.yaml" (rc/inline "taiga/async-service.yaml")
|
||||||
|
"taiga/events-deployment.yaml" (rc/inline "taiga/events-deployment.yaml")
|
||||||
|
"taiga/async-deployment.yaml" (rc/inline "taiga/async-deployment.yaml")
|
||||||
|
"taiga/back-deployment.yaml" (rc/inline "taiga/back-deployment.yaml")
|
||||||
|
"taiga/front-deployment.yaml" (rc/inline "taiga/front-deployment.yaml")
|
||||||
|
"taiga/front-service.yaml" (rc/inline "taiga/front-service.yaml")
|
||||||
|
"taiga/gateway-service.yaml" (rc/inline "taiga/gateway-service.yaml")
|
||||||
|
"taiga/pvc-taiga-media-data.yaml" (rc/inline "taiga/pvc-taiga-media-data.yaml")
|
||||||
|
"taiga/pvc-taiga-static-data.yaml" (rc/inline "taiga/pvc-taiga-static-data.yaml")
|
||||||
|
"taiga/async-rabbitmq-deployment.yaml" (rc/inline "taiga/async-rabbitmq-deployment.yaml")
|
||||||
|
"taiga/protected-service.yaml" (rc/inline "taiga/protected-service.yaml")
|
||||||
|
"taiga/secret.yaml" (rc/inline "taiga/secret.yaml")
|
||||||
|
"taiga/async-rabbitmq-service.yaml" (rc/inline "taiga/async-rabbitmq-service.yaml")
|
||||||
|
"taiga/events-service.yaml" (rc/inline "taiga/events-service.yaml")
|
||||||
|
"taiga/back-service.yaml" (rc/inline "taiga/back-service.yaml")
|
||||||
|
"taiga/events-rabbitmq-service.yaml" (rc/inline "taiga/events-rabbitmq-service.yaml")
|
||||||
|
"taiga/rabbitmq-pvc-async.yaml" (rc/inline "taiga/rabbitmq-pvc-async.yaml")
|
||||||
|
"taiga/rabbitmq-pvc-events.yaml" (rc/inline "taiga/rabbitmq-pvc-events.yaml")
|
||||||
|
(throw (js/Error. "Undefined Resource!")))))
|
||||||
|
|
||||||
(defn-spec generate-ingress-and-cert p/map-or-seq?
|
(defn-spec generate-ingress-and-cert cp/map-or-seq?
|
||||||
[config ::config]
|
[config config?]
|
||||||
(let [{:keys [fqdn]} config]
|
(let [{:keys [fqdn]} config]
|
||||||
(ing/generate-ingress-and-cert
|
(ing/generate-ingress-and-cert
|
||||||
(merge
|
(merge
|
||||||
|
@ -66,91 +111,91 @@
|
||||||
:fqdns [fqdn]}
|
:fqdns [fqdn]}
|
||||||
config))))
|
config))))
|
||||||
|
|
||||||
(defn-spec generate-async-deployment p/map-or-seq? []
|
(defn-spec generate-async-deployment cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/async-deployment.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/async-deployment.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-async-service p/map-or-seq? []
|
(defn-spec generate-async-service cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/async-service.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/async-service.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-async-rabbitmq-deployment p/map-or-seq? []
|
(defn-spec generate-async-rabbitmq-deployment cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/async-rabbitmq-deployment.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/async-rabbitmq-deployment.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-events-rabbitmq-service p/map-or-seq? []
|
(defn-spec generate-events-rabbitmq-service cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/events-rabbitmq-service.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/events-rabbitmq-service.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-async-rabbitmq-service p/map-or-seq? []
|
(defn-spec generate-async-rabbitmq-service cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/async-rabbitmq-service.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/async-rabbitmq-service.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-back-deployment p/map-or-seq? []
|
(defn-spec generate-back-deployment cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/back-deployment.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/back-deployment.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-back-service p/map-or-seq? []
|
(defn-spec generate-back-service cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/back-service.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/back-service.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-events-rabbitmq-deployment p/map-or-seq? []
|
(defn-spec generate-events-rabbitmq-deployment cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/events-rabbitmq-deployment.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/events-rabbitmq-deployment.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-events-deployment p/map-or-seq? []
|
(defn-spec generate-events-deployment cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/events-deployment.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/events-deployment.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-events-service p/map-or-seq? []
|
(defn-spec generate-events-service cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/events-service.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/events-service.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-front-deployment p/map-or-seq? []
|
(defn-spec generate-front-deployment cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/front-deployment.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/front-deployment.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-front-service p/map-or-seq? []
|
(defn-spec generate-front-service cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/front-service.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/front-service.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-gateway-configmap p/map-or-seq? []
|
(defn-spec generate-gateway-configmap cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/gateway-configmap.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/gateway-configmap.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-gateway-deployment p/map-or-seq? []
|
(defn-spec generate-gateway-deployment cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/gateway-deployment.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/gateway-deployment.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-gateway-service p/map-or-seq? []
|
(defn-spec generate-gateway-service cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/gateway-service.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/gateway-service.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-protected-deployment p/map-or-seq? []
|
(defn-spec generate-protected-deployment cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/protected-deployment.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/protected-deployment.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-protected-service p/map-or-seq? []
|
(defn-spec generate-protected-service cp/map-or-seq? []
|
||||||
(yaml/load-as-edn "taiga/protected-service.yaml"))
|
(yaml/from-string (yaml/load-resource "taiga/protected-service.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-configmap p/map-or-seq?
|
(defn-spec generate-configmap cp/map-or-seq?
|
||||||
[config ::config]
|
[config config?]
|
||||||
(let [{:keys [fqdn enable-telemetry public-register-enabled]} config]
|
(let [{:keys [fqdn enable-telemetry public-register-enabled]} (merge config-defaults config)]
|
||||||
(-> (yaml/load-as-edn "taiga/configmap.yaml")
|
(-> (yaml/load-as-edn "taiga/configmap.yaml")
|
||||||
(cm/replace-key-value :TAIGA_SITES_DOMAIN fqdn)
|
(cm/replace-key-value :TAIGA_SITES_DOMAIN fqdn)
|
||||||
(cm/replace-key-value :TAIGA_URL (str "https://" fqdn))
|
(cm/replace-key-value :TAIGA_URL (str "https://" fqdn))
|
||||||
(cm/replace-key-value :TAIGA_WEBSOCKETS_URL (str "wss://" fqdn))
|
(cm/replace-key-value :TAIGA_WEBSOCKETS_URL (str "wss://" fqdn))
|
||||||
(cm/replace-key-value :ENABLE_TELEMETRY enable-telemetry)
|
(cm/replace-key-value :ENABLE_TELEMETRY enable-telemetry)
|
||||||
(cm/replace-key-value :PUBLIC_REGISTER_ENABLED public-register-enabled))))
|
(cm/replace-key-value :PUBLIC_REGISTER_ENABLED public-register-enabled))))
|
||||||
|
|
||||||
(defn-spec generate-pvc-taiga-media-data p/map-or-seq?
|
(defn-spec generate-pvc-taiga-media-data cp/map-or-seq?
|
||||||
[config ::config]
|
[config config?]
|
||||||
(let [{:keys [storage-class-name storage-media-size]} config]
|
(let [{:keys [storage-class-name storage-media-size]} (merge config-defaults config)]
|
||||||
(->
|
(->
|
||||||
(yaml/load-as-edn "taiga/pvc-taiga-media-data.yaml")
|
(yaml/from-string (yaml/load-resource "taiga/pvc-taiga-media-data.yaml"))
|
||||||
(assoc-in [:spec :storageClassName] storage-class-name)
|
(assoc-in [:spec :storageClassName] storage-class-name)
|
||||||
(assoc-in [:spec :resources :requests :storage] (str storage-media-size "Gi")))))
|
(assoc-in [:spec :resources :requests :storage] (str storage-media-size "Gi")))))
|
||||||
|
|
||||||
(defn-spec generate-pvc-taiga-static-data p/map-or-seq?
|
(defn-spec generate-pvc-taiga-static-data cp/map-or-seq?
|
||||||
[config ::config]
|
[config config?]
|
||||||
(let [{:keys [storage-class-name storage-static-size]} config]
|
(let [{:keys [storage-class-name storage-static-size]} (merge config-defaults config)]
|
||||||
(->
|
(->
|
||||||
(yaml/load-as-edn "taiga/pvc-taiga-static-data.yaml")
|
(yaml/from-string (yaml/load-resource "taiga/pvc-taiga-static-data.yaml"))
|
||||||
(assoc-in [:spec :storageClassName] storage-class-name)
|
(assoc-in [:spec :storageClassName] storage-class-name)
|
||||||
(assoc-in [:spec :resources :requests :storage] (str storage-static-size "Gi")))))
|
(assoc-in [:spec :resources :requests :storage] (str storage-static-size "Gi")))))
|
||||||
|
|
||||||
(defn-spec generate-secret p/map-or-seq?
|
(defn-spec generate-secret cp/map-or-seq?
|
||||||
[auth ::auth]
|
[auth auth?]
|
||||||
(let [{:keys [taiga-secret-key
|
(let [{:keys [taiga-secret-key
|
||||||
mailer-user mailer-pw
|
mailer-user mailer-pw
|
||||||
rabbitmq-user rabbitmq-pw rabbitmq-erlang-cookie
|
rabbitmq-user rabbitmq-pw rabbitmq-erlang-cookie
|
||||||
django-superuser-username django-superuser-password django-superuser-email]} auth]
|
django-superuser-username django-superuser-password django-superuser-email]} auth]
|
||||||
(->
|
(->
|
||||||
(yaml/load-as-edn "taiga/secret.yaml")
|
(yaml/from-string (yaml/load-resource "taiga/secret.yaml"))
|
||||||
(cm/replace-key-value :TAIGA_SECRET_KEY (b64/encode taiga-secret-key))
|
(cm/replace-key-value :TAIGA_SECRET_KEY (b64/encode taiga-secret-key))
|
||||||
(cm/replace-key-value :EMAIL_HOST_USER (b64/encode mailer-user))
|
(cm/replace-key-value :EMAIL_HOST_USER (b64/encode mailer-user))
|
||||||
(cm/replace-key-value :EMAIL_HOST_PASSWORD (b64/encode mailer-pw))
|
(cm/replace-key-value :EMAIL_HOST_PASSWORD (b64/encode mailer-pw))
|
||||||
|
@ -161,19 +206,19 @@
|
||||||
(cm/replace-key-value :DJANGO_SUPERUSER_PASSWORD (b64/encode django-superuser-password))
|
(cm/replace-key-value :DJANGO_SUPERUSER_PASSWORD (b64/encode django-superuser-password))
|
||||||
(cm/replace-key-value :DJANGO_SUPERUSER_EMAIL (b64/encode django-superuser-email)))))
|
(cm/replace-key-value :DJANGO_SUPERUSER_EMAIL (b64/encode django-superuser-email)))))
|
||||||
|
|
||||||
(defn-spec generate-rabbitmq-pvc-async p/map-or-seq?
|
(defn-spec generate-rabbitmq-pvc-async cp/map-or-seq?
|
||||||
[config ::config]
|
[config config?]
|
||||||
(let [{:keys [storage-class-name storage-async-rabbitmq-size]} config]
|
(let [{:keys [storage-class-name storage-async-rabbitmq-size]} (merge config-defaults config)]
|
||||||
(->
|
(->
|
||||||
(yaml/load-as-edn "taiga/rabbitmq-pvc-async.yaml")
|
(yaml/from-string (yaml/load-resource "taiga/rabbitmq-pvc-async.yaml"))
|
||||||
(assoc-in [:spec :storageClassName] storage-class-name)
|
(assoc-in [:spec :storageClassName] storage-class-name)
|
||||||
(assoc-in [:spec :resources :requests :storage] (str storage-async-rabbitmq-size "Gi")))))
|
(assoc-in [:spec :resources :requests :storage] (str storage-async-rabbitmq-size "Gi")))))
|
||||||
|
|
||||||
(defn-spec generate-rabbitmq-pvc-events p/map-or-seq?
|
(defn-spec generate-rabbitmq-pvc-events cp/map-or-seq?
|
||||||
[config ::config]
|
[config config?]
|
||||||
(let [{:keys [storage-class-name storage-events-rabbitmq-size]} config]
|
(let [{:keys [storage-class-name storage-events-rabbitmq-size]} (merge config-defaults config)]
|
||||||
(->
|
(->
|
||||||
(yaml/load-as-edn "taiga/rabbitmq-pvc-events.yaml")
|
(yaml/from-string (yaml/load-resource "taiga/rabbitmq-pvc-events.yaml"))
|
||||||
(assoc-in [:spec :storageClassName] storage-class-name)
|
(assoc-in [:spec :storageClassName] storage-class-name)
|
||||||
(assoc-in [:spec :resources :requests :storage] (str storage-events-rabbitmq-size "Gi")))))
|
(assoc-in [:spec :resources :requests :storage] (str storage-events-rabbitmq-size "Gi")))))
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
(ns dda.c4k-taiga.browser
|
(ns dda.c4k-taiga.browser
|
||||||
(:require
|
(:require
|
||||||
|
[clojure.string :as st]
|
||||||
[clojure.tools.reader.edn :as edn]
|
[clojure.tools.reader.edn :as edn]
|
||||||
|
[dda.c4k-common.monitoring :as mon]
|
||||||
[dda.c4k-taiga.core :as core]
|
[dda.c4k-taiga.core :as core]
|
||||||
[dda.c4k-common.common :as cm]
|
[dda.c4k-taiga.taiga :as taiga]
|
||||||
[dda.c4k-common.browser :as br]))
|
[dda.c4k-common.common :as cm]
|
||||||
|
[dda.c4k-common.browser :as br]
|
||||||
|
))
|
||||||
|
|
||||||
(defn generate-content []
|
(defn generate-content []
|
||||||
(cm/concat-vec
|
(cm/concat-vec
|
||||||
|
@ -11,40 +15,51 @@
|
||||||
(br/generate-needs-validation) :content
|
(br/generate-needs-validation) :content
|
||||||
(cm/concat-vec
|
(cm/concat-vec
|
||||||
(br/generate-group
|
(br/generate-group
|
||||||
"config"
|
"domain"
|
||||||
(br/generate-text-area
|
(cm/concat-vec
|
||||||
"config" "Your config.edn:"
|
(br/generate-input-field "issuer" "(Optional) Your issuer prod/staging:" "staging")
|
||||||
"{:fqdn \"taiga.your.domain\"
|
(br/generate-input-field "mon-cluster-name" "(Optional) monitoring cluster name:" "taiga")
|
||||||
:issuer \"staging\"
|
(br/generate-input-field "mon-cluster-stage" "(Optional) monitoring cluster stage:" "test")
|
||||||
:restic-repository \"s3://yourbucket/your-repo\"
|
(br/generate-input-field "mon-cloud-url" "(Optional) grafana cloud url:" "https://prometheus-prod-01-eu-west-0.grafana.net/api/prom/push")))
|
||||||
:mon-cfg {:cluster-name \"taiga\"
|
|
||||||
:cluster-stage \"test\"
|
|
||||||
:grafana-cloud-url \"https://prometheus-prod-01-eu-west-0.grafana.net/api/prom/push\"}}"
|
|
||||||
"6"))
|
|
||||||
(br/generate-group
|
(br/generate-group
|
||||||
"auth"
|
"taiga-data"
|
||||||
(br/generate-text-area
|
(br/generate-text-area
|
||||||
"auth" "Your auth.edn:"
|
"taigas" "Contains fqdns, repo infos, an optional sha256sum-output for script execution for each taiga:"
|
||||||
"{:postgres-db-user \"taiga\"
|
"{ :taigas
|
||||||
:postgres-db-password \"db-password\"
|
[{:unique-name \"test.io\",
|
||||||
:mailer-user \"mail[at]example.com\"
|
:fqdns [\"test.de\" \"www.test.de\"],
|
||||||
:mailer-pw \"change-me\"
|
:gitea-host \"githost.de\",
|
||||||
:django-superuser-username \"admin\"
|
:gitea-repo \"repo\",
|
||||||
:django-superuser-password \"change-me\"
|
:branchname \"main\",
|
||||||
:django-superuser-email \"mail[at]example.com\"
|
:sha256sum-output \"123456789ab123cd345de script-file-name.sh\"}
|
||||||
:rabbitmq-user \"user\"
|
{:unique-name \"example.io \",
|
||||||
:rabbitmq-pw \"change-me\"
|
:fqdns [\"example.org\" \"www.example.org\"],
|
||||||
:rabbitmq-erlang-cookie \"change-me\"
|
:gitea-host \"githost.org\",
|
||||||
:taiga-secret-key \"change-me\"
|
:gitea-repo \"repo\",
|
||||||
:aws-access-key-id \"aws-id\"
|
:branchname \"main\",
|
||||||
:aws-secret-access-key \"aws-secret\"
|
:build-cpu-request \"1500m\",
|
||||||
:restic-password \"restic-password\"
|
:build-cpu-limit \"3000m\",
|
||||||
:mon-auth {:grafana-cloud-user \"your-user-id\"
|
:build-memory-request \"512Mi\",
|
||||||
:grafana-cloud-password \"your-cloud-password\"}}"
|
:build-memory-limit \"1024Mi\"}] }"
|
||||||
"16"))
|
"16"))
|
||||||
|
(br/generate-group
|
||||||
|
"credentials"
|
||||||
|
(br/generate-text-area
|
||||||
|
"auth" "Your authentication data for each taiga or git repo:"
|
||||||
|
"{:mon-auth
|
||||||
|
{:grafana-cloud-user \"your-user-id\"
|
||||||
|
:grafana-cloud-password \"your-cloud-password\"}
|
||||||
|
:auth
|
||||||
|
[{:unique-name \"test.io\",
|
||||||
|
:username \"someuser\",
|
||||||
|
:authtoken \"abedjgbasdodj\"}
|
||||||
|
{:unique-name \"example.io\",
|
||||||
|
:username \"someuser\",
|
||||||
|
:authtoken \"abedjgbasdodj\"}]}"
|
||||||
|
"7"))
|
||||||
[(br/generate-br)]
|
[(br/generate-br)]
|
||||||
(br/generate-button "generate-button" "Generate c4k yaml")))]
|
(br/generate-button "generate-button" "Generate c4k yaml")))]
|
||||||
(br/generate-output "c4k-taiga-output" "Your c4k deployment.yaml:" "25")))
|
(br/generate-output "c4k-taiga-output" "Your c4k deployment.yaml:" "15")))
|
||||||
|
|
||||||
(defn generate-content-div
|
(defn generate-content-div
|
||||||
[]
|
[]
|
||||||
|
@ -53,9 +68,28 @@
|
||||||
:content
|
:content
|
||||||
(generate-content)})
|
(generate-content)})
|
||||||
|
|
||||||
|
(defn config-from-document []
|
||||||
|
(let [issuer (br/get-content-from-element "issuer" :optional true)
|
||||||
|
taigas (br/get-content-from-element "taigas" :deserializer edn/read-string)
|
||||||
|
mon-cluster-name (br/get-content-from-element "mon-cluster-name" :optional true)
|
||||||
|
mon-cluster-stage (br/get-content-from-element "mon-cluster-stage" :optional true)
|
||||||
|
mon-cloud-url (br/get-content-from-element "mon-cloud-url" :optional true)]
|
||||||
|
(merge
|
||||||
|
{:taigas taigas}
|
||||||
|
(when (not (st/blank? issuer))
|
||||||
|
{:issuer issuer})
|
||||||
|
(when (some? mon-cluster-name)
|
||||||
|
{:mon-cfg {:cluster-name mon-cluster-name
|
||||||
|
:cluster-stage (keyword mon-cluster-stage)
|
||||||
|
:grafana-cloud-url mon-cloud-url}}))))
|
||||||
|
|
||||||
(defn validate-all! []
|
(defn validate-all! []
|
||||||
(br/validate! "config" core/config? :deserializer edn/read-string)
|
(br/validate! "taigas" taiga/taigas? :deserializer edn/read-string)
|
||||||
(br/validate! "auth" core/auth? :deserializer edn/read-string)
|
(br/validate! "issuer" ::taiga/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" taiga/auth? :deserializer edn/read-string)
|
||||||
(br/set-form-validated!))
|
(br/set-form-validated!))
|
||||||
|
|
||||||
(defn add-validate-listener [name]
|
(defn add-validate-listener [name]
|
||||||
|
@ -68,14 +102,15 @@
|
||||||
(.getElementById "generate-button")
|
(.getElementById "generate-button")
|
||||||
(.addEventListener "click"
|
(.addEventListener "click"
|
||||||
#(do (validate-all!)
|
#(do (validate-all!)
|
||||||
(-> (cm/generate-cm
|
(-> (cm/generate-common
|
||||||
(br/get-content-from-element "config" :deserializer edn/read-string)
|
(config-from-document)
|
||||||
(br/get-content-from-element "auth" :deserializer edn/read-string)
|
(br/get-content-from-element "auth" :deserializer edn/read-string)
|
||||||
core/config-defaults
|
core/config-defaults
|
||||||
core/config-objects
|
core/k8s-objects)
|
||||||
core/auth-objects
|
|
||||||
false
|
|
||||||
false)
|
|
||||||
(br/set-output!)))))
|
(br/set-output!)))))
|
||||||
(add-validate-listener "config")
|
(add-validate-listener "taigas")
|
||||||
|
(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"))
|
(add-validate-listener "auth"))
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: backup-restore
|
|
||||||
namespace: taiga
|
|
||||||
spec:
|
|
||||||
replicas: 0
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: backup-restore
|
|
||||||
strategy:
|
|
||||||
type: Recreate
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: backup-restore
|
|
||||||
app.kubernetes.io/name: backup-restore
|
|
||||||
app.kubernetes.io/part-of: c4k-taiga
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- image: domaindrivenarchitecture/c4k-taiga-backup
|
|
||||||
name: backup-app
|
|
||||||
imagePullPolicy: IfNotPresent
|
|
||||||
command: ["wait.bb"]
|
|
||||||
env:
|
|
||||||
- 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"
|
|
||||||
- name: POSTGRES_SERVICE
|
|
||||||
value: "postgresql-service"
|
|
||||||
- name: POSTGRES_PORT
|
|
||||||
value: "5432"
|
|
||||||
- name: AWS_DEFAULT_REGION
|
|
||||||
value: eu-central-1
|
|
||||||
- name: AWS_ACCESS_KEY_ID_FILE
|
|
||||||
value: /var/run/secrets/backup-secrets/aws-access-key-id
|
|
||||||
- name: AWS_SECRET_ACCESS_KEY_FILE
|
|
||||||
value: /var/run/secrets/backup-secrets/aws-secret-access-key
|
|
||||||
- name: RESTIC_REPOSITORY
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: backup-config
|
|
||||||
key: restic-repository
|
|
||||||
- name: RESTIC_PASSWORD_FILE
|
|
||||||
value: /var/run/secrets/backup-secrets/restic-password
|
|
||||||
- name: RESTIC_NEW_PASSWORD_FILE
|
|
||||||
value: /var/run/secrets/backup-secrets/restic-new-password
|
|
||||||
volumeMounts:
|
|
||||||
- name: taiga-media
|
|
||||||
mountPath: /media
|
|
||||||
readOnly: false
|
|
||||||
- name: backup-secret-volume
|
|
||||||
mountPath: /var/run/secrets/backup-secrets
|
|
||||||
readOnly: true
|
|
||||||
volumes:
|
|
||||||
- name: taiga-media
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: taiga-media-data
|
|
||||||
- name: backup-secret-volume
|
|
||||||
secret:
|
|
||||||
secretName: backup-secret
|
|
|
@ -1,10 +0,0 @@
|
||||||
apiVersion: v1
|
|
||||||
kind: ConfigMap
|
|
||||||
metadata:
|
|
||||||
name: backup-config
|
|
||||||
namespace: taiga
|
|
||||||
labels:
|
|
||||||
app.kubernetes.io/name: backup
|
|
||||||
app.kubernetes.io/part-of: c4k-taiga
|
|
||||||
data:
|
|
||||||
restic-repository: restic-repository
|
|
|
@ -1,70 +0,0 @@
|
||||||
apiVersion: batch/v1
|
|
||||||
kind: CronJob
|
|
||||||
metadata:
|
|
||||||
name: taiga-backup
|
|
||||||
namespace: taiga
|
|
||||||
labels:
|
|
||||||
app.kubernetes.part-of: c4k-taiga
|
|
||||||
spec:
|
|
||||||
schedule: "10 23 * * *"
|
|
||||||
successfulJobsHistoryLimit: 1
|
|
||||||
failedJobsHistoryLimit: 1
|
|
||||||
jobTemplate:
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: backup-app
|
|
||||||
image: domaindrivenarchitecture/c4k-taiga-backup
|
|
||||||
imagePullPolicy: IfNotPresent
|
|
||||||
command: ["backup.bb"]
|
|
||||||
env:
|
|
||||||
- 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"
|
|
||||||
- name: POSTGRES_SERVICE
|
|
||||||
value: "postgresql-service"
|
|
||||||
- name: POSTGRES_PORT
|
|
||||||
value: "5432"
|
|
||||||
- name: AWS_DEFAULT_REGION
|
|
||||||
value: eu-central-1
|
|
||||||
- name: AWS_ACCESS_KEY_ID_FILE
|
|
||||||
value: /var/run/secrets/backup-secrets/aws-access-key-id
|
|
||||||
- name: AWS_SECRET_ACCESS_KEY_FILE
|
|
||||||
value: /var/run/secrets/backup-secrets/aws-secret-access-key
|
|
||||||
- name: RESTIC_REPOSITORY
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: backup-config
|
|
||||||
key: restic-repository
|
|
||||||
- name: RESTIC_PASSWORD_FILE
|
|
||||||
value: /var/run/secrets/backup-secrets/restic-password
|
|
||||||
volumeMounts:
|
|
||||||
- name: taiga-media
|
|
||||||
mountPath: /media
|
|
||||||
readOnly: true
|
|
||||||
- name: backup-secret-volume
|
|
||||||
mountPath: /var/run/secrets/backup-secrets
|
|
||||||
readOnly: true
|
|
||||||
volumes:
|
|
||||||
- name: taiga-media
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: taiga-media-data
|
|
||||||
- name: backup-secret-volume
|
|
||||||
secret:
|
|
||||||
secretName: backup-secret
|
|
||||||
restartPolicy: OnFailure
|
|
|
@ -1,10 +0,0 @@
|
||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
|
||||||
metadata:
|
|
||||||
name: backup-secret
|
|
||||||
namespace: taiga
|
|
||||||
type: Opaque
|
|
||||||
data:
|
|
||||||
aws-access-key-id: aws-access-key-id
|
|
||||||
aws-secret-access-key: aws-secret-access-key
|
|
||||||
restic-password: restic-password
|
|
|
@ -2,7 +2,6 @@ apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-async-deployment
|
name: taiga-async-deployment
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: c4k-taiga
|
||||||
app.kubernetes.io/component: taiga-async
|
app.kubernetes.io/component: taiga-async
|
||||||
|
|
|
@ -2,7 +2,6 @@ apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-async-rabbitmq-deployment
|
name: taiga-async-rabbitmq-deployment
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: c4k-taiga
|
||||||
app.kubernetes.io/component: taiga-async-rabbitmq
|
app.kubernetes.io/component: taiga-async-rabbitmq
|
||||||
|
@ -48,6 +47,7 @@ spec:
|
||||||
configMapKeyRef:
|
configMapKeyRef:
|
||||||
name: taiga-configmap
|
name: taiga-configmap
|
||||||
key: RABBITMQ_DEFAULT_VHOST
|
key: RABBITMQ_DEFAULT_VHOST
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
- name: taiga-async-rabbitmq-data
|
- name: taiga-async-rabbitmq-data
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
|
|
|
@ -2,10 +2,10 @@ kind: Service
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-async-rabbitmq
|
name: taiga-async-rabbitmq
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: c4k-taiga
|
||||||
app.kubernetes.io/component: taiga-async-rabbitmq
|
app.kubernetes.io/component: taiga-async-rabbitmq
|
||||||
|
namespace: default
|
||||||
spec:
|
spec:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
selector:
|
selector:
|
||||||
|
|
|
@ -2,10 +2,10 @@ kind: Service
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-async
|
name: taiga-async
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: c4k-taiga
|
||||||
app.kubernetes.io/component: taiga-async
|
app.kubernetes.io/component: taiga-async
|
||||||
|
namespace: default
|
||||||
spec:
|
spec:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
selector:
|
selector:
|
||||||
|
|
|
@ -2,7 +2,6 @@ apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-back-deployment
|
name: taiga-back-deployment
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: c4k-taiga
|
||||||
app.kubernetes.io/component: taiga-back
|
app.kubernetes.io/component: taiga-back
|
||||||
|
@ -21,7 +20,7 @@ spec:
|
||||||
image: taigaio/taiga-back:latest
|
image: taigaio/taiga-back:latest
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command: ["/bin/bash"]
|
command: ["/bin/bash"]
|
||||||
args: ["-c", "source /opt/venv/bin/activate && CELERY_ENABLE=true python manage.py migrate && sleep 15"]
|
args: ["-c", "source /opt/venv/bin/activate && CELERY_ENABLE=true python manage.py migrate && sleep 15 && python manage.py createsuperuser --noinput"]
|
||||||
ports:
|
ports:
|
||||||
- name: http
|
- name: http
|
||||||
containerPort: 8000
|
containerPort: 8000
|
||||||
|
|
|
@ -2,10 +2,10 @@ kind: Service
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-back
|
name: taiga-back
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: c4k-taiga
|
||||||
app.kubernetes.io/component: taiga-back
|
app.kubernetes.io/component: taiga-back
|
||||||
|
namespace: default
|
||||||
spec:
|
spec:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
selector:
|
selector:
|
||||||
|
|
|
@ -2,9 +2,7 @@ apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-configmap
|
name: taiga-configmap
|
||||||
namespace: taiga
|
namespace: default
|
||||||
labels:
|
|
||||||
app.kubernetes.part-of: c4k-taiga
|
|
||||||
data:
|
data:
|
||||||
# These environment variables will be used by taiga-back and taiga-async.
|
# These environment variables will be used by taiga-back and taiga-async.
|
||||||
# Database settings handled in deployment
|
# Database settings handled in deployment
|
||||||
|
|
|
@ -2,7 +2,6 @@ apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-events-deployment
|
name: taiga-events-deployment
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: c4k-taiga
|
||||||
app.kubernetes.io/component: taiga-events
|
app.kubernetes.io/component: taiga-events
|
||||||
|
|
|
@ -2,7 +2,6 @@ apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-events-rabbitmq-deployment
|
name: taiga-events-rabbitmq-deployment
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: c4k-taiga
|
||||||
app.kubernetes.io/component: taiga-events-rabbitmq
|
app.kubernetes.io/component: taiga-events-rabbitmq
|
||||||
|
@ -48,6 +47,7 @@ spec:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: taiga-secret
|
name: taiga-secret
|
||||||
key: RABBITMQ_PASS
|
key: RABBITMQ_PASS
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
- name: taiga-events-rabbitmq-data
|
- name: taiga-events-rabbitmq-data
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
|
|
|
@ -2,10 +2,10 @@ kind: Service
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-events-rabbitmq
|
name: taiga-events-rabbitmq
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: c4k-taiga
|
||||||
app.kubernetes.io/component: taiga-events-rabbitmq
|
app.kubernetes.io/component: taiga-events-rabbitmq
|
||||||
|
namespace: default
|
||||||
spec:
|
spec:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
selector:
|
selector:
|
||||||
|
|
|
@ -2,10 +2,10 @@ kind: Service
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-events
|
name: taiga-events
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: c4k-taiga
|
||||||
app.kubernetes.io/component: taiga-events
|
app.kubernetes.io/component: taiga-events
|
||||||
|
namespace: default
|
||||||
spec:
|
spec:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
selector:
|
selector:
|
||||||
|
|
|
@ -2,7 +2,6 @@ apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-front-deployment
|
name: taiga-front-deployment
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: c4k-taiga
|
||||||
app.kubernetes.io/component: taiga-front
|
app.kubernetes.io/component: taiga-front
|
||||||
|
|
|
@ -2,10 +2,10 @@ kind: Service
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-front
|
name: taiga-front
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: c4k-taiga
|
||||||
app.kubernetes.io/component: taiga-front
|
app.kubernetes.io/component: taiga-front
|
||||||
|
namespace: default
|
||||||
spec:
|
spec:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
selector:
|
selector:
|
||||||
|
|
|
@ -2,9 +2,6 @@ apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-gateway-configmap
|
name: taiga-gateway-configmap
|
||||||
namespace: taiga
|
|
||||||
labels:
|
|
||||||
app.kubernetes.part-of: c4k-taiga
|
|
||||||
data:
|
data:
|
||||||
default.conf: |
|
default.conf: |
|
||||||
server {
|
server {
|
||||||
|
|
|
@ -2,7 +2,6 @@ apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-gateway-deployment
|
name: taiga-gateway-deployment
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: c4k-taiga
|
||||||
app.kubernetes.io/component: taiga-gateway
|
app.kubernetes.io/component: taiga-gateway
|
||||||
|
@ -34,6 +33,7 @@ spec:
|
||||||
- name: taiga-media
|
- name: taiga-media
|
||||||
mountPath: /taiga/media
|
mountPath: /taiga/media
|
||||||
readOnly: false
|
readOnly: false
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
- name: taiga-gateway-configmap
|
- name: taiga-gateway-configmap
|
||||||
configMap:
|
configMap:
|
||||||
|
|
|
@ -2,10 +2,10 @@ kind: Service
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-gateway
|
name: taiga-gateway
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: c4k-taiga
|
||||||
app.kubernetes.io/component: taiga-gateway
|
app.kubernetes.io/component: taiga-gateway
|
||||||
|
namespace: default
|
||||||
spec:
|
spec:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
selector:
|
selector:
|
||||||
|
|
|
@ -2,7 +2,6 @@ apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-protected-deployment
|
name: taiga-protected-deployment
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: c4k-taiga
|
||||||
app.kubernetes.io/component: taiga-protected
|
app.kubernetes.io/component: taiga-protected
|
||||||
|
|
|
@ -2,10 +2,10 @@ kind: Service
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-protected
|
name: taiga-protected
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: c4k-taiga
|
||||||
app.kubernetes.io/component: taiga-protected
|
app.kubernetes.io/component: taiga-protected
|
||||||
|
namespace: default
|
||||||
spec:
|
spec:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
selector:
|
selector:
|
||||||
|
|
|
@ -2,9 +2,10 @@ apiVersion: v1
|
||||||
kind: PersistentVolumeClaim
|
kind: PersistentVolumeClaim
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-media-data
|
name: taiga-media-data
|
||||||
namespace: taiga
|
namespace: default
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app: taiga
|
||||||
|
app.kubernetes.part-of: taiga
|
||||||
spec:
|
spec:
|
||||||
storageClassName: REPLACEME
|
storageClassName: REPLACEME
|
||||||
accessModes:
|
accessModes:
|
||||||
|
|
|
@ -2,9 +2,10 @@ apiVersion: v1
|
||||||
kind: PersistentVolumeClaim
|
kind: PersistentVolumeClaim
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-static-data
|
name: taiga-static-data
|
||||||
namespace: taiga
|
namespace: default
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app: taiga
|
||||||
|
app.kubernetes.part-of: taiga
|
||||||
spec:
|
spec:
|
||||||
storageClassName: REPLACEME
|
storageClassName: REPLACEME
|
||||||
accessModes:
|
accessModes:
|
||||||
|
|
|
@ -2,9 +2,10 @@ apiVersion: v1
|
||||||
kind: PersistentVolumeClaim
|
kind: PersistentVolumeClaim
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-async-rabbitmq-data
|
name: taiga-async-rabbitmq-data
|
||||||
namespace: taiga
|
namespace: default
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app: taiga
|
||||||
|
app.kubernetes.part-of: taiga
|
||||||
spec:
|
spec:
|
||||||
storageClassName: REPLACEME
|
storageClassName: REPLACEME
|
||||||
accessModes:
|
accessModes:
|
||||||
|
|
|
@ -2,9 +2,10 @@ apiVersion: v1
|
||||||
kind: PersistentVolumeClaim
|
kind: PersistentVolumeClaim
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-events-rabbitmq-data
|
name: taiga-events-rabbitmq-data
|
||||||
namespace: taiga
|
namespace: default
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app: taiga
|
||||||
|
app.kubernetes.part-of: taiga
|
||||||
spec:
|
spec:
|
||||||
storageClassName: REPLACEME
|
storageClassName: REPLACEME
|
||||||
accessModes:
|
accessModes:
|
||||||
|
|
|
@ -2,9 +2,8 @@ apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: taiga-secret
|
name: taiga-secret
|
||||||
namespace: taiga
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: c4k-taiga
|
app.kubernetes.part-of: taiga
|
||||||
data:
|
data:
|
||||||
# Taiga settings
|
# Taiga settings
|
||||||
TAIGA_SECRET_KEY: TAIGA_SECRET_KEY
|
TAIGA_SECRET_KEY: TAIGA_SECRET_KEY
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
(ns dda.c4k-taiga.backup-test
|
|
||||||
(:require
|
|
||||||
#?(:clj [clojure.test :refer [deftest is are testing run-tests]]
|
|
||||||
:cljs [cljs.test :refer-macros [deftest is are testing run-tests]])
|
|
||||||
[clojure.spec.test.alpha :as st]
|
|
||||||
[dda.c4k-taiga.backup :as cut]))
|
|
||||||
|
|
||||||
(st/instrument `cut/generate-secret)
|
|
||||||
(st/instrument `cut/generate-config)
|
|
||||||
(st/instrument `cut/generate-cron)
|
|
||||||
|
|
||||||
(deftest should-generate-config
|
|
||||||
(is (= {:apiVersion "v1"
|
|
||||||
:kind "ConfigMap"
|
|
||||||
:metadata {:name "backup-config"
|
|
||||||
:namespace "taiga"
|
|
||||||
:labels {:app.kubernetes.io/name "backup"
|
|
||||||
:app.kubernetes.io/part-of "c4k-taiga"}}
|
|
||||||
:data
|
|
||||||
{:restic-repository "s3:restic-repository"}}
|
|
||||||
(cut/generate-config {:restic-repository "s3:restic-repository"}))))
|
|
||||||
|
|
||||||
(deftest should-generate-secret
|
|
||||||
(is (= {:apiVersion "v1"
|
|
||||||
:kind "Secret"
|
|
||||||
:metadata {:name "backup-secret", :namespace "taiga"}
|
|
||||||
:type "Opaque"
|
|
||||||
:data
|
|
||||||
{:aws-access-key-id "YXdzLWlk",
|
|
||||||
:aws-secret-access-key "YXdzLXNlY3JldA==",
|
|
||||||
:restic-password "cmVzdGljLXB3"}}
|
|
||||||
(cut/generate-secret {:aws-access-key-id "aws-id"
|
|
||||||
:aws-secret-access-key "aws-secret"
|
|
||||||
:restic-password "restic-pw"})))
|
|
||||||
(is (= {:apiVersion "v1"
|
|
||||||
:kind "Secret"
|
|
||||||
:metadata {:name "backup-secret", :namespace "taiga"}
|
|
||||||
:type "Opaque"
|
|
||||||
:data
|
|
||||||
{:aws-access-key-id "YXdzLWlk",
|
|
||||||
:aws-secret-access-key "YXdzLXNlY3JldA==",
|
|
||||||
:restic-password "cmVzdGljLXB3"
|
|
||||||
:restic-new-password "bmV3LXJlc3RpYy1wdw=="}}
|
|
||||||
(cut/generate-secret {:aws-access-key-id "aws-id"
|
|
||||||
:aws-secret-access-key "aws-secret"
|
|
||||||
:restic-password "restic-pw"
|
|
||||||
:restic-new-password "new-restic-pw"}))))
|
|
|
@ -1,6 +1,6 @@
|
||||||
(ns dda.c4k-taiga.core-test
|
(ns dda.c4k-taiga.core-test
|
||||||
(:require
|
(:require
|
||||||
#?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]])
|
#?(:cljs [shadow.resource :as rc])
|
||||||
#?(: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.alpha :as s]
|
[clojure.spec.alpha :as s]
|
||||||
|
@ -8,20 +8,12 @@
|
||||||
[dda.c4k-taiga.core :as cut]))
|
[dda.c4k-taiga.core :as cut]))
|
||||||
|
|
||||||
#?(:cljs
|
#?(:cljs
|
||||||
(defmethod yaml/load-resource :taiga-test [resource-name]
|
(defmethod yaml/load-resource :website-test [resource-name]
|
||||||
(get (inline-resources "taiga-test") resource-name)))
|
(case resource-name
|
||||||
|
"taiga-test/valid-config.yaml" (rc/inline "taiga-test/valid-config.yaml")
|
||||||
|
"taiga-test/valid-auth.yaml" (rc/inline "taiga-test/valid-auth.yaml")
|
||||||
|
(throw (js/Error. "Undefined Resource!")))))
|
||||||
|
|
||||||
(deftest validate-valid-resources
|
(deftest validate-valid-resources
|
||||||
(is (s/valid? cut/config? (yaml/load-as-edn "taiga-test/valid-config.yaml")))
|
(is (s/valid? cut/config? (yaml/load-as-edn "taiga-test/valid-config.yaml")))
|
||||||
(is (s/valid? cut/auth? (yaml/load-as-edn "taiga-test/valid-auth.yaml"))))
|
(is (s/valid? cut/auth? (yaml/load-as-edn "taiga-test/valid-auth.yaml"))))
|
||||||
|
|
||||||
(deftest test-whole-generation
|
|
||||||
(is (= 49
|
|
||||||
(count
|
|
||||||
(cut/config-objects
|
|
||||||
(yaml/load-as-edn "taiga-test/valid-config.yaml")))))
|
|
||||||
(is (= 4
|
|
||||||
(count
|
|
||||||
(cut/auth-objects
|
|
||||||
(yaml/load-as-edn "taiga-test/valid-config.yaml")
|
|
||||||
(yaml/load-as-edn "taiga-test/valid-auth.yaml"))))))
|
|
||||||
|
|
|
@ -1,30 +1,26 @@
|
||||||
(ns dda.c4k-taiga.taiga-test
|
(ns dda.c4k-taiga.taiga-test
|
||||||
(:require
|
(:require
|
||||||
#?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]])
|
#?(:cljs [shadow.resource :as rc])
|
||||||
#?(: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.alpha :as s]
|
||||||
[dda.c4k-common.yaml :as yaml]
|
[dda.c4k-common.yaml :as yaml]
|
||||||
[dda.c4k-taiga.taiga :as cut]))
|
[dda.c4k-taiga.taiga :as cut]))
|
||||||
|
|
||||||
(st/instrument `cut/generate-configmap)
|
|
||||||
(st/instrument `cut/generate-pvc-taiga-media-data)
|
|
||||||
(st/instrument `cut/generate-rabbitmq-pvc-async)
|
|
||||||
(st/instrument `cut/generate-rabbitmq-pvc-events)
|
|
||||||
(st/instrument `cut/generate-secret)
|
|
||||||
|
|
||||||
#?(:cljs
|
#?(:cljs
|
||||||
(defmethod yaml/load-resource :taiga-test [resource-name]
|
(defmethod yaml/load-resource :taiga-test [resource-name]
|
||||||
(get (inline-resources "taiga-test") resource-name)))
|
(case resource-name
|
||||||
|
"taiga-test/valid-config.yaml" (rc/inline "taiga-test/valid-config.yaml")
|
||||||
|
"taiga-test/valid-auth.yaml" (rc/inline "taiga-test/valid-auth.yaml")
|
||||||
|
(throw (js/Error. "Undefined Resource!")))))
|
||||||
|
|
||||||
(deftest should-generate-configmap
|
(deftest should-generate-configmap
|
||||||
(is (= {:apiVersion "v1",
|
(is (= {:apiVersion "v1",
|
||||||
:kind "ConfigMap",
|
:kind "ConfigMap",
|
||||||
:metadata
|
:metadata {:name "taiga-configmap", :namespace "default"},
|
||||||
{:name "taiga-configmap", :namespace "taiga"
|
|
||||||
:labels {:app.kubernetes.part-of "c4k-taiga"}},
|
|
||||||
:data
|
:data
|
||||||
{:ENABLE_TELEMETRY "false",
|
{:CELERY_ENABLED "false",
|
||||||
|
:ENABLE_TELEMETRY "false",
|
||||||
:TAIGA_SITES_SCHEME "https",
|
:TAIGA_SITES_SCHEME "https",
|
||||||
:TAIGA_SITES_DOMAIN "taiga.test.meissa.de",
|
:TAIGA_SITES_DOMAIN "taiga.test.meissa.de",
|
||||||
:TAIGA_SUBPATH "",
|
:TAIGA_SUBPATH "",
|
||||||
|
@ -35,8 +31,8 @@
|
||||||
:ENABLE_JIRA_IMPORTER "false",
|
:ENABLE_JIRA_IMPORTER "false",
|
||||||
:ENABLE_TRELLO_IMPORTER "false",
|
:ENABLE_TRELLO_IMPORTER "false",
|
||||||
:RABBITMQ_DEFAULT_VHOST "taiga",
|
:RABBITMQ_DEFAULT_VHOST "taiga",
|
||||||
:SESSION_COOKIE_SECURE "False",
|
:SESSION_COOKIE_SECURE "false",
|
||||||
:CSRF_COOKIE_SECURE "False"}}
|
:CSRF_COOKIE_SECURE "false"}}
|
||||||
(cut/generate-configmap (yaml/load-as-edn "taiga-test/valid-config.yaml")))))
|
(cut/generate-configmap (yaml/load-as-edn "taiga-test/valid-config.yaml")))))
|
||||||
|
|
||||||
(deftest should-generate-pvc-taiga-media-data
|
(deftest should-generate-pvc-taiga-media-data
|
||||||
|
@ -44,19 +40,21 @@
|
||||||
:kind "PersistentVolumeClaim",
|
:kind "PersistentVolumeClaim",
|
||||||
:metadata
|
:metadata
|
||||||
{:name "taiga-media-data",
|
{:name "taiga-media-data",
|
||||||
:namespace "taiga"
|
:namespace "default",
|
||||||
:labels {:app.kubernetes.part-of "c4k-taiga"}},
|
:labels {:app "taiga", :app.kubernetes.part-of "taiga"}},
|
||||||
:spec
|
:spec
|
||||||
{:storageClassName "local-path",
|
{:storageClassName "local-path",
|
||||||
:accessModes ["ReadWriteOnce"],
|
:accessModes ["ReadWriteOnce"],
|
||||||
:resources {:requests {:storage "2Gi"}}}}
|
:resources {:requests {:storage "2Gi"}}}}
|
||||||
(cut/generate-pvc-taiga-media-data (yaml/load-as-edn "taiga-test/valid-config.yaml"))))
|
(cut/generate-pvc-taiga-media-data (yaml/load-as-edn "taiga-test/valid-config.yaml")))))
|
||||||
|
|
||||||
|
(deftest should-generate-pvc-taiga-static-data
|
||||||
(is (= {:apiVersion "v1",
|
(is (= {:apiVersion "v1",
|
||||||
:kind "PersistentVolumeClaim",
|
:kind "PersistentVolumeClaim",
|
||||||
:metadata
|
:metadata
|
||||||
{:name "taiga-static-data",
|
{:name "taiga-static-data",
|
||||||
:namespace "taiga"
|
:namespace "default",
|
||||||
:labels {:app.kubernetes.part-of "c4k-taiga"}},
|
:labels {:app "taiga", :app.kubernetes.part-of "taiga"}},
|
||||||
:spec
|
:spec
|
||||||
{:storageClassName "local-path",
|
{:storageClassName "local-path",
|
||||||
:accessModes ["ReadWriteOnce"],
|
:accessModes ["ReadWriteOnce"],
|
||||||
|
@ -68,21 +66,21 @@
|
||||||
:kind "PersistentVolumeClaim",
|
:kind "PersistentVolumeClaim",
|
||||||
:metadata
|
:metadata
|
||||||
{:name "taiga-async-rabbitmq-data",
|
{:name "taiga-async-rabbitmq-data",
|
||||||
:namespace "taiga"
|
:namespace "default",
|
||||||
:labels {:app.kubernetes.part-of "c4k-taiga"}},
|
:labels {:app "taiga", :app.kubernetes.part-of "taiga"}},
|
||||||
:spec
|
:spec
|
||||||
{:storageClassName "local-path",
|
{:storageClassName "local-path",
|
||||||
:accessModes ["ReadWriteOnce"],
|
:accessModes ["ReadWriteOnce"],
|
||||||
:resources {:requests {:storage "4Gi"}}}}
|
:resources {:requests {:storage "4Gi"}}}}
|
||||||
(cut/generate-rabbitmq-pvc-async (yaml/load-as-edn "taiga-test/valid-config.yaml")))))
|
(cut/generate-rabbitmq-pvc-async(yaml/load-as-edn "taiga-test/valid-config.yaml")))))
|
||||||
|
|
||||||
(deftest should-generate-rabbitmq-pvc-events
|
(deftest should-generate-rabbitmq-pvc-events
|
||||||
(is (= {:apiVersion "v1",
|
(is (= {:apiVersion "v1",
|
||||||
:kind "PersistentVolumeClaim",
|
:kind "PersistentVolumeClaim",
|
||||||
:metadata
|
:metadata
|
||||||
{:name "taiga-events-rabbitmq-data",
|
{:name "taiga-events-rabbitmq-data",
|
||||||
:namespace "taiga"
|
:namespace "default",
|
||||||
:labels {:app.kubernetes.part-of "c4k-taiga"}},
|
:labels {:app "taiga", :app.kubernetes.part-of "taiga"}},
|
||||||
:spec
|
:spec
|
||||||
{:storageClassName "local-path",
|
{:storageClassName "local-path",
|
||||||
:accessModes ["ReadWriteOnce"],
|
:accessModes ["ReadWriteOnce"],
|
||||||
|
@ -93,7 +91,7 @@
|
||||||
(is (= {:apiVersion "v1",
|
(is (= {:apiVersion "v1",
|
||||||
:kind "Secret",
|
:kind "Secret",
|
||||||
:metadata
|
:metadata
|
||||||
{:name "taiga-secret", :namespace "taiga" :labels {:app.kubernetes.part-of "c4k-taiga"}},
|
{:name "taiga-secret", :labels {:app.kubernetes.part-of "taiga"}},
|
||||||
:data
|
:data
|
||||||
{:TAIGA_SECRET_KEY "c29tZS1rZXk=",
|
{:TAIGA_SECRET_KEY "c29tZS1rZXk=",
|
||||||
:EMAIL_HOST_USER "bWFpbGVyLXVzZXI=",
|
:EMAIL_HOST_USER "bWFpbGVyLXVzZXI=",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
taiga-secret-key: "some-key"
|
taiga-secret-key: "some-key"
|
||||||
postgres-db-user: "taiga"
|
postgres-db-user: "forgejo"
|
||||||
postgres-db-password: "taiga-db-password"
|
postgres-db-password: "forgejo-db-password"
|
||||||
mailer-user: "mailer-user"
|
mailer-user: "mailer-user"
|
||||||
mailer-pw: "mailer-pw"
|
mailer-pw: "mailer-pw"
|
||||||
django-superuser-username: "taiga-admin"
|
django-superuser-username: "taiga-admin"
|
||||||
|
@ -9,9 +9,6 @@ django-superuser-email: "some@example.com"
|
||||||
rabbitmq-user: "rabbit-user"
|
rabbitmq-user: "rabbit-user"
|
||||||
rabbitmq-pw: "rabbit-pw"
|
rabbitmq-pw: "rabbit-pw"
|
||||||
rabbitmq-erlang-cookie: "rabbit-erlang"
|
rabbitmq-erlang-cookie: "rabbit-erlang"
|
||||||
aws-access-key-id: "AWS_KEY_ID"
|
|
||||||
aws-secret-access-key: "AWS_KEY_SECRET"
|
|
||||||
restic-password: ""
|
|
||||||
mon-auth:
|
mon-auth:
|
||||||
grafana-cloud-user: "user"
|
grafana-cloud-user: "user"
|
||||||
grafana-cloud-password: "password"
|
grafana-cloud-password: "password"
|
||||||
|
|
|
@ -7,7 +7,6 @@ storage-media-size: 2
|
||||||
storage-static-size: 3
|
storage-static-size: 3
|
||||||
storage-async-rabbitmq-size: 4
|
storage-async-rabbitmq-size: 4
|
||||||
storage-events-rabbitmq-size: 5
|
storage-events-rabbitmq-size: 5
|
||||||
restic-repository: "repo-path"
|
|
||||||
mon-cfg:
|
mon-cfg:
|
||||||
grafana-cloud-url: "url-for-your-prom-remote-write-endpoint"
|
grafana-cloud-url: "url-for-your-prom-remote-write-endpoint"
|
||||||
cluster-name: "jitsi"
|
cluster-name: "jitsi"
|
||||||
|
|
Loading…
Add table
Reference in a new issue