blob: d6e3c268bf8ee5b9dc34f17127f4a7881c7a9931 [file] [log] [blame]
Piotr Dobrowolskia2226912019-05-14 18:49:29 +02001# matrix.hackerspace.pl, a matrix/synapse instance
2# This needs a secret provisioned, create with:
Piotr Dobrowolskieabbe8a2019-08-11 19:49:08 +02003# kubectl -n matrix create secret generic synapse --from-literal=postgres_password=$(pwgen 24 1) --from-literal=macaroon_secret_key=$(pwgen 32 1) --from-literal=registration_shared_secret=$(pwgen 32 1)
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +02004# kubectl -n matrix create secret generic oauth2-cas-proxy --from-literal=oauth2_secret=...
Piotr Dobrowolski3ea979d2019-05-23 16:11:52 +02005# kubectl -n matrix create secret generic appservice-irc-freenode-registration --from-file=registration.yaml=<(kubectl logs -n matrix $(kubectl get pods -n matrix --selector=job-name=appservice-irc-freenode-bootstrap --output=jsonpath='{.items[*].metadata.name}') | tail -n +4 | sed -r 's/(.*aliases:.*)/ group_id: "+freenode:hackerspace.pl"\n\1/')
Piotr Dobrowolskia2226912019-05-14 18:49:29 +02006
7local kube = import "../../kube/kube.libsonnet";
8local postgres = import "../../kube/postgres.libsonnet";
9
10{
11 local app = self,
12 local cfg = app.cfg,
13 cfg:: {
14 namespace: "matrix",
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020015 domain: "matrix.hackerspace.pl",
16 serverName: "hackerspace.pl",
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +020017 storageClassName: "waw-hdd-paranoid-2",
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +020018
Piotr Dobrowolski8ebfc1d2020-03-03 21:01:18 +010019 synapseImage: "matrixdotorg/synapse:v1.11.1",
Piotr Dobrowolskiaca7e282020-03-21 22:14:38 +010020 riotImage: "vectorim/riot-web:v1.5.13",
Sergiusz Bazanski735ac9c2020-07-17 12:10:42 +020021 casProxyImage: "registry.k0.hswaw.net/q3k/oauth2-cas-proxy:0.1.4",
22 appserviceIRCImage: "matrixdotorg/matrix-appservice-irc:release-0.17.1",
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020023 },
24
25 metadata(component):: {
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +020026 namespace: cfg.namespace,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020027 labels: {
28 "app.kubernetes.io/name": "matrix",
29 "app.kubernetes.io/managed-by": "kubecfg",
30 "app.kubernetes.io/component": component,
31 },
32 },
33
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +020034 namespace: kube.Namespace(cfg.namespace),
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020035
36 postgres: postgres {
37 cfg+: {
38 namespace: cfg.namespace,
39 appName: "synapse",
40 database: "synapse",
41 username: "synapse",
42 password: { secretKeyRef: { name: "synapse", key: "postgres_password" } },
Piotr Dobrowolskib20b3662019-08-11 19:23:45 +020043 storageClassName: cfg.storageClassName,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020044 },
45 },
46
47 dataVolume: kube.PersistentVolumeClaim("synapse-data") {
48 metadata+: app.metadata("synapse-data"),
49 spec+: {
50 storageClassName: cfg.storageClassName,
51 accessModes: [ "ReadWriteOnce" ],
52 resources: {
53 requests: {
54 storage: "50Gi",
55 },
56 },
57 },
58 },
Piotr Dobrowolskiffbb47c2019-05-16 12:18:39 +020059
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +020060 synapseConfig: kube.ConfigMap("synapse") {
61 metadata+: app.metadata("synapse"),
62 data: {
Piotr Dobrowolskieabbe8a2019-08-11 19:49:08 +020063 "homeserver.yaml": importstr "homeserver.yaml",
64 "log.config": importstr "log.config",
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +020065 },
66 },
67
68 casDeployment: kube.Deployment("oauth2-cas-proxy") {
69 metadata+: app.metadata("oauth2-cas-proxy"),
70 spec+: {
71 replicas: 1,
72 template+: {
73 spec+: {
74 containers_: {
75 proxy: kube.Container("oauth2-cas-proxy") {
76 image: cfg.casProxyImage,
77 ports_: {
78 http: { containerPort: 5000 },
79 },
80 env_: {
81 BASE_URL: "https://matrix.hackerspace.pl",
Piotr Dobrowolskiaa0e7552019-05-17 12:55:48 +020082 SERVICE_URL: "https://matrix.hackerspace.pl",
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +020083 OAUTH2_CLIENT: "matrix",
84 OAUTH2_SECRET: { secretKeyRef: { name: "oauth2-cas-proxy", key: "oauth2_secret" } },
85 },
86 },
87 },
88 },
89 },
90 },
91 },
92
93 casSvc: kube.Service("oauth2-cas-proxy") {
94 metadata+: app.metadata("oauth2-cas-proxy"),
95 target_pod:: app.casDeployment.spec.template,
96 },
97
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +020098 synapseDeployment: kube.Deployment("synapse") {
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020099 metadata+: app.metadata("synapse"),
100 spec+: {
101 replicas: 1,
102 template+: {
103 spec+: {
104 volumes_: {
105 data: kube.PersistentVolumeClaimVolume(app.dataVolume),
Piotr Dobrowolski8ebfc1d2020-03-03 21:01:18 +0100106 config_template: kube.ConfigMapVolume(app.synapseConfig),
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200107 } + {
108 [k]: { secret: { secretName: "appservice-%s-registration" % [k] } }
109 for k in std.objectFields(app.appservices)
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200110 },
111 containers_: {
112 web: kube.Container("synapse") {
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200113 image: cfg.synapseImage,
Piotr Dobrowolski8ebfc1d2020-03-03 21:01:18 +0100114 command: ["/bin/sh", "-c", "/start.py migrate_config && exec /start.py"],
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200115 ports_: {
116 http: { containerPort: 8008 },
117 },
118 env_: {
Piotr Dobrowolski8ebfc1d2020-03-03 21:01:18 +0100119 SYNAPSE_CONFIG_DIR: "/config",
Piotr Dobrowolskieabbe8a2019-08-11 19:49:08 +0200120 SYNAPSE_CONFIG_PATH: "/config/homeserver.yaml",
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200121
Piotr Dobrowolski8ebfc1d2020-03-03 21:01:18 +0100122 # These values are not used in a template, but
123 # are required by /start.py migrate_config
124 SYNAPSE_SERVER_NAME: "hackerspace.pl",
125 SYNAPSE_REPORT_STATS: "no",
126
127 SYNAPSE_MACAROON_SECRET_KEY: { secretKeyRef: { name: "synapse", key: "macaroon_secret_key" } },
128 SYNAPSE_REGISTRATION_SHARED_SECRET: { secretKeyRef: { name: "synapse", key: "registration_shared_secret" } },
129 POSTGRES_PASSWORD: { secretKeyRef: { name: "synapse", key: "postgres_password" } },
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200130 },
131 volumeMounts_: {
132 data: { mountPath: "/data" },
Piotr Dobrowolski8ebfc1d2020-03-03 21:01:18 +0100133 config_template: {
134 mountPath: "/conf/homeserver.yaml",
135 subPath: "homeserver.yaml",
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +0200136 },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200137 } + {
138 [k]: { mountPath: "/appservices/%s" % [k] }
139 for k in std.objectFields(app.appservices)
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200140 },
141 },
142 },
143 },
144 },
145 },
146 },
147
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200148 synapseSvc: kube.Service("synapse") {
Piotr Dobrowolskiffbb47c2019-05-16 12:18:39 +0200149 metadata+: app.metadata("synapse"),
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200150 target_pod:: app.synapseDeployment.spec.template,
Piotr Dobrowolskiffbb47c2019-05-16 12:18:39 +0200151 },
152
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200153 riotConfig: kube.ConfigMap("riot-web-config") {
154 metadata+: app.metadata("riot-web-config"),
155 data: {
156 "config.json": std.manifestJsonEx({
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200157 "default_hs_url": "https://%s" % [cfg.domain],
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200158 "disable_custom_urls": false,
159 "disable_guests": false,
160 "disable_login_language_selector": false,
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200161 "disable_3pid_login": true,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200162 "brand": "Riot",
163 "integrations_ui_url": "https://scalar.vector.im/",
164 "integrations_rest_url": "https://scalar.vector.im/api",
165 "integrations_jitsi_widget_url": "https://scalar.vector.im/api/widgets/jitsi.html",
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200166
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200167 "bug_report_endpoint_url": "https://riot.im/bugreports/submit",
168 "features": {
169 "feature_groups": "labs",
170 "feature_pinning": "labs",
171 "feature_reactions": "labs"
172 },
173 "default_federate": true,
174 "default_theme": "light",
175 "roomDirectory": {
176 "servers": [
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200177 "hackerspace.pl"
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200178 ]
179 },
180 "welcomeUserId": "@riot-bot:matrix.org",
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200181 "enable_presence_by_hs_url": {
182 "https://matrix.org": false
183 }
184 }, ""),
185 },
186 },
187
188 riotDeployment: kube.Deployment("riot-web") {
189 metadata+: app.metadata("riot-web"),
190 spec+: {
191 replicas: 1,
192 template+: {
193 spec+: {
194 volumes_: {
195 config: kube.ConfigMapVolume(app.riotConfig),
196 },
197 containers_: {
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200198 web: kube.Container("riot-web") {
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200199 image: cfg.riotImage,
200 ports_: {
201 http: { containerPort: 80 },
202 },
203 volumeMounts_: {
204 config: {
Piotr Dobrowolskiaca7e282020-03-21 22:14:38 +0100205 mountPath: "/app/config.json",
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200206 subPath: "config.json",
207 },
208 },
209 },
210 },
211 },
212 },
213 },
214 },
215
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200216 riotSvc: kube.Service("riot-web") {
217 metadata+: app.metadata("riot-web"),
218 target_pod:: app.riotDeployment.spec.template,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200219 },
220
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200221 appservices: {
222 "irc-freenode": app.AppServiceIrc("freenode") {
223 cfg+: {
224 metadata: app.metadata("appservice-irc-freenode"),
Sergiusz Bazanski92b48d62020-01-08 13:59:04 +0100225 // TODO(q3k): add labels to blessed nodes
226 nodeSelector: {
227 "kubernetes.io/hostname": "bc01n02.hswaw.net",
228 },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200229 config+: {
230 homeserver+: {
231 url: "https://%s" % [cfg.domain],
232 domain: "%s" % [cfg.serverName],
233 },
Piotr Dobrowolskieabbe8a2019-08-11 19:49:08 +0200234 ircService+: {
235 servers+: {
236 "irc.freenode.net"+: {
237 ircClients+: {
238 maxClients: 150,
239 },
240 },
241 },
242 },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200243 },
244 },
245 },
246 },
247
248 ingress: kube.Ingress("matrix") {
249 metadata+: app.metadata("matrix") {
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200250 annotations+: {
251 "kubernetes.io/tls-acme": "true",
252 "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod",
253 "nginx.ingress.kubernetes.io/proxy-body-size": "0",
254 },
255 },
256 spec+: {
257 tls: [
258 {
259 hosts: [cfg.domain],
260 secretName: "synapse-tls",
261 },
262 ],
263 rules: [
264 {
265 host: cfg.domain,
266 http: {
267 paths: [
268 { path: "/", backend: app.riotSvc.name_port },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200269 { path: "/_matrix", backend: app.synapseSvc.name_port },
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +0200270 { path: "/_cas", backend: app.casSvc.name_port },
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200271 ]
272 },
273 }
274 ],
275 },
276 },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200277
278 AppServiceIrc(name):: {
279 local bridge = self,
280 local cfg = bridge.cfg,
281 cfg:: {
Sergiusz Bazanski735ac9c2020-07-17 12:10:42 +0200282 image: app.cfg.appserviceIRCImage,
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200283 metadata: {},
284 config: std.native("parseYaml")(importstr "appservice-irc.yaml")[0],
Piotr Dobrowolskib20b3662019-08-11 19:23:45 +0200285 storageClassName: app.cfg.storageClassName,
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200286 },
287
288 config: kube.ConfigMap("appservice-irc-%s" % [name]) {
289 metadata+: cfg.metadata,
290 data: {
291 "config.yaml": std.manifestJsonEx(cfg.config, ""),
292 },
293 },
294
295 dataVolume: kube.PersistentVolumeClaim("appservice-irc-%s" % [name]) {
296 metadata+: cfg.metadata,
297 spec+: {
298 storageClassName: cfg.storageClassName,
299 accessModes: [ "ReadWriteOnce" ],
300 resources: {
301 requests: {
302 storage: "10Gi",
303 },
304 },
305 },
306 },
307
308 bootstrapJob: kube.Job("appservice-irc-%s-bootstrap" % [name]) {
309 metadata+: cfg.metadata {
310 labels: {
311 "job-name": "appservice-irc-%s-bootstrap" % [name],
312 },
313 },
314 spec+: {
315 template+: {
316 spec+: {
317 volumes_: {
318 config: kube.ConfigMapVolume(bridge.config),
319 },
320 containers_: {
321 bootstrap: kube.Container("appservice-irc-%s-bootstrap" % [name]) {
322 image: cfg.image,
Piotr Dobrowolski57349d22020-03-21 22:15:18 +0100323 command: ["sh", "-c", "node app.js -r -u http://appservice-irc-%s:9999 -c /config/config.yaml -f /tmp/registration.yaml && cat /tmp/registration.yaml" % [name]],
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200324 volumeMounts_: {
325 config: { mountPath: "/config" },
326 },
327 },
328 },
329 },
330 },
331 },
332 },
333
334 deployment: kube.Deployment("appservice-irc-%s" % [name]) {
335 metadata+: cfg.metadata,
336 spec+: {
337 replicas: 1,
338 template+: {
339 spec+: {
340 volumes_: {
341 config: kube.ConfigMapVolume(bridge.config),
342 data: kube.PersistentVolumeClaimVolume(bridge.dataVolume),
343 registration: { secret: { secretName: "appservice-irc-%s-registration" % [name] } },
344 },
Sergiusz Bazanski92b48d62020-01-08 13:59:04 +0100345 nodeSelector: cfg.nodeSelector,
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200346 containers_: {
347 appserviceIrc: kube.Container("appservice-irc-%s" % [name]) {
348 image: cfg.image,
Piotr Dobrowolski57349d22020-03-21 22:15:18 +0100349 command: ["node", "app.js", "-c", "/config/config.yaml", "-f", "/registration/registration.yaml", "-p", "9999"],
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200350 ports_: {
351 http: { containerPort: 9999 },
352 },
353 volumeMounts_: {
354 registration: { mountPath: "/registration", },
355 config: { mountPath: "/config", },
356 data: { mountPath: "/data" },
357 },
358 },
359 },
360 },
361 },
362 },
363 },
364
365 svc: kube.Service("appservice-irc-%s" % [name]) {
366 metadata+: cfg.metadata,
367 target_pod:: bridge.deployment.spec.template,
368 },
369 },
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200370}