fix: expand bgp pipeline and stabilize backend tests

This commit is contained in:
linkong
2026-03-30 16:13:36 +08:00
parent 2015ab79bd
commit 945786cee5
22 changed files with 1787 additions and 228 deletions

View File

@@ -8,7 +8,8 @@ from sqlalchemy.ext.asyncio import AsyncSession
from app.core.security import get_current_user
from app.db.session import get_db
from app.models.bgp_anomaly import BGPAnomaly
from app.models.collected_data import CollectedData
from app.models.bgp_incident import BGPIncident
from app.models.bgp_observation import BGPObservation
from app.models.user import User
router = APIRouter()
@@ -48,12 +49,12 @@ async def list_bgp_events(
db: AsyncSession = Depends(get_db),
):
stmt = (
select(CollectedData)
.where(CollectedData.source.in_(BGP_SOURCES))
.order_by(CollectedData.reference_date.desc().nullslast(), CollectedData.id.desc())
select(BGPObservation)
.where(BGPObservation.source.in_(BGP_SOURCES))
.order_by(BGPObservation.observed_at.desc(), BGPObservation.id.desc())
)
if source:
stmt = stmt.where(CollectedData.source == source)
stmt = stmt.where(BGPObservation.source == source)
result = await db.execute(stmt)
records = result.scalars().all()
@@ -62,18 +63,17 @@ async def list_bgp_events(
filtered = []
for record in records:
metadata = record.extra_data or {}
if prefix and metadata.get("prefix") != prefix:
if prefix and record.prefix != prefix:
continue
if origin_asn is not None and metadata.get("origin_asn") != origin_asn:
if origin_asn is not None and record.origin_asn != origin_asn:
continue
if peer_asn is not None and metadata.get("peer_asn") != peer_asn:
if peer_asn is not None and record.peer_asn != peer_asn:
continue
if collector and metadata.get("collector") != collector:
if collector and record.collector != collector:
continue
if event_type and metadata.get("event_type") != event_type:
if event_type and record.event_type != event_type:
continue
if (dt_from or dt_to) and not _matches_time(record.reference_date, dt_from, dt_to):
if (dt_from or dt_to) and not _matches_time(record.observed_at, dt_from, dt_to):
continue
filtered.append(record)
@@ -92,7 +92,7 @@ async def get_bgp_event(
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
record = await db.get(CollectedData, event_id)
record = await db.get(BGPObservation, event_id)
if not record or record.source not in BGP_SOURCES:
raise HTTPException(status_code=404, detail="BGP event not found")
return record.to_dict()
@@ -180,3 +180,44 @@ async def get_bgp_anomaly(
if not record:
raise HTTPException(status_code=404, detail="BGP anomaly not found")
return record.to_dict()
@router.get("/incidents")
async def list_bgp_incidents(
severity: Optional[str] = Query(None),
incident_type: Optional[str] = Query(None),
status: Optional[str] = Query(None),
page: int = Query(1, ge=1),
page_size: int = Query(50, ge=1, le=200),
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
stmt = select(BGPIncident).order_by(BGPIncident.created_at.desc(), BGPIncident.id.desc())
if severity:
stmt = stmt.where(BGPIncident.severity == severity)
if incident_type:
stmt = stmt.where(BGPIncident.incident_type == incident_type)
if status:
stmt = stmt.where(BGPIncident.status == status)
result = await db.execute(stmt)
records = result.scalars().all()
offset = (page - 1) * page_size
return {
"total": len(records),
"page": page,
"page_size": page_size,
"data": [record.to_dict() for record in records[offset : offset + page_size]],
}
@router.get("/incidents/{incident_id}")
async def get_bgp_incident(
incident_id: int,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
record = await db.get(BGPIncident, incident_id)
if not record:
raise HTTPException(status_code=404, detail="BGP incident not found")
return record.to_dict()