diff --git a/terranix/main/kubernetes/matrix.nix b/terranix/main/kubernetes/matrix.nix new file mode 100644 index 0000000..5fc7b28 --- /dev/null +++ b/terranix/main/kubernetes/matrix.nix @@ -0,0 +1,880 @@ +{ + elib, + inputs, + pkgs, + config, + uterranix-lib, + lib, + ... +}: let + inherit + (uterranix-lib) + tf + ; + inherit + (elib) + copyNixNGImage + ; +in { + imports = [ + (copyNixNGImage { + name = "synapse-redis"; + image = + (inputs.nix-snapshotter.packages.${pkgs.stdenv.system}.nix-snapshotter.buildImage { + name = "synapse-redis"; + resolvedByNix = true; + config.entrypoint = ["${inputs.self.nixngConfigurations.synapseRedis.config.system.build.toplevel}/init"]; + }) + .image; + hosts = [ + "blowhole.hosts.in.redalder.org" + ]; + }) + (copyNixNGImage { + name = "synapse-client"; + image = + (inputs.nix-snapshotter.packages.${pkgs.stdenv.system}.nix-snapshotter.buildImage { + name = "synapse-client"; + resolvedByNix = true; + config.entrypoint = ["${inputs.self.nixngConfigurations.synapseClient.config.system.build.toplevel}/init"]; + }) + .image; + hosts = [ + "blowhole.hosts.in.redalder.org" + ]; + }) + (copyNixNGImage { + name = "synapse-sync"; + image = + (inputs.nix-snapshotter.packages.${pkgs.stdenv.system}.nix-snapshotter.buildImage { + name = "synapse-sync"; + resolvedByNix = true; + config.entrypoint = ["${inputs.self.nixngConfigurations.synapseSync.config.system.build.toplevel}/init"]; + }) + .image; + hosts = [ + "blowhole.hosts.in.redalder.org" + ]; + }) + (copyNixNGImage { + name = "synapse-federation-receiver"; + image = + (inputs.nix-snapshotter.packages.${pkgs.stdenv.system}.nix-snapshotter.buildImage { + name = "synapse-federation-receiver"; + resolvedByNix = true; + config.entrypoint = ["${inputs.self.nixngConfigurations.synapseFederationReceiver.config.system.build.toplevel}/init"]; + }) + .image; + hosts = [ + "blowhole.hosts.in.redalder.org" + ]; + }) + (copyNixNGImage { + name = "synapse-federation-sender"; + image = + (inputs.nix-snapshotter.packages.${pkgs.stdenv.system}.nix-snapshotter.buildImage { + name = "synapse-federation-sender"; + resolvedByNix = true; + config.entrypoint = ["${inputs.self.nixngConfigurations.synapseFederationSender.config.system.build.toplevel}/init"]; + }) + .image; + hosts = [ + "blowhole.hosts.in.redalder.org" + ]; + }) + (copyNixNGImage { + name = "synapse-postgresql"; + image = + (inputs.nix-snapshotter.packages.${pkgs.stdenv.system}.nix-snapshotter.buildImage { + name = "synapse-postgresql"; + resolvedByNix = true; + config.entrypoint = ["${inputs.self.nixngConfigurations.synapsePostgreSQL.config.system.build.toplevel}/init"]; + }) + .image; + hosts = [ + "blowhole.hosts.in.redalder.org" + ]; + }) + (copyNixNGImage { + name = "synapse"; + image = + (inputs.nix-snapshotter.packages.${pkgs.stdenv.system}.nix-snapshotter.buildImage { + name = "synapse"; + resolvedByNix = true; + config.entrypoint = ["${inputs.self.nixngConfigurations.synapse.config.system.build.toplevel}/init"]; + }) + .image; + hosts = [ + "blowhole.hosts.in.redalder.org" + ]; + }) + ]; + + resource."kubernetes_namespace"."matrix" = { + metadata = { + name = "matrix"; + + labels = { + visibility = "public"; + # has to be kept in sync with `prepare` profile + "istio.io/rev" = config.uk3s.istio.revision; + }; + }; + }; + + resource."kubernetes_manifest"."synapse-data_persistent-volume" = { + manifest = { + apiVersion = "v1"; + kind = "PersistentVolume"; + metadata = { + name = "synapse-data"; + labels.type = "local"; + }; + spec = { + capacity.storage = "10Gi"; + claimRef = { + name = "synapse-data"; + namespace = "matrix"; + }; + volumeModule = "Filesystem"; + accessModes = [ + "ReadWriteOnce" + ]; + persistentVolumeReclaimPolicy = "Retain"; + storageClassName = "hostpath"; + hostPath.path = "/data/matrix/synapse/data"; + }; + }; + }; + + resource."kubernetes_manifest"."synapse-postgresql_persistent-volume" = { + manifest = { + apiVersion = "v1"; + kind = "PersistentVolume"; + metadata = { + name = "synapse-postgresql"; + labels.type = "local"; + }; + spec = { + capacity.storage = "10Gi"; + claimRef = { + name = "synapse-postgresql"; + namespace = "matrix"; + }; + volumeModule = "Filesystem"; + accessModes = [ + "ReadWriteOnce" + ]; + persistentVolumeReclaimPolicy = "Retain"; + storageClassName = "hostpath"; + hostPath.path = "/data/matrix/synapse/postgresql"; + }; + }; + }; + + resource."kubernetes_manifest"."synapse-redis_persistent-volume" = { + manifest = { + apiVersion = "v1"; + kind = "PersistentVolume"; + metadata = { + name = "synapse-redis"; + labels.type = "local"; + }; + spec = { + capacity.storage = "10Gi"; + claimRef = { + name = "synapse-redis"; + namespace = "matrix"; + }; + volumeModule = "Filesystem"; + accessModes = [ + "ReadWriteOnce" + ]; + persistentVolumeReclaimPolicy = "Retain"; + storageClassName = "hostpath"; + hostPath.path = "/data/matrix/synapse/redis"; + }; + }; + }; + + resource."kubernetes_manifest"."synapse-registrations_persistent-volume" = { + manifest = { + apiVersion = "v1"; + kind = "PersistentVolume"; + metadata = { + name = "synapse-registrations"; + labels.type = "local"; + }; + spec = { + capacity.storage = "10Gi"; + volumeModule = "Filesystem"; + accessModes = [ + "ReadWriteOnce" + ]; + persistentVolumeReclaimPolicy = "Retain"; + storageClassName = "hostpath"; + hostPath.path = "/data/matrix/synapse/registrations"; + }; + }; + }; + + resource."kubernetes_manifest"."synapse-data_persistent-volume-claim" = { + manifest = { + kind = "PersistentVolumeClaim"; + apiVersion = "v1"; + metadata = { + name = "synapse-data"; + namespace = "matrix"; + }; + spec = { + volumeName = "synapse-data"; + storageClassName = "hostpath"; + accessModels = [ + "ReadWriteOnce" + ]; + resources.requests.storage = "10Gi"; + }; + }; + }; + + resource."kubernetes_manifest"."synapse-postgresql_persistent-volume-claim" = { + manifest = { + kind = "PersistentVolumeClaim"; + apiVersion = "v1"; + metadata = { + name = "synapse-postgresql"; + namespace = "matrix"; + }; + spec = { + volumeName = "synapse-postgresql"; + storageClassName = "hostpath"; + accessModels = [ + "ReadWriteOnce" + ]; + resources.requests.storage = "10Gi"; + }; + }; + }; + + resource."kubernetes_manifest"."synapse-redis_persistent-volume-claim" = { + manifest = { + kind = "PersistentVolumeClaim"; + apiVersion = "v1"; + metadata = { + name = "synapse-redis"; + namespace = "matrix"; + }; + spec = { + volumeName = "synapse-redis"; + storageClassName = "hostpath"; + accessModels = [ + "ReadWriteOnce" + ]; + resources.requests.storage = "10Gi"; + }; + }; + }; + + resource."kubernetes_manifest"."synapse-registrations_synapse_persistent-volume-claim" = { + manifest = { + kind = "PersistentVolumeClaim"; + apiVersion = "v1"; + metadata = { + name = "synapse-registrations_synapse"; + namespace = "matrix"; + }; + spec = { + volumeName = "synapse-registrations"; + storageClassName = "hostpath"; + accessModels = [ + "ReadWriteOnce" + ]; + resources.requests.storage = "1Gi"; + }; + }; + }; + + resource."kubernetes_manifest"."synapse-deployment" = { + manifest = { + apiVersion = "apps/v1"; + kind = "Deployment"; + metadata = { + name = "synapse"; + namespace = "matrix"; + labels = { + app = "synapse"; + }; + }; + spec = { + replicas = 1; + strategy.type = "Recreate"; + selector.matchLabels.app = "synapse"; + template = { + metadata.labels.app = "synapse"; + metadata.annotations = { + "vault.hashicorp.com/agent-inject" = true; + "vault.hashicorp.com/role" = "synapse"; + + "vault.hashicorp.com/agent-init-first" = true; + "vault.hashicorp.com/secret-volume-path" = "/secrets"; + + "vault.hashicorp.com/agent-inject-secret-redis_password" = "kv/data/cluster/matrix/synapse"; + "vault.hashicorp.com/agent-inject-template-redis_password" = '' + {{ with secret "kv/data/cluster/matrix/synapse" -}}{{ .Data.data.redis_password }} {{ end -}} + ''; + + # "vault.hashicorp.com/agent-inject-secret-init.sql" = ""; ??? + "vault.hashicorp.com/agent-inject-template-init.sql" = '' + alter user "synapse" with password + '{{ with secret "kv/data/cluster/matrix/synapse" }}{{ .Data.data.pgpass }}{{ end }}'; + alter user "mautrix-facebook" with password + '{{ with secret "kv/data/cluster/matrix/mautrix-facebook/postgresql" }}{{ .Data.data.pgpass }}{{ end }}'; + alter user "mautrix-signal" with password + '{{ with secret "kv/data/cluster/matrix/mautrix-signal/postgresql" }}{{ .Data.data.pgpass }}{{ end }}'; + alter user "mautrix-discord" with password + '{{ with secret "kv/data/cluster/matrix/mautrix-discord/postgresql" }}{{ .Data.data.pgpass }}{{ end }}'; + alter user "mautrix-slack" with password + '{{ with secret "kv/data/cluster/matrix/mautrix-slack/postgresql" }}{{ .Data.data.pgpass }}{{ end }}'; + ''; + + "vault.hashicorp.com/agent-inject-secret-env" = "kv/data/cluster/matrix/synapse"; + "vault.hashicorp.com/agent-inject-template-env" = '' + {{ with secret "kv/data/cluster/matrix/synapse" }} + http_proxy=https://synapse:{{ .Data.data.proxy_pass }}@synapse-proxy.in.redalder.org:8883/ + https_proxy=https://synapse:{{ .Data.data.proxy_pass }}@synapse-proxy.in.redalder.org:8883/ + {{ end }} + ''; + + "vault.hashicorp.com/agent-inject-secret-extra.yaml" = "kv/data/cluster/matrix/synapse"; + "vault.hashicorp.com/agent-inject-template-extra.yaml" = '' + {{ with secret "kv/data/cluster/matrix/synapse" }} + registration_shared_secret: "{{ .Data.data.registration_shared_secret }}" + macaroon_secret_key: "{{ .Data.data.macaroon_secret_key }}" + form_secret: "{{ .Data.data.form_secret }}" + database: + name: "psycopg2" + args: + user: "synapse" + password: "{{ .Data.data.pgpass }}" + database: "synapse" + host: "127.0.0.1" + cp_min: 5 + cp_max: 10 + redis: + enabled: true + password: "{{ .Data.data.redis_password }}" + {{ end }} + ''; + }; + spec = { + containers = [ + { + name = "redis"; + image = + tf "data.external.nixng-image-synapse-redis.result.out"; + ports = [ + { + name = "redis"; + containerPort = 6379; + } + ]; + volumeMounts = [ + { + name = "synapse-redis"; + mountPath = "/var/lib/redis/"; + } + ]; + resources.limits = { + cpu = "400m"; + memory = "128Mi"; + }; + resources.requests = { + cpu = "200m"; + memory = "96Mi"; + }; + } + { + name = "postgresql"; + image = + tf "data.external.nixng-image-synapse-postgresql.result.out"; + ports = [ + { + name = "posgresql"; + containerPort = 5432; + } + ]; + volumeMounts = [ + { + name = "synapse-postgresql"; + mountPath = "/var/lib/postgresql"; + } + ]; + resources.limits = { + cpu = "800m"; + memory = "2048Mi"; + }; + resources.requests = { + cpu = "400m"; + memory = "1536Mi"; + }; + } + { + name = "synapse"; + image = + tf "data.external.nixng-image-synapse.result.out"; + ports = [ + { + name = "master-http"; + containerPort = 6167; + } + { + name = "replication"; + containerPort = 9093; + } + ]; + volumeMounts = [ + { + name = "synapse-data"; + mountPath = "/var/lib/synapse/"; + } + { + name = "synapse-registrations"; + mountPath = "/var/lib/registrations/"; + } + ]; + resources.limits = { + cpu = "1600m"; + memory = "3076Mi"; + }; + resources.requests = { + cpu = "800m"; + memory = "2048i"; + }; + } + { + name = "synapse-client"; + image = + tf "data.external.nixng-image-synapse-client.result.out"; + ports = [ + { + name = "client-http"; + containerPort = 6168; + } + ]; + volumeMounts = [ + { + name = "synapse-data"; + mountPath = "/var/lib/synapse/"; + } + { + name = "synapse-registrations"; + mountPath = "/var/lib/registrations/"; + } + ]; + resources.limits = { + cpu = "1600m"; + memory = "3076Mi"; + }; + resources.requests = { + cpu = "800m"; + memory = "2048i"; + }; + } + { + name = "synapse-sync"; + image = + tf "data.external.nixng-image-synapse-sync.result.out"; + ports = [ + { + name = "sync-http"; + containerPort = 6169; + } + ]; + volumeMounts = [ + { + name = "synapse-data"; + mountPath = "/var/lib/synapse/"; + } + { + name = "synapse-registrations"; + mountPath = "/var/lib/registrations/"; + } + ]; + resources.limits = { + cpu = "1600m"; + memory = "3076Mi"; + }; + resources.requests = { + cpu = "800m"; + memory = "2048i"; + }; + } + { + name = "synapse-federation-receiver"; + image = + tf "data.external.nixng-image-synapse-federation-receiver.result.out"; + ports = [ + { + name = "federation-receiver-http"; + containerPort = 6170; + } + ]; + volumeMounts = [ + { + name = "synapse-data"; + mountPath = "/var/lib/synapse/"; + } + { + name = "synapse-registrations"; + mountPath = "/var/lib/registrations/"; + } + ]; + resources.limits = { + cpu = "1600m"; + memory = "3076Mi"; + }; + resources.requests = { + cpu = "800m"; + memory = "2048i"; + }; + } + { + name = "synapse-federation-sender"; + image = + tf "data.external.nixng-image-synapse-federation-sender.result.out"; + ports = [ + { + name = "federation-sender-http"; + containerPort = 6171; + } + ]; + volumeMounts = [ + { + name = "synapse-data"; + mountPath = "/var/lib/synapse/"; + } + { + name = "synapse-registrations"; + mountPath = "/var/lib/registrations/"; + } + ]; + resources.limits = { + cpu = "1600m"; + memory = "3076Mi"; + }; + resources.requests = { + cpu = "800m"; + memory = "2048i"; + }; + } + ]; + volumes = [ + { + name = "synapse-redis"; + persistentVolumeClaim.claimName = "synapse-redis"; + } + { + name = "synapse-postgresql"; + persistentVolumeClaim.claimName = "synapse-postgresql"; + } + { + name = "synapse-data"; + persistentVolumeClaim.claimName = "synapse-data"; + } + { + name = "synapse-registrations"; + persistentVolumeClaim.claimName = "synapse-registrations"; + } + ]; + }; + }; + }; + }; + }; + + resource."kubernetes_manifest"."synapse-service" = { + manifest = { + apiVersion = "v1"; + kind = "Service"; + metadata = { + name = "synapse"; + namespace = "matrix"; + }; + spec = { + ports = [ + { + name = "master-http"; + port = 6167; + protocol = "TCP"; + targetPort = 6167; + } + { + name = "client-http"; + port = 6168; + protocol = "TCP"; + targetPort = 6168; + } + { + name = "sync-http"; + port = 6169; + protocol = "TCP"; + targetPort = 6169; + } + { + name = "federation-receiver-http"; + port = 6170; + protocol = "TCP"; + targetPort = 6170; + } + { + name = "federation-sender-http"; + port = 6171; + protocol = "TCP"; + targetPort = 6171; + } + ]; + selector.app = "synapse"; + }; + }; + }; + + resource."kubernetes_manifest"."synapse-httproute" = { + manifest = { + apiVersion = "gateway.networking.k8s.io/v1"; + kind = "HTTPRoute"; + metadata = { + name = "synapse"; + namespace = "ingress"; + }; + spec = { + parentRefs = [ + { + name = "website"; + sectionName = "http"; + } + ]; + hostnames = ["matrix.redalder.org"]; + rules = [ + # Client Worker + { + match = + lib.map (regex: { + path.value = regex; + path.type = "RegularExpression"; + }) [ + # Federation requests + "^/_matrix/federation/v1/event/" + "^/_matrix/federation/v1/state/" + "^/_matrix/federation/v1/state_ids/" + "^/_matrix/federation/v1/backfill/" + "^/_matrix/federation/v1/get_missing_events/" + "^/_matrix/federation/v1/publicRooms" + "^/_matrix/federation/v1/query/" + "^/_matrix/federation/v1/make_join/" + "^/_matrix/federation/v1/make_leave/" + "^/_matrix/federation/(v1|v2)/send_join/" + "^/_matrix/federation/(v1|v2)/send_leave/" + "^/_matrix/federation/(v1|v2)/invite/" + "^/_matrix/federation/v1/event_auth/" + "^/_matrix/federation/v1/exchange_third_party_invite/" + "^/_matrix/federation/v1/user/devices/" + "^/_matrix/key/v2/query" + "^/_matrix/federation/v1/hierarchy/" + + # Inbound federation transaction request + "^/_matrix/federation/v1/send/" + ]; + backendRefs = [ + { + name = "synapse"; + namespace = "matrix"; + port = 6170; + } + ]; + } + # Client Worker + { + match = + lib.map (regex: { + path.value = regex; + path.type = "RegularExpression"; + }) [ + # Client API requests + "^/_matrix/client/(api/v1|r0|v3|unstable)/createRoom$" + "^/_matrix/client/(api/v1|r0|v3|unstable)/publicRooms$" + "^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/joined_members$" + "^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/context/.*$" + "^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/members$" + "^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/state$" + "^/_matrix/client/v1/rooms/.*/hierarchy$" + "^/_matrix/client/(v1|unstable)/rooms/.*/relations/" + "^/_matrix/client/v1/rooms/.*/threads$" + "^/_matrix/client/unstable/im.nheko.summary/summary/.*$" + "^/_matrix/client/(r0|v3|unstable)/account/3pid$" + "^/_matrix/client/(r0|v3|unstable)/account/whoami$" + "^/_matrix/client/(r0|v3|unstable)/devices$" + "^/_matrix/client/versions$" + "^/_matrix/client/(api/v1|r0|v3|unstable)/voip/turnServer$" + "^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/event/" + "^/_matrix/client/(api/v1|r0|v3|unstable)/joined_rooms$" + "^/_matrix/client/v1/rooms/.*/timestamp_to_event$" + "^/_matrix/client/(api/v1|r0|v3|unstable/.*)/rooms/.*/aliases" + "^/_matrix/client/(api/v1|r0|v3|unstable)/search$" + "^/_matrix/client/(r0|v3|unstable)/user/.*/filter(/|$)" + "^/_matrix/client/(api/v1|r0|v3|unstable)/directory/room/.*$" + "^/_matrix/client/(r0|v3|unstable)/capabilities$" + "^/_matrix/client/(r0|v3|unstable)/notifications$" + + # Encryption requests + "^/_matrix/client/(r0|v3|unstable)/keys/query$" + "^/_matrix/client/(r0|v3|unstable)/keys/changes$" + "^/_matrix/client/(r0|v3|unstable)/keys/claim$" + "^/_matrix/client/(r0|v3|unstable)/room_keys/" + "^/_matrix/client/(r0|v3|unstable)/keys/upload/" + + # Registration/login requests + "^/_matrix/client/(api/v1|r0|v3|unstable)/login$" + "^/_matrix/client/(r0|v3|unstable)/register$" + "^/_matrix/client/(r0|v3|unstable)/register/available$" + "^/_matrix/client/v1/register/m.login.registration_token/validity$" + "^/_matrix/client/(r0|v3|unstable)/password_policy$" + + # Event sending requests + "^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/redact" + "^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/send" + "^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/state/" + "^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/(join|invite|leave|ban|unban|kick)$" + "^/_matrix/client/(api/v1|r0|v3|unstable)/join/" + "^/_matrix/client/(api/v1|r0|v3|unstable)/knock/" + "^/_matrix/client/(api/v1|r0|v3|unstable)/profile/" + + # Account data requests + "^/_matrix/client/(r0|v3|unstable)/.*/tags" + "^/_matrix/client/(r0|v3|unstable)/.*/account_data" + + # Receipts requests + "^/_matrix/client/(r0|v3|unstable)/rooms/.*/receipt" + "^/_matrix/client/(r0|v3|unstable)/rooms/.*/read_markers" + + # Presence requests + "^/_matrix/client/(api/v1|r0|v3|unstable)/presence/" + + # User directory search requests + "^/_matrix/client/(r0|v3|unstable)/user_directory/search$" + ]; + backendRefs = [ + { + name = "synapse"; + namespace = "matrix"; + port = 6168; + } + ]; + } + # Sync Worker + { + match = + lib.map (regex: { + path.value = regex; + path.type = "RegularExpression"; + }) [ + "^/_matrix/client/(r0|v3)/sync$" + "^/_matrix/client/(api/v1|r0|v3)/events$" + "^/_matrix/client/(api/v1|r0|v3)/initialSync$" + "^/_matrix/client/(api/v1|r0|v3)/rooms/[^/]+/initialSync$" + ]; + backendRefs = [ + { + name = "synapse"; + namespace = "matrix"; + port = 6169; + } + ]; + } + { + backendRefs = [ + { + name = "synapse"; + namespace = "matrix"; + port = 6167; + } + ]; + } + ]; + }; + }; + }; + + resource."kubernetes_manifest"."synapse_reference_grant" = { + manifest = { + apiVersion = "gateway.networking.k8s.io/v1alpha2"; + kind = "ReferenceGrant"; + metadata = { + name = "synapse"; + namespace = "matrix"; + }; + spec = { + from = [ + { + group = "gateway.networking.k8s.io"; + kind = "HTTPRoute"; + namespace = "ingress"; + } + ]; + to = [ + { + group = ""; + kind = "Service"; + name = "synapse"; + } + ]; + }; + }; + }; + + resource."kubernetes_manifest"."synapse_authorization_policy" = { + manifest = { + apiVersion = "security.istio.io/v1"; + kind = "AuthorizationPolicy"; + metadata = { + name = "synapse"; + namespace = "matrix"; + }; + spec = { + action = "ALLOW"; + selector.matchLabels.app = "synapse"; + rules = [ + { + from = [ + { + source.principals = ["cluster.local/ns/ingress/sa/website-istio"]; + } + ]; + to = [ + { + ports = ["master-http" "client-http" "sync-http" "federation-reciver-http"]; + } + ]; + } + { + from = [ + { + source.principals = [ + "cluster.local/ns/matrix/sa/mautrix-discord" + "cluster.local/ns/matrix/sa/heisenbridge" + "cluster.local/ns/matrix/sa/mautrix-signal" + "cluster.local/ns/matrix/sa/mautrix-slack" + "cluster.local/ns/matrix/sa/mautrix-facebook" + ]; + } + ]; + to = [ + { + ports = ["postgresql"]; + } + ]; + } + ]; + }; + }; + }; +} diff --git a/terranix/main/kubernetes/mautrix-discord.nix b/terranix/main/kubernetes/mautrix-discord.nix new file mode 100644 index 0000000..c94d767 --- /dev/null +++ b/terranix/main/kubernetes/mautrix-discord.nix @@ -0,0 +1,233 @@ +{ + elib, + inputs, + pkgs, + config, + uterranix-lib, + lib, + ... +}: let + inherit + (uterranix-lib) + tf + ; + inherit + (elib) + copyNixNGImage + ; +in { + imports = [ + (copyNixNGImage { + name = "mautrix-discord"; + image = + (inputs.nix-snapshotter.packages.${pkgs.stdenv.system}.nix-snapshotter.buildImage { + name = "mautrix-discord"; + resolvedByNix = true; + config.entrypoint = ["${inputs.self.nixngConfigurations.mautrixDiscord.config.system.build.toplevel}/init"]; + }) + .image; + hosts = [ + "blowhole.hosts.in.redalder.org" + ]; + }) + ]; + + resource."kubernetes_manifest"."mautrix-discord_persistent-volume" = { + manifest = { + apiVersion = "v1"; + kind = "PersistentVolume"; + metadata = { + name = "mautrix-discord"; + labels.type = "local"; + }; + spec = { + capacity.storage = "10Gi"; + claimRef = { + name = "mautrix-discord"; + namespace = "matrix"; + }; + volumeModule = "Filesystem"; + accessModes = [ + "ReadWriteOnce" + ]; + persistentVolumeReclaimPolicy = "Retain"; + storageClassName = "hostpath"; + hostPath.path = "/data/matrix/mautrix-discord"; + }; + }; + }; + + resource."kubernetes_manifest"."mautrix-discord_persistent-volume-claim" = { + manifest = { + kind = "PersistentVolumeClaim"; + apiVersion = "v1"; + metadata = { + name = "mautrix-discord"; + namespace = "matrix"; + }; + spec = { + volumeName = "mautrix-discord"; + storageClassName = "hostpath"; + accessModels = [ + "ReadWriteOnce" + ]; + resources.requests.storage = "10Gi"; + }; + }; + }; + + resource."kubernetes_manifest"."synapse-registrations_mautrix-discord_persistent-volume-claim" = { + manifest = { + kind = "PersistentVolumeClaim"; + apiVersion = "v1"; + metadata = { + name = "synapse-registrations_mautrix-discord"; + namespace = "matrix"; + }; + spec = { + volumeName = "synapse-registrations"; + storageClassName = "hostpath"; + accessModels = [ + "ReadWriteOnce" + ]; + resources.requests.storage = "1Gi"; + }; + }; + }; + + resource."kubernetes_manifest"."mautrix-discord-deployment" = { + manifest = { + apiVersion = "apps/v1"; + kind = "Deployment"; + metadata = { + name = "mautrix-discord"; + namespace = "matrix"; + labels = { + app = "mautrix-discord"; + }; + }; + spec = { + replicas = 1; + strategy.type = "Recreate"; + selector.matchLabels.app = "mautrix-discord"; + template = { + metadata.labels.app = "mautrix-discord"; + metadata.annotations = { + "vault.hashicorp.com/agent-inject" = true; + "vault.hashicorp.com/role" = "mautrix-discord"; + + "vault.hashicorp.com/agent-init-first" = true; + "vault.hashicorp.com/secret-volume-path" = "/secrets"; + + # "vault.hashicorp.com/agent-inject-secret-environment" = ""; ??? + "vault.hashicorp.com/agent-inject-template-environment" = '' + {{ with secret "kv/data/cluster/matrix/mautrix-discord/main" }} + MAUTRIX_DISCORD_APPSERVICE_AS_TOKEN={{ .Data.data.as_token }} + MAUTRIX_DISCORD_APPSERVICE_HS_TOKEN={{ .Data.data.hs_token }} + {{ end }} + {{ with secret "kv/data/cluster/matrix/mautrix-discord/postgresql" }} + MAUTRIX_DISCORD_APPSERVICE_DATABASE_PASSWORD={{ .Data.data.pgpass }} + {{ end }} + ''; + }; + }; + spec = { + containers = [ + { + name = "mautrix-discord"; + image = + tf "data.external.nixng-image-mautrix-discord.result.out"; + ports = [ + { + name = "app-service"; + containerPort = 29334; + } + ]; + volumeMounts = [ + { + name = "mautrix-discord"; + mountPath = "/var/lib/mautrix-discord/"; + } + { + name = "matrix-registrations"; + mountPath = "/var/lib/registrations/"; + } + ]; + resources.limits = { + cpu = "400m"; + memory = "256Mi"; + }; + resources.requests = { + cpu = "200m"; + memory = "128Mi"; + }; + } + ]; + volumes = [ + { + name = "synapse-registrations"; + persistentVolumeClaim.claimName = "synapse-registrations"; + } + { + name = "mautrix-discord"; + persistentVolumeClaim.claimName = "mautrix-discord"; + } + ]; + }; + }; + }; + }; + + resource."kubernetes_manifest"."mautrix-discord-service" = { + manifest = { + apiVersion = "v1"; + kind = "Service"; + metadata = { + name = "mautrix-discord"; + namespace = "matrix"; + }; + spec = { + ports = [ + { + name = "app-service"; + port = 29334; + protocol = "TCP"; + targetPort = 29334; + } + ]; + selector.app = "mautrix-discord"; + }; + }; + }; + + resource."kubernetes_manifest"."mautrix-discord_authorization_policy" = { + manifest = { + apiVersion = "security.istio.io/v1"; + kind = "AuthorizationPolicy"; + metadata = { + name = "mautrix-discord"; + namespace = "matrix"; + }; + spec = { + action = "ALLOW"; + selector.matchLabels.app = "mautrix-discord"; + rules = [ + { + from = [ + { + source = { + principals = ["cluster.local/ns/matrix/sa/synapse"]; + }; + } + ]; + to = [ + { + ports = ["app-service"]; + } + ]; + } + ]; + }; + }; + }; +}