furtka-gateway/tests/test_traefikconf.py
Robert Syrnicki 3a9d18fcd5 Scaffold gateway stack and single-tenant control plane
wg-easy + Traefik docker-compose stack (Phase 1) plus a stdlib-only
control-plane API for box registration, WireGuard peer provisioning via
wg-easy, and per-box route publish/unpublish backed by Traefik's file
provider (Phase 2, single-tenant mode). SQLite holds accounts/boxes/routes
so a later multi-tenant shared instance is the same schema with more rows,
not a reshape.

wg-easy's actual REST API was verified against its source rather than
assumed: it has no bearer-token auth (session-cookie login via
POST /api/auth/password) and no way to accept an externally-generated
public key (it always mints the keypair itself, private key included) —
both corrected from the original plan during implementation.
2026-08-24 11:50:25 +02:00

47 lines
1.7 KiB
Python

from control_plane import paths, traefikconf
def test_write_route_single_mode_content(gateway_paths):
traefikconf.write_route("r1", "app.example.com", "10.8.0.5", 8081, cert_resolver="le")
content = (paths.dynamic_dir() / "route-r1.yml").read_text()
assert "route-r1:" in content
assert 'rule: "Host(`app.example.com`)"' in content
assert "service: svc-r1" in content
assert "certResolver: le" in content
assert 'url: "http://10.8.0.5:8081"' in content
def test_write_route_shared_mode_no_cert_resolver(gateway_paths):
traefikconf.write_route("r2", "app.boxes.example.com", "10.8.0.9", 8096, cert_resolver=None)
content = (paths.dynamic_dir() / "route-r2.yml").read_text()
assert "tls: {}" in content
assert "certResolver" not in content
def test_write_route_is_idempotent(gateway_paths):
traefikconf.write_route("r1", "app.example.com", "10.8.0.5", 8081, cert_resolver="le")
traefikconf.write_route("r1", "app.example.com", "10.8.0.5", 8081, cert_resolver="le")
assert traefikconf.existing_route_ids() == {"r1"}
def test_remove_route(gateway_paths):
traefikconf.write_route("r1", "app.example.com", "10.8.0.5", 8081, cert_resolver="le")
traefikconf.remove_route("r1")
assert not (paths.dynamic_dir() / "route-r1.yml").exists()
def test_remove_route_missing_file_is_a_noop(gateway_paths):
traefikconf.remove_route("does-not-exist") # must not raise
def test_existing_route_ids(gateway_paths):
traefikconf.write_route("r1", "a.example.com", "10.8.0.1", 80, cert_resolver="le")
traefikconf.write_route("r2", "b.example.com", "10.8.0.2", 80, cert_resolver="le")
assert traefikconf.existing_route_ids() == {"r1", "r2"}