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的子语句

  1. +--------------+---------+-------------+
  2. | substatement | section | cardinality |
  3. +--------------+---------+-------------+
  4. | action | 7.15 | 0..n |
  5. | anydata | 7.10 | 0..n |
  6. | anyxml | 7.11 | 0..n |
  7. | choice | 7.9 | 0..n |
  8. | config | 7.21.1 | 0..1 |
  9. | container | 7.5 | 0..n |
  10. | description | 7.21.3 | 0..1 |
  11. | grouping | 7.12 | 0..n |
  12. | if-feature | 7.20.2 | 0..n |
  13. | leaf | 7.6 | 0..n |
  14. | leaf-list | 7.7 | 0..n |
  15. | list | 7.8 | 0..n |
  16. | must | 7.5.3 | 0..n |
  17. | notification | 7.16 | 0..n |
  18. | presence | 7.5.5 | 0..1 |
  19. | reference | 7.21.4 | 0..1 |
  20. | status | 7.21.2 | 0..1 |
  21. | typedef | 7.3 | 0..n |
  22. | uses | 7.13 | 0..n |
  23. | when | 7.21.5 | 0..1 |
  24. +--------------+---------+-------------+

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. musterror-message的使用示例

  1. container interface {
  2. leaf ifType {
  3. type enumeration {
  4. enum ethernet;
  5. enum atm;
  6. }
  7. }
  8. leaf ifMTU {
  9. type uint32;
  10. }
  11. must 'ifType != "ethernet" or ifMTU = 1500' {
  12. error-message "An Ethernet MTU must be 1500";
  13. }
  14. must 'ifType != "atm" or'
  15. + ' (ifMTU <= 17966 and ifMTU >= 64)' {
  16. error-message "An ATM MTU must be 64 .. 17966";
  17. }
  18. }

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. 使用示例

鉴于以下容器定义:

  1. container system {
  2. description
  3. "Contains various system parameters.";
  4. container services {
  5. description
  6. "Configure externally available services.";
  7. container "ssh" {
  8. presence "Enables SSH";
  9. description
  10. "SSH service-specific configuration.";
  11. // more leafs, containers, and stuff here...
  12. }
  13. }
  14. }

相应的XML实例示例:

  1. <system>
  2. <services>
  3. <ssh/>
  4. </services>
  5. </system>

由于存在<ssh>元素,所以启用了SSH

使用<edit-config>删除容器:

  1. <rpc message-id="101"
  2. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
  3. xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
  4. <edit-config>
  5. <target>
  6. <running/>
  7. </target>
  8. <config>
  9. <system xmlns="urn:example:config">
  10. <services>
  11. <ssh nc:operation="delete"/>
  12. </services>
  13. </system>
  14. </config>
  15. </edit-config>
  16. </rpc>