blob: a105d8fe126f5f6457f12fec765724bf360258a4 [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 Dobrowolskifef4c122019-05-16 21:05:02 +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)
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",
17 storageClassName: "waw-hdd-redundant-1",
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +020018
19 synapseImage: "matrixdotorg/synapse:v0.99.4",
20 riotImage: "bubuntux/riot-web:v1.1.0",
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +020021 casProxyImage: "registry.k0.hswaw.net/informatic/oauth2-cas-proxy:0.1.3"
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" } },
42 },
43 },
44
45 dataVolume: kube.PersistentVolumeClaim("synapse-data") {
46 metadata+: app.metadata("synapse-data"),
47 spec+: {
48 storageClassName: cfg.storageClassName,
49 accessModes: [ "ReadWriteOnce" ],
50 resources: {
51 requests: {
52 storage: "50Gi",
53 },
54 },
55 },
56 },
Piotr Dobrowolskiffbb47c2019-05-16 12:18:39 +020057
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +020058 synapseConfig: kube.ConfigMap("synapse") {
59 metadata+: app.metadata("synapse"),
60 data: {
61 "homeserver.yaml": importstr "homeserver.yaml.j2",
62 },
63 },
64
65 casDeployment: kube.Deployment("oauth2-cas-proxy") {
66 metadata+: app.metadata("oauth2-cas-proxy"),
67 spec+: {
68 replicas: 1,
69 template+: {
70 spec+: {
71 containers_: {
72 proxy: kube.Container("oauth2-cas-proxy") {
73 image: cfg.casProxyImage,
74 ports_: {
75 http: { containerPort: 5000 },
76 },
77 env_: {
78 BASE_URL: "https://matrix.hackerspace.pl",
79 OAUTH2_CLIENT: "matrix",
80 OAUTH2_SECRET: { secretKeyRef: { name: "oauth2-cas-proxy", key: "oauth2_secret" } },
81 },
82 },
83 },
84 },
85 },
86 },
87 },
88
89 casSvc: kube.Service("oauth2-cas-proxy") {
90 metadata+: app.metadata("oauth2-cas-proxy"),
91 target_pod:: app.casDeployment.spec.template,
92 },
93
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +020094 synapseDeployment: kube.Deployment("synapse") {
Piotr Dobrowolskia2226912019-05-14 18:49:29 +020095 metadata+: app.metadata("synapse"),
96 spec+: {
97 replicas: 1,
98 template+: {
99 spec+: {
100 volumes_: {
101 data: kube.PersistentVolumeClaimVolume(app.dataVolume),
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +0200102 config: kube.ConfigMapVolume(app.synapseConfig),
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200103 } + {
104 [k]: { secret: { secretName: "appservice-%s-registration" % [k] } }
105 for k in std.objectFields(app.appservices)
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200106 },
107 containers_: {
108 web: kube.Container("synapse") {
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200109 image: cfg.synapseImage,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200110 ports_: {
111 http: { containerPort: 8008 },
112 },
113 env_: {
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200114 SYNAPSE_SERVER_NAME: cfg.serverName,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200115 SYNAPSE_REPORT_STATS: "no",
116 SYNAPSE_NO_TLS: "1",
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200117 SYNAPSE_ALLOW_GUEST: "yes",
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200118
119 POSTGRES_HOST: "postgres",
120 POSTGRES_USER: app.postgres.cfg.username,
121 POSTGRES_PORT: "5432",
122 POSTGRES_DB: app.postgres.cfg.database,
123 POSTGRES_PASSWORD: { secretKeyRef: { name: "synapse", key: "postgres_password" } },
124 },
125 volumeMounts_: {
126 data: { mountPath: "/data" },
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +0200127 config: {
128 mountPath: "/conf/homeserver.yaml",
129 subPath: "homeserver.yaml",
130 },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200131 } + {
132 [k]: { mountPath: "/appservices/%s" % [k] }
133 for k in std.objectFields(app.appservices)
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200134 },
135 },
136 },
137 },
138 },
139 },
140 },
141
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200142 synapseSvc: kube.Service("synapse") {
Piotr Dobrowolskiffbb47c2019-05-16 12:18:39 +0200143 metadata+: app.metadata("synapse"),
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200144 target_pod:: app.synapseDeployment.spec.template,
Piotr Dobrowolskiffbb47c2019-05-16 12:18:39 +0200145 },
146
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200147 riotConfig: kube.ConfigMap("riot-web-config") {
148 metadata+: app.metadata("riot-web-config"),
149 data: {
150 "config.json": std.manifestJsonEx({
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200151 "default_hs_url": "https://%s" % [cfg.domain],
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200152 "disable_custom_urls": false,
153 "disable_guests": false,
154 "disable_login_language_selector": false,
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200155 "disable_3pid_login": true,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200156 "brand": "Riot",
157 "integrations_ui_url": "https://scalar.vector.im/",
158 "integrations_rest_url": "https://scalar.vector.im/api",
159 "integrations_jitsi_widget_url": "https://scalar.vector.im/api/widgets/jitsi.html",
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200160
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200161 "bug_report_endpoint_url": "https://riot.im/bugreports/submit",
162 "features": {
163 "feature_groups": "labs",
164 "feature_pinning": "labs",
165 "feature_reactions": "labs"
166 },
167 "default_federate": true,
168 "default_theme": "light",
169 "roomDirectory": {
170 "servers": [
Piotr Dobrowolski4b4231d2019-05-15 11:41:21 +0200171 "hackerspace.pl"
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200172 ]
173 },
174 "welcomeUserId": "@riot-bot:matrix.org",
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200175 "enable_presence_by_hs_url": {
176 "https://matrix.org": false
177 }
178 }, ""),
179 },
180 },
181
182 riotDeployment: kube.Deployment("riot-web") {
183 metadata+: app.metadata("riot-web"),
184 spec+: {
185 replicas: 1,
186 template+: {
187 spec+: {
188 volumes_: {
189 config: kube.ConfigMapVolume(app.riotConfig),
190 },
191 containers_: {
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200192 web: kube.Container("riot-web") {
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200193 image: cfg.riotImage,
194 ports_: {
195 http: { containerPort: 80 },
196 },
197 volumeMounts_: {
198 config: {
199 mountPath: "/etc/riot-web/config.json",
200 subPath: "config.json",
201 },
202 },
203 },
204 },
205 },
206 },
207 },
208 },
209
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200210 riotSvc: kube.Service("riot-web") {
211 metadata+: app.metadata("riot-web"),
212 target_pod:: app.riotDeployment.spec.template,
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200213 },
214
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200215 appservices: {
216 "irc-freenode": app.AppServiceIrc("freenode") {
217 cfg+: {
218 metadata: app.metadata("appservice-irc-freenode"),
219 config+: {
220 homeserver+: {
221 url: "https://%s" % [cfg.domain],
222 domain: "%s" % [cfg.serverName],
223 },
224 },
225 },
226 },
227 },
228
229 ingress: kube.Ingress("matrix") {
230 metadata+: app.metadata("matrix") {
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200231 annotations+: {
232 "kubernetes.io/tls-acme": "true",
233 "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod",
234 "nginx.ingress.kubernetes.io/proxy-body-size": "0",
235 },
236 },
237 spec+: {
238 tls: [
239 {
240 hosts: [cfg.domain],
241 secretName: "synapse-tls",
242 },
243 ],
244 rules: [
245 {
246 host: cfg.domain,
247 http: {
248 paths: [
249 { path: "/", backend: app.riotSvc.name_port },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200250 { path: "/_matrix", backend: app.synapseSvc.name_port },
Piotr Dobrowolskic39fb042019-05-17 09:13:56 +0200251 { path: "/_cas", backend: app.casSvc.name_port },
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200252 ]
253 },
254 }
255 ],
256 },
257 },
Piotr Dobrowolskifef4c122019-05-16 21:05:02 +0200258
259 AppServiceIrc(name):: {
260 local bridge = self,
261 local cfg = bridge.cfg,
262 cfg:: {
263 image: "registry.k0.hswaw.net/informatic/matrix-appservice-irc:0.11.2",
264 metadata: {},
265 config: std.native("parseYaml")(importstr "appservice-irc.yaml")[0],
266 storageClassName: "waw-hdd-redundant-1",
267 },
268
269 config: kube.ConfigMap("appservice-irc-%s" % [name]) {
270 metadata+: cfg.metadata,
271 data: {
272 "config.yaml": std.manifestJsonEx(cfg.config, ""),
273 },
274 },
275
276 dataVolume: kube.PersistentVolumeClaim("appservice-irc-%s" % [name]) {
277 metadata+: cfg.metadata,
278 spec+: {
279 storageClassName: cfg.storageClassName,
280 accessModes: [ "ReadWriteOnce" ],
281 resources: {
282 requests: {
283 storage: "10Gi",
284 },
285 },
286 },
287 },
288
289 bootstrapJob: kube.Job("appservice-irc-%s-bootstrap" % [name]) {
290 metadata+: cfg.metadata {
291 labels: {
292 "job-name": "appservice-irc-%s-bootstrap" % [name],
293 },
294 },
295 spec+: {
296 template+: {
297 spec+: {
298 volumes_: {
299 config: kube.ConfigMapVolume(bridge.config),
300 },
301 containers_: {
302 bootstrap: kube.Container("appservice-irc-%s-bootstrap" % [name]) {
303 image: cfg.image,
304 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]],
305 volumeMounts_: {
306 config: { mountPath: "/config" },
307 },
308 },
309 },
310 },
311 },
312 },
313 },
314
315 deployment: kube.Deployment("appservice-irc-%s" % [name]) {
316 metadata+: cfg.metadata,
317 spec+: {
318 replicas: 1,
319 template+: {
320 spec+: {
321 volumes_: {
322 config: kube.ConfigMapVolume(bridge.config),
323 data: kube.PersistentVolumeClaimVolume(bridge.dataVolume),
324 registration: { secret: { secretName: "appservice-irc-%s-registration" % [name] } },
325 },
326 containers_: {
327 appserviceIrc: kube.Container("appservice-irc-%s" % [name]) {
328 image: cfg.image,
329 command: ["matrix-appservice-irc", "-c", "/config/config.yaml", "-f", "/registration/registration.yaml", "-p", "9999"],
330 ports_: {
331 http: { containerPort: 9999 },
332 },
333 volumeMounts_: {
334 registration: { mountPath: "/registration", },
335 config: { mountPath: "/config", },
336 data: { mountPath: "/data" },
337 },
338 },
339 },
340 },
341 },
342 },
343 },
344
345 svc: kube.Service("appservice-irc-%s" % [name]) {
346 metadata+: cfg.metadata,
347 target_pod:: bridge.deployment.spec.template,
348 },
349 },
Piotr Dobrowolskia2226912019-05-14 18:49:29 +0200350}