A5: Extract all route groups into Flask blueprints (app.py -1735 lines)

Extract 9 route groups out of app.py into routes/ blueprints:
- routes/network.py  — DNS, DHCP, NTP, network info/test (10 routes)
- routes/wireguard.py — WireGuard keys, peers, config, enforcement (18 routes)
- routes/cells.py    — cell-to-cell connections (5 routes)
- routes/peers.py    — peer CRUD + IP update + _next_peer_ip helper (10 routes)
- routes/routing.py  — NAT, peer routes, firewall, iptables (17 routes)
- routes/vault.py    — certs, trust, secrets (19 routes)
- routes/containers.py — containers, images, volumes (14 routes)
- routes/services.py — service bus, logs, services status/connectivity (18 routes)
- routes/peer_dashboard.py — peer-scoped dashboard/services (2 routes)

All blueprints use lazy `from app import X` inside route bodies to preserve
test patch compatibility (patch('app.email_manager', mock) still works).

Also included in this commit:
- A1 fix: backup/restore now includes email/calendar user files
- A2 fix: apply_config sets applying=True flag via helper container
- A3 fix: add_peer rolls back firewall on DNS failure

app.py reduced: 3011 → 1294 lines. 1021 tests passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-01 06:11:21 -04:00
parent d54844cd44
commit 09138fbc18
16 changed files with 2108 additions and 2072 deletions
+2 -2
View File
@@ -31,7 +31,7 @@ class TestAddPeerSubnetExhaustion(unittest.TestCase):
app.config['TESTING'] = True
self.client = app.test_client()
@patch('app._next_peer_ip')
@patch('routes.peers._next_peer_ip')
@patch('app.auth_manager')
def test_add_peer_returns_409_when_subnet_exhausted(self, mock_auth, mock_next_ip):
mock_auth.create_user.return_value = True
@@ -50,7 +50,7 @@ class TestAddPeerSubnetExhaustion(unittest.TestCase):
data = json.loads(r.data)
self.assertIn('error', data)
@patch('app._next_peer_ip')
@patch('routes.peers._next_peer_ip')
@patch('app.auth_manager')
def test_add_peer_409_error_message_mentions_ip(self, mock_auth, mock_next_ip):
mock_auth.create_user.return_value = True