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 IPAddressListResponse, IPAddressUpdate, IPAddress from app.models.network import IPStatus from app.services.ip_service import IPService from app.services.audit_service import AuditService, AuditAction router = APIRouter( prefix="/ips", tags=["IP地址管理"], 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=IPAddressListResponse, summary="获取IP列表") def get_ips( network_id: Optional[int] = None, status: Optional[IPStatus] = None, search: Optional[str] = None, skip: int = 0, limit: int = 100, db: Session = Depends(get_db) ): """获取IP地址列表,支持过滤和搜索""" total, items = IPService.get_list( db, network_id=network_id, status=status, skip=skip, limit=limit, search=search ) return {"total": total, "items": items} @router.get("/{ip_id}", response_model=IPAddress, summary="获取IP详情") def get_ip(ip_id: int, db: Session = Depends(get_db)): """根据ID获取IP详情""" ip = IPService.get_by_id(db, ip_id) if not ip: raise HTTPException(status_code=404, detail="IP不存在") return ip @router.get("/address/{ip_address}", response_model=IPAddress, summary="根据IP地址查询") def get_ip_by_address(ip_address: str, db: Session = Depends(get_db)): """根据IP地址查询详细信息""" ip = IPService.get_by_ip(db, ip_address) if not ip: raise HTTPException(status_code=404, detail="IP不存在") return ip @router.put("/{ip_id}", response_model=IPAddress, summary="更新IP信息") def update_ip( ip_id: int, ip_in: IPAddressUpdate, request: Request, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """更新IP地址的属性信息""" old = IPService.get_by_id(db, ip_id) if not old: raise HTTPException(status_code=404, detail="IP不存在") ip = IPService.update(db, ip_id, ip_in) if not ip: raise HTTPException(status_code=404, detail="IP不存在") c, u = _client_info(request) AuditService.record( db, action=AuditAction.IP_UPDATE, user=current_user, resource_type="ip", resource_id=str(ip.id), resource_name=ip.ip_address, method="PUT", path=str(request.url.path), ip_address=c, user_agent=u, detail={ "before": { "owner": old.owner, "hostname": old.hostname, "mac_address": old.mac_address, "vendor": old.vendor, "status": old.status.value if old.status else None, "notes": old.notes, "switch_name": old.switch_name, "switch_port": old.switch_port, }, "after": { "owner": ip.owner, "hostname": ip.hostname, "mac_address": ip.mac_address, "vendor": ip.vendor, "status": ip.status.value if ip.status else None, "notes": ip.notes, "switch_name": ip.switch_name, "switch_port": ip.switch_port, }, }, ) return ip @router.post("/{ip_id}/reserve", response_model=IPAddress, summary="标记为保留IP") def reserve_ip( ip_id: int, request: Request, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """将IP标记为保留状态,禁止分配""" ip = IPService.set_reserved(db, ip_id, reserved=True) if not ip: raise HTTPException(status_code=404, detail="IP不存在") c, u = _client_info(request) AuditService.record( db, action=AuditAction.IP_RESERVE, user=current_user, resource_type="ip", resource_id=str(ip.id), resource_name=ip.ip_address, method="POST", path=str(request.url.path), ip_address=c, user_agent=u, ) return ip @router.post("/{ip_id}/unreserve", response_model=IPAddress, summary="取消保留IP") def unreserve_ip( ip_id: int, request: Request, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """取消IP的保留状态""" ip = IPService.set_reserved(db, ip_id, reserved=False) if not ip: raise HTTPException(status_code=404, detail="IP不存在") c, u = _client_info(request) AuditService.record( db, action=AuditAction.IP_UNRESERVE, user=current_user, resource_type="ip", resource_id=str(ip.id), resource_name=ip.ip_address, method="POST", path=str(request.url.path), ip_address=c, user_agent=u, ) return ip