{ config, lib, ... }: with lib; let utilities = import ./utilities.nix { inherit lib config; }; inherit (utilities) architectInterfaceAddress; in { options.architect = { firewall = { openTCP = mkOption { type = types.listOf types.int; default = [ ]; }; openUDP = mkOption { type = types.listOf types.int; default = [ ]; }; openTCPVPN = mkOption { type = types.listOf types.int; default = [ ]; }; openUDPVPN = mkOption { type = types.listOf types.int; default = [ ]; }; }; networks = mkOption { type = types.attrsOf (types.submodule { options = { interface = mkOption { type = types.str; description = "The network interface name."; }; net = mkOption { type = types.str; description = "The network address in CIDR format."; }; devices = mkOption { type = types.attrsOf (types.submodule { options = { address = mkOption { type = types.str; description = "The IP address of the device."; }; hostname = mkOption { type = types.str; description = "The hostname of the device."; }; }; }); default = { }; description = "An attribute set of devices with their configurations."; }; }; }); default = { }; description = "An attribute set of networks with their configurations."; }; vhost = mkOption { type = types.attrsOf (types.submodule { options = { dnsInterfaces = mkOption { type = types.listOf types.str; default = [ ]; description = "List of interfaces to add extra DNS hosts for this vhost."; }; locations = mkOption { type = types.attrsOf (types.submodule { options = { port = mkOption { type = types.int; description = "The port number for the location."; }; allow = mkOption { type = types.listOf types.str; default = [ ]; description = "IP address or CIDR block to allow."; }; deny = mkOption { type = types.listOf types.str; default = [ ]; description = "IP address or CIDR block to deny."; }; }; }); default = { }; description = "An attribute set of location configurations."; }; }; }); default = { }; description = "An attribute set of domain configurations."; }; }; config = { services.nginx.virtualHosts = mapAttrs (domain: conf: { forceSSL = true; enableACME = true; locations = mapAttrs (path: location: { proxyPass = "http://127.0.0.1:${toString location.port}"; extraConfig = '' ${concatMapStringsSep "\n" (denyCIDR: "deny ${denyCIDR};") location.deny} ${concatMapStringsSep "\n" (allowCIDR: "allow ${allowCIDR};") location.allow} ''; }) conf.locations; }) config.architect.vhost; networking.extraHosts = concatStringsSep "\n" ( mapAttrsToList (domain: conf: concatMapStringsSep "\n" (iface: "${architectInterfaceAddress iface} ${domain}") conf.dnsInterfaces) config.architect.vhost ); }; }