netviz/app/api/routes.py
2025-03-25 23:41:13 +01:00

134 lines
No EOL
4.1 KiB
Python

"""
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/<int:network_id>")
@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/<int:network_id>/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