Compare commits
217 commits
integratio
...
main
Author | SHA1 | Date | |
---|---|---|---|
d1a8479598 | |||
c4832b1107 | |||
7e3312e285 | |||
f636f7ffc3 | |||
bba6bbe830 | |||
8388d72517 | |||
f2b583c060 | |||
5a3aca38cf | |||
4764d1db67 | |||
8aef785bdc | |||
5eb83f78a0 | |||
d997e470a0 | |||
dc86531454 | |||
ca0d4ac7b2 | |||
e4666a592e | |||
fa48d9762a | |||
6a278ece0d | |||
dda45d92d6 | |||
c69c9da659 | |||
de53b9b7a5 | |||
cc845af696 | |||
f5aa2295f0 | |||
1d344abc27 | |||
7cd4e4101d | |||
5d2a65079e | |||
b36808de7c | |||
3e588c082c | |||
4a74a1bec0 | |||
1ff8a0dc13 | |||
fd27c15ec7 | |||
192e053afc | |||
cab9b573c1 | |||
226046d278 | |||
f108b67e62 | |||
96343b9af5 | |||
f072ff027d | |||
e396880365 | |||
83080b30a8 | |||
4a78a35424 | |||
8727f16c75 | |||
ac3f2a455d | |||
c05ecfa427 | |||
fff2c939d9 | |||
e8cec9de8a | |||
1fb309f213 | |||
70d41ca532 | |||
a96cba8cb1 | |||
3bdf2ea553 | |||
fcf6d7783e | |||
ab4c6e0d76 | |||
ef8bfa11fc | |||
7d9ca203bb | |||
f8bcbe63ba | |||
7219533c86 | |||
9b13b96ff6 | |||
351b2295e3 | |||
3a9694d9a1 | |||
3b458b980b | |||
5f38fb7526 | |||
fa81908791 | |||
17ffd5a10e | |||
f765b17dad | |||
2119a8b037 | |||
c2574c481f | |||
b08831c477 | |||
212a56b1ef | |||
ee2751509b | |||
59391d96d4 | |||
3b8ae92b83 | |||
408376a5ca | |||
e6785784a7 | |||
69f5e31c56 | |||
2f5dd28c23 | |||
de69d87c87 | |||
76cb0b5182 | |||
76cbffe348 | |||
4a2afd65b5 | |||
84f6974175 | |||
b8d241a2c8 | |||
439385933e | |||
2e90bae8c9 | |||
2771fed341 | |||
fad3a4d07c | |||
b51363bead | |||
47fa110f02 | |||
dc3e14517b | |||
741f0ce716 | |||
7ccf587c00 | |||
96b8b6a448 | |||
c931e36a0a | |||
252f14b987 | |||
99407b70f3 | |||
680f364b24 | |||
43ebd230e4 | |||
6837a99cdf | |||
f211a8b75c | |||
e57c43bd1e | |||
3bc19ea5f1 | |||
dd9cc84472 | |||
e6c334f5ed | |||
f064fb98ed | |||
c7297fc953 | |||
00c317a55b | |||
|
b862f8943a | ||
|
848857b6a9 | ||
|
75629ae366 | ||
2c0f340903 | |||
1757fcebb9 | |||
|
bc2f444b75 | ||
eb2cbad90f | |||
8afc7ee9e1 | |||
c3c2740e5a | |||
53e4f0781f | |||
11323e2832 | |||
861f1f1c21 | |||
0e14a59f6d | |||
6215434199 | |||
2198b2c76c | |||
4cad3daa3f | |||
27c2044913 | |||
|
a286cffb03 | ||
f43e46ac3b | |||
483fb69918 | |||
efac24b6df | |||
be684408a0 | |||
3ffd98786b | |||
234c920c63 | |||
d6ab7c555a | |||
e74280bf78 | |||
84e70af742 | |||
fe4c381791 | |||
16dd0c5828 | |||
19682eec36 | |||
91d88d2a68 | |||
88a077e776 | |||
107b8c3872 | |||
74505dbab7 | |||
|
018d8d8b61 | ||
1c9c1a732e | |||
05edb62598 | |||
2e7bce20a2 | |||
ccfde9a447 | |||
d2be6989d0 | |||
92f234ae6e | |||
344b417c40 | |||
728915e887 | |||
82290cbaec | |||
1e9cd59b50 | |||
a9fab1d963 | |||
85eb5c8541 | |||
2734125b8e | |||
66aefb4c5c | |||
90acdc034e | |||
16ab44be95 | |||
44589b787b | |||
|
16308798c0 | ||
c49031da18 | |||
c2e2ea6c67 | |||
|
0d3a4c334a | ||
ed60947087 | |||
2dbc40fb0c | |||
9f94116777 | |||
5b4e68ae2a | |||
775689b348 | |||
34a3ca4728 | |||
b1ad85fd6a | |||
6b6cc630c6 | |||
a224506caa | |||
4dbe5367a7 | |||
02a15fd708 | |||
c0345830ef | |||
6fb941b9a0 | |||
7eb560a7f0 | |||
20b2659b89 | |||
a1cdb3f4fa | |||
ecca694f4c | |||
f35983c6b4 | |||
4e677385b4 | |||
9f2977133a | |||
28de47db4d | |||
8f050d4736 | |||
44ed9dd0c2 | |||
484b165a81 | |||
960e5ee613 | |||
2a0efa37d0 | |||
7006250375 | |||
4538cc5a24 | |||
aca8c7a397 | |||
f6598e68f6 | |||
a470dbc5fc | |||
48918d8d8c | |||
7453c4edd9 | |||
1c179daf2c | |||
3a2f587709 | |||
8b8a39ceb3 | |||
18526e8c08 | |||
ed1127edfb | |||
200bb02853 | |||
f45105ba68 | |||
471e920f60 | |||
4836f7a977 | |||
7e9bd75cde | |||
a49b07e7de | |||
2607f759c6 | |||
11b00bd525 | |||
66cdecc048 | |||
f27c101f48 | |||
|
d228fdfd2a | ||
|
8e03b1c11e | ||
7b642db03c | |||
de67d4eba9 | |||
3265b6aaaf | |||
20380ba193 | |||
f943994afa | |||
8be078b09c | |||
64585b8d39 | |||
bac7cd5713 |
69 changed files with 1460 additions and 757 deletions
13
.gitignore
vendored
13
.gitignore
vendored
|
@ -22,8 +22,17 @@ logs/
|
|||
*.iml
|
||||
.idea/
|
||||
|
||||
#valid-auth.edn
|
||||
#valid-config.edn
|
||||
# config files
|
||||
my-auth.edn
|
||||
my-config.edn
|
||||
auth.edn
|
||||
config.edn
|
||||
|
||||
# certificate
|
||||
ca.crt
|
||||
|
||||
# chaches
|
||||
.clj-kondo/.cache
|
||||
.lsp/.cache/
|
||||
|
||||
.eastwood
|
138
.gitlab-ci.yml
138
.gitlab-ci.yml
|
@ -5,11 +5,18 @@ stages:
|
|||
- upload
|
||||
- image
|
||||
|
||||
services:
|
||||
- docker:19.03.12-dind
|
||||
.img: &img
|
||||
image: "domaindrivenarchitecture/ddadevops-dind:4.11.3"
|
||||
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
|
||||
image: domaindrivenarchitecture/shadow-cljs
|
||||
image: "domaindrivenarchitecture/ddadevops-clj-cljs:4.11.3"
|
||||
cache:
|
||||
key: ${CI_COMMIT_REF_SLUG}
|
||||
paths:
|
||||
|
@ -17,60 +24,62 @@ services:
|
|||
- .shadow-cljs/
|
||||
- .m2
|
||||
before_script:
|
||||
- echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
|
||||
- npm install
|
||||
- export RELEASE_ARTIFACT_TOKEN=$MEISSA_REPO_BUERO_RW
|
||||
- echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
|
||||
- npm install
|
||||
|
||||
.clj-uploadjob: &clj
|
||||
image: domaindrivenarchitecture/lein
|
||||
.clj-job: &clj
|
||||
image: "domaindrivenarchitecture/ddadevops-clj:4.11.3"
|
||||
cache:
|
||||
key: ${CI_COMMIT_REF_SLUG}
|
||||
paths:
|
||||
- .m2
|
||||
before_script:
|
||||
- mkdir -p /root/.lein
|
||||
- echo "{:auth {:repository-auth {#\"clojars\" {:username \"${CLOJARS_USER}\" :password \"${CLOJARS_TOKEN_DOMAINDRIVENARCHITECTURE}\" }}}}" > ~/.lein/profiles.clj
|
||||
- export RELEASE_ARTIFACT_TOKEN=$MEISSA_REPO_BUERO_RW
|
||||
- mkdir -p /root/.lein
|
||||
- echo "{:auth {:repository-auth {#\"clojars\" {:username \"${CLOJARS_USER}\" :password \"${CLOJARS_TOKEN_DOMAINDRIVENARCHITECTURE}\" }}}}" > ~/.lein/profiles.clj
|
||||
|
||||
test-cljs:
|
||||
<<: *cljs
|
||||
stage: build_and_test
|
||||
script:
|
||||
- shadow-cljs compile test
|
||||
.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:
|
||||
- lein test
|
||||
- pyb test_clj
|
||||
|
||||
test-cljs:
|
||||
<<: *cljs
|
||||
stage: build_and_test
|
||||
script:
|
||||
- pyb test_cljs
|
||||
|
||||
test-schema:
|
||||
<<: *clj
|
||||
stage: build_and_test
|
||||
script:
|
||||
- lein uberjar
|
||||
- java -jar target/uberjar/c4k-nextcloud-standalone.jar valid-config.edn valid-auth.edn | kubeconform --kubernetes-version 1.19.0 --strict --skip "Certificate,CronJob" -
|
||||
- pyb test_schema
|
||||
artifacts:
|
||||
paths:
|
||||
- target/uberjar
|
||||
|
||||
.report-frontend:
|
||||
report-frontend:
|
||||
<<: *cljs
|
||||
stage: package
|
||||
script:
|
||||
- mkdir -p target/frontend-build
|
||||
- shadow-cljs run shadow.cljs.build-report frontend target/frontend-build/build-report.html
|
||||
- pyb report_frontend
|
||||
artifacts:
|
||||
paths:
|
||||
- target/frontend-build/build-report.html
|
||||
|
||||
.package-frontend:
|
||||
package-frontend:
|
||||
<<: *cljs
|
||||
stage: package
|
||||
script:
|
||||
- mkdir -p target/frontend-build
|
||||
- shadow-cljs release frontend
|
||||
- cp public/js/main.js target/frontend-build/c4k-nextcloud.js
|
||||
- sha256sum target/frontend-build/c4k-nextcloud.js > target/frontend-build/c4k-nextcloud.js.sha256
|
||||
- sha512sum target/frontend-build/c4k-nextcloud.js > target/frontend-build/c4k-nextcloud.js.sha512
|
||||
- pyb package_frontend
|
||||
artifacts:
|
||||
paths:
|
||||
- target/frontend-build
|
||||
|
@ -79,63 +88,44 @@ package-uberjar:
|
|||
<<: *clj
|
||||
stage: package
|
||||
script:
|
||||
- sha256sum target/uberjar/c4k-nextcloud-standalone.jar > target/uberjar/c4k-nextcloud-standalone.jar.sha256
|
||||
- sha512sum target/uberjar/c4k-nextcloud-standalone.jar > target/uberjar/c4k-nextcloud-standalone.jar.sha512
|
||||
- pyb package_uberjar
|
||||
artifacts:
|
||||
paths:
|
||||
- target/uberjar
|
||||
|
||||
sast:
|
||||
variables:
|
||||
SAST_EXCLUDED_ANALYZERS:
|
||||
bandit, brakeman, flawfinder, gosec, kubesec, phpcs-security-audit,
|
||||
pmd-apex, security-code-scan, sobelow, spotbugs
|
||||
stage: security
|
||||
before_script:
|
||||
- mkdir -p builds && cp -r target/ builds/
|
||||
include:
|
||||
- template: Security/SAST.gitlab-ci.yml
|
||||
|
||||
upload-clj-prerelease:
|
||||
package-native:
|
||||
<<: *clj
|
||||
stage: upload
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH == "master" && $CI_COMMIT_TAG == null'
|
||||
stage: package
|
||||
script:
|
||||
- lein deploy clojars
|
||||
|
||||
release:
|
||||
image: registry.gitlab.com/gitlab-org/release-cli:latest
|
||||
stage: upload
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG != null'
|
||||
- pyb package_native
|
||||
artifacts:
|
||||
paths:
|
||||
- target/uberjar
|
||||
- target/frontend-build
|
||||
script:
|
||||
- apk --no-cache add curl
|
||||
- |
|
||||
release-cli create --name "Release $CI_COMMIT_TAG" --tag-name $CI_COMMIT_TAG \
|
||||
--assets-link "{\"name\":\"c4k-nextcloud-standalone.jar\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud/-/jobs/${CI_JOB_ID}/artifacts/file/target/uberjar/c4k-nextcloud-standalone.jar\"}" \
|
||||
--assets-link "{\"name\":\"c4k-nextcloud-standalone.jar.sha256\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud/-/jobs/${CI_JOB_ID}/artifacts/file/target/uberjar/c4k-nextcloud-standalone.jar.sha256\"}" \
|
||||
--assets-link "{\"name\":\"c4k-nextcloud-standalone.jar.sha512\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud/-/jobs/${CI_JOB_ID}/artifacts/file/target/uberjar/c4k-nextcloud-standalone.jar.sha512\"}" \
|
||||
--assets-link "{\"name\":\"c4k-nextcloud.js\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud/-/jobs/${CI_JOB_ID}/artifacts/file/target/frontend-build/c4k-nextcloud.js\"}" \
|
||||
--assets-link "{\"name\":\"c4k-nextcloud.js.sha256\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud/-/jobs/${CI_JOB_ID}/artifacts/file/target/frontend-build/c4k-nextcloud.js.sha256\"}" \
|
||||
--assets-link "{\"name\":\"c4k-nextcloud.js.sha512\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud/-/jobs/${CI_JOB_ID}/artifacts/file/target/frontend-build/c4k-nextcloud.js.sha512\"}" \
|
||||
- target/graalvm
|
||||
|
||||
nextcloud-image-test-publish:
|
||||
image: domaindrivenarchitecture/devops-build:latest
|
||||
stage: image
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG != null'
|
||||
release-to-clojars:
|
||||
<<: *clj
|
||||
<<: *tag_only
|
||||
stage: upload
|
||||
script:
|
||||
- cd infrastructure/docker-nextcloud && pyb image test publish
|
||||
- pyb upload_clj
|
||||
|
||||
backup-image-test-publish:
|
||||
image: domaindrivenarchitecture/devops-build:latest
|
||||
stage: image
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG != null'
|
||||
release-to-forgejo:
|
||||
<<: *clj
|
||||
<<: *tag_only
|
||||
stage: upload
|
||||
script:
|
||||
- cd infrastructure/docker-backup && pyb image test publish
|
||||
- pyb publish_artifacts
|
||||
|
||||
backup-image-publish:
|
||||
<<: *img
|
||||
<<: *tag_only
|
||||
stage: image
|
||||
script:
|
||||
- cd infrastructure/backup && pyb image publish
|
||||
|
||||
nextcloud-image-publish:
|
||||
<<: *img
|
||||
<<: *tag_only
|
||||
stage: image
|
||||
script:
|
||||
- cd infrastructure/nextcloud && pyb image publish
|
||||
|
|
17
README.md
17
README.md
|
@ -35,8 +35,21 @@ target/graalvm/c4k-nextcloud src/test/resources/valid-config.edn src/test/resour
|
|||
* [Example Setup on Hetzner](doc/SetupOnHetzner.md)
|
||||
* Backup and Restore
|
||||
|
||||
## Development & mirrors
|
||||
|
||||
Development happens at: https://repo.prod.meissa.de/meissa/c4k-nextcloud
|
||||
|
||||
Mirrors are:
|
||||
|
||||
* https://codeberg.org/meissa/c4k-nextcloud (Issues and PR)
|
||||
* https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud (CI)
|
||||
* https://github.com/DomainDrivenArchitecture/c4k-nextcloud
|
||||
|
||||
For more details about our repository model see: https://repo.prod.meissa.de/meissa/federate-your-repos
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2021 meissa GmbH
|
||||
Copyright © 2021, 2022, 2023, 2024 meissa GmbH
|
||||
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)
|
||||
|
|
233
build.py
Normal file
233
build.py
Normal file
|
@ -0,0 +1,233 @@
|
|||
from os import environ
|
||||
from subprocess import run
|
||||
from pybuilder.core import init, task
|
||||
from ddadevops import *
|
||||
|
||||
default_task = "dev"
|
||||
name = 'c4k-nextcloud'
|
||||
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",
|
||||
"infrastructure/nextcloud/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_clj():
|
||||
run("lein test", shell=True, check=True)
|
||||
|
||||
|
||||
@task
|
||||
def test_cljs():
|
||||
run("shadow-cljs compile test", shell=True, check=True)
|
||||
run("node target/node-tests.js", shell=True, check=True)
|
||||
|
||||
|
||||
@task
|
||||
def test_schema():
|
||||
run("lein uberjar", shell=True, check=True)
|
||||
run(
|
||||
"java -jar target/uberjar/c4k-nextcloud-standalone.jar "
|
||||
+ "src/test/resources/nextcloud-test/valid-config.yaml "
|
||||
+ "src/test/resources/nextcloud-test/valid-auth.yaml | "
|
||||
+ "kubeconform --kubernetes-version 1.23.0 --strict --skip Certificate -",
|
||||
shell=True,
|
||||
check=True,
|
||||
)
|
||||
|
||||
@task
|
||||
def test():
|
||||
test_clj()
|
||||
test_cljs()
|
||||
test_schema()
|
||||
|
||||
@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(
|
||||
"cp public/js/main.js target/frontend-build/c4k-nextcloud.js",
|
||||
shell=True,
|
||||
check=True,
|
||||
)
|
||||
run(
|
||||
"sha256sum target/frontend-build/c4k-nextcloud.js > target/frontend-build/c4k-nextcloud.js.sha256",
|
||||
shell=True,
|
||||
check=True,
|
||||
)
|
||||
run(
|
||||
"sha512sum target/frontend-build/c4k-nextcloud.js > target/frontend-build/c4k-nextcloud.js.sha512",
|
||||
shell=True,
|
||||
check=True,
|
||||
)
|
||||
|
||||
|
||||
@task
|
||||
def package_uberjar(project):
|
||||
run("lein uberjar", shell=True, check=True)
|
||||
run(
|
||||
"sha256sum target/uberjar/c4k-nextcloud-standalone.jar > target/uberjar/c4k-nextcloud-standalone.jar.sha256",
|
||||
shell=True,
|
||||
check=True,
|
||||
)
|
||||
run(
|
||||
"sha512sum target/uberjar/c4k-nextcloud-standalone.jar > target/uberjar/c4k-nextcloud-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 lint(project):
|
||||
run(
|
||||
"lein eastwood",
|
||||
shell=True,
|
||||
check=True,
|
||||
)
|
||||
run(
|
||||
"lein ancient check",
|
||||
shell=True,
|
||||
check=True,
|
||||
)
|
||||
|
||||
@task
|
||||
def inst(project):
|
||||
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 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()
|
||||
test_cljs()
|
||||
test_schema()
|
||||
lint(project)
|
46
doc/BackupAndRestore.md
Normal file
46
doc/BackupAndRestore.md
Normal file
|
@ -0,0 +1,46 @@
|
|||
# Backup Architecture details
|
||||
|
||||
![](backup.svg)
|
||||
|
||||
* we use restic to produce small & encrypted backups
|
||||
* backup is scheduled at `schedule: "10 23 * * *"`
|
||||
* Cloud stores files on `/var/jira`, these files are backuped. If you create a jira xml backup located in /var/jira this file will also be backed up.
|
||||
* postgres db is backed up as pgdump
|
||||
|
||||
## Manual init the restic repository for the first time
|
||||
|
||||
1. Scale backup-restore deployment up:
|
||||
`kubectl -n nextcloud scale deployment backup-restore --replicas=1`
|
||||
1. exec into pod and execute restore pod
|
||||
`kubectl -n nextcloud exec -it backup-restore -- /usr/local/bin/init.sh`
|
||||
1. Scale backup-restore deployment down:
|
||||
`kubectl -n nextcloud scale deployment backup-restore --replicas=0`
|
||||
|
||||
|
||||
|
||||
## Manual backup
|
||||
|
||||
1. Scale Cloud deployment down:
|
||||
`kubectl -n nextcloud scale deployment cloud-deployment --replicas=0`
|
||||
1. Scale backup-restore deployment up:
|
||||
`kubectl -n nextcloud scale deployment backup-restore --replicas=1`
|
||||
1. exec into pod and execute restore pod
|
||||
`kubectl -n nextcloud exec -it backup-restore -- /usr/local/bin/backup.sh`
|
||||
1. Scale backup-restore deployment down:
|
||||
`kubectl -n nextcloud scale deployment backup-restore --replicas=0`
|
||||
1. Scale Cloud deployment up:
|
||||
`kubectl -n nextcloud scale deployment cloud-deployment --replicas=1`
|
||||
|
||||
|
||||
## Manual restore
|
||||
|
||||
1. Scale Cloud deployment down:
|
||||
`kubectl -n nextcloud scale deployment cloud-deployment --replicas=0`
|
||||
2. Scale backup-restore deployment up:
|
||||
`kubectl -n nextcloud scale deployment backup-restore --replicas=1`
|
||||
3. exec into pod and execute restore pod
|
||||
`kubectl -n nextcloud exec -it backup-restore -- /usr/local/bin/restore.sh`
|
||||
4. Scale backup-restore deployment down:
|
||||
`kubectl -n nextcloud scale deployment backup-restore --replicas=0`
|
||||
5. Scale Cloud deployment up:
|
||||
`kubectl -n nextcloud scale deployment cloud-deployment --replicas=1`
|
|
@ -39,34 +39,31 @@ npx shadow-cljs release frontend
|
|||
## graalvm-setup
|
||||
|
||||
```
|
||||
curl -LO https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-21.0.0.2/graalvm-ce-java11-linux-amd64-21.0.0.2.tar.gz
|
||||
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-ce-java11-linux-amd64-21.0.0.2.tar.gz
|
||||
tar -xzf graalvm-community-jdk-21.0.2_linux-x64_bin.tar.gz
|
||||
|
||||
sudo mv graalvm-ce-java11-21.0.0.2 /usr/lib/jvm/
|
||||
sudo ln -s /usr/lib/jvm/graalvm-ce-java11-21.0.0.2 /usr/lib/jvm/graalvm
|
||||
sudo ln -s /usr/lib/jvm/graalvm/bin/gu /usr/local/bin
|
||||
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/graalvm/bin/java 2
|
||||
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
|
||||
|
||||
# install native-image in graalvm-ce-java11-linux-amd64-21.0.0.2/bin
|
||||
sudo gu install native-image
|
||||
sudo ln -s /usr/lib/jvm/graalvm/bin/native-image /usr/local/bin
|
||||
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/dda/c4k-cloud
|
||||
cd ~/repo/c4k/c4k-nextcloud
|
||||
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
|
||||
./target/graalvm/c4k-nextcloud -h
|
||||
./target/graalvm/c4k-nextcloud src/test/resources/nextcloud-test/valid-config.yaml src/test/resources/nextcloud-test/valid-auth.yaml
|
||||
./target/graalvm/c4k-nextcloud src/test/resources/nextcloud-test/invalid-config.yaml src/test/resources/nextcloud-test/invalid-auth.yaml
|
||||
```
|
||||
|
||||
## c4k-setup
|
||||
|
|
22
doc/LiveUpgrade.md
Normal file
22
doc/LiveUpgrade.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Upgrade major or minor versions of nextcloud
|
||||
|
||||
## Nextcloud versions of c4k-nextcloud docker images
|
||||
|
||||
- 4.0.3: nextcloud 22
|
||||
- 5.0.0: nextcloud 23
|
||||
- 6.0.0: nextcloud 24
|
||||
- 7.0.7: nextcloud 25.0.13
|
||||
- 7.1.1: nextcloud 26.0.0 (manual publish) => attention - only upgrade to 26.0.0 is working
|
||||
- 7.1.0: nextcloud 26.0.13 (manual publish)
|
||||
- 7.2.0: nextcloud 27 (manual publish)
|
||||
- 10.0.0: nextcloud 28.0.5
|
||||
- 10.1.0: nextcloud 29.0.0
|
||||
|
||||
## Uprgrading process
|
||||
|
||||
1. Change the version of the docker image in the deployment to the next major version
|
||||
- `kubectl -n=nextcloud edit deploy cloud-deployment`
|
||||
- change `image: domaindrivenarchitecture/c4k-cloud:4.0.3`
|
||||
2. Wait for the pod to finish restarting
|
||||
3. Verify the website is working and https://URL/settings/admin/overview shows the correct version
|
||||
4. Repeat until desired version is reached
|
41
doc/RenameDatabase.md
Normal file
41
doc/RenameDatabase.md
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Rename Database
|
||||
|
||||
## Start
|
||||
|
||||
1. Scale down cloud deployment
|
||||
`k -n nextcloud scale deployment cloud-deployment --replicas 0`
|
||||
|
||||
## Change db-name in postgres
|
||||
|
||||
1. Connect to postgres-pod
|
||||
`k -n nextcloud exec -it postgresql-... -- bash`
|
||||
2. Connect to a database
|
||||
`PGPASSWORD=$POSTGRES_PASSWORD psql -h postgresql-service -U $POSTGRES_USER postgres`
|
||||
3. List available databases
|
||||
`\l`
|
||||
4. Rename database
|
||||
`ALTER DATABASE cloud RENAME TO nextcloud;`
|
||||
5. Verify
|
||||
`\l`
|
||||
6. Quit
|
||||
`\q`
|
||||
|
||||
## Update postgres-config
|
||||
|
||||
1. Edit configmap
|
||||
`k -n nextcloud edit configmap postgres-config`
|
||||
2. Update postgres-db value
|
||||
3. Save
|
||||
|
||||
## Update nextcloud db-name
|
||||
|
||||
1. Scale up nextcloud
|
||||
`k -n nextcloud scale deployment cloud-deployment --replicas 1`
|
||||
2. Connect
|
||||
`k -n nextcloud exec -it cloud-deployment-... -- bash`
|
||||
3. Update db value in config.php
|
||||
`apt update`
|
||||
`apt install vim`
|
||||
`vim config/config.php`
|
||||
4. Update dbname field
|
||||
5. Verify server+website is working
|
|
@ -45,15 +45,17 @@ output "ipv4" {
|
|||
|
||||
## k8s minicluster
|
||||
|
||||
For k8s installation we use our [dda-k8s-crate](https://github.com/DomainDrivenArchitecture/dda-k8s-crate) with the following configuation:
|
||||
For k8s installation we use our [provs](https://repo.prod.meissa.de/meissa/provs) with the following configuation:
|
||||
|
||||
|
||||
```
|
||||
{:user :k8s
|
||||
:k8s {:external-ip "ip-from-above"}
|
||||
:cert-manager :letsencrypt-prod-issuer
|
||||
:persistent-dirs ["cloud", "postgres"]
|
||||
}
|
||||
postgres-db-user: "nextcloud"
|
||||
postgres-db-password: "nextcloud-db-password"
|
||||
nextcloud-admin-user: "cloudadmin"
|
||||
nextcloud-admin-password: "cloudpassword"
|
||||
aws-access-key-id: "aws-id"
|
||||
aws-secret-access-key: "aws-secret"
|
||||
restic-password: "restic-password"
|
||||
```
|
||||
|
||||
## kubectl apply c4k-nextcloud
|
||||
|
|
10
doc/Upgrade.md
Normal file
10
doc/Upgrade.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Upgrade with a new nextcloud version
|
||||
|
||||
1. Pull a new image
|
||||
1. Trigger deployment
|
||||
|
||||
```
|
||||
k3s crictl pull domaindrivenarchitecture/c4k-cloud
|
||||
k3s crictl images
|
||||
kubectl set env deployment cloud-deployment DEPLOY_DATE="$(date)"
|
||||
```
|
294
doc/backup.svg
Normal file
294
doc/backup.svg
Normal file
|
@ -0,0 +1,294 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="297mm"
|
||||
height="210mm"
|
||||
viewBox="0 0 297 210"
|
||||
version="1.1"
|
||||
id="svg3835"
|
||||
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
|
||||
sodipodi:docname="backup.svg">
|
||||
<defs
|
||||
id="defs3829" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4"
|
||||
inkscape:cx="401.60934"
|
||||
inkscape:cy="468.05499"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:snap-text-baseline="true"
|
||||
inkscape:window-width="3072"
|
||||
inkscape:window-height="1614"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata3832">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-87)">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
x="74.461304"
|
||||
y="214.22322"
|
||||
id="text3897"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3895"
|
||||
x="74.461304"
|
||||
y="214.22322"
|
||||
style="stroke-width:0.26458332">/var/jira</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="74.461304"
|
||||
y="219.51489"
|
||||
style="stroke-width:0.26458332"
|
||||
id="tspan3899">/var/postgres</tspan></text>
|
||||
<path
|
||||
id="path3843"
|
||||
d="m 23.928181,109.95955 c -0.03502,0.28187 -0.06495,0.56441 -0.105072,0.8456 -0.241563,1.69302 -0.514704,3.37966 -0.718689,5.07821 -0.224627,1.87044 -0.2236,2.05097 -0.387224,3.95474 -0.182611,3.20929 -0.396631,6.42977 -0.33565,9.64677 0.01463,0.77188 0.06165,1.54281 0.09247,2.31421 0.2865,4.13208 0.623369,8.26573 1.257784,12.36151 0.473742,3.05847 1.070569,6.05824 1.647011,9.09919 1.371342,7.38573 2.932193,14.74091 4.003443,22.17939 0.711486,4.94039 0.783532,6.24004 1.270172,11.18791 0.62489,7.91962 1.08907,15.86308 1.106733,23.80963 -0.08352,4.61198 -0.593383,9.2019 -0.930801,13.79934 -0.193958,3.15149 -0.256831,6.30687 -0.50723,9.45493 -0.191466,2.01724 -0.649743,3.99296 -1.26169,5.92065 -0.422531,1.31219 -1.134943,2.50065 -1.669743,3.76541 -0.02201,0.10972 -0.134403,0.3286 0.03627,0.41461 0.102896,0.0519 0.222845,0.0601 0.336483,0.0792 0.417455,0.07 0.836634,0.12944 1.255877,0.18775 1.872573,0.26047 3.305635,0.43219 5.224412,0.67266 9.134991,1.26831 18.356659,1.75044 27.564432,2.12585 4.020296,0.0609 8.049791,0.2484 12.07031,0.0726 1.16719,-0.051 2.572668,-0.17725 3.745476,-0.27392 2.929988,-0.26622 5.864217,-0.46476 8.802372,-0.61181 2.745777,-0.20556 5.492565,-0.3765 8.232034,-0.65588 1.80018,-0.12366 3.573132,-0.4627 5.367809,-0.62978 2.47194,-0.14926 4.95085,-0.13045 7.42637,-0.1494 1.49367,-0.009 2.98732,-0.0254 4.48103,-0.0248 2.29679,-0.0599 4.59581,-0.14828 6.89038,-0.27668 0.81386,-0.0997 1.68932,-0.0697 2.46058,-0.40019 0.12174,-0.0522 0.45801,-0.26514 0.33841,-0.20823 -0.77384,0.3683 -1.53526,0.76213 -2.3029,1.14319 0,0 2.51167,-1.2405 2.51167,-1.2405 v 0 c -0.79711,0.61588 -1.57648,1.25544 -2.39134,1.84764 -0.10539,0.0766 -0.23564,0.11344 -0.36009,0.15199 -0.78823,0.24415 -1.62793,0.23535 -2.44043,0.31034 -1.41196,0.0678 -2.82453,0.11789 -4.23623,0.19148 -0.17293,0.009 -1.91647,0.10988 -2.19401,0.11936 -0.17739,0.006 -0.35499,2.6e-4 -0.53249,5.3e-4 -1.47242,-0.004 -2.94479,-0.0239 -4.41725,-0.0192 -2.48349,0.007 -4.97162,0.005 -7.449094,0.19777 -1.777994,0.18636 -3.542387,0.48844 -5.328734,0.60062 -2.743859,0.25998 -5.492994,0.45303 -8.242266,0.64644 -2.925051,0.13255 -5.843926,0.35386 -8.762105,0.59232 -1.275369,0.0943 -2.432024,0.19257 -3.715295,0.23243 -3.976204,0.12353 -7.955569,-0.10992 -11.929526,-0.19412 -6.311511,-0.28924 -12.61361,-0.67269 -18.91022,-1.19841 -1.661732,-0.13874 -3.324495,-0.26742 -4.983742,-0.43325 -1.260668,-0.126 -2.516693,-0.29475 -3.775038,-0.44212 -1.010235,-0.11141 -2.020361,-0.22381 -3.030704,-0.33422 -0.776195,-0.0848 -1.553652,-0.15844 -2.328907,-0.25145 -0.358395,-0.043 -1.828279,0.006 -1.987163,-0.72851 -0.02454,-0.11344 0.02479,-0.2308 0.03718,-0.3462 0.529586,-1.27373 1.273345,-2.45184 1.71838,-3.76221 0.628139,-1.91168 1.102071,-3.87248 1.315069,-5.87713 0.281196,-3.15784 0.392117,-6.32368 0.578982,-9.4878 0.346115,-4.60085 0.895514,-9.19023 0.98575,-13.80717 0.117658,-7.97861 -0.22843,-15.9623 -0.844523,-23.91625 -0.478076,-4.94937 -0.54664,-6.24035 -1.250995,-11.18235 -1.058987,-7.43023 -2.624648,-14.77189 -4.077173,-22.13128 -0.371913,-1.88541 -1.410546,-7.07391 -1.745556,-9.06111 -0.687537,-4.0783 -1.054877,-8.20269 -1.384652,-12.32221 -0.04044,-0.77119 -0.0992,-1.54163 -0.121307,-2.31355 -0.0923,-3.22357 0.137938,-6.45038 0.325406,-9.6657 0.151052,-1.87677 0.152788,-2.11389 0.368253,-3.9587 0.226945,-1.9431 0.526741,-3.87837 0.708071,-5.82662 0,0 2.49922,-1.27341 2.49922,-1.27341 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3845"
|
||||
d="m 28.130875,108.00453 c 5.212191,0.57627 10.460583,0.70514 15.698888,0.82825 4.485651,0.0237 8.966081,0.25521 13.446953,0.43548 1.82303,0.0733 3.647096,0.12187 5.469533,0.20869 1.498195,0.0714 10.067176,0.57498 11.685537,0.66936 8.487032,0.51062 16.981302,0.91422 25.483994,0.99653 4.56085,0.0396 9.08507,-0.53046 13.60104,-1.08804 2.40321,-0.27519 4.81604,-0.44912 7.23241,-0.54969 0.46287,-0.0426 0.92916,-0.008 1.39242,-0.0399 0.49434,-0.0337 0.93148,-0.17323 1.41699,-0.0295 0.29303,0.22862 0.21115,0.5271 0.15648,0.85829 -0.0436,0.26401 -0.10151,0.52549 -0.14614,0.78933 -0.19575,1.15706 -0.28757,1.85842 -0.46203,3.0704 -0.61198,4.65348 -0.79895,9.36043 -0.89594,14.049 -0.0427,2.06422 -0.0653,4.12927 -0.0439,6.19381 0.0254,2.45295 0.12284,4.90463 0.18425,7.35695 0.48153,10.01687 1.49626,19.99668 2.22895,29.9961 0.23554,3.21446 0.57053,8.79293 0.77491,12.11225 0.0803,1.7862 0.16464,3.57223 0.24104,5.3586 0.19194,4.48776 0.19441,4.58821 0.30358,8.97704 0.08,3.21674 0.0712,4.4087 0.23315,7.6258 0.0606,1.20422 0.15109,2.40675 0.22663,3.61013 0.42017,5.78041 1.0165,11.54597 1.49742,17.32137 0.44429,3.51382 -0.078,7.0229 -0.49495,10.50984 -0.29104,1.84314 -0.35449,3.71791 -0.62928,5.56185 -0.0977,0.36571 -0.11623,0.52472 -0.29541,0.85607 -0.6173,1.14155 -2.46566,1.72568 -3.32773,2.08177 -0.1973,0.0815 -0.4255,-0.035 -0.63825,-0.0525 -1.12405,-0.13092 -2.21612,-0.46593 -3.2975,-0.78879 0,0 2.27468,-1.554 2.27468,-1.554 v 0 c 1.0698,0.31852 2.1536,0.64176 3.27325,0.71702 0.20072,-0.006 0.74975,-0.15519 0.60217,-0.019 -0.56743,0.52361 -1.2902,0.84877 -1.94491,1.25806 -0.0953,0.0596 0.18395,-0.13072 0.26548,-0.20817 0.30896,-0.29351 0.47998,-0.65737 0.58463,-1.06648 0.1146,-0.62083 0.17214,-1.24395 0.25,-1.87057 0.15476,-1.24543 0.32998,-2.48816 0.49009,-3.7329 0.44221,-3.47443 0.90709,-6.97153 0.54919,-10.47841 -0.39314,-5.80198 -0.95971,-11.58955 -1.373,-17.39009 -0.16694,-2.85115 -0.29084,-4.57227 -0.36291,-7.44826 -0.0319,-1.27522 -0.0208,-2.55119 -0.041,-3.82666 -0.076,-4.79717 -0.20739,-9.5941 -0.42868,-14.38687 -0.28729,-5.82808 -0.27671,-6.08872 -0.67926,-12.15673 -0.66433,-10.01409 -1.57629,-20.01014 -2.18762,-30.02802 -0.32945,-8.46033 -0.31545,-5.64351 -0.2831,-13.49137 0.0191,-4.63452 -0.0538,-9.3022 0.55233,-13.90778 0.15362,-1.26505 0.2577,-2.56066 0.48546,-3.81669 0.0217,-0.1195 0.0687,-0.2332 0.0945,-0.35187 0.025,-0.11466 0.0242,-0.0944 -0.0529,-0.12284 -0.27774,-0.038 -0.52963,-0.005 -0.80951,0.0191 -0.69672,0.0593 -0.40465,0.0348 -1.15318,0.0511 -0.25007,0.005 -0.50009,0.013 -0.75013,0.0195 -2.398,0.0884 -4.79305,0.25133 -7.17655,0.53493 -4.47608,0.50352 -8.96101,1.02749 -13.474878,0.95289 -2.786645,-0.0504 -4.346922,-0.0679 -7.187401,-0.16679 -6.047637,-0.21044 -12.086111,-0.6047 -18.125916,-0.96644 -1.888175,-0.11638 -3.775715,-0.2436 -5.664528,-0.34913 -8.359304,-0.46702 -16.731708,-0.72316 -25.102844,-0.83436 -5.323048,-0.11891 -10.646013,-0.25637 -15.95545,-0.68066 0,0 2.288922,-1.61708 2.288922,-1.61708 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3847"
|
||||
d="m 193.19838,160.92997 c 0.5335,0.99245 1.40599,2.07766 2.29191,2.76011 0.62363,0.48041 1.29755,0.89487 1.98014,1.28704 0.77762,0.44676 1.57,0.87399 2.39467,1.22642 1.06766,0.45626 2.18116,0.79676 3.27174,1.19515 1.46006,0.34668 2.90737,0.7523 4.38018,1.04005 3.46844,0.67765 7.24048,1.11215 10.74925,1.45797 3.35367,0.33053 7.44918,0.61489 10.79743,0.74796 1.76205,0.07 3.52599,0.0789 5.28899,0.1183 2.7261,-0.0447 6.38393,-0.0253 9.1317,-0.36261 1.39512,-0.17125 2.78187,-0.42677 4.1487,-0.75455 2.71805,-0.65182 5.04542,-1.53001 7.58796,-2.65977 1.01883,-0.45271 2.00248,-0.98076 3.00372,-1.47114 2.00901,-1.31808 4.09153,-2.60725 5.81013,-4.30854 0.2469,-0.24442 0.47226,-0.50968 0.7084,-0.76452 0.9743,-1.16709 1.64367,-2.45964 2.2502,-3.84058 0,0 2.50494,-1.14891 2.50494,-1.14891 v 0 c -0.15213,0.34969 -0.54049,1.2568 -0.70974,1.58476 -0.4281,0.82955 -0.98118,1.5899 -1.52302,2.34633 -0.23675,0.26359 -0.46117,0.53881 -0.71028,0.79078 -0.65135,0.65881 -1.30146,1.18183 -2.04358,1.74594 -2.59143,1.96986 -5.38693,3.63452 -8.25788,5.16721 -0.99113,0.47505 -1.96536,0.9871 -2.9734,1.42514 -2.53897,1.10332 -4.88417,1.96936 -7.59298,2.59997 -1.37082,0.31912 -2.76107,0.56624 -4.15928,0.72757 -2.65887,0.30679 -6.44337,0.26647 -9.0692,0.29154 -4.32665,-0.1181 -6.54556,-0.13457 -10.91571,-0.44008 -1.72226,-0.12039 -3.44115,-0.28683 -5.15897,-0.4593 -3.52774,-0.35417 -7.35185,-0.77398 -10.84527,-1.42405 -1.50374,-0.27983 -2.98423,-0.67268 -4.47635,-1.00902 -1.11776,-0.39319 -2.25955,-0.72378 -3.35328,-1.17956 -0.83885,-0.34956 -1.63938,-0.78753 -2.43236,-1.23144 -0.71089,-0.39795 -1.42116,-0.80548 -2.07486,-1.29169 -0.42711,-0.31768 -0.78355,-0.72185 -1.1506,-1.10737 -0.80351,-0.84391 -0.76491,-0.85198 -1.28775,-1.67297 0,0 2.43445,-1.38614 2.43445,-1.38614 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3849"
|
||||
d="m 190.18307,160.00292 c 2.00424,-2.85472 4.84564,-4.98907 7.55472,-7.1314 2.41218,-1.63 3.54608,-2.50276 6.71473,-3.77643 2.17758,-0.87531 7.3175,-1.69 9.37707,-2.01647 5.00434,-0.79326 5.8307,-0.80686 10.89647,-1.32614 6.71624,-0.64395 13.46511,-0.85066 20.20776,-0.97444 1.50289,-0.0276 3.00573,-0.0674 4.50887,-0.0707 1.33781,-0.003 2.6754,0.0346 4.01311,0.0519 1.15708,0.0887 2.31926,0.12592 3.47125,0.26597 1.86256,0.22645 3.82339,0.65977 5.62961,1.18349 1.25525,0.36398 2.45942,0.79614 3.62883,1.37788 0.42381,0.21083 0.82187,0.4699 1.2328,0.70485 1.19623,0.85324 0.65169,0.41677 1.64719,1.29225 0,0 -2.33434,1.44914 -2.33434,1.44914 v 0 c -0.95166,-0.85841 -0.42979,-0.42955 -1.57941,-1.26954 -0.39806,-0.23232 -0.78391,-0.487 -1.19421,-0.69697 -2.71335,-1.38851 -6.07218,-2.20444 -9.07148,-2.58285 -1.13521,-0.14322 -2.28065,-0.18843 -3.42098,-0.28265 -1.32364,-0.0246 -2.64706,-0.0696 -3.97092,-0.0739 -1.49078,-0.005 -2.98154,0.0217 -4.47213,0.0464 -6.72442,0.11145 -13.45204,0.34355 -20.15165,0.95691 -4.5776,0.48001 -6.372,0.59809 -10.89659,1.34855 -1.79029,0.29694 -3.58213,0.59897 -5.34984,1.00954 -1.41139,0.3278 -2.77219,0.84839 -4.17706,1.20315 -0.12363,0.0312 -0.26624,-0.11239 -0.37891,-0.0527 -0.66899,0.3546 -1.26153,0.83768 -1.89231,1.25651 -2.66631,2.09232 -5.45443,4.18036 -7.43991,6.96766 0,0 -2.55267,1.13995 -2.55267,1.13995 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3851"
|
||||
d="m 271.68872,164.83536 c -0.0127,1.74752 -0.12738,3.50552 -0.0491,5.25222 0.1239,2.76402 0.52413,6.13937 0.8355,8.83661 0.20754,1.79771 0.43309,3.5933 0.64963,5.38995 0.56689,4.92216 1.13493,9.8446 1.65391,14.77212 0.11784,1.1188 0.24506,2.23686 0.3375,3.35804 0.0691,0.83754 0.098,1.6779 0.14692,2.51685 0,0 -2.30772,1.18831 -2.30772,1.18831 v 0 c -0.0233,-0.84789 -0.0225,-1.69678 -0.0697,-2.54368 -0.0632,-1.13305 -0.16462,-2.26371 -0.26143,-3.39439 -0.42363,-4.94827 -0.95422,-9.88746 -1.55602,-14.81705 -0.23063,-1.78972 -0.46164,-3.57941 -0.69193,-5.36918 -0.28557,-2.21921 -0.85466,-6.38358 -1.04156,-8.75811 -0.13528,-1.7184 -0.0665,-3.44122 -0.13952,-5.16118 0,0 2.49352,-1.27051 2.49352,-1.27051 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3853"
|
||||
d="m 195.60386,172.0818 c -0.0651,0.4794 -0.14584,0.95692 -0.19518,1.43819 -0.19379,1.89011 -0.3049,3.99332 -0.3868,5.86731 -0.19254,4.40526 -0.18355,8.80255 -0.16306,13.21087 0.0403,4.10293 0.11093,8.20549 0.19664,12.30769 0.0134,0.64224 0.0912,4.58278 0.14929,5.46495 0.043,0.65245 0.13756,1.30046 0.20634,1.95068 0.27639,0.51376 0.41499,1.13045 0.82919,1.54127 0.52711,0.5228 1.22402,0.85441 1.89867,1.16428 1.89625,0.87098 4.04282,1.23653 6.08733,1.47647 3.9029,0.45803 7.86212,0.54041 11.7811,0.70475 7.64075,0.12222 15.29998,0.43674 22.93373,-0.0868 3.64098,-0.2497 5.99962,-0.57571 9.56465,-1.00445 3.83084,-0.47534 7.78869,-1.06074 11.08432,-3.23077 0.1174,-0.0773 -0.51343,0.15062 -0.41911,0.0464 0.43361,-0.47913 0.99636,-0.82315 1.49454,-1.23473 1.70629,-1.60527 3.52041,-3.08587 5.29876,-4.60806 0.42077,-0.32181 0.76028,-0.71441 1.07712,-1.13346 0,0 2.56246,-1.11086 2.56246,-1.11086 v 0 c -0.30729,0.45155 -0.63042,0.87882 -1.07796,1.20613 -1.80253,1.54921 -3.68192,3.0101 -5.40265,4.6543 -2.46313,2.06823 -1.60455,1.46471 -5.5653,3.81584 -0.68571,0.40703 -1.38404,0.79974 -2.11643,1.11513 -2.80683,1.20869 -5.87047,1.56384 -8.87252,1.9217 -3.3331,0.37247 -6.1303,0.72024 -9.50557,0.93997 -7.61323,0.49563 -15.24312,0.15276 -22.86126,0.0108 -3.28354,-0.11147 -8.63341,-0.22688 -12.01268,-0.57694 -2.11302,-0.21888 -4.30145,-0.57367 -6.25034,-1.48659 -0.71617,-0.33548 -1.45418,-0.69724 -2.01109,-1.25874 -0.43532,-0.43891 -0.5764,-1.09376 -0.86459,-1.64064 -0.059,-0.6626 -0.14586,-1.32331 -0.17689,-1.9878 -0.0271,-0.58076 -0.0458,-5.25701 -0.0476,-5.51961 -0.0284,-4.11731 -0.0757,-8.23445 -0.11467,-12.35166 -0.0206,-2.67387 -0.0621,-6.43756 -0.0341,-9.12418 0.014,-1.34823 0.0532,-2.6961 0.0871,-4.04398 0.0458,-1.8215 0.10238,-3.94926 0.21347,-5.80017 0.0285,-0.47489 0.0779,-0.94828 0.11687,-1.42242 0,0 2.49629,-1.21488 2.49629,-1.21488 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3855"
|
||||
d="m 142.16697,190.72343 c 5.77242,0.10734 11.54659,0.0846 17.3198,0.0836 4.53725,-0.008 9.07893,0.0205 13.61217,-0.20134 0.33318,-0.0212 0.66639,-0.0416 0.99952,-0.0635 0.27,-0.0178 0.54072,-0.0274 0.80984,-0.0555 0.69715,-0.0729 1.38432,-0.23923 2.07276,-0.36617 0.14615,-0.017 0.2923,-0.0339 0.43845,-0.0509 0,0 -2.23815,1.67138 -2.23815,1.67138 v 0 c -0.14417,0.0214 -0.28835,0.0427 -0.43252,0.064 -1.27053,0.23212 -2.54377,0.41189 -3.84031,0.40563 -4.4826,0.14092 -8.96823,0.0588 -13.45213,0.0716 -5.84997,-0.001 -11.70082,-0.0221 -17.55005,0.0836 0,0 2.26062,-1.64243 2.26062,-1.64243 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3857"
|
||||
d="m 180.63866,185.95955 c 0.39579,0.21823 0.76251,0.3614 1.00662,0.7924 0.50105,0.88465 0.27921,2.07038 -0.0491,2.96158 -0.13567,0.36833 -0.33831,0.7084 -0.50746,1.0626 -0.6136,0.8265 -0.68879,1.01307 -1.43598,1.69765 -0.47214,0.43258 -0.9632,0.77606 -1.51153,1.10078 -2.79757,1.6567 -2.05448,1.27539 -3.61662,2.04121 0,0 2.16488,-1.73245 2.16488,-1.73245 v 0 c 0.9952,-0.51297 1.25762,-0.6606 -1.1139,0.68573 -0.25618,0.14543 0.51442,-0.2886 0.7584,-0.45367 0.88751,-0.60049 1.64794,-1.34313 2.27191,-2.21521 0.17463,-0.33756 0.3814,-0.66033 0.52389,-1.01266 0.30297,-0.74912 0.61126,-1.91262 0.15791,-2.6843 -0.22325,-0.38003 -0.60929,-0.50405 -0.97199,-0.67479 0,0 2.32292,-1.56887 2.32292,-1.56887 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3859"
|
||||
d="m 74.040039,202.1013 c 1.507289,1.67348 3.504721,2.75904 5.600263,3.52615 0.55113,0.20175 1.118431,0.35625 1.677646,0.53437 1.950511,0.48369 3.944366,0.76727 5.947238,0.9126 1.288558,0.0935 2.176814,0.1221 3.459017,0.0103 0.521981,-0.0455 1.038468,-0.14047 1.5577,-0.2107 1.265732,-0.2562 2.55479,-0.50869 3.735051,-1.05717 0.349396,-0.16237 1.38388,-0.658 1.011413,-0.55947 -1.058336,0.27997 -2.209734,1.36382 -0.511803,-0.0587 1.247434,-1.10126 2.285596,-2.39581 3.315695,-3.69331 0.466311,-0.58466 0.919351,-1.1802 1.363181,-1.78211 0,0 2.55374,-1.10497 2.55374,-1.10497 v 0 c -0.43793,0.61052 -0.89795,1.20514 -1.36142,1.79631 -0.44073,0.53921 -0.85326,1.10361 -1.3069,1.632 -0.63909,0.74439 -1.333603,1.44195 -2.034053,2.12772 -1.72271,1.48945 -0.892429,0.84756 -4.142402,2.79106 -0.331811,0.19842 -0.677235,0.37571 -1.032076,0.5292 -1.190781,0.51509 -2.476402,0.75178 -3.743634,0.98569 -1.438405,0.16989 -1.776455,0.25672 -3.256442,0.23322 -2.612707,-0.0415 -5.218718,-0.47649 -7.759948,-1.0515 -0.566111,-0.18297 -1.140685,-0.34157 -1.698329,-0.54891 -2.142085,-0.79644 -4.163666,-1.92417 -5.76861,-3.56946 0,0 2.394673,-1.44229 2.394673,-1.44229 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3861"
|
||||
d="m 71.10673,201.52597 c 0.643126,-1.58881 1.656485,-2.71609 3.164761,-3.55887 3.806999,-2.12725 2.884733,-1.72346 5.86037,-2.62764 0.642199,-0.14271 1.277829,-0.3191 1.926595,-0.42813 2.456664,-0.41287 5.225613,-0.3823 7.69896,-0.0969 0.556775,0.0643 1.108614,0.16578 1.662919,0.24867 3.157416,0.55558 6.210628,1.53956 9.245585,2.54867 1.00864,0.36413 2.0228,0.71255 3.03419,1.06892 0,0 -2.27774,1.53781 -2.27774,1.53781 v 0 c -0.99895,-0.36538 -1.999434,-0.72646 -3.000634,-1.08563 -3.005698,-1.03649 -6.047787,-1.99591 -9.18978,-2.52817 -0.549254,-0.0795 -1.096296,-0.17624 -1.647759,-0.23864 -3.187039,-0.36062 -6.444607,-0.25475 -9.547738,0.59499 -0.622554,0.20012 -1.213901,0.58557 -1.867662,0.60037 -0.276881,0.006 0.861581,-0.67055 0.602853,-0.57174 -0.490368,0.18727 -0.913635,0.5244 -1.326774,0.8482 -0.84821,0.66478 -1.423202,1.52686 -1.803001,2.52113 0,0 -2.535145,1.16693 -2.535145,1.16693 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3863"
|
||||
d="m 105.94426,203.6241 c -0.0774,3.13849 -0.0294,6.27793 -0.10347,9.41633 -0.0444,1.8556 -0.13938,3.70985 -0.29802,5.55909 0,0 -2.45094,1.21885 -2.45094,1.21885 v 0 c 0.20354,-1.85246 0.32489,-3.71286 0.37576,-5.57604 0.0789,-3.1158 0.048,-6.23358 -0.013,-9.34965 0,0 2.48971,-1.26858 2.48971,-1.26858 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3865"
|
||||
d="m 73.248368,205.72606 c -0.0702,2.5347 -0.01323,5.07624 -0.187372,7.60759 -0.04694,0.68233 -0.126355,1.36203 -0.189529,2.04305 -0.401125,3.81892 -0.946928,7.62002 -1.401321,11.43247 0.01254,0.5006 -0.268473,1.65792 -0.04123,2.15876 0.243404,0.53646 1.04376,0.598 1.505339,0.69076 2.35145,0.34734 4.734378,0.36014 7.105465,0.3519 2.28845,-0.008 4.196141,-0.039 6.472481,-0.24556 0.983051,-0.0892 1.959581,-0.23966 2.939372,-0.35949 3.122198,-0.48599 6.242206,-1.16273 9.198364,-2.30184 1.451313,-0.55925 1.728583,-0.74629 3.070483,-1.43918 -0.37853,0.20119 -0.76335,0.81617 -1.13559,0.60358 -0.34286,-0.19582 0.64224,-0.46047 0.94735,-0.71108 0.8686,-0.71344 1.33821,-1.3312 1.95486,-2.24946 0,0 2.51536,-1.10287 2.51536,-1.10287 v 0 c -0.41359,0.64604 -0.61765,1.02496 -1.14832,1.59838 -1.44125,1.55737 -3.43512,2.50061 -5.228325,3.53907 -1.337117,0.66701 -1.624436,0.85266 -3.066981,1.38871 -2.94893,1.09582 -6.053064,1.74048 -9.157023,2.20116 -0.977085,0.11163 -1.951291,0.25229 -2.931258,0.33489 -2.344893,0.19767 -4.117057,0.21009 -6.475851,0.22832 -2.440538,0.0189 -4.900285,0.0622 -7.325659,-0.26607 -0.636019,-0.15702 -1.394045,-0.26647 -1.704671,-0.95979 -0.239847,-0.53535 0.06696,-1.72365 0.07386,-2.25979 0.52143,-3.81411 1.111699,-7.62021 1.468487,-11.45486 0.06027,-0.67507 0.133829,-1.34909 0.180817,-2.02521 0.174373,-2.50918 0.126362,-5.02365 0.07309,-7.53583 0,0 2.487811,-1.26761 2.487811,-1.26761 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3867"
|
||||
d="m 35.834431,122.05478 c -0.02482,1.68544 -0.02981,3.37113 -0.03304,5.05673 0.0094,2.28586 -0.0057,4.5717 -0.008,6.85756 -0.0011,2.9198 -0.01577,5.83954 -0.0083,8.75935 0.0033,1.97579 0.02397,3.95148 0.03406,5.92723 0.0072,1.55377 -0.02784,3.10769 0.01495,4.66102 0.05444,0.33104 0.09041,1.52222 0.354116,1.78613 0.377682,0.37798 1.887767,0.43831 2.013063,0.44966 0.827985,0.075 1.659409,0.1054 2.489113,0.1581 4.551852,0.18 9.105723,-0.0311 13.651394,-0.26213 1.07778,-0.0293 2.14513,-0.10983 3.206377,-0.29364 0,0 -2.210163,1.65728 -2.210163,1.65728 v 0 c -1.046464,0.13666 -2.096428,0.19512 -3.152134,0.21796 -4.531821,0.18725 -9.067496,0.36587 -13.603571,0.19433 -0.858866,-0.0412 -1.719937,-0.0495 -2.576602,-0.12354 -0.674431,-0.0583 -1.710918,-0.0462 -2.256261,-0.64626 -0.252434,-0.27777 -0.320858,-1.5331 -0.368729,-1.87929 -0.04287,-1.55345 -0.02233,-3.10783 -0.03025,-4.66176 0.01011,-1.98732 0.03071,-3.97458 0.03406,-5.96194 0.0074,-2.91697 -0.0072,-5.83388 -0.0083,-8.75086 -0.0024,-2.28315 -0.01733,-4.5663 -0.008,-6.84945 -0.0032,-1.67438 -0.0081,-3.34884 -0.03304,-5.02306 0,0 2.499219,-1.27342 2.499219,-1.27342 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3869"
|
||||
d="m 40.584712,121.9865 c 0.498113,0.11343 0.990994,0.25298 1.494343,0.34031 2.010733,0.34886 4.123611,0.54239 6.147109,0.70866 3.606906,0.29637 7.218821,0.45789 10.834672,0.58618 1.620785,0.0684 3.243352,0.0125 4.864481,0.0509 0.529473,0.0125 1.058884,0.036 1.587164,0.0737 0.678071,0.0484 1.283737,-0.0212 1.738008,0.5864 0.17522,0.23436 0.205161,0.54809 0.307742,0.82214 0.01598,0.37833 0.05977,0.75651 0.04791,1.13499 -0.02111,0.67338 -0.252058,2.49434 -0.325684,3.10731 -0.202919,1.68938 -0.434636,3.37405 -0.664421,5.05994 -0.494827,3.18499 -0.852848,6.38825 -1.115259,9.60013 -0.169127,2.15341 -0.195643,4.31361 -0.215466,6.47235 -0.0042,1.0658 -1.24e-4,2.13163 0.01016,3.19738 0.0019,0.18323 0.0646,0.37608 0.006,0.54969 -0.07552,0.22367 -0.260657,0.39369 -0.390983,0.59054 -1.025247,0.60637 -2.02066,1.26628 -3.075739,1.81911 -0.296063,0.15513 -0.634852,0.21099 -0.958445,0.29468 -0.503224,0.13015 -1.54963,0.32993 -2.071452,0.38149 -0.682532,0.0675 -1.496163,0.0528 -2.181407,0.0541 -0.822127,0.0169 -1.636073,-0.0573 -2.447608,-0.17561 0,0 2.267672,-1.5987 2.267672,-1.5987 v 0 c 0.792737,0.11176 1.58795,0.18319 2.39041,0.16609 1.42929,-0.0161 2.826375,-0.0932 4.205769,-0.50933 0.319016,-0.0962 1.179671,-0.57486 0.938112,-0.34534 -0.459462,0.43659 -1.080574,0.66273 -1.620861,0.99409 0.155152,-0.13571 0.375155,-0.22183 0.465452,-0.40713 0.08098,-0.16618 0.0021,-0.36971 0.0032,-0.55457 0.0056,-1.0709 0.0075,-2.14183 0.01413,-3.21273 0.01368,-2.17066 0.06919,-4.34188 0.236832,-6.50679 0.287692,-3.22057 0.653671,-6.43372 1.145921,-9.62991 0.223935,-1.68297 0.461496,-3.36444 0.658161,-5.0509 0.07077,-0.60684 0.273759,-2.37481 0.296183,-3.04662 0.01167,-0.34927 -0.02228,-0.69857 -0.03342,-1.04785 -0.07476,-0.224 -0.08296,-0.48281 -0.224274,-0.67202 -0.369726,-0.49501 -1.071184,-0.45973 -1.588992,-0.50526 -0.512035,-0.045 -1.025464,-0.0751 -1.539071,-0.0955 -1.592897,-0.0632 -3.188565,-0.0381 -4.78097,-0.11917 -3.607866,-0.1603 -7.213135,-0.34901 -10.815079,-0.61519 -2.097146,-0.15498 -4.23716,-0.31151 -6.322317,-0.62374 -0.527897,-0.079 -1.047128,-0.20787 -1.570694,-0.31181 0,0 2.28272,-1.5619 2.28272,-1.5619 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3871"
|
||||
d="m 82.625876,125.72272 c -0.590052,1.9898 -1.079457,4.00817 -1.54796,6.02952 -0.682681,2.95934 -1.168435,5.95705 -1.498238,8.97478 -0.262927,2.55099 -0.303504,5.11635 -0.322953,7.67842 0.01564,1.67949 -0.0052,3.35782 -0.07779,5.03575 0.103463,0.18674 -0.110289,0.46148 -0.01212,0.65746 0.03164,0.0632 0.115509,0.0909 0.185066,0.10334 0.30395,0.0542 0.61368,0.0696 0.921459,0.094 1.525428,0.12113 1.960073,0.11184 3.638783,0.16671 0.892161,0.0144 1.78427,0.0325 2.676482,0.0432 1.03428,0.0124 2.068648,0.0358 3.102957,0.026 2.930279,-0.0279 5.856242,-0.19776 8.779586,-0.38465 0,0 -2.087144,1.53535 -2.087144,1.53535 v 0 c -4.862857,0.26507 -9.730195,0.43375 -14.601097,0.31891 -0.887127,-0.0159 -2.749844,-0.0202 -3.749027,-0.12622 -0.454885,-0.0483 -1.110398,0.002 -1.36597,-0.49673 -0.03415,-0.0666 0.01749,-0.66528 0.01879,-0.68467 0.111789,-1.68384 0.170061,-3.369 0.147976,-5.05701 0.02527,-2.57356 0.04294,-5.153 0.33243,-7.71367 0.333661,-3.01949 0.814113,-6.02018 1.458138,-8.98985 0.452032,-2.00988 0.955966,-4.00785 1.475766,-6.00112 0,0 2.524866,-1.20952 2.524866,-1.20952 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3873"
|
||||
d="m 86.947041,125.7817 c 5.284819,0.22555 10.570421,0.42877 15.858099,0.57355 1.78635,0.10916 3.5911,-0.0218 5.3721,0.18996 0.415,0.0493 0.70451,0.11706 1.1035,0.19994 0.47456,0.18832 1.02456,0.1829 1.48017,0.42204 0.23318,0.12239 0.29224,0.21013 0.46889,0.39152 0.0504,0.0834 0.12362,0.15683 0.15132,0.25031 0.16054,0.54186 -0.0369,1.18359 -0.16114,1.70386 -0.0889,0.37233 -0.40365,1.58799 -0.48614,1.9086 -0.64307,2.33282 -1.04354,4.7138 -1.26108,7.12074 -0.15426,2.04713 -0.13376,4.10078 -0.2076,6.15119 0.007,1.32962 -0.12049,2.54741 -0.39619,3.8438 -0.32023,1.38543 -0.48611,2.79839 -0.59454,4.21414 -0.0767,0.64965 0.0209,1.37681 -0.25767,1.99155 -0.0439,0.0968 -0.11191,0.18072 -0.16786,0.27109 -2.51966,1.98133 -3.75158,2.11991 -6.53947,2.28631 -2.410197,0.11517 -4.819432,-0.10635 -7.222053,-0.27265 -0.767215,-0.0267 -1.527794,-0.10896 -2.285624,-0.22528 0,0 2.271609,-1.59845 2.271609,-1.59845 v 0 c 0.741993,0.11244 1.486681,0.19536 2.23687,0.23305 2.395603,0.17962 4.800908,0.39573 7.204228,0.23833 0.71464,-0.0543 1.19399,-0.0751 1.89255,-0.18502 0.25787,-0.0406 0.51515,-0.0879 0.76836,-0.15136 0.19939,-0.05 0.75232,-0.31085 0.58718,-0.18845 -0.99723,0.73917 -2.75674,1.57268 -1.49579,0.96392 0.0689,-0.0628 0.15271,-0.11253 0.20677,-0.18854 0.31807,-0.44727 0.2458,-1.4075 0.31087,-1.93129 0.12423,-1.42596 0.28572,-2.85186 0.5923,-4.25171 0.12036,-0.58224 0.25051,-1.16779 0.31548,-1.75982 0.0562,-0.51178 0.053,-0.79567 0.0765,-1.31868 0.0109,-0.24333 0.0243,-0.48653 0.0364,-0.72979 0.0903,-2.0584 0.0937,-4.11957 0.22766,-6.17604 0.0807,-0.93415 0.10478,-1.36811 0.2386,-2.29752 0.23583,-1.63795 0.61742,-3.2494 0.99635,-4.85857 0.25885,-1.05269 0.22449,-0.90335 0.4585,-1.88884 0.0798,-0.33626 0.3063,-1.12296 0.22387,-1.49443 -0.0161,-0.0726 -0.077,-0.12732 -0.11546,-0.19098 -0.49738,-0.47039 -1.21328,-0.49567 -1.84367,-0.69014 -2.07144,-0.43255 -4.20028,-0.33393 -6.30258,-0.45532 -5.315789,-0.20095 -10.631863,-0.41989 -15.950962,-0.50852 0,0 2.209703,-1.5925 2.209703,-1.5925 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3875"
|
||||
d="m 39.42045,171.8741 c -0.386061,3.07114 -0.825233,6.13534 -1.193122,9.20898 -0.325438,2.75157 -0.460682,5.51909 -0.517205,8.2876 -0.07618,1.33576 0.122145,2.66699 0.530346,3.93752 0.251127,0.59229 0.386845,0.54578 1.048401,0.583 0.442587,0.0249 0.885439,0.0462 1.328516,0.0599 0.73439,0.0226 1.469117,0.0325 2.203674,0.0487 0.99631,0.011 1.992564,0.0299 2.988932,0.033 1.667436,0.005 4.801145,-0.0262 6.470452,-0.048 1.08346,-0.0141 4.085306,-0.0541 5.283252,-0.11613 0.606796,-0.0314 1.211231,-0.0983 1.816847,-0.14752 0.383124,-0.09 0.766249,-0.18008 1.149373,-0.27012 0,0 -2.171319,1.64692 -2.171319,1.64692 v 0 c -0.374234,0.0682 -0.748466,0.13633 -1.122701,0.2045 -0.593473,0.0351 -1.186278,0.0845 -1.780421,0.10546 -1.044802,0.0368 -4.32322,0.0576 -5.220382,0.0661 -3.179358,0.03 -6.358723,0.0678 -9.538287,0.0652 -0.758175,-0.002 -1.51641,0.004 -2.274523,-0.006 -0.466423,-0.006 -0.933749,-0.005 -1.398757,-0.0419 -0.752882,-0.0596 -0.969369,-0.18472 -1.234966,-0.83876 -0.40009,-1.30923 -0.605938,-2.67916 -0.512268,-4.04945 0.07915,-2.78506 0.218033,-5.56834 0.555382,-8.33603 0.378595,-3.03989 0.809051,-6.07462 1.099066,-9.1246 0,0 2.48971,-1.26857 2.48971,-1.26857 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3877"
|
||||
d="m 41.127254,171.0983 c 5.502198,0.6054 11.022999,0.98873 16.548107,1.30717 1.769994,0.0896 3.08473,0.14105 4.816068,0.27928 0.783788,0.0626 2.59589,0.12526 3.235497,0.81271 0.149976,0.16119 0.1881,0.39815 0.282149,0.59722 -0.0058,0.28725 0.01892,0.57674 -0.0173,0.86176 -0.137467,1.08131 -0.633929,2.13435 -0.977966,3.15649 -0.409279,1.21599 -0.44527,1.37954 -0.802749,2.59214 -0.521033,1.85894 -0.765349,3.77645 -1.162063,5.66243 -0.0776,0.25012 -0.145298,0.50354 -0.232804,0.75037 -0.174321,0.49172 -0.402199,0.96322 -0.579366,1.45391 -0.271359,0.75157 -0.449863,1.51498 -0.612434,2.29541 0,0 -2.487181,1.20429 -2.487181,1.20429 v 0 c 0.160972,-0.7906 0.3293,-1.57549 0.594601,-2.3395 0.351806,-1.01315 0.210518,-0.45006 0.585753,-1.43782 0.09045,-0.2381 0.162351,-0.48285 0.243528,-0.72427 0.41207,-1.89958 0.691454,-3.82664 1.201462,-5.70447 0.307348,-1.04118 0.453091,-1.56165 0.792528,-2.60107 0.328207,-1.00503 0.787952,-2.01953 0.972253,-3.06702 0.04277,-0.24309 0.03952,-0.49205 0.05927,-0.73808 -0.06189,-0.15243 -0.07336,-0.33707 -0.185671,-0.45727 -0.579885,-0.62066 -2.361078,-0.71636 -3.054485,-0.78324 -1.752089,-0.16898 -2.91846,-0.225 -4.726493,-0.33904 -5.586902,-0.36182 -11.169819,-0.77655 -16.755512,-1.15302 0,0 2.262812,-1.62838 2.262812,-1.62838 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:6.3499999px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
x="39.6875"
|
||||
y="135.41519"
|
||||
id="text3881"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3879"
|
||||
x="39.6875"
|
||||
y="135.41519"
|
||||
style="stroke-width:0.26458332">jira-pod</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:6.3499999px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
x="84.666664"
|
||||
y="135.60417"
|
||||
id="text3885"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3883"
|
||||
x="84.666664"
|
||||
y="135.60417"
|
||||
style="stroke-width:0.26458332">backup</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="84.666664"
|
||||
y="143.54167"
|
||||
style="stroke-width:0.26458332"
|
||||
id="tspan3887">pod</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.23333333px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
x="41.955357"
|
||||
y="180.58334"
|
||||
id="text3891"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3889"
|
||||
x="41.955357"
|
||||
y="180.58334"
|
||||
style="stroke-width:0.26458332">postgres</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="41.955357"
|
||||
y="188.52084"
|
||||
style="stroke-width:0.26458332"
|
||||
id="tspan3893">pod</tspan></text>
|
||||
<path
|
||||
id="path3907"
|
||||
d="m 52.944442,158.72263 c -0.494538,1.16082 -0.734864,2.40421 -0.908976,3.64743 -0.144328,1.19587 -0.152612,2.40227 -0.155803,3.6051 -0.0011,0.5429 0.0011,1.08579 0.0044,1.62868 0,0 -2.483165,1.26595 -2.483165,1.26595 v 0 c 0.0011,-0.54498 2.14e-4,-1.08995 0.0029,-1.63493 0.01069,-1.21331 -0.0028,-2.43073 0.139443,-3.63784 0.171741,-1.25572 0.411848,-2.50691 0.851694,-3.69971 0,0 2.549472,-1.17468 2.549472,-1.17468 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3909"
|
||||
d="m 48.702891,196.58962 c -0.983491,1.38136 -1.620311,2.94593 -2.079914,4.56733 -0.20266,0.86633 -0.362188,1.75156 -0.359669,2.64457 0.0011,0.39477 0.03945,0.70759 0.07655,1.09786 0.133447,0.70089 0.12818,1.57125 0.544298,2.18748 0.0759,0.11239 0.181306,0.20175 0.271957,0.30262 0.145984,0.10334 0.279003,0.22801 0.437952,0.31002 0.476173,0.24569 1.311666,0.45462 1.778269,0.57179 1.466292,0.3682 2.942921,0.61885 4.435962,0.84728 2.846943,0.39365 5.69304,0.79395 8.53716,1.20799 1.030647,0.15529 2.067353,0.23849 3.107126,0.29421 0,0 -2.232737,1.6009 -2.232737,1.6009 v 0 c -1.037595,-0.0746 -2.073079,-0.16892 -3.10208,-0.32668 -2.831767,-0.43649 -5.66892,-0.83888 -8.507153,-1.23063 -1.506183,-0.23508 -3.003103,-0.48864 -4.485291,-0.85044 -0.620178,-0.15138 -1.307746,-0.30904 -1.879489,-0.62406 -0.174649,-0.0962 -0.320207,-0.23772 -0.480309,-0.35659 -0.105394,-0.1223 -0.226369,-0.23274 -0.316185,-0.36689 -0.43444,-0.64893 -0.433845,-1.54238 -0.57804,-2.27942 -0.03598,-0.37414 -0.08011,-0.75709 -0.08497,-1.13331 -0.01183,-0.91532 0.141254,-1.82249 0.345377,-2.71159 0.447873,-1.62994 1.06616,-3.21228 2.008486,-4.62608 0,0 2.562694,-1.12636 2.562694,-1.12636 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3911"
|
||||
d="m 67.962922,208.49623 c 1.070838,0.31779 2.167284,0.54226 3.214373,0.93861 0.197241,0.0747 0.397279,0.14594 0.582877,0.2461 0.125605,0.0678 0.229637,0.16957 0.344458,0.25435 0.01669,0.12371 0.08987,0.25281 0.05009,0.37113 -0.04888,0.14537 -0.16351,0.27326 -0.293905,0.354 -0.928216,0.57473 -1.886839,1.10107 -2.85886,1.59814 -0.206107,0.1054 -0.440912,0.14168 -0.664032,0.20338 -0.717156,0.1983 -0.81847,0.20034 -1.564466,0.3399 -1.206381,0.11959 -2.377842,0.43781 -3.573502,0.61874 -0.447103,0.0779 -0.86301,0.25918 -1.280184,0.42923 0,0 2.194981,-1.72259 2.194981,-1.72259 v 0 c 0.430683,-0.15951 0.861899,-0.32128 1.320041,-0.38459 1.17993,-0.19528 2.348624,-0.4561 3.536698,-0.6044 0.660292,-0.13819 0.917766,-0.17416 1.553038,-0.37515 0.222552,-0.0704 0.846693,-0.37617 0.658627,-0.2379 -0.60353,0.44372 -1.297225,0.7514 -1.921076,1.16606 -0.110376,0.0734 0.256448,-0.0744 0.373182,-0.13719 0.04729,-0.0254 0.07108,-0.0805 0.106611,-0.12075 -0.497805,-0.36195 -0.972431,-0.50844 -1.562304,-0.6935 -0.832008,-0.26102 -1.685035,-0.4405 -2.523384,-0.67847 0,0 2.306741,-1.5651 2.306741,-1.5651 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3913"
|
||||
d="m 39.426155,195.73705 c 0.130109,1.74138 0.315502,3.4774 0.411678,5.22191 0.02657,2.29955 0.218123,4.5906 0.346969,6.8854 0.181595,2.14019 0.03349,4.27787 -0.127632,6.41272 -0.167685,2.00592 -0.548558,3.98491 -0.761238,5.98502 -1.43e-4,0.0239 -0.03462,0.7161 0.05031,0.83327 0.08978,0.12385 0.629618,0.0619 0.766376,0.0481 0.409287,-0.0413 1.421601,-0.21601 1.769012,-0.27324 3.044381,-0.61198 6.140601,-0.86782 9.236567,-1.02681 2.907319,-0.14732 5.818301,-0.15465 8.728422,-0.17088 2.001536,-0.0442 4.002434,-0.11204 6.00371,-0.1659 0.51657,-0.009 1.030671,-0.0181 1.545387,-0.0615 0,0 -2.249906,1.65733 -2.249906,1.65733 v 0 c -0.509751,0.0241 -1.019328,0.0303 -1.529659,0.0352 -1.98863,0.0367 -3.976619,0.0997 -5.965323,0.13113 -2.895195,-10e-4 -5.791366,0.0239 -8.684,0.15555 -3.110183,0.17656 -6.218859,0.45175 -9.273397,1.09096 -0.592434,0.0975 -2.393484,0.57517 -2.8227,-0.10631 -0.09725,-0.1544 -0.05146,-0.83294 -0.04986,-0.92063 0.23949,-1.99988 0.613863,-3.98168 0.793954,-5.98933 0.152844,-2.12428 0.324363,-4.25145 0.143322,-6.38112 -0.126492,-2.29393 -0.30217,-4.58494 -0.351922,-6.8825 -0.101545,-1.74025 -0.254855,-3.47516 -0.481187,-5.20391 0,0 2.501122,-1.27438 2.501122,-1.27438 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3915"
|
||||
d="m 66.072366,216.95851 c 0.159356,0.069 0.31765,0.1405 0.47807,0.20698 0.56293,0.2333 0.612868,0.25391 1.231924,0.41939 0.341617,0.0913 0.903883,0.17795 1.224502,0.38031 0.109281,0.069 0.172664,0.19232 0.258998,0.28847 -0.02923,0.15056 -0.0055,0.32217 -0.0877,0.45168 -0.102698,0.16184 -0.272053,0.27585 -0.436468,0.37439 -0.992952,0.59509 -2.007229,1.15454 -3.027447,1.70157 -0.833075,0.44669 -1.7858,0.70879 -2.675686,1.01244 -0.305697,0.10363 -0.611394,0.20726 -0.917094,0.31088 0,0 2.165753,-1.68434 2.165753,-1.68434 v 0 c 0.304175,-0.10313 0.608353,-0.20626 0.912529,-0.30939 0.62801,-0.21987 1.247357,-0.42545 1.861008,-0.68377 0.27492,-0.11573 1.052922,-0.55116 0.812953,-0.37399 -2.543275,1.87773 -2.042072,1.11792 -1.007078,0.65271 -0.05659,-0.0634 -0.09585,-0.14825 -0.169759,-0.19019 -0.312222,-0.17717 -0.882116,-0.28123 -1.199301,-0.36981 -0.602935,-0.16838 -1.18201,-0.38839 -1.759529,-0.62828 0,0 2.334326,-1.55905 2.334326,-1.55905 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3917"
|
||||
d="m 51.503606,167.96544 c -0.08266,0.89345 -0.109286,1.78994 -0.201771,2.68247 -0.01302,0.12242 -0.02604,0.24483 -0.03904,0.36725 0,0 -2.508607,1.24347 -2.508607,1.24347 v 0 c 0.01418,-0.12277 0.02838,-0.24555 0.04257,-0.36833 0.101182,-0.88755 0.144767,-1.778 0.196094,-2.66975 0,0 2.510758,-1.25511 2.510758,-1.25511 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3919"
|
||||
d="m 45.447285,198.11493 c 0.01156,-0.12851 0.02313,-0.25702 0.03471,-0.38552 0,0 2.503757,-1.2502 2.503757,-1.2502 v 0 c -0.0092,0.12687 -0.01847,0.25374 -0.0277,0.38061 0,0 -2.510759,1.25511 -2.510759,1.25511 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3921"
|
||||
d="m 64.059876,171.53602 c 1.900489,-1.71523 3.942122,-3.26578 5.944502,-4.85871 1.85697,-1.49953 3.883628,-2.7665 5.94346,-3.96428 1.576517,-0.98722 3.241336,-1.80545 4.884642,-2.66746 0,0 -2.147583,1.72401 -2.147583,1.72401 v 0 c -0.665753,0.34578 -3.396488,1.79756 -0.192357,-0.0335 -2.067388,1.18774 -4.103844,2.44352 -5.971104,3.93239 -1.985666,1.5694 -4.009927,3.0999 -5.879319,4.80838 0,0 -2.582241,1.05918 -2.582241,1.05918 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3923"
|
||||
d="m 77.394656,160.5203 c 1.71513,-0.51237 3.402428,-1.10991 5.106115,-1.65813 0.731046,-0.20514 1.445453,-0.47607 2.192218,-0.61835 0.104561,-0.0199 0.20833,-0.0604 0.314616,-0.0546 0.07719,0.004 0.14428,0.0555 0.216419,0.0833 0.03782,0.12287 0.115371,0.24007 0.113466,0.36862 -0.0043,0.28902 -0.259276,0.78355 -0.381381,1.01141 -0.3425,0.63913 -0.75638,1.23516 -1.172686,1.82705 -0.133842,0.17621 -0.267687,0.35242 -0.401532,0.52864 0,0 -2.54744,1.09328 -2.54744,1.09328 v 0 c 0.136983,-0.17389 0.273966,-0.34778 0.410946,-0.52168 0.421023,-0.57643 0.823592,-1.16024 1.177112,-1.78149 0.716511,-1.25915 -0.09667,0.13344 0.422593,-0.85095 0.01468,-0.0278 0.04181,-0.047 0.06272,-0.0706 -0.855752,0.009 -1.756891,0.50569 -2.587709,0.67547 -1.716987,0.54835 -3.422219,1.13217 -5.135367,1.69243 0,0 2.209911,-1.72442 2.209911,-1.72442 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3925"
|
||||
d="m 91.683138,212.09182 c 1.137703,-1.27556 2.22654,-2.5865 3.263471,-3.9453 0.205557,-0.29666 0.41461,-0.59094 0.616672,-0.88999 0.201801,-0.29867 0.410565,-0.59327 0.594834,-0.90306 0.767257,-1.28989 1.24637,-2.68889 1.649878,-4.12529 0.522272,-2.45874 -0.09514,-4.92399 -0.664305,-7.31516 -0.480769,-1.80394 -1.205447,-3.52772 -1.834835,-5.28175 -0.298577,-0.8321 -0.5046,-1.46266 -0.781976,-2.29274 -0.695264,-2.33261 -0.985563,-4.7562 -1.379644,-7.1512 -0.210613,-1.35997 -0.401425,-2.72626 -0.525383,-4.09719 -0.104293,-1.69462 -0.09761,-3.39385 -0.106246,-5.09099 -0.0078,-0.97578 -0.01262,-1.95157 -0.01765,-2.92736 0,0 2.474648,-1.26073 2.474648,-1.26073 v 0 c -0.006,0.98012 -0.01124,1.96025 -0.0113,2.94039 0.0083,1.68507 0.0096,3.37227 0.125936,5.05414 0.125944,1.37044 0.28489,2.73904 0.477658,4.10158 0.364437,2.38643 0.652237,4.7988 1.351819,7.11689 0.817494,2.55338 1.826959,5.03793 2.613068,7.6012 0.501657,2.05518 1.054037,4.2044 0.903427,6.33968 -0.0258,0.36576 -0.10537,0.72574 -0.15806,1.08861 -0.392003,1.44997 -0.858281,2.89413 -1.614436,4.20269 -0.180864,0.31299 -0.392888,0.60693 -0.592895,0.90804 -0.200612,0.30204 -0.405952,0.60091 -0.60893,0.90137 -1.017805,1.34721 -2.073376,2.65982 -3.194034,3.92315 0,0 -2.581733,1.10302 -2.581733,1.10302 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<path
|
||||
id="path3927"
|
||||
d="m 86.290988,166.10648 c 1.277006,-1.25353 2.595866,-2.46288 3.881532,-3.70761 1.234541,-1.2677 2.435617,-2.17255 4.171458,-2.88723 0.218774,-0.0901 0.879158,0.68042 0.917866,0.72019 0.503224,0.62344 0.920787,1.30821 1.349386,1.98309 0,0 -2.385978,1.39024 -2.385978,1.39024 v 0 c -0.413814,-0.65854 -0.815473,-1.32949 -1.329338,-1.9175 -0.137113,-0.12254 -0.252312,-0.27528 -0.411338,-0.36762 -0.09482,-0.0551 -0.411628,0.006 -0.323577,-0.0591 0.633148,-0.4698 1.346676,-0.82077 2.032794,-1.20913 0.151402,-0.0857 -0.292542,0.18973 -0.426956,0.30018 -0.224541,0.18451 -0.861785,0.816 -1.046877,0.99661 -1.276379,1.23421 -2.592424,2.42705 -3.843401,3.6869 0,0 -2.585571,1.07098 -2.585571,1.07098 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="stroke-width:0.26458332" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:6.3499999px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
x="137.20535"
|
||||
y="180.77232"
|
||||
id="text3931"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3929"
|
||||
x="137.20535"
|
||||
y="180.77232"
|
||||
style="stroke-width:0.26458332">restic - backup</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:6.3499999px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
x="206.375"
|
||||
y="180.58334"
|
||||
id="text3954"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3952"
|
||||
x="206.375"
|
||||
y="180.58334"
|
||||
style="stroke-width:0.26458332">S3-Bucket</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="206.375"
|
||||
y="188.52084"
|
||||
style="stroke-width:0.26458332"
|
||||
id="tspan3956" /><tspan
|
||||
sodipodi:role="line"
|
||||
x="206.375"
|
||||
y="196.45834"
|
||||
style="stroke-width:0.26458332"
|
||||
id="tspan3958">with folder /jira</tspan></text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 42 KiB |
BIN
doc/tryItOut.png
Normal file
BIN
doc/tryItOut.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 63 KiB |
30
infrastructure/README.md
Normal file
30
infrastructure/README.md
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Build images
|
||||
|
||||
## Prerequisites
|
||||
|
||||
See also https://pypi.org/project/ddadevops/
|
||||
|
||||
```bash
|
||||
# Ensure that yout python3 version is at least Python 3.7!
|
||||
|
||||
sudo apt install python3-pip
|
||||
pip3 install pip --upgrade --user
|
||||
pip3 install pybuilder ddadevops deprecation --user
|
||||
export PATH=$PATH:~/.local/bin
|
||||
|
||||
# terraform
|
||||
pip3 install dda-python-terraform --user
|
||||
|
||||
# AwsMixin
|
||||
pip3 install boto3 --user
|
||||
|
||||
# AwsMfaMixin
|
||||
pip3 install boto3 mfa --user
|
||||
```
|
||||
|
||||
In folder "docker-backup" resp. "docker-nextcloud":
|
||||
|
||||
```bash
|
||||
# step test is optional
|
||||
pyb image test publish
|
||||
```
|
54
infrastructure/backup/build.py
Normal file
54
infrastructure/backup/build.py
Normal file
|
@ -0,0 +1,54 @@
|
|||
from os import environ
|
||||
from datetime import datetime
|
||||
from pybuilder.core import task, init
|
||||
from ddadevops import *
|
||||
|
||||
name = "c4k-cloud"
|
||||
MODULE = "backup"
|
||||
PROJECT_ROOT_PATH = "../.."
|
||||
version = "10.2.1-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,4 +1,4 @@
|
|||
FROM domaindrivenarchitecture/dda-backup
|
||||
FROM domaindrivenarchitecture/dda-backup:latest
|
||||
|
||||
# Prepare Entrypoint Script
|
||||
ADD resources /tmp
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -o pipefail
|
||||
set -Eexo pipefail
|
||||
|
||||
function main() {
|
||||
|
||||
|
@ -11,7 +11,8 @@ function main() {
|
|||
file_env POSTGRES_DB
|
||||
file_env POSTGRES_PASSWORD
|
||||
file_env POSTGRES_USER
|
||||
file_env RESTIC_DAYS_TO_KEEP 14
|
||||
file_env RESTIC_DAYS_TO_KEEP 30
|
||||
file_env RESTIC_MONTHS_TO_KEEP 12
|
||||
|
||||
backup-roles 'oc_'
|
||||
backup-db-dump
|
|
@ -1,5 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -exo pipefail
|
||||
|
||||
if test -f "/var/backups/config/config.orig"; then
|
||||
|
||||
rm /var/backups/config/config.php
|
|
@ -1,5 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -exo pipefail
|
||||
|
||||
function main() {
|
||||
file_env POSTGRES_DB
|
||||
file_env POSTGRES_PASSWORD
|
|
@ -1,5 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -Eexo pipefail
|
||||
|
||||
function main() {
|
||||
file_env POSTGRES_DB
|
||||
file_env POSTGRES_PASSWORD
|
|
@ -1,5 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -Eexo pipefail
|
||||
|
||||
function main() {
|
||||
file_env AWS_ACCESS_KEY_ID
|
||||
file_env AWS_SECRET_ACCESS_KEY
|
21
infrastructure/backup/image/resources/install.sh
Executable file
21
infrastructure/backup/image/resources/install.sh
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -exo pipefail
|
||||
|
||||
function main() {
|
||||
{
|
||||
install -m 0700 /tmp/entrypoint.sh /
|
||||
install -m 0700 /tmp/entrypoint-start-and-wait.sh /
|
||||
|
||||
install -m 0700 /tmp/init.sh /usr/local/bin/
|
||||
install -m 0700 /tmp/backup.sh /usr/local/bin/
|
||||
install -m 0700 /tmp/restore.sh /usr/local/bin/
|
||||
install -m 0700 /tmp/list-snapshots.sh /usr/local/bin/
|
||||
install -m 0700 /tmp/start-maintenance.sh /usr/local/bin/
|
||||
install -m 0700 /tmp/end-maintenance.sh /usr/local/bin/
|
||||
cleanupDocker
|
||||
} > /dev/null
|
||||
}
|
||||
|
||||
source /tmp/install_functions_debian.sh
|
||||
main
|
31
infrastructure/backup/image/resources/list-snapshots.sh
Executable file
31
infrastructure/backup/image/resources/list-snapshots.sh
Executable file
|
@ -0,0 +1,31 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -exo pipefail
|
||||
|
||||
function list-snapshot-files() {
|
||||
if [ -z ${CERTIFICATE_FILE} ];
|
||||
then
|
||||
restic -r ${RESTIC_REPOSITORY}/${backup_file_path} snapshots
|
||||
else
|
||||
restic -r ${RESTIC_REPOSITORY}/${backup_file_path} snapshots --cacert ${CERTIFICATE_FILE}
|
||||
fi
|
||||
}
|
||||
|
||||
function main() {
|
||||
file_env AWS_ACCESS_KEY_ID
|
||||
file_env AWS_SECRET_ACCESS_KEY
|
||||
|
||||
file_env POSTGRES_DB
|
||||
file_env POSTGRES_PASSWORD
|
||||
file_env POSTGRES_USER
|
||||
|
||||
list-snapshot-roles
|
||||
list-snapshot-db
|
||||
list-snapshot-files
|
||||
}
|
||||
|
||||
source /usr/local/lib/functions.sh
|
||||
source /usr/local/lib/file-functions.sh
|
||||
source /usr/local/lib/pg-functions.sh
|
||||
|
||||
main
|
|
@ -1,8 +1,12 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -Eeo pipefail
|
||||
set -Eexo pipefail
|
||||
|
||||
function main() {
|
||||
local role_snapshot_id="${1:-latest}"
|
||||
local db_snapshot_id="${2:-latest}"
|
||||
local file_snapshot_id="${3:-latest}"
|
||||
|
||||
|
||||
start-maintenance.sh
|
||||
|
||||
|
@ -15,14 +19,15 @@ function main() {
|
|||
|
||||
drop-create-db
|
||||
|
||||
restore-roles
|
||||
restore-db
|
||||
restore-directory '/var/backups/'
|
||||
restore-roles ${role_snapshot_id}
|
||||
restore-db ${db_snapshot_id}
|
||||
restore-directory '/var/backups/' ${file_snapshot_id}
|
||||
|
||||
end-maintenance.sh
|
||||
}
|
||||
|
||||
source /usr/local/lib/functions.sh
|
||||
source /usr/local/lib/pg-functions.sh
|
||||
source /usr/local/lib/file-functions.sh
|
||||
main
|
||||
|
||||
main "$@"
|
|
@ -4,7 +4,10 @@ if [ ! -f "/var/backups/config/config.orig" ]; then
|
|||
|
||||
rm -f /var/backups/config/config.orig
|
||||
cp /var/backups/config/config.php /var/backups/config/config.orig
|
||||
|
||||
# put nextcloud in maintenance mode
|
||||
sed -i "s/);/ \'maintenance\' => true,\n);/g" /var/backups/config/config.php
|
||||
|
||||
chown www-data:root /var/backups/config/config.php
|
||||
touch /var/backups/config/config.php
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
from os import environ
|
||||
from pybuilder.core import task, init
|
||||
from ddadevops import *
|
||||
import logging
|
||||
|
||||
name = 'c4k-cloud-backup'
|
||||
MODULE = 'docker'
|
||||
PROJECT_ROOT_PATH = '../..'
|
||||
|
||||
|
||||
class MyBuild(DevopsDockerBuild):
|
||||
pass
|
||||
|
||||
@init
|
||||
def initialize(project):
|
||||
project.build_depends_on('ddadevops>=0.12.4')
|
||||
stage = 'notused'
|
||||
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')
|
||||
config = create_devops_docker_build_config(
|
||||
stage, PROJECT_ROOT_PATH, MODULE, dockerhub_user, dockerhub_password)
|
||||
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 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,12 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
apt-get update > /dev/null;
|
||||
|
||||
install -m 0700 /tmp/entrypoint.sh /
|
||||
install -m 0700 /tmp/entrypoint-start-and-wait.sh /
|
||||
|
||||
install -m 0700 /tmp/init.sh /usr/local/bin/
|
||||
install -m 0700 /tmp/backup.sh /usr/local/bin/
|
||||
install -m 0700 /tmp/restore.sh /usr/local/bin/
|
||||
install -m 0700 /tmp/start-maintenance.sh /usr/local/bin/
|
||||
install -m 0700 /tmp/end-maintenance.sh /usr/local/bin/
|
|
@ -1,10 +0,0 @@
|
|||
FROM meissa-cloud-backup
|
||||
|
||||
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
|
|
@ -1,7 +0,0 @@
|
|||
{:file [{:path "/usr/local/bin/init.sh" :mod "700"}
|
||||
{:path "/usr/local/bin/backup.sh" :mod "700"}
|
||||
{:path "/usr/local/bin/restore.sh" :mod "700"}
|
||||
{:path "/usr/local/bin/start-maintenance.sh" :mod "700"}
|
||||
{:path "/usr/local/bin/end-maintenance.sh" :mod "700"}
|
||||
{:path "/entrypoint.sh" :mod "700"}
|
||||
{:path "/entrypoint-start-and-wait.sh" :mod "700"}]}
|
|
@ -1,49 +0,0 @@
|
|||
from os import environ
|
||||
from pybuilder.core import task, init
|
||||
from ddadevops import *
|
||||
import logging
|
||||
|
||||
name = 'c4k-cloud'
|
||||
MODULE = 'docker'
|
||||
PROJECT_ROOT_PATH = '../..'
|
||||
|
||||
|
||||
class MyBuild(DevopsDockerBuild):
|
||||
pass
|
||||
|
||||
@init
|
||||
def initialize(project):
|
||||
project.build_depends_on('ddadevops>=0.12.7')
|
||||
stage = 'notused'
|
||||
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')
|
||||
config = create_devops_docker_build_config(
|
||||
stage, PROJECT_ROOT_PATH, MODULE, dockerhub_user, dockerhub_password)
|
||||
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 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,11 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -Eeo pipefail
|
||||
|
||||
apt update && apt -qqy install postgresql-client > /dev/null
|
||||
|
||||
mkdir /var/data
|
||||
|
||||
install -m 0700 /tmp/install-debug.sh /usr/local/bin/
|
||||
install -m 0544 /tmp/upload-max-limit.ini /usr/local/etc/php/conf.d/
|
||||
install -m 0544 /tmp/memory-limit.ini /usr/local/etc/php/conf.d/
|
||||
install -m 0755 /tmp/entrypoint.sh /
|
|
@ -1,11 +0,0 @@
|
|||
FROM meissa-cloud-app
|
||||
|
||||
RUN apt update
|
||||
RUN mkdir /usr/share/man/man1/
|
||||
RUN apt -yqq install --no-install-recommends --yes 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
|
|
@ -1,2 +0,0 @@
|
|||
{:file [{:path "/var/data"}
|
||||
{:path "/entrypoint.sh" :mod "755"}]}
|
53
infrastructure/nextcloud/build.py
Normal file
53
infrastructure/nextcloud/build.py
Normal file
|
@ -0,0 +1,53 @@
|
|||
from os import environ
|
||||
from datetime import datetime
|
||||
from pybuilder.core import task, init
|
||||
from ddadevops import *
|
||||
|
||||
name = 'c4k-cloud'
|
||||
MODULE = 'not_set'
|
||||
PROJECT_ROOT_PATH = '../..'
|
||||
version = "10.2.1-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_ONLY",
|
||||
"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,4 +1,7 @@
|
|||
FROM nextcloud:22
|
||||
FROM nextcloud:29
|
||||
|
||||
# REQUIRES docker >= 2.10.10
|
||||
# https://docs.docker.com/engine/release-notes/20.10/#201010
|
||||
|
||||
# Prepare Entrypoint Script
|
||||
ADD resources /tmp
|
|
@ -1,5 +1,6 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
#!/bin/bash
|
||||
|
||||
set -exo pipefail
|
||||
|
||||
# version_greater A B returns whether A > B
|
||||
version_greater() {
|
20
infrastructure/nextcloud/image/resources/install.sh
Executable file
20
infrastructure/nextcloud/image/resources/install.sh
Executable file
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
set -exo pipefail
|
||||
|
||||
function main() {
|
||||
{
|
||||
upgradeSystem
|
||||
apt-get install -qqy ca-certificates curl gnupg postgresql-client
|
||||
mkdir /var/data
|
||||
} > /dev/null
|
||||
|
||||
install -m 0700 /tmp/install-debug.sh /usr/local/bin/
|
||||
install -m 0544 /tmp/upload-max-limit.ini /usr/local/etc/php/conf.d/
|
||||
install -m 0544 /tmp/memory-limit.ini /usr/local/etc/php/conf.d/
|
||||
install -m 0755 /tmp/entrypoint.sh /
|
||||
|
||||
cleanupDocker
|
||||
}
|
||||
|
||||
source /tmp/install_functions_debian.sh
|
||||
DEBIAN_FRONTEND=noninteractive DEBCONF_NOWARNINGS=yes main
|
64
package.json
64
package.json
|
@ -1,33 +1,33 @@
|
|||
{
|
||||
"name": "c4k-nextcloud",
|
||||
"description": "Generate c4k yaml for a nextcloud deployment.",
|
||||
"author": "meissa GmbH",
|
||||
"version": "0.1.3-SNAPSHOT",
|
||||
"homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud#readme",
|
||||
"repository": "https://www.npmjs.com/package/c4k-nextcloud",
|
||||
"license": "APACHE2",
|
||||
"main": "c4k-nextcloud.js",
|
||||
"bin": {
|
||||
"c4k-nextcloud": "./c4k-nextcloud.js"
|
||||
},
|
||||
"keywords": [
|
||||
"cljs",
|
||||
"nextcloud",
|
||||
"k8s",
|
||||
"c4k",
|
||||
"deployment",
|
||||
"yaml",
|
||||
"convention4kubernetes"
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"js-base64": "^3.6.1",
|
||||
"js-yaml": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"shadow-cljs": "^2.11.18",
|
||||
"source-map-support": "^0.5.19"
|
||||
}
|
||||
}
|
||||
"name": "c4k-nextcloud",
|
||||
"description": "Generate c4k yaml for a nextcloud deployment.",
|
||||
"author": "meissa GmbH",
|
||||
"version": "10.2.1-SNAPSHOT",
|
||||
"homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud#readme",
|
||||
"repository": "https://www.npmjs.com/package/c4k-nextcloud",
|
||||
"license": "APACHE2",
|
||||
"main": "c4k-nextcloud.js",
|
||||
"bin": {
|
||||
"c4k-nextcloud": "./c4k-nextcloud.js"
|
||||
},
|
||||
"keywords": [
|
||||
"cljs",
|
||||
"nextcloud",
|
||||
"k8s",
|
||||
"c4k",
|
||||
"deployment",
|
||||
"yaml",
|
||||
"convention4kubernetes"
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"js-base64": "^3.6.1",
|
||||
"js-yaml": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"shadow-cljs": "^2.11.18",
|
||||
"source-map-support": "^0.5.19"
|
||||
}
|
||||
}
|
32
project.clj
32
project.clj
|
@ -1,19 +1,20 @@
|
|||
(defproject org.domaindrivenarchitecture/c4k-nextcloud "1.0.2-SNAPSHOT"
|
||||
(defproject org.domaindrivenarchitecture/c4k-nextcloud "10.2.1-SNAPSHOT"
|
||||
:description "nextcloud c4k-installation package"
|
||||
:url "https://domaindrivenarchitecture.org"
|
||||
:license {:name "Apache License, Version 2.0"
|
||||
:url "https://www.apache.org/licenses/LICENSE-2.0.html"}
|
||||
:dependencies [[org.clojure/clojure "1.10.3"]
|
||||
[org.clojure/tools.reader "1.3.4"]
|
||||
[org.domaindrivenarchitecture/c4k-common-clj "0.3.2-SNAPSHOT"]]
|
||||
:dependencies [[org.clojure/clojure "1.11.3"]
|
||||
[org.clojure/tools.reader "1.4.2"]
|
||||
[org.domaindrivenarchitecture/c4k-common-clj "6.3.1"]
|
||||
[hickory "0.7.1" :exclusions [viebel/codox-klipse-theme]]]
|
||||
:target-path "target/%s/"
|
||||
:source-paths ["src/main/cljc"
|
||||
"src/main/clj"]
|
||||
:resource-paths ["src/main/resources"]
|
||||
:repositories [["snapshots" :clojars]
|
||||
["releases" :clojars]]
|
||||
:deploy-repositories [["snapshots" :clojars]
|
||||
["releases" :clojars]]
|
||||
:deploy-repositories [["snapshots" {:sign-releases false :url "https://clojars.org/repo"}]
|
||||
["releases" {:sign-releases false :url "https://clojars.org/repo"}]]
|
||||
:profiles {:test {:test-paths ["src/test/cljc"]
|
||||
:resource-paths ["src/test/resources"]
|
||||
:dependencies [[dda/data-test "0.1.1"]]}
|
||||
|
@ -21,21 +22,14 @@
|
|||
:uberjar {:aot :all
|
||||
:main dda.c4k-nextcloud.uberjar
|
||||
:uberjar-name "c4k-nextcloud-standalone.jar"
|
||||
:dependencies [[org.clojure/tools.cli "1.0.206"]
|
||||
[ch.qos.logback/logback-classic "1.3.0-alpha4"
|
||||
:dependencies [[org.clojure/tools.cli "1.1.230"]
|
||||
[ch.qos.logback/logback-classic "1.5.6"
|
||||
:exclusions [com.sun.mail/javax.mail]]
|
||||
[org.slf4j/jcl-over-slf4j "2.0.0-alpha1"]]}}
|
||||
[org.slf4j/jcl-over-slf4j "2.0.13"]
|
||||
[com.github.clj-easy/graal-build-time "1.0.5"]]}}
|
||||
:release-tasks [["test"]
|
||||
["vcs" "assert-committed"]
|
||||
["change" "version" "leiningen.release/bump-version" "release"]
|
||||
["vcs" "commit"]
|
||||
["vcs" "tag"]
|
||||
["change" "version" "leiningen.release/bump-version"]]
|
||||
:aliases {"native" ["shell"
|
||||
"native-image"
|
||||
"--report-unsupported-elements-at-runtime"
|
||||
"--initialize-at-build-time"
|
||||
"-jar" "target/uberjar/c4k-nextcloud-standalone.jar"
|
||||
"-H:ResourceConfigurationFiles=graalvm-resource-config.json"
|
||||
"-H:Log=registerResource"
|
||||
"-H:Name=target/graalvm/${:name}"]})
|
||||
["vcs" "tag" "v" "--no-sign"]
|
||||
["change" "version" "leiningen.release/bump-version"]])
|
|
@ -4,7 +4,7 @@
|
|||
"src/test/cljc"
|
||||
"src/test/cljs"
|
||||
"src/test/resources"]
|
||||
:dependencies [[org.domaindrivenarchitecture/c4k-common-cljs "0.4.3"]
|
||||
:dependencies [[org.domaindrivenarchitecture/c4k-common-cljs "6.3.1"]
|
||||
[hickory "0.7.1"]]
|
||||
:builds {:frontend {:target :browser
|
||||
:modules {:main {:init-fn dda.c4k-nextcloud.browser/init}}
|
||||
|
@ -12,5 +12,4 @@
|
|||
:compiler-options {:optimizations :advanced}}
|
||||
:test {:target :node-test
|
||||
:output-to "target/node-tests.js"
|
||||
:autorun true
|
||||
:repl-pprint true}}}
|
|
@ -1,56 +1,15 @@
|
|||
(ns dda.c4k-nextcloud.uberjar
|
||||
(:gen-class)
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]
|
||||
[clojure.string :as cs]
|
||||
[clojure.tools.reader.edn :as edn]
|
||||
[expound.alpha :as expound]
|
||||
[dda.c4k-common.uberjar :as uberjar]
|
||||
[dda.c4k-nextcloud.nextcloud :as nextcloud]
|
||||
[dda.c4k-nextcloud.core :as core]))
|
||||
|
||||
(def usage
|
||||
"usage:
|
||||
|
||||
c4k-nextcloud {your configuraton file} {your authorization file}")
|
||||
|
||||
(s/def ::options (s/* #{"-h"}))
|
||||
(s/def ::filename (s/and string?
|
||||
#(not (cs/starts-with? % "-"))))
|
||||
(s/def ::cmd-args (s/cat :options ::options
|
||||
:args (s/?
|
||||
(s/cat :config ::filename
|
||||
:auth ::filename))))
|
||||
|
||||
(defn expound-config
|
||||
[config]
|
||||
(expound/expound ::core/config config))
|
||||
|
||||
(defn invalid-args-msg
|
||||
[spec args]
|
||||
(s/explain spec args)
|
||||
(println (str "Bad commandline arguments\n" usage)))
|
||||
|
||||
(defn -main [& cmd-args]
|
||||
(let [parsed-args-cmd (s/conform ::cmd-args cmd-args)]
|
||||
(if (= ::s/invalid parsed-args-cmd)
|
||||
(invalid-args-msg ::cmd-args cmd-args)
|
||||
(let [{:keys [options args]} parsed-args-cmd
|
||||
{:keys [config auth]} args]
|
||||
(cond
|
||||
(some #(= "-h" %) options)
|
||||
(println usage)
|
||||
:default
|
||||
(let [config-str (slurp config)
|
||||
auth-str (slurp auth)
|
||||
config-edn (edn/read-string config-str)
|
||||
auth-edn (edn/read-string auth-str)
|
||||
config-valid? (s/valid? core/config? config-edn)
|
||||
auth-valid? (s/valid? core/auth? auth-edn)]
|
||||
(if (and config-valid? auth-valid?)
|
||||
(println (core/generate config-edn auth-edn))
|
||||
(do
|
||||
(when (not config-valid?)
|
||||
(println
|
||||
(expound/expound-str core/config? config-edn {:print-specs? false})))
|
||||
(when (not auth-valid?)
|
||||
(println
|
||||
(expound/expound-str core/auth? auth-edn {:print-specs? false})))))))))))
|
||||
(uberjar/main-common
|
||||
"c4k-nextcloud"
|
||||
nextcloud/config?
|
||||
nextcloud/auth?
|
||||
core/config-defaults
|
||||
core/k8s-objects
|
||||
cmd-args))
|
||||
|
|
|
@ -1,37 +1,40 @@
|
|||
(ns dda.c4k-nextcloud.backup
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]
|
||||
#?(:cljs [shadow.resource :as rc])
|
||||
[dda.c4k-common.yaml :as yaml]
|
||||
[dda.c4k-common.base64 :as b64]
|
||||
[dda.c4k-common.common :as cm]))
|
||||
[dda.c4k-common.common :as cm]
|
||||
[dda.c4k-common.predicate :as cp]
|
||||
#?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]])))
|
||||
|
||||
(s/def ::aws-access-key-id cm/bash-env-string?)
|
||||
(s/def ::aws-secret-access-key cm/bash-env-string?)
|
||||
(s/def ::restic-password cm/bash-env-string?)
|
||||
(s/def ::restic-repository cm/bash-env-string?)
|
||||
(s/def ::aws-access-key-id cp/bash-env-string?)
|
||||
(s/def ::aws-secret-access-key cp/bash-env-string?)
|
||||
(s/def ::restic-password cp/bash-env-string?)
|
||||
(s/def ::restic-repository cp/bash-env-string?)
|
||||
|
||||
#?(:cljs
|
||||
(defmethod yaml/load-resource :backup [resource-name]
|
||||
(case resource-name
|
||||
"backup/config.yaml" (rc/inline "backup/config.yaml")
|
||||
"backup/cron.yaml" (rc/inline "backup/cron.yaml")
|
||||
"backup/secret.yaml" (rc/inline "backup/secret.yaml")
|
||||
(throw (js/Error. "Undefined Resource!")))))
|
||||
(get (inline-resources "backup") resource-name)))
|
||||
|
||||
(defn generate-config [my-conf]
|
||||
(let [{:keys [restic-repository]} my-conf]
|
||||
(->
|
||||
(yaml/from-string (yaml/load-resource "backup/config.yaml"))
|
||||
(yaml/load-as-edn "backup/config.yaml")
|
||||
(cm/replace-key-value :restic-repository restic-repository))))
|
||||
|
||||
(defn generate-cron []
|
||||
(yaml/from-string (yaml/load-resource "backup/cron.yaml")))
|
||||
|
||||
(defn generate-backup-restore-deployment [my-conf]
|
||||
(let [backup-restore-yaml (yaml/load-as-edn "backup/backup-restore-deployment.yaml")]
|
||||
(if (and (contains? my-conf :local-integration-test) (= true (:local-integration-test my-conf)))
|
||||
(cm/replace-named-value backup-restore-yaml "CERTIFICATE_FILE" "/var/run/secrets/localstack-secrets/ca.crt")
|
||||
backup-restore-yaml)))
|
||||
|
||||
(defn generate-secret [my-auth]
|
||||
(let [{:keys [aws-access-key-id aws-secret-access-key restic-password]} my-auth]
|
||||
(->
|
||||
(yaml/from-string (yaml/load-resource "backup/secret.yaml"))
|
||||
(yaml/load-as-edn "backup/secret.yaml")
|
||||
(cm/replace-key-value :aws-access-key-id (b64/encode aws-access-key-id))
|
||||
(cm/replace-key-value :aws-secret-access-key (b64/encode aws-secret-access-key))
|
||||
(cm/replace-key-value :restic-password (b64/encode restic-password)))))
|
||||
|
|
|
@ -1,53 +1,43 @@
|
|||
(ns dda.c4k-nextcloud.core
|
||||
(:require
|
||||
[clojure.string :as cs]
|
||||
[clojure.spec.alpha :as s]
|
||||
#?(:clj [orchestra.core :refer [defn-spec]]
|
||||
:cljs [orchestra.core :refer-macros [defn-spec]])
|
||||
[dda.c4k-common.yaml :as yaml]
|
||||
[dda.c4k-common.postgres :as postgres]
|
||||
[dda.c4k-nextcloud.nextcloud :as nextcloud]
|
||||
[dda.c4k-nextcloud.backup :as backup]))
|
||||
(:require
|
||||
#?(:clj [orchestra.core :refer [defn-spec]]
|
||||
:cljs [orchestra.core :refer-macros [defn-spec]])
|
||||
[dda.c4k-common.common :as cm]
|
||||
[dda.c4k-common.predicate :as cp]
|
||||
[dda.c4k-common.yaml :as yaml]
|
||||
[dda.c4k-common.postgres :as postgres]
|
||||
[dda.c4k-nextcloud.nextcloud :as nextcloud]
|
||||
[dda.c4k-nextcloud.backup :as backup]
|
||||
[dda.c4k-common.monitoring :as mon]
|
||||
[dda.c4k-common.namespace :as ns]))
|
||||
|
||||
(def config-defaults {:issuer :staging})
|
||||
(def config-defaults {:namespace "nextcloud"
|
||||
:issuer "staging"
|
||||
:pvc-storage-class-name "hcloud-volumes-encrypted"
|
||||
:pv-storage-size-gb 200})
|
||||
|
||||
(def config? (s/keys :req-un [::nextcloud/fqdn]
|
||||
:opt-un [::nextcloud/issuer ::nextcloud/nextcloud-data-volume-path
|
||||
::postgres/postgres-data-volume-path ::restic-repository
|
||||
::nextcloud/storage-size]))
|
||||
|
||||
(def auth? (s/keys :req-un [::postgres/postgres-db-user ::postgres/postgres-db-password
|
||||
::nextcloud/nextcloud-admin-user ::nextcloud/nextcloud-admin-password
|
||||
::aws-access-key-id ::aws-secret-access-key
|
||||
::restic-password]))
|
||||
|
||||
(defn k8s-objects [config]
|
||||
(into
|
||||
[]
|
||||
(concat [(yaml/to-string (postgres/generate-config :postgres-size :8gb))
|
||||
(yaml/to-string (postgres/generate-secret config))]
|
||||
(when (contains? config :postgres-data-volume-path)
|
||||
[(yaml/to-string (postgres/generate-persistent-volume config))])
|
||||
[(yaml/to-string (postgres/generate-pvc))
|
||||
(yaml/to-string (postgres/generate-deployment))
|
||||
(yaml/to-string (postgres/generate-service))]
|
||||
(when (contains? config :nextcloud-data-volume-path)
|
||||
[(yaml/to-string (nextcloud/generate-persistent-volume config))])
|
||||
[(yaml/to-string (nextcloud/generate-secret config))
|
||||
(yaml/to-string (nextcloud/generate-pvc))
|
||||
(yaml/to-string (nextcloud/generate-deployment config))
|
||||
(yaml/to-string (nextcloud/generate-service))
|
||||
(yaml/to-string (nextcloud/generate-certificate config))
|
||||
(yaml/to-string (nextcloud/generate-ingress config))]
|
||||
(when (contains? config :restic-repository)
|
||||
[(yaml/to-string (backup/generate-config config))
|
||||
(yaml/to-string (backup/generate-secret config))
|
||||
(yaml/to-string (backup/generate-cron))]))))
|
||||
|
||||
(defn-spec generate any?
|
||||
[my-config config?
|
||||
my-auth auth?]
|
||||
(let [resulting-config (merge config-defaults my-config my-auth)]
|
||||
(cs/join
|
||||
"\n---\n"
|
||||
(k8s-objects resulting-config))))
|
||||
(defn-spec k8s-objects cp/map-or-seq?
|
||||
[config nextcloud/config?
|
||||
auth nextcloud/auth?]
|
||||
(let [resolved-config (merge config-defaults config)]
|
||||
(map yaml/to-string
|
||||
(filter
|
||||
#(not (nil? %))
|
||||
(cm/concat-vec
|
||||
(ns/generate resolved-config)
|
||||
(postgres/generate (merge resolved-config {:postgres-size :8gb
|
||||
:db-name "cloud"
|
||||
:pv-storage-size-gb 50})
|
||||
auth)
|
||||
[(nextcloud/generate-secret auth)
|
||||
(nextcloud/generate-pvc resolved-config)
|
||||
(nextcloud/generate-deployment resolved-config)
|
||||
(nextcloud/generate-service)]
|
||||
(nextcloud/generate-ingress-and-cert resolved-config)
|
||||
(when (:contains? resolved-config :restic-repository)
|
||||
[(backup/generate-config resolved-config)
|
||||
(backup/generate-secret auth)
|
||||
(backup/generate-cron)
|
||||
(backup/generate-backup-restore-deployment resolved-config)])
|
||||
(when (:contains? resolved-config :mon-cfg)
|
||||
(mon/generate (:mon-cfg resolved-config) (:mon-auth auth))))))))
|
||||
|
|
|
@ -1,71 +1,72 @@
|
|||
(ns dda.c4k-nextcloud.nextcloud
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]
|
||||
#?(:cljs [shadow.resource :as rc])
|
||||
#?(:clj [orchestra.core :refer [defn-spec]]
|
||||
:cljs [orchestra.core :refer-macros [defn-spec]])
|
||||
[dda.c4k-common.yaml :as yaml]
|
||||
[dda.c4k-common.ingress :as ing]
|
||||
[dda.c4k-common.base64 :as b64]
|
||||
[dda.c4k-common.prefixes :as cp]
|
||||
[dda.c4k-common.common :as cm]))
|
||||
[dda.c4k-common.predicate :as cp]
|
||||
[dda.c4k-common.postgres :as postgres]
|
||||
[dda.c4k-common.common :as cm]
|
||||
[dda.c4k-common.monitoring :as mon]
|
||||
#?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]])))
|
||||
|
||||
(s/def ::fqdn cp/fqdn-string?)
|
||||
(s/def ::issuer cp/letsencrypt-issuer?)
|
||||
(s/def ::restic-repository string?)
|
||||
(s/def ::nextcloud-data-volume-path string?)
|
||||
(s/def ::nextcloud-admin-user cp/bash-env-string?)
|
||||
(s/def ::nextcloud-admin-password cp/bash-env-string?)
|
||||
(s/def ::pvc-storage-class-name cp/pvc-storage-class-name?)
|
||||
(s/def ::pv-storage-size-gb pos?)
|
||||
|
||||
(def config? (s/keys :req-un [::fqdn]
|
||||
:opt-un [::issuer
|
||||
::restic-repository
|
||||
::pv-storage-size-gb
|
||||
::pvc-storage-class-name
|
||||
::mon/mon-cfg]))
|
||||
|
||||
(def auth? (s/keys :req-un [::postgres/postgres-db-user ::postgres/postgres-db-password
|
||||
::nextcloud-admin-user ::nextcloud-admin-password
|
||||
::aws-access-key-id ::aws-secret-access-key
|
||||
::restic-password]
|
||||
:opt-un [::mon/mon-auth]))
|
||||
|
||||
#?(:cljs
|
||||
(defmethod yaml/load-resource :nextcloud [resource-name]
|
||||
(case resource-name
|
||||
"nextcloud/certificate.yaml" (rc/inline "nextcloud/certificate.yaml")
|
||||
"nextcloud/deployment.yaml" (rc/inline "nextcloud/deployment.yaml")
|
||||
"nextcloud/ingress.yaml" (rc/inline "nextcloud/ingress.yaml")
|
||||
"nextcloud/persistent-volume.yaml" (rc/inline "nextcloud/persistent-volume.yaml")
|
||||
"nextcloud/pvc.yaml" (rc/inline "nextcloud/pvc.yaml")
|
||||
"nextcloud/service.yaml" (rc/inline "nextcloud/service.yaml")
|
||||
"nextcloud/secret.yaml" (rc/inline "nextcloud/secret.yaml")
|
||||
(throw (js/Error. "Undefined Resource!")))))
|
||||
(get (inline-resources "nextcloud") resource-name)))
|
||||
|
||||
(defn generate-certificate [config]
|
||||
(let [{:keys [fqdn issuer]} config
|
||||
letsencrypt-issuer (str "letsencrypt-" (name issuer) "-issuer")]
|
||||
(->
|
||||
(yaml/from-string (yaml/load-resource "nextcloud/certificate.yaml"))
|
||||
(assoc-in [:spec :commonName] fqdn)
|
||||
(assoc-in [:spec :dnsNames] [fqdn])
|
||||
(assoc-in [:spec :issuerRef :name] letsencrypt-issuer))))
|
||||
|
||||
(defn generate-deployment [config]
|
||||
(defn-spec generate-deployment cp/map-or-seq?
|
||||
[config config?]
|
||||
(let [{:keys [fqdn]} config]
|
||||
(-> (yaml/from-string (yaml/load-resource "nextcloud/deployment.yaml"))
|
||||
(cm/replace-all-matching-values-by-new-value "fqdn" fqdn))))
|
||||
(-> (yaml/load-as-edn "nextcloud/deployment.yaml")
|
||||
(cm/replace-all-matching "fqdn" fqdn))))
|
||||
|
||||
(defn generate-ingress [config]
|
||||
(let [{:keys [fqdn issuer]
|
||||
:or {issuer :staging}} config
|
||||
letsencrypt-issuer (str "letsencrypt-" (name issuer) "-issuer")]
|
||||
(defn-spec generate-ingress-and-cert cp/map-or-seq?
|
||||
[config config?]
|
||||
(ing/generate-ingress-and-cert
|
||||
(merge
|
||||
{:service-name "cloud-service"
|
||||
:service-port 80
|
||||
:fqdns [(:fqdn config)]}
|
||||
config)))
|
||||
|
||||
(defn-spec generate-pvc cp/map-or-seq?
|
||||
[config (s/keys :req-un [::pv-storage-size-gb ::pvc-storage-class-name])]
|
||||
(let [{:keys [pv-storage-size-gb pvc-storage-class-name]} config]
|
||||
(->
|
||||
(yaml/from-string (yaml/load-resource "nextcloud/ingress.yaml"))
|
||||
(assoc-in [:metadata :annotations :cert-manager.io/cluster-issuer] letsencrypt-issuer)
|
||||
(cm/replace-all-matching-values-by-new-value "fqdn" fqdn))))
|
||||
|
||||
(defn generate-persistent-volume [config]
|
||||
(let [{:keys [nextcloud-data-volume-path storage-size]} config]
|
||||
(->
|
||||
(yaml/from-string (yaml/load-resource "nextcloud/persistent-volume.yaml"))
|
||||
(assoc-in [:spec :hostPath :path] nextcloud-data-volume-path)
|
||||
;(assoc-in [:spec :capacity :storage] (str storage-size "Gi"))
|
||||
)))
|
||||
|
||||
(defn generate-pvc []
|
||||
(yaml/from-string (yaml/load-resource "nextcloud/pvc.yaml")))
|
||||
(yaml/load-as-edn "nextcloud/pvc.yaml")
|
||||
(assoc-in [:spec :resources :requests :storage] (str pv-storage-size-gb "Gi"))
|
||||
(assoc-in [:spec :storageClassName] (name pvc-storage-class-name)))))
|
||||
|
||||
(defn generate-service []
|
||||
(yaml/from-string (yaml/load-resource "nextcloud/service.yaml")))
|
||||
(yaml/load-as-edn "nextcloud/service.yaml"))
|
||||
|
||||
(defn generate-secret [config]
|
||||
(let [{:keys [nextcloud-admin-user nextcloud-admin-password]} config]
|
||||
(defn-spec generate-secret cp/map-or-seq?
|
||||
[auth auth?]
|
||||
(let [{:keys [nextcloud-admin-user nextcloud-admin-password]} auth]
|
||||
(->
|
||||
(yaml/from-string (yaml/load-resource "nextcloud/secret.yaml"))
|
||||
(yaml/load-as-edn "nextcloud/secret.yaml")
|
||||
(cm/replace-key-value :nextcloud-admin-user (b64/encode nextcloud-admin-user))
|
||||
(cm/replace-key-value :nextcloud-admin-password (b64/encode nextcloud-admin-password)))))
|
||||
|
|
|
@ -1,31 +1,42 @@
|
|||
(ns dda.c4k-nextcloud.browser
|
||||
(:require
|
||||
[clojure.tools.reader.edn :as edn]
|
||||
[dda.c4k-common.common :as cm]
|
||||
[dda.c4k-common.monitoring :as mon]
|
||||
[dda.c4k-nextcloud.core :as core]
|
||||
[dda.c4k-nextcloud.nextcloud :as nextcloud]
|
||||
[dda.c4k-common.browser :as br]
|
||||
[dda.c4k-common.postgres :as pgc]))
|
||||
|
||||
(defn generate-content
|
||||
[]
|
||||
(into [] (concat [(assoc (br/generate-needs-validation) :content
|
||||
(into [] (concat (br/generate-input-field "fqdn" "Your fqdn:" "nextcloud-neu.prod.meissa-gmbh.de")
|
||||
(br/generate-input-field "nextcloud-data-volume-path" "(Optional) Your nextcloud-data-volume-path:" "/var/nextcloud")
|
||||
(br/generate-input-field "postgres-data-volume-path" "(Optional) Your postgres-data-volume-path:" "/var/postgres")
|
||||
(br/generate-input-field "restic-repository" "(Optional) Your restic-repository:" "restic-repository")
|
||||
(br/generate-input-field "issuer" "(Optional) Your issuer prod/staging:" "")
|
||||
[(br/generate-br)]
|
||||
(br/generate-text-area "auth" "Your auth.edn:" "{:postgres-db-user \"nextcloud\"
|
||||
(defn generate-content []
|
||||
(cm/concat-vec
|
||||
[(assoc
|
||||
(br/generate-needs-validation) :content
|
||||
(cm/concat-vec
|
||||
(br/generate-group "domain"
|
||||
(cm/concat-vec (br/generate-input-field "fqdn" "Your fqdn:" "nextcloud-neu.prod.meissa-gmbh.de")
|
||||
(br/generate-input-field "issuer" "(Optional) Your issuer prod/staging:" "")
|
||||
(br/generate-input-field "pv-storage-size-gb" "(Optional) Your nextcloud storage size in GB" "8")
|
||||
(br/generate-input-field "pvc-storage-class-name" "(Optional) Your storage class type (manual / local-path):" "local-path")
|
||||
(br/generate-input-field "postgres-data-volume-path" "(Optional) Your postgres-data-volume-path:" "/var/postgres")
|
||||
(br/generate-input-field "restic-repository" "(Optional) Your restic-repository:" "restic-repository")
|
||||
(br/generate-input-field "mon-cluster-name" "(Optional) monitoring cluster name:" "keycloak")
|
||||
(br/generate-input-field "mon-cluster-stage" "(Optional) monitoring cluster stage:" "test")
|
||||
(br/generate-input-field "mon-cloud-url" "(Optional) grafana cloud url:" "https://prometheus-prod-01-eu-west-0.grafana.net/api/prom/push")))
|
||||
(br/generate-group "credentials"
|
||||
(br/generate-text-area "auth" "Your auth.edn:" "{:postgres-db-user \"nextcloud\"
|
||||
:postgres-db-password \"nextcloud-db-password\"
|
||||
:nextcloud-admin-password \"nextcloud-admin-password\"
|
||||
:nextcloud-admin-user \"nextcloud-admin-user\"
|
||||
:aws-access-key-id \"aws-id\"
|
||||
:aws-secret-access-key \"aws-secret\"
|
||||
:restic-password \"restic-password\"}"
|
||||
"5")
|
||||
[(br/generate-br)]
|
||||
(br/generate-button "generate-button" "Generate c4k yaml"))))]
|
||||
(br/generate-output "c4k-nextcloud-output" "Your c4k deployment.yaml:" "25"))))
|
||||
:restic-password \"restic-password\"}
|
||||
:mon-auth {:grafana-cloud-user \"your-user-id\"
|
||||
:grafana-cloud-password \"your-cloud-password\"}"
|
||||
"5"))
|
||||
[(br/generate-br)]
|
||||
(br/generate-button "generate-button" "Generate c4k yaml")))]
|
||||
(br/generate-output "c4k-nextcloud-output" "Your c4k deployment.yaml:" "25")))
|
||||
|
||||
(defn generate-content-div
|
||||
[]
|
||||
|
@ -35,29 +46,40 @@
|
|||
(generate-content)})
|
||||
|
||||
(defn config-from-document []
|
||||
(let [nextcloud-data-volume-path (br/get-content-from-element "nextcloud-data-volume-path" :optional true)
|
||||
(let [pv-storage-size-gb (br/get-content-from-element "pv-storage-size-gb" :optional true)
|
||||
pvc-storage-class-name (br/get-content-from-element "pvc-storage-class-name" :optional true)
|
||||
postgres-data-volume-path (br/get-content-from-element "postgres-data-volume-path" :optional true)
|
||||
restic-repository (br/get-content-from-element "restic-repository" :optional true)
|
||||
issuer (br/get-content-from-element "issuer" :optional true :deserializer keyword)]
|
||||
issuer (br/get-content-from-element "issuer" :optional true)
|
||||
mon-cluster-name (br/get-content-from-element "mon-cluster-name" :optional true)
|
||||
mon-cluster-stage (br/get-content-from-element "mon-cluster-stage" :optional true)
|
||||
mon-cloud-url (br/get-content-from-element "mon-cloud-url" :optional true)]
|
||||
(merge
|
||||
{:fqdn (br/get-content-from-element "fqdn")}
|
||||
(when (some? nextcloud-data-volume-path)
|
||||
{:nextcloud-data-volume-path nextcloud-data-volume-path})
|
||||
(when (and (some? pv-storage-size-gb) (some? pvc-storage-class-name))
|
||||
{:pv-storage-size-gb pv-storage-size-gb :pvc-storage-class-name pvc-storage-class-name})
|
||||
(when (some? postgres-data-volume-path)
|
||||
{:postgres-data-volume-path postgres-data-volume-path})
|
||||
(when (some? restic-repository)
|
||||
{:restic-repository restic-repository})
|
||||
(when (some? issuer)
|
||||
{:issuer issuer})
|
||||
)))
|
||||
(when (some? mon-cluster-name)
|
||||
{:mon-cfg {:cluster-name mon-cluster-name
|
||||
:cluster-stage (keyword mon-cluster-stage)
|
||||
:grafana-cloud-url mon-cloud-url}}))))
|
||||
|
||||
(defn validate-all! []
|
||||
(br/validate! "fqdn" ::nextcloud/fqdn)
|
||||
(br/validate! "nextcloud-data-volume-path" ::nextcloud/nextcloud-data-volume-path :optional true)
|
||||
(br/validate! "pv-storage-size-gb" ::nextcloud/pv-storage-size-gb :optional true)
|
||||
(br/validate! "pvc-storage-class-name" ::nextcloud/pvc-storage-class-name :optional true)
|
||||
(br/validate! "postgres-data-volume-path" ::pgc/postgres-data-volume-path :optional true)
|
||||
(br/validate! "restic-repository" ::nextcloud/restic-repository :optional true)
|
||||
(br/validate! "issuer" ::nextcloud/issuer :optional true :deserializer keyword)
|
||||
(br/validate! "auth" core/auth? :deserializer edn/read-string)
|
||||
(br/validate! "issuer" ::nextcloud/issuer :optional true)
|
||||
(br/validate! "mon-cluster-name" ::mon/cluster-name :optional true)
|
||||
(br/validate! "mon-cluster-stage" ::mon/cluster-stage :optional true)
|
||||
(br/validate! "mon-cloud-url" ::mon/grafana-cloud-url :optional true)
|
||||
(br/validate! "auth" nextcloud/auth? :deserializer edn/read-string)
|
||||
(br/set-validated!))
|
||||
|
||||
(defn add-validate-listener [name]
|
||||
|
@ -70,13 +92,19 @@
|
|||
(.getElementById "generate-button")
|
||||
(.addEventListener "click"
|
||||
#(do (validate-all!)
|
||||
(-> (core/generate
|
||||
(config-from-document)
|
||||
(br/get-content-from-element "auth" :deserializer edn/read-string))
|
||||
(-> (cm/generate-common
|
||||
(config-from-document)
|
||||
(br/get-content-from-element "auth" :deserializer edn/read-string)
|
||||
{}
|
||||
core/k8s-objects)
|
||||
(br/set-output!)))))
|
||||
(add-validate-listener "fqdn")
|
||||
(add-validate-listener "nextcloud-data-volume-path")
|
||||
(add-validate-listener "pv-storage-size-gb")
|
||||
(add-validate-listener "pvc-storage-class-name")
|
||||
(add-validate-listener "postgres-data-volume-path")
|
||||
(add-validate-listener "restic-repository")
|
||||
(add-validate-listener "issuer")
|
||||
(add-validate-listener "mon-cluster-name")
|
||||
(add-validate-listener "mon-cluster-stage")
|
||||
(add-validate-listener "mon-cloud-url")
|
||||
(add-validate-listener "auth"))
|
||||
|
|
87
src/main/resources/backup/backup-restore-deployment.yaml
Normal file
87
src/main/resources/backup/backup-restore-deployment.yaml
Normal file
|
@ -0,0 +1,87 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: backup-restore
|
||||
namespace: nextcloud
|
||||
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: cloud
|
||||
spec:
|
||||
containers:
|
||||
- name: backup-app
|
||||
image: domaindrivenarchitecture/c4k-cloud-backup
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: ["/entrypoint-start-and-wait.sh"]
|
||||
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: CERTIFICATE_FILE
|
||||
value: ""
|
||||
volumeMounts:
|
||||
- name: cloud-data-volume
|
||||
mountPath: /var/backups
|
||||
- name: backup-secret-volume
|
||||
mountPath: /var/run/secrets/backup-secrets
|
||||
readOnly: true
|
||||
- name: cloud-secret-volume
|
||||
mountPath: /var/run/secrets/cloud-secrets
|
||||
readOnly: true
|
||||
- name: rotation-credential-secret-volume
|
||||
mountPath: /var/run/secrets/rotation-credential-secret
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: cloud-data-volume
|
||||
persistentVolumeClaim:
|
||||
claimName: cloud-pvc
|
||||
- name: cloud-secret-volume
|
||||
secret:
|
||||
secretName: cloud-secret
|
||||
- name: backup-secret-volume
|
||||
secret:
|
||||
secretName: backup-secret
|
||||
- name: rotation-credential-secret-volume
|
||||
secret:
|
||||
secretName: rotation-credential-secret
|
||||
optional: true
|
|
@ -1,68 +0,0 @@
|
|||
kind: Pod
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: backup-restore
|
||||
labels:
|
||||
app.kubernetes.io/name: backup-restore
|
||||
app.kubernetes.io/part-of: cloud
|
||||
spec:
|
||||
containers:
|
||||
- name: backup-app
|
||||
image: domaindrivenarchitecture/c4k-cloud-backup
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: ["/entrypoint-start-and-wait.sh"]
|
||||
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: cloud-data-volume
|
||||
mountPath: /var/backups
|
||||
- name: backup-secret-volume
|
||||
mountPath: /var/run/secrets/backup-secrets
|
||||
readOnly: true
|
||||
- name: cloud-secret-volume
|
||||
mountPath: /var/run/secrets/cloud-secrets
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: cloud-data-volume
|
||||
persistentVolumeClaim:
|
||||
claimName: cloud-pvc
|
||||
- name: cloud-secret-volume
|
||||
secret:
|
||||
secretName: cloud-secret
|
||||
- name: backup-secret-volume
|
||||
secret:
|
||||
secretName: backup-secret
|
||||
restartPolicy: OnFailure
|
|
@ -2,6 +2,7 @@ apiVersion: v1
|
|||
kind: ConfigMap
|
||||
metadata:
|
||||
name: backup-config
|
||||
namespace: nextcloud
|
||||
labels:
|
||||
app.kubernetes.io/name: backup
|
||||
app.kubernetes.io/part-of: cloud
|
||||
|
|
8
src/main/resources/backup/credential-rotation.yaml
Normal file
8
src/main/resources/backup/credential-rotation.yaml
Normal file
|
@ -0,0 +1,8 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: rotation-credential-secret
|
||||
namespace: nextcloud
|
||||
type: Opaque
|
||||
data:
|
||||
rotation-credential: "dGVzdAo="
|
|
@ -2,12 +2,13 @@ apiVersion: batch/v1
|
|||
kind: CronJob
|
||||
metadata:
|
||||
name: cloud-backup
|
||||
namespace: nextcloud
|
||||
labels:
|
||||
app.kubernetes.part-of: cloud
|
||||
spec:
|
||||
schedule: "10 23 * * *"
|
||||
successfulJobsHistoryLimit: 0
|
||||
failedJobsHistoryLimit: 0
|
||||
successfulJobsHistoryLimit: 1
|
||||
failedJobsHistoryLimit: 1
|
||||
jobTemplate:
|
||||
spec:
|
||||
template:
|
||||
|
@ -18,12 +19,21 @@ spec:
|
|||
imagePullPolicy: IfNotPresent
|
||||
command: ["/entrypoint.sh"]
|
||||
env:
|
||||
- name: POSTGRES_USER_FILE
|
||||
value: /var/run/secrets/cloud-secrets/postgres-user
|
||||
- name: POSTGRES_DB_FILE
|
||||
value: /var/run/secrets/cloud-secrets/postgres-db
|
||||
- name: POSTGRES_PASSWORD_FILE
|
||||
value: /var/run/secrets/cloud-secrets/postgres-password
|
||||
- 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
|
||||
|
|
|
@ -2,6 +2,7 @@ apiVersion: v1
|
|||
kind: Secret
|
||||
metadata:
|
||||
name: backup-secret
|
||||
namespace: nextcloud
|
||||
type: Opaque
|
||||
data:
|
||||
aws-access-key-id: "aws-access-key-id"
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: cloud-cert
|
||||
namespace: default
|
||||
spec:
|
||||
secretName: cloud-secret
|
||||
commonName: fqdn
|
||||
dnsNames:
|
||||
- fqdn
|
||||
issuerRef:
|
||||
name: letsencrypt-staging-issuer
|
||||
kind: ClusterIssuer
|
|
@ -2,6 +2,7 @@ apiVersion: apps/v1
|
|||
kind: Deployment
|
||||
metadata:
|
||||
name: cloud-deployment
|
||||
namespace: nextcloud
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
|
@ -12,12 +13,13 @@ spec:
|
|||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: cloud-app
|
||||
app.kubernetes.io/name: cloud-pod
|
||||
app.kubernetes.io/application: cloud
|
||||
redeploy: v3
|
||||
spec:
|
||||
containers:
|
||||
- image: domaindrivenarchitecture/c4k-cloud
|
||||
- image: domaindrivenarchitecture/c4k-cloud:8.0.0
|
||||
name: cloud-app
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-cloud
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-staging-issuer
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "256m"
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/rewrite-target: /
|
||||
nginx.ingress.kubernetes.io/proxy-connect-timeout: "300"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
|
||||
namespace: default
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- fqdn
|
||||
secretName: cloud-secret
|
||||
rules:
|
||||
- host: fqdn
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: cloud-service
|
||||
port:
|
||||
number: 80
|
|
@ -1,15 +0,0 @@
|
|||
kind: PersistentVolume
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: cloud-pv-volume
|
||||
labels:
|
||||
type: local
|
||||
app.kubernetes.io/application: cloud
|
||||
spec:
|
||||
storageClassName: manual
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
capacity:
|
||||
storage: 200Gi
|
||||
hostPath:
|
||||
path: "/var/cloud"
|
|
@ -2,15 +2,14 @@ apiVersion: v1
|
|||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: cloud-pvc
|
||||
namespace: nextcloud
|
||||
labels:
|
||||
app.kubernetes.io/application: cloud
|
||||
spec:
|
||||
storageClassName: manual
|
||||
storageClassName: REPLACEME
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 200Gi
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/application: cloud
|
||||
storage: REPLACEME
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ apiVersion: v1
|
|||
kind: Secret
|
||||
metadata:
|
||||
name: cloud-secret
|
||||
namespace: nextcloud
|
||||
type: Opaque
|
||||
data:
|
||||
nextcloud-admin-user: "admin-user"
|
||||
|
|
|
@ -2,6 +2,7 @@ apiVersion: v1
|
|||
kind: Service
|
||||
metadata:
|
||||
name: cloud-service
|
||||
namespace: nextcloud
|
||||
labels:
|
||||
app.kubernetes.io/name: cloud-service
|
||||
app.kubernetes.io/application: cloud
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
(deftest should-generate-secret
|
||||
(is (= {:apiVersion "v1"
|
||||
:kind "Secret"
|
||||
:metadata {:name "backup-secret"}
|
||||
:metadata {:name "backup-secret", :namespace "nextcloud"}
|
||||
:type "Opaque"
|
||||
:data
|
||||
{:aws-access-key-id "YXdzLWlk", :aws-secret-access-key "YXdzLXNlY3JldA==", :restic-password "cmVzdGljLXB3"}}
|
||||
|
@ -18,6 +18,7 @@
|
|||
(is (= {:apiVersion "v1"
|
||||
:kind "ConfigMap"
|
||||
:metadata {:name "backup-config"
|
||||
:namespace "nextcloud"
|
||||
:labels {:app.kubernetes.io/name "backup"
|
||||
:app.kubernetes.io/part-of "cloud"}}
|
||||
:data
|
||||
|
@ -27,11 +28,11 @@
|
|||
(deftest should-generate-cron
|
||||
(is (= {:apiVersion "batch/v1"
|
||||
:kind "CronJob"
|
||||
:metadata {:name "cloud-backup", :labels {:app.kubernetes.part-of "cloud"}}
|
||||
:metadata {:name "cloud-backup", :namespace "nextcloud", :labels {:app.kubernetes.part-of "cloud"}}
|
||||
:spec
|
||||
{:schedule "10 23 * * *"
|
||||
:successfulJobsHistoryLimit 0
|
||||
:failedJobsHistoryLimit 0
|
||||
:successfulJobsHistoryLimit 1
|
||||
:failedJobsHistoryLimit 1
|
||||
:jobTemplate
|
||||
{:spec
|
||||
{:template
|
||||
|
@ -42,9 +43,20 @@
|
|||
:imagePullPolicy "IfNotPresent"
|
||||
:command ["/entrypoint.sh"]
|
||||
:env
|
||||
[{:name "POSTGRES_USER_FILE", :value "/var/run/secrets/cloud-secrets/postgres-user"}
|
||||
{:name "POSTGRES_DB_FILE", :value "/var/run/secrets/cloud-secrets/postgres-db"}
|
||||
{:name "POSTGRES_PASSWORD_FILE", :value "/var/run/secrets/cloud-secrets/postgres-password"}
|
||||
[{:valueFrom
|
||||
{:secretKeyRef
|
||||
{:name "postgres-secret",
|
||||
:key "postgres-user"}},
|
||||
:name "POSTGRES_USER"}
|
||||
{:valueFrom
|
||||
{:secretKeyRef
|
||||
{:name "postgres-secret",
|
||||
:key "postgres-password"}},
|
||||
:name "POSTGRES_PASSWORD"}
|
||||
{:valueFrom
|
||||
{:configMapKeyRef
|
||||
{:name "postgres-config", :key "postgres-db"}},
|
||||
:name "POSTGRES_DB"}
|
||||
{:name "POSTGRES_HOST", :value "postgresql-service:5432"}
|
||||
{:name "POSTGRES_SERVICE", :value "postgresql-service"}
|
||||
{:name "POSTGRES_PORT", :value "5432"}
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
(ns dda.c4k-nextcloud.core-test
|
||||
(:require
|
||||
#?(:clj [clojure.test :refer [deftest is are testing run-tests]]
|
||||
:cljs [cljs.test :refer-macros [deftest is are testing run-tests]])
|
||||
[dda.c4k-nextcloud.core :as cut]))
|
||||
|
||||
(deftest should-k8s-objects
|
||||
(is (= 16
|
||||
(count (cut/k8s-objects {:fqdn "nextcloud-neu.prod.meissa-gmbh.de"
|
||||
:postgres-db-user "nextcloud"
|
||||
:postgres-db-password "nextcloud-db-password"
|
||||
:nextcloud-admin-user "cloudadmin"
|
||||
:nextcloud-admin-password "cloudpassword"
|
||||
:issuer :prod
|
||||
:nextcloud-data-volume-path "/var/nextcloud"
|
||||
:postgres-data-volume-path "/var/postgres"
|
||||
:aws-access-key-id "aws-id"
|
||||
:aws-secret-access-key "aws-secret"
|
||||
:restic-password "restic-pw"
|
||||
:restic-repository "restic-repository"}))))
|
||||
(is (= 14
|
||||
(count (cut/k8s-objects {:fqdn "nextcloud-neu.prod.meissa-gmbh.de"
|
||||
:postgres-db-user "nextcloud"
|
||||
:postgres-db-password "nextcloud-db-password"
|
||||
:nextcloud-admin-user "cloudadmin"
|
||||
:nextcloud-admin-password "cloudpassword"
|
||||
:issuer :prod
|
||||
:aws-access-key-id "aws-id"
|
||||
:aws-secret-access-key "aws-secret"
|
||||
:restic-password "restic-pw"
|
||||
:restic-repository "restic-repository"}))))
|
||||
(is (= 11
|
||||
(count (cut/k8s-objects {:fqdn "nextcloud-neu.prod.meissa-gmbh.de"
|
||||
:postgres-db-user "nextcloud"
|
||||
:postgres-db-password "nextcloud-db-password"
|
||||
:nextcloud-admin-user "cloudadmin"
|
||||
:nextcloud-admin-password "cloudpassword"
|
||||
:issuer :prod
|
||||
:aws-access-key-id "aws-id"
|
||||
:aws-secret-access-key "aws-secret"
|
||||
:restic-password "restic-pw"})))))
|
|
@ -2,82 +2,100 @@
|
|||
(:require
|
||||
#?(:clj [clojure.test :refer [deftest is are testing run-tests]]
|
||||
:cljs [cljs.test :refer-macros [deftest is are testing run-tests]])
|
||||
[dda.c4k-nextcloud.nextcloud :as cut]))
|
||||
[clojure.spec.alpha :as s]
|
||||
[clojure.spec.test.alpha :as st]
|
||||
[dda.c4k-common.yaml :as yaml]
|
||||
[dda.c4k-nextcloud.nextcloud :as cut]
|
||||
#?(:cljs [dda.c4k-common.macros :refer-macros [inline-resources]])))
|
||||
|
||||
(st/instrument)
|
||||
|
||||
#?(:cljs
|
||||
(defmethod yaml/load-resource :nextcloud-test [resource-name]
|
||||
(get (inline-resources "nextcloud-test") resource-name)))
|
||||
|
||||
(deftest validate-valid-resources
|
||||
(is (s/valid? cut/config? (yaml/load-as-edn "nextcloud-test/valid-config.yaml")))
|
||||
(is (s/valid? cut/auth? (yaml/load-as-edn "nextcloud-test/valid-auth.yaml")))
|
||||
(is (not (s/valid? cut/config? (yaml/load-as-edn "nextcloud-test/invalid-config.yaml"))))
|
||||
(is (not (s/valid? cut/auth? (yaml/load-as-edn "nextcloud-test/invalid-auth.yaml")))))
|
||||
|
||||
(deftest should-generate-secret
|
||||
(is (= {:apiVersion "v1"
|
||||
:kind "Secret"
|
||||
:metadata {:name "cloud-secret"}
|
||||
:metadata {:name "cloud-secret", :namespace "nextcloud"}
|
||||
:type "Opaque"
|
||||
:data
|
||||
{:nextcloud-admin-user "Y2xvdWRhZG1pbg=="
|
||||
:nextcloud-admin-password "Y2xvdWRwYXNzd29yZA=="}}
|
||||
(cut/generate-secret {:nextcloud-admin-user "cloudadmin"
|
||||
(cut/generate-secret {:postgres-db-user "postgres-user"
|
||||
:postgres-db-password "postgres-password"
|
||||
:aws-access-key-id "aws-key"
|
||||
:aws-secret-access-key "aws-secret-key"
|
||||
:restic-password "restic-password"
|
||||
:nextcloud-admin-user "cloudadmin"
|
||||
:nextcloud-admin-password "cloudpassword"}))))
|
||||
|
||||
(deftest should-generate-certificate
|
||||
(is (= {:apiVersion "cert-manager.io/v1"
|
||||
:kind "Certificate"
|
||||
:metadata {:name "cloud-cert", :namespace "default"}
|
||||
:spec
|
||||
{:secretName "cloud-secret"
|
||||
:commonName "xx"
|
||||
:dnsNames ["xx"]
|
||||
:issuerRef
|
||||
{:name "letsencrypt-prod-issuer", :kind "ClusterIssuer"}}}
|
||||
(cut/generate-certificate {:fqdn "xx" :issuer :prod}))))
|
||||
|
||||
(deftest should-generate-ingress
|
||||
(is (= {:apiVersion "networking.k8s.io/v1"
|
||||
:kind "Ingress"
|
||||
:metadata
|
||||
{:name "ingress-cloud"
|
||||
:annotations
|
||||
{:cert-manager.io/cluster-issuer
|
||||
"letsencrypt-staging-issuer"
|
||||
:nginx.ingress.kubernetes.io/proxy-body-size "256m"
|
||||
:nginx.ingress.kubernetes.io/ssl-redirect "true"
|
||||
:nginx.ingress.kubernetes.io/rewrite-target "/"
|
||||
:nginx.ingress.kubernetes.io/proxy-connect-timeout "300"
|
||||
:nginx.ingress.kubernetes.io/proxy-send-timeout "300"
|
||||
:nginx.ingress.kubernetes.io/proxy-read-timeout "300"}
|
||||
:namespace "default"}
|
||||
:spec
|
||||
{:tls [{:hosts ["xx"], :secretName "cloud-secret"}]
|
||||
:rules
|
||||
[{:host "xx"
|
||||
:http
|
||||
{:paths
|
||||
[{:path "/"
|
||||
:pathType "Prefix"
|
||||
:backend
|
||||
{:service
|
||||
{:name "cloud-service", :port {:number 80}}}}]}}]}}
|
||||
(cut/generate-ingress {:fqdn "xx"}))))
|
||||
|
||||
(deftest should-generate-persistent-volume
|
||||
(is (= {:kind "PersistentVolume"
|
||||
:apiVersion "v1"
|
||||
:metadata {:name "cloud-pv-volume"
|
||||
:labels {:type "local", :app.kubernetes.io/application "cloud"}}
|
||||
:spec {:storageClassName "manual"
|
||||
:accessModes ["ReadWriteOnce"]
|
||||
:capacity {:storage "200Gi"}
|
||||
:hostPath {:path "xx"}}}
|
||||
(cut/generate-persistent-volume {:nextcloud-data-volume-path "xx"}))))
|
||||
(deftest should-generate-ingress-and-cert
|
||||
(is (= [{:apiVersion "cert-manager.io/v1",
|
||||
:kind "Certificate",
|
||||
:metadata
|
||||
{:name "cloud-service",
|
||||
:labels {:app.kubernetes.part-of "cloud-service"},
|
||||
:namespace "default"},
|
||||
:spec
|
||||
{:secretName "cloud-service",
|
||||
:commonName "somefqdn.de",
|
||||
:duration "2160h",
|
||||
:renewBefore "720h",
|
||||
:dnsNames ["somefqdn.de"],
|
||||
:issuerRef {:name "staging", :kind "ClusterIssuer"}}}
|
||||
{:apiVersion "networking.k8s.io/v1",
|
||||
:kind "Ingress",
|
||||
:metadata
|
||||
{:name "cloud-service",
|
||||
:namespace "default",
|
||||
:labels {:app.kubernetes.part-of "cloud-service"},
|
||||
:annotations
|
||||
{:traefik.ingress.kubernetes.io/router.entrypoints "web, websecure",
|
||||
:traefik.ingress.kubernetes.io/router.middlewares
|
||||
"default-redirect-https@kubernetescrd",
|
||||
:metallb.universe.tf/address-pool "public"}},
|
||||
:spec
|
||||
{:tls [{:hosts ["somefqdn.de"], :secretName "cloud-service"}],
|
||||
:rules
|
||||
[{:host "somefqdn.de",
|
||||
:http
|
||||
{:paths
|
||||
[{:pathType "Prefix",
|
||||
:path "/",
|
||||
:backend
|
||||
{:service {:name "cloud-service", :port {:number 80}}}}]}}]}}]
|
||||
(cut/generate-ingress-and-cert {:fqdn "somefqdn.de"}))))
|
||||
|
||||
(deftest should-generate-pvc
|
||||
(is (= {:apiVersion "v1"
|
||||
:kind "PersistentVolumeClaim"
|
||||
:metadata {:name "cloud-pvc"
|
||||
:namespace "nextcloud"
|
||||
:labels {:app.kubernetes.io/application "cloud"}}
|
||||
:spec {:storageClassName "local-path"
|
||||
:accessModes ["ReadWriteOnce"]
|
||||
:resources {:requests {:storage "50Gi"}}}}
|
||||
(cut/generate-pvc {:pv-storage-size-gb 50 :pvc-storage-class-name "local-path"}))))
|
||||
|
||||
(deftest should-generate-deployment
|
||||
(is (= {:apiVersion "apps/v1"
|
||||
:kind "Deployment"
|
||||
:metadata {:name "cloud-deployment"}
|
||||
:metadata {:name "cloud-deployment", :namespace "nextcloud"}
|
||||
:spec
|
||||
{:selector {:matchLabels #:app.kubernetes.io{:name "cloud-pod", :application "cloud"}}
|
||||
:strategy {:type "Recreate"}
|
||||
:template
|
||||
{:metadata {:labels {:app.kubernetes.io/name "cloud-pod", :app.kubernetes.io/application "cloud", :redeploy "v3"}}
|
||||
{:metadata {:labels {:app "cloud-app", :app.kubernetes.io/name "cloud-pod", :app.kubernetes.io/application "cloud", :redeploy "v3"}}
|
||||
:spec
|
||||
{:containers
|
||||
[{:image "domaindrivenarchitecture/c4k-cloud"
|
||||
[{:image "domaindrivenarchitecture/c4k-cloud:8.0.0"
|
||||
:name "cloud-app"
|
||||
:imagePullPolicy "IfNotPresent"
|
||||
:ports [{:containerPort 80}]
|
||||
|
@ -93,11 +111,11 @@
|
|||
[{:name "NEXTCLOUD_ADMIN_USER", :valueFrom {:secretKeyRef {:name "cloud-secret", :key "nextcloud-admin-user"}}}
|
||||
{:name "NEXTCLOUD_ADMIN_PASSWORD"
|
||||
:valueFrom {:secretKeyRef {:name "cloud-secret", :key "nextcloud-admin-password"}}}
|
||||
{:name "NEXTCLOUD_TRUSTED_DOMAINS", :value "xx"}
|
||||
{:name "NEXTCLOUD_TRUSTED_DOMAINS", :value "somefqdn.de"}
|
||||
{:name "POSTGRES_USER", :valueFrom {:secretKeyRef {:name "postgres-secret", :key "postgres-user"}}}
|
||||
{:name "POSTGRES_PASSWORD", :valueFrom {:secretKeyRef {:name "postgres-secret", :key "postgres-password"}}}
|
||||
{:name "POSTGRES_DB", :valueFrom {:configMapKeyRef {:name "postgres-config", :key "postgres-db"}}}
|
||||
{:name "POSTGRES_HOST", :value "postgresql-service:5432"}]
|
||||
:volumeMounts [{:name "cloud-data-volume", :mountPath "/var/www/html"}]}]
|
||||
:volumes [{:name "cloud-data-volume", :persistentVolumeClaim {:claimName "cloud-pvc"}}]}}}}
|
||||
(cut/generate-deployment {:fqdn "xx"}))))
|
||||
(cut/generate-deployment {:fqdn "somefqdn.de"}))))
|
7
src/test/resources/nextcloud-test/invalid-auth.yaml
Normal file
7
src/test/resources/nextcloud-test/invalid-auth.yaml
Normal file
|
@ -0,0 +1,7 @@
|
|||
postgres-db-user: "nextcloud"
|
||||
postgres-db-password: "nextcloud-db-password"
|
||||
nextcloud-admin-user: "cloudadmin"
|
||||
nextcloud-admin-password: "cloudpassword"
|
||||
aws-accss-key-id: "aws-id"
|
||||
aws-secret-access-key: "aws-secret"
|
||||
restic-password: "restic-password"
|
5
src/test/resources/nextcloud-test/invalid-config.yaml
Normal file
5
src/test/resources/nextcloud-test/invalid-config.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
fqdns: "cloud.test.meissa-gmbh.de"
|
||||
issuer: "none"
|
||||
nextcloud-data-volume-path: "/var/cloud"
|
||||
postgres-data-volume-path: "/var/postgres"
|
||||
restic-repository: "s3:s3.amazonaws.com/your-bucket/your-folder"
|
10
src/test/resources/nextcloud-test/valid-auth.yaml
Normal file
10
src/test/resources/nextcloud-test/valid-auth.yaml
Normal file
|
@ -0,0 +1,10 @@
|
|||
postgres-db-user: "nextcloud"
|
||||
postgres-db-password: "nextcloud-db-password"
|
||||
nextcloud-admin-user: "cloudadmin"
|
||||
nextcloud-admin-password: "cloudpassword"
|
||||
aws-access-key-id: "aws-id"
|
||||
aws-secret-access-key: "aws-secret"
|
||||
restic-password: "restic-password"
|
||||
mon-auth:
|
||||
grafana-cloud-user: "user"
|
||||
grafana-cloud-password: "password"
|
9
src/test/resources/nextcloud-test/valid-config.yaml
Normal file
9
src/test/resources/nextcloud-test/valid-config.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
fqdn: "cloud.test.meissa-gmbh.de"
|
||||
issuer: "staging"
|
||||
nextcloud-data-volume-path: "/var/cloud"
|
||||
postgres-data-volume-path: "/var/postgres"
|
||||
restic-repository: "s3:s3.amazonaws.com/your-bucket/your-folder"
|
||||
mon-cfg:
|
||||
grafana-cloud-url: "url-for-your-prom-remote-write-endpoint"
|
||||
cluster-name: "keycloak"
|
||||
cluster-stage: "test"
|
|
@ -1,7 +0,0 @@
|
|||
{:postgres-db-user "nextcloud"
|
||||
:postgres-db-password "nextcloud-db-password"
|
||||
:nextcloud-admin-user "cloudadmin"
|
||||
:nextcloud-admin-password "cloudpassword"
|
||||
:aws-access-key-id "aws-id"
|
||||
:aws-secret-access-key "aws-secret"
|
||||
:restic-password "restic-password"}
|
|
@ -1,5 +0,0 @@
|
|||
{:fqdn "cloud.test.meissa-gmbh.de"
|
||||
:issuer :staging
|
||||
:nextcloud-data-volume-path "/var/cloud"
|
||||
:postgres-data-volume-path "/var/postgres"
|
||||
:restic-repository "s3:s3.amazonaws.com/your-bucket/your-folder"}
|
Loading…
Reference in a new issue