chore: initial baseline with P0-safety .gitignore

This commit is contained in:
Simon
2026-06-14 16:49:18 +08:00
commit 63262292d7
510 changed files with 146008 additions and 0 deletions
+373
View File
@@ -0,0 +1,373 @@
# =============================================================================
# 企微IT智能服务台 — 火绒集成数据模型
# =============================================================================
# 说明:火绒API请求/响应的 Pydantic 数据模型
# 包含:终端信息、漏洞信息、病毒事件、任务下发等
# =============================================================================
from typing import Any, Dict, List, Optional
from pydantic import BaseModel, Field, model_validator
# ==========================================================================
# 通用响应模型
# ==========================================================================
class HuorongApiResponse(BaseModel):
"""火绒API统一响应模型。
火绒所有API返回格式一致(官方API文档 v1):
成功时: { "errno": 0, "errmsg": "", "data": { ... } }
失败时: { "errno": 1, "errmsg": "Authentication failed" }
官方错误码定义:
- errno=0: 成功
- errno=1: 认证失败
- errno=2: 参数错误
- errno=3: 服务器内部错误
- errno=4: API未授权
注意:火绒API始终使用 errno(不是 errcode)。
使用 model_validator 在验证前将 errno 归一化为 errcode
保持内部代码统一使用 errcode 字段。
Attributes:
errcode: 错误码,0表示成功(从 errno 归一化而来)
errmsg: 错误描述(成功时为空字符串)
data: 业务数据(成功时非None)
"""
@model_validator(mode='before')
@classmethod
def normalize_error_fields(cls, data: Any) -> Any:
"""将火绒API返回的 errno 字段归一化为 errcode。
火绒API在认证失败等错误场景下返回 errno 而非 errcode
此验证器在 Pydantic 字段校验前将 errno 转换为 errcode
统一后续处理逻辑。
Args:
data: 原始输入数据(通常为dict)
Returns:
归一化后的数据
"""
if isinstance(data, dict) and 'errno' in data and 'errcode' not in data:
data['errcode'] = data.pop('errno')
return data
errcode: int = Field(..., description="错误码,0=成功")
errmsg: str = Field(default="ok", description="错误描述")
data: Optional[Any] = Field(default=None, description="业务数据")
# ==========================================================================
# 终端基本信息 — /api/clnts/_list 返回
# ==========================================================================
class TerminalBasicInfo(BaseModel):
"""终端基本信息(_list 接口返回的每条记录)。
字段名严格按照火绒API文档实际返回值定义。
注意:API返回的字段名与之前猜测不同,已根据官方文档修正。
Attributes:
id: 内部数据库ID
client_id: 终端唯一ID(40位十六进制字符串,用于所有任务下发)
client_name: 客户端名称
computer_name: 计算机名
local_ip: 本地IP
connect_ip: 连接IP(客户端连接控制中心使用的IP)
mac: MAC地址
group_id: 分组ID
os_version: 操作系统版本
version: 火绒客户端版本
definitions: 病毒库更新时间
is_online: 在线状态
last_connect_time: 最后连接时间(Unix时间戳)
last_seen_time: 最后可见时间(Unix时间戳)
first_appear_time: 首次出现时间(Unix时间戳)
"""
id: Optional[int] = Field(default=None, description="内部数据库ID")
client_id: str = Field(..., description="终端唯一ID")
client_name: str = Field(default="", description="客户端名称")
computer_name: str = Field(default="", description="计算机名")
local_ip: str = Field(default="", description="本地IP")
connect_ip: str = Field(default="", description="连接IP")
mac: str = Field(default="", description="MAC地址")
group_id: Optional[Any] = Field(default=None, description="分组IDint或str")
os_version: str = Field(default="", description="操作系统版本")
version: str = Field(default="", description="火绒客户端版本")
definitions: str = Field(default="", description="病毒库更新时间")
is_online: bool = Field(default=False, description="在线状态")
last_connect_time: Optional[int] = Field(default=None, description="最后连接时间")
last_seen_time: Optional[int] = Field(default=None, description="最后可见时间")
first_appear_time: Optional[int] = Field(default=None, description="首次出现时间")
class TerminalListRequest(BaseModel):
"""终端列表查询请求。
Attributes:
group_id: 分组ID(可选,不传则查全部分组)
page: 页码(从1开始)
per_page: 每页条数
"""
group_id: Optional[str] = Field(default=None, description="分组ID")
page: int = Field(default=1, ge=1, description="页码")
per_page: int = Field(default=20, ge=1, le=100, description="每页条数")
# ==========================================================================
# 终端详细信息v2 — /api/clnts/_info2 返回
# ==========================================================================
class HardwareInfo(BaseModel):
"""终端硬件信息。
Attributes:
cpu: CPU信息
memory: 内存信息
disk: 磁盘信息
motherboard: 主板信息
network_card: 网卡信息
"""
cpu: str = Field(default="", description="CPU信息")
memory: str = Field(default="", description="内存信息")
disk: str = Field(default="", description="磁盘信息")
motherboard: str = Field(default="", description="主板信息")
network_card: str = Field(default="", description="网卡信息")
class SoftwareInfo(BaseModel):
"""已安装软件条目。
Attributes:
name: 软件名称
version: 版本号
publisher: 发布者
"""
name: str = Field(default="", description="软件名称")
version: str = Field(default="", description="版本号")
publisher: str = Field(default="", description="发布者")
class AssetInfo(BaseModel):
"""资产信息。
Attributes:
asset_tag: 资产标签
serial_number: 序列号
"""
asset_tag: str = Field(default="", description="资产标签")
serial_number: str = Field(default="", description="序列号")
class NetworkConfig(BaseModel):
"""网络配置信息。
Attributes:
ip: IP地址
gateway: 网关
dns: DNS服务器
adapter_info: 网卡适配器信息
"""
ip: str = Field(default="", description="IP地址")
gateway: str = Field(default="", description="网关")
dns: str = Field(default="", description="DNS服务器")
adapter_info: str = Field(default="", description="网卡适配器信息")
class TerminalDetailV2(BaseModel):
"""终端详细信息v2(_info2 接口返回)。
通过 optional_fields 参数指定需要返回的信息块:
- hardware: 硬件信息
- software: 已安装软件
- assets: 资产信息
- netconf: 网络配置
Attributes:
client_id: 终端唯一ID
computer_name: 计算机名
hardware: 硬件信息(可选)
software: 已安装软件列表(可选)
assets: 资产信息(可选)
netconf: 网络配置(可选)
"""
client_id: str = Field(..., description="终端唯一ID")
computer_name: str = Field(default="", description="计算机名")
hardware: Optional[HardwareInfo] = Field(default=None, description="硬件信息")
software: Optional[List[SoftwareInfo]] = Field(default=None, description="已安装软件")
assets: Optional[AssetInfo] = Field(default=None, description="资产信息")
netconf: Optional[NetworkConfig] = Field(default=None, description="网络配置")
class TerminalDetailRequest(BaseModel):
"""终端详细信息查询请求。
Attributes:
client_id: 终端唯一ID
optional_fields: 需要返回的可选信息块列表
"""
client_id: str = Field(..., description="终端唯一ID")
optional_fields: List[str] = Field(
default_factory=lambda: ["hardware", "software", "assets", "netconf"],
description="可选信息块: hardware/software/assets/netconf",
)
# ==========================================================================
# 漏洞信息 — /api/clnts/_leak 返回
# 说明:_leak 接口返回的是"存在高危漏洞未修复的终端列表",
# 每条记录是终端信息(非漏洞详情),API不返回具体漏洞CVE列表。
# 外层还有 all_client(终端总数)和 risk_client(高危终端数)统计。
# ==========================================================================
class TerminalLeakInfo(BaseModel):
"""存在高危漏洞的终端信息(_leak 接口返回的每条记录)。
注意:_leak 返回的是终端维度数据,不是漏洞维度。
字段名严格按照火绒API文档实际返回值定义。
与 _list 接口的字段名不同!
Attributes:
cid: 终端唯一ID_leak 中叫 cid_list 中叫 client_id
hostname: 计算机名(_leak 中叫 hostname_list 中叫 computer_name
client_name: 终端名称
group_name: 分组名称
group_id: 分组ID
ip_addr: 本地IP_leak 中叫 ip_addr_list 中叫 local_ip
call_ip: 连接IP_leak 中叫 call_ip_list 中叫 connect_ip
mac: MAC地址
osver: 操作系统版本(_leak 中叫 osver_list 中叫 os_version
os_type: 终端类型(如 Windows
prodver: 火绒客户端版本(_leak 中叫 prodver_list 中叫 version
virdb: 病毒库版本(Unix时间戳,_leak 中叫 virdb_list 中叫 definitions
stat: 在线状态码(1=离线, 2=在线, 3=异常,_list 中是 is_online 布尔值)
"""
cid: str = Field(..., description="终端唯一ID")
hostname: str = Field(default="", description="计算机名")
client_name: str = Field(default="", description="终端名称")
group_name: str = Field(default="", description="分组名称")
group_id: Optional[Any] = Field(default=None, description="分组ID")
ip_addr: str = Field(default="", description="本地IP")
call_ip: str = Field(default="", description="连接IP")
mac: str = Field(default="", description="MAC地址")
osver: str = Field(default="", description="操作系统版本")
os_type: str = Field(default="", description="终端类型")
prodver: str = Field(default="", description="火绒客户端版本")
virdb: Optional[Any] = Field(default=None, description="病毒库版本(Unix时间戳)")
stat: int = Field(default=1, description="在线状态码: 1=离线 2=在线 3=异常")
# ==========================================================================
# 病毒事件 — /api/clnts/_virus_events 返回
# 说明:_virus_events 返回终端维度的病毒日志统计,
# 含总数(count)和4种处理结果(result)的明细。
# 请求需指定 type: 0=按client_id查, 1=按group_id查, 2=查全部
# ==========================================================================
class VirusHandleResult(BaseModel):
"""病毒事件处理结果统计。
Attributes:
success: 处理成功数
fail: 处理失败数
ignored: 暂不处理数
trusted: 已信任数
"""
success: int = Field(default=0, description="处理成功数")
fail: int = Field(default=0, description="处理失败数")
ignored: int = Field(default=0, description="暂不处理数")
trusted: int = Field(default=0, description="已信任数")
class VirusEventStats(BaseModel):
"""终端病毒事件统计(_virus_events 接口返回的每条记录)。
字段名严格按照火绒API文档实际返回值定义。
与 _list 接口的字段名基本一致。
Attributes:
group_id: 分组ID
client_id: 终端唯一ID
client_name: 终端名称
computer_name: 计算机名
local_ip: 本地IP
connect_ip: 连接IP
mac: MAC地址
count: 病毒日志总数
result: 处理结果统计(success/fail/ignored/trusted
"""
group_id: Optional[Any] = Field(default=None, description="分组ID")
client_id: str = Field(..., description="终端唯一ID")
client_name: str = Field(default="", description="终端名称")
computer_name: str = Field(default="", description="计算机名")
local_ip: str = Field(default="", description="本地IP")
connect_ip: str = Field(default="", description="连接IP")
mac: str = Field(default="", description="MAC地址")
count: int = Field(default=0, description="病毒日志总数")
result: Optional[VirusHandleResult] = Field(default=None, description="处理结果统计")
# ==========================================================================
# 终端任务 — /api/task/_create
# ==========================================================================
class TaskCreateRequest(BaseModel):
"""终端任务创建请求。
支持的任务类型:
- quick_scan: 快速扫描
- full_scan: 全盘扫描
- custom_scan: 自定义扫描
- netctrl: 终端隔离/解除
- message: 发送通知
Attributes:
task_type: 任务类型
client_ids: 目标终端ID列表
net_isolation: 是否隔离(仅 netctrl 类型有效)
message_content: 通知内容(仅 message 类型有效)
"""
task_type: str = Field(..., description="任务类型: quick_scan/full_scan/custom_scan/netctrl/message")
client_ids: List[str] = Field(..., min_length=1, description="目标终端ID列表")
net_isolation: Optional[bool] = Field(default=None, description="是否隔离(仅netctrl类型)")
message_content: Optional[str] = Field(default=None, description="通知内容(仅message类型)")
# ==========================================================================
# 终端安全画像(聚合模型,供前端直接使用)
# ==========================================================================
class TerminalSecurityProfile(BaseModel):
"""终端安全画像(聚合模型)。
将终端基本信息+安全状态聚合成一个模型,供坐席端直接展示。
Attributes:
client_id: 终端唯一ID
computer_name: 计算机名
ip: 本地IP
mac: MAC地址
os_version: 操作系统版本
is_online: 在线状态
group_name: 分组名称
hardware: 硬件概要
high_risk_leaks: 高危漏洞数
uncleaned_virus: 未处理病毒事件数
security_score: 安全评分(0-100,综合漏洞+病毒+在线状态)
"""
client_id: str = Field(..., description="终端唯一ID")
computer_name: str = Field(default="", description="计算机名")
ip: str = Field(default="", description="本地IP")
mac: str = Field(default="", description="MAC地址")
os_version: str = Field(default="", description="操作系统版本")
is_online: bool = Field(default=False, description="在线状态")
group_name: str = Field(default="", description="分组名称")
hardware: Optional[HardwareInfo] = Field(default=None, description="硬件概要")
high_risk_leaks: int = Field(default=0, description="高危漏洞数")
uncleaned_virus: int = Field(default=0, description="未处理病毒事件数")
security_score: int = Field(default=100, description="安全评分(0-100)")