Many changes
This commit is contained in:
parent
9edae4a39c
commit
df53c13bb7
|
@ -102,7 +102,7 @@ in {
|
||||||
EmailSettings = {
|
EmailSettings = {
|
||||||
RequireEmailVerification = true;
|
RequireEmailVerification = true;
|
||||||
SMTPServer = cfg.smtp.server;
|
SMTPServer = cfg.smtp.server;
|
||||||
SMTPPort = 587;
|
SMTPPort = "587";
|
||||||
EnableSMTPAuth = true;
|
EnableSMTPAuth = true;
|
||||||
SMTPUsername = cfg.smtp.user;
|
SMTPUsername = cfg.smtp.user;
|
||||||
SMTPPassword = "__SMTP_PASSWD__";
|
SMTPPassword = "__SMTP_PASSWD__";
|
||||||
|
@ -113,22 +113,20 @@ in {
|
||||||
};
|
};
|
||||||
EnableEmailInvitations = true;
|
EnableEmailInvitations = true;
|
||||||
SqlSettings.DriverName = "postgres";
|
SqlSettings.DriverName = "postgres";
|
||||||
SqlSettings.DataSource = "postgres://${
|
SqlSettings.DataSource =
|
||||||
cfg.database.user
|
"postgres://${cfg.database.user}:__DATABASE_PASSWORD__@${cfg.database.hostname}:5432/${cfg.database.name}";
|
||||||
}:__DATABASE_PASSWORD__@${
|
|
||||||
cfg.database.hostname
|
|
||||||
}:5432/${
|
|
||||||
cfg.database.name
|
|
||||||
}";
|
|
||||||
};
|
};
|
||||||
mattermost-config-file-template =
|
mattermost-config-file-template =
|
||||||
pkgs.writeText "mattermost-config.json.template" (builtins.toJSON modified-config);
|
pkgs.writeText "mattermost-config.json.template"
|
||||||
|
(builtins.toJSON modified-config);
|
||||||
|
|
||||||
generate-mattermost-config = target: template: smtp-passwd-file: db-passwd-file:
|
generate-mattermost-config =
|
||||||
|
target: template: smtp-passwd-file: db-passwd-file:
|
||||||
pkgs.writeScript "mattermost-config-generator.sh" ''
|
pkgs.writeScript "mattermost-config-generator.sh" ''
|
||||||
|
rm ${target}
|
||||||
SMTP_PASSWD=$( cat ${smtp-passwd-file} )
|
SMTP_PASSWD=$( cat ${smtp-passwd-file} )
|
||||||
DATABASE_PASSWORD=$( cat ${db-passwd-file} )
|
DATABASE_PASSWORD=$( cat ${db-passwd-file} )
|
||||||
sed -e 's/__SMTP_PASSWD__/"$SMTP_PASSWD"/' -e 's/__DATABASE_PASSWORD__/"$DATABASE_PASSWORD"/' ${template} > ${target}
|
sed -e "s/__SMTP_PASSWD__/$SMTP_PASSWD/" -e "s/__DATABASE_PASSWORD__/$DATABASE_PASSWORD/" ${template} > ${target}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
@ -136,10 +134,10 @@ in {
|
||||||
users = {
|
users = {
|
||||||
${cfg.user} = {
|
${cfg.user} = {
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
group = mattermost-group;
|
group = cfg.group;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
groups.${cfg.group}.members = [ cfg.user ];
|
groups = { ${cfg.group} = { members = [ cfg.user ]; }; };
|
||||||
};
|
};
|
||||||
|
|
||||||
fudo.system.services.mattermost = {
|
fudo.system.services.mattermost = {
|
||||||
|
@ -147,17 +145,25 @@ in {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "network.target" ];
|
after = [ "network.target" ];
|
||||||
|
|
||||||
preStart = ''
|
preStart =
|
||||||
${generate-mattermost-config
|
let config-target = "${cfg.state-directory}/config/config.json";
|
||||||
mattermost-config-target
|
in ''
|
||||||
mattermost-config-file-template
|
if [ ! -f ${config-target} ]; then
|
||||||
cfg.smtp.password-file
|
${
|
||||||
cfg.database.password-file}
|
generate-mattermost-config mattermost-config-target
|
||||||
cp ${cfg.smtp.password-file} ${cfg.state-directory}/config/config.json
|
mattermost-config-file-template cfg.smtp.password-file
|
||||||
cp -uRL ${pkg}/client ${cfg.state-directory}
|
cfg.database.password-file
|
||||||
chown ${cfg.user}:${cfg.group} ${cfg.state-directory}/client
|
}
|
||||||
chmod 0750 ${cfg.state-directory}/client
|
cp ${mattermost-config-target} ${config-target}
|
||||||
'';
|
chown ${cfg.user}:${cfg.group} ${config-target}
|
||||||
|
chmod 640 ${config-target}
|
||||||
|
fi
|
||||||
|
if [ ! -e ${cfg.state-directory} ]; then
|
||||||
|
cp -uRL ${pkg}/client ${cfg.state-directory}
|
||||||
|
chown ${cfg.user}:${cfg.group} ${cfg.state-directory}/client
|
||||||
|
chmod 0750 ${cfg.state-directory}/client
|
||||||
|
fi
|
||||||
|
'';
|
||||||
execStart = "${pkg}/bin/mattermost";
|
execStart = "${pkg}/bin/mattermost";
|
||||||
workingDirectory = cfg.state-directory;
|
workingDirectory = cfg.state-directory;
|
||||||
user = cfg.user;
|
user = cfg.user;
|
||||||
|
@ -167,8 +173,9 @@ in {
|
||||||
systemd = {
|
systemd = {
|
||||||
|
|
||||||
tmpfiles.rules = [
|
tmpfiles.rules = [
|
||||||
"d ${cfg.state-directory} 0750 ${cfg.user} ${cfg.group} - -"
|
"d ${cfg.state-directory} 0750 ${cfg.user} - - -"
|
||||||
"d ${cfg.state-directory}/config 0750 ${cfg.user} ${cfg.group} - -"
|
"d ${cfg.state-directory}/config 0750 ${cfg.user} - - -"
|
||||||
|
"d ${dirOf mattermost-config-target} 0750 ${cfg.user} - - -"
|
||||||
"L ${cfg.state-directory}/bin - - - - ${pkg}/bin"
|
"L ${cfg.state-directory}/bin - - - - ${pkg}/bin"
|
||||||
"L ${cfg.state-directory}/fonts - - - - ${pkg}/fonts"
|
"L ${cfg.state-directory}/fonts - - - - ${pkg}/fonts"
|
||||||
"L ${cfg.state-directory}/i18n - - - - ${pkg}/i18n"
|
"L ${cfg.state-directory}/i18n - - - - ${pkg}/i18n"
|
||||||
|
@ -183,6 +190,8 @@ in {
|
||||||
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;
|
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
recommendedProxySettings = true;
|
||||||
|
|
||||||
virtualHosts = {
|
virtualHosts = {
|
||||||
"${cfg.hostname}" = {
|
"${cfg.hostname}" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
|
@ -190,51 +199,52 @@ in {
|
||||||
|
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
proxyPass = "http://127.0.0.1:8065";
|
proxyPass = "http://127.0.0.1:8065";
|
||||||
|
proxyWebsockets = true;
|
||||||
|
|
||||||
extraConfig = ''
|
# extraConfig = ''
|
||||||
client_max_body_size 50M;
|
# client_max_body_size 50M;
|
||||||
proxy_set_header Connection "";
|
# proxy_set_header Connection "";
|
||||||
proxy_set_header Host $host;
|
# proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
# proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-By $server_addr:$server_port;
|
# proxy_set_header X-Forwarded-By $server_addr:$server_port;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
# proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_set_header X-Frame-Options SAMEORIGIN;
|
# proxy_set_header X-Frame-Options SAMEORIGIN;
|
||||||
proxy_buffers 256 16k;
|
# proxy_buffers 256 16k;
|
||||||
proxy_buffer_size 16k;
|
# proxy_buffer_size 16k;
|
||||||
proxy_read_timeout 600s;
|
# proxy_read_timeout 600s;
|
||||||
proxy_cache mattermost_cache;
|
# proxy_cache mattermost_cache;
|
||||||
proxy_cache_revalidate on;
|
# proxy_cache_revalidate on;
|
||||||
proxy_cache_min_uses 2;
|
# proxy_cache_min_uses 2;
|
||||||
proxy_cache_use_stale timeout;
|
# proxy_cache_use_stale timeout;
|
||||||
proxy_cache_lock on;
|
# proxy_cache_lock on;
|
||||||
proxy_http_version 1.1;
|
# proxy_http_version 1.1;
|
||||||
'';
|
# '';
|
||||||
};
|
};
|
||||||
|
|
||||||
locations."~ /api/v[0-9]+/(users/)?websocket$" = {
|
# locations."~ /api/v[0-9]+/(users/)?websocket$" = {
|
||||||
proxyPass = "http://127.0.0.1:8065";
|
# proxyPass = "http://127.0.0.1:8065";
|
||||||
|
|
||||||
extraConfig = ''
|
# extraConfig = ''
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
# proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
# proxy_set_header Connection "upgrade";
|
||||||
client_max_body_size 50M;
|
# client_max_body_size 50M;
|
||||||
proxy_set_header Host $host;
|
# proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
# proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-By $server_addr:$server_port;
|
# proxy_set_header X-Forwarded-By $server_addr:$server_port;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
# proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_set_header X-Frame-Options SAMEORIGIN;
|
# proxy_set_header X-Frame-Options SAMEORIGIN;
|
||||||
proxy_buffers 256 16k;
|
# proxy_buffers 256 16k;
|
||||||
proxy_buffer_size 16k;
|
# proxy_buffer_size 16k;
|
||||||
client_body_timeout 60;
|
# client_body_timeout 60;
|
||||||
send_timeout 300;
|
# send_timeout 300;
|
||||||
lingering_timeout 5;
|
# lingering_timeout 5;
|
||||||
proxy_connect_timeout 90;
|
# proxy_connect_timeout 90;
|
||||||
proxy_send_timeout 300;
|
# proxy_send_timeout 300;
|
||||||
proxy_read_timeout 90s;
|
# proxy_read_timeout 90s;
|
||||||
'';
|
# '';
|
||||||
};
|
# };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,171 +5,185 @@ let
|
||||||
hostname = config.instance.hostname;
|
hostname = config.instance.hostname;
|
||||||
domain = config.instance.local-domain;
|
domain = config.instance.local-domain;
|
||||||
|
|
||||||
domainOpts = { name, ... }: let
|
domainOpts = { name, ... }:
|
||||||
domain = name;
|
let domain = name;
|
||||||
in {
|
in {
|
||||||
options = with types; {
|
options = with types; {
|
||||||
domain = mkOption {
|
domain = mkOption {
|
||||||
type = str;
|
|
||||||
description = "Domain name.";
|
|
||||||
default = domain;
|
|
||||||
};
|
|
||||||
|
|
||||||
local-networks = mkOption {
|
|
||||||
type = listOf str;
|
|
||||||
description =
|
|
||||||
"A list of networks to be considered trusted on this network.";
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
|
|
||||||
local-users = mkOption {
|
|
||||||
type = listOf str;
|
|
||||||
description =
|
|
||||||
"A list of users who should have local (i.e. login) access to _all_ hosts in this domain.";
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
|
|
||||||
local-admins = mkOption {
|
|
||||||
type = listOf str;
|
|
||||||
description =
|
|
||||||
"A list of users who should have admin access to _all_ hosts in this domain.";
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
|
|
||||||
local-groups = mkOption {
|
|
||||||
type = listOf str;
|
|
||||||
description = "List of groups which should exist within this domain.";
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
|
|
||||||
admin-email = mkOption {
|
|
||||||
type = str;
|
|
||||||
description = "Email for the administrator of this domain.";
|
|
||||||
default = "admin@${domain}";
|
|
||||||
};
|
|
||||||
|
|
||||||
grafana-hosts = mkOption {
|
|
||||||
type = listOf str;
|
|
||||||
description = "List of hosts acting as Grafana metric analyzers. Requires prometheus hosts as well.";
|
|
||||||
default = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
log-aggregator = mkOption {
|
|
||||||
type = nullOr str;
|
|
||||||
description = "Host which will accept incoming log pushes.";
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
postgresql-server = mkOption {
|
|
||||||
type = nullOr str;
|
|
||||||
description = "Hostname acting as the local PostgreSQL server.";
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
backplane = mkOption {
|
|
||||||
type = nullOr (submodule {
|
|
||||||
options = {
|
|
||||||
nameserver = mkOption {
|
|
||||||
type = nullOr str;
|
|
||||||
description = "Host acting as backplane dynamic DNS server.";
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
dns-service = mkOption {
|
|
||||||
type = nullOr str;
|
|
||||||
description = "DNS backplane service host.";
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
domain = mkOption {
|
|
||||||
type = str;
|
|
||||||
description = "Domain name of the dynamic zone served by this server.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
description = "Backplane configuration.";
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
wireguard = {
|
|
||||||
gateway = mkOption {
|
|
||||||
type = str;
|
type = str;
|
||||||
description = "Host serving as WireGuard gateway for this domain.";
|
description = "Domain name.";
|
||||||
|
default = domain;
|
||||||
};
|
};
|
||||||
|
|
||||||
network = mkOption {
|
local-networks = mkOption {
|
||||||
type = str;
|
type = listOf str;
|
||||||
description = "IP subnet used for WireGuard clients.";
|
description =
|
||||||
default = "172.16.0.0/16";
|
"A list of networks to be considered trusted on this network.";
|
||||||
|
default = [ ];
|
||||||
};
|
};
|
||||||
|
|
||||||
routed-network = mkOption {
|
local-users = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
description =
|
||||||
|
"A list of users who should have local (i.e. login) access to _all_ hosts in this domain.";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
local-admins = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
description =
|
||||||
|
"A list of users who should have admin access to _all_ hosts in this domain.";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
local-groups = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
description = "List of groups which should exist within this domain.";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
admin-email = mkOption {
|
||||||
|
type = str;
|
||||||
|
description = "Email for the administrator of this domain.";
|
||||||
|
default = "admin@${domain}";
|
||||||
|
};
|
||||||
|
|
||||||
|
grafana-hosts = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
description =
|
||||||
|
"List of hosts acting as Grafana metric analyzers. Requires prometheus hosts as well.";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
log-aggregator = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
description = "Subnet of larger network for which we NAT traffic.";
|
description = "Host which will accept incoming log pushes.";
|
||||||
default = "172.16.16.0/20";
|
default = null;
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
gssapi-realm = mkOption {
|
postgresql-server = mkOption {
|
||||||
type = str;
|
type = nullOr str;
|
||||||
description = "GSSAPI (i.e. Kerberos) realm of this domain.";
|
description = "Hostname acting as the local PostgreSQL server.";
|
||||||
};
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
kerberos-master = mkOption {
|
chat-server = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
description = "Hostname of the Kerberos master server for the domain, if applicable.";
|
description =
|
||||||
default = null;
|
"Hostname acting as the domain chat server (using Mattermost).";
|
||||||
};
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
kerberos-slaves = mkOption {
|
backplane = mkOption {
|
||||||
type = listOf str;
|
type = nullOr (submodule {
|
||||||
description = "List of hosts acting as Kerberos slaves for the domain.";
|
options = {
|
||||||
default = [];
|
nameserver = mkOption {
|
||||||
};
|
type = nullOr str;
|
||||||
|
description = "Host acting as backplane dynamic DNS server.";
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
ldap-servers = mkOption {
|
dns-service = mkOption {
|
||||||
type = listOf str;
|
type = nullOr str;
|
||||||
description = "List of hosts acting as LDAP authentication servers for the domain.";
|
description = "DNS backplane service host.";
|
||||||
default = [];
|
default = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
prometheus-hosts = mkOption {
|
domain = mkOption {
|
||||||
type = listOf str;
|
type = str;
|
||||||
description = "List of hosts acting aas prometheus metric scrapers for hosts in this network.";
|
description =
|
||||||
default = [];
|
"Domain name of the dynamic zone served by this server.";
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
description = "Backplane configuration.";
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
primary-nameserver = mkOption {
|
wireguard = {
|
||||||
type = nullOr str;
|
gateway = mkOption {
|
||||||
description = "Hostname of the primary nameserver for this domain.";
|
type = str;
|
||||||
default = null;
|
description = "Host serving as WireGuard gateway for this domain.";
|
||||||
};
|
};
|
||||||
|
|
||||||
secondary-nameservers = mkOption {
|
network = mkOption {
|
||||||
type = listOf str;
|
type = str;
|
||||||
description = "List of hostnames of slave nameservers for this domain.";
|
description = "IP subnet used for WireGuard clients.";
|
||||||
default = [];
|
default = "172.16.0.0/16";
|
||||||
};
|
};
|
||||||
|
|
||||||
primary-mailserver = mkOption {
|
routed-network = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
description = "Hostname of the primary mail server for this domain.";
|
description = "Subnet of larger network for which we NAT traffic.";
|
||||||
default = null;
|
default = "172.16.16.0/20";
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
xmpp-servers = mkOption {
|
gssapi-realm = mkOption {
|
||||||
type = listOf str;
|
type = str;
|
||||||
description = "Hostnames of the domain XMPP servers.";
|
description = "GSSAPI (i.e. Kerberos) realm of this domain.";
|
||||||
default = [];
|
};
|
||||||
};
|
|
||||||
|
|
||||||
zone = mkOption {
|
kerberos-master = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
description = "Name of the DNS zone associated with domain.";
|
description =
|
||||||
default = null;
|
"Hostname of the Kerberos master server for the domain, if applicable.";
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
kerberos-slaves = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
description =
|
||||||
|
"List of hosts acting as Kerberos slaves for the domain.";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
ldap-servers = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
description =
|
||||||
|
"List of hosts acting as LDAP authentication servers for the domain.";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
prometheus-hosts = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
description =
|
||||||
|
"List of hosts acting aas prometheus metric scrapers for hosts in this network.";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
primary-nameserver = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
description = "Hostname of the primary nameserver for this domain.";
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
secondary-nameservers = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
description =
|
||||||
|
"List of hostnames of slave nameservers for this domain.";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
primary-mailserver = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
description = "Hostname of the primary mail server for this domain.";
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
xmpp-servers = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
description = "Hostnames of the domain XMPP servers.";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
zone = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
description = "Name of the DNS zone associated with domain.";
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
in {
|
in {
|
||||||
options.fudo.domains = mkOption {
|
options.fudo.domains = mkOption {
|
||||||
|
|
|
@ -64,6 +64,13 @@ let
|
||||||
"A list of users who should have full access to this database.";
|
"A list of users who should have full access to this database.";
|
||||||
default = [ ];
|
default = [ ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extensions = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
description =
|
||||||
|
"A list of extensions which should be created for this database.";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -121,6 +128,13 @@ let
|
||||||
${network-entries user db}
|
${network-entries user db}
|
||||||
'') (attrNames opts.databases))) (filterPasswordedUsers users));
|
'') (attrNames opts.databases))) (filterPasswordedUsers users));
|
||||||
|
|
||||||
|
enableExtensionSql = ext: ''CREATE EXTENSION IF NOT EXISTS "${ext}";'';
|
||||||
|
|
||||||
|
enableDatabaseExtensionsSql = database: databaseOpts: ''
|
||||||
|
\c ${database}
|
||||||
|
${join-lines (map enableExtensionSql databaseOpts.extensions)}
|
||||||
|
'';
|
||||||
|
|
||||||
userTableAccessSql = user: entity: access:
|
userTableAccessSql = user: entity: access:
|
||||||
"GRANT ${access} ON ${entity} TO ${user};";
|
"GRANT ${access} ON ${entity} TO ${user};";
|
||||||
userDatabaseAccessSql = user: database: dbOpts: ''
|
userDatabaseAccessSql = user: database: dbOpts: ''
|
||||||
|
@ -382,8 +396,12 @@ in {
|
||||||
allow-user-login = user: "ALTER ROLE ${user} WITH LOGIN;";
|
allow-user-login = user: "ALTER ROLE ${user} WITH LOGIN;";
|
||||||
|
|
||||||
extra-settings-sql = pkgs.writeText "settings.sql" ''
|
extra-settings-sql = pkgs.writeText "settings.sql" ''
|
||||||
|
${join-lines
|
||||||
|
(mapAttrsToList enableDatabaseExtensionsSql cfg.databases)}
|
||||||
|
|
||||||
${concatStringsSep "\n" (map allow-user-login
|
${concatStringsSep "\n" (map allow-user-login
|
||||||
(mapAttrsToList (key: val: key) cfg.users))}
|
(mapAttrsToList (key: val: key) cfg.users))}
|
||||||
|
|
||||||
${usersAccessSql cfg.users}
|
${usersAccessSql cfg.users}
|
||||||
'';
|
'';
|
||||||
in pkgs.writeShellScript "postgresql-finalizer.sh" ''
|
in pkgs.writeShellScript "postgresql-finalizer.sh" ''
|
||||||
|
|
|
@ -2,13 +2,14 @@
|
||||||
|
|
||||||
with pkgs.lib;
|
with pkgs.lib;
|
||||||
let
|
let
|
||||||
generate-mac-address = hostname: interface: pkgs.stdenv.mkDerivation {
|
generate-mac-address = hostname: interface:
|
||||||
name = "mk-mac-${hostname}-${interface}";
|
pkgs.stdenv.mkDerivation {
|
||||||
phases = [ "installPhase" ];
|
name = "mk-mac-${hostname}-${interface}";
|
||||||
installPhase = ''
|
phases = [ "installPhase" ];
|
||||||
echo ${hostname}-${interface} | sha1sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/' > $out
|
installPhase = ''
|
||||||
'';
|
echo ${hostname}-${interface} | sha1sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/' > $out
|
||||||
};
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
# dropUntil = pred: lst: let
|
# dropUntil = pred: lst: let
|
||||||
# drop-until-helper = pred: lst:
|
# drop-until-helper = pred: lst:
|
||||||
|
@ -28,32 +29,40 @@ let
|
||||||
# (lib.reverseList lines-front-stripped));
|
# (lib.reverseList lines-front-stripped));
|
||||||
# in concatStringsSep "\n" lines-rear-stripped;
|
# in concatStringsSep "\n" lines-rear-stripped;
|
||||||
|
|
||||||
host-ipv4 = config: hostname: let
|
host-ipv4 = config: hostname:
|
||||||
domain = config.fudo.hosts.${hostname}.domain;
|
let
|
||||||
host-network = config.fudo.zones.${domain};
|
domain = config.fudo.hosts.${hostname}.domain;
|
||||||
in host-network.hosts.${hostname}.ipv4-address;
|
host-network = config.fudo.zones.${domain};
|
||||||
|
in host-network.hosts.${hostname}.ipv4-address;
|
||||||
|
|
||||||
host-ipv6 = config: hostname: let
|
host-ipv6 = config: hostname:
|
||||||
domain = config.fudo.hosts.${hostname}.domain;
|
let
|
||||||
host-network = config.fudo.zones.${domain};
|
domain = config.fudo.hosts.${hostname}.domain;
|
||||||
in host-network.hosts.${hostname}.ipv6-address;
|
host-network = config.fudo.zones.${domain};
|
||||||
|
in host-network.hosts.${hostname}.ipv6-address;
|
||||||
|
|
||||||
host-ips = config: hostname: let
|
host-ips = config: hostname:
|
||||||
ipv4 = host-ipv4 config hostname;
|
let
|
||||||
ipv6 = host-ipv6 config hostname;
|
ipv4 = host-ipv4 config hostname;
|
||||||
not-null = o: o != null;
|
ipv6 = host-ipv6 config hostname;
|
||||||
in filter not-null [ ipv4 ipv6 ];
|
not-null = o: o != null;
|
||||||
|
in filter not-null [ ipv4 ipv6 ];
|
||||||
|
|
||||||
site-gateway = config: site-name: let
|
site-gateway = config: site-name:
|
||||||
site = config.fudo.sites.${site-name};
|
let site = config.fudo.sites.${site-name};
|
||||||
in if (site.local-gateway != null)
|
in if (site.local-gateway != null) then
|
||||||
then host-ipv4 config site.local-gateway
|
host-ipv4 config site.local-gateway
|
||||||
else site.gateway-v4;
|
else
|
||||||
|
site.gateway-v4;
|
||||||
|
|
||||||
|
host-fqdn = config: hostname:
|
||||||
|
let domain-name = config.fudo.hosts.${hostname}.domain;
|
||||||
|
in "${hostname}.${domain-name}";
|
||||||
|
|
||||||
in {
|
in {
|
||||||
inherit host-ipv4 host-ipv6 host-ips site-gateway;
|
inherit host-ipv4 host-ipv6 host-ips site-gateway host-fqdn;
|
||||||
|
|
||||||
generate-mac-address = hostname: interface: let
|
generate-mac-address = hostname: interface:
|
||||||
pkg = generate-mac-address hostname interface;
|
let pkg = generate-mac-address hostname interface;
|
||||||
in removeSuffix "\n" (builtins.readFile "${pkg}");
|
in removeSuffix "\n" (builtins.readFile "${pkg}");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue