""" API routes for the NetViz application. """ from flask import jsonify, request, abort from flask_login import login_required, current_user from app.api import api_bp from app.models.network import Network, Subnet, Device, FirewallRule from app.extensions import db, limiter @api_bp.route("/health") def health_check(): """Health check endpoint.""" return jsonify({"status": "ok"}) @api_bp.route("/networks") @login_required @limiter.limit("60/minute") def get_networks(): """Get all networks for the current user.""" networks = Network.query.filter_by(user_id=current_user.id).all() return jsonify([{ "id": network.id, "name": network.name, "description": network.description, "created_at": network.created_at.isoformat(), "updated_at": network.updated_at.isoformat(), "subnet_count": len(network.subnets), "device_count": len(network.devices) } for network in networks]) @api_bp.route("/networks/") @login_required @limiter.limit("60/minute") def get_network(network_id): """Get a specific network.""" network = Network.query.get_or_404(network_id) # Security check if network.user_id != current_user.id: abort(403) return jsonify(network.to_dict()) @api_bp.route("/networks//export") @login_required @limiter.limit("10/minute") def export_network(network_id): """Export a network as JSON.""" network = Network.query.get_or_404(network_id) # Security check if network.user_id != current_user.id: abort(403) return jsonify(network.to_dict()) @api_bp.route("/networks/import", methods=["POST"]) @login_required @limiter.limit("5/minute") def import_network(): """Import a network from JSON.""" if not request.is_json: return jsonify({"error": "Request must be JSON"}), 400 data = request.get_json() try: # Create network network = Network.from_dict(data, current_user.id) db.session.add(network) db.session.flush() # Get ID without committing # Create subnets for subnet_data in data.get("subnets", []): subnet = Subnet( name=subnet_data["name"], cidr=subnet_data["cidr"], vlan=subnet_data.get("vlan"), description=subnet_data.get("description", ""), network_id=network.id ) db.session.add(subnet) db.session.flush() # Create devices for device_data in data.get("devices", []): device = Device( name=device_data["name"], ip_address=device_data.get("ip_address"), mac_address=device_data.get("mac_address"), device_type=device_data.get("device_type"), os=device_data.get("os"), description=device_data.get("description", ""), network_id=network.id, subnet_id=device_data.get("subnet_id") ) if "properties" in device_data: device.set_properties(device_data["properties"]) db.session.add(device) # Create firewall rules for rule_data in data.get("firewall_rules", []): rule = FirewallRule( name=rule_data["name"], source=rule_data["source"], destination=rule_data["destination"], protocol=rule_data.get("protocol"), port_range=rule_data.get("port_range"), action=rule_data["action"], description=rule_data.get("description", ""), network_id=network.id ) db.session.add(rule) db.session.commit() return jsonify({ "message": "Network imported successfully", "network_id": network.id }), 201 except KeyError as e: db.session.rollback() return jsonify({"error": f"Missing required field: {str(e)}"}), 400 except Exception as e: db.session.rollback() return jsonify({"error": str(e)}), 400