diff options
Diffstat (limited to '')
-rw-r--r-- | flake.nix | 2 | ||||
-rw-r--r-- | tools/default.nix | 1 | ||||
-rw-r--r-- | tools/dnsmasq-leases-html/README.md | 37 | ||||
-rw-r--r-- | tools/dnsmasq-leases-html/default.nix | 36 | ||||
-rwxr-xr-x | tools/dnsmasq-leases-html/dnsmasq-leases-html.py | 37 | ||||
-rw-r--r-- | tools/dnsmasq-leases-html/templates/index.html | 60 |
6 files changed, 172 insertions, 1 deletions
diff --git a/flake.nix b/flake.nix index 4fd7946..12f3b5b 100644 --- a/flake.nix +++ b/flake.nix @@ -156,7 +156,7 @@ { inherit (inputs.futils.lib) filterPackages flattenTree; ops = import ./ops { inherit pkgs; }; - users.fcuny = import ./users/fcuny { inherit pkgs; }; + tools = import ./tools { inherit pkgs; }; }); nixosConfigurations = { diff --git a/tools/default.nix b/tools/default.nix index 1737aa5..f7051fb 100644 --- a/tools/default.nix +++ b/tools/default.nix @@ -1,6 +1,7 @@ { pkgs, ... }: pkgs.lib.makeScope pkgs.newScope (pkgs: { + dnsmasq-to-html = pkgs.callPackage ./dnsmasq-leases-html { }; gha-billing = pkgs.callPackage ./gha-billing { }; git-blame-stats = pkgs.callPackage ./git-blame-stats { }; git-broom = pkgs.callPackage ./git-broom { }; diff --git a/tools/dnsmasq-leases-html/README.md b/tools/dnsmasq-leases-html/README.md new file mode 100644 index 0000000..2437deb --- /dev/null +++ b/tools/dnsmasq-leases-html/README.md @@ -0,0 +1,37 @@ +Generates a static HTML page with a list of all the leases allocated by `dnsmasq`. + +A simple template written in the jinja syntax is used. + +The file containing the leases is expected to be at `/var/lib/dnsmasq/dnsmasq.leases`, but this can be overwritten by setting the environment variable `DNSMASQ_LEASES`. + +The output of the script is written to `/var/lib/dnsmasq/leases.html` by default, but the destination can be overwritten by setting the environment variable `DNSMASQ_LEASES_OUT`. + +The script can be executed automatically by `dnsmasq` if the configuration for `dhcp-script` is set to the path of the script. This will only be executed when a *new* lease is created or an *old* lease is deleted. To execute the script when a lease is *updated* you need to use the configuration `script-on-renewal`. + +A configuration looks like this: + +``` ini +dhcp-script=${pkgs.tools.dnsmasq-to-html}/bin/dnsmasq-leases-html +script-on-renewal +``` + +## nginx +To serve the page with nginx, you can use the following configuration: + +``` nix +services.nginx = { + enable = true; + virtualHosts."dnsmasq" = { + listen = [ + { + addr = "192.168.6.1"; + port = 8067; + } + ]; + locations."/" = { + root = "/var/lib/dnsmasq"; + index = "leases.html"; + }; + }; +}; +``` diff --git a/tools/dnsmasq-leases-html/default.nix b/tools/dnsmasq-leases-html/default.nix new file mode 100644 index 0000000..4848ea7 --- /dev/null +++ b/tools/dnsmasq-leases-html/default.nix @@ -0,0 +1,36 @@ +{ self, lib, stdenvNoCC, pkgs }: + +stdenvNoCC.mkDerivation rec { + pname = "dnsmasq-leases-html"; + src = ./dnsmasq-leases-html.py; + templates = ./templates; + version = "0.1.0"; + + buildInputs = [ + (pkgs.python310.withPackages (ps: with ps; [ + jinja2 + ])) + ]; + + propagatedBuildInputs = [ + (pkgs.python310.withPackages (ps: with ps; [ + jinja2 + ])) + ]; + + dontUnpack = true; + dontBuild = true; + + installPhase = '' + mkdir -p $out/bin + cp $src $out/bin/${pname} + cp -r $templates $out/bin/templates + ''; + + meta = with pkgs.lib; { + description = "CLI to generate a HTML page with dnsmasq leases."; + license = licenses.mit; + platforms = platforms.unix; + maintainers = [ ]; + }; +} diff --git a/tools/dnsmasq-leases-html/dnsmasq-leases-html.py b/tools/dnsmasq-leases-html/dnsmasq-leases-html.py new file mode 100755 index 0000000..c1f03db --- /dev/null +++ b/tools/dnsmasq-leases-html/dnsmasq-leases-html.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 + +import datetime +import ipaddress +import os + +from jinja2 import Environment, FileSystemLoader + + +outfile = os.getenv("DNSMASQ_LEASES_OUT", "/var/lib/dnsmasq/leases.html") +leases_file = os.getenv("DNSMASQ_LEASES", "/var/lib/dnsmasq/dnsmasq.leases") + +leases = [] + +with open(leases_file, "r") as f: + for line in f: + content = line.rstrip("\n").split(" ") + lease = dict() + if int(content[0]) == 0: + lease["expire"] = "never" + else: + lease["expire"] = datetime.datetime.fromtimestamp(int(content[0])) + lease["MAC"] = content[1] + lease["IP"] = ipaddress.ip_address(content[2]) + lease["hostname"] = content[3] + leases.append(lease) + +leases = sorted(leases, key=lambda d: d["IP"]) + +dir_path = os.path.dirname(os.path.realpath(__file__)) +templates_dir = os.path.join(dir_path, "templates") +environment = Environment(loader=FileSystemLoader(templates_dir)) +template = environment.get_template("index.html") + +content = template.render(leases=leases) +with open(outfile, "w") as fh: + print(content, file=fh) diff --git a/tools/dnsmasq-leases-html/templates/index.html b/tools/dnsmasq-leases-html/templates/index.html new file mode 100644 index 0000000..913a0c9 --- /dev/null +++ b/tools/dnsmasq-leases-html/templates/index.html @@ -0,0 +1,60 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>Leases assigned by dnsmasq</title> + <style type="text/css"> + body { + margin: auto; + width: 70%; + font-family: monospace; + font-size: 16px; + } + .center { + margin-left: auto; + margin-right: auto; + } + td, th { + padding-left: 1em; + padding-right: 1em; + padding-top: .5em; + padding-bottom: .5em; + } + td:first-child, th:first-child { + padding-left: .25em; + } + td:last-child, th:last-child { + padding-right: .25em; + } + th { + padding-top: 1em; + text-align: left; + } + tr:nth-child(even) { + background: #eee; + } + form { + display: inline; + } + </style> +</head> + +<body> + <table> + <tr> + <th>IP address</th> + <th>MAC address</th> + <th>Hostname</th> + <th>Expire</th> + </tr> + {% for lease in leases %} + <tr> + <td>{{ lease.IP }}</td> + <td>{{ lease.MAC }}</td> + <td>{{ lease.hostname }}</td> + <td>{{ lease.expire }}</td> + </tr> + {% endfor %} + </table> +</body> +</html> |