nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix

nixos/tests/knot: migrate to runTest

Part of #386873

+230 -228
+1 -1
nixos/tests/all-tests.nix
··· 589 589 keymap = handleTest ./keymap.nix {}; 590 590 kimai = handleTest ./kimai.nix {}; 591 591 kmonad = runTest ./kmonad.nix; 592 - knot = handleTest ./knot.nix {}; 592 + knot = runTest ./knot.nix; 593 593 komga = handleTest ./komga.nix {}; 594 594 krb5 = discoverTests (import ./krb5); 595 595 ksm = handleTest ./ksm.nix {};
+229 -227
nixos/tests/knot.nix
··· 1 - import ./make-test-python.nix ( 2 - { pkgs, lib, ... }: 3 - let 4 - common = { 5 - networking.firewall.enable = false; 6 - networking.useDHCP = false; 7 - }; 8 - exampleZone = pkgs.writeTextDir "example.com.zone" '' 9 - @ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800 10 - @ NS ns1 11 - @ NS ns2 12 - ns1 A 192.168.0.1 13 - ns1 AAAA fd00::1 14 - ns2 A 192.168.0.2 15 - ns2 AAAA fd00::2 16 - www A 192.0.2.1 17 - www AAAA 2001:DB8::1 18 - sub NS ns.example.com. 19 - ''; 20 - delegatedZone = pkgs.writeTextDir "sub.example.com.zone" '' 21 - @ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800 22 - @ NS ns1.example.com. 23 - @ NS ns2.example.com. 24 - @ A 192.0.2.2 25 - @ AAAA 2001:DB8::2 26 - ''; 1 + { 2 + pkgs, 3 + lib, 4 + ... 5 + }: 6 + let 7 + common = { 8 + networking.firewall.enable = false; 9 + networking.useDHCP = false; 10 + }; 11 + exampleZone = pkgs.writeTextDir "example.com.zone" '' 12 + @ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800 13 + @ NS ns1 14 + @ NS ns2 15 + ns1 A 192.168.0.1 16 + ns1 AAAA fd00::1 17 + ns2 A 192.168.0.2 18 + ns2 AAAA fd00::2 19 + www A 192.0.2.1 20 + www AAAA 2001:DB8::1 21 + sub NS ns.example.com. 22 + ''; 23 + delegatedZone = pkgs.writeTextDir "sub.example.com.zone" '' 24 + @ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800 25 + @ NS ns1.example.com. 26 + @ NS ns2.example.com. 27 + @ A 192.0.2.2 28 + @ AAAA 2001:DB8::2 29 + ''; 27 30 28 - knotZonesEnv = pkgs.buildEnv { 29 - name = "knot-zones"; 30 - paths = [ 31 - exampleZone 32 - delegatedZone 33 - ]; 34 - }; 35 - # DO NOT USE pkgs.writeText IN PRODUCTION. This put secrets in the nix store! 36 - tsigFile = pkgs.writeText "tsig.conf" '' 37 - key: 38 - - id: xfr_key 39 - algorithm: hmac-sha256 40 - secret: zOYgOgnzx3TGe5J5I/0kxd7gTcxXhLYMEq3Ek3fY37s= 41 - ''; 42 - in 43 - { 44 - name = "knot"; 45 - meta = with pkgs.lib.maintainers; { 46 - maintainers = [ hexa ]; 47 - }; 31 + knotZonesEnv = pkgs.buildEnv { 32 + name = "knot-zones"; 33 + paths = [ 34 + exampleZone 35 + delegatedZone 36 + ]; 37 + }; 38 + # DO NOT USE pkgs.writeText IN PRODUCTION. This put secrets in the nix store! 39 + tsigFile = pkgs.writeText "tsig.conf" '' 40 + key: 41 + - id: xfr_key 42 + algorithm: hmac-sha256 43 + secret: zOYgOgnzx3TGe5J5I/0kxd7gTcxXhLYMEq3Ek3fY37s= 44 + ''; 45 + in 46 + { 47 + name = "knot"; 48 + meta = with pkgs.lib.maintainers; { 49 + maintainers = [ hexa ]; 50 + }; 48 51 49 - nodes = { 50 - primary = 51 - { lib, ... }: 52 - { 53 - imports = [ common ]; 52 + nodes = { 53 + primary = 54 + { lib, ... }: 55 + { 56 + imports = [ common ]; 54 57 55 - # trigger sched_setaffinity syscall 56 - virtualisation.cores = 2; 58 + # trigger sched_setaffinity syscall 59 + virtualisation.cores = 2; 57 60 58 - networking.interfaces.eth1 = { 59 - ipv4.addresses = lib.mkForce [ 60 - { 61 - address = "192.168.0.1"; 62 - prefixLength = 24; 63 - } 61 + networking.interfaces.eth1 = { 62 + ipv4.addresses = lib.mkForce [ 63 + { 64 + address = "192.168.0.1"; 65 + prefixLength = 24; 66 + } 67 + ]; 68 + ipv6.addresses = lib.mkForce [ 69 + { 70 + address = "fd00::1"; 71 + prefixLength = 64; 72 + } 73 + ]; 74 + }; 75 + services.knot.enable = true; 76 + services.knot.extraArgs = [ "-v" ]; 77 + services.knot.keyFiles = [ tsigFile ]; 78 + services.knot.settings = { 79 + server = { 80 + listen = [ 81 + "0.0.0.0@53" 82 + "::@53" 64 83 ]; 65 - ipv6.addresses = lib.mkForce [ 66 - { 67 - address = "fd00::1"; 68 - prefixLength = 64; 69 - } 84 + listen-quic = [ 85 + "0.0.0.0@853" 86 + "::@853" 70 87 ]; 88 + automatic-acl = true; 71 89 }; 72 - services.knot.enable = true; 73 - services.knot.extraArgs = [ "-v" ]; 74 - services.knot.keyFiles = [ tsigFile ]; 75 - services.knot.settings = { 76 - server = { 77 - listen = [ 78 - "0.0.0.0@53" 79 - "::@53" 80 - ]; 81 - listen-quic = [ 82 - "0.0.0.0@853" 83 - "::@853" 84 - ]; 85 - automatic-acl = true; 86 - }; 87 90 88 - acl.secondary_acl = { 91 + acl.secondary_acl = { 92 + address = "192.168.0.2"; 93 + key = "xfr_key"; 94 + action = "transfer"; 95 + }; 96 + 97 + remote.secondary.address = "192.168.0.2@53"; 98 + 99 + template.default = { 100 + storage = knotZonesEnv; 101 + notify = [ "secondary" ]; 102 + acl = [ "secondary_acl" ]; 103 + dnssec-signing = true; 104 + # Input-only zone files 105 + # https://www.knot-dns.cz/docs/2.8/html/operation.html#example-3 106 + # prevents modification of the zonefiles, since the zonefiles are immutable 107 + zonefile-sync = -1; 108 + zonefile-load = "difference"; 109 + journal-content = "changes"; 110 + }; 111 + 112 + zone = { 113 + "example.com".file = "example.com.zone"; 114 + "sub.example.com".file = "sub.example.com.zone"; 115 + }; 116 + 117 + log.syslog.any = "info"; 118 + }; 119 + }; 120 + 121 + secondary = 122 + { lib, ... }: 123 + { 124 + imports = [ common ]; 125 + networking.interfaces.eth1 = { 126 + ipv4.addresses = lib.mkForce [ 127 + { 89 128 address = "192.168.0.2"; 90 - key = "xfr_key"; 91 - action = "transfer"; 92 - }; 93 - 94 - remote.secondary.address = "192.168.0.2@53"; 95 - 96 - template.default = { 97 - storage = knotZonesEnv; 98 - notify = [ "secondary" ]; 99 - acl = [ "secondary_acl" ]; 100 - dnssec-signing = true; 101 - # Input-only zone files 102 - # https://www.knot-dns.cz/docs/2.8/html/operation.html#example-3 103 - # prevents modification of the zonefiles, since the zonefiles are immutable 104 - zonefile-sync = -1; 105 - zonefile-load = "difference"; 106 - journal-content = "changes"; 107 - }; 108 - 109 - zone = { 110 - "example.com".file = "example.com.zone"; 111 - "sub.example.com".file = "sub.example.com.zone"; 112 - }; 113 - 114 - log.syslog.any = "info"; 115 - }; 129 + prefixLength = 24; 130 + } 131 + ]; 132 + ipv6.addresses = lib.mkForce [ 133 + { 134 + address = "fd00::2"; 135 + prefixLength = 64; 136 + } 137 + ]; 116 138 }; 117 - 118 - secondary = 119 - { lib, ... }: 120 - { 121 - imports = [ common ]; 122 - networking.interfaces.eth1 = { 123 - ipv4.addresses = lib.mkForce [ 124 - { 125 - address = "192.168.0.2"; 126 - prefixLength = 24; 127 - } 128 - ]; 129 - ipv6.addresses = lib.mkForce [ 130 - { 131 - address = "fd00::2"; 132 - prefixLength = 64; 133 - } 134 - ]; 139 + services.knot.enable = true; 140 + services.knot.keyFiles = [ tsigFile ]; 141 + services.knot.extraArgs = [ "-v" ]; 142 + services.knot.settings = { 143 + server = { 144 + automatic-acl = true; 135 145 }; 136 - services.knot.enable = true; 137 - services.knot.keyFiles = [ tsigFile ]; 138 - services.knot.extraArgs = [ "-v" ]; 139 - services.knot.settings = { 140 - server = { 141 - automatic-acl = true; 142 - }; 143 146 144 - xdp = { 145 - listen = [ 146 - "eth1" 147 - ]; 148 - tcp = true; 149 - }; 150 - 151 - remote.primary = { 152 - address = "192.168.0.1@53"; 153 - key = "xfr_key"; 154 - }; 155 - 156 - remote.primary-quic = { 157 - address = "192.168.0.1@853"; 158 - key = "xfr_key"; 159 - quic = true; 160 - }; 161 - 162 - template.default = { 163 - # zonefileless setup 164 - # https://www.knot-dns.cz/docs/2.8/html/operation.html#example-2 165 - zonefile-sync = "-1"; 166 - zonefile-load = "none"; 167 - journal-content = "all"; 168 - }; 169 - 170 - zone = { 171 - "example.com" = { 172 - master = "primary"; 173 - file = "example.com.zone"; 174 - }; 175 - "sub.example.com" = { 176 - master = "primary-quic"; 177 - file = "sub.example.com.zone"; 178 - }; 179 - }; 180 - 181 - log.syslog.any = "debug"; 147 + xdp = { 148 + listen = [ 149 + "eth1" 150 + ]; 151 + tcp = true; 182 152 }; 153 + 154 + remote.primary = { 155 + address = "192.168.0.1@53"; 156 + key = "xfr_key"; 157 + }; 158 + 159 + remote.primary-quic = { 160 + address = "192.168.0.1@853"; 161 + key = "xfr_key"; 162 + quic = true; 163 + }; 164 + 165 + template.default = { 166 + # zonefileless setup 167 + # https://www.knot-dns.cz/docs/2.8/html/operation.html#example-2 168 + zonefile-sync = "-1"; 169 + zonefile-load = "none"; 170 + journal-content = "all"; 171 + }; 172 + 173 + zone = { 174 + "example.com" = { 175 + master = "primary"; 176 + file = "example.com.zone"; 177 + }; 178 + "sub.example.com" = { 179 + master = "primary-quic"; 180 + file = "sub.example.com.zone"; 181 + }; 182 + }; 183 + 184 + log.syslog.any = "debug"; 183 185 }; 184 - client = 185 - { lib, nodes, ... }: 186 - { 187 - imports = [ common ]; 188 - networking.interfaces.eth1 = { 189 - ipv4.addresses = [ 190 - { 191 - address = "192.168.0.3"; 192 - prefixLength = 24; 193 - } 194 - ]; 195 - ipv6.addresses = [ 196 - { 197 - address = "fd00::3"; 198 - prefixLength = 64; 199 - } 200 - ]; 201 - }; 202 - environment.systemPackages = [ pkgs.knot-dns ]; 186 + }; 187 + client = 188 + { lib, nodes, ... }: 189 + { 190 + imports = [ common ]; 191 + networking.interfaces.eth1 = { 192 + ipv4.addresses = [ 193 + { 194 + address = "192.168.0.3"; 195 + prefixLength = 24; 196 + } 197 + ]; 198 + ipv6.addresses = [ 199 + { 200 + address = "fd00::3"; 201 + prefixLength = 64; 202 + } 203 + ]; 203 204 }; 204 - }; 205 + environment.systemPackages = [ pkgs.knot-dns ]; 206 + }; 207 + }; 205 208 206 - testScript = 207 - { nodes, ... }: 208 - let 209 - primary4 = (lib.head nodes.primary.config.networking.interfaces.eth1.ipv4.addresses).address; 210 - primary6 = (lib.head nodes.primary.config.networking.interfaces.eth1.ipv6.addresses).address; 209 + testScript = 210 + { nodes, ... }: 211 + let 212 + primary4 = (lib.head nodes.primary.config.networking.interfaces.eth1.ipv4.addresses).address; 213 + primary6 = (lib.head nodes.primary.config.networking.interfaces.eth1.ipv6.addresses).address; 211 214 212 - secondary4 = (lib.head nodes.secondary.config.networking.interfaces.eth1.ipv4.addresses).address; 213 - secondary6 = (lib.head nodes.secondary.config.networking.interfaces.eth1.ipv6.addresses).address; 214 - in 215 - '' 216 - import re 215 + secondary4 = (lib.head nodes.secondary.config.networking.interfaces.eth1.ipv4.addresses).address; 216 + secondary6 = (lib.head nodes.secondary.config.networking.interfaces.eth1.ipv6.addresses).address; 217 + in 218 + '' 219 + import re 217 220 218 - start_all() 221 + start_all() 219 222 220 - client.wait_for_unit("network.target") 221 - primary.wait_for_unit("knot.service") 222 - secondary.wait_for_unit("knot.service") 223 + client.wait_for_unit("network.target") 224 + primary.wait_for_unit("knot.service") 225 + secondary.wait_for_unit("knot.service") 223 226 224 - for zone in ("example.com.", "sub.example.com."): 225 - secondary.wait_until_succeeds( 226 - f"knotc zone-status {zone} | grep -q 'serial: 2019031302'" 227 - ) 227 + for zone in ("example.com.", "sub.example.com."): 228 + secondary.wait_until_succeeds( 229 + f"knotc zone-status {zone} | grep -q 'serial: 2019031302'" 230 + ) 228 231 229 - def test(host, query_type, query, pattern): 230 - out = client.succeed(f"khost -t {query_type} {query} {host}").strip() 231 - client.log(f"{host} replied with: {out}") 232 - assert re.search(pattern, out), f'Did not match "{pattern}"' 232 + def test(host, query_type, query, pattern): 233 + out = client.succeed(f"khost -t {query_type} {query} {host}").strip() 234 + client.log(f"{host} replied with: {out}") 235 + assert re.search(pattern, out), f'Did not match "{pattern}"' 233 236 234 237 235 - for host in ("${primary4}", "${primary6}", "${secondary4}", "${secondary6}"): 236 - with subtest(f"Interrogate {host}"): 237 - test(host, "SOA", "example.com", r"start of authority.*noc\.example\.com\.") 238 - test(host, "A", "example.com", r"has no [^ ]+ record") 239 - test(host, "AAAA", "example.com", r"has no [^ ]+ record") 238 + for host in ("${primary4}", "${primary6}", "${secondary4}", "${secondary6}"): 239 + with subtest(f"Interrogate {host}"): 240 + test(host, "SOA", "example.com", r"start of authority.*noc\.example\.com\.") 241 + test(host, "A", "example.com", r"has no [^ ]+ record") 242 + test(host, "AAAA", "example.com", r"has no [^ ]+ record") 240 243 241 - test(host, "A", "www.example.com", r"address 192.0.2.1$") 242 - test(host, "AAAA", "www.example.com", r"address 2001:db8::1$") 244 + test(host, "A", "www.example.com", r"address 192.0.2.1$") 245 + test(host, "AAAA", "www.example.com", r"address 2001:db8::1$") 243 246 244 - test(host, "NS", "sub.example.com", r"nameserver is ns\d\.example\.com.$") 245 - test(host, "A", "sub.example.com", r"address 192.0.2.2$") 246 - test(host, "AAAA", "sub.example.com", r"address 2001:db8::2$") 247 + test(host, "NS", "sub.example.com", r"nameserver is ns\d\.example\.com.$") 248 + test(host, "A", "sub.example.com", r"address 192.0.2.2$") 249 + test(host, "AAAA", "sub.example.com", r"address 2001:db8::2$") 247 250 248 - test(host, "RRSIG", "www.example.com", r"RR set signature is") 249 - test(host, "DNSKEY", "example.com", r"DNSSEC key is") 251 + test(host, "RRSIG", "www.example.com", r"RR set signature is") 252 + test(host, "DNSKEY", "example.com", r"DNSSEC key is") 250 253 251 - primary.log(primary.succeed("systemd-analyze security knot.service | grep -v '✓'")) 252 - ''; 253 - } 254 - ) 254 + primary.log(primary.succeed("systemd-analyze security knot.service | grep -v '✓'")) 255 + ''; 256 + }