1e1e5957e8
- Ips.vue: el-select 添加 width: 280px,修复网段下拉框过窄 - Ips.vue: query 参数 networkId → network_id(与 FastAPI snake_case 一致) - Scan.vue: el-select 用 network.id 代替整个 network 对象作为 value,修复切换网段不生效 - enhanced_scan_service.py: 替换失效的 scapy ARP 扫描为 arp-scan 命令;扫描结果自动创建缺失 IP 记录
121 lines
4.5 KiB
Python
121 lines
4.5 KiB
Python
from sqlalchemy import Column, Integer, String, Text, DateTime, ForeignKey, Enum, Boolean, Float
|
|
from sqlalchemy.orm import relationship
|
|
from sqlalchemy.sql import func
|
|
from app.core.database import Base
|
|
import enum
|
|
|
|
|
|
class AlertType(str, enum.Enum):
|
|
"""告警类型"""
|
|
IP_CONFLICT = "ip_conflict" # IP 冲突
|
|
UNAUTHORIZED_ACCESS = "unauthorized_access" # 未授权接入
|
|
SUBNET_FULL = "subnet_full" # 网段耗尽
|
|
SCAN_FAILED = "scan_failed" # 扫描失败
|
|
DEVICE_OFFLINE = "device_offline" # 设备离线
|
|
NEW_DEVICE_DETECTED = "new_device_detected" # 新设备发现
|
|
MAC_CHANGED = "mac_changed" # MAC 地址变化
|
|
|
|
|
|
class AlertSeverity(str, enum.Enum):
|
|
"""告警级别"""
|
|
INFO = "info" # 信息
|
|
WARNING = "warning" # 警告
|
|
ERROR = "error" # 错误
|
|
CRITICAL = "critical" # 严重
|
|
|
|
|
|
class AlertStatus(str, enum.Enum):
|
|
"""告警状态"""
|
|
ACTIVE = "active" # 活跃
|
|
ACKNOWLEDGED = "acknowledged" # 已确认
|
|
RESOLVED = "resolved" # 已解决
|
|
IGNORED = "ignored" # 已忽略
|
|
|
|
|
|
class Alert(Base):
|
|
"""告警"""
|
|
__tablename__ = "alerts"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
alert_type = Column(Enum(AlertType), nullable=False, index=True)
|
|
severity = Column(Enum(AlertSeverity), default=AlertSeverity.WARNING, index=True)
|
|
status = Column(Enum(AlertStatus), default=AlertStatus.ACTIVE, index=True)
|
|
|
|
title = Column(String(255), nullable=False)
|
|
message = Column(Text)
|
|
|
|
# 关联对象
|
|
network_id = Column(Integer, ForeignKey("networks.id"), nullable=True)
|
|
ip_address_id = Column(Integer, ForeignKey("ip_addresses.id"), nullable=True)
|
|
device_id = Column(Integer, ForeignKey("network_devices.id"), nullable=True)
|
|
ip_address_str = Column(String(50), nullable=True) # 冗余存储便于查询
|
|
|
|
# 关联的 IP/MAC 信息
|
|
mac_address = Column(String(50), nullable=True)
|
|
conflicting_mac = Column(String(50), nullable=True) # 用于 IP 冲突告警
|
|
|
|
# 统计信息
|
|
usage_percent = Column(Float, nullable=True) # 网段使用率告警时存储
|
|
|
|
# 处理信息
|
|
acknowledged_by = Column(String(100), nullable=True)
|
|
acknowledged_at = Column(DateTime(timezone=True), nullable=True)
|
|
resolved_by = Column(String(100), nullable=True)
|
|
resolved_at = Column(DateTime(timezone=True), nullable=True)
|
|
resolution_notes = Column(Text, nullable=True)
|
|
|
|
created_at = Column(DateTime(timezone=True), server_default=func.now(), index=True)
|
|
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
|
|
|
# 关系
|
|
network = relationship("Network")
|
|
ip_address = relationship("IPAddress")
|
|
device = relationship("NetworkDevice")
|
|
|
|
|
|
class AlertRule(Base):
|
|
"""告警规则配置"""
|
|
__tablename__ = "alert_rules"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
name = Column(String(100), unique=True, nullable=False)
|
|
description = Column(Text, nullable=True)
|
|
|
|
alert_type = Column(Enum(AlertType), nullable=False)
|
|
severity = Column(Enum(AlertSeverity), default=AlertSeverity.WARNING)
|
|
|
|
# 规则条件
|
|
enabled = Column(Boolean, default=True)
|
|
|
|
# 阈值配置
|
|
subnet_usage_threshold = Column(Float, default=90.0) # 网段使用率阈值 %
|
|
scan_failure_threshold = Column(Integer, default=3) # 扫描失败次数阈值
|
|
inactivity_threshold_minutes = Column(Integer, default=60) # 设备不活动阈值(分钟)
|
|
|
|
# MAC 白名单(用于未授权接入检测)
|
|
mac_whitelist_enabled = Column(Boolean, default=False)
|
|
mac_whitelist = Column(Text, nullable=True) # JSON 格式的 MAC 列表
|
|
|
|
# 通知配置
|
|
notify_email = Column(Boolean, default=False)
|
|
notify_webhook = Column(Boolean, default=False)
|
|
notification_channels = Column(Text, nullable=True) # JSON 格式的通知渠道
|
|
|
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
|
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
|
|
|
|
|
class WhitelistedMAC(Base):
|
|
"""MAC 地址白名单"""
|
|
__tablename__ = "whitelisted_macs"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
mac_address = Column(String(50), unique=True, nullable=False, index=True)
|
|
description = Column(String(255), nullable=True)
|
|
owner = Column(String(100), nullable=True)
|
|
|
|
is_active = Column(Boolean, default=True)
|
|
|
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
|
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|