Migrate my NixOS tests to runTest (#388795)
This commit is contained in:
@@ -190,7 +190,7 @@ in {
|
||||
avahi = handleTest ./avahi.nix {};
|
||||
avahi-with-resolved = handleTest ./avahi.nix { networkd = true; };
|
||||
ayatana-indicators = runTest ./ayatana-indicators.nix;
|
||||
babeld = handleTest ./babeld.nix {};
|
||||
babeld = runTest ./babeld.nix;
|
||||
bazarr = handleTest ./bazarr.nix {};
|
||||
bcachefs = handleTestOn ["x86_64-linux" "aarch64-linux"] ./bcachefs.nix {};
|
||||
beanstalkd = handleTest ./beanstalkd.nix {};
|
||||
@@ -212,7 +212,7 @@ in {
|
||||
boot-stage2 = handleTest ./boot-stage2.nix {};
|
||||
borgbackup = handleTest ./borgbackup.nix {};
|
||||
borgmatic = handleTest ./borgmatic.nix {};
|
||||
botamusique = handleTest ./botamusique.nix {};
|
||||
botamusique = runTest ./botamusique.nix;
|
||||
bpf = handleTestOn ["x86_64-linux" "aarch64-linux"] ./bpf.nix {};
|
||||
bpftune = handleTest ./bpftune.nix {};
|
||||
breitbandmessung = handleTest ./breitbandmessung.nix {};
|
||||
@@ -460,7 +460,7 @@ in {
|
||||
gnupg = handleTest ./gnupg.nix {};
|
||||
goatcounter = handleTest ./goatcounter.nix {};
|
||||
go-camo = handleTest ./go-camo.nix { };
|
||||
go-neb = handleTest ./go-neb.nix {};
|
||||
go-neb = runTest ./go-neb.nix;
|
||||
gobgpd = handleTest ./gobgpd.nix {};
|
||||
gocd-agent = handleTest ./gocd-agent.nix {};
|
||||
gocd-server = handleTest ./gocd-server.nix {};
|
||||
@@ -575,7 +575,7 @@ in {
|
||||
kavita = handleTest ./kavita.nix {};
|
||||
kbd-setfont-decompress = handleTest ./kbd-setfont-decompress.nix {};
|
||||
kbd-update-search-paths-patch = handleTest ./kbd-update-search-paths-patch.nix {};
|
||||
kea = handleTest ./kea.nix {};
|
||||
kea = runTest ./kea.nix;
|
||||
keepalived = handleTest ./keepalived.nix {};
|
||||
keepassxc = handleTest ./keepassxc.nix {};
|
||||
kerberos = handleTest ./kerberos/default.nix {};
|
||||
@@ -589,7 +589,7 @@ in {
|
||||
keymap = handleTest ./keymap.nix {};
|
||||
kimai = handleTest ./kimai.nix {};
|
||||
kmonad = runTest ./kmonad.nix;
|
||||
knot = handleTest ./knot.nix {};
|
||||
knot = runTest ./knot.nix;
|
||||
komga = handleTest ./komga.nix {};
|
||||
krb5 = discoverTests (import ./krb5);
|
||||
ksm = handleTest ./ksm.nix {};
|
||||
@@ -903,7 +903,7 @@ in {
|
||||
phylactery = handleTest ./web-apps/phylactery.nix {};
|
||||
pict-rs = handleTest ./pict-rs.nix {};
|
||||
pingvin-share = handleTest ./pingvin-share.nix {} ;
|
||||
pinnwand = handleTest ./pinnwand.nix {};
|
||||
pinnwand = runTest ./pinnwand.nix;
|
||||
plantuml-server = handleTest ./plantuml-server.nix {};
|
||||
plasma-bigscreen = handleTest ./plasma-bigscreen.nix {};
|
||||
plasma5 = handleTest ./plasma5.nix {};
|
||||
@@ -1036,7 +1036,7 @@ in {
|
||||
slurm = handleTest ./slurm.nix {};
|
||||
snmpd = handleTest ./snmpd.nix {};
|
||||
smokeping = handleTest ./smokeping.nix {};
|
||||
snapcast = handleTest ./snapcast.nix {};
|
||||
snapcast = runTest ./snapcast.nix;
|
||||
snapper = handleTest ./snapper.nix {};
|
||||
snipe-it = runTest ./web-apps/snipe-it.nix;
|
||||
soapui = handleTest ./soapui.nix {};
|
||||
|
||||
+185
-184
@@ -1,210 +1,211 @@
|
||||
import ./make-test-python.nix (
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
name = "babeld";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ hexa ];
|
||||
};
|
||||
{
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
name = "babeld";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ hexa ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
client =
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
virtualisation.vlans = [ 10 ];
|
||||
nodes = {
|
||||
client =
|
||||
{ lib, ... }:
|
||||
{
|
||||
virtualisation.vlans = [ 10 ];
|
||||
|
||||
networking = {
|
||||
useDHCP = false;
|
||||
interfaces."eth1" = {
|
||||
ipv4.addresses = lib.mkForce [
|
||||
{
|
||||
address = "192.168.10.2";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv4.routes = lib.mkForce [
|
||||
{
|
||||
address = "0.0.0.0";
|
||||
prefixLength = 0;
|
||||
via = "192.168.10.1";
|
||||
}
|
||||
];
|
||||
ipv6.addresses = lib.mkForce [
|
||||
{
|
||||
address = "2001:db8:10::2";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
ipv6.routes = lib.mkForce [
|
||||
{
|
||||
address = "::";
|
||||
prefixLength = 0;
|
||||
via = "2001:db8:10::1";
|
||||
}
|
||||
];
|
||||
};
|
||||
networking = {
|
||||
useDHCP = false;
|
||||
interfaces."eth1" = {
|
||||
ipv4.addresses = lib.mkForce [
|
||||
{
|
||||
address = "192.168.10.2";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv4.routes = lib.mkForce [
|
||||
{
|
||||
address = "0.0.0.0";
|
||||
prefixLength = 0;
|
||||
via = "192.168.10.1";
|
||||
}
|
||||
];
|
||||
ipv6.addresses = lib.mkForce [
|
||||
{
|
||||
address = "2001:db8:10::2";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
ipv6.routes = lib.mkForce [
|
||||
{
|
||||
address = "::";
|
||||
prefixLength = 0;
|
||||
via = "2001:db8:10::1";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
local_router =
|
||||
{ lib, ... }:
|
||||
{
|
||||
virtualisation.vlans = [
|
||||
10
|
||||
20
|
||||
];
|
||||
|
||||
networking = {
|
||||
useDHCP = false;
|
||||
firewall.enable = false;
|
||||
|
||||
interfaces."eth1" = {
|
||||
ipv4.addresses = lib.mkForce [
|
||||
{
|
||||
address = "192.168.10.1";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = lib.mkForce [
|
||||
{
|
||||
address = "2001:db8:10::1";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
interfaces."eth2" = {
|
||||
ipv4.addresses = lib.mkForce [
|
||||
{
|
||||
address = "192.168.20.1";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = lib.mkForce [
|
||||
{
|
||||
address = "2001:db8:20::1";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
local_router =
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
virtualisation.vlans = [
|
||||
10
|
||||
20
|
||||
];
|
||||
services.babeld = {
|
||||
enable = true;
|
||||
interfaces.eth2 = {
|
||||
hello-interval = 1;
|
||||
type = "wired";
|
||||
};
|
||||
extraConfig = ''
|
||||
local-port-readwrite 33123
|
||||
|
||||
networking = {
|
||||
useDHCP = false;
|
||||
firewall.enable = false;
|
||||
import-table 254 # main
|
||||
export-table 254 # main
|
||||
|
||||
interfaces."eth1" = {
|
||||
ipv4.addresses = lib.mkForce [
|
||||
{
|
||||
address = "192.168.10.1";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = lib.mkForce [
|
||||
{
|
||||
address = "2001:db8:10::1";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
};
|
||||
in ip 192.168.10.0/24 deny
|
||||
in ip 192.168.20.0/24 deny
|
||||
in ip 2001:db8:10::/64 deny
|
||||
in ip 2001:db8:20::/64 deny
|
||||
|
||||
interfaces."eth2" = {
|
||||
ipv4.addresses = lib.mkForce [
|
||||
{
|
||||
address = "192.168.20.1";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = lib.mkForce [
|
||||
{
|
||||
address = "2001:db8:20::1";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
};
|
||||
in ip 192.168.30.0/24 allow
|
||||
in ip 2001:db8:30::/64 allow
|
||||
|
||||
in deny
|
||||
|
||||
redistribute local proto 2
|
||||
redistribute local deny
|
||||
'';
|
||||
};
|
||||
};
|
||||
remote_router =
|
||||
{ lib, ... }:
|
||||
{
|
||||
virtualisation.vlans = [
|
||||
20
|
||||
30
|
||||
];
|
||||
|
||||
networking = {
|
||||
useDHCP = false;
|
||||
firewall.enable = false;
|
||||
|
||||
interfaces."eth1" = {
|
||||
ipv4.addresses = lib.mkForce [
|
||||
{
|
||||
address = "192.168.20.2";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = lib.mkForce [
|
||||
{
|
||||
address = "2001:db8:20::2";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
services.babeld = {
|
||||
enable = true;
|
||||
interfaces.eth2 = {
|
||||
hello-interval = 1;
|
||||
type = "wired";
|
||||
};
|
||||
extraConfig = ''
|
||||
local-port-readwrite 33123
|
||||
|
||||
import-table 254 # main
|
||||
export-table 254 # main
|
||||
|
||||
in ip 192.168.10.0/24 deny
|
||||
in ip 192.168.20.0/24 deny
|
||||
in ip 2001:db8:10::/64 deny
|
||||
in ip 2001:db8:20::/64 deny
|
||||
|
||||
in ip 192.168.30.0/24 allow
|
||||
in ip 2001:db8:30::/64 allow
|
||||
|
||||
in deny
|
||||
|
||||
redistribute local proto 2
|
||||
redistribute local deny
|
||||
'';
|
||||
interfaces."eth2" = {
|
||||
ipv4.addresses = lib.mkForce [
|
||||
{
|
||||
address = "192.168.30.1";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = lib.mkForce [
|
||||
{
|
||||
address = "2001:db8:30::1";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
remote_router =
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
virtualisation.vlans = [
|
||||
20
|
||||
30
|
||||
];
|
||||
|
||||
networking = {
|
||||
useDHCP = false;
|
||||
firewall.enable = false;
|
||||
|
||||
interfaces."eth1" = {
|
||||
ipv4.addresses = lib.mkForce [
|
||||
{
|
||||
address = "192.168.20.2";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = lib.mkForce [
|
||||
{
|
||||
address = "2001:db8:20::2";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
interfaces."eth2" = {
|
||||
ipv4.addresses = lib.mkForce [
|
||||
{
|
||||
address = "192.168.30.1";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = lib.mkForce [
|
||||
{
|
||||
address = "2001:db8:30::1";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
};
|
||||
services.babeld = {
|
||||
enable = true;
|
||||
interfaces.eth1 = {
|
||||
hello-interval = 1;
|
||||
type = "wired";
|
||||
};
|
||||
extraConfig = ''
|
||||
local-port-readwrite 33123
|
||||
|
||||
services.babeld = {
|
||||
enable = true;
|
||||
interfaces.eth1 = {
|
||||
hello-interval = 1;
|
||||
type = "wired";
|
||||
};
|
||||
extraConfig = ''
|
||||
local-port-readwrite 33123
|
||||
import-table 254 # main
|
||||
export-table 254 # main
|
||||
|
||||
import-table 254 # main
|
||||
export-table 254 # main
|
||||
in ip 192.168.20.0/24 deny
|
||||
in ip 192.168.30.0/24 deny
|
||||
in ip 2001:db8:20::/64 deny
|
||||
in ip 2001:db8:30::/64 deny
|
||||
|
||||
in ip 192.168.20.0/24 deny
|
||||
in ip 192.168.30.0/24 deny
|
||||
in ip 2001:db8:20::/64 deny
|
||||
in ip 2001:db8:30::/64 deny
|
||||
in ip 192.168.10.0/24 allow
|
||||
in ip 2001:db8:10::/64 allow
|
||||
|
||||
in ip 192.168.10.0/24 allow
|
||||
in ip 2001:db8:10::/64 allow
|
||||
|
||||
in deny
|
||||
|
||||
redistribute local proto 2
|
||||
redistribute local deny
|
||||
'';
|
||||
};
|
||||
in deny
|
||||
|
||||
redistribute local proto 2
|
||||
redistribute local deny
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
};
|
||||
};
|
||||
|
||||
local_router.wait_for_unit("babeld.service")
|
||||
remote_router.wait_for_unit("babeld.service")
|
||||
testScript = ''
|
||||
start_all()
|
||||
|
||||
local_router.wait_until_succeeds("ip route get 192.168.30.1")
|
||||
local_router.wait_until_succeeds("ip route get 2001:db8:30::1")
|
||||
local_router.wait_for_unit("babeld.service")
|
||||
remote_router.wait_for_unit("babeld.service")
|
||||
|
||||
remote_router.wait_until_succeeds("ip route get 192.168.10.1")
|
||||
remote_router.wait_until_succeeds("ip route get 2001:db8:10::1")
|
||||
local_router.wait_until_succeeds("ip route get 192.168.30.1")
|
||||
local_router.wait_until_succeeds("ip route get 2001:db8:30::1")
|
||||
|
||||
client.succeed("ping -c1 192.168.30.1")
|
||||
client.succeed("ping -c1 2001:db8:30::1")
|
||||
remote_router.wait_until_succeeds("ip route get 192.168.10.1")
|
||||
remote_router.wait_until_succeeds("ip route get 2001:db8:10::1")
|
||||
|
||||
remote_router.succeed("ping -c1 192.168.10.2")
|
||||
remote_router.succeed("ping -c1 2001:db8:10::2")
|
||||
'';
|
||||
}
|
||||
)
|
||||
client.succeed("ping -c1 192.168.30.1")
|
||||
client.succeed("ping -c1 2001:db8:30::1")
|
||||
|
||||
remote_router.succeed("ping -c1 192.168.10.2")
|
||||
remote_router.succeed("ping -c1 2001:db8:10::2")
|
||||
'';
|
||||
}
|
||||
|
||||
+45
-43
@@ -1,55 +1,57 @@
|
||||
import ./make-test-python.nix (
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
name = "botamusique";
|
||||
meta.maintainers = with lib.maintainers; [ hexa ];
|
||||
{
|
||||
name = "botamusique";
|
||||
meta.maintainers = with lib.maintainers; [ hexa ];
|
||||
|
||||
nodes = {
|
||||
machine =
|
||||
{ config, ... }:
|
||||
{
|
||||
networking.extraHosts = ''
|
||||
127.0.0.1 all.api.radio-browser.info
|
||||
'';
|
||||
nodes = {
|
||||
machine =
|
||||
{ config, ... }:
|
||||
{
|
||||
networking.extraHosts = ''
|
||||
127.0.0.1 all.api.radio-browser.info
|
||||
'';
|
||||
|
||||
services.murmur = {
|
||||
enable = true;
|
||||
registerName = "NixOS tests";
|
||||
};
|
||||
services.murmur = {
|
||||
enable = true;
|
||||
registerName = "NixOS tests";
|
||||
};
|
||||
|
||||
services.botamusique = {
|
||||
enable = true;
|
||||
settings = {
|
||||
server = {
|
||||
channel = "NixOS tests";
|
||||
};
|
||||
bot = {
|
||||
version = false;
|
||||
auto_check_update = false;
|
||||
};
|
||||
services.botamusique = {
|
||||
enable = true;
|
||||
settings = {
|
||||
server = {
|
||||
channel = "NixOS tests";
|
||||
};
|
||||
bot = {
|
||||
version = false;
|
||||
auto_check_update = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
testScript = ''
|
||||
start_all()
|
||||
|
||||
machine.wait_for_unit("murmur.service")
|
||||
machine.wait_for_unit("botamusique.service")
|
||||
machine.wait_for_unit("murmur.service")
|
||||
machine.wait_for_unit("botamusique.service")
|
||||
|
||||
machine.sleep(10)
|
||||
machine.sleep(10)
|
||||
|
||||
machine.wait_until_succeeds(
|
||||
"journalctl -u murmur.service -e | grep -q '<1:botamusique(-1)> Authenticated'"
|
||||
)
|
||||
machine.wait_until_succeeds(
|
||||
"journalctl -u murmur.service -e | grep -q '<1:botamusique(-1)> Authenticated'"
|
||||
)
|
||||
|
||||
with subtest("Check systemd hardening"):
|
||||
output = machine.execute("systemctl show botamusique.service")[1]
|
||||
machine.log(output)
|
||||
output = machine.execute("systemd-analyze security botamusique.service")[1]
|
||||
machine.log(output)
|
||||
'';
|
||||
}
|
||||
)
|
||||
with subtest("Check systemd hardening"):
|
||||
output = machine.execute("systemctl show botamusique.service")[1]
|
||||
machine.log(output)
|
||||
output = machine.execute("systemd-analyze security botamusique.service")[1]
|
||||
machine.log(output)
|
||||
'';
|
||||
}
|
||||
|
||||
+48
-47
@@ -1,53 +1,54 @@
|
||||
import ./make-test-python.nix (
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
name = "go-neb";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [
|
||||
hexa
|
||||
maralorn
|
||||
];
|
||||
};
|
||||
{
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
name = "go-neb";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [
|
||||
hexa
|
||||
maralorn
|
||||
];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
server = {
|
||||
services.go-neb = {
|
||||
enable = true;
|
||||
baseUrl = "http://localhost";
|
||||
secretFile = pkgs.writeText "secrets" "ACCESS_TOKEN=changeme";
|
||||
config = {
|
||||
clients = [
|
||||
{
|
||||
UserId = "@test:localhost";
|
||||
AccessToken = "$ACCESS_TOKEN";
|
||||
HomeServerUrl = "http://localhost";
|
||||
Sync = false;
|
||||
AutoJoinRooms = false;
|
||||
DisplayName = "neverbeseen";
|
||||
}
|
||||
];
|
||||
services = [
|
||||
{
|
||||
ID = "wikipedia_service";
|
||||
Type = "wikipedia";
|
||||
UserID = "@test:localhost";
|
||||
Config = { };
|
||||
}
|
||||
];
|
||||
};
|
||||
nodes = {
|
||||
server = {
|
||||
services.go-neb = {
|
||||
enable = true;
|
||||
baseUrl = "http://localhost";
|
||||
secretFile = pkgs.writeText "secrets" "ACCESS_TOKEN=changeme";
|
||||
config = {
|
||||
clients = [
|
||||
{
|
||||
UserId = "@test:localhost";
|
||||
AccessToken = "$ACCESS_TOKEN";
|
||||
HomeServerUrl = "http://localhost";
|
||||
Sync = false;
|
||||
AutoJoinRooms = false;
|
||||
DisplayName = "neverbeseen";
|
||||
}
|
||||
];
|
||||
services = [
|
||||
{
|
||||
ID = "wikipedia_service";
|
||||
Type = "wikipedia";
|
||||
UserID = "@test:localhost";
|
||||
Config = { };
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
server.wait_for_unit("go-neb.service")
|
||||
server.wait_until_succeeds("curl -fL http://localhost:4050/services/hooks/d2lraXBlZGlhX3NlcnZpY2U")
|
||||
server.succeed(
|
||||
"journalctl -eu go-neb -o cat | grep -q service_id=wikipedia_service",
|
||||
"grep -q changeme /var/run/go-neb/config.yaml",
|
||||
)
|
||||
'';
|
||||
testScript = ''
|
||||
start_all()
|
||||
server.wait_for_unit("go-neb.service")
|
||||
server.wait_until_succeeds("curl -fL http://localhost:4050/services/hooks/d2lraXBlZGlhX3NlcnZpY2U")
|
||||
server.succeed(
|
||||
"journalctl -eu go-neb -o cat | grep -q service_id=wikipedia_service",
|
||||
"grep -q changeme /var/run/go-neb/config.yaml",
|
||||
)
|
||||
'';
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
+195
-193
@@ -5,231 +5,233 @@
|
||||
# that the nameserver can resolve the clients fqdn to the correct IP
|
||||
# address.
|
||||
|
||||
import ./make-test-python.nix (
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ hexa ];
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ hexa ];
|
||||
|
||||
name = "kea";
|
||||
name = "kea";
|
||||
|
||||
nodes = {
|
||||
router =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
virtualisation.vlans = [ 1 ];
|
||||
nodes = {
|
||||
router =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
virtualisation.vlans = [ 1 ];
|
||||
|
||||
networking = {
|
||||
useDHCP = false;
|
||||
firewall.allowedUDPPorts = [ 67 ];
|
||||
};
|
||||
networking = {
|
||||
useDHCP = false;
|
||||
firewall.allowedUDPPorts = [ 67 ];
|
||||
};
|
||||
|
||||
systemd.network = {
|
||||
enable = true;
|
||||
networks = {
|
||||
"01-eth1" = {
|
||||
name = "eth1";
|
||||
networkConfig = {
|
||||
Address = "10.0.0.1/29";
|
||||
};
|
||||
systemd.network = {
|
||||
enable = true;
|
||||
networks = {
|
||||
"01-eth1" = {
|
||||
name = "eth1";
|
||||
networkConfig = {
|
||||
Address = "10.0.0.1/29";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.kea.dhcp4 = {
|
||||
enable = true;
|
||||
settings = {
|
||||
valid-lifetime = 3600;
|
||||
renew-timer = 900;
|
||||
rebind-timer = 1800;
|
||||
services.kea.dhcp4 = {
|
||||
enable = true;
|
||||
settings = {
|
||||
valid-lifetime = 3600;
|
||||
renew-timer = 900;
|
||||
rebind-timer = 1800;
|
||||
|
||||
lease-database = {
|
||||
type = "memfile";
|
||||
persist = true;
|
||||
name = "/var/lib/kea/dhcp4.leases";
|
||||
};
|
||||
lease-database = {
|
||||
type = "memfile";
|
||||
persist = true;
|
||||
name = "/var/lib/kea/dhcp4.leases";
|
||||
};
|
||||
|
||||
control-socket = {
|
||||
socket-type = "unix";
|
||||
socket-name = "/run/kea/dhcp4.sock";
|
||||
};
|
||||
control-socket = {
|
||||
socket-type = "unix";
|
||||
socket-name = "/run/kea/dhcp4.sock";
|
||||
};
|
||||
|
||||
interfaces-config = {
|
||||
dhcp-socket-type = "raw";
|
||||
interfaces = [
|
||||
"eth1"
|
||||
interfaces-config = {
|
||||
dhcp-socket-type = "raw";
|
||||
interfaces = [
|
||||
"eth1"
|
||||
];
|
||||
};
|
||||
|
||||
subnet4 = [
|
||||
{
|
||||
id = 1;
|
||||
subnet = "10.0.0.0/29";
|
||||
pools = [
|
||||
{
|
||||
pool = "10.0.0.3 - 10.0.0.3";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
subnet4 = [
|
||||
# Enable communication between dhcp4 and a local dhcp-ddns
|
||||
# instance.
|
||||
# https://kea.readthedocs.io/en/kea-2.2.0/arm/dhcp4-srv.html#ddns-for-dhcpv4
|
||||
dhcp-ddns = {
|
||||
enable-updates = true;
|
||||
};
|
||||
|
||||
ddns-send-updates = true;
|
||||
ddns-qualifying-suffix = "lan.nixos.test.";
|
||||
};
|
||||
};
|
||||
|
||||
services.kea.dhcp-ddns = {
|
||||
enable = true;
|
||||
settings = {
|
||||
forward-ddns = {
|
||||
# Configure updates of a forward zone named `lan.nixos.test`
|
||||
# hosted at the nameserver at 10.0.0.2
|
||||
# https://kea.readthedocs.io/en/kea-2.2.0/arm/ddns.html#adding-forward-dns-servers
|
||||
ddns-domains = [
|
||||
{
|
||||
id = 1;
|
||||
subnet = "10.0.0.0/29";
|
||||
pools = [
|
||||
name = "lan.nixos.test.";
|
||||
# Use a TSIG key in production!
|
||||
key-name = "";
|
||||
dns-servers = [
|
||||
{
|
||||
pool = "10.0.0.3 - 10.0.0.3";
|
||||
ip-address = "10.0.0.2";
|
||||
port = 53;
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
# Enable communication between dhcp4 and a local dhcp-ddns
|
||||
# instance.
|
||||
# https://kea.readthedocs.io/en/kea-2.2.0/arm/dhcp4-srv.html#ddns-for-dhcpv4
|
||||
dhcp-ddns = {
|
||||
enable-updates = true;
|
||||
};
|
||||
|
||||
ddns-send-updates = true;
|
||||
ddns-qualifying-suffix = "lan.nixos.test.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.kea.dhcp-ddns = {
|
||||
enable = true;
|
||||
settings = {
|
||||
forward-ddns = {
|
||||
# Configure updates of a forward zone named `lan.nixos.test`
|
||||
# hosted at the nameserver at 10.0.0.2
|
||||
# https://kea.readthedocs.io/en/kea-2.2.0/arm/ddns.html#adding-forward-dns-servers
|
||||
ddns-domains = [
|
||||
{
|
||||
name = "lan.nixos.test.";
|
||||
# Use a TSIG key in production!
|
||||
key-name = "";
|
||||
dns-servers = [
|
||||
{
|
||||
ip-address = "10.0.0.2";
|
||||
port = 53;
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
services.kea.ctrl-agent = {
|
||||
enable = true;
|
||||
settings = {
|
||||
http-host = "127.0.0.1";
|
||||
http-port = 8000;
|
||||
control-sockets.dhcp4 = {
|
||||
socket-type = "unix";
|
||||
socket-name = "/run/kea/dhcp4.sock";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.prometheus.exporters.kea = {
|
||||
enable = true;
|
||||
controlSocketPaths = [
|
||||
"http://127.0.0.1:8000"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
nameserver =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
virtualisation.vlans = [ 1 ];
|
||||
|
||||
networking = {
|
||||
useDHCP = false;
|
||||
firewall.allowedUDPPorts = [ 53 ];
|
||||
};
|
||||
|
||||
systemd.network = {
|
||||
enable = true;
|
||||
networks = {
|
||||
"01-eth1" = {
|
||||
name = "eth1";
|
||||
networkConfig = {
|
||||
Address = "10.0.0.2/29";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.kea.ctrl-agent = {
|
||||
enable = true;
|
||||
settings = {
|
||||
http-host = "127.0.0.1";
|
||||
http-port = 8000;
|
||||
control-sockets.dhcp4 = {
|
||||
socket-type = "unix";
|
||||
socket-name = "/run/kea/dhcp4.sock";
|
||||
};
|
||||
services.resolved.enable = false;
|
||||
|
||||
# Set up an authoritative nameserver, serving the `lan.nixos.test`
|
||||
# zone and configure an ACL that allows dynamic updates from
|
||||
# the router's ip address.
|
||||
# This ACL is likely insufficient for production usage. Please
|
||||
# use TSIG keys.
|
||||
services.knot =
|
||||
let
|
||||
zone = pkgs.writeTextDir "lan.nixos.test.zone" ''
|
||||
@ SOA ns.nixos.test nox.nixos.test 0 86400 7200 3600000 172800
|
||||
@ NS nameserver
|
||||
nameserver A 10.0.0.3
|
||||
router A 10.0.0.1
|
||||
'';
|
||||
zonesDir = pkgs.buildEnv {
|
||||
name = "knot-zones";
|
||||
paths = [ zone ];
|
||||
};
|
||||
};
|
||||
|
||||
services.prometheus.exporters.kea = {
|
||||
in
|
||||
{
|
||||
enable = true;
|
||||
controlSocketPaths = [
|
||||
"http://127.0.0.1:8000"
|
||||
extraArgs = [
|
||||
"-v"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
nameserver =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
virtualisation.vlans = [ 1 ];
|
||||
|
||||
networking = {
|
||||
useDHCP = false;
|
||||
firewall.allowedUDPPorts = [ 53 ];
|
||||
};
|
||||
|
||||
systemd.network = {
|
||||
enable = true;
|
||||
networks = {
|
||||
"01-eth1" = {
|
||||
name = "eth1";
|
||||
networkConfig = {
|
||||
Address = "10.0.0.2/29";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.resolved.enable = false;
|
||||
|
||||
# Set up an authoritative nameserver, serving the `lan.nixos.test`
|
||||
# zone and configure an ACL that allows dynamic updates from
|
||||
# the router's ip address.
|
||||
# This ACL is likely insufficient for production usage. Please
|
||||
# use TSIG keys.
|
||||
services.knot =
|
||||
let
|
||||
zone = pkgs.writeTextDir "lan.nixos.test.zone" ''
|
||||
@ SOA ns.nixos.test nox.nixos.test 0 86400 7200 3600000 172800
|
||||
@ NS nameserver
|
||||
nameserver A 10.0.0.3
|
||||
router A 10.0.0.1
|
||||
'';
|
||||
zonesDir = pkgs.buildEnv {
|
||||
name = "knot-zones";
|
||||
paths = [ zone ];
|
||||
};
|
||||
in
|
||||
{
|
||||
enable = true;
|
||||
extraArgs = [
|
||||
"-v"
|
||||
settings = {
|
||||
server.listen = [
|
||||
"0.0.0.0@53"
|
||||
];
|
||||
settings = {
|
||||
server.listen = [
|
||||
"0.0.0.0@53"
|
||||
|
||||
log.syslog.any = "info";
|
||||
|
||||
acl.dhcp_ddns = {
|
||||
address = "10.0.0.1";
|
||||
action = "update";
|
||||
};
|
||||
|
||||
template.default = {
|
||||
storage = zonesDir;
|
||||
zonefile-sync = "-1";
|
||||
zonefile-load = "difference-no-serial";
|
||||
journal-content = "all";
|
||||
};
|
||||
|
||||
zone."lan.nixos.test" = {
|
||||
file = "lan.nixos.test.zone";
|
||||
acl = [
|
||||
"dhcp_ddns"
|
||||
];
|
||||
|
||||
log.syslog.any = "info";
|
||||
|
||||
acl.dhcp_ddns = {
|
||||
address = "10.0.0.1";
|
||||
action = "update";
|
||||
};
|
||||
|
||||
template.default = {
|
||||
storage = zonesDir;
|
||||
zonefile-sync = "-1";
|
||||
zonefile-load = "difference-no-serial";
|
||||
journal-content = "all";
|
||||
};
|
||||
|
||||
zone."lan.nixos.test" = {
|
||||
file = "lan.nixos.test.zone";
|
||||
acl = [
|
||||
"dhcp_ddns"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
client =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
virtualisation.vlans = [ 1 ];
|
||||
systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug";
|
||||
networking = {
|
||||
useNetworkd = true;
|
||||
useDHCP = false;
|
||||
firewall.enable = false;
|
||||
interfaces.eth1.useDHCP = true;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
client =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
virtualisation.vlans = [ 1 ];
|
||||
systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug";
|
||||
networking = {
|
||||
useNetworkd = true;
|
||||
useDHCP = false;
|
||||
firewall.enable = false;
|
||||
interfaces.eth1.useDHCP = true;
|
||||
};
|
||||
};
|
||||
testScript =
|
||||
{ ... }:
|
||||
''
|
||||
start_all()
|
||||
router.wait_for_unit("kea-dhcp4-server.service")
|
||||
client.systemctl("start systemd-networkd-wait-online.service")
|
||||
client.wait_for_unit("systemd-networkd-wait-online.service")
|
||||
client.wait_until_succeeds("ping -c 5 10.0.0.1")
|
||||
router.wait_until_succeeds("ping -c 5 10.0.0.3")
|
||||
nameserver.wait_until_succeeds("kdig +short client.lan.nixos.test @10.0.0.2 | grep -q 10.0.0.3")
|
||||
router.log(router.execute("curl 127.0.0.1:9547")[1])
|
||||
router.succeed("curl --no-buffer 127.0.0.1:9547 | grep -qE '^kea_dhcp4_addresses_assigned_total.*1.0$'")
|
||||
'';
|
||||
}
|
||||
)
|
||||
};
|
||||
};
|
||||
testScript =
|
||||
{ ... }:
|
||||
''
|
||||
start_all()
|
||||
router.wait_for_unit("kea-dhcp4-server.service")
|
||||
client.systemctl("start systemd-networkd-wait-online.service")
|
||||
client.wait_for_unit("systemd-networkd-wait-online.service")
|
||||
client.wait_until_succeeds("ping -c 5 10.0.0.1")
|
||||
router.wait_until_succeeds("ping -c 5 10.0.0.3")
|
||||
nameserver.wait_until_succeeds("kdig +short client.lan.nixos.test @10.0.0.2 | grep -q 10.0.0.3")
|
||||
router.log(router.execute("curl 127.0.0.1:9547")[1])
|
||||
router.succeed("curl --no-buffer 127.0.0.1:9547 | grep -qE '^kea_dhcp4_addresses_assigned_total.*1.0$'")
|
||||
'';
|
||||
}
|
||||
|
||||
+229
-227
@@ -1,254 +1,256 @@
|
||||
import ./make-test-python.nix (
|
||||
{ pkgs, lib, ... }:
|
||||
let
|
||||
common = {
|
||||
networking.firewall.enable = false;
|
||||
networking.useDHCP = false;
|
||||
};
|
||||
exampleZone = pkgs.writeTextDir "example.com.zone" ''
|
||||
@ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800
|
||||
@ NS ns1
|
||||
@ NS ns2
|
||||
ns1 A 192.168.0.1
|
||||
ns1 AAAA fd00::1
|
||||
ns2 A 192.168.0.2
|
||||
ns2 AAAA fd00::2
|
||||
www A 192.0.2.1
|
||||
www AAAA 2001:DB8::1
|
||||
sub NS ns.example.com.
|
||||
'';
|
||||
delegatedZone = pkgs.writeTextDir "sub.example.com.zone" ''
|
||||
@ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800
|
||||
@ NS ns1.example.com.
|
||||
@ NS ns2.example.com.
|
||||
@ A 192.0.2.2
|
||||
@ AAAA 2001:DB8::2
|
||||
'';
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
common = {
|
||||
networking.firewall.enable = false;
|
||||
networking.useDHCP = false;
|
||||
};
|
||||
exampleZone = pkgs.writeTextDir "example.com.zone" ''
|
||||
@ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800
|
||||
@ NS ns1
|
||||
@ NS ns2
|
||||
ns1 A 192.168.0.1
|
||||
ns1 AAAA fd00::1
|
||||
ns2 A 192.168.0.2
|
||||
ns2 AAAA fd00::2
|
||||
www A 192.0.2.1
|
||||
www AAAA 2001:DB8::1
|
||||
sub NS ns.example.com.
|
||||
'';
|
||||
delegatedZone = pkgs.writeTextDir "sub.example.com.zone" ''
|
||||
@ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800
|
||||
@ NS ns1.example.com.
|
||||
@ NS ns2.example.com.
|
||||
@ A 192.0.2.2
|
||||
@ AAAA 2001:DB8::2
|
||||
'';
|
||||
|
||||
knotZonesEnv = pkgs.buildEnv {
|
||||
name = "knot-zones";
|
||||
paths = [
|
||||
exampleZone
|
||||
delegatedZone
|
||||
];
|
||||
};
|
||||
# DO NOT USE pkgs.writeText IN PRODUCTION. This put secrets in the nix store!
|
||||
tsigFile = pkgs.writeText "tsig.conf" ''
|
||||
key:
|
||||
- id: xfr_key
|
||||
algorithm: hmac-sha256
|
||||
secret: zOYgOgnzx3TGe5J5I/0kxd7gTcxXhLYMEq3Ek3fY37s=
|
||||
'';
|
||||
in
|
||||
{
|
||||
name = "knot";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ hexa ];
|
||||
};
|
||||
knotZonesEnv = pkgs.buildEnv {
|
||||
name = "knot-zones";
|
||||
paths = [
|
||||
exampleZone
|
||||
delegatedZone
|
||||
];
|
||||
};
|
||||
# DO NOT USE pkgs.writeText IN PRODUCTION. This put secrets in the nix store!
|
||||
tsigFile = pkgs.writeText "tsig.conf" ''
|
||||
key:
|
||||
- id: xfr_key
|
||||
algorithm: hmac-sha256
|
||||
secret: zOYgOgnzx3TGe5J5I/0kxd7gTcxXhLYMEq3Ek3fY37s=
|
||||
'';
|
||||
in
|
||||
{
|
||||
name = "knot";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ hexa ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
primary =
|
||||
{ lib, ... }:
|
||||
{
|
||||
imports = [ common ];
|
||||
nodes = {
|
||||
primary =
|
||||
{ lib, ... }:
|
||||
{
|
||||
imports = [ common ];
|
||||
|
||||
# trigger sched_setaffinity syscall
|
||||
virtualisation.cores = 2;
|
||||
# trigger sched_setaffinity syscall
|
||||
virtualisation.cores = 2;
|
||||
|
||||
networking.interfaces.eth1 = {
|
||||
ipv4.addresses = lib.mkForce [
|
||||
{
|
||||
address = "192.168.0.1";
|
||||
prefixLength = 24;
|
||||
}
|
||||
networking.interfaces.eth1 = {
|
||||
ipv4.addresses = lib.mkForce [
|
||||
{
|
||||
address = "192.168.0.1";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = lib.mkForce [
|
||||
{
|
||||
address = "fd00::1";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
};
|
||||
services.knot.enable = true;
|
||||
services.knot.extraArgs = [ "-v" ];
|
||||
services.knot.keyFiles = [ tsigFile ];
|
||||
services.knot.settings = {
|
||||
server = {
|
||||
listen = [
|
||||
"0.0.0.0@53"
|
||||
"::@53"
|
||||
];
|
||||
ipv6.addresses = lib.mkForce [
|
||||
{
|
||||
address = "fd00::1";
|
||||
prefixLength = 64;
|
||||
}
|
||||
listen-quic = [
|
||||
"0.0.0.0@853"
|
||||
"::@853"
|
||||
];
|
||||
automatic-acl = true;
|
||||
};
|
||||
services.knot.enable = true;
|
||||
services.knot.extraArgs = [ "-v" ];
|
||||
services.knot.keyFiles = [ tsigFile ];
|
||||
services.knot.settings = {
|
||||
server = {
|
||||
listen = [
|
||||
"0.0.0.0@53"
|
||||
"::@53"
|
||||
];
|
||||
listen-quic = [
|
||||
"0.0.0.0@853"
|
||||
"::@853"
|
||||
];
|
||||
automatic-acl = true;
|
||||
};
|
||||
|
||||
acl.secondary_acl = {
|
||||
acl.secondary_acl = {
|
||||
address = "192.168.0.2";
|
||||
key = "xfr_key";
|
||||
action = "transfer";
|
||||
};
|
||||
|
||||
remote.secondary.address = "192.168.0.2@53";
|
||||
|
||||
template.default = {
|
||||
storage = knotZonesEnv;
|
||||
notify = [ "secondary" ];
|
||||
acl = [ "secondary_acl" ];
|
||||
dnssec-signing = true;
|
||||
# Input-only zone files
|
||||
# https://www.knot-dns.cz/docs/2.8/html/operation.html#example-3
|
||||
# prevents modification of the zonefiles, since the zonefiles are immutable
|
||||
zonefile-sync = -1;
|
||||
zonefile-load = "difference";
|
||||
journal-content = "changes";
|
||||
};
|
||||
|
||||
zone = {
|
||||
"example.com".file = "example.com.zone";
|
||||
"sub.example.com".file = "sub.example.com.zone";
|
||||
};
|
||||
|
||||
log.syslog.any = "info";
|
||||
};
|
||||
};
|
||||
|
||||
secondary =
|
||||
{ lib, ... }:
|
||||
{
|
||||
imports = [ common ];
|
||||
networking.interfaces.eth1 = {
|
||||
ipv4.addresses = lib.mkForce [
|
||||
{
|
||||
address = "192.168.0.2";
|
||||
key = "xfr_key";
|
||||
action = "transfer";
|
||||
};
|
||||
|
||||
remote.secondary.address = "192.168.0.2@53";
|
||||
|
||||
template.default = {
|
||||
storage = knotZonesEnv;
|
||||
notify = [ "secondary" ];
|
||||
acl = [ "secondary_acl" ];
|
||||
dnssec-signing = true;
|
||||
# Input-only zone files
|
||||
# https://www.knot-dns.cz/docs/2.8/html/operation.html#example-3
|
||||
# prevents modification of the zonefiles, since the zonefiles are immutable
|
||||
zonefile-sync = -1;
|
||||
zonefile-load = "difference";
|
||||
journal-content = "changes";
|
||||
};
|
||||
|
||||
zone = {
|
||||
"example.com".file = "example.com.zone";
|
||||
"sub.example.com".file = "sub.example.com.zone";
|
||||
};
|
||||
|
||||
log.syslog.any = "info";
|
||||
};
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = lib.mkForce [
|
||||
{
|
||||
address = "fd00::2";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
secondary =
|
||||
{ lib, ... }:
|
||||
{
|
||||
imports = [ common ];
|
||||
networking.interfaces.eth1 = {
|
||||
ipv4.addresses = lib.mkForce [
|
||||
{
|
||||
address = "192.168.0.2";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = lib.mkForce [
|
||||
{
|
||||
address = "fd00::2";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
services.knot.enable = true;
|
||||
services.knot.keyFiles = [ tsigFile ];
|
||||
services.knot.extraArgs = [ "-v" ];
|
||||
services.knot.settings = {
|
||||
server = {
|
||||
automatic-acl = true;
|
||||
};
|
||||
services.knot.enable = true;
|
||||
services.knot.keyFiles = [ tsigFile ];
|
||||
services.knot.extraArgs = [ "-v" ];
|
||||
services.knot.settings = {
|
||||
server = {
|
||||
automatic-acl = true;
|
||||
};
|
||||
|
||||
xdp = {
|
||||
listen = [
|
||||
"eth1"
|
||||
];
|
||||
tcp = true;
|
||||
};
|
||||
|
||||
remote.primary = {
|
||||
address = "192.168.0.1@53";
|
||||
key = "xfr_key";
|
||||
};
|
||||
|
||||
remote.primary-quic = {
|
||||
address = "192.168.0.1@853";
|
||||
key = "xfr_key";
|
||||
quic = true;
|
||||
};
|
||||
|
||||
template.default = {
|
||||
# zonefileless setup
|
||||
# https://www.knot-dns.cz/docs/2.8/html/operation.html#example-2
|
||||
zonefile-sync = "-1";
|
||||
zonefile-load = "none";
|
||||
journal-content = "all";
|
||||
};
|
||||
|
||||
zone = {
|
||||
"example.com" = {
|
||||
master = "primary";
|
||||
file = "example.com.zone";
|
||||
};
|
||||
"sub.example.com" = {
|
||||
master = "primary-quic";
|
||||
file = "sub.example.com.zone";
|
||||
};
|
||||
};
|
||||
|
||||
log.syslog.any = "debug";
|
||||
xdp = {
|
||||
listen = [
|
||||
"eth1"
|
||||
];
|
||||
tcp = true;
|
||||
};
|
||||
|
||||
remote.primary = {
|
||||
address = "192.168.0.1@53";
|
||||
key = "xfr_key";
|
||||
};
|
||||
|
||||
remote.primary-quic = {
|
||||
address = "192.168.0.1@853";
|
||||
key = "xfr_key";
|
||||
quic = true;
|
||||
};
|
||||
|
||||
template.default = {
|
||||
# zonefileless setup
|
||||
# https://www.knot-dns.cz/docs/2.8/html/operation.html#example-2
|
||||
zonefile-sync = "-1";
|
||||
zonefile-load = "none";
|
||||
journal-content = "all";
|
||||
};
|
||||
|
||||
zone = {
|
||||
"example.com" = {
|
||||
master = "primary";
|
||||
file = "example.com.zone";
|
||||
};
|
||||
"sub.example.com" = {
|
||||
master = "primary-quic";
|
||||
file = "sub.example.com.zone";
|
||||
};
|
||||
};
|
||||
|
||||
log.syslog.any = "debug";
|
||||
};
|
||||
client =
|
||||
{ lib, nodes, ... }:
|
||||
{
|
||||
imports = [ common ];
|
||||
networking.interfaces.eth1 = {
|
||||
ipv4.addresses = [
|
||||
{
|
||||
address = "192.168.0.3";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = [
|
||||
{
|
||||
address = "fd00::3";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
};
|
||||
environment.systemPackages = [ pkgs.knot-dns ];
|
||||
};
|
||||
client =
|
||||
{ lib, nodes, ... }:
|
||||
{
|
||||
imports = [ common ];
|
||||
networking.interfaces.eth1 = {
|
||||
ipv4.addresses = [
|
||||
{
|
||||
address = "192.168.0.3";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = [
|
||||
{
|
||||
address = "fd00::3";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
environment.systemPackages = [ pkgs.knot-dns ];
|
||||
};
|
||||
};
|
||||
|
||||
testScript =
|
||||
{ nodes, ... }:
|
||||
let
|
||||
primary4 = (lib.head nodes.primary.config.networking.interfaces.eth1.ipv4.addresses).address;
|
||||
primary6 = (lib.head nodes.primary.config.networking.interfaces.eth1.ipv6.addresses).address;
|
||||
testScript =
|
||||
{ nodes, ... }:
|
||||
let
|
||||
primary4 = (lib.head nodes.primary.config.networking.interfaces.eth1.ipv4.addresses).address;
|
||||
primary6 = (lib.head nodes.primary.config.networking.interfaces.eth1.ipv6.addresses).address;
|
||||
|
||||
secondary4 = (lib.head nodes.secondary.config.networking.interfaces.eth1.ipv4.addresses).address;
|
||||
secondary6 = (lib.head nodes.secondary.config.networking.interfaces.eth1.ipv6.addresses).address;
|
||||
in
|
||||
''
|
||||
import re
|
||||
secondary4 = (lib.head nodes.secondary.config.networking.interfaces.eth1.ipv4.addresses).address;
|
||||
secondary6 = (lib.head nodes.secondary.config.networking.interfaces.eth1.ipv6.addresses).address;
|
||||
in
|
||||
''
|
||||
import re
|
||||
|
||||
start_all()
|
||||
start_all()
|
||||
|
||||
client.wait_for_unit("network.target")
|
||||
primary.wait_for_unit("knot.service")
|
||||
secondary.wait_for_unit("knot.service")
|
||||
client.wait_for_unit("network.target")
|
||||
primary.wait_for_unit("knot.service")
|
||||
secondary.wait_for_unit("knot.service")
|
||||
|
||||
for zone in ("example.com.", "sub.example.com."):
|
||||
secondary.wait_until_succeeds(
|
||||
f"knotc zone-status {zone} | grep -q 'serial: 2019031302'"
|
||||
)
|
||||
for zone in ("example.com.", "sub.example.com."):
|
||||
secondary.wait_until_succeeds(
|
||||
f"knotc zone-status {zone} | grep -q 'serial: 2019031302'"
|
||||
)
|
||||
|
||||
def test(host, query_type, query, pattern):
|
||||
out = client.succeed(f"khost -t {query_type} {query} {host}").strip()
|
||||
client.log(f"{host} replied with: {out}")
|
||||
assert re.search(pattern, out), f'Did not match "{pattern}"'
|
||||
def test(host, query_type, query, pattern):
|
||||
out = client.succeed(f"khost -t {query_type} {query} {host}").strip()
|
||||
client.log(f"{host} replied with: {out}")
|
||||
assert re.search(pattern, out), f'Did not match "{pattern}"'
|
||||
|
||||
|
||||
for host in ("${primary4}", "${primary6}", "${secondary4}", "${secondary6}"):
|
||||
with subtest(f"Interrogate {host}"):
|
||||
test(host, "SOA", "example.com", r"start of authority.*noc\.example\.com\.")
|
||||
test(host, "A", "example.com", r"has no [^ ]+ record")
|
||||
test(host, "AAAA", "example.com", r"has no [^ ]+ record")
|
||||
for host in ("${primary4}", "${primary6}", "${secondary4}", "${secondary6}"):
|
||||
with subtest(f"Interrogate {host}"):
|
||||
test(host, "SOA", "example.com", r"start of authority.*noc\.example\.com\.")
|
||||
test(host, "A", "example.com", r"has no [^ ]+ record")
|
||||
test(host, "AAAA", "example.com", r"has no [^ ]+ record")
|
||||
|
||||
test(host, "A", "www.example.com", r"address 192.0.2.1$")
|
||||
test(host, "AAAA", "www.example.com", r"address 2001:db8::1$")
|
||||
test(host, "A", "www.example.com", r"address 192.0.2.1$")
|
||||
test(host, "AAAA", "www.example.com", r"address 2001:db8::1$")
|
||||
|
||||
test(host, "NS", "sub.example.com", r"nameserver is ns\d\.example\.com.$")
|
||||
test(host, "A", "sub.example.com", r"address 192.0.2.2$")
|
||||
test(host, "AAAA", "sub.example.com", r"address 2001:db8::2$")
|
||||
test(host, "NS", "sub.example.com", r"nameserver is ns\d\.example\.com.$")
|
||||
test(host, "A", "sub.example.com", r"address 192.0.2.2$")
|
||||
test(host, "AAAA", "sub.example.com", r"address 2001:db8::2$")
|
||||
|
||||
test(host, "RRSIG", "www.example.com", r"RR set signature is")
|
||||
test(host, "DNSKEY", "example.com", r"DNSSEC key is")
|
||||
test(host, "RRSIG", "www.example.com", r"RR set signature is")
|
||||
test(host, "DNSKEY", "example.com", r"DNSSEC key is")
|
||||
|
||||
primary.log(primary.succeed("systemd-analyze security knot.service | grep -v '✓'"))
|
||||
'';
|
||||
}
|
||||
)
|
||||
primary.log(primary.succeed("systemd-analyze security knot.service | grep -v '✓'"))
|
||||
'';
|
||||
}
|
||||
|
||||
+86
-85
@@ -1,102 +1,103 @@
|
||||
import ./make-test-python.nix (
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
port = 8000;
|
||||
baseUrl = "http://server:${toString port}";
|
||||
in
|
||||
{
|
||||
name = "pinnwand";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ hexa ];
|
||||
};
|
||||
{
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
port = 8000;
|
||||
baseUrl = "http://server:${toString port}";
|
||||
in
|
||||
{
|
||||
name = "pinnwand";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ hexa ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
server =
|
||||
{ config, ... }:
|
||||
{
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
port
|
||||
];
|
||||
nodes = {
|
||||
server =
|
||||
{ config, ... }:
|
||||
{
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
port
|
||||
];
|
||||
|
||||
services.pinnwand = {
|
||||
enable = true;
|
||||
port = port;
|
||||
};
|
||||
services.pinnwand = {
|
||||
enable = true;
|
||||
port = port;
|
||||
};
|
||||
};
|
||||
|
||||
client =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = [
|
||||
pkgs.steck
|
||||
client =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = [
|
||||
pkgs.steck
|
||||
|
||||
(pkgs.writers.writePython3Bin "setup-steck.py"
|
||||
{
|
||||
libraries = with pkgs.python3.pkgs; [
|
||||
appdirs
|
||||
toml
|
||||
];
|
||||
flakeIgnore = [
|
||||
"E501"
|
||||
];
|
||||
(pkgs.writers.writePython3Bin "setup-steck.py"
|
||||
{
|
||||
libraries = with pkgs.python3.pkgs; [
|
||||
appdirs
|
||||
toml
|
||||
];
|
||||
flakeIgnore = [
|
||||
"E501"
|
||||
];
|
||||
}
|
||||
''
|
||||
import appdirs
|
||||
import toml
|
||||
import os
|
||||
|
||||
CONFIG = {
|
||||
"base": "${baseUrl}/",
|
||||
"confirm": False,
|
||||
"magic": True,
|
||||
"ignore": True
|
||||
}
|
||||
''
|
||||
import appdirs
|
||||
import toml
|
||||
import os
|
||||
|
||||
CONFIG = {
|
||||
"base": "${baseUrl}/",
|
||||
"confirm": False,
|
||||
"magic": True,
|
||||
"ignore": True
|
||||
}
|
||||
os.makedirs(appdirs.user_config_dir('steck'))
|
||||
with open(os.path.join(appdirs.user_config_dir('steck'), 'steck.toml'), "w") as fd:
|
||||
toml.dump(CONFIG, fd)
|
||||
''
|
||||
)
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
os.makedirs(appdirs.user_config_dir('steck'))
|
||||
with open(os.path.join(appdirs.user_config_dir('steck'), 'steck.toml'), "w") as fd:
|
||||
toml.dump(CONFIG, fd)
|
||||
''
|
||||
)
|
||||
];
|
||||
};
|
||||
};
|
||||
testScript = ''
|
||||
start_all()
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
server.wait_for_unit("pinnwand.service")
|
||||
client.wait_for_unit("network.target")
|
||||
|
||||
server.wait_for_unit("pinnwand.service")
|
||||
client.wait_for_unit("network.target")
|
||||
# create steck.toml config file
|
||||
client.succeed("setup-steck.py")
|
||||
|
||||
# create steck.toml config file
|
||||
client.succeed("setup-steck.py")
|
||||
# wait until the server running pinnwand is reachable
|
||||
client.wait_until_succeeds("ping -c1 server")
|
||||
|
||||
# wait until the server running pinnwand is reachable
|
||||
client.wait_until_succeeds("ping -c1 server")
|
||||
# make sure pinnwand is listening
|
||||
server.wait_for_open_port(${toString port})
|
||||
|
||||
# make sure pinnwand is listening
|
||||
server.wait_for_open_port(${toString port})
|
||||
# send the contents of /etc/machine-id
|
||||
response = client.succeed("steck paste /etc/machine-id")
|
||||
|
||||
# send the contents of /etc/machine-id
|
||||
response = client.succeed("steck paste /etc/machine-id")
|
||||
# parse the steck response
|
||||
raw_url = None
|
||||
removal_link = None
|
||||
for line in response.split("\n"):
|
||||
if line.startswith("View link:"):
|
||||
raw_url = f"${baseUrl}/raw/{line.split('/')[-1]}"
|
||||
if line.startswith("Removal link:"):
|
||||
removal_link = line.split(":", 1)[1]
|
||||
|
||||
# parse the steck response
|
||||
raw_url = None
|
||||
removal_link = None
|
||||
for line in response.split("\n"):
|
||||
if line.startswith("View link:"):
|
||||
raw_url = f"${baseUrl}/raw/{line.split('/')[-1]}"
|
||||
if line.startswith("Removal link:"):
|
||||
removal_link = line.split(":", 1)[1]
|
||||
# check whether paste matches what we sent
|
||||
client.succeed(f"curl {raw_url} > /tmp/machine-id")
|
||||
client.succeed("diff /tmp/machine-id /etc/machine-id")
|
||||
|
||||
# check whether paste matches what we sent
|
||||
client.succeed(f"curl {raw_url} > /tmp/machine-id")
|
||||
client.succeed("diff /tmp/machine-id /etc/machine-id")
|
||||
# remove paste and check that it's not available any more
|
||||
client.succeed(f"curl {removal_link}")
|
||||
client.fail(f"curl --fail {raw_url}")
|
||||
|
||||
# remove paste and check that it's not available any more
|
||||
client.succeed(f"curl {removal_link}")
|
||||
client.fail(f"curl --fail {raw_url}")
|
||||
|
||||
server.log(server.execute("systemd-analyze security pinnwand | grep '✗'")[1])
|
||||
'';
|
||||
}
|
||||
)
|
||||
server.log(server.execute("systemd-analyze security pinnwand | grep '✗'")[1])
|
||||
'';
|
||||
}
|
||||
|
||||
+79
-78
@@ -1,93 +1,94 @@
|
||||
import ./make-test-python.nix (
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
port = 10004;
|
||||
tcpPort = 10005;
|
||||
httpPort = 10080;
|
||||
tcpStreamPort = 10006;
|
||||
bufferSize = 742;
|
||||
in
|
||||
{
|
||||
name = "snapcast";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ hexa ];
|
||||
};
|
||||
let
|
||||
port = 10004;
|
||||
tcpPort = 10005;
|
||||
httpPort = 10080;
|
||||
tcpStreamPort = 10006;
|
||||
bufferSize = 742;
|
||||
in
|
||||
{
|
||||
name = "snapcast";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ hexa ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
server = {
|
||||
services.snapserver = {
|
||||
enable = true;
|
||||
port = port;
|
||||
tcp.port = tcpPort;
|
||||
http.port = httpPort;
|
||||
openFirewall = true;
|
||||
buffer = bufferSize;
|
||||
streams = {
|
||||
mpd = {
|
||||
type = "pipe";
|
||||
location = "/run/snapserver/mpd";
|
||||
query.mode = "create";
|
||||
};
|
||||
bluetooth = {
|
||||
type = "pipe";
|
||||
location = "/run/snapserver/bluetooth";
|
||||
};
|
||||
tcp = {
|
||||
type = "tcp";
|
||||
location = "127.0.0.1:${toString tcpStreamPort}";
|
||||
};
|
||||
meta = {
|
||||
type = "meta";
|
||||
location = "/mpd/bluetooth/tcp";
|
||||
};
|
||||
nodes = {
|
||||
server = {
|
||||
services.snapserver = {
|
||||
enable = true;
|
||||
port = port;
|
||||
tcp.port = tcpPort;
|
||||
http.port = httpPort;
|
||||
openFirewall = true;
|
||||
buffer = bufferSize;
|
||||
streams = {
|
||||
mpd = {
|
||||
type = "pipe";
|
||||
location = "/run/snapserver/mpd";
|
||||
query.mode = "create";
|
||||
};
|
||||
bluetooth = {
|
||||
type = "pipe";
|
||||
location = "/run/snapserver/bluetooth";
|
||||
};
|
||||
tcp = {
|
||||
type = "tcp";
|
||||
location = "127.0.0.1:${toString tcpStreamPort}";
|
||||
};
|
||||
meta = {
|
||||
type = "meta";
|
||||
location = "/mpd/bluetooth/tcp";
|
||||
};
|
||||
};
|
||||
environment.systemPackages = [ pkgs.snapcast ];
|
||||
};
|
||||
client = {
|
||||
environment.systemPackages = [ pkgs.snapcast ];
|
||||
};
|
||||
environment.systemPackages = [ pkgs.snapcast ];
|
||||
};
|
||||
client = {
|
||||
environment.systemPackages = [ pkgs.snapcast ];
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
import json
|
||||
testScript = ''
|
||||
import json
|
||||
|
||||
get_rpc_version = {"id": "1", "jsonrpc": "2.0", "method": "Server.GetRPCVersion"}
|
||||
get_rpc_version = {"id": "1", "jsonrpc": "2.0", "method": "Server.GetRPCVersion"}
|
||||
|
||||
start_all()
|
||||
start_all()
|
||||
|
||||
server.wait_for_unit("snapserver.service")
|
||||
server.wait_until_succeeds("ss -ntl | grep -q ${toString port}")
|
||||
server.wait_until_succeeds("ss -ntl | grep -q ${toString tcpPort}")
|
||||
server.wait_until_succeeds("ss -ntl | grep -q ${toString httpPort}")
|
||||
server.wait_until_succeeds("ss -ntl | grep -q ${toString tcpStreamPort}")
|
||||
server.wait_for_unit("snapserver.service")
|
||||
server.wait_until_succeeds("ss -ntl | grep -q ${toString port}")
|
||||
server.wait_until_succeeds("ss -ntl | grep -q ${toString tcpPort}")
|
||||
server.wait_until_succeeds("ss -ntl | grep -q ${toString httpPort}")
|
||||
server.wait_until_succeeds("ss -ntl | grep -q ${toString tcpStreamPort}")
|
||||
|
||||
with subtest("check that pipes are created"):
|
||||
server.succeed("test -p /run/snapserver/mpd")
|
||||
server.succeed("test -p /run/snapserver/bluetooth")
|
||||
with subtest("check that pipes are created"):
|
||||
server.succeed("test -p /run/snapserver/mpd")
|
||||
server.succeed("test -p /run/snapserver/bluetooth")
|
||||
|
||||
with subtest("test tcp json-rpc"):
|
||||
server.succeed(f"echo '{json.dumps(get_rpc_version)}' | nc -w 1 localhost ${toString tcpPort}")
|
||||
with subtest("test tcp json-rpc"):
|
||||
server.succeed(f"echo '{json.dumps(get_rpc_version)}' | nc -w 1 localhost ${toString tcpPort}")
|
||||
|
||||
with subtest("test http json-rpc"):
|
||||
server.succeed(
|
||||
"curl --fail http://localhost:${toString httpPort}/jsonrpc -d '{json.dumps(get_rpc_version)}'"
|
||||
)
|
||||
with subtest("test http json-rpc"):
|
||||
server.succeed(
|
||||
"curl --fail http://localhost:${toString httpPort}/jsonrpc -d '{json.dumps(get_rpc_version)}'"
|
||||
)
|
||||
|
||||
with subtest("test a ipv6 connection"):
|
||||
server.execute("systemd-run --unit=snapcast-local-client snapclient -h ::1 -p ${toString port}")
|
||||
server.wait_until_succeeds(
|
||||
"journalctl -o cat -u snapserver.service | grep -q 'Hello from'"
|
||||
)
|
||||
server.wait_until_succeeds("journalctl -o cat -u snapcast-local-client | grep -q 'buffer: ${toString bufferSize}'")
|
||||
with subtest("test a ipv6 connection"):
|
||||
server.execute("systemd-run --unit=snapcast-local-client snapclient -h ::1 -p ${toString port}")
|
||||
server.wait_until_succeeds(
|
||||
"journalctl -o cat -u snapserver.service | grep -q 'Hello from'"
|
||||
)
|
||||
server.wait_until_succeeds("journalctl -o cat -u snapcast-local-client | grep -q 'buffer: ${toString bufferSize}'")
|
||||
|
||||
with subtest("test a connection"):
|
||||
client.execute("systemd-run --unit=snapcast-client snapclient -h server -p ${toString port}")
|
||||
server.wait_until_succeeds(
|
||||
"journalctl -o cat -u snapserver.service | grep -q 'Hello from'"
|
||||
)
|
||||
client.wait_until_succeeds("journalctl -o cat -u snapcast-client | grep -q 'buffer: ${toString bufferSize}'")
|
||||
'';
|
||||
}
|
||||
)
|
||||
with subtest("test a connection"):
|
||||
client.execute("systemd-run --unit=snapcast-client snapclient -h server -p ${toString port}")
|
||||
server.wait_until_succeeds(
|
||||
"journalctl -o cat -u snapserver.service | grep -q 'Hello from'"
|
||||
)
|
||||
client.wait_until_succeeds("journalctl -o cat -u snapcast-client | grep -q 'buffer: ${toString bufferSize}'")
|
||||
'';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user