blob: e9d43be40e00d61e34aa773b69b1d8a9d3881e12 [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 Bazanski5f3a5e02019-09-25 02:51:51 +020021 casProxyImage: "registry.k0.hswaw.net/q3k/oauth2-cas-proxy:0.1.4"
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020022 },
23
24 metadata(component):: {
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +020025 namespace: cfg.namespace,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020026 labels: {
27 "app.kubernetes.io/name": "matrix",
28 "app.kubernetes.io/managed-by": "kubecfg",
29 "app.kubernetes.io/component": component,
30 },
31 },
32
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +020033 namespace: kube.Namespace(cfg.namespace),
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020034
35 postgres: postgres {
36 cfg+: {
37 namespace: cfg.namespace,
38 appName: "synapse",
39 database: "synapse",
40 username: "synapse",
41 password: { secretKeyRef: { name: "synapse", key: "postgres_password" } },
Piotr Dobrowolskib20b3662019-08-11 19:23:45 +020042 storageClassName: cfg.storageClassName,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020043 },
44 },
45
46 dataVolume: kube.PersistentVolumeClaim("synapse-data") {
47 metadata+: app.metadata("synapse-data"),
48 spec+: {
49 storageClassName: cfg.storageClassName,
50 accessModes: [ "ReadWriteOnce" ],
51 resources: {
52 requests: {
53 storage: "50Gi",
54 },
55 },
56 },
57 },
Piotr Dobrowolskiffbb47c2019-05-16 12:18:39 +020058
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +020059 synapseConfig: kube.ConfigMap("synapse") {
60 metadata+: app.metadata("synapse"),
61 data: {
Piotr Dobrowolskieabbe8a2019-08-11 19:49:08 +020062 "homeserver.yaml": importstr "homeserver.yaml",
63 "log.config": importstr "log.config",
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +020064 },
65 },
66
67 casDeployment: kube.Deployment("oauth2-cas-proxy") {
68 metadata+: app.metadata("oauth2-cas-proxy"),
69 spec+: {
70 replicas: 1,
71 template+: {
72 spec+: {
73 containers_: {
74 proxy: kube.Container("oauth2-cas-proxy") {
75 image: cfg.casProxyImage,
76 ports_: {
77 http: { containerPort: 5000 },
78 },
79 env_: {
80 BASE_URL: "https://matrix.hackerspace.pl",
Piotr Dobrowolskiaa0e7552019-05-17 12:55:48 +020081 SERVICE_URL: "https://matrix.hackerspace.pl",
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +020082 OAUTH2_CLIENT: "matrix",
83 OAUTH2_SECRET: { secretKeyRef: { name: "oauth2-cas-proxy", key: "oauth2_secret" } },
84 },
85 },
86 },
87 },
88 },
89 },
90 },
91
92 casSvc: kube.Service("oauth2-cas-proxy") {
93 metadata+: app.metadata("oauth2-cas-proxy"),
94 target_pod:: app.casDeployment.spec.template,
95 },
96
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +020097 synapseDeployment: kube.Deployment("synapse") {
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020098 metadata+: app.metadata("synapse"),
99 spec+: {
100 replicas: 1,
101 template+: {
102 spec+: {
103 volumes_: {
104 data: kube.PersistentVolumeClaimVolume(app.dataVolume),
Piotr Dobrowolski8ebfc1d2020-03-03 21:01:18 +0100105 config_template: kube.ConfigMapVolume(app.synapseConfig),
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200106 } + {
107 [k]: { secret: { secretName: "appservice-%s-registration" % [k] } }
108 for k in std.objectFields(app.appservices)
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200109 },
110 containers_: {
111 web: kube.Container("synapse") {
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200112 image: cfg.synapseImage,
Piotr Dobrowolski8ebfc1d2020-03-03 21:01:18 +0100113 command: ["/bin/sh", "-c", "/start.py migrate_config && exec /start.py"],
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200114 ports_: {
115 http: { containerPort: 8008 },
116 },
117 env_: {
Piotr Dobrowolski8ebfc1d2020-03-03 21:01:18 +0100118 SYNAPSE_CONFIG_DIR: "/config",
Piotr Dobrowolskieabbe8a2019-08-11 19:49:08 +0200119 SYNAPSE_CONFIG_PATH: "/config/homeserver.yaml",
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200120
Piotr Dobrowolski8ebfc1d2020-03-03 21:01:18 +0100121 # These values are not used in a template, but
122 # are required by /start.py migrate_config
123 SYNAPSE_SERVER_NAME: "hackerspace.pl",
124 SYNAPSE_REPORT_STATS: "no",
125
126 SYNAPSE_MACAROON_SECRET_KEY: { secretKeyRef: { name: "synapse", key: "macaroon_secret_key" } },
127 SYNAPSE_REGISTRATION_SHARED_SECRET: { secretKeyRef: { name: "synapse", key: "registration_shared_secret" } },
128 POSTGRES_PASSWORD: { secretKeyRef: { name: "synapse", key: "postgres_password" } },
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200129 },
130 volumeMounts_: {
131 data: { mountPath: "/data" },
Piotr Dobrowolski8ebfc1d2020-03-03 21:01:18 +0100132 config_template: {
133 mountPath: "/conf/homeserver.yaml",
134 subPath: "homeserver.yaml",
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +0200135 },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200136 } + {
137 [k]: { mountPath: "/appservices/%s" % [k] }
138 for k in std.objectFields(app.appservices)
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200139 },
140 },
141 },
142 },
143 },
144 },
145 },
146
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200147 synapseSvc: kube.Service("synapse") {
Piotr Dobrowolskiffbb47c2019-05-16 12:18:39 +0200148 metadata+: app.metadata("synapse"),
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200149 target_pod:: app.synapseDeployment.spec.template,
Piotr Dobrowolskiffbb47c2019-05-16 12:18:39 +0200150 },
151
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200152 riotConfig: kube.ConfigMap("riot-web-config") {
153 metadata+: app.metadata("riot-web-config"),
154 data: {
155 "config.json": std.manifestJsonEx({
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200156 "default_hs_url": "https://%s" % [cfg.domain],
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200157 "disable_custom_urls": false,
158 "disable_guests": false,
159 "disable_login_language_selector": false,
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200160 "disable_3pid_login": true,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200161 "brand": "Riot",
162 "integrations_ui_url": "https://scalar.vector.im/",
163 "integrations_rest_url": "https://scalar.vector.im/api",
164 "integrations_jitsi_widget_url": "https://scalar.vector.im/api/widgets/jitsi.html",
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200165
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200166 "bug_report_endpoint_url": "https://riot.im/bugreports/submit",
167 "features": {
168 "feature_groups": "labs",
169 "feature_pinning": "labs",
170 "feature_reactions": "labs"
171 },
172 "default_federate": true,
173 "default_theme": "light",
174 "roomDirectory": {
175 "servers": [
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200176 "hackerspace.pl"
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200177 ]
178 },
179 "welcomeUserId": "@riot-bot:matrix.org",
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200180 "enable_presence_by_hs_url": {
181 "https://matrix.org": false
182 }
183 }, ""),
184 },
185 },
186
187 riotDeployment: kube.Deployment("riot-web") {
188 metadata+: app.metadata("riot-web"),
189 spec+: {
190 replicas: 1,
191 template+: {
192 spec+: {
193 volumes_: {
194 config: kube.ConfigMapVolume(app.riotConfig),
195 },
196 containers_: {
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200197 web: kube.Container("riot-web") {
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200198 image: cfg.riotImage,
199 ports_: {
200 http: { containerPort: 80 },
201 },
202 volumeMounts_: {
203 config: {
Piotr Dobrowolskiaca7e282020-03-21 22:14:38 +0100204 mountPath: "/app/config.json",
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200205 subPath: "config.json",
206 },
207 },
208 },
209 },
210 },
211 },
212 },
213 },
214
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200215 riotSvc: kube.Service("riot-web") {
216 metadata+: app.metadata("riot-web"),
217 target_pod:: app.riotDeployment.spec.template,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200218 },
219
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200220 appservices: {
221 "irc-freenode": app.AppServiceIrc("freenode") {
222 cfg+: {
223 metadata: app.metadata("appservice-irc-freenode"),
Sergiusz Bazanski92b48d62020-01-08 13:59:04 +0100224 // TODO(q3k): add labels to blessed nodes
225 nodeSelector: {
226 "kubernetes.io/hostname": "bc01n02.hswaw.net",
227 },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200228 config+: {
229 homeserver+: {
230 url: "https://%s" % [cfg.domain],
231 domain: "%s" % [cfg.serverName],
232 },
Piotr Dobrowolskieabbe8a2019-08-11 19:49:08 +0200233 ircService+: {
234 servers+: {
235 "irc.freenode.net"+: {
236 ircClients+: {
237 maxClients: 150,
238 },
239 },
240 },
241 },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200242 },
243 },
244 },
245 },
246
247 ingress: kube.Ingress("matrix") {
248 metadata+: app.metadata("matrix") {
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200249 annotations+: {
250 "kubernetes.io/tls-acme": "true",
251 "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod",
252 "nginx.ingress.kubernetes.io/proxy-body-size": "0",
253 },
254 },
255 spec+: {
256 tls: [
257 {
258 hosts: [cfg.domain],
259 secretName: "synapse-tls",
260 },
261 ],
262 rules: [
263 {
264 host: cfg.domain,
265 http: {
266 paths: [
267 { path: "/", backend: app.riotSvc.name_port },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200268 { path: "/_matrix", backend: app.synapseSvc.name_port },
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +0200269 { path: "/_cas", backend: app.casSvc.name_port },
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200270 ]
271 },
272 }
273 ],
274 },
275 },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200276
277 AppServiceIrc(name):: {
278 local bridge = self,
279 local cfg = bridge.cfg,
280 cfg:: {
Piotr Dobrowolski57349d22020-03-21 22:15:18 +0100281 image: "matrixdotorg/matrix-appservice-irc:release-0.16.0",
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200282 metadata: {},
283 config: std.native("parseYaml")(importstr "appservice-irc.yaml")[0],
Piotr Dobrowolskib20b3662019-08-11 19:23:45 +0200284 storageClassName: app.cfg.storageClassName,
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200285 },
286
287 config: kube.ConfigMap("appservice-irc-%s" % [name]) {
288 metadata+: cfg.metadata,
289 data: {
290 "config.yaml": std.manifestJsonEx(cfg.config, ""),
291 },
292 },
293
294 dataVolume: kube.PersistentVolumeClaim("appservice-irc-%s" % [name]) {
295 metadata+: cfg.metadata,
296 spec+: {
297 storageClassName: cfg.storageClassName,
298 accessModes: [ "ReadWriteOnce" ],
299 resources: {
300 requests: {
301 storage: "10Gi",
302 },
303 },
304 },
305 },
306
307 bootstrapJob: kube.Job("appservice-irc-%s-bootstrap" % [name]) {
308 metadata+: cfg.metadata {
309 labels: {
310 "job-name": "appservice-irc-%s-bootstrap" % [name],
311 },
312 },
313 spec+: {
314 template+: {
315 spec+: {
316 volumes_: {
317 config: kube.ConfigMapVolume(bridge.config),
318 },
319 containers_: {
320 bootstrap: kube.Container("appservice-irc-%s-bootstrap" % [name]) {
321 image: cfg.image,
Piotr Dobrowolski57349d22020-03-21 22:15:18 +0100322 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 +0200323 volumeMounts_: {
324 config: { mountPath: "/config" },
325 },
326 },
327 },
328 },
329 },
330 },
331 },
332
333 deployment: kube.Deployment("appservice-irc-%s" % [name]) {
334 metadata+: cfg.metadata,
335 spec+: {
336 replicas: 1,
337 template+: {
338 spec+: {
339 volumes_: {
340 config: kube.ConfigMapVolume(bridge.config),
341 data: kube.PersistentVolumeClaimVolume(bridge.dataVolume),
342 registration: { secret: { secretName: "appservice-irc-%s-registration" % [name] } },
343 },
Sergiusz Bazanski92b48d62020-01-08 13:59:04 +0100344 nodeSelector: cfg.nodeSelector,
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200345 containers_: {
346 appserviceIrc: kube.Container("appservice-irc-%s" % [name]) {
347 image: cfg.image,
Piotr Dobrowolski57349d22020-03-21 22:15:18 +0100348 command: ["node", "app.js", "-c", "/config/config.yaml", "-f", "/registration/registration.yaml", "-p", "9999"],
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200349 ports_: {
350 http: { containerPort: 9999 },
351 },
352 volumeMounts_: {
353 registration: { mountPath: "/registration", },
354 config: { mountPath: "/config", },
355 data: { mountPath: "/data" },
356 },
357 },
358 },
359 },
360 },
361 },
362 },
363
364 svc: kube.Service("appservice-irc-%s" % [name]) {
365 metadata+: cfg.metadata,
366 target_pod:: bridge.deployment.spec.template,
367 },
368 },
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200369}