YANG:when和must(已完成)

2023-11-21 07:30
文章标签 完成 must yang

本文主要是介绍YANG:when和must(已完成),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

专注NETCONF/YANG技术科普,接受任何问题,包括我答不上来的问题。欢迎光临!欢迎提问:链接

目录

  • 一、when和must的含义
    • when
    • must
    • 扩展:NP-container和must
  • 二、XPATH1.0函数
    • XPATH按“绝对路径”和“相对路径”,有两类写法。
    • current()函数
  • 网管数据库对when/must的实现
  • 使用when/must的必要性
  • 设备厂商的when/must使用现状
    • juniper
    • NOKIA
    • CISCO
    • 问题来了:您所在产品的业务特性中有很多依赖互斥的约束吗?
  • 如何优化when/must逻辑
    • 案例一:当xxx=true时yyy必须存在——改presence container
    • 案例二:当xxx=true时yyy必须存在——改when - mandatory
    • 案例三:must逻辑冗余——简化must逻辑(when类似)

按计划这篇是写when和must,但这篇要不要写,写到什么程度我心里一直没底。碰巧又是外出刚回来,头脑思路还不够清晰。这篇计划边写边看,后面慢慢丰富。
7月10日:我又外出又回来了。sorry。

一、when和must的含义

when

when是说其数据节点是否存在需要满足一定的条件。满足when条件(when表达式值为true)时,此数据定义节点存在;不满足when条件时,此数据定义节点不存在。
因此,when条件一般要优先于其他属性要求。
比如如下一段YANG模型:leaf vlan-end先检查when条件是否成立;如果vlan-begin存在,则when条件成立,vlan-end节点存在;再检查vlan-end字段是否有值,如果vlan-end有值,则满足mandatory属性;leaf value节点也类似,如果vlan-begin存在,则leaf value节点的when条件也成立,value节点存在,如果未设置取值,按默认值=7处理。

  container dscp { leaf vlan-begin {type uint16;}leaf vlan-end {when "../vlan-begin";type uint16;mandatory true;  // when条件成立时,vlan-end节点才存在,最后检查是否mandatory属性}leaf value {when "../vlan-begin";type uint8;default 7;  // when条件成立时,value节点才存在,如果没有设置value的值,按默认值=7处理}}
}

must

must是在节点已经存在的前提下对有效数据的一种强制约束。must后面跟着XPATH表达式,里面可以包含XPATH1.0的函数。在commit阶段会进行数据的validation,此时会验证must条件的表达式值必须为true。

也就是说,有节点存在,进行数据validation验证强制约束必须满足。比如下面这段,如果vlan-begin没有值,则vlan-end上的must条件不用管它;如果vlan-begin有值,则vlan-end必须存在,且必须满足vlan-begin < vlan-end。

  container dscp { leaf vlan-begin {type uint16;}leaf vlan-end {when "../vlan-begin";must "../vlan-begin < ../vlan-end";  // when条件成立时,检查此must条件必须成立,即:必须vlan-begin < vlan-endtype uint16;mandatory true; }}
}

扩展:NP-container和must

结合之前说过的NP-container认为永远存在,那么NP-container上的must条件就要永远为true,否则会报错。
下面给出一个错误模型的例子:如果dscp/vlan-begin和dscp/vlan-end都没有值,但是container dscp认为还是存在,那么container dscp上的must条件还是要求成立。这就跟“dscp/vlan-begin和dscp/vlan-end都没有值”是矛盾的。所以说这个例子是错误的。

// 这是个错误的例子container dscp { must "vlan-begin < vlan-end";  // NP-container认为永远存在,检查此must条件必须成立,即:必须vlan-begin < vlan-endleaf vlan-begin {type uint16;}leaf vlan-end {when "../vlan-begin";type uint16;mandatory true; }}
}

总结一下,when是对节点是否存在的一个前提条件;而must是在节点存在的前提下对数据validation的一个约束校验。由此可见,两者的含义完全不同,网管实现的阶段也完全不同。

二、XPATH1.0函数

when/must都是使用的XPATH1.0的语法和函数。相关语法和函数建议查看链接。
XPATH实际支持的运算符和函数不少。实际YANG文件中XPATH函数用的并不多,常见的有运算符(见下图)、获取实例(current)、数值计算函数/字符串函数/合计函数等。
在这里插入图片描述
YANG的XPATH函数写太复杂了也未必就好。YANG毕竟是机机语言,现在又有哪些网管能完整解析XPATH1.0的函数呢?XPATH的解析栈深度到达一定字节数后就溢出了,XPATH写复杂后网管可能就无法解析了。——这块并不想展开多说。

XPATH按“绝对路径”和“相对路径”,有两类写法。

绝对路径是用"/"开头,只能表达路径位置,对应这个路径位置的所有管理对象模型。写法如:/interface/enabled 是绝对路径的XPATH。
相对路径是从当前路径开始找起,向上或者向下找路径位置,可以表达是相同的实例对象。写法如:…/enabled 是相对路径的XPATH。

下面用一个例子来描述两者区别:
当接口使能的情况下,才能设置mirror-enable=true。因此设置mirror-enable=true时要求这个接口必须enable。这里要找同一个interface实例对象,因此使用的是相对路径…/enabled = true。
如果改成绝对路径“/interface/enabled = true”,含义就变成,任意/interface实例只要有一个enabled=true,其他接口就可以设置mirror-enable=true了。这样显然含义就变了。

     list interface {key "name";...leaf enabled {type boolean;}leaf mirror-enable {type boolean;must '../enabled = "true"'; // 同一个接口必须enabled=true,才能设置mirror-enable// must '/interface/enabled = "true"'; // 所有接口中只要有一个接口enabled=true,才能设置mirror-enable。 <-- 这样写是错误的。}...}

current()函数

如果两个不同的YANG实例模型中用到了相同的实例对象,并且相同的实例对象中两个模型中的一些属性要形成一定的业务约束。怎么办呢?
下面只说一种YANG1.1中推荐的当前实例表达的XPATH函数current()。current()函数没有入参,返回的是当前实例对象。
比如:

//模型一:接口创建时生成/interface对象。list interface {key "name";...leaf enabled {type boolean;}...}
//模型二:路由策略模型,要求出接口的是能状态必须是true(使能)。其中的路由出接口引用了/interface/name,要求必须和/interface对象名称保持一致。leaf outgoing-interface {type leafref {path "/interface/name";}must '/interface[name=current()]/enabled = "true"'; // outgoing-interface引用(leafref)的接口对象,必须在/interface实例下,且enabled=true。}

网管数据库对when/must的实现

刚才的current函数已经展示了其XPATH的复杂性。这就给网管无论是做when节点的存在性判断,还是must的数据强制约束,都带来了内存的消耗以及时间开销。
更重要的是:有些数据约束must能表达,有些业务上的数据约束,当前的XPATH函数甚至是写不出来的(如:IPV4组播地址仅支持某个小网段)。所以,当前网管当前对when/must的数据校验并不那么热衷于其完备性。
另一方面,when/must并不影响数据库建表。因此网管对于when/must的态度是:交给设备侧自己做校验。网管dryrun一般是尽力而为,甚至不做校验。

使用when/must的必要性

when/must只是模型约束的一种表达。模型约束是业务约束的体现。因此,如果业务约束客观存在无法消除的话,模型约束也是客观存在的。
在数据通信行业中,技术迭代更新慢、可靠性要求高、运营商网络、网管的维护成本也高。因此对兼容性要求比较高。也就是说,在不改变配置模型的情况下,也无约束又客观存在,很大程度上的模型约束是无法消除的(除非有约束但是在YANG模型中不表达,思科的有些产品就是这么做的)。
目前的确有设备供应厂商在对业务特性的配置界面进行重构。传闻:NOKIA在2022年(?)完成重构、思科在近期的CISCO LIVE上也开始宣传他们重构后的YANG模型。
但还有厂商对此持怀疑态度。毕竟,为了一个大家都没有看到商业盈利价值的更高阶的网管配置、管理功能,就让设备厂商进行业务重构,这个代价是巨大的。我们目前看到NOKIA和CISCO的重构也仅仅是针对部分产品进行的。不是所有产品都铺开搞。

设备厂商的when/must使用现状

juniper

juniper在2023年发布的“23.1R1.8\junos-qfx”YANG模型中,

  • 没有使用when。
  • must采用了juniper自己的私有语法“junos:must”,并对此增加了相关说明“junos:must-message”,两者配对使用。
  • 总结:可以看出juniper一贯的XML风格配置能极好地适应机机接口,配置联动(when)很少,业务约束存在,但是juniper只用了私有语法,看来也不指望通用网管能做啥。

NOKIA

诺基亚2022年在欧洲就号称已经完成YANG机机风格的配置模型重构。现拿2023年7月发布的Nokia7x50_YangModels\latest_sros_23.7YANG模型分析:

  • when使用了1671次。
  • must在私有YANG中没有。但是模型description中有很多约束类的文字描述(must单词搜到1214次):可见诺基亚还是有很多操作限制的,应该是处于一个转型的过程中。
  • 另外,openconfig的deviation YANG文件中有deviate add must:可见openconfig对设备厂商的排斥,诺基亚也遇到了类似的问题。

CISCO

CISCO在2023年发布的“xr\791”YANG模型中,除去公有YANG,

  • when使用了1710次。
  • must使用了5260次。
  • 总结:配置联动和业务约束不少,显然没有拜托人机界面防呆的历史特点。但是XPATH并不复杂,when/must比较容易看懂。XPATH相对路径也比较浅,说明相同业务模型聚合的比较好。另外思科喜欢用"…/interface-name[starts-with(text(),‘Loopback’)]"表达接口类型,是这家公司的配置特点。

问题来了:您所在产品的业务特性中有很多依赖互斥的约束吗?

如何优化when/must逻辑

具体问题具体对待。我在github上找了一些模型,给出一些我认为的更合理的优化方案。因为涉及一些厂商比较尴尬,这里略去厂商名称。

案例一:当xxx=true时yyy必须存在——改presence container

        container bit-error-detection {leaf enable {type boolean;must "(../enable='false') or (../enable='true' and (../med or ../local-preference))";  // <-- (2)default "false";}leaf med {when "../enable='true'"; // <-- (1)type uint32;}leaf local-preference {when "../enable='true'"; // <-- (1)type uint32;}leaf route-policy {when "../enable='true'"; // <-- (1)type leafref {path "/rtp:routing-policy/rtp:policy-definitions/rtp:policy-definition/rtp:name";}}}}

优化点:
(1) container中的其他leaf都是when “…/enable=‘true’”,显然leaf enable可以改presence container,从而省略下面的when条件。
(2) bit-error-detection使能时,med 和 local-preference两个节点必须二选一。这个must条件提到container上。并做优化。
优化后的模型如下:

        container bit-error-detection {presence "Enable bit error detection";must "med or local-preference"; leaf med {type uint32;}leaf local-preference {type uint32;}leaf route-policy {type leafref {path "/rtp:routing-policy/rtp:policy-definitions/rtp:policy-definition/rtp:name";}}}}

案例二:当xxx=true时yyy必须存在——改when - mandatory

  typedef route-limit-type {type enumeration {enum "noparameter" { value 0; }enum "alert-only" { value 1; }enum "idle-forever" { value 2; }enum "idle-timeout" { value 3; }}}...augment "/ni:network-instance/ni:instances/ni:instance/bgp:bgp/bgp:base-process/bgp:peers/bgp:peer/bgp:afs/bgp:af" {description "Augment for an L2VPN instance and EVPN association.";...container l2vpn-evpn {leaf route-limit-type {when "../route-limit";type route-limit-type;must "(../route-limit-type = 'idle-timeout' and ../route-limit-idle-timeout) or (../route-limit-type = 'alert-only') or (../route-limit-type = 'idle-forever') or (../route-limit-type = 'noparameter')";; // <-- (1)}leaf route-limit-idle-timeout {when "../route-limit-type = 'idle-timeout'";type uint16;units "min";}}}

优化点:
(1) leaf route-limit-type的must条件中,对所有的route-limit-type枚举做了列举。纯属多余,且后续typedef扩充时这里容易修改遗漏。这里是为了表达leaf route-limit-type = 'idle-timeout’时,下面的leaf route-limit-idle-timeout必须有值。这里改成when-mandatory即可。
优化后的模型如下:

  typedef route-limit-type {type enumeration {enum "noparameter" { value 0; }enum "alert-only" { value 1; }enum "idle-forever" { value 2; }enum "idle-timeout" { value 3; }}}...augment "/ni:network-instance/ni:instances/ni:instance/bgp:bgp/bgp:base-process/bgp:peers/bgp:peer/bgp:afs/bgp:af" {description "Augment for an L2VPN instance and EVPN association.";...container l2vpn-evpn {leaf route-limit-type {when "../route-limit";type route-limit-type;}leaf route-limit-idle-timeout {when "../route-limit-type = 'idle-timeout'";mandatory true;type uint16;units "min";}}}

案例三:must逻辑冗余——简化must逻辑(when类似)

        container color-aware {leaf cir-value {type uint32;must "(../cir-units and ../set-dei) or (../cir-units and ../eir-cos) or (../cir-units and ../set-dei and ../eir-cos)"; // <-- (1)}leaf cir-units {type dt1:Sat-inf-rate-units;must "(../cir-value and ../set-dei) or (../cir-value and ../eir-cos) or (../cir-value and ../set-dei and ../eir-cos)"; // <-- (1)}leaf set-dei {type boolean;must "../cir-value and ../cir-units"; // <-- (2)}leaf eir-cos {type uint32 { range "0..7"; }must "../cir-value and ../cir-units"; // <-- (2)}}

优化点:
(1) 单独阅读leaf cir-value 和cir-units的must条件,呈现A or B or (A and B)的格式,因此第三个“或”逻辑语句冗余,可以删除。
优化后的模型如下:

        container color-aware {leaf cir-value {type uint32;must "../cir-units and (../set-dei or ../eir-cos)"; // <-- (1)}leaf cir-units {type dt1:Sat-inf-rate-units;must "../cir-value and (../set-dei or ../eir-cos)"; // <-- (1)}leaf set-dei {type boolean;must "../cir-value and ../cir-units"; // <-- (2)}leaf eir-cos {type uint32 { range "0..7"; }must "../cir-value and ../cir-units"; // <-- (2)}}

这篇关于YANG:when和must(已完成)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/400790

相关文章

SpringBoot使用OkHttp完成高效网络请求详解

《SpringBoot使用OkHttp完成高效网络请求详解》OkHttp是一个高效的HTTP客户端,支持同步和异步请求,且具备自动处理cookie、缓存和连接池等高级功能,下面我们来看看SpringB... 目录一、OkHttp 简介二、在 Spring Boot 中集成 OkHttp三、封装 OkHttp

JAVA调用Deepseek的api完成基本对话简单代码示例

《JAVA调用Deepseek的api完成基本对话简单代码示例》:本文主要介绍JAVA调用Deepseek的api完成基本对话的相关资料,文中详细讲解了如何获取DeepSeekAPI密钥、添加H... 获取API密钥首先,从DeepSeek平台获取API密钥,用于身份验证。添加HTTP客户端依赖使用Jav

python安装完成后可以进行的后续步骤和注意事项小结

《python安装完成后可以进行的后续步骤和注意事项小结》本文详细介绍了安装Python3后的后续步骤,包括验证安装、配置环境、安装包、创建和运行脚本,以及使用虚拟环境,还强调了注意事项,如系统更新、... 目录验证安装配置环境(可选)安装python包创建和运行Python脚本虚拟环境(可选)注意事项安装

Java 后端接口入参 - 联合前端VUE 使用AES完成入参出参加密解密

加密效果: 解密后的数据就是正常数据: 后端:使用的是spring-cloud框架,在gateway模块进行操作 <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>30.0-jre</version></dependency> 编写一个AES加密

如何完成本科毕业论文设计

完成本科毕业论文设计是一个系统性的工程,需要经过多个阶段的规划、执行和总结。以下是一个详细的步骤指南,帮助你顺利完成本科毕业论文设计。 ### 1. 选题与开题 - **选题**:选择一个有研究价值且你感兴趣的题目。与导师讨论,确保题目具有可行性和创新性。 - **开题报告**:撰写开题报告,包括研究背景、研究目的、研究内容、研究方法、预期成果等。 ### 2. 文献综述 - **文献检索**

LabVIEW环境中等待FPGA模块初始化完成

这个程序使用的是LabVIEW环境中的FPGA模块和I/O模块初始化功能,主要实现等待FAM(Field-Programmable Gate Array Module,FPGA模块)的初始化完成,并处理初始化过程中的错误。让我们逐步分析各部分的功能: 1. Wait for FAM Initialization框架 此程序框架用于等待I/O模块成功初始化。如果在5秒钟内模块没有完成配

完成一个项目的流程

我自己总结的,有什么问题,请大家指点啊! 1. 制定项目的周期。工具:project 2. 确定需求,设计界面。工具:Axure 3. 写需求文档。 4. 写接口文档。 5. 设计项目架构。工具:Visio 6. 做图。工具:ps 7. 编码。 8. 写测试用例。 9.测试。

idea中配置Translation插件完成翻译功能

文章目录 idea下载插件配置有道云阿里云百度翻译开放平台 idea下载插件 idea中安装Translation插件 使用方法:右下角选择翻译引擎,鼠标选中想翻译的部分,右键翻译即可 之前一直用的微软的翻译,不需要配置,但是最近微软服务器总是抽风,无法使用,故打算配置一下国内的翻译服务。 配置 有道云 只有初始的一点额度,用完就要收费了,不推荐

解决解压缩时的错误提示 “无法成功完成操作, 因为文件包含病毒或者潜在垃圾文件“

近期, 有一些朋友反馈在解压zip压缩包, 或者在安装软件的过程中出现了下面的错误提示: "无法成功完成操作, 因为文件包含病毒或者潜在垃圾文件" "Operation did not complete successfully because the file contains a virus or potentially unwanted software" 上述错误一般

亚信安慧AntDB数据库与华为DPA数据保护一体机完成兼容性互认证,共筑数据安全与效率新高地

近日,湖南亚信安慧科技有限公司(简称“亚信安慧”)与华为技术有限公司(简称“华为”)完成了亚信安慧AntDB数据库与华为DPA数据保护一体机兼容性互认证。 图1:华为DPA数据保护一体机兼容性互认证 亚信安慧AntDB数据库作为领先的数据库解决方案提供商,专注于数据库产品的研发与创新,以其卓越的性能和稳定性,服务于超数亿用户,连续十年无故障运行。亚信安慧AntDB数据库的云原生分布式架