c41cadafb4
Network Services page is rebuilt around real API data: GET /api/dns/overview returns provider-aware records; per-service Cloudflare sync is exposed via POST /api/ddns/sync; effective domain is displayed so operators can verify what external name resolves to the cell; NTP status reflects the actual systemd-timesyncd state rather than a hardcoded boolean. DHCP is fully decommissioned: the cell-dhcp container is removed from docker-compose.yml, DHCP methods are stripped from network_manager, the setup_cell script no longer seeds DHCP config, and the Settings DHCP field is gone. DHCP was never a PIC responsibility and the container was consuming resources for no benefit. Dead code removed: api/config.py (superseded by config_manager), the standalone Email/Calendar/Files pages (these are now optional store services and do not need dedicated pages). api/constants.py is introduced to hold RESERVED_SUBDOMAINS in one place rather than scattered literals. Docker resource limits (mem_limit, cpus, pids_limit) are added to all compose services so a runaway process cannot starve the host. Makefile gains a warning before the backup target so operators are not surprised by the archive path. Settings same/accept state fix ensures the Cell Identity section correctly shows the accept/discard banner and does not flash a false-positive change indicator on first load. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
97 lines
3.3 KiB
Python
97 lines
3.3 KiB
Python
import logging
|
|
import os
|
|
from flask import Blueprint, request, jsonify, Response
|
|
logger = logging.getLogger('picell')
|
|
bp = Blueprint('network', __name__)
|
|
|
|
@bp.route('/api/dns/records', methods=['GET'])
|
|
def get_dns_records():
|
|
try:
|
|
from app import network_manager
|
|
return jsonify(network_manager.get_dns_records())
|
|
except Exception as e:
|
|
logger.error(f"Error getting DNS records: {e}")
|
|
return jsonify({"error": str(e)}), 500
|
|
|
|
@bp.route('/api/dns/records', methods=['POST'])
|
|
def add_dns_record():
|
|
try:
|
|
from app import network_manager
|
|
data = request.get_json(silent=True)
|
|
if data is None:
|
|
return jsonify({"error": "No data provided"}), 400
|
|
return jsonify(network_manager.add_dns_record(**data))
|
|
except Exception as e:
|
|
logger.error(f"Error adding DNS record: {e}")
|
|
return jsonify({"error": str(e)}), 500
|
|
|
|
@bp.route('/api/dns/records', methods=['DELETE'])
|
|
def remove_dns_record():
|
|
try:
|
|
from app import network_manager
|
|
data = request.get_json(silent=True)
|
|
return jsonify(network_manager.remove_dns_record(**data))
|
|
except Exception as e:
|
|
logger.error(f"Error removing DNS record: {e}")
|
|
return jsonify({"error": str(e)}), 500
|
|
|
|
@bp.route('/api/dns/overview', methods=['GET'])
|
|
def get_dns_overview():
|
|
try:
|
|
from app import network_manager, config_manager, ddns_manager
|
|
overview = network_manager.get_dns_overview(config_manager, ddns_manager)
|
|
return jsonify(overview)
|
|
except Exception as e:
|
|
logger.error(f"Error getting DNS overview: {e}")
|
|
return jsonify({"error": str(e)}), 500
|
|
|
|
@bp.route('/api/ntp/status', methods=['GET'])
|
|
def get_ntp_status():
|
|
try:
|
|
from app import network_manager
|
|
return jsonify(network_manager.get_ntp_status())
|
|
except Exception as e:
|
|
logger.error(f"Error getting NTP status: {e}")
|
|
return jsonify({"error": str(e)}), 500
|
|
|
|
@bp.route('/api/network/info', methods=['GET'])
|
|
def get_network_info():
|
|
try:
|
|
from app import network_manager
|
|
return jsonify(network_manager.get_network_info())
|
|
except Exception as e:
|
|
logger.error(f"Error getting network info: {e}")
|
|
return jsonify({"error": str(e)}), 500
|
|
|
|
@bp.route('/api/dns/status', methods=['GET'])
|
|
def get_dns_status():
|
|
try:
|
|
from app import network_manager
|
|
return jsonify(network_manager.get_dns_status())
|
|
except Exception as e:
|
|
logger.error(f"Error getting DNS status: {e}")
|
|
return jsonify({"error": str(e)}), 500
|
|
|
|
@bp.route('/api/network/dns/corefile', methods=['GET'])
|
|
def get_corefile():
|
|
try:
|
|
from app import COREFILE_PATH
|
|
with open(COREFILE_PATH, 'r') as f:
|
|
content = f.read()
|
|
return Response(content, mimetype='text/plain')
|
|
except FileNotFoundError:
|
|
return Response('', mimetype='text/plain'), 404
|
|
except Exception as e:
|
|
logger.error(f"Error reading Corefile: {e}")
|
|
return jsonify({"error": str(e)}), 500
|
|
|
|
|
|
@bp.route('/api/network/test', methods=['POST'])
|
|
def test_network():
|
|
try:
|
|
from app import network_manager
|
|
return jsonify(network_manager.test_connectivity())
|
|
except Exception as e:
|
|
logger.error(f"Error testing network: {e}")
|
|
return jsonify({"error": str(e)}), 500
|