refactor(nixos): model local routes as HTTP routes
This commit is contained in:
@@ -148,11 +148,13 @@
|
|||||||
enable = true;
|
enable = true;
|
||||||
vlan = 20;
|
vlan = 20;
|
||||||
address = "10.23.20.110";
|
address = "10.23.20.110";
|
||||||
};
|
reverseProxy = {
|
||||||
|
enable = true;
|
||||||
registry.local-route.${config.networking.hostName}.homepage = {
|
route = {
|
||||||
domain = "home";
|
domain = "home";
|
||||||
port = 8082;
|
http.port = 8082;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
guests.copyparty = {
|
guests.copyparty = {
|
||||||
|
|||||||
@@ -9,59 +9,46 @@ let
|
|||||||
|
|
||||||
mkRegistryPath = registryName: host: entry: "registry.${registryName}.${host}.${entry}";
|
mkRegistryPath = registryName: host: entry: "registry.${registryName}.${host}.${entry}";
|
||||||
|
|
||||||
mkBackend = address: route: "http://${address}:${toString route.port}";
|
mkBackend = address: port: "http://${address}:${toString port}";
|
||||||
|
|
||||||
mkPublicVirtualHost = host: entry:
|
mkVirtualHost = host: entry: mode:
|
||||||
let
|
let
|
||||||
compositeEntry = registry.join host entry;
|
compositeEntry = registry.join host entry;
|
||||||
route = compositeEntry.route;
|
route = compositeEntry.route;
|
||||||
address = compositeEntry.address or (throw "no matching entry in registry.address for ${mkRegistryPath "route" host entry}");
|
address = compositeEntry.address or (throw "no matching entry in registry.address for ${mkRegistryPath "route" host entry}");
|
||||||
|
isHttp = mode == "http";
|
||||||
|
port = if isHttp then route.http.port else route.port;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
inherit host entry;
|
inherit host entry;
|
||||||
registryName = "route";
|
registryName = "route";
|
||||||
name = route.domain;
|
name = route.domain;
|
||||||
value = {
|
value = {
|
||||||
forceSSL = true;
|
forceSSL = !isHttp;
|
||||||
enableACME = true;
|
enableACME = !isHttp;
|
||||||
locations."/".proxyPass = mkBackend address route;
|
locations."/".proxyPass = mkBackend address port;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
mkLocalVirtualHost = host: entry:
|
generatedHttpsVirtualHostList = lib.concatLists (
|
||||||
let
|
|
||||||
compositeEntry = registry.join host entry;
|
|
||||||
route = compositeEntry.local-route;
|
|
||||||
address = compositeEntry.address or (throw "no matching entry in registry.address for ${mkRegistryPath "local-route" host entry}");
|
|
||||||
in
|
|
||||||
{
|
|
||||||
inherit host entry;
|
|
||||||
registryName = "local-route";
|
|
||||||
name = route.domain;
|
|
||||||
value = {
|
|
||||||
forceSSL = false;
|
|
||||||
enableACME = false;
|
|
||||||
locations."/".proxyPass = mkBackend address route;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
generatedPublicVirtualHostList = lib.concatLists (
|
|
||||||
lib.mapAttrsToList (
|
lib.mapAttrsToList (
|
||||||
host: routes:
|
host: routes:
|
||||||
lib.mapAttrsToList (entry: _route: mkPublicVirtualHost host entry) (
|
lib.mapAttrsToList (entry: _route: mkVirtualHost host entry "https") (
|
||||||
lib.filterAttrs (_entry: route: route.port != null) routes
|
lib.filterAttrs (_entry: route: route.port != null) routes
|
||||||
)
|
)
|
||||||
) registry.route
|
) registry.route
|
||||||
);
|
);
|
||||||
|
|
||||||
generatedLocalVirtualHostList = lib.concatLists (
|
generatedHttpVirtualHostList = lib.concatLists (
|
||||||
lib.mapAttrsToList (
|
lib.mapAttrsToList (
|
||||||
host: routes:
|
host: routes:
|
||||||
lib.mapAttrsToList (entry: _route: mkLocalVirtualHost host entry) routes
|
lib.mapAttrsToList (entry: _route: mkVirtualHost host entry "http") (
|
||||||
) registry.local-route
|
lib.filterAttrs (_entry: route: route.http.port != null) routes
|
||||||
|
)
|
||||||
|
) registry.route
|
||||||
);
|
);
|
||||||
|
|
||||||
generatedVirtualHostList = generatedPublicVirtualHostList ++ generatedLocalVirtualHostList;
|
generatedVirtualHostList = generatedHttpsVirtualHostList ++ generatedHttpVirtualHostList;
|
||||||
|
|
||||||
virtualHostsByDomain = lib.foldl' (
|
virtualHostsByDomain = lib.foldl' (
|
||||||
acc: virtualHost:
|
acc: virtualHost:
|
||||||
@@ -76,7 +63,7 @@ let
|
|||||||
domain: virtualHosts:
|
domain: virtualHosts:
|
||||||
if lib.length virtualHosts > 1 then
|
if lib.length virtualHosts > 1 then
|
||||||
[
|
[
|
||||||
"duplicate reverse-proxy domain ${domain} in ${lib.concatMapStringsSep " and " (virtualHost: mkRegistryPath virtualHost.registryName virtualHost.host virtualHost.entry) virtualHosts}"
|
"duplicate route domain ${domain} in ${lib.concatMapStringsSep " and " (virtualHost: mkRegistryPath virtualHost.registryName virtualHost.host virtualHost.entry) virtualHosts}"
|
||||||
]
|
]
|
||||||
else
|
else
|
||||||
[ ]
|
[ ]
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
{ lib, ... }:
|
|
||||||
{
|
|
||||||
checks = [
|
|
||||||
{
|
|
||||||
assertion = lib.registry.predicates.uniqueValue (entry: entry.value.domain);
|
|
||||||
message = "Local route domains must be unique.";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
type = lib.types.submodule {
|
|
||||||
options = {
|
|
||||||
domain = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
example = "home";
|
|
||||||
description = "Local HTTP domain served by this route entry.";
|
|
||||||
};
|
|
||||||
|
|
||||||
port = lib.mkOption {
|
|
||||||
type = lib.types.port;
|
|
||||||
example = 8082;
|
|
||||||
description = "Backend TCP port served by the matching address registry entry.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -12,6 +12,10 @@
|
|||||||
);
|
);
|
||||||
message = "Route UDP ports must be unique.";
|
message = "Route UDP ports must be unique.";
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
assertion = entries: lib.all (entry: entry.value.port == null || entry.value.http.port == null) entries;
|
||||||
|
message = "Route entries must not set both port and http.port.";
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
type = lib.types.submodule {
|
type = lib.types.submodule {
|
||||||
@@ -19,14 +23,21 @@
|
|||||||
domain = lib.mkOption {
|
domain = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
example = "files.alexion.dev";
|
example = "files.alexion.dev";
|
||||||
description = "Public domain served by this route entry.";
|
description = "Domain served by this route entry.";
|
||||||
};
|
};
|
||||||
|
|
||||||
port = lib.mkOption {
|
port = lib.mkOption {
|
||||||
type = lib.types.nullOr lib.types.port;
|
type = lib.types.nullOr lib.types.port;
|
||||||
default = null;
|
default = null;
|
||||||
example = 3923;
|
example = 3923;
|
||||||
description = "Backend TCP port served by the matching address registry entry.";
|
description = "HTTPS backend TCP port served by the matching address registry entry.";
|
||||||
|
};
|
||||||
|
|
||||||
|
http.port = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.port;
|
||||||
|
default = null;
|
||||||
|
example = 8082;
|
||||||
|
description = "HTTP backend TCP port served by the matching address registry entry.";
|
||||||
};
|
};
|
||||||
|
|
||||||
udp.ports = lib.mkOption {
|
udp.ports = lib.mkOption {
|
||||||
|
|||||||
Reference in New Issue
Block a user