7.7. “叶列表”声明

在使用“leaf”语句定义特定类型的简单标量变量的情况下,“leaf-list”语句用于定义特定类型的数组。 “leaf-list”语句带有一个参数,这个参数是一个标识符,后面是一个包含叶列表信息的子语句块。

在配置数据中,叶列表中的值必须是唯一的。

默认值的定义不能用“if-feature”语句来标记。

从概念上讲,数据树中的值必须是规范形式(见9.1节)。

7.7.1. 排序

YANG支持两种样式来排序列表和叶列表中的条目。在许多列表中,列表条目的顺序不会影响列表配置的实现,服务器可以按任何合理的顺序自由排列列表条目。列表的“description”字符串可能会向服务器实现者建议一个排序。YANG将这种风格称为“系统排序(system ordered)”这样的列表用“ordered-by system”的语句表示。

例如,有效用户列表通常会按字母顺序排序,因为用户在配置中出现的顺序不会影响用户帐户的创建。

在其他样式的列表中,列表条目的顺序对于列表配置的实现是重要的,并且用户负责对条目进行排序,而服务器维持该顺序。YANG称这种风格的“用户排序(user ordered)”的名单;这样的列表用“按用户排序(ordered-by user)”的语句表示。

例如,数据包筛选器条目应用于传入流量的顺序可能会影响该流量被过滤的方式。用户需要决定是否应该在过滤条目之前或之后应用丢弃所有TCP流量的过滤条目,以允许来自可信接口的所有流量。排序的选择是至关重要的。

YANGNETCONF<edit-config>操作中提供了丰富的功能,可以控制用户排序列表中列表条目的顺序。列表条目可以被插入或重新排列,被定位为列表中的第一个或最后一个条目,或被定位在另一个特定条目之前或之后。

7.7.7节介绍了“ordered-by”语句。

7.7.2. 叶列表的默认值

如果数据树中不存在叶列表,则叶列表的缺省值是服务器使用的值。缺省值的使用取决于架构树中不是无状态容器的叶节点最近的祖先节点(参见7.5.1节):

  • 如果模式树中不存在这样的祖先,则必须使用默认值。

  • 否则,如果这个祖先是一个case节点,如果数据树中有任何节点存在于数据树中,或者case节点是选择的缺省情况,并且数据中没有任何其他情况的节点,则必须使用默认值树。

  • 否则,如果祖先节点存在于数据树中,则必须使用默认值。

在这些情况下,默认值被认为正在使用中。

请注意,如果叶列表或其任何祖先具有“​​when”条件或“if-feature”表达式的计算结果为“false”,则默认值不会被使用。

当使用默认值时,服务器必须在操作上表现得像数据树中存在的叶表一样,其默认值是其值。

如果叶列表具有一个或多个“default”语句,叶列表的默认值是“default”语句的值,并且如果叶列表是用户排序的,则默认值按照“default”语句。否则,如果叶列表的类型有一个默认值,并且叶列表没有一个值大于或等于1的“min-elements”语句,那么叶列表的默认值是该类型的一个实例默认值。在所有其他情况下,叶列表没有任何默认值。

7.7.3. leaf-list子语句

  1. +--------------+---------+-------------+
  2. | substatement | section | cardinality |
  3. +--------------+---------+-------------+
  4. | config | 7.21.1 | 0..1 |
  5. | default | 7.7.4 | 0..n |
  6. | description | 7.21.3 | 0..1 |
  7. | if-feature | 7.20.2 | 0..n |
  8. | max-elements | 7.7.6 | 0..1 |
  9. | min-elements | 7.7.5 | 0..1 |
  10. | must | 7.5.3 | 0..n |
  11. | ordered-by | 7.7.7 | 0..1 |
  12. | reference | 7.21.4 | 0..1 |
  13. | status | 7.21.2 | 0..1 |
  14. | type | 7.4 | 1 |
  15. | units | 7.3.3 | 0..1 |
  16. | when | 7.21.5 | 0..1 |
  17. +--------------+---------+-------------+

7.7.4. 叶列表的“default”声明

default”语句是可选的,它将一个字符串作为参数,该字符串包含叶列表的默认值。

default”语句的值必须根据叶列表的“type”语句中指定的类型有效。

在“min-elements”的值大于或等于1的节点上,“default”语句不能出现。

7.7.5. “最小元素”声明

min-elements”语句是可选的,它将一个非负整数作为参数,对有效列表条目进行约束。 一个有效的叶列表或者列表必须至少有min元素条目。

如果不存在“min-elements”语句,则默认为零。

约束的行为取决于模式树中叶列表或列表最近的祖先节点的类型,它不是一个不存在的容器(见7.5.1节):

  • 如果模式树中不存在这样的祖先,则强制约束。

  • 否则,如果这个祖先是一个case节点,那么如果这个case的任何其他节点存在,这个约束就会被执行。

  • 否则,如果祖先节点存在,则强制执行。

根据第8节的规定,约束条件得到了进一步的执行。

7.7.6. “最大元素”声明

max-elements”语句是可选的,它将一个正整数或字符串“unbounded”作为参数,对有效的列表条目进行约束。一个有效的叶列表或列表总是至多有最大元素条目。

如果不存在“max-elements”语句,则默认为“unbounded”。

“最大元素”约束按照第8节的规定执行。

7.7.7. “排序”声明

“ordered-by”语句定义列表中的条目顺序是由用户还是系统确定的。 参数是字符串“system”或“user”之一。 如果不存在,则默认为“system”。

如果列表代表状态数据,RPC输出参数或通知内容,则该语句将被忽略。

更多信息见7.7.1节。

7.7.7.1. 基于系统的排序

列表中的条目按照系统确定的顺序排序。 列表的“description”字符串可能会向服务器实现者建议一个命令。如果没有,则可以按照任何顺序自由地对条目进行排序。一个实现应该使用相同的顺序来处理相同的数据,而不管数据是如何创建的。使用确定性顺序将使用简单工具(比如“diff”)进行比较。

这是默认的顺序。

7.7.7.2. 基于用户的排序

列表中的条目按照用户定义的顺序排序。在NETCONF中,这个顺序是通过在<edit-config>请求中使用特殊的XML属性来控制的。细节见7.7.9节

7.7.8. XML编码规则

叶列表节点被编码为一系列XML元素。 每个元素的本地名称是叶列表的标识符,其名称空间是模块的XML名称空间(参见第7.1.3节)。

每个叶列表项的值根据类型被编码为XML,并作为元素中的字符数据被发送。

如果叶列表是“ordered-by user”,则表示叶列表项的XML元素必须以用户指定的顺序出现; 否则,顺序依赖于实现。 表示叶列表项的XML元素可以与叶列表的同级元素交织,除非叶列表定义了RPC或动作输入(action input)或输出参数(output parameters)。

参见7.7.10节的例子。

7.7.9. NETCONF <edit-config>操作

叶列表条目可以通过使用叶列表条目的XML元素中的“operation”属性,通过<edit-config>创建和删除,但不能修改。

在“ordered-by user”的叶列表中,YANG XML命名空间(第5.3.1节)中的属性“insert”和“value”可以用来控制叶列表中插入条目的位置。这些可以在“create”操作期间用于插入新的叶列表条目,或者在“merge”或“replace”操作期间插入新的叶列表条目或移动现有的叶列表条目。

insert”属性可以取值“first”,“last”,“before”和“after”。如果值是“before”或“after”,那么“value”属性也必须用于指定叶列表中的现有条目。

如果在“create”操作中没有“insert”属性,则默认为“last”。

如果在“ordered-by user”叶列表中的几个条目在同一个<edit-config>请求中被修改,则按照请求中的XML元素的顺序一次修改一个条目。

在具有覆盖整个叶列表的“merge”操作的<copy-config><edit-config>中,叶列表顺序与请求中XML元素的顺序相同。

当一个NETCONF服务器处理一个<edit-config>请求时,叶列表节点的过程元素如下:

  • 如果操作是“merge”或“replace”,则叶列表条目如果不存在则创建。

  • 如果操作是“create”,则创建叶列表条目(如果不存在)。如果叶列表项已经存在,则返回“data-exists”错误。

  • 如果操作是“delete”,则从叶列表中删除条目(如果存在)。如果叶列表项不存在,则返回“data-missing”错误。

7.7.10. 使用示例

  1. leaf-list allow-user {
  2. type string;
  3. description
  4. "A list of user name patterns to allow.";
  5. }

相应的XML实例示例:

  1. <allow-user>alice</allow-user>
  2. <allow-user>bob</allow-user>

要在此列表中创建一个新元素,请使用默认的<edit-config>操作“merge”:

  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>
  12. <allow-user>eric</allow-user>
  13. </ssh>
  14. </services>
  15. </system>
  16. </config>
  17. </edit-config>
  18. </rpc>

给出以下按用户排序的列表:

  1. leaf-list cipher {
  2. type string;
  3. ordered-by user;
  4. description
  5. "A list of ciphers.";
  6. }

以下将被用于在“3des-cbc”之后插入新的密码“blowfish-cbc”:

  1. <rpc message-id="102"
  2. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
  3. xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
  4. xmlns:yang="urn:ietf:params:xml:ns:yang:1">
  5. <edit-config>
  6. <target>
  7. <running/>
  8. </target>
  9. <config>
  10. <system xmlns="urn:example:config">
  11. <services>
  12. <ssh>
  13. <cipher nc:operation="create"
  14. yang:insert="after"
  15. yang:value="3des-cbc">blowfish-cbc</cipher>
  16. </ssh>
  17. </services>
  18. </system>
  19. </config>
  20. </edit-config>
  21. </rpc>