├── .gitattributes ├── .github └── workflows │ └── publish-charts.yml ├── .reuse └── dep5 ├── Dockerfile.base ├── Dockerfile.operator ├── Dockerfile.updater ├── LICENSES ├── Apache-2.0.txt ├── operator │ └── AGPL-3.0-or-later.txt └── updater │ ├── AGPL-3.0-or-later.txt │ └── MIT.txt ├── Makefile ├── README.md ├── common.mk ├── config ├── common-rbac │ ├── auth_proxy_client_clusterrole.yaml │ ├── auth_proxy_role.yaml │ ├── kustomization.yaml │ └── leader_election_role.yaml ├── crd │ ├── bases │ │ └── starter-core │ │ │ ├── kustomization.yaml │ │ │ ├── matrix.element.io_elementwebs.yaml │ │ │ ├── matrix.element.io_synapses.yaml │ │ │ └── matrix.element.io_wellknowndelegations.yaml │ ├── cleanup │ │ └── starter-core │ │ │ └── kustomization.yaml │ ├── default-resources │ │ └── starter-core │ │ │ ├── default-resources.yaml │ │ │ └── kustomization.yaml │ ├── deprecated-patches │ │ └── starter-core │ │ │ └── kustomization.yaml │ ├── deprecated-replacements │ │ └── starter-core │ │ │ └── kustomization.yaml │ ├── element-deployment │ │ ├── base │ │ │ ├── common │ │ │ │ ├── kustomization.yaml │ │ │ │ └── matrix.element.io_elementdeployments.yaml │ │ │ └── starter-core │ │ │ │ ├── element_web.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ ├── synapse.yaml │ │ │ │ └── well_known_delegation.yaml │ │ ├── cleanup │ │ │ └── starter-core │ │ │ │ └── kustomization.yaml │ │ ├── deprecated-patches │ │ │ ├── starter-core │ │ │ │ └── kustomization.yaml │ │ │ └── starter │ │ │ │ └── kustomization.yaml │ │ ├── deprecated-replacements │ │ │ ├── starter-core │ │ │ │ └── kustomization.yaml │ │ │ └── starter │ │ │ │ └── kustomization.yaml │ │ ├── inline-patches │ │ │ └── starter-core │ │ │ │ ├── certificates-keys.yaml │ │ │ │ ├── clean-global-k8s.yaml │ │ │ │ ├── defaults-global-k8s.yaml │ │ │ │ ├── descriptions.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ ├── replicas.yaml │ │ │ │ ├── synapse-op-del-k8s-synapse-storage-volume.yaml │ │ │ │ ├── uids-gids.yaml │ │ │ │ └── wellknowndelegation-no-fqdn.yaml │ │ └── replacements │ │ │ └── starter-core │ │ │ ├── default-resources-replacements.yaml │ │ │ ├── element_web.yaml │ │ │ ├── global.yaml │ │ │ ├── k8s-common.yaml │ │ │ ├── k8s-ingresses.yaml │ │ │ ├── k8s-monitoring.yaml │ │ │ ├── k8s-storage.yaml │ │ │ ├── k8s-workloads-resources.yaml │ │ │ ├── k8s-workloads.yaml │ │ │ ├── kustomization.yaml │ │ │ ├── postgres-libpq.yaml │ │ │ ├── synapse.yaml │ │ │ └── well_known_delegation.yaml │ ├── patches │ │ └── starter-core │ │ │ ├── kustomization.yaml │ │ │ └── synapse-add-external-ingress-path.yaml │ └── replacements │ │ ├── common │ │ ├── containers-security-context.yaml │ │ ├── host-aliases.yaml │ │ ├── image.yaml │ │ ├── ingress.yaml │ │ ├── k8s-workloads-resources.yaml │ │ ├── kustomization.yaml │ │ ├── matrix-server.yaml │ │ ├── pods-security-context.yaml │ │ ├── postgres-golang.yaml │ │ ├── postgres-libpq.yaml │ │ ├── service.yaml │ │ └── workloads.yaml │ │ └── starter-core │ │ ├── default-resources-replacements.yaml │ │ └── kustomization.yaml ├── default │ └── kustomization.yaml ├── rbac │ ├── auth_proxy_role_binding.yaml │ ├── kustomization.yaml │ ├── leader_election_role_binding.yaml │ ├── role.yaml │ ├── role_binding.yaml │ └── service_account.yaml ├── samples │ ├── matrix_v1alpha1_elementweb.yaml │ ├── matrix_v1alpha1_synapse.yaml │ └── matrix_v1alpha1_wellknowndelegation.yaml └── updater │ ├── default │ └── kustomization.yaml │ └── rbac │ └── kustomization.yaml ├── conversion ├── Dockerfile.operator ├── Dockerfile.updater ├── cmd │ ├── operator │ │ └── main.go │ └── updater │ │ └── main.go ├── go.mod ├── go.sum ├── go.sum.license └── internal │ └── pkg │ ├── converter │ ├── kubernetes │ │ └── framework.go │ ├── processor.go │ ├── v1alpha1 │ │ ├── processor.go │ │ └── starter │ │ │ ├── elementdeployment.go │ │ │ ├── processor.go │ │ │ └── synapse.go │ └── v1alpha2 │ │ ├── processor.go │ │ └── starter │ │ ├── elementdeployment.go │ │ ├── processor.go │ │ └── synapse.go │ ├── operator │ ├── serve.go │ └── serve_test.go │ ├── updater │ └── serve.go │ └── webhook │ └── config.go ├── helm ├── easy-setup │ ├── README.md │ ├── deploy.sh │ ├── ess-meta │ │ ├── Chart.yaml │ │ ├── templates │ │ │ ├── _helpers.tpl │ │ │ ├── postgres-db-secrets.yaml │ │ │ └── selfsigned-cert.yaml │ │ └── values.yaml │ ├── extract-ca.sh │ ├── helm-diff.sh │ ├── helm-template.sh │ ├── prepare.sh │ ├── tests │ │ ├── kind.yml │ │ ├── nginx-cm.yml │ │ └── self-signed-ca.yml │ ├── values.ess-crds.yaml.example │ └── values.ess-stack.yaml.example ├── ess-stack │ ├── Chart.yaml │ ├── templates │ │ ├── _helpers.tpl │ │ ├── elementdeployment.yaml │ │ └── secrets.yaml │ ├── values.schema.json │ ├── values.schema.json.license │ └── values.yaml ├── ess-system │ ├── Chart.yaml │ ├── templates │ │ ├── _helpers.tpl │ │ ├── webhook-certificate.yaml │ │ └── webhook-issuer.yaml │ └── values.yaml ├── operator │ ├── Chart.yaml │ ├── build.sh │ ├── fragments │ │ ├── ClusterRole-Editor.yaml │ │ ├── ClusterRole-Namespace.yaml │ │ ├── ClusterRole-Viewer.yaml │ │ ├── ConversionWebhook-CaBundle.yaml │ │ ├── ConversionWebhook-Service.yaml │ │ ├── CustomResourceDefinition-Annotations.yaml │ │ ├── Deployment-conversion-webhook.yaml │ │ ├── Deployment-element-operator-controller-manager.yaml │ │ ├── Operator-ConfigMap.yaml │ │ ├── Operator-Permissions.yaml │ │ ├── Operator-Service.yaml │ │ ├── Operator-ServiceMonitor.yaml │ │ ├── ServiceAccount-conversion-webhook.yaml │ │ ├── _helpers.tpl │ │ └── _variables.tpl │ ├── source-values.yaml │ ├── templates │ │ ├── _variables.tpl │ │ ├── clusterrole-element-operator-metrics-reader.yaml │ │ ├── clusterrole-element-operator-proxy.yaml │ │ ├── clusterrole-elementweb-editor.yaml │ │ ├── clusterrole-elementweb-viewer.yaml │ │ ├── clusterrole-manager.yaml │ │ ├── clusterrole-synapse-editor.yaml │ │ ├── clusterrole-synapse-viewer.yaml │ │ ├── clusterrole-wellknowndelegation-editor.yaml │ │ ├── clusterrole-wellknowndelegation-viewer.yaml │ │ ├── clusterrolebinding-element-operator-manager.yaml │ │ ├── clusterrolebinding-element-operator-proxy.yaml │ │ ├── configmap-ansible-cfg.yaml │ │ ├── customresourcedefinition-elementwebs.matrix.element.io.yaml │ │ ├── customresourcedefinition-synapses.matrix.element.io.yaml │ │ ├── customresourcedefinition-wellknowndelegations.matrix.element.io.yaml │ │ ├── deployment-conversion-webhook.yaml │ │ ├── deployment-element-operator-controller-manager.yaml │ │ ├── helpers.tpl │ │ ├── role-element-operator-leader-election.yaml │ │ ├── rolebinding-element-operator-leader-election.yaml │ │ ├── service-element-conversion-webhook.yaml │ │ ├── service-manager-metrics.yaml │ │ ├── service-monitor-manager.yaml │ │ ├── serviceaccount-conversion-webhook.yaml │ │ └── serviceaccount-element-operator-controller-manager.yaml │ ├── values.yaml │ └── yq │ │ ├── clusterdeployment.yq │ │ ├── crds-conversion.yq │ │ ├── main-role.yq │ │ ├── prefixes.yq │ │ ├── resource-editor-role.yq │ │ └── resource-viewer-role.yq └── updater │ ├── Chart.yaml │ ├── build.sh │ ├── fragments │ ├── ConversionWebhook-CaBundle.yaml │ ├── Deployment-element-updater-controller-manager.yaml │ ├── Updater-Permissions.yaml │ ├── Updater-Service.yaml │ ├── Updater-ServiceMonitor.yaml │ └── _variables.tpl │ ├── source-values.yaml │ ├── templates │ ├── _helpers.tpl │ ├── _variables.tpl │ ├── clusterrole-element-updater-metrics-reader.yaml │ ├── clusterrole-element-updater-proxy.yaml │ ├── clusterrole-elementdeployment-editor.yaml │ ├── clusterrole-elementdeployment-viewer.yaml │ ├── clusterrole-manager.yaml │ ├── clusterrolebinding-element-updater-manager.yaml │ ├── clusterrolebinding-element-updater-proxy.yaml │ ├── configmap-ansible-cfg.yaml │ ├── customresourcedefinition-elementdeployment.yaml │ ├── deployment-conversion-webhook.yaml │ ├── deployment-element-updater-controller-manager.yaml │ ├── role-element-updater-leader-election.yaml │ ├── rolebinding-element-updater-leader-election.yaml │ ├── service-element-conversion-webhook.yaml │ ├── service-manager-metrics.yaml │ ├── service-monitor-manager.yaml │ ├── serviceaccount-conversion-webhook.yaml │ └── serviceaccount-element-updater-controller-manager.yaml │ ├── values.yaml │ └── yq │ ├── prefixes.yq │ └── prefixes.yq.license ├── makefiles └── starter-edition-core ├── playbooks ├── any.yml └── elementdeployment.yml ├── requirements.txt ├── requirements.yml ├── roles ├── elementdeployment │ ├── defaults │ │ └── main │ │ │ ├── images.yml │ │ │ └── main.yml │ ├── filter_plugins │ │ ├── camel_case.py │ │ ├── mapattributes.py │ │ └── sort_apply_order.py │ ├── tasks │ │ ├── main.yml │ │ ├── prepare.yml │ │ └── prerequisites │ │ │ ├── all_secrets.yml │ │ │ ├── crds.yml │ │ │ ├── global_secret.yml │ │ │ ├── images_digests.yml │ │ │ └── name.yml │ ├── templates │ │ ├── any │ │ │ ├── k8s-config.yaml.j2 │ │ │ ├── k8s-host-aliases.yaml.j2 │ │ │ ├── k8s-image.yaml.j2 │ │ │ ├── k8s-ingress.yaml.j2 │ │ │ ├── k8s-services.yaml.j2 │ │ │ ├── k8s-volume-claim.yaml.j2 │ │ │ ├── k8s-workloads.yaml.j2 │ │ │ ├── pvc.yaml.j2 │ │ │ └── tls-secrets.yaml.j2 │ │ ├── element_web │ │ │ ├── config │ │ │ │ └── 50-user_provided.json.j2 │ │ │ ├── elementweb.yaml.j2 │ │ │ └── tls-secrets.yaml.j2 │ │ ├── synapse │ │ │ ├── config │ │ │ │ ├── 25-authenticated-media.yml.j2 │ │ │ │ └── 50-user_provided.yml.j2 │ │ │ ├── external_appservices.yaml.j2 │ │ │ ├── haproxy_service_monitor.yaml.j2 │ │ │ ├── pvc.yaml.j2 │ │ │ ├── secrets.yaml.j2 │ │ │ ├── service_monitor │ │ │ │ ├── haproxy_service_monitor.yaml.j2 │ │ │ │ └── synapse_service_monitor.yaml.j2 │ │ │ ├── synapse.yaml.j2 │ │ │ ├── synapse_service_monitor.yaml.j2 │ │ │ └── tls-secrets.yaml.j2 │ │ └── well_known_delegation │ │ │ ├── config_client │ │ │ └── 50-user_provided.json.j2 │ │ │ ├── config_element │ │ │ └── 50-user_provided.json.j2 │ │ │ ├── config_server │ │ │ └── 50-user_provided.json.j2 │ │ │ ├── tls-secrets.yaml.j2 │ │ │ └── wellknowndelegation.yaml.j2 │ └── vars │ │ └── main │ │ ├── element_web.yml │ │ ├── main.yml │ │ ├── replicas.yaml │ │ ├── synapse.yml │ │ ├── synapse_admin.yml │ │ └── well_known_delegation.yml ├── elementweb │ ├── defaults │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ ├── templates │ │ ├── config.json.j2 │ │ ├── manifests │ │ │ ├── element_config.yaml.j2 │ │ │ ├── element_deployment.yaml.j2 │ │ │ ├── element_ingress.yaml.j2 │ │ │ ├── element_nginx_config.yaml.j2 │ │ │ └── element_web_service.yaml.j2 │ │ └── nginx.conf.j2 │ └── vars │ │ └── main.yml ├── generic_apply │ ├── filter_plugins │ │ ├── drop_null_values.py │ │ ├── sort_apply_order.py │ │ └── split_regex.py │ └── tasks │ │ ├── apply_then_recreate.yml │ │ └── main.yml ├── synapse │ ├── defaults │ │ └── main │ │ │ ├── haproxy.yml │ │ │ └── main.yml │ ├── files │ │ ├── haproxy-429.http │ │ └── haproxy-429.http.license │ ├── tasks │ │ ├── dependencies.yml │ │ ├── dependencies │ │ │ └── registration_files.yml │ │ ├── ingress.yml │ │ ├── main.yml │ │ ├── redis_setup.yml │ │ ├── shared.yml │ │ ├── synapse_process.yml │ │ └── validation.yml │ ├── templates │ │ ├── haproxy-path_map_file.j2 │ │ ├── haproxy-path_map_file_get.j2 │ │ ├── haproxy.cfg.j2 │ │ ├── log_config.yaml.j2 │ │ ├── manifests │ │ │ ├── haproxy_configmap.yaml.j2 │ │ │ ├── haproxy_deployment.yaml.j2 │ │ │ ├── redis_configmap.yaml.j2 │ │ │ ├── redis_deployment.yaml.j2 │ │ │ ├── redis_service.yaml.j2 │ │ │ ├── synapse_config_secrets.yaml.j2 │ │ │ ├── synapse_http_service.yaml.j2 │ │ │ ├── synapse_ingress.yaml.j2 │ │ │ ├── synapse_service.yaml.j2 │ │ │ └── synapse_statefulset.yaml.j2 │ │ ├── redis.conf.j2 │ │ └── secrets │ │ │ ├── 10-defaults.yaml.j2 │ │ │ ├── 20-additional.yaml.j2 │ │ │ ├── 20-worker-additional.yaml.j2 │ │ │ ├── 25-homeserver.yaml.j2 │ │ │ ├── 25-registration.yaml.j2 │ │ │ ├── 25-with-workers.yaml.j2 │ │ │ └── 30-worker.yaml.j2 │ └── vars │ │ └── main │ │ └── main.yml ├── teardown │ ├── defaults │ │ └── main.yml │ ├── filter_plugins │ │ └── mapattributes.py │ └── tasks │ │ └── main.yml └── wellknowndelegation │ ├── defaults │ └── main.yml │ ├── files │ └── nginx.conf │ ├── tasks │ └── main.yml │ ├── templates │ ├── client.j2 │ ├── manifests │ │ ├── wellknown_configmap.yaml.j2 │ │ ├── wellknown_deployment.yaml.j2 │ │ ├── wellknown_ingress.yaml.j2 │ │ ├── wellknown_nginx_configmap.yaml.j2 │ │ └── wellknown_service.yaml.j2 │ └── server.j2 │ └── vars │ └── main.yml ├── sboms ├── docker.io_library_haproxy:3.0-alpine.json ├── docker.io_library_nginx:1.26-alpine-slim.json ├── docker.io_library_redis:7.4-alpine.json ├── docker.io_matrixdotorg_synapse:v1.116.0.json ├── docker.io_vectorim_element-web:v1.11.82.json ├── docker.io_vectorim_ess-core-operator-conversion-webhook:2.21.1.json ├── docker.io_vectorim_ess-core-operator:2.21.1.json ├── docker.io_vectorim_ess-core-updater-conversion-webhook:2.21.1.json ├── docker.io_vectorim_ess-core-updater:2.21.1.json └── quay.io_brancz_kube-rbac-proxy:v0.18.0.json ├── watches.updater.yaml └── watches.yaml /.gitattributes: -------------------------------------------------------------------------------- 1 | # Mark as generated for both GH & GL 2 | sboms/*.json gitlab-generated linguist-generated=true 3 | # Treat as binary files (no diff, no merge-conflicts - latest wins) 4 | sboms/* -diff -merge 5 | -------------------------------------------------------------------------------- /.reuse/dep5: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 6 | Upstream-Name: ess-starter-edition-core 7 | Upstream-Contact: New-Vector 8 | Source: https://gitlab.element.io 9 | 10 | Files: helm/operator/fragments/* 11 | Copyright: Copyright 2023 New Vector Ltd 12 | License: AGPL-3.0-or-later 13 | 14 | Files: helm/operator/yq/* 15 | Copyright: Copyright 2023 New Vector Ltd 16 | License: AGPL-3.0-or-later 17 | 18 | Files: helm/updater/fragments/* 19 | Copyright: Copyright 2023 New Vector Ltd 20 | License: AGPL-3.0-or-later 21 | 22 | Files: requirements.txt 23 | Copyright: Copyright 2023 New Vector Ltd 24 | License: AGPL-3.0-or-later 25 | 26 | Files: .gitattributes 27 | Copyright: Copyright 2024 New Vector Ltd 28 | License: AGPL-3.0-or-later 29 | 30 | Files: sboms/* 31 | Copyright: Copyright 2024 New Vector Ltd 32 | License: AGPL-3.0-or-later 33 | -------------------------------------------------------------------------------- /Dockerfile.operator: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | ARG DISTROLESS_BASE_IMAGE=registry.gitlab.element.io/engineering/ess/operator/element-kubernetes-operator/base:latest 6 | 7 | 8 | # We need to run a first build step to remove elementdeployment role 9 | FROM python:3.12-slim-bookworm AS build-tmp 10 | 11 | COPY LICENSES/operator /element.io/LICENSES 12 | COPY watches.yaml /element.io/watches.yaml 13 | 14 | COPY roles/ /tmp/prepare/roles/ 15 | COPY playbooks/ /tmp/prepare/playbooks/ 16 | # We copy to the target directory using rsync to be able to exclude some files 17 | RUN apt update && apt install -y rsync && \ 18 | rsync -av --progress /tmp/prepare/ /element.io/ \ 19 | --exclude roles/elementdeployment \ 20 | --exclude playbooks/elementdeployment.yml && \ 21 | apt remove -y rsync 22 | 23 | FROM $DISTROLESS_BASE_IMAGE as base 24 | 25 | # Label this image with the repo and commit that built it, for freshmaking purposes. 26 | ARG GIT_COMMIT=devel 27 | LABEL git_commit=$GIT_COMMIT 28 | 29 | COPY --from=build-tmp /element.io /element.io 30 | RUN chmod -R 0755 /element.io 31 | 32 | USER 32000 33 | -------------------------------------------------------------------------------- /Dockerfile.updater: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | ARG DISTROLESS_BASE_IMAGE=registry.gitlab.element.io/engineering/ess/operator/element-kubernetes-operator/base:latest 6 | 7 | FROM $DISTROLESS_BASE_IMAGE as base 8 | 9 | # Label this image with the repo and commit that built it, for freshmaking purposes. 10 | ARG GIT_COMMIT=devel 11 | LABEL git_commit=$GIT_COMMIT 12 | 13 | COPY LICENSES/updater /element.io/LICENSES 14 | COPY watches.updater.yaml /element.io/watches.yaml 15 | 16 | COPY roles/elementdeployment /element.io/roles/elementdeployment/ 17 | COPY roles/teardown /element.io/roles/teardown/ 18 | COPY roles/generic_apply /element.io/roles/generic_apply/ 19 | COPY playbooks/elementdeployment.yml playbooks/any.yml /element.io/playbooks/ 20 | 21 | USER 0 22 | RUN chmod -R 0755 /element.io 23 | 24 | USER 32001 25 | -------------------------------------------------------------------------------- /LICENSES/updater/MIT.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | include common.mk 6 | 7 | .PHONY: all 8 | all: buildah-build 9 | 10 | build-helm-charts: 11 | cd helm/operator && BASE_CRD_KUSTOMIZE_TARGET=config/crd/cleanup/starter-core bash build.sh 12 | cd helm/updater && ELEMENT_DEPLOYMENT_KUSTOMIZE_TARGET=config/crd/element-deployment/cleanup/starter-core bash build.sh 13 | 14 | .PHONY: build-crds 15 | build-crds: kustomize 16 | mkdir -p ${ARTIFACT_DIR} 17 | $(KUSTOMIZE) build config/crd/cleanup/starter-core | sed '/x-ui/d' > ${ARTIFACT_DIR}/crds.yml 18 | 19 | .PHONY: build-crds-ui 20 | build-crds-ui: kustomize 21 | mkdir -p ${ARTIFACT_DIR} 22 | $(KUSTOMIZE) build config/crd/element-deployment/cleanup/starter-core -o ${ARTIFACT_DIR}/crds-ui.yml 23 | 24 | .PHONY: build-all-crds 25 | build-all-crds: build-crds build-crds-ui 26 | 27 | .PHONY: buildah-build 28 | buildah-build: ## Build docker image with the manager. 29 | buildah bud -t operator 30 | buildah bud -t operator-conversion-webhook -f Dockerfile.operator conversion/ 31 | buildah bud -t updater -f Dockerfile.updater 32 | buildah bud -t updater-conversion-webhook -f Dockerfile.updater conversion/ 33 | 34 | .PHONY: local-build 35 | local-build: 36 | docker buildx build --load --metadata-file operator-metadata.json -t operator . 37 | docker buildx build --metadata-file updater-metadata.json --load -t updater -f Dockerfile.updater . 38 | -------------------------------------------------------------------------------- /common.mk: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | # VERSION defines the project version for the bundle. 6 | # Update this value when you upgrade the version of your project. 7 | # To re-generate a bundle for another specific version without changing the standard setup, you can: 8 | # - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) 9 | # - use environment variables to overwrite this value (e.g export VERSION=0.0.2) 10 | ARTIFACT_DIR = ./build 11 | 12 | .PHONY: kustomize 13 | KUSTOMIZE = $(shell pwd)/bin/kustomize 14 | kustomize: ## Download kustomize locally if necessary. 15 | ifeq (,$(wildcard $(KUSTOMIZE))) 16 | ifeq (,$(shell which kustomize 2>/dev/null)) 17 | @{ \ 18 | set -e ;\ 19 | mkdir -p $(dir $(KUSTOMIZE)) ;\ 20 | curl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v4.5.7/kustomize_v4.5.7_$(OS)_$(ARCH).tar.gz | \ 21 | tar xzf - -C bin/ ;\ 22 | } 23 | else 24 | KUSTOMIZE = $(shell which kustomize) 25 | endif 26 | endif 27 | -------------------------------------------------------------------------------- /config/common-rbac/auth_proxy_client_clusterrole.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: rbac.authorization.k8s.io/v1 7 | kind: ClusterRole 8 | metadata: 9 | name: metrics-reader 10 | rules: 11 | - nonResourceURLs: 12 | - "/metrics" 13 | verbs: 14 | - get 15 | -------------------------------------------------------------------------------- /config/common-rbac/auth_proxy_role.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: rbac.authorization.k8s.io/v1 7 | kind: ClusterRole 8 | metadata: 9 | name: proxy 10 | rules: 11 | - apiGroups: 12 | - authentication.k8s.io 13 | resources: 14 | - tokenreviews 15 | verbs: 16 | - create 17 | - apiGroups: 18 | - authorization.k8s.io 19 | resources: 20 | - subjectaccessreviews 21 | verbs: 22 | - create 23 | -------------------------------------------------------------------------------- /config/common-rbac/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | resources: 7 | # All RBAC will be applied under this service account in 8 | # the deployment namespace. You may comment out this resource 9 | # if your manager will use a service account that exists at 10 | # runtime. Be sure to update RoleBinding and ClusterRoleBinding 11 | # subjects if changing service account names. 12 | - leader_election_role.yaml 13 | # Comment the following 4 lines if you want to disable 14 | # the auth proxy (https://github.com/brancz/kube-rbac-proxy) 15 | # which protects your /metrics endpoint. 16 | - auth_proxy_role.yaml 17 | - auth_proxy_client_clusterrole.yaml 18 | -------------------------------------------------------------------------------- /config/common-rbac/leader_election_role.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | # permissions to do leader election. 7 | apiVersion: rbac.authorization.k8s.io/v1 8 | kind: Role 9 | metadata: 10 | name: leader-election 11 | rules: 12 | - apiGroups: 13 | - "" 14 | resources: 15 | - configmaps 16 | verbs: 17 | - get 18 | - list 19 | - watch 20 | - create 21 | - update 22 | - patch 23 | - delete 24 | - apiGroups: 25 | - coordination.k8s.io 26 | resources: 27 | - leases 28 | verbs: 29 | - get 30 | - list 31 | - watch 32 | - create 33 | - update 34 | - patch 35 | - delete 36 | - apiGroups: 37 | - "" 38 | resources: 39 | - events 40 | verbs: 41 | - create 42 | - patch 43 | -------------------------------------------------------------------------------- /config/crd/bases/starter-core/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | resources: 7 | - matrix.element.io_elementwebs.yaml 8 | - matrix.element.io_synapses.yaml 9 | - matrix.element.io_wellknowndelegations.yaml 10 | -------------------------------------------------------------------------------- /config/crd/default-resources/starter-core/default-resources.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | kind: KustomizeSchema 6 | metadata: 7 | name: default-resources-starter-core 8 | spec: 9 | schemas: 10 | elementWeb: 11 | limits: 12 | memory: 200Mi 13 | requests: 14 | cpu: 50m 15 | memory: 50Mi 16 | synapse: 17 | haproxy: 18 | limits: 19 | memory: 200Mi 20 | requests: 21 | cpu: 100m 22 | memory: 100Mi 23 | redis: 24 | limits: 25 | memory: 50Mi 26 | requests: 27 | cpu: 50m 28 | memory: 50Mi 29 | synapse: 30 | limits: 31 | memory: 4Gi 32 | requests: 33 | cpu: 100m 34 | memory: 100Mi 35 | workers: 36 | limits: 37 | memory: 4Gi 38 | requests: 39 | cpu: 100m 40 | memory: 100Mi 41 | wellKnownDelegation: 42 | limits: 43 | memory: 200Mi 44 | requests: 45 | cpu: 50m 46 | memory: 50Mi 47 | -------------------------------------------------------------------------------- /config/crd/default-resources/starter-core/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: kustomize.config.k8s.io/v1beta1 7 | kind: Kustomization 8 | metadata: 9 | name: default-resources-starter-core 10 | resources: 11 | - ./default-resources.yaml 12 | -------------------------------------------------------------------------------- /config/crd/deprecated-patches/starter-core/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | resources: 7 | - ../../deprecated-replacements/starter-core 8 | -------------------------------------------------------------------------------- /config/crd/deprecated-replacements/starter-core/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | resources: 7 | - ../../patches/starter-core 8 | # Inject old versions 9 | replacements: 10 | - source: 11 | kind: CustomResourceDefinition 12 | name: synapses.matrix.element.io 13 | fieldPath: spec.versions.0.schema.openAPIV3Schema.properties.spec 14 | targets: 15 | - select: 16 | kind: CustomResourceDefinition 17 | name: synapses.matrix.element.io 18 | fieldPaths: 19 | - spec.versions.1.schema.openAPIV3Schema.properties.spec 20 | -------------------------------------------------------------------------------- /config/crd/element-deployment/base/common/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: kustomize.config.k8s.io/v1beta1 7 | kind: Kustomization 8 | resources: 9 | - matrix.element.io_elementdeployments.yaml 10 | -------------------------------------------------------------------------------- /config/crd/element-deployment/base/starter-core/element_web.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | - op: add 7 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/components/properties/elementWeb' 8 | value: 9 | type: object 10 | description: This is the user interface used by desktops to access Matrix rooms. 11 | properties: 12 | secretName: 13 | default: element-web 14 | type: string 15 | description: The secret data associated to synapse config If ingress is tls mode is using certificate, key matching `k8s.ingress.certificate.certFileSecretKey` and `k8s.ingress.certificate.privateKeySecretKey` must be present 16 | pattern: ^[a-z0-9]([\-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([\-a-z0-9]*[a-z0-9])?)*$ 17 | maxLength: 253 18 | config: 19 | description: This field will be replaced by kustomize 20 | k8s: 21 | type: object 22 | description: You can override Kubernetes configuration for each component of Element Web 23 | default: {} 24 | properties: 25 | ingress: 26 | description: This field will be replaced by kustomize 27 | common: 28 | description: This field will be replaced by kustomize 29 | workloads: 30 | description: This field will be replaced by kustomize 31 | -------------------------------------------------------------------------------- /config/crd/element-deployment/base/starter-core/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: kustomize.config.k8s.io/v1beta1 7 | kind: Kustomization 8 | resources: 9 | - ../common 10 | patches: 11 | - path: element_web.yaml 12 | target: 13 | kind: CustomResourceDefinition 14 | name: elementdeployments.matrix.element.io 15 | - path: synapse.yaml 16 | target: 17 | kind: CustomResourceDefinition 18 | name: elementdeployments.matrix.element.io 19 | - path: well_known_delegation.yaml 20 | target: 21 | kind: CustomResourceDefinition 22 | name: elementdeployments.matrix.element.io 23 | -------------------------------------------------------------------------------- /config/crd/element-deployment/base/starter-core/well_known_delegation.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | - op: add 7 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/components/properties/wellKnownDelegation' 8 | value: 9 | type: object 10 | description: This is a well known delegation file hosted as a static site. 11 | properties: 12 | secretName: 13 | default: well-known-delegation 14 | type: string 15 | description: The secret data associated to wellKnownDelegation config If ingress is tls mode is using certificate, key matching `k8s.ingress.certificate.certFileSecretKey` and `k8s.ingress.certificate.privateKeySecretKey` must be present 16 | pattern: ^[a-z0-9]([\-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([\-a-z0-9]*[a-z0-9])?)*$ 17 | maxLength: 253 18 | config: 19 | description: This field will be replaced by kustomize 20 | k8s: 21 | type: object 22 | description: You can override Kubernetes configuration for each component of WellKnownDelegation 23 | default: {} 24 | properties: 25 | ingress: 26 | description: This field will be replaced by kustomize 27 | common: 28 | description: This field will be replaced by kustomize 29 | workloads: 30 | description: This field will be replaced by kustomize 31 | -------------------------------------------------------------------------------- /config/crd/element-deployment/cleanup/starter-core/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | # This kustomization.yaml is not intended to be run by itself, 7 | # since it depends on service name and namespace that are out of this kustomize package. 8 | # It should be run by config/default 9 | resources: 10 | - ../../deprecated-patches/starter-core 11 | patches: 12 | - |- 13 | kind: KustomizeSchema 14 | metadata: 15 | name: default-resources-starter-core 16 | $patch: delete 17 | - |- 18 | kind: KustomizeSchema 19 | metadata: 20 | name: elementWeb 21 | $patch: delete 22 | - |- 23 | kind: KustomizeSchema 24 | metadata: 25 | name: synapse 26 | $patch: delete 27 | - |- 28 | kind: KustomizeSchema 29 | metadata: 30 | name: wellKnownDelegation 31 | $patch: delete 32 | # common to cleanup 33 | - |- 34 | kind: KustomizeSchema 35 | metadata: 36 | name: global 37 | $patch: delete 38 | - |- 39 | kind: KustomizeSchema 40 | metadata: 41 | name: k8s-common 42 | $patch: delete 43 | - |- 44 | kind: KustomizeSchema 45 | metadata: 46 | name: k8s-ingresses 47 | $patch: delete 48 | - |- 49 | kind: KustomizeSchema 50 | metadata: 51 | name: k8s-monitoring 52 | $patch: delete 53 | - |- 54 | kind: KustomizeSchema 55 | metadata: 56 | name: k8s-storage 57 | $patch: delete 58 | - |- 59 | kind: KustomizeSchema 60 | metadata: 61 | name: k8s-workloads 62 | $patch: delete 63 | - |- 64 | kind: KustomizeSchema 65 | metadata: 66 | name: k8s-workloads-resources 67 | $patch: delete 68 | - |- 69 | kind: KustomizeSchema 70 | metadata: 71 | name: postgres-libpq 72 | $patch: delete 73 | -------------------------------------------------------------------------------- /config/crd/element-deployment/deprecated-patches/starter-core/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | resources: 7 | - ../../deprecated-replacements/starter-core 8 | # Make old version properties consistent for round-trip conversions to work properly 9 | # Compatible properties get added to all CRD versions 10 | # Incompatible properties rely on annotations via the conversion webhook 11 | replacements: 12 | - source: 13 | kind: CustomResourceDefinition 14 | name: elementdeployments.matrix.element.io 15 | fieldPath: spec.versions.0.schema.openAPIV3Schema.properties.spec 16 | targets: 17 | - select: 18 | kind: CustomResourceDefinition 19 | name: elementdeployments.matrix.element.io 20 | fieldPaths: 21 | - spec.versions.1.schema.openAPIV3Schema.properties.spec 22 | -------------------------------------------------------------------------------- /config/crd/element-deployment/deprecated-patches/starter/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | resources: 7 | - ../../deprecated-replacements/starter 8 | # Make old version properties consistent for round-trip conversions to work properly 9 | # Compatible properties get added to all CRD versions 10 | # Incompatible properties rely on annotations via the conversion webhook 11 | replacements: 12 | - source: 13 | kind: CustomResourceDefinition 14 | name: elementdeployments.matrix.element.io 15 | fieldPath: spec.versions.0.schema.openAPIV3Schema.properties.spec 16 | targets: 17 | - select: 18 | kind: CustomResourceDefinition 19 | name: elementdeployments.matrix.element.io 20 | fieldPaths: 21 | - spec.versions.1.schema.openAPIV3Schema.properties.spec 22 | -------------------------------------------------------------------------------- /config/crd/element-deployment/deprecated-replacements/starter-core/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | resources: 7 | - ../../inline-patches/starter-core 8 | # Make old version properties consistent for round-trip conversions to work properly 9 | # Compatible properties get added to all CRD versions 10 | # Incompatible properties rely on annotations via the conversion webhook 11 | replacements: 12 | - source: 13 | kind: CustomResourceDefinition 14 | name: elementdeployments.matrix.element.io 15 | fieldPath: spec.versions.0.schema.openAPIV3Schema.properties.spec 16 | targets: 17 | - select: 18 | kind: CustomResourceDefinition 19 | name: elementdeployments.matrix.element.io 20 | fieldPaths: 21 | - spec.versions.1.schema.openAPIV3Schema.properties.spec 22 | -------------------------------------------------------------------------------- /config/crd/element-deployment/deprecated-replacements/starter/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | resources: 7 | - ../../inline-patches/starter 8 | # Make old version properties consistent for round-trip conversions to work properly 9 | # Compatible properties get added to all CRD versions 10 | # Incompatible properties rely on annotations via the conversion webhook 11 | replacements: 12 | - source: 13 | kind: CustomResourceDefinition 14 | name: elementdeployments.matrix.element.io 15 | fieldPath: spec.versions.0.schema.openAPIV3Schema.properties.spec 16 | targets: 17 | - select: 18 | kind: CustomResourceDefinition 19 | name: elementdeployments.matrix.element.io 20 | fieldPaths: 21 | - spec.versions.1.schema.openAPIV3Schema.properties.spec 22 | -------------------------------------------------------------------------------- /config/crd/element-deployment/inline-patches/starter-core/clean-global-k8s.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | - op: remove 7 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/global/properties/k8s/properties/workloads/properties/resources' 8 | - op: remove 9 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/global/properties/k8s/properties/workloads/properties/securityContext/properties/runAsUser' 10 | - op: remove 11 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/global/properties/k8s/properties/workloads/properties/securityContext/properties/fsGroup' 12 | - op: remove 13 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/global/properties/k8s/properties/ingresses/properties/fqdn' 14 | - op: remove 15 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/global/properties/k8s/properties/ingresses/required' 16 | - op: add 17 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/global/properties/k8s/properties/ingresses/default' 18 | value: {} 19 | - op: add 20 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/global/properties/k8s/properties/workloads/properties/replicas' 21 | value: 22 | type: number 23 | description: The number of replicas for workloads supporting it 24 | default: 2 25 | -------------------------------------------------------------------------------- /config/crd/element-deployment/inline-patches/starter-core/defaults-global-k8s.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | - op: add 7 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/global/properties/k8s/properties/monitoring/properties/serviceMonitor/properties/deploy/default' 8 | value: auto 9 | - op: add 10 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/global/properties/k8s/properties/workloads/properties/securityContext/properties/forceUidGid/default' 11 | value: enable 12 | - op: add 13 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/global/properties/k8s/properties/workloads/properties/securityContext/properties/setSecComp/default' 14 | value: enable 15 | - op: add 16 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/global/properties/k8s/properties/workloads/properties/hostAliases/default' 17 | value: [] 18 | - op: add 19 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/global/properties/k8s/properties/ingresses/properties/services/properties/type/default' 20 | value: ClusterIP 21 | - op: add 22 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/global/properties/k8s/properties/workloads/properties/replicas' 23 | value: 24 | type: number 25 | description: The number of replicas for workloads supporting it 26 | minimum: 1 27 | default: 2 28 | -------------------------------------------------------------------------------- /config/crd/element-deployment/inline-patches/starter-core/descriptions.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | - op: replace 7 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/global/properties/k8s/properties/ingresses/properties/tls/properties/certificate/description' 8 | value: The default certificate for every ingresses can be configured here. It can be used for example if you plan to use a wildcard certificate, or a certificate containing all components fqdns as SAN. 9 | - op: replace 10 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/global/properties/k8s/properties/ingresses/properties/tls/properties/mode/description' 11 | value: The default TLS mode of deployed ingresses. Use external if TLS is managed externaly to the cluster, certmanager if you want to use cert manager to issue certificate automatically, or certfile if you want to upload certificate files to kubernetes tls secrets manually. 12 | - op: replace 13 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/components/properties/synapse/properties/k8s/properties/common/description' 14 | value: The annotations to add to every workloads, volume claims and service monitors deployed 15 | -------------------------------------------------------------------------------- /config/crd/element-deployment/inline-patches/starter-core/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | # This kustomization.yaml is not intended to be run by itself, 7 | # since it depends on service name and namespace that are out of this kustomize package. 8 | # It should be run by config/default 9 | resources: 10 | - ../../replacements/starter-core 11 | patches: 12 | - path: descriptions.yaml 13 | target: 14 | kind: CustomResourceDefinition 15 | name: elementdeployments.matrix.element.io 16 | - path: uids-gids.yaml 17 | target: 18 | kind: CustomResourceDefinition 19 | name: elementdeployments.matrix.element.io 20 | - path: certificates-keys.yaml 21 | target: 22 | kind: CustomResourceDefinition 23 | name: elementdeployments.matrix.element.io 24 | - path: replicas.yaml 25 | target: 26 | kind: CustomResourceDefinition 27 | name: elementdeployments.matrix.element.io 28 | - path: wellknowndelegation-no-fqdn.yaml 29 | target: 30 | kind: CustomResourceDefinition 31 | name: elementdeployments.matrix.element.io 32 | - path: synapse-op-del-k8s-synapse-storage-volume.yaml 33 | target: 34 | kind: CustomResourceDefinition 35 | name: elementdeployments.matrix.element.io 36 | - path: clean-global-k8s.yaml 37 | target: 38 | kind: CustomResourceDefinition 39 | name: elementdeployments.matrix.element.io 40 | - path: defaults-global-k8s.yaml 41 | target: 42 | kind: CustomResourceDefinition 43 | name: elementdeployments.matrix.element.io 44 | - path: descriptions.yaml 45 | target: 46 | kind: CustomResourceDefinition 47 | name: elementdeployments.matrix.element.io 48 | - path: certificates-keys.yaml 49 | target: 50 | kind: CustomResourceDefinition 51 | name: elementdeployments.matrix.element.io 52 | -------------------------------------------------------------------------------- /config/crd/element-deployment/inline-patches/starter-core/replicas.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | - op: add 7 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/components/properties/elementWeb/properties/k8s/properties/workloads/properties/replicas' 8 | value: 9 | type: number 10 | description: The number of Element Web replicas 11 | minimum: 1 12 | - op: add 13 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/components/properties/synapse/properties/k8s/properties/haproxy/properties/workloads/properties/replicas' 14 | value: 15 | type: number 16 | description: The number of Synapse HAProxy replicas 17 | minimum: 1 18 | - op: add 19 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/components/properties/wellKnownDelegation/properties/k8s/properties/workloads/properties/replicas' 20 | value: 21 | type: number 22 | description: The number of Well-Known Delegation replicas 23 | minimum: 1 24 | -------------------------------------------------------------------------------- /config/crd/element-deployment/inline-patches/starter-core/synapse-op-del-k8s-synapse-storage-volume.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | # Synapse is has not been migrated yet to volume names and size being handled under the k8s key 7 | # Nuke out everything but storage.volume.storageClassName which is used 8 | - op: remove 9 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/components/properties/synapse/properties/k8s/properties/synapse/properties/storage/default' 10 | - op: remove 11 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/components/properties/synapse/properties/k8s/properties/synapse/properties/storage/properties/volume/default' 12 | - op: remove 13 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/components/properties/synapse/properties/k8s/properties/synapse/properties/storage/properties/volume/oneOf' 14 | - op: remove 15 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/components/properties/synapse/properties/k8s/properties/synapse/properties/storage/properties/volume/properties/persistentVolumeClaimName' 16 | - op: remove 17 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/components/properties/synapse/properties/k8s/properties/synapse/properties/storage/properties/volume/properties/size' 18 | -------------------------------------------------------------------------------- /config/crd/element-deployment/inline-patches/starter-core/wellknowndelegation-no-fqdn.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | # Remove WellKnownDelegation ingress fqdn, its using global domain_name. 7 | # As there's no FQDN there's no need for an ingress object so we might not have annotations set 8 | - op: remove 9 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/components/properties/wellKnownDelegation/properties/k8s/properties/ingress/properties/fqdn' 10 | - op: remove 11 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/components/properties/wellKnownDelegation/properties/k8s/properties/ingress/required' 12 | - op: add 13 | path: '/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/components/properties/wellKnownDelegation/properties/k8s/properties/ingress/default' 14 | value: {} 15 | -------------------------------------------------------------------------------- /config/crd/element-deployment/replacements/starter-core/element_web.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | kind: KustomizeSchema 7 | metadata: 8 | name: elementWeb 9 | spec: 10 | schema: 11 | type: object 12 | default: {} 13 | properties: 14 | additionalConfig: 15 | type: string 16 | description: Element web additional configuration. 17 | -------------------------------------------------------------------------------- /config/crd/element-deployment/replacements/starter-core/global.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | kind: KustomizeSchema 7 | metadata: 8 | name: global 9 | spec: 10 | schema: 11 | type: object 12 | required: 13 | - domainName 14 | properties: 15 | domainName: 16 | type: string 17 | description: The domain name of this deployment. It will be used for the of the users MXIDs, and cannot be changed afterwards 18 | genericSharedSecretSecretKey: 19 | type: string 20 | default: genericSharedSecret 21 | description: The generic shared secret to use as a seed for all internally-generated secrets 22 | verifyTls: 23 | type: boolean 24 | description: TLS verification 25 | default: true 26 | imagesDigestsConfigMap: 27 | type: string 28 | description: A configmap containing images digests metadata to override 29 | -------------------------------------------------------------------------------- /config/crd/element-deployment/replacements/starter-core/k8s-common.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | kind: KustomizeSchema 7 | metadata: 8 | name: k8s-common 9 | spec: 10 | schema: 11 | type: object 12 | default: {} 13 | description: Settings dedicated to k8s 14 | properties: 15 | annotations: 16 | description: The annotations to add to every workloads and ingresses deployed 17 | type: object 18 | default: {} 19 | additionalProperties: 20 | description: Defines the annotations to add 21 | type: string 22 | -------------------------------------------------------------------------------- /config/crd/element-deployment/replacements/starter-core/k8s-monitoring.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | kind: KustomizeSchema 7 | metadata: 8 | name: k8s-monitoring 9 | spec: 10 | schema: 11 | type: object 12 | default: {} 13 | description: Settings dedicated to monitoring 14 | properties: 15 | serviceMonitor: 16 | type: object 17 | default: {} 18 | description: Service monitor settings 19 | properties: 20 | deploy: 21 | description: Enable or disable monitoring using ServiceMonitor resources 22 | type: string 23 | default: auto 24 | enum: 25 | - enable 26 | - disable 27 | - auto 28 | -------------------------------------------------------------------------------- /config/crd/element-deployment/replacements/starter-core/k8s-storage.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | kind: KustomizeSchema 7 | metadata: 8 | name: k8s-storage 9 | spec: 10 | schema: 11 | type: object 12 | default: 13 | volume: 14 | size: This field will be replaced by kustomize 15 | description: Settings dedicated to k8s storage 16 | properties: 17 | volume: 18 | type: object 19 | default: 20 | size: This field will be replaced by kustomize 21 | oneOf: 22 | - required: [size] 23 | not: 24 | required: [persistentVolumeClaimName] 25 | - required: [persistentVolumeClaimName] 26 | not: 27 | required: [size] 28 | properties: 29 | persistentVolumeClaimName: 30 | type: string 31 | description: The persistent volume claim name to use to store the media 32 | size: 33 | anyOf: 34 | - type: integer 35 | - type: string 36 | pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[MGTPE])?$ 37 | x-kubernetes-int-or-string: true 38 | description: The volume size to use to store the media 39 | storageClassName: 40 | type: string 41 | description: The storage class name to use 42 | -------------------------------------------------------------------------------- /config/crd/element-deployment/replacements/starter-core/k8s-workloads-resources.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | kind: KustomizeSchema 7 | metadata: 8 | name: k8s-workloads-resources 9 | spec: 10 | schema: 11 | description: Kubernetes resources to allocate to each instance. 12 | type: object 13 | default: {} 14 | properties: 15 | limits: 16 | default: 17 | description: This will be replaced by kustomize 18 | additionalProperties: 19 | anyOf: 20 | - type: integer 21 | - type: string 22 | pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ 23 | x-kubernetes-int-or-string: true 24 | description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' 25 | type: object 26 | requests: 27 | default: 28 | description: This will be replaced by kustomize 29 | additionalProperties: 30 | anyOf: 31 | - type: integer 32 | - type: string 33 | pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ 34 | x-kubernetes-int-or-string: true 35 | description: 'Requests describes the minimum amount of compute resources required. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' 36 | type: object 37 | -------------------------------------------------------------------------------- /config/crd/element-deployment/replacements/starter-core/postgres-libpq.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | kind: KustomizeSchema 7 | metadata: 8 | name: postgres-libpq 9 | spec: 10 | schema: 11 | description: Configuration of the PostgreSQL database 12 | type: object 13 | required: 14 | - host 15 | - user 16 | - database 17 | properties: 18 | host: 19 | description: PostgreSQL database host 20 | type: string 21 | port: 22 | description: PostgreSQL port 23 | type: integer 24 | default: 5432 25 | minimum: 0 26 | maximum: 65535 27 | user: 28 | description: PostgreSQL username 29 | type: string 30 | database: 31 | description: PostgreSQL database name 32 | type: string 33 | sslMode: 34 | description: TLS settings to use for the PostgreSQL connection 35 | type: string 36 | default: require 37 | enum: 38 | - disable 39 | - allow 40 | - prefer 41 | - require 42 | - verify-ca 43 | - verify-full 44 | passwordSecretKey: 45 | type: string 46 | description: The PostgreSQL password 47 | default: postgresPassword 48 | -------------------------------------------------------------------------------- /config/crd/element-deployment/replacements/starter-core/well_known_delegation.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | kind: KustomizeSchema 7 | metadata: 8 | name: wellKnownDelegation 9 | spec: 10 | schema: 11 | type: object 12 | default: {} 13 | properties: 14 | additionalElementConfig: 15 | type: string 16 | description: WellKnownDelegation additional element configuration. 17 | additionalClientConfig: 18 | type: string 19 | description: WellKnownDelegation additional client configuration. 20 | additionalServerConfig: 21 | type: string 22 | description: WellKnownDelegation additional server configuration. 23 | -------------------------------------------------------------------------------- /config/crd/patches/starter-core/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | resources: 7 | - ../../replacements/starter-core 8 | patches: 9 | - target: 10 | kind: CustomResourceDefinition 11 | name: synapses.matrix.element.io 12 | path: synapse-add-external-ingress-path.yaml 13 | # Remove extraEnv from workloads that couldn't possibly benefit from it 14 | # These are all Nginx's, HAProxies or Redis 15 | - target: 16 | kind: CustomResourceDefinition 17 | name: (elementweb|wellknowndelegation)s.matrix.element.io 18 | patch: |- 19 | - op: remove 20 | path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/workloads/properties/extraEnv 21 | - target: 22 | kind: CustomResourceDefinition 23 | name: synapses.matrix.element.io 24 | patch: |- 25 | - op: remove 26 | path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/workloads/properties/haproxy/properties/extraEnv 27 | - op: remove 28 | path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/workloads/properties/redis/properties/extraEnv 29 | - target: 30 | kind: CustomResourceDefinition 31 | name: livekits.matrix.element.io 32 | patch: |- 33 | - op: remove 34 | path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/workloads/properties/redis/properties/extraEnv 35 | -------------------------------------------------------------------------------- /config/crd/replacements/common/host-aliases.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | kind: KustomizeSchema 7 | metadata: 8 | name: host-aliases 9 | spec: 10 | schema: 11 | type: array 12 | description: The list of hosts aliases to configure on the pod spec. It should be avoid as much as possible to use this feature. Please prefer using an DNS entry to resolve your hostnames. This can be used as a workaround when entries cannot be resolved using DNS, for example for our automated testings. 13 | items: 14 | type: object 15 | properties: 16 | ip: 17 | description: An IP resolution to add to /etc/hosts 18 | type: string 19 | hostnames: 20 | type: array 21 | items: 22 | type: string 23 | description: An hostname of the associated ip to add to /etc/hosts 24 | -------------------------------------------------------------------------------- /config/crd/replacements/common/image.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | kind: KustomizeSchema 7 | metadata: 8 | name: image 9 | spec: 10 | schema: 11 | description: Defines the image to be used 12 | type: object 13 | properties: 14 | pullSecrets: 15 | description: Pull secrets to make available for any of the images below 16 | type: array 17 | items: 18 | type: object 19 | properties: 20 | name: 21 | description: The name of the image pull secret in this namespace to use 22 | type: string 23 | repository: 24 | description: Image repository to use 25 | type: string 26 | tag: 27 | description: Image tag in the repository to use 28 | type: string 29 | digest: 30 | description: Image digest. If defined, this will be used instead of image tag. Image tag is still mandatory to render annotations on the statefulsets and deployments. 31 | type: string 32 | pullPolicy: 33 | description: Image pull policy 34 | type: string 35 | enum: 36 | - Always 37 | - IfNotPresent 38 | - Never 39 | -------------------------------------------------------------------------------- /config/crd/replacements/common/ingress.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | kind: KustomizeSchema 7 | metadata: 8 | name: ingress 9 | spec: 10 | schema: 11 | description: Defines how to access this resource 12 | type: object 13 | properties: 14 | domainName: 15 | description: What domain name to create this ingress at 16 | type: string 17 | annotations: 18 | description: Defines the annotations to add to the ingress object 19 | type: object 20 | additionalProperties: 21 | type: string 22 | tlsSecret: 23 | description: An optional TLS secret to be used to secure this ingress with. Optional as if used in OpenShift the default Router certificates can be used 24 | type: string 25 | ingressClassName: 26 | description: An optional IngressClass name to be used for this ingress. Optional if you are managing ingress / loadbalancer external to the operator. 27 | type: string 28 | -------------------------------------------------------------------------------- /config/crd/replacements/common/k8s-workloads-resources.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | kind: KustomizeSchema 7 | metadata: 8 | name: k8s-workloads-resources 9 | spec: 10 | schema: 11 | description: Kubernetes resources to allocate to each instance. 12 | type: object 13 | default: {} 14 | properties: 15 | limits: 16 | default: 17 | description: This will be replaced by kustomize 18 | additionalProperties: 19 | anyOf: 20 | - type: integer 21 | - type: string 22 | pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ 23 | x-kubernetes-int-or-string: true 24 | description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' 25 | type: object 26 | requests: 27 | default: 28 | description: This will be replaced by kustomize 29 | additionalProperties: 30 | anyOf: 31 | - type: integer 32 | - type: string 33 | pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ 34 | x-kubernetes-int-or-string: true 35 | description: 'Requests describes the minimum amount of compute resources required. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' 36 | type: object 37 | -------------------------------------------------------------------------------- /config/crd/replacements/common/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: kustomize.config.k8s.io/v1beta1 7 | kind: Kustomization 8 | metadata: 9 | name: replacements-common 10 | resources: 11 | - containers-security-context.yaml 12 | - host-aliases.yaml 13 | - image.yaml 14 | - ingress.yaml 15 | - kustomization.yaml 16 | - matrix-server.yaml 17 | - pods-security-context.yaml 18 | - postgres-golang.yaml 19 | - postgres-libpq.yaml 20 | - service.yaml 21 | - workloads.yaml 22 | - k8s-workloads-resources.yaml 23 | -------------------------------------------------------------------------------- /config/crd/replacements/common/matrix-server.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | kind: KustomizeSchema 7 | metadata: 8 | name: matrix-server 9 | spec: 10 | schema: 11 | description: Defines which Matrix server this component should point at. 12 | type: object 13 | properties: 14 | baseUrl: 15 | description: Domain name where the Matrix server is hosted 16 | type: string 17 | serverName: 18 | description: Server name of the default Matrix server (if distinct from the baseUrl) 19 | type: string 20 | -------------------------------------------------------------------------------- /config/crd/replacements/common/postgres-golang.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | kind: KustomizeSchema 7 | metadata: 8 | name: postgres-golang 9 | spec: 10 | schema: 11 | description: Configuration of the PostgreSQL database 12 | type: object 13 | required: 14 | - host 15 | - user 16 | - name 17 | properties: 18 | host: 19 | description: Database host to connect to 20 | type: string 21 | port: 22 | description: Port to connect to 23 | type: integer 24 | default: 5432 25 | minimum: 0 26 | maximum: 65535 27 | user: 28 | description: Username to use for auth 29 | type: string 30 | name: 31 | description: Database within the PostgreSQL instance to use 32 | type: string 33 | sslmode: 34 | description: TLS settings to use for the PostgreSQL connection 35 | type: string 36 | default: require 37 | enum: 38 | - disable 39 | - require 40 | - verify-ca 41 | - verify-full 42 | -------------------------------------------------------------------------------- /config/crd/replacements/common/postgres-libpq.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | kind: KustomizeSchema 7 | metadata: 8 | name: postgres-libpq 9 | spec: 10 | schema: 11 | description: Configuration of the PostgreSQL database 12 | type: object 13 | required: 14 | - host 15 | - user 16 | - name 17 | properties: 18 | host: 19 | description: Database host to connect to 20 | type: string 21 | port: 22 | description: Port to connect to 23 | type: integer 24 | default: 5432 25 | minimum: 0 26 | maximum: 65535 27 | user: 28 | description: Username to use for auth 29 | type: string 30 | name: 31 | description: Database within the PostgreSQL instance to use 32 | type: string 33 | sslmode: 34 | description: TLS settings to use for the PostgreSQL connection 35 | type: string 36 | default: prefer 37 | enum: 38 | - disable 39 | - allow 40 | - prefer 41 | - require 42 | - verify-ca 43 | - verify-full 44 | -------------------------------------------------------------------------------- /config/crd/replacements/common/service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | kind: KustomizeSchema 7 | metadata: 8 | name: service 9 | spec: 10 | schema: 11 | description: Describes the service created to expose this resource 12 | type: object 13 | properties: 14 | type: 15 | description: What type of service to create 16 | type: string 17 | enum: 18 | - ClusterIP 19 | - NodePort 20 | - LoadBalancer 21 | -------------------------------------------------------------------------------- /config/default/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | # Adds namespace to all resources. 7 | namespace: element-operator-system 8 | # Value of this field is prepended to the 9 | # names of all resources, e.g. a deployment named 10 | # "wordpress" becomes "alices-wordpress". 11 | # Note that it should also match with the prefix (text before '-') of the namespace 12 | # field above. 13 | namePrefix: element-operator- 14 | # Labels to add to all resources and selectors. 15 | #labels: 16 | #- includeSelectors: true 17 | # pairs: 18 | # someName: someValue 19 | resources: 20 | - ../common-rbac 21 | - ../rbac 22 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_role_binding.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: rbac.authorization.k8s.io/v1 7 | kind: ClusterRoleBinding 8 | metadata: 9 | name: proxy 10 | roleRef: 11 | apiGroup: rbac.authorization.k8s.io 12 | kind: ClusterRole 13 | name: proxy 14 | subjects: 15 | - kind: ServiceAccount 16 | name: controller-manager 17 | namespace: system 18 | -------------------------------------------------------------------------------- /config/rbac/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | resources: 7 | # All RBAC will be applied under this service account in 8 | # the deployment namespace. You may comment out this resource 9 | # if your manager will use a service account that exists at 10 | # runtime. Be sure to update RoleBinding and ClusterRoleBinding 11 | # subjects if changing service account names. 12 | - service_account.yaml 13 | - role_binding.yaml 14 | - leader_election_role_binding.yaml 15 | # Comment the following 4 lines if you want to disable 16 | # the auth proxy (https://github.com/brancz/kube-rbac-proxy) 17 | # which protects your /metrics endpoint. 18 | - auth_proxy_role_binding.yaml 19 | -------------------------------------------------------------------------------- /config/rbac/leader_election_role_binding.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: rbac.authorization.k8s.io/v1 7 | kind: RoleBinding 8 | metadata: 9 | name: leader-election 10 | roleRef: 11 | apiGroup: rbac.authorization.k8s.io 12 | kind: Role 13 | name: leader-election 14 | subjects: 15 | - kind: ServiceAccount 16 | name: controller-manager 17 | namespace: system 18 | -------------------------------------------------------------------------------- /config/rbac/role.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | # Stub file for operator-sdk create api --group matrix --version v1alpha1 --kind to work 7 | -------------------------------------------------------------------------------- /config/rbac/role_binding.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: rbac.authorization.k8s.io/v1 7 | kind: ClusterRoleBinding 8 | metadata: 9 | name: manager 10 | roleRef: 11 | apiGroup: rbac.authorization.k8s.io 12 | kind: ClusterRole 13 | name: manager 14 | subjects: 15 | - kind: ServiceAccount 16 | name: controller-manager 17 | namespace: system 18 | -------------------------------------------------------------------------------- /config/rbac/service_account.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: v1 7 | kind: ServiceAccount 8 | metadata: 9 | name: controller-manager 10 | namespace: system 11 | -------------------------------------------------------------------------------- /config/samples/matrix_v1alpha1_elementweb.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: matrix.element.io/v1alpha1 7 | kind: ElementWeb 8 | metadata: 9 | name: sample 10 | spec: 11 | image: 12 | tag: v1.9.2 13 | service: 14 | type: ClusterIP 15 | ingress: 16 | domainName: your-element.fdqn.tld 17 | annotations: 18 | route.openshift.io/termination: edge 19 | workloads: 20 | annotations: 21 | some.annotation.io/info: custom 22 | config: 23 | defaultMatrixServer: 24 | baseUrl: your-synapse.fqdn.tld 25 | serverName: fqdn.tld 26 | replicas: 1 27 | inject: 28 | origin: your-synapseadminui.fqdn.tld 29 | -------------------------------------------------------------------------------- /config/samples/matrix_v1alpha1_synapse.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: matrix.element.io/v1alpha2 7 | kind: Synapse 8 | metadata: 9 | name: sample 10 | spec: 11 | image: 12 | tag: latest 13 | haproxyTag: latest 14 | redisTag: latest 15 | ingress: 16 | domainName: matrix.fqdn.tld 17 | annotations: 18 | route.openshift.io/termination: edge 19 | service: 20 | type: ClusterIP 21 | config: 22 | externalSecret: 23 | name: synapse-secrets 24 | serverName: fqdn.tld 25 | database: 26 | host: postgres 27 | user: synapse_user 28 | name: synapse 29 | media: 30 | volumeClaim: synapse-media 31 | registration: open 32 | -------------------------------------------------------------------------------- /config/samples/matrix_v1alpha1_wellknowndelegation.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: matrix.element.io/v1alpha1 7 | kind: WellKnownDelegation 8 | metadata: 9 | name: sample 10 | spec: 11 | image: 12 | tag: stable-alpine 13 | ingress: 14 | domainName: fdqn.tld 15 | annotations: 16 | route.openshift.io/termination: edge 17 | workloads: 18 | annotations: 19 | some.annotation.io/info: custom 20 | service: 21 | type: ClusterIP 22 | config: 23 | client: 24 | homeserverBaseUrl: https://your-synapse.fqdn.tld 25 | federation: 26 | endpoint: your-synapse.fqdn.tld:443 27 | replicas: 1 28 | podSecurityContext: 29 | supplementalGroups: [65534] 30 | -------------------------------------------------------------------------------- /config/updater/default/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | # Adds namespace to all resources. 7 | namespace: element-updater-system 8 | # Value of this field is prepended to the 9 | # names of all resources, e.g. a deployment named 10 | # "wordpress" becomes "alices-wordpress". 11 | # Note that it should also match with the prefix (text before '-') of the namespace 12 | # field above. 13 | namePrefix: element-updater- 14 | # Labels to add to all resources and selectors. 15 | #labels: 16 | #- includeSelectors: true 17 | # pairs: 18 | # someName: someValue 19 | resources: 20 | - ../../common-rbac 21 | - ../rbac 22 | -------------------------------------------------------------------------------- /config/updater/rbac/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | # Value of this field is prepended to the 7 | # names of all resources, e.g. a deployment named 8 | # "wordpress" becomes "alices-wordpress". 9 | # Note that it should also match with the prefix (text before '-') of the namespace 10 | # field above. 11 | 12 | resources: 13 | - ../../rbac 14 | -------------------------------------------------------------------------------- /conversion/Dockerfile.operator: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | FROM golang:1.21 AS buildstage 7 | 8 | WORKDIR /app 9 | COPY . /app 10 | RUN go mod download 11 | RUN CGO_ENABLED=0 go build -o /app/conversion-webhook cmd/operator/main.go 12 | RUN chmod 755 /app/conversion-webhook 13 | 14 | FROM gcr.io/distroless/static-debian12 15 | # Label this image with the repo and commit that built it, for freshmaking purposes. 16 | ARG GIT_COMMIT=devel 17 | LABEL git_commit=$GIT_COMMIT 18 | WORKDIR / 19 | 20 | COPY --from=buildstage /app/conversion-webhook / 21 | EXPOSE 8443 22 | ENTRYPOINT ["/conversion-webhook"] 23 | 24 | USER 30000 25 | -------------------------------------------------------------------------------- /conversion/Dockerfile.updater: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | FROM golang:1.21-bookworm AS buildstage 7 | 8 | WORKDIR /app 9 | COPY . /app 10 | RUN go mod download 11 | RUN CGO_ENABLED=0 go build -o /app/conversion-webhook cmd/updater/main.go 12 | RUN chmod 755 /app/conversion-webhook 13 | 14 | FROM gcr.io/distroless/static-debian12 15 | # Label this image with the repo and commit that built it, for freshmaking purposes. 16 | ARG GIT_COMMIT=devel 17 | LABEL git_commit=$GIT_COMMIT 18 | WORKDIR / 19 | 20 | COPY --from=buildstage /app/conversion-webhook / 21 | 22 | EXPOSE 8443 23 | ENTRYPOINT ["/conversion-webhook"] 24 | 25 | USER 30001 26 | -------------------------------------------------------------------------------- /conversion/go.sum.license: -------------------------------------------------------------------------------- 1 | Copyright 2023 New Vector Ltd 2 | 3 | SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | -------------------------------------------------------------------------------- /conversion/internal/pkg/converter/v1alpha1/processor.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023-2024 New Vector Ltd 2 | // 3 | // SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | package v1alpha1 7 | 8 | import ( 9 | 10 | "element.io/conversion-webhook/internal/pkg/converter/v1alpha1/starter" 11 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 12 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 13 | ) 14 | 15 | func Convert(Object *unstructured.Unstructured) (*unstructured.Unstructured, metav1.Status) { 16 | convertedObject := Object.DeepCopy() 17 | convertedObject.SetAPIVersion("matrix.element.io/v1alpha1") 18 | 19 | convertedObject, status := starter.Convert(convertedObject) 20 | 21 | return convertedObject, status 22 | } 23 | -------------------------------------------------------------------------------- /conversion/internal/pkg/converter/v1alpha1/starter/elementdeployment.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 New Vector Ltd 2 | // 3 | // SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | package starter 7 | 8 | import ( 9 | "element.io/conversion-webhook/internal/pkg/converter/kubernetes" 10 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 12 | ) 13 | 14 | func ConvertElementDeployment(convertedObject *unstructured.Unstructured) (*unstructured.Unstructured, metav1.Status) { 15 | return convertedObject, kubernetes.StatusSucceed() 16 | } 17 | -------------------------------------------------------------------------------- /conversion/internal/pkg/converter/v1alpha1/starter/processor.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 New Vector Ltd 2 | // 3 | // SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | package starter 7 | 8 | import ( 9 | "element.io/conversion-webhook/internal/pkg/converter/kubernetes" 10 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 12 | "k8s.io/klog" 13 | ) 14 | 15 | func Convert(Object *unstructured.Unstructured) (*unstructured.Unstructured, metav1.Status) { 16 | convertedObject := Object.DeepCopy() 17 | switch Object.Object["kind"] { 18 | case "Synapse": 19 | klog.Info("Downgrading starter Synapse ") 20 | return ConvertSynapse(convertedObject) 21 | case "ElementDeployment": 22 | klog.Info("Downgrading starter ElementDeployment ") 23 | return ConvertElementDeployment(convertedObject) 24 | default: 25 | return nil, kubernetes.StatusErrorWithMessage("unexpected kind conversion %q", Object.Object["kind"]) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /conversion/internal/pkg/converter/v1alpha1/starter/synapse.go: -------------------------------------------------------------------------------- 1 | // Copyright 2024 New Vector Ltd 2 | // 3 | // SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | package starter 7 | 8 | import ( 9 | "element.io/conversion-webhook/internal/pkg/converter/kubernetes" 10 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 12 | ) 13 | 14 | func ConvertSynapse(convertedObject *unstructured.Unstructured) (*unstructured.Unstructured, metav1.Status) { 15 | return convertedObject, kubernetes.StatusSucceed() 16 | } 17 | -------------------------------------------------------------------------------- /conversion/internal/pkg/converter/v1alpha2/processor.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023-2024 New Vector Ltd 2 | // 3 | // SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | package v1alpha2 7 | 8 | import ( 9 | 10 | "element.io/conversion-webhook/internal/pkg/converter/v1alpha2/starter" 11 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 12 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 13 | ) 14 | 15 | func Convert(Object *unstructured.Unstructured) (*unstructured.Unstructured, metav1.Status) { 16 | convertedObject := Object.DeepCopy() 17 | convertedObject.SetAPIVersion("matrix.element.io/v1alpha2") 18 | convertedObject, status := starter.Convert(convertedObject) 19 | return convertedObject, status 20 | } 21 | -------------------------------------------------------------------------------- /conversion/internal/pkg/converter/v1alpha2/starter/elementdeployment.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023 New Vector Ltd 2 | // 3 | // SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | package starter 7 | 8 | import ( 9 | "element.io/conversion-webhook/internal/pkg/converter/kubernetes" 10 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 12 | ) 13 | 14 | func ConvertElementDeployment(convertedObject *unstructured.Unstructured) (*unstructured.Unstructured, metav1.Status) { 15 | return convertedObject, kubernetes.StatusSucceed() 16 | } 17 | -------------------------------------------------------------------------------- /conversion/internal/pkg/converter/v1alpha2/starter/processor.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023-2024 New Vector Ltd 2 | // 3 | // SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | package starter 7 | 8 | import ( 9 | "element.io/conversion-webhook/internal/pkg/converter/kubernetes" 10 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 12 | "k8s.io/klog" 13 | ) 14 | 15 | func Convert(Object *unstructured.Unstructured) (*unstructured.Unstructured, metav1.Status) { 16 | convertedObject := Object.DeepCopy() 17 | switch Object.Object["kind"] { 18 | case "Synapse": 19 | klog.Info("Converting starter Synapse to v1alpha2") 20 | return ConvertSynapse(convertedObject) 21 | case "ElementDeployment": 22 | klog.Info("Converting starter ElementDeployment to v1alpha2") 23 | return ConvertElementDeployment(convertedObject) 24 | default: 25 | return nil, kubernetes.StatusErrorWithMessage("unexpected kind conversion %q", Object.Object["kind"]) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /conversion/internal/pkg/converter/v1alpha2/starter/synapse.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023 New Vector Ltd 2 | // 3 | // SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | package starter 7 | 8 | import ( 9 | "element.io/conversion-webhook/internal/pkg/converter/kubernetes" 10 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 12 | ) 13 | 14 | func ConvertSynapse(convertedObject *unstructured.Unstructured) (*unstructured.Unstructured, metav1.Status) { 15 | return convertedObject, kubernetes.StatusSucceed() 16 | } 17 | -------------------------------------------------------------------------------- /conversion/internal/pkg/operator/serve.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023 New Vector Ltd 2 | // 3 | // SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | package operator 7 | 8 | import ( 9 | "net/http" 10 | 11 | "element.io/conversion-webhook/internal/pkg/converter" 12 | "element.io/conversion-webhook/internal/pkg/converter/kubernetes" 13 | ) 14 | 15 | func ServeConvert(w http.ResponseWriter, r *http.Request) { 16 | kubernetes.Serve(w, r, converter.Process) 17 | } 18 | -------------------------------------------------------------------------------- /conversion/internal/pkg/updater/serve.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023 New Vector Ltd 2 | // 3 | // SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | package updater 7 | 8 | import ( 9 | "net/http" 10 | 11 | "element.io/conversion-webhook/internal/pkg/converter" 12 | "element.io/conversion-webhook/internal/pkg/converter/kubernetes" 13 | ) 14 | 15 | func ServeConvert(w http.ResponseWriter, r *http.Request) { 16 | kubernetes.Serve(w, r, converter.Process) 17 | } 18 | -------------------------------------------------------------------------------- /conversion/internal/pkg/webhook/config.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023 New Vector Ltd 2 | // 3 | // SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | package webhook 7 | 8 | import ( 9 | "crypto/tls" 10 | 11 | "k8s.io/client-go/kubernetes" 12 | "k8s.io/client-go/rest" 13 | "k8s.io/klog/v2" 14 | ) 15 | 16 | // Config contains the server (the webhook) cert and key. 17 | type Config struct { 18 | CertFile string 19 | KeyFile string 20 | } 21 | 22 | // Get a clientset with in-cluster config. 23 | func GetClient() *kubernetes.Clientset { 24 | config, err := rest.InClusterConfig() 25 | if err != nil { 26 | klog.Fatal(err) 27 | } 28 | clientset, err := kubernetes.NewForConfig(config) 29 | if err != nil { 30 | klog.Fatal(err) 31 | } 32 | return clientset 33 | } 34 | 35 | func ConfigTLS(config Config, clientset *kubernetes.Clientset) *tls.Config { 36 | sCert, err := tls.LoadX509KeyPair(config.CertFile, config.KeyFile) 37 | if err != nil { 38 | klog.Fatal(err) 39 | } 40 | return &tls.Config{ 41 | Certificates: []tls.Certificate{sCert}, 42 | // TODO: uses mutual tls after we agree on what cert the apiserver should use. 43 | // ClientAuth: tls.RequireAndVerifyClientCert, 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /helm/easy-setup/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2024 New Vector Ltd 4 | # 5 | # SPDX-License-Identifier: AGPL-3.0-or-later 6 | 7 | 8 | set -e 9 | 10 | values_files_args="" 11 | for arg in "$@" 12 | do 13 | values_files_args+=" -f values/values.${arg}.yaml" 14 | done 15 | 16 | if [[ -z "$ESS_SYSTEM_CHART" ]]; then 17 | ESS_SYSTEM_CHART="ess-starter-edition-core/ess-system" 18 | fi 19 | 20 | 21 | helm --kube-context kind-easy-setup upgrade ess-system $ESS_SYSTEM_CHART --install --create-namespace --namespace ess-system --wait -f values.ess-crds.yaml --version 2.21.1 22 | helm --kube-context kind-easy-setup upgrade ess ./ess-meta --install --create-namespace --namespace ess --wait -f values.ess-stack.yaml $values_files_args 23 | 24 | 25 | kubectl --context kind-easy-setup wait -n ess --timeout=10m --for=condition=Successful ElementDeployment ess 26 | -------------------------------------------------------------------------------- /helm/easy-setup/ess-meta/Chart.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: v2 7 | name: ess-meta 8 | description: A Helm chart to deploy ESS easily 9 | type: application 10 | version: 2.21.1 11 | appVersion: "2.21.1" 12 | dependencies: 13 | - name: ess-stack 14 | repository: https://element-hq.github.io/ess-starter-edition-core 15 | version: 2.21.1 16 | - name: ess-system 17 | repository: https://element-hq.github.io/ess-starter-edition-core 18 | version: 2.21.1 19 | - name: postgresql 20 | version: 13.2.24 21 | repository: https://charts.bitnami.com/bitnami 22 | - name: common 23 | repository: https://charts.bitnami.com/bitnami 24 | tags: 25 | - bitnami-common 26 | version: 2.x.x 27 | -------------------------------------------------------------------------------- /helm/easy-setup/ess-meta/templates/postgres-db-secrets.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | --- 6 | {{- $postgresPassword := include "ess.secrets.passwords.manage-with-default" (dict "secret" (printf "%s-stack-synapse" (include "ess-stack.fullname" $)) "key" "postgresPassword" "defaultPasswordValue" (include "ess.secrets.password.shared-password" (dict "sharedPasswordId" "synapse-pg-password" "context" $)) "context" $) -}} 7 | {{- $adminPassword := include "ess.secrets.passwords.manage" (dict "secret" (printf "%s-postgres-db" .Release.Name) "key" "adminPassword" "context" $) -}} 8 | apiVersion: v1 9 | kind: Secret 10 | metadata: 11 | name: {{ .Release.Name }}-postgres-db 12 | type: Opaque 13 | data: 14 | adminPassword: {{ $adminPassword }} 15 | synapsePassword: {{ $postgresPassword | b64enc | quote }} 16 | -------------------------------------------------------------------------------- /helm/easy-setup/ess-meta/templates/selfsigned-cert.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | --- 6 | apiVersion: cert-manager.io/v1 7 | kind: Certificate 8 | metadata: 9 | name: {{ .Release.Name }}-selfsigned 10 | namespace: {{ .Release.Namespace }} 11 | spec: 12 | commonName: "{{ .Values.global.baseUrl }}" 13 | secretName: {{ .Release.Name }}-selfsigned 14 | privateKey: 15 | algorithm: RSA 16 | issuerRef: 17 | name: ess-stack-selfsigned 18 | kind: ClusterIssuer 19 | group: cert-manager.io 20 | dnsNames: 21 | - "{{ .Values.global.baseUrl }}" 22 | - "*.{{ .Values.global.baseUrl }}" 23 | -------------------------------------------------------------------------------- /helm/easy-setup/extract-ca.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2024 New Vector Ltd 4 | # 5 | # SPDX-License-Identifier: AGPL-3.0-or-later 6 | 7 | 8 | kubectl get secrets/ess-stack-ca -n cert-manager --template='{{index .data "tls.crt"}}' | base64 -d > ca.crt 9 | -------------------------------------------------------------------------------- /helm/easy-setup/helm-diff.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2024 New Vector Ltd 4 | # 5 | # SPDX-License-Identifier: AGPL-3.0-or-later 6 | 7 | 8 | values_files_args="" 9 | for arg in "$@" 10 | do 11 | values_files_args+=" -f values/values.${arg}.yaml" 12 | done 13 | 14 | helm --kube-context kind-easy-setup diff upgrade --detailed-exitcode --dry-run=server --namespace ess -f values.ess-stack.yaml $values_files_args ess ./ess-meta 15 | -------------------------------------------------------------------------------- /helm/easy-setup/helm-template.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2024 New Vector Ltd 4 | # 5 | # SPDX-License-Identifier: AGPL-3.0-or-later 6 | 7 | 8 | values_files_args="" 9 | for arg in "$@" 10 | do 11 | values_files_args+=" -f values/values.${arg}.yaml" 12 | done 13 | 14 | helm --kube-context kind-easy-setup template --namespace ess -f values.ess-stack.yaml $values_files_args ess ./ess-meta --debug 15 | -------------------------------------------------------------------------------- /helm/easy-setup/prepare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2024 New Vector Ltd 4 | # 5 | # SPDX-License-Identifier: AGPL-3.0-or-later 6 | 7 | 8 | set -e 9 | 10 | kind_cluster_name="easy-setup" 11 | kind_context_name="kind-$kind_cluster_name" 12 | 13 | docker stop "${kind_cluster_name}-registry" || true 14 | docker rm "${kind_cluster_name}-registry" || true 15 | 16 | if kind get clusters | grep "$kind_cluster_name"; then 17 | echo "Cluster '$kind_cluster_name' is already provisioned by Kind" 18 | else 19 | echo "Creating new Kind cluster '$kind_cluster_name'" 20 | cat tests/kind.yml | kind create cluster --name "$kind_cluster_name" --config - 21 | fi 22 | 23 | network=`docker inspect $kind_cluster_name-control-plane | jq '.[0].NetworkSettings.Networks | keys | .[0]' -r` 24 | docker run \ 25 | -d --restart=always -p "127.0.0.1:5000:5000" --network $network --name "${kind_cluster_name}-registry" \ 26 | registry:2 27 | 28 | echo "now on kind context, going to apply whats next in 15seconds" 29 | sleep 5 30 | kubectl --context $kind_context_name apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml 31 | kubectl patch configmap/ingress-nginx-controller -n ingress-nginx --type merge --patch-file tests/nginx-cm.yml 32 | helm --kube-context $kind_context_name install \ 33 | cert-manager jetstack/cert-manager \ 34 | --namespace cert-manager \ 35 | --create-namespace \ 36 | --version "v1.13.3" \ 37 | --set installCRDs=true 38 | kubectl --context $kind_context_name apply -f tests/self-signed-ca.yml 39 | -------------------------------------------------------------------------------- /helm/easy-setup/tests/kind.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: kind.x-k8s.io/v1alpha4 7 | kind: Cluster 8 | nodes: 9 | - role: control-plane 10 | kubeadmConfigPatches: 11 | - |- 12 | kind: InitConfiguration 13 | nodeRegistration: 14 | kubeletExtraArgs: 15 | node-labels: "ingress-ready=true" 16 | extraPortMappings: 17 | - containerPort: 80 18 | hostPort: 80 19 | protocol: TCP 20 | - containerPort: 443 21 | hostPort: 443 22 | protocol: TCP 23 | - containerPort: 31000 24 | hostPort: 31000 25 | protocol: UDP 26 | - containerPort: 31000 27 | hostPort: 31000 28 | protocol: TCP 29 | containerdConfigPatches: 30 | - |- 31 | [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:5000"] 32 | endpoint = ["http://easy-setup-registry:5000"] 33 | -------------------------------------------------------------------------------- /helm/easy-setup/tests/nginx-cm.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | data: 7 | # we need this for all our path prefixs with dots, like `.well-known ` 8 | strict-validate-path-type: "false" 9 | -------------------------------------------------------------------------------- /helm/easy-setup/tests/self-signed-ca.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | --- 6 | apiVersion: cert-manager.io/v1 7 | kind: ClusterIssuer 8 | metadata: 9 | name: ess-stack-ca 10 | spec: 11 | selfSigned: {} 12 | --- 13 | apiVersion: cert-manager.io/v1 14 | kind: Certificate 15 | metadata: 16 | name: ess-stack-ca 17 | namespace: cert-manager 18 | spec: 19 | isCA: true 20 | commonName: ess-stack-ca 21 | secretName: ess-stack-ca 22 | # 10 years 23 | duration: 87660h0m0s 24 | privateKey: 25 | algorithm: RSA 26 | issuerRef: 27 | name: ess-stack-ca 28 | kind: ClusterIssuer 29 | group: cert-manager.io 30 | --- 31 | apiVersion: cert-manager.io/v1 32 | kind: ClusterIssuer 33 | metadata: 34 | name: ess-stack-selfsigned 35 | spec: 36 | ca: 37 | secretName: ess-stack-ca -------------------------------------------------------------------------------- /helm/easy-setup/values.ess-crds.yaml.example: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | 7 | element-operator: 8 | deployManager: true 9 | 10 | element-updater: 11 | deployManager: true 12 | -------------------------------------------------------------------------------- /helm/easy-setup/values.ess-stack.yaml.example: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | global: 7 | baseUrl: ess.localhost 8 | 9 | ess-stack: 10 | secrets: 11 | synapse: 12 | content: 13 | # python3 -c "import signedjson.key; signing_key = signedjson.key.generate_signing_key(0); print(f\"{signing_key.alg} {signing_key.version} {signedjson.key.encode_signing_key_base64(signing_key)}\")" 14 | signingKey: ed25519 0 7SyX4/XJuMxulOTRIzjw+jgNwcWC9XRnkUJn3CfI6Kg 15 | 16 | 17 | -------------------------------------------------------------------------------- /helm/ess-stack/Chart.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: v2 7 | name: ess-stack 8 | description: A Helm chart to deploy ESS stack 9 | type: application 10 | version: 2.21.1 11 | appVersion: 2.21.1 12 | -------------------------------------------------------------------------------- /helm/ess-stack/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | */}} 11 | {{- define "ess-stack.fullname" -}} 12 | {{- if .Values.fullnameOverride }} 13 | {{- tpl .Values.fullnameOverride . | trunc 63 | trimSuffix "-" }} 14 | {{- else }} 15 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 16 | {{- end }} 17 | {{- end }} 18 | -------------------------------------------------------------------------------- /helm/ess-stack/templates/elementdeployment.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | --- 6 | apiVersion: matrix.element.io/v1alpha2 7 | kind: ElementDeployment 8 | metadata: 9 | name: {{ include "ess-stack.fullname" $ }} 10 | annotations: 11 | k8s.element.io/secretshash: {{ $.Values.secrets | toJson | sha256sum }} 12 | spec: 13 | components: 14 | {{- $sortedComponents := sortAlpha (keys $.Values.components) -}} 15 | {{- range $component := $sortedComponents }} 16 | {{- $properties := index $.Values.components $component }} 17 | {{ $component }}: 18 | secretName: {{ (index $.Values.secrets $component).existingSecret | default (printf "%s-stack-%s" (include "ess-stack.fullname" $) ($component | lower) ) }} 19 | {{ tpl (toYaml $properties) $ | nindent 6 }} 20 | {{ end }} 21 | global: 22 | secretName: {{ $.Values.secrets.global.existingSecret | default (printf "%s-stack-global" (include "ess-stack.fullname" $) ) }} 23 | {{ tpl (toYaml $.Values.globalOptions) . | nindent 4 }} 24 | -------------------------------------------------------------------------------- /helm/ess-stack/templates/secrets.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | --- 6 | 7 | {{- $sortedSecrets := sortAlpha (keys $.Values.secrets) -}} 8 | {{- range $secretEntry := $sortedSecrets }} 9 | {{- $secret := (index $.Values.secrets $secretEntry) -}} 10 | apiVersion: v1 11 | kind: Secret 12 | metadata: 13 | name: {{ include "ess-stack.fullname" $ }}-stack-{{ $secretEntry | lower }} 14 | type: Opaque 15 | data: 16 | {{- $sortedKeys := sortAlpha (keys $secret.content) -}} 17 | {{- range $sortedKeys }} 18 | {{ . }}: {{ (tpl (index $secret.content .) $) | b64enc }} 19 | {{ end }} 20 | --- 21 | {{ end }} 22 | -------------------------------------------------------------------------------- /helm/ess-stack/values.schema.json.license: -------------------------------------------------------------------------------- 1 | Copyright 2024 New Vector Ltd 2 | 3 | SPDX-License-Identifier: AGPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /helm/ess-stack/values.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | 7 | secrets: 8 | global: {} 9 | 10 | globalOptions: 11 | k8s: 12 | ingresses: {} 13 | 14 | 15 | components: {} 16 | -------------------------------------------------------------------------------- /helm/ess-system/Chart.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: v2 7 | name: ess-system 8 | description: A Helm chart to deploy ESS System prerequisites (operators & crds) 9 | type: application 10 | version: 2.21.1 11 | appVersion: 2.21.1 12 | dependencies: 13 | - name: element-operator 14 | repository: https://element-hq.github.io/ess-starter-edition-core 15 | version: 2.21.1 16 | - name: element-updater 17 | repository: https://element-hq.github.io/ess-starter-edition-core 18 | version: 2.21.1 19 | -------------------------------------------------------------------------------- /helm/ess-system/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | 7 | {{/* 8 | Create a default fully qualified app name. 9 | */}} 10 | {{- define "ess-system.fullname" -}} 11 | {{- if .Values.fullnameOverride }} 12 | {{- tpl .Values.fullnameOverride . | trunc 63 | trimSuffix "-" }} 13 | {{- else }} 14 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 15 | {{- end }} 16 | {{- end }} 17 | -------------------------------------------------------------------------------- /helm/ess-system/templates/webhook-issuer.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | --- 6 | 7 | {{ if or (eq (index .Values "element-operator").deployCrds true) (eq (index .Values "element-updater").deployCrds true) }} 8 | apiVersion: cert-manager.io/v1 9 | kind: Issuer 10 | metadata: 11 | name: {{ include "ess-system.fullname" $ }}-webhook-ca 12 | namespace: {{ .Release.Namespace }} 13 | spec: 14 | selfSigned: {} 15 | --- 16 | apiVersion: cert-manager.io/v1 17 | kind: Certificate 18 | metadata: 19 | name: {{ include "ess-system.fullname" $ }}-webhook-ca 20 | namespace: {{ .Release.Namespace }} 21 | spec: 22 | isCA: true 23 | commonName: {{ include "ess-system.fullname" $ }}-webhook-ca 24 | secretName: {{ include "ess-system.fullname" $ }}-webhook-ca 25 | # 10 years 26 | duration: 87660h0m0s 27 | privateKey: 28 | algorithm: RSA 29 | issuerRef: 30 | name: {{ include "ess-system.fullname" $ }}-webhook-ca 31 | kind: Issuer 32 | group: cert-manager.io 33 | --- 34 | apiVersion: cert-manager.io/v1 35 | kind: Issuer 36 | metadata: 37 | name: {{ include "ess-system.fullname" $ }}-webhook 38 | namespace: {{ .Release.Namespace }} 39 | spec: 40 | ca: 41 | secretName: {{ include "ess-system.fullname" $ }}-webhook-ca 42 | {{ end }} 43 | -------------------------------------------------------------------------------- /helm/ess-system/values.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | 7 | element-operator: 8 | namePrefix: operator 9 | deployCrds: true 10 | deployManager: false 11 | crds: 12 | annotations: 13 | cert-manager.io/inject-ca-from: >- 14 | {{ .Release.Namespace }}/{{ include "ess-system.fullname" $ }}-{{ .Values.namePrefix }}-conversion-webhook-tls 15 | conversionWebhook: 16 | tlsSecretName: >- 17 | {{ include "ess-system.fullname" $ }}-operator-selfsigned-certs 18 | emsImageStore: {} 19 | 20 | element-updater: 21 | namePrefix: updater 22 | deployCrds: true 23 | deployManager: false 24 | crds: 25 | annotations: 26 | cert-manager.io/inject-ca-from: >- 27 | {{ .Release.Namespace }}/{{ include "ess-system.fullname" $ }}-{{ .Values.namePrefix }}-conversion-webhook-tls 28 | conversionWebhook: 29 | tlsSecretName: >- 30 | {{ include "ess-system.fullname" $ }}-updater-selfsigned-certs 31 | emsImageStore: {} 32 | -------------------------------------------------------------------------------- /helm/operator/Chart.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: v2 7 | name: element-operator 8 | description: A Helm chart for Kubernetes 9 | 10 | # A chart can be either an 'application' or a 'library' chart. 11 | # 12 | # Application charts are a collection of templates that can be packaged into versioned archives 13 | # to be deployed. 14 | # 15 | # Library charts provide useful utilities or functions for the chart developer. They're included as 16 | # a dependency of application charts to inject those utilities and functions into the rendering 17 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 18 | type: application 19 | 20 | # This is the chart version. This version number should be incremented each time you make changes 21 | # to the chart and its templates, including the app version. 22 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 23 | version: 2.21.1 24 | 25 | # This is the version number of the application being deployed. This version number should be 26 | # incremented each time you make changes to the application. Versions are not expected to 27 | # follow Semantic Versioning. They should reflect the version the application is using. 28 | appVersion: 2.21.1 29 | -------------------------------------------------------------------------------- /helm/operator/fragments/ClusterRole-Editor.yaml: -------------------------------------------------------------------------------- 1 | {{- end }} 2 | {{- if $.Values.clusterDeployment }} 3 | labels: 4 | rbac.authorization.k8s.io/aggregate-to-admin: "true" 5 | rbac.authorization.k8s.io/aggregate-to-edit: "true" 6 | -------------------------------------------------------------------------------- /helm/operator/fragments/ClusterRole-Namespace.yaml: -------------------------------------------------------------------------------- 1 | {{- if not $.Values.clusterDeployment }} 2 | namespace: {{ $.Release.Namespace }} 3 | {{- end }} 4 | -------------------------------------------------------------------------------- /helm/operator/fragments/ClusterRole-Viewer.yaml: -------------------------------------------------------------------------------- 1 | {{- end }} 2 | {{- if $.Values.clusterDeployment }} 3 | labels: 4 | rbac.authorization.k8s.io/aggregate-to-view: "true" 5 | -------------------------------------------------------------------------------- /helm/operator/fragments/ConversionWebhook-CaBundle.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.crds.conversionWebhook.caBundle }} 2 | caBundle: {{ $.Values.crds.conversionWebhook.caBundle }} 3 | {{- end }} 4 | -------------------------------------------------------------------------------- /helm/operator/fragments/ConversionWebhook-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | {{- if $.Values.crds.conversionWebhook.annotations }} 5 | annotations: 6 | {{- toYaml $.Values.crds.conversionWebhook.annotations | nindent 4 }} 7 | {{- end }} 8 | name: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.conversionWebhookFullname" . }}' 9 | namespace: '{{ .Release.Namespace }}' 10 | spec: 11 | ports: 12 | - port: 443 13 | protocol: TCP 14 | targetPort: 7443 15 | selector: 16 | app.kubernetes.io/instance: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.conversionWebhookFullname" . }}' 17 | -------------------------------------------------------------------------------- /helm/operator/fragments/CustomResourceDefinition-Annotations.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.crds.annotations }} 2 | annotations: 3 | {{- range $key, $value := $.Values.crds.annotations }} 4 | {{ $key }}: {{ tpl $value $ }} 5 | {{- end }} 6 | {{- end }} 7 | -------------------------------------------------------------------------------- /helm/operator/fragments/Operator-ConfigMap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | {{- if $.Values.__VALUES_MANAGER_PARENT_KEY__.annotations }} 5 | annotations: 6 | {{- toYaml $.Values.__VALUES_MANAGER_PARENT_KEY__.annotations | nindent 4 }} 7 | {{- end }} 8 | labels: 9 | app.kubernetes.io/instance: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname" . }}' 10 | {{- if $.Values.__VALUES_MANAGER_PARENT_KEY__.labels }} 11 | {{- toYaml $.Values.__VALUES_MANAGER_PARENT_KEY__.labels | nindent 4 }} 12 | {{- end }} 13 | name: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname" . }}-ansible-cfg' 14 | namespace: '{{ .Release.Namespace }}' 15 | data: 16 | ansible.cfg: | 17 | [defaults] 18 | callbacks_enabled = ansible.posix.profile_tasks 19 | internal_poll_interval = {{ .Values.__VALUES_MANAGER_PARENT_KEY__.manager.ansibleInternalPollInterval }} 20 | roles_path = /element.io/roles 21 | collections_path = /ansible/collections 22 | library = /usr/share/ansible/openshift 23 | home = /.ansible 24 | local_tmp = /.ansible/tmp 25 | -------------------------------------------------------------------------------- /helm/operator/fragments/Operator-Permissions.yaml: -------------------------------------------------------------------------------- 1 | 2 | - apiGroups: 3 | - "" 4 | resources: 5 | - secrets 6 | - configmaps 7 | - services 8 | verbs: 9 | - create 10 | - delete 11 | - get 12 | - list 13 | - patch 14 | - update 15 | - watch 16 | - apiGroups: 17 | - apps 18 | resources: 19 | - deployments 20 | - daemonsets 21 | - statefulsets 22 | verbs: 23 | - create 24 | - delete 25 | - get 26 | - list 27 | - patch 28 | - update 29 | - watch 30 | - apiGroups: 31 | - networking.k8s.io 32 | resources: 33 | - ingresses 34 | verbs: 35 | - create 36 | - delete 37 | - get 38 | - list 39 | - patch 40 | - update 41 | - watch 42 | - apiGroups: 43 | - "" 44 | resources: 45 | - persistentvolumeclaims 46 | verbs: 47 | - get 48 | - list 49 | - watch 50 | -------------------------------------------------------------------------------- /helm/operator/fragments/Operator-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | {{- if $.Values.__VALUES_MANAGER_PARENT_KEY__.annotations }} 5 | annotations: 6 | {{- toYaml $.Values.__VALUES_MANAGER_PARENT_KEY__.annotations | nindent 4 }} 7 | {{- end }} 8 | labels: 9 | app.kubernetes.io/instance: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname" . }}' 10 | {{- if $.Values.__VALUES_MANAGER_PARENT_KEY__.labels }} 11 | {{- toYaml $.Values.__VALUES_MANAGER_PARENT_KEY__.labels | nindent 4 }} 12 | {{- end }} 13 | name: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname" . }}-metrics' 14 | namespace: '{{ .Release.Namespace }}' 15 | spec: 16 | ports: 17 | - port: 8080 18 | protocol: TCP 19 | name: metrics 20 | targetPort: 8080 21 | selector: 22 | app.kubernetes.io/instance: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname" . }}' 23 | -------------------------------------------------------------------------------- /helm/operator/fragments/Operator-ServiceMonitor.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Capabilities.APIVersions.Has "monitoring.coreos.com/v1/ServiceMonitor" }} 2 | {{- if $.Values.deployServiceMonitor }} 3 | apiVersion: monitoring.coreos.com/v1 4 | kind: ServiceMonitor 5 | metadata: 6 | {{- if $.Values.__VALUES_MANAGER_PARENT_KEY__.annotations }} 7 | annotations: 8 | {{- toYaml $.Values.__VALUES_MANAGER_PARENT_KEY__.annotations | nindent 4 }} 9 | {{- end }} 10 | labels: 11 | app.kubernetes.io/instance: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname" . }}' 12 | {{- if $.Values.__VALUES_MANAGER_PARENT_KEY__.labels }} 13 | {{- toYaml $.Values.__VALUES_MANAGER_PARENT_KEY__.labels | nindent 4 }} 14 | {{- end }} 15 | name: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname" . }}-metrics' 16 | namespace: '{{ .Release.Namespace }}' 17 | spec: 18 | endpoints: 19 | - interval: 30s 20 | port: metrics 21 | selector: 22 | matchLabels: 23 | app.kubernetes.io/instance: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname" . }}' 24 | {{- end }} 25 | {{- end }} 26 | -------------------------------------------------------------------------------- /helm/operator/fragments/ServiceAccount-conversion-webhook.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployCrds }} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.conversionWebhookFullname" . }}' 6 | namespace: '{{ .Release.Namespace }}' 7 | {{ end }} 8 | -------------------------------------------------------------------------------- /helm/operator/fragments/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{- define "__CHART_FUNCTIONS_NAMESPACE__.prefix" }} 2 | {{- if .Values.nameOverride -}} 3 | {{ .Values.nameOverride }} 4 | {{- else -}} 5 | {{- if .Values.namePrefix -}} 6 | {{ .Release.Name }}-{{ .Values.namePrefix }} 7 | {{- else -}} 8 | {{ .Release.Name }} 9 | {{- end -}} 10 | {{- end -}} 11 | {{ end -}} 12 | 13 | {{- define "__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname" }} 14 | {{- include "__CHART_FUNCTIONS_NAMESPACE__.prefix" . }}-controller-manager 15 | {{- end -}} 16 | 17 | {{- define "__CHART_FUNCTIONS_NAMESPACE__.conversionWebhookFullname" }} 18 | {{- include "__CHART_FUNCTIONS_NAMESPACE__.prefix" . }}-conversion-webhook 19 | {{- end -}} 20 | 21 | {{- define "__CHART_FUNCTIONS_NAMESPACE__.managerEnv" }} 22 | {{- $defaultEnv := (include "__CHART_FUNCTIONS_NAMESPACE__.baseEnv" .) | fromJson -}} 23 | {{- $extraEnvs := dict -}} 24 | {{- range .Values.__VALUES_MANAGER_PARENT_KEY__.manager.extraEnvs }} 25 | {{- $extraEnvs = merge $extraEnvs (dict .name .value) -}} 26 | {{- end }} 27 | {{- $env := merge $defaultEnv $extraEnvs -}} 28 | {{- range $key, $value := $env -}} 29 | - name: {{ $key }} 30 | value: {{ $value | quote }} 31 | {{ end -}} 32 | {{- end -}} 33 | 34 | 35 | 36 | {{- define "__CHART_FUNCTIONS_NAMESPACE__.managerMaxReconciliationProcesses" }} 37 | {{- $memoryLimit := .Values.__VALUES_MANAGER_PARENT_KEY__.manager.resources.limits.memory -}} 38 | {{- $value := regexFind "\\d+" $memoryLimit -}} 39 | {{- $reconciliationProcesses := "" -}} 40 | {{- if hasSuffix "Mi" $memoryLimit -}} 41 | {{- $reconciliationProcesses = max 1 (div (sub (int $value) 2048) 512 | int) -}} 42 | {{- else if hasSuffix "Gi" $memoryLimit -}} 43 | {{- $reconciliationProcesses = max 1 (div (mul 1024 (sub (int $value) 2)) 512 | int) -}} 44 | {{- end -}} 45 | {{ $reconciliationProcesses }} 46 | {{- end -}} 47 | 48 | -------------------------------------------------------------------------------- /helm/operator/fragments/_variables.tpl: -------------------------------------------------------------------------------- 1 | 2 | {{- define "elementOperator.baseEnv" }} 3 | {{- $default_env := dict "ANSIBLE_GATHERING" "explicit" "ANSIBLE_REMOTE_TMP" "/.ansible/tmp" -}} 4 | {{- if not $.Values.clusterDeployment -}} 5 | {{- $default_env := merge $default_env (dict "WATCH_NAMESPACE" .Release.Namespace) -}} 6 | {{- end -}} 7 | {{- $default_env | toJson -}} 8 | {{- end -}} 9 | -------------------------------------------------------------------------------- /helm/operator/templates/_variables.tpl: -------------------------------------------------------------------------------- 1 | 2 | {{- define "elementOperator.baseEnv" }} 3 | {{- $default_env := dict "ANSIBLE_GATHERING" "explicit" "ANSIBLE_REMOTE_TMP" "/.ansible/tmp" -}} 4 | {{- if not $.Values.clusterDeployment -}} 5 | {{- $default_env := merge $default_env (dict "WATCH_NAMESPACE" .Release.Namespace) -}} 6 | {{- end -}} 7 | {{- $default_env | toJson -}} 8 | {{- end -}} 9 | -------------------------------------------------------------------------------- /helm/operator/templates/clusterrole-element-operator-metrics-reader.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.clusterDeployment }} 2 | --- 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}' 5 | metadata: 6 | name: '{{ include "elementOperator.prefix" . }}-metrics-reader' 7 | {{- if not $.Values.clusterDeployment }} 8 | namespace: {{ $.Release.Namespace }} 9 | {{- end }} 10 | rules: 11 | - nonResourceURLs: 12 | - /metrics 13 | verbs: 14 | - get 15 | {{ end }} 16 | -------------------------------------------------------------------------------- /helm/operator/templates/clusterrole-element-operator-proxy.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.clusterDeployment }} 2 | --- 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}' 5 | metadata: 6 | name: '{{ include "elementOperator.prefix" . }}-proxy' 7 | {{- if not $.Values.clusterDeployment }} 8 | namespace: {{ $.Release.Namespace }} 9 | {{- end }} 10 | rules: 11 | - apiGroups: 12 | - authentication.k8s.io 13 | resources: 14 | - tokenreviews 15 | verbs: 16 | - create 17 | - apiGroups: 18 | - authorization.k8s.io 19 | resources: 20 | - subjectaccessreviews 21 | verbs: 22 | - create 23 | {{ end }} 24 | -------------------------------------------------------------------------------- /helm/operator/templates/clusterrole-elementweb-editor.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployCrdRoles }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}' 4 | metadata: 5 | name: elementweb-editor 6 | {{- if not $.Values.clusterDeployment }} 7 | namespace: {{ $.Release.Namespace }} 8 | {{- end }} 9 | {{- if $.Values.clusterDeployment }} 10 | labels: 11 | rbac.authorization.k8s.io/aggregate-to-admin: "true" 12 | rbac.authorization.k8s.io/aggregate-to-edit: "true" 13 | {{- end }} 14 | rules: 15 | - apiGroups: 16 | - matrix.element.io 17 | resources: 18 | - elementwebs 19 | verbs: 20 | - create 21 | - delete 22 | - get 23 | - list 24 | - patch 25 | - update 26 | - watch 27 | - apiGroups: 28 | - matrix.element.io 29 | resources: 30 | - elementwebs/status 31 | verbs: 32 | - get 33 | {{ end }} 34 | -------------------------------------------------------------------------------- /helm/operator/templates/clusterrole-elementweb-viewer.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployCrdRoles }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}' 4 | metadata: 5 | name: elementweb-viewer 6 | {{- if not $.Values.clusterDeployment }} 7 | namespace: {{ $.Release.Namespace }} 8 | {{- end }} 9 | {{- if $.Values.clusterDeployment }} 10 | labels: 11 | rbac.authorization.k8s.io/aggregate-to-view: "true" 12 | {{- end }} 13 | rules: 14 | - apiGroups: 15 | - matrix.element.io 16 | resources: 17 | - elementwebs 18 | verbs: 19 | - get 20 | - list 21 | - watch 22 | - apiGroups: 23 | - matrix.element.io 24 | resources: 25 | - elementwebs/status 26 | verbs: 27 | - get 28 | {{ end }} 29 | -------------------------------------------------------------------------------- /helm/operator/templates/clusterrole-synapse-editor.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployCrdRoles }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}' 4 | metadata: 5 | name: synapse-editor 6 | {{- if not $.Values.clusterDeployment }} 7 | namespace: {{ $.Release.Namespace }} 8 | {{- end }} 9 | {{- if $.Values.clusterDeployment }} 10 | labels: 11 | rbac.authorization.k8s.io/aggregate-to-admin: "true" 12 | rbac.authorization.k8s.io/aggregate-to-edit: "true" 13 | {{- end }} 14 | rules: 15 | - apiGroups: 16 | - matrix.element.io 17 | resources: 18 | - synapses 19 | verbs: 20 | - create 21 | - delete 22 | - get 23 | - list 24 | - patch 25 | - update 26 | - watch 27 | - apiGroups: 28 | - matrix.element.io 29 | resources: 30 | - synapses/status 31 | verbs: 32 | - get 33 | {{ end }} 34 | -------------------------------------------------------------------------------- /helm/operator/templates/clusterrole-synapse-viewer.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployCrdRoles }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}' 4 | metadata: 5 | name: synapse-viewer 6 | {{- if not $.Values.clusterDeployment }} 7 | namespace: {{ $.Release.Namespace }} 8 | {{- end }} 9 | {{- if $.Values.clusterDeployment }} 10 | labels: 11 | rbac.authorization.k8s.io/aggregate-to-view: "true" 12 | {{- end }} 13 | rules: 14 | - apiGroups: 15 | - matrix.element.io 16 | resources: 17 | - synapses 18 | verbs: 19 | - get 20 | - list 21 | - watch 22 | - apiGroups: 23 | - matrix.element.io 24 | resources: 25 | - synapses/status 26 | verbs: 27 | - get 28 | {{ end }} 29 | -------------------------------------------------------------------------------- /helm/operator/templates/clusterrole-wellknowndelegation-editor.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployCrdRoles }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}' 4 | metadata: 5 | name: wellknowndelegation-editor 6 | {{- if not $.Values.clusterDeployment }} 7 | namespace: {{ $.Release.Namespace }} 8 | {{- end }} 9 | {{- if $.Values.clusterDeployment }} 10 | labels: 11 | rbac.authorization.k8s.io/aggregate-to-admin: "true" 12 | rbac.authorization.k8s.io/aggregate-to-edit: "true" 13 | {{- end }} 14 | rules: 15 | - apiGroups: 16 | - matrix.element.io 17 | resources: 18 | - wellknowndelegations 19 | verbs: 20 | - create 21 | - delete 22 | - get 23 | - list 24 | - patch 25 | - update 26 | - watch 27 | - apiGroups: 28 | - matrix.element.io 29 | resources: 30 | - wellknowndelegations/status 31 | verbs: 32 | - get 33 | {{ end }} 34 | -------------------------------------------------------------------------------- /helm/operator/templates/clusterrole-wellknowndelegation-viewer.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployCrdRoles }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}' 4 | metadata: 5 | name: wellknowndelegation-viewer 6 | {{- if not $.Values.clusterDeployment }} 7 | namespace: {{ $.Release.Namespace }} 8 | {{- end }} 9 | {{- if $.Values.clusterDeployment }} 10 | labels: 11 | rbac.authorization.k8s.io/aggregate-to-view: "true" 12 | {{- end }} 13 | rules: 14 | - apiGroups: 15 | - matrix.element.io 16 | resources: 17 | - wellknowndelegations 18 | verbs: 19 | - get 20 | - list 21 | - watch 22 | - apiGroups: 23 | - matrix.element.io 24 | resources: 25 | - wellknowndelegations/status 26 | verbs: 27 | - get 28 | {{ end }} 29 | -------------------------------------------------------------------------------- /helm/operator/templates/clusterrolebinding-element-operator-manager.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}Binding' 4 | metadata: 5 | name: '{{ include "elementOperator.prefix" . }}-manager' 6 | {{- if not $.Values.clusterDeployment }} 7 | namespace: {{ $.Release.Namespace }} 8 | {{- end }} 9 | roleRef: 10 | apiGroup: rbac.authorization.k8s.io 11 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}' 12 | name: '{{ include "elementOperator.prefix" . }}-manager' 13 | subjects: 14 | - kind: ServiceAccount 15 | name: '{{ include "elementOperator.prefix" . }}-controller-manager' 16 | namespace: '{{ .Release.Namespace }}' 17 | -------------------------------------------------------------------------------- /helm/operator/templates/clusterrolebinding-element-operator-proxy.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.clusterDeployment }} 2 | --- 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}Binding' 5 | metadata: 6 | name: '{{ include "elementOperator.prefix" . }}-proxy' 7 | {{- if not $.Values.clusterDeployment }} 8 | namespace: {{ $.Release.Namespace }} 9 | {{- end }} 10 | roleRef: 11 | apiGroup: rbac.authorization.k8s.io 12 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}' 13 | name: '{{ include "elementOperator.prefix" . }}-proxy' 14 | subjects: 15 | - kind: ServiceAccount 16 | name: '{{ include "elementOperator.prefix" . }}-controller-manager' 17 | namespace: '{{ .Release.Namespace }}' 18 | {{ end }} 19 | -------------------------------------------------------------------------------- /helm/operator/templates/configmap-ansible-cfg.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | {{- if $.Values.operator.annotations }} 5 | annotations: 6 | {{- toYaml $.Values.operator.annotations | nindent 4 }} 7 | {{- end }} 8 | labels: 9 | app.kubernetes.io/instance: '{{ include "elementOperator.controllerManagerFullname" . }}' 10 | {{- if $.Values.operator.labels }} 11 | {{- toYaml $.Values.operator.labels | nindent 4 }} 12 | {{- end }} 13 | name: '{{ include "elementOperator.controllerManagerFullname" . }}-ansible-cfg' 14 | namespace: '{{ .Release.Namespace }}' 15 | data: 16 | ansible.cfg: | 17 | [defaults] 18 | callbacks_enabled = ansible.posix.profile_tasks 19 | internal_poll_interval = {{ .Values.operator.manager.ansibleInternalPollInterval }} 20 | roles_path = /element.io/roles 21 | collections_path = /ansible/collections 22 | library = /usr/share/ansible/openshift 23 | home = /.ansible 24 | local_tmp = /.ansible/tmp 25 | -------------------------------------------------------------------------------- /helm/operator/templates/helpers.tpl: -------------------------------------------------------------------------------- 1 | {{- define "elementOperator.prefix" }} 2 | {{- if .Values.nameOverride -}} 3 | {{ .Values.nameOverride }} 4 | {{- else -}} 5 | {{- if .Values.namePrefix -}} 6 | {{ .Release.Name }}-{{ .Values.namePrefix }} 7 | {{- else -}} 8 | {{ .Release.Name }} 9 | {{- end -}} 10 | {{- end -}} 11 | {{ end -}} 12 | 13 | {{- define "elementOperator.controllerManagerFullname" }} 14 | {{- include "elementOperator.prefix" . }}-controller-manager 15 | {{- end -}} 16 | 17 | {{- define "elementOperator.conversionWebhookFullname" }} 18 | {{- include "elementOperator.prefix" . }}-conversion-webhook 19 | {{- end -}} 20 | 21 | {{- define "elementOperator.managerEnv" }} 22 | {{- $defaultEnv := (include "elementOperator.baseEnv" .) | fromJson -}} 23 | {{- $extraEnvs := dict -}} 24 | {{- range .Values.operator.manager.extraEnvs }} 25 | {{- $extraEnvs = merge $extraEnvs (dict .name .value) -}} 26 | {{- end }} 27 | {{- $env := merge $defaultEnv $extraEnvs -}} 28 | {{- range $key, $value := $env -}} 29 | - name: {{ $key }} 30 | value: {{ $value | quote }} 31 | {{ end -}} 32 | {{- end -}} 33 | 34 | 35 | 36 | {{- define "elementOperator.managerMaxReconciliationProcesses" }} 37 | {{- $memoryLimit := .Values.operator.manager.resources.limits.memory -}} 38 | {{- $value := regexFind "\\d+" $memoryLimit -}} 39 | {{- $reconciliationProcesses := "" -}} 40 | {{- if hasSuffix "Mi" $memoryLimit -}} 41 | {{- $reconciliationProcesses = max 1 (div (sub (int $value) 2048) 512 | int) -}} 42 | {{- else if hasSuffix "Gi" $memoryLimit -}} 43 | {{- $reconciliationProcesses = max 1 (div (mul 1024 (sub (int $value) 2)) 512 | int) -}} 44 | {{- end -}} 45 | {{ $reconciliationProcesses }} 46 | {{- end -}} 47 | 48 | -------------------------------------------------------------------------------- /helm/operator/templates/role-element-operator-leader-election.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployManager }} 2 | --- 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: Role 5 | metadata: 6 | name: '{{ include "elementOperator.prefix" . }}-leader-election' 7 | namespace: '{{ .Release.Namespace }}' 8 | rules: 9 | - apiGroups: 10 | - "" 11 | resources: 12 | - configmaps 13 | verbs: 14 | - get 15 | - list 16 | - watch 17 | - create 18 | - update 19 | - patch 20 | - delete 21 | - apiGroups: 22 | - coordination.k8s.io 23 | resources: 24 | - leases 25 | verbs: 26 | - get 27 | - list 28 | - watch 29 | - create 30 | - update 31 | - patch 32 | - delete 33 | - apiGroups: 34 | - "" 35 | resources: 36 | - events 37 | verbs: 38 | - create 39 | - patch 40 | {{ end }} 41 | -------------------------------------------------------------------------------- /helm/operator/templates/rolebinding-element-operator-leader-election.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployManager }} 2 | --- 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: RoleBinding 5 | metadata: 6 | name: '{{ include "elementOperator.prefix" . }}-leader-election' 7 | namespace: '{{ .Release.Namespace }}' 8 | roleRef: 9 | apiGroup: rbac.authorization.k8s.io 10 | kind: Role 11 | name: '{{ include "elementOperator.prefix" . }}-leader-election' 12 | subjects: 13 | - kind: ServiceAccount 14 | name: '{{ include "elementOperator.prefix" . }}-controller-manager' 15 | namespace: '{{ .Release.Namespace }}' 16 | {{ end }} 17 | -------------------------------------------------------------------------------- /helm/operator/templates/service-element-conversion-webhook.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | {{- if $.Values.crds.conversionWebhook.annotations }} 5 | annotations: 6 | {{- toYaml $.Values.crds.conversionWebhook.annotations | nindent 4 }} 7 | {{- end }} 8 | name: '{{ include "elementOperator.conversionWebhookFullname" . }}' 9 | namespace: '{{ .Release.Namespace }}' 10 | spec: 11 | ports: 12 | - port: 443 13 | protocol: TCP 14 | targetPort: 7443 15 | selector: 16 | app.kubernetes.io/instance: '{{ include "elementOperator.conversionWebhookFullname" . }}' 17 | -------------------------------------------------------------------------------- /helm/operator/templates/service-manager-metrics.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployManager }} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | {{- if $.Values.operator.annotations }} 6 | annotations: 7 | {{- toYaml $.Values.operator.annotations | nindent 4 }} 8 | {{- end }} 9 | labels: 10 | app.kubernetes.io/instance: '{{ include "elementOperator.controllerManagerFullname" . }}' 11 | {{- if $.Values.operator.labels }} 12 | {{- toYaml $.Values.operator.labels | nindent 4 }} 13 | {{- end }} 14 | name: '{{ include "elementOperator.controllerManagerFullname" . }}-metrics' 15 | namespace: '{{ .Release.Namespace }}' 16 | spec: 17 | ports: 18 | - port: 8080 19 | protocol: TCP 20 | name: metrics 21 | targetPort: 8080 22 | selector: 23 | app.kubernetes.io/instance: '{{ include "elementOperator.controllerManagerFullname" . }}' 24 | {{ end }} 25 | -------------------------------------------------------------------------------- /helm/operator/templates/service-monitor-manager.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Capabilities.APIVersions.Has "monitoring.coreos.com/v1/ServiceMonitor" }} 2 | {{- if $.Values.deployServiceMonitor }} 3 | apiVersion: monitoring.coreos.com/v1 4 | kind: ServiceMonitor 5 | metadata: 6 | {{- if $.Values.operator.annotations }} 7 | annotations: 8 | {{- toYaml $.Values.operator.annotations | nindent 4 }} 9 | {{- end }} 10 | labels: 11 | app.kubernetes.io/instance: '{{ include "elementOperator.controllerManagerFullname" . }}' 12 | {{- if $.Values.operator.labels }} 13 | {{- toYaml $.Values.operator.labels | nindent 4 }} 14 | {{- end }} 15 | name: '{{ include "elementOperator.controllerManagerFullname" . }}-metrics' 16 | namespace: '{{ .Release.Namespace }}' 17 | spec: 18 | endpoints: 19 | - interval: 30s 20 | port: metrics 21 | selector: 22 | matchLabels: 23 | app.kubernetes.io/instance: '{{ include "elementOperator.controllerManagerFullname" . }}' 24 | {{- end }} 25 | {{- end }} 26 | -------------------------------------------------------------------------------- /helm/operator/templates/serviceaccount-conversion-webhook.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployCrds }} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: '{{ include "elementOperator.conversionWebhookFullname" . }}' 6 | namespace: '{{ .Release.Namespace }}' 7 | {{ end }} 8 | -------------------------------------------------------------------------------- /helm/operator/templates/serviceaccount-element-operator-controller-manager.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: '{{ include "elementOperator.prefix" . }}-controller-manager' 5 | namespace: '{{ .Release.Namespace }}' 6 | -------------------------------------------------------------------------------- /helm/operator/yq/clusterdeployment.yq: -------------------------------------------------------------------------------- 1 | .kind |= sub("ClusterRole", "{{ .Values.clusterDeployment | ternary \"ClusterRole\" \"Role\" }}") | 2 | (. | select(has("roleRef"))).roleRef.kind |= sub("ClusterRole", "{{ .Values.clusterDeployment | ternary \"ClusterRole\" \"Role\" }}") 3 | -------------------------------------------------------------------------------- /helm/operator/yq/crds-conversion.yq: -------------------------------------------------------------------------------- 1 | . | 2 | (.spec | select(has("conversion")).conversion.webhook.clientConfig.service.name) |= "{{ include \"__CHART_FUNCTIONS_NAMESPACE__.conversionWebhookFullname\" . }}" | 3 | (.spec | select(has("conversion")).conversion.webhook.clientConfig.service.namespace) |= "{{ .Release.Namespace }}" 4 | -------------------------------------------------------------------------------- /helm/operator/yq/main-role.yq: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "rbac.authorization.k8s.io/v1", 3 | "kind": "{{ .Values.clusterDeployment | ternary \"ClusterRole\" \"Role\" }}", 4 | "metadata": { 5 | "name": "{{ include \"__CHART_FUNCTIONS_NAMESPACE__.prefix\" . }}-manager" 6 | }, 7 | "rules": ((sort_by(.kind | downcase).[] as $item ireduce({}; [] + . + { 8 | "apiGroups": ["matrix.element.io"], 9 | "resources": [ 10 | $item.kind | downcase | sub("([a-rt-wyz])$", "${1}s") | sub("x$", "xes"), 11 | ($item.kind | downcase | sub("([a-rt-wyz])$", "${1}s") | sub("x$", "xes")) + "/status", 12 | ($item.kind | downcase | sub("([a-rt-wyz])$", "${1}s") | sub("x$", "xes")) + "/finalizers" 13 | ], 14 | "verbs": [ 15 | "create", 16 | "delete", 17 | "get", 18 | "list", 19 | "patch", 20 | "update", 21 | "watch" 22 | ] 23 | } 24 | ) 25 | ) 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /helm/operator/yq/prefixes.yq: -------------------------------------------------------------------------------- 1 | .metadata.name |= sub("element-operator", "{{ include \"__CHART_FUNCTIONS_NAMESPACE__.prefix\" . }}") | 2 | (. | select(.kind == "Namespace")).metadata.name |= "{{ .Release.Namespace }}" | 3 | (.metadata | select(has("namespace"))).namespace |= "{{ .Release.Namespace }}" | 4 | ((. | select(has("roleRef"))).roleRef | select(has("name"))).name |= sub("element-operator", "{{ include \"__CHART_FUNCTIONS_NAMESPACE__.prefix\" . }}") | 5 | ((. | select(has("roleRef"))).roleRef | select(has("name"))).name |= sub("^manager$", "{{ include \"__CHART_FUNCTIONS_NAMESPACE__.prefix\" . }}-manager") | 6 | ((. | select(has("subjects"))).subjects[] | select(has("name"))).name |= sub("element-operator", "{{ include \"__CHART_FUNCTIONS_NAMESPACE__.prefix\" . }}") | 7 | ((. | select(has("subjects"))).subjects[] | select(has("namespace"))).namespace = "{{ .Release.Namespace }}" | 8 | ((.metadata | select(has("labels"))).labels | select(has("app.kubernetes.io/instance")))."app.kubernetes.io/instance" |= sub("controller-manager", "{{ include \"__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname\" . }}") | 9 | (((. | select(has("spec"))).spec | select(has("selector"))).selector | select(has("app.kubernetes.io/instance")))."app.kubernetes.io/instance" |= sub("controller-manager", "{{ include \"__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname\" . }}") | 10 | (((. | select(has("spec"))).spec | select(has("selector"))).selector | select(has("matchLabels"))).matchLabels."app.kubernetes.io/instance" |= sub("controller-manager", "{{ include \"__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname\" . }}") 11 | -------------------------------------------------------------------------------- /helm/operator/yq/resource-editor-role.yq: -------------------------------------------------------------------------------- 1 | (.[] as $item ireduce({}; [] + . + { 2 | "apiVersion": "rbac.authorization.k8s.io/v1", 3 | "kind": "{{ .Values.clusterDeployment | ternary \"ClusterRole\" \"Role\" }}", 4 | "metadata": { 5 | "name": ($item.kind | downcase) + "-editor" 6 | }, 7 | "rules": [ 8 | { 9 | "apiGroups": ["matrix.element.io"], 10 | "resources": [$item.kind | downcase | sub("([a-rt-wyz])$", "${1}s") | sub("x$", "xes")], 11 | "verbs": [ 12 | "create", 13 | "delete", 14 | "get", 15 | "list", 16 | "patch", 17 | "update", 18 | "watch" 19 | ] 20 | }, 21 | { 22 | "apiGroups": ["matrix.element.io"], 23 | "resources": [($item.kind | downcase | sub("([a-rt-wyz])$", "${1}s") | sub("x$", "xes")) + "/status"], 24 | "verbs": [ 25 | "get" 26 | ] 27 | } 28 | ] 29 | } 30 | ) 31 | ).[] 32 | -------------------------------------------------------------------------------- /helm/operator/yq/resource-viewer-role.yq: -------------------------------------------------------------------------------- 1 | (.[] as $item ireduce({}; [] + . + { 2 | "apiVersion": "rbac.authorization.k8s.io/v1", 3 | "kind": "{{ .Values.clusterDeployment | ternary \"ClusterRole\" \"Role\" }}", 4 | "metadata": { 5 | "name": ($item.kind | downcase) + "-viewer" 6 | }, 7 | "rules": [ 8 | { 9 | "apiGroups": ["matrix.element.io"], 10 | "resources": [$item.kind | downcase | sub("([a-rt-wyz])$", "${1}s") | sub("x$", "xes")], 11 | "verbs": [ 12 | "get", 13 | "list", 14 | "watch" 15 | ] 16 | }, 17 | { 18 | "apiGroups": ["matrix.element.io"], 19 | "resources": [($item.kind | downcase | sub("([a-rt-wyz])$", "${1}s") | sub("x$", "xes")) + "/status"], 20 | "verbs": [ 21 | "get" 22 | ] 23 | } 24 | ] 25 | } 26 | ) 27 | ).[] 28 | -------------------------------------------------------------------------------- /helm/updater/Chart.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | apiVersion: v2 7 | name: element-updater 8 | description: A Helm chart for Kubernetes 9 | 10 | # A chart can be either an 'application' or a 'library' chart. 11 | # 12 | # Application charts are a collection of templates that can be packaged into versioned archives 13 | # to be deployed. 14 | # 15 | # Library charts provide useful utilities or functions for the chart developer. They're included as 16 | # a dependency of application charts to inject those utilities and functions into the rendering 17 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 18 | type: application 19 | 20 | # This is the chart version. This version number should be incremented each time you make changes 21 | # to the chart and its templates, including the app version. 22 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 23 | version: 2.21.1 24 | 25 | # This is the version number of the application being deployed. This version number should be 26 | # incremented each time you make changes to the application. Versions are not expected to 27 | # follow Semantic Versioning. They should reflect the version the application is using. 28 | appVersion: 2.21.1 29 | -------------------------------------------------------------------------------- /helm/updater/fragments/ConversionWebhook-CaBundle.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.crds.conversionWebhook.caBundle }} 2 | caBundle: {{ $.Values.crds.conversionWebhook.caBundle }} 3 | {{- end }} 4 | -------------------------------------------------------------------------------- /helm/updater/fragments/Updater-Permissions.yaml: -------------------------------------------------------------------------------- 1 | 2 | - apiGroups: 3 | - "" 4 | resources: 5 | - secrets 6 | - configmaps 7 | - services 8 | verbs: 9 | - create 10 | - delete 11 | - get 12 | - list 13 | - patch 14 | - update 15 | - watch 16 | - apiGroups: 17 | - apps 18 | resources: 19 | - deployments 20 | - daemonsets 21 | - statefulsets 22 | verbs: 23 | - create 24 | - delete 25 | - get 26 | - list 27 | - patch 28 | - update 29 | - watch 30 | - apiGroups: 31 | - networking.k8s.io 32 | resources: 33 | - ingresses 34 | verbs: 35 | - create 36 | - delete 37 | - get 38 | - list 39 | - patch 40 | - update 41 | - watch 42 | - apiGroups: 43 | - "" 44 | resources: 45 | - persistentvolumeclaims 46 | verbs: 47 | - create 48 | - delete 49 | - get 50 | - list 51 | - patch 52 | - update 53 | - watch 54 | - apiGroups: 55 | - monitoring.coreos.com 56 | resources: 57 | - servicemonitors 58 | verbs: 59 | - create 60 | - delete 61 | - get 62 | - list 63 | - patch 64 | - update 65 | - watch 66 | -------------------------------------------------------------------------------- /helm/updater/fragments/Updater-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | {{- if $.Values.__VALUES_MANAGER_PARENT_KEY__.annotations }} 5 | annotations: 6 | {{- toYaml $.Values.__VALUES_MANAGER_PARENT_KEY__.annotations | nindent 4 }} 7 | {{- end }} 8 | labels: 9 | app.kubernetes.io/instance: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname" . }}' 10 | {{- if $.Values.__VALUES_MANAGER_PARENT_KEY__.labels }} 11 | {{- toYaml $.Values.__VALUES_MANAGER_PARENT_KEY__.labels | nindent 4 }} 12 | {{- end }} 13 | name: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname" . }}-metrics' 14 | namespace: '{{ .Release.Namespace }}' 15 | spec: 16 | ports: 17 | - port: 8080 18 | protocol: TCP 19 | targetPort: 8080 20 | name: metrics 21 | - port: 8090 22 | protocol: TCP 23 | targetPort: 8090 24 | name: metrics-watch 25 | selector: 26 | app.kubernetes.io/instance: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname" . }}' 27 | -------------------------------------------------------------------------------- /helm/updater/fragments/Updater-ServiceMonitor.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Capabilities.APIVersions.Has "monitoring.coreos.com/v1/ServiceMonitor" }} 2 | {{- if $.Values.deployServiceMonitor }} 3 | apiVersion: monitoring.coreos.com/v1 4 | kind: ServiceMonitor 5 | metadata: 6 | {{- if $.Values.__VALUES_MANAGER_PARENT_KEY__.annotations }} 7 | annotations: 8 | {{- toYaml $.Values.__VALUES_MANAGER_PARENT_KEY__.annotations | nindent 4 }} 9 | {{- end }} 10 | labels: 11 | app.kubernetes.io/instance: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname" . }}' 12 | {{- if $.Values.__VALUES_MANAGER_PARENT_KEY__.labels }} 13 | {{- toYaml $.Values.__VALUES_MANAGER_PARENT_KEY__.labels | nindent 4 }} 14 | {{- end }} 15 | name: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname" . }}-metrics' 16 | namespace: '{{ .Release.Namespace }}' 17 | spec: 18 | endpoints: 19 | - interval: 30s 20 | port: metrics 21 | - interval: 30s 22 | port: metrics-watch 23 | selector: 24 | matchLabels: 25 | app.kubernetes.io/instance: '{{ include "__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname" . }}' 26 | {{- end }} 27 | {{- end }} 28 | -------------------------------------------------------------------------------- /helm/updater/fragments/_variables.tpl: -------------------------------------------------------------------------------- 1 | 2 | {{- define "elementUpdater.baseEnv" }} 3 | {{- $defaultEnv := dict "ANSIBLE_GATHERING" "explicit" "ANSIBLE_REMOTE_TMP" "/.ansible/tmp" -}} 4 | {{- if not $.Values.clusterDeployment -}} 5 | {{- $defaultEnv := merge $defaultEnv (dict "WATCH_NAMESPACE" .Release.Namespace) -}} 6 | {{- end -}} 7 | {{- $defaultEnv | toJson -}} 8 | {{- end -}} 9 | -------------------------------------------------------------------------------- /helm/updater/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{- define "elementUpdater.prefix" }} 2 | {{- if .Values.nameOverride -}} 3 | {{ .Values.nameOverride }} 4 | {{- else -}} 5 | {{- if .Values.namePrefix -}} 6 | {{ .Release.Name }}-{{ .Values.namePrefix }} 7 | {{- else -}} 8 | {{ .Release.Name }} 9 | {{- end -}} 10 | {{- end -}} 11 | {{ end -}} 12 | 13 | {{- define "elementUpdater.controllerManagerFullname" }} 14 | {{- include "elementUpdater.prefix" . }}-controller-manager 15 | {{- end -}} 16 | 17 | {{- define "elementUpdater.conversionWebhookFullname" }} 18 | {{- include "elementUpdater.prefix" . }}-conversion-webhook 19 | {{- end -}} 20 | 21 | {{- define "elementUpdater.managerEnv" }} 22 | {{- $defaultEnv := (include "elementUpdater.baseEnv" .) | fromJson -}} 23 | {{- $extraEnvs := dict -}} 24 | {{- range .Values.updater.manager.extraEnvs }} 25 | {{- $extraEnvs = merge $extraEnvs (dict .name .value) -}} 26 | {{- end }} 27 | {{- $env := merge $defaultEnv $extraEnvs -}} 28 | {{- range $key, $value := $env -}} 29 | - name: {{ $key }} 30 | value: {{ $value | quote }} 31 | {{ end -}} 32 | {{- end -}} 33 | 34 | 35 | 36 | {{- define "elementUpdater.managerMaxReconciliationProcesses" }} 37 | {{- $memoryLimit := .Values.updater.manager.resources.limits.memory -}} 38 | {{- $value := regexFind "\\d+" $memoryLimit -}} 39 | {{- $reconciliationProcesses := "" -}} 40 | {{- if hasSuffix "Mi" $memoryLimit -}} 41 | {{- $reconciliationProcesses = max 1 (div (sub (int $value) 2048) 512 | int) -}} 42 | {{- else if hasSuffix "Gi" $memoryLimit -}} 43 | {{- $reconciliationProcesses = max 1 (div (mul 1024 (sub (int $value) 2)) 512 | int) -}} 44 | {{- end -}} 45 | {{ $reconciliationProcesses }} 46 | {{- end -}} 47 | 48 | -------------------------------------------------------------------------------- /helm/updater/templates/_variables.tpl: -------------------------------------------------------------------------------- 1 | 2 | {{- define "elementUpdater.baseEnv" }} 3 | {{- $defaultEnv := dict "ANSIBLE_GATHERING" "explicit" "ANSIBLE_REMOTE_TMP" "/.ansible/tmp" -}} 4 | {{- if not $.Values.clusterDeployment -}} 5 | {{- $defaultEnv := merge $defaultEnv (dict "WATCH_NAMESPACE" .Release.Namespace) -}} 6 | {{- end -}} 7 | {{- $defaultEnv | toJson -}} 8 | {{- end -}} 9 | -------------------------------------------------------------------------------- /helm/updater/templates/clusterrole-element-updater-metrics-reader.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.clusterDeployment }} 2 | --- 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}' 5 | metadata: 6 | name: '{{ include "elementUpdater.prefix" . }}-metrics-reader' 7 | {{- if not $.Values.clusterDeployment }} 8 | namespace: {{ $.Release.Namespace }} 9 | {{- end }} 10 | rules: 11 | - nonResourceURLs: 12 | - /metrics 13 | verbs: 14 | - get 15 | {{ end }} 16 | -------------------------------------------------------------------------------- /helm/updater/templates/clusterrole-element-updater-proxy.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.clusterDeployment }} 2 | --- 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}' 5 | metadata: 6 | name: '{{ include "elementUpdater.prefix" . }}-proxy' 7 | {{- if not $.Values.clusterDeployment }} 8 | namespace: {{ $.Release.Namespace }} 9 | {{- end }} 10 | rules: 11 | - apiGroups: 12 | - authentication.k8s.io 13 | resources: 14 | - tokenreviews 15 | verbs: 16 | - create 17 | - apiGroups: 18 | - authorization.k8s.io 19 | resources: 20 | - subjectaccessreviews 21 | verbs: 22 | - create 23 | {{ end }} 24 | -------------------------------------------------------------------------------- /helm/updater/templates/clusterrole-elementdeployment-editor.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployCrdRoles }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}' 4 | metadata: 5 | name: elementdeployment-editor 6 | {{- if not $.Values.clusterDeployment }} 7 | namespace: {{ $.Release.Namespace }} 8 | {{- end }} 9 | {{- if $.Values.clusterDeployment }} 10 | labels: 11 | rbac.authorization.k8s.io/aggregate-to-admin: "true" 12 | rbac.authorization.k8s.io/aggregate-to-edit: "true" 13 | {{- end }} 14 | rules: 15 | - apiGroups: 16 | - matrix.element.io 17 | resources: 18 | - elementdeployments 19 | verbs: 20 | - create 21 | - delete 22 | - get 23 | - list 24 | - patch 25 | - update 26 | - watch 27 | - apiGroups: 28 | - matrix.element.io 29 | resources: 30 | - elementdeployments/status 31 | verbs: 32 | - get 33 | {{ end }} 34 | -------------------------------------------------------------------------------- /helm/updater/templates/clusterrole-elementdeployment-viewer.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployCrdRoles }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}' 4 | metadata: 5 | name: elementdeployment-viewer 6 | {{- if not $.Values.clusterDeployment }} 7 | namespace: {{ $.Release.Namespace }} 8 | {{- end }} 9 | {{- if $.Values.clusterDeployment }} 10 | labels: 11 | rbac.authorization.k8s.io/aggregate-to-view: "true" 12 | {{- end }} 13 | rules: 14 | - apiGroups: 15 | - matrix.element.io 16 | resources: 17 | - elementdeployments 18 | verbs: 19 | - get 20 | - list 21 | - watch 22 | - apiGroups: 23 | - matrix.element.io 24 | resources: 25 | - elementdeployments/status 26 | verbs: 27 | - get 28 | {{ end }} 29 | -------------------------------------------------------------------------------- /helm/updater/templates/clusterrolebinding-element-updater-manager.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}Binding' 4 | metadata: 5 | name: '{{ include "elementUpdater.prefix" . }}-manager' 6 | {{- if not $.Values.clusterDeployment }} 7 | namespace: {{ $.Release.Namespace }} 8 | {{- end }} 9 | roleRef: 10 | apiGroup: rbac.authorization.k8s.io 11 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}' 12 | name: '{{ include "elementUpdater.prefix" . }}-manager' 13 | subjects: 14 | - kind: ServiceAccount 15 | name: '{{ include "elementUpdater.prefix" . }}-controller-manager' 16 | namespace: '{{ .Release.Namespace }}' 17 | -------------------------------------------------------------------------------- /helm/updater/templates/clusterrolebinding-element-updater-proxy.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.clusterDeployment }} 2 | --- 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}Binding' 5 | metadata: 6 | name: '{{ include "elementUpdater.prefix" . }}-proxy' 7 | {{- if not $.Values.clusterDeployment }} 8 | namespace: {{ $.Release.Namespace }} 9 | {{- end }} 10 | roleRef: 11 | apiGroup: rbac.authorization.k8s.io 12 | kind: '{{ .Values.clusterDeployment | ternary "ClusterRole" "Role" }}' 13 | name: '{{ include "elementUpdater.prefix" . }}-proxy' 14 | subjects: 15 | - kind: ServiceAccount 16 | name: '{{ include "elementUpdater.prefix" . }}-controller-manager' 17 | namespace: '{{ .Release.Namespace }}' 18 | {{ end }} 19 | -------------------------------------------------------------------------------- /helm/updater/templates/configmap-ansible-cfg.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | {{- if $.Values.updater.annotations }} 5 | annotations: 6 | {{- toYaml $.Values.updater.annotations | nindent 4 }} 7 | {{- end }} 8 | labels: 9 | app.kubernetes.io/instance: '{{ include "elementUpdater.controllerManagerFullname" . }}' 10 | {{- if $.Values.updater.labels }} 11 | {{- toYaml $.Values.updater.labels | nindent 4 }} 12 | {{- end }} 13 | name: '{{ include "elementUpdater.controllerManagerFullname" . }}-ansible-cfg' 14 | namespace: '{{ .Release.Namespace }}' 15 | data: 16 | ansible.cfg: | 17 | [defaults] 18 | callbacks_enabled = ansible.posix.profile_tasks 19 | internal_poll_interval = {{ .Values.updater.manager.ansibleInternalPollInterval }} 20 | roles_path = /element.io/roles 21 | collections_path = /ansible/collections 22 | library = /usr/share/ansible/openshift 23 | home = /.ansible 24 | local_tmp = /.ansible/tmp 25 | -------------------------------------------------------------------------------- /helm/updater/templates/role-element-updater-leader-election.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployManager }} 2 | --- 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: Role 5 | metadata: 6 | name: '{{ include "elementUpdater.prefix" . }}-leader-election' 7 | namespace: '{{ .Release.Namespace }}' 8 | rules: 9 | - apiGroups: 10 | - "" 11 | resources: 12 | - configmaps 13 | verbs: 14 | - get 15 | - list 16 | - watch 17 | - create 18 | - update 19 | - patch 20 | - delete 21 | - apiGroups: 22 | - coordination.k8s.io 23 | resources: 24 | - leases 25 | verbs: 26 | - get 27 | - list 28 | - watch 29 | - create 30 | - update 31 | - patch 32 | - delete 33 | - apiGroups: 34 | - "" 35 | resources: 36 | - events 37 | verbs: 38 | - create 39 | - patch 40 | {{ end }} 41 | -------------------------------------------------------------------------------- /helm/updater/templates/rolebinding-element-updater-leader-election.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployManager }} 2 | --- 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: RoleBinding 5 | metadata: 6 | name: '{{ include "elementUpdater.prefix" . }}-leader-election' 7 | namespace: '{{ .Release.Namespace }}' 8 | roleRef: 9 | apiGroup: rbac.authorization.k8s.io 10 | kind: Role 11 | name: '{{ include "elementUpdater.prefix" . }}-leader-election' 12 | subjects: 13 | - kind: ServiceAccount 14 | name: '{{ include "elementUpdater.prefix" . }}-controller-manager' 15 | namespace: '{{ .Release.Namespace }}' 16 | {{ end }} 17 | -------------------------------------------------------------------------------- /helm/updater/templates/service-element-conversion-webhook.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | {{- if $.Values.crds.conversionWebhook.annotations }} 5 | annotations: 6 | {{- toYaml $.Values.crds.conversionWebhook.annotations | nindent 4 }} 7 | {{- end }} 8 | name: '{{ include "elementUpdater.conversionWebhookFullname" . }}' 9 | namespace: '{{ .Release.Namespace }}' 10 | spec: 11 | ports: 12 | - port: 443 13 | protocol: TCP 14 | targetPort: 7443 15 | selector: 16 | app.kubernetes.io/instance: '{{ include "elementUpdater.conversionWebhookFullname" . }}' 17 | -------------------------------------------------------------------------------- /helm/updater/templates/service-manager-metrics.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployManager }} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | {{- if $.Values.updater.annotations }} 6 | annotations: 7 | {{- toYaml $.Values.updater.annotations | nindent 4 }} 8 | {{- end }} 9 | labels: 10 | app.kubernetes.io/instance: '{{ include "elementUpdater.controllerManagerFullname" . }}' 11 | {{- if $.Values.updater.labels }} 12 | {{- toYaml $.Values.updater.labels | nindent 4 }} 13 | {{- end }} 14 | name: '{{ include "elementUpdater.controllerManagerFullname" . }}-metrics' 15 | namespace: '{{ .Release.Namespace }}' 16 | spec: 17 | ports: 18 | - port: 8080 19 | protocol: TCP 20 | targetPort: 8080 21 | name: metrics 22 | - port: 8090 23 | protocol: TCP 24 | targetPort: 8090 25 | name: metrics-watch 26 | selector: 27 | app.kubernetes.io/instance: '{{ include "elementUpdater.controllerManagerFullname" . }}' 28 | {{ end }} 29 | -------------------------------------------------------------------------------- /helm/updater/templates/service-monitor-manager.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Capabilities.APIVersions.Has "monitoring.coreos.com/v1/ServiceMonitor" }} 2 | {{- if $.Values.deployServiceMonitor }} 3 | apiVersion: monitoring.coreos.com/v1 4 | kind: ServiceMonitor 5 | metadata: 6 | {{- if $.Values.updater.annotations }} 7 | annotations: 8 | {{- toYaml $.Values.updater.annotations | nindent 4 }} 9 | {{- end }} 10 | labels: 11 | app.kubernetes.io/instance: '{{ include "elementUpdater.controllerManagerFullname" . }}' 12 | {{- if $.Values.updater.labels }} 13 | {{- toYaml $.Values.updater.labels | nindent 4 }} 14 | {{- end }} 15 | name: '{{ include "elementUpdater.controllerManagerFullname" . }}-metrics' 16 | namespace: '{{ .Release.Namespace }}' 17 | spec: 18 | endpoints: 19 | - interval: 30s 20 | port: metrics 21 | - interval: 30s 22 | port: metrics-watch 23 | selector: 24 | matchLabels: 25 | app.kubernetes.io/instance: '{{ include "elementUpdater.controllerManagerFullname" . }}' 26 | {{- end }} 27 | {{- end }} 28 | -------------------------------------------------------------------------------- /helm/updater/templates/serviceaccount-conversion-webhook.yaml: -------------------------------------------------------------------------------- 1 | {{- if $.Values.deployCrds }} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: '{{ include "elementUpdater.conversionWebhookFullname" . }}' 6 | namespace: '{{ .Release.Namespace }}' 7 | {{ end }} 8 | -------------------------------------------------------------------------------- /helm/updater/templates/serviceaccount-element-updater-controller-manager.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: '{{ include "elementUpdater.prefix" . }}-controller-manager' 5 | namespace: '{{ .Release.Namespace }}' 6 | -------------------------------------------------------------------------------- /helm/updater/yq/prefixes.yq: -------------------------------------------------------------------------------- 1 | .metadata.name |= sub("element-updater", "{{ include \"__CHART_FUNCTIONS_NAMESPACE__.prefix\" . }}") | 2 | (. | select(.kind == "Namespace")).metadata.name |= "{{ .Release.Namespace }}" | 3 | (.metadata | select(has("namespace"))).namespace |= "{{ .Release.Namespace }}" | 4 | ((. | select(has("roleRef"))).roleRef | select(has("name"))).name |= sub("element-updater", "{{ include \"__CHART_FUNCTIONS_NAMESPACE__.prefix\" . }}") | 5 | ((. | select(has("roleRef"))).roleRef | select(has("name"))).name |= sub("^manager$", "{{ include \"__CHART_FUNCTIONS_NAMESPACE__.prefix\" . }}-manager") | 6 | ((. | select(has("subjects"))).subjects[] | select(has("name"))).name |= sub("element-updater", "{{ include \"__CHART_FUNCTIONS_NAMESPACE__.prefix\" . }}") | 7 | ((. | select(has("subjects"))).subjects[] | select(has("namespace"))).namespace = "{{ .Release.Namespace }}" | 8 | ((.metadata | select(has("labels"))).labels | select(has("app.kubernetes.io/instance")))."app.kubernetes.io/instance" |= sub("controller-manager", "{{ include \"__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname\" . }}") | 9 | (((. | select(has("spec"))).spec | select(has("selector"))).selector | select(has("app.kubernetes.io/instance")))."app.kubernetes.io/instance" |= sub("controller-manager", "{{ include \"__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname\" . }}") | 10 | (((. | select(has("spec"))).spec | select(has("selector"))).selector | select(has("matchLabels"))).matchLabels."app.kubernetes.io/instance" |= sub("controller-manager", "{{ include \"__CHART_FUNCTIONS_NAMESPACE__.controllerManagerFullname\" . }}") 11 | -------------------------------------------------------------------------------- /helm/updater/yq/prefixes.yq.license: -------------------------------------------------------------------------------- 1 | Copyright 2023 New Vector Ltd 2 | SPDX-License-Identifier: AGPL-3.0-or-later 3 | 4 | -------------------------------------------------------------------------------- /makefiles/starter-edition-core: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | include common.mk 7 | 8 | .PHONY: all 9 | all: buildah-build 10 | 11 | build-helm-charts: 12 | cd helm/operator && BASE_CRD_KUSTOMIZE_TARGET=config/crd/cleanup/starter-core bash build.sh 13 | cd helm/updater && ELEMENT_DEPLOYMENT_KUSTOMIZE_TARGET=config/crd/element-deployment/cleanup/starter-core bash build.sh 14 | 15 | .PHONY: build-crds 16 | build-crds: kustomize 17 | mkdir -p ${ARTIFACT_DIR} 18 | $(KUSTOMIZE) build config/crd/cleanup/starter-core | sed '/x-ui/d' > ${ARTIFACT_DIR}/crds.yml 19 | 20 | .PHONY: build-crds-ui 21 | build-crds-ui: kustomize 22 | mkdir -p ${ARTIFACT_DIR} 23 | $(KUSTOMIZE) build config/crd/element-deployment/cleanup/starter-core -o ${ARTIFACT_DIR}/crds-ui.yml 24 | 25 | .PHONY: build-all-crds 26 | build-all-crds: build-crds build-crds-ui 27 | 28 | .PHONY: buildah-build 29 | buildah-build: ## Build docker image with the manager. 30 | buildah bud -t operator 31 | buildah bud -t operator-conversion-webhook -f Dockerfile.operator conversion/ 32 | buildah bud -t updater -f Dockerfile.updater 33 | buildah bud -t updater-conversion-webhook -f Dockerfile.updater conversion/ 34 | 35 | .PHONY: local-build 36 | local-build: 37 | docker buildx build --load --metadata-file operator-metadata.json -t operator . 38 | docker buildx build --metadata-file updater-metadata.json --load -t updater -f Dockerfile.updater . 39 | -------------------------------------------------------------------------------- /playbooks/elementdeployment.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | - name: "ElementDeployment" 8 | ansible.builtin.import_playbook: "any.yml" 9 | vars: 10 | # - it needs to cleanup the same kinds as the operator CRDs (default_kinds_to_teardown in the role) 11 | # - it needs to cleanup ServiceMonitors 12 | # - it needs to cleanup operator managed CRDs 13 | # - PVCs could be here but are deliberately excluded out of an abundance of caution 14 | additional_kinds_to_teardown: "{{ element_operator_crds + [{'kind': 'ServiceMonitor', 'api_version': 'monitoring.coreos.com/v1'}] }}" 15 | -------------------------------------------------------------------------------- /requirements.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | collections: 8 | # ansible-galaxy is timeouting a lot, so use git as a workaround to get collections 9 | # https://github.com/ansible/galaxy/issues/3086 10 | - name: operator_sdk.util 11 | # We can't use version with operator-sdk-ansible-util because of 12 | # ERROR! Unexpected Exception, this is probably a bug: Non integer values in LooseVersion ('v0.4.0') 13 | source: https://github.com/operator-framework/operator-sdk-ansible-util.git,v0.5.0 14 | type: git 15 | - name: kubernetes.core 16 | source: https://github.com/ansible-collections/kubernetes.core.git 17 | type: git 18 | version: "3.2.0" 19 | - name: community.postgresql 20 | source: https://github.com/ansible-collections/community.postgresql.git 21 | type: git 22 | version: "3.6.1" 23 | - name: community.general 24 | source: https://github.com/ansible-collections/community.general.git 25 | type: git 26 | version: "9.4.0" 27 | - name: ansible.utils 28 | source: https://github.com/element-hq/ansible.utils,gaelg/fix-keep-keys-keeping-wrong-lists 29 | type: git 30 | - name: ansible.posix 31 | source: https://github.com/ansible-collections/ansible.posix.git 32 | type: git 33 | version: "1.6.0" 34 | - name: community.crypto 35 | source: https://github.com/ansible-collections/community.crypto 36 | type: git 37 | version: "2.22.1" 38 | -------------------------------------------------------------------------------- /roles/elementdeployment/defaults/main/images.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | default_images_digests: 6 | element_web: 7 | element_web: 8 | image_repository_server: docker.io 9 | image_repository_path: vectorim/element-web 10 | image_tag: v1.11.82 11 | kube_rbac_proxy: 12 | kube_rbac_proxy: 13 | image_repository_server: quay.io 14 | image_repository_path: brancz/kube-rbac-proxy 15 | image_tag: v0.18.0 16 | synapse: 17 | haproxy: 18 | image_repository_server: docker.io 19 | image_repository_path: library/haproxy 20 | image_tag: 3.0-alpine 21 | redis: 22 | image_repository_server: docker.io 23 | image_repository_path: library/redis 24 | image_tag: 7.4-alpine 25 | synapse: 26 | image_repository_server: docker.io 27 | image_repository_path: matrixdotorg/synapse 28 | image_tag: v1.116.0 29 | well_known_delegation: 30 | well_known_delegation: 31 | image_repository_server: docker.io 32 | image_repository_path: library/nginx 33 | image_tag: 1.26-alpine-slim 34 | -------------------------------------------------------------------------------- /roles/elementdeployment/filter_plugins/mapattributes.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | class FilterModule(object): 7 | def filters(self): 8 | return { 'mapattributes': self.mapattributes } 9 | 10 | def mapattributes(self, list_of_dicts, list_of_keys): 11 | l = [] 12 | for di in list_of_dicts: 13 | newdi = { } 14 | for key in list_of_keys: 15 | newdi[key] = di[key] 16 | l.append(newdi) 17 | return l 18 | -------------------------------------------------------------------------------- /roles/elementdeployment/filter_plugins/sort_apply_order.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | # Anything not listed below gets sorted after Kinds that have been listed, maintaining the input order 7 | components_order = [ 8 | "synapse", 9 | "well_known_delegation", 10 | "element_web", 11 | ] 12 | 13 | class FilterModule(object): 14 | def filters(self): return {'sort_apply_order': sort_apply_order} 15 | 16 | def _component_order(c): 17 | try: 18 | return components_order.index(c) 19 | except ValueError: 20 | return len(components_order) 21 | 22 | def sort_apply_order(data): 23 | if isinstance(data, list): 24 | data.sort(key=_component_order) 25 | return data 26 | 27 | -------------------------------------------------------------------------------- /roles/elementdeployment/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | - name: "Check prerequisites" 8 | ansible.builtin.include_tasks: "{{ prerequisite_task }}" 9 | loop: "{{ query('fileglob', 'tasks/prerequisites/*.yml') }}" 10 | loop_control: 11 | loop_var: prerequisite_task 12 | 13 | - name: "Prepare all components manifests" 14 | ansible.builtin.include_tasks: prepare.yml 15 | 16 | 17 | - name: Use generic apply 18 | ansible.builtin.include_role: 19 | name: "generic_apply" 20 | vars: 21 | _rendered_manifests_strings: "{{ [_all_components_manifests_content] }}" 22 | when: "_all_components_manifests_content | length > 0" 23 | 24 | - name: "Finalising tasks" 25 | ansible.builtin.include_tasks: "{{ finalising_task }}" 26 | loop: "{{ query('fileglob', 'tasks/finalising/*.yml') }}" 27 | loop_control: 28 | loop_var: finalising_task 29 | -------------------------------------------------------------------------------- /roles/elementdeployment/tasks/prepare.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | - name: "Display input" 8 | ansible.builtin.debug: 9 | msg: "{{ item.input }}" 10 | when: lookup('env', 'DEBUG_MANIFESTS') | int == 1 11 | loop_control: 12 | label: "{{ item.name }}" 13 | loop: 14 | - name: "global" 15 | input: "{{ _global }}" 16 | - name: "components" 17 | input: "{{ components }}" 18 | - name: "secret" 19 | input: "{{ _global_secret }}" 20 | 21 | - name: "Build all components manifests" 22 | vars: 23 | # We cannot use `{% set _component_item = ... %}` because the variable used in the set is not reachable outside of jinja engine 24 | # and ansible cannot use the macros defined in defaults. 25 | # Instead we use a magic variable injected by ansible into the jinja engine 26 | # https://github.com/ansible/ansible/blob/devel/lib/ansible/template/__init__.py#L105 27 | _component_item: "{{ template_path | dirname | basename }}" 28 | ansible.builtin.set_fact: 29 | _all_components_manifests_content: | 30 | {% for _comp in components %} 31 | {% set _manifest_template_filenames = query('fileglob', 'templates/' + _comp + '/*.j2') | sort | list %} 32 | {% if _manifest_template_filenames | length > 0 %} 33 | {% for _template in query('template', *_manifest_template_filenames) %} 34 | {% if _template | select | length > 0 %} 35 | {{ _template }} 36 | --- 37 | {% endif %} 38 | {% endfor %} 39 | {% endif %} 40 | {% endfor %} 41 | no_log: "{{ lookup('env', 'DEBUG_MANIFESTS') | int != 1 }}" 42 | -------------------------------------------------------------------------------- /roles/elementdeployment/tasks/prerequisites/crds.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | - name: Fetch CRDs resources 8 | kubernetes.core.k8s_cluster_info: 9 | invalidate_cache: false 10 | register: _cluster_info 11 | -------------------------------------------------------------------------------- /roles/elementdeployment/tasks/prerequisites/global_secret.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | - name: Fetch global secret 8 | no_log: "{{ lookup('env', 'DEBUG_MANIFESTS') | int != 1 }}" 9 | ansible.builtin.set_fact: 10 | _global_secret: > 11 | {{ 12 | query('kubernetes.core.k8s', 13 | kind='Secret', 14 | api_version='v1', 15 | resource_name=_global.secret_name, 16 | namespace=ansible_operator_meta.namespace) 17 | }} 18 | 19 | - name: Check that the global secret was found 20 | ansible.builtin.assert: 21 | that: _global_secret | length == 1 22 | msg: The global secret {{ _global.secret_name }} could not be found 23 | 24 | - name: Check that the generic shared secret is present 25 | ansible.builtin.assert: 26 | that: _global.config.generic_shared_secret_secret_key in (_global_secret[0].data | default({})) 27 | msg: Missing generic shared secret from global secret 28 | -------------------------------------------------------------------------------- /roles/elementdeployment/tasks/prerequisites/images_digests.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | 8 | - name: Fetch overriden images digests 9 | when: _global.config.images_digests_config_map | default(false) 10 | block: 11 | - name: Lookup imported images digests 12 | ansible.builtin.set_fact: 13 | _global_images_digests: > 14 | {{ 15 | query('kubernetes.core.k8s', 16 | kind='ConfigMap', 17 | api_version='v1', 18 | resource_name=_global.config.images_digests_config_map, 19 | namespace=ansible_operator_meta.namespace) 20 | }} 21 | 22 | - name: Check that the images digests cm was found 23 | ansible.builtin.assert: 24 | that: _global_images_digests | length == 1 25 | msg: Missing images digests config map {{ _global.config.images_digests_config_map }} 26 | 27 | - name: Check that the images digests cm contains `images_digests` key 28 | ansible.builtin.assert: 29 | that: ('images_digests' in _global_images_digests[0].data) 30 | msg: Missing `images_digests` entry from configmap {{ _global.config.images_digests_config_map }} 31 | 32 | - name: Set imported images digests 33 | ansible.builtin.set_fact: 34 | imported_images_digests: "{{ _global_images_digests[0].data.images_digests | from_yaml }}" 35 | -------------------------------------------------------------------------------- /roles/elementdeployment/tasks/prerequisites/name.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | - name: Check that the ElementDeployment name isn't too long 8 | ansible.builtin.fail: 9 | msg: The name of this ElementDeployment is too long. Dependent resources can't be created if 10 | its name is longer than 25 characters 11 | when: "ansible_operator_meta.name | length > 25" 12 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/any/k8s-host-aliases.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {% if components_k8s_properties.workloads.host_aliases | default(_global.k8s.workloads.host_aliases) | length > 0 %} 9 | hostAliases: 10 | {{ components_k8s_properties.workloads.host_aliases | default(_global.k8s.workloads.host_aliases) | to_nice_yaml(indent=2) | indent(2) }} 11 | {% endif %} 12 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/any/k8s-ingress.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {%- set _ingress_annotations = _matrix_element_io_elementdeployment_spec.global.k8s.common.annotations 9 | | combine(_matrix_element_io_elementdeployment_spec.global.k8s.ingresses.annotations) 10 | | combine(components_k8s_properties_camelled.common.annotations) 11 | | combine(components_ingress_properties_camelled.annotations) 12 | | dict2items 13 | | rejectattr('value', 'equalto', '') 14 | | items2dict %} 15 | {% if _ingress_annotations | length > 0 or 16 | (components_ingress_tls.mode | default('') == "certmanager" and 17 | components_ingress_tls.certmanager.issuer | default(false)) %} 18 | annotations: 19 | {{ _ingress_annotations 20 | | combine((components_ingress_tls.mode | default('') == "certmanager" and 21 | components_ingress_tls.certmanager.issuer | default(false)) 22 | | ternary({'cert-manager.io/cluster-issuer': components_ingress_tls.certmanager.issuer}, 23 | {})) 24 | | to_nice_yaml(indent=2) | indent(2) }} 25 | {% endif %} 26 | {% if components_ingress_tls.mode | default('') != 'external' %} 27 | tlsSecret: {{ components_ingress_tls.secret_name | default(ansible_operator_meta.name ~ '-' ~ _tls_secret) }} 28 | {% endif %} 29 | domainName: "{{ _ingress_fqdn | default(components_ingress_properties.fqdn) }}" 30 | {% if components_ingress_ingress_class_name | length > 0 %} 31 | ingressClassName: {{ components_ingress_ingress_class_name }} 32 | {% endif %} 33 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/any/k8s-services.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | type: {{ components_ingress_properties.services.type | default(_global.k8s.ingresses.services.type) }} 9 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/any/k8s-volume-claim.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {% if components_k8s_properties.storage.volume.size | default(false) %} 9 | volumeClaim: {{ ansible_operator_meta.name }}-{{ _claim_name | default(_component_item | regex_replace('_', '-')) }} 10 | {% else %} 11 | volumeClaim: {{ components_k8s_properties.storage.volume.persistent_volume_claim_name }} 12 | {% endif %} 13 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/any/pvc.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {% if components_k8s_properties.storage.volume.size | default(false) %} 9 | apiVersion: v1 10 | kind: PersistentVolumeClaim 11 | metadata: 12 | name: {{ ansible_operator_meta.name }}-{{ _claim_name | default(_component_item | regex_replace('_', '-')) }} 13 | namespace: {{ ansible_operator_meta.namespace }} 14 | spec: 15 | {% if components_k8s_properties.storage.volume.storage_class_name | default(_global.k8s.storage.storage_class_name) | default(false) %} 16 | storageClassName: "{{ components_k8s_properties.storage.volume.storage_class_name | default(_global.k8s.storage.storage_class_name) }}" 17 | {% endif %} 18 | accessModes: 19 | - ReadWriteOnce 20 | resources: 21 | requests: 22 | storage: "{{ components_k8s_properties.storage.volume.size }}" 23 | {% endif %} 24 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/any/tls-secrets.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {% if components_ingress_tls.mode | default('') == 'certfile' %} 9 | apiVersion: v1 10 | kind: Secret 11 | metadata: 12 | name: {{ ansible_operator_meta.name }}-{{ _tls_secret }} 13 | namespace: "{{ ansible_operator_meta.namespace }}" 14 | annotations: 15 | {% if components_k8s_properties.common.annotations | combine(_global.k8s.common.annotations) | length > 0 %} 16 | {{ components_k8s_properties.common.annotations | combine(_global.k8s.common.annotations) | to_nice_yaml(indent=2) | indent(4) }} 17 | {% endif %} 18 | type: kubernetes.io/tls 19 | data: 20 | {% if "tls" in components_ingress_properties and 21 | "certificate" in components_ingress_properties.tls and 22 | "cert_file_secret_key" in components_ingress_properties.tls.certificate and 23 | "private_key_secret_key" in components_ingress_properties.tls.certificate and 24 | components_ingress_properties.tls.certificate.cert_file_secret_key in _fetched_components_secrets and 25 | components_ingress_properties.tls.certificate.private_key_secret_key in _fetched_components_secrets %} 26 | tls.crt: {{ _fetched_components_secrets[components_ingress_properties.tls.certificate.cert_file_secret_key] | b64encode }} 27 | tls.key: {{ _fetched_components_secrets[components_ingress_properties.tls.certificate.private_key_secret_key] | b64encode }} 28 | {% else %} 29 | tls.crt: {{ _global_secret[0].data[global.k8s.ingresses.tls.certificate.cert_file_secret_key] }} 30 | tls.key: {{ _global_secret[0].data[global.k8s.ingresses.tls.certificate.private_key_secret_key] }} 31 | {% endif %} 32 | {% endif %} 33 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/element_web/config/50-user_provided.json.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {% if components.element_web.config.additional_config | default(false) %} 9 | {{ components.element_web.config.additional_config }} 10 | {% endif %} 11 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/element_web/elementweb.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | apiVersion: matrix.element.io/v1alpha1 9 | kind: ElementWeb 10 | metadata: 11 | name: "{{ ansible_operator_meta.name }}" 12 | namespace: "{{ ansible_operator_meta.namespace }}" 13 | spec: 14 | {{ lookup('template', 'templates/any/k8s-image.yaml.j2', template_vars={'_component_item': _component_item}) | indent(2) }} 15 | {{ lookup('template', 'templates/any/k8s-workloads.yaml.j2', template_vars={'_component_item': _component_item}) | indent(2) }} 16 | ingress: 17 | {{ lookup('template', 'templates/any/k8s-ingress.yaml.j2', template_vars={'_component_item': _component_item, '_tls_secret': 'element-tls-secret'}) | indent(4) }} 18 | service: 19 | {{ lookup('template', 'templates/any/k8s-services.yaml.j2', template_vars={'_component_item': _component_item}) | indent(4) }} 20 | config: 21 | {{ lookup('template', 'templates/any/k8s-config.yaml.j2', template_vars={'_component_item': _component_item}) | indent(4) }} 22 | defaultMatrixServer: 23 | baseUrl: {{ synapse_public_url }} 24 | serverName: {{ _global.config.domain_name }} 25 | {% set _config_template_files = query('fileglob', 'templates/element_web/config/*.json.j2') | sort %} 26 | {% set _additional_configs = query('template', *_config_template_files, convert_data=false, template_vars={'_component_item': _component_item}) | select | map('trim') | select | map('from_json') %} 27 | {% if _additional_configs | length > 0 %} 28 | additional: | 29 | {{ ({} | combine(_additional_configs, recursive=true) | to_nice_json(indent=2) | indent(6) | trim)[1:-1] }} 30 | 31 | {% endif %} 32 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/element_web/tls-secrets.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {{ lookup('template', 'templates/any/tls-secrets.yaml.j2', template_vars={'_component_item': _component_item, '_tls_secret': 'element-tls-secret'}) }} 9 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/synapse/config/25-authenticated-media.yml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | enable_authenticated_media: true -------------------------------------------------------------------------------- /roles/elementdeployment/templates/synapse/config/50-user_provided.yml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {% if components.synapse.config.additional | default(false) %} 9 | {{ components.synapse.config.additional | from_yaml | to_nice_yaml(indent=2) }} 10 | {% endif %} 11 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/synapse/external_appservices.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {% for key, value in components.synapse.config.external_appservices.files.items() %} 9 | --- 10 | apiVersion: v1 11 | kind: ConfigMap 12 | metadata: 13 | name: "{{ ansible_operator_meta.name }}-appservice-{{ key }}-config" 14 | namespace: "{{ ansible_operator_meta.namespace }}" 15 | labels: 16 | app.kubernetes.io/component: external-appservice 17 | annotations: 18 | data: 19 | registration.yaml: | 20 | {{ value | from_yaml | to_nice_yaml(indent=2) | indent(4) }} 21 | {% endfor %} 22 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/synapse/haproxy_service_monitor.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {{ lookup('template', 'synapse/service_monitor/haproxy_service_monitor.yaml.j2', template_vars={'_component_item': _component_item, '_subcomponent': 'haproxy'}) }} 9 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/synapse/pvc.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | apiVersion: v1 9 | kind: PersistentVolumeClaim 10 | metadata: 11 | name: {{ ansible_operator_meta.name }}-synapse-media 12 | namespace: "{{ ansible_operator_meta.namespace }}" 13 | spec: 14 | {% if components_k8s_properties.storage.volume.storage_class_name | default(_global.k8s.storage.storage_class_name) | default(false) %} 15 | storageClassName: "{{ components_k8s_properties.storage.volume.storage_class_name | default(_global.k8s.storage.storage_class_name) }}" 16 | {% endif %} 17 | {% if components.synapse.config.media.volume.name | default(false) %} 18 | volumeName: {{ components.synapse.config.media.volume.name }} 19 | {% endif %} 20 | accessModes: 21 | - ReadWriteOnce 22 | resources: 23 | requests: 24 | storage: "{{ components.synapse.config.media.volume.size }}" 25 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/synapse/secrets.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | apiVersion: v1 9 | kind: Secret 10 | metadata: 11 | name: {{ ansible_operator_meta.name }}-synapse-secrets 12 | namespace: "{{ ansible_operator_meta.namespace }}" 13 | data: 14 | macaroon: "{{ _fetched_components_secrets[components.synapse.config.macaroon_secret_key] | b64encode }}" 15 | postgresPassword: "{{ _fetched_components_secrets[components.synapse.config.postgresql.password_secret_key] | b64encode }}" 16 | registrationSharedSecret: "{{ _fetched_components_secrets[components.synapse.config.registration_shared_secret_secret_key] | b64encode }}" 17 | signingKey: "{{ _fetched_components_secrets[components.synapse.config.signing_key_secret_key] | b64encode }}" 18 | {% for worker in components.synapse.config.workers | default([]) %} 19 | {% if worker.additional | length > 0 %} 20 | {{ worker.type }}.yaml: {{ worker.additional | from_yaml | to_nice_yaml(indent=2) | b64encode }} 21 | {% endif %} 22 | {% endfor %} 23 | {% set _config_template_files = query('fileglob', 'templates/synapse/config/*.yml.j2') | sort %} 24 | {% set _additional_configs = query('template', *_config_template_files, convert_data=false, template_vars={'_component_item': _component_item}) | select | map('trim') | select | map('from_yaml') %} 25 | {% if _additional_configs | length > 0 %} 26 | shared.yaml: {{ {} | combine(_additional_configs, recursive=true) | to_nice_yaml(indent=2) | b64encode }} 27 | {% endif %} 28 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/synapse/service_monitor/haproxy_service_monitor.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {% if component_k8s_service_monitor_deploy %} 9 | apiVersion: monitoring.coreos.com/v1 10 | kind: ServiceMonitor 11 | metadata: 12 | name: {{ ansible_operator_meta.name }}-synapse-haproxy 13 | namespace: "{{ ansible_operator_meta.namespace }}" 14 | spec: 15 | endpoints: 16 | - interval: 30s 17 | port: haproxy-metrics 18 | selector: 19 | matchLabels: 20 | app.kubernetes.io/managed-by: element-operator 21 | app.kubernetes.io/part-of: matrix-stack 22 | app.kubernetes.io/component: matrix-server-ingress 23 | app.kubernetes.io/instance: {{ ansible_operator_meta.name }}-synapse-haproxy 24 | {% endif %} 25 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/synapse/service_monitor/synapse_service_monitor.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {% if component_k8s_service_monitor_deploy %} 9 | apiVersion: monitoring.coreos.com/v1 10 | kind: ServiceMonitor 11 | metadata: 12 | name: {{ ansible_operator_meta.name }}-synapse 13 | namespace: "{{ ansible_operator_meta.namespace }}" 14 | spec: 15 | endpoints: 16 | - interval: 30s 17 | port: synapse-metrics 18 | relabelings: 19 | - targetLabel: instance 20 | action: replace 21 | replacement: "{{ components.synapse.k8s.ingress.fqdn }}" 22 | selector: 23 | matchLabels: 24 | app.kubernetes.io/managed-by: element-operator 25 | app.kubernetes.io/part-of: matrix-stack 26 | app.kubernetes.io/component: matrix-server 27 | k8s.element.io/synapse-instance: "{{ ansible_operator_meta.name }}-synapse" 28 | k8s.element.io/service-type: headless 29 | {% endif %} 30 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/synapse/synapse_service_monitor.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {{ lookup('template', 'synapse/service_monitor/synapse_service_monitor.yaml.j2', template_vars={'_component_item': _component_item, '_subcomponent': 'synapse'}) }} 9 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/synapse/tls-secrets.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {{ lookup('template', 'templates/any/tls-secrets.yaml.j2', template_vars={'_component_item': _component_item, '_tls_secret': 'synapse-tls-secret'}) }} 9 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/well_known_delegation/config_client/50-user_provided.json.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {% if components.well_known_delegation.config.additional_client_config | default(false) %} 9 | {{ components.well_known_delegation.config.additional_client_config }} 10 | {% endif %} 11 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/well_known_delegation/config_element/50-user_provided.json.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {% if components.well_known_delegation.config.additional_element_config | default(false) %} 9 | {{ components.well_known_delegation.config.additional_element_config }} 10 | {% endif %} 11 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/well_known_delegation/config_server/50-user_provided.json.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {% if components.well_known_delegation.config.additional_server_config | default(false) %} 9 | {{ components.well_known_delegation.config.additional_server_config }} 10 | {% endif %} 11 | -------------------------------------------------------------------------------- /roles/elementdeployment/templates/well_known_delegation/tls-secrets.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {{ lookup('template', 'templates/any/tls-secrets.yaml.j2', template_vars={'_component_item': _component_item, '_tls_secret': 'wellknowndelegation-tls-secret'}) }} 9 | -------------------------------------------------------------------------------- /roles/elementdeployment/vars/main/element_web.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | component_info_element_web: 7 | - id: element_web 8 | application_services: false 9 | secret_name_is_optional: true 10 | -------------------------------------------------------------------------------- /roles/elementdeployment/vars/main/main.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | components_properties: "{{ query('vars', *query('ansible.builtin.varnames', 'component_info_.+')) | list | flatten }}" 7 | -------------------------------------------------------------------------------- /roles/elementdeployment/vars/main/replicas.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | schema_has_replicas: 6 | elementWeb: 7 | main: true 8 | synapse: 9 | haproxy: true 10 | redis: false 11 | synapse: false 12 | wellKnownDelegation: 13 | main: true 14 | 15 | -------------------------------------------------------------------------------- /roles/elementdeployment/vars/main/synapse.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | component_info_synapse: 7 | - id: synapse 8 | application_services: false 9 | secret_name_is_optional: false 10 | 11 | synapse_public_url: https://{{ components.synapse.k8s.ingress.fqdn }} 12 | synapse_internal_url: http://{{ ansible_operator_meta.name }}-synapse-haproxy.{{ ansible_operator_meta.namespace }}.svc.cluster.local:8008 13 | -------------------------------------------------------------------------------- /roles/elementdeployment/vars/main/synapse_admin.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | component_info_synapse_admin: 7 | - id: synapse_admin 8 | application_services: false 9 | secret_name_is_optional: true 10 | -------------------------------------------------------------------------------- /roles/elementdeployment/vars/main/well_known_delegation.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | component_info_well_known_delegation: 7 | - id: well_known_delegation 8 | application_services: false 9 | secret_name_is_optional: true 10 | -------------------------------------------------------------------------------- /roles/elementweb/defaults/main.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | image_repository: vectorim/element-web 8 | image_pull_secrets: [] 9 | image_has_digest: "{{ (image.digest | default('')) | length > 0 }}" 10 | image_pull_policy: "{{ image_has_digest | ternary('IfNotPresent', 'Always') }}" 11 | 12 | replicas: 2 13 | -------------------------------------------------------------------------------- /roles/elementweb/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | - name: "Manage manifests" 8 | ansible.builtin.include_role: 9 | name: "generic_apply" 10 | vars: 11 | _manifest_template_filenames: "{{ query('fileglob', 'templates/manifests/*.yaml.j2') }}" 12 | -------------------------------------------------------------------------------- /roles/elementweb/templates/config.json.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | { 9 | {% if config.default_matrix_server is defined %} 10 | "default_server_config": { 11 | "m.homeserver": { 12 | "base_url": "{{ config.default_matrix_server.base_url }}", 13 | "server_name": "{{ config.default_matrix_server.server_name | default(config.default_matrix_server.base_url) }}" 14 | } 15 | }, 16 | {% endif %} 17 | {% if config.additional | default("") | trim | length > 0 %} 18 | {{ config.additional }}, 19 | {% endif %} 20 | "dummy_end": "placeholder" 21 | } 22 | -------------------------------------------------------------------------------- /roles/elementweb/templates/manifests/element_config.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | apiVersion: v1 9 | kind: ConfigMap 10 | metadata: 11 | labels: 12 | app.kubernetes.io/part-of: matrix-stack 13 | app.kubernetes.io/component: matrix-client 14 | app.kubernetes.io/name: element-web 15 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-element-web" 16 | app.kubernetes.io/version: "{{ image.tag }}" 17 | name: "{{ ansible_operator_meta.name }}-element-web" 18 | namespace: "{{ ansible_operator_meta.namespace }}" 19 | data: 20 | config.json: |- 21 | {{ lookup('template', 'config.json.j2') | from_json | to_nice_json | indent(4) }} 22 | -------------------------------------------------------------------------------- /roles/elementweb/templates/manifests/element_ingress.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | apiVersion: networking.k8s.io/v1 9 | kind: Ingress 10 | metadata: 11 | annotations: 12 | {{ _matrix_element_io_elementweb_spec.ingress.annotations | default({}) | to_nice_yaml(2) | indent(4) }} 13 | labels: 14 | app.kubernetes.io/part-of: matrix-stack 15 | app.kubernetes.io/component: matrix-client 16 | app.kubernetes.io/name: element-web 17 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-element-web" 18 | app.kubernetes.io/version: "{{ image.tag }}" 19 | name: "{{ ansible_operator_meta.name }}-element-web" 20 | namespace: "{{ ansible_operator_meta.namespace }}" 21 | spec: 22 | {% if ingress.tls_secret | default(false) %} 23 | tls: 24 | - hosts: 25 | - "{{ ingress.domain_name }}" 26 | secretName: "{{ ingress.tls_secret }}" 27 | {% endif %} 28 | {% if ingress.ingress_class_name | default(false) %} 29 | ingressClassName: "{{ ingress.ingress_class_name }}" 30 | {% endif %} 31 | rules: 32 | - host: "{{ ingress.domain_name }}" 33 | http: 34 | paths: 35 | - path: / 36 | pathType: Prefix 37 | backend: 38 | service: 39 | name: "{{ ansible_operator_meta.name }}-element-web" 40 | port: 41 | number: 80 42 | -------------------------------------------------------------------------------- /roles/elementweb/templates/manifests/element_nginx_config.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | apiVersion: v1 9 | kind: ConfigMap 10 | metadata: 11 | labels: 12 | app.kubernetes.io/part-of: matrix-stack 13 | app.kubernetes.io/component: matrix-client 14 | app.kubernetes.io/name: element-web 15 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-element-web" 16 | app.kubernetes.io/version: "{{ image.tag }}" 17 | name: "{{ ansible_operator_meta.name }}-element-web-nginx" 18 | namespace: "{{ ansible_operator_meta.namespace }}" 19 | data: 20 | nginx.conf: |- 21 | {{ lookup('template', 'nginx.conf.j2') | indent(4) }} 22 | -------------------------------------------------------------------------------- /roles/elementweb/templates/manifests/element_web_service.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | --- 9 | apiVersion: v1 10 | kind: Service 11 | metadata: 12 | labels: 13 | app.kubernetes.io/part-of: matrix-stack 14 | app.kubernetes.io/component: matrix-client 15 | app.kubernetes.io/name: element-web 16 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-element-web" 17 | app.kubernetes.io/version: "{{ image.tag }}" 18 | name: "{{ ansible_operator_meta.name }}-element-web" 19 | namespace: "{{ ansible_operator_meta.namespace }}" 20 | spec: 21 | type: "{{ service.type | default('ClusterIP', true) }}" 22 | ports: 23 | - port: 80 24 | targetPort: element 25 | name: web 26 | selector: 27 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-element-web" 28 | -------------------------------------------------------------------------------- /roles/elementweb/templates/nginx.conf.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | worker_processes auto; 9 | 10 | error_log stderr warn; 11 | pid /tmp/nginx.pid; 12 | 13 | 14 | events { 15 | worker_connections 1024; 16 | } 17 | 18 | http { 19 | client_body_temp_path /tmp/client_temp; 20 | proxy_temp_path /tmp/proxy_temp_path; 21 | fastcgi_temp_path /tmp/fastcgi_temp; 22 | uwsgi_temp_path /tmp/uwsgi_temp; 23 | scgi_temp_path /tmp/scgi_temp; 24 | 25 | include /etc/nginx/mime.types; 26 | default_type application/octet-stream; 27 | 28 | server_tokens off; 29 | 30 | set_real_ip_from 0.0.0.0/0; 31 | real_ip_header X-Forwarded-For; 32 | 33 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 34 | '$status $body_bytes_sent "$http_referer" ' 35 | '"$http_user_agent"'; 36 | 37 | access_log /var/log/nginx/access.log main; 38 | 39 | sendfile on; 40 | #tcp_nopush on; 41 | 42 | keepalive_timeout 65; 43 | 44 | server { 45 | listen 8080; 46 | 47 | add_header X-Frame-Options SAMEORIGIN; 48 | add_header X-Content-Type-Options nosniff; 49 | add_header X-XSS-Protection "1; mode=block"; 50 | add_header Content-Security-Policy "frame-ancestors 'self'"; 51 | add_header X-Robots-Tag "noindex, nofollow, noarchive, noimageindex"; 52 | 53 | location / { 54 | root /usr/share/nginx/html; 55 | index index.html index.htm; 56 | 57 | charset utf-8; 58 | } 59 | 60 | location = /health { 61 | allow all; 62 | default_type 'application/json'; 63 | return 200 '{"status": "ok"}'; 64 | } 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /roles/elementweb/vars/main.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | # vars file for ElementWeb 8 | -------------------------------------------------------------------------------- /roles/generic_apply/filter_plugins/drop_null_values.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | class FilterModule(object): 7 | def filters(self): return {'drop_null_values': drop_null_values} 8 | 9 | def drop_null_values(data): 10 | if isinstance(data, dict): 11 | data_copy = data.copy() 12 | for k, v in data_copy.items(): 13 | if v == None: 14 | del data[k] 15 | elif isinstance(v, (dict, list)): 16 | drop_null_values(v) 17 | elif isinstance(data, list): 18 | for item in data: 19 | drop_null_values(item) 20 | return data 21 | -------------------------------------------------------------------------------- /roles/generic_apply/filter_plugins/sort_apply_order.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | # Anything not listed below gets sorted after Kinds that have been listed, maintaining the input order 7 | resources_order = [ 8 | "Secret", 9 | "ConfigMap", 10 | "PersistentVolumeClaim", 11 | "Pod", 12 | "Deployment", 13 | "StatefulSet", 14 | "Ingress", 15 | "Service", 16 | # We deploy Synapse here because 17 | # we want to deploy it before every other resources 18 | "Synapse" 19 | ] 20 | 21 | class FilterModule(object): 22 | def filters(self): return {'sort_apply_order': sort_apply_order} 23 | 24 | def _res_order(o): 25 | try: 26 | return resources_order.index(o['kind']) 27 | except ValueError: 28 | return len(resources_order) 29 | 30 | def sort_apply_order(data): 31 | if isinstance(data, list): 32 | data.sort(key=_res_order) 33 | return data 34 | 35 | -------------------------------------------------------------------------------- /roles/generic_apply/filter_plugins/split_regex.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | from ansible.errors import AnsibleError, AnsibleFilterError, AnsibleFilterTypeError 7 | from ansible.module_utils.six import string_types 8 | import re 9 | 10 | class FilterModule(object): 11 | def filters(self): return {'split_regex': split_regex} 12 | 13 | def split_regex(string_value, separator_pattern): 14 | if not isinstance(string_value, (string_types)): 15 | raise AnsibleFilterTypeError("The string value should be a string : %s" % type(string_value)) 16 | if not isinstance(separator_pattern, (string_types)): 17 | raise AnsibleFilterTypeError("The separator pattern should be a string : %s" % type(separator_pattern)) 18 | try: 19 | return re.split(separator_pattern, string_value, flags=re.MULTILINE) 20 | except Exception as e: 21 | raise errors.AnsibleFilterError('split_regex error : %s, provided string: "%s"' % str(e),str(string_value) ) 22 | -------------------------------------------------------------------------------- /roles/generic_apply/tasks/apply_then_recreate.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | - name: Maintain Manifest 8 | block: 9 | - name: Apply Manifest 10 | no_log: "{{ lookup('env', 'DEBUG_MANIFESTS') | int != 1 }}" 11 | kubernetes.core.k8s: 12 | resource_definition: "{{ _manifest }}" 13 | rescue: 14 | - name: Destroy Manifest 15 | no_log: "{{ lookup('env', 'DEBUG_MANIFESTS') | int != 1 }}" 16 | kubernetes.core.k8s: 17 | state: absent 18 | resource_definition: "{{ _manifest }}" 19 | 20 | - name: Apply Manifest from scratch 21 | no_log: "{{ lookup('env', 'DEBUG_MANIFESTS') | int != 1 }}" 22 | kubernetes.core.k8s: 23 | resource_definition: "{{ _manifest }}" 24 | -------------------------------------------------------------------------------- /roles/synapse/defaults/main/haproxy.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | 8 | 9 | 10 | # close client connections 5m after the last request 11 | # (as recommened by https://support.cloudflare.com/hc/en-us/articles/212794707-General-Best-Practices-for-Load-Balancing-with-CloudFlare) 12 | _haproxy_timeout_client: '900s' 13 | 14 | # give clients 5m between requests (otherwise it defaults to the value of 'timeout http-request') 15 | _haproxy_timeout_http_keep_alive: '900s' 16 | 17 | # give clients 10s to complete a request (either time between handshake and first request, or time spent sending headers) 18 | _haproxy_timeout_http_request: '10s' 19 | -------------------------------------------------------------------------------- /roles/synapse/files/haproxy-429.http: -------------------------------------------------------------------------------- 1 | HTTP/1.0 429 Too Many Requests 2 | Cache-Control: no-cache 3 | Connection: close 4 | Content-Type: text/html 5 | access-control-allow-origin: * 6 | access-control-allow-methods: GET, POST, PUT, DELETE, OPTIONS 7 | access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, Authorization 8 | 9 |

429 Too Many Requests

10 | No server is available to handle this request. 11 | 12 | -------------------------------------------------------------------------------- /roles/synapse/files/haproxy-429.http.license: -------------------------------------------------------------------------------- 1 | Copyright 2023 New Vector Ltd 2 | 3 | SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | -------------------------------------------------------------------------------- /roles/synapse/tasks/dependencies.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | - name: Import all dependencies 8 | ansible.builtin.include_tasks: '{{ item }}' 9 | loop: "{{ query('fileglob', 'dependencies/*.yml') | sort }}" 10 | -------------------------------------------------------------------------------- /roles/synapse/tasks/dependencies/registration_files.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | - name: "Fetch ApplicationServices registration files" 8 | vars: 9 | regfile_found_str: | 10 | {% for _cm_name_item in synapse_appservices_registrations %} 11 | {% set _res = query('k8s', 12 | api_version="v1", 13 | kind="ConfigMap", 14 | namespace=ansible_operator_meta.namespace, 15 | resource_name=_cm_name_item 16 | ) %} 17 | {% if _res | length > 0 %} 18 | {{ _res | to_nice_yaml }} 19 | {% endif %} 20 | {% endfor %} 21 | ansible.builtin.set_fact: 22 | regfile_found: >- 23 | {{ 24 | regfile_found_str | from_yaml | select 25 | }} 26 | 27 | - name: "Assert ApplicationServices registration files found" 28 | ansible.builtin.assert: 29 | that: 30 | - (regfile_found | length) == (synapse_appservices_registrations | length) 31 | msg: | 32 | Some ApplicationServices registration files are missing 33 | Expected : {{ synapse_appservices_registrations | join(', ') }} 34 | Found : {{ regfile_found | map(attribute='metadata.name') | join(', ') }} 35 | 36 | # We make sure that all registration files have a registation.yaml key 37 | # and we build a list of hashes 38 | - name: "Lookup the registration files hashes" 39 | no_log: "{{ lookup('env', 'DEBUG_MANIFESTS') | int != 1 }}" 40 | ansible.builtin.set_fact: 41 | _fetched_registration_files_hash: > 42 | {{ 43 | ( 44 | regfile_found 45 | | map(attribute='data') 46 | | community.general.json_query('[]."registration.yaml"') 47 | | map('hash', 'sha1') 48 | ) 49 | }} 50 | failed_when: (_fetched_registration_files_hash | length) != (synapse_appservices_registrations | length) 51 | -------------------------------------------------------------------------------- /roles/synapse/tasks/ingress.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | - name: Merge initial-synchrotron paths into synchrotron paths if initial variant is absent 8 | ansible.builtin.set_fact: 9 | synapse_available_worker_types: > 10 | {{ synapse_available_worker_types 11 | | combine( 12 | { 13 | 'synchrotron': 14 | { 15 | 'paths': synapse_available_worker_types['synchrotron'].paths 16 | + synapse_available_worker_types['initial-synchrotron'].paths 17 | } 18 | }, 19 | recursive=True 20 | ) 21 | }} 22 | when: not synapse_has['initial-synchrotron'] 23 | 24 | - name: "Construct manifests" 25 | ansible.builtin.set_fact: 26 | synapse_manifests: "{{ synapse_manifests + query('template', item) }}" 27 | loop: "{{ _manifest_template_filenames }}" 28 | vars: 29 | _manifest_template_filenames: > 30 | {{ 31 | query('fileglob', 'templates/manifests/haproxy_*.yaml.j2') + [ 32 | role_path ~ '/../synapse/templates/manifests/synapse_http_service.yaml.j2', 33 | role_path ~ '/../synapse/templates/manifests/synapse_ingress.yaml.j2', 34 | ] 35 | }} 36 | -------------------------------------------------------------------------------- /roles/synapse/tasks/redis_setup.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | - name: "Construct Redis manifests" 8 | ansible.builtin.set_fact: 9 | synapse_manifests: "{{ synapse_manifests + query('template', item) }}" 10 | loop: "{{ _manifest_template_filenames }}" 11 | vars: 12 | _manifest_template_filenames: "{{ query('fileglob', 'templates/manifests/redis_*.yaml.j2') }}" 13 | -------------------------------------------------------------------------------- /roles/synapse/tasks/shared.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | - name: Initialise the list of manifests to manage 8 | ansible.builtin.set_fact: 9 | synapse_manifests: [] 10 | 11 | -------------------------------------------------------------------------------- /roles/synapse/tasks/synapse_process.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | # It is somewhat tempting to put the specific ConfigMap into the shared ConfigMap however 8 | # a) that isn't needed 9 | # b) imposes the complexity of having to loop on worker types in multiple places 10 | # e.g. defining has_replication, has_http, process_additional, etc 11 | - name: "Construct manifests - {{ process_type }}" 12 | ansible.builtin.set_fact: 13 | synapse_manifests: "{{ synapse_manifests + query('template', item) }}" 14 | loop: "{{ _manifest_template_filenames }}" 15 | vars: 16 | _manifest_template_filenames: 17 | - "{{ role_path }}/../synapse/templates/manifests/synapse_service.yaml.j2" 18 | - "{{ role_path }}/../synapse/templates/manifests/synapse_config_secrets.yaml.j2" 19 | - "{{ role_path }}/../synapse/templates/manifests/synapse_statefulset.yaml.j2" 20 | -------------------------------------------------------------------------------- /roles/synapse/templates/haproxy-path_map_file.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | # A map file that is used in haproxy config to map from matrix paths to the 9 | # named backend. The format is: path_regexp backend_name 10 | 11 | {% for type, details in synapse_configured_workers | dictsort %} 12 | {% if 'paths' in synapse_available_worker_types[type] %} 13 | {% for path in synapse_available_worker_types[type]['paths'] %} 14 | {{ path }} {{ type }} 15 | {% endfor %} 16 | {% endif %} 17 | {% endfor %} 18 | -------------------------------------------------------------------------------- /roles/synapse/templates/haproxy-path_map_file_get.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | # A map file that is used in haproxy config to map from matrix paths to the 9 | # named backend. The format is: path_regexp backend_name 10 | 11 | 12 | {% for type, details in synapse_configured_workers | dictsort %} 13 | {% if 'paths_get_only' in synapse_available_worker_types[type] %} 14 | {% for path in synapse_available_worker_types[type]['paths_get_only'] %} 15 | {{ path }} {{ type }} 16 | {% endfor %} 17 | {% endif %} 18 | {% endfor %} 19 | -------------------------------------------------------------------------------- /roles/synapse/templates/log_config.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | version: 1 9 | 10 | formatters: 11 | precise: 12 | format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s' 13 | 14 | handlers: 15 | console: 16 | class: logging.StreamHandler 17 | formatter: precise 18 | 19 | loggers: 20 | {# 21 | Increasing synapse.storage.SQL past INFO will log access tokens. Putting in the CRD default will mean it gets 22 | nuked if an override is set and then if the root level is increased to debug, the access tokens will be logged. 23 | Putting here means it is an explicit customer choice to override it. 24 | #} 25 | {% set _overrides = {"synapse.storage.SQL": "INFO"} | combine(_matrix_element_io_synapse_spec.config.log.levelOverrides | default({})) %} 26 | {% for logger, level in _overrides.items() %} 27 | {{ logger }}: 28 | level: "{{ level | upper }}" 29 | {% endfor %} 30 | 31 | root: 32 | level: "{{ config.log.root_level | upper }}" 33 | handlers: 34 | - console 35 | 36 | disable_existing_loggers: false 37 | -------------------------------------------------------------------------------- /roles/synapse/templates/manifests/haproxy_configmap.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | apiVersion: v1 9 | kind: ConfigMap 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: synapse-haproxy 13 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-synapse-haproxy" 14 | app.kubernetes.io/part-of: matrix-stack 15 | app.kubernetes.io/component: matrix-server-ingress 16 | app.kubernetes.io/version: "{{ image.haproxy_tag }}" 17 | name: "{{ ansible_operator_meta.name }}-synapse-haproxy" 18 | namespace: "{{ ansible_operator_meta.namespace }}" 19 | data: 20 | haproxy.cfg: | 21 | {{ lookup('template', 'haproxy.cfg.j2') | indent(4) }} 22 | path_map_file: | 23 | {{ lookup('template', 'haproxy-path_map_file.j2') | indent(4) }} 24 | path_map_file_get: | 25 | {{ lookup('template', 'haproxy-path_map_file_get.j2') | indent(4) }} 26 | 429.http: | 27 | {{ lookup('file', 'haproxy-429.http', rstrip=false) | indent(4) }} 28 | -------------------------------------------------------------------------------- /roles/synapse/templates/manifests/redis_configmap.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | apiVersion: v1 9 | kind: ConfigMap 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: synapse-redis 13 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-synapse-redis" 14 | app.kubernetes.io/part-of: matrix-stack 15 | app.kubernetes.io/component: matrix-server-pubsub 16 | app.kubernetes.io/version: "{{ image.redis_tag }}" 17 | name: "{{ ansible_operator_meta.name }}-synapse-redis" 18 | namespace: "{{ ansible_operator_meta.namespace }}" 19 | data: 20 | redis.conf: | 21 | {{ redis_config | indent(4) }} 22 | -------------------------------------------------------------------------------- /roles/synapse/templates/manifests/redis_service.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | apiVersion: v1 9 | kind: Service 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: synapse-redis 13 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-synapse-redis" 14 | app.kubernetes.io/part-of: matrix-stack 15 | app.kubernetes.io/component: matrix-server-pubsub 16 | app.kubernetes.io/version: "{{ image.redis_tag }}" 17 | name: "{{ ansible_operator_meta.name }}-synapse-redis" 18 | namespace: "{{ ansible_operator_meta.namespace }}" 19 | spec: 20 | ports: 21 | - port: 6379 22 | targetPort: redis 23 | selector: 24 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-synapse-redis" 25 | -------------------------------------------------------------------------------- /roles/synapse/templates/manifests/synapse_config_secrets.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | apiVersion: v1 9 | kind: Secret 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: synapse-{{ process_type }} 13 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-synapse-{{ process_type }}" 14 | app.kubernetes.io/part-of: matrix-stack 15 | app.kubernetes.io/component: matrix-server 16 | app.kubernetes.io/version: "{{ image.tag }}" 17 | name: "{{ ansible_operator_meta.name }}-synapse-{{ process_type }}" 18 | namespace: "{{ ansible_operator_meta.namespace }}" 19 | data: 20 | {% set _secrets_template_files = query('fileglob', 'templates/secrets/*.yaml.j2') | sort %} 21 | {% set _config_secrets = query('template', *_secrets_template_files, convert_data=false) | select | map('trim') | select | map('from_yaml') %} 22 | {% if _config_secrets | length > 0 %} 23 | instance_template.yaml: {{ {} | combine(_config_secrets, recursive=true) | to_nice_yaml(indent=2) | b64encode }} 24 | {% endif %} 25 | log_config.yaml: {{ log_config_yaml | b64encode }} 26 | -------------------------------------------------------------------------------- /roles/synapse/templates/manifests/synapse_http_service.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | --- 9 | apiVersion: v1 10 | kind: Service 11 | metadata: 12 | labels: 13 | app.kubernetes.io/name: synapse-haproxy 14 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-synapse-haproxy" 15 | app.kubernetes.io/part-of: matrix-stack 16 | app.kubernetes.io/component: matrix-server-ingress 17 | app.kubernetes.io/version: "{{ image.haproxy_tag }}" 18 | name: "{{ ansible_operator_meta.name }}-synapse-haproxy" 19 | namespace: "{{ ansible_operator_meta.namespace }}" 20 | spec: 21 | type: "{{ service.type | default('ClusterIP', true) }}" 22 | ports: 23 | - name: haproxy-http 24 | port: 8008 25 | targetPort: haproxy-http 26 | - name: haproxy-403 27 | port: 8009 28 | targetPort: haproxy-403 29 | - name: haproxy-metrics 30 | port: 8405 31 | targetPort: haproxy-metrics 32 | selector: 33 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-synapse-haproxy" 34 | -------------------------------------------------------------------------------- /roles/synapse/templates/manifests/synapse_service.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | apiVersion: v1 9 | kind: Service 10 | metadata: 11 | labels: 12 | app.kubernetes.io/name: synapse-{{ process_type }} 13 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-synapse-{{ process_type }}" 14 | app.kubernetes.io/part-of: matrix-stack 15 | app.kubernetes.io/component: matrix-server 16 | app.kubernetes.io/version: "{{ image.tag }}" 17 | k8s.element.io/synapse-instance: "{{ ansible_operator_meta.name }}-synapse" 18 | k8s.element.io/service-type: headless 19 | name: "{{ ansible_operator_meta.name }}-synapse-{{ process_type }}" 20 | namespace: "{{ ansible_operator_meta.namespace }}" 21 | spec: 22 | clusterIP: None 23 | ports: 24 | {% if has_http %} 25 | - name: synapse-http 26 | port: 8008 27 | targetPort: synapse-http 28 | {% endif %} 29 | - name: synapse-health 30 | port: 8080 31 | targetPort: synapse-health 32 | {% if has_replication %} 33 | - name: synapse-repl 34 | port: 9093 35 | targetPort: synapse-repl 36 | {% endif %} 37 | - name: synapse-metrics 38 | port: 9001 39 | targetPort: synapse-metrics 40 | selector: 41 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-synapse-{{ process_type }}" 42 | -------------------------------------------------------------------------------- /roles/synapse/templates/secrets/10-defaults.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | report_stats: false 9 | 10 | require_auth_for_profile_requests: true 11 | -------------------------------------------------------------------------------- /roles/synapse/templates/secrets/20-additional.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {% if config.additional is defined %} 9 | {{ config.additional }} 10 | {% endif %} 11 | 12 | {%- if 'shared.yaml' in _fetched_synapse_secrets[0].data -%} 13 | {{ _fetched_synapse_secrets[0].data['shared.yaml'] | b64decode }} 14 | {%- endif -%} 15 | -------------------------------------------------------------------------------- /roles/synapse/templates/secrets/20-worker-additional.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {% if process_additional | length > 0 %} 9 | {{ process_additional }} 10 | {% endif %} 11 | 12 | {%- if (process_type ~ '.yaml') in _fetched_synapse_secrets[0].data -%} 13 | {{ _fetched_synapse_secrets[0].data[process_type ~ '.yaml'] | b64decode }} 14 | {% endif %} 15 | -------------------------------------------------------------------------------- /roles/synapse/templates/secrets/25-registration.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {% if synapse_appservices_registrations | length > 0 %} 9 | app_service_config_files: 10 | {% for as_registration in synapse_appservices_registrations %} 11 | - /as/{{ as_registration }}/registration.yaml 12 | {% endfor %} 13 | {% endif %} 14 | -------------------------------------------------------------------------------- /roles/synapse/templates/secrets/25-with-workers.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | {% if has_any_workers %} 9 | redis: 10 | enabled: true 11 | host: "{{ ansible_operator_meta.name }}-synapse-redis.{{ ansible_operator_meta.namespace }}.svc.cluster.local" 12 | 13 | presence: 14 | enabled: {{ not synapse_has['presence-writer'] }} 15 | 16 | {% if synapse_stream_writer_worker_types | map('extract', synapse_has) | select('equalto', true) | list | length > 0 %} 17 | instance_map: 18 | {% for type in synapse_stream_writer_worker_types %} 19 | {% for index in range(synapse_configured_workers[type].instances | default(0)) %} 20 | {{ type }}-{{ index }}: 21 | host: {{ ansible_operator_meta.name }}-synapse-{{ type }}-{{ index }}.{{ ansible_operator_meta.name }}-synapse-{{ type }}.{{ ansible_operator_meta.namespace }}.svc.cluster.local. 22 | port: 9093 23 | {% endfor %} 24 | {% endfor %} 25 | 26 | stream_writers: 27 | {% for type in synapse_stream_writer_worker_types %} 28 | {% if (synapse_configured_workers[type].instances | default(0)) > 0 %} 29 | {% for stream_writer in synapse_available_worker_types[type].stream_writers %} 30 | {% if synapse_available_worker_types[type].single %} 31 | {{ stream_writer }}: {{ type }}-0 32 | {% else %} 33 | {{ stream_writer }}: 34 | {% for index in range(synapse_configured_workers[type].instances) %} 35 | - {{ type }}-{{ index }} 36 | {% endfor %} 37 | {% endif %} 38 | {% endfor %} 39 | {% endif %} 40 | {% endfor %} 41 | 42 | 43 | {% endif %} 44 | {% endif %} 45 | -------------------------------------------------------------------------------- /roles/teardown/defaults/main.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | kinds_to_teardown: "{{ default_kinds_to_teardown + additional_kinds_to_teardown }}" 8 | default_kinds_to_teardown: 9 | - kind: Deployment 10 | api_version: apps/v1 11 | - kind: StatefulSet 12 | api_version: apps/v1 13 | - kind: DaemonSet 14 | api_version: apps/v1 15 | - kind: Secret 16 | api_version: v1 17 | - kind: ConfigMap 18 | api_version: v1 19 | - kind: Service 20 | api_version: v1 21 | - kind: Ingress 22 | api_version: networking.k8s.io/v1 23 | 24 | additional_kinds_to_teardown: [] 25 | -------------------------------------------------------------------------------- /roles/teardown/filter_plugins/mapattributes.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | class FilterModule(object): 7 | def filters(self): 8 | return { 'mapattributes': self.mapattributes } 9 | 10 | def mapattributes(self, list_of_dicts, list_of_keys): 11 | l = [] 12 | for di in list_of_dicts: 13 | newdi = { } 14 | for key in list_of_keys: 15 | newdi[key] = di[key] 16 | l.append(newdi) 17 | return l 18 | -------------------------------------------------------------------------------- /roles/wellknowndelegation/defaults/main.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | image_repository: nginx 8 | image_pull_secrets: [] 9 | image_has_digest: "{{ (image.digest | default('')) | length > 0 }}" 10 | image_pull_policy: "{{ image_has_digest | ternary('IfNotPresent', 'Always') }}" 11 | 12 | replicas: 2 13 | 14 | nginx_config: "{{ lookup('file', 'nginx.conf') }}" 15 | client_json: "{{ lookup('template', 'client.j2') | from_json }}" 16 | server_json: "{{ lookup('template', 'server.j2') | from_json }}" 17 | element_json: "{{ config.element | default('{}') | from_json }}" 18 | -------------------------------------------------------------------------------- /roles/wellknowndelegation/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | - name: "Manage manifests" 8 | ansible.builtin.include_role: 9 | name: "generic_apply" 10 | vars: 11 | _manifest_template_filenames: "{{ query('fileglob', 'templates/manifests/*.yaml.j2') }}" 12 | -------------------------------------------------------------------------------- /roles/wellknowndelegation/templates/client.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | { 9 | {% if config.client is defined %} 10 | "m.homeserver": { 11 | "base_url": "{{ config.client.homeserver_base_url }}" 12 | }{% if config.client.additional | default("") | trim | length > 0 %}, 13 | {{ config.client.additional }} 14 | {% endif %} 15 | {% endif %} 16 | } 17 | -------------------------------------------------------------------------------- /roles/wellknowndelegation/templates/manifests/wellknown_configmap.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | apiVersion: v1 9 | kind: ConfigMap 10 | metadata: 11 | labels: 12 | app.kubernetes.io/part-of: matrix-stack 13 | app.kubernetes.io/component: matrix-delegation 14 | app.kubernetes.io/name: well-known 15 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-well-known" 16 | app.kubernetes.io/version: "{{ image.tag }}" 17 | name: "{{ ansible_operator_meta.name }}-well-known" 18 | namespace: "{{ ansible_operator_meta.namespace }}" 19 | data: 20 | client: |- 21 | {{ client_json | to_nice_json | indent(4) }} 22 | server: |- 23 | {{ server_json | to_nice_json | indent(4) }} 24 | element.json: |- 25 | {{ element_json | to_nice_json | indent(4) }} 26 | -------------------------------------------------------------------------------- /roles/wellknowndelegation/templates/manifests/wellknown_ingress.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | apiVersion: networking.k8s.io/v1 9 | kind: Ingress 10 | metadata: 11 | annotations: 12 | {{ _matrix_element_io_wellknowndelegation_spec.ingress.annotations | default({}) | to_nice_yaml(2) | indent(4) }} 13 | labels: 14 | app.kubernetes.io/part-of: matrix-stack 15 | app.kubernetes.io/component: matrix-delegation 16 | app.kubernetes.io/name: well-known 17 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-well-known" 18 | app.kubernetes.io/version: "{{ image.tag }}" 19 | name: "{{ ansible_operator_meta.name }}-well-known" 20 | namespace: "{{ ansible_operator_meta.namespace }}" 21 | spec: 22 | {% if ingress.tls_secret | default(false) %} 23 | tls: 24 | - hosts: 25 | - "{{ ingress.domain_name }}" 26 | secretName: "{{ ingress.tls_secret }}" 27 | {% endif %} 28 | {% if ingress.ingress_class_name | default(false) %} 29 | ingressClassName: "{{ ingress.ingress_class_name }}" 30 | {% endif %} 31 | rules: 32 | - host: "{{ ingress.domain_name }}" 33 | http: 34 | paths: 35 | - path: /.well-known/matrix 36 | pathType: Prefix 37 | backend: 38 | service: 39 | name: "{{ ansible_operator_meta.name }}-well-known" 40 | port: 41 | number: 80 42 | - path: /.well-known/element 43 | pathType: Prefix 44 | backend: 45 | service: 46 | name: "{{ ansible_operator_meta.name }}-well-known" 47 | port: 48 | number: 80 49 | -------------------------------------------------------------------------------- /roles/wellknowndelegation/templates/manifests/wellknown_nginx_configmap.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | apiVersion: v1 9 | kind: ConfigMap 10 | metadata: 11 | labels: 12 | app.kubernetes.io/part-of: matrix-stack 13 | app.kubernetes.io/component: matrix-delegation 14 | app.kubernetes.io/name: well-known 15 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-well-known" 16 | app.kubernetes.io/version: "{{ image.tag }}" 17 | name: "{{ ansible_operator_meta.name }}-well-known-nginx" 18 | namespace: "{{ ansible_operator_meta.namespace }}" 19 | data: 20 | nginx.conf: |- 21 | {{ nginx_config | indent(4) }} 22 | -------------------------------------------------------------------------------- /roles/wellknowndelegation/templates/manifests/wellknown_service.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | --- 9 | apiVersion: v1 10 | kind: Service 11 | metadata: 12 | labels: 13 | app.kubernetes.io/part-of: matrix-stack 14 | app.kubernetes.io/component: matrix-delegation 15 | app.kubernetes.io/name: well-known 16 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-well-known" 17 | app.kubernetes.io/version: "{{ image.tag }}" 18 | name: "{{ ansible_operator_meta.name }}-well-known" 19 | namespace: "{{ ansible_operator_meta.namespace }}" 20 | spec: 21 | type: "{{ service.type | default('ClusterIP', true) }}" 22 | ports: 23 | - port: 80 24 | name: web 25 | targetPort: well-known 26 | selector: 27 | app.kubernetes.io/instance: "{{ ansible_operator_meta.name }}-well-known" 28 | -------------------------------------------------------------------------------- /roles/wellknowndelegation/templates/server.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Copyright 2023-2024 New Vector Ltd 3 | 4 | SPDX-License-Identifier: AGPL-3.0-or-later 5 | 6 | #} 7 | 8 | { 9 | {% if config.federation is defined %} 10 | "m.server": "{{ config.federation.endpoint }}"{% if config.federation.additional | default("") | trim | length > 0 %}, 11 | {{ config.federation.additional }} 12 | {% endif %} 13 | {% endif %} 14 | } 15 | -------------------------------------------------------------------------------- /roles/wellknowndelegation/vars/main.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | --- 7 | # vars file for WellKnownDelegation 8 | -------------------------------------------------------------------------------- /watches.updater.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | - version: v1alpha2 6 | group: matrix.element.io 7 | kind: ElementDeployment 8 | playbook: playbooks/elementdeployment.yml 9 | watchAnnotationsChanges: true 10 | markUnsafe: true 11 | maxRunnerArtifacts: 3 12 | vars: 13 | _kind: ElementDeployment 14 | _api_version: matrix.element.io/v1alpha2 15 | element_operator_crds: 16 | - kind: ElementWeb 17 | api_version: matrix.element.io/v1alpha1 18 | - kind: Synapse 19 | api_version: matrix.element.io/v1alpha2 20 | - kind: WellKnownDelegation 21 | api_version: matrix.element.io/v1alpha1 22 | -------------------------------------------------------------------------------- /watches.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2024 New Vector Ltd 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | - version: v1alpha1 6 | group: matrix.element.io 7 | kind: ElementWeb 8 | playbook: playbooks/any.yml 9 | watchAnnotationsChanges: true 10 | markUnsafe: true 11 | maxRunnerArtifacts: 3 12 | vars: 13 | _kind: ElementWeb 14 | _api_version: matrix.element.io/v1alpha1 15 | - version: v1alpha2 16 | group: matrix.element.io 17 | kind: Synapse 18 | playbook: playbooks/any.yml 19 | watchAnnotationsChanges: true 20 | markUnsafe: true 21 | maxRunnerArtifacts: 3 22 | vars: 23 | _kind: Synapse 24 | _api_version: matrix.element.io/v1alpha2 25 | - version: v1alpha1 26 | group: matrix.element.io 27 | kind: WellKnownDelegation 28 | playbook: playbooks/any.yml 29 | watchAnnotationsChanges: true 30 | markUnsafe: true 31 | maxRunnerArtifacts: 3 32 | vars: 33 | _kind: WellKnownDelegation 34 | _api_version: matrix.element.io/v1alpha1 35 | --------------------------------------------------------------------------------