7.5. “容器”声明
“container
”语句用于定义架构树中的内部数据节点。 它有一个参数,它是一个标识符,后面跟着一个包含详细容器信息的子状态块。
容器节点没有值,但在数据树中有一个子节点的列表。 子节点在容器的子状态中定义。
7.5.1. 容器的存在
YANG
支持两种类型的容器,这些容器仅用于组织数据节点的层次结构,以及那些在数据树中的存在具有明确含义的容器。
在第一种风格中,容器没有其自身的意义,只存在于包含子节点。 特别是,没有子节点的容器节点的存在在语义上等同于不存在容器节点。 YANG
称这种风格为“不存在容器”(non-presence container
)。 这是默认的类型。
例如,用于同步光网络(SONET
)接口的一组加扰选项可以放置在“scrambling
”容器内以增强配置分层结构的组织并将这些节点保持在一起。 “scrambling
”节点本身没有任何意义,所以当节点变空时删除节点,可以减轻用户的工作量。
在第二种方式中,容器本身的存在具有一些含义,代表一个数据位。
对于配置数据,容器既充当配置按钮又充当组织相关配置节点的手段。 这些容器是显式创建和删除的。
YANG
将这种风格称为“存在容器”(presence container
),并使用“存在”语句来指示它,该存储过程以一个文本字符串作为参数,表示节点的存在。
例如,“ssh
”容器可以使用Secure Shell(SSH)
打开登录服务器的能力,但也可以包含任何与SSH
有关的配置按钮,例如连接速率或重试限制。
“presence
”语句(见第7.5.5节)用于给出数据树中容器的存在的语义。
7.5.2. container
的子语句
+--------------+---------+-------------+
| substatement | section | cardinality |
+--------------+---------+-------------+
| action | 7.15 | 0..n |
| anydata | 7.10 | 0..n |
| anyxml | 7.11 | 0..n |
| choice | 7.9 | 0..n |
| config | 7.21.1 | 0..1 |
| container | 7.5 | 0..n |
| description | 7.21.3 | 0..1 |
| grouping | 7.12 | 0..n |
| if-feature | 7.20.2 | 0..n |
| leaf | 7.6 | 0..n |
| leaf-list | 7.7 | 0..n |
| list | 7.8 | 0..n |
| must | 7.5.3 | 0..n |
| notification | 7.16 | 0..n |
| presence | 7.5.5 | 0..1 |
| reference | 7.21.4 | 0..1 |
| status | 7.21.2 | 0..1 |
| typedef | 7.3 | 0..n |
| uses | 7.13 | 0..n |
| when | 7.21.5 | 0..1 |
+--------------+---------+-------------+
7.5.3. “必须”(must
)声明
“must
”语句是可选的,它将一个包含XPath
表达式的字符串作为参数(见6.4节)。它用于正式声明对有效数据的约束。约束条件按照第8节的规定执行。
当一个数据存储被验证时,所有的“must
”约束在可访问树中的每个节点的概念上被评估一次(见第6.4.1节)。
所有这些约束必须评估为“true
”,以使数据有效。
除了第6.4.1节中的定义之外,XPath
表达式在以下上下文中概念性地评估:
如果“
must
”语句是“notification
”语句的子语句,则上下文节点是表示可访问树中通知的节点。如果“
must
”语句是“input
”语句的子语句,则上下文节点是表示可访问树中操作的节点。如果“
must
”语句是“output
”语句的子语句,则上下文节点是表示可访问树中操作的节点。
否则,上下文节点是可访问树中为其定义“must
”语句的节点。
使用标准的XPath
规则将XPath
表达式的结果转换为布尔值。
请注意,由于数据树中的所有叶子值在概念上都是以规范形式存储的(请参见第9.1节),所以任何XPath
比较都是在规范值上进行的。
另请注意,XPath
表达式是在概念上评估的。这意味着实现不必在服务器中使用XPath
评估程序。评估如何在实践中完成是一个实施决策。
7.5.4.1. “错误消息”(error-message
)声明
“error-message
”语句是可选的,它将字符串作为参数。 如果约束的计算结果为“false
”,则字符串在NETCONF
的<rpc-error>
中作为<error-message>
传递。
7.5.4.2. “错误应用标记”(error-app-tag
)声明
“error-app-tag
”语句是可选的,它将字符串作为参数。 如果约束条件的计算结果为“false
”,则字符串在NETCONF
的<rpc-error>
中作为<error-app-tag>
传递。
7.5.4.3. must
和error-message
的使用示例
container interface {
leaf ifType {
type enumeration {
enum ethernet;
enum atm;
}
}
leaf ifMTU {
type uint32;
}
must 'ifType != "ethernet" or ifMTU = 1500' {
error-message "An Ethernet MTU must be 1500";
}
must 'ifType != "atm" or'
+ ' (ifMTU <= 17966 and ifMTU >= 64)' {
error-message "An ATM MTU must be 64 .. 17966";
}
}
7.5.5. “存在”(presence
)声明
“presence
”语句为数据树中容器的存在赋予一个含义。 它以一个字符串作为参数,该字符串包含文本描述节点存在的含义。
如果容器具有“presence
”语句,则数据树中的容器存在意义。 否则,容器被用来给数据一些结构,它本身没有意义。
有关更多信息,请参阅第7.5.1节。
7.5.6. 容器的子节点语句
在一个容器中,可以使用“container
”,“leaf
”,“list
”,“leaf-list
”,“uses
”,“choice
”,“anydata
”和“anyxml
”语句来定义容器的子节点。
7.5.7. XML
编码规则
一个容器节点被编码为一个XML
元素。 元素的本地名称是容器的标识符,其名称空间是模块的XML
名称空间(参见第7.1.3节)。
容器的子节点被编码为容器元素的子元素。 如果容器定义了RPC
或操作输入或输出参数,则这些子元素将按照“container
”语句中定义的顺序进行编码。 否则,子元素按任何顺序编码。
容器的子元素之间的任何空格都是不重要的,即一个实现可以在子元素之间插入空白字符。
如果一个不存在的容器没有任何子节点,容器可能会或可能不会出现在XML
编码中。
7.5.8.NETCONF <edit-config>
操作
通过使用容器的XML
元素中的“operation
”属性(参见[RFC6241]中的第7.2节),可以通过<edit-config>
创建,删除,替换和修改容器。
如果一个容器没有“presence
”语句并且最后一个子节点被删除,NETCONF
服务器可能会删除该容器。
当NETCONF
服务器处理<edit-config>
请求时,容器节点的过程元素如下所示:
如果操作是“合并(
merge
)”或“替换(replace
)”,则创建该节点(如果该节点不存在)。如果操作是“创建(
create
)”,则创建该节点(如果该节点不存在)。 如果节点已经存在,则返回“数据存在(data-exists
)”错误。如果操作是“删除(
delete
)”,则该节点将被删除(如果存在)。 如果节点不存在,则返回“数据缺失(data-missing
)”错误。
7.5.9. 使用示例
鉴于以下容器定义:
container system {
description
"Contains various system parameters.";
container services {
description
"Configure externally available services.";
container "ssh" {
presence "Enables SSH";
description
"SSH service-specific configuration.";
// more leafs, containers, and stuff here...
}
}
}
相应的XML实例示例:
<system>
<services>
<ssh/>
</services>
</system>
由于存在<ssh>
元素,所以启用了SSH
。
使用<edit-config>
删除容器:
<rpc message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
<edit-config>
<target>
<running/>
</target>
<config>
<system xmlns="urn:example:config">
<services>
<ssh nc:operation="delete"/>
</services>
</system>
</config>
</edit-config>
</rpc>