this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

test(e2e): reject unknown PXE clients

+47 -9
+47 -9
tests/e2e/run.py
··· 20 20 "dhcp_range_end": "192.168.50.20", 21 21 "machine1_ip": "192.168.50.11", 22 22 "machine2_ip": "192.168.50.12", 23 + "rogue_ip": "192.168.50.13", 23 24 } 24 25 25 - MACHINES = [ 26 + MANAGED_MACHINES = [ 26 27 { 27 28 "name": "machine1", 28 29 "mac": "52:54:00:12:34:56", ··· 34 35 "ip": NETWORK["machine2_ip"], 35 36 }, 36 37 ] 38 + 39 + ROGUE_MACHINE = { 40 + "name": "rogue-machine", 41 + "mac": "52:54:00:12:34:58", 42 + "ip": NETWORK["rogue_ip"], 43 + } 44 + 45 + ALL_MACHINES = MANAGED_MACHINES + [ROGUE_MACHINE] 37 46 38 47 39 48 def log(message): ··· 130 139 raise TimeoutError(f"timed out waiting for SSH on {ip}") 131 140 132 141 142 + def wait_for_no_ssh(key_path, ip, timeout): 143 + deadline = time.time() + timeout 144 + cmd = [ 145 + "ssh", 146 + "-i", 147 + str(key_path), 148 + "-o", 149 + "BatchMode=yes", 150 + "-o", 151 + "ConnectTimeout=5", 152 + "-o", 153 + "StrictHostKeyChecking=no", 154 + "-o", 155 + "UserKnownHostsFile=/dev/null", 156 + f"root@{ip}", 157 + "true", 158 + ] 159 + 160 + while time.time() < deadline: 161 + result = subprocess.run(cmd, capture_output=True, text=True) 162 + if result.returncode == 0: 163 + raise RuntimeError(f"unexpected SSH access on {ip}") 164 + time.sleep(10) 165 + 166 + 133 167 def machine_artifact_paths(workdir, machine): 134 168 return { 135 169 "disk": workdir / f"{machine['name']}.qcow2", ··· 198 232 f"dhcp-range={NETWORK['dhcp_range_start']},{NETWORK['dhcp_range_end']},255.255.255.0,1h", 199 233 f"dhcp-option=option:router,{NETWORK['controller_ip']}", 200 234 f"dhcp-option=option:dns-server,{NETWORK['controller_ip']}", 201 - f"dhcp-host={MACHINES[0]['mac']},{NETWORK['machine1_ip']}", 202 - f"dhcp-host={MACHINES[1]['mac']},{NETWORK['machine2_ip']}", 203 235 ] 236 + for machine in ALL_MACHINES: 237 + lines.append(f"dhcp-host={machine['mac']},{machine['ip']}") 204 238 path.write_text("\n".join(lines) + "\n", encoding="utf-8") 205 239 206 240 ··· 337 371 338 372 suffix = secrets.token_hex(2) 339 373 bridge = f"brnxe{suffix}" 340 - taps = [f"tapn1{suffix}", f"tapn2{suffix}"] 374 + taps = [f"tapn{index + 1}{suffix}" for index in range(len(ALL_MACHINES))] 341 375 processes = [] 342 376 qemu_processes = [] 343 377 ··· 399 433 wait_for_port(NETWORK["controller_ip"], 5000, timeout=1800) 400 434 time.sleep(2) 401 435 402 - for machine, tap in zip(MACHINES, taps, strict=True): 436 + for machine, tap in zip(ALL_MACHINES, taps, strict=True): 403 437 qemu_proc, qemu_handle = start_machine( 404 438 machine, 405 439 tap, ··· 412 446 413 447 wait_for_nixie(nixie_proc, nixie_log, timeout=7200) 414 448 415 - for machine in MACHINES: 449 + for machine in MANAGED_MACHINES: 416 450 wait_for_ssh(key_path, machine["ip"], machine["name"], timeout=1800) 417 451 log(f"verified {machine['name']} at {machine['ip']}") 452 + wait_for_no_ssh(key_path, ROGUE_MACHINE["ip"], timeout=60) 453 + log(f"verified {ROGUE_MACHINE['name']} was not installed") 418 454 419 455 log("power cycling machines to verify disk boot without the installer") 420 456 for _, _, qemu_proc, qemu_handle in reversed(qemu_processes): ··· 422 458 qemu_handle.close() 423 459 qemu_processes = [] 424 460 425 - for machine, tap in zip(MACHINES, taps, strict=True): 461 + for machine, tap in zip(ALL_MACHINES, taps, strict=True): 426 462 qemu_proc, qemu_handle = start_machine( 427 463 machine, 428 464 tap, ··· 433 469 qemu_processes.append((machine, tap, qemu_proc, qemu_handle)) 434 470 processes.append((qemu_proc, qemu_handle)) 435 471 436 - for machine in MACHINES: 472 + for machine in MANAGED_MACHINES: 437 473 wait_for_ssh(key_path, machine["ip"], machine["name"], timeout=900) 438 474 log(f"verified cold boot for {machine['name']} at {machine['ip']}") 475 + wait_for_no_ssh(key_path, ROGUE_MACHINE["ip"], timeout=60) 476 + log(f"verified cold boot remained unavailable for {ROGUE_MACHINE['name']}") 439 477 440 478 log("end-to-end test passed") 441 479 return 0 ··· 445 483 print(tail(workdir / "nixie.log"), file=sys.stderr) 446 484 print("\n== dnsmasq.log ==", file=sys.stderr) 447 485 print(tail(workdir / "dnsmasq.log"), file=sys.stderr) 448 - for machine in MACHINES: 486 + for machine in ALL_MACHINES: 449 487 print(f"\n== {machine['name']}.serial.log ==", file=sys.stderr) 450 488 print(tail(workdir / f"{machine['name']}.serial.log"), file=sys.stderr) 451 489 return 1