from fastapi import APIRouter, Depends, HTTPException, Request from sqlalchemy.orm import Session from typing import Optional from app.core.database import get_db from app.core.security import get_current_user from app.models.auth import User from app.schemas.network import ( NetworkCreate, NetworkUpdate, Network, NetworkListResponse, NetworkStats, IPAddressListResponse, IPAddressUpdate, IPAddress ) from app.services.network_service import NetworkService from app.services.audit_service import AuditService, AuditAction router = APIRouter( prefix="/networks", tags=["网段管理"], dependencies=[Depends(get_current_user)], ) def _client_info(request: Request) -> tuple[str, str]: return ( request.client.host if request.client else "", (request.headers.get("user-agent") or "")[:500], ) @router.get("", response_model=NetworkListResponse, summary="获取网段列表") def get_networks( skip: int = 0, limit: int = 100, group_name: Optional[str] = None, db: Session = Depends(get_db) ): """获取所有网段列表""" total, items = NetworkService.get_list(db, skip=skip, limit=limit, group_name=group_name) return {"total": total, "items": items} @router.get("/stats", response_model=list[NetworkStats], summary="获取所有网段统计") def get_all_network_stats(db: Session = Depends(get_db)): """获取所有网段的统计信息""" return NetworkService.get_all_stats(db) @router.get("/{network_id}", response_model=Network, summary="获取网段详情") def get_network(network_id: int, db: Session = Depends(get_db)): """根据ID获取网段详情""" network = NetworkService.get_by_id(db, network_id) if not network: raise HTTPException(status_code=404, detail="网段不存在") return network @router.get("/{network_id}/stats", response_model=NetworkStats, summary="获取网段统计") def get_network_stats(network_id: int, db: Session = Depends(get_db)): """获取指定网段的统计信息""" stats = NetworkService.get_stats(db, network_id) if not stats: raise HTTPException(status_code=404, detail="网段不存在") return stats @router.get("/{network_id}/ips", response_model=IPAddressListResponse, summary="获取网段下的IP列表") def get_network_ips( network_id: int, skip: int = 0, limit: int = 200, db: Session = Depends(get_db) ): """获取指定网段下的所有IP地址""" from app.services.ip_service import IPService total, items = IPService.get_list(db, network_id=network_id, skip=skip, limit=limit) return {"total": total, "items": items} @router.post("", response_model=Network, status_code=201, summary="创建网段") def create_network( network_in: NetworkCreate, request: Request, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """创建新网段,支持CIDR格式""" existing = NetworkService.get_by_cidr(db, network_in.cidr) if existing: raise HTTPException(status_code=400, detail="该网段已存在") ip, ua = _client_info(request) try: network = NetworkService.create(db, network_in) except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) AuditService.record( db, action=AuditAction.NETWORK_CREATE, user=current_user, resource_type="network", resource_id=network.id, resource_name=network.cidr, method="POST", path=str(request.url.path), ip_address=ip, user_agent=ua, detail={"cidr": network.cidr, "name": network.name}, ) return network @router.put("/{network_id}", response_model=Network, summary="更新网段") def update_network( network_id: int, network_in: NetworkUpdate, request: Request, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """更新网段信息""" old = NetworkService.get_by_id(db, network_id) if not old: raise HTTPException(status_code=404, detail="网段不存在") network = NetworkService.update(db, network_id, network_in) if not network: raise HTTPException(status_code=404, detail="网段不存在") ip, ua = _client_info(request) AuditService.record( db, action=AuditAction.NETWORK_UPDATE, user=current_user, resource_type="network", resource_id=network.id, resource_name=network.cidr, method="PUT", path=str(request.url.path), ip_address=ip, user_agent=ua, detail={ "before": {"name": old.name, "gateway": old.gateway, "group_name": old.group_name, "vlan_id": old.vlan_id, "description": old.description}, "after": {"name": network.name, "gateway": network.gateway, "group_name": network.group_name, "vlan_id": network.vlan_id, "description": network.description}, }, ) return network @router.delete("/{network_id}", summary="删除网段") def delete_network( network_id: int, request: Request, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """删除网段及其下的所有IP记录""" network = NetworkService.get_by_id(db, network_id) if not network: raise HTTPException(status_code=404, detail="网段不存在") cidr_snapshot = network.cidr success = NetworkService.delete(db, network_id) if not success: raise HTTPException(status_code=404, detail="网段不存在") ip, ua = _client_info(request) AuditService.record( db, action=AuditAction.NETWORK_DELETE, user=current_user, resource_type="network", resource_id=network_id, resource_name=cidr_snapshot, method="DELETE", path=str(request.url.path), ip_address=ip, user_agent=ua, detail={"cidr": cidr_snapshot}, ) return {"message": "删除成功"}