Files
pic/api/routes/network.py
T
roof f84f16fcd6
Unit Tests / test (push) Successful in 11m13s
fix: add /api/network/dns/corefile endpoint and per-line iptables check
The e2e tests were reading a stale Corefile at a hardcoded fallback path
(/home/roof/pic/config/dns/Corefile) instead of the live one written by
the API (/opt/pic/config/dns/Corefile on pic1). Adding a proper API
endpoint eliminates the path ambiguity.

The iptables test was checking whether peer_ip, DROP, and dpt:80 appeared
anywhere in the full multi-line output rather than on the same rule line,
producing false positives. Now checks per line.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 05:54:17 -04:00

125 lines
4.4 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/dhcp/leases', methods=['GET'])
def get_dhcp_leases():
try:
from app import network_manager
return jsonify(network_manager.get_dhcp_leases())
except Exception as e:
logger.error(f"Error getting DHCP leases: {e}")
return jsonify({"error": str(e)}), 500
@bp.route('/api/dhcp/reservations', methods=['POST'])
def add_dhcp_reservation():
try:
from app import network_manager
data = request.get_json(silent=True)
if not data:
return jsonify({"error": "No data provided"}), 400
for field in ('mac', 'ip'):
if field not in data:
return jsonify({"error": f"Missing required field: {field}"}), 400
result = network_manager.add_dhcp_reservation(data['mac'], data['ip'], data.get('hostname', ''))
return jsonify({"success": result})
except Exception as e:
logger.error(f"Error adding DHCP reservation: {e}")
return jsonify({"error": str(e)}), 500
@bp.route('/api/dhcp/reservations', methods=['DELETE'])
def remove_dhcp_reservation():
try:
from app import network_manager
data = request.get_json(silent=True)
if not data or 'mac' not in data:
return jsonify({"error": "Missing required field: mac"}), 400
result = network_manager.remove_dhcp_reservation(data['mac'])
return jsonify({"success": result})
except Exception as e:
logger.error(f"Error removing DHCP reservation: {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