diff --git a/hedgedoc/env.template b/hedgedoc/env.template new file mode 100644 index 0000000000000000000000000000000000000000..4bf97a70354fe266ddf6d07697aa5ecd9133bf8e --- /dev/null +++ b/hedgedoc/env.template @@ -0,0 +1,2 @@ +CMD_DB_URL=postgres://hedgedoc:${POSTGRES_PASSWORD}@pg-${NS}:5432/hedgedoc +CMD_SESSION_SECRET=${CMD_SESSION_SECRET} diff --git a/hedgedoc/kustomization.yaml.template b/hedgedoc/kustomization.yaml.template new file mode 100644 index 0000000000000000000000000000000000000000..a7cbb42fc04d1605f4340eb64eab42ec80ea3192 --- /dev/null +++ b/hedgedoc/kustomization.yaml.template @@ -0,0 +1,10 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +generatorOptions: + disableNameSuffixHash: true +secretGenerator: +- name: ${FQDN}-app + envs: + - env + type: Opaque + diff --git a/hedgedoc/manifests/app.yaml b/hedgedoc/manifests/app.yaml new file mode 100644 index 0000000000000000000000000000000000000000..302bd8abec86591461006393c6e954faf4ee4c93 --- /dev/null +++ b/hedgedoc/manifests/app.yaml @@ -0,0 +1,158 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: hedgedoc + app.kubernetes.io/part-of: hedgedoc + name: ${FQDN}-app +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: hedgedoc + app.kubernetes.io/part-of: hedgedoc + template: + metadata: + labels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: hedgedoc + app.kubernetes.io/part-of: hedgedoc + spec: + volumes: + - name: conf + secret: + secretName: ${FQDN}-pgconf + - name: sequelize + configMap: + name: ${FQDN}-sequelize + - name: foo + secret: + secretName: ${FQDN}-foo + containers: + - env: + - name: CMD_MINIO_ACCESS_KEY + valueFrom: + secretKeyRef: + key: AWS_ACCESS_KEY_ID + name: ${FQDN}-s3 + - name: CMD_MINIO_SECRET_KEY + valueFrom: + secretKeyRef: + key: AWS_SECRET_ACCESS_KEY + name: ${FQDN}-s3 +{{if .ConfigureOAuth}} + - name: CMD_OAUTH2_CLIENT_ID + valueFrom: + secretKeyRef: + key: client-id + name: ${FQDN}-oidc + - name: CMD_OAUTH2_CLIENT_SECRET + valueFrom: + secretKeyRef: + key: client-secret + name: ${FQDN}-oidc +{{end}} + envFrom: + - secretRef: + name: ${FQDN}-app + - configMapRef: + name: ${FQDN}-config + volumeMounts: + - name: conf + mountPath: /hedgedoc/config.json + subPath: config.json + - name: sequelize + mountPath: /hedgedoc/lib/models/index.js + subPath: index.js + - name: foo + mountPath: /hedgedoc/.sequelizerc + subPath: .sequelizerc + image: quay.io/hedgedoc/hedgedoc:1.7.2-alpine + imagePullPolicy: IfNotPresent + name: codimd + ports: + - containerPort: 3000 + name: http + protocol: TCP +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: hedgedoc + app.kubernetes.io/part-of: hedgedoc + name: ${FQDN}-app + namespace: ${DOMAIN} +spec: + ports: + - name: http + port: 3000 + protocol: TCP + targetPort: http + selector: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: hedgedoc + app.kubernetes.io/part-of: hedgedoc + type: ClusterIP +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + annotations: + kubernetes.io/tls-acme: "true" + labels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: hedgedoc + app.kubernetes.io/part-of: hedgedoc + name: ${FQDN}-app + namespace: ${DOMAIN} +spec: + rules: + - host: ${FQDN_DOTS} + http: + paths: + - backend: + serviceName: ${FQDN}-app + servicePort: http + path: / + tls: + - hosts: + - ${FQDN_DOTS} + secretName: ${FQDN}-tls +--- +kind: ConfigMap +metadata: + name: ${FQDN}-config +apiVersion: v1 +data: +{{ if .ConfigureOAuth }} + CMD_OAUTH2_USER_PROFILE_URL: https://id.indie.host/auth/realms/${DOMAIN}/protocol/openid-connect/userinfo + CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR: preferred_username + CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR: name + CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR: email + CMD_OAUTH2_TOKEN_URL: https://id.indie.host/com/auth/realms/${DOMAIN}/protocol/openid-connect/token + CMD_OAUTH2_AUTHORIZATION_URL: https://id.indie.host/auth/realms/${DOMAIN}/protocol/openid-connect/auth + CMD_OAUTH2_PROVIDERNAME: Keycloak +{{ end }} + CMD_IMAGE_UPLOAD_TYPE: minio + CMD_S3_REGION: default + CMD_S3_BUCKET: ${FQDN} + CMD_MINIO_ENDPOINT: "s3.standard.indie.host" + CMD_PROTOCOL_USESSL: "true" + CMD_URL_ADDPORT: "false" + CMD_ALLOW_FREEURL: "true" + CMD_MINIO_PORT: "443" + CMD_MINIO_SECURE: "true" + CMD_USECDN: "false" + CMD_DOMAIN: ${FQDN_DOTS} + CMD_PROTOCOL_USESSL: "true" + CMD_URL_ADDPORT: "false" diff --git a/hedgedoc/source b/hedgedoc/source new file mode 100644 index 0000000000000000000000000000000000000000..895d828ada8a0f93fdff40d906b46e97d6b4734d --- /dev/null +++ b/hedgedoc/source @@ -0,0 +1,7 @@ +export FQDN=${SUBDOMAIN}-${NS} +export FQDN_DOTS=${SUBDOMAIN}.${DOMAIN} + +export CMD_SESSION_SECRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 18 | head -n 1) + +export POSTGRES_USERNAME=$(kubectl get secrets -n liiib-re -o json hedgedoc.pg-${FQDN}.credentials | jq -r '.data.username' | base64 -d) +export POSTGRES_PASSWORD=$(kubectl get secrets -n liiib-re -o json hedgedoc.pg-${FQDN}.credentials | jq -r '.data.password' | base64 -d) diff --git a/lool/manifests/app.yml b/lool/manifests/app.yml new file mode 100644 index 0000000000000000000000000000000000000000..b1e6b3a4c445d4143e28c0eb44434aecbc3e1d39 --- /dev/null +++ b/lool/manifests/app.yml @@ -0,0 +1,109 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + labels: + app.kubernetes.io/name: ${FQDN}-app + namespace: ${NS} + name: ${FQDN}-app +spec: + progressDeadlineSeconds: 600 + replicas: 2 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/name: ${FQDN}-app + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + app.kubernetes.io/name: ${FQDN}-app + spec: + containers: + - env: + - name: ALLOWED_HOSTS + value: ${ALLOWED_HOSTS} + - name: HOSTNAME + value: ${FQDN_DOTS} + - name: ADMIN_PASS + valueFrom: + secretKeyRef: + key: ADMIN_PASS + name: ${FQDN}-auth + - name: DICTIONARIES + value: fr_FR en_GB en_US + - name: LOG_LEVEL + value: warning + image: tiredofit/libreoffice-online:2.1.6 + imagePullPolicy: Always + name: collabora + ports: + - containerPort: 9980 + name: api + protocol: TCP + resources: + limits: + memory: 5Gi + securityContext: + capabilities: + add: + - MKNOD + - NET_ADMIN + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 +--- +apiVersion: v1 +data: + ADMIN_PASS: +kind: Secret +metadata: + name: ${FQDN}-auth + namespace: ${NS} +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: ${FQDN} + name: ${FQDN} + namespace: ${NS} +spec: + ports: + - name: api + port: 9980 + protocol: TCP + targetPort: api + selector: + app.kubernetes.io/name: ${FQDN}-app + sessionAffinity: None +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + annotations: + kubernetes.io/tls-acme: "true" + nginx.ingress.kubernetes.io/upstream-hash-by: $arg_WOPISrc + name: ${FQDN} + namespace: ${NS} +spec: + rules: + - host: ${FQDN_DOTS} + http: + paths: + - backend: + serviceName: ${FQDN} + servicePort: api + path: / + tls: + - hosts: + - ${FQDN_DOTS} + secretName: ${FQDN}-tls diff --git a/migrations/03-08-2021-update-nc-20.sh b/migrations/03-08-2021-update-nc-20.sh new file mode 100755 index 0000000000000000000000000000000000000000..804fced1800b121a96c5de1238d2af90efa59339 --- /dev/null +++ b/migrations/03-08-2021-update-nc-20.sh @@ -0,0 +1,7 @@ +#!/bin/bash +for folder in `find . -type d | grep -v 'chat\|trash\|temp\|tmp\|pad\|git\|common\|alpha' | grep 'wombat\|nuage\|partage\|mairie'`; +do + cd $folder; + libre update --batch + cd ../..; +done diff --git a/migrations/12-06-2021-harmonize-nc.yml b/migrations/12-06-2021-harmonize-nc.yml new file mode 100644 index 0000000000000000000000000000000000000000..be0a75d24922c80b72e97278ba0c726a133c546b --- /dev/null +++ b/migrations/12-06-2021-harmonize-nc.yml @@ -0,0 +1,64 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: update-nc-11-06 + namespace: ${NS} +spec: + template: + spec: + containers: + - command: + - /bin/sh + - -c + args: + - set -e; + /usr/local/bin/php /usr/src/nextcloud/occ config:app:set onlyoffice sameTab --value true; + /usr/local/bin/php /usr/src/nextcloud/occ config:app:set onlyoffice versionHistory --value true; + /usr/local/bin/php /usr/src/nextcloud/occ config:app:set onlyoffice customizationForcesave --value true; + /usr/local/bin/php /usr/src/nextcloud/occ config:app:set files default_quota --value="10 GB" + env: + - name: INSTALLED + value: "true" + - name: VERSION + value: ${NC_VERSION} + - name: OBJECTSTORE_S3_KEY + valueFrom: + secretKeyRef: + key: AWS_ACCESS_KEY_ID + name: ${FQDN}-s3 + - name: OBJECTSTORE_S3_SECRET + valueFrom: + secretKeyRef: + key: AWS_SECRET_ACCESS_KEY + name: ${FQDN}-s3 + - name: MAIL_FROM_ADDRESS + valueFrom: + secretKeyRef: + key: mail_from_address + name: ${NS}-smtp + - name: SMTP_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: ${NS}-smtp + - name: SMTP_NAME + valueFrom: + secretKeyRef: + key: username + name: ${NS}-smtp + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: nextcloud.pg-${PG_DOMAIN}.credentials + envFrom: + - secretRef: + name: ${FQDN}-app + image: libresh/nextcloud:${NC_IMAGE_TAG} + imagePullPolicy: IfNotPresent + name: install-nuage + restartPolicy: Never + securityContext: + fsGroup: 82 + runAsGroup: 82 + runAsUser: 82 diff --git a/migrations/12-06-2021-update-and-harmonize.sh b/migrations/12-06-2021-update-and-harmonize.sh new file mode 100755 index 0000000000000000000000000000000000000000..bf28a16575a7783dc1957108c892f8207e5e1435 --- /dev/null +++ b/migrations/12-06-2021-update-and-harmonize.sh @@ -0,0 +1,10 @@ +#!/bin/bash +for folder in `find . -type d | grep -v 'chat\|trash\|temp\|tmp\|pad\|git\|common' | grep 'wombat\|nuage\|partage\|mairie'`; +do + cd $folder; + libre update + export NS=`pwd | rev | cut -d'/' -f 2 | rev` + kubectl -n $NS delete job update-nc-11-06 + libre apply ../../common/migrations/12-06-2021-harmonize-nc.yml; + cd ../..; +done diff --git a/migrations/13-08-2021-update-rc-16-4.sh b/migrations/13-08-2021-update-rc-16-4.sh new file mode 100755 index 0000000000000000000000000000000000000000..12b9fe401de4d846a88ba543a21e7e3b26237a4b --- /dev/null +++ b/migrations/13-08-2021-update-rc-16-4.sh @@ -0,0 +1,7 @@ +#!/bin/bash +for folder in `find . -maxdepth 2 -mindepth 2 -type d | grep -v 'wombat\|nuage\|partage\|mairie\|trash\|temp\|tmp\|pad\|git\|common\|alpha\|lool' | grep -v 'fabmob\|lescommuns'`; +do + cd $folder; + libre update --batch + cd ../..; +done diff --git a/migrations/14-05-2021-backup-all-nc.sh b/migrations/14-05-2021-backup-all-nc.sh new file mode 100755 index 0000000000000000000000000000000000000000..35b157a2920a5f23f16129b113692cc6c8f38db7 --- /dev/null +++ b/migrations/14-05-2021-backup-all-nc.sh @@ -0,0 +1,10 @@ +#!/bin/bash +for folder in `find . -type d | grep -v 'chat\|trash\|temp\|pad\|git\|common' | grep 'wombat\|nuage\|partage\|mairie'`; +do + cd $folder; + export NS=`pwd | rev | cut -d'/' -f 2 | rev` + kubectl -n $NS delete job dump + libre apply ../../common/nextcloud/other-manifests/dump.yml; + cd ../..; +done +kubectl get po -A | grep -v '\-dump' | grep dump diff --git a/migrations/14-05-2021-fix-postgres-backup-job.sh b/migrations/14-05-2021-fix-postgres-backup-job.sh new file mode 100755 index 0000000000000000000000000000000000000000..7e7bf079077615cfddd01f506e75fd811af978be --- /dev/null +++ b/migrations/14-05-2021-fix-postgres-backup-job.sh @@ -0,0 +1,11 @@ +for folder in `find . -type d | grep -v 'chat\|trash\|temp\|pad\|git\|common' | grep 'wombat\|nuage\|partage\|mairie'`; +do + cd $folder; + libre diff ../../common/nextcloud/manifests/pg.yml; + retVal=$? + if [ $retVal -ne 0 ]; then + read -p "Press any key to apply..." + libre apply ../../common/nextcloud/manifests/pg.yml; + fi + cd ../..; +done diff --git a/migrations/15-06-2021-create-nc-env.sh b/migrations/15-06-2021-create-nc-env.sh new file mode 100755 index 0000000000000000000000000000000000000000..589952338a35b0003304a4ec86f7ba94400e3b48 --- /dev/null +++ b/migrations/15-06-2021-create-nc-env.sh @@ -0,0 +1,17 @@ +#!/bin/bash +#opposite filter: +#find . -maxdepth 2 -mindepth 2 -type d | grep -v 'trash\|temp\|tmp\|git\|common' | grep -v 'wombat\|nuage\|partage\|mairie' | grep -v chat + +for folder in `find . -maxdepth 2 -mindepth 2 -type d | grep -v 'chat\|trash\|temp\|tmp\|pad\|git\|common' | grep 'wombat\|nuage\|partage\|mairie'`; +do + cd $folder; + echo $folder + cat .env + if ! grep APP .env ; then + echo "Adding APP env" + echo export APP=nextcloud >> .env + else + echo "Skipping..." + fi + cd ../..; +done diff --git a/migrations/15-06-2021-create-rc-env.sh b/migrations/15-06-2021-create-rc-env.sh new file mode 100755 index 0000000000000000000000000000000000000000..6c69e90efe29cedf3db4ef921d563f80324d2987 --- /dev/null +++ b/migrations/15-06-2021-create-rc-env.sh @@ -0,0 +1,14 @@ +#!/bin/bash +for folder in `find . -maxdepth 2 -mindepth 2 -type d | grep -v 'trash\|temp\|tmp\|git\|common' | grep 'chat'`; +do + cd $folder; + echo $folder + cat .env + if ! grep APP .env ; then + echo "Adding APP env" + echo export APP=rocketchat >> .env + else + echo "Skipping..." + fi + cd ../..; +done diff --git a/migrations/23-02-2021-update-mongo-operators-v1-6.sh b/migrations/23-02-2021-update-mongo-operators-v1-6.sh new file mode 100755 index 0000000000000000000000000000000000000000..db8924bdb2c436a00cb29b938311076530ae422e --- /dev/null +++ b/migrations/23-02-2021-update-mongo-operators-v1-6.sh @@ -0,0 +1,11 @@ +#!/bin/bash -eux + +kubectl get psmdb -A +for ns in `kubectl get psmdb -A | grep -v cluster | grep chat | cut -d" " -f1`; do + cd $ns/chat + libre diff ../../common/rocketchat/manifests/mongo-operator.yml || true + libre apply ../../common/rocketchat/manifests/mongo-operator.yml + libre diff ../../common/rocketchat/manifests/mongo.yml || true + libre apply ../../common/rocketchat/manifests/mongo.yml + cd ../.. +done diff --git a/migrations/23-02-2021-update-mongo-operators.sh b/migrations/23-02-2021-update-mongo-operators.sh new file mode 100755 index 0000000000000000000000000000000000000000..389549a02d7ac63f16e4a28af35039b3a9d07b07 --- /dev/null +++ b/migrations/23-02-2021-update-mongo-operators.sh @@ -0,0 +1,9 @@ +#!/bin/bash -eux + +kubectl get psmdb -A +for ns in `kubectl get psmdb -A | grep -v cluster | grep chat | cut -d" " -f1`; do + cd $ns/chat + libre apply ../../common/rocketchat/manifests/backup/mongo-operator-v1-5-0.yml + libre apply ../../common/rocketchat/manifests/backup/mongo-v1-5-0.yml + cd ../.. +done diff --git a/networkpolicies.yml b/networkpolicies.yml new file mode 100644 index 0000000000000000000000000000000000000000..c86a322a4f9c95e202c8a5b2e0c40d6355f3285b --- /dev/null +++ b/networkpolicies.yml @@ -0,0 +1,33 @@ +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: allow-from-ingress-namespace +spec: + podSelector: + matchLabels: + app.kubernetes.io/component: web + ingress: + - from: + - namespaceSelector: + matchLabels: + name: ingress +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: allow-from-same-namespace +spec: + podSelector: {} + ingress: + - {} + policyTypes: + - Ingress +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: default-deny-all +spec: + podSelector: {} + policyTypes: + - Ingress diff --git a/nextcloud/env.template b/nextcloud/env.template new file mode 100644 index 0000000000000000000000000000000000000000..1ebf79b117b11dab1ef1b14cd43c004d33681a40 --- /dev/null +++ b/nextcloud/env.template @@ -0,0 +1,44 @@ +VERSION=18.0.9.1 + +APPS_STORE_ENABLE=false +CONFIG_READONLY=true +DATA_DIRECTORY=/usr/src/nextcloud/data +DB_NAME=nextcloud +DB_PORT=5432 +DB_TYPE=pgsql +DB_USER=nextcloud +NEXTCLOUD_ADMIN_USER=admin +OBJECTSTORE_S3_HOST=s3.standard.indie.host +OBJECTSTORE_S3_PORT=443 +OBJECTSTORE_S3_REGION=default +OBJECTSTORE_S3_AUTOCREATE=false +OBJECTSTORE_S3_USEPATH_STYLE=true +OBJECTSTORE_S3_SSL=true +REDIS_HOST=redis +REDIS_HOST_PORT=6379 +REDIS_PORT=6379 +MAIL_DOMAIN=indie.host +SMTP_HOST=mail.indie.host +SMTP_PORT=587 +SMTP_SECURE=tls +UPDATE_CHECKER=false +UPDATE_DISABLE_WEB=true +DISABLE_APPS=firstrunwizard +ENABLE_APPS=user_saml,apporder,calendar,indie_external,admin_audit +TRUSTED_PROXIES=10.0.0.0/8 +PRIVACY_DATA_LOCATION=de +SAML_IDP_URL=https://id.indie.host +SAML_REALM=${NS} +CHAT_URL=https://${CHAT_SUBDOMAIN}.${DOMAIN} +SAML_DISPLAY_NAME=LiiibreSSO + +DB_HOST=pg-${NS} +OBJECTSTORE_S3_BUCKET=${FQDN} +OVERWRITE_CLI_URL=https://${FQDN_DOTS} +NEXTCLOUD_TRUSTED_DOMAINS=${FQDN_DOTS} + +INSTANCE_ID=${INSTANCE_ID} + +SECRET=${SECRET} +PASSWORD_SALT=${PASSWORD_SALT} +NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD} diff --git a/nextcloud/kustomization.yaml.template b/nextcloud/kustomization.yaml.template new file mode 100644 index 0000000000000000000000000000000000000000..82d56ee3235abc5bb5cc63d4d9c797a5360185ce --- /dev/null +++ b/nextcloud/kustomization.yaml.template @@ -0,0 +1,9 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +generatorOptions: + disableNameSuffixHash: true +secretGenerator: +- name: ${FQDN}-app + envs: + - env + type: Opaque diff --git a/nextcloud/manifests/app.yml b/nextcloud/manifests/app.yml new file mode 100644 index 0000000000000000000000000000000000000000..5ad14c0cc74f4778507de4c0755e9378b4fbc951 --- /dev/null +++ b/nextcloud/manifests/app.yml @@ -0,0 +1,331 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: nextcloud + app.kubernetes.io/part-of: Nextcloud + name: ${FQDN}-app + namespace: ${NS} +spec: + ports: + - name: api + port: 9000 + protocol: TCP + targetPort: api + selector: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: nextcloud + app.kubernetes.io/part-of: Nextcloud + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: web + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: nextcloud + app.kubernetes.io/part-of: Nextcloud + name: ${FQDN}-web + namespace: ${NS} +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: http + selector: + app.kubernetes.io/component: web + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: nextcloud + app.kubernetes.io/part-of: Nextcloud + sessionAffinity: None + type: ClusterIP +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + annotations: + kubernetes.io/tls-acme: "true" + nginx.ingress.kubernetes.io/proxy-body-size: 100g + nginx.ingress.kubernetes.io/proxy-request-buffering: "off" + labels: + app.kubernetes.io/component: web + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: nextcloud + app.kubernetes.io/part-of: Nextcloud + name: ${FQDN}-web + namespace: ${NS} +spec: + rules: + - host: ${FQDN_DOTS} + http: + paths: + - backend: + serviceName: ${FQDN}-web + servicePort: http + path: / + tls: + - hosts: + - ${FQDN_DOTS} + secretName: ${FQDN}-tls +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: nextcloud + app.kubernetes.io/part-of: Nextcloud + name: ${FQDN}-app + namespace: ${NS} +spec: + progressDeadlineSeconds: 600 + replicas: 2 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: nextcloud + app.kubernetes.io/part-of: Nextcloud + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + labels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: nextcloud + app.kubernetes.io/part-of: Nextcloud + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + topologyKey: kubernetes.io/hostname + labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - ${FQDN} + - key: app.kubernetes.io/component + operator: In + values: + - app + containers: + - command: + - php-fpm + env: +#cat ./version.php | grep 'array(' | cut -d\( -f2 | cut -d\) -f1 | sed 's/,/\./g' + - name: VERSION + value: ${NC_VERSION} + - name: INSTALLED + value: "true" + - name: OBJECTSTORE_S3_KEY + valueFrom: + secretKeyRef: + key: AWS_ACCESS_KEY_ID + name: ${FQDN}-s3 + - name: OBJECTSTORE_S3_SECRET + valueFrom: + secretKeyRef: + key: AWS_SECRET_ACCESS_KEY + name: ${FQDN}-s3 + - name: MAIL_FROM_ADDRESS + valueFrom: + secretKeyRef: + key: mail_from_address + name: ${NS}-smtp + - name: SMTP_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: ${NS}-smtp + - name: SMTP_NAME + valueFrom: + secretKeyRef: + key: username + name: ${NS}-smtp + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: nextcloud.pg-${PG_DOMAIN}.credentials + envFrom: + - secretRef: + name: ${FQDN}-app + image: libresh/nextcloud:${NC_IMAGE_TAG} + imagePullPolicy: Always + name: app + ports: + - containerPort: 9000 + name: api + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: + fsGroup: 82 + runAsGroup: 82 + runAsUser: 82 + terminationGracePeriodSeconds: 30 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: web + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: nextcloud + app.kubernetes.io/part-of: Nextcloud + name: ${FQDN}-web + namespace: ${NS} +spec: + progressDeadlineSeconds: 600 + replicas: 2 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: web + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: nextcloud + app.kubernetes.io/part-of: Nextcloud + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + labels: + app.kubernetes.io/component: web + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: nextcloud + app.kubernetes.io/part-of: Nextcloud + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + topologyKey: kubernetes.io/hostname + labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - ${FQDN} + - key: app.kubernetes.io/component + operator: In + values: + - web + containers: + - image: libresh/nextcloud:${NC_WEB_IMAGE_TAG} + imagePullPolicy: Always + name: web + ports: + - containerPort: 80 + name: http + protocol: TCP + env: + - name: BACKEND_HOST + value: ${FQDN}-app + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 +--- +apiVersion: batch/v1beta1 +kind: CronJob +metadata: + labels: + app.kubernetes.io/component: cron + app.kubernetes.io/instance: ${FQDN}-cron + app.kubernetes.io/part-of: nextcloud + name: ${FQDN}-cron +spec: + jobTemplate: + metadata: + labels: + app.kubernetes.io/component: cron + app.kubernetes.io/instance: ${FQDN}-cron + app.kubernetes.io/part-of: nextcloud + name: nextcloud-cron + spec: + manualSelector: false + template: + metadata: + labels: + app.kubernetes.io/component: cron + app.kubernetes.io/instance: ${FQDN}-cron + app.kubernetes.io/part-of: nextcloud + name: nextcloud-cron + spec: + containers: + - args: + - /bin/echo start cron;/usr/local/bin/php occ status;/usr/local/bin/php /usr/src/nextcloud/cron.php;/bin/echo stop cron;/usr/local/bin/php occ config:list | grep lastcron | cut -d\" -f4 | xargs -I{} date -d @{} + command: + - /bin/sh + - -c + env: + - name: INSTALLED + value: "true" + - name: VERSION + value: ${NC_VERSION} + - name: OBJECTSTORE_S3_KEY + valueFrom: + secretKeyRef: + key: AWS_ACCESS_KEY_ID + name: ${FQDN}-s3 + - name: OBJECTSTORE_S3_SECRET + valueFrom: + secretKeyRef: + key: AWS_SECRET_ACCESS_KEY + name: ${FQDN}-s3 + - name: MAIL_FROM_ADDRESS + valueFrom: + secretKeyRef: + key: mail_from_address + name: ${NS}-smtp + - name: SMTP_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: ${NS}-smtp + - name: SMTP_NAME + valueFrom: + secretKeyRef: + key: username + name: ${NS}-smtp + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: nextcloud.pg-${PG_DOMAIN}.credentials + envFrom: + - secretRef: + name: ${FQDN}-app + image: libresh/nextcloud:${NC_IMAGE_TAG} + imagePullPolicy: Always + name: cli + restartPolicy: OnFailure + schedule: '*/5 * * * *' + successfulJobsHistoryLimit: 3 + suspend: false diff --git a/nextcloud/manifests/install-job.yml b/nextcloud/manifests/install-job.yml new file mode 100644 index 0000000000000000000000000000000000000000..ed6f855a98568e9f266e015ba517e65114f6f482 --- /dev/null +++ b/nextcloud/manifests/install-job.yml @@ -0,0 +1,71 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: ${FQDN}-install + namespace: ${DOMAIN} +spec: + template: + spec: + containers: + - command: + - /install.sh + env: + - name: VERSION + value: ${NC_VERSION} + - name: OBJECTSTORE_S3_KEY + valueFrom: + secretKeyRef: + key: AWS_ACCESS_KEY_ID + name: ${FQDN}-s3 + - name: OBJECTSTORE_S3_SECRET + valueFrom: + secretKeyRef: + key: AWS_SECRET_ACCESS_KEY + name: ${FQDN}-s3 + - name: MAIL_FROM_ADDRESS + valueFrom: + secretKeyRef: + key: mail_from_address + name: ${DOMAIN}-smtp + - name: SMTP_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: ${DOMAIN}-smtp + - name: SMTP_NAME + valueFrom: + secretKeyRef: + key: username + name: ${DOMAIN}-smtp + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: nextcloud.pg-${DOMAIN}.credentials + envFrom: + - secretRef: + name: ${FQDN}-app + - secretRef: + name: ${FQDN}-oo + image: libresh/nextcloud:${NC_IMAGE_TAG} + imagePullPolicy: IfNotPresent + name: install-nuage + volumeMounts: + - name: realm + mountPath: "/etc/tls/idp" + readOnly: true + - name: saml + mountPath: "/etc/tls/saml" + readOnly: true + volumes: + - name: saml + secret: + secretName: ${FQDN}-saml + - name: realm + secret: + secretName: ${DOMAIN}-realm + restartPolicy: Never + securityContext: + fsGroup: 82 + runAsGroup: 82 + runAsUser: 82 diff --git a/nextcloud/manifests/pg.yml b/nextcloud/manifests/pg.yml new file mode 100644 index 0000000000000000000000000000000000000000..566cb45d6662c930e50efb2bcbb11ec26543eb4d --- /dev/null +++ b/nextcloud/manifests/pg.yml @@ -0,0 +1,160 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: zalando-postgres +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: zalando-postgres +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: zalando-postgres +subjects: +- kind: ServiceAccount + name: zalando-postgres +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: postgres-pod-config +data: + AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} + AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} + AWS_S3_FORCE_PATH_STYLE: "true" + WAL_S3_BUCKET: ${NS}-dumps + AWS_ENDPOINT: https://minio.k7.indie.host + WAL_S3_ENDPOINT: https://minio.k7.indie.host + AWS_REGION: default + USE_WALE: "true" + USE_WALG_BACKUP: "true" + WALG_DISABLE_S3_SSE: "true" + BACKUP_SCHEDULE: "5 0 * * *" +--- +apiVersion: "acid.zalan.do/v1" +kind: postgresql +metadata: + name: pg-${PG_DOMAIN} +spec: + teamId: "pg" + volume: + size: 4975Mi + storageClass: small + numberOfInstances: 2 + users: + hedgedoc: # database owner + - superuser + - createdb + discourse: # database owner + - superuser + - createdb + nextcloud: # database owner + - superuser + - createdb + databases: + nextcloud: nextcloud # dbname: owner + hedgedoc: hedgedoc # dbname: owner + discourse: discourse # dbname: owner + postgresql: + version: "12" +--- +apiVersion: batch/v1beta1 +kind: CronJob +metadata: + labels: + application: spilo + cluster-name: pg-${PG_DOMAIN} + team: pg + name: ${PG_DOMAIN}-dump +spec: + concurrencyPolicy: Forbid + failedJobsHistoryLimit: 1 + jobTemplate: + spec: + template: + metadata: + labels: + application: spilo-logical-backup + version: pg-${PG_DOMAIN} + spec: + affinity: + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + application: spilo-logical-backup + version: pg-${PG_DOMAIN} + topologyKey: kubernetes.io/hostname + weight: 1 + containers: + - env: + - name: SCOPE + value: pg-${PG_DOMAIN} + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: LOGICAL_BACKUP_PROVIDER + value: minio + - name: CLUSTER_NAME_LABEL + value: cluster-name + - name: LOGICAL_BACKUP_S3_BUCKET + value: ${NS}-dumps + - name: LOGICAL_BACKUP_S3_ENDPOINT + value: https://minio.k7.indie.host + - name: LOGICAL_BACKUP_S3_BUCKET_SCOPE_SUFFIX + value: "/nextcloud" + - name: LOGICAL_BACKUP_S3_REGION + value: default + - name: LOGICAL_BACKUP_S3_SSE + value: "" + - name: PG_VERSION + value: "12" + - name: PGPORT + value: "5432" + - name: PGUSER + value: postgres + - name: PGDATABASE + value: postgres + - name: PGSSLMODE + value: require + - name: PGPASSWORD + valueFrom: + secretKeyRef: + key: password + name: postgres.pg-${PG_DOMAIN}.credentials + - name: AWS_S3_FORCE_PATH_STYLE + value: "true" + envFrom: + - secretRef: + name: ${NS}-dumps + image: registry.opensource.zalan.do/acid/logical-backup:v1.6.2 + imagePullPolicy: IfNotPresent + name: logical-backup + ports: + - containerPort: 8008 + protocol: TCP + - containerPort: 5432 + protocol: TCP + - containerPort: 8080 + protocol: TCP + resources: + limits: + cpu: "3" + memory: 1Gi + requests: + cpu: 100m + memory: 100Mi + securityContext: + privileged: false + readOnlyRootFilesystem: false + restartPolicy: Never + schedulerName: default-scheduler + serviceAccount: zalando-postgres + serviceAccountName: zalando-postgres + schedule: '15 2 * * *' + diff --git a/nextcloud/manifests/redis.yml b/nextcloud/manifests/redis.yml new file mode 100644 index 0000000000000000000000000000000000000000..648b1c1c91f9e1b76c46005c2ff05cd94e487d88 --- /dev/null +++ b/nextcloud/manifests/redis.yml @@ -0,0 +1,51 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: redis + name: redis +spec: + replicas: 1 + selector: + matchLabels: + app: redis + role: master + tier: backend + template: + metadata: + labels: + app: redis + role: master + tier: backend + spec: + containers: + - image: redis + imagePullPolicy: Always + name: master + ports: + - containerPort: 6379 + protocol: TCP + resources: + requests: + cpu: 100m + memory: 100M +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: redis + role: master + tier: backend + name: redis +spec: + ports: + - port: 6379 + protocol: TCP + targetPort: 6379 + selector: + app: redis + role: master + tier: backend + type: ClusterIP diff --git a/nextcloud/other-manifests/dump.yml b/nextcloud/other-manifests/dump.yml new file mode 100644 index 0000000000000000000000000000000000000000..e5698f31f3d8dce2c6fb4abbee51752ab79531c2 --- /dev/null +++ b/nextcloud/other-manifests/dump.yml @@ -0,0 +1,96 @@ +apiVersion: batch/v1 +kind: Job +metadata: + labels: + application: spilo-logical-backup + job-name: dump + name: dump +spec: + backoffLimit: 6 + completions: 1 + parallelism: 1 + selector: + matchLabels: + job-name: dump + template: + metadata: + creationTimestamp: null + labels: + application: spilo-logical-backup + job-name: dump + spec: + affinity: + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + application: spilo-logical-backup + version: pg-${PG_DOMAIN} + topologyKey: kubernetes.io/hostname + weight: 1 + containers: + - env: + - name: LOGICAL_BACKUP_PROVIDER + value: minio + - name: SCOPE + value: pg-${PG_DOMAIN} + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: CLUSTER_NAME_LABEL + value: cluster-name + - name: LOGICAL_BACKUP_S3_BUCKET + value: ${NS}-dumps + - name: LOGICAL_BACKUP_S3_ENDPOINT + value: https://minio.k7.indie.host + - name: LOGICAL_BACKUP_S3_BUCKET_SCOPE_SUFFIX + value: /nextcloud + - name: LOGICAL_BACKUP_S3_REGION + value: default + - name: LOGICAL_BACKUP_S3_SSE + - name: PG_VERSION + value: "12" + - name: PGPORT + value: "5432" + - name: PGUSER + value: postgres + - name: PGDATABASE + value: postgres + - name: PGSSLMODE + value: require + - name: PGPASSWORD + valueFrom: + secretKeyRef: + key: password + name: postgres.pg-${PG_DOMAIN}.credentials + - name: AWS_S3_FORCE_PATH_STYLE + value: "true" + envFrom: + - secretRef: + name: ${NS}-dumps + image: registry.opensource.zalan.do/acid/logical-backup:v1.6.2 + imagePullPolicy: IfNotPresent + name: logical-backup + ports: + - containerPort: 8008 + protocol: TCP + - containerPort: 5432 + protocol: TCP + - containerPort: 8080 + protocol: TCP + resources: {} + securityContext: + privileged: false + readOnlyRootFilesystem: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Never + schedulerName: default-scheduler + securityContext: {} + serviceAccount: zalando-postgres + serviceAccountName: zalando-postgres + terminationGracePeriodSeconds: 30 diff --git a/nextcloud/other-manifests/saml-cert.yaml b/nextcloud/other-manifests/saml-cert.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7f365f058028d87f4bf627ce5f9e0234da3f2462 --- /dev/null +++ b/nextcloud/other-manifests/saml-cert.yaml @@ -0,0 +1,17 @@ +apiVersion: cert-manager.io/v1alpha3 +kind: Certificate +metadata: + name: ${FQDN}-saml +spec: + dnsNames: + - ${FQDN_DOTS} + issuerRef: + group: cert-manager.io + kind: ClusterIssuer + name: selfsigned-issuer + secretName: ${FQDN}-saml + commonName: ${FQDN_DOTS} + duration: "26280h" + subject: + organizations: + - indiehost diff --git a/nextcloud/other-manifests/update-job.yml b/nextcloud/other-manifests/update-job.yml new file mode 100644 index 0000000000000000000000000000000000000000..a6bcdb4da99d7c20e077bf87cb1c838624e2cb8e --- /dev/null +++ b/nextcloud/other-manifests/update-job.yml @@ -0,0 +1,67 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: update-nc + namespace: ${NS} +spec: + template: + spec: + containers: + - command: + - /bin/sh + - -c + args: + - /bin/echo start update; + /usr/local/bin/php occ status; + /usr/local/bin/php occ upgrade; + /usr/local/bin/php occ app:disable dashboard; + /usr/local/bin/php occ db:add-missing-indices -n; + /usr/local/bin/php occ db:add-missing-primary-keys -n; + /usr/local/bin/php occ db:convert-filecache-bigint -n; + /usr/local/bin/php occ db:add-missing-columns -n + env: + - name: INSTALLED + value: "true" + - name: VERSION + value: ${NC_VERSION} + - name: OBJECTSTORE_S3_KEY + valueFrom: + secretKeyRef: + key: AWS_ACCESS_KEY_ID + name: ${FQDN}-s3 + - name: OBJECTSTORE_S3_SECRET + valueFrom: + secretKeyRef: + key: AWS_SECRET_ACCESS_KEY + name: ${FQDN}-s3 + - name: MAIL_FROM_ADDRESS + valueFrom: + secretKeyRef: + key: mail_from_address + name: ${NS}-smtp + - name: SMTP_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: ${NS}-smtp + - name: SMTP_NAME + valueFrom: + secretKeyRef: + key: username + name: ${NS}-smtp + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: nextcloud.pg-${PG_DOMAIN}.credentials + envFrom: + - secretRef: + name: ${FQDN}-app + image: libresh/nextcloud:${NC_IMAGE_TAG} + imagePullPolicy: IfNotPresent + name: install-nuage + restartPolicy: Never + securityContext: + fsGroup: 82 + runAsGroup: 82 + runAsUser: 82 diff --git a/nextcloud/source b/nextcloud/source new file mode 100644 index 0000000000000000000000000000000000000000..3a8eb2211aa2afa6f9fd3005febc1067e1bdece9 --- /dev/null +++ b/nextcloud/source @@ -0,0 +1,7 @@ +export INSTANCE_ID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 7 | head -n 1) +export SECRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 18 | head -n 1) +export PASSWORD_SALT=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 18 | head -n 1) +export NEXTCLOUD_ADMIN_PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 18 | head -n 1) + +export FQDN=${NUAGE_SUBDOMAIN}-${NS} +export FQDN_DOTS=${NUAGE_SUBDOMAIN}.${DOMAIN} diff --git a/nextcloud/update_all.sh b/nextcloud/update_all.sh new file mode 100644 index 0000000000000000000000000000000000000000..e0c1c8820abafd3f6ad0298dc5d3e2bb6c736e49 --- /dev/null +++ b/nextcloud/update_all.sh @@ -0,0 +1,24 @@ +for folder in `find . -type d | grep -v 'chat\|trash\|temp\|pad\|git\|common' | grep 'wombat\|nuage\|partage\|mairie'`; +do + cd $folder; + export NS=`pwd | rev | cut -d'/' -f 2 | rev` + k -n $NS delete job dump + libre apply ../../common/nextcloud/manifests/dump.yml; + cd ../..; +done +k get po -A | grep -v '\-dump' | grep dump + +for folder in `find . -type d | grep -v 'chat\|trash\|temp\|pad\|git\|common' | grep 'wombat\|nuage\|partage\|mairie'`; +do + cd $folder; + libre diff ../../common/nextcloud/manifests/app.yaml; + retVal=$? + if [ $retVal -ne 0 ]; then + read -p "Press any key to apply..." + libre apply ../../common/nextcloud/manifests/app.yaml; + export NS=`pwd | rev | cut -d'/' -f 2 | rev` + k -n $NS delete update-nc + libre apply ../../common/nextcloud/manifests/update-job.yml; + fi + cd ../..; +done diff --git a/rocketchat/backup/backup.yml b/rocketchat/backup/backup.yml new file mode 100644 index 0000000000000000000000000000000000000000..d60d82c905a142c43c82f52ddb1402bd3e51e89b --- /dev/null +++ b/rocketchat/backup/backup.yml @@ -0,0 +1,7 @@ +apiVersion: psmdb.percona.com/v1 +kind: PerconaServerMongoDBBackup +metadata: + name: backup-${EPOCH} +spec: + psmdbCluster: ${FQDN} + storageName: backup diff --git a/rocketchat/config.yaml b/rocketchat/config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..77e73b0d71e681a386b36300ec8ebda561f310c0 --- /dev/null +++ b/rocketchat/config.yaml @@ -0,0 +1 @@ +configureOAuth: true diff --git a/rocketchat/env.template b/rocketchat/env.template new file mode 100644 index 0000000000000000000000000000000000000000..9ed0427785d7c14fedd1ddeea7aa3c80e19c784c --- /dev/null +++ b/rocketchat/env.template @@ -0,0 +1,5 @@ +ADMIN_PASS=${ADMIN_PASS} +MONGO_PASSWORD=${MONGO_PASSWORD} +MONGO_OPLOG_PASSWORD=${MONGO_OPLOG_PASSWORD} +MONGO_URL=mongodb://rocketchat:${MONGO_PASSWORD}@${FQDN}-rs0-0.${FQDN}-rs0.${NS}.svc.cluster.local:27017,${FQDN}-rs0-1.${FQDN}-rs0.${NS}.svc.cluster.local:27017,${FQDN}-rs0-2.${FQDN}-rs0.${NS}.svc.cluster.local:27017/rocketchat?authSource=admin&replicaSet=rs0&w=majority +MONGO_OPLOG_URL=mongodb://oplog:${MONGO_OPLOG_PASSWORD}@${FQDN}-rs0-0.${FQDN}-rs0.${NS}.svc.cluster.local:27017,${FQDN}-rs0-1.${FQDN}-rs0.${NS}.svc.cluster.local:27017,${FQDN}-rs0-2.${FQDN}-rs0.${NS}.svc.cluster.local:27017/local?authSource=admin&replicaSet=rs0 diff --git a/rocketchat/kustomization.yaml.template b/rocketchat/kustomization.yaml.template new file mode 100644 index 0000000000000000000000000000000000000000..82d56ee3235abc5bb5cc63d4d9c797a5360185ce --- /dev/null +++ b/rocketchat/kustomization.yaml.template @@ -0,0 +1,9 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +generatorOptions: + disableNameSuffixHash: true +secretGenerator: +- name: ${FQDN}-app + envs: + - env + type: Opaque diff --git a/rocketchat/manifests/app.yml b/rocketchat/manifests/app.yml new file mode 100644 index 0000000000000000000000000000000000000000..7de56f3d86b072f42d422ca2e976c193c0918ebe --- /dev/null +++ b/rocketchat/manifests/app.yml @@ -0,0 +1,268 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: Rocketchat + app.kubernetes.io/part-of: Rocketchat + name: ${FQDN}-app + namespace: ${NS} +spec: + progressDeadlineSeconds: 600 + replicas: 2 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: Rocketchat + app.kubernetes.io/part-of: Rocketchat + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + labels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: Rocketchat + app.kubernetes.io/part-of: Rocketchat + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 20 + preference: + matchExpressions: + - key: stateless + operator: In + values: + - "true" + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + topologyKey: kubernetes.io/hostname + labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - ${FQDN} + containers: + - env: + - name: TZ + value: Europe/Berlin + - name: INSTANCE_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: OVERWRITE_SETTING_FileUpload_S3_AWSSecretAccessKey + valueFrom: + secretKeyRef: + key: AWS_SECRET_ACCESS_KEY + name: ${FQDN}-s3 + - name: OVERWRITE_SETTING_FileUpload_S3_AWSAccessKeyId + valueFrom: + secretKeyRef: + key: AWS_ACCESS_KEY_ID + name: ${FQDN}-s3 + #- name: Direct_Reply_Username + # valueFrom: + # secretKeyRef: + # key: username + # name: ${FQDN}-smtp + #- name: Direct_Reply_Password + # valueFrom: + # secretKeyRef: + # key: password + # name: ${FQDN}-smtp + #- name: Direct_Reply_ReplyTo + # valueFrom: + # secretKeyRef: + # key: username + # name: ${FQDN}-smtp + - name: OVERWRITE_SETTING_From_Email + valueFrom: + secretKeyRef: + key: from_email + name: ${NS}-smtp + - name: OVERWRITE_SETTING_SMTP_Username + valueFrom: + secretKeyRef: + key: username + name: ${NS}-smtp + - name: OVERWRITE_SETTING_SMTP_Password + valueFrom: + secretKeyRef: + key: password + name: ${NS}-smtp + - name: OVERWRITE_SETTING_SMTP_Host + valueFrom: + secretKeyRef: + key: host + name: ${NS}-smtp + - name: OVERWRITE_SETTING_SMTP_Port + valueFrom: + secretKeyRef: + key: port + name: ${NS}-smtp + - name: EXIT_UNHANDLEDPROMISEREJECTION + value: "1" + - name: USE_NATIVE_OPLOG + value: "true" +{{if .ConfigureOAuth}} + - name: Accounts_OAuth_Custom_Liiibre_id + valueFrom: + secretKeyRef: + key: client-id + name: ${FQDN}-oidc + - name: Accounts_OAuth_Custom_Liiibre_secret + valueFrom: + secretKeyRef: + key: client-secret + name: ${FQDN}-oidc +{{end}} + envFrom: + - secretRef: + name: ${FQDN}-app + - configMapRef: + name: ${FQDN}-config + image: libresh/rocketchat:3.16.4 + imagePullPolicy: IfNotPresent + name: app + ports: + - containerPort: 3000 + name: http + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: Rocketchat + app.kubernetes.io/part-of: Rocketchat + name: ${FQDN}-app + namespace: ${NS} +spec: + ports: + - name: http + port: 3000 + protocol: TCP + targetPort: http + selector: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: Rocketchat + app.kubernetes.io/part-of: Rocketchat + type: ClusterIP +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + annotations: + kubernetes.io/tls-acme: "true" + labels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: ${FQDN} + app.kubernetes.io/name: Rocketchat + app.kubernetes.io/part-of: Rocketchat + name: ${FQDN}-app + namespace: ${NS} +spec: + rules: + - host: ${FQDN_DOTS} + http: + paths: + - backend: + serviceName: ${FQDN}-app + servicePort: http + path: / + tls: + - hosts: + - ${FQDN_DOTS} + secretName: ${FQDN}-tls +--- +kind: ConfigMap +metadata: + name: ${FQDN}-config +apiVersion: v1 +data: + ADMIN_USERNAME: admin + ADMIN_EMAIL: contact@indiehosters.net + MONGO_USERNAME: rocketchat + MONGO_OPLOG_USERNAME: oplog + ROOT_URL: https://${FQDN_DOTS} + OVERWRITE_SETTING_Update_EnableChecker: 'false' + OVERWRITE_SETTING_Show_Setup_Wizard: completed + OVERWRITE_SETTING_Accounts_AllowDeleteOwnAccount: 'true' + # Email + OVERWRITE_SETTING_SMTP_Protocol: smtp + OVERWRITE_SETTING_SMTP_Pool: 'true' + OVERWRITE_SETTING_SMTP_IgnoreTLS: 'false' + # S3 + OVERWRITE_SETTING_FileUpload_S3_Bucket: ${BUCKET} + OVERWRITE_SETTING_FileUpload_S3_BucketURL: https://s3.standard.indie.host + OVERWRITE_SETTING_FileUpload_S3_ForcePathStyle: 'true' + OVERWRITE_SETTING_FileUpload_S3_Region: default + OVERWRITE_SETTING_FileUpload_Storage_Type: AmazonS3 + # Jitsi + OVERWRITE_SETTING_Jitsi_Enabled: 'true' + Jitsi_Domain: meet.liiib.re + Jitsi_URL_Room_Prefix: ${NS} + OVERWRITE_SETTING_Jitsi_URL_Room_Hash: 'true' + OVERWRITE_SETTING_Jitsi_SSL: 'true' + OVERWRITE_SETTING_Jitsi_Open_New_Window: 'true' + OVERWRITE_SETTING_Jitsi_Enable_Channels: 'true' +{{if .ConfigureOAuth}} + # OAuth + OVERWRITE_SETTING_Accounts_TwoFactorAuthentication_By_Email_Enabled: 'false' + OVERWRITE_SETTING_Accounts_TwoFactorAuthentication_Enabled: 'false' + OVERWRITE_SETTING_Accounts_TwoFactorAuthentication_Enforce_Password_Fallback: 'false' + Accounts_OAuth_Custom_Liiibre: 'true' + Accounts_OAuth_Custom_Liiibre_url: https://id.indie.host/auth/realms/${NS}/protocol/openid-connect + Accounts_OAuth_Custom_Liiibre_token_path: /token + Accounts_OAuth_Custom_Liiibre_identity_path: /userinfo + Accounts_OAuth_Custom_Liiibre_token_sent_via: header + Accounts_OAuth_Custom_Liiibre_identity_token_sent_via: header + Accounts_OAuth_Custom_Liiibre_login_style: redirect + Accounts_OAuth_Custom_Liiibre_authorize_path: /auth + Accounts_OAuth_Custom_Liiibre_scope: openid + Accounts_OAuth_Custom_Liiibre_roles_claim: groups + Accounts_OAuth_Custom_Liiibre_groups_claim: groups + Accounts_OAuth_Custom_Liiibre_button_label_text: 'Entrez dans le Chat' + # To check + Accounts_OAuth_Custom_Liiibre_key_field: username + Accounts_OAuth_Custom_Liiibre_merge_roles: 'true' + Accounts_OAuth_Custom_Liiibre_merge_users: 'true' + Layout_Sidenav_Footer: '<a href="https://${NUAGE_URL}" class="backToNuage"><img src="assets/logo.png" alt="Nuage"/></a>' +{{end}} + # Direct Reply + Direct_Reply_Enable: "false" + Direct_Reply_Protocol: "IMAP" + Direct_Reply_Host: mail.indie.host + Direct_Reply_Port: "993" + #OVERWRITE_SETTING_Assets_SvgFavicon_Enable: 'false' + OVERWRITE_SETTING_Accounts_RegistrationForm_LinkReplacementText: '-' + Accounts_ShowFormLogin: 'false' + Accounts_RegistrationForm: disabled + OVERWRITE_SETTING_Accounts_AllowPasswordChangeForOAuthUsers: 'false' + OVERWRITE_SETTING_Accounts_Send_Email_When_Activating: 'false' + OVERWRITE_SETTING_Accounts_RequirePasswordConfirmation: 'false' + OVERWRITE_SETTING_Accounts_Verify_Email_For_External_Accounts: 'true' + SETTINGS_BLOCKED: Accounts_TwoFactorAuthentication_By_Email_Enabled,Accounts_TwoFactorAuthentication_Enabled,Accounts_TwoFactorAuthentication_Enforce_Password_Fallback + Layout_Home_Body: '<h1>Bienvenue sur l''espace de discussion de ${NS}</h1> <p>Retrouvez-ici tous les membres de l''organisation, les canaux de discussion et échangez en temps réel :)</p> <p>Les applications de bureau Rocket.Chat pour Windows, macOS et Linux sont disponibles en téléchargement <a title="Rocket.Chat desktop apps" href="https://rocket.chat/download" target="_blank" rel="noopener">ici</a>.</p><p>L''application mobile native, Rocket.Chat, pour Android et iOS est disponible à l''adresse suivante <a title="Rocket.Chat on Google Play" href="https://play.google.com/store/apps/details?id=chat.rocket.android" target="_blank" rel="noopener">Google Play</a> et <a title="Rocket.Chat on the App Store" href="https://itunes.apple.com/app/rocket-chat/id1148741252" target="_blank" rel="noopener">App Store</a>. <p>Si besoin d''aide pour configurer votre application Rocketchat, <a href="https://support.indie.host/help/fr-fr" target="_blank" rel="noopener">une documentation</a> est à votre disposition.</p> <img src="assets/logo.png" width="120px"/>' diff --git a/rocketchat/manifests/mongo-configure-job.yml b/rocketchat/manifests/mongo-configure-job.yml new file mode 100644 index 0000000000000000000000000000000000000000..475cd0c4ea3c3c151a0e3e264cd6e8755506a512 --- /dev/null +++ b/rocketchat/manifests/mongo-configure-job.yml @@ -0,0 +1,45 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: ${FQDN}-configure-mongo + namespace: ${NS} +spec: + template: + spec: + containers: + - command: [/init/configure-mongo.sh] + env: + - name: FQDN + value: ${FQDN} + - name: NS + value: ${NS} + envFrom: + - secretRef: + name: ${FQDN}-app + - secretRef: + name: ${FQDN}-mongodb-users + image: mongo + imagePullPolicy: IfNotPresent + name: configure + volumeMounts: + - name: init-script + mountPath: /init/ + volumes: + - name: init-script + configMap: + name: configure-mongo + defaultMode: 0700 + restartPolicy: Never +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: configure-mongo +data: + configure-mongo.sh: | + #!/bin/bash -eux + export host="mongodb://${MONGODB_USER_ADMIN_USER}:${MONGODB_USER_ADMIN_PASSWORD}@${FQDN}-rs0-0.${FQDN}-rs0.${NS}.svc.cluster.local:27017,${FQDN}-rs0-1.${FQDN}-rs0.${NS}.svc.cluster.local:27017,${FQDN}-rs0-2.${FQDN}-rs0.${NS}.svc.cluster.local:27017/rocketchat?authSource=admin&replicaSet=rs0" + mongo --host=$host --eval "db.getSiblingDB('admin');" + mongo --host=$host --eval "db.getSiblingDB('admin').createUser({user: 'oplog', pwd: \"$MONGO_OPLOG_PASSWORD\", roles: [{role: 'read', db: 'local'}, {role: 'clusterMonitor', db: 'admin'}]});"; + mongo --host=$host --eval "db.getSiblingDB('admin').createUser({user: 'rocketchat',pwd: \"$MONGO_PASSWORD\", roles: [{ role: 'readWrite', db: 'rocketchat' }, {role: 'clusterMonitor', db: 'admin'}]});" + diff --git a/rocketchat/manifests/mongo-operator.yml b/rocketchat/manifests/mongo-operator.yml new file mode 100644 index 0000000000000000000000000000000000000000..8a2ec14bcb9956f7b7186e168b2378654d1f1793 --- /dev/null +++ b/rocketchat/manifests/mongo-operator.yml @@ -0,0 +1,144 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: percona-server-mongodb-operator +spec: + replicas: 1 + selector: + matchLabels: + name: percona-server-mongodb-operator + template: + metadata: + labels: + name: percona-server-mongodb-operator + spec: + serviceAccountName: percona-server-mongodb-operator + containers: + - name: percona-server-mongodb-operator + image: percona/percona-server-mongodb-operator:1.6.0 + ports: + - containerPort: 60000 + name: metrics + command: + - percona-server-mongodb-operator + imagePullPolicy: Always + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: OPERATOR_NAME + value: percona-server-mongodb-operator + - name: RESYNC_PERIOD + value: 5s + - name: LOG_VERBOSE + value: "false" +--- +kind: Role +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: percona-server-mongodb-operator +rules: +- apiGroups: + - psmdb.percona.com + resources: + - perconaservermongodbs + - perconaservermongodbs/status + - perconaservermongodbbackups + - perconaservermongodbbackups/status + - perconaservermongodbrestores + - perconaservermongodbrestores/status + verbs: + - get + - list + - update + - watch + - create +- apiGroups: + - "" + resources: + - pods + - pods/exec + - services + - persistentvolumeclaims + - secrets + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - apps + resources: + - deployments + - replicasets + - statefulsets + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - batch + resources: + - cronjobs + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - certmanager.k8s.io + - cert-manager.io + resources: + - issuers + - certificates + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - deletecollection +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: percona-server-mongodb-operator +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: service-account-percona-server-mongodb-operator +subjects: +- kind: ServiceAccount + name: percona-server-mongodb-operator +roleRef: + kind: Role + name: percona-server-mongodb-operator + apiGroup: rbac.authorization.k8s.io + diff --git a/rocketchat/manifests/mongo.yml b/rocketchat/manifests/mongo.yml new file mode 100644 index 0000000000000000000000000000000000000000..44514f6514dffd01209f0127f89b4f12c752bb9d --- /dev/null +++ b/rocketchat/manifests/mongo.yml @@ -0,0 +1,101 @@ +--- +apiVersion: psmdb.percona.com/v1-4-0 +kind: PerconaServerMongoDB +metadata: + name: ${FQDN} +spec: + updateStrategy: RollingUpdate + crVersion: "1.6.0" + image: percona/percona-server-mongodb:4.2.8-8 + imagePullPolicy: Always + allowUnsafeConfigurations: false + secrets: + users: ${FQDN}-mongodb-users + pmm: + enabled: false + replsets: + - name: rs0 + size: 3 + affinity: + antiAffinityTopologyKey: "kubernetes.io/hostname" + arbiter: + enabled: false + size: 0 + podDisruptionBudget: + maxUnavailable: 1 + podSecurityContext: + fsGroup: 1001 + containerSecurityContext: + runAsNonRoot: true + runAsUser: 1001 + expose: + enabled: false + livenessProbe: + exec: + command: + - mongodb-healthcheck + - k8s + - liveness + - --startupDelaySeconds + - "61" + failureThreshold: 4 + initialDelaySeconds: 60 + periodSeconds: 30 + startupDelaySeconds: 61 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + failureThreshold: 8 + initialDelaySeconds: 10 + periodSeconds: 3 + successThreshold: 1 + tcpSocket: + port: 27017 + timeoutSeconds: 2 + resources: + limits: + memory: 1500Mi + requests: + memory: 500Mi + storage: + engine: wiredTiger + wiredTiger: + collectionConfig: {} + engineConfig: + cacheSizeRatio: 0.5 + indexConfig: + prefixCompression: true + volumeSpec: + persistentVolumeClaim: + storageClassName: small + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 5Gi + mongod: + security: + redactClientLogData: false + enableEncryption: true + encryptionCipherMode: AES256-CBC + net: + port: 27017 + backup: + enabled: true + restartOnFailure: true + image: percona/percona-server-mongodb-operator:1.6.0-backup + serviceAccountName: percona-server-mongodb-operator + storages: + backup: + type: s3 + s3: + bucket: ${DOMAIN}-dumps + credentialsSecret: ${DOMAIN}-dumps + region: default + endpointUrl: https://minio.k7.indie.host/ + prefix: mongodb + tasks: + - name: daily-backup + enabled: true + schedule: "0 0 * * *" + storageName: backup + compressionType: gzip diff --git a/rocketchat/migrations/fix-cluster-monitor/cm.yml b/rocketchat/migrations/fix-cluster-monitor/cm.yml new file mode 100644 index 0000000000000000000000000000000000000000..bf1a332e5b86bd046f90d2da8c2bc9728ab4a753 --- /dev/null +++ b/rocketchat/migrations/fix-cluster-monitor/cm.yml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: fix-mongo-cluster-monitor +data: + fix-mongo.sh: | + #!/bin/bash -eux + export host="mongodb://${MONGODB_USER_ADMIN_USER}:${MONGODB_USER_ADMIN_PASSWORD}@${FQDN}-rs0-0.${FQDN}-rs0.${DOMAIN}.svc.cluster.local:27017,${FQDN}-rs0-1.${FQDN}-rs0.${DOMAIN}.svc.cluster.local:27017,${FQDN}-rs0-2.${FQDN}-rs0.${DOMAIN}.svc.cluster.local:27017/rocketchat?authSource=admin&replicaSet=rs0" + mongo --host=$host --eval "db.getSiblingDB('admin');" + mongo --host=$host --eval "db.getSiblingDB('admin').grantRolesToUser('oplog', [{role: 'clusterMonitor', db: 'admin'}]);"; + mongo --host=$host --eval "db.getSiblingDB('admin').grantRolesToUser('rocketchat', [{role: 'clusterMonitor', db: 'admin'}]);" diff --git a/rocketchat/migrations/fix-cluster-monitor/job.yml b/rocketchat/migrations/fix-cluster-monitor/job.yml new file mode 100644 index 0000000000000000000000000000000000000000..02e331e32c10f8553066206495de6dda801e0ad9 --- /dev/null +++ b/rocketchat/migrations/fix-cluster-monitor/job.yml @@ -0,0 +1,27 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: ${FQDN}-fix-mongo-cluster-monitor + namespace: ${NS} +spec: + template: + spec: + containers: + - command: [/init/fix-mongo.sh] + envFrom: + - secretRef: + name: ${FQDN}-app + - secretRef: + name: ${FQDN}-mongodb-users + image: mongo + imagePullPolicy: IfNotPresent + name: configure + volumeMounts: + - name: init-script + mountPath: /init/ + volumes: + - name: init-script + configMap: + name: fix-mongo-cluster-monitor + defaultMode: 0700 + restartPolicy: Never diff --git a/rocketchat/source b/rocketchat/source new file mode 100644 index 0000000000000000000000000000000000000000..5b94ff2eca15a1f54614bc0f28cc9c38a8698ec2 --- /dev/null +++ b/rocketchat/source @@ -0,0 +1,7 @@ +export MONGO_PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 18 | head -n 1) +export MONGO_OPLOG_PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 18 | head -n 1) +export ADMIN_PASS=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 18 | head -n 1) + +export FQDN=${CHAT_SUBDOMAIN}-${NS} +export FQDN_DOTS=${CHAT_SUBDOMAIN}.${DOMAIN} + diff --git a/rocketchat/update_all.sh b/rocketchat/update_all.sh new file mode 100755 index 0000000000000000000000000000000000000000..35c3fa3d475fc1eaca5c12a56f0b2ec846374400 --- /dev/null +++ b/rocketchat/update_all.sh @@ -0,0 +1,7 @@ +#!/bin/bash +for folder in `find . -maxdepth 2 -mindepth 2 -type d | grep -v 'trash\|temp\|tmp\|git\|common' | grep 'chat'`; +do + cd $folder; + libre update + cd ../..; +done