diff --git a/modules/nixos/_private/default.nix b/modules/nixos/_private/default.nix index fefc498a..ac264ce8 100644 --- a/modules/nixos/_private/default.nix +++ b/modules/nixos/_private/default.nix @@ -1,7 +1,7 @@ { imports = [ ./extra-arguments.nix - ./state.nix + ./state ./suites/archiving.nix ./suites/browsers.nix ./suites/desktop.nix diff --git a/modules/nixos/_private/state.nix b/modules/nixos/_private/state/default.nix similarity index 86% rename from modules/nixos/_private/state.nix rename to modules/nixos/_private/state/default.nix index 48b5fb13..d9db7bbd 100644 --- a/modules/nixos/_private/state.nix +++ b/modules/nixos/_private/state/default.nix @@ -1,9 +1,13 @@ { lib, ... }: { + imports = [ + ./ports.nix + ]; + options.state = lib.mkOption { type = lib.types.submodule { - freeFormType = with lib.types; attrsOf anything; + freeformType = with lib.types; attrsOf anything; default = { }; }; description = '' diff --git a/modules/nixos/_private/state/ports.nix b/modules/nixos/_private/state/ports.nix new file mode 100644 index 00000000..092e1544 --- /dev/null +++ b/modules/nixos/_private/state/ports.nix @@ -0,0 +1,108 @@ +{ config, lib, ... }: + +let + cfg = config.state; + + supportedProtocols = [ "tcp" "udp" ]; + + portRangeType = { + options = { + from = lib.mkOption { + type = lib.types.port; + description = '' + The start of the range of TCP/UDP ports to be taken over. + ''; + }; + + to = lib.mkOption { + type = lib.types.port; + description = '' + The end of the range of TCP/UDP ports to be taken over. + ''; + }; + }; + }; + + portModule = { lib, ... }: { + options = { + protocols = lib.mkOption { + type = with lib.types; listOf (enum supportedProtocols); + description = '' + Indicates the type of protocol of the service. + ''; + default = [ "tcp" "udp" ]; + example = [ "tcp" ]; + }; + + value = lib.mkOption { + type = with lib.types; either port (submodule portRangeType); + description = '' + The port number itself. + ''; + }; + + openFirewall = lib.mkEnableOption "opening the ports to firewall"; + }; + }; +in +{ + options.state = + let + portsModule = { lib, ... }: { + options = { + ports = lib.mkOption { + type = with lib.types; attrsOf (submodule portModule); + description = '' + A set of ports indicating what goes where in the NixOS system. + ''; + example = lib.literalExpression '' + rec { + gonic = { + value = 5757; + protocols = [ "tcp" ]; + openFirewall = true; + }; + uxplay = { + value = 7864; + openFirewall = true; + }; + uxplayClients.value = { + from = uxplay.value + 1; + to = uxplay.value + 20; + }; + } + ''; + }; + }; + }; + in lib.mkOption { + type = lib.types.submodule portsModule; + }; + + config = lib.mkIf (cfg.ports != { }) { + networking.firewall = + let + allPortsToBeOpened = lib.filterAttrs (_: v: v.openFirewall) cfg.ports; + hasProtocol = protocol: v: lib.elem protocol v.protocols; + mkFirewallEntry = protocol: v: + let + inherit (v) value; + in + if lib.isAttrs value then { + ${if protocol == "tcp" + then "allowedTCPPortRanges" + else "allowedUDPPortRanges"} = [ value ]; + } else { + ${if protocol == "tcp" + then "allowedTCPPorts" + else "allowedUDPPorts"} = [ value ]; + }; + + mkFirewallEntryModule = _: v: + lib.optionalAttrs (hasProtocol "udp" v) (mkFirewallEntry "udp" v) + // lib.optionalAttrs (hasProtocol "tcp" v) (mkFirewallEntry "tcp" v); + in + lib.mkMerge + (lib.mapAttrsToList mkFirewallEntryModule allPortsToBeOpened); + }; +}