Compare commits
No commits in common. "main" and "add_skeleton" have entirely different histories.
main
...
add_skelet
73 changed files with 892 additions and 1741 deletions
13
.gitignore
vendored
13
.gitignore
vendored
|
@ -22,17 +22,8 @@ logs/
|
||||||
*.iml
|
*.iml
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
# config files
|
#valid-auth.edn
|
||||||
|
#valid-config.edn
|
||||||
my-auth.edn
|
my-auth.edn
|
||||||
my-config.edn
|
|
||||||
auth.edn
|
auth.edn
|
||||||
config.edn
|
config.edn
|
||||||
|
|
||||||
# certificate
|
|
||||||
ca.crt
|
|
||||||
|
|
||||||
# chaches
|
|
||||||
.clj-kondo/.cache
|
|
||||||
.lsp/.cache/
|
|
||||||
|
|
||||||
.eastwood
|
|
126
.gitlab-ci.yml
126
.gitlab-ci.yml
|
@ -5,18 +5,11 @@ stages:
|
||||||
- upload
|
- upload
|
||||||
- image
|
- image
|
||||||
|
|
||||||
.img: &img
|
services:
|
||||||
image: "domaindrivenarchitecture/ddadevops-dind:4.11.3"
|
- docker:19.03.12-dind
|
||||||
services:
|
|
||||||
- docker:dind
|
|
||||||
before_script:
|
|
||||||
- export RELEASE_ARTIFACT_TOKEN=$MEISSA_REPO_BUERO_RW
|
|
||||||
- export IMAGE_DOCKERHUB_USER=$DOCKERHUB_USER
|
|
||||||
- export IMAGE_DOCKERHUB_PASSWORD=$DOCKERHUB_PASSWORD
|
|
||||||
- export IMAGE_TAG=$CI_COMMIT_TAG
|
|
||||||
|
|
||||||
.cljs-job: &cljs
|
.cljs-job: &cljs
|
||||||
image: "domaindrivenarchitecture/ddadevops-clj-cljs:4.11.3"
|
image: domaindrivenarchitecture/shadow-cljs
|
||||||
cache:
|
cache:
|
||||||
key: ${CI_COMMIT_REF_SLUG}
|
key: ${CI_COMMIT_REF_SLUG}
|
||||||
paths:
|
paths:
|
||||||
|
@ -24,62 +17,60 @@ stages:
|
||||||
- .shadow-cljs/
|
- .shadow-cljs/
|
||||||
- .m2
|
- .m2
|
||||||
before_script:
|
before_script:
|
||||||
- export RELEASE_ARTIFACT_TOKEN=$MEISSA_REPO_BUERO_RW
|
|
||||||
- echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
|
- echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
|
||||||
- npm install
|
- npm install
|
||||||
|
|
||||||
.clj-job: &clj
|
.clj-uploadjob: &clj
|
||||||
image: "domaindrivenarchitecture/ddadevops-clj:4.11.3"
|
image: domaindrivenarchitecture/lein
|
||||||
cache:
|
cache:
|
||||||
key: ${CI_COMMIT_REF_SLUG}
|
key: ${CI_COMMIT_REF_SLUG}
|
||||||
paths:
|
paths:
|
||||||
- .m2
|
- .m2
|
||||||
before_script:
|
before_script:
|
||||||
- export RELEASE_ARTIFACT_TOKEN=$MEISSA_REPO_BUERO_RW
|
|
||||||
- mkdir -p /root/.lein
|
- mkdir -p /root/.lein
|
||||||
- echo "{:auth {:repository-auth {#\"clojars\" {:username \"${CLOJARS_USER}\" :password \"${CLOJARS_TOKEN_DOMAINDRIVENARCHITECTURE}\" }}}}" > ~/.lein/profiles.clj
|
- echo "{:auth {:repository-auth {#\"clojars\" {:username \"${CLOJARS_USER}\" :password \"${CLOJARS_TOKEN_DOMAINDRIVENARCHITECTURE}\" }}}}" > ~/.lein/profiles.clj
|
||||||
|
|
||||||
.tag_only: &tag_only
|
|
||||||
rules:
|
|
||||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
|
||||||
when: never
|
|
||||||
- if: '$CI_COMMIT_TAG =~ /^[0-9]+\.[0-9]+\.[0-9]+$/'
|
|
||||||
|
|
||||||
test-clj:
|
|
||||||
<<: *clj
|
|
||||||
stage: build_and_test
|
|
||||||
script:
|
|
||||||
- pyb test_clj
|
|
||||||
|
|
||||||
test-cljs:
|
test-cljs:
|
||||||
<<: *cljs
|
<<: *cljs
|
||||||
stage: build_and_test
|
stage: build_and_test
|
||||||
script:
|
script:
|
||||||
- pyb test_cljs
|
- shadow-cljs compile test
|
||||||
|
|
||||||
|
test-clj:
|
||||||
|
<<: *clj
|
||||||
|
stage: build_and_test
|
||||||
|
script:
|
||||||
|
- lein test
|
||||||
|
|
||||||
test-schema:
|
test-schema:
|
||||||
<<: *clj
|
<<: *clj
|
||||||
stage: build_and_test
|
stage: build_and_test
|
||||||
script:
|
script:
|
||||||
- pyb test_schema
|
- lein uberjar
|
||||||
|
- java -jar target/uberjar/c4k-nextcloud-standalone.jar valid-config.edn valid-auth.edn | kubeconform --kubernetes-version 1.19.0 --strict --skip Certificate -
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- target/uberjar
|
- target/uberjar
|
||||||
|
|
||||||
report-frontend:
|
.report-frontend:
|
||||||
<<: *cljs
|
<<: *cljs
|
||||||
stage: package
|
stage: package
|
||||||
script:
|
script:
|
||||||
- pyb report_frontend
|
- mkdir -p target/frontend-build
|
||||||
|
- shadow-cljs run shadow.cljs.build-report frontend target/frontend-build/build-report.html
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- target/frontend-build/build-report.html
|
- target/frontend-build/build-report.html
|
||||||
|
|
||||||
package-frontend:
|
.package-frontend:
|
||||||
<<: *cljs
|
<<: *cljs
|
||||||
stage: package
|
stage: package
|
||||||
script:
|
script:
|
||||||
- pyb package_frontend
|
- mkdir -p target/frontend-build
|
||||||
|
- shadow-cljs release frontend
|
||||||
|
- cp public/js/main.js target/frontend-build/c4k-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
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- target/frontend-build
|
- target/frontend-build
|
||||||
|
@ -88,44 +79,63 @@ package-uberjar:
|
||||||
<<: *clj
|
<<: *clj
|
||||||
stage: package
|
stage: package
|
||||||
script:
|
script:
|
||||||
- pyb package_uberjar
|
- 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
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- target/uberjar
|
- target/uberjar
|
||||||
|
|
||||||
package-native:
|
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:
|
||||||
<<: *clj
|
<<: *clj
|
||||||
stage: package
|
stage: upload
|
||||||
|
rules:
|
||||||
|
- if: '$CI_COMMIT_BRANCH == "master" && $CI_COMMIT_TAG == null'
|
||||||
script:
|
script:
|
||||||
- pyb package_native
|
- lein deploy clojars
|
||||||
|
|
||||||
|
release:
|
||||||
|
image: registry.gitlab.com/gitlab-org/release-cli:latest
|
||||||
|
stage: upload
|
||||||
|
rules:
|
||||||
|
- if: '$CI_COMMIT_TAG != null'
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- target/graalvm
|
- target/uberjar
|
||||||
|
- target/frontend-build
|
||||||
release-to-clojars:
|
|
||||||
<<: *clj
|
|
||||||
<<: *tag_only
|
|
||||||
stage: upload
|
|
||||||
script:
|
script:
|
||||||
- pyb upload_clj
|
- 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\"}" \
|
||||||
|
|
||||||
release-to-forgejo:
|
nextcloud-image-test-publish:
|
||||||
<<: *clj
|
image: domaindrivenarchitecture/devops-build:latest
|
||||||
<<: *tag_only
|
|
||||||
stage: upload
|
|
||||||
script:
|
|
||||||
- pyb publish_artifacts
|
|
||||||
|
|
||||||
backup-image-publish:
|
|
||||||
<<: *img
|
|
||||||
<<: *tag_only
|
|
||||||
stage: image
|
stage: image
|
||||||
|
rules:
|
||||||
|
- if: '$CI_COMMIT_TAG != null'
|
||||||
script:
|
script:
|
||||||
- cd infrastructure/backup && pyb image publish
|
- cd infrastructure/docker-nextcloud && pyb image test publish
|
||||||
|
|
||||||
nextcloud-image-publish:
|
backup-image-test-publish:
|
||||||
<<: *img
|
image: domaindrivenarchitecture/devops-build:latest
|
||||||
<<: *tag_only
|
|
||||||
stage: image
|
stage: image
|
||||||
|
rules:
|
||||||
|
- if: '$CI_COMMIT_TAG != null'
|
||||||
script:
|
script:
|
||||||
- cd infrastructure/nextcloud && pyb image publish
|
- cd infrastructure/docker-backup && pyb image test publish
|
56
README.md
56
README.md
|
@ -1,55 +1,5 @@
|
||||||
# convention 4 kubernetes: c4k-nextcloud
|
# meissa-cloud
|
||||||
[![Clojars Project](https://img.shields.io/clojars/v/org.domaindrivenarchitecture/c4k-nextcloud.svg)](https://clojars.org/org.domaindrivenarchitecture/c4k-nextcloud) [![pipeline status](https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud/badges/master/pipeline.svg)](https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud/-/commits/master)
|
|
||||||
|
|
||||||
[<img src="https://domaindrivenarchitecture.org/img/delta-chat.svg" width=20 alt="DeltaChat"> chat over e-mail](mailto:buero@meissa-gmbh.de?subject=community-chat) | [<img src="https://meissa-gmbh.de/img/community/Mastodon_Logotype.svg" width=20 alt="team@social.meissa-gmbh.de"> team@social.meissa-gmbh.de](https://social.meissa-gmbh.de/@team) | [Website & Blog](https://domaindrivenarchitecture.org)
|
# backup manuell triggern
|
||||||
|
|
||||||
## Purpose
|
# restore manuell triggern
|
||||||
|
|
||||||
c4k-nextcloud provides a k8s deployment for nextcloud containing:
|
|
||||||
* adjusted nextcloud docker image
|
|
||||||
* nextcloud
|
|
||||||
* ingress having a letsencrypt managed certificate
|
|
||||||
* postgres database
|
|
||||||
|
|
||||||
The package aims to a low load sceanrio.
|
|
||||||
|
|
||||||
## Status
|
|
||||||
|
|
||||||
Stable - we use this setup on production.
|
|
||||||
|
|
||||||
## Try out
|
|
||||||
|
|
||||||
Click on the image to try out live in your browser:
|
|
||||||
|
|
||||||
[![Try it out](doc/tryItOut.png "Try out yourself")](https://domaindrivenarchitecture.org/pages/dda-provision/c4k-nextcloud/)
|
|
||||||
|
|
||||||
Your input will stay in your browser. No server interaction is required.
|
|
||||||
|
|
||||||
You will also be able to try out on cli:
|
|
||||||
```
|
|
||||||
target/graalvm/c4k-nextcloud src/test/resources/valid-config.edn src/test/resources/valid-auth.edn | kubeval -
|
|
||||||
target/graalvm/c4k-nextcloud src/test/resources/valid-config.edn src/test/resources/valid-auth.edn | kubectl apply -f -
|
|
||||||
```
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
* [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, 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)
|
|
233
build.py
233
build.py
|
@ -1,233 +0,0 @@
|
||||||
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)
|
|
|
@ -1,46 +0,0 @@
|
||||||
# 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,31 +39,34 @@ npx shadow-cljs release frontend
|
||||||
## graalvm-setup
|
## graalvm-setup
|
||||||
|
|
||||||
```
|
```
|
||||||
curl -LO https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-21.0.2/graalvm-community-jdk-21.0.2_linux-x64_bin.tar.gz
|
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
|
||||||
|
|
||||||
# unpack
|
# unpack
|
||||||
tar -xzf graalvm-community-jdk-21.0.2_linux-x64_bin.tar.gz
|
tar -xzf graalvm-ce-java11-linux-amd64-21.0.0.2.tar.gz
|
||||||
|
|
||||||
sudo mv graalvm-community-openjdk-21.0.2+13.1 /usr/lib/jvm/
|
sudo mv graalvm-ce-java11-21.0.0.2 /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-ce-java11-21.0.0.2 /usr/lib/jvm/graalvm
|
||||||
sudo ln -s /usr/lib/jvm/graalvm-21/bin/gu /usr/local/bin
|
sudo ln -s /usr/lib/jvm/graalvm/bin/gu /usr/local/bin
|
||||||
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/graalvm-21/bin/java 2
|
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/graalvm/bin/java 2
|
||||||
sudo update-alternatives --config java
|
sudo update-alternatives --config java
|
||||||
sudo ln -s /usr/lib/jvm/graalvm-21/bin/native-image /usr/local/bin
|
|
||||||
|
# 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
|
||||||
|
|
||||||
# deps
|
# deps
|
||||||
sudo apt-get install build-essential libz-dev zlib1g-dev
|
sudo apt-get install build-essential libz-dev zlib1g-dev
|
||||||
|
|
||||||
# build
|
# build
|
||||||
cd ~/repo/c4k/c4k-nextcloud
|
cd ~/repo/dda/c4k-cloud
|
||||||
lein uberjar
|
lein uberjar
|
||||||
mkdir -p target/graalvm
|
mkdir -p target/graalvm
|
||||||
lein native
|
lein native
|
||||||
|
|
||||||
# execute
|
# execute
|
||||||
./target/graalvm/c4k-nextcloud -h
|
./target/graalvm/c4k-cloud -h
|
||||||
./target/graalvm/c4k-nextcloud src/test/resources/nextcloud-test/valid-config.yaml src/test/resources/nextcloud-test/valid-auth.yaml
|
./target/graalvm/c4k-cloud src/test/resources/valid-config.edn src/test/resources/valid-auth.edn
|
||||||
./target/graalvm/c4k-nextcloud src/test/resources/nextcloud-test/invalid-config.yaml src/test/resources/nextcloud-test/invalid-auth.yaml
|
./target/graalvm/c4k-cloud src/test/resources/invalid-config.edn src/test/resources/invalid-auth.edn
|
||||||
```
|
```
|
||||||
|
|
||||||
## c4k-setup
|
## c4k-setup
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
# 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
|
|
|
@ -1,41 +0,0 @@
|
||||||
# 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
|
|
|
@ -1,76 +0,0 @@
|
||||||
# Setup
|
|
||||||
## Infrastructure on Hetzner / Aws
|
|
||||||
|
|
||||||
For a setup on hetzner / aws we use terraform.
|
|
||||||
|
|
||||||
```
|
|
||||||
resource "aws_s3_bucket" "backup" {
|
|
||||||
bucket = "backup"
|
|
||||||
acl = "private"
|
|
||||||
|
|
||||||
versioning {
|
|
||||||
enabled = false
|
|
||||||
}
|
|
||||||
tags = {
|
|
||||||
name = "backup"
|
|
||||||
Description = "bucket for backups in stage: ${var.stage}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "hcloud_server" "cloud_09_2021" {
|
|
||||||
name = "the name"
|
|
||||||
image = "ubuntu-20.04"
|
|
||||||
server_type = "cx31"
|
|
||||||
location = "fsn1"
|
|
||||||
ssh_keys = ...
|
|
||||||
|
|
||||||
lifecycle {
|
|
||||||
ignore_changes = [ssh_keys]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "aws_route53_record" "v4_neu" {
|
|
||||||
zone_id = the_dns_zone
|
|
||||||
name = "cloud-neu"
|
|
||||||
type = "A"
|
|
||||||
ttl = "300"
|
|
||||||
records = [hcloud_server.cloud_09_2021.ipv4_address]
|
|
||||||
}
|
|
||||||
|
|
||||||
output "ipv4" {
|
|
||||||
value = hcloud_server.cloud_09_2021.ipv4_address
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## k8s minicluster
|
|
||||||
|
|
||||||
For k8s installation we use our [provs](https://repo.prod.meissa.de/meissa/provs) with the following configuation:
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
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
|
|
||||||
|
|
||||||
The last step for applying the nextcloud deployment is
|
|
||||||
|
|
||||||
```
|
|
||||||
c4k-nextcloud config.edn auth.edn | kubectl apply -f -
|
|
||||||
```
|
|
||||||
|
|
||||||
with the following config.edn:
|
|
||||||
|
|
||||||
```
|
|
||||||
{:fqdn "the-fqdn-from aws_route53_record.v4_neu"
|
|
||||||
:nextcloud-data-volume-path "/var/cloud" ;; Volume was configured at dda-k8s-crate, results in a PersistentVolume definition.
|
|
||||||
:postgres-data-volume-path "/var/postgres" ;; Volume was configured at dda-k8s-crate, results in a PersistentVolume definition.
|
|
||||||
:restic-repository "s3:s3.amazonaws.com/your-bucket/your-folder"}
|
|
||||||
```
|
|
|
@ -1,10 +0,0 @@
|
||||||
# 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
294
doc/backup.svg
|
@ -1,294 +0,0 @@
|
||||||
<?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>
|
|
Before Width: | Height: | Size: 42 KiB |
BIN
doc/tryItOut.png
BIN
doc/tryItOut.png
Binary file not shown.
Before Width: | Height: | Size: 63 KiB |
|
@ -1,30 +0,0 @@
|
||||||
# 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
|
|
||||||
```
|
|
|
@ -1,54 +0,0 @@
|
||||||
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,21 +0,0 @@
|
||||||
#!/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
|
|
|
@ -1,31 +0,0 @@
|
||||||
#!/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
|
|
49
infrastructure/docker-backup/build.py
Normal file
49
infrastructure/docker-backup/build.py
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
from os import environ
|
||||||
|
from pybuilder.core import task, init
|
||||||
|
from ddadevops import *
|
||||||
|
import logging
|
||||||
|
|
||||||
|
name = 'meissa-cloud-backup'
|
||||||
|
MODULE = 'docker'
|
||||||
|
PROJECT_ROOT_PATH = '../..'
|
||||||
|
|
||||||
|
|
||||||
|
class MyBuild(DevopsDockerBuild):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@init
|
||||||
|
def initialize(project):
|
||||||
|
project.build_depends_on('ddadevops>=0.6.1')
|
||||||
|
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,4 +1,4 @@
|
||||||
FROM domaindrivenarchitecture/dda-backup:latest
|
FROM domaindrivenarchitecture/dda-backup
|
||||||
|
|
||||||
# Prepare Entrypoint Script
|
# Prepare Entrypoint Script
|
||||||
ADD resources /tmp
|
ADD resources /tmp
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -Eexo pipefail
|
set -o pipefail
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
|
|
||||||
|
@ -11,8 +11,7 @@ function main() {
|
||||||
file_env POSTGRES_DB
|
file_env POSTGRES_DB
|
||||||
file_env POSTGRES_PASSWORD
|
file_env POSTGRES_PASSWORD
|
||||||
file_env POSTGRES_USER
|
file_env POSTGRES_USER
|
||||||
file_env RESTIC_DAYS_TO_KEEP 30
|
file_env RESTIC_DAYS_TO_KEEP 14
|
||||||
file_env RESTIC_MONTHS_TO_KEEP 12
|
|
||||||
|
|
||||||
backup-roles 'oc_'
|
backup-roles 'oc_'
|
||||||
backup-db-dump
|
backup-db-dump
|
|
@ -1,7 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -exo pipefail
|
|
||||||
|
|
||||||
if test -f "/var/backups/config/config.orig"; then
|
if test -f "/var/backups/config/config.orig"; then
|
||||||
|
|
||||||
rm /var/backups/config/config.php
|
rm /var/backups/config/config.php
|
|
@ -1,7 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -exo pipefail
|
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
file_env POSTGRES_DB
|
file_env POSTGRES_DB
|
||||||
file_env POSTGRES_PASSWORD
|
file_env POSTGRES_PASSWORD
|
|
@ -1,7 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -Eexo pipefail
|
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
file_env POSTGRES_DB
|
file_env POSTGRES_DB
|
||||||
file_env POSTGRES_PASSWORD
|
file_env POSTGRES_PASSWORD
|
|
@ -1,7 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -Eexo pipefail
|
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
file_env AWS_ACCESS_KEY_ID
|
file_env AWS_ACCESS_KEY_ID
|
||||||
file_env AWS_SECRET_ACCESS_KEY
|
file_env AWS_SECRET_ACCESS_KEY
|
12
infrastructure/docker-backup/image/resources/install.sh
Executable file
12
infrastructure/docker-backup/image/resources/install.sh
Executable file
|
@ -0,0 +1,12 @@
|
||||||
|
#!/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,12 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -Eexo pipefail
|
set -Eeo pipefail
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
local role_snapshot_id="${1:-latest}"
|
|
||||||
local db_snapshot_id="${2:-latest}"
|
|
||||||
local file_snapshot_id="${3:-latest}"
|
|
||||||
|
|
||||||
|
|
||||||
start-maintenance.sh
|
start-maintenance.sh
|
||||||
|
|
||||||
|
@ -19,15 +15,14 @@ function main() {
|
||||||
|
|
||||||
drop-create-db
|
drop-create-db
|
||||||
|
|
||||||
restore-roles ${role_snapshot_id}
|
restore-roles
|
||||||
restore-db ${db_snapshot_id}
|
restore-db
|
||||||
restore-directory '/var/backups/' ${file_snapshot_id}
|
restore-directory '/var/backups/'
|
||||||
|
|
||||||
end-maintenance.sh
|
|
||||||
}
|
}
|
||||||
|
|
||||||
source /usr/local/lib/functions.sh
|
source /usr/local/lib/functions.sh
|
||||||
source /usr/local/lib/pg-functions.sh
|
source /usr/local/lib/pg-functions.sh
|
||||||
source /usr/local/lib/file-functions.sh
|
source /usr/local/lib/file-functions.sh
|
||||||
|
main
|
||||||
|
|
||||||
main "$@"
|
|
|
@ -4,10 +4,7 @@ if [ ! -f "/var/backups/config/config.orig" ]; then
|
||||||
|
|
||||||
rm -f /var/backups/config/config.orig
|
rm -f /var/backups/config/config.orig
|
||||||
cp /var/backups/config/config.php /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
|
sed -i "s/);/ \'maintenance\' => true,\n);/g" /var/backups/config/config.php
|
||||||
|
|
||||||
chown www-data:root /var/backups/config/config.php
|
chown www-data:root /var/backups/config/config.php
|
||||||
touch /var/backups/config/config.php
|
touch /var/backups/config/config.php
|
||||||
|
|
10
infrastructure/docker-backup/test/Dockerfile
Normal file
10
infrastructure/docker-backup/test/Dockerfile
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
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
|
7
infrastructure/docker-backup/test/serverspec.edn
Normal file
7
infrastructure/docker-backup/test/serverspec.edn
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{: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"}]}
|
49
infrastructure/docker-nextcloud/build.py
Normal file
49
infrastructure/docker-nextcloud/build.py
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
from os import environ
|
||||||
|
from pybuilder.core import task, init
|
||||||
|
from ddadevops import *
|
||||||
|
import logging
|
||||||
|
|
||||||
|
name = 'meissa-cloud-app'
|
||||||
|
MODULE = 'docker'
|
||||||
|
PROJECT_ROOT_PATH = '../..'
|
||||||
|
|
||||||
|
|
||||||
|
class MyBuild(DevopsDockerBuild):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@init
|
||||||
|
def initialize(project):
|
||||||
|
project.build_depends_on('ddadevops>=0.6.1')
|
||||||
|
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,7 +1,4 @@
|
||||||
FROM nextcloud:29
|
FROM nextcloud:19
|
||||||
|
|
||||||
# REQUIRES docker >= 2.10.10
|
|
||||||
# https://docs.docker.com/engine/release-notes/20.10/#201010
|
|
||||||
|
|
||||||
# Prepare Entrypoint Script
|
# Prepare Entrypoint Script
|
||||||
ADD resources /tmp
|
ADD resources /tmp
|
|
@ -1,6 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
set -exo pipefail
|
|
||||||
|
|
||||||
# version_greater A B returns whether A > B
|
# version_greater A B returns whether A > B
|
||||||
version_greater() {
|
version_greater() {
|
9
infrastructure/docker-nextcloud/image/resources/install.sh
Executable file
9
infrastructure/docker-nextcloud/image/resources/install.sh
Executable file
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -Eeo pipefail
|
||||||
|
|
||||||
|
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 /
|
11
infrastructure/docker-nextcloud/test/Dockerfile
Normal file
11
infrastructure/docker-nextcloud/test/Dockerfile
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
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
|
2
infrastructure/docker-nextcloud/test/serverspec.edn
Normal file
2
infrastructure/docker-nextcloud/test/serverspec.edn
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
{:file [{:path "/var/data"}
|
||||||
|
{:path "/entrypoint.sh" :mod "755"}]}
|
|
@ -1,53 +0,0 @@
|
||||||
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,20 +0,0 @@
|
||||||
#!/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
|
|
|
@ -2,7 +2,7 @@
|
||||||
"name": "c4k-nextcloud",
|
"name": "c4k-nextcloud",
|
||||||
"description": "Generate c4k yaml for a nextcloud deployment.",
|
"description": "Generate c4k yaml for a nextcloud deployment.",
|
||||||
"author": "meissa GmbH",
|
"author": "meissa GmbH",
|
||||||
"version": "10.2.1-SNAPSHOT",
|
"version": "0.1.3-SNAPSHOT",
|
||||||
"homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud#readme",
|
"homepage": "https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud#readme",
|
||||||
"repository": "https://www.npmjs.com/package/c4k-nextcloud",
|
"repository": "https://www.npmjs.com/package/c4k-nextcloud",
|
||||||
"license": "APACHE2",
|
"license": "APACHE2",
|
||||||
|
|
32
project.clj
32
project.clj
|
@ -1,20 +1,19 @@
|
||||||
(defproject org.domaindrivenarchitecture/c4k-nextcloud "10.2.1-SNAPSHOT"
|
(defproject org.domaindrivenarchitecture/c4k-nextcloud "1.0.2-SNAPSHOT"
|
||||||
:description "nextcloud c4k-installation package"
|
:description "nextcloud c4k-installation package"
|
||||||
:url "https://domaindrivenarchitecture.org"
|
:url "https://domaindrivenarchitecture.org"
|
||||||
:license {:name "Apache License, Version 2.0"
|
:license {:name "Apache License, Version 2.0"
|
||||||
:url "https://www.apache.org/licenses/LICENSE-2.0.html"}
|
:url "https://www.apache.org/licenses/LICENSE-2.0.html"}
|
||||||
:dependencies [[org.clojure/clojure "1.11.3"]
|
:dependencies [[org.clojure/clojure "1.10.3"]
|
||||||
[org.clojure/tools.reader "1.4.2"]
|
[org.clojure/tools.reader "1.3.4"]
|
||||||
[org.domaindrivenarchitecture/c4k-common-clj "6.3.1"]
|
[org.domaindrivenarchitecture/c4k-common-clj "0.2.8"]]
|
||||||
[hickory "0.7.1" :exclusions [viebel/codox-klipse-theme]]]
|
|
||||||
:target-path "target/%s/"
|
:target-path "target/%s/"
|
||||||
:source-paths ["src/main/cljc"
|
:source-paths ["src/main/cljc"
|
||||||
"src/main/clj"]
|
"src/main/clj"]
|
||||||
:resource-paths ["src/main/resources"]
|
:resource-paths ["src/main/resources"]
|
||||||
:repositories [["snapshots" :clojars]
|
:repositories [["snapshots" :clojars]
|
||||||
["releases" :clojars]]
|
["releases" :clojars]]
|
||||||
:deploy-repositories [["snapshots" {:sign-releases false :url "https://clojars.org/repo"}]
|
:deploy-repositories [["snapshots" :clojars]
|
||||||
["releases" {:sign-releases false :url "https://clojars.org/repo"}]]
|
["releases" :clojars]]
|
||||||
:profiles {:test {:test-paths ["src/test/cljc"]
|
:profiles {:test {:test-paths ["src/test/cljc"]
|
||||||
:resource-paths ["src/test/resources"]
|
:resource-paths ["src/test/resources"]
|
||||||
:dependencies [[dda/data-test "0.1.1"]]}
|
:dependencies [[dda/data-test "0.1.1"]]}
|
||||||
|
@ -22,14 +21,21 @@
|
||||||
:uberjar {:aot :all
|
:uberjar {:aot :all
|
||||||
:main dda.c4k-nextcloud.uberjar
|
:main dda.c4k-nextcloud.uberjar
|
||||||
:uberjar-name "c4k-nextcloud-standalone.jar"
|
:uberjar-name "c4k-nextcloud-standalone.jar"
|
||||||
:dependencies [[org.clojure/tools.cli "1.1.230"]
|
:dependencies [[org.clojure/tools.cli "1.0.206"]
|
||||||
[ch.qos.logback/logback-classic "1.5.6"
|
[ch.qos.logback/logback-classic "1.3.0-alpha4"
|
||||||
:exclusions [com.sun.mail/javax.mail]]
|
:exclusions [com.sun.mail/javax.mail]]
|
||||||
[org.slf4j/jcl-over-slf4j "2.0.13"]
|
[org.slf4j/jcl-over-slf4j "2.0.0-alpha1"]]}}
|
||||||
[com.github.clj-easy/graal-build-time "1.0.5"]]}}
|
|
||||||
:release-tasks [["test"]
|
:release-tasks [["test"]
|
||||||
["vcs" "assert-committed"]
|
["vcs" "assert-committed"]
|
||||||
["change" "version" "leiningen.release/bump-version" "release"]
|
["change" "version" "leiningen.release/bump-version" "release"]
|
||||||
["vcs" "commit"]
|
["vcs" "commit"]
|
||||||
["vcs" "tag" "v" "--no-sign"]
|
["vcs" "tag"]
|
||||||
["change" "version" "leiningen.release/bump-version"]])
|
["change" "version" "leiningen.release/bump-version"]]
|
||||||
|
:aliases {"native" ["shell"
|
||||||
|
"native-image"
|
||||||
|
"--report-unsupported-elements-at-runtime"
|
||||||
|
"--initialize-at-build-time"
|
||||||
|
"-jar" "target/uberjar/c4k-nextcloud-standalone.jar"
|
||||||
|
"-H:ResourceConfigurationFiles=graalvm-resource-config.json"
|
||||||
|
"-H:Log=registerResource"
|
||||||
|
"-H:Name=target/graalvm/${:name}"]})
|
|
@ -1,18 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<title>c4k-nextcloud</title>
|
|
||||||
<link href="https://domaindrivenarchitecture.org/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
|
|
||||||
<link href="https://domaindrivenarchitecture.org/css/fonts/fontawesome/fontawesome.css" rel="stylesheet"
|
|
||||||
type="text/css" />
|
|
||||||
<link href="https://domaindrivenarchitecture.org/css/custom.css" rel="stylesheet" type="text/css" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="c4k-content"></div>
|
|
||||||
<script src="js/main.js"></script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
|
@ -4,12 +4,12 @@
|
||||||
"src/test/cljc"
|
"src/test/cljc"
|
||||||
"src/test/cljs"
|
"src/test/cljs"
|
||||||
"src/test/resources"]
|
"src/test/resources"]
|
||||||
:dependencies [[org.domaindrivenarchitecture/c4k-common-cljs "6.3.1"]
|
:dependencies [[org.domaindrivenarchitecture/c4k-common-cljs "0.2.8"]]
|
||||||
[hickory "0.7.1"]]
|
|
||||||
:builds {:frontend {:target :browser
|
:builds {:frontend {:target :browser
|
||||||
:modules {:main {:init-fn dda.c4k-nextcloud.browser/init}}
|
:modules {:main {:init-fn dda.c4k-nextcloud.browser/init}}
|
||||||
:release {}
|
:release {}
|
||||||
:compiler-options {:optimizations :advanced}}
|
:compiler-options {:optimizations :advanced}}
|
||||||
:test {:target :node-test
|
:test {:target :node-test
|
||||||
:output-to "target/node-tests.js"
|
:output-to "target/node-tests.js"
|
||||||
|
:autorun true
|
||||||
:repl-pprint true}}}
|
:repl-pprint true}}}
|
|
@ -1,15 +1,56 @@
|
||||||
(ns dda.c4k-nextcloud.uberjar
|
(ns dda.c4k-nextcloud.uberjar
|
||||||
(:gen-class)
|
(:gen-class)
|
||||||
(:require
|
(:require
|
||||||
[dda.c4k-common.uberjar :as uberjar]
|
[clojure.spec.alpha :as s]
|
||||||
[dda.c4k-nextcloud.nextcloud :as nextcloud]
|
[clojure.string :as cs]
|
||||||
|
[clojure.tools.reader.edn :as edn]
|
||||||
|
[expound.alpha :as expound]
|
||||||
[dda.c4k-nextcloud.core :as core]))
|
[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]
|
(defn -main [& cmd-args]
|
||||||
(uberjar/main-common
|
(let [parsed-args-cmd (s/conform ::cmd-args cmd-args)]
|
||||||
"c4k-nextcloud"
|
(if (= ::s/invalid parsed-args-cmd)
|
||||||
nextcloud/config?
|
(invalid-args-msg ::cmd-args cmd-args)
|
||||||
nextcloud/auth?
|
(let [{:keys [options args]} parsed-args-cmd
|
||||||
core/config-defaults
|
{:keys [config auth]} args]
|
||||||
core/k8s-objects
|
(cond
|
||||||
cmd-args))
|
(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})))))))))))
|
||||||
|
|
|
@ -1,40 +1,37 @@
|
||||||
(ns dda.c4k-nextcloud.backup
|
(ns dda.c4k-nextcloud.backup
|
||||||
(:require
|
(:require
|
||||||
[clojure.spec.alpha :as s]
|
[clojure.spec.alpha :as s]
|
||||||
|
#?(:cljs [shadow.resource :as rc])
|
||||||
[dda.c4k-common.yaml :as yaml]
|
[dda.c4k-common.yaml :as yaml]
|
||||||
[dda.c4k-common.base64 :as b64]
|
[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 cp/bash-env-string?)
|
(s/def ::aws-access-key-id cm/bash-env-string?)
|
||||||
(s/def ::aws-secret-access-key cp/bash-env-string?)
|
(s/def ::aws-secret-access-key cm/bash-env-string?)
|
||||||
(s/def ::restic-password cp/bash-env-string?)
|
(s/def ::restic-password cm/bash-env-string?)
|
||||||
(s/def ::restic-repository cp/bash-env-string?)
|
(s/def ::restic-repository cm/bash-env-string?)
|
||||||
|
|
||||||
#?(:cljs
|
#?(:cljs
|
||||||
(defmethod yaml/load-resource :backup [resource-name]
|
(defmethod yaml/load-resource :backup [resource-name]
|
||||||
(get (inline-resources "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!")))))
|
||||||
|
|
||||||
(defn generate-config [my-conf]
|
(defn generate-config [my-conf]
|
||||||
(let [{:keys [restic-repository]} my-conf]
|
(let [{:keys [restic-repository]} my-conf]
|
||||||
(->
|
(->
|
||||||
(yaml/load-as-edn "backup/config.yaml")
|
(yaml/from-string (yaml/load-resource "backup/config.yaml"))
|
||||||
(cm/replace-key-value :restic-repository restic-repository))))
|
(cm/replace-key-value :restic-repository restic-repository))))
|
||||||
|
|
||||||
(defn generate-cron []
|
(defn generate-cron []
|
||||||
(yaml/from-string (yaml/load-resource "backup/cron.yaml")))
|
(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]
|
(defn generate-secret [my-auth]
|
||||||
(let [{:keys [aws-access-key-id aws-secret-access-key restic-password]} my-auth]
|
(let [{:keys [aws-access-key-id aws-secret-access-key restic-password]} my-auth]
|
||||||
(->
|
(->
|
||||||
(yaml/load-as-edn "backup/secret.yaml")
|
(yaml/from-string (yaml/load-resource "backup/secret.yaml"))
|
||||||
(cm/replace-key-value :aws-access-key-id (b64/encode aws-access-key-id))
|
(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 :aws-secret-access-key (b64/encode aws-secret-access-key))
|
||||||
(cm/replace-key-value :restic-password (b64/encode restic-password)))))
|
(cm/replace-key-value :restic-password (b64/encode restic-password)))))
|
||||||
|
|
|
@ -1,43 +1,52 @@
|
||||||
(ns dda.c4k-nextcloud.core
|
(ns dda.c4k-nextcloud.core
|
||||||
(:require
|
(:require
|
||||||
|
[clojure.string :as cs]
|
||||||
|
[clojure.spec.alpha :as s]
|
||||||
#?(:clj [orchestra.core :refer [defn-spec]]
|
#?(:clj [orchestra.core :refer [defn-spec]]
|
||||||
:cljs [orchestra.core :refer-macros [defn-spec]])
|
:cljs [orchestra.core :refer-macros [defn-spec]])
|
||||||
[dda.c4k-common.common :as cm]
|
|
||||||
[dda.c4k-common.predicate :as cp]
|
|
||||||
[dda.c4k-common.yaml :as yaml]
|
[dda.c4k-common.yaml :as yaml]
|
||||||
[dda.c4k-common.postgres :as postgres]
|
[dda.c4k-common.postgres :as postgres]
|
||||||
[dda.c4k-nextcloud.nextcloud :as nextcloud]
|
[dda.c4k-nextcloud.nextcloud :as nextcloud]
|
||||||
[dda.c4k-nextcloud.backup :as backup]
|
[dda.c4k-nextcloud.backup :as backup]))
|
||||||
[dda.c4k-common.monitoring :as mon]
|
|
||||||
[dda.c4k-common.namespace :as ns]))
|
|
||||||
|
|
||||||
(def config-defaults {:namespace "nextcloud"
|
(def config-defaults {:issuer :staging})
|
||||||
:issuer "staging"
|
|
||||||
:pvc-storage-class-name "hcloud-volumes-encrypted"
|
|
||||||
:pv-storage-size-gb 200})
|
|
||||||
|
|
||||||
(defn-spec k8s-objects cp/map-or-seq?
|
(def config? (s/keys :req-un [::nextcloud/fqdn]
|
||||||
[config nextcloud/config?
|
:opt-un [::nextcloud/issuer ::nextcloud/nextcloud-data-volume-path
|
||||||
auth nextcloud/auth?]
|
::postgres/postgres-data-volume-path ::restic-repository
|
||||||
(let [resolved-config (merge config-defaults config)]
|
::nextcloud/storage-size]))
|
||||||
(map yaml/to-string
|
|
||||||
(filter
|
(def auth? (s/keys :req-un [::postgres/postgres-db-user ::postgres/postgres-db-password
|
||||||
#(not (nil? %))
|
::aws-access-key-id ::aws-secret-access-key
|
||||||
(cm/concat-vec
|
::restic-password]))
|
||||||
(ns/generate resolved-config)
|
|
||||||
(postgres/generate (merge resolved-config {:postgres-size :8gb
|
(defn k8s-objects [config]
|
||||||
:db-name "cloud"
|
(into
|
||||||
:pv-storage-size-gb 50})
|
[]
|
||||||
auth)
|
(concat [(yaml/to-string (postgres/generate-config))
|
||||||
[(nextcloud/generate-secret auth)
|
(yaml/to-string (postgres/generate-secret config))]
|
||||||
(nextcloud/generate-pvc resolved-config)
|
(when (contains? config :postgres-data-volume-path)
|
||||||
(nextcloud/generate-deployment resolved-config)
|
[(yaml/to-string (postgres/generate-persistent-volume config))])
|
||||||
(nextcloud/generate-service)]
|
[(yaml/to-string (postgres/generate-pvc))
|
||||||
(nextcloud/generate-ingress-and-cert resolved-config)
|
(yaml/to-string (postgres/generate-deployment))
|
||||||
(when (:contains? resolved-config :restic-repository)
|
(yaml/to-string (postgres/generate-service))]
|
||||||
[(backup/generate-config resolved-config)
|
(when (contains? config :nextcloud-data-volume-path)
|
||||||
(backup/generate-secret auth)
|
[(yaml/to-string (nextcloud/generate-persistent-volume config))])
|
||||||
(backup/generate-cron)
|
[(yaml/to-string (nextcloud/generate-pvc))
|
||||||
(backup/generate-backup-restore-deployment resolved-config)])
|
(yaml/to-string (nextcloud/generate-deployment config))
|
||||||
(when (:contains? resolved-config :mon-cfg)
|
(yaml/to-string (nextcloud/generate-service))
|
||||||
(mon/generate (:mon-cfg resolved-config) (:mon-auth auth))))))))
|
(yaml/to-string (nextcloud/generate-certificate config))
|
||||||
|
(yaml/to-string (nextcloud/generate-ingress config))
|
||||||
|
(yaml/to-string (nextcloud/generate-service))]
|
||||||
|
(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))))
|
||||||
|
|
|
@ -1,72 +1,59 @@
|
||||||
(ns dda.c4k-nextcloud.nextcloud
|
(ns dda.c4k-nextcloud.nextcloud
|
||||||
(:require
|
(:require
|
||||||
[clojure.spec.alpha :as s]
|
[clojure.spec.alpha :as s]
|
||||||
#?(:clj [orchestra.core :refer [defn-spec]]
|
#?(:cljs [shadow.resource :as rc])
|
||||||
:cljs [orchestra.core :refer-macros [defn-spec]])
|
|
||||||
[dda.c4k-common.yaml :as yaml]
|
[dda.c4k-common.yaml :as yaml]
|
||||||
[dda.c4k-common.ingress :as ing]
|
[dda.c4k-common.common :as cm]))
|
||||||
[dda.c4k-common.base64 :as b64]
|
|
||||||
[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 ::fqdn cm/fqdn-string?)
|
||||||
(s/def ::issuer cp/letsencrypt-issuer?)
|
(s/def ::issuer cm/letsencrypt-issuer?)
|
||||||
(s/def ::restic-repository string?)
|
(s/def ::restic-repository string?)
|
||||||
(s/def ::nextcloud-admin-user cp/bash-env-string?)
|
(s/def ::nextcloud-data-volume-path 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
|
#?(:cljs
|
||||||
(defmethod yaml/load-resource :nextcloud [resource-name]
|
(defmethod yaml/load-resource :nextcloud [resource-name]
|
||||||
(get (inline-resources "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")
|
||||||
|
(throw (js/Error. "Undefined Resource!")))))
|
||||||
|
|
||||||
(defn-spec generate-deployment cp/map-or-seq?
|
(defn generate-certificate [config]
|
||||||
[config config?]
|
(let [{:keys [fqdn issuer]} config
|
||||||
(let [{:keys [fqdn]} config]
|
letsencrypt-issuer (str "letsencrypt-" (name issuer) "-issuer")]
|
||||||
(-> (yaml/load-as-edn "nextcloud/deployment.yaml")
|
|
||||||
(cm/replace-all-matching "fqdn" fqdn))))
|
|
||||||
|
|
||||||
(defn-spec generate-ingress-and-cert cp/map-or-seq?
|
|
||||||
[config config?]
|
|
||||||
(ing/generate-ingress-and-cert
|
|
||||||
(merge
|
|
||||||
{:service-name "cloud-service"
|
|
||||||
:service-port 80
|
|
||||||
:fqdns [(:fqdn config)]}
|
|
||||||
config)))
|
|
||||||
|
|
||||||
(defn-spec generate-pvc cp/map-or-seq?
|
|
||||||
[config (s/keys :req-un [::pv-storage-size-gb ::pvc-storage-class-name])]
|
|
||||||
(let [{:keys [pv-storage-size-gb pvc-storage-class-name]} config]
|
|
||||||
(->
|
(->
|
||||||
(yaml/load-as-edn "nextcloud/pvc.yaml")
|
(yaml/from-string (yaml/load-resource "nextcloud/certificate.yaml"))
|
||||||
(assoc-in [:spec :resources :requests :storage] (str pv-storage-size-gb "Gi"))
|
(assoc-in [:spec :commonName] fqdn)
|
||||||
(assoc-in [:spec :storageClassName] (name pvc-storage-class-name)))))
|
(assoc-in [:spec :dnsNames] [fqdn])
|
||||||
|
(assoc-in [:spec :issuerRef :name] letsencrypt-issuer))))
|
||||||
|
|
||||||
|
(defn generate-deployment [config]
|
||||||
|
(let [{:keys [fqdn]} config]
|
||||||
|
(-> (yaml/from-string (yaml/load-resource "nextcloud/deployment.yaml"))
|
||||||
|
(cm/replace-all-matching-values-by-new-value "fqdn" fqdn))))
|
||||||
|
|
||||||
|
(defn generate-ingress [config]
|
||||||
|
(let [{:keys [fqdn issuer]
|
||||||
|
:or {issuer :staging}} config
|
||||||
|
letsencrypt-issuer (str "letsencrypt-" (name issuer) "-issuer")]
|
||||||
|
(->
|
||||||
|
(yaml/from-string (yaml/load-resource "nextcloud/ingress.yaml"))
|
||||||
|
(assoc-in [:metadata :annotations :cert-manager.io/cluster-issuer] letsencrypt-issuer)
|
||||||
|
(cm/replace-all-matching-values-by-new-value "fqdn" fqdn))))
|
||||||
|
|
||||||
|
(defn 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")))
|
||||||
|
|
||||||
(defn generate-service []
|
(defn generate-service []
|
||||||
(yaml/load-as-edn "nextcloud/service.yaml"))
|
(yaml/from-string (yaml/load-resource "nextcloud/service.yaml")))
|
||||||
|
|
||||||
(defn-spec generate-secret cp/map-or-seq?
|
|
||||||
[auth auth?]
|
|
||||||
(let [{:keys [nextcloud-admin-user nextcloud-admin-password]} auth]
|
|
||||||
(->
|
|
||||||
(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,110 +1,62 @@
|
||||||
(ns dda.c4k-nextcloud.browser
|
(ns dda.c4k-nextcloud.browser
|
||||||
(:require
|
(:require
|
||||||
[clojure.tools.reader.edn :as edn]
|
[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.core :as core]
|
||||||
[dda.c4k-nextcloud.nextcloud :as nextcloud]
|
[dda.c4k-nextcloud.nextcloud :as nextcloud]
|
||||||
[dda.c4k-common.browser :as br]
|
[dda.c4k-common.browser :as br]
|
||||||
[dda.c4k-common.postgres :as pgc]))
|
[dda.c4k-common.postgres :as pgc]))
|
||||||
|
|
||||||
(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\"}
|
|
||||||
: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
|
|
||||||
[]
|
|
||||||
{:type :element
|
|
||||||
:tag :div
|
|
||||||
:content
|
|
||||||
(generate-content)})
|
|
||||||
|
|
||||||
(defn config-from-document []
|
(defn config-from-document []
|
||||||
(let [pv-storage-size-gb (br/get-content-from-element "pv-storage-size-gb" :optional true)
|
(let [nextcloud-data-volume-path (br/get-content-from-element "nextcloud-data-volume-path" :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)
|
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)
|
restic-repository (br/get-content-from-element "restic-repository" :optional true)
|
||||||
issuer (br/get-content-from-element "issuer" :optional true)
|
issuer (br/get-content-from-element "issuer" :optional true :deserializer keyword)]
|
||||||
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
|
(merge
|
||||||
{:fqdn (br/get-content-from-element "fqdn")}
|
{:fqdn (br/get-content-from-element "fqdn")}
|
||||||
(when (and (some? pv-storage-size-gb) (some? pvc-storage-class-name))
|
(when (some? nextcloud-data-volume-path)
|
||||||
{:pv-storage-size-gb pv-storage-size-gb :pvc-storage-class-name pvc-storage-class-name})
|
{:nextcloud-data-volume-path nextcloud-data-volume-path})
|
||||||
(when (some? postgres-data-volume-path)
|
(when (some? postgres-data-volume-path)
|
||||||
{:postgres-data-volume-path postgres-data-volume-path})
|
{:postgres-data-volume-path postgres-data-volume-path})
|
||||||
(when (some? restic-repository)
|
(when (some? restic-repository)
|
||||||
{:restic-repository restic-repository})
|
{:restic-repository restic-repository})
|
||||||
(when (some? issuer)
|
(when (some? issuer)
|
||||||
{:issuer issuer})
|
{:issuer issuer})
|
||||||
(when (some? mon-cluster-name)
|
)))
|
||||||
{:mon-cfg {:cluster-name mon-cluster-name
|
|
||||||
:cluster-stage (keyword mon-cluster-stage)
|
|
||||||
:grafana-cloud-url mon-cloud-url}}))))
|
|
||||||
|
|
||||||
(defn validate-all! []
|
(defn validate-all! []
|
||||||
(br/validate! "fqdn" ::nextcloud/fqdn)
|
(br/validate! "fqdn" ::nextcloud/fqdn)
|
||||||
(br/validate! "pv-storage-size-gb" ::nextcloud/pv-storage-size-gb :optional true)
|
(br/validate! "nextcloud-data-volume-path" ::nextcloud/nextcloud-data-volume-path :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! "postgres-data-volume-path" ::pgc/postgres-data-volume-path :optional true)
|
||||||
(br/validate! "restic-repository" ::nextcloud/restic-repository :optional true)
|
(br/validate! "restic-repository" ::nextcloud/restic-repository :optional true)
|
||||||
(br/validate! "issuer" ::nextcloud/issuer :optional true)
|
(br/validate! "issuer" ::nextcloud/issuer :optional true :deserializer keyword)
|
||||||
(br/validate! "mon-cluster-name" ::mon/cluster-name :optional true)
|
(br/validate! "auth" core/auth? :deserializer edn/read-string)
|
||||||
(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!))
|
(br/set-validated!))
|
||||||
|
|
||||||
(defn add-validate-listener [name]
|
|
||||||
(-> (br/get-element-by-id name)
|
|
||||||
(.addEventListener "blur" #(do (validate-all!)))))
|
|
||||||
|
|
||||||
(defn init []
|
(defn init []
|
||||||
(br/append-hickory (generate-content-div))
|
|
||||||
(-> js/document
|
(-> js/document
|
||||||
(.getElementById "generate-button")
|
(.getElementById "generate-button")
|
||||||
(.addEventListener "click"
|
(.addEventListener "click"
|
||||||
#(do (validate-all!)
|
#(do (validate-all!)
|
||||||
(-> (cm/generate-common
|
(-> (core/generate
|
||||||
(config-from-document)
|
(config-from-document)
|
||||||
(br/get-content-from-element "auth" :deserializer edn/read-string)
|
(br/get-content-from-element "auth" :deserializer edn/read-string))
|
||||||
{}
|
|
||||||
core/k8s-objects)
|
|
||||||
(br/set-output!)))))
|
(br/set-output!)))))
|
||||||
(add-validate-listener "fqdn")
|
(-> (br/get-element-by-id "fqdn")
|
||||||
(add-validate-listener "pv-storage-size-gb")
|
(.addEventListener "blur"
|
||||||
(add-validate-listener "pvc-storage-class-name")
|
#(do (validate-all!))))
|
||||||
(add-validate-listener "postgres-data-volume-path")
|
(-> (br/get-element-by-id "nextcloud-data-volume-path")
|
||||||
(add-validate-listener "restic-repository")
|
(.addEventListener "blur"
|
||||||
(add-validate-listener "issuer")
|
#(do (validate-all!))))
|
||||||
(add-validate-listener "mon-cluster-name")
|
(-> (br/get-element-by-id "postgres-data-volume-path")
|
||||||
(add-validate-listener "mon-cluster-stage")
|
(.addEventListener "blur"
|
||||||
(add-validate-listener "mon-cloud-url")
|
#(do (validate-all!))))
|
||||||
(add-validate-listener "auth"))
|
(-> (br/get-element-by-id "restic-repository")
|
||||||
|
(.addEventListener "blur"
|
||||||
|
#(do (validate-all!))))
|
||||||
|
(-> (br/get-element-by-id "issuer")
|
||||||
|
(.addEventListener "blur"
|
||||||
|
#(do (validate-all!))))
|
||||||
|
(-> (br/get-element-by-id "auth")
|
||||||
|
(.addEventListener "blur"
|
||||||
|
#(do (validate-all!))))
|
||||||
|
)
|
|
@ -1,87 +0,0 @@
|
||||||
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
|
|
59
src/main/resources/backup/backup-restore.yaml
Normal file
59
src/main/resources/backup/backup-restore.yaml
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
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_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_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,7 +2,6 @@ apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: backup-config
|
name: backup-config
|
||||||
namespace: nextcloud
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: backup
|
app.kubernetes.io/name: backup
|
||||||
app.kubernetes.io/part-of: cloud
|
app.kubernetes.io/part-of: cloud
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
|
||||||
metadata:
|
|
||||||
name: rotation-credential-secret
|
|
||||||
namespace: nextcloud
|
|
||||||
type: Opaque
|
|
||||||
data:
|
|
||||||
rotation-credential: "dGVzdAo="
|
|
|
@ -1,39 +1,29 @@
|
||||||
apiVersion: batch/v1
|
apiVersion: batch/v1beta1
|
||||||
kind: CronJob
|
kind: CronJob
|
||||||
metadata:
|
metadata:
|
||||||
name: cloud-backup
|
name: cloud-backup
|
||||||
namespace: nextcloud
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.part-of: cloud
|
app.kubernetes.part-of: cloud
|
||||||
spec:
|
spec:
|
||||||
schedule: "10 23 * * *"
|
schedule: "10 23 * * *"
|
||||||
successfulJobsHistoryLimit: 1
|
successfulJobsHistoryLimit: 0
|
||||||
failedJobsHistoryLimit: 1
|
failedJobsHistoryLimit: 0
|
||||||
jobTemplate:
|
jobTemplate:
|
||||||
spec:
|
spec:
|
||||||
template:
|
template:
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: backup-app
|
- name: backup-app
|
||||||
image: domaindrivenarchitecture/c4k-cloud-backup
|
image: domaindrivenarchitecture/meissa-cloud-backup
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command: ["/entrypoint.sh"]
|
command: ["/entrypoint.sh"]
|
||||||
env:
|
env:
|
||||||
- name: POSTGRES_USER
|
- name: POSTGRES_USER_FILE
|
||||||
valueFrom:
|
value: /var/run/secrets/cloud-secrets/postgres-user
|
||||||
secretKeyRef:
|
- name: POSTGRES_DB_FILE
|
||||||
name: postgres-secret
|
value: /var/run/secrets/cloud-secrets/postgres-db
|
||||||
key: postgres-user
|
- name: POSTGRES_PASSWORD_FILE
|
||||||
- name: POSTGRES_PASSWORD
|
value: /var/run/secrets/cloud-secrets/postgres-password
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: postgres-secret
|
|
||||||
key: postgres-password
|
|
||||||
- name: POSTGRES_DB
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: postgres-config
|
|
||||||
key: postgres-db
|
|
||||||
- name: POSTGRES_HOST
|
- name: POSTGRES_HOST
|
||||||
value: "postgresql-service:5432"
|
value: "postgresql-service:5432"
|
||||||
- name: POSTGRES_SERVICE
|
- name: POSTGRES_SERVICE
|
||||||
|
|
|
@ -2,9 +2,8 @@ apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: backup-secret
|
name: backup-secret
|
||||||
namespace: nextcloud
|
|
||||||
type: Opaque
|
type: Opaque
|
||||||
data:
|
stringData:
|
||||||
aws-access-key-id: "aws-access-key-id"
|
aws-access-key-id: aws-access-key-id
|
||||||
aws-secret-access-key: "aws-secret-access-key"
|
aws-secret-access-key: aws-secret-access-key
|
||||||
restic-password: "restic-password"
|
restic-password: restic-password
|
13
src/main/resources/nextcloud/certificate.yaml
Normal file
13
src/main/resources/nextcloud/certificate.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
apiVersion: cert-manager.io/v1alpha2
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: cloud-cert
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
secretName: cloud-secret
|
||||||
|
commonName: fqdn
|
||||||
|
dnsNames:
|
||||||
|
- fqdn
|
||||||
|
issuerRef:
|
||||||
|
name: letsencrypt-staging-issuer
|
||||||
|
kind: ClusterIssuer
|
22
src/main/resources/nextcloud/configure-as-user.sh
Normal file
22
src/main/resources/nextcloud/configure-as-user.sh
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
kubectl delete --ignore-not-found=true -f cloud-ingress.yml
|
||||||
|
kubectl delete --ignore-not-found=true -f cloud-pod.yml
|
||||||
|
kubectl delete --ignore-not-found=true -f cloud-pvc.yml
|
||||||
|
kubectl delete --ignore-not-found=true -f cloud-service.yml
|
||||||
|
kubectl delete --ignore-not-found=true -f cloud-secret.yml
|
||||||
|
kubectl delete --ignore-not-found=true -f cloud-persistent-volume.yml
|
||||||
|
|
||||||
|
#Wait for postgres to be running
|
||||||
|
while [$POSTGRES = ""]
|
||||||
|
do
|
||||||
|
POSTGRES=$(kubectl get pods --selector=app=postgresql -o jsonpath='{.items[*].metadata.name}')
|
||||||
|
done
|
||||||
|
kubectl wait --for=condition=ready pod/$POSTGRES
|
||||||
|
|
||||||
|
kubectl apply -f cloud-persistent-volume.yml
|
||||||
|
kubectl apply -f cloud-secret.yml
|
||||||
|
kubectl apply -f cloud-service.yml
|
||||||
|
kubectl apply -f cloud-pvc.yml
|
||||||
|
kubectl apply -f cloud-pod.yml
|
||||||
|
kubectl apply -f cloud-ingress.yml
|
|
@ -1,71 +1,52 @@
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: cloud-deployment
|
name: cloud
|
||||||
namespace: nextcloud
|
|
||||||
spec:
|
spec:
|
||||||
selector:
|
selector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app.kubernetes.io/name: cloud-pod
|
app: cloud
|
||||||
app.kubernetes.io/application: cloud
|
|
||||||
strategy:
|
strategy:
|
||||||
type: Recreate
|
type: Recreate
|
||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
app: cloud-app
|
app: cloud
|
||||||
app.kubernetes.io/name: cloud-pod
|
|
||||||
app.kubernetes.io/application: cloud
|
|
||||||
redeploy: v3
|
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- image: domaindrivenarchitecture/c4k-cloud:8.0.0
|
- image: domaindrivenarchitecture/meissa-cloud-app
|
||||||
name: cloud-app
|
name: cloud-app
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 80
|
- containerPort: 80
|
||||||
livenessProbe:
|
|
||||||
exec:
|
|
||||||
command:
|
|
||||||
- /bin/sh
|
|
||||||
- -c
|
|
||||||
- PGPASSWORD=$POSTGRES_PASSWORD psql -h postgresql-service -U $POSTGRES_USER $POSTGRES_DB
|
|
||||||
initialDelaySeconds: 1
|
|
||||||
periodSeconds: 5
|
|
||||||
env:
|
env:
|
||||||
- name: NEXTCLOUD_ADMIN_USER
|
- name: NEXTCLOUD_ADMIN_USER_FILE
|
||||||
valueFrom:
|
value: /var/run/secrets/cloud-secrets/nextcloud-admin-user
|
||||||
secretKeyRef:
|
- name: NEXTCLOUD_ADMIN_PASSWORD_FILE
|
||||||
name: cloud-secret
|
value: /var/run/secrets/cloud-secrets/nextcloud-admin-password
|
||||||
key: nextcloud-admin-user
|
|
||||||
- name: NEXTCLOUD_ADMIN_PASSWORD
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: cloud-secret
|
|
||||||
key: nextcloud-admin-password
|
|
||||||
- name: NEXTCLOUD_TRUSTED_DOMAINS
|
- name: NEXTCLOUD_TRUSTED_DOMAINS
|
||||||
value: fqdn
|
value: fqdn
|
||||||
- name: POSTGRES_USER
|
- name: POSTGRES_USER_FILE
|
||||||
valueFrom:
|
value: /var/run/secrets/cloud-secrets/postgres-user
|
||||||
secretKeyRef:
|
- name: POSTGRES_PASSWORD_FILE
|
||||||
name: postgres-secret
|
value: /var/run/secrets/cloud-secrets/postgres-password
|
||||||
key: postgres-user
|
- name: POSTGRES_DB_FILE
|
||||||
- name: POSTGRES_PASSWORD
|
value: /var/run/secrets/cloud-secrets/postgres-db
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: postgres-secret
|
|
||||||
key: postgres-password
|
|
||||||
- name: POSTGRES_DB
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: postgres-config
|
|
||||||
key: postgres-db
|
|
||||||
- name: POSTGRES_HOST
|
- name: POSTGRES_HOST
|
||||||
value: "postgresql-service:5432"
|
value: "postgresql-service:5432"
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: cloud-data-volume
|
- name: cloud-data-volume
|
||||||
mountPath: /var/www/html
|
mountPath: /var/www/html
|
||||||
|
- name: cloud-secret-volume
|
||||||
|
mountPath: /var/run/secrets/cloud-secrets
|
||||||
|
readOnly: true
|
||||||
volumes:
|
volumes:
|
||||||
- name: cloud-data-volume
|
- name: cloud-data-volume
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
claimName: cloud-pvc
|
claimName: cloud-pvc
|
||||||
|
- name: cloud-secret-volume
|
||||||
|
secret:
|
||||||
|
secretName: cloud-secret
|
||||||
|
- name: backup-secret-volume
|
||||||
|
secret:
|
||||||
|
secretName: backup-secret
|
||||||
|
|
26
src/main/resources/nextcloud/ingress.yaml
Normal file
26
src/main/resources/nextcloud/ingress.yaml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
apiVersion: extensions/v1beta1
|
||||||
|
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: /
|
||||||
|
backend:
|
||||||
|
serviceName: cloud-service
|
||||||
|
servicePort: 80
|
4
src/main/resources/nextcloud/install-as-root.sh.template
Normal file
4
src/main/resources/nextcloud/install-as-root.sh.template
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
mkdir -p /var/cloud
|
||||||
|
install -d -m 0777 -o {{user}} -g {{user}} /var/cloud
|
15
src/main/resources/nextcloud/persistent-volume.yaml
Normal file
15
src/main/resources/nextcloud/persistent-volume.yaml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
kind: PersistentVolume
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: cloud-pv-volume
|
||||||
|
labels:
|
||||||
|
type: local
|
||||||
|
app: cloud
|
||||||
|
spec:
|
||||||
|
storageClassName: manual
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
capacity:
|
||||||
|
storage: 200Gi
|
||||||
|
hostPath:
|
||||||
|
path: "/var/cloud"
|
25
src/main/resources/nextcloud/pod-running.sh
Normal file
25
src/main/resources/nextcloud/pod-running.sh
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#!/bin/bash
|
||||||
|
SECONDS=0
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
|
||||||
|
POD_STATUS="$(kubectl get pods --all-namespaces --field-selector=status.phase=Running | grep $1 )";
|
||||||
|
if [ ! -z "$POD_STATUS" ]
|
||||||
|
then
|
||||||
|
# pod = ready is not enough
|
||||||
|
sleep $4
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
let duration=$SECONDS/60
|
||||||
|
# pallet needs a regular action, otherwise unwanted timeout after 5 min
|
||||||
|
echo "Seconds waited: ${SECONDS}"
|
||||||
|
if [ "$duration" -ge "$2" ]
|
||||||
|
then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep $3
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 0
|
|
@ -2,14 +2,15 @@ apiVersion: v1
|
||||||
kind: PersistentVolumeClaim
|
kind: PersistentVolumeClaim
|
||||||
metadata:
|
metadata:
|
||||||
name: cloud-pvc
|
name: cloud-pvc
|
||||||
namespace: nextcloud
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/application: cloud
|
app: cloud
|
||||||
spec:
|
spec:
|
||||||
storageClassName: REPLACEME
|
storageClassName: manual
|
||||||
accessModes:
|
accessModes:
|
||||||
- ReadWriteOnce
|
- ReadWriteOnce
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
storage: REPLACEME
|
storage: 200Gi
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: cloud
|
||||||
|
|
|
@ -2,8 +2,10 @@ apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: cloud-secret
|
name: cloud-secret
|
||||||
namespace: nextcloud
|
|
||||||
type: Opaque
|
type: Opaque
|
||||||
data:
|
stringData:
|
||||||
nextcloud-admin-user: "admin-user"
|
postgres-db: db-name
|
||||||
nextcloud-admin-password: "admin-password"
|
postgres-user: db-user-name
|
||||||
|
postgres-password: db-user-password
|
||||||
|
nextcloud-admin-user: admin-user
|
||||||
|
nextcloud-admin-password: admin-password
|
||||||
|
|
|
@ -2,13 +2,8 @@ apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
name: cloud-service
|
name: cloud-service
|
||||||
namespace: nextcloud
|
|
||||||
labels:
|
|
||||||
app.kubernetes.io/name: cloud-service
|
|
||||||
app.kubernetes.io/application: cloud
|
|
||||||
spec:
|
spec:
|
||||||
selector:
|
selector:
|
||||||
app.kubernetes.io/name: cloud-pod
|
app.kubernetes.io/name: cloud
|
||||||
app.kubernetes.io/application: cloud
|
|
||||||
ports:
|
ports:
|
||||||
- port: 80
|
- port: 80
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
(deftest should-generate-secret
|
(deftest should-generate-secret
|
||||||
(is (= {:apiVersion "v1"
|
(is (= {:apiVersion "v1"
|
||||||
:kind "Secret"
|
:kind "Secret"
|
||||||
:metadata {:name "backup-secret", :namespace "nextcloud"}
|
:metadata {:name "backup-secret"}
|
||||||
:type "Opaque"
|
:type "Opaque"
|
||||||
:data
|
:stringData
|
||||||
{:aws-access-key-id "YXdzLWlk", :aws-secret-access-key "YXdzLXNlY3JldA==", :restic-password "cmVzdGljLXB3"}}
|
{:aws-access-key-id "YXdzLWlk", :aws-secret-access-key "YXdzLXNlY3JldA==", :restic-password "cmVzdGljLXB3"}}
|
||||||
(cut/generate-secret {:aws-access-key-id "aws-id" :aws-secret-access-key "aws-secret" :restic-password "restic-pw"}))))
|
(cut/generate-secret {:aws-access-key-id "aws-id" :aws-secret-access-key "aws-secret" :restic-password "restic-pw"}))))
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@
|
||||||
(is (= {:apiVersion "v1"
|
(is (= {:apiVersion "v1"
|
||||||
:kind "ConfigMap"
|
:kind "ConfigMap"
|
||||||
:metadata {:name "backup-config"
|
:metadata {:name "backup-config"
|
||||||
:namespace "nextcloud"
|
|
||||||
:labels {:app.kubernetes.io/name "backup"
|
:labels {:app.kubernetes.io/name "backup"
|
||||||
:app.kubernetes.io/part-of "cloud"}}
|
:app.kubernetes.io/part-of "cloud"}}
|
||||||
:data
|
:data
|
||||||
|
@ -26,11 +25,11 @@
|
||||||
(cut/generate-config {:restic-repository "s3:restic-repository"}))))
|
(cut/generate-config {:restic-repository "s3:restic-repository"}))))
|
||||||
|
|
||||||
(deftest should-generate-cron
|
(deftest should-generate-cron
|
||||||
(is (= {:apiVersion "batch/v1"
|
(is (= {:apiVersion "batch/v1beta1"
|
||||||
:kind "CronJob"
|
:kind "CronJob"
|
||||||
:metadata {:name "cloud-backup", :namespace "nextcloud", :labels {:app.kubernetes.part-of "cloud"}}
|
:metadata {:name "cloud-backup"
|
||||||
:spec
|
:labels {:app.kubernetes.part-of "cloud"}}
|
||||||
{:schedule "10 23 * * *"
|
:spec {:schedule "10 23 * * *"
|
||||||
:successfulJobsHistoryLimit 1
|
:successfulJobsHistoryLimit 1
|
||||||
:failedJobsHistoryLimit 1
|
:failedJobsHistoryLimit 1
|
||||||
:jobTemplate
|
:jobTemplate
|
||||||
|
@ -39,39 +38,56 @@
|
||||||
{:spec
|
{:spec
|
||||||
{:containers
|
{:containers
|
||||||
[{:name "backup-app"
|
[{:name "backup-app"
|
||||||
:image "domaindrivenarchitecture/c4k-cloud-backup"
|
:image "domaindrivenarchitecture/c4k-nextcloud-backup"
|
||||||
:imagePullPolicy "IfNotPresent"
|
:imagePullPolicy "IfNotPresent"
|
||||||
:command ["/entrypoint.sh"]
|
:command ["/entrypoint.sh"]
|
||||||
:env
|
:env
|
||||||
[{:valueFrom
|
[{:name "POSTGRES_USER"
|
||||||
|
:valueFrom
|
||||||
{:secretKeyRef
|
{:secretKeyRef
|
||||||
{:name "postgres-secret",
|
{:name "postgres-secret"
|
||||||
:key "postgres-user"}},
|
:key "postgres-user"}}}
|
||||||
:name "POSTGRES_USER"}
|
{:name "POSTGRES_PASSWORD"
|
||||||
{:valueFrom
|
:valueFrom
|
||||||
{:secretKeyRef
|
{:secretKeyRef
|
||||||
{:name "postgres-secret",
|
{:name "postgres-secret"
|
||||||
:key "postgres-password"}},
|
:key "postgres-password"}}}
|
||||||
:name "POSTGRES_PASSWORD"}
|
{:name "POSTGRES_DB"
|
||||||
{:valueFrom
|
:valueFrom
|
||||||
{:configMapKeyRef
|
{:configMapKeyRef
|
||||||
{:name "postgres-config", :key "postgres-db"}},
|
{:name "postgres-config"
|
||||||
:name "POSTGRES_DB"}
|
:key "postgres-db"}}}
|
||||||
{:name "POSTGRES_HOST", :value "postgresql-service:5432"}
|
{:name "POSTGRES_HOST"
|
||||||
{:name "POSTGRES_SERVICE", :value "postgresql-service"}
|
:value "postgresql-service:5432"}
|
||||||
{:name "POSTGRES_PORT", :value "5432"}
|
{:name "POSTGRES_SERVICE"
|
||||||
{:name "AWS_DEFAULT_REGION", :value "eu-central-1"}
|
:value "postgresql-service"}
|
||||||
{:name "AWS_ACCESS_KEY_ID_FILE", :value "/var/run/secrets/backup-secrets/aws-access-key-id"}
|
{:name "POSTGRES_PORT"
|
||||||
{:name "AWS_SECRET_ACCESS_KEY_FILE", :value "/var/run/secrets/backup-secrets/aws-secret-access-key"}
|
:value "5432"}
|
||||||
{:name "RESTIC_REPOSITORY", :valueFrom {:configMapKeyRef {:name "backup-config", :key "restic-repository"}}}
|
{:name "AWS_DEFAULT_REGION"
|
||||||
{:name "RESTIC_PASSWORD_FILE", :value "/var/run/secrets/backup-secrets/restic-password"}]
|
: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
|
:volumeMounts
|
||||||
[{:name "cloud-data-volume", :mountPath "/var/backups"}
|
[{:name "nextcloud-data-volume"
|
||||||
{:name "backup-secret-volume", :mountPath "/var/run/secrets/backup-secrets", :readOnly true}
|
:mountPath "/var/backups"}
|
||||||
{:name "cloud-secret-volume", :mountPath "/var/run/secrets/cloud-secrets", :readOnly true}]}]
|
{:name "backup-secret-volume"
|
||||||
|
:mountPath "/var/run/secrets/backup-secrets"
|
||||||
|
:readOnly true}]}]
|
||||||
:volumes
|
:volumes
|
||||||
[{:name "cloud-data-volume", :persistentVolumeClaim {:claimName "cloud-pvc"}}
|
[{:name "nextcloud-data-volume"
|
||||||
{:name "cloud-secret-volume", :secret {:secretName "cloud-secret"}}
|
:persistentVolumeClaim
|
||||||
{:name "backup-secret-volume", :secret {:secretName "backup-secret"}}]
|
{:claimName "cloud-pvc"}}
|
||||||
|
{:name "backup-secret-volume"
|
||||||
|
:secret
|
||||||
|
{:secretName "backup-secret"}}]
|
||||||
:restartPolicy "OnFailure"}}}}}}
|
:restartPolicy "OnFailure"}}}}}}
|
||||||
(cut/generate-cron))))
|
(cut/generate-cron))))
|
||||||
|
|
35
src/test/cljc/dda/c4k_nextcloud/core_test.cljc
Normal file
35
src/test/cljc/dda/c4k_nextcloud/core_test.cljc
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
(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"
|
||||||
|
: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"
|
||||||
|
: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"
|
||||||
|
:issuer :prod
|
||||||
|
:aws-access-key-id "aws-id"
|
||||||
|
:aws-secret-access-key "aws-secret"
|
||||||
|
:restic-password "restic-pw"})))))
|
|
@ -2,120 +2,80 @@
|
||||||
(:require
|
(:require
|
||||||
#?(:clj [clojure.test :refer [deftest is are testing run-tests]]
|
#?(:clj [clojure.test :refer [deftest is are testing run-tests]]
|
||||||
:cljs [cljs.test :refer-macros [deftest is are testing run-tests]])
|
:cljs [cljs.test :refer-macros [deftest is are testing run-tests]])
|
||||||
[clojure.spec.alpha :as s]
|
[dda.c4k-nextcloud.nextcloud :as cut]))
|
||||||
[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)
|
(deftest should-generate-certificate
|
||||||
|
(is (= {:apiVersion "cert-manager.io/v1alpha2"
|
||||||
#?(:cljs
|
:kind "Certificate"
|
||||||
(defmethod yaml/load-resource :nextcloud-test [resource-name]
|
:metadata {:name "cloud-cert", :namespace "default"}
|
||||||
(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", :namespace "nextcloud"}
|
|
||||||
:type "Opaque"
|
|
||||||
:data
|
|
||||||
{:nextcloud-admin-user "Y2xvdWRhZG1pbg=="
|
|
||||||
:nextcloud-admin-password "Y2xvdWRwYXNzd29yZA=="}}
|
|
||||||
(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-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
|
:spec
|
||||||
{:secretName "cloud-service",
|
{:secretName "cloud-secret"
|
||||||
:commonName "somefqdn.de",
|
:commonName "xx"
|
||||||
:duration "2160h",
|
:dnsNames ["xx"]
|
||||||
:renewBefore "720h",
|
:issuerRef
|
||||||
:dnsNames ["somefqdn.de"],
|
{:name "letsencrypt-prod-issuer", :kind "ClusterIssuer"}}}
|
||||||
:issuerRef {:name "staging", :kind "ClusterIssuer"}}}
|
(cut/generate-certificate {:fqdn "xx" :issuer :prod}))))
|
||||||
{:apiVersion "networking.k8s.io/v1",
|
|
||||||
:kind "Ingress",
|
(deftest should-generate-ingress
|
||||||
|
(is (= {:apiVersion "extensions/v1beta1"
|
||||||
|
:kind "Ingress"
|
||||||
:metadata
|
:metadata
|
||||||
{:name "cloud-service",
|
{:name "ingress-cloud"
|
||||||
:namespace "default",
|
|
||||||
:labels {:app.kubernetes.part-of "cloud-service"},
|
|
||||||
:annotations
|
:annotations
|
||||||
{:traefik.ingress.kubernetes.io/router.entrypoints "web, websecure",
|
{:cert-manager.io/cluster-issuer
|
||||||
:traefik.ingress.kubernetes.io/router.middlewares
|
"letsencrypt-staging-issuer"
|
||||||
"default-redirect-https@kubernetescrd",
|
:nginx.ingress.kubernetes.io/proxy-body-size "256m"
|
||||||
:metallb.universe.tf/address-pool "public"}},
|
: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
|
:spec
|
||||||
{:tls [{:hosts ["somefqdn.de"], :secretName "cloud-service"}],
|
{:tls [{:hosts ["xx"], :secretName "cloud-secret"}]
|
||||||
:rules
|
:rules
|
||||||
[{:host "somefqdn.de",
|
[{:host "xx"
|
||||||
:http
|
:http
|
||||||
{:paths
|
{:paths
|
||||||
[{:pathType "Prefix",
|
[{:path "/"
|
||||||
:path "/",
|
|
||||||
:backend
|
:backend
|
||||||
{:service {:name "cloud-service", :port {:number 80}}}}]}}]}}]
|
{:serviceName "cloud-service", :servicePort 80}}]}}]}}
|
||||||
(cut/generate-ingress-and-cert {:fqdn "somefqdn.de"}))))
|
(cut/generate-ingress {:fqdn "xx"}))))
|
||||||
|
|
||||||
(deftest should-generate-pvc
|
(deftest should-generate-persistent-volume
|
||||||
(is (= {:apiVersion "v1"
|
(is (= {:kind "PersistentVolume"
|
||||||
:kind "PersistentVolumeClaim"
|
:apiVersion "v1"
|
||||||
:metadata {:name "cloud-pvc"
|
:metadata {:name "cloud-pv-volume", :labels {:type "local" :app "cloud"}}
|
||||||
:namespace "nextcloud"
|
:spec
|
||||||
:labels {:app.kubernetes.io/application "cloud"}}
|
{:storageClassName "manual"
|
||||||
:spec {:storageClassName "local-path"
|
|
||||||
:accessModes ["ReadWriteOnce"]
|
:accessModes ["ReadWriteOnce"]
|
||||||
:resources {:requests {:storage "50Gi"}}}}
|
:capacity {:storage "200Gi"}
|
||||||
(cut/generate-pvc {:pv-storage-size-gb 50 :pvc-storage-class-name "local-path"}))))
|
:hostPath {:path "xx"}}}
|
||||||
|
(cut/generate-persistent-volume {:nextcloud-data-volume-path "xx"}))))
|
||||||
|
|
||||||
(deftest should-generate-deployment
|
(deftest should-generate-deployment
|
||||||
(is (= {:apiVersion "apps/v1"
|
(is (= {:containers
|
||||||
:kind "Deployment"
|
[{:image "domaindrivenarchitecture/meissa-cloud-app"
|
||||||
:metadata {:name "cloud-deployment", :namespace "nextcloud"}
|
|
||||||
:spec
|
|
||||||
{:selector {:matchLabels #:app.kubernetes.io{:name "cloud-pod", :application "cloud"}}
|
|
||||||
:strategy {:type "Recreate"}
|
|
||||||
: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:8.0.0"
|
|
||||||
:name "cloud-app"
|
:name "cloud-app"
|
||||||
:imagePullPolicy "IfNotPresent"
|
:imagePullPolicy "IfNotPresent"
|
||||||
:ports [{:containerPort 80}]
|
:ports [{:containerPort 80}]
|
||||||
:livenessProbe
|
|
||||||
{:exec
|
|
||||||
{:command
|
|
||||||
["/bin/sh"
|
|
||||||
"-c"
|
|
||||||
"PGPASSWORD=$POSTGRES_PASSWORD psql -h postgresql-service -U $POSTGRES_USER $POSTGRES_DB"]}
|
|
||||||
:initialDelaySeconds 1
|
|
||||||
:periodSeconds 5}
|
|
||||||
:env
|
:env
|
||||||
[{:name "NEXTCLOUD_ADMIN_USER", :valueFrom {:secretKeyRef {:name "cloud-secret", :key "nextcloud-admin-user"}}}
|
[{:name "DB_USERNAME_FILE"
|
||||||
{:name "NEXTCLOUD_ADMIN_PASSWORD"
|
:value
|
||||||
:valueFrom {:secretKeyRef {:name "cloud-secret", :key "nextcloud-admin-password"}}}
|
"/var/run/secrets/postgres-secret/postgres-user"}
|
||||||
{:name "NEXTCLOUD_TRUSTED_DOMAINS", :value "somefqdn.de"}
|
{:name "DB_PASSWORD_FILE"
|
||||||
{:name "POSTGRES_USER", :valueFrom {:secretKeyRef {:name "postgres-secret", :key "postgres-user"}}}
|
:value
|
||||||
{:name "POSTGRES_PASSWORD", :valueFrom {:secretKeyRef {:name "postgres-secret", :key "postgres-password"}}}
|
"/var/run/secrets/postgres-secret/postgres-password"}
|
||||||
{:name "POSTGRES_DB", :valueFrom {:configMapKeyRef {:name "postgres-config", :key "postgres-db"}}}
|
{:name "FQDN", :value "xx"}]
|
||||||
{:name "POSTGRES_HOST", :value "postgresql-service:5432"}]
|
:command ["/app/entrypoint.sh"]
|
||||||
:volumeMounts [{:name "cloud-data-volume", :mountPath "/var/www/html"}]}]
|
:volumeMounts
|
||||||
:volumes [{:name "cloud-data-volume", :persistentVolumeClaim {:claimName "cloud-pvc"}}]}}}}
|
[{:mountPath "/var/nextcloud", :name "cloud-data-volume"}
|
||||||
(cut/generate-deployment {:fqdn "somefqdn.de"}))))
|
{:name "postgres-secret-volume"
|
||||||
|
:mountPath "/var/run/secrets/postgres-secret"
|
||||||
|
:readOnly true}]}]
|
||||||
|
:volumes
|
||||||
|
[{:name "cloud-data-volume"
|
||||||
|
:persistentVolumeClaim {:claimName "cloud-pvc"}}
|
||||||
|
{:name "postgres-secret-volume"
|
||||||
|
:secret {:secretName "postgres-secret"}}]}
|
||||||
|
(get-in (cut/generate-deployment {:fqdn "xx"}) [:spec :template :spec]))))
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
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"
|
|
|
@ -1,5 +0,0 @@
|
||||||
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"
|
|
|
@ -1,10 +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"
|
|
||||||
mon-auth:
|
|
||||||
grafana-cloud-user: "user"
|
|
||||||
grafana-cloud-password: "password"
|
|
|
@ -1,9 +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"
|
|
||||||
mon-cfg:
|
|
||||||
grafana-cloud-url: "url-for-your-prom-remote-write-endpoint"
|
|
||||||
cluster-name: "keycloak"
|
|
||||||
cluster-stage: "test"
|
|
5
valid-auth.edn
Normal file
5
valid-auth.edn
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{:postgres-db-user "nextcloud"
|
||||||
|
:postgres-db-password "nextcloud-db-password"
|
||||||
|
:aws-access-key-id "aws-id"
|
||||||
|
:aws-secret-access-key "aws-secret"
|
||||||
|
:restic-password "restic-password"}
|
5
valid-config.edn
Normal file
5
valid-config.edn
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{:fqdn "cloud-neu.prod.meissa-gmbh.de"
|
||||||
|
:nextcloud-data-volume-path "/var/nextcloud"
|
||||||
|
:postgres-data-volume-path "/var/postgres"
|
||||||
|
;:storage-size 300
|
||||||
|
:restic-repository "restic-repository"}
|
Loading…
Reference in a new issue