depot/modules/port-magic/link.nix

80 lines
1.8 KiB
Nix

{ config, lib, name, ... }:
with builtins;
with lib;
let
cfg = config;
portHash = flip pipe [
(hashString "md5")
(substring 0 7)
(hash: (fromTOML "v=0x${hash}").v)
(flip mod cfg.reservedPorts.amount)
(add cfg.reservedPorts.start)
];
in
{
options = {
ipv4 = mkOption {
type = types.str;
default = "127.0.0.1";
description = "The IPv4 address.";
};
hostname = mkOption {
type = types.str;
description = "The hostname.";
};
port = mkOption {
type = types.int;
description = "The TCP or UDP port.";
};
portStr = mkOption {
type = types.str;
description = "The TCP or UDP port, as a string.";
};
reservedPorts = {
amount = mkOption {
type = types.int;
default = 10000;
description = "Amount of ports to reserve at most.";
};
start = mkOption {
type = types.int;
default = 30000;
description = "Starting point for reserved ports.";
};
};
protocol = mkOption {
type = types.str;
description = "The protocol in URL scheme name format.";
};
path = mkOption {
type = types.nullOr types.path;
default = null;
description = "The resource path.";
};
url = mkOption {
type = types.str;
description = "The URL.";
};
tuple = mkOption {
type = types.str;
description = "The hostname:port tuple.";
};
extra = mkOption {
type = types.attrs;
description = "Arbitrary extra data.";
};
};
config = mkIf true {
hostname = mkDefault cfg.ipv4;
port = mkDefault (portHash "${cfg.hostname}:${name}");
portStr = toString cfg.port;
tuple = "${cfg.hostname}:${cfg.portStr}";
url = "${cfg.protocol}://${cfg.hostname}:${cfg.portStr}${if cfg.path == null then "" else cfg.path}";
};
}