From 52e01114beb7e915d74eb97f1dce98d584dc5458 Mon Sep 17 00:00:00 2001 From: "Janik H." Date: Fri, 1 Mar 2024 01:38:35 +0100 Subject: [PATCH] nixosTests.networking: refactor and add NetworkManager support --- nixos/tests/all-tests.nix | 1 + nixos/tests/networking/networkmanager.nix | 169 ++++++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 nixos/tests/networking/networkmanager.nix diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index a99fedaddd76..0d5b442a17bc 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -598,6 +598,7 @@ in { netdata = handleTest ./netdata.nix {}; networking.scripted = handleTest ./networking/networkd-and-scripted.nix { networkd = false; }; networking.networkd = handleTest ./networking/networkd-and-scripted.nix { networkd = true; }; + networking.networkmanager = handleTest ./networking/networkmanager.nix {}; netbox_3_6 = handleTest ./web-apps/netbox.nix { netbox = pkgs.netbox_3_6; }; netbox_3_7 = handleTest ./web-apps/netbox.nix { netbox = pkgs.netbox_3_7; }; netbox-upgrade = handleTest ./web-apps/netbox-upgrade.nix {}; diff --git a/nixos/tests/networking/networkmanager.nix b/nixos/tests/networking/networkmanager.nix new file mode 100644 index 000000000000..14dbafc6305d --- /dev/null +++ b/nixos/tests/networking/networkmanager.nix @@ -0,0 +1,169 @@ +{ system ? builtins.currentSystem +, config ? {} +, pkgs ? import ../.. { inherit system config; } +}: + +with import ../../lib/testing-python.nix { inherit system pkgs; }; + +let + lib = pkgs.lib; + # this is intended as a client test since you shouldn't use NetworkManager for a router or server + # so using systemd-networkd for the router vm is fine in these tests. + router = import ./router.nix { networkd = true; }; + qemu-common = import ../../lib/qemu-common.nix { inherit (pkgs) lib pkgs; }; + clientConfig = extraConfig: lib.recursiveUpdate { + networking.useDHCP = false; + + # Make sure that only NetworkManager configures the interface + networking.interfaces = lib.mkForce { + eth1 = {}; + }; + networking.networkmanager = { + enable = true; + # this is needed so NM doesn't generate 'Wired Connection' profiles and instead uses the default one + settings.main.no-auto-default = "*"; + ensureProfiles.profiles.default = { + connection = { + id = "default"; + type = "ethernet"; + interface-name = "eth1"; + autoconnect = true; + }; + }; + }; + } extraConfig; + testCases = { + static = { + name = "static"; + nodes = { + inherit router; + client = clientConfig { + networking.networkmanager.ensureProfiles.profiles.default = { + ipv4.method = "manual"; + ipv4.addresses = "192.168.1.42/24"; + ipv4.gateway = "192.168.1.1"; + ipv6.method = "manual"; + ipv6.addresses = "fd00:1234:5678:1::42/64"; + ipv6.gateway = "fd00:1234:5678:1::1"; + }; + }; + }; + testScript = '' + start_all() + router.wait_for_unit("network-online.target") + client.wait_for_unit("NetworkManager.service") + + with subtest("Wait until we have an ip address on each interface"): + client.wait_until_succeeds("ip addr show dev eth1 | grep -q '192.168.1'") + client.wait_until_succeeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'") + + with subtest("Test if icmp echo works"): + client.wait_until_succeeds("ping -c 1 192.168.3.1") + client.wait_until_succeeds("ping -c 1 fd00:1234:5678:3::1") + router.wait_until_succeeds("ping -c 1 192.168.1.42") + router.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::42") + ''; + }; + auto = { + name = "auto"; + nodes = { + inherit router; + client = clientConfig { + networking.networkmanager.ensureProfiles.profiles.default = { + ipv4.method = "auto"; + ipv6.method = "auto"; + }; + }; + }; + testScript = '' + start_all() + router.wait_for_unit("network-online.target") + client.wait_for_unit("NetworkManager.service") + + with subtest("Wait until we have an ip address on each interface"): + client.wait_until_succeeds("ip addr show dev eth1 | grep -q '192.168.1'") + client.wait_until_succeeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'") + + with subtest("Test if icmp echo works"): + client.wait_until_succeeds("ping -c 1 192.168.1.1") + client.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::1") + router.wait_until_succeeds("ping -c 1 192.168.1.2") + router.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::2") + ''; + }; + dns = { + name = "dns"; + nodes = { + inherit router; + dynamic = clientConfig { + networking.networkmanager.ensureProfiles.profiles.default = { + ipv4.method = "auto"; + }; + }; + static = clientConfig { + networking.networkmanager.ensureProfiles.profiles.default = { + ipv4 = { + method = "auto"; + ignore-auto-dns = "true"; + dns = "10.10.10.10"; + dns-search = ""; + }; + }; + }; + }; + testScript = '' + start_all() + router.wait_for_unit("network-online.target") + dynamic.wait_for_unit("NetworkManager.service") + static.wait_for_unit("NetworkManager.service") + + dynamic.wait_until_succeeds("cat /etc/resolv.conf | grep -q '192.168.1.1'") + static.wait_until_succeeds("cat /etc/resolv.conf | grep -q '10.10.10.10'") + static.wait_until_fails("cat /etc/resolv.conf | grep -q '192.168.1.1'") + ''; + }; + dispatcherScripts = { + name = "dispatcherScripts"; + nodes.client = clientConfig { + networking.networkmanager.dispatcherScripts = [{ + type = "pre-up"; + source = pkgs.writeText "testHook" '' + touch /tmp/dispatcher-scripts-are-working + ''; + }]; + }; + testScript = '' + start_all() + client.wait_for_unit("NetworkManager.service") + client.wait_until_succeeds("stat /tmp/dispatcher-scripts-are-working") + ''; + }; + envsubst = { + name = "envsubst"; + nodes.client = let + # you should never write secrets in to your nixos configuration, please use tools like sops-nix or agenix + secretFile = pkgs.writeText "my-secret.env" '' + MY_SECRET_IP=fd00:1234:5678:1::23/64 + ''; + in clientConfig { + networking.networkmanager.ensureProfiles.environmentFiles = [ secretFile ]; + networking.networkmanager.ensureProfiles.profiles.default = { + ipv6.method = "manual"; + ipv6.addresses = "$MY_SECRET_IP"; + }; + }; + testScript = '' + start_all() + client.wait_for_unit("NetworkManager.service") + client.wait_until_succeeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'") + client.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::23") + ''; + }; + }; +in lib.mapAttrs (lib.const (attrs: makeTest (attrs // { + name = "${attrs.name}-Networking-NetworkManager"; + meta = { + maintainers = with lib.maintainers; [ janik ]; + }; + +}))) testCases