feat: add initial config
This commit is contained in:
commit
fb98563bb6
26 changed files with 576 additions and 0 deletions
78
validation/endpoints.nix
Normal file
78
validation/endpoints.nix
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
let
|
||||
lib = import <nixpkgs/lib>;
|
||||
|
||||
allowedEndpointKeys = [ "type" "listenPort" "content" ];
|
||||
allowedContentKeys = [ "host" "port" ];
|
||||
|
||||
ensureNoUnknownKeys = context: obj: allowedKeys:
|
||||
let
|
||||
unknown = builtins.filter (key: !(lib.elem key allowedKeys)) (builtins.attrNames obj);
|
||||
in
|
||||
if unknown != [] then
|
||||
throw "${context} contains unknown keys: ${builtins.concatStringsSep ", " unknown}"
|
||||
else
|
||||
obj;
|
||||
|
||||
ensurePort = value:
|
||||
builtins.isInt value && value > 0 && value <= 65535;
|
||||
|
||||
validateEndpointShape = index: endpoint:
|
||||
let
|
||||
_ = if builtins.isAttrs endpoint then null else throw "Endpoint at index ${toString index} must be an attrset.";
|
||||
__ = ensureNoUnknownKeys "Endpoint at index ${toString index}" endpoint allowedEndpointKeys;
|
||||
typeValue =
|
||||
if endpoint ? type && builtins.isString endpoint.type then
|
||||
endpoint.type
|
||||
else
|
||||
throw "Endpoint at index ${toString index} must define type as a string.";
|
||||
_type =
|
||||
if lib.elem typeValue [ "forwarding" "proxy" ] then
|
||||
null
|
||||
else
|
||||
throw "Endpoint at index ${toString index} type must be 'forwarding' or 'proxy'.";
|
||||
_listenPort =
|
||||
if endpoint ? listenPort && ensurePort endpoint.listenPort then
|
||||
null
|
||||
else
|
||||
throw "Endpoint at index ${toString index} must define listenPort as int in range 1..65535.";
|
||||
contentValue =
|
||||
if endpoint ? content then
|
||||
endpoint.content
|
||||
else
|
||||
throw "Endpoint at index ${toString index} must define content.";
|
||||
_content =
|
||||
let
|
||||
_attrs = if builtins.isAttrs contentValue then null else throw "Endpoint at index ${toString index} must define content as an attrset.";
|
||||
____ = ensureNoUnknownKeys "Endpoint content at index ${toString index}" contentValue allowedContentKeys;
|
||||
in
|
||||
if !(contentValue ? port) || !ensurePort contentValue.port then
|
||||
throw "Endpoint at index ${toString index} must define content.port as int in range 1..65535."
|
||||
else if typeValue == "proxy" && (!(contentValue ? host) || !builtins.isString contentValue.host || contentValue.host == "") then
|
||||
throw "Proxy endpoint at index ${toString index} must define content.host as non-empty string."
|
||||
else if typeValue == "forwarding" && contentValue ? host then
|
||||
throw "Forwarding endpoint at index ${toString index} must not define content.host."
|
||||
else
|
||||
null;
|
||||
in
|
||||
endpoint;
|
||||
|
||||
validateEndpointsShape = endpoints:
|
||||
if !builtins.isList endpoints then
|
||||
throw "config/endpoints.nix must evaluate to a list of endpoint attrsets."
|
||||
else
|
||||
lib.imap0 validateEndpointShape endpoints;
|
||||
|
||||
validateUniqueHostPath = endpoints:
|
||||
let
|
||||
keyFor = endpoint: toString endpoint.listenPort;
|
||||
keys = map keyFor endpoints;
|
||||
in
|
||||
if builtins.length keys == builtins.length (lib.unique keys) then
|
||||
endpoints
|
||||
else
|
||||
throw "Duplicate listenPort detected in config/endpoints.nix.";
|
||||
in
|
||||
{
|
||||
getValidatedEndpoints = endpoints:
|
||||
validateUniqueHostPath (validateEndpointsShape endpoints);
|
||||
}
|
||||
29
validation/secrets.nix
Normal file
29
validation/secrets.nix
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
let
|
||||
lib = import <nixpkgs/lib>;
|
||||
helperNames = [ "getSecretsConfig" ];
|
||||
|
||||
validateTree = context: node:
|
||||
if builtins.isAttrs node then
|
||||
lib.mapAttrs (name: value:
|
||||
if lib.elem name helperNames then
|
||||
value
|
||||
else
|
||||
validateTree "${context}.${name}" value
|
||||
) node
|
||||
else
|
||||
throw "${context} must be an attrset at non-leaf level.";
|
||||
|
||||
getSecretsConfig = secretsConfig:
|
||||
let
|
||||
_ =
|
||||
if builtins.isAttrs secretsConfig then
|
||||
null
|
||||
else
|
||||
throw "config/secrets.nix must evaluate to an attrset.";
|
||||
__ = validateTree "config/secrets.nix" secretsConfig;
|
||||
in
|
||||
secretsConfig;
|
||||
in
|
||||
rec {
|
||||
inherit getSecretsConfig validateTree;
|
||||
}
|
||||
10
validation/tunnel_ports.nix
Normal file
10
validation/tunnel_ports.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
let
|
||||
net = import ../config/network.nix;
|
||||
allowedPorts = net.tunnel.allowedPorts;
|
||||
in
|
||||
{
|
||||
inherit allowedPorts;
|
||||
|
||||
isAllowedTunnelPort = port:
|
||||
builtins.isInt port && builtins.elem port allowedPorts;
|
||||
}
|
||||
30
validation/web.nix
Normal file
30
validation/web.nix
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
let
|
||||
lib = import <nixpkgs/lib>;
|
||||
|
||||
validateFile = siteName: index: file:
|
||||
let
|
||||
_ = if builtins.isAttrs file then null else throw "web.${siteName}.files[${toString index}] must be an attrset.";
|
||||
__ = if file ? path && builtins.isString file.path then null else throw "web.${siteName}.files[${toString index}].path must be a string.";
|
||||
___ = if file ? content && builtins.isString file.content then null else throw "web.${siteName}.files[${toString index}].content must be a string.";
|
||||
____ = if file ? contentType && builtins.isString file.contentType && file.contentType != "" then null else throw "web.${siteName}.files[${toString index}].contentType must be a non-empty string.";
|
||||
_____ = if file ? status && builtins.isInt file.status then null else throw "web.${siteName}.files[${toString index}].status must be an int.";
|
||||
in
|
||||
file;
|
||||
|
||||
validateSite = siteName: site:
|
||||
let
|
||||
_ = if builtins.isAttrs site then null else throw "web.${siteName} must be an attrset.";
|
||||
__ = if site ? files && builtins.isList site.files then null else throw "web.${siteName}.files must be a list.";
|
||||
___ = lib.imap0 (index: file: validateFile siteName index file) site.files;
|
||||
in
|
||||
site;
|
||||
|
||||
getWebConfig = webConfig:
|
||||
if builtins.isAttrs webConfig then
|
||||
lib.mapAttrs validateSite webConfig
|
||||
else
|
||||
throw "config/web.nix must evaluate to an attrset.";
|
||||
in
|
||||
{
|
||||
inherit getWebConfig;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue