{ lib, config, ... }: with lib; let cfg = config.services.znc; networkOpts = { options = { server = mkOption { type = types.str; example = "chat.freenode.net"; description = '' IRC server address. ''; }; port = mkOption { type = types.ints.u16; default = 6697; description = '' IRC server port. ''; }; password = mkOption { type = types.str; default = ""; description = '' IRC server password, such as for a Slack gateway. ''; }; useSSL = mkOption { type = types.bool; default = true; description = '' Whether to use SSL to connect to the IRC server. ''; }; modules = mkOption { type = types.listOf types.str; default = [ "simple_away" ]; example = literalExample "[ simple_away sasl ]"; description = '' ZNC network modules to load. ''; }; channels = mkOption { type = types.listOf types.str; default = []; example = [ "nixos" ]; description = '' IRC channels to join. ''; }; hasBitlbeeControlChannel = mkOption { type = types.bool; default = false; description = '' Whether to add the special Bitlbee operations channel. ''; }; extraConf = mkOption { default = ""; type = types.lines; example = '' Encoding = ^UTF-8 FloodBurst = 4 FloodRate = 1.00 IRCConnectEnabled = true Ident = johntron JoinDelay = 0 Nick = johntron ''; description = '' Extra config for the network. Consider using instead. ''; }; }; }; in { options = { services.znc = { useLegacyConfig = mkOption { default = true; type = types.bool; description = '' Whether to propagate the legacy options under to the znc config. If this is turned on, the znc config will contain a user with the default name "znc", global modules "webadmin" and "adminlog" will be enabled by default, and more, all controlled through the options. You can use nix-instantiate --eval --strict '<nixpkgs/nixos>' -A config.services.znc.config to view the current value of the config. In any case, if you need more flexibility, can be used to override/add to all of the legacy options. ''; }; confOptions = { modules = mkOption { type = types.listOf types.str; default = [ "webadmin" "adminlog" ]; example = [ "partyline" "webadmin" "adminlog" "log" ]; description = '' A list of modules to include in the `znc.conf` file. ''; }; userModules = mkOption { type = types.listOf types.str; default = [ "chansaver" "controlpanel" ]; example = [ "chansaver" "controlpanel" "fish" "push" ]; description = '' A list of user modules to include in the `znc.conf` file. ''; }; userName = mkOption { default = "znc"; example = "johntron"; type = types.str; description = '' The user name used to log in to the ZNC web admin interface. ''; }; networks = mkOption { default = { }; type = with types; attrsOf (submodule networkOpts); description = '' IRC networks to connect the user to. ''; example = literalExample '' { "freenode" = { server = "chat.freenode.net"; port = 6697; useSSL = true; modules = [ "simple_away" ]; }; }; ''; }; nick = mkOption { default = "znc-user"; example = "john"; type = types.str; description = '' The IRC nick. ''; }; passBlock = mkOption { example = literalExample '' <Pass password> Method = sha256 Hash = e2ce303c7ea75c571d80d8540a8699b46535be6a085be3414947d638e48d9e93 Salt = l5Xryew4g*!oa(ECfX2o </Pass> ''; type = types.str; description = '' Generate with `nix-shell -p znc --command "znc --makepass"`. This is the password used to log in to the ZNC web admin interface. You can also set this through and co. ''; }; port = mkOption { default = 5000; type = types.int; description = '' Specifies the port on which to listen. ''; }; useSSL = mkOption { default = true; type = types.bool; description = '' Indicates whether the ZNC server should use SSL when listening on the specified port. A self-signed certificate will be generated. ''; }; uriPrefix = mkOption { type = types.nullOr types.str; default = null; example = "/znc/"; description = '' An optional URI prefix for the ZNC web interface. Can be used to make ZNC available behind a reverse proxy. ''; }; extraZncConf = mkOption { default = ""; type = types.lines; description = '' Extra config to `znc.conf` file. ''; }; }; }; }; config = mkIf cfg.useLegacyConfig { services.znc.config = let c = cfg.confOptions; # defaults here should override defaults set in the non-legacy part mkDefault = mkOverride 900; in { LoadModule = mkDefault c.modules; Listener.l = { Port = mkDefault c.port; IPv4 = mkDefault true; IPv6 = mkDefault true; SSL = mkDefault c.useSSL; URIPrefix = c.uriPrefix; }; User.${c.userName} = { Admin = mkDefault true; Nick = mkDefault c.nick; AltNick = mkDefault "${c.nick}_"; Ident = mkDefault c.nick; RealName = mkDefault c.nick; LoadModule = mkDefault c.userModules; Network = mapAttrs (name: net: { LoadModule = mkDefault net.modules; Server = mkDefault "${net.server} ${optionalString net.useSSL "+"}${toString net.port} ${net.password}"; Chan = optionalAttrs net.hasBitlbeeControlChannel { "&bitlbee" = mkDefault {}; } // listToAttrs (map (n: nameValuePair "#${n}" (mkDefault {})) net.channels); extraConfig = if net.extraConf == "" then mkDefault null else net.extraConf; }) c.networks; extraConfig = [ c.passBlock ]; }; extraConfig = optional (c.extraZncConf != "") c.extraZncConf; }; }; imports = [ (mkRemovedOptionModule ["services" "znc" "zncConf"] '' Instead of `services.znc.zncConf = "... foo ...";`, use `services.znc.configFile = pkgs.writeText "znc.conf" "... foo ...";`. '') ]; }