blob: 62ed291bb11f39306337710781f3502befc987c6 [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:
3# kubectl -n matrix create secret generic synapse --from-literal=postgres_password=$(pwgen 24 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/')
6#
Piotr Dobrowolskiaa0e7552019-05-17 12:55:48 +02007# TODO: /appservices/*/registration.yaml needs to be copied into /data/appservices/*.yaml manually
Piotr Dobrowolski3ea979d2019-05-23 16:11:52 +02008# kubectl exec -n matrix synapse-7b69cd5b6c-6686j -- sh -c 'mkdir /data/appservices ; cp /appservices/irc-freenode/registration.yaml /data/appservices/freenode-irc.yaml'
Piotr Dobrowolskia2226912019-05-14 18:49:29 +02009
10local kube = import "../../kube/kube.libsonnet";
11local postgres = import "../../kube/postgres.libsonnet";
12
13{
14 local app = self,
15 local cfg = app.cfg,
16 cfg:: {
17 namespace: "matrix",
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020018 domain: "matrix.hackerspace.pl",
19 serverName: "hackerspace.pl",
20 storageClassName: "waw-hdd-redundant-1",
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +020021
22 synapseImage: "matrixdotorg/synapse:v0.99.4",
Piotr Dobrowolski9ab9f612019-05-17 09:53:13 +020023 riotImage: "bubuntux/riot-web:v1.1.2",
Piotr Dobrowolskiaa0e7552019-05-17 12:55:48 +020024 casProxyImage: "registry.k0.hswaw.net/informatic/oauth2-cas-proxy:0.1.4"
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020025 },
26
27 metadata(component):: {
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +020028 namespace: cfg.namespace,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020029 labels: {
30 "app.kubernetes.io/name": "matrix",
31 "app.kubernetes.io/managed-by": "kubecfg",
32 "app.kubernetes.io/component": component,
33 },
34 },
35
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +020036 namespace: kube.Namespace(cfg.namespace),
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020037
38 postgres: postgres {
39 cfg+: {
40 namespace: cfg.namespace,
41 appName: "synapse",
42 database: "synapse",
43 username: "synapse",
44 password: { secretKeyRef: { name: "synapse", key: "postgres_password" } },
45 },
46 },
47
48 dataVolume: kube.PersistentVolumeClaim("synapse-data") {
49 metadata+: app.metadata("synapse-data"),
50 spec+: {
51 storageClassName: cfg.storageClassName,
52 accessModes: [ "ReadWriteOnce" ],
53 resources: {
54 requests: {
55 storage: "50Gi",
56 },
57 },
58 },
59 },
Piotr Dobrowolskiffbb47c2019-05-16 12:18:39 +020060
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +020061 synapseConfig: kube.ConfigMap("synapse") {
62 metadata+: app.metadata("synapse"),
63 data: {
64 "homeserver.yaml": importstr "homeserver.yaml.j2",
65 },
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 Dobrowolskic39fb042019-05-17 09:13:56 +0200106 config: 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 Dobrowolskia2226912019-05-14 18:49:29 +0200114 ports_: {
115 http: { containerPort: 8008 },
116 },
117 env_: {
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200118 SYNAPSE_SERVER_NAME: cfg.serverName,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200119 SYNAPSE_REPORT_STATS: "no",
120 SYNAPSE_NO_TLS: "1",
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200121 SYNAPSE_ALLOW_GUEST: "yes",
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200122
123 POSTGRES_HOST: "postgres",
124 POSTGRES_USER: app.postgres.cfg.username,
125 POSTGRES_PORT: "5432",
126 POSTGRES_DB: app.postgres.cfg.database,
127 POSTGRES_PASSWORD: { secretKeyRef: { name: "synapse", key: "postgres_password" } },
128 },
129 volumeMounts_: {
130 data: { mountPath: "/data" },
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +0200131 config: {
132 mountPath: "/conf/homeserver.yaml",
133 subPath: "homeserver.yaml",
134 },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200135 } + {
136 [k]: { mountPath: "/appservices/%s" % [k] }
137 for k in std.objectFields(app.appservices)
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200138 },
139 },
140 },
141 },
142 },
143 },
144 },
145
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200146 synapseSvc: kube.Service("synapse") {
Piotr Dobrowolskiffbb47c2019-05-16 12:18:39 +0200147 metadata+: app.metadata("synapse"),
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200148 target_pod:: app.synapseDeployment.spec.template,
Piotr Dobrowolskiffbb47c2019-05-16 12:18:39 +0200149 },
150
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200151 riotConfig: kube.ConfigMap("riot-web-config") {
152 metadata+: app.metadata("riot-web-config"),
153 data: {
154 "config.json": std.manifestJsonEx({
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200155 "default_hs_url": "https://%s" % [cfg.domain],
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200156 "disable_custom_urls": false,
157 "disable_guests": false,
158 "disable_login_language_selector": false,
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200159 "disable_3pid_login": true,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200160 "brand": "Riot",
161 "integrations_ui_url": "https://scalar.vector.im/",
162 "integrations_rest_url": "https://scalar.vector.im/api",
163 "integrations_jitsi_widget_url": "https://scalar.vector.im/api/widgets/jitsi.html",
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200164
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200165 "bug_report_endpoint_url": "https://riot.im/bugreports/submit",
166 "features": {
167 "feature_groups": "labs",
168 "feature_pinning": "labs",
169 "feature_reactions": "labs"
170 },
171 "default_federate": true,
172 "default_theme": "light",
173 "roomDirectory": {
174 "servers": [
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200175 "hackerspace.pl"
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200176 ]
177 },
178 "welcomeUserId": "@riot-bot:matrix.org",
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200179 "enable_presence_by_hs_url": {
180 "https://matrix.org": false
181 }
182 }, ""),
183 },
184 },
185
186 riotDeployment: kube.Deployment("riot-web") {
187 metadata+: app.metadata("riot-web"),
188 spec+: {
189 replicas: 1,
190 template+: {
191 spec+: {
192 volumes_: {
193 config: kube.ConfigMapVolume(app.riotConfig),
194 },
195 containers_: {
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200196 web: kube.Container("riot-web") {
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200197 image: cfg.riotImage,
198 ports_: {
199 http: { containerPort: 80 },
200 },
201 volumeMounts_: {
202 config: {
203 mountPath: "/etc/riot-web/config.json",
204 subPath: "config.json",
205 },
206 },
207 },
208 },
209 },
210 },
211 },
212 },
213
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200214 riotSvc: kube.Service("riot-web") {
215 metadata+: app.metadata("riot-web"),
216 target_pod:: app.riotDeployment.spec.template,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200217 },
218
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200219 appservices: {
220 "irc-freenode": app.AppServiceIrc("freenode") {
221 cfg+: {
222 metadata: app.metadata("appservice-irc-freenode"),
223 config+: {
224 homeserver+: {
225 url: "https://%s" % [cfg.domain],
226 domain: "%s" % [cfg.serverName],
227 },
228 },
229 },
230 },
231 },
232
233 ingress: kube.Ingress("matrix") {
234 metadata+: app.metadata("matrix") {
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200235 annotations+: {
236 "kubernetes.io/tls-acme": "true",
237 "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod",
238 "nginx.ingress.kubernetes.io/proxy-body-size": "0",
239 },
240 },
241 spec+: {
242 tls: [
243 {
244 hosts: [cfg.domain],
245 secretName: "synapse-tls",
246 },
247 ],
248 rules: [
249 {
250 host: cfg.domain,
251 http: {
252 paths: [
253 { path: "/", backend: app.riotSvc.name_port },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200254 { path: "/_matrix", backend: app.synapseSvc.name_port },
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +0200255 { path: "/_cas", backend: app.casSvc.name_port },
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200256 ]
257 },
258 }
259 ],
260 },
261 },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200262
263 AppServiceIrc(name):: {
264 local bridge = self,
265 local cfg = bridge.cfg,
266 cfg:: {
267 image: "registry.k0.hswaw.net/informatic/matrix-appservice-irc:0.11.2",
268 metadata: {},
269 config: std.native("parseYaml")(importstr "appservice-irc.yaml")[0],
270 storageClassName: "waw-hdd-redundant-1",
271 },
272
273 config: kube.ConfigMap("appservice-irc-%s" % [name]) {
274 metadata+: cfg.metadata,
275 data: {
276 "config.yaml": std.manifestJsonEx(cfg.config, ""),
277 },
278 },
279
280 dataVolume: kube.PersistentVolumeClaim("appservice-irc-%s" % [name]) {
281 metadata+: cfg.metadata,
282 spec+: {
283 storageClassName: cfg.storageClassName,
284 accessModes: [ "ReadWriteOnce" ],
285 resources: {
286 requests: {
287 storage: "10Gi",
288 },
289 },
290 },
291 },
292
293 bootstrapJob: kube.Job("appservice-irc-%s-bootstrap" % [name]) {
294 metadata+: cfg.metadata {
295 labels: {
296 "job-name": "appservice-irc-%s-bootstrap" % [name],
297 },
298 },
299 spec+: {
300 template+: {
301 spec+: {
302 volumes_: {
303 config: kube.ConfigMapVolume(bridge.config),
304 },
305 containers_: {
306 bootstrap: kube.Container("appservice-irc-%s-bootstrap" % [name]) {
307 image: cfg.image,
308 command: ["sh", "-c", "matrix-appservice-irc -r -u http://appservice-irc-%s:9999 -c /config/config.yaml -f /tmp/registration.yaml && cat /tmp/registration.yaml" % [name]],
309 volumeMounts_: {
310 config: { mountPath: "/config" },
311 },
312 },
313 },
314 },
315 },
316 },
317 },
318
319 deployment: kube.Deployment("appservice-irc-%s" % [name]) {
320 metadata+: cfg.metadata,
321 spec+: {
322 replicas: 1,
323 template+: {
324 spec+: {
325 volumes_: {
326 config: kube.ConfigMapVolume(bridge.config),
327 data: kube.PersistentVolumeClaimVolume(bridge.dataVolume),
328 registration: { secret: { secretName: "appservice-irc-%s-registration" % [name] } },
329 },
330 containers_: {
331 appserviceIrc: kube.Container("appservice-irc-%s" % [name]) {
332 image: cfg.image,
333 command: ["matrix-appservice-irc", "-c", "/config/config.yaml", "-f", "/registration/registration.yaml", "-p", "9999"],
334 ports_: {
335 http: { containerPort: 9999 },
336 },
337 volumeMounts_: {
338 registration: { mountPath: "/registration", },
339 config: { mountPath: "/config", },
340 data: { mountPath: "/data" },
341 },
342 },
343 },
344 },
345 },
346 },
347 },
348
349 svc: kube.Service("appservice-irc-%s" % [name]) {
350 metadata+: cfg.metadata,
351 target_pod:: bridge.deployment.spec.template,
352 },
353 },
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200354}