blob: 5e07c4b934f6f8eb06d115bad22338270fe70b14 [file] [log] [blame]
Skyler Greya78aa672023-05-20 13:48:18 +02001{ lib, config, pkgs, ... }: {
Skyler Grey915067d2023-12-03 13:46:53 +00002 systemd.services.postgresql.after = [
3 "docker-network-taiga.service" # Needed to listen in 172.20.0.1
4 ];
5
Skyler Greya78aa672023-05-20 13:48:18 +02006 services.postgresql = {
7 enable = true;
8
9 package = pkgs.postgresql;
10 settings = {
Samuel Shuert45489982023-11-29 15:29:36 -050011 listen_addresses = lib.mkForce "standard, 172.20.0.1";
Skyler Greya78aa672023-05-20 13:48:18 +020012 log_connections = true;
Skyler Greya78aa672023-05-20 13:48:18 +020013 logging_collector = true;
14 log_disconnections = true;
15 log_destination = lib.mkForce "syslog";
16 };
17
Skyler Greyf1c352b2024-04-19 00:07:44 +000018 ensureDatabases = [
19 "vaultwarden"
20 "gerrit"
21 "privatebin"
22 "keycloak"
23 "nextcloud"
24 "synapse"
25 "taiga"
26 "jinx"
27 "wiki"
28 ];
TheCodedProfb6184602023-06-13 17:04:59 -040029
Skyler Greya78aa672023-05-20 13:48:18 +020030 ensureUsers = [
31 {
32 name = "clicks_grafana";
Skyler Greya78aa672023-05-20 13:48:18 +020033 }
34 {
Skyler Grey22428b02023-11-19 13:20:56 +000035 name = "matrix-synapse";
Skyler Greya78aa672023-05-20 13:48:18 +020036 }
TheCodedProfb6184602023-06-13 17:04:59 -040037 {
Skyler Grey0e05d262023-10-09 07:04:36 +000038 name = "keycloak";
Skyler Grey915067d2023-12-03 13:46:53 +000039 ensureDBOwnership = true;
Skyler Grey0e05d262023-10-09 07:04:36 +000040 }
41 {
TheCodedProfb6184602023-06-13 17:04:59 -040042 name = "vaultwarden";
Skyler Grey915067d2023-12-03 13:46:53 +000043 ensureDBOwnership = true;
TheCodedProfb6184602023-06-13 17:04:59 -040044 }
Skyler Grey9fe61282023-08-20 21:52:48 +000045 {
46 name = "privatebin";
Skyler Grey915067d2023-12-03 13:46:53 +000047 ensureDBOwnership = true;
Skyler Grey9fe61282023-08-20 21:52:48 +000048 }
Skyler Grey09c5cda2023-10-09 07:10:10 +000049 {
50 name = "nextcloud";
Skyler Grey915067d2023-12-03 13:46:53 +000051 ensureDBOwnership = true;
Skyler Grey09c5cda2023-10-09 07:10:10 +000052 }
Samuel Shuert45489982023-11-29 15:29:36 -050053 {
54 name = "taiga";
Skyler Grey915067d2023-12-03 13:46:53 +000055 ensureDBOwnership = true;
Samuel Shuert45489982023-11-29 15:29:36 -050056 }
Skyler Grey8b4f7b62024-02-17 12:23:02 +000057 {
58 name = "taiga";
59 ensureDBOwnership = true;
60 }
61 {
62 name = "jinx";
63 ensureDBOwnership = true;
64 }
Skyler Greyf1c352b2024-04-19 00:07:44 +000065 {
66 name = "wiki";
67 ensureDBOwnership = true;
68 }
Skyler Greyfe1740c2023-10-21 01:24:18 +000069 ] ++ (map (name: ({
70 inherit name;
Skyler Greya7b38dd2023-10-25 21:42:45 +000071 })) [ "minion" "coded" "pineafan" ]);
Skyler Greya78aa672023-05-20 13:48:18 +020072
Samuel Shuert45489982023-11-29 15:29:36 -050073 # method database user address auth-method
74 authentication = "host all all samenet scram-sha-256";
Skyler Greya78aa672023-05-20 13:48:18 +020075 };
76
Skyler Grey8b4f7b62024-02-17 12:23:02 +000077 systemd.services.postgresql.restartTriggers = [
78 config.systemd.services.postgresql.postStart
79 ];
Skyler Grey8e32c832023-05-20 22:54:30 +020080 systemd.services.postgresql.postStart = lib.mkMerge [
Skyler Greyfe1740c2023-10-21 01:24:18 +000081 (let
82 database = "synapse";
83 cfg = config.services.postgresql;
84 in lib.mkBefore (''
85 PSQL="psql --port=${toString cfg.port}"
Skyler Grey8e32c832023-05-20 22:54:30 +020086
Skyler Greyfe1740c2023-10-21 01:24:18 +000087 while ! $PSQL -d postgres -c "" 2> /dev/null; do
88 if ! kill -0 "$MAINPID"; then exit 1; fi
89 sleep 0.1
90 done
Skyler Grey8e32c832023-05-20 22:54:30 +020091
Skyler Greyfe1740c2023-10-21 01:24:18 +000092 $PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = '${database}'" | grep -q 1 || $PSQL -tAc 'CREATE DATABASE "${database}" WITH LC_CTYPE="C" LC_COLLATE="C" TEMPLATE="template0"'
93 '') # synapse needs C collation, so we can't use ensureDatabases for it
Skyler Grey8e32c832023-05-20 22:54:30 +020094 )
95 (lib.mkAfter (lib.pipe [
Skyler Greyfe1740c2023-10-21 01:24:18 +000096 {
97 user = "clicks_grafana";
98 passwordFile = config.sops.secrets.clicks_grafana_db_password.path;
99 }
100 {
101 user = "keycloak";
102 passwordFile = config.sops.secrets.clicks_keycloak_db_password.path;
103 }
104 {
Skyler Greyfe1740c2023-10-21 01:24:18 +0000105 user = "vaultwarden";
Skyler Grey22428b02023-11-19 13:20:56 +0000106 passwordFile = config.sops.secrets.clicks_vaultwarden_db_password.path;
Skyler Greyfe1740c2023-10-21 01:24:18 +0000107 }
108 {
109 user = "privatebin";
110 passwordFile = config.sops.secrets.clicks_privatebin_db_password.path;
111 }
112 {
113 user = "nextcloud";
114 passwordFile = config.sops.secrets.clicks_nextcloud_db_password.path;
115 }
Samuel Shuert45489982023-11-29 15:29:36 -0500116 {
117 user = "taiga";
118 passwordFile = config.sops.secrets.clicks_taiga_db_password.path;
119 }
Skyler Grey8b4f7b62024-02-17 12:23:02 +0000120 {
121 user = "jinx";
122 passwordFile = config.sops.secrets.clicks_jinx_db_password.path;
123 }
Skyler Greyf1c352b2024-04-19 00:07:44 +0000124 {
125 user = "wiki";
126 passwordFile = config.sops.secrets.clicks_wiki_db_password.path;
127 }
Skyler Grey8e32c832023-05-20 22:54:30 +0200128 ] [
129 (map (userData: ''
130 $PSQL -tAc "ALTER USER ${userData.user} PASSWORD '$(cat ${userData.passwordFile})';"
131 ''))
132 (lib.concatStringsSep "\n")
133 ]))
Skyler Grey915067d2023-12-03 13:46:53 +0000134 ''
135 $PSQL -tAc 'ALTER DATABASE synapse OWNER TO "matrix-synapse";'
136 # matrix-synapse is done manually, because the database does not have the same name as the user
137
138 $PSQL -tAc 'GRANT SELECT ON ALL TABLES IN SCHEMA public TO "clicks_grafana"'
139 $PSQL -tAc 'GRANT USAGE ON SCHEMA public TO "clicks_grafana"'
140 # grafana is done manually, because it needs read permission in lots of places
141
142 $PSQL -tAc 'GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "coded"'
143 $PSQL -tAc 'GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "minion"'
144 $PSQL -tAc 'GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "pineafan"'
145 # leadership is done manually, because we need owner-level permissions in lots of places but cannot specify ourselves as the database owners (as there may only be 1)
146 ''
Skyler Grey8e32c832023-05-20 22:54:30 +0200147 ];
Skyler Greya78aa672023-05-20 13:48:18 +0200148
149 sops.secrets = lib.pipe [
150 "clicks_grafana_db_password"
Skyler Grey0e05d262023-10-09 07:04:36 +0000151 "clicks_keycloak_db_password"
Skyler Grey22428b02023-11-19 13:20:56 +0000152 "clicks_vaultwarden_db_password"
Skyler Grey9fe61282023-08-20 21:52:48 +0000153 "clicks_privatebin_db_password"
Skyler Grey09c5cda2023-10-09 07:10:10 +0000154 "clicks_nextcloud_db_password"
Samuel Shuert45489982023-11-29 15:29:36 -0500155 "clicks_taiga_db_password"
Skyler Grey8b4f7b62024-02-17 12:23:02 +0000156 "clicks_jinx_db_password"
Skyler Greyf1c352b2024-04-19 00:07:44 +0000157 "clicks_wiki_db_password"
Skyler Greya78aa672023-05-20 13:48:18 +0200158 ] [
159 (map (name: {
160 inherit name;
161 value = {
162 mode = "0400";
163 owner = config.services.postgresql.superUser;
Skyler Greyfe1740c2023-10-21 01:24:18 +0000164 group =
165 config.users.users.${config.services.postgresql.superUser}.group;
Samuel Shuertf68685d2023-10-28 20:07:56 -0400166 sopsFile = ../../secrets/postgres.json;
Skyler Greya78aa672023-05-20 13:48:18 +0200167 format = "json";
168 };
169 }))
170 builtins.listToAttrs
171 ];
172}