rpkiparrot 设计
本文确定 rpkiparrot 的功能范围、接口边界和验收要求,供库开发者及所有第三方使用者与集成者使用。项目定位为面向广泛第三方开发者和应用的通用 Python 库,配套提供可独立使用的轻量级 CLI。库提供 RTR 客户端、JSON 读取器,以及 VRP 和 ASPA 的内存存储与验证能力;持久化、共享读取和集中查询按需启用。
bmparrot 和 bmpalert 是初期集成参考与示例使用方。公共 API、默认行为、文档和示例面向独立的第三方集成设计,使用者无需了解或依赖这些应用的配置、数据模型与运行流程。第三方可以按需组合各模块,接入自己的应用、服务或工具。
产品主线是可嵌入应用的 RTR 客户端库,后续演进优先依据 BMP 等实际应用的接入需求,完善公共 API、使用示例和运行可靠性。应用可以连接自行部署的 Routinator 等上游验证器;完整独立 RP 验证器、生产 RTR 服务器及面向设备实验室的可编程 RTR 服务器均不纳入当前实施范围。下表中的客户端配套能力及既定扩展继续保留,BMP 采集、应用 RIB 和业务告警仍由宿主负责。
设计基线更新于 2026 年 10 月 3 日。本文描述完整首版的行为;已实现入口见源码生成参考,文中的所有能力及安装 extras 仍未发布。最低 Python 版本确定为 3.11。数据变更订阅、验证依据、查询 API、可观测性、传输注入、诊断工具、SLURM、Router Key 查询和 SSH 全部纳入设计,具体交付阶段见下表。
首版详细契约见 文档导航。公共 API、数据与错误、生命周期和使用示例确定第三方调用方式;协议、输入、持久化及外部接口由对应专题细化,行为验收提供规范与测试的映射。这些是实现与验收的长期契约,未发布接口调整时同步文档;签名和字段参考从源码生成,执行状态与证据在 Issues 中维护。
功能范围与交付阶段
| 能力 | 交付安排 |
|---|---|
| RTR v1 与实验性 v2,TCP 与 TLS;显式历史草案兼容及按 AFI 的 ASPA 授权 | 首版,默认 -27,首批历史 profile 固定 -10/-13 |
| Routinator 与 rpki-client JSON 解析,本地文件与可选 HTTP 更新 | 首版 |
| VRP 验证,标准 ASPA 验证,独立的 BMP 保守分析 | 首版 |
| 多源合并,分组优先级切换与回切,来源和时效管理 | 首版 |
| 运行中增删来源、修改配置,按来源注入自定义 JSON reader | 首版,原子提交与字段边界见配置变更 |
| 可选 SQLite 与 DuckDB 持久化,启动恢复 | 首版,两种后端均实现 |
| 嵌入库,本机共享快照,集中 HTTP 查询服务 | 首版 |
| 变更订阅,受影响范围,慢消费者重新同步 | 首版 |
| 按需验证依据,快照查询与生效 ASPA 遍历,数据源差异与导出 | 首版 |
| 结构化状态、指标接口、等待就绪、资源限制 | 首版 |
| 自定义传输,显式协议录制与离线回放 | 首版 |
| 轻量级 CLI,Typer 命令框架与 Rich 终端输出 | 首版,可选安装;随对应库功能分阶段交付 |
| SLURM 本地策略与原始及生效视图 | 扩展阶段;首版预留策略版本与视图边界 |
| Router Key 公共查询、导出与变更订阅 | 扩展阶段;首版完成协议处理和内部状态维护 |
| 内置 SSH 适配器 | 已纳入当前交付:可选 ssh extra,首先支持 asyncio;严格主机密钥验证与显式用户认证 |
首版不包含 RPKI 证书链及签名对象验证、RRDP/rsync 仓库抓取、BGPsec 路径验证、历史数据库或生产 RTR 服务器。上游 RP 验证器负责产生可信载荷;本库负责接收、管理并使用载荷。TLS 服务器身份验证属于传输功能,包含在首版中。
SLURM 与 Router Key 公共能力仍为既定扩展范围;用户另行要求提前交付内置 SSH。本文固定它们的接口边界和验收要求。
具体拒绝项、首版限制及已承诺扩展的区别见 Decision / Decline。实现不能把其他项目具备的能力自动加入本库,也不能以该文档为由删除本表已承诺的功能。
协议与 Python 基线
协议原文、相关 RFC、勘误与 IANA 注册表见 本地规范镜像。开发时优先查阅镜像;镜像中的补充资料不自动改变下表的实现基线。
| 项目 | 基线 |
|---|---|
| 平台目标 | Windows 11 仅 x86_64/AMD64,macOS、Linux 为原生 x86_64/AMD64 与 ARM64;本次 CI/CD 及必需运行验收仅 Linux x86_64,其余四种组合交付本机命令并保留当前候选未验证状态,见兼容;不包含 Windows ARM64 和 32 位 x86 |
| Python | requires-python = ">=3.11";Ruff 和类型检查同样以 3.11 为目标 |
| RTR v1 | RFC 8210 |
| RTR v2 | 实验性默认 8210bis-27;显式 v2_profile="8210bis-10" 使用固定历史草案,8210bis-13 使用固定无AFI历史草案,各自规则隔离 |
| ROV | RFC 6811 与 RFC 8481 |
| ASPA 验证 | 实验性支持 draft-ietf-sidrops-aspa-verification-28 |
| SLURM | RFC 8416,在扩展阶段实现 |
草案版本固定在实现、测试向量、能力报告和详细结果中。升级草案需检查行为差异并更新兼容矩阵,不能仅凭另一实现声明支持 ASPA 就认定互通。首版不实现 RTR v0。
首版尽可能验证可找到的真实 v2 实现。兼容 profile 必须固定原文、字段与状态规则,并取得独立向量或实际互通依据;不依据 wire version=2 自动猜测草案,不以关闭全部检查取得互通。合法的 check_order=False 只处理可选顺序检查,不能修复非法撤销或非最小事务。历史 profile 是来源身份的一部分,切换时替换来源并使旧恢复身份失配。
类型注解使用 3.11 兼容语法。仅在确有需要时引入 typing_extensions。SQLite 后端统一封装显式事务,兼容 3.11 的事务接口,不依赖 3.12 才新增的 autocommit 参数。参见 Python 3.11 事务控制。
模块与调用边界
| 模块 | 职责 |
|---|---|
models |
不可变载荷、快照、来源、能力、状态和验证结果 |
rtr.codec |
同步的 PDU 编解码与字段检查,无网络依赖 |
rtr.client |
协议状态机、同步事务、定时器、版本协商与重连 |
transports |
AnyIO 字节流、连接工厂、TCP/TLS 和可选 SSH 适配器 |
readers |
同步 JSON 解析、格式适配器和完整性检查 |
client |
数据源生命周期、合并、时效、分组切换及热配置;内部来源组件不作为独立公共模块 |
store |
内存索引、不可变快照、查询与原子发布 |
validation |
同步 ROV、标准 ASPA 验证和独立 BMP 分析 |
events |
快照变更、受影响范围、状态事件和订阅恢复 |
persistence |
同步后端契约,SQLite、DuckDB 与自定义后端 |
policy |
扩展阶段的 SLURM、策略版本与派生视图 |
service / remote |
可选 HTTP 服务工厂 / 独立远程 SDK |
cli |
调用公共 API 的命令行入口,负责参数、输出、退出码及进程生命周期 |
协议、读取器和存储通过规范化载荷及更新事务交互,保持可独立使用。高级管理器负责组合这些模块;调用方也可以只解析 JSON、持有离线快照或使用协议编解码器。
网络和后台管理使用 AnyIO。核心 TCP/TLS 功能覆盖 asyncio、Trio 两种后端;应用拥有事件循环和任务组,库不在嵌入模式自行创建事件循环或脱离生命周期的任务。数据库等阻塞操作使用受管理的工作线程,明确连接归属和取消后的清理行为。
数据模型使用标准库类型与 dataclass。Pydantic 限于可选 HTTP 服务的输入输出边界,不成为核心模型的基类。
数据模型与一致性
VRP 的键由地址族、规范化前缀、最大长度和源 ASN 组成。ASPA 保留每个来源的 customer ASN、AFI 与 provider 集合;同一 (customer, AFI) 的有效记录取 provider 并集,保留每个 provider 的来源,绝不跨 AFI 扩大授权。Afi.IPV4=1、Afi.IPV6=2 使用 IANA 标识,区别于 IP version 4/6;Aspa.afi=None 明确表示双 AFI 共同授权,不表示未知。无 AFI 的新版草案与 JSON 属于共同授权。合并 AS0 标志按 aspa-profile-29 §5.2 在各族内处理,原始支持保留。Router Key 内部保留 ASN、SKI、SPKI 和来源,不能只用 ASN 作为唯一键。
完整数据集另声明 ASPA 覆盖的 AFI,不能从是否有记录推断能力。来源和快照分别保留各 AFI 的能力、有效期与活动组。完整 RTR v2 EOD 覆盖双 AFI,某族没有记录表示该族 ready_empty;程序化或自定义读取器明确只提供一族时,另一族 unsupported。ASPA 查询、标准验证和 BMP 分析允许显式选择 AFI;省略时仅在两族授权、能力与活动组语义完全相同时作为共同授权兼容调用,否则要求显式 AFI。按 AFI 过滤后仍执行固定的 aspa-verification-28 算法,不自动切换历史路径算法。
每个来源分别记录协议或格式版本、完整同步状态、载荷能力、最后成功同步时间、失效时间,以及 RTR 的 session ID 和 serial。保留来源原始状态,再构造合并视图。来源信息表示数据来自哪个缓存或文件;RTR 未提供的证书链、TAL 或 ROA 对象地址不能凭空补全。
快照同时包含数据索引、来源与时效、能力及策略身份。数据、来源和元数据作为一个整体原子发布,批量验证及查询固定在同一快照。不得先更新 VRP 再单独替换 ASPA,让调用方看到混合版本。
快照标识包含存储身份、发布者 epoch 和单调递增 generation。发布者重启开启新 epoch;仅在同一身份和 epoch 内比较 generation,避免恢复旧数据库后误接续新事件。每条记录保留原始时间,发布新 generation 不延长旧数据的有效期。
共享读取者因本地失效处理产生派生快照时,使用自己的发布身份,同时保留上游持久化快照标识,不能冒用数据库写入者的 generation。纯连接状态事件另有事件序号,可以引用未变化的数据快照。
以下情况必须分别表达:功能不受支持、尚未加载、已完成同步且为空、仍有效但连接中断、数据已失效。VRP 与 ASPA 的可用性分别判断;没有可用数据不能伪装为正常 ROV notfound 或 ASPA unknown。
固定快照保证数据一致性,不会冻结其有效期限。在线验证按调用时刻检查时效;离线回放使用显式参考时间,并在结果中标明离线模式。
首版查询使用明确的结果与异常类型;无可用数据抛 DataUnavailableError,批量按条目保存错误。固定快照达到某类载荷最早需要重算的 usable_until 时,该类查询抛 SnapshotExpiredError,调用方重新获取当前快照。每条批量评价均检查期限,具体模型见数据契约。
RTR 与数据源管理
RTR 事务在收到有效 End of Data 后才提交。完整同步和增量同步均采用暂存状态;异常、断线或取消不能发布半份数据。v1 与 v2 分别遵循相应版本的顺序、错误、定时器和状态规则。
提供最低和最高协议版本配置,并按协议协商 v2 到 v1 的降级。v1 无法提供 ASPA,降级后不能继续把上个 v2 会话的 ASPA 当作当前会话数据。仅在缓存身份、协议、session 和完整载荷状态匹配时恢复 Serial Query,否则执行 Reset Query。
默认启用 v1;实验性 v2 由 max_version=2 显式开启,并先请求配置范围最高版本。v2 的新增错误码、ASPA 替换与 PDU 排序不能从 v1 推导,见 RTR 状态机;其中记录固定草案内部冲突的实施解释。
同组内合并有效来源,组之间按优先级切换。同组至少一个来源完成同步且仍有效,才具备该数据类型的基础可用性;所有来源均无法刷新时启动备用组准备。备用组就绪后原子切换,高优先级组恢复后回切。调用方可以要求特定载荷能力,VRP 就绪不能替代 ASPA 就绪。
活动组按载荷类型分别选择并在同一快照中记录;VRP 和 ASPA 可以来自不同优先级组,组内仍保留每个来源的支持。首次备用准备、回切等待和可观察性见生命周期与配置契约。
来源撤销、失效和移除只影响该来源的记录;其他来源仍支持的记录继续保留。切换等待期间旧数据的保留或清除遵循相应协议错误及失效规则。合并策略、活动组和能力降级必须可观察,不自动根据多数来源决定哪条记录可信。
JSON 解析接受文件、字节或已解码对象;本地文件轮询和 HTTP 获取属于独立适配器。为支持的生产者版本维护真实样例和格式矩阵。完整解析成功后才替换来源状态;无效记录默认导致本次更新失败,并报告位置和原因,不能静默跳过后宣称加载成功。
JSON 缺少 ASPA 字段与明确的空 ASPA 数组具有不同含义。旧格式或草案的 ASPA 字段不能在语义不明时直接转换。失效时间由可信导出时间和配置的最大年龄确定;缺少必要时间信息时要求显式有效期策略。同一旧文件被再次读取、收到 HTTP 304 或进程重启,都不能让数据重新变新。
验证依据与查询 API
ROV 同时考虑全部覆盖 VRP;存在任意符合条件的记录即可有效,不能只检查最长匹配前缀。详细结果列出覆盖记录及各自的 ASN、长度匹配情况,允许多个不匹配原因同时存在。AS0 按规范处理,不能作为有效公告的源 ASN。
标准 ASPA API 要求调用方提供规范所需的路径和邻居上下文;输入契约明确 AS_PATH 与 AS4_PATH 重建、路径段类型、重复 ASN 和路由服务器场景的责任。BMP 场景的保守分析使用独立接口和结果类型,不能将上下文不足的分析包装成标准验证结论。
详细结果按需启用,包含判定依据、相关 VRP 或 ASPA、关键路径位置、无法判定原因,以及快照、来源、时效、算法和策略版本。简要模式避免构造大规模解释对象。证据需要截断时必须标记,并提供继续查询的依据。
以下为接口职责;调用签名和完整流程见公共 API 契约与使用示例:
| 接口 | 语义 |
|---|---|
validate_origin / validate_origins |
单条及批量 ROV,支持按需解释 |
validate_aspa / validate_aspa_batch |
带完整上下文的标准 ASPA 验证 |
analyze_bmp_path |
上下文受限时的独立路径分析 |
covering_vrps |
返回覆盖指定前缀的全部 VRP |
iter_vrps |
按 ASN、来源、地址族等筛选固定快照 |
iter_aspas |
遍历生效 customer 及其完整 provider 并集,可按参与支持的来源筛选 |
aspa_providers |
查询指定 customer ASN 的 providers 及来源 |
compare_sources |
比较来源数据与能力、时间差异,不自动裁决可信性 |
export_snapshot |
导出固定快照及格式版本、能力、来源和原始时间 |
wait_ready |
按所需能力等待就绪,支持超时和取消 |
watch |
原子取得初始快照或标识及后续订阅 |
apply_config |
运行中原子增删来源、修改配置并返回配置版本回执 |
get_status / get_metrics |
查询结构化运行状态和指标 |
apply_config 仅用于拥有来源任务的 Client;共享读取和远程 SDK 不提供写配置方法。上述查询在离线 JSON、嵌入式和共享读取模式均可使用;远程 SDK 提供对应语义。远程分页必须绑定快照,快照不再可用时要求重试,不能混用不同 generation 的页。导出文件重新加载时保留原始有效期限。
变更事件与重新验证
VRP 或 ASPA 更新可能改变已有 BGP 路由的验证结果,即使没有新的 BGP UPDATE。库发布数据变化和保守的受影响范围,由调用方应用(例如 bmparrot、bmpalert)使用自己的路由索引筛选并重新验证;库不维护应用的 BGP RIB。
变更在完整快照发布后产生,携带新旧快照标识、原因、生效数据增删、ASPA customer 变化及来源变化。事件原因包含 RTR 或 JSON 更新、数据失效、活动组切换和后续策略更新。以合并后的有效变化为依据,区分数据变化与仅来源、时间或状态变化。
VRP 变更的受影响范围至少包括被变化前缀覆盖的所有路由前缀,不能仅按该 VRP 的 ASN 或 maxLength 筛选,否则可能漏掉 invalid 与 notfound 的转换。ASPA 变更保守地标记路径或验证上下文涉及相应 customer ASN 的路由。能力或可用性整体变化时,可以要求重新验证整类路由。
订阅具有以下契约:
- 初始快照获取与订阅注册形成一个原子观察点,之后的变化不会落在二者之间而丢失。
- 快照变化在同一发布身份和 epoch 内按 generation 有序交付。事件携带可校验的前后标识;跨进程重连不承诺恰好一次,调用方按标识处理重复。纯状态变化按事件序号排序。
- 每个订阅者使用有界队列。慢消费者不阻塞 RTR 同步,也不无限保留旧快照。
- 队列溢出、游标失效或 epoch 改变时,订阅进入明确的
ResyncRequired状态。该状态必须可观察,不能作为另一条普通事件再次被静默丢弃。 - 收到重新同步要求后,调用方重新获取快照并验证相关路由。库只保留有限的内存事件窗口,不承诺永久事件重放。
- SQLite 共享读取者可能跳过中间 generation,必须标记为合并后的净变化或要求重新同步;不能宣称观察到了每次提交。
消费者回调不在协议接收路径中执行。回调异常与耗时不得破坏同步任务;优先提供可取消的异步迭代订阅接口。在线有效期变化同样触发事件;共享读取者独立检查失效时间,不依赖写入进程仍在运行。
持久化与运行模式
默认只使用内存,不创建数据库或自动落盘。显式选择后端和路径后才启用持久化。
| 模式 | 无持久化 | SQLite | DuckDB |
|---|---|---|---|
| 进程内嵌入 | 支持 | 支持 | 支持 |
| 集中 HTTP 查询服务 | 支持 | 支持 | 支持 |
| 多进程直接读取正在更新的共享数据库 | 不适用 | 支持,本机 WAL | 首版不支持 |
共享文件模式选择 SQLite,采用单一写入者和多个读取者;DuckDB 由一个拥有者进程维护,其余应用通过 HTTP 访问。该限制针对本设计采用的原生嵌入文件方式,依据 SQLite WAL 和 DuckDB 并发文档。
PersistenceBackend 为同步协议,提供能力声明、读取当前完整状态、原子提交和关闭。提交覆盖启用载荷的完整来源状态、协议会话、时效和非敏感配置身份;后端不向公共接口暴露 SQL 或连接。SQLite 与 DuckDB 运行同一套后端契约测试。
启动时先检查依赖、schema、配置和模式兼容性,再启动网络。缺少 DuckDB 依赖或在共享文件模式选择 DuckDB 时立即报错,不静默切换后端。跨后端迁移不自动执行,首版重新同步建立新状态。
恢复时验证完整性、来源身份和有效期限,并重建内存索引。时钟回拨或时间有效性无法确定时触发重新同步,不能重置失效时间。持久化失败不破坏已发布的有效内存快照;单独报告内存与持久化版本及错误,重启仅能恢复最后成功提交的状态。
SQLite 共享模式限定本机文件系统,使用拥有者锁阻止第二个写入者。读取者默认每秒检查一次版本,在一致性读事务内加载完整数据,关闭事务后构建索引并原子替换本地快照。构建期间继续使用仍有效的旧快照;读取失败不能让过期数据继续服务。DuckDB 的写入所有权同样明确,数据库操作串行调度。
本地策略与 Router Key 扩展
SLURM 作为来源合并之后、验证之前的显式策略层。保留来源原始状态、合并原始视图和策略生效视图,支持比较策略前后的结果。策略具有稳定身份与版本,更新必须完整校验并原子应用,失败时保留上一份有效策略。
按 RFC 8416 实现 VRP 与 Router Key 的过滤、添加及多文件组合规则。本地添加记录标记为本地断言,详细结果指出受哪些规则影响。策略更新通过同一套快照与事件机制通知调用方,不允许私下修改只读快照。
RFC 8416 未定义 ASPA 策略格式;首个 SLURM 实现不自行把 ASPA 字段塞入该标准格式。如后续增加 ASPA 本地策略,使用独立命名和版本,保持原始与派生数据的区分。策略持久化保留版本和非敏感内容身份,不能把派生结果误当作缓存原始状态用于 RTR 增量恢复。
Router Key 在首版正确处理协议载荷、撤销及内部来源状态。扩展阶段开放按 ASN 或 SKI 查询、固定快照遍历、导出和变更订阅,遵循相同的合并、时效、持久化与 SLURM 语义。维护 Router Key 不等于执行 BGPsec 签名或路径验证。
传输与 SSH 扩展
连接工厂接受端点配置并返回 AnyIO 兼容的双向字节流。库管理的工厂在重连时创建新连接;直接注入已有连接时,明确关闭所有权,并在无法重建连接时结束会话。支持源地址、连接超时、TLS 配置及 IPv4/IPv6;调用方可通过自定义工厂接入隧道或测试流。
TLS 默认验证服务器身份和主机名,允许调用方提供 SSLContext。传输身份及配置变化影响恢复匹配;凭据、私钥和令牌不进入快照、录制元数据或日志。
内置 SSH 适配器提供主机密钥校验、公钥/密码认证、rpki-rtr subsystem、重连和取消关闭。使用 AsyncSSH 的 ssh 可选依赖(含加密私钥所需 bcrypt);它基于 asyncio,因此该适配器仅支持 asyncio,启动前检查后端并给出明确错误。显式 SshConfig、凭据准备、信任与热配置边界见 SSH 配置。核心 TCP/TLS 对 Trio 的支持保持独立,Trio 应用也可以注入与自身后端兼容的流。适配器不得隐式创建另一个事件循环来掩盖后端差异。
状态指标与诊断工具
连接成功、完整同步和验证可用分别表达。wait_ready 接受所需载荷能力、超时和取消,应用可明确等待 VRP 或 ASPA。运行中能力降级通过状态接口及事件报告。健康检查区分进程存活与指定能力就绪,已同步的空数据集可以处于就绪状态。
结构化状态包括活动组、每个来源的会话与协议、最后成功同步、失效时间、载荷数量、内存及持久化版本。错误按网络、TLS/SSH、协议、输入数据、能力、资源限制和持久化分类,提供稳定错误码、来源、重试信息及底层异常链。
指标至少包含全量与增量同步次数和耗时、载荷数量、重连与失败次数、快照构建及持久化耗时、订阅积压与重新同步次数、验证吞吐和延迟。指标接口不绑定监控产品,按需采集查询路径上的昂贵统计,避免用前缀或 ASN 作为默认高基数标签。标准 logging 交由宿主配置,核心包不修改根日志处理器。
为输入大小、载荷记录数、同步暂存区、订阅队列、批量查询、保留快照及录制文件设置可配置的有限上限。协议规定的硬限制独立检查。超限更新整体失败并提供诊断,不发布截断后的数据集;配置契约给出未发布的工程初值,发布默认值须经实际数据基准确认。
录制需显式开启,保存格式版本、协议或草案版本、连接边界、方向、接收字节和相对时间,可设置大小限制。任何截断或缺口必须标明。回放注入测试时钟与字节流,在独立离线状态中重现分包、断线、顺序和定时器行为,不连接真实服务器或写入在线数据库。录制文件不是历史数据库,也不作为自动恢复的可信状态。
轻量级 CLI
CLI 是与 Python API 配套的正式交付入口,供第三方用户直接查询、验证、诊断和编写自动化脚本。命令处理器只负责参数转换、调用公共 API、输出与退出码;RTR、JSON、快照、验证及持久化逻辑由库实现,保证同一快照和输入下 CLI 与 Python API 的结果一致。
选用 Typer 通过 Python 类型注解与 Annotated 声明参数,管理子命令、参数校验、帮助和补全;使用 Rich 提供表格、颜色与进度显示。Typer 元数据限于 CLI 命令函数,核心模型和公共 API 不依赖命令框架。配置读取使用标准库 tomllib,可选后端在实际执行对应命令时加载。
CLI 依赖放入 cli extra,显式声明 typer 与直接使用的 rich,计划通过 pip install 'rpkiparrot[cli]' 安装,入口为 rpkiparrot,同时支持 python -m rpkiparrot。仅安装核心库时不要求 Typer 或 Rich;命令启动器在缺少 CLI 依赖时提示安装方式并退出。安装 CLI 后,帮助、版本与补全不连接网络、不打开数据库,也不要求安装未使用的后端。已声明的 Typer 和 Rich 版本范围以 pyproject.toml 为准,锁定解析见 uv.lock;最低、锁定及最新依赖线分别运行兼容检查。Typer 发布元数据、Rich 发布元数据
Typer 自 0.26.0 起内置 Click 源码。CLI 使用 Typer 的公共接口及测试入口,不混用独立 Click 包或访问内置实现;不为 CLI 单独声明 Click 依赖。Typer 依赖说明
以下为首版命令;参数、模式和输出映射见 CLI 契约,实现对应库功能时同步提供可运行示例:
| 命令 | 职责 |
|---|---|
sync |
连接检查并等待所需载荷完整同步,默认单次;--watch 在前台持续同步,持久化须显式配置 |
status |
显示所选本地数据或远程实例的来源、能力、时效、快照和同步状态 |
validate origin / validate aspa |
单条及批量验证,支持详细依据;标准 ASPA 必须提供所需上下文 |
analyze bmp |
调用独立的 BMP 保守分析接口,并明确标识分析模式 |
query vrps / query aspa |
查询覆盖前缀、ASN、来源和 customer 的 providers,支持生效 ASPA 遍历 |
sources diff / export |
比较来源,导出固定快照及原始时效;导出沿用库的版本化格式 |
watch |
观察初始快照与后续变更,支持 JSON Lines;明确输出重新同步要求并重建观察 |
record / replay |
显式录制协议流或在独立离线状态中回放 |
serve |
启动既定 HTTP 服务,需同时安装 cli,service,复用服务的配置与生命周期 |
数据来源沿用库配置:离线 JSON、直接 RTR、本地持久化快照或远程服务。直接 RTR 验证先在有限超时内等待所需能力就绪;共享读取与 DuckDB 单一拥有者限制保持不变。状态输出标明观察对象,不把一次临时连接的状态描述成另一个常驻进程的状态。后续 Router Key 与 SLURM 命令随对应库能力扩展。
支持显式 --config TOML 文件、带 RPKIPARROT_ 前缀的环境变量及命令行选项,优先级为命令行、环境变量、配置文件、默认值。共享配置模型与库保持一致,冲突或不兼容的来源模式在执行前报错。同步、验证和查询提供有限超时;持续运行由用户显式选择。
输出约定如下:
- 默认输出适合人读的文本或表格;支持
--format json,批量及事件流命令另支持--format jsonl。机器输出包含格式版本、结果语义及相关快照、来源和时效信息。 - stdout 只写结果;日志、进度和错误写 stderr。JSON / JSON Lines 直接序列化,不经过 Rich 排版,不含 ANSI 控制码或进度条;错误包含稳定错误码,不能污染 stdout 的结果格式。
- 终端输出提供
--no-color并遵守NO_COLOR;重定向时关闭样式和动画。结果规模受资源限制约束,文本显示截断必须标注,导出不能静默丢失记录。 - 批量输入支持文件和 stdin,JSON Lines 的逐条结果保留输入标识。使用同一批量 API 固定快照,并保留在线有效期检查。
- 提供
--help、--version、--quiet和--verbose;使用 Typer 的 Bash、Zsh、Fish 补全,补全安装由用户显式执行。Typer 帮助与补全说明
退出码作为脚本接口维护,库中的领域结果保持原样,CLI 只进行映射:
| 退出码 | 语义 |
|---|---|
0 |
普通命令执行成功;验证命令的结果全部为 valid |
1 |
执行失败,例如网络、协议、文件或持久化操作失败 |
2 |
参数、配置或输入格式错误,或缺少所选功能的依赖 |
3 |
所需数据或能力不可用、已过期,或等待就绪超时 |
10 |
验证或分析已完成,包含 invalid 结果 |
11 |
验证或分析已完成,没有 invalid,但包含 notfound 或 unknown |
130 |
用户通过 Ctrl+C 中断 |
批量处理有执行错误时优先返回对应错误码;无执行错误时,invalid 优先于 notfound / unknown。输出保留逐条结果和完成状态。BMP 分析沿用其独立结果类型,并明确映射,不能将上下文不足或数据不可用混为正常验证成功。
CLI 作为应用入口拥有事件循环及任务生命周期,网络命令通过 AnyIO 运行;serve 复用 Uvicorn 的 asyncio 入口。中断时取消任务、关闭连接和后端并清理未提交事务。核心库导入不触发 CLI 初始化。
CLI 验收使用 typer.testing.CliRunner 检查参数、stdout / stderr 和退出码,并用独立子进程验证实际入口、信号和管道行为。覆盖缺少 extras、帮助无副作用、无颜色机器输出、批量不完整结果及与公共 API 的一致性;CLI 测试不替代协议与验证算法测试。
HTTP 服务与远程 SDK
可选服务以单个拥有者进程运行来源管理、内存索引和快照发布,可仅发布 SQLite 共享快照,也可提供 HTTP API。API 包含批量 ROV、标准 ASPA、BMP 分析、详细依据、快照查询、来源比较、状态及指标;扩展阶段增加 Router Key 查询。
远程变更订阅首版采用带游标的有界长轮询。连接重试沿用事件标识;服务内存窗口不足时返回 ResyncRequired,不依赖历史数据库。SDK 对嵌入式和远程模式提供一致的结果、能力和重新同步语义。
响应携带快照、时效与规则版本。分页或按快照验证通过有期限的快照引用保持一致;超过保留窗口时返回明确错误。设置批量大小、并发数和请求时间上限。
服务默认监听本机;远程部署要求 TLS 与认证,可由受信任的反向代理承担。配置采用 TOML,敏感配置独立提供。首版不使用多 worker 启动多个更新拥有者;HTTP 服务使用 Uvicorn 的 asyncio 运行环境,不将它描述为 Trio 服务。
依赖与安装组合
核心直接运行依赖为 AnyIO;标准库负责 struct、ipaddress、ssl、json、sqlite3、tomllib、数据类、类型和日志。前缀索引与验证算法先用 Python 实现,根据基准决定是否需要可选加速后端。
| extra | 额外依赖与用途 |
|---|---|
| 无 | 核心客户端、JSON 解析、内存存储与验证 |
cli |
Typer、Rich,用于轻量级命令行入口 |
http |
HTTPX、HTTPcore,用于 HTTP JSON 和远程 SDK |
sqlite |
filelock,用于写入拥有者锁;SQLite 驱动来自标准库 |
duckdb |
duckdb 与 filelock |
service |
FastAPI、Uvicorn、Pydantic、HTTPX、HTTPcore 及默认 SQLite 支持 |
trio |
Trio 异步后端 |
ssh |
AsyncSSH 与 bcrypt,RTR over SSH,限 asyncio |
extras 可组合,例如 cli,sqlite、cli,http 或 cli,service,duckdb。可选依赖延迟导入;未安装它们时核心包仍可导入和使用。SLURM 不强制增加第三方依赖。开发工具使用 pytest、pytest-cov、Hypothesis、Ruff、mypy,构建使用 Hatchling 和 build;版本范围通过最低版本与当前版本测试确定,不直接照搬其他应用的固定版本。
包以 PyPI 为发布目标。按当前纯 Python 实现设计交付通用 wheel 与 sdist;可选依赖的原生组件不自动改变本包的分发形式。CI/CD 对最终制品检查元数据、包内容、许可、类型信息和入口,并在干净环境验证核心与 extras 的安装及实际调用;上传经过验收的同一批文件。PyPI 接收上传不替代项目的功能与兼容性验收。具体平台要求、发布包检查及 TestPyPI 演练见 CI/CD 落地参考;构建和验证配置已建立;发布前仍须对最终提交的同一批制品完成全范围验收。
API 文档与实现同步
公共 API 的实现与文档属于同一项交付。新增、修改、弃用或移除接口时,必须在同一项变更中完成对应文档;当前直接在 main 开发,代码与文档一同检查和提交。文档缺失的 API 不算完成,不将文档推迟到功能实现之后或发布之前集中补写。这一要求从第一个公开模型和离线接口开始执行。
API 参考以源码签名、类型注解和 docstring 为事实来源,Markdown 页面组织入口、说明和交叉引用,避免手工维护第二份函数签名。公开范围按公共模块、导出入口及其公开成员明确列出,覆盖函数、类、方法、模型字段、枚举值、异常和扩展协议;不能仅因实现名称没有下划线就把内部对象发布为受支持接口。
文档应说明用途、输入约束与默认行为、返回值及结果状态、异常和稳定错误码。异步及有状态 API 另说明资源归属、取消与关闭、并发使用限制、快照一致性、数据时效和所需能力;协议相关行为引用适用的 RFC 或固定草案。条件不适用时无需机械堆砌空章节,不能用函数名称的改写替代行为说明。
| 文档部分 | 编写与同步方式 |
|---|---|
| Python API 参考 | 从类型注解和 docstring 生成;建议统一使用 Google 风格,按需提供 Args、Returns / Yields、Raises、Attributes 和 Examples |
| 使用指南与示例 | 手写任务流程与行为解释;优先引用可执行示例文件,让展示与测试使用同一份代码 |
| CLI 参考 | 参数和帮助取自 Typer 命令定义及公共帮助入口;补充退出码、输入输出格式和完整用例 |
| HTTP API 参考 | 服务实现阶段从 FastAPI 路由与边界模型生成 OpenAPI;补充能力、时效、分页、错误及游标语义 |
| 变更与迁移说明 | API 行为变化时同步编写,标明实验性接口、引入或弃用版本及迁移方式 |
自动生成负责呈现已编写的接口信息,行为解释与可用示例仍由开发者完成。每个新公开入口都必须能从参考文档找到;相同调用模式可共享示例,涉及不同生命周期或能力要求时提供对应示例。文档构建成功不能单独证明内容完整或准确,验收还须检查公开接口覆盖、说明与签名的一致性以及相关示例的实际运行。
生成工具采用 Zensical 与 mkdocstrings 的 Python handler,已有严格构建、公开导出覆盖和错误链接失败验证;具体依据和命令见 CI/CD 落地参考。文档工具属于开发依赖,不进入核心或用户安装 extras。
文档按发布版本保留,与对应代码和制品一致;main 上尚未发布的文档明确标识未发布。生成站点作为构建制品发布,源码仓库维护 docstring、Markdown、示例与配置,不手工修改生成的 API 页面。
验收与实施顺序
| 范围 | 关键验收条件 |
|---|---|
| 协议 | 分包、畸形 PDU、重复与不存在的撤销、增量、session 变化、serial 回绕、版本协商、定时器、取消;更新失败无部分发布 |
| 多源 | 独立撤销、来源去重、失效、切换和回切;有效数据未变时不制造数据删除事件 |
| 验证 | 独立标准向量、全部覆盖 VRP、AS0、ASPA 上下文;简要与详细结果一致;无数据和空数据区分 |
| 查询 | 固定快照的一致性、分页失效提示、来源差异、导出重载不延长有效期 |
| 事件 | 无 BGP UPDATE 时也能触发重验;快照与订阅无空窗;溢出、重复、epoch 变化、跨代读取与恢复;影响范围不漏掉结果变化 |
| 持久化 | 两后端同一契约、事务回滚、崩溃恢复、配置变化、时钟异常;持久化故障不污染内存状态 |
| 共享模式 | SQLite 多读取者及第二写入者拒绝;写入者退出后读取者仍使数据失效;DuckDB 模式不兼容在启动时报错 |
| 传输 | TCP/TLS 在 asyncio 和 Trio 上运行;连接工厂重连、关闭归属、身份校验、超时与取消 |
| 诊断 | 可重复的离线回放、不完整录制检测和结构化错误 |
| CLI | 与公共 API 结果一致;帮助无副作用;stdout / stderr 分离;JSON 可解析且无 ANSI;退出码、批量结果、Ctrl+C 清理及可选命令依赖隔离 |
| 服务 | 同一快照同一输入与嵌入式结果一致;远程游标恢复、分页、就绪、限额和单一拥有者 |
| API 文档 | 公共 API 与 docstring、参考文档和相关示例同项交付;公开入口可查、说明与签名一致、相关示例通过;发布文档与代码版本对应 |
| 可选安装 | 无持久化不创建文件;缺少 CLI、DuckDB、HTTP 或 SSH 依赖不影响其他模块 |
| PyPI 分发 | sdist 可独立构建 wheel;元数据、README、许可与包内容检查通过;安装后的核心、extras、类型和入口可用;发布文件与已验收制品一致 |
| 扩展功能 | SLURM 原子加载与标准规则、策略前后依据和事件;Router Key 多键与撤销;SSH 主机密钥和后端限制 |
兼容性支持目标保留 CPython 3.11、3.12、3.13、3.14;按用户最新确认,自动 CI 与候选验收只运行真实 CPython 3.11、3.14 的安装、行为和制品检查,核心异步功能分别覆盖 asyncio 与 Trio。3.12、3.13 提供手动验收命令,未执行不计为通过,也不阻塞此次交付。Ruff 和常规类型检查以最低版本 3.11 为基线,涉及版本分支时补充相应目标版本的静态检查。requires-python 只是版本声明,静态检查不能替代真实运行;缺少目标环境或必需检查未执行时,不宣称该组合兼容。当前为计划验收范围,正式支持以实际验证为依据;新增 Python 版本同样先验证依赖与行为,再纳入正式支持矩阵。
互操作测试记录真实服务器、软件版本、协议和草案版本,不能用本项目自己的编码器作为唯一正确性依据。
当前采用单维护者、直接在 main 开发的方式,全库代码由 Codex 或 Claude Code 实现和修改,具体协作约定见 AGENTS.md。工具建议、兼容性矩阵组织、质量门槛、制品验收和发布流程见 CI/CD 落地参考。该文档按本节的实施顺序安排本地检查、主分支 CI、定期检查和发布验收,区分既定设计约束与待验证的工具和平台建议;已落地命令及工作流以 CI/CD 文档和仓库配置为准,运行证据另行核验。
基准记录全量加载、增量更新、峰值内存、持久化与恢复、共享传播延迟,以及简要和详细验证吞吐;性能目标以规模与资源基线中的真实数据、多源部署和工程预算测量后确定,不直接照搬其他实现的资源或吞吐数字。
实施顺序如下:
- 固定协议矩阵、公开模型与调用示例,建立 API 文档生成及检查;实现离线 JSON、内存快照、查询和验证,同步交付 API 文档、CLI 入口及对应离线命令,预留策略与 Router Key 接口边界。
- 实现 RTR、传输工厂、多源管理、运行中配置变更、在线自定义 reader、完整事务发布及变更订阅,同步交付 CLI 的同步、状态与观察命令。
- 实现 SQLite 与 DuckDB、恢复和本机共享读取,接入 CLI 后端选择,验证事件与持久化故障行为。
- 完成详细依据、可观测性、录制回放、HTTP 服务和远程 SDK 及对应 CLI 命令,执行首版全范围验收并发布 0.1.x。
- 按扩展阶段完成 SLURM、Router Key 公共 API;进行应用集成反馈与兼容性评估后确定 1.0 接口承诺。
第三方应用通过公共 API 集成,文档与示例应能支持使用者独立完成接入。bmparrot 与 bmpalert 的迁移属于后续集成工作,可用于验证通用接口的适用性;不在库实现过程中自动修改这两个应用。