From fad1bc733e7d5ec44d2a17583d8f6cb7ed24b500 Mon Sep 17 00:00:00 2001 From: Jannik Badenhop Date: Fri, 21 Jun 2024 14:49:29 +0200 Subject: [PATCH] DBP-805 Initial version of the Moodle Helm chart (#30) * Initial push * Added existing tasks of the ansible playbook to helm chart * Added remaining templates from original playbook except secrets * Fix some small variable issues so that the chart is in a working state * renaming variables, added gitignore * add subfolders, rename files to follow helm best practices * lowercase ns * fix namespace issue. helm v3 is not supposed to create the namespace it installs into. use helm install ... -n target-namespace * rename duply map to lower * Add alias for backup * move infratools_image_tag to globals trying out Yaml anchors * add update helper configs * move infratools_image_tag to globals trying out Yaml anchors * add values for backup-cronjob * moodle-> dbpMoodle & small stuff * Moodle Values added for bitnami test deployment * mariaDB values are not working as intended for subchart mariadb and moodle * Fixed config.php and moodle values * changed comment * change valeus to use correct secrets * Changed secrets and values for external mariadb * remove mariadb * rename moodleSecre * add mariadb values in seperate chart * testing moodle db connection * enable debug * quote values * Redis is working * value refactoring * remove some unneccessary values from Chart.yaml * change to consistent naming * Created more exclusion checks for update and backup files * Enabled the use of etherpad * Added etherpad secrets * WIP: etherpad not working currently * minor value and condition refactoring * Create Readme, quote a bunch of vars * bump version * Rename folders and fix typos * Fixed quotation error and added existing secret to redis * Adjusted redis values and disabled redis by default * Modified external PVC to ReadWriteMany * Final changes * Update README.md --------- Co-authored-by: marhode Co-authored-by: marhode <121863882+marhode@users.noreply.github.com> --- .gitignore | 12 + charts/dbp-moodle/.helmignore | 23 + charts/dbp-moodle/Chart.lock | 24 ++ charts/dbp-moodle/Chart.yaml | 47 +++ charts/dbp-moodle/README.md | 311 ++++++++++++++ .../charts/backup-cronjob/Chart.yaml | 6 + .../backup-cronjob/templates/_helpers.tpl | 62 +++ .../backup-cronjob/templates/clusterrole.yml | 16 + .../templates/clusterrolebinding.yml | 16 + .../backup-cronjob/templates/cronjob.yml | 150 +++++++ .../templates/serviceaccount.yml | 12 + .../charts/backup-cronjob/values.yaml | 128 ++++++ charts/dbp-moodle/charts/etherpad/.helmignore | 23 + charts/dbp-moodle/charts/etherpad/Chart.yaml | 6 + charts/dbp-moodle/charts/etherpad/README.md | 63 +++ .../charts/etherpad/templates/_helpers.tpl | 62 +++ .../charts/etherpad/templates/deployment.yaml | 73 ++++ .../charts/etherpad/templates/ingress.yaml | 46 ++ .../charts/etherpad/templates/service.yaml | 15 + .../etherpad/templates/serviceaccount.yaml | 12 + charts/dbp-moodle/charts/etherpad/values.yaml | 93 ++++ charts/dbp-moodle/scripts/backup.sh | 134 ++++++ charts/dbp-moodle/scripts/config.php | 68 +++ .../dbp-moodle/scripts/moodleCronjobScript.sh | 10 + .../dbp-moodle/scripts/moodleRestoreScript.sh | 97 +++++ .../scripts/moodleUpdateHelperJobScript.sh | 155 +++++++ charts/dbp-moodle/scripts/php.ini | 5 + charts/dbp-moodle/templates/_helpers.tpl | 50 +++ .../update-helper-clusterrolebinding.yml | 14 + .../update-helper-clusterrole.yaml | 8 + .../templates/configmaps/duply-configmap.yaml | 21 + .../moodle-backup-script-configmap.yaml | 10 + .../configmaps/moodle-cronjob-configmap.yaml | 8 + .../configmaps/moodle-plugin-configmap.yaml | 25 ++ .../moodle-restore-script-configmap.yaml | 10 + .../update-helper-script-configmap.yaml | 10 + charts/dbp-moodle/templates/hpa.yaml | 35 ++ .../templates/jobs/moodle-restore-job.yaml | 82 ++++ .../templates/jobs/update-helper-job.yaml | 39 ++ .../templates/metrics-servicemonitor.yaml | 16 + charts/dbp-moodle/templates/moodle-pvc.yaml | 22 + .../secrets/moodle-config-secret.yaml | 9 + .../templates/secrets/moodle-secret.yaml | 25 ++ .../update-helper-serviceaccount.yaml | 6 + charts/dbp-moodle/values.yaml | 399 ++++++++++++++++++ 45 files changed, 2458 insertions(+) create mode 100644 .gitignore create mode 100644 charts/dbp-moodle/.helmignore create mode 100644 charts/dbp-moodle/Chart.lock create mode 100644 charts/dbp-moodle/Chart.yaml create mode 100644 charts/dbp-moodle/README.md create mode 100644 charts/dbp-moodle/charts/backup-cronjob/Chart.yaml create mode 100644 charts/dbp-moodle/charts/backup-cronjob/templates/_helpers.tpl create mode 100644 charts/dbp-moodle/charts/backup-cronjob/templates/clusterrole.yml create mode 100644 charts/dbp-moodle/charts/backup-cronjob/templates/clusterrolebinding.yml create mode 100644 charts/dbp-moodle/charts/backup-cronjob/templates/cronjob.yml create mode 100644 charts/dbp-moodle/charts/backup-cronjob/templates/serviceaccount.yml create mode 100644 charts/dbp-moodle/charts/backup-cronjob/values.yaml create mode 100644 charts/dbp-moodle/charts/etherpad/.helmignore create mode 100644 charts/dbp-moodle/charts/etherpad/Chart.yaml create mode 100644 charts/dbp-moodle/charts/etherpad/README.md create mode 100644 charts/dbp-moodle/charts/etherpad/templates/_helpers.tpl create mode 100644 charts/dbp-moodle/charts/etherpad/templates/deployment.yaml create mode 100644 charts/dbp-moodle/charts/etherpad/templates/ingress.yaml create mode 100644 charts/dbp-moodle/charts/etherpad/templates/service.yaml create mode 100644 charts/dbp-moodle/charts/etherpad/templates/serviceaccount.yaml create mode 100644 charts/dbp-moodle/charts/etherpad/values.yaml create mode 100644 charts/dbp-moodle/scripts/backup.sh create mode 100644 charts/dbp-moodle/scripts/config.php create mode 100644 charts/dbp-moodle/scripts/moodleCronjobScript.sh create mode 100644 charts/dbp-moodle/scripts/moodleRestoreScript.sh create mode 100644 charts/dbp-moodle/scripts/moodleUpdateHelperJobScript.sh create mode 100644 charts/dbp-moodle/scripts/php.ini create mode 100644 charts/dbp-moodle/templates/_helpers.tpl create mode 100644 charts/dbp-moodle/templates/clusterrolebindings/update-helper-clusterrolebinding.yml create mode 100644 charts/dbp-moodle/templates/clusterroles/update-helper-clusterrole.yaml create mode 100644 charts/dbp-moodle/templates/configmaps/duply-configmap.yaml create mode 100644 charts/dbp-moodle/templates/configmaps/moodle-backup-script-configmap.yaml create mode 100644 charts/dbp-moodle/templates/configmaps/moodle-cronjob-configmap.yaml create mode 100644 charts/dbp-moodle/templates/configmaps/moodle-plugin-configmap.yaml create mode 100644 charts/dbp-moodle/templates/configmaps/moodle-restore-script-configmap.yaml create mode 100644 charts/dbp-moodle/templates/configmaps/update-helper-script-configmap.yaml create mode 100644 charts/dbp-moodle/templates/hpa.yaml create mode 100644 charts/dbp-moodle/templates/jobs/moodle-restore-job.yaml create mode 100644 charts/dbp-moodle/templates/jobs/update-helper-job.yaml create mode 100644 charts/dbp-moodle/templates/metrics-servicemonitor.yaml create mode 100644 charts/dbp-moodle/templates/moodle-pvc.yaml create mode 100644 charts/dbp-moodle/templates/secrets/moodle-config-secret.yaml create mode 100644 charts/dbp-moodle/templates/secrets/moodle-secret.yaml create mode 100644 charts/dbp-moodle/templates/serviceaccounts/update-helper-serviceaccount.yaml create mode 100644 charts/dbp-moodle/values.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7ad0047 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +### Helm ### +# Chart dependencies +**/charts/*.tgz + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Local test files +tmp/ diff --git a/charts/dbp-moodle/.helmignore b/charts/dbp-moodle/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/dbp-moodle/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/dbp-moodle/Chart.lock b/charts/dbp-moodle/Chart.lock new file mode 100644 index 0000000..457d774 --- /dev/null +++ b/charts/dbp-moodle/Chart.lock @@ -0,0 +1,24 @@ +dependencies: +- name: moodle + repository: https://charts.bitnami.com/bitnami + version: 22.2.7 +- name: redis + repository: https://charts.bitnami.com/bitnami + version: 19.5.3 +- name: mariadb + repository: https://charts.bitnami.com/bitnami + version: 18.2.2 +- name: postgresql + repository: https://charts.bitnami.com/bitnami + version: 15.5.7 +- name: cronjob + repository: file://charts/backup-cronjob + version: 0.1.0 +- name: postgresql + repository: https://charts.bitnami.com/bitnami + version: 15.5.7 +- name: etherpad + repository: file://charts/etherpad + version: 0.1.0 +digest: sha256:0bcbb8bdf12bab5529a1360b1157e36d2bd51e1d12b3ef653c61b07ba6936ce8 +generated: "2024-06-20T12:13:11.419404592Z" diff --git a/charts/dbp-moodle/Chart.yaml b/charts/dbp-moodle/Chart.yaml new file mode 100644 index 0000000..b1be389 --- /dev/null +++ b/charts/dbp-moodle/Chart.yaml @@ -0,0 +1,47 @@ +apiVersion: v2 +name: dbp-moodle +description: A Helm chart for dBildungsplattform Moodle including customizations +type: application +version: 1.0.0 +appVersion: "1.16.0" +dependencies: + - name: moodle + version: "22.2.7" + repository: https://charts.bitnami.com/bitnami + + - name: redis + version: "19.5.3" + repository: https://charts.bitnami.com/bitnami + condition: redis.enabled + + - name: mariadb + version: "18.2.2" + repository: https://charts.bitnami.com/bitnami + condition: mariadb.enabled + + - name: postgresql + version: "15.5.7" + repository: https://charts.bitnami.com/bitnami + condition: postgresql.enabled + + - name: cronjob + alias: backup-cronjob + version: 0.1.0 + repository: "file://charts/backup-cronjob" + condition: backup.enabled + + - name: postgresql + version: "15.5.7" + repository: https://charts.bitnami.com/bitnami + alias: etherpad-postgresql + condition: etherpadlite.enabled + + - name: etherpad + version: 0.1.0 + repository: "file://charts/etherpad" + alias: etherpadlite + condition: etherpadlite.enabled + +# - name: sql-exporter + +#Include tasks for sc-serviceaccounts.yml diff --git a/charts/dbp-moodle/README.md b/charts/dbp-moodle/README.md new file mode 100644 index 0000000..e8dfc29 --- /dev/null +++ b/charts/dbp-moodle/README.md @@ -0,0 +1,311 @@ +# dbp Moodle Helm Chart + +A [Helm Library Chart](https://helm.sh/docs/topics/library_charts/#helm) for grouping common logic between bitnami charts. + +## TL;DR + +```console +$ helm repo add my-repo https://charts.bitnami.com/bitnami +$ helm install moodle my-repo/dbp-moodle +``` +Notice: It is advised to use "moodle" as helm chart name due to naming of database configurations which are set in the default values. This can be circumvented by setting the values: + - moodle.externalDatabase.host + - etherpad-postgresql.persistence.existingClaim + - etherpadlite.env.DB_HOST.value + - moodle_hpa.deployment_name_ref + + +The dbp-moodle Helm Chart dependencies +```yaml +dependencies: + - name: moodle + version: "22.2.7" + repository: https://charts.bitnami.com/bitnami + + - name: redis + version: "19.5.3" + repository: https://charts.bitnami.com/bitnami + condition: redis.enabled + + - name: mariadb + version: "18.2.2" + repository: https://charts.bitnami.com/bitnami + condition: mariadb.enabled + + - name: postgresql + version: "15.5.7" + repository: https://charts.bitnami.com/bitnami + condition: postgresql.enabled + + - name: cronjob + alias: backup-cronjob + version: 0.1.0 + repository: "file://charts/backup-cronjob" + condition: backup.enabled + + - name: postgresql + version: "15.5.7" + repository: https://charts.bitnami.com/bitnami + alias: etherpad-postgresql + condition: etherpadlite.enabled + + - name: etherpad + version: 0.1.0 + repository: "file://charts/etherpad" + alias: etherpadlite + condition: etherpadlite.enabled +``` + +## Introduction + +This is a Helm Chart bundling some of the bitnami resources to deploy Moodle for DBildungsplattform. Extending them with features such as + +MariaDB and PostgreSQL support, Horizontal Autoscaling capabilities, Redis Session Store, Etherpad-Lite. +The Chart can be deployed without any modification but it is advised to set own secrets acccording to this readme. + +## Parameters + +The following table lists the helpers available in the library which are scoped in different sections. + +### Globals +| Name | Description | Value | +| ----- | ------------ | -------- | +| `name` | | `"infra"` | +| `stage` | | `"infra"` | +| `kubectl_version` | | `"1.28.7"` | +| `infratools_image_tag` | | `"4.0.3"` | +| `storageClass` | | `"nfs-client"` | + +### Backup +| Name | Description | Value | +| ----- | ------------ | -------- | +| `enabled` | | `false` | +| `gpg_key_names` | | `"dbpinfra"` | +| `s3_bucket_name` | | `"default"` | +| `cluster_name` | | `"default"` | +| `endpoint.url` | | `"moodle.example.de"` | + +### dbpMoodle +| Name | Description | Value | +| ----- | ------------ | -------- | +| `logging` | | `false` | +| `debug` | Moodle Debugging is not safe for production | `false` | +| `restore` | | `false` | +| `update_migration.enabled` | The dbp update process to migrate moodle date when Moodle versions are increased | `false` | +| `redis.host` | | `"moodle-redis-master`"| +| `redis.port` | | `6379` | +| `redis.password` | | `"moodle"` | +| `secrets.useChartSecret` | If set to true the secret will be created with given values. | `true` | +| `updateHelper.rules` | [WIP] Set permissions for the updateHelper that is created when `update_migration.enabled=true`| `[...]` | +| `secrets.moodle_password` | | `randAlphaNum 16` | +| `secrets.postgres_password` | | `randAlphaNum 16` | +| `secrets.mariadb_password` | | `randAlphaNum 16` | +| `secrets.mariadb_root_password` | | `randAlphaNum 16` | +| `secrets.etherpad_postgresql_password` | | `randAlphaNum 16` | +| `secrets.etherpad_api_key` | | `"moodle"` | + +### infratools +| Name | Description | Value | +| ----- | ------------ | -------- | +|`repository`||`schulcloud`| +|`image_tag`||`4.0.3`| + +### external_pvc +| Name | Description | Value | +| ----- | ------------ | -------- | +| `enabled` | Currently not operational. WIP | `false` | +| `name` | The Name of the external PVC to use. | `"moodle-data"` | +| `size` | | `"8Gi"` | +| `storage_class` | | `"nfs-client"` | +| `accessModes` | Because of Autoscaling and [WIP] Update Process it needs to be accessed by multiple Pods. | `["ReadWriteMany"]` | +| `annotations."helm.sh/resource-policy"`| | `"keep"` | + +### moodle_hpa +Horizontal Pod Autoscaling Values +| Name | Description | Value | +| ----- | ------------ | -------- | +| `deployment_name_ref` | |`"moodle"`| +| `enabled` | |`false` | +| `min_replicas` | |`1`| +| `max_replicas` | |`4`| +| `average_cpu_utilization` | |`50`| +| `scaledown_value` | The max amount in percent to scale in one step per cooldown period | `25` | +| `scaledown_cooldown` ||`60`| +| `scaleup_value` ||`50`| +| `scaleup_cooldown` ||`15`| + +## Parameters for Dependencies + +### moodle +| Name | Description | Value | +|--- |---|---| +| `image.registry` ||`ghcr.io`| +| `image.repository` ||`dbildungsplattform/moodle`| +| `image.tag` | The dbp Image which is build for this Helm Chart. |`"4.1.10-debian-12-r5"`| +| `image.pullPolicy` ||`Always`| +| `image.debug` | Debug mode for more detailed Moodle installation and log output. |`false`| +| `moodleSkipInstall` ||`false`| +| `moodleSiteName` ||`"Moodle"`| +| `moodleLang` ||`"de"`| +| `moodleUsername` ||`admin`| +| `moodleEmail` ||`devops@dbildungscloud.de`| +| `allowEmptyPassword` ||`false`| +| `extraEnvVars` | | `[...] `| +| `extraEnvVars.PHP_POST_MAX_SIZE` ||`200M`| +| `extraEnvVars.PHP_UPLOAD_MAX_FILESIZE` ||`200M`| +| `extraEnvVars.PHP_MAX_INPUT_VARS` ||`"5000"`| +| `extraEnvVars.MOODLE_PLUGINS` | WIP | | +| `extraEnvVars.ENABLE_KALTURA` ||`"false"`| +| `extraEnvVarsSecret` ||`"moodle"`| +| `existingSecret` ||`"moodle"`| +| `persistence.enabled` ||`true`| +| `persistence.storageClass` ||`"nfs-client"`| +| `persistence.annotations` ||`"helm.sh/resource-policy":"keep"`| +| `resources.requests.cpu` ||`300m`| +| `resources.requests.memory` ||`512Mi`| +| `resources.limits.cpu` ||`6`| +| `resources.limits.memory` ||`3Gi`| +| `mariadb.enabled` ||`false`| +| `externalDatabase.type` ||`"mariadb"`| +| `externalDatabase.host` ||`"moodle-mariadb"`| +| `externalDatabase.port` ||`3306`| +| `externalDatabase.user` ||`"moodle"`| +| `externalDatabase.database` ||`"moodle"`| +| `externalDatabase.password` ||`"moodle"`| +| `externalDatabase.existingSecret` ||`"moodle"`| +| `service.type` ||`ClusterIP`| +| `ingress.enabled` ||`true`| +| `ingress.hostname` | The corresponding hostname of the moodle application. |`"example.hostname.de"`| +| `ingress.tls` ||`true`| +| `ingress.annotations` ||`[...] `| +| `metrics.enabled` ||`true`| +| `metrics.service.type` ||`ClusterIP`| +| `metrics.resources.requests.cpu` ||`10m`| +| `metrics.resources.requests.memory` ||`16Mi`| +| `metrics.resources.limits.cpu` ||`200m`| +| `metrics.resources.limits.memory` ||`256Mi`| +| `metrics.extraVolumeMounts` | The required configuration files for Moodle to work. | `[...] `| +| `metrics.extraVolumeMounts.name` ||`moodle-config`| +| `metrics.extraVolumeMounts.readOnly` ||`true`| +| `metrics.extraVolumeMounts.mountPath` ||`/moodleconfig`| +| `metrics.extraVolumes` | A List of Files to mount | `[...] `| +| `metrics.extraVolumes.name` ||`moodle-config`| +| `metrics.extraVolumes.secret.secretName` ||`moodle-config`| +| `metrics.extraVolumes.secret.items[0].key` | The custom config.php File that is used to configure Moodle to use the Database and Redis (If activated) |`config.php`| +| `metrics.extraVolumes.secret.items[0].path` ||`config.php`| +| `metrics.extraVolumes.secret.items[1].key` | The php.ini which installs the php-redis extension to enable the use for redis. |`php.ini`| +| `metrics.extraVolumes.secret.items[1].path` ||`php.ini`| +| `metrics.extraVolumes.secret.defaultMode` ||`644`| + +### mariadb +| Name | Description | Value | +| ----- | ------------ | -------- | +| `enabled` || `true` | +| `global.storageClass` || `"nfs-client"` | +| `image.tag` || `"11.3.2-debian-12-r5"` | +| `auth.username` || `"moodle"` | +| `auth.database` || `"moodle"` | +| `auth.rootPassword` || `"moodle"` | +| `auth.password` || `"moodle"` | +| `auth.existingSecret` || `"moodle"` | +| `metrics.enabled` || `true` | +| `metrics.serviceMonitor.enabled` || `true` | +| `primary.resources.requests.cpu` || `"250m" ` | +| `primary.resources.requests.memory` || `"256Mi" ` | +| `primary.resources.limits.cpu` || `9 ` | +| `primary.resources.limits.memory` || `"3Gi" ` | + +### postgresql +| Name | Description | Value | +| ----- | ------------ | -------- | +| `enabled` || `false` | +| `image.tag` || `"14.8.0-debian-11-r0"` | +| `auth.username` || `"moodle"` | +| `auth.database` || `"moodle"` | +| `auth.existingSecret` || `"moodle"` | +| `auth.secretKeys.adminPasswordKey` || `"PGSQL_POSTGRES_PASSWORD"` | +| `auth.secretKeys.userPasswordKey` || `"postgresql-password"` | +| `metrics.enabled` || `true` | +| `metrics.serviceMonitor.enabled` || `true` | +| `primary.extendedConfiguration` || `"max_connections = 800"` | +| `primary.resources.requests.cpu` || `"250m"` | +| `primary.resources.requests.memory` || `"256Mi"` | +| `primary.resources.limits.cpu` || `9` | +| `primary.resources.limits.memory` || `"3Gi"` | + +### redis +| Name | Description | Value | +| ----- | ------------ | -------- | +| `enabled` || `false` | +| `architecture` || `"standalone"` | +| `auth.enabled` || `true` | +| `auth.password` || `"moodle"` | +| `auth.existingSecret` || `"moodle"` | +| `auth.existingSecretPasswordKey` || `"redis-password"` | +| `auth.usePasswordFileFromSecret` || `true` | + +### etherpad-postgresql +| Name | Description | Value | +| ----- | ------------ | -------- | +| `auth.enablePostgresUser` | | `false` | +| `auth.username` | | `"etherpad"` | +| `auth.existingSecret` | | `"moodle"` | +| `auth.secretKeys.userPasswordKey` | | `"etherpad-postgresql-password"` | +| `auth.database` | | `"etherpad"` | +| `persistence.existingClaim` | | `"moodle-etherpad-postgresql"` | +| `primary.resources.requests.cpu` | | `"50m"` | +| `primary.resources.requests.memory` | | `"128Mi"` | +| `primary.resources.limits.cpu` | | `"1000m"` | +| `primary.resources.limits.memory` | | `"1Gi"` | + +### etherpadlite +Etherpad requires configuration to work. +| Name | Description | Value | +| ----- | ------------ | -------- | +| `enabled` | | `true `| +| `image.repository` | | `"ghcr.io/dbildungsplattform/etherpad"` | +| `image.tag` | | `"1.8.18.0"` | +| `env.DB_TYPE` | | `"postgres"` | +| `env.DB_HOST` | | `"moodle-etherpad-postgresql"` | +| `env.DB_PORT` | | `5432 `| +| `env.DB_NAME` | | `"etherpad"` | +| `env.DB_USER` | | `"etherpad"` | +| `env.DB_PASS.valueFrom.secretKeyRef.name` | | `"moodle"` | +| `env.DB_PASS.valueFrom.secretKeyRef.key` | | `"etherpad-postgresql-password"` | +| `env.REQUIRE_SESSION` | | `"true"` | +| `volumes.name` | | `"api-key"` | +| `volumes.name` | | `"api-key"` | +| `volumes.secret.secretName` | | `"moodle"` | +| `volumes.secret.items.key` | | `"etherpad-api-key"` | +| `volumes.secret.items.path` | | `"APIKEY.txt"` | +| `volumeMounts.name` | | `"api-key"` | +| `volumeMounts.mountPath` | | `"api-key"` | +| `volumeMounts.subPath` | | `"APIKEY.txt"` | +| `ingress.enabled` | | `true `| +| `ingress.annotations` | | ` [...] ` | +| `ingress.hosts.host` | | `["etherpad.example.de"] `| +| `ingress.paths.path` | | `"/"` | +| `ingress.paths.pathType` | | `Prefix`| +| `ingress.tls.secretName` | | ` ["etherpad.example.de-tls"]`| +| `ingress.tls.hosts` | | ` ["etherpad.example.de"]` | +| `resources.requests.cpu` | | `"100m"` | +| `resources.requests.memory` | | `"128Mi"` | +| `resources.limits.cpu` | | `"1000m"` | +| `resources.limits.memory` | | `"1Gi"` | + +## Secrets +There is a default secret that will be created with the chart deployment, it covers all necessary secrets that cover all featurs: +values.yaml + +```yaml +secrets: + useChartSecret: true + moodle_password: "moodle" + postgres_password: "moodle" + mariadb_password: "moodle" + mariadb_root_password: "moodle" + etherpad_postgresql_password: "moodle" + etherpad_api_key: "moodle" +``` + +In case an own secret will be provided and should be used the value "useChartSecret" can be set to "false" and all existingSecret Values need to be set accordingly. diff --git a/charts/dbp-moodle/charts/backup-cronjob/Chart.yaml b/charts/dbp-moodle/charts/backup-cronjob/Chart.yaml new file mode 100644 index 0000000..67c75b3 --- /dev/null +++ b/charts/dbp-moodle/charts/backup-cronjob/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: cronjob +description: A generic Helm chart for Kubernetes cronjobs +type: application +version: 0.1.0 +appVersion: 2.1.3 diff --git a/charts/dbp-moodle/charts/backup-cronjob/templates/_helpers.tpl b/charts/dbp-moodle/charts/backup-cronjob/templates/_helpers.tpl new file mode 100644 index 0000000..27be823 --- /dev/null +++ b/charts/dbp-moodle/charts/backup-cronjob/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "cronjob.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "cronjob.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "cronjob.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "cronjob.labels" -}} +helm.sh/chart: {{ include "cronjob.chart" . }} +{{ include "cronjob.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "cronjob.selectorLabels" -}} +app.kubernetes.io/name: {{ include "cronjob.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "cronjob.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "cronjob.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/dbp-moodle/charts/backup-cronjob/templates/clusterrole.yml b/charts/dbp-moodle/charts/backup-cronjob/templates/clusterrole.yml new file mode 100644 index 0000000..43d94bc --- /dev/null +++ b/charts/dbp-moodle/charts/backup-cronjob/templates/clusterrole.yml @@ -0,0 +1,16 @@ +{{- if .Values.clusterRole.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "cronjob.serviceAccountName" . }} + labels: + {{- include "cronjob.labels" . | nindent 4 }} + {{- with .Values.clusterRole.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.clusterRole.rules }} +rules: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/dbp-moodle/charts/backup-cronjob/templates/clusterrolebinding.yml b/charts/dbp-moodle/charts/backup-cronjob/templates/clusterrolebinding.yml new file mode 100644 index 0000000..60b8370 --- /dev/null +++ b/charts/dbp-moodle/charts/backup-cronjob/templates/clusterrolebinding.yml @@ -0,0 +1,16 @@ +{{- if .Values.clusterRole.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "cronjob.serviceAccountName" . }} + labels: + {{- include "cronjob.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ include "cronjob.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ include "cronjob.serviceAccountName" . }} + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/charts/dbp-moodle/charts/backup-cronjob/templates/cronjob.yml b/charts/dbp-moodle/charts/backup-cronjob/templates/cronjob.yml new file mode 100644 index 0000000..8e76e27 --- /dev/null +++ b/charts/dbp-moodle/charts/backup-cronjob/templates/cronjob.yml @@ -0,0 +1,150 @@ +{{- $chart_name := include "cronjob.fullname" . }} +{{- $chart_labels := include "cronjob.labels" . }} +{{- $chart_selector_labels := include "cronjob.selectorLabels" . }} +{{- $service_account_name := include "cronjob.serviceAccountName" . }} +{{- $tag := .Values.image.tag | default .Chart.AppVersion }} +{{- $image_pull_secrets := .Values.imagePullSecrets }} + +{{- range $job := .Values.jobs }} +{{- $image := print $.Values.image.repository ":" $tag }} +{{- $image_pull_policy := $.Values.image.pullPolicy }} +{{- if .image }} + {{- $image = print .image.repository ":" (default $tag .image.tag) }} + {{- if .image.pullPolicy }} + {{- $image_pull_policy = .image.pullPolicy }} + {{- end }} +{{- end }} + +{{- $env := $.Values.env }} +{{- if .env }} + {{- $env = concat $env .env }} +{{- end }} + +{{- $env_from := $.Values.envFrom }} +{{- if .envFrom }} + {{- $env_from = concat $env_from .envFrom }} +{{- end }} + +{{- $resources := $.Values.resources }} +{{- if .resources }} + {{- $resources = .resources }} +{{- end }} + +{{- $extra_volume_mounts := $.Values.extraVolumeMounts }} +{{- if .extraVolumeMounts }} + {{- $extra_volume_mounts = concat $extra_volume_mounts .extraVolumeMounts }} +{{- end }} + +{{- $extra_volumes := $.Values.extraVolumes }} +{{- if .extraVolumes }} + {{- $extra_volumes = concat $extra_volumes .extraVolumes }} +{{- end }} +{{- $checksum := toYaml . | sha256sum | trunc 20 | quote }} +--- +{{- if semverCompare ">=1.21" $.Capabilities.KubeVersion.GitVersion }} +apiVersion: batch/v1 +{{- else -}} +apiVersion: batch/v1beta1 +{{- end }} +kind: CronJob +metadata: + name: {{ $chart_name }}-{{ $job.name }} + labels: + {{- $chart_labels | nindent 4 }} + annotations: + values/checksum: {{ $checksum }} +spec: + concurrencyPolicy: {{ default "Forbid" .concurrencyPolicy }} + failedJobsHistoryLimit: {{ default 1 .failedJobsHistoryLimit }} + successfulJobsHistoryLimit: {{ default 1 .successfulJobsHistoryLimit }} + schedule: {{ .schedule | quote }} + {{- if .suspend }} + suspend: {{ .suspend }} + {{- end }} + {{- if .startingDeadlineSeconds }} + startingDeadlineSeconds: {{ .startingDeadlineSeconds }} + {{- end }} + jobTemplate: + metadata: + spec: + {{- if .activeDeadlineSeconds }} + activeDeadlineSeconds: {{ .activeDeadlineSeconds }} + {{- end }} + {{- if .backoffLimit }} + backoffLimit: {{ .backoffLimit }} + {{- end }} + {{- if .completions }} + completions: {{ .completions }} + {{- end }} + {{- if .parallelism }} + parallelism: {{ .parallelism }} + {{- end }} + {{- if .ttlSecondsAfterFinished }} + ttlSecondsAfterFinished: {{ .ttlSecondsAfterFinished }} + {{- end}} + template: + metadata: + {{- with .podAnnotations }} + annotations: + {{- toYaml . | nindent 12 }} + {{- end }} + labels: + {{- $chart_selector_labels | nindent 12 }} + spec: + restartPolicy: {{ default "Never" .restartPolicy }} + imagePullSecrets: + {{- with default $image_pull_secrets .imagePullSecrets }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if or $.Values.serviceAccount.create $.Values.serviceAccount.name }} + serviceAccountName: {{ $service_account_name }} + {{- end }} + securityContext: + {{- toYaml $.Values.podSecurityContext | nindent 12 }} + containers: + - name: {{ $job.name }} + securityContext: + {{- toYaml $.Values.securityContext | nindent 16 }} + image: {{ $image }} + imagePullPolicy: {{ $image_pull_policy }} + {{- if .command }} + command: + {{- toYaml .command | nindent 16 }} + {{- end }} + {{- with .args }} + args: + {{- toYaml . | nindent 16 }} + {{- end }} + {{- with $env }} + env: + {{- toYaml . | nindent 16 }} + {{- end }} + {{- with $env_from }} + envFrom: + {{- toYaml . | nindent 16 }} + {{- end }} + {{- with $resources }} + resources: + {{- toYaml . | nindent 16 }} + {{- end }} + {{- with $extra_volume_mounts }} + volumeMounts: + {{- toYaml . | nindent 16 }} + {{- end }} + {{- with $.Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with $.Values.affinity }} + affinity: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with $.Values.tolerations }} + tolerations: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with $extra_volumes }} + volumes: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- end }} diff --git a/charts/dbp-moodle/charts/backup-cronjob/templates/serviceaccount.yml b/charts/dbp-moodle/charts/backup-cronjob/templates/serviceaccount.yml new file mode 100644 index 0000000..a0a582a --- /dev/null +++ b/charts/dbp-moodle/charts/backup-cronjob/templates/serviceaccount.yml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "cronjob.serviceAccountName" . }} + labels: + {{- include "cronjob.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/dbp-moodle/charts/backup-cronjob/values.yaml b/charts/dbp-moodle/charts/backup-cronjob/values.yaml new file mode 100644 index 0000000..0c4dbb2 --- /dev/null +++ b/charts/dbp-moodle/charts/backup-cronjob/values.yaml @@ -0,0 +1,128 @@ +image: + repository: schulcloud/infra-tools + pullPolicy: IfNotPresent + # -- Overrides the image tag whose default is the chart appVersion. + tag: "3.0.0" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # -- Specifies whether a service account should be created + create: true + annotations: {} + # -- The name of the service account to use. If not set and create is true, a name is generated using the fullname template + name: "" + +clusterRole: + # -- Create a clusterRole and bind it to the serviceaccount with a clusterRoleBinding + # (see https://kubernetes.io/docs/reference/access-authn-authz/rbac/) + create: false + annotations: {} + rules: [] + # - apiGroups: [""] + # resources: ["namespaces", "configmaps", "persistentvolumeclaims", "services", "limitranges", "secrets", "pods"] + # verbs: "GET" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +# -- Environment variables to be passed to all job pods +# (see https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/ +# and https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables) +env: [] + # - name: VARIABLE + # value: value + # - name: VARIABLE + # valueFrom: + # secretKeyRef: + # name: secret + # key: KEY +# -- ConfigMaps and secrets to be passed as environment variables to all job pods +# (see https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/ +# and https://kubernetes.io/docs/concepts/configuration/secret/#use-case-as-container-environment-variables) +envFrom: [] + # - configMapRef: + # name: configmap-name + + +# -- VolumeMounts to be passed to all job pods +# (see https://kubernetes.io/docs/concepts/storage/volumes/) +extraVolumeMounts: [] + # - name: configmap-volume + # mountPath: /etc/config + +# -- Volumes to be passed to all job pods +# (see https://kubernetes.io/docs/concepts/storage/volumes/) +extraVolumes: [] + # - name: configmap-volume + # configMap: + # name: configmap-name + # items: + # - key: log_level + # path: log_level + +jobs: + # jobs[0].name -- Not optional + - name: example + # -- Not optional + schedule: "*/5 * * * *" + concurrencyPolicy: Forbid + failedJobsHistoryLimit: 1 + successfulJobsHistoryLimit: 1 + restartPolicy: Never + command: + - /bin/sh + - -c + args: + - echo "foo" + startingDeadlineSeconds: 30 + activeDeadlineSeconds: 300 + backoffLimit: 3 + completions: 5 + parallelism: 1 + ttlSecondsAfterFinished: 0 + suspend: false + image: + repository: nginx + tag: latest + pullPolicy: IfNotPresent + # -- Additional job specific environment variables + env: [] + # -- Additional job specific environment variables from configMaps or secrets + envFrom: [] + podAnnotations: {} + resources: {} + # -- Additional job specific volumeMounts + extraVolumeMounts: [] + # -- Additional job specific volumes + extraVolumes: [] diff --git a/charts/dbp-moodle/charts/etherpad/.helmignore b/charts/dbp-moodle/charts/etherpad/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/dbp-moodle/charts/etherpad/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/dbp-moodle/charts/etherpad/Chart.yaml b/charts/dbp-moodle/charts/etherpad/Chart.yaml new file mode 100644 index 0000000..cca76e1 --- /dev/null +++ b/charts/dbp-moodle/charts/etherpad/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: etherpad +description: A Helm chart to install Etherpad in Kubernetes +type: application +version: 0.1.0 +appVersion: 1.8.18 diff --git a/charts/dbp-moodle/charts/etherpad/README.md b/charts/dbp-moodle/charts/etherpad/README.md new file mode 100644 index 0000000..f591a63 --- /dev/null +++ b/charts/dbp-moodle/charts/etherpad/README.md @@ -0,0 +1,63 @@ +# etherpad + +![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.8.18](https://img.shields.io/badge/AppVersion-1.8.18-informational?style=flat-square) + +A Helm chart to install Etherpad in Kubernetes + +## How to install this chart + +```console +helm install chart_name ./etherpad +``` + +To install the chart with the release name `my-release`: + +```console +helm install chart_name ./etherpad +``` + +To install with some set values: + +```console +helm install chart_name ./etherpad --set values_key1=value1 --set values_key2=value2 +``` + +To install with custom values file: + +```console +helm install chart_name ./etherpad -f values.yaml +``` + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | | +| env | list | `[]` | | +| envFrom | list | `[]` | | +| fullnameOverride | string | `""` | | +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.repository | string | `"etherpad/etherpad"` | | +| image.tag | string | `""` | | +| imagePullSecrets | list | `[]` | | +| ingress.annotations | object | `{}` | | +| ingress.enabled | bool | `false` | | +| ingress.hosts[0].host | string | `"chart-example.local"` | | +| ingress.hosts[0].paths | list | `[]` | | +| ingress.tls | list | `[]` | | +| nameOverride | string | `""` | | +| nodeSelector | object | `{}` | | +| podAnnotations | object | `{}` | | +| podSecurityContext | object | `{}` | | +| replicaCount | int | `1` | | +| resources | object | `{}` | | +| securityContext | object | `{}` | | +| service.port | int | `9001` | | +| service.type | string | `"ClusterIP"` | | +| serviceAccount.annotations | object | `{}` | | +| serviceAccount.create | bool | `true` | | +| serviceAccount.name | string | `""` | | +| tolerations | list | `[]` | | +| volumeMounts | list | `[]` | | +| volumes | list | `[]` | | + diff --git a/charts/dbp-moodle/charts/etherpad/templates/_helpers.tpl b/charts/dbp-moodle/charts/etherpad/templates/_helpers.tpl new file mode 100644 index 0000000..0ad1d0f --- /dev/null +++ b/charts/dbp-moodle/charts/etherpad/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "etherpad.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "etherpad.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "etherpad.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "etherpad.labels" -}} +helm.sh/chart: {{ include "etherpad.chart" . }} +{{ include "etherpad.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "etherpad.selectorLabels" -}} +app.kubernetes.io/name: {{ include "etherpad.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "etherpad.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "etherpad.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/dbp-moodle/charts/etherpad/templates/deployment.yaml b/charts/dbp-moodle/charts/etherpad/templates/deployment.yaml new file mode 100644 index 0000000..f059b71 --- /dev/null +++ b/charts/dbp-moodle/charts/etherpad/templates/deployment.yaml @@ -0,0 +1,73 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "etherpad.fullname" . }} + labels: + {{- include "etherpad.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "etherpad.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "etherpad.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "etherpad.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.service.port }} + protocol: TCP + env: + {{- toYaml .Values.env | nindent 12 }} + {{- with .Values.envFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.volumeMounts }} + volumeMounts: + {{- toYaml . | nindent 12 }} + {{- end }} + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.volumes }} + volumes: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/dbp-moodle/charts/etherpad/templates/ingress.yaml b/charts/dbp-moodle/charts/etherpad/templates/ingress.yaml new file mode 100644 index 0000000..89370f6 --- /dev/null +++ b/charts/dbp-moodle/charts/etherpad/templates/ingress.yaml @@ -0,0 +1,46 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "etherpad.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "etherpad.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} diff --git a/charts/dbp-moodle/charts/etherpad/templates/service.yaml b/charts/dbp-moodle/charts/etherpad/templates/service.yaml new file mode 100644 index 0000000..5ce5c43 --- /dev/null +++ b/charts/dbp-moodle/charts/etherpad/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "etherpad.fullname" . }} + labels: + {{- include "etherpad.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "etherpad.selectorLabels" . | nindent 4 }} diff --git a/charts/dbp-moodle/charts/etherpad/templates/serviceaccount.yaml b/charts/dbp-moodle/charts/etherpad/templates/serviceaccount.yaml new file mode 100644 index 0000000..912d699 --- /dev/null +++ b/charts/dbp-moodle/charts/etherpad/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "etherpad.serviceAccountName" . }} + labels: + {{- include "etherpad.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/dbp-moodle/charts/etherpad/values.yaml b/charts/dbp-moodle/charts/etherpad/values.yaml new file mode 100644 index 0000000..5b859d9 --- /dev/null +++ b/charts/dbp-moodle/charts/etherpad/values.yaml @@ -0,0 +1,93 @@ +replicaCount: 1 + +image: + repository: etherpad/etherpad + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 9001 + +ingress: + enabled: false + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: [] + # - path: / + # pathType: Prefix + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +env: [] + # - name: DB_TYPE + # value: + # - name: DB_HOST + # value: + # - name: DB_PORT + # value: + # - name: DB_NAME + # value: + # - name: DB_USER + # value: + # - name: DB_PASS + # valueFrom: + # secretKeyRef: + # name: + # key: + +envFrom: [] + +volumes: [] + +volumeMounts: [] + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/charts/dbp-moodle/scripts/backup.sh b/charts/dbp-moodle/scripts/backup.sh new file mode 100644 index 0000000..557fcb2 --- /dev/null +++ b/charts/dbp-moodle/scripts/backup.sh @@ -0,0 +1,134 @@ +#!/bin/bash +# create destination dir if not exists +set -e +if [ ! -d /backup ] +then + mkdir -p /backup +fi + +curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null +echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list +curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | tee /usr/share/keyrings/helm.gpg > /dev/null +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | tee /etc/apt/sources.list.d/helm-stable-debian.list +apt-get update + +apt install duply +# Install postgresql-client-14 +apt-get -y remove postgresql-client-common +apt-get -y install ca-certificates gnupg +apt-get install apt-transport-https --yes +apt-get -y install mariadb-client +apt-get -y install postgresql-client-14 +pg_dump -V +pip install boto + +#Cleanup after finish only if not an Update Backup (Normal Backup has no CliUpdate file) +#If Update Backup: depending on exit code create the signal for the Update Helper Job with success or failure +function clean_up() { + exit_code=$? + if ! [ -a /mountData/moodledata/CliUpdate ] + then + echo "=== Starting cleanup ===" + echo "=== Stopping Maintenance Mode ===" + rm -f /mountData/moodledata/climaintenance.html + + echo "=== Turn on liveness and readiness probe ===" + helm upgrade --reuse-values --set livenessProbe.enabled=true --set readinessProbe.enabled=true moodle bitnami/moodle --namespace {{ .Release.Namespace }} + + echo "=== Unsuspending moodle cronjob ===" + kubectl patch cronjobs moodle-{{ .Release.Namespace }}-cronjob-php-script -n {{ .Release.Namespace }} -p '{"spec" : {"suspend" : false }}' + elif [ $exit_code -eq 0 ] + then + echo "=== Update Backup was successful with exit code $exit_code ===" + rm -f /mountData/moodledata/UpdateBackupFailure + touch /mountData/moodledata/UpdateBackupSuccess + exit $exit_code + else + echo "=== Update Backup failed with exit code $exit_code ===" + rm -f /mountData/moodledata/UpdateBackupSuccess + touch /mountData/moodledata/UpdateBackupFailure + exit $exit_code + fi +} + +trap "clean_up" EXIT + +# install kubectl +curl -LO https://dl.k8s.io/release/v{{ .Values.global.kubectl_version }}/bin/linux/amd64/kubectl +chmod +x kubectl +mv ./kubectl /usr/local/bin/kubectl +apt-get -y install helm +helm repo add bitnami https://charts.bitnami.com/bitnami + +#If the Backup is done for the Update it skips the preparation because the Update Helper already did this +if ! [ -a /mountData/moodledata/CliUpdate ] +then + #Suspend the cronjob to avoid errors due to missing moodle + echo "=== Suspending moodle cronjob ===" + kubectl patch cronjobs moodle-{{ .Release.Namespace }}-cronjob-php-script -n {{ .Release.Namespace }} -p '{"spec" : {"suspend" : true }}' + + echo "=== Turn off liveness and readiness probe ===" + helm upgrade --reuse-values --set livenessProbe.enabled=false --set readinessProbe.enabled=false moodle --wait bitnami/moodle --namespace {{ .Release.Namespace }} + + kubectl rollout status deployment/moodle + + #Wait for running Jobs to finish to avoid errors + echo "=== Waiting for Jobs to finish ===" + sleep 30 + + echo "=== Starting Maintenance mode ===" + echo '

Sorry, maintenance in progress

' > /mountData/moodledata/climaintenance.html +fi + +echo "=== start backup ===" +date +%Y%m%d_%H%M%S%Z + +cd /backup +# get dump of db +echo "=== start DB dump ===" +export DATE=$( date "+%Y-%m-%d" ) + +{% if moodle_use_mariadb %} +MYSQL_PWD="$MARIADB_PASSWORD" mysqldump -h moodle-mariadb -P 3306 -u moodle moodle > moodle_mariadb_dump_$DATE.sql +gzip moodle_mariadb_dump_$DATE.sql +{% else %} +PGPASSWORD="$POSTGRESQL_PASSWORD" pg_dump -h moodle-postgres-postgresql -p 5432 -U postgres moodle > moodle_postgresqldb_dump_$DATE.sql +gzip moodle_postgresqldb_dump_$DATE.sql +{% endif %} + +# get moodle folder +echo "=== start moodle directory backup ===" +tar -zcf moodle.tar.gz /mountData/moodle/ + +# get moodledata folder +echo "=== start moodledata directory backup ===" +if [ -a /mountData/moodledata/CliUpdate ] +then + #Backup during the Moodle Update Process + tar --exclude="/mountData/moodledata/cache" --exclude="/mountData/moodledata/sessions" --exclude="/mountData/moodledata/moodle-backup" --exclude="/mountData/moodledata/CliUpdate" -zcf moodledata.tar.gz /mountData/moodledata/ +else + #Regular scheduled daily Backup process + tar --exclude="/mountData/moodledata/cache" --exclude="/mountData/moodledata/sessions" -zcf moodledata.tar.gz /mountData/moodledata/ +fi + +echo "=== Start duply process ===" +cd /etc/duply/default +for cert in *.asc + do + echo "=== Import key $cert ===" + gpg --import --batch $cert + done +for fpr in $(gpg --batch --no-tty --command-fd 0 --list-keys --with-colons | awk -F: '/fpr:/ {print $10}' | sort -u); + do + echo "=== Trusts key $fpr ===" + echo -e "5\ny\n" | gpg --batch --no-tty --command-fd 0 --expert --edit-key $fpr trust; + done +echo "=== Execute backup ===" +/usr/bin/duply default backup +/usr/bin/duply default status +cd / +rm -rf /backup +echo "=== backup finished ===" +echo "=== Clean up old backups ===" +/usr/bin/duply default purge --force +date +%Y%m%d_%H%M%S%Z \ No newline at end of file diff --git a/charts/dbp-moodle/scripts/config.php b/charts/dbp-moodle/scripts/config.php new file mode 100644 index 0000000..bac5bbc --- /dev/null +++ b/charts/dbp-moodle/scripts/config.php @@ -0,0 +1,68 @@ +dbtype = '{{ .Values.moodle.externalDatabase.type }}'; +$CFG->dblibrary = 'native'; +$CFG->dbhost = '{{ .Values.moodle.externalDatabase.host }}'; +$CFG->dbname = '{{ .Values.moodle.externalDatabase.database }}'; +$CFG->dbuser = '{{ .Values.moodle.externalDatabase.user }}'; +$CFG->dbpass = '{{ .Values.moodle.externalDatabase.password }}'; +$CFG->prefix = 'mdl_'; +$CFG->dboptions = array ( + 'dbpersist' => 0, + 'dbport' => {{ .Values.moodle.externalDatabase.port }}, + 'dbsocket' => '', +); + +$_SERVER['HTTP_HOST'] = '{{ .Values.moodle.ingress.hostname }}'; + +$CFG->wwwroot = 'https://{{ .Values.moodle.ingress.hostname }}'; + +$CFG->dataroot = '/bitnami/moodledata'; +$CFG->admin = 'admin'; +$CFG->directorypermissions = 02775; + +{{- if .Values.redis.enabled }} +$CFG->session_handler_class = '\core\session\redis'; +$CFG->session_redis_host = '{{ .Values.dbpMoodle.redis.host }}'; +$CFG->session_redis_port = {{ .Values.dbpMoodle.redis.port }}; +$CFG->session_redis_database = 0; +$CFG->session_redis_auth = '{{ .Values.dbpMoodle.redis.password }}'; +$CFG->session_redis_prefix = 'mdl_'; +$CFG->session_redis_acquire_lock_timeout = 60; +$CFG->session_redis_acquire_lock_warn = 0; +$CFG->session_redis_lock_expire = 7200; + +$CFG->session_redis_serializer_use_igbinary = false; +$CFG->session_redis_compressor = 'none'; +{{- end }} + +require_once(__DIR__ . '/lib/setup.php'); + +{{ if .Values.dbpMoodle.logging }} +define('MDL_PERF' , true); +define('MDL_PERFDB' , true); +define('MDL_PERFTOLOG' , true); //OK for production +{{ end }} + + +{{ if .Values.dbpMoodle.debug }} +@error_reporting(E_ALL | E_STRICT); // NOT FOR PRODUCTION SERVERS! +@ini_set('display_errors', '1'); // NOT FOR PRODUCTION SERVERS! +$CFG->debug = 32767; // === DEBUG_DEVELOPER - NOT FOR PRODUCTION SERVERS! +$CFG->debugdisplay = 1; // NOT FOR PRODUCTION SERVERS! +$CFG->debugpageinfo = 1; +$CFG->perfdebug = 7; +{{ else }} +$CFG->debug = 0; +$CFG->debugdisplay = 0; +$CFG->debugpageinfo = 0; +$CFG->perfdebug = 7; +$CFG->debugsqltrace = 0; +{{ end }} + +// There is no php closing tag in this file, +// it is intentional because it prevents trailing whitespace problems! \ No newline at end of file diff --git a/charts/dbp-moodle/scripts/moodleCronjobScript.sh b/charts/dbp-moodle/scripts/moodleCronjobScript.sh new file mode 100644 index 0000000..06c9c2a --- /dev/null +++ b/charts/dbp-moodle/scripts/moodleCronjobScript.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e +# get kubectl command +curl -LO https://dl.k8s.io/release/v{{ .Values.global.kubectl_version }}/bin/linux/amd64/kubectl +chmod +x kubectl +mv ./kubectl /usr/local/bin/kubectl + +kubectl get pods -n {{ .Release.Namespace }} | egrep "^moodle-[a-z0-9]{8,10}-[a-z0-9]{5,5}" +kubectl exec $(kubectl get pods -n {{ .Release.Namespace }} --field-selector=status.phase=Running | egrep "^moodle-[a-z0-9]{5,10}-[a-z0-9]{3,5}[^a-z0-9]") -- /opt/bitnami/php/bin/php ./bitnami/moodle/admin/cli/cron.php +echo "Command '/opt/bitnami/php/bin/php ./bitnami/moodle/admin/cli/cron.php' has been run!" \ No newline at end of file diff --git a/charts/dbp-moodle/scripts/moodleRestoreScript.sh b/charts/dbp-moodle/scripts/moodleRestoreScript.sh new file mode 100644 index 0000000..54b4d96 --- /dev/null +++ b/charts/dbp-moodle/scripts/moodleRestoreScript.sh @@ -0,0 +1,97 @@ +#!/bin/bash +# create destination dir if not exists +set -e +if [ ! -d /backup ] +then +mkdir -p /backup +fi + +curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null +echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list +apt-get update + +apt install duply +# Install mariadb-client and postgresql-client-14 +# Needed for moodle restore +# Differs from other backup Helm Charts +apt-get -y remove postgresql-client-common +apt-get -y install ca-certificates gnupg +apt-get -y install mariadb-client +apt-get -y install postgresql-client-14 +pg_dump -V + +# install kubectl +curl -LO https://dl.k8s.io/release/v{{ .Values.global.kubectl_version }}/bin/linux/amd64/kubectl +chmod +x kubectl +mv ./kubectl /usr/local/bin/kubectl + +# get current replicas and scale down deployment +replicas=$(kubectl get deployment -n {{ .Release.Namespace }} moodle -o=jsonpath='{.status.replicas}') +if [ $replicas -eq 0 ] +then +replicas=1 +fi +echo "=== Scale Moodle Deployment to 0 replicas for restore operation ===" +echo "=== Current replicas detected: $replicas ===" +kubectl scale deployment/moodle --replicas=0 -n {{ .Release.Namespace }} + +# restore +cd /etc/duply/default +for cert in *.asc +do +echo "=== Import key $cert ===" +gpg --import --batch $cert +done +for fpr in $(gpg --batch --no-tty --command-fd 0 --list-keys --with-colons | awk -F: '/fpr:/ {print $10}' | sort -u); +do +echo "=== Trusts key $fpr ===" +echo -e "5\ny\n" | gpg --batch --no-tty --command-fd 0 --expert --edit-key $fpr trust; +done + +cd /bitnami/ +echo "=== Download Backup ===" +duply default restore Full +echo "=== Clear PVC ===" +rm -rf /binami/moodle/* +rm -rf /binami/moodledata/* +echo "=== Extract Backup Files ===" +tar -xzf ./Full/backup/moodle.tar.gz -C /bitnami/ +tar -xzf ./Full/backup/moodledata.tar.gz -C /bitnami/ +# set Moodle user 1001 +chown -R 1001 /bitnami/moodle +chown -R 1001 /bitnami/moodledata + +cd /bitnami/ +echo "=== Clear DB ===" + +{{- if moodle_use_mariadb }} +MYSQL_PWD="$MARIADB_PASSWORD" mariadb -u moodle -h moodle-mariadb --port=3306 -e "DROP DATABASE moodle;" +MYSQL_PWD="$MARIADB_PASSWORD" mariadb -u moodle -h moodle-mariadb --port=3306 -e "CREATE DATABASE moodle;" +{{- else }} +# if you cant delete the DB use this command (ERROR: database "moodle" is being accessed by other users) +# PGPASSWORD="$POSTGRESQL_PASSWORD" psql -U postgres -h moodle-postgres-postgresql -c "REVOKE CONNECT ON DATABASE moodle FROM public;SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = 'moodle';" +PGPASSWORD="$POSTGRESQL_PASSWORD" psql -U postgres -h moodle-postgres-postgresql -c "DROP DATABASE moodle" +PGPASSWORD="$POSTGRESQL_PASSWORD" psql -U postgres -h moodle-postgres-postgresql -c "CREATE DATABASE moodle" +{{- endif }} + +echo "=== Copy dump to DB ===" +{{- if moodle_use_mariadb }} +gunzip ./Full/backup/moodle_mariadb_dump_* +mv ./Full/backup/moodle_mariadb_dump_* moodledb_dump.sql +{{- else }} +gunzip ./Full/backup/moodle_postgresqldb_dump_* +mv ./Full/backup/moodle_postgresqldb_dump_* moodledb_dump.sql +{{- endif }} + +{{- if moodle_use_mariadb }} +MYSQL_PWD="$MARIADB_PASSWORD" mariadb -u moodle -h moodle-mariadb moodle < moodledb_dump.sql +{{- else }} +PGPASSWORD="$POSTGRESQL_PASSWORD" psql -U postgres -h moodle-postgres-postgresql moodle < moodledb_dump.sql +{{- endif }} +echo "=== Finish Restore ===" + +echo "=== Scaling deployment replicas to $replicas ===" +kubectl scale deployment/moodle --replicas=$replicas -n {{ .Release.Namespace }} +sleep 2 +scaledTo=$(kubectl get deployment -n {{ .Release.Namespace }} moodle -o=jsonpath='{.status.replicas}') +echo "=== Deployment scaled to: $scaledTo ===" \ No newline at end of file diff --git a/charts/dbp-moodle/scripts/moodleUpdateHelperJobScript.sh b/charts/dbp-moodle/scripts/moodleUpdateHelperJobScript.sh new file mode 100644 index 0000000..9834d6b --- /dev/null +++ b/charts/dbp-moodle/scripts/moodleUpdateHelperJobScript.sh @@ -0,0 +1,155 @@ +#!/bin/bash +if [ -a /volumes/moodledata/UpdateFailed ] +then + echo "=== UpdateFailed file found, skipping Helper Job ===" + exit 1 +fi + +curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | tee /usr/share/keyrings/helm.gpg > /dev/null +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | tee /etc/apt/sources.list.d/helm-stable-debian.list +apt-get update + +apt-get install apt-transport-https --yes +#get kubectl command +curl -LO https://dl.k8s.io/release/v{{ .Values.global.kubectl_version }}/bin/linux/amd64/kubectl +chmod +x kubectl +mv ./kubectl /usr/local/bin/kubectl + +apt-get -y install helm +helm repo add bitnami https://charts.bitnami.com/bitnami + +unsuspend(){ + echo "=== Unsuspending moodle cronjob ===" + kubectl patch cronjobs moodle-{{ .Release.Namespace }}-cronjob-php-script -n {{ .Release.Namespace }} -p '{"spec" : {"suspend" : false }}' +} + +trap "unsuspend" EXIT + +# get current available replicas (availableReplicas because we don't want the new Moodle pod from the RollingUpdate) +replicas=$(kubectl get deployment -n {{ .Release.Namespace }} moodle -o=jsonpath='{.status.availableReplicas}') +if [[ $replicas -eq 0 ]] +then + replicas=1 +fi +echo "=== Current replicas detected: $replicas ===" + +getMoodleVersion(){ + if [ -f /volumes/moodle/version.php ] + then + LINE=$(grep release /volumes/moodle/version.php) + REGEX="release\s*=\s*'([0-9]+\.[0-9]+\.[0-9]+)" + if [[ $LINE =~ $REGEX ]] + then + echo "=== The newly installed Moodle version is: ${BASH_REMATCH[1]} ===" + fi + else + echo "=== No Moodle Version found ===" + exit 1 + fi +} + +scaleUpOnBackupFailure(){ + touch /volumes/moodledata/UpdateFailed + rm -f /volumes/moodledata/climaintenance.html + kubectl scale deployment/moodle --replicas=$replicas -n {{ .Release.Namespace }} + exit 1 +} + +scaleUpOnInstallationFailure(){ + touch /volumes/moodledata/UpdateFailed + rm -f /volumes/moodledata/climaintenance.html + helm upgrade --reuse-values --set livenessProbe.enabled=true --set readinessProbe.enabled=true moodle bitnami/moodle --namespace {{ .Release.Namespace }} + sleep 10 + kubectl scale deployment/moodle --replicas=$replicas -n {{ .Release.Namespace }} + exit 1 +} + +#Suspend the cronjob to avoid errors due to missing moodle +echo "=== Suspending moodle cronjob ===" +kubectl patch cronjobs moodle-{{ .Release.Namespace }}-cronjob-php-script -n {{ .Release.Namespace }} -p '{"spec" : {"suspend" : true }}' + +echo "=== Starting waiting period for CliUpdate from Moodle Pod ===" +for i in {0..1001..2} +do + if [ -a /volumes/moodledata/CliUpdate ] + then + echo "=== CliUpdate file found, starting Update process ===" + break + elif [ $i -gt 998 ] + then + echo "=== Waited for set duration but no Update is required ===" + sleep 2 + exit 0 + fi + sleep 2 +done + +echo "=== Scale Moodle Deployment to 0 replicas for update operation ===" +kubectl scale deployment/moodle --replicas=0 -n {{ .Release.Namespace }} +sleep 10 + +#Backup job gets started here if stage == prod, otherwise skip full backup +if [ {{ .Values.global.stage }} == "prod" ] +then + #Delete moodle-update-backup-job in case it already exists + kubectl delete job moodle-update-backup-job -n {{ .Release.Namespace }} + sleep 1 + kubectl create job moodle-update-backup-job --from=cronjob.batch/moodle-backup-cronjob-backup -n {{ .Release.Namespace }} + + #Wait for the Backup job to finish + echo "=== Starting waiting period for full Backup ===" + for j in {0..900..2} + do + if [ -a /volumes/moodledata/UpdateBackupSuccess ] + then + echo "=== Update Backup successful, starting update installation process ===" + rm -f /volumes/moodledata/UpdateBackupSuccess + break + elif [ -a /volumes/moodledata/UpdateBackupFailure ] + then + echo "=== The Update Backup Job failed and the old moodle Version will be started again ===" + rm -f /volumes/moodledata/UpdateBackupFailure + scaleUpOnBackupFailure + elif [[ j -gt 896 ]] + then + echo "=== Full Backup timeout, fallback to old version ===" + scaleUpOnBackupFailure + fi + sleep 2 + done +else + echo "=== Skipping full Backup because of {{ .Values.global.stage }} ===" +fi + +echo "=== Turn off liveness probe ===" +helm upgrade --reuse-values --set livenessProbe.enabled=false --set readinessProbe.enabled=false moodle --wait bitnami/moodle --namespace {{ .Release.Namespace }} +sleep 10 +echo "=== Scale back to 1 replica to continue the Update ===" +kubectl scale deployment/moodle --replicas=1 -n {{ .Release.Namespace }} + +echo "=== Waiting for Pod to install the Update ===" +for j in {0..1200..2} +do + #The update has failed which gets visible by creation of the UpdateFailed File + if [ -a /volumes/moodledata/UpdateFailed ] + then + echo "=== Update failed, manual intervention required ===" + scaleUpOnInstallationFailure + elif ! [ -a /volumes/moodledata/CliUpdate ] && ! [ -a /volumes/moodledata/UpdateFailed ] + then + echo "=== Update finished successfully, waiting for Moodle Database Update ===" + sleep 300 + echo "=== Restore functionality ===" + echo "=== Turn liveness & readiness probe back on again ===" + helm upgrade --reuse-values --set livenessProbe.enabled=true --set readinessProbe.enabled=true moodle bitnami/moodle --namespace {{ .Release.Namespace }} + sleep 10 + echo "=== Scale replicas to previous amount ===" + kubectl scale deployment/moodle --replicas=$replicas -n {{ .Release.Namespace }} + getMoodleVersion + sleep 1 + exit 0 + fi + sleep 2 +done +echo "=== Update installation took to long, error ===" +scaleUpOnInstallationFailure \ No newline at end of file diff --git a/charts/dbp-moodle/scripts/php.ini b/charts/dbp-moodle/scripts/php.ini new file mode 100644 index 0000000..1655ff4 --- /dev/null +++ b/charts/dbp-moodle/scripts/php.ini @@ -0,0 +1,5 @@ +extension=redis.so +redis.session.locking_enabled = 1 +redis.session.lock_retries = -1 +redis.session.lock_wait_time = 10000 +redis.session.early_refresh = 1 \ No newline at end of file diff --git a/charts/dbp-moodle/templates/_helpers.tpl b/charts/dbp-moodle/templates/_helpers.tpl new file mode 100644 index 0000000..b5d2f91 --- /dev/null +++ b/charts/dbp-moodle/templates/_helpers.tpl @@ -0,0 +1,50 @@ +{{- define "dbpMoodle.stageBackupEnabled" -}} +{{- if and (or (eq .Values.global.stage "prod") (eq .Values.global.name "infra")) ( .Values.backup.enabled ) -}} +true +{{- else -}} +false +{{- end -}} +{{- end -}} + +{{- define "dbpMoodle.moodlePvc.name" -}} +{{- if .Values.external_pvc.enabled }} +"{{- .Values.external_pvc.name -}}" +{{- else if .Values.moodle.persistence.enabled }} +"{{- .Release.Name }}-moodle" +{{- else }} +{{- printf "Warning: Neither external_pvc nor moodle.persistence is enabled, using default value 'moodle-moodle' which will probably fail." }} +"moodle-moodle" +{{- end -}} +{{- end -}} + +{{- define "moodle_hpa.deployment_name_ref" -}} +{{- default "moodle" .Values.moodle_hpa.deployment_name_ref }} +{{- end -}} + +{{- define "dbpMoodle.secrets.moodle_password" -}} +{{- default (randAlphaNum 16) .Values.dbpMoodle.secrets.moodle_password }} +{{- end -}} + +{{- define "dbpMoodle.secrets.postgres_password" -}} +{{- default (randAlphaNum 16) .Values.dbpMoodle.secrets.postgres_password }} +{{- end -}} + +{{- define "dbpMoodle.secrets.mariadb_password" -}} +{{- default (randAlphaNum 16) .Values.dbpMoodle.secrets.mariadb_password }} +{{- end -}} + +{{- define "dbpMoodle.secrets.mariadb_root_password" -}} +{{- default (randAlphaNum 16) .Values.dbpMoodle.secrets.mariadb_root_password }} +{{- end -}} + +{{- define "dbpMoodle.secrets.redis_password" -}} +{{- default (randAlphaNum 16) .Values.dbpMoodle.redis.password }} +{{- end -}} + +{{- define "dbpMoodle.secrets.etherpad_postgresql_password" -}} +{{- default (randAlphaNum 16) .Values.dbpMoodle.secrets.etherpad_postgresql_password }} +{{- end -}} + +{{- define "dbpMoodle.secrets.etherpad_api_key" -}} +{{- default "moodle" .Values.dbpMoodle.secrets.etherpad_api_key }} +{{- end -}} \ No newline at end of file diff --git a/charts/dbp-moodle/templates/clusterrolebindings/update-helper-clusterrolebinding.yml b/charts/dbp-moodle/templates/clusterrolebindings/update-helper-clusterrolebinding.yml new file mode 100644 index 0000000..c7b9a44 --- /dev/null +++ b/charts/dbp-moodle/templates/clusterrolebindings/update-helper-clusterrolebinding.yml @@ -0,0 +1,14 @@ +{{- if .Values.dbpMoodle.update_migration.enabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: "{{ .Release.Name }}-update-helper-job" +subjects: + - kind: ServiceAccount + name: "{{ .Release.Name }}-update-helper-job" + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: "{{ .Release.Name }}-update-helper-job" + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/charts/dbp-moodle/templates/clusterroles/update-helper-clusterrole.yaml b/charts/dbp-moodle/templates/clusterroles/update-helper-clusterrole.yaml new file mode 100644 index 0000000..007b7f4 --- /dev/null +++ b/charts/dbp-moodle/templates/clusterroles/update-helper-clusterrole.yaml @@ -0,0 +1,8 @@ +{{- if .Values.dbpMoodle.update_migration.enabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: "{{ .Release.Name }}-update-helper-job-{{ .Release.Namespace }}" +rules: + {{- toYaml .Values.dbpMoodle.updateHelper.rules | nindent 2 }} +{{- end }} diff --git a/charts/dbp-moodle/templates/configmaps/duply-configmap.yaml b/charts/dbp-moodle/templates/configmaps/duply-configmap.yaml new file mode 100644 index 0000000..06af78b --- /dev/null +++ b/charts/dbp-moodle/templates/configmaps/duply-configmap.yaml @@ -0,0 +1,21 @@ +{{- if include "dbpMoodle.stageBackupEnabled" . }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ .Release.Name }}-duply" + namespace: "{{ .Release.Namespace }}" +data: + conf: |- + GPG_KEYS_ENC="{{ .Values.backup.gpg_key_names }}" + GPG_KEY_SIGN="disabled" + GPG_OPTS="--pinentry-mode loopback --trust-model always" + GPG="/usr/bin/gpg" + TARGET="boto3+s3://{{ .Values.backup.s3_bucket_name }}/{{ .Values.backup.cluster_name }}/{{ .Release.Namespace }}/" + SOURCE='/' + MAX_AGE=6M + MAX_FULLBKP_AGE=1W + DUPL_PARAMS="$DUPL_PARAMS --full-if-older-than $MAX_FULLBKP_AGE --allow-source-mismatch --s3-endpoint-url {{ .Values.backup.endpoint }}" + exclude: |- + + /backup + - ** +{{- end }} \ No newline at end of file diff --git a/charts/dbp-moodle/templates/configmaps/moodle-backup-script-configmap.yaml b/charts/dbp-moodle/templates/configmaps/moodle-backup-script-configmap.yaml new file mode 100644 index 0000000..d385fbd --- /dev/null +++ b/charts/dbp-moodle/templates/configmaps/moodle-backup-script-configmap.yaml @@ -0,0 +1,10 @@ +{{- if .Values.backup.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-backup-script + namespace: {{ .Release.Namespace }} +data: + backup-script: |- +{{ tpl ( .Files.Get "scripts/backup.sh" ) . | indent 4 }} +{{- end }} \ No newline at end of file diff --git a/charts/dbp-moodle/templates/configmaps/moodle-cronjob-configmap.yaml b/charts/dbp-moodle/templates/configmaps/moodle-cronjob-configmap.yaml new file mode 100644 index 0000000..616499d --- /dev/null +++ b/charts/dbp-moodle/templates/configmaps/moodle-cronjob-configmap.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-cronjob-php + namespace: {{ .Release.Namespace }} +data: + cronjob-script: |- +{{ tpl ( .Files.Get "scripts/moodleCronjobScript.sh" ) . | nindent 4 }} \ No newline at end of file diff --git a/charts/dbp-moodle/templates/configmaps/moodle-plugin-configmap.yaml b/charts/dbp-moodle/templates/configmaps/moodle-plugin-configmap.yaml new file mode 100644 index 0000000..3c276e0 --- /dev/null +++ b/charts/dbp-moodle/templates/configmaps/moodle-plugin-configmap.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: moodle-plugins + namespace: {{ .Release.Namespace }} +data: + plugin_list: |- + mod_etherpadlite#mod/etherpadlite + mod_hvp#mod/hvp + mod_groupselect#mod/groupselect + mod_jitsi#mod/jitsi + mod_pdfannotator#mod/pdfannotator + mod_skype#mod/skype + mod_zoom#mod/zoom + mod_booking#mod/booking + mod_reengagement#mod/reengagement + mod_unilabel#mod/unilabel + format_remuiformat#course/format/remuiformat + format_tiles#course/format/tiles + format_topcoll#course/format/topcoll + auth_oidc#auth/oidc + auth_saml2#auth/saml2 + block_dash#blocks/dash + tool_certificate#admin/tool/certificate + mod_coursecertificate#mod/coursecertificate \ No newline at end of file diff --git a/charts/dbp-moodle/templates/configmaps/moodle-restore-script-configmap.yaml b/charts/dbp-moodle/templates/configmaps/moodle-restore-script-configmap.yaml new file mode 100644 index 0000000..fbc5faa --- /dev/null +++ b/charts/dbp-moodle/templates/configmaps/moodle-restore-script-configmap.yaml @@ -0,0 +1,10 @@ +{{- if and .Values.dbpMoodle.update_migration.enabled .Values.dbpMoodle.restore }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-restore-script + namespace: {{ .Release.Namespace }} +data: + restore-script: |- +{{ tpl ( .Files.Get "scripts/moodleRestoreScript.sh" ) . | nindent 4 }} +{{- end }} \ No newline at end of file diff --git a/charts/dbp-moodle/templates/configmaps/update-helper-script-configmap.yaml b/charts/dbp-moodle/templates/configmaps/update-helper-script-configmap.yaml new file mode 100644 index 0000000..3e08ad5 --- /dev/null +++ b/charts/dbp-moodle/templates/configmaps/update-helper-script-configmap.yaml @@ -0,0 +1,10 @@ +{{- if .Values.dbpMoodle.update_migration.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-update-helper-job-script + namespace: {{ .Release.Namespace }} +data: + {{ .Release.Name }}-update-helper-job-script: |- +{{ tpl ( .Files.Get "scripts/moodleUpdateHelperJobScript.sh" ) . | indent 4 }} +{{- end }} \ No newline at end of file diff --git a/charts/dbp-moodle/templates/hpa.yaml b/charts/dbp-moodle/templates/hpa.yaml new file mode 100644 index 0000000..762fd34 --- /dev/null +++ b/charts/dbp-moodle/templates/hpa.yaml @@ -0,0 +1,35 @@ +{{- if .Values.moodle_hpa.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ .Release.Name }}-autoscaler + namespace: {{ .Release.Namespace }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "moodle_hpa.deployment_name_ref" . }} + minReplicas: {{ .Values.moodle_hpa.min_replicas }} + maxReplicas: {{ .Values.moodle_hpa.max_replicas }} + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.moodle_hpa.average_cpu_utilization }} + behavior: + scaleUp: + stabilizationWindowSeconds: 0 + selectPolicy: Max + policies: + - type: Percent + value: {{ .Values.moodle_hpa.scaleup_value }} + periodSeconds: {{ .Values.moodle_hpa.scaleup_cooldown }} + scaleDown: + selectPolicy: Max + policies: + - type: Percent + value: {{ .Values.moodle_hpa.scaledown_value }} + periodSeconds: {{ .Values.moodle_hpa.scaledown_cooldown }} +{{- end }} diff --git a/charts/dbp-moodle/templates/jobs/moodle-restore-job.yaml b/charts/dbp-moodle/templates/jobs/moodle-restore-job.yaml new file mode 100644 index 0000000..9506d65 --- /dev/null +++ b/charts/dbp-moodle/templates/jobs/moodle-restore-job.yaml @@ -0,0 +1,82 @@ +{{- if .Values.dbpMoodle.restore }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ .Release.Name }}-restore-job" + namespace: {{ .Release.Namespace }} +spec: + template: + spec: + volumes: + - name: moodle-data + persistentVolumeClaim: + claimName: {{ include "dbpMoodle.moodlePvc.name" . }} + - name: moodle-restore-script + configMap: + name: moodle-restore-script + defaultMode: 0711 + - name: duply + projected: + sources: + - configMap: + name: moodle-duply + items: + - key: conf + path: conf + - key: exclude + path: exclude + - secret: + name: moodle-backup-gpg-keys + defaultMode: 0644 + serviceAccountName: moodle-restore-job + serviceAccount: moodle-restore-job + containers: + - name: moodle-restore-job + image: schulcloud/infra-tools:{{ .Values.infratools.image_tag }} + command: + - /bin/sh + - -c + args: + - /scripts/restore-script + resources: + limits: + cpu: 2000m + memory: 16Gi + requests: + cpu: 1000m + memory: 8Gi + volumeMounts: + - name: moodle-data + mountPath: /bitnami/moodle + subPath: moodle + - name: moodle-data + mountPath: /bitnami/moodledata + subPath: moodledata + - name: moodle-restore-script + mountPath: /scripts/ + - name: duply + mountPath: /etc/duply/default/ + env: + - name: POSTGRESQL_PASSWORD + valueFrom: + secretKeyRef: + name: moodle + key: PGSQL_POSTGRES_PASSWORD + - name: MARIADB_PASSWORD + valueFrom: + secretKeyRef: + name: moodle + key: mariadb-password + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: moodle-backup-s3 + key: s3_access_key + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: moodle-backup-s3 + key: s3_access_secret + restartPolicy: Never + backoffLimit: 4 +{{- end }} diff --git a/charts/dbp-moodle/templates/jobs/update-helper-job.yaml b/charts/dbp-moodle/templates/jobs/update-helper-job.yaml new file mode 100644 index 0000000..cca03d9 --- /dev/null +++ b/charts/dbp-moodle/templates/jobs/update-helper-job.yaml @@ -0,0 +1,39 @@ +{{- if .Values.dbpMoodle.update_migration.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ .Release.Name }}-update-helper-job-{{ .Values.moodle.image.tag | lower }}" + namespace: {{ .Release.Namespace }} +spec: + ttlSecondsAfterFinished: 80000 + template: + spec: + volumes: + - name: moodle-data + persistentVolumeClaim: + claimName: {{ .Release.Name }}-data + - name: {{ .Release.Name }}-update-helper-job-script + configMap: + name: {{ .Release.Name }}-update-helper-job-script + defaultMode: 0711 + serviceAccountName: {{ .Release.Name }}-update-helper-job + serviceAccount: {{ .Release.Name }}-update-helper-job + containers: + - name: {{ .Release.Name }}-update-helper-job + image: schulcloud/{{ .Values.global.infratools_image_tag }} + command: + - /bin/sh + - -c + args: + - /scripts/{{ .Release.Name }}-update-helper-job-script + volumeMounts: + - name: moodle-data + mountPath: /volumes/moodle + subPath: moodle + - name: moodle-data + mountPath: /volumes/moodledata + subPath: moodledata + - name: {{ .Release.Name }}-update-helper-job-script + mountPath: /scripts/ + restartPolicy: Never +{{- end }} \ No newline at end of file diff --git a/charts/dbp-moodle/templates/metrics-servicemonitor.yaml b/charts/dbp-moodle/templates/metrics-servicemonitor.yaml new file mode 100644 index 0000000..d18a7ef --- /dev/null +++ b/charts/dbp-moodle/templates/metrics-servicemonitor.yaml @@ -0,0 +1,16 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ .Release.Name }}-metrics + namespace: {{ .Release.Namespace }} +spec: + endpoints: + - port: metrics + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + app.kubernetes.io/name: moodle + app.kubernetes.io/instance: moodle + app.kubernetes.io/component: metrics diff --git a/charts/dbp-moodle/templates/moodle-pvc.yaml b/charts/dbp-moodle/templates/moodle-pvc.yaml new file mode 100644 index 0000000..9143cad --- /dev/null +++ b/charts/dbp-moodle/templates/moodle-pvc.yaml @@ -0,0 +1,22 @@ +{{- if .Values.external_pvc.enabled -}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + {{- with .Values.external_pvc.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: "{{ .Values.external_pvc.name }}" + namespace: "{{ .Release.Namespace }}" +spec: + storageClassName: "{{ .Values.external_pvc.storage_class }}" + accessModes: + {{- if not (empty .Values.external_pvc.accessModes) }} + {{- range .Values.external_pvc.accessModes }} + - {{ . | quote }} + {{- end }} + {{- end }} + resources: + requests: + storage: "{{ .Values.external_pvc.size }}" +{{- end }} \ No newline at end of file diff --git a/charts/dbp-moodle/templates/secrets/moodle-config-secret.yaml b/charts/dbp-moodle/templates/secrets/moodle-config-secret.yaml new file mode 100644 index 0000000..ef6787e --- /dev/null +++ b/charts/dbp-moodle/templates/secrets/moodle-config-secret.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: moodle-config + namespace: {{ .Release.Namespace }} +data: + php.ini: {{ .Files.Get "scripts/php.ini" | b64enc }} + config.php: {{ tpl (.Files.Get "scripts/config.php") . | b64enc }} \ No newline at end of file diff --git a/charts/dbp-moodle/templates/secrets/moodle-secret.yaml b/charts/dbp-moodle/templates/secrets/moodle-secret.yaml new file mode 100644 index 0000000..ca4db55 --- /dev/null +++ b/charts/dbp-moodle/templates/secrets/moodle-secret.yaml @@ -0,0 +1,25 @@ +{{- if (.Values.dbpMoodle.secrets.useChartSecret) }} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: "{{ .Release.Name }}" + namespace: "{{ .Release.Namespace }}" +stringData: + moodle-password: {{ include "dbpMoodle.secrets.moodle_password" . }} + {{- if .Values.postgresql.enabled }} + PGSQL_POSTGRES_PASSWORD: {{ include "dbpMoodle.secrets.postgres_password" . }} + postgresql-password: {{ include "dbpMoodle.secrets.postgres_password" . }} + {{- end }} + {{- if .Values.mariadb.enabled }} + mariadb-password: {{ include "dbpMoodle.secrets.mariadb_password" . }} + mariadb-root-password: {{ include "dbpMoodle.secrets.mariadb_root_password" . }} + {{- end }} + {{- if .Values.redis.enabled }} + redis-password: {{ include "dbpMoodle.secrets.redis_password" . }} + {{- end }} + {{- if .Values.etherpadlite.enabled }} + etherpad-postgresql-password: {{ include "dbpMoodle.secrets.etherpad_postgresql_password" . }} + etherpad-api-key: {{ include "dbpMoodle.secrets.etherpad_api_key" . }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/dbp-moodle/templates/serviceaccounts/update-helper-serviceaccount.yaml b/charts/dbp-moodle/templates/serviceaccounts/update-helper-serviceaccount.yaml new file mode 100644 index 0000000..909c82e --- /dev/null +++ b/charts/dbp-moodle/templates/serviceaccounts/update-helper-serviceaccount.yaml @@ -0,0 +1,6 @@ +{{- if .Values.dbpMoodle.update_migration.enabled -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: "{{ .Release.Name }}-update-helper-job-{{ .Release.Namespace }}" +{{- end }} diff --git a/charts/dbp-moodle/values.yaml b/charts/dbp-moodle/values.yaml new file mode 100644 index 0000000..784d193 --- /dev/null +++ b/charts/dbp-moodle/values.yaml @@ -0,0 +1,399 @@ +global: + name: infra + stage: infra + kubectl_version: "1.28.7" + infratools_image_tag: 4.0.3 + storageClass: "nfs-client" + +backup: + enabled: false + gpg_key_names: dbpinfra + s3_bucket_name: default + cluster_name: default + endpoint: https://s3-eu-central-2.ionoscloud.com #s3 region Berlin endpoint + +dbpMoodle: + logging: false + debug: false # Moodle Debugging is not safe for production + restore: false # Only to be used to restore a snapshot with the dbp-restore script + update_migration: # The dbp update process to migrate moodle date when Moodle versions are increased + enabled: false + + redis: + host : "moodle-redis-master" + port: 6379 + password: "moodle" + + secrets: + useChartSecret: true + moodle_password: "moodle" + postgres_password: "moodle" + mariadb_password: "moodle" + mariadb_root_password: "moodle" + etherpad_postgresql_password: "moodle" + etherpad_api_key: "moodle" + + updateHelper: + rules: + - apiGroups: [""] + resources: ["pods", "pods/exec", "secrets", "persistentvolumeclaims", "services", "deployments"] + verbs: ["get", "list", "create", "delete", "patch", "update"] + - apiGroups: ["apps"] + resources: ["deployments", "replicasets", "deployments/scale"] + verbs: ["get", "list", "create", "delete", "patch", "update"] + - apiGroups: ["networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get", "list", "create", "delete", "patch", "update"] + - apiGroups: ["batch"] + resources: ["cronjobs", "jobs"] + verbs: ["get", "list", "create", "delete", "patch", "update"] + - apiGroups: ["autoscaling"] + resources: ["horizontalpodautoscalers"] + verbs: ["get", "list", "create", "patch", "update"] + +infratools: + repository: schulcloud + image_tag: 4.0.3 + +external_pvc: + enabled: true + name: "moodle-data" + size: "8Gi" + storage_class: "nfs-client" + accessModes: ["ReadWriteMany"] + annotations: + "helm.sh/resource-policy": "keep" + +moodle: + image: + registry: ghcr.io + repository: dbildungsplattform/moodle + tag: "4.1.10-debian-12-r5" + pullPolicy: Always + debug: false + moodleSkipInstall: false + moodleSiteName: "Moodle" + moodleLang: "de" + moodleUsername: admin + moodleEmail: devops@dbildungscloud.de + allowEmptyPassword: false + extraEnvVars: + - name: PHP_POST_MAX_SIZE + value: 200M + - name: PHP_UPLOAD_MAX_FILESIZE + value: 200M + - name: PHP_MAX_INPUT_VARS + value: "5000" + - name: MOODLE_PLUGINS + valueFrom: + configMapKeyRef: + name: moodle-plugins + key: plugin_list + - name: ENABLE_KALTURA + value: "false" + extraEnvVarsSecret: "moodle" + existingSecret: "moodle" + persistence: + # existingClaim: "moodle-data" + enabled: true + storageClass: "nfs-client" + annotations: + "helm.sh/resource-policy": "keep" + resources: + requests: + cpu: 300m + memory: 512Mi + limits: + cpu: 6 + memory: 3Gi + mariadb: + enabled: false + externalDatabase: + type: "mariadb" + host: "moodle-mariadb" + port: 3306 + user: "moodle" + database: "moodle" + password: "moodle" + existingSecret: "moodle" + service: + type: ClusterIP + ingress: + enabled: true + hostname: "moodle.example.de" + tls: true + annotations: + cert-manager.io/cluster-issuer: sc-cert-manager-clusterissuer-letsencrypt + nginx.ingress.kubernetes.io/proxy-connect-timeout: "30s" + nginx.ingress.kubernetes.io/proxy-read-timeout: "20s" + nginx.ingress.kubernetes.io/proxy-body-size: "200M" + metrics: + enabled: true + service: + type: ClusterIP + resources: # We need those resources so the Horizontal Pod Autoscaler for moodle can read the moodle cpu consumption correctly + requests: + cpu: 10m + memory: 16Mi + limits: + cpu: 200m + memory: 256Mi + extraVolumeMounts: + - name: moodle-config + readOnly: true + mountPath: /moodleconfig + extraVolumes: + - name: moodle-config + secret: + secretName: moodle-config + items: + - key: config.php + path: config.php + - key: php.ini + path: php.ini + defaultMode: 0644 + +mariadb: + enabled: true + global: + storageClass: "nfs-client" + image: + tag: "11.3.2-debian-12-r5" + auth: + username: "moodle" + database: "moodle" + rootPassword: "moodle" + password: "moodle" + existingSecret: "moodle" + metrics: + enabled: true + serviceMonitor: + enabled: true + primary: + resources: + requests: + cpu: 250m + memory: 256Mi + limits: + cpu: 9 + memory: 3Gi + +postgresql: + enabled: false + image: + tag: "14.8.0-debian-11-r0" + auth: + username: "moodle" + database: "moodle" + existingSecret: "moodle" + secretKeys: + adminPasswordKey: "PGSQL_POSTGRES_PASSWORD" + userPasswordKey: "postgresql-password" + metrics: + enabled: true + serviceMonitor: + enabled: true + primary: + extendedConfiguration: | + max_connections = 800 + resources: + requests: + cpu: "250m" + memory: "256Mi" + limits: + cpu: 9 + memory: "3Gi" + +# Horizontal Pod Autoscaling Values +moodle_hpa: + deployment_name_ref: "moodle" + enabled: false + # Moodle Autoscaling Values + min_replicas: 1 + max_replicas: 4 + average_cpu_utilization: 50 + # The up and downscaling values to have more control over the speed moodle will be scaled + scaledown_value: 25 # The max amount in percent to scale in one step per cooldown period + scaledown_cooldown: 60 + scaleup_value: 50 + scaleup_cooldown: 15 + +# redis helm chart values +redis: + enabled: false + architecture: "standalone" + auth: + enabled: true + existingSecret: "moodle" + existingSecretPasswordKey: "redis-password" + usePasswordFileFromSecret: true + +etherpad-postgresql: + auth: + enablePostgresUser: false + username: etherpad + existingSecret: "moodle" + secretKeys: + userPasswordKey: "etherpad-postgresql-password" + database: "etherpad" + persistence: + existingClaim: "moodle-etherpad-postgresql" + primary: + resources: + requests: + cpu: "50m" + memory: "128Mi" + limits: + cpu: "1000m" + memory: "1Gi" + +etherpadlite: + enabled: true + image: + repository: "ghcr.io/dbildungsplattform/etherpad" + tag: "1.8.18.0" + env: + - name: DB_TYPE + value: "postgres" + - name: DB_HOST + value: "moodle-etherpad-postgresql" + - name: DB_PORT + value: "5432" + - name: DB_NAME + value: "etherpad" + - name: DB_USER + value: "etherpad" + - name: DB_PASS + valueFrom: + secretKeyRef: + name: "moodle" + key: "etherpad-postgresql-password" + - name: REQUIRE_SESSION + value: "true" + + + volumes: + - name: "api-key" + secret: + secretName: "moodle" + items: + - key: "etherpad-api-key" + path: "APIKEY.txt" + volumeMounts: + - name: "api-key" + mountPath: "/opt/etherpad-lite/APIKEY.txt" + subPath: "APIKEY.txt" + ingress: + enabled: true + annotations: + cert-manager.io/cluster-issuer: "sc-cert-manager-clusterissuer-letsencrypt" + hosts: + - host: "etherpad.example.de" + paths: + - path: "/" + pathType: "Prefix" + tls: + - secretName: "etherpad.example.de-tls" + hosts: + - "etherpad.example.de" + resources: + requests: + cpu: "100m" + memory: "128Mi" + limits: + cpu: "1000m" + memory: "1Gi" + + +backup-cronjob: + image: + tag: 4.0.3 + clusterRole: + create: false + rules: + - apiGroups: [""] + resources: ["pods", "pods/exec", "secrets", "persistentvolumeclaims", "services", "deployments"] + verbs: ["get", "list", "create", "delete", "patch", "update"] + - apiGroups: ["apps"] + resources: ["deployments", "replicasets"] + verbs: ["get", "list", "create", "delete", "patch", "update"] + - apiGroups: ["networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get", "list", "create", "delete", "patch", "update"] + - apiGroups: ["batch"] + resources: ["cronjobs", "jobs"] + verbs: ["get", "patch", "update", "list", "delete"] + serviceAccount: + name: "moodle-backup" + env: + - name: POSTGRESQL_PASSWORD + valueFrom: + secretKeyRef: + name: moodle + key: PGSQL_POSTGRES_PASSWORD + #This is required for the MariaDB backup to securely hand over the password in the script + - name: MARIADB_PASSWORD + valueFrom: + secretKeyRef: + name: moodle + key: mariadb-password + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: moodle-backup-s3 + key: s3_access_key + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: moodle-backup-s3 + key: s3_access_secret + - name: S3_BACKUP_REGION_URL + valueFrom: + secretKeyRef: + name: moodle-backup-s3 + key: s3_endpoint_url + extraVolumeMounts: + - name: moodle-backup-script + mountPath: /scripts/ + - name: moodle-pvc-data + mountPath: /mountData + - name: duply + mountPath: /etc/duply/default/ + extraVolumes: + - name: moodle-pvc-data + persistentVolumeClaim: + claimName: "moodle-data" + - name: moodle-backup-script + configMap: + name: moodle-backup-script + defaultMode: 0711 + - name: duply + projected: + sources: + - configMap: + name: moodle-duply + items: + - key: conf + path: conf + - key: exclude + path: exclude + - secret: + name: moodle-backup-gpg-keys + defaultMode: 0644 + resources: + limits: + cpu: 2000m + memory: 4Gi + requests: + cpu: 500m + memory: 1Gi + jobs: + - name: backup + schedule: "0 3 * * *" + failedJobsHistoryLimit: 1 + successfulJobsHistoryLimit: 1 + command: + - /bin/sh + - -c + args: + - /scripts/backup-script