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:
@@ -0,0 +1,65 @@
|
||||
import logging
|
||||
import os
|
||||
from flask import Blueprint, request, jsonify
|
||||
logger = logging.getLogger('picell')
|
||||
bp = Blueprint('cells', __name__)
|
||||
|
||||
@bp.route('/api/cells/invite', methods=['GET'])
|
||||
def get_cell_invite():
|
||||
try:
|
||||
from app import cell_link_manager, config_manager
|
||||
identity = config_manager.configs.get('_identity', {})
|
||||
cell_name = identity.get('cell_name', os.environ.get('CELL_NAME', 'mycell'))
|
||||
domain = identity.get('domain', os.environ.get('CELL_DOMAIN', 'cell'))
|
||||
return jsonify(cell_link_manager.generate_invite(cell_name, domain))
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating cell invite: {e}")
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
@bp.route('/api/cells', methods=['GET'])
|
||||
def list_cell_connections():
|
||||
try:
|
||||
from app import cell_link_manager
|
||||
return jsonify(cell_link_manager.list_connections())
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
@bp.route('/api/cells', methods=['POST'])
|
||||
def add_cell_connection():
|
||||
try:
|
||||
from app import cell_link_manager
|
||||
data = request.get_json(silent=True)
|
||||
if not data:
|
||||
return jsonify({'error': 'No data provided'}), 400
|
||||
for field in ('cell_name', 'public_key', 'vpn_subnet', 'dns_ip', 'domain'):
|
||||
if field not in data:
|
||||
return jsonify({'error': f'Missing field: {field}'}), 400
|
||||
link = cell_link_manager.add_connection(data)
|
||||
return jsonify({'message': f"Connected to cell '{data['cell_name']}'", 'link': link}), 201
|
||||
except ValueError as e:
|
||||
return jsonify({'error': str(e)}), 400
|
||||
except Exception as e:
|
||||
logger.error(f"Error adding cell connection: {e}")
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
@bp.route('/api/cells/<cell_name>', methods=['DELETE'])
|
||||
def remove_cell_connection(cell_name):
|
||||
try:
|
||||
from app import cell_link_manager
|
||||
cell_link_manager.remove_connection(cell_name)
|
||||
return jsonify({'message': f"Cell '{cell_name}' disconnected"})
|
||||
except ValueError as e:
|
||||
return jsonify({'error': str(e)}), 404
|
||||
except Exception as e:
|
||||
logger.error(f"Error removing cell connection: {e}")
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
@bp.route('/api/cells/<cell_name>/status', methods=['GET'])
|
||||
def get_cell_connection_status(cell_name):
|
||||
try:
|
||||
from app import cell_link_manager
|
||||
return jsonify(cell_link_manager.get_connection_status(cell_name))
|
||||
except ValueError as e:
|
||||
return jsonify({'error': str(e)}), 404
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
Reference in New Issue
Block a user