专注NETCONF/YANG技术科普,接受任何问题,包括我答不上来的问题。欢迎光临!欢迎提问:链接
引子、基本概念
前两天在CSDN上搜yang相关的帖子,发现有人就提出不知道“schema tree”和“data tree”的区别。这里做一个讲解。
先上基本概念,见昨天的帖子《YANG:术语说明》。
- schema tree:是模块(指YANG module)中定义的模型层次结构。
- schema node:就是schema tree中的节点。可以是:container, leaf, leaf-list, list, choice, case, rpc, input, output, notification, anydata, anyxml其中之一。
- data tree:设备通过YANG数据建模的一棵实例化树,包括:配置或状态数据,RPC、action操作的输入输出,或者notification。
- data node:schema tree中可以在data tree中实例化的节点。可以是:container, leaf, leaf-list, list, anydata, anyxml其中之一。
XX node和XX tree的关系
XX node是XX tree上的节点。XX tree是一棵树。这棵树上有着枝干和树叶,都被称作是“node”。所以XX node是体现XX tree中的一个具体的业务模型。因此实战中,我们提及XX node更多一些。
schema node和schema tree
schema tree是YANG模型的层次结构。整个层次结构是树形的(感兴趣的同学可以用PYANG的YANG tree转出来看一下),这棵树上有一些枝枝丫丫,这些中间的节点就是container、list、choice…。还有一些末端的叶子节点,就是leaf、leaf-list…。这些枝枝丫丫、叶子在这棵树上的位置就是schema node。
既然schema node只表明模型的所处位置,那么schema node的所在位置并不一定有值。
举例choice-case:
choice dscp-or-tos {
case dscp {
leaf dscp {
type inet:dscp;
description
"Match packets with given dscp value";
}
}
case tos {
leaf tos {
type c-types:tos;
description
"Match packets with given TOS value";
}
leaf precedence {
when "boolean(../tos)" ;
type c-types:precedence;
description
"Match packets with given precedence value";
}
}
}
这段代码的YANG choice-case只是让在TOS和DSCP中二选一,对于“choice dscp-or-tos”、“case dscp”、“case tos”,这些节点的层次位置,并没有数据对应。这些节点是只有schema node,没有data node。
data node和data tree
YANG网管上的网元数据库和设备上的数据库表项相对应。设备和网管的一套数据库则跟YANG模型相对应。——某种意义上说,设备和网管的数据库表项可以根据YANG文件自动生成。这些实例化1后的表项数据形成了一棵实例化的树,即data tree。data tree中的节点是能实例化的节点,被称为data node。
这样说可能不够直观。如果直接看NETCONF报文的内容层则会对data tree有一个直观的感受。
<!-- 这是一个全量配置查询响应报文 -->
<?xml version="1.0" encoding="utf-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="378">
<data>
<telemetry-system xmlns="http://openconfig.net/yang/telemetry">
<global xmlns="urn:huawei:yang:huawei-openconfig-telemetry-ext">
<config>
<json-only-content>false</json-only-content>
<cpu-max-usage>5</cpu-max-usage>
</config>
</global>
</telemetry-system>
<snmp xmlns="urn:ietf:params:xml:ns:yang:ietf-snmp"> <!-- 这段是ietf-snmp模块的data tree -->
<engine>
<enabled>false</enabled>
<engine-id>80:00:07:DB:03:38:BA:39:D4:96:01</engine-id>
<enable-authen-traps>false</enable-authen-traps>
<listen>
<name>snmpListen</name>
<udp>
<port>161</port>
</udp>
</listen>
<version>
<v3/>
</version>
</engine>
<vacm>
<view>
<name>ViewDefault</name>
<include>internet</include>
<exclude>snmpCommunityMIB</exclude>
<exclude>snmpUsmMIB</exclude>
<exclude>snmpVacmMIB</exclude>
</view>
</vacm>
</snmp>
</data>
</rpc-reply>
我们在上面这段get-config的reply报文中找到ietf-snmp模块,根据XML报文结合行缩进能够看到snmp模块的data tree。data tree上的节点被称为data node。
注意到:
choice, case, rpc, input, output这些节点是不在data tree中体现,没有data node。也不会出现在netconf报文中。
rpc、notification节点目前根据RFC7950和RFC6020均不属于data node,但是个人认为此场景下应该算data node(跟普通container地位类似)。可能是因为container考虑到还有存在性容器的存在,所以container作为data node理由更充分一下。鉴于rpc、notification是独立关键字,网管解析转换成表项很容易。
schema node XPATH和data node XPATH
schema node和data node一般用XPATH来表达。我们回到“choice dscp-or-tos”的模型(第1段代码),并省略了description:
choice dscp-or-tos {
case if-dscp {
leaf dscp {
type inet:dscp;
}
}
case if-tos {
leaf tos {
type c-types:tos;
}
leaf precedence {
when "boolean(../tos)" ;
type c-types:precedence;
}
}
}
leaf dscp的schema node XPATH为:dscp-or-tos/if-dscp/dscp;
leaf dscp的data node XPATH为:dscp
可见,data node XPATH的层次路径中会省略掉非data node节点。而schema node XPATH的层次路径中则会把每层schema node都带上。
如果你还闹不清楚schema node XPATH和data node XPATH,可以用netconf browser软件在在左侧schema tree上直接右击,最后一个是属性按钮,里面有schema node XPATH和data node XPATH。
很抱歉我家里没有此软件,没法截图出来。
when must leafref用的是schema node XPATH,还是data node XPATH
when must leafref使用的schema node XPATH。
“实例化后的表项”指有了具体数据内容的表项,与数据库空表相对应。 ↩︎