摘要

  • YANG 2.0 不取代 YANG 1 与 1.1,完整数据模型可以混用不同语言版本;但导入规则是有意设计成非对称的。
  • 旧模块 A 可在未指定 revision 的条件下继续与已升级到 2.0 的 B 共存,从而避免级联改写;服务器通告这组模块,却不能证明客户端绑定、有效模式、兼容性、互操作或生产采用。

设想一个维护窗口:B 已改写为 YANG 2.0,仍停留在 YANG 1.1 的 A 在导入 B 时没有指定 revision。服务器顺利启动,清单里出现 A 和 B,变更看板显示成功。这一切都可能符合草案。问题出在下一句话——“既然能共存,各客户端得到的模式当然相同。”

当前的 YANG 2.0 revision 00 草案 日期为 2026 年 7 月 6 日。它明确说 YANG 2.0 不废止 RFC 6020 或 RFC 7950,完整数据模型可以包含以多个 YANG 语言版本编写的模块。IETF Datatracker 将其列为 NETMOD 工作组的活跃 Internet-Draft。文首建议的目标状态是 Standards Track,但它目前不是 RFC,更不是实现或部署证明。

非对称不是缺陷,而是迁移边界

草案第 12 节画出一条单向边界。YANG 2.0 模块只能 include 2.0 子模块;YANG 1 或 1.1 模块不得 include 2.0 子模块。旧语言模块或子模块不得按 revision 导入 2.0 模块;反方向则被允许——2.0 模块或子模块可以按 revision 导入 YANG 1 或 1.1 模块。

这不是一句对称的“向后兼容”承诺,而是一张迁移拓扑:新语言可以明确回看旧依赖,旧语言不能以固定 revision 向前声明新语言依赖。

特殊规则处理了最棘手的现实情形。若 YANG 1/1.1 模块 A 导入 B 时没有指定 revision,之后 B 升级到 2.0,服务器可以同时实现 A 与 B。服务器必须按第 5.6.4 节规则通告这些模块,并应通告 A 以及仍用 YANG 1 或 1.1 表达的 B 的最新 revision。草案解释得很直接:没有这条规则,B 的一次升级就可能迫使 A、A 的导入者以及更远的依赖逐层改写,形成级联效应。

这条规则的价值在于克制。它没有把语言升级变成整个依赖图必须同步服从的命令。这与 Lu Heng 关于最小初始规范、本地化未来决策与自愿采用的分析相呼应:共同规则应尽量薄,后续采用交给能自行验证和运行代码的参与者。但分散采用也意味着,证明责任会从“规范允许什么”转向“每个参与者实际选择并运行了什么”。

通告只能证明服务器作出了什么声明

草案第 5.6.4 节还规定,服务器不得实现同一模块的多个 revision。它同时区分 implemented 与 import-only:后者可能只提供 typedef 或其他模式材料。RFC 8525 的 YANG Library 把这套清单扩展为模块集合、实现/仅导入角色、feature、deviation 与变更标识。

这些信息不可或缺。它们可以证明某个时间点服务器声称有哪些模块,A 是否存在,B 的哪些 revision 被列出,各 revision 扮演什么一致性角色,以及哪些 feature 和 deviation 生效。它们不能单独证明客户端取回了哪一组字节、如何解析 A 未指定 revision 的导入、两个解析器是否生成同一棵模式树,或者正在运行的客户端是否真的使用了刚读取的清单。

这也是本文与相邻主题的边界。模块版本标签改善身份识别,Semver 表达式可以约束可接受更新,YANG package 可以描述一组材料,schema comparison 可以分类变化,文件名可以帮助人找到候选文件。它们都很有用,却都不能用一个标签替代解析、编译、验证与运行证据。

共存之后,证据还要逐层向下

一项升级主张至少应沿着以下阶梯验证:

  1. 源文件身份。 保存模块与子模块的精确字节、来源、namespace、语言版本、revision 与内容哈希。revision 名称不是文件本身。
  2. 依赖解析。 记录完整 import/include 闭包,尤其记录每条未指定 revision 的边由解析器选择了什么。A 的分歧最可能在这里发生。
  3. 服务器声明。 捕获完整 YANG Library 快照、一致性角色、feature、deviation、module-set 标识与时间,而不是只截取 A/B 两个名字。
  4. 有效模式构造。 记录解析器/编译器身份、诊断结果,以及 import、include、augment、feature、deviation 应用后的规范化有效模式指纹。
  5. 实例验证。 用代表性实例与故意构造的反例验证冻结模式。能解析不等于实例符合。
  6. 客户端行为。 追踪彼此独立的客户端如何选择 revision、如何编译;共享服务器清单不自动带来一致结果。
  7. 互操作。 在混合版本边界上测试读取、编辑、RPC、action、notification,并测试失败与回滚。
  8. 运行状态。 观察 intended 与 operational datastore、生产行为和恢复结果。RFC 8342 已明确区分预期配置与运行状态。

这条阶梯只能累积,不能折叠。较高层证据不能抹掉较低层材料,较低层声明也不能借用较高层的权威。Lu Heng 关于现实层的论述在这里提供了有用框架:通告、解析产物、验证成功与运行结果彼此相关,却不是同一件事。

因此,草案给运营者的是避免无谓级联改写的工具,不是绕开证据的捷径。两个语言世代可以合法地共处一台服务器;它们是否为特定客户端形成相同契约,仍必须被测量和复现。

来源