blob: ac3e71f7263a1bf7e564f8f6d230ac9cbf72061b [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",
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +020020 storageClassName: "waw-hdd-paranoid-2",
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" } },
Piotr Dobrowolskib20b3662019-08-11 19:23:45 +020045 storageClassName: cfg.storageClassName,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020046 },
47 },
48
49 dataVolume: kube.PersistentVolumeClaim("synapse-data") {
50 metadata+: app.metadata("synapse-data"),
51 spec+: {
52 storageClassName: cfg.storageClassName,
53 accessModes: [ "ReadWriteOnce" ],
54 resources: {
55 requests: {
56 storage: "50Gi",
57 },
58 },
59 },
60 },
Piotr Dobrowolskiffbb47c2019-05-16 12:18:39 +020061
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +020062 synapseConfig: kube.ConfigMap("synapse") {
63 metadata+: app.metadata("synapse"),
64 data: {
65 "homeserver.yaml": importstr "homeserver.yaml.j2",
66 },
67 },
68
69 casDeployment: kube.Deployment("oauth2-cas-proxy") {
70 metadata+: app.metadata("oauth2-cas-proxy"),
71 spec+: {
72 replicas: 1,
73 template+: {
74 spec+: {
75 containers_: {
76 proxy: kube.Container("oauth2-cas-proxy") {
77 image: cfg.casProxyImage,
78 ports_: {
79 http: { containerPort: 5000 },
80 },
81 env_: {
82 BASE_URL: "https://matrix.hackerspace.pl",
Piotr Dobrowolskiaa0e7552019-05-17 12:55:48 +020083 SERVICE_URL: "https://matrix.hackerspace.pl",
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +020084 OAUTH2_CLIENT: "matrix",
85 OAUTH2_SECRET: { secretKeyRef: { name: "oauth2-cas-proxy", key: "oauth2_secret" } },
86 },
87 },
88 },
89 },
90 },
91 },
92 },
93
94 casSvc: kube.Service("oauth2-cas-proxy") {
95 metadata+: app.metadata("oauth2-cas-proxy"),
96 target_pod:: app.casDeployment.spec.template,
97 },
98
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +020099 synapseDeployment: kube.Deployment("synapse") {
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200100 metadata+: app.metadata("synapse"),
101 spec+: {
102 replicas: 1,
103 template+: {
104 spec+: {
105 volumes_: {
106 data: kube.PersistentVolumeClaimVolume(app.dataVolume),
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +0200107 config: kube.ConfigMapVolume(app.synapseConfig),
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200108 } + {
109 [k]: { secret: { secretName: "appservice-%s-registration" % [k] } }
110 for k in std.objectFields(app.appservices)
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200111 },
112 containers_: {
113 web: kube.Container("synapse") {
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200114 image: cfg.synapseImage,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200115 ports_: {
116 http: { containerPort: 8008 },
117 },
118 env_: {
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200119 SYNAPSE_SERVER_NAME: cfg.serverName,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200120 SYNAPSE_REPORT_STATS: "no",
121 SYNAPSE_NO_TLS: "1",
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200122 SYNAPSE_ALLOW_GUEST: "yes",
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200123
124 POSTGRES_HOST: "postgres",
125 POSTGRES_USER: app.postgres.cfg.username,
126 POSTGRES_PORT: "5432",
127 POSTGRES_DB: app.postgres.cfg.database,
128 POSTGRES_PASSWORD: { secretKeyRef: { name: "synapse", key: "postgres_password" } },
129 },
130 volumeMounts_: {
131 data: { mountPath: "/data" },
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +0200132 config: {
133 mountPath: "/conf/homeserver.yaml",
134 subPath: "homeserver.yaml",
135 },
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: {
204 mountPath: "/etc/riot-web/config.json",
205 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"),
224 config+: {
225 homeserver+: {
226 url: "https://%s" % [cfg.domain],
227 domain: "%s" % [cfg.serverName],
228 },
229 },
230 },
231 },
232 },
233
234 ingress: kube.Ingress("matrix") {
235 metadata+: app.metadata("matrix") {
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200236 annotations+: {
237 "kubernetes.io/tls-acme": "true",
238 "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod",
239 "nginx.ingress.kubernetes.io/proxy-body-size": "0",
240 },
241 },
242 spec+: {
243 tls: [
244 {
245 hosts: [cfg.domain],
246 secretName: "synapse-tls",
247 },
248 ],
249 rules: [
250 {
251 host: cfg.domain,
252 http: {
253 paths: [
254 { path: "/", backend: app.riotSvc.name_port },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200255 { path: "/_matrix", backend: app.synapseSvc.name_port },
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +0200256 { path: "/_cas", backend: app.casSvc.name_port },
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200257 ]
258 },
259 }
260 ],
261 },
262 },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200263
264 AppServiceIrc(name):: {
265 local bridge = self,
266 local cfg = bridge.cfg,
267 cfg:: {
268 image: "registry.k0.hswaw.net/informatic/matrix-appservice-irc:0.11.2",
269 metadata: {},
270 config: std.native("parseYaml")(importstr "appservice-irc.yaml")[0],
Piotr Dobrowolskib20b3662019-08-11 19:23:45 +0200271 storageClassName: app.cfg.storageClassName,
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200272 },
273
274 config: kube.ConfigMap("appservice-irc-%s" % [name]) {
275 metadata+: cfg.metadata,
276 data: {
277 "config.yaml": std.manifestJsonEx(cfg.config, ""),
278 },
279 },
280
281 dataVolume: kube.PersistentVolumeClaim("appservice-irc-%s" % [name]) {
282 metadata+: cfg.metadata,
283 spec+: {
284 storageClassName: cfg.storageClassName,
285 accessModes: [ "ReadWriteOnce" ],
286 resources: {
287 requests: {
288 storage: "10Gi",
289 },
290 },
291 },
292 },
293
294 bootstrapJob: kube.Job("appservice-irc-%s-bootstrap" % [name]) {
295 metadata+: cfg.metadata {
296 labels: {
297 "job-name": "appservice-irc-%s-bootstrap" % [name],
298 },
299 },
300 spec+: {
301 template+: {
302 spec+: {
303 volumes_: {
304 config: kube.ConfigMapVolume(bridge.config),
305 },
306 containers_: {
307 bootstrap: kube.Container("appservice-irc-%s-bootstrap" % [name]) {
308 image: cfg.image,
309 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]],
310 volumeMounts_: {
311 config: { mountPath: "/config" },
312 },
313 },
314 },
315 },
316 },
317 },
318 },
319
320 deployment: kube.Deployment("appservice-irc-%s" % [name]) {
321 metadata+: cfg.metadata,
322 spec+: {
323 replicas: 1,
324 template+: {
325 spec+: {
326 volumes_: {
327 config: kube.ConfigMapVolume(bridge.config),
328 data: kube.PersistentVolumeClaimVolume(bridge.dataVolume),
329 registration: { secret: { secretName: "appservice-irc-%s-registration" % [name] } },
330 },
331 containers_: {
332 appserviceIrc: kube.Container("appservice-irc-%s" % [name]) {
333 image: cfg.image,
334 command: ["matrix-appservice-irc", "-c", "/config/config.yaml", "-f", "/registration/registration.yaml", "-p", "9999"],
335 ports_: {
336 http: { containerPort: 9999 },
337 },
338 volumeMounts_: {
339 registration: { mountPath: "/registration", },
340 config: { mountPath: "/config", },
341 data: { mountPath: "/data" },
342 },
343 },
344 },
345 },
346 },
347 },
348 },
349
350 svc: kube.Service("appservice-irc-%s" % [name]) {
351 metadata+: cfg.metadata,
352 target_pod:: bridge.deployment.spec.template,
353 },
354 },
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200355}