63 lines
2.7 KiB
Python
63 lines
2.7 KiB
Python
"""BGP raw observation model for routing event ingestion."""
|
|
|
|
from sqlalchemy import Column, DateTime, ForeignKey, Index, Integer, JSON, String, Text
|
|
from sqlalchemy.sql import func
|
|
|
|
from app.core.time import to_iso8601_utc
|
|
from app.db.session import Base
|
|
|
|
|
|
class BGPObservation(Base):
|
|
__tablename__ = "bgp_observations"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
snapshot_id = Column(Integer, ForeignKey("data_snapshots.id"), nullable=True, index=True)
|
|
task_id = Column(Integer, ForeignKey("collection_tasks.id"), nullable=True, index=True)
|
|
source = Column(String(100), nullable=False, index=True)
|
|
ingest_batch_id = Column(String(100), nullable=True, index=True)
|
|
source_event_id = Column(String(100), nullable=True, index=True)
|
|
collector = Column(String(100), nullable=True, index=True)
|
|
peer_asn = Column(Integer, nullable=True, index=True)
|
|
peer_ip = Column(String(100), nullable=True)
|
|
prefix = Column(String(64), nullable=True, index=True)
|
|
event_type = Column(String(32), nullable=False, index=True)
|
|
as_path = Column(JSON, default=list)
|
|
origin_asn = Column(Integer, nullable=True, index=True)
|
|
next_hop = Column(String(100), nullable=True)
|
|
communities = Column(JSON, default=list)
|
|
observed_at = Column(DateTime(timezone=True), nullable=False, index=True)
|
|
collector_geo = Column(JSON, default=dict)
|
|
raw_payload = Column(JSON, default=dict)
|
|
created_at = Column(DateTime(timezone=True), nullable=False, server_default=func.now(), index=True)
|
|
note = Column(Text, nullable=True)
|
|
|
|
__table_args__ = (
|
|
Index("idx_bgp_obs_source_observed", "source", "observed_at"),
|
|
Index("idx_bgp_obs_collector_prefix", "collector", "prefix"),
|
|
Index("idx_bgp_obs_task_source_event", "task_id", "source_event_id"),
|
|
)
|
|
|
|
def to_dict(self) -> dict:
|
|
return {
|
|
"id": self.id,
|
|
"snapshot_id": self.snapshot_id,
|
|
"task_id": self.task_id,
|
|
"source": self.source,
|
|
"ingest_batch_id": self.ingest_batch_id,
|
|
"source_event_id": self.source_event_id,
|
|
"collector": self.collector,
|
|
"peer_asn": self.peer_asn,
|
|
"peer_ip": self.peer_ip,
|
|
"prefix": self.prefix,
|
|
"event_type": self.event_type,
|
|
"as_path": self.as_path or [],
|
|
"origin_asn": self.origin_asn,
|
|
"next_hop": self.next_hop,
|
|
"communities": self.communities or [],
|
|
"observed_at": to_iso8601_utc(self.observed_at),
|
|
"collector_geo": self.collector_geo or {},
|
|
"raw_payload": self.raw_payload or {},
|
|
"created_at": to_iso8601_utc(self.created_at),
|
|
"note": self.note,
|
|
}
|