diff --git a/charts/matrix/.gitignore b/charts/matrix/.gitignore new file mode 100644 index 0000000..a8d4be7 --- /dev/null +++ b/charts/matrix/.gitignore @@ -0,0 +1,2 @@ +.idea/ +charts/ diff --git a/charts/matrix/.helmignore b/charts/matrix/.helmignore new file mode 100644 index 0000000..cdd8ee1 --- /dev/null +++ b/charts/matrix/.helmignore @@ -0,0 +1,4 @@ +.git/ +.idea/ +.gitignore +README.md diff --git a/charts/matrix/Chart.lock b/charts/matrix/Chart.lock new file mode 100644 index 0000000..8b3b211 --- /dev/null +++ b/charts/matrix/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: postgresql + repository: https://kubernetes-charts.storage.googleapis.com + version: 8.0.0 +digest: sha256:54b8dbbf92f98a307a15de995f41897aa3ea3f3252b6f594d058530755b3dfa8 +generated: "2020-03-30T22:24:34.251333366-07:00" diff --git a/charts/matrix/Chart.yaml b/charts/matrix/Chart.yaml new file mode 100644 index 0000000..27a9850 --- /dev/null +++ b/charts/matrix/Chart.yaml @@ -0,0 +1,36 @@ +apiVersion: v2 +name: matrix +description: A Helm chart to deploy a Matrix homeserver stack into Kubernetes +icon: "https://dacruz21.github.io/helm-charts/icons/matrix.svg" +home: "https://github.com/dacruz21/matrix-chart" +sources: + - "https://github.com/dacruz21/matrix-chart" + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +version: 2.8.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. +appVersion: 1.22.1 + +maintainers: + - name: "David Cruz" + email: "david@typokign.com" + url: "https://github.com/dacruz21/" + +dependencies: + - name: postgresql + version: 8.0.0 + repository: https://kubernetes-charts.storage.googleapis.com + condition: postgresql.enabled diff --git a/charts/matrix/LICENSE b/charts/matrix/LICENSE new file mode 100644 index 0000000..971cbb3 --- /dev/null +++ b/charts/matrix/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2021 David Cruz + +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: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +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. + diff --git a/charts/matrix/README.md b/charts/matrix/README.md new file mode 100644 index 0000000..61f1a29 --- /dev/null +++ b/charts/matrix/README.md @@ -0,0 +1,68 @@ +# Matrix Chart + +A Helm chart for deploying a Matrix homeserver stack in Kubernetes. + +## Features + +- Latest version of Synapse +- (Optional) Latest version of Riot Web +- (Optional) Choice of lightweight Exim relay or external mail server for email notifications +- (Optional) Coturn TURN server for VoIP calls +- (Optional) PostgreSQL cluster via stable/postgresql chart +- (Optional) [matrix-org/matrix-appservice-irc](https://github.com/matrix-org/matrix-appservice-irc) IRC bridge +- (Optional) [tulir/mautrix-whatsapp](https://github.com/tulir/mautrix-whatsapp) WhatsApp bridge +- (Optional) [Half-Shot/matrix-appservice-discord](https://github.com/Half-Shot/matrix-appservice-discord) Discord bridge +- Fully configurable via values.yaml +- Ingress definition for federated Synapse and Riot + +## Installation + +Some documentation is available in values.yaml, and a complete configuration guide is coming soon. + +Choose one of the two options below to install the chart. + +### Chart Repository (recommended) + +This chart is published to my Helm chart repository at https://dacruz21.github.io/helm-charts. To install this chart: + +1. Create an empty chart to hold your configuration + + ```shell script + helm create mychart + cd mychart + ``` + +1. Add this chart to your chart's dependencies by editing `Chart.yaml` and adding the following lines: + + ```yaml + dependencies: + - name: matrix + version: 2.8.0 + repository: https://dacruz21.github.io/helm-charts + ``` + +1. Run `helm dependency update` to download the chart into the `charts/` directory. + +1. Configure the chart by editing `values.yaml`, adding a `matrix:` object, and adding any config overrides under this object. + +1. Deploy your customized chart with `helm install mychart .` + +### Git + +You can also clone this repo directly and override the values.yaml provided. To do so, run the following commands: + +```shell script +git clone https://github.com/dacruz21/matrix-chart.git +cd matrix-chart +helm dependency update +helm install matrix . +``` + +## Security +Helm currently [does not officially support chart signatures created by GPG keys stored on smartcards](https://github.com/helm/helm/issues/2843#issuecomment-379532906). This may change in the future, in which case I will start packaging this chart with the standard `.prov` signatures, but until then signatures must be verified manually. + +GPG signatures are available within the chart repo and can be found by appending `.gpg` to the end of the package URL. For example, the signature for v2.8.0 is available at https://dacruz21.github.io/helm-charts/matrix-2.8.0.tgz.gpg. + +These GPG signatures are signed with the same PGP key that is used to sign commits in this Git repository. The key is available by searching for david@typokign.com on a public keyserver, or by downloading it from my website at https://typokign.com/key.gpg. + +If you find any security vulnerabilities in this Helm chart, please contact me by sending a PGP-encrypted email (encrypted to `F13C346C0DE56944`) to david@typokign.com. Vulnerabilities in upstream services should be reported to that service's developers. diff --git a/charts/matrix/templates/NOTES.txt b/charts/matrix/templates/NOTES.txt new file mode 100644 index 0000000..8d7c939 --- /dev/null +++ b/charts/matrix/templates/NOTES.txt @@ -0,0 +1,58 @@ +{{- if .Release.IsInstall }} +dacruz21/matrix-chart has been installed! + +Installed components: + - Synapse ({{ .Values.synapse.image.repository }}) +{{- if .Values.riot.enabled }} + - Element Web ({{ .Values.riot.image.repository }}) +{{- end }} +{{- if .Values.postgresql.enabled }} + - PostgreSQL ({{ .Values.postgresql.image.repository }}) +{{- end }} +{{- if .Values.coturn.enabled }} + - Coturn ({{ .Values.coturn.image.repository }}) +{{- end }} +{{- if .Values.mail.relay.enabled }} + - Exim Relay ({{ .Values.mail.relay.image.repository }}) +{{- end }} +{{- if .Values.bridges.irc.enabled }} + - IRC Bridge ({{ .Values.bridges.irc.image.repository }}) +{{- end }} +{{- if .Values.bridges.whatsapp.enabled }} + - WhatsApp Bridge ({{ .Values.bridges.whatsapp.image.repository }}) +{{- end }} +{{- if .Values.bridges.discord.enabled }} + - Discord Bridge ({{ .Values.bridges.discord.image.repository }}) +{{- end }} + +Thank you for installing dacruz21/matrix-chart! If you have any questions or run into any issues, please file a GitHub issue or join us at #matrix-chart:typokign.com. + +{{ if .Values.ingress.enabled }} +Your Synapse homeserver should soon be available at https://{{ .Values.ingress.hosts.synapse }} +{{- if .Values.riot.enabled }} +Your Element Web instance should soon be available at https://{{ .Values.ingress.hosts.riot }} +{{- end }} +{{- end }} + +{{ if .Values.bridges.irc.enabled }} +The IRC bridge has been enabled! + +You can now join IRC channels on any servers you have configured by joining #:{{ .Values.matrix.serverName }}. +For more information, check out the official documentation at https://github.com/matrix-org/matrix-appservice-irc +{{- end }} + +{{ if .Values.bridges.whatsapp.enabled }} +The WhatsApp bridge has been enabled! + +To get started, start a chat with the bridge bot (@{{ .Values.bridges.whatsapp.bot.username }}:{{ .Values.matrix.serverName }}). +For more information, check out the official documentation at https://github.com/tulir/mautrix-whatsapp/wiki/Authentication +{{- end }} + +{{ if .Values.bridges.discord.enabled }} +The Discord bridge has been enabled! + +You'll need to follow the instructions at https://github.com/Half-Shot/matrix-appservice-discord#setting-up-discord to finish setting up the bridge + +When you've finished setting up the bridge, head to https://discord.com/oauth2/authorize?client_id={{ .Values.bridges.discord.auth.clientId }}&scope=bot&permissions=607251456 to invite the bridge bot to a Discord guild. +{{- end }} +{{- end }} diff --git a/charts/matrix/templates/_helpers.tpl b/charts/matrix/templates/_helpers.tpl new file mode 100644 index 0000000..67c126b --- /dev/null +++ b/charts/matrix/templates/_helpers.tpl @@ -0,0 +1,114 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "matrix.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "matrix.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "matrix.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "matrix.labels" -}} +helm.sh/chart: {{ include "matrix.chart" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/name: "matrix" +{{- end -}} +# TODO: Include labels from values +{{/* +Synapse specific labels +*/}} +{{- define "matrix.synapse.labels" -}} +{{- range $key, $val := .Values.synapse.labels -}} +{{ $key }}: {{ $val }} +{{- end }} +{{- end -}} + +{{/* +Element specific labels +*/}} +#TOOO: Change riot to element +{{- define "matrix.element.labels" -}} +{{- range $key, $val := .Values.riot.labels }} +{{ $key }}: {{ $val }} +{{- end }} +{{- end -}} + +{{/* +Coturn specific labels +*/}} +{{- define "matrix.coturn.labels" -}} +{{- range $key, $val := .Values.coturn.labels -}} +{{ $key }}: {{ $val }} +{{- end }} +{{- end -}} + +{{/* +Mail relay specific labels +*/}} +{{- define "matrix.mail.labels" -}} +{{- range $key, $val := .Values.mail.relay.labels -}} +{{ $key }}: {{ $val }} +{{- end }} +{{- end -}} + +{{/* +Synapse hostname, derived from either the Values.matrix.hostname override or the Ingress definition +*/}} +{{- define "matrix.hostname" -}} +{{- if .Values.matrix.hostname }} +{{- .Values.matrix.hostname -}} +{{- else }} +{{- .Values.ingress.hosts.synapse -}} +{{- end }} +{{- end }} + +{{/* +Synapse hostname prepended with https:// to form a complete URL +*/}} +{{- define "matrix.baseUrl" -}} +{{- if .Values.matrix.hostname }} +{{- printf "https://%s" .Values.matrix.hostname -}} +{{- else }} +{{- printf "https://%s" .Values.ingress.hosts.synapse -}} +{{- end }} +{{- end }} + +{{/* +Helper function to get a postgres connection string for the database, with all of the auth and SSL settings automatically applied +*/}} +{{- define "matrix.postgresUri" -}} +{{- if .Values.postgresql.enabled -}} +postgres://{{ .Values.postgresql.username }}:{{ .Values.postgresql.password }}@{{ include "matrix.fullname" . }}-postgresql/%s{{ if .Values.postgresql.ssl }}?ssl=true&sslmode={{ .Values.postgresql.sslMode}}{{ end }} +{{- else -}} +postgres://{{ .Values.postgresql.username }}:{{ .Values.postgresql.password }}@{{ .Values.postgresql.hostname }}:{{ .Values.postgresql.port }}/%s{{ if .Values.postgresql.ssl }}?ssl=true&sslmode={{ .Values.postgresql.sslMode }}{{ end }} +{{- end }} +{{- end }} diff --git a/charts/matrix/templates/bridge-discord/_helpers.tpl b/charts/matrix/templates/bridge-discord/_helpers.tpl new file mode 100644 index 0000000..2c94255 --- /dev/null +++ b/charts/matrix/templates/bridge-discord/_helpers.tpl @@ -0,0 +1,11 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Shared secret for the discord server +*/}} +{{- define "matrix.discord.as_token" -}} +{{- randAlphaNum 64 -}} +{{- end -}} + +{{- define "matrix.discord.hs_token" -}} +{{- randAlphaNum 64 -}} +{{- end -}} diff --git a/charts/matrix/templates/bridge-discord/configmap.yaml b/charts/matrix/templates/bridge-discord/configmap.yaml new file mode 100644 index 0000000..436b222 --- /dev/null +++ b/charts/matrix/templates/bridge-discord/configmap.yaml @@ -0,0 +1,109 @@ +{{- if .Values.bridges.discord.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "matrix.fullname" . }}-discord-config + labels: + {{ include "matrix.labels" . | nindent 4}} +data: + config.yaml: | + bridge: + # Domain part of the bridge, e.g. matrix.org + domain: {{ .Values.matrix.serverName }} + # This should be your publically facing URL because Discord may use it to + # fetch media from the media store. + homeserverUrl: "{{ include "matrix.baseUrl" . }}" + # Interval at which to process users in the 'presence queue'. If you have + # 5 users, one user will be processed every 500 milliseconds according to the + # value below. This has a minimum value of 250. + # WARNING: This has a high chance of spamming the homeserver with presence + # updates since it will send one each time somebody changes state or is online. + presenceInterval: 500 + # Disable setting presence for 'ghost users' which means Discord users on Matrix + # will not be shown as away or online. + disablePresence: {{ not .Values.bridges.discord.presence }} + # Disable sending typing notifications when somebody on Discord types. + disableTypingNotifications: {{ .Values.bridges.discord.typingNotifications }} + # Disable deleting messages on Discord if a message is redacted on Matrix. + disableDeletionForwarding: false + # Enable users to bridge rooms using !discord commands. See + # https://t2bot.io/discord for instructions. + enableSelfServiceBridging: {{ .Values.bridges.discord.selfService }} + # Disable sending of read receipts for Matrix events which have been + # successfully bridged to Discord. + disableReadReceipts: {{ not .Values.bridges.discord.readReceipt }} + # Disable Join Leave echos from matrix + disableJoinLeaveNotifications: {{ not .Values.bridges.discord.joinLeaveEvents }} + # Authentication configuration for the discord bot. + auth: + clientID: {{ .Values.bridges.discord.auth.clientId | quote }} + botToken: {{ .Values.bridges.discord.auth.botToken | quote }} + logging: + # What level should the logger output to the console at. + console: "warn" #silly, verbose, info, http, warn, error, silent + lineDateFormat: "MMM-D HH:mm:ss.SSS" # This is in moment.js format + files: [] + database: + userStorePath: "/data/user-store.db" + roomStorePath: "/data/room-store.db" + # You may either use SQLite or Postgresql for the bridge database, which contains + # important mappings for events and user puppeting configurations. + # Use the filename option for SQLite, or connString for Postgresql. + # If you are migrating, see https://github.com/Half-Shot/matrix-appservice-discord/blob/master/docs/howto.md#migrate-to-postgres-from-sqlite + # WARNING: You will almost certainly be fine with sqlite unless your bridge + # is in heavy demand and you suffer from IO slowness. + filename: "/data/discord.db" + # connString: "postgresql://user:password@localhost/database_name" + room: + # Set the default visibility of alias rooms, defaults to "public". + # One of: "public", "private" + defaultVisibility: {{ .Values.bridges.discord.defaultVisibility }} + channel: + # Pattern of the name given to bridged rooms. + # Can use :guild for the guild name and :name for the channel name. + namePattern: {{ .Values.bridges.discord.channelName | quote }} + # Changes made to rooms when a channel is deleted. + deleteOptions: + # Prefix the room name with a string. + #namePrefix: "[Deleted]" + # Prefix the room topic with a string. + #topicPrefix: "This room has been deleted" + # Disable people from talking in the room by raising the event PL to 50 + disableMessaging: false + # Remove the discord alias from the room. + unsetRoomAlias: true + # Remove the room from the directory. + unlistFromDirectory: true + # Set the room to be unavaliable for joining without an invite. + setInviteOnly: true + # Make all the discord users leave the room. + ghostsLeave: true + limits: + # Delay in milliseconds between discord users joining a room. + roomGhostJoinDelay: 6000 + # Delay in milliseconds before sending messages to discord to avoid echos. + # (Copies of a sent message may arrive from discord before we've + # fininished handling it, causing us to echo it back to the room) + discordSendDelay: 750 + ghosts: + # Pattern for the ghosts nick, available is :nick, :username, :tag and :id + nickPattern: {{ .Values.bridges.discord.users.nickname | quote }} + # Pattern for the ghosts username, available is :username, :tag and :id + usernamePattern: {{ .Values.bridges.discord.users.username | quote }} + registration.yaml: | + id: appservice-discord + as_token: "{{ include "matrix.discord.as_token" . }}" + hs_token: "{{ include "matrix.discord.hs_token" . }}" + namespaces: + users: + - exclusive: true + regex: '^@_discord_.*' + aliases: + - exclusive: true + regex: '^#_discord_.*' + url: "http://{{ include "matrix.fullname" . }}-bridge-discord:{{ .Values.bridges.discord.service.port }}" + sender_localpart: _discord_bot + rate_limited: false + protocols: + - discord +{{- end }} diff --git a/charts/matrix/templates/bridge-discord/data-pvc.yaml b/charts/matrix/templates/bridge-discord/data-pvc.yaml new file mode 100644 index 0000000..05737c8 --- /dev/null +++ b/charts/matrix/templates/bridge-discord/data-pvc.yaml @@ -0,0 +1,17 @@ +{{- if .Values.bridges.discord.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "matrix.fullname" . }}-discord-data + labels: +{{ include "matrix.labels" . | indent 4}} +spec: + {{- if .Values.bridges.discord.data.storageClass }} + storageClassName: {{ .Values.bridges.discord.data.storageClass }} + {{- end }} + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.bridges.discord.data.capacity }} +{{- end }} diff --git a/charts/matrix/templates/bridge-discord/deployment.yaml b/charts/matrix/templates/bridge-discord/deployment.yaml new file mode 100644 index 0000000..09378ba --- /dev/null +++ b/charts/matrix/templates/bridge-discord/deployment.yaml @@ -0,0 +1,105 @@ +{{- if .Values.bridges.discord.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "matrix.fullname" . }}-bridge-discord + labels: +{{ include "matrix.labels" . | indent 4 }} +spec: + replicas: {{ .Values.bridges.discord.replicaCount }} + strategy: + rollingUpdate: + maxUnavailable: 1 + maxSurge: 0 + type: RollingUpdate + selector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-bridge-discord + app.kubernetes.io/instance: {{ .Release.Name }} + matrix-chart/allow-synapse-access: allow + template: + metadata: + annotations: + # re-roll deployment on config change + checksum/discord-config: {{ include (print $.Template.BasePath "/bridge-discord/configmap.yaml") . | sha256sum }} + labels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-bridge-discord + app.kubernetes.io/instance: {{ .Release.Name }} + matrix-chart/allow-synapse-access: allow + spec: + {{- if .Values.bridges.affinity }} + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - {{ include "matrix.name" . }}-synapse + - key: app.kubernetes.io/instance + operator: In + values: + - {{ .Release.Name }} + topologyKey: kubernetes.io/hostname + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + initContainers: + - name: "load-config" + image: "{{ .Values.bridges.discord.image.repository }}:{{ .Values.bridges.discord.image.tag }}" + imagePullPolicy: {{ .Values.bridges.discord.image.pullPolicy }} + command: ["sh"] + args: ["-c", "cp /load/registration.yaml /data/discord-registration.yaml; cp /load/config.yaml /data/config.yaml; cp /load/registration.yaml /bridges/discord.yaml"] + volumeMounts: + - name: data + mountPath: /data + - name: bridges + mountPath: /bridges + - name: config + mountPath: /load + readOnly: true + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + containers: + - name: "bridge-discord" + image: "{{ .Values.bridges.discord.image.repository }}:{{ .Values.bridges.discord.image.tag }}" + imagePullPolicy: {{ .Values.bridges.discord.image.pullPolicy }} + ports: + - name: bridge + containerPort: 9005 + protocol: TCP + volumeMounts: + - name: data + mountPath: /data + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + {{- with .Values.bridges.discord.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumes: + - name: data + persistentVolumeClaim: + claimName: "{{ include "matrix.fullname" . }}-discord-data" + - name: config + configMap: + name: "{{ include "matrix.fullname" . }}-discord-config" + - name: bridges + persistentVolumeClaim: + claimName: "{{ include "matrix.fullname" . }}-bridges" +{{- end }} diff --git a/charts/matrix/templates/bridge-discord/network-policy.yaml b/charts/matrix/templates/bridge-discord/network-policy.yaml new file mode 100644 index 0000000..a34834d --- /dev/null +++ b/charts/matrix/templates/bridge-discord/network-policy.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.networkPolicies.enabled .Values.bridges.discord.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "matrix.fullname" . }}-bridge-discord + labels: +{{ include "matrix.labels" . | indent 4 }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.fullname" . }}-bridge-discord + app.kubernetes.io/instance: {{ .Release.Name }} + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-synapse + app.kubernetes.io/instance: {{ .Release.Name }} + ports: + - port: bridge + protocol: TCP +{{- end }} diff --git a/charts/matrix/templates/bridge-discord/service.yaml b/charts/matrix/templates/bridge-discord/service.yaml new file mode 100644 index 0000000..b50d793 --- /dev/null +++ b/charts/matrix/templates/bridge-discord/service.yaml @@ -0,0 +1,18 @@ +{{- if .Values.bridges.discord.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "matrix.fullname" . }}-bridge-discord + labels: +{{ include "matrix.labels" . | indent 4 }} +spec: + type: {{ .Values.bridges.discord.service.type }} + ports: + - port: {{ .Values.bridges.discord.service.port }} + targetPort: bridge + protocol: TCP + name: bridge + selector: + app.kubernetes.io/name: {{ include "matrix.name" . }}-bridge-discord + app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/matrix/templates/bridge-irc/_config.yaml b/charts/matrix/templates/bridge-irc/_config.yaml new file mode 100644 index 0000000..e6b68ae --- /dev/null +++ b/charts/matrix/templates/bridge-irc/_config.yaml @@ -0,0 +1,190 @@ +{{- define "matrix.irc.config" }} +homeserver: + # The URL to the home server for client-server API calls, also used to form the + # media URLs as displayed in bridged IRC channels: + url: "{{ include "matrix.baseUrl" . }}" + # + # The URL of the homeserver hosting media files. This is only used to transform + # mxc URIs to http URIs when bridging m.room.[file|image] events. Optional. By + # default, this is the homeserver URL, specified above. + # + # media_url: "http://media.repo:8008" + + # Drop Matrix messages which are older than this number of seconds, according to + # the event's origin_server_ts. + # If the bridge is down for a while, the homeserver will attempt to send all missed + # events on reconnection. These events may be hours old, which can be confusing to + # IRC users if they are then bridged. This option allows these old messages to be + # dropped. + # CAUTION: This is a very coarse heuristic. Federated homeservers may have different + # clock times and hence produce different origin_server_ts values, which may be old + # enough to cause *all* events from the homeserver to be dropped. + # Default: 0 (don't ever drop) + # dropMatrixMessagesAfterSecs: 300 # 5 minutes + + # The 'domain' part for user IDs on this home server. Usually (but not always) + # is the "domain name" part of the HS URL. + domain: "{{ .Values.matrix.serverName }}" + + # Should presence be enabled for matrix clients on this bridge. If disabled on the + # homeserver then it should also be disabled here to avoid excess traffic. + # Default: true + enablePresence: {{ .Values.bridges.irc.presence }} + + # Which port should the appservice bind to. Takes priority over the one provided in the + # command line! Optional. + bindPort: 9006 + + # Use this option to force the appservice to listen on another hostname for transactions. + # This is NOT your synapse hostname. E.g. use 127.0.0.1 to only listen locally. Optional. + bindHostname: 0.0.0.0 + +# Configuration specific to the IRC service +ircService: + servers: + {{ toYaml .Values.bridges.irc.servers | nindent 4 }} + # Set information about the bridged channel in the room state, so that client's may + # present relevant UI to the user. MSC2346 + bridgeInfoState: + enabled: false + initial: false + # Configuration for an ident server. If you are running a public bridge it is + # advised you setup an ident server so IRC mods can ban specific matrix users + # rather than the application service itself. + ident: + # True to listen for Ident requests and respond with the + # matrix user's user_id (converted to ASCII, respecting RFC 1413). + # Default: false. + enabled: false + # The port to listen on for incoming ident requests. + # Ports below 1024 require root to listen on, and you may not want this to + # run as root. Instead, you can get something like an Apache to yank up + # incoming requests to 113 to a high numbered port. Set the port to listen + # on instead of 113 here. + # Default: 113. + port: 1113 + # The address to listen on for incoming ident requests. + # Default: 0.0.0.0 + address: "::" + + # Configuration for logging. Optional. Default: console debug level logging + # only. + logging: + # Level to log on console/logfile. One of error|warn|info|debug + level: "debug" + # The file location to log to. This is relative to the project directory. + logfile: "/data/debug.log" + # The file location to log errors to. This is relative to the project + # directory. + errfile: "/data/errors.log" + # Whether to log to the console or not. + toConsole: true + # The max number of files to keep. Files will be overwritten eventually due + # to rotations. + maxFiles: 5 + + # Metrics will then be available via GET /metrics on the bridge listening port (-p). + metrics: + # Whether to actually enable the metric endpoint. Default: false + enabled: false {{/* TODO: Enable this when Prometheus support added */}} + # When collecting remote user active times, which "buckets" should be used. Defaults are given below. + # The bucket name is formed of a duration and a period. (h=hours,d=days,w=weeks). + remoteUserAgeBuckets: + - "1h" + - "1d" + - "1w" + + # Configuration options for the debug HTTP API. To access this API, you must + # append ?access_token=$APPSERVICE_TOKEN (from the registration file) to the requests. + # + # The debug API exposes the following endpoints: + # + # GET /irc/$domain/user/$user_id => Return internal state for the IRC client for this user ID. + # + # POST /irc/$domain/user/$user_id => Issue a raw IRC command down this connection. + # Format: new line delimited commands as per IRC protocol. + # + debugApi: + # True to enable the HTTP API endpoint. Default: false. + enabled: false + # The port to host the HTTP API. + port: 11100 + + # Configuration for the provisioning API. + # + # GET /_matrix/provision/link + # GET /_matrix/provision/unlink + # GET /_matrix/provision/listlinks + # + provisioning: + # True to enable the provisioning HTTP endpoint. Default: false. + enabled: false + # The number of seconds to wait before giving up on getting a response from + # an IRC channel operator. If the channel operator does not respond within the + # allotted time period, the provisioning request will fail. + # Default: 300 seconds (5 mins) + requestTimeoutSeconds: 300 + # A file defining the provisioning rules for rooms. Format is documented + # in rules.sample.yaml. Leave undefined to not specify any rules. + ruleFile: "./provisioning.rules.yaml" + # Watch the file for changes, and apply the rules. Default: false + enableReload: true + + # WARNING: The bridge needs to send plaintext passwords to the IRC server, it cannot + # send a password hash. As a result, passwords (NOT hashes) are stored encrypted in + # the database. + # + # To generate a .pem file: + # $ openssl genpkey -out passkey.pem -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:2048 + # + # The path to the RSA PEM-formatted private key to use when encrypting IRC passwords + # for storage in the database. Passwords are stored by using the admin room command + # `!storepass server.name passw0rd. When a connection is made to IRC on behalf of + # the Matrix user, this password will be sent as the server password (PASS command). + passwordEncryptionKeyPath: "/data/passkey.pem" + + # Config for Matrix -> IRC bridging + matrixHandler: + # Cache this many matrix events in memory to be used for m.relates_to messages (usually replies). + eventCacheSize: 4096 + + ircHandler: + # How many /leave requests can be ongoing at a time. + # This is used to stem the flow of requests in case of a mass quit/leave, which might + # slow down the homeserver. + leaveConcurrency: 10 + # Should we attempt to match an IRC side mention (nickaname match) + # with the nickname's owner's matrixId, if we are bridging them? + # "on" - Defaults to enabled, users can choose to disable. + # "off" - Defaults to disabled, users can choose to enable. + # "force-off" - Disabled, cannot be enabled. + mapIrcMentionsToMatrix: "on" # This can be "on", "off", "force-off". +# Options here are generally only applicable to large-scale bridges and may have +# consequences greater than other options in this configuration file. +advanced: + # The maximum number of HTTP(S) sockets to maintain. Usually this is unlimited + # however for large bridges it is important to rate limit the bridge to avoid + # accidentally overloading the homeserver. Defaults to 1000, which should be + # enough for the vast majority of use cases. + maxHttpSockets: 1000 + # Max size of an appservice transaction payload, in bytes. Defaults to 10Mb + maxTxnSize: 10000000 + +# Capture information to a sentry.io instance +sentry: + enabled: false + dsn: "https://@sentry.io/" + # Optional. A tag to specify the production environment. Not set by default + # environment: "" + # Optional. A tag to specify the server name. Not set by default + # serverName: "" + +# Use an external database to store bridge state. +database: + # database engine (must be 'postgres' or 'nedb'). Default: nedb + engine: "postgres" + # Either a PostgreSQL connection string, or a path to the NeDB storage directory. + # For postgres, it must start with postgres:// + # For NeDB, it must start with nedb://. The path is relative to the project directory. + connectionString: {{ printf (include "matrix.postgresUri" .) .Values.bridges.irc.database | quote }} +{{- end }} \ No newline at end of file diff --git a/charts/matrix/templates/bridge-irc/_helpers.tpl b/charts/matrix/templates/bridge-irc/_helpers.tpl new file mode 100644 index 0000000..6024e43 --- /dev/null +++ b/charts/matrix/templates/bridge-irc/_helpers.tpl @@ -0,0 +1,15 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Shared secret for the irc server +*/}} +{{- define "matrix.irc.as_token" -}} +{{- randAlphaNum 64 -}} +{{- end }} + +{{- define "matrix.irc.hs_token" -}} +{{- randAlphaNum 64 -}} +{{- end }} + +{{- define "matrix.irc.passkey" -}} +{{- genPrivateKey "rsa" -}} +{{- end -}} \ No newline at end of file diff --git a/charts/matrix/templates/bridge-irc/configmap.yaml b/charts/matrix/templates/bridge-irc/configmap.yaml new file mode 100644 index 0000000..706d950 --- /dev/null +++ b/charts/matrix/templates/bridge-irc/configmap.yaml @@ -0,0 +1,29 @@ +{{- if .Values.bridges.irc.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "matrix.fullname" . }}-irc-config + labels: + {{ include "matrix.labels" . | nindent 4}} +data: + config.yaml: | + {{ include "matrix.irc.config" . | nindent 4 }} + registration.yaml: | + id: appservice-irc + as_token: "{{ include "matrix.irc.as_token" . }}" + hs_token: "{{ include "matrix.irc.hs_token" . }}" + namespaces: + users: + - exclusive: true + regex: '@irc_.*:{{ include "matrix.fullname" . }}' + aliases: + - exclusive: true + regex: '#irc_.*:{{ include "matrix.fullname" . }}' + url: "http://{{ include "matrix.fullname" . }}-bridge-irc:{{ .Values.bridges.irc.service.port }}" + sender_localpart: irc_bot + rate_limited: false + protocols: + - irc + passkey.pem: | + {{ include "matrix.irc.passkey" . | nindent 4 }} +{{- end }} diff --git a/charts/matrix/templates/bridge-irc/data-pvc.yaml b/charts/matrix/templates/bridge-irc/data-pvc.yaml new file mode 100644 index 0000000..26f3f0a --- /dev/null +++ b/charts/matrix/templates/bridge-irc/data-pvc.yaml @@ -0,0 +1,14 @@ +{{- if .Values.bridges.irc.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "matrix.fullname" . }}-irc-data + labels: + {{ include "matrix.labels" . | nindent 4}} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.bridges.irc.data.capacity }} +{{- end }} diff --git a/charts/matrix/templates/bridge-irc/deployment.yaml b/charts/matrix/templates/bridge-irc/deployment.yaml new file mode 100644 index 0000000..98dc72e --- /dev/null +++ b/charts/matrix/templates/bridge-irc/deployment.yaml @@ -0,0 +1,110 @@ +{{- if .Values.bridges.irc.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "matrix.fullname" . }}-bridge-irc + labels: + {{ include "matrix.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.bridges.irc.replicaCount }} + strategy: + rollingUpdate: + maxUnavailable: 1 + maxSurge: 0 + type: RollingUpdate + selector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-bridge-irc + app.kubernetes.io/instance: {{ .Release.Name }} + matrix-chart/allow-synapse-access: allow + template: + metadata: + annotations: + # re-roll deployment on config change + checksum/irc-config: {{ include (print $.Template.BasePath "/bridge-irc/configmap.yaml") . | sha256sum }} + labels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-bridge-irc + app.kubernetes.io/instance: {{ .Release.Name }} + matrix-chart/allow-synapse-access: allow + spec: + {{- if .Values.bridges.affinity }} + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - {{ include "matrix.name" . }}-synapse + - key: app.kubernetes.io/instance + operator: In + values: + - {{ .Release.Name }} + topologyKey: kubernetes.io/hostname + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + initContainers: + - name: "load-config" + image: "{{ .Values.bridges.irc.image.repository }}:{{ .Values.bridges.irc.image.tag }}" + imagePullPolicy: {{ .Values.bridges.irc.image.pullPolicy }} + command: ["sh"] + args: ["-c", "cp /load/registration.yaml /data/appservice-registration-irc.yaml; cp /load/passkey.pem /data/passkey.pem; cp /load/config.yaml /data/config.yaml; cp /load/registration.yaml /bridges/irc.yaml"] + volumeMounts: + - name: data + mountPath: /data + - name: bridges + mountPath: /bridges + - name: config + mountPath: /load + readOnly: true + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + containers: + - name: "bridge-irc" + image: "{{ .Values.bridges.irc.image.repository }}:{{ .Values.bridges.irc.image.tag }}" + imagePullPolicy: {{ .Values.bridges.irc.image.pullPolicy }} + {{- if not .Values.bridges.irc.databaseSslVerify }} + env: + - name: NODE_TLS_REJECT_UNAUTHORIZED + value: "0" + {{- end }} + ports: + - name: bridge + containerPort: 9006 + protocol: TCP + volumeMounts: + - name: data + mountPath: /data + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + {{- with .Values.bridges.irc.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumes: + - name: data + persistentVolumeClaim: + claimName: "{{ include "matrix.fullname" . }}-irc-data" + - name: config + configMap: + name: "{{ include "matrix.fullname" . }}-irc-config" + - name: bridges + persistentVolumeClaim: + claimName: "{{ include "matrix.fullname" . }}-bridges" + {{- end }} diff --git a/charts/matrix/templates/bridge-irc/network-policy.yaml b/charts/matrix/templates/bridge-irc/network-policy.yaml new file mode 100644 index 0000000..7d74e21 --- /dev/null +++ b/charts/matrix/templates/bridge-irc/network-policy.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.networkPolicies.enabled .Values.bridges.irc.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "matrix.fullname" . }}-bridge-irc + labels: + {{ include "matrix.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.fullname" . }}-bridge-irc + app.kubernetes.io/instance: {{ .Release.Name }} + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-synapse + app.kubernetes.io/instance: {{ .Release.Name }} + ports: + - port: bridge + protocol: TCP +{{- end }} diff --git a/charts/matrix/templates/bridge-irc/service.yaml b/charts/matrix/templates/bridge-irc/service.yaml new file mode 100644 index 0000000..088b4a8 --- /dev/null +++ b/charts/matrix/templates/bridge-irc/service.yaml @@ -0,0 +1,18 @@ +{{- if .Values.bridges.irc.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "matrix.fullname" . }}-bridge-irc + labels: + {{ include "matrix.labels" . | nindent 4 }} +spec: + type: {{ .Values.bridges.irc.service.type }} + ports: + - port: {{ .Values.bridges.irc.service.port }} + targetPort: bridge + protocol: TCP + name: bridge + selector: + app.kubernetes.io/name: {{ include "matrix.name" . }}-bridge-irc + app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/matrix/templates/bridge-whatsapp/configmap.yaml b/charts/matrix/templates/bridge-whatsapp/configmap.yaml new file mode 100644 index 0000000..754ba71 --- /dev/null +++ b/charts/matrix/templates/bridge-whatsapp/configmap.yaml @@ -0,0 +1,181 @@ +{{- if .Values.bridges.whatsapp.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "matrix.fullname" . }}-whatsapp-config + labels: + {{ include "matrix.labels" . | nindent 4}} +data: + config.yaml: | + # Homeserver details. + homeserver: + # The address that this appservice can use to connect to the homeserver. + address: http://{{ include "matrix.fullname" . }}-synapse + # The domain of the homeserver (for MXIDs, etc). + domain: {{ .Values.matrix.serverName }} + + # Application service host/registration related details. + # Changing these values requires regeneration of the registration. + appservice: + # The address that the homeserver can use to connect to this appservice. + address: http://{{ include "matrix.fullname" . }}-bridge-whatsapp:{{ .Values.bridges.whatsapp.service.port }} + + # The hostname and port where this appservice should listen. + hostname: 0.0.0.0 + port: 29318 + + # Database config. + database: + # The database type. "sqlite3" and "postgres" are supported. + type: sqlite3 + # The database URI. + # SQLite: File name is enough. https://github.com/mattn/go-sqlite3#connection-string + # Postgres: Connection string. For example, postgres://user:password@host/database + uri: /data/mautrix-whatsapp.db + # Maximum number of connections. Mostly relevant for Postgres. + max_open_conns: 20 + max_idle_conns: 2 + + # The unique ID of this appservice. + id: whatsapp + # Appservice bot details. + bot: + # Username of the appservice bot. + username: {{ .Values.bridges.whatsapp.bot.username }} + # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty + # to leave display name/avatar as-is. + displayname: {{ .Values.bridges.whatsapp.bot.displayname }} + avatar: {{ .Values.bridges.whatsapp.bot.avatar }} + + # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. + as_token: "This value is generated when generating the registration" + hs_token: "This value is generated when generating the registration" + + # Bridge config + bridge: + # Localpart template of MXIDs for WhatsApp users. + # {{ "{{.}}" }} is replaced with the phone number of the WhatsApp user. + username_template: {{ .Values.bridges.whatsapp.users.username | quote }} + # Displayname template for WhatsApp users. + displayname_template: {{ .Values.bridges.whatsapp.users.displayName | quote }} + # Localpart template for per-user room grouping community IDs. + # The bridge will create these communities and add all of the specific user's portals to the community. + community_template: {{ .Values.bridges.whatsapp.communityName | quote }} + + # WhatsApp connection timeout in seconds. + connection_timeout: {{ .Values.bridges.whatsapp.connection.timeout }} + # Number of times to regenerate QR code when logging in. + # The regenerated QR code is sent as an edit and essentially multiplies the login timeout (20 seconds) + login_qr_regen_count: {{ .Values.bridges.whatsapp.connection.qrRegenCount }} + # Maximum number of times to retry connecting on connection error. + max_connection_attempts: {{ .Values.bridges.whatsapp.connection.maxAttempts }} + # Number of seconds to wait between connection attempts. + # Negative numbers are exponential backoff: -connection_retry_delay + 1 + 2^attempts + connection_retry_delay: {{ .Values.bridges.whatsapp.connection.retryDelay }} + # Whether or not the bridge should send a notice to the user's management room when it retries connecting. + # If false, it will only report when it stops retrying. + report_connection_retry: {{ .Values.bridges.whatsapp.connection.reportRetry }} + # Maximum number of seconds to wait for chats to be sent at startup. + # If this is too low and you have lots of chats, it could cause backfilling to fail. + chat_list_wait: 30 + # Maximum number of seconds to wait to sync portals before force unlocking message processing. + # If this is too low and you have lots of chats, it could cause backfilling to fail. + portal_sync_wait: 600 + + # Whether or not to send call start/end notices to Matrix. + call_notices: + start: {{ .Values.bridges.whatsapp.callNotices }} + end: {{ .Values.bridges.whatsapp.callNotices }} + + # Number of chats to sync for new users. + initial_chat_sync_count: 10 + # Number of old messages to fill when creating new portal rooms. + initial_history_fill_count: 20 + # Maximum number of chats to sync when recovering from downtime. + # Set to -1 to sync all new chats during downtime. + recovery_chat_sync_limit: -1 + # Whether or not to sync history when recovering from downtime. + recovery_history_backfill: true + # Maximum number of seconds since last message in chat to skip + # syncing the chat in any case. This setting will take priority + # over both recovery_chat_sync_limit and initial_chat_sync_count. + # Default is 3 days = 259200 seconds + sync_max_chat_age: 259200 + + # Whether or not to sync with custom puppets to receive EDUs that + # are not normally sent to appservices. + sync_with_custom_puppets: true + # Shared secret for https://github.com/devture/matrix-synapse-shared-secret-auth + # + # If set, custom puppets will be enabled automatically for local users + # instead of users having to find an access token and run `login-matrix` + # manually. + login_shared_secret: null + + # Whether or not to invite own WhatsApp user's Matrix puppet into private + # chat portals when backfilling if needed. + # This always uses the default puppet instead of custom puppets due to + # rate limits and timestamp massaging. + invite_own_puppet_for_backfilling: true + # Whether or not to explicitly set the avatar and room name for private + # chat portal rooms. This can be useful if the previous field works fine, + # but causes room avatar/name bugs. + private_chat_portal_meta: false + + # Allow invite permission for user. User can invite any bots to room with whatsapp + # users (private chat and groups) + allow_user_invite: false + + # The prefix for commands. Only required in non-management rooms. + command_prefix: "!wa" + + # Permissions for using the bridge. + # Permitted values: + # relaybot - Talk through the relaybot (if enabled), no access otherwise + # user - Access to use the bridge to chat with a WhatsApp account. + # admin - User level and some additional administration tools + # Permitted keys: + # * - All Matrix users + # domain - All users on that homeserver + # mxid - Specific user + permissions: + "*": relaybot + "example.com": user + "@admin:example.com": admin + + relaybot: + # Whether or not relaybot support is enabled. + enabled: {{ .Values.bridges.whatsapp.relaybot.enabled }} + # The management room for the bot. This is where all status notifications are posted and + # in this room, you can use `!wa ` instead of `!wa relaybot `. Omitting + # the command prefix completely like in user management rooms is not possible. + management: {{ .Values.bridges.whatsapp.relaybot.management }} + # List of users to invite to all created rooms that include the relaybot. + invites: {{ .Values.bridges.whatsapp.relaybot.invites }} + # The formats to use when sending messages to WhatsApp via the relaybot. + message_formats: + m.text: "{{ "{{ .Sender.Displayname }}" }}: {{ "{{ .Message }}" }}" + m.notice: "{{ "{{ .Sender.Displayname }}" }}: {{ "{{ .Message }}" }}" + m.emote: "* {{ "{{ .Sender.Displayname }}" }} {{ "{{ .Message }}" }}" + m.file: "{{ "{{ .Sender.Displayname }}" }} sent a file" + m.image: "{{ "{{ .Sender.Displayname }}" }} sent an image" + m.audio: "{{ "{{ .Sender.Displayname }}" }} sent an audio file" + m.video: "{{ "{{ .Sender.Displayname }}" }} sent a video" + m.location: "{{ "{{ .Sender.Displayname }}" }} sent a location" + + # Logging config. + logging: + # The directory for log files. Will be created if not found. + directory: /tmp + # Available variables: .Date for the file date and .Index for different log files on the same day. + file_name_format: "{{ "{{.Date}}-{{.Index}}" }}.log" + # Date format for file names in the Go time format: https://golang.org/pkg/time/#pkg-constants + file_date_format: 2006-01-02 + # Log file permissions. + file_mode: 0600 + # Timestamp format for log entries in the Go time format. + timestamp_format: Jan _2, 2006 15:04:05 + # Minimum severity for log messages. + # Options: debug, info, warn, error, fatal + print_level: debug +{{- end }} diff --git a/charts/matrix/templates/bridge-whatsapp/data-pvc.yaml b/charts/matrix/templates/bridge-whatsapp/data-pvc.yaml new file mode 100644 index 0000000..fd9a52a --- /dev/null +++ b/charts/matrix/templates/bridge-whatsapp/data-pvc.yaml @@ -0,0 +1,17 @@ +{{- if .Values.bridges.whatsapp.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "matrix.fullname" . }}-whatsapp-data + labels: +{{ include "matrix.labels" . | indent 4}} +spec: + {{- if .Values.bridges.whatsapp.data.storageClass }} + storageClassName: {{ .Values.bridges.whatsapp.data.storageClass }} + {{- end }} + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.bridges.whatsapp.data.capacity }} +{{- end }} diff --git a/charts/matrix/templates/bridge-whatsapp/deployment.yaml b/charts/matrix/templates/bridge-whatsapp/deployment.yaml new file mode 100644 index 0000000..660a49e --- /dev/null +++ b/charts/matrix/templates/bridge-whatsapp/deployment.yaml @@ -0,0 +1,129 @@ +{{- if .Values.bridges.whatsapp.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "matrix.fullname" . }}-bridge-whatsapp + labels: +{{ include "matrix.labels" . | indent 4 }} +spec: + replicas: {{ .Values.bridges.whatsapp.replicaCount }} + strategy: + rollingUpdate: + maxUnavailable: 1 + maxSurge: 0 + type: RollingUpdate + selector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-bridge-whatsapp + app.kubernetes.io/instance: {{ .Release.Name }} + matrix-chart/allow-synapse-access: allow + template: + metadata: + annotations: + # re-roll deployment on config change + checksum/whatsapp-config: {{ include (print $.Template.BasePath "/bridge-whatsapp/configmap.yaml") . | sha256sum }} + labels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-bridge-whatsapp + app.kubernetes.io/instance: {{ .Release.Name }} + matrix-chart/allow-synapse-access: allow + spec: + {{- if .Values.bridges.affinity }} + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - {{ include "matrix.name" . }}-synapse + - key: app.kubernetes.io/instance + operator: In + values: + - {{ .Release.Name }} + topologyKey: kubernetes.io/hostname + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + initContainers: + - name: "load-config" + image: "{{ .Values.bridges.whatsapp.image.repository }}:{{ .Values.bridges.whatsapp.image.tag }}" + imagePullPolicy: {{ .Values.bridges.whatsapp.image.pullPolicy }} + command: ["sh"] + args: ["-c", "cp /load/config.yaml /data/config.yaml"] + volumeMounts: + - name: data + mountPath: /data + - name: config + mountPath: /load + readOnly: true + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + - name: "generate-config" + image: "{{ .Values.bridges.whatsapp.image.repository }}:{{ .Values.bridges.whatsapp.image.tag }}" + imagePullPolicy: {{ .Values.bridges.whatsapp.image.pullPolicy }} + command: ["mautrix-whatsapp"] + args: ["-g", "-c", "/data/config.yaml", "-r", "/bridges/whatsapp.yaml"] + volumeMounts: + - name: data + mountPath: /data + - name: bridges + mountPath: /bridges + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + {{- with .Values.bridges.whatsapp.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + containers: + - name: "bridge-whatsapp" + image: "{{ .Values.bridges.whatsapp.image.repository }}:{{ .Values.bridges.whatsapp.image.tag }}" + imagePullPolicy: {{ .Values.bridges.whatsapp.image.pullPolicy }} + command: ["mautrix-whatsapp"] + args: ["-c", "/data/config.yaml"] + ports: + - name: bridge + containerPort: 29318 + protocol: TCP + volumeMounts: + - name: data + mountPath: /data + - name: tmp + mountPath: /tmp + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + {{- with .Values.bridges.whatsapp.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumes: + - name: data + persistentVolumeClaim: + claimName: "{{ include "matrix.fullname" . }}-whatsapp-data" + - name: config + configMap: + name: "{{ include "matrix.fullname" . }}-whatsapp-config" + - name: bridges + persistentVolumeClaim: + claimName: "{{ include "matrix.fullname" . }}-bridges" + - name: tmp + emptyDir: {} +{{- end }} diff --git a/charts/matrix/templates/bridge-whatsapp/network-policy.yaml b/charts/matrix/templates/bridge-whatsapp/network-policy.yaml new file mode 100644 index 0000000..f2298d1 --- /dev/null +++ b/charts/matrix/templates/bridge-whatsapp/network-policy.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.networkPolicies.enabled .Values.bridges.whatsapp.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "matrix.fullname" . }}-bridge-whatsapp + labels: +{{ include "matrix.labels" . | indent 4 }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.fullname" . }}-bridge-whatsapp + app.kubernetes.io/instance: {{ .Release.Name }} + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-synapse + app.kubernetes.io/instance: {{ .Release.Name }} + ports: + - port: bridge + protocol: TCP +{{- end }} diff --git a/charts/matrix/templates/bridge-whatsapp/service.yaml b/charts/matrix/templates/bridge-whatsapp/service.yaml new file mode 100644 index 0000000..54e8fe4 --- /dev/null +++ b/charts/matrix/templates/bridge-whatsapp/service.yaml @@ -0,0 +1,18 @@ +{{- if .Values.bridges.whatsapp.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "matrix.fullname" . }}-bridge-whatsapp + labels: +{{ include "matrix.labels" . | indent 4 }} +spec: + type: {{ .Values.bridges.whatsapp.service.type }} + ports: + - port: {{ .Values.bridges.whatsapp.service.port }} + targetPort: bridge + protocol: TCP + name: bridge + selector: + app.kubernetes.io/name: {{ include "matrix.name" . }}-bridge-whatsapp + app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/matrix/templates/bridges-pvc.yaml b/charts/matrix/templates/bridges-pvc.yaml new file mode 100644 index 0000000..e3a490a --- /dev/null +++ b/charts/matrix/templates/bridges-pvc.yaml @@ -0,0 +1,17 @@ +{{- if or .Values.bridges.whatsapp.enabled .Values.bridges.discord.enabled .Values.bridges.irc.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "matrix.fullname" . }}-bridges + labels: +{{ include "matrix.labels" . | indent 4}} +spec: + {{- if .Values.bridges.volume.storageClass }} + storageClassName: {{ .Values.bridges.volume.storageClass }} + {{- end }} + accessModes: + - {{ .Values.bridges.volume.accessMode }} + resources: + requests: + storage: {{ .Values.bridges.volume.capacity }} +{{- end }} diff --git a/charts/matrix/templates/coturn/_helpers.tpl b/charts/matrix/templates/coturn/_helpers.tpl new file mode 100644 index 0000000..b50ddac --- /dev/null +++ b/charts/matrix/templates/coturn/_helpers.tpl @@ -0,0 +1,11 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Shared secret for the Coturn server +*/}} +{{- define "matrix.coturn.sharedSecret" -}} +{{- if .Values.coturn.sharedSecret }} +{{- .Values.coturn.sharedSecret -}} +{{- else }} +{{- randAlphaNum 64 -}} +{{- end }} +{{- end -}} diff --git a/charts/matrix/templates/coturn/configmap.yaml b/charts/matrix/templates/coturn/configmap.yaml new file mode 100644 index 0000000..80cc573 --- /dev/null +++ b/charts/matrix/templates/coturn/configmap.yaml @@ -0,0 +1,29 @@ +{{- if .Values.coturn.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "matrix.fullname" . }}-coturn-config + labels: +{{ include "matrix.labels" . | nindent 4}} +{{ include "matrix.coturn.labels" . | indent 4}} +data: + turnserver.conf: | + use-auth-secret + static-auth-secret={{ include "matrix.coturn.sharedSecret" . }} + realm=turn.{{ .Values.matrix.serverName }} + + min-port={{ .Values.coturn.ports.from }} + max-port={{ .Values.coturn.ports.to }} + + log-file=stdout + pidfile=/var/tmp/turnserver.pid + userdb=/var/tmp/turnserver.db + + no-cli + + no-tls + no-dtls + + prod + no-tcp-relay +{{- end }} \ No newline at end of file diff --git a/charts/matrix/templates/coturn/deployment.yaml b/charts/matrix/templates/coturn/deployment.yaml new file mode 100644 index 0000000..850f533 --- /dev/null +++ b/charts/matrix/templates/coturn/deployment.yaml @@ -0,0 +1,77 @@ +{{- if .Values.coturn.enabled }} +{{- $portRange := untilStep (int .Values.coturn.ports.from) (int (add1 .Values.coturn.ports.to)) 1 -}} +apiVersion: apps/v1 +kind: {{ .Values.coturn.kind }} +metadata: + name: {{ include "matrix.fullname" . }}-coturn + labels: +{{ include "matrix.labels" . | indent 4 }} +{{ include "matrix.coturn.labels" . | indent 4}} +spec: + {{- if eq .Values.coturn.kind "Deployment" }} + replicas: {{ .Values.coturn.replicaCount }} + {{- end }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-coturn + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + annotations: + # re-roll deployment on config change + checksum/coturn-config: {{ include (print $.Template.BasePath "/coturn/configmap.yaml") . | sha256sum }} + labels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-coturn + app.kubernetes.io/instance: {{ .Release.Name }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + {{- if eq .Values.coturn.kind "DaemonSet" }} + hostNetwork: true + {{- end }} + containers: + - name: "coturn" + image: "{{ .Values.coturn.image.repository }}:{{ .Values.coturn.image.tag }}" + imagePullPolicy: {{ .Values.coturn.image.pullPolicy }} + args: ["-c", "/turnserver.conf"] + ports: + - name: turn-3478 + containerPort: 3478 + protocol: UDP + {{- range $portRange }} + - name: turn-{{ . }} + containerPort: {{ . }} + {{- if eq $.Values.coturn.kind "DaemonSet" }} + hostPort: {{ . }} + {{- end }} + protocol: UDP + {{- end }} + volumeMounts: + - name: coturn-config + mountPath: /turnserver.conf + subPath: turnserver.conf + readOnly: true + - name: var-tmp + mountPath: /var/tmp + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + {{- with .Values.coturn.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumes: + - name: coturn-config + configMap: + name: {{ include "matrix.fullname" . }}-coturn-config + - name: var-tmp + emptyDir: {} +{{- end }} diff --git a/charts/matrix/templates/coturn/network-policy.yaml b/charts/matrix/templates/coturn/network-policy.yaml new file mode 100644 index 0000000..059c956 --- /dev/null +++ b/charts/matrix/templates/coturn/network-policy.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.networkPolicies.enabled .Values.coturn.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "matrix.fullname" . }}-coturn + labels: +{{ include "matrix.labels" . | indent 4 }} +{{ include "matrix.coturn.labels" . | indent 4}} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.fullname" . }}-coturn + app.kubernetes.io/instance: {{ .Release.Name }} + policyTypes: + - Ingress +{{- end }} diff --git a/charts/matrix/templates/coturn/service.yaml b/charts/matrix/templates/coturn/service.yaml new file mode 100644 index 0000000..a129ac6 --- /dev/null +++ b/charts/matrix/templates/coturn/service.yaml @@ -0,0 +1,32 @@ +{{- if .Values.coturn.enabled }} +{{- $portRange := untilStep (int .Values.coturn.ports.from) (int (add1 .Values.coturn.ports.to)) 1 -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "matrix.fullname" . }}-coturn + labels: +{{ include "matrix.labels" . | indent 4 }} +{{ include "matrix.coturn.labels" . | indent 4}} +spec: + type: {{ .Values.coturn.service.type }} + ports: + - port: 3478 + targetPort: turn-3478 + {{- if eq .Values.coturn.service.type "NodePort" }} + nodePort: 3478 + {{- end }} + protocol: UDP + name: turn-3478 + {{- range $portRange }} + - port: {{ . }} + targetPort: {{ . }} + {{- if eq $.Values.coturn.service.type "NodePort" }} + nodePort: {{ . }} + {{- end }} + protocol: UDP + name: turn-{{ . }} + {{- end }} + selector: + app.kubernetes.io/name: {{ include "matrix.name" . }}-coturn + app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/matrix/templates/exim/deployment.yaml b/charts/matrix/templates/exim/deployment.yaml new file mode 100644 index 0000000..3b88dbb --- /dev/null +++ b/charts/matrix/templates/exim/deployment.yaml @@ -0,0 +1,64 @@ +{{- if and .Values.mail.enabled .Values.mail.relay.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "matrix.fullname" . }}-exim-relay + labels: +{{ include "matrix.labels" . | indent 4 }} +{{ include "matrix.mail.labels" . | indent 4}} +spec: + replicas: {{ .Values.mail.relay.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-exim-relay + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-exim-relay + app.kubernetes.io/instance: {{ .Release.Name }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + runAsUser: 100 + runAsGroup: 101 + containers: + - name: "exim-relay" + image: "{{ .Values.mail.relay.image.repository }}:{{ .Values.mail.relay.image.tag }}" + imagePullPolicy: {{ .Values.mail.relay.image.pullPolicy }} + ports: + - name: smtp + containerPort: 8025 + protocol: TCP + readinessProbe: + tcpSocket: + port: smtp + {{- if .Values.mail.relay.probes.readiness }} + {{- toYaml .Values.mail.relay.probes.readiness | nindent 12 }} + {{- end }} + startupProbe: + tcpSocket: + port: smtp + {{- if .Values.mail.relay.probes.startup }} + {{- toYaml .Values.mail.relay.probes.startup | nindent 12 }} + {{- end }} + livenessProbe: + tcpSocket: + port: smtp + {{- if .Values.mail.relay.probes.liveness }} + {{- toYaml .Values.mail.relay.probes.liveness | nindent 12 }} + {{- end }} + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + {{- with .Values.mail.relay.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} +{{- end }} diff --git a/charts/matrix/templates/exim/network-policy.yaml b/charts/matrix/templates/exim/network-policy.yaml new file mode 100644 index 0000000..a9055bf --- /dev/null +++ b/charts/matrix/templates/exim/network-policy.yaml @@ -0,0 +1,23 @@ +{{- if and .Values.networkPolicies.enabled .Values.mail.relay.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "matrix.fullname" . }}-exim-relay + labels: +{{ include "matrix.labels" . | indent 4 }} +{{ include "matrix.mail.labels" . | indent 4}} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.fullname" . }}-exim-relay + app.kubernetes.io/instance: {{ .Release.Name }} + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-synapse + app.kubernetes.io/instance: {{ .Release.Name }} + ports: + - port: smtp + protocol: TCP +{{- end }} diff --git a/charts/matrix/templates/exim/service.yaml b/charts/matrix/templates/exim/service.yaml new file mode 100644 index 0000000..8b661a3 --- /dev/null +++ b/charts/matrix/templates/exim/service.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.mail.enabled .Values.mail.relay.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "matrix.fullname" . }}-exim-relay + labels: +{{ include "matrix.labels" . | indent 4 }} +{{ include "matrix.mail.labels" . | indent 4}} +spec: + type: {{ .Values.mail.relay.service.type }} + ports: + - port: {{ .Values.mail.relay.service.port }} + targetPort: smtp + protocol: TCP + name: smtp + selector: + app.kubernetes.io/name: {{ include "matrix.name" . }}-exim-relay + app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/matrix/templates/ingress.yaml b/charts/matrix/templates/ingress.yaml new file mode 100644 index 0000000..3a35306 --- /dev/null +++ b/charts/matrix/templates/ingress.yaml @@ -0,0 +1,53 @@ +{{- if .Values.ingress.enabled -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ include "matrix.fullname" . }} + labels: + {{- include "matrix.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} +{{- end }} + rules: + - host: {{ .Values.ingress.hosts.synapse }} + http: + paths: + - path: "/" + backend: + serviceName: "{{ include "matrix.fullname" . }}-synapse" + servicePort: {{ .Values.synapse.service.port }} + {{- if .Values.riot.enabled }} + - host: {{ .Values.ingress.hosts.riot }} + http: + paths: + - path: "/" + backend: + serviceName: "{{ include "matrix.fullname" . }}-riot" + servicePort: {{ .Values.riot.service.port }} + {{- end }} + {{- if .Values.ingress.federation }} + - host: {{ .Values.ingress.hosts.federation }} + http: + paths: + - path: "/" + backend: + serviceName: "{{ include "matrix.fullname" . }}-synapse-federation" + servicePort: {{ .Values.synapse.service.federation.port }} + {{- end }} +{{- end }} diff --git a/charts/matrix/templates/postgresql/initdb-configmap.yaml b/charts/matrix/templates/postgresql/initdb-configmap.yaml new file mode 100644 index 0000000..2c060a3 --- /dev/null +++ b/charts/matrix/templates/postgresql/initdb-configmap.yaml @@ -0,0 +1,30 @@ +{{- if .Values.postgresql.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "matrix.fullname" . }}-postgresql-initdb + labels: + {{ include "matrix.labels" . | nindent 4}} +data: + matrix.sql: | + CREATE USER {{ .Values.postgresql.username }} + LOGIN + ENCRYPTED PASSWORD '{{ .Values.postgresql.password }}'; + + CREATE DATABASE {{ .Values.postgresql.database }} + ENCODING 'UTF8' + LC_COLLATE='C' + LC_CTYPE='C' + template=template0 + OWNER {{ .Values.postgresql.username }}; + {{- if .Values.bridges.irc.enabled }} + {{/* Scripts are run in alphabetical order */}} + zzz_irc.sql: | + CREATE DATABASE {{ .Values.bridges.irc.database }} + ENCODING 'UTF8' + LC_COLLATE='C' + LC_CTYPE='C' + template=template0 + OWNER {{ .Values.postgresql.username }}; + {{- end }} +{{- end }} diff --git a/charts/matrix/templates/postgresql/network-policy.yaml b/charts/matrix/templates/postgresql/network-policy.yaml new file mode 100644 index 0000000..d78cd3f --- /dev/null +++ b/charts/matrix/templates/postgresql/network-policy.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.networkPolicies.enabled .Values.postgresql.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "matrix.fullname" . }}-postgresql + labels: +{{ include "matrix.labels" . | indent 4 }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: {{ include "postgresql.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-synapse + app.kubernetes.io/instance: {{ .Release.Name }} + ports: + - port: tcp-postgresql + protocol: TCP +{{- end }} diff --git a/charts/matrix/templates/riot/configmap.yaml b/charts/matrix/templates/riot/configmap.yaml new file mode 100644 index 0000000..c27de19 --- /dev/null +++ b/charts/matrix/templates/riot/configmap.yaml @@ -0,0 +1,127 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "matrix.fullname" . }}-riot-config + labels: +{{ include "matrix.labels" . | nindent 4}} +{{ include "matrix.element.labels" . | indent 4}} +data: + config.json: | + { + "default_server_config": { + "m.homeserver": { + "base_url": {{ include "matrix.baseUrl" . | quote }} + } + }, + "brand": {{ .Values.riot.branding.brand | quote }}, + "branding": { + {{- if .Values.riot.branding.welcomeBackgroundUrl }} + "welcomeBackgroundUrl": {{ .Values.riot.branding.welcomeBackgroundUrl | quote }}, + {{- end }} + {{- if .Values.riot.branding.authHeaderLogoUrl }} + "authHeaderLogoUrl": {{ .Values.riot.branding.authHeaderLogoUrl | quote }}, + {{- end }} + {{- if .Values.riot.branding.authFooterLinks }} + "authFooterLinks": {{ .Values.riot.branding.authFooterLinks | toJson }}, + {{- end }} + }, + {{- if .Values.riot.integrations.enabled }} + "integrations_ui_url": {{ .Values.riot.integrations.ui | quote }}, + "integrations_rest_url": {{ .Values.riot.integrations.api | quote }}, + "integrations_widgets_urls": {{ .Values.riot.integrations.widgets | toJson }}, + {{- end }} + {{- if .Values.riot.labs }} {{/* if not empty */}} + "showLabsSettings": true, + {{- else }} + "showLabsSettings": false, + {{- end }} + "features": { + {{- if .Values.riot.labs }} + {{- range initial .Values.riot.labs }} + {{ . | quote }}: "labs", + {{- end }} + {{ last .Values.riot.labs | quote }}: "labs" + {{- end }} + }, + "roomDirectory": { + "servers": {{ .Values.riot.roomDirectoryServers | toJson }} + }, + {{- if .Values.riot.welcomeUserId }} + "welcomeUserId": {{ .Values.riot.welcomeUserId | quote }}, + {{- end }} + "permalinkPrefix": {{ .Values.riot.permalinkPrefix | quote }} + } + nginx.conf: | + worker_processes auto; + + error_log /var/log/nginx/error.log warn; + pid /var/run/pid/nginx.pid; + + events { + worker_connections 1024; + } + + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + include /etc/nginx/conf.d/*.conf; + } + default.conf: | + server { + listen 8080; + server_name localhost; + + #charset koi8-r; + #access_log /var/log/nginx/host.access.log main; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + + #error_page 404 /404.html; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + # proxy the PHP scripts to Apache listening on 127.0.0.1:80 + # + #location ~ \.php$ { + # proxy_pass http://127.0.0.1; + #} + + # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 + # + #location ~ \.php$ { + # root html; + # fastcgi_pass 127.0.0.1:9000; + # fastcgi_index index.php; + # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; + # include fastcgi_params; + #} + + # deny access to .htaccess files, if Apache's document root + # concurs with nginx's one + # + #location ~ /\.ht { + # deny all; + #} + } \ No newline at end of file diff --git a/charts/matrix/templates/riot/deployment.yaml b/charts/matrix/templates/riot/deployment.yaml new file mode 100644 index 0000000..890417b --- /dev/null +++ b/charts/matrix/templates/riot/deployment.yaml @@ -0,0 +1,97 @@ +{{- if .Values.riot.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "matrix.fullname" . }}-riot + labels: +{{ include "matrix.labels" . | indent 4 }} +{{ include "matrix.element.labels" . | indent 4}} +spec: + replicas: {{ .Values.riot.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-riot + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + annotations: + # re-roll deployment on config change + checksum/riot-config: {{ include (print $.Template.BasePath "/riot/configmap.yaml") . | sha256sum }} + labels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-riot + app.kubernetes.io/instance: {{ .Release.Name }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + containers: + - name: "riot" + image: "{{ .Values.riot.image.repository }}:{{ .Values.riot.image.tag }}" + imagePullPolicy: {{ .Values.riot.image.pullPolicy }} + ports: + - name: http + containerPort: 8080 + protocol: TCP + volumeMounts: + - mountPath: /app/config.json + name: riot-config + subPath: config.json + readOnly: true + - mountPath: /etc/nginx/nginx.conf + name: riot-config + subPath: nginx.conf + readOnly: true + - mountPath: /etc/nginx/conf.d/default.conf + name: riot-config + subPath: default.conf + readOnly: true + - mountPath: /var/cache/nginx + name: ephemeral + subPath: cache + - mountPath: /var/run/pid + name: ephemeral + subPath: pid + readinessProbe: + httpGet: + path: / + port: http + {{- if .Values.riot.probes.readiness }} + {{- toYaml .Values.riot.probes.readiness | nindent 12 }} + {{- end }} + startupProbe: + httpGet: + path: / + port: http + {{- if .Values.riot.probes.startup }} + {{- toYaml .Values.riot.probes.startup | nindent 12 }} + {{- end }} + livenessProbe: + httpGet: + path: / + port: http + {{- if .Values.riot.probes.liveness }} + {{- toYaml .Values.riot.probes.liveness | nindent 12 }} + {{- end }} + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + {{- with .Values.riot.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumes: + - name: riot-config + configMap: + name: {{ include "matrix.fullname" . }}-riot-config + # ephemeral cache, PID file, and any other temporary files nginx needs access to + - name: ephemeral + emptyDir: {} +{{- end }} diff --git a/charts/matrix/templates/riot/network-policy.yaml b/charts/matrix/templates/riot/network-policy.yaml new file mode 100644 index 0000000..df9b0a8 --- /dev/null +++ b/charts/matrix/templates/riot/network-policy.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.networkPolicies.enabled .Values.riot.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "matrix.fullname" . }}-riot + labels: +{{ include "matrix.labels" . | indent 4 }} +{{ include "matrix.element.labels" . | indent 4}} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.fullname" . }}-riot + app.kubernetes.io/instance: {{ .Release.Name }} + policyTypes: + - Ingress +{{- end }} diff --git a/charts/matrix/templates/riot/service.yaml b/charts/matrix/templates/riot/service.yaml new file mode 100644 index 0000000..93209c8 --- /dev/null +++ b/charts/matrix/templates/riot/service.yaml @@ -0,0 +1,19 @@ +{{- if .Values.riot.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "matrix.fullname" . }}-riot + labels: +{{ include "matrix.labels" . | indent 4 }} +{{ include "matrix.element.labels" . | indent 4}} +spec: + type: {{ .Values.riot.service.type }} + ports: + - port: {{ .Values.riot.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + app.kubernetes.io/name: {{ include "matrix.name" . }}-riot + app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/matrix/templates/synapse/_homeserver.yaml b/charts/matrix/templates/synapse/_homeserver.yaml new file mode 100644 index 0000000..876337e --- /dev/null +++ b/charts/matrix/templates/synapse/_homeserver.yaml @@ -0,0 +1,2293 @@ +{{- define "homeserver.yaml" }} +{{- if .Values.matrix.homeserverOverride }} +{{- toYaml .Values.matrix.homeserverOverride }} +{{- else }} +## Server ## + +# The domain name of the server, with optional explicit port. +# This is used by remote servers to connect to this server, +# e.g. matrix.org, localhost:8080, etc. +# This is also the last part of your UserID. +# +server_name: {{ .Values.matrix.serverName }} + +# When running as a daemon, the file to store the pid in +# +pid_file: /data/homeserver.pid + +# The absolute URL to the web client which /_matrix/client will redirect +# to if 'webclient' is configured under the 'listeners' configuration. +# +# This option can be also set to the filesystem path to the web client +# which will be served at /_matrix/client/ if 'webclient' is configured +# under the 'listeners' configuration, however this is a security risk: +# https://github.com/matrix-org/synapse#security-note +# +#web_client_location: https://riot.example.com/ + +# The public-facing base URL that clients use to access this HS +# (not including _matrix/...). This is the same URL a user would +# enter into the 'custom HS URL' field on their client. If you +# use synapse with a reverse proxy, this should be the URL to reach +# synapse via the proxy. +# +public_baseurl: {{ include "matrix.baseUrl" . | quote }} +# Set the soft limit on the number of file descriptors synapse can use +# Zero is used to indicate synapse should set the soft limit to the +# hard limit. +# +#soft_file_limit: 0 + +# Set to false to disable presence tracking on this homeserver. +# +use_presence: {{ .Values.matrix.presence }} + +# Whether to require authentication to retrieve profile data (avatars, +# display names) of other users through the client API. Defaults to +# 'false'. Note that profile data is also available via the federation +# API, so this setting is of limited value if federation is enabled on +# the server. +# +#require_auth_for_profile_requests: true + +# Uncomment to require a user to share a room with another user in order +# to retrieve their profile information. Only checked on Client-Server +# requests. Profile requests from other servers should be checked by the +# requesting server. Defaults to 'false'. +# +#limit_profile_requests_to_users_who_share_rooms: true + +# If set to 'true', removes the need for authentication to access the server's +# public rooms directory through the client API, meaning that anyone can +# query the room directory. Defaults to 'false'. +# +#allow_public_rooms_without_auth: true + +# If set to 'true', allows any other homeserver to fetch the server's public +# rooms directory via federation. Defaults to 'false'. +# +allow_public_rooms_over_federation: {{ and .Values.matrix.federation.enabled .Values.matrix.federation.allowPublicRooms }} + +# The default room version for newly created rooms. +# +# Known room versions are listed here: +# https://matrix.org/docs/spec/#complete-list-of-room-versions +# +# For example, for room version 1, default_room_version should be set +# to "1". +# +#default_room_version: "5" + +# The GC threshold parameters to pass to `gc.set_threshold`, if defined +# +#gc_thresholds: [700, 10, 10] + +# Set the limit on the returned events in the timeline in the get +# and sync operations. The default value is -1, means no upper limit. +# +#filter_timeline_limit: 5000 + +# Whether room invites to users on this server should be blocked +# (except those sent by local server admins). The default is False. +# +block_non_admin_invites: {{ .Values.matrix.blockNonAdminInvites }} + +# Room searching +# +# If disabled, new messages will not be indexed for searching and users +# will receive errors when searching for messages. Defaults to enabled. +# +enable_search: {{ .Values.matrix.search }} + +# Restrict federation to the following whitelist of domains. +# N.B. we recommend also firewalling your federation listener to limit +# inbound federation traffic as early as possible, rather than relying +# purely on this application-layer restriction. If not specified, the +# default is to whitelist everything. + +{{- if .Values.matrix.federation.whitelist }} +federation_domain_whitelist: + {{- range .Values.matrix.federation.whitelist }} + - {{ . }} + {{- end }} +{{- end}} + +# Prevent federation requests from being sent to the following +# blacklist IP address CIDR ranges. If this option is not specified, or +# specified with an empty list, no ip range blacklist will be enforced. +# +# As of Synapse v1.4.0 this option also affects any outbound requests to identity +# servers provided by user input. +# +# (0.0.0.0 and :: are always blacklisted, whether or not they are explicitly +# listed here, since they correspond to unroutable addresses.) + +federation_ip_range_blacklist: +{{- range .Values.matrix.federation.blacklist }} + - {{ . }} +{{- end }} + +# List of ports that Synapse should listen on, their purpose and their +# configuration. +# +# Options for each listener include: +# +# port: the TCP port to bind to +# +# bind_addresses: a list of local addresses to listen on. The default is +# 'all local interfaces'. +# +# type: the type of listener. Normally 'http', but other valid options are: +# 'manhole' (see docs/manhole.md), +# 'metrics' (see docs/metrics-howto.md), +# 'replication' (see docs/workers.md). +# +# tls: set to true to enable TLS for this listener. Will use the TLS +# key/cert specified in tls_private_key_path / tls_certificate_path. +# +# x_forwarded: Only valid for an 'http' listener. Set to true to use the +# X-Forwarded-For header as the client IP. Useful when Synapse is +# behind a reverse-proxy. +# +# resources: Only valid for an 'http' listener. A list of resources to host +# on this port. Options for each resource are: +# +# names: a list of names of HTTP resources. See below for a list of +# valid resource names. +# +# compress: set to true to enable HTTP comression for this resource. +# +# additional_resources: Only valid for an 'http' listener. A map of +# additional endpoints which should be loaded via dynamic modules. +# +# Valid resource names are: +# +# client: the client-server API (/_matrix/client), and the synapse admin +# API (/_synapse/admin). Also implies 'media' and 'static'. +# +# consent: user consent forms (/_matrix/consent). See +# docs/consent_tracking.md. +# +# federation: the server-server API (/_matrix/federation). Also implies +# 'media', 'keys', 'openid' +# +# keys: the key discovery API (/_matrix/keys). +# +# media: the media API (/_matrix/media). +# +# metrics: the metrics interface. See docs/metrics-howto.md. +# +# openid: OpenID authentication. +# +# replication: the HTTP replication API (/_synapse/replication). See +# docs/workers.md. +# +# static: static resources under synapse/static (/_matrix/static). (Mostly +# useful for 'fallback authentication'.) +# +# webclient: A web client. Requires web_client_location to be set. +# +listeners: + # TLS-enabled listener: for when matrix traffic is sent directly to synapse. + # + # Disabled by default. To enable it, uncomment the following. (Note that you + # will also need to give Synapse a TLS key and certificate: see the TLS section + # below.) + # + #- port: 8448 + # type: http + # tls: true + # resources: + # - names: [client, federation] + + # Unsecure HTTP listener: for when matrix traffic passes through a reverse proxy + # that unwraps TLS. + # + # If you plan to use a reverse proxy, please see + # https://github.com/matrix-org/synapse/blob/master/docs/reverse_proxy.md. + # + - port: 8008 + tls: false + type: http + x_forwarded: true + bind_addresses: ['0.0.0.0'] + + resources: + - names: [client, federation] + compress: false + + # example additional_resources: + # + #additional_resources: + # "/_matrix/my/custom/endpoint": + # module: my_module.CustomRequestHandler + # config: {} + +{{- if .Values.synapse.metrics.enabled }} + - type: metrics + port: {{ .Values.synapse.metrics.port }} + bind_addresses: ['0.0.0.0'] + + resources: + - names: [metrics] +{{- end }} + # Turn on the twisted ssh manhole service on localhost on the given + # port. + # + #- port: 9000 + # bind_addresses: ['::1', '127.0.0.1'] + # type: manhole + +# Forward extremities can build up in a room due to networking delays between +# homeservers. Once this happens in a large room, calculation of the state of +# that room can become quite expensive. To mitigate this, once the number of +# forward extremities reaches a given threshold, Synapse will send an +# org.matrix.dummy_event event, which will reduce the forward extremities +# in the room. +# +# This setting defines the threshold (i.e. number of forward extremities in the +# room) at which dummy events are sent. The default value is 10. +# +#dummy_events_threshold: 5 + + +## Homeserver blocking ## + +# How to reach the server admin, used in ResourceLimitError +# +admin_contact: 'mailto:{{ .Values.matrix.adminEmail }}' + +# Global blocking +# +hs_disabled: {{ .Values.matrix.disabled }} +hs_disabled_message: {{ .Values.matrix.disabledMessage }} + +# Monthly Active User Blocking +# +# Used in cases where the admin or server owner wants to limit to the +# number of monthly active users. +# +# 'limit_usage_by_mau' disables/enables monthly active user blocking. When +# enabled and a limit is reached the server returns a 'ResourceLimitError' +# with error type Codes.RESOURCE_LIMIT_EXCEEDED +# +# 'max_mau_value' is the hard limit of monthly active users above which +# the server will start blocking user actions. +# +# 'mau_trial_days' is a means to add a grace period for active users. It +# means that users must be active for this number of days before they +# can be considered active and guards against the case where lots of users +# sign up in a short space of time never to return after their initial +# session. +# +# 'mau_limit_alerting' is a means of limiting client side alerting +# should the mau limit be reached. This is useful for small instances +# where the admin has 5 mau seats (say) for 5 specific people and no +# interest increasing the mau limit further. Defaults to True, which +# means that alerting is enabled +# +#limit_usage_by_mau: false +#max_mau_value: 50 +#mau_trial_days: 2 +#mau_limit_alerting: false + +# If enabled, the metrics for the number of monthly active users will +# be populated, however no one will be limited. If limit_usage_by_mau +# is true, this is implied to be true. +# +#mau_stats_only: false + +# Sometimes the server admin will want to ensure certain accounts are +# never blocked by mau checking. These accounts are specified here. +# +#mau_limit_reserved_threepids: +# - medium: 'email' +# address: 'reserved_user@example.com' + +# Used by phonehome stats to group together related servers. +#server_context: context + +# Resource-constrained homeserver settings +# +# When this is enabled, the room "complexity" will be checked before a user +# joins a new remote room. If it is above the complexity limit, the server will +# disallow joining, or will instantly leave. +# +# Room complexity is an arbitrary measure based on factors such as the number of +# users in the room. +# +limit_remote_rooms: + # Uncomment to enable room complexity checking. + # + #enabled: true + + # the limit above which rooms cannot be joined. The default is 1.0. + # + #complexity: 0.5 + + # override the error which is returned when the room is too complex. + # + #complexity_error: "This room is too complex." + +# Whether to require a user to be in the room to add an alias to it. +# Defaults to 'true'. +# +#require_membership_for_aliases: false + +# Whether to allow per-room membership profiles through the send of membership +# events with profile information that differ from the target's global profile. +# Defaults to 'true'. +# +#allow_per_room_profiles: false + +# How long to keep redacted events in unredacted form in the database. After +# this period redacted events get replaced with their redacted form in the DB. +# +# Defaults to `7d`. Set to `null` to disable. +# +redaction_retention_period: {{ .Values.matrix.retentionPeriod }} + +# How long to track users' last seen time and IPs in the database. +# +# Defaults to `28d`. Set to `null` to disable clearing out of old rows. +# +#user_ips_max_age: 14d + +# Message retention policy at the server level. +# +# Room admins and mods can define a retention period for their rooms using the +# 'm.room.retention' state event, and server admins can cap this period by setting +# the 'allowed_lifetime_min' and 'allowed_lifetime_max' config options. +# +# If this feature is enabled, Synapse will regularly look for and purge events +# which are older than the room's maximum retention period. Synapse will also +# filter events received over federation so that events that should have been +# purged are ignored and not stored again. +# +retention: + # The message retention policies feature is disabled by default. Uncomment the + # following line to enable it. + # + #enabled: true + + # Default retention policy. If set, Synapse will apply it to rooms that lack the + # 'm.room.retention' state event. Currently, the value of 'min_lifetime' doesn't + # matter much because Synapse doesn't take it into account yet. + # + #default_policy: + # min_lifetime: 1d + # max_lifetime: 1y + + # Retention policy limits. If set, a user won't be able to send a + # 'm.room.retention' event which features a 'min_lifetime' or a 'max_lifetime' + # that's not within this range. This is especially useful in closed federations, + # in which server admins can make sure every federating server applies the same + # rules. + # + #allowed_lifetime_min: 1d + #allowed_lifetime_max: 1y + + # Server admins can define the settings of the background jobs purging the + # events which lifetime has expired under the 'purge_jobs' section. + # + # If no configuration is provided, a single job will be set up to delete expired + # events in every room daily. + # + # Each job's configuration defines which range of message lifetimes the job + # takes care of. For example, if 'shortest_max_lifetime' is '2d' and + # 'longest_max_lifetime' is '3d', the job will handle purging expired events in + # rooms whose state defines a 'max_lifetime' that's both higher than 2 days, and + # lower than or equal to 3 days. Both the minimum and the maximum value of a + # range are optional, e.g. a job with no 'shortest_max_lifetime' and a + # 'longest_max_lifetime' of '3d' will handle every room with a retention policy + # which 'max_lifetime' is lower than or equal to three days. + # + # The rationale for this per-job configuration is that some rooms might have a + # retention policy with a low 'max_lifetime', where history needs to be purged + # of outdated messages on a more frequent basis than for the rest of the rooms + # (e.g. every 12h), but not want that purge to be performed by a job that's + # iterating over every room it knows, which could be heavy on the server. + # + #purge_jobs: + # - shortest_max_lifetime: 1d + # longest_max_lifetime: 3d + # interval: 12h + # - shortest_max_lifetime: 3d + # longest_max_lifetime: 1y + # interval: 1d + +# Inhibits the /requestToken endpoints from returning an error that might leak +# information about whether an e-mail address is in use or not on this +# homeserver. +# Note that for some endpoints the error situation is the e-mail already being +# used, and for others the error is entering the e-mail being unused. +# If this option is enabled, instead of returning an error, these endpoints will +# act as if no error happened and return a fake session ID ('sid') to clients. +# +#request_token_inhibit_3pid_errors: true + + +## TLS ## + +# PEM-encoded X509 certificate for TLS. +# This certificate, as of Synapse 1.0, will need to be a valid and verifiable +# certificate, signed by a recognised Certificate Authority. +# +# See 'ACME support' below to enable auto-provisioning this certificate via +# Let's Encrypt. +# +# If supplying your own, be sure to use a `.pem` file that includes the +# full certificate chain including any intermediate certificates (for +# instance, if using certbot, use `fullchain.pem` as your certificate, +# not `cert.pem`). +# +#tls_certificate_path: "CONFDIR/SERVERNAME.tls.crt" + +# PEM-encoded private key for TLS +# +#tls_private_key_path: "CONFDIR/SERVERNAME.tls.key" + +# Whether to verify TLS server certificates for outbound federation requests. +# +# Defaults to `true`. To disable certificate verification, uncomment the +# following line. +# +#federation_verify_certificates: false + +# The minimum TLS version that will be used for outbound federation requests. +# +# Defaults to `1`. Configurable to `1`, `1.1`, `1.2`, or `1.3`. Note +# that setting this value higher than `1.2` will prevent federation to most +# of the public Matrix network: only configure it to `1.3` if you have an +# entirely private federation setup and you can ensure TLS 1.3 support. +# +#federation_client_minimum_tls_version: 1.2 + +# Skip federation certificate verification on the following whitelist +# of domains. +# +# This setting should only be used in very specific cases, such as +# federation over Tor hidden services and similar. For private networks +# of homeservers, you likely want to use a private CA instead. +# +# Only effective if federation_verify_certicates is `true`. +# +#federation_certificate_verification_whitelist: +# - lon.example.com +# - *.domain.com +# - *.onion + +# List of custom certificate authorities for federation traffic. +# +# This setting should only normally be used within a private network of +# homeservers. +# +# Note that this list will replace those that are provided by your +# operating environment. Certificates must be in PEM format. +# +#federation_custom_ca_list: +# - myCA1.pem +# - myCA2.pem +# - myCA3.pem + +# ACME support: This will configure Synapse to request a valid TLS certificate +# for your configured `server_name` via Let's Encrypt. +# +# Note that ACME v1 is now deprecated, and Synapse currently doesn't support +# ACME v2. This means that this feature currently won't work with installs set +# up after November 2019. For more info, and alternative solutions, see +# https://github.com/matrix-org/synapse/blob/master/docs/ACME.md#deprecation-of-acme-v1 +# +# Note that provisioning a certificate in this way requires port 80 to be +# routed to Synapse so that it can complete the http-01 ACME challenge. +# By default, if you enable ACME support, Synapse will attempt to listen on +# port 80 for incoming http-01 challenges - however, this will likely fail +# with 'Permission denied' or a similar error. +# +# There are a couple of potential solutions to this: +# +# * If you already have an Apache, Nginx, or similar listening on port 80, +# you can configure Synapse to use an alternate port, and have your web +# server forward the requests. For example, assuming you set 'port: 8009' +# below, on Apache, you would write: +# +# ProxyPass /.well-known/acme-challenge http://localhost:8009/.well-known/acme-challenge +# +# * Alternatively, you can use something like `authbind` to give Synapse +# permission to listen on port 80. +# +acme: + # ACME support is disabled by default. Set this to `true` and uncomment + # tls_certificate_path and tls_private_key_path above to enable it. + # + enabled: false + + # Endpoint to use to request certificates. If you only want to test, + # use Let's Encrypt's staging url: + # https://acme-staging.api.letsencrypt.org/directory + # + #url: https://acme-v01.api.letsencrypt.org/directory + + # Port number to listen on for the HTTP-01 challenge. Change this if + # you are forwarding connections through Apache/Nginx/etc. + # + port: 80 + + # Local addresses to listen on for incoming connections. + # Again, you may want to change this if you are forwarding connections + # through Apache/Nginx/etc. + # + bind_addresses: ['::', '0.0.0.0'] + + # How many days remaining on a certificate before it is renewed. + # + reprovision_threshold: 30 + + # The domain that the certificate should be for. Normally this + # should be the same as your Matrix domain (i.e., 'server_name'), but, + # by putting a file at 'https:///.well-known/matrix/server', + # you can delegate incoming traffic to another server. If you do that, + # you should give the target of the delegation here. + # + # For example: if your 'server_name' is 'example.com', but + # 'https://example.com/.well-known/matrix/server' delegates to + # 'matrix.example.com', you should put 'matrix.example.com' here. + # + # If not set, defaults to your 'server_name'. + # + domain: matrix.example.com + + # file to use for the account key. This will be generated if it doesn't + # exist. + # + # If unspecified, we will use CONFDIR/client.key. + # + account_key_file: DATADIR/acme_account.key + +# List of allowed TLS fingerprints for this server to publish along +# with the signing keys for this server. Other matrix servers that +# make HTTPS requests to this server will check that the TLS +# certificates returned by this server match one of the fingerprints. +# +# Synapse automatically adds the fingerprint of its own certificate +# to the list. So if federation traffic is handled directly by synapse +# then no modification to the list is required. +# +# If synapse is run behind a load balancer that handles the TLS then it +# will be necessary to add the fingerprints of the certificates used by +# the loadbalancers to this list if they are different to the one +# synapse is using. +# +# Homeservers are permitted to cache the list of TLS fingerprints +# returned in the key responses up to the "valid_until_ts" returned in +# key. It may be necessary to publish the fingerprints of a new +# certificate and wait until the "valid_until_ts" of the previous key +# responses have passed before deploying it. +# +# You can calculate a fingerprint from a given TLS listener via: +# openssl s_client -connect $host:$port < /dev/null 2> /dev/null | +# openssl x509 -outform DER | openssl sha256 -binary | base64 | tr -d '=' +# or by checking matrix.org/federationtester/api/report?server_name=$host +# +#tls_fingerprints: [{"sha256": ""}] + +## Database ## + +database: + # The database engine name + name: "psycopg2" + # Arguments to pass to the engine + args: + user: "{{ .Values.postgresql.username }}" + password: "{{ .Values.postgresql.password }}" + database: "{{ .Values.postgresql.database }}" + + {{- if .Values.postgresql.enabled }} + host: "{{ include "matrix.fullname" . }}-postgresql" + port: "5432" + {{- else }} + host: "{{ .Values.postgresql.hostname }}" + port: "{{ .Values.postgresql.port }}" + {{- end }} + sslmode: {{ .Values.postgresql.sslMode }} + cp_min: 5 + cp_max: 10 + +# Number of events to cache in memory. +# +#event_cache_size: 10K + + +## Logging ## + +# A yaml python logging config file as described by +# https://docs.python.org/3.7/library/logging.config.html#configuration-dictionary-schema +# +log_config: "/data/{{ .Values.matrix.serverName }}.log.config" + + +## Ratelimiting ## + +# Ratelimiting settings for client actions (registration, login, messaging). +# +# Each ratelimiting configuration is made of two parameters: +# - per_second: number of requests a client can send per second. +# - burst_count: number of requests a client can send before being throttled. +# +# Synapse currently uses the following configurations: +# - one for messages that ratelimits sending based on the account the client +# is using +# - one for registration that ratelimits registration requests based on the +# client's IP address. +# - one for login that ratelimits login requests based on the client's IP +# address. +# - one for login that ratelimits login requests based on the account the +# client is attempting to log into. +# - one for login that ratelimits login requests based on the account the +# client is attempting to log into, based on the amount of failed login +# attempts for this account. +# - one for ratelimiting redactions by room admins. If this is not explicitly +# set then it uses the same ratelimiting as per rc_message. This is useful +# to allow room admins to deal with abuse quickly. +# +# The defaults are as shown below. +# +#rc_message: +# per_second: 0.2 +# burst_count: 10 +# +#rc_registration: +# per_second: 0.17 +# burst_count: 3 +# +#rc_login: +# address: +# per_second: 0.17 +# burst_count: 3 +# account: +# per_second: 0.17 +# burst_count: 3 +# failed_attempts: +# per_second: 0.17 +# burst_count: 3 +# +#rc_admin_redaction: +# per_second: 1 +# burst_count: 50 + + +# Ratelimiting settings for incoming federation +# +# The rc_federation configuration is made up of the following settings: +# - window_size: window size in milliseconds +# - sleep_limit: number of federation requests from a single server in +# a window before the server will delay processing the request. +# - sleep_delay: duration in milliseconds to delay processing events +# from remote servers by if they go over the sleep limit. +# - reject_limit: maximum number of concurrent federation requests +# allowed from a single server +# - concurrent: number of federation requests to concurrently process +# from a single server +# +# The defaults are as shown below. +# +#rc_federation: +# window_size: 1000 +# sleep_limit: 10 +# sleep_delay: 500 +# reject_limit: 50 +# concurrent: 3 + +# Target outgoing federation transaction frequency for sending read-receipts, +# per-room. +# +# If we end up trying to send out more read-receipts, they will get buffered up +# into fewer transactions. +# +#federation_rr_transactions_per_room_per_second: 50 + + + +## Media Store ## + +# Enable the media store service in the Synapse master. Uncomment the +# following if you are using a separate media store worker. +# +#enable_media_repo: false + +# Directory where uploaded images and attachments are stored. +# +media_store_path: "/data/media_store" + +# Media storage providers allow media to be stored in different +# locations. +# +#media_storage_providers: +# - module: file_system +# # Whether to write new local files. +# store_local: false +# # Whether to write new remote media +# store_remote: false +# # Whether to block upload requests waiting for write to this +# # provider to complete +# store_synchronous: false +# config: +# directory: /mnt/some/other/directory + +# Directory where in-progress uploads are stored. +# +uploads_path: "/data/uploads" + +# The largest allowed upload size in bytes + +max_upload_size: {{ .Values.matrix.uploads.maxSize }} + +# Maximum number of pixels that will be thumbnailed + +max_image_pixels: {{ .Values.matrix.uploads.maxPixels }} + +# Whether to generate new thumbnails on the fly to precisely match +# the resolution requested by the client. If true then whenever +# a new resolution is requested by the client the server will +# generate a new thumbnail. If false the server will pick a thumbnail +# from a precalculated list. +# +#dynamic_thumbnails: false + +# List of thumbnails to precalculate when an image is uploaded. +# +#thumbnail_sizes: +# - width: 32 +# height: 32 +# method: crop +# - width: 96 +# height: 96 +# method: crop +# - width: 320 +# height: 240 +# method: scale +# - width: 640 +# height: 480 +# method: scale +# - width: 800 +# height: 600 +# method: scale + +# Is the preview URL API enabled? +# +# 'false' by default: uncomment the following to enable it (and specify a +# url_preview_ip_range_blacklist blacklist). +# +url_preview_enabled: {{ .Values.matrix.urlPreviews.enabled }} + +# List of IP address CIDR ranges that the URL preview spider is denied +# from accessing. There are no defaults: you must explicitly +# specify a list for URL previewing to work. You should specify any +# internal services in your network that you do not want synapse to try +# to connect to, otherwise anyone in any Matrix room could cause your +# synapse to issue arbitrary GET requests to your internal services, +# causing serious security issues. +# +# (0.0.0.0 and :: are always blacklisted, whether or not they are explicitly +# listed here, since they correspond to unroutable addresses.) +# +# This must be specified if url_preview_enabled is set. It is recommended that +# you uncomment the following list as a starting point. + +{{- if .Values.matrix.urlPreviews.rules.ip.blacklist }} +url_preview_ip_range_blacklist: + {{- range .Values.matrix.urlPreviews.rules.ip.blacklist }} + - {{ . }} + {{- end }} +{{- end }} + +# List of IP address CIDR ranges that the URL preview spider is allowed +# to access even if they are specified in url_preview_ip_range_blacklist. +# This is useful for specifying exceptions to wide-ranging blacklisted +# target IP ranges - e.g. for enabling URL previews for a specific private +# website only visible in your network. + +{{- if .Values.matrix.urlPreviews.rules.ip.whitelist }} +url_preview_ip_range_whitelist: + {{- range .Values.matrix.urlPreviews.rules.ip.whitelist}} + - {{ . }} + {{- end }} +{{- end }} + +# Optional list of URL matches that the URL preview spider is +# denied from accessing. You should use url_preview_ip_range_blacklist +# in preference to this, otherwise someone could define a public DNS +# entry that points to a private IP address and circumvent the blacklist. +# This is more useful if you know there is an entire shape of URL that +# you know that will never want synapse to try to spider. +# +# Each list entry is a dictionary of url component attributes as returned +# by urlparse.urlsplit as applied to the absolute form of the URL. See +# https://docs.python.org/2/library/urlparse.html#urlparse.urlsplit +# The values of the dictionary are treated as an filename match pattern +# applied to that component of URLs, unless they start with a ^ in which +# case they are treated as a regular expression match. If all the +# specified component matches for a given list item succeed, the URL is +# blacklisted. + +{{- if .Values.matrix.urlPreviews.rules.url.blacklist }} +url_preview_url_blacklist: +{{ include .Values.matrix.urlPreviews.rules.url.blacklist . | nindent 2 }} +{{- end }} + +# The largest allowed URL preview spidering size in bytes + +max_spider_size: {{ .Values.matrix.urlPreviews.rules.maxSize }} + +## Captcha ## +# See docs/CAPTCHA_SETUP for full details of configuring this. + +# This homeserver's ReCAPTCHA public key. +# +#recaptcha_public_key: "YOUR_PUBLIC_KEY" + +# This homeserver's ReCAPTCHA private key. +# +#recaptcha_private_key: "YOUR_PRIVATE_KEY" + +# Enables ReCaptcha checks when registering, preventing signup +# unless a captcha is answered. Requires a valid ReCaptcha +# public/private key. +# +#enable_registration_captcha: false + +# A secret key used to bypass the captcha test entirely. +# +#captcha_bypass_secret: "YOUR_SECRET_HERE" + +# The API endpoint to use for verifying m.login.recaptcha responses. +# +#recaptcha_siteverify_api: "https://www.recaptcha.net/recaptcha/api/siteverify" + +{{- if .Values.coturn.enabled -}} + +## TURN ## + +# The public URIs of the TURN server to give to clients + +# Let the user specify coturn URIs explicitly +{{- if not (empty .Values.coturn.uris) }} +turn_uris: + {{- range .Values.coturn.uris }} + - {{ . }} + {{- end }} +{{- else }} + +# Default to using the matrix hostname as +turn_uris: + - "turn:{{ include "matrix.hostname" . }}?transport=udp" + +{{- end }} +# The shared secret used to compute passwords for the TURN server + +turn_shared_secret: {{ include "matrix.coturn.sharedSecret" . }} + +# How long generated TURN credentials last + +turn_user_lifetime: 1h + +# Whether guests should be allowed to use the TURN server. +# This defaults to True, otherwise VoIP will be unreliable for guests. +# However, it does introduce a slight security risk as it allows users to +# connect to arbitrary endpoints without having first signed up for a +# valid account (e.g. by passing a CAPTCHA). + +turn_allow_guests: {{ .Values.coturn.allowGuests }} +{{- end }} + +## Registration ## +# +# Registration can be rate-limited using the parameters in the "Ratelimiting" +# section of this file. + +# Enable registration for new users. +# +enable_registration: {{ .Values.matrix.registration.enabled }} + +# Optional account validity configuration. This allows for accounts to be denied +# any request after a given period. +# +# ``enabled`` defines whether the account validity feature is enabled. Defaults +# to False. +# +# ``period`` allows setting the period after which an account is valid +# after its registration. When renewing the account, its validity period +# will be extended by this amount of time. This parameter is required when using +# the account validity feature. +# +# ``renew_at`` is the amount of time before an account's expiry date at which +# Synapse will send an email to the account's email address with a renewal link. +# This needs the ``email`` and ``public_baseurl`` configuration sections to be +# filled. +# +# ``renew_email_subject`` is the subject of the email sent out with the renewal +# link. ``%(app)s`` can be used as a placeholder for the ``app_name`` parameter +# from the ``email`` section. +# +# Once this feature is enabled, Synapse will look for registered users without an +# expiration date at startup and will add one to every account it found using the +# current settings at that time. +# This means that, if a validity period is set, and Synapse is restarted (it will +# then derive an expiration date from the current validity period), and some time +# after that the validity period changes and Synapse is restarted, the users' +# expiration dates won't be updated unless their account is manually renewed. This +# date will be randomly selected within a range [now + period - d ; now + period], +# where d is equal to 10% of the validity period. +# +#account_validity: +# enabled: true +# period: 6w +# renew_at: 1w +# renew_email_subject: "Renew your %(app)s account" +# # Directory in which Synapse will try to find the HTML files to serve to the +# # user when trying to renew an account. Optional, defaults to +# # synapse/res/templates. +# template_dir: "res/templates" +# # HTML to be displayed to the user after they successfully renewed their +# # account. Optional. +# account_renewed_html_path: "account_renewed.html" +# # HTML to be displayed when the user tries to renew an account with an invalid +# # renewal token. Optional. +# invalid_token_html_path: "invalid_token.html" + +# Time that a user's session remains valid for, after they log in. +# +# Note that this is not currently compatible with guest logins. +# +# Note also that this is calculated at login time: changes are not applied +# retrospectively to users who have already logged in. +# +# By default, this is infinite. +# +#session_lifetime: 24h + +# The user must provide all of the below types of 3PID when registering. + +{{- if .Values.matrix.registration.required3Pids }} +registrations_require_3pid: + {{- range .Values.matrix.registration.required3Pids }} + - {{ . }} + {{- end }} +{{- end }} + +# Explicitly disable asking for MSISDNs from the registration +# flow (overrides registrations_require_3pid if MSISDNs are set as required) +# +#disable_msisdn_registration: true + +# Mandate that users are only allowed to associate certain formats of +# 3PIDs with accounts on this server. +# +#allowed_local_3pids: +# - medium: email +# pattern: '.*@matrix\.org' +# - medium: email +# pattern: '.*@vector\.im' +# - medium: msisdn +# pattern: '\+44' + +# Enable 3PIDs lookup requests to identity servers from this server. +# +#enable_3pid_lookup: true + +# If set, allows registration of standard or admin accounts by anyone who +# has the shared secret, even if registration is otherwise disabled. +# +{{- if .Values.matrix.registration.sharedSecret }} +registration_shared_secret: {{ .Values.matrix.registration.sharedSecret }} +{{- end }} + +# Set the number of bcrypt rounds used to generate password hash. +# Larger numbers increase the work factor needed to generate the hash. +# The default number is 12 (which equates to 2^12 rounds). +# N.B. that increasing this will exponentially increase the time required +# to register or login - e.g. 24 => 2^24 rounds which will take >20 mins. +# +#bcrypt_rounds: 12 + +# Allows users to register as guests without a password/email/etc, and +# participate in rooms hosted on this server which have been made +# accessible to anonymous users. + +allow_guest_access: {{ .Values.matrix.registration.allowGuests }} + +# The identity server which we suggest that clients should use when users log +# in on this server. +# +# (By default, no suggestion is made, so it is left up to the client. +# This setting is ignored unless public_baseurl is also set.) +# +#default_identity_server: https://matrix.org + +# The list of identity servers trusted to verify third party +# identifiers by this server. +# +# Also defines the ID server which will be called when an account is +# deactivated (one will be picked arbitrarily). +# +# Note: This option is deprecated. Since v0.99.4, Synapse has tracked which identity +# server a 3PID has been bound to. For 3PIDs bound before then, Synapse runs a +# background migration script, informing itself that the identity server all of its +# 3PIDs have been bound to is likely one of the below. +# +# As of Synapse v1.4.0, all other functionality of this option has been deprecated, and +# it is now solely used for the purposes of the background migration script, and can be +# removed once it has run. +#trusted_third_party_id_servers: +# - matrix.org +# - vector.im + +# Handle threepid (email/phone etc) registration and password resets through a set of +# *trusted* identity servers. Note that this allows the configured identity server to +# reset passwords for accounts! +# +# Be aware that if `email` is not set, and SMTP options have not been +# configured in the email config block, registration and user password resets via +# email will be globally disabled. +# +# Additionally, if `msisdn` is not set, registration and password resets via msisdn +# will be disabled regardless. This is due to Synapse currently not supporting any +# method of sending SMS messages on its own. +# +# To enable using an identity server for operations regarding a particular third-party +# identifier type, set the value to the URL of that identity server as shown in the +# examples below. +# +# Servers handling the these requests must answer the `/requestToken` endpoints defined +# by the Matrix Identity Service API specification: +# https://matrix.org/docs/spec/identity_service/latest +# +# If a delegate is specified, the config option public_baseurl must also be filled out. +# +account_threepid_delegates: +#email: https://example.com # Delegate email sending to example.com +#msisdn: http://localhost:8090 # Delegate SMS sending to this local process + +# Whether users are allowed to change their displayname after it has +# been initially set. Useful when provisioning users based on the +# contents of a third-party directory. +# +# Does not apply to server administrators. Defaults to 'true' +# +#enable_set_displayname: false + +# Whether users are allowed to change their avatar after it has been +# initially set. Useful when provisioning users based on the contents +# of a third-party directory. +# +# Does not apply to server administrators. Defaults to 'true' +# +#enable_set_avatar_url: false + +# Whether users can change the 3PIDs associated with their accounts +# (email address and msisdn). +# +# Defaults to 'true' +# +#enable_3pid_changes: false + +# Users who register on this homeserver will automatically be joined +# to these rooms + +{{- if not (empty .Values.matrix.autoJoinRooms) }} +auto_join_rooms: + {{- range .Values.matrix.autoJoinRooms }} + - {{ . }} + {{- end }} +{{- end }} + +# Where auto_join_rooms are specified, setting this flag ensures that the +# the rooms exist by creating them when the first user on the +# homeserver registers. +# +# By default the auto-created rooms are publicly joinable from any federated +# server. Use the autocreate_auto_join_rooms_federated and +# autocreate_auto_join_room_preset settings below to customise this behaviour. +# +# Setting to false means that if the rooms are not manually created, +# users cannot be auto-joined since they do not exist. +# +# Defaults to true. Uncomment the following line to disable automatically +# creating auto-join rooms. +# +#autocreate_auto_join_rooms: false + +# Whether the auto_join_rooms that are auto-created are available via +# federation. Only has an effect if autocreate_auto_join_rooms is true. +# +# Note that whether a room is federated cannot be modified after +# creation. +# +# Defaults to true: the room will be joinable from other servers. +# Uncomment the following to prevent users from other homeservers from +# joining these rooms. +# +#autocreate_auto_join_rooms_federated: false + +# The room preset to use when auto-creating one of auto_join_rooms. Only has an +# effect if autocreate_auto_join_rooms is true. +# +# This can be one of "public_chat", "private_chat", or "trusted_private_chat". +# If a value of "private_chat" or "trusted_private_chat" is used then +# auto_join_mxid_localpart must also be configured. +# +# Defaults to "public_chat", meaning that the room is joinable by anyone, including +# federated servers if autocreate_auto_join_rooms_federated is true (the default). +# Uncomment the following to require an invitation to join these rooms. +# +#autocreate_auto_join_room_preset: private_chat + +# The local part of the user id which is used to create auto_join_rooms if +# autocreate_auto_join_rooms is true. If this is not provided then the +# initial user account that registers will be used to create the rooms. +# +# The user id is also used to invite new users to any auto-join rooms which +# are set to invite-only. +# +# It *must* be configured if autocreate_auto_join_room_preset is set to +# "private_chat" or "trusted_private_chat". +# +# Note that this must be specified in order for new users to be correctly +# invited to any auto-join rooms which have been set to invite-only (either +# at the time of creation or subsequently). +# +# Note that, if the room already exists, this user must be joined and +# have the appropriate permissions to invite new members. +# +#auto_join_mxid_localpart: system + +# When auto_join_rooms is specified, setting this flag to false prevents +# guest accounts from being automatically joined to the rooms. +# +# Defaults to true. +# +#auto_join_rooms_for_guests: false + + +## Metrics ### + +# Enable collection and rendering of performance metrics +# + +{{- if .Values.synapse.metrics.enabled }} +enable_metrics: true +{{- end }} + +# Enable sentry integration +# NOTE: While attempts are made to ensure that the logs don't contain +# any sensitive information, this cannot be guaranteed. By enabling +# this option the sentry server may therefore receive sensitive +# information, and it in turn may then diseminate sensitive information +# through insecure notification channels if so configured. +# +#sentry: +# dsn: "..." + +# Flags to enable Prometheus metrics which are not suitable to be +# enabled by default, either for performance reasons or limited use. +# +metrics_flags: + # Publish synapse_federation_known_servers, a gauge of the number of + # servers this homeserver knows about, including itself. May cause + # performance problems on large homeservers. + # + #known_servers: true + +# Whether or not to report anonymized homeserver usage statistics. +report_stats: {{ .Values.matrix.telemetry }} + +# The endpoint to report the anonymized homeserver usage statistics to. +# Defaults to https://matrix.org/report-usage-stats/push +# +#report_stats_endpoint: https://example.com/report-usage-stats/push + + +## API Configuration ## + +# A list of event types that will be included in the room_invite_state +# +#room_invite_state_types: +# - "m.room.join_rules" +# - "m.room.canonical_alias" +# - "m.room.avatar" +# - "m.room.encryption" +# - "m.room.name" + + +# A list of application service config files to use +# +{{- if or .Values.bridges.whatsapp.enabled .Values.bridges.discord.enabled .Values.bridges.irc.enabled }} +app_service_config_files: +{{- end }} +{{- if .Values.bridges.whatsapp.enabled }} + - "/bridges/whatsapp.yaml" +{{- end }} +{{- if .Values.bridges.discord.enabled }} + - "/bridges/discord.yaml" +{{- end }} +{{- if .Values.bridges.irc.enabled }} + - "/bridges/irc.yaml" +{{- end }} + +# Uncomment to enable tracking of application service IP addresses. Implicitly +# enables MAU tracking for application service users. +# +#track_appservice_user_ips: true + + +# a secret which is used to sign access tokens. If none is specified, +# the registration_shared_secret is used, if one is given; otherwise, +# a secret key is derived from the signing key. +# +{{- if .Values.matrix.security.macaroonSecretKey }} +macaroon_secret_key: {{ .Values.matrix.security.macaroonSecretKey }} +{{- end }} + + +# a secret which is used to calculate HMACs for form values, to stop +# falsification of values. Must be specified for the User Consent +# forms to work. +# +# form_secret: + +## Signing Keys ## + +# Path to the signing key to sign messages with +# +signing_key_path: "/data/keys/{{ .Values.matrix.serverName }}.signing.key" + +# The keys that the server used to sign messages with but won't use +# to sign new messages. E.g. it has lost its private key +# +#old_signing_keys: +# "ed25519:auto": +# # Base64 encoded public key +# key: "The public part of your old signing key." +# # Millisecond POSIX timestamp when the key expired. +# expired_ts: 123456789123 + +# How long key response published by this server is valid for. +# Used to set the valid_until_ts in /key/v2 APIs. +# Determines how quickly servers will query to check which keys +# are still valid. +# +#key_refresh_interval: 1d + +# The trusted servers to download signing keys from. +# +# When we need to fetch a signing key, each server is tried in parallel. +# +# Normally, the connection to the key server is validated via TLS certificates. +# Additional security can be provided by configuring a `verify key`, which +# will make synapse check that the response is signed by that key. +# +# This setting supercedes an older setting named `perspectives`. The old format +# is still supported for backwards-compatibility, but it is deprecated. +# +# 'trusted_key_servers' defaults to matrix.org, but using it will generate a +# warning on start-up. To suppress this warning, set +# 'suppress_key_server_warning' to true. +# +# Options for each entry in the list include: +# +# server_name: the name of the server. required. +# +# verify_keys: an optional map from key id to base64-encoded public key. +# If specified, we will check that the response is signed by at least +# one of the given keys. +# +# accept_keys_insecurely: a boolean. Normally, if `verify_keys` is unset, +# and federation_verify_certificates is not `true`, synapse will refuse +# to start, because this would allow anyone who can spoof DNS responses +# to masquerade as the trusted key server. If you know what you are doing +# and are sure that your network environment provides a secure connection +# to the key server, you can set this to `true` to override this +# behaviour. +# +# An example configuration might look like: +# +#trusted_key_servers: +# - server_name: "my_trusted_server.example.com" +# verify_keys: +# "ed25519:auto": "abcdefghijklmnopqrstuvwxyzabcdefghijklmopqr" +# - server_name: "my_other_trusted_server.example.com" +# +{{- if .Values.matrix.security.trustedKeyServers }} +trusted_key_servers: + {{- range .Values.matrix.security.trustedKeyServers }} + - server_name: {{ .serverName }} + {{- if .verifyKeys }} + verify_keys: + {{- range .verifyKeys }} + {{ .id | quote }}: {{ .key | quote }} + {{- end }} + {{- end }} + {{- if .acceptKeysInsecurely }} + accept_keys_insecurely: {{ .acceptKeysInsecurely }} + {{- end }} + {{- end }} +{{- end }} + +# Uncomment the following to disable the warning that is emitted when the +# trusted_key_servers include 'matrix.org'. See above. +# +suppress_key_server_warning: {{ .Values.matrix.security.supressKeyServerWarning }} + + +# The signing keys to use when acting as a trusted key server. If not specified +# defaults to the server signing key. +# +# Can contain multiple keys, one per line. +# +#key_server_signing_keys_path: "key_server_signing_keys.key" + + +# Enable SAML2 for registration and login. Uses pysaml2. +# +# At least one of `sp_config` or `config_path` must be set in this section to +# enable SAML login. +# +# (You will probably also want to set the following options to `false` to +# disable the regular login/registration flows: +# * enable_registration +# * password_config.enabled +# +# Once SAML support is enabled, a metadata file will be exposed at +# https://:/_matrix/saml2/metadata.xml, which you may be able to +# use to configure your SAML IdP with. Alternatively, you can manually configure +# the IdP to use an ACS location of +# https://:/_matrix/saml2/authn_response. +# +saml2_config: + # `sp_config` is the configuration for the pysaml2 Service Provider. + # See pysaml2 docs for format of config. + # + # Default values will be used for the 'entityid' and 'service' settings, + # so it is not normally necessary to specify them unless you need to + # override them. + # + #sp_config: + # # point this to the IdP's metadata. You can use either a local file or + # # (preferably) a URL. + # metadata: + # #local: ["saml2/idp.xml"] + # remote: + # - url: https://our_idp/metadata.xml + # + # # By default, the user has to go to our login page first. If you'd like + # # to allow IdP-initiated login, set 'allow_unsolicited: true' in a + # # 'service.sp' section: + # # + # #service: + # # sp: + # # allow_unsolicited: true + # + # # The examples below are just used to generate our metadata xml, and you + # # may well not need them, depending on your setup. Alternatively you + # # may need a whole lot more detail - see the pysaml2 docs! + # + # description: ["My awesome SP", "en"] + # name: ["Test SP", "en"] + # + # organization: + # name: Example com + # display_name: + # - ["Example co", "en"] + # url: "http://example.com" + # + # contact_person: + # - given_name: Bob + # sur_name: "the Sysadmin" + # email_address": ["admin@example.com"] + # contact_type": technical + + # Instead of putting the config inline as above, you can specify a + # separate pysaml2 configuration file: + # + #config_path: "CONFDIR/sp_conf.py" + + # The lifetime of a SAML session. This defines how long a user has to + # complete the authentication process, if allow_unsolicited is unset. + # The default is 15 minutes. + # + #saml_session_lifetime: 5m + + # An external module can be provided here as a custom solution to + # mapping attributes returned from a saml provider onto a matrix user. + # + user_mapping_provider: + # The custom module's class. Uncomment to use a custom module. + # + #module: mapping_provider.SamlMappingProvider + + # Custom configuration values for the module. Below options are + # intended for the built-in provider, they should be changed if + # using a custom module. This section will be passed as a Python + # dictionary to the module's `parse_config` method. + # + config: + # The SAML attribute (after mapping via the attribute maps) to use + # to derive the Matrix ID from. 'uid' by default. + # + # Note: This used to be configured by the + # saml2_config.mxid_source_attribute option. If that is still + # defined, its value will be used instead. + # + #mxid_source_attribute: displayName + + # The mapping system to use for mapping the saml attribute onto a + # matrix ID. + # + # Options include: + # * 'hexencode' (which maps unpermitted characters to '=xx') + # * 'dotreplace' (which replaces unpermitted characters with + # '.'). + # The default is 'hexencode'. + # + # Note: This used to be configured by the + # saml2_config.mxid_mapping option. If that is still defined, its + # value will be used instead. + # + #mxid_mapping: dotreplace + + # In previous versions of synapse, the mapping from SAML attribute to + # MXID was always calculated dynamically rather than stored in a + # table. For backwards- compatibility, we will look for user_ids + # matching such a pattern before creating a new account. + # + # This setting controls the SAML attribute which will be used for this + # backwards-compatibility lookup. Typically it should be 'uid', but if + # the attribute maps are changed, it may be necessary to change it. + # + # The default is 'uid'. + # + #grandfathered_mxid_source_attribute: upn + + # Directory in which Synapse will try to find the template files below. + # If not set, default templates from within the Synapse package will be used. + # + # DO NOT UNCOMMENT THIS SETTING unless you want to customise the templates. + # If you *do* uncomment it, you will need to make sure that all the templates + # below are in the directory. + # + # Synapse will look for the following templates in this directory: + # + # * HTML page to display to users if something goes wrong during the + # authentication process: 'saml_error.html'. + # + # When rendering, this template is given the following variables: + # * code: an HTML error code corresponding to the error that is being + # returned (typically 400 or 500) + # + # * msg: a textual message describing the error. + # + # The variables will automatically be HTML-escaped. + # + # You can see the default templates at: + # https://github.com/matrix-org/synapse/tree/master/synapse/res/templates + # + #template_dir: "res/templates" + + +# OpenID Connect integration. The following settings can be used to make Synapse +# use an OpenID Connect Provider for authentication, instead of its internal +# password database. +# +# See https://github.com/matrix-org/synapse/blob/master/docs/openid.md. +# +oidc_config: + # Uncomment the following to enable authorization against an OpenID Connect + # server. Defaults to false. + # + #enabled: true + + # Uncomment the following to disable use of the OIDC discovery mechanism to + # discover endpoints. Defaults to true. + # + #discover: false + + # the OIDC issuer. Used to validate tokens and (if discovery is enabled) to + # discover the provider's endpoints. + # + # Required if 'enabled' is true. + # + #issuer: "https://accounts.example.com/" + + # oauth2 client id to use. + # + # Required if 'enabled' is true. + # + #client_id: "provided-by-your-issuer" + + # oauth2 client secret to use. + # + # Required if 'enabled' is true. + # + #client_secret: "provided-by-your-issuer" + + # auth method to use when exchanging the token. + # Valid values are 'client_secret_basic' (default), 'client_secret_post' and + # 'none'. + # + #client_auth_method: client_secret_post + + # list of scopes to request. This should normally include the "openid" scope. + # Defaults to ["openid"]. + # + #scopes: ["openid", "profile"] + + # the oauth2 authorization endpoint. Required if provider discovery is disabled. + # + #authorization_endpoint: "https://accounts.example.com/oauth2/auth" + + # the oauth2 token endpoint. Required if provider discovery is disabled. + # + #token_endpoint: "https://accounts.example.com/oauth2/token" + + # the OIDC userinfo endpoint. Required if discovery is disabled and the + # "openid" scope is not requested. + # + #userinfo_endpoint: "https://accounts.example.com/userinfo" + + # URI where to fetch the JWKS. Required if discovery is disabled and the + # "openid" scope is used. + # + #jwks_uri: "https://accounts.example.com/.well-known/jwks.json" + + # Uncomment to skip metadata verification. Defaults to false. + # + # Use this if you are connecting to a provider that is not OpenID Connect + # compliant. + # Avoid this in production. + # + #skip_verification: true + + # An external module can be provided here as a custom solution to mapping + # attributes returned from a OIDC provider onto a matrix user. + # + user_mapping_provider: + # The custom module's class. Uncomment to use a custom module. + # Default is 'synapse.handlers.oidc_handler.JinjaOidcMappingProvider'. + # + # See https://github.com/matrix-org/synapse/blob/master/docs/sso_mapping_providers.md#openid-mapping-providers + # for information on implementing a custom mapping provider. + # + #module: mapping_provider.OidcMappingProvider + + # Custom configuration values for the module. This section will be passed as + # a Python dictionary to the user mapping provider module's `parse_config` + # method. + # + # The examples below are intended for the default provider: they should be + # changed if using a custom provider. + # + config: + # name of the claim containing a unique identifier for the user. + # Defaults to `sub`, which OpenID Connect compliant providers should provide. + # + #subject_claim: "sub" + + # Jinja2 template for the localpart of the MXID. + # + # When rendering, this template is given the following variables: + # * user: The claims returned by the UserInfo Endpoint and/or in the ID + # Token + # + # This must be configured if using the default mapping provider. + # +{{/* localpart_template: "{{ user.preferred_username }}"*/}} + + # Jinja2 template for the display name to set on first login. + # + # If unset, no displayname will be set. + # +{{/* #display_name_template: "{{ user.given_name }} {{ user.last_name }}"*/}} + + + +# Enable CAS for registration and login. +# +#cas_config: +# enabled: true +# server_url: "https://cas-server.com" +# service_url: "https://homeserver.domain.com:8448" +# #displayname_attribute: name +# #required_attributes: +# # name: value + + +# Additional settings to use with single-sign on systems such as OpenID Connect, +# SAML2 and CAS. +# +sso: + # A list of client URLs which are whitelisted so that the user does not + # have to confirm giving access to their account to the URL. Any client + # whose URL starts with an entry in the following list will not be subject + # to an additional confirmation step after the SSO login is completed. + # + # WARNING: An entry such as "https://my.client" is insecure, because it + # will also match "https://my.client.evil.site", exposing your users to + # phishing attacks from evil.site. To avoid this, include a slash after the + # hostname: "https://my.client/". + # + # If public_baseurl is set, then the login fallback page (used by clients + # that don't natively support the required login flows) is whitelisted in + # addition to any URLs in this list. + # + # By default, this list is empty. + # + #client_whitelist: + # - https://riot.im/develop + # - https://my.custom.client/ + + # Directory in which Synapse will try to find the template files below. + # If not set, default templates from within the Synapse package will be used. + # + # DO NOT UNCOMMENT THIS SETTING unless you want to customise the templates. + # If you *do* uncomment it, you will need to make sure that all the templates + # below are in the directory. + # + # Synapse will look for the following templates in this directory: + # + # * HTML page for a confirmation step before redirecting back to the client + # with the login token: 'sso_redirect_confirm.html'. + # + # When rendering, this template is given three variables: + # * redirect_url: the URL the user is about to be redirected to. Needs + # manual escaping (see + # https://jinja.palletsprojects.com/en/2.11.x/templates/#html-escaping). + # + # * display_url: the same as `redirect_url`, but with the query + # parameters stripped. The intention is to have a + # human-readable URL to show to users, not to use it as + # the final address to redirect to. Needs manual escaping + # (see https://jinja.palletsprojects.com/en/2.11.x/templates/#html-escaping). + # + # * server_name: the homeserver's name. + # + # * HTML page which notifies the user that they are authenticating to confirm + # an operation on their account during the user interactive authentication + # process: 'sso_auth_confirm.html'. + # + # When rendering, this template is given the following variables: + # * redirect_url: the URL the user is about to be redirected to. Needs + # manual escaping (see + # https://jinja.palletsprojects.com/en/2.11.x/templates/#html-escaping). + # + # * description: the operation which the user is being asked to confirm + # + # * HTML page shown after a successful user interactive authentication session: + # 'sso_auth_success.html'. + # + # Note that this page must include the JavaScript which notifies of a successful authentication + # (see https://matrix.org/docs/spec/client_server/r0.6.0#fallback). + # + # This template has no additional variables. + # + # * HTML page shown during single sign-on if a deactivated user (according to Synapse's database) + # attempts to login: 'sso_account_deactivated.html'. + # + # This template has no additional variables. + # + # * HTML page to display to users if something goes wrong during the + # OpenID Connect authentication process: 'sso_error.html'. + # + # When rendering, this template is given two variables: + # * error: the technical name of the error + # * error_description: a human-readable message for the error + # + # You can see the default templates at: + # https://github.com/matrix-org/synapse/tree/master/synapse/res/templates + # + #template_dir: "res/templates" + + +# JSON web token integration. The following settings can be used to make +# Synapse JSON web tokens for authentication, instead of its internal +# password database. +# +# Each JSON Web Token needs to contain a "sub" (subject) claim, which is +# used as the localpart of the mxid. +# +# Additionally, the expiration time ("exp"), not before time ("nbf"), +# and issued at ("iat") claims are validated if present. +# +# Note that this is a non-standard login type and client support is +# expected to be non-existant. +# +# See https://github.com/matrix-org/synapse/blob/master/docs/jwt.md. +# +#jwt_config: + # Uncomment the following to enable authorization using JSON web + # tokens. Defaults to false. + # + #enabled: true + + # This is either the private shared secret or the public key used to + # decode the contents of the JSON web token. + # + # Required if 'enabled' is true. + # + #secret: "provided-by-your-issuer" + + # The algorithm used to sign the JSON web token. + # + # Supported algorithms are listed at + # https://pyjwt.readthedocs.io/en/latest/algorithms.html + # + # Required if 'enabled' is true. + # + #algorithm: "provided-by-your-issuer" + + # The issuer to validate the "iss" claim against. + # + # Optional, if provided the "iss" claim will be required and + # validated for all JSON web tokens. + # + #issuer: "provided-by-your-issuer" + + # A list of audiences to validate the "aud" claim against. + # + # Optional, if provided the "aud" claim will be required and + # validated for all JSON web tokens. + # + # Note that if the "aud" claim is included in a JSON web token then + # validation will fail without configuring audiences. + # + #audiences: + # - "provided-by-your-issuer" + + +password_config: + # Uncomment to disable password login + # + #enabled: false + + # Uncomment to disable authentication against the local password + # database. This is ignored if `enabled` is false, and is only useful + # if you have other password_providers. + # + #localdb_enabled: false + + # Uncomment and change to a secret random string for extra security. + # DO NOT CHANGE THIS AFTER INITIAL SETUP! + # + #pepper: "EVEN_MORE_SECRET" + + # Define and enforce a password policy. Each parameter is optional. + # This is an implementation of MSC2000. + # + policy: + # Whether to enforce the password policy. + # Defaults to 'false'. + # + #enabled: true + + # Minimum accepted length for a password. + # Defaults to 0. + # + #minimum_length: 15 + + # Whether a password must contain at least one digit. + # Defaults to 'false'. + # + #require_digit: true + + # Whether a password must contain at least one symbol. + # A symbol is any character that's not a number or a letter. + # Defaults to 'false'. + # + #require_symbol: true + + # Whether a password must contain at least one lowercase letter. + # Defaults to 'false'. + # + #require_lowercase: true + + # Whether a password must contain at least one lowercase letter. + # Defaults to 'false'. + # + #require_uppercase: true + + +# Configuration for sending emails from Synapse. +# +email: + enable_notifs: {{ .Values.mail.enabled }} + notif_from: {{ .Values.mail.from }} + {{- if .Values.mail.relay.enabled }} + smtp_host: {{ include "matrix.fullname" . }}-exim-relay + smtp_port: {{ .Values.mail.relay.service.port }} + {{- else }} + smtp_host: {{ .Values.mail.external.host }} + smtp_port: {{ .Values.mail.external.port }} + smtp_user: {{ .Values.mail.external.username }} + smtp_pass: {{ .Values.mail.external.password }} + require_transport_security: {{ .Values.mail.external.requireTransportSecurity }} + {{- end }} + + # notif_from defines the "From" address to use when sending emails. + # It must be set if email sending is enabled. + # + # The placeholder '%(app)s' will be replaced by the application name, + # which is normally 'app_name' (below), but may be overridden by the + # Matrix client application. + # + # Note that the placeholder must be written '%(app)s', including the + # trailing 's'. + # + notif_from: {{ .Values.mail.from }} + + # Uncomment the following to enable sending emails for messages that the user + # has missed. Disabled by default. + # + #enable_notifs: true + + # Uncomment the following to disable automatic subscription to email + # notifications for new users. Enabled by default. + # + #notif_for_new_users: false + + # Custom URL for client links within the email notifications. By default + # links will be based on "https://matrix.to". + # + # (This setting used to be called riot_base_url; the old name is still + # supported for backwards-compatibility but is now deprecated.) + {{- if .Values.mail.riotUrl }} + client_base_url: {{ .Values.mail.riotUrl }} + {{- else if .Values.ingress.enabled }} + client_base_url: {{ .Values.ingress.hosts.riot }} + {{- end }} + + # Configure the time that a validation email will expire after sending. + # Defaults to 1h. + # + #validation_token_lifetime: 15m + + # DO NOT UNCOMMENT THIS SETTING unless you want to customise the templates. + # If you *do* uncomment it, you will need to make sure that all the templates + # below are in the directory. + # + # Synapse will look for the following templates in this directory: + # + # * The contents of email notifications of missed events: 'notif_mail.html' and + # 'notif_mail.txt'. + # + # * The contents of account expiry notice emails: 'notice_expiry.html' and + # 'notice_expiry.txt'. + # + # * The contents of password reset emails sent by the homeserver: + # 'password_reset.html' and 'password_reset.txt' + # + # * HTML pages for success and failure that a user will see when they follow + # the link in the password reset email: 'password_reset_success.html' and + # 'password_reset_failure.html' + # + # * The contents of address verification emails sent during registration: + # 'registration.html' and 'registration.txt' + # + # * HTML pages for success and failure that a user will see when they follow + # the link in an address verification email sent during registration: + # 'registration_success.html' and 'registration_failure.html' + # + # * The contents of address verification emails sent when an address is added + # to a Matrix account: 'add_threepid.html' and 'add_threepid.txt' + # + # * HTML pages for success and failure that a user will see when they follow + # the link in an address verification email sent when an address is added + # to a Matrix account: 'add_threepid_success.html' and + # 'add_threepid_failure.html' + # + # You can see the default templates at: + # https://github.com/matrix-org/synapse/tree/master/synapse/res/templates + # + #template_dir: "res/templates" + + # Subjects to use when sending emails from Synapse. + # + # The placeholder '%(app)s' will be replaced with the value of the 'app_name' + # setting above, or by a value dictated by the Matrix client application. + # + # If a subject isn't overridden in this configuration file, the value used as + # its example will be used. + # + #subjects: + + # Subjects for notification emails. + # + # On top of the '%(app)s' placeholder, these can use the following + # placeholders: + # + # * '%(person)s', which will be replaced by the display name of the user(s) + # that sent the message(s), e.g. "Alice and Bob". + # * '%(room)s', which will be replaced by the name of the room the + # message(s) have been sent to, e.g. "My super room". + # + # See the example provided for each setting to see which placeholder can be + # used and how to use them. + # + # Subject to use to notify about one message from one or more user(s) in a + # room which has a name. + #message_from_person_in_room: "[%(app)s] You have a message on %(app)s from %(person)s in the %(room)s room..." + # + # Subject to use to notify about one message from one or more user(s) in a + # room which doesn't have a name. + #message_from_person: "[%(app)s] You have a message on %(app)s from %(person)s..." + # + # Subject to use to notify about multiple messages from one or more users in + # a room which doesn't have a name. + #messages_from_person: "[%(app)s] You have messages on %(app)s from %(person)s..." + # + # Subject to use to notify about multiple messages in a room which has a + # name. + #messages_in_room: "[%(app)s] You have messages on %(app)s in the %(room)s room..." + # + # Subject to use to notify about multiple messages in multiple rooms. + #messages_in_room_and_others: "[%(app)s] You have messages on %(app)s in the %(room)s room and others..." + # + # Subject to use to notify about multiple messages from multiple persons in + # multiple rooms. This is similar to the setting above except it's used when + # the room in which the notification was triggered has no name. + #messages_from_person_and_others: "[%(app)s] You have messages on %(app)s from %(person)s and others..." + # + # Subject to use to notify about an invite to a room which has a name. + #invite_from_person_to_room: "[%(app)s] %(person)s has invited you to join the %(room)s room on %(app)s..." + # + # Subject to use to notify about an invite to a room which doesn't have a + # name. + #invite_from_person: "[%(app)s] %(person)s has invited you to chat on %(app)s..." + + # Subject for emails related to account administration. + # + # On top of the '%(app)s' placeholder, these one can use the + # '%(server_name)s' placeholder, which will be replaced by the value of the + # 'server_name' setting in your Synapse configuration. + # + # Subject to use when sending a password reset email. + #password_reset: "[%(server_name)s] Password reset" + # + # Subject to use when sending a verification email to assert an address's + # ownership. + #email_validation: "[%(server_name)s] Validate your email" + + +# Password providers allow homeserver administrators to integrate +# their Synapse installation with existing authentication methods +# ex. LDAP, external tokens, etc. +# +# For more information and known implementations, please see +# https://github.com/matrix-org/synapse/blob/master/docs/password_auth_providers.md +# +# Note: instances wishing to use SAML or CAS authentication should +# instead use the `saml2_config` or `cas_config` options, +# respectively. +# +password_providers: +# # Example config for an LDAP auth provider +# - module: "ldap_auth_provider.LdapAuthProvider" +# config: +# enabled: true +# uri: "ldap://ldap.example.com:389" +# start_tls: true +# base: "ou=users,dc=example,dc=com" +# attributes: +# uid: "cn" +# mail: "email" +# name: "givenName" +# #bind_dn: +# #bind_password: +# #filter: "(objectClass=posixAccount)" + + + +# Clients requesting push notifications can either have the body of +# the message sent in the notification poke along with other details +# like the sender, or just the event ID and room ID (`event_id_only`). +# If clients choose the former, this option controls whether the +# notification request includes the content of the event (other details +# like the sender are still included). For `event_id_only` push, it +# has no effect. +# +# For modern android devices the notification content will still appear +# because it is loaded by the app. iPhone, however will send a +# notification saying only that a message arrived and who it came from. +# +#push: +# include_content: true + + +# Spam checkers are third-party modules that can block specific actions +# of local users, such as creating rooms and registering undesirable +# usernames, as well as remote users by redacting incoming events. +# +spam_checker: + #- module: "my_custom_project.SuperSpamChecker" + # config: + # example_option: 'things' + #- module: "some_other_project.BadEventStopper" + # config: + # example_stop_events_from: ['@bad:example.com'] + + +## Rooms ## + +# Controls whether locally-created rooms should be end-to-end encrypted by +# default. +# +# Possible options are "all", "invite", and "off". They are defined as: +# +# * "all": any locally-created room +# * "invite": any room created with the "private_chat" or "trusted_private_chat" +# room creation presets +# * "off": this option will take no effect +# +# The default value is "off". +# +# Note that this option will only affect rooms created after it is set. It +# will also not affect rooms created by other servers. +# +encryption_enabled_by_default_for_room_type: {{ .Values.matrix.encryptByDefault }} + + +# Uncomment to allow non-server-admin users to create groups on this server +# +#enable_group_creation: true + +# If enabled, non server admins can only create groups with local parts +# starting with this prefix +# +#group_creation_prefix: "unofficial/" + + + +# User Directory configuration +# +# 'enabled' defines whether users can search the user directory. If +# false then empty responses are returned to all queries. Defaults to +# true. +# +# 'search_all_users' defines whether to search all users visible to your HS +# when searching the user directory, rather than limiting to users visible +# in public rooms. Defaults to false. If you set it True, you'll have to +# rebuild the user_directory search indexes, see +# https://github.com/matrix-org/synapse/blob/master/docs/user_directory.md +# +#user_directory: +# enabled: true +# search_all_users: false + + +# User Consent configuration +# +# for detailed instructions, see +# https://github.com/matrix-org/synapse/blob/master/docs/consent_tracking.md +# +# Parts of this section are required if enabling the 'consent' resource under +# 'listeners', in particular 'template_dir' and 'version'. +# +# 'template_dir' gives the location of the templates for the HTML forms. +# This directory should contain one subdirectory per language (eg, 'en', 'fr'), +# and each language directory should contain the policy document (named as +# '.html') and a success page (success.html). +# +# 'version' specifies the 'current' version of the policy document. It defines +# the version to be served by the consent resource if there is no 'v' +# parameter. +# +# 'server_notice_content', if enabled, will send a user a "Server Notice" +# asking them to consent to the privacy policy. The 'server_notices' section +# must also be configured for this to work. Notices will *not* be sent to +# guest users unless 'send_server_notice_to_guests' is set to true. +# +# 'block_events_error', if set, will block any attempts to send events +# until the user consents to the privacy policy. The value of the setting is +# used as the text of the error. +# +# 'require_at_registration', if enabled, will add a step to the registration +# process, similar to how captcha works. Users will be required to accept the +# policy before their account is created. +# +# 'policy_name' is the display name of the policy users will see when registering +# for an account. Has no effect unless `require_at_registration` is enabled. +# Defaults to "Privacy Policy". +# +#user_consent: +# template_dir: res/templates/privacy +# version: 1.0 +# server_notice_content: +# msgtype: m.text +# body: >- +# To continue using this homeserver you must review and agree to the +# terms and conditions at %(consent_uri)s +# send_server_notice_to_guests: true +# block_events_error: >- +# To continue using this homeserver you must review and agree to the +# terms and conditions at %(consent_uri)s +# require_at_registration: false +# policy_name: Privacy Policy +# + + + +# Local statistics collection. Used in populating the room directory. +# +# 'bucket_size' controls how large each statistics timeslice is. It can +# be defined in a human readable short form -- e.g. "1d", "1y". +# +# 'retention' controls how long historical statistics will be kept for. +# It can be defined in a human readable short form -- e.g. "1d", "1y". +# +# +#stats: +# enabled: true +# bucket_size: 1d +# retention: 1y + + +# Server Notices room configuration +# +# Uncomment this section to enable a room which can be used to send notices +# from the server to users. It is a special room which cannot be left; notices +# come from a special "notices" user id. +# +# If you uncomment this section, you *must* define the system_mxid_localpart +# setting, which defines the id of the user which will be used to send the +# notices. +# +# It's also possible to override the room name, the display name of the +# "notices" user, and the avatar for the user. +# +#server_notices: +# system_mxid_localpart: notices +# system_mxid_display_name: "Server Notices" +# system_mxid_avatar_url: "mxc://server.com/oumMVlgDnLYFaPVkExemNVVZ" +# room_name: "Server Notices" + + + +# Uncomment to disable searching the public room list. When disabled +# blocks searching local and remote room lists for local and remote +# users by always returning an empty list for all queries. +# +#enable_room_list_search: false + +# The `alias_creation` option controls who's allowed to create aliases +# on this server. +# +# The format of this option is a list of rules that contain globs that +# match against user_id, room_id and the new alias (fully qualified with +# server name). The action in the first rule that matches is taken, +# which can currently either be "allow" or "deny". +# +# Missing user_id/room_id/alias fields default to "*". +# +# If no rules match the request is denied. An empty list means no one +# can create aliases. +# +# Options for the rules include: +# +# user_id: Matches against the creator of the alias +# alias: Matches against the alias being created +# room_id: Matches against the room ID the alias is being pointed at +# action: Whether to "allow" or "deny" the request if the rule matches +# +# The default is: +# +#alias_creation_rules: +# - user_id: "*" +# alias: "*" +# room_id: "*" +# action: allow + +# The `room_list_publication_rules` option controls who can publish and +# which rooms can be published in the public room list. +# +# The format of this option is the same as that for +# `alias_creation_rules`. +# +# If the room has one or more aliases associated with it, only one of +# the aliases needs to match the alias rule. If there are no aliases +# then only rules with `alias: *` match. +# +# If no rules match the request is denied. An empty list means no one +# can publish rooms. +# +# Options for the rules include: +# +# user_id: Matches agaisnt the creator of the alias +# room_id: Matches against the room ID being published +# alias: Matches against any current local or canonical aliases +# associated with the room +# action: Whether to "allow" or "deny" the request if the rule matches +# +# The default is: +# +#room_list_publication_rules: +# - user_id: "*" +# alias: "*" +# room_id: "*" +# action: allow + + +# Server admins can define a Python module that implements extra rules for +# allowing or denying incoming events. In order to work, this module needs to +# override the methods defined in synapse/events/third_party_rules.py. +# +# This feature is designed to be used in closed federations only, where each +# participating server enforces the same rules. +# +#third_party_event_rules: +# module: "my_custom_project.SuperRulesSet" +# config: +# example_option: 'things' + + +## Opentracing ## + +# These settings enable opentracing, which implements distributed tracing. +# This allows you to observe the causal chains of events across servers +# including requests, key lookups etc., across any server running +# synapse or any other other services which supports opentracing +# (specifically those implemented with Jaeger). +# +opentracing: + # tracing is disabled by default. Uncomment the following line to enable it. + # + #enabled: true + + # The list of homeservers we wish to send and receive span contexts and span baggage. + # See docs/opentracing.rst + # This is a list of regexes which are matched against the server_name of the + # homeserver. + # + # By defult, it is empty, so no servers are matched. + # + #homeserver_whitelist: + # - ".*" + + # Jaeger can be configured to sample traces at different rates. + # All configuration options provided by Jaeger can be set here. + # Jaeger's configuration mostly related to trace sampling which + # is documented here: + # https://www.jaegertracing.io/docs/1.13/sampling/. + # + #jaeger_config: + # sampler: + # type: const + # param: 1 + + # Logging whether spans were started and reported + # + # logging: + # false + +{{ if .Values.matrix.homeserverExtra }} +{{- toYaml .Values.matrix.homeserverExtra }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/matrix/templates/synapse/configmap.yaml b/charts/matrix/templates/synapse/configmap.yaml new file mode 100644 index 0000000..5a64f23 --- /dev/null +++ b/charts/matrix/templates/synapse/configmap.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "matrix.fullname" . }}-synapse-config + labels: +{{ include "matrix.labels" . | nindent 4}} +{{ include "matrix.synapse.labels" . | nindent 4}} +data: + homeserver.yaml: | + {{ include "homeserver.yaml" . | nindent 4 }} + {{ .Values.matrix.serverName }}.log.config: | + version: 1 + + formatters: + precise: + format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s' + + filters: + context: + (): synapse.util.logcontext.LoggingContextFilter + request: "" + + handlers: + console: + class: logging.StreamHandler + formatter: precise + filters: [context] + + loggers: + synapse: + level: {{ .Values.matrix.logging.synapseLogLevel }} + + synapse.storage.SQL: + # beware: increasing this to DEBUG will make synapse log sensitive + # information such as access tokens. + level: {{ .Values.matrix.logging.sqlLogLevel }} + + + root: + level: {{ .Values.matrix.logging.rootLogLevel }} + handlers: [console] diff --git a/charts/matrix/templates/synapse/deployment.yaml b/charts/matrix/templates/synapse/deployment.yaml new file mode 100644 index 0000000..5d57125 --- /dev/null +++ b/charts/matrix/templates/synapse/deployment.yaml @@ -0,0 +1,143 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "matrix.fullname" . }}-synapse + labels: +{{ include "matrix.labels" . | indent 4 }} +{{ include "matrix.synapse.labels" . | indent 4}} +spec: + replicas: {{ .Values.synapse.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-synapse + app.kubernetes.io/instance: {{ .Release.Name }} + strategy: + type: Recreate + template: + metadata: + annotations: + # re-roll deployment on homeserver.yaml change + checksum/synapse-config: {{ include (print $.Template.BasePath "/synapse/configmap.yaml") . | sha256sum }} + labels: + app.kubernetes.io/name: {{ include "matrix.name" . }}-synapse + app.kubernetes.io/instance: {{ .Release.Name }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + # generate signing key only on fresh install + {{- if .Release.IsInstall }} + initContainers: + - name: generate-signing-key + image: "{{ .Values.synapse.image.repository }}:{{ .Values.synapse.image.tag }}" + imagePullPolicy: {{ .Values.synapse.image.pullPolicy }} + env: + - name: SYNAPSE_SERVER_NAME + value: {{ .Values.matrix.serverName }} + - name: SYNAPSE_REPORT_STATS + value: {{ .Values.matrix.telemetry | ternary "yes" "no" | quote }} + command: ["python"] + args: + - "-m" + - "synapse.app.homeserver" + - "--config-path" + - "/data/homeserver.yaml" + - "--keys-directory" + - "/data/keys" + - "--generate-keys" + volumeMounts: + - name: synapse-config + mountPath: /data + - name: signing-key + mountPath: /data/keys + {{- end }} {{/* end if .Release.IsInstall */}} + containers: + - name: "synapse" + image: "{{ .Values.synapse.image.repository }}:{{ .Values.synapse.image.tag }}" + imagePullPolicy: {{ .Values.synapse.image.pullPolicy }} + env: + - name: UID + value: "1000" + - name: GID + value: "1000" + ports: + - name: http + containerPort: 8008 + protocol: TCP + {{- if .Values.synapse.metrics.enabled }} + - name: metrics + containerPort: {{ .Values.synapse.metrics.port }} + protocol: TCP + {{- end }} + volumeMounts: + - name: synapse-config + mountPath: /data + - name: signing-key + mountPath: /data/keys + - name: media-store + mountPath: /data/media_store + {{- if or .Values.bridges.whatsapp.enabled .Values.bridges.discord.enabled .Values.bridges.irc.enabled }} + - name: bridges + mountPath: /bridges + readOnly: true + {{- end }} + - name: uploads + mountPath: /data/uploads + - name: tmp + mountPath: /tmp + readinessProbe: + httpGet: + path: /_matrix/static/ + port: http + {{- if .Values.synapse.probes.readiness }} + {{- toYaml .Values.synapse.probes.readiness | nindent 12 }} + {{- end }} + startupProbe: + httpGet: + path: /_matrix/static/ + port: http + {{- if .Values.synapse.probes.startup }} + {{- toYaml .Values.synapse.probes.startup | nindent 12 }} + {{- end }} + livenessProbe: + httpGet: + path: /_matrix/static/ + port: http + {{- if .Values.synapse.probes.liveness }} + {{- toYaml .Values.synapse.probes.liveness | nindent 12 }} + {{- end }} + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + {{- with .Values.synapse.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumes: + - name: synapse-config + configMap: + name: {{ include "matrix.fullname" . }}-synapse-config + - name: signing-key + persistentVolumeClaim: + claimName: {{ include "matrix.fullname" . }}-signing-key + - name: media-store + persistentVolumeClaim: + claimName: {{ include "matrix.fullname" . }}-media-store + {{- if or .Values.bridges.whatsapp.enabled .Values.bridges.discord.enabled .Values.bridges.irc.enabled }} + - name: bridges + persistentVolumeClaim: + claimName: {{ include "matrix.fullname" . }}-bridges + {{- end }} + # Ephemeral in-progress uploads + - name: uploads + emptyDir: {} + - name: tmp + emptyDir: {} diff --git a/charts/matrix/templates/synapse/federation-svc.yaml b/charts/matrix/templates/synapse/federation-svc.yaml new file mode 100644 index 0000000..2f2fcb6 --- /dev/null +++ b/charts/matrix/templates/synapse/federation-svc.yaml @@ -0,0 +1,18 @@ +{{- if .Values.matrix.federation.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "matrix.fullname" . }}-synapse-federation + labels: +{{ include "matrix.labels" . | indent 4 }} +{{ include "matrix.synapse.labels" . | indent 4}} +spec: + type: {{ .Values.synapse.service.federation.type }} + ports: + - port: {{ .Values.synapse.service.federation.port }} + targetPort: http + protocol: TCP + selector: + app.kubernetes.io/name: {{ include "matrix.name" . }}-synapse + app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/matrix/templates/synapse/media-pvc.yaml b/charts/matrix/templates/synapse/media-pvc.yaml new file mode 100644 index 0000000..cee149d --- /dev/null +++ b/charts/matrix/templates/synapse/media-pvc.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "matrix.fullname" . }}-media-store + labels: +{{ include "matrix.labels" . | indent 4}} +{{ include "matrix.synapse.labels" . | indent 4}} +spec: + {{- if .Values.volumes.media.storageClass }} + storageClassName: {{ .Values.volumes.media.storageClass }} + {{- end }} + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.volumes.media.capacity }} diff --git a/charts/matrix/templates/synapse/network-policy.yaml b/charts/matrix/templates/synapse/network-policy.yaml new file mode 100644 index 0000000..081c178 --- /dev/null +++ b/charts/matrix/templates/synapse/network-policy.yaml @@ -0,0 +1,23 @@ +{{- if .Values.networkPolicies.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "matrix.fullname" . }}-synapse + labels: +{{ include "matrix.labels" . | indent 4 }} +{{ include "matrix.synapse.labels" . | indent 4}} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: {{ include "matrix.fullname" . }}-synapse + app.kubernetes.io/instance: {{ .Release.Name }} + ingress: + - from: + - podSelector: + matchLabels: + matrix-chart/allow-synapse-access: allow + app.kubernetes.io/instance: {{ .Release.Name }} + ports: + - port: http + protocol: TCP +{{- end }} diff --git a/charts/matrix/templates/synapse/service.yaml b/charts/matrix/templates/synapse/service.yaml new file mode 100644 index 0000000..0d194f1 --- /dev/null +++ b/charts/matrix/templates/synapse/service.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "matrix.fullname" . }}-synapse + labels: +{{ include "matrix.labels" . | indent 4 }} +{{ include "matrix.synapse.labels" . | indent 4}} + annotations: +{{- if and (eq .Values.synapse.metrics.enabled true) (eq .Values.synapse.metrics.annotations true) }} + prometheus.io/scrape: "true" + prometheus.io/path: "/_synapse/metrics" + prometheus.io/port: {{ .Values.synapse.metrics.port | quote }} +{{- end }} +spec: + type: {{ .Values.synapse.service.type }} + ports: + - port: {{ .Values.synapse.service.port }} + targetPort: http + protocol: TCP + name: http + {{- if .Values.synapse.metrics.enabled }} + - port: {{ .Values.synapse.metrics.port }} + targetPort: metrics + protocol: TCP + name: metrics + {{- end }} + selector: + app.kubernetes.io/name: {{ include "matrix.name" . }}-synapse + app.kubernetes.io/instance: {{ .Release.Name }} diff --git a/charts/matrix/templates/synapse/signing-key-pvc.yaml b/charts/matrix/templates/synapse/signing-key-pvc.yaml new file mode 100644 index 0000000..84d9d19 --- /dev/null +++ b/charts/matrix/templates/synapse/signing-key-pvc.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "matrix.fullname" . }}-signing-key + labels: +{{ include "matrix.labels" . | indent 4}} +{{ include "matrix.synapse.labels" . | indent 4}} +spec: + {{- if .Values.volumes.signingKey.storageClass }} + storageClassName: {{ .Values.volumes.signingKey.storageClass }} + {{- end }} + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.volumes.signingKey.capacity }} diff --git a/charts/matrix/values.yaml b/charts/matrix/values.yaml new file mode 100644 index 0000000..db2f79c --- /dev/null +++ b/charts/matrix/values.yaml @@ -0,0 +1,693 @@ +# Runtime configuration for Synapse and settings related to the Matrix protocol +matrix: + # Manual overrides for homeserver.yaml, the main configuration file for Synapse + # If homeserverOverride is set, the entirety of homeserver.yaml will be replaced with the contents. + # If homeserverExtra is set, the contents will be appended to the end of the default configuration. + # It is highly recommended that you take a look at the defaults in templates/synapse/_homeserver.yaml, to get a sense + # of the requirements and default configuration options to use other services in this chart. + # homeserverOverride: {} + # homeserverExtra: {} + + # Domain name of the server + # This is not necessarily the host name where the service is reachable. In fact, you may want to omit any subdomains + # from this value as the server name set here will be the name of your homeserver in the fediverse, and will be the + # domain name at the end of every user's username + serverName: "example.com" + + # Enable anonymous telemetry to matrix.org + telemetry: false + + # Hostname where Synapse can be reached. + # This is *optional* if an Ingress is configured below. If hostname is unspecified, the Synapse hostname of the + # Ingress will be used + # hostname: "matrix.example.com" + + # Set to false to disable presence (online/offline indicators) + presence: true + + # Set to true to block non-admins from inviting users to any rooms + blockNonAdminInvites: false + + # Set to false to disable message searching + search: true + + # Which types of rooms to enable end-to-end encryption on by default + # off: none + # invite: private messages, or rooms created with the private_chat or trusted_private_chat room preset + # all: all rooms + encryptByDefault: invite + + # Email address of the administrator + adminEmail: "admin@example.com" + + # Settings related to image and multimedia uploads + uploads: + # Max upload size in bytes + maxSize: 10M + + # Max image size in pixels + maxPixels: 32M + + # Settings related to federation + federation: + # Set to false to disable federation and run an isolated homeserver + enabled: true + + # Set to false to disallow members of other homeservers from fetching *public* rooms + allowPublicRooms: true + + # Whitelist of domains to federate with (comment for all domains except blacklisted) + # whitelist: [] + + # IP addresses to blacklist federation requests to + blacklist: + - '127.0.0.0/8' + - '10.0.0.0/8' + - '172.16.0.0/12' + - '192.168.0.0/16' + - '100.64.0.0/10' + - '169.254.0.0/16' + - '::1/128' + - 'fe80::/64' + - 'fc00::/7' + + # User registration settings + registration: + # Allow new users to register an account + enabled: false + + # If set, allows registration of standard or admin accounts by anyone who + # has the shared secret, even if registration is otherwise disabled. + # + # sharedSecret: + + # Allow users to join rooms as a guest + allowGuests: false + + # Required "3PIDs" - third-party identifiers such as email or msisdn (SMS) + # required3Pids: + # - email + # - msisdn + + # Rooms to automatically join all new users to + autoJoinRooms: [] + # - "#welcome:example.com" + + # Settings for the URL preview crawler + urlPreviews: + # Enable URL previews. + # WARNING: Make sure to review the default rules below to ensure that users cannot crawl + # sensitive internal endpoints in your cluster. + enabled: false + + # Blacklists and whitelists for the URL preview crawler + rules: + # Maximum size of a crawlable page. Keep this low to prevent a DOS vector + maxSize: 10M + + # Whitelist and blacklist for crawlable IP addresses + ip: + # whitelist: + blacklist: + - '127.0.0.0/8' + - '10.0.0.0/8' + - '172.16.0.0/12' + - '192.168.0.0/16' + - '100.64.0.0/10' + - '169.254.0.0/16' + - '::1/128' + - 'fe80::/64' + - 'fc00::/7' + + # Whitelist and blacklist based on URL pattern matching + url: {} + # whitelist: + # blacklist: + # # blacklist any URL with a username in its URI + # - username: '*' + # + # # blacklist all *.google.com URLs + # - netloc: 'google.com' + # - netloc: '*.google.com' + # + # # blacklist all plain HTTP URLs + # - scheme: 'http' + # + # # blacklist http(s)://www.acme.com/foo + # - netloc: 'www.acme.com' + # path: '/foo' + # + # # blacklist any URL with a literal IPv4 address + # - netloc: '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' + + # How long to keep redacted events in unredacted form in the database + retentionPeriod: 7d + + security: + # a secret which is used to sign access tokens. If none is specified, + # the registration_shared_secret is used, if one is given; otherwise, + # a secret key is derived from the signing key. + # + # macaroonSecretKey: + + # This disables the warning that is emitted when the + # trustedKeyServers include 'matrix.org'. See below. + # Set to false to re-enable the warning. + # + surpressKeyServerWarning: true + + # The trusted servers to download signing keys from. + # + # When we need to fetch a signing key, each server is tried in parallel. + # + # Normally, the connection to the key server is validated via TLS certificates. + # Additional security can be provided by configuring a `verify key`, which + # will make synapse check that the response is signed by that key. + # + # This setting supercedes an older setting named `perspectives`. The old format + # is still supported for backwards-compatibility, but it is deprecated. + # + # 'trustedKeyServers' defaults to matrix.org, but using it will generate a + # warning on start-up. To suppress this warning, set + # 'surpressKeyServerWarning' to true. + # + # Options for each entry in the list include: + # + # serverName: the name of the server. required. + # + # verifyKeys: an optional map from key id to base64-encoded public key. + # If specified, we will check that the response is signed by at least + # one of the given keys. + # + # acceptKeysInsecurely: a boolean. Normally, if `verify_keys` is unset, + # and federation_verify_certificates is not `true`, synapse will refuse + # to start, because this would allow anyone who can spoof DNS responses + # to masquerade as the trusted key server. If you know what you are doing + # and are sure that your network environment provides a secure connection + # to the key server, you can set this to `true` to override this + # behaviour. + # + # An example configuration might look like: + # + # trustedKeyServers: + # - serverName: my_trusted_server.example.com + # verifyKeys: + # - id: "ed25519:auto" + # key: "abcdefghijklmnopqrstuvwxyzabcdefghijklmopqr" + # acceptKeysInsecurely: false + # - serverName: my_other_trusted_server.example.com + + # Set to true to globally block access to the homeserver + disabled: false + # Human readable reason for why the homeserver is blocked + disabledMessage: "" + + logging: + # Root log level is the default log level for log outputs that do not have more + # specific settings. + rootLogLevel: WARNING + # beware: increasing this to DEBUG will make synapse log sensitive + # information such as access tokens. + sqlLogLevel: WARNING + # The log level for the synapse server + synapseLogLevel: WARNING + +# Persistent volumes configuration +volumes: + # Uploaded attachments/multimedia + media: + # Capacity of the media persistent volume claim + capacity: 10Gi + # Storage class (optional) + storageClass: "" + signingKey: + # Capacity of the signing key PVC + # Note: 1Mi is more than enough, but some cloud providers set a minimum PVC size of 1Mi or 1Gi, adjust as necessary + capacity: 1Mi + # Storage class (optional) + storageClass: "" + +ingress: + enabled: true + # Whether to expose the federation API behind the Ingress + # If you would rather use an external proxy to run federation on a port other than 443, set this to false and set the synapse.service.federation.type value to either LoadBalancer or NodePort + federation: true + tls: [] + hosts: + synapse: matrix.chart-example.local + riot: element.chart-example.local + federation: matrix-fed.chart-example.local + annotations: + # This annotation is required for the Nginx ingress provider. You can remove it if you use a different ingress provider + nginx.ingress.kubernetes.io/configuration-snippet: | + proxy_intercept_errors off; + +# PostgreSQL Database Configuration +postgresql: + # Whether to deploy the stable/postgresql chart with this chart. If disabled, make sure PostgreSQL is available at the hostname below and credentials are configured below + enabled: true + + username: matrix + password: matrix + database: matrix + + # Set this if postgresql.enabled = false + hostname: "" + port: 5432 + + # Whether to connect to the database over SSL + ssl: false + # See https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS for documentation of these modes + sslMode: prefer + + # Storage to allocate for stable/postgresql + persistence: + size: 8Gi + + # If postgresql.enabled, stable/postgresql will run the scripts in templates/postgresql/initdb-configmap.yaml + # If using an external Postgres server, make sure to configure the database as specified at https://github.com/matrix-org/synapse/blob/master/docs/postgres.md + initdbScriptsConfigMap: "{{ .Release.Name }}-postgresql-initdb" + + securityContext: + enabled: true + runAsUser: 1000 + fsGroup: 1000 + +# Synapse Kubernetes resource settings +synapse: + image: + repository: "matrixdotorg/synapse" + tag: v1.22.1 + pullPolicy: IfNotPresent + service: + type: ClusterIP + port: 80 + federation: + type: ClusterIP + port: 80 + replicaCount: 1 + resources: {} + # Configure timings for readiness, startup, and liveness probes here + probes: + readiness: + timeoutSeconds: 5 + periodSeconds: 10 + startup: + timeoutSeconds: 5 + periodSeconds: 5 + failureThreshold: 6 + liveness: + timeoutSeconds: 5 + periodSeconds: 10 + + # Labels to be appended to all Synapse resources + labels: + component: synapse + + # Prometheus metrics for Synapse + # https://github.com/matrix-org/synapse/blob/master/docs/metrics-howto.md + metrics: + # Whether Synapse should capture metrics on an additional endpoint + enabled: true + # Port to listen on for metrics scraping + port: 9092 + annotations: true + + +# Element (formerly Riot Web) client configuration +riot: + # Set to false to disable a deployment of Element. Users will still be able to connect via any other instances of Element (such as https://app.element.io), Element Desktop, or any other Matrix clients + enabled: true + + # Organization/enterprise branding + branding: + # Shown in email notifications + brand: "Element" + # Background of login splash screen + welcomeBackgroundUrl: "" + # Logo shown at top of login screen + authHeaderLogoUrl: "" + # Array of links to show at the bottom of the login screen + authFooterLinks: [] +# - text: +# url: + + # Element integrations configuration + integrations: + # Set to false to disable the Integrations menu (including widgets, bots, and other plugins to Element) + enabled: true + # UI to load when a user selects the Integrations button at the top-right of a room + ui: "https://scalar.vector.im/" + # API for the integration server + api: "https://scalar.vector.im/api" + # Array of API paths providing widgets + widgets: + - "https://scalar.vector.im/_matrix/integrations/v1" + - "https://scalar.vector.im/api" + - "https://scalar-staging.vector.im/_matrix/integrations/v1" + - "https://scalar-staging.vector.im/api" + - "https://scalar-staging.riot.im/scalar/api" + + # Experimental features in Element, see https://github.com/vector-im/riot-web/blob/develop/docs/labs.md + labs: + - feature_new_spinner + - feature_pinning + - feature_custom_status + - feature_custom_tags + - feature_state_counters + - feature_many_integration_managers + - feature_mjolnir + - feature_dm_verification + - feature_bridge_state + - feature_presence_in_room_list + - feature_custom_themes + + # Servers to show in the Explore menu (the current server is always shown) + roomDirectoryServers: + - matrix.org + + # Set to the user ID (@username:domain.tld) of a bot to invite all new users to a DM with the bot upon registration + welcomeUserId: "" + + # Prefix before permalinks generated when users share links to rooms, users, or messages. If running an unfederated Synapse, set the below to the URL of your Element instance. + permalinkPrefix: "https://matrix.to" + + # Element Kubernetes resource settings + image: + repository: "vectorim/riot-web" + tag: v1.7.12 + pullPolicy: IfNotPresent + service: + type: ClusterIP + port: 80 + replicaCount: 1 + resources: {} + probes: + readiness: {} + startup: {} + liveness: {} + + # Element specific labels + labels: + component: element + +# Settings for Coturn TURN relay, used for routing voice calls +coturn: + # Set to false to disable the included deployment of Coturn + enabled: true + + # URIs of the Coturn servers + # If deploying Coturn with this chart, include the public IPs of each node in your cluster (or a DNS round-robin hostname) + # You can also include an external Coturn instance if you'd prefer + uris: [] +# - "turn:turn.example.com?transport=udp" + + # How to deploy Coturn + # Options: + # DaemonSet: A DaemonSet will be used to schedule one Coturn pod per node. Each Coturn pod will open the ports it needs directly on the host it is scheduled on. + # This maximizes compatibility and will allow you to set up Coturn without any additional cluster configuration. + # Deployment: A Deployment will be used to schedule Coturn pods. The number of Coturn pods will be configurable (via the replicaCount setting below). + # You will need to use a NodePort service or an external load balancer to route traffic to the Coturn pods. + # This is more flexible and can use fewer pods in a multi-node setup, but will require additional networking configuration. + kind: DaemonSet + + # Whether to allow guests to use the TURN server + allowGuests: true + + # Shared secret for communication between Synapse and Coturn. + # Optional, will be auto-generated if not overridden here. + sharedSecret: "" + + # UDP port range for TURN connections + ports: + from: 49152 + to: 49172 + + service: + # The type of service to deploy for routing Coturn traffic + # Options: + # ClusterIP: Recommended for DaemonSet configurations. This will create a standard Kubernetes service for Coturn within the cluster. No external networking + # will be configured as the DaemonSet will handle binding to each Node's host networking + # NodePort: Recommended for Deployment configurations. This will open TURN ports on every node and route traffic on these ports to the Coturn pods. + # You will need to make sure your cloud provider supports the cluster config setting "apiserver.service-node-port-range", as this range must contain + # the ports defined above for the service to be created. + type: ClusterIP + + image: + repository: "instrumentisto/coturn" + tag: "4.5.1.3" + pullPolicy: IfNotPresent + replicaCount: 1 + resources: {} + + # Coturn specific labels + labels: + component: coturn + +# Settings for email notifications +mail: + # Set to false to disable all email notifications + # NOTE: If enabled, either enable the Exim relay or configure an external mail server below + enabled: true + # Name and email address for outgoing mail + from: "Matrix " + # Optional: Element instance URL. + # If the ingress is enabled, this is unnecessary. + # If the ingress is disabled and this is left unspecified, emails will contain a link to https://app.element.io + riotUrl: "" + + # Exim relay + relay: + enabled: true + image: + repository: "devture/exim-relay" + tag: "4.93.1-r0" + pullPolicy: IfNotPresent + service: + type: ClusterIP + port: 25 + replicaCount: 1 + resources: {} + probes: + readiness: {} + startup: {} + liveness: {} + # Mail relay specific labels + labels: + component: mail + + + # External mail server + external: + host: "" + port: 25 # SSL: 465, STARTTLS: 587 + username: "" + password: "" + requireTransportSecurity: true + +bridges: + irc: + # Set to true to enable the IRC bridge + enabled: false + # Whether to enable presence (online/offline indicators). If presence is disabled for the homeserver (above), it should be disabled here too + presence: false + # Name of Postgres database to store IRC bridge data in, this database will be created if the included Postgres chart is enabled, otherwise you must create it manually + database: "matrix_irc" + databaseSslVerify: true + + # Object of IRC servers to connect to, see https://github.com/matrix-org/matrix-appservice-irc/blob/master/config.sample.yaml for config options + servers: + chat.freenode.net: + # A human-readable short name. + name: "Freenode" + # The port to connect to. Optional. + port: 6697 + # Whether to use SSL or not. Default: false. + ssl: true + + data: + # Size of the data PVC to allocate + capacity: 1Mi + + image: + repository: "matrixdotorg/matrix-appservice-irc" + tag: "release-0.22.0-rc1" + pullPolicy: IfNotPresent + replicaCount: 1 + resources: {} + service: + type: ClusterIP + port: 9006 + + whatsapp: + # Set to true to enable the WhatsApp bridge + enabled: false + + # Username and display name of the WhatsApp bridge bot + bot: + username: "whatsappbot" + displayName: "WhatsApp bridge bot" + avatar: "mxc://maunium.net/NeXNQarUbrlYBiPCpprYsRqr" + + # Permissions for using the bridge. + # Permitted values: + # relaybot - Talk through the relaybot (if enabled), no access otherwise + # user - Access to use the bridge to chat with a WhatsApp account. + # admin - User level and some additional administration tools + # Permitted keys: + # * - All Matrix users + # domain - All users on that homeserver + # mxid - Specific user + permissions: + "*": relaybot + + # WhatsApp server connection settings + connection: + # WhatsApp server connection timeout (seconds) + timeout: 20 + # Number of QR codes to store, essentially multiplying the connection timeout + qrRegenCount: 2 + # Maximum number of connection attempts before failing + maxAttempts: 3 + # Retry delay + # Negative numbers are exponential backoff: -connection_retry_delay + 1 + 2^attempts + retryDelay: -1 + # Whether or not to notify the user when attempting to reconnect. Set to false to only report when maxAttempts has been reached + reportRetry: true + + # Send notifications for incoming calls + callNotices: true + + users: + # Username for WhatsApp users + # Evaluated as a template where {{ . }} is replaced with the phone number of the WhatsApp user + username: "whatsapp_{{.}}" + + # Display name for WhatsApp users + # Evaluated as a template, with variables: + # {{.Notify}} - nickname set by the WhatsApp user + # {{.Jid}} - phone number (international format) + # The following variables are also available, but will cause problems on multi-user instances: + # {{.Name}} - display name from contact list + # {{.Short}} - short display name from contact list + displayName: "{{if .Notify}}{{.Notify}}{{else}}{{.Jid}}{{end}} (WA)" + + # Display name for communities. + # A community will be automatically generated for each user using the bridge, and can be used to group WhatsApp chats together + # Evaluated as a template, with variables: + # {{.Localpart}} - MXID localpart + # {{.Server}} - MXID server part of the user. + communityName: "whatsapp_{{.Localpart}}={{.Server}}" + + relaybot: + # Set to true to enable the relaybot and management room + enabled: false + + # Management room for the relay bot where status notifications are posted + management: "!foo:example.com" + + # Users to invite to the management room automatically + invites: [] + + data: + # Size of the PVC to allocate for the SQLite database + capacity: 512Mi + # Storage class (optional) + storageClass: "" + + image: + repository: "dock.mau.dev/tulir/mautrix-whatsapp" + tag: "latest" + pullPolicy: Always + replicaCount: 1 + resources: {} + service: + type: ClusterIP + port: 29318 + + discord: + # Set to true to enable the Discord bridge + enabled: false + + # Discord bot authentication + # See https://github.com/Half-Shot/matrix-appservice-discord#setting-up-discord + auth: + clientId: "" + botToken: "" + + # The name of bridged rooms + # Available vars: + # :guild - guild/server name + # :name - channel name prefixed with # + channelName: "[Discord] :guild :name" + + users: + # Nickname of bridged Discord users + # Available vars: + # :nick - user's Discord nickname + # :username - user's Discord username + # :tag - user's 4 digit Discord tag + # :id - user's Discord developer ID (long) + nickname: ":nick" + # Username of bridged Discord users + # Available vars: + # :username - user's Discord username + # :tag - user's 4 digit Discord tag + # :id - user's Discord developer ID (long) + username: ":username#:tag" + + # Set to false to disable online/offline presence for Discord users + presence: true + + # Set to false to disable typing notifications (only for Discord to Matrix) + typingNotifications: true + + # Set to true to allow users to bridge rooms themselves using !discord commands + # More info: https://t2bot.io/discord + selfService: false + + # Set to false to disable the Discord bot read receipt, which advances whenever the bot bridges a message + readReceipt: true + + # Set to false to disable Discord notifications when a user joins/leaves the Matrix channel + joinLeaveEvents: true + + # Default visibility of bridged rooms (public/private) + defaultVisibility: public + + data: + # Size of the PVC to allocate for the SQLite database + capacity: 512Mi + # Storage class (optional) + storageClass: "" + + image: + repository: "halfshot/matrix-appservice-discord" + tag: "latest" + pullPolicy: Always + replicaCount: 1 + resources: {} + service: + type: ClusterIP + port: 9005 + # Recommended to leave this disabled to allow bridges to be scheduled on separate nodes. + # Set this to true to reduce latency between the homeserver and bridges, or if your cloud provider does not allow + # the ReadWriteMany access mode (see below) + affinity: false + volume: + # Capacity of the shared volume for storing bridge/appservice registration files + # Note: 1Mi should be enough but some cloud providers may set a minimum PVC size of 1Gi, adjust as necessary + capacity: 1Mi + # Storage class (optional) + storageClass: "" + # Access mode of the shared volume. ReadWriteMany is recommended to allow bridges to be scheduled on separate nodes. + # Some cloud providers may not allow the ReadWriteMany access mode. In that case, change this to ReadWriteOnce -AND- + # set bridges.affinity (above) to true + accessMode: ReadWriteMany + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +networkPolicies: + enabled: true