at 23.11-pre 9.8 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.bird-lg; 7 8 stringOrConcat = sep: v: if builtins.isString v then v else concatStringsSep sep v; 9 10 frontend_args = let 11 fe = cfg.frontend; 12 in { 13 "--servers" = concatStringsSep "," fe.servers; 14 "--domain" = fe.domain; 15 "--listen" = fe.listenAddress; 16 "--proxy-port" = fe.proxyPort; 17 "--whois" = fe.whois; 18 "--dns-interface" = fe.dnsInterface; 19 "--bgpmap-info" = concatStringsSep "," cfg.frontend.bgpMapInfo; 20 "--title-brand" = fe.titleBrand; 21 "--navbar-brand" = fe.navbar.brand; 22 "--navbar-brand-url" = fe.navbar.brandURL; 23 "--navbar-all-servers" = fe.navbar.allServers; 24 "--navbar-all-url" = fe.navbar.allServersURL; 25 "--net-specific-mode" = fe.netSpecificMode; 26 "--protocol-filter" = concatStringsSep "," cfg.frontend.protocolFilter; 27 }; 28 29 proxy_args = let 30 px = cfg.proxy; 31 in { 32 "--allowed" = concatStringsSep "," px.allowedIPs; 33 "--bird" = px.birdSocket; 34 "--listen" = px.listenAddress; 35 "--traceroute_bin" = px.traceroute.binary; 36 "--traceroute_flags" = concatStringsSep " " px.traceroute.flags; 37 "--traceroute_raw" = px.traceroute.rawOutput; 38 }; 39 40 mkArgValue = value: 41 if isString value 42 then escapeShellArg value 43 else if isBool value 44 then boolToString value 45 else toString value; 46 47 filterNull = filterAttrs (_: v: v != "" && v != null && v != []); 48 49 argsAttrToList = args: mapAttrsToList (name: value: "${name} " + mkArgValue value ) (filterNull args); 50in 51{ 52 options = { 53 services.bird-lg = { 54 package = mkOption { 55 type = types.package; 56 default = pkgs.bird-lg; 57 defaultText = literalExpression "pkgs.bird-lg"; 58 description = lib.mdDoc "The Bird Looking Glass package to use."; 59 }; 60 61 user = mkOption { 62 type = types.str; 63 default = "bird-lg"; 64 description = lib.mdDoc "User to run the service."; 65 }; 66 67 group = mkOption { 68 type = types.str; 69 default = "bird-lg"; 70 description = lib.mdDoc "Group to run the service."; 71 }; 72 73 frontend = { 74 enable = mkEnableOption (lib.mdDoc "Bird Looking Glass Frontend Webserver"); 75 76 listenAddress = mkOption { 77 type = types.str; 78 default = "127.0.0.1:5000"; 79 description = lib.mdDoc "Address to listen on."; 80 }; 81 82 proxyPort = mkOption { 83 type = types.port; 84 default = 8000; 85 description = lib.mdDoc "Port bird-lg-proxy is running on."; 86 }; 87 88 domain = mkOption { 89 type = types.str; 90 example = "dn42.lantian.pub"; 91 description = lib.mdDoc "Server name domain suffixes."; 92 }; 93 94 servers = mkOption { 95 type = types.listOf types.str; 96 example = [ "gigsgigscloud" "hostdare" ]; 97 description = lib.mdDoc "Server name prefixes."; 98 }; 99 100 whois = mkOption { 101 type = types.str; 102 default = "whois.verisign-grs.com"; 103 description = lib.mdDoc "Whois server for queries."; 104 }; 105 106 dnsInterface = mkOption { 107 type = types.str; 108 default = "asn.cymru.com"; 109 description = lib.mdDoc "DNS zone to query ASN information."; 110 }; 111 112 bgpMapInfo = mkOption { 113 type = types.listOf types.str; 114 default = [ "asn" "as-name" "ASName" "descr" ]; 115 description = lib.mdDoc "Information displayed in bgpmap."; 116 }; 117 118 titleBrand = mkOption { 119 type = types.str; 120 default = "Bird-lg Go"; 121 description = lib.mdDoc "Prefix of page titles in browser tabs."; 122 }; 123 124 netSpecificMode = mkOption { 125 type = types.str; 126 default = ""; 127 example = "dn42"; 128 description = lib.mdDoc "Apply network-specific changes for some networks."; 129 }; 130 131 protocolFilter = mkOption { 132 type = types.listOf types.str; 133 default = [ ]; 134 example = [ "ospf" ]; 135 description = lib.mdDoc "Information displayed in bgpmap."; 136 }; 137 138 nameFilter = mkOption { 139 type = types.str; 140 default = ""; 141 example = "^ospf"; 142 description = lib.mdDoc "Protocol names to hide in summary tables (RE2 syntax),"; 143 }; 144 145 timeout = mkOption { 146 type = types.int; 147 default = 120; 148 description = lib.mdDoc "Time before request timed out, in seconds."; 149 }; 150 151 navbar = { 152 brand = mkOption { 153 type = types.str; 154 default = "Bird-lg Go"; 155 description = lib.mdDoc "Brand to show in the navigation bar ."; 156 }; 157 158 brandURL = mkOption { 159 type = types.str; 160 default = "/"; 161 description = lib.mdDoc "URL of the brand to show in the navigation bar."; 162 }; 163 164 allServers = mkOption { 165 type = types.str; 166 default = "ALL Servers"; 167 description = lib.mdDoc "Text of 'All server' button in the navigation bar."; 168 }; 169 170 allServersURL = mkOption { 171 type = types.str; 172 default = "all"; 173 description = lib.mdDoc "URL of 'All servers' button."; 174 }; 175 }; 176 177 extraArgs = mkOption { 178 type = with types; either lines (listOf str); 179 default = [ ]; 180 description = lib.mdDoc '' 181 Extra parameters documented [here](https://github.com/xddxdd/bird-lg-go#frontend). 182 183 :::{.note} 184 Passing lines (plain strings) is deprecated in favour of passing lists of strings. 185 ::: 186 ''; 187 }; 188 }; 189 190 proxy = { 191 enable = mkEnableOption (lib.mdDoc "Bird Looking Glass Proxy"); 192 193 listenAddress = mkOption { 194 type = types.str; 195 default = "127.0.0.1:8000"; 196 description = lib.mdDoc "Address to listen on."; 197 }; 198 199 allowedIPs = mkOption { 200 type = types.listOf types.str; 201 default = [ ]; 202 example = [ "192.168.25.52" "192.168.25.53" ]; 203 description = lib.mdDoc "List of IPs to allow (default all allowed)."; 204 }; 205 206 birdSocket = mkOption { 207 type = types.str; 208 default = "/var/run/bird/bird.ctl"; 209 description = lib.mdDoc "Bird control socket path."; 210 }; 211 212 traceroute = { 213 binary = mkOption { 214 type = types.str; 215 default = "${pkgs.traceroute}/bin/traceroute"; 216 defaultText = literalExpression ''"''${pkgs.traceroute}/bin/traceroute"''; 217 description = lib.mdDoc "Traceroute's binary path."; 218 }; 219 220 flags = mkOption { 221 type = with types; listOf str; 222 default = [ ]; 223 description = lib.mdDoc "Flags for traceroute process"; 224 }; 225 226 rawOutput = mkOption { 227 type = types.bool; 228 default = false; 229 description = lib.mdDoc "Display traceroute output in raw format."; 230 }; 231 }; 232 233 extraArgs = mkOption { 234 type = with types; either lines (listOf str); 235 default = [ ]; 236 description = lib.mdDoc '' 237 Extra parameters documented [here](https://github.com/xddxdd/bird-lg-go#proxy). 238 239 :::{.note} 240 Passing lines (plain strings) is deprecated in favour of passing lists of strings. 241 ::: 242 ''; 243 }; 244 }; 245 }; 246 }; 247 248 ###### implementation 249 250 config = { 251 252 warnings = 253 lib.optional (cfg.frontend.enable && builtins.isString cfg.frontend.extraArgs) '' 254 Passing strings to `services.bird-lg.frontend.extraOptions' is deprecated. Please pass a list of strings instead. 255 '' 256 ++ lib.optional (cfg.proxy.enable && builtins.isString cfg.proxy.extraArgs) '' 257 Passing strings to `services.bird-lg.proxy.extraOptions' is deprecated. Please pass a list of strings instead. 258 '' 259 ; 260 261 systemd.services = { 262 bird-lg-frontend = mkIf cfg.frontend.enable { 263 enable = true; 264 after = [ "network.target" ]; 265 wantedBy = [ "multi-user.target" ]; 266 description = "Bird Looking Glass Frontend Webserver"; 267 serviceConfig = { 268 Type = "simple"; 269 Restart = "on-failure"; 270 ProtectSystem = "full"; 271 ProtectHome = "yes"; 272 MemoryDenyWriteExecute = "yes"; 273 User = cfg.user; 274 Group = cfg.group; 275 }; 276 script = '' 277 ${cfg.package}/bin/frontend \ 278 ${concatStringsSep " \\\n " (argsAttrToList frontend_args)} \ 279 ${stringOrConcat " " cfg.frontend.extraArgs} 280 ''; 281 }; 282 283 bird-lg-proxy = mkIf cfg.proxy.enable { 284 enable = true; 285 after = [ "network.target" ]; 286 wantedBy = [ "multi-user.target" ]; 287 description = "Bird Looking Glass Proxy"; 288 serviceConfig = { 289 Type = "simple"; 290 Restart = "on-failure"; 291 ProtectSystem = "full"; 292 ProtectHome = "yes"; 293 MemoryDenyWriteExecute = "yes"; 294 User = cfg.user; 295 Group = cfg.group; 296 }; 297 script = '' 298 ${cfg.package}/bin/proxy \ 299 ${concatStringsSep " \\\n " (argsAttrToList proxy_args)} \ 300 ${stringOrConcat " " cfg.proxy.extraArgs} 301 ''; 302 }; 303 }; 304 users = mkIf (cfg.frontend.enable || cfg.proxy.enable) { 305 groups."bird-lg" = mkIf (cfg.group == "bird-lg") { }; 306 users."bird-lg" = mkIf (cfg.user == "bird-lg") { 307 description = "Bird Looking Glass user"; 308 extraGroups = lib.optionals (config.services.bird2.enable) [ "bird2" ]; 309 group = cfg.group; 310 isSystemUser = true; 311 }; 312 }; 313 }; 314 315 meta.maintainers = with lib.maintainers; [ 316 e1mo 317 tchekda 318 ]; 319}