From 972b9554b7fc440b0e91d9f512a284d34a3ed0ce Mon Sep 17 00:00:00 2001 From: Tom Hubrecht Date: Mon, 21 Oct 2024 10:40:33 +0200 Subject: [PATCH] feat(netbox-agent): Internalize --- .../dgn-netbox-agent/01-batch-filter.patch | 35 ------ modules/dgn-netbox-agent/default.nix | 13 +- modules/dgn-netbox-agent/module.nix | 115 ++++++++++++++++++ modules/dgn-netbox-agent/netifaces2.nix | 46 +++++++ modules/dgn-netbox-agent/package.nix | 64 ++++++++++ .../{ => secrets}/netbox-agent | 0 .../{ => secrets}/secrets.nix | 0 patches/default.nix | 11 -- 8 files changed, 229 insertions(+), 55 deletions(-) delete mode 100644 modules/dgn-netbox-agent/01-batch-filter.patch create mode 100644 modules/dgn-netbox-agent/module.nix create mode 100644 modules/dgn-netbox-agent/netifaces2.nix create mode 100644 modules/dgn-netbox-agent/package.nix rename modules/dgn-netbox-agent/{ => secrets}/netbox-agent (100%) rename modules/dgn-netbox-agent/{ => secrets}/secrets.nix (100%) diff --git a/modules/dgn-netbox-agent/01-batch-filter.patch b/modules/dgn-netbox-agent/01-batch-filter.patch deleted file mode 100644 index 1d6df7e..0000000 --- a/modules/dgn-netbox-agent/01-batch-filter.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git a/netbox_agent/network.py b/netbox_agent/network.py -index 673dfc1..8ef60aa 100644 ---- a/netbox_agent/network.py -+++ b/netbox_agent/network.py -@@ -1,7 +1,7 @@ - import logging - import os - import re --from itertools import chain -+from itertools import chain, islice - - import netifaces - from netaddr import IPAddress -@@ -413,11 +413,17 @@ class Network(object): - - # delete IP on netbox that are not known on this server - if len(nb_nics): -- netbox_ips = nb.ipam.ip_addresses.filter( -- **{self.intf_type: [x.id for x in nb_nics]} -- ) -+ -+ def batched(it, n): -+ while batch := tuple(islice(it, n)): -+ yield batch -+ -+ netbox_ips = [] -+ for ids in batched((x.id for x in nb_nics), 25): -+ netbox_ips += list( -+ nb.ipam.ip_addresses.filter(**{self.intf_type: ids}) -+ ) - -- netbox_ips = list(netbox_ips) - all_local_ips = list(chain.from_iterable([ - x['ip'] for x in self.nics if x['ip'] is not None - ])) diff --git a/modules/dgn-netbox-agent/default.nix b/modules/dgn-netbox-agent/default.nix index 40b4239..75edec8 100644 --- a/modules/dgn-netbox-agent/default.nix +++ b/modules/dgn-netbox-agent/default.nix @@ -7,7 +7,9 @@ let inherit (config.networking) hostName domain; in + { + imports = [ ./module.nix ]; options.dgn-netbox-agent = { enable = lib.mkEnableOption "DGNum netbox agent setup." // { @@ -16,14 +18,6 @@ in }; config = lib.mkIf config.dgn-netbox-agent.enable { - nixpkgs.overlays = [ - (_: super: { - netbox-agent = super.netbox-agent.overrideAttrs (old: { - patches = (old.patches or [ ]) ++ [ ./01-batch-filter.patch ]; - }); - }) - ]; - services.netbox-agent = { enable = true; @@ -51,6 +45,7 @@ in randomizedDelaySec = "3h"; environmentFile = config.age.secrets."netbox-agent".path; }; - age-secrets.sources = [ ./. ]; + + age-secrets.sources = [ ./secrets ]; }; } diff --git a/modules/dgn-netbox-agent/module.nix b/modules/dgn-netbox-agent/module.nix new file mode 100644 index 0000000..2aa9069 --- /dev/null +++ b/modules/dgn-netbox-agent/module.nix @@ -0,0 +1,115 @@ +{ + config, + pkgs, + lib, + utils, + ... +}: + +let + inherit (lib) + getExe + mkEnableOption + mkIf + mkOption + mkPackageOption + ; + + inherit (lib.types) + either + listOf + nullOr + path + str + ; + + settingsFormat = pkgs.formats.yaml { }; + + cfg = config.services.netbox-agent; +in +{ + options.services.netbox-agent = { + enable = mkEnableOption "Netbox-agent"; + + package = (mkPackageOption pkgs "netbox-agent" { }) // { + default = pkgs.callPackage ./package.nix { }; + }; + + startAt = mkOption { + type = either str (listOf str); + default = "*-*-* 00:00:00"; + description = '' + Automatically start this unit at the given date/time, which + must be in the format described in + {manpage}`systemd.time(7)`. + ''; + }; + + randomizedDelaySec = mkOption { + type = str; + default = "0"; + example = "45min"; + description = '' + Add a randomized delay before each netbox-agent runs. + The delay will be chosen between zero and this value. + This value must be a time span in the format specified by + {manpage}`systemd.time(7)` + ''; + }; + + settings = mkOption { + inherit (settingsFormat) type; + description = '' + Settings to be passed to the netbox agent. Will be converted to a YAML + config file + ''; + default = { }; + }; + + environmentFile = mkOption { + type = nullOr path; + default = null; + description = '' + Environment file to pass to netbox-agent. See `netbox-agent --help` for + possible environment variables + ''; + }; + }; + + config = mkIf cfg.enable { + systemd.services.netbox-agent = { + description = "Netbox-agent service. It generates an existing infrastructure on Netbox and have the ability to update it regularly through this service."; + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; + + serviceConfig = { + Type = "oneshot"; + # We could link directly into pkgs.tzdata, but at least timedatectl seems + # to expect the symlink to point directly to a file in etc. + # Setting the "debian timezone file" to point at /dev/null stops it doing anything. + ExecStart = utils.escapeSystemdExecArgs [ + (getExe cfg.package) + "-c" + (settingsFormat.generate "config.yaml" cfg.settings) + ]; + EnvironmentFile = cfg.environmentFile; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateTmp = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectSystem = "strict"; + RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_NETLINK"; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + }; + inherit (cfg) startAt; + }; + + systemd.timers.netbox-agent.timerConfig.RandomizedDelaySec = cfg.randomizedDelaySec; + }; +} diff --git a/modules/dgn-netbox-agent/netifaces2.nix b/modules/dgn-netbox-agent/netifaces2.nix new file mode 100644 index 0000000..1c2cdf9 --- /dev/null +++ b/modules/dgn-netbox-agent/netifaces2.nix @@ -0,0 +1,46 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + cargo, + rustPlatform, + rustc, + typing-extensions, +}: + +buildPythonPackage rec { + pname = "netifaces-2"; + version = "0.0.22"; + pyproject = true; + + src = fetchFromGitHub { + owner = "SamuelYvon"; + repo = "netifaces-2"; + rev = "V${version}"; + hash = "sha256-XO3HWq8FOVzvpbK8mIBOup6hFMnhDpqOK/5bPziPZQ8="; + }; + + cargoDeps = rustPlatform.fetchCargoTarball { + inherit src; + name = "${pname}-${version}"; + hash = "sha256-uoUa6DSBuIV3RrE7svT1TVLxPHdx8BFu/C6mbpRmor0="; + }; + + build-system = [ + cargo + rustPlatform.cargoSetupHook + rustPlatform.maturinBuildHook + rustc + ]; + + dependencies = [ typing-extensions ]; + + pythonImportsCheck = [ "netifaces" ]; + + meta = { + description = "Netifaces reborn"; + homepage = "https://github.com/SamuelYvon/netifaces-2.git"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ ]; + }; +} diff --git a/modules/dgn-netbox-agent/package.nix b/modules/dgn-netbox-agent/package.nix new file mode 100644 index 0000000..637bbe6 --- /dev/null +++ b/modules/dgn-netbox-agent/package.nix @@ -0,0 +1,64 @@ +{ + lib, + python3, + fetchgit, + ethtool, + dmidecode, + ipmitool, + lldpd, + lshw, +}: + +python3.pkgs.buildPythonApplication { + pname = "netbox-agent"; + version = "unstable-2023-03-19"; + pyproject = true; + + src = fetchgit { + url = "https://git.dgnum.eu/DGNum/netbox-agent"; + rev = "12ceea413cbb87280713de734b5e1b3e88c00178"; + hash = "sha256-v6H8/yNUcpHERiyzytR2ZADLiDK2QpzSEmxTP5m9BLE="; + }; + + nativeBuildInputs = with python3.pkgs; [ + setuptools + wheel + pythonRelaxDepsHook + ]; + + pythonRelaxDeps = true; + + propagatedBuildInputs = with python3.pkgs; [ + distro + jsonargparse + netaddr + (callPackage ./netifaces2.nix { }) + packaging + pynetbox + python-slugify + pyyaml + ]; + + postInstall = '' + wrapProgram $out/bin/netbox_agent \ + --prefix PATH ":" ${ + lib.makeBinPath [ + ethtool + dmidecode + ipmitool + lldpd + lshw + ] + } + ''; + + pythonImportsCheck = [ "netbox_agent" ]; + + meta = with lib; { + description = "Netbox agent to run on your infrastructure's servers"; + homepage = "https://git.dgnum.eu/DGNum/netbox-agent"; + license = licenses.asl20; + maintainers = [ ]; + mainProgram = "netbox_agent"; + }; +} diff --git a/modules/dgn-netbox-agent/netbox-agent b/modules/dgn-netbox-agent/secrets/netbox-agent similarity index 100% rename from modules/dgn-netbox-agent/netbox-agent rename to modules/dgn-netbox-agent/secrets/netbox-agent diff --git a/modules/dgn-netbox-agent/secrets.nix b/modules/dgn-netbox-agent/secrets/secrets.nix similarity index 100% rename from modules/dgn-netbox-agent/secrets.nix rename to modules/dgn-netbox-agent/secrets/secrets.nix diff --git a/patches/default.nix b/patches/default.nix index e86ef62..f47c144 100644 --- a/patches/default.nix +++ b/patches/default.nix @@ -1,10 +1,3 @@ -let - netboxAgent = { - id = "244549"; - hash = "sha256-SePkKEYQGDj6FpuyxZ+1ASeVPA02mCHf0G5i3koMdNw="; - }; -in - { "nixos-24.05" = [ # netbox qrcode plugin @@ -14,8 +7,6 @@ in hash = "sha256-TooktlqihtULzJJsHvm8EubbUdJZvbDKdIDcYu7Qcig="; } - netboxAgent - { id = "275165"; hash = "sha256-9a26V3Pi8yLD3N9+mC1kvJoruxRTp/qOHapnt6VX7pw="; @@ -56,8 +47,6 @@ in ]; "nixos-unstable" = [ - netboxAgent - # netbox qrcode plugin { _type = "commit"; -- 2.47.0