| local kube = import "../../../kube/kube.libsonnet"; |
| |
| { |
| AppServiceIrc(name):: { |
| local bridge = self, |
| local cfg = bridge.cfg, |
| cfg:: { |
| metadata: {}, |
| // Whether the bootstrap job should be created/updated. Kubernetes |
| // doesn't like changing the configuration of jobs, so once this |
| // appservice has been set up, this flag should be flipped to |
| // false. |
| bootstrapJob: true, |
| config: std.native("parseYaml")(importstr "appservice/appservice-irc.yaml")[0] { |
| local appservicecfg = self, |
| ircService+: { |
| [if cfg.passwordEncryptionKeySecret != null then "passwordEncryptionKeyPath"]: "/key/key.pem", |
| debugApi+: { |
| # Unfortunately, we have to enable the debugApi if any |
| # configured server wants to use |
| # ignoreIdleUsersOnStartup. This is seemingly an |
| # appservice-irc bug: |
| # https://github.com/matrix-org/matrix-appservice-irc/issues/1240 |
| enabled: std.length(std.filter( |
| function (k) ( |
| local v = appservicecfg.ircService.servers[k]; |
| v.membershipLists.ignoreIdleUsersOnStartup.enabled == true |
| ), |
| std.objectFields(appservicecfg.ircService.servers) |
| )) > 0, |
| }, |
| }, |
| }, |
| image: error "image must be set", |
| storageClassName: error "storageClassName must be set", |
| |
| # RSA encryption private key secret name containing "key.pem" key |
| # Create using: |
| # kubectl -n matrix create secret generic appservice-irc-password-encryption-key --from-file=key.pem=<(openssl genpkey -out - -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:2048) |
| passwordEncryptionKeySecret: null, |
| }, |
| |
| config: kube.Secret("appservice-irc-%s" % [name]) { |
| metadata+: cfg.metadata, |
| data_: { |
| "config.yaml": std.manifestJsonEx(cfg.config, ""), |
| }, |
| }, |
| |
| dataVolume: kube.PersistentVolumeClaim("appservice-irc-%s" % [name]) { |
| metadata+: cfg.metadata, |
| spec+: { |
| storageClassName: cfg.storageClassName, |
| accessModes: [ "ReadWriteOnce" ], |
| resources: { |
| requests: { |
| storage: "10Gi", |
| }, |
| }, |
| }, |
| }, |
| |
| bootstrapJob: if cfg.bootstrapJob then (kube.Job("appservice-irc-%s-bootstrap" % [name]) { |
| metadata+: cfg.metadata { |
| labels: { |
| "job-name": "appservice-irc-%s-bootstrap" % [name], |
| }, |
| }, |
| spec+: { |
| template+: { |
| spec+: { |
| volumes_: { |
| config: kube.SecretVolume(bridge.config), |
| }, |
| containers_: { |
| bootstrap: kube.Container("appservice-irc-%s-bootstrap" % [name]) { |
| image: cfg.image, |
| 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]], |
| volumeMounts_: { |
| config: { mountPath: "/config" }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }) else {}, |
| |
| deployment: kube.Deployment("appservice-irc-%s" % [name]) { |
| metadata+: cfg.metadata, |
| spec+: { |
| replicas: 1, |
| template+: { |
| spec+: { |
| volumes_: { |
| config: kube.SecretVolume(bridge.config), |
| data: kube.PersistentVolumeClaimVolume(bridge.dataVolume), |
| registration: { secret: { secretName: "appservice-irc-%s-registration" % [name] } }, |
| } + (if cfg.passwordEncryptionKeySecret != null then { |
| key: { secret: { secretName: cfg.passwordEncryptionKeySecret } }, |
| } else {}), |
| nodeSelector: cfg.nodeSelector, |
| containers_: { |
| appserviceIrc: kube.Container("appservice-irc-%s" % [name]) { |
| image: cfg.image, |
| command: ["node", "app.js", "-c", "/config/config.yaml", "-f", "/registration/registration.yaml", "-p", "9999"], |
| ports_: { |
| http: { containerPort: 9999 }, |
| }, |
| volumeMounts_: { |
| registration: { mountPath: "/registration", }, |
| config: { mountPath: "/config", }, |
| data: { mountPath: "/data" }, |
| } + (if cfg.passwordEncryptionKeySecret != null then { |
| key: { mountPath: "/key" }, |
| } else {}), |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| |
| svc: kube.Service("appservice-irc-%s" % [name]) { |
| metadata+: cfg.metadata, |
| target_pod:: bridge.deployment.spec.template, |
| }, |
| }, |
| } |