7.7. The leaf-list Statement
Where the "leaf" statement is used to define a simple scalar variable of a particular type, the "leaf-list" statement is used to define an array of a particular type. The "leaf-list" statement takes one argument, which is an identifier, followed by a block of substatements that holds detailed leaf-list information. The values in a leaf-list MUST be unique. Conceptually, the values in the data tree are always in the canonical form (see Section 9.1). If the type referenced by the leaf-list has a default value, it has no effect in the leaf-list.7.7.1. Ordering
YANG supports two styles for ordering the entries within lists and leaf-lists. In many lists, the order of list entries does not impact the implementation of the list's configuration, and the device is free to sort the list entries in any reasonable order. The "description" string for the list may suggest an order to the device implementor. YANG calls this style of list "system ordered" and they are indicated with the statement "ordered-by system". For example, a list of valid users would typically be sorted alphabetically, since the order in which the users appeared in the configuration would not impact the creation of those users' accounts. In the other style of lists, the order of list entries matters for the implementation of the list's configuration and the user is responsible for ordering the entries, while the device maintains that order. YANG calls this style of list "user ordered" and they are indicated with the statement "ordered-by user". For example, the order in which firewall filters entries are applied to incoming traffic may affect how that traffic is filtered. The user would need to decide if the filter entry that discards all TCP traffic should be applied before or after the filter entry that allows all traffic from trusted interfaces. The choice of order would be crucial. YANG provides a rich set of facilities within NETCONF's <edit-config> operation that allows the order of list entries in user-ordered lists to be controlled. List entries may be inserted or rearranged, positioned as the first or last entry in the list, or positioned before or after another specific entry.
The "ordered-by" statement is covered in Section 7.7.5.7.7.2. The leaf-list's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | config | 7.19.1 | 0..1 | | description | 7.19.3 | 0..1 | | if-feature | 7.18.2 | 0..n | | max-elements | 7.7.4 | 0..1 | | min-elements | 7.7.3 | 0..1 | | must | 7.5.3 | 0..n | | ordered-by | 7.7.5 | 0..1 | | reference | 7.19.4 | 0..1 | | status | 7.19.2 | 0..1 | | type | 7.4 | 1 | | units | 7.3.3 | 0..1 | | when | 7.19.5 | 0..1 | +--------------+---------+-------------+7.7.3. The min-elements Statement
The "min-elements" statement, which is optional, takes as an argument a non-negative integer that puts a constraint on valid list entries. A valid leaf-list or list MUST have at least min-elements entries. If no "min-elements" statement is present, it defaults to zero. The behavior of the constraint depends on the type of the leaf-list's or list's closest ancestor node in the schema tree that is not a non- presence container (see Section 7.5.1): o If this ancestor is a case node, the constraint is enforced if any other node from the case exists. o Otherwise, it is enforced if the ancestor node exists. The constraint is further enforced according to the rules in Section 8.7.7.4. The max-elements Statement
The "max-elements" statement, which is optional, takes as an argument a positive integer or the string "unbounded", which puts a constraint on valid list entries. A valid leaf-list or list always has at most max-elements entries.
If no "max-elements" statement is present, it defaults to "unbounded". The "max-elements" constraint is enforced according to the rules in Section 8.7.7.5. The ordered-by Statement
The "ordered-by" statement defines whether the order of entries within a list are determined by the user or the system. The argument is one of the strings "system" or "user". If not present, order defaults to "system". This statement is ignored if the list represents state data, RPC output parameters, or notification content. See Section 7.7.1 for additional information.7.7.5.1. ordered-by system
The entries in the list are sorted according to an unspecified order. Thus, an implementation is free to sort the entries in the most appropriate order. An implementation SHOULD use the same order for the same data, regardless of how the data were created. Using a deterministic order will make comparisons possible using simple tools like "diff". This is the default order.7.7.5.2. ordered-by user
The entries in the list are sorted according to an order defined by the user. This order is controlled by using special XML attributes in the <edit-config> request. See Section 7.7.7 for details.7.7.6. XML Mapping Rules
A leaf-list node is encoded as a series of XML elements. Each element's local name is the leaf-list's identifier, and its namespace is the module's XML namespace (see Section 7.1.3). The value of each leaf-list entry is encoded to XML according to the type, and sent as character data in the element. The XML elements representing leaf-list entries MUST appear in the order specified by the user if the leaf-list is "ordered-by user"; otherwise, the order is implementation-dependent. The XML elements
representing leaf-list entries MAY be interleaved with other sibling elements, unless the leaf-list defines RPC input or output parameters. See Section 7.7.8 for an example.7.7.7. NETCONF <edit-config> Operations
Leaf-list entries can be created and deleted, but not modified, through <edit-config>, by using the "operation" attribute in the leaf-list entry's XML element. In an "ordered-by user" leaf-list, the attributes "insert" and "value" in the YANG XML namespace (Section 5.3.1) can be used to control where in the leaf-list the entry is inserted. These can be used during "create" operations to insert a new leaf-list entry, or during "merge" or "replace" operations to insert a new leaf-list entry or move an existing one. The "insert" attribute can take the values "first", "last", "before", and "after". If the value is "before" or "after", the "value" attribute MUST also be used to specify an existing entry in the leaf- list. If no "insert" attribute is present in the "create" operation, it defaults to "last". If several entries in an "ordered-by user" leaf-list are modified in the same <edit-config> request, the entries are modified one at the time, in the order of the XML elements in the request. In a <copy-config>, or an <edit-config> with a "replace" operation that covers the entire leaf-list, the leaf-list order is the same as the order of the XML elements in the request. When a NETCONF server processes an <edit-config> request, the elements of procedure for a leaf-list node are: If the operation is "merge" or "replace", the leaf-list entry is created if it does not exist. If the operation is "create", the leaf-list entry is created if it does not exist. If the leaf-list entry already exists, a "data-exists" error is returned. If the operation is "delete", the entry is deleted from the leaf- list if it exists. If the leaf-list entry does not exist, a "data-missing" error is returned.
7.7.8. Usage Example
leaf-list allow-user { type string; description "A list of user name patterns to allow"; } A corresponding XML instance example: <allow-user>alice</allow-user> <allow-user>bob</allow-user> To create a new element in this list, using the default <edit-config> operation "merge": <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="http://example.com/schema/config"> <services> <ssh> <allow-user>eric</allow-user> </ssh> </services> </system> </config> </edit-config> </rpc> Given the following ordered-by user leaf-list: leaf-list cipher { type string; ordered-by user; description "A list of ciphers"; } The following would be used to insert a new cipher "blowfish-cbc" after "3des-cbc":
<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" xmlns:yang="urn:ietf:params:xml:ns:yang:1"> <edit-config> <target> <running/> </target> <config> <system xmlns="http://example.com/schema/config"> <services> <ssh> <cipher nc:operation="create" yang:insert="after" yang:value="3des-cbc">blowfish-cbc</cipher> </ssh> </services> </system> </config> </edit-config> </rpc>7.8. The list Statement
The "list" statement is used to define an interior data node in the schema tree. A list node may exist in multiple instances in the data tree. Each such instance is known as a list entry. The "list" statement takes one argument, which is an identifier, followed by a block of substatements that holds detailed list information. A list entry is uniquely identified by the values of the list's keys, if defined.
7.8.1. The list's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | anyxml | 7.10 | 0..n | | choice | 7.9 | 0..n | | config | 7.19.1 | 0..1 | | container | 7.5 | 0..n | | description | 7.19.3 | 0..1 | | grouping | 7.11 | 0..n | | if-feature | 7.18.2 | 0..n | | key | 7.8.2 | 0..1 | | leaf | 7.6 | 0..n | | leaf-list | 7.7 | 0..n | | list | 7.8 | 0..n | | max-elements | 7.7.4 | 0..1 | | min-elements | 7.7.3 | 0..1 | | must | 7.5.3 | 0..n | | ordered-by | 7.7.5 | 0..1 | | reference | 7.19.4 | 0..1 | | status | 7.19.2 | 0..1 | | typedef | 7.3 | 0..n | | unique | 7.8.3 | 0..n | | uses | 7.12 | 0..n | | when | 7.19.5 | 0..1 | +--------------+---------+-------------+7.8.2. The list's key Statement
The "key" statement, which MUST be present if the list represents configuration, and MAY be present otherwise, takes as an argument a string that specifies a space-separated list of leaf identifiers of this list. A leaf identifier MUST NOT appear more than once in the key. Each such leaf identifier MUST refer to a child leaf of the list. The leafs can be defined directly in substatements to the list, or in groupings used in the list. The combined values of all the leafs specified in the key are used to uniquely identify a list entry. All key leafs MUST be given values when a list entry is created. Thus, any default values in the key leafs or their types are ignored. It also implies that any mandatory statement in the key leafs are ignored. A leaf that is part of the key can be of any built-in or derived type, except it MUST NOT be the built-in type "empty".
All key leafs in a list MUST have the same value for their "config" as the list itself. The key string syntax is formally defined by the rule "key-arg" in Section 12.7.8.3. The list's unique Statement
The "unique" statement is used to put constraints on valid list entries. It takes as an argument a string that contains a space- separated list of schema node identifiers, which MUST be given in the descendant form (see the rule "descendant-schema-nodeid" in Section 12). Each such schema node identifier MUST refer to a leaf. If one of the referenced leafs represents configuration data, then all of the referenced leafs MUST represent configuration data. The "unique" constraint specifies that the combined values of all the leaf instances specified in the argument string, including leafs with default values, MUST be unique within all list entry instances in which all referenced leafs exist. The constraint is enforced according to the rules in Section 8. The unique string syntax is formally defined by the rule "unique-arg" in Section 12.7.8.3.1. Usage Example
With the following list: list server { key "name"; unique "ip port"; leaf name { type string; } leaf ip { type inet:ip-address; } leaf port { type inet:port-number; } }
The following configuration is not valid: <server> <name>smtp</name> <ip>192.0.2.1</ip> <port>25</port> </server> <server> <name>http</name> <ip>192.0.2.1</ip> <port>25</port> </server> The following configuration is valid, since the "http" and "ftp" list entries do not have a value for all referenced leafs, and are thus not taken into account when the "unique" constraint is enforced: <server> <name>smtp</name> <ip>192.0.2.1</ip> <port>25</port> </server> <server> <name>http</name> <ip>192.0.2.1</ip> </server> <server> <name>ftp</name> <ip>192.0.2.1</ip> </server>7.8.4. The list's Child Node Statements
Within a list, the "container", "leaf", "list", "leaf-list", "uses", "choice", and "anyxml" statements can be used to define child nodes to the list.7.8.5. XML Mapping Rules
A list is encoded as a series of XML elements, one for each entry in the list. Each element's local name is the list's identifier, and its namespace is the module's XML namespace (see Section 7.1.3).
The list's key nodes are encoded as subelements to the list's identifier element, in the same order as they are defined within the "key" statement. The rest of the list's child nodes are encoded as subelements to the list element, after the keys. If the list defines RPC input or output parameters, the subelements are encoded in the same order as they are defined within the "list" statement. Otherwise, the subelements are encoded in any order. The XML elements representing list entries MUST appear in the order specified by the user if the list is "ordered-by user", otherwise the order is implementation-dependent. The XML elements representing list entries MAY be interleaved with other sibling elements, unless the list defines RPC input or output parameters.7.8.6. NETCONF <edit-config> Operations
List entries can be created, deleted, replaced, and modified through <edit-config>, by using the "operation" attribute in the list's XML element. In each case, the values of all keys are used to uniquely identify a list entry. If all keys are not specified for a list entry, a "missing-element" error is returned. In an "ordered-by user" list, the attributes "insert" and "key" in the YANG XML namespace (Section 5.3.1) can be used to control where in the list the entry is inserted. These can be used during "create" operations to insert a new list entry, or during "merge" or "replace" operations to insert a new list entry or move an existing one. The "insert" attribute can take the values "first", "last", "before", and "after". If the value is "before" or "after", the "key" attribute MUST also be used, to specify an existing element in the list. The value of the "key" attribute is the key predicates of the full instance identifier (see Section 9.13) for the list entry. If no "insert" attribute is present in the "create" operation, it defaults to "last". If several entries in an "ordered-by user" list are modified in the same <edit-config> request, the entries are modified one at the time, in the order of the XML elements in the request. In a <copy-config>, or an <edit-config> with a "replace" operation that covers the entire list, the list entry order is the same as the order of the XML elements in the request.
When a NETCONF server processes an <edit-config> request, the elements of procedure for a list node are: If the operation is "merge" or "replace", the list entry is created if it does not exist. If the list entry already exists and the "insert" and "key" attributes are present, the list entry is moved according to the values of the "insert" and "key" attributes. If the list entry exists and the "insert" and "key" attributes are not present, the list entry is not moved. If the operation is "create", the list entry is created if it does not exist. If the list entry already exists, a "data-exists" error is returned. If the operation is "delete", the entry is deleted from the list if it exists. If the list entry does not exist, a "data-missing" error is returned.7.8.7. Usage Example
Given the following list: list user { key "name"; config true; description "This is a list of users in the system."; leaf name { type string; } leaf type { type string; } leaf full-name { type string; } } A corresponding XML instance example: <user> <name>fred</name> <type>admin</type> <full-name>Fred Flintstone</full-name> </user>
To create a new user "barney": <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="http://example.com/schema/config"> <user nc:operation="create"> <name>barney</name> <type>admin</type> <full-name>Barney Rubble</full-name> </user> </system> </config> </edit-config> </rpc> To change the type of "fred" to "superuser": <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="http://example.com/schema/config"> <user> <name>fred</name> <type>superuser</type> </user> </system> </config> </edit-config> </rpc>
Given the following ordered-by user list: list user { description "This is a list of users in the system."; ordered-by user; config true; key "name"; leaf name { type string; } leaf type { type string; } leaf full-name { type string; } } The following would be used to insert a new user "barney" after the user "fred": <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" xmlns:yang="urn:ietf:params:xml:ns:yang:1"> <edit-config> <target> <running/> </target> <config> <system xmlns="http://example.com/schema/config" xmlns:ex="http://example.com/schema/config"> <user nc:operation="create" yang:insert="after" yang:key="[ex:name='fred']"> <name>barney</name> <type>admin</type> <full-name>Barney Rubble</full-name> </user> </system> </config> </edit-config> </rpc>
The following would be used to move the user "barney" before the user "fred": <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" xmlns:yang="urn:ietf:params:xml:ns:yang:1"> <edit-config> <target> <running/> </target> <config> <system xmlns="http://example.com/schema/config" xmlns:ex="http://example.com/schema/config"> <user nc:operation="merge" yang:insert="before" yang:key="[ex:name='fred']"> <name>barney</name> </user> </system> </config> </edit-config> </rpc>7.9. The choice Statement
The "choice" statement defines a set of alternatives, only one of which may exist at any one time. The argument is an identifier, followed by a block of substatements that holds detailed choice information. The identifier is used to identify the choice node in the schema tree. A choice node does not exist in the data tree. A choice consists of a number of branches, defined with the "case" substatement. Each branch contains a number of child nodes. The nodes from at most one of the choice's branches exist at the same time. See Section 8.3.2 for additional information.
7.9.1. The choice's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | anyxml | 7.10 | 0..n | | case | 7.9.2 | 0..n | | config | 7.19.1 | 0..1 | | container | 7.5 | 0..n | | default | 7.9.3 | 0..1 | | description | 7.19.3 | 0..1 | | if-feature | 7.18.2 | 0..n | | leaf | 7.6 | 0..n | | leaf-list | 7.7 | 0..n | | list | 7.8 | 0..n | | mandatory | 7.9.4 | 0..1 | | reference | 7.19.4 | 0..1 | | status | 7.19.2 | 0..1 | | when | 7.19.5 | 0..1 | +--------------+---------+-------------+7.9.2. The choice's case Statement
The "case" statement is used to define branches of the choice. It takes as an argument an identifier, followed by a block of substatements that holds detailed case information. The identifier is used to identify the case node in the schema tree. A case node does not exist in the data tree. Within a "case" statement, the "anyxml", "choice", "container", "leaf", "list", "leaf-list", and "uses" statements can be used to define child nodes to the case node. The identifiers of all these child nodes MUST be unique within all cases in a choice. For example, the following is illegal: choice interface-type { // This example is illegal YANG case a { leaf ethernet { ... } } case b { container ethernet { ...} } }
As a shorthand, the "case" statement can be omitted if the branch contains a single "anyxml", "container", "leaf", "list", or "leaf-list" statement. In this case, the identifier of the case node is the same as the identifier in the branch statement. The following example: choice interface-type { container ethernet { ... } } is equivalent to: choice interface-type { case ethernet { container ethernet { ... } } } The case identifier MUST be unique within a choice.7.9.2.1. The case's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | anyxml | 7.10 | 0..n | | choice | 7.9 | 0..n | | container | 7.5 | 0..n | | description | 7.19.3 | 0..1 | | if-feature | 7.18.2 | 0..n | | leaf | 7.6 | 0..n | | leaf-list | 7.7 | 0..n | | list | 7.8 | 0..n | | reference | 7.19.4 | 0..1 | | status | 7.19.2 | 0..1 | | uses | 7.12 | 0..n | | when | 7.19.5 | 0..1 | +--------------+---------+-------------+7.9.3. The choice's default Statement
The "default" statement indicates if a case should be considered as the default if no child nodes from any of the choice's cases exist. The argument is the identifier of the "case" statement. If the "default" statement is missing, there is no default case. The "default" statement MUST NOT be present on choices where "mandatory" is true.
The default case is only important when considering the default values of nodes under the cases. The default values for nodes under the default case are used if none of the nodes under any of the cases are present. There MUST NOT be any mandatory nodes (Section 3.1) directly under the default case. Default values for child nodes under a case are only used if one of the nodes under that case is present, or if that case is the default case. If none of the nodes under a case are present and the case is not the default case, the default values of the cases' child nodes are ignored. In this example, the choice defaults to "interval", and the default value will be used if none of "daily", "time-of-day", or "manual" are present. If "daily" is present, the default value for "time-of-day" will be used. container transfer { choice how { default interval; case interval { leaf interval { type uint16; default 30; units minutes; } } case daily { leaf daily { type empty; } leaf time-of-day { type string; units 24-hour-clock; default 1am; } } case manual { leaf manual { type empty; } } } }
7.9.4. The choice's mandatory Statement
The "mandatory" statement, which is optional, takes as an argument the string "true" or "false", and puts a constraint on valid data. If "mandatory" is "true", at least one node from exactly one of the choice's case branches MUST exist. If not specified, the default is "false". The behavior of the constraint depends on the type of the choice's closest ancestor node in the schema tree which is not a non-presence container (see Section 7.5.1): o If this ancestor is a case node, the constraint is enforced if any other node from the case exists. o Otherwise, it is enforced if the ancestor node exists. The constraint is further enforced according to the rules in Section 8.7.9.5. XML Mapping Rules
The choice and case nodes are not visible in XML. The child nodes of the selected "case" statement MUST be encoded in the same order as they are defined in the "case" statement if they are part of an RPC input or output parameter definition. Otherwise, the subelements are encoded in any order.7.9.6. NETCONF <edit-config> Operations
Since only one of the choice's cases can be valid at any time, the creation of a node from one case implicitly deletes all nodes from all other cases. If an <edit-config> operation creates a node from a case, the NETCONF server will delete any existing nodes that are defined in other cases inside the choice.7.9.7. Usage Example
Given the following choice:
container protocol { choice name { case a { leaf udp { type empty; } } case b { leaf tcp { type empty; } } } } A corresponding XML instance example: <protocol> <tcp/> </protocol> To change the protocol from tcp to udp: <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="http://example.com/schema/config"> <protocol> <udp nc:operation="create"/> </protocol> </system> </config> </edit-config> </rpc>7.10. The anyxml Statement
The "anyxml" statement defines an interior node in the schema tree. It takes one argument, which is an identifier, followed by a block of substatements that holds detailed anyxml information.
The "anyxml" statement is used to represent an unknown chunk of XML. No restrictions are placed on the XML. This can be useful, for example, in RPC replies. An example is the <filter> parameter in the <get-config> operation. An anyxml node cannot be augmented (see Section 7.15). Since the use of anyxml limits the manipulation of the content, it is RECOMMENDED that the "anyxml" statement not be used to represent configuration data. An anyxml node exists in zero or one instances in the data tree.7.10.1. The anyxml's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | config | 7.19.1 | 0..1 | | description | 7.19.3 | 0..1 | | if-feature | 7.18.2 | 0..n | | mandatory | 7.6.5 | 0..1 | | must | 7.5.3 | 0..n | | reference | 7.19.4 | 0..1 | | status | 7.19.2 | 0..1 | | when | 7.19.5 | 0..1 | +--------------+---------+-------------+7.10.2. XML Mapping Rules
An anyxml node is encoded as an XML element. The element's local name is the anyxml's identifier, and its namespace is the module's XML namespace (see Section 7.1.3). The value of the anyxml node is encoded as XML content of this element. Note that any prefixes used in the encoding are local to each instance encoding. This means that the same XML may be encoded differently by different implementations.7.10.3. NETCONF <edit-config> Operations
An anyxml node is treated as an opaque chunk of data. This data can be modified in its entirety only. Any "operation" attributes present on subelements of an anyxml node are ignored by the NETCONF server.
When a NETCONF server processes an <edit-config> request, the elements of procedure for the anyxml node are: If the operation is "merge" or "replace", the node is created if it does not exist, and its value is set to the XML content of the anyxml node found in the XML RPC data. If the operation is "create", the node is created if it does not exist, and its value is set to the XML content of the anyxml node found in the XML RPC data. If the node already exists, a "data-exists" error is returned. If the operation is "delete", the node is deleted if it exists. If the node does not exist, a "data-missing" error is returned.7.10.4. Usage Example
Given the following "anyxml" statement: anyxml data; The following are two valid encodings of the same anyxml value: <data xmlns:if="http://example.com/ns/interface"> <if:interface> <if:ifIndex>1</if:ifIndex> </if:interface> </data> <data> <interface xmlns="http://example.com/ns/interface"> <ifIndex>1</ifIndex> </interface> </data>7.11. The grouping Statement
The "grouping" statement is used to define a reusable block of nodes, which may be used locally in the module, in modules that include it, and by other modules that import from it, according to the rules in Section 5.5. It takes one argument, which is an identifier, followed by a block of substatements that holds detailed grouping information. The "grouping" statement is not a data definition statement and, as such, does not define any nodes in the schema tree. A grouping is like a "structure" or a "record" in conventional programming languages.
Once a grouping is defined, it can be referenced in a "uses" statement (see Section 7.12). A grouping MUST NOT reference itself, neither directly nor indirectly through a chain of other groupings. If the grouping is defined at the top level of a YANG module or submodule, the grouping's identifier MUST be unique within the module. A grouping is more than just a mechanism for textual substitution, but defines a collection of nodes. Identifiers appearing inside the grouping are resolved relative to the scope in which the grouping is defined, not where it is used. Prefix mappings, type names, grouping names, and extension usage are evaluated in the hierarchy where the "grouping" statement appears. For extensions, this means that extensions are applied to the grouping node, not the uses node.7.11.1. The grouping's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | anyxml | 7.10 | 0..n | | choice | 7.9 | 0..n | | container | 7.5 | 0..n | | description | 7.19.3 | 0..1 | | grouping | 7.11 | 0..n | | leaf | 7.6 | 0..n | | leaf-list | 7.7 | 0..n | | list | 7.8 | 0..n | | reference | 7.19.4 | 0..1 | | status | 7.19.2 | 0..1 | | typedef | 7.3 | 0..n | | uses | 7.12 | 0..n | +--------------+---------+-------------+
7.11.2. Usage Example
import ietf-inet-types { prefix "inet"; } grouping endpoint { description "A reusable endpoint group."; leaf ip { type inet:ip-address; } leaf port { type inet:port-number; } }7.12. The uses Statement
The "uses" statement is used to reference a "grouping" definition. It takes one argument, which is the name of the grouping. The effect of a "uses" reference to a grouping is that the nodes defined by the grouping are copied into the current schema tree, and then updated according to the "refine" and "augment" statements. The identifiers defined in the grouping are not bound to a namespace until the contents of the grouping are added to the schema tree via a "uses" statement that does not appear inside a "grouping" statement, at which point they are bound to the namespace of the current module.
7.12.1. The uses's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | augment | 7.15 | 0..1 | | description | 7.19.3 | 0..1 | | if-feature | 7.18.2 | 0..n | | refine | 7.12.2 | 0..1 | | reference | 7.19.4 | 0..1 | | status | 7.19.2 | 0..1 | | when | 7.19.5 | 0..1 | +--------------+---------+-------------+7.12.2. The refine Statement
Some of the properties of each node in the grouping can be refined with the "refine" statement. The argument is a string that identifies a node in the grouping. This node is called the refine's target node. If a node in the grouping is not present as a target node of a "refine" statement, it is not refined, and thus used exactly as it was defined in the grouping. The argument string is a descendant schema node identifier (see Section 6.5). The following refinements can be done: o A leaf or choice node may get a default value, or a new default value if it already had one. o Any node may get a specialized "description" string. o Any node may get a specialized "reference" string. o Any node may get a different "config" statement. o A leaf, anyxml, or choice node may get a different "mandatory" statement. o A container node may get a "presence" statement. o A leaf, leaf-list, list, container, or anyxml node may get additional "must" expressions. o A leaf-list or list node may get a different "min-elements" or "max-elements" statement.
7.12.3. XML Mapping Rules
Each node in the grouping is encoded as if it was defined inline, even if it is imported from another module with another XML namespace.7.12.4. Usage Example
To use the "endpoint" grouping defined in Section 7.11.2 in a definition of an HTTP server in some other module, we can do: import acme-system { prefix "acme"; } container http-server { leaf name { type string; } uses acme:endpoint; } A corresponding XML instance example: <http-server> <name>extern-web</name> <ip>192.0.2.1</ip> <port>80</port> </http-server> If port 80 should be the default for the HTTP server, default can be added: container http-server { leaf name { type string; } uses acme:endpoint { refine port { default 80; } } } If we want to define a list of servers, and each server has the ip and port as keys, we can do:
list server { key "ip port"; leaf name { type string; } uses acme:endpoint; } The following is an error: container http-server { uses acme:endpoint; leaf ip { // illegal - same identifier "ip" used twice type string; } }7.13. The rpc Statement
The "rpc" statement is used to define a NETCONF RPC operation. It takes one argument, which is an identifier, followed by a block of substatements that holds detailed rpc information. This argument is the name of the RPC, and is used as the element name directly under the <rpc> element, as designated by the substitution group "rpcOperation" in [RFC4741]. The "rpc" statement defines an rpc node in the schema tree. Under the rpc node, a schema node with the name "input", and a schema node with the name "output" are also defined. The nodes "input" and "output" are defined in the module's namespace.
7.13.1. The rpc's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | description | 7.19.3 | 0..1 | | grouping | 7.11 | 0..n | | if-feature | 7.18.2 | 0..n | | input | 7.13.2 | 0..1 | | output | 7.13.3 | 0..1 | | reference | 7.19.4 | 0..1 | | status | 7.19.2 | 0..1 | | typedef | 7.3 | 0..n | +--------------+---------+-------------+7.13.2. The input Statement
The "input" statement, which is optional, is used to define input parameters to the RPC operation. It does not take an argument. The substatements to "input" define nodes under the RPC's input node. If a leaf in the input tree has a "mandatory" statement with the value "true", the leaf MUST be present in a NETCONF RPC invocation. Otherwise, the server MUST return a "missing-element" error. If a leaf in the input tree has a default value, the NETCONF server MUST use this value in the same cases as described in Section 7.6.1. In these cases, the server MUST operationally behave as if the leaf was present in the NETCONF RPC invocation with the default value as its value. If a "config" statement is present for any node in the input tree, the "config" statement is ignored. If any node has a "when" statement that would evaluate to false, then this node MUST NOT be present in the input tree.
7.13.2.1. The input's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | anyxml | 7.10 | 0..n | | choice | 7.9 | 0..n | | container | 7.5 | 0..n | | grouping | 7.11 | 0..n | | leaf | 7.6 | 0..n | | leaf-list | 7.7 | 0..n | | list | 7.8 | 0..n | | typedef | 7.3 | 0..n | | uses | 7.12 | 0..n | +--------------+---------+-------------+7.13.3. The output Statement
The "output" statement, which is optional, is used to define output parameters to the RPC operation. It does not take an argument. The substatements to "output" define nodes under the RPC's output node. If a leaf in the output tree has a "mandatory" statement with the value "true", the leaf MUST be present in a NETCONF RPC reply. If a leaf in the output tree has a default value, the NETCONF client MUST use this value in the same cases as described in Section 7.6.1. In these cases, the client MUST operationally behave as if the leaf was present in the NETCONF RPC reply with the default value as its value. If a "config" statement is present for any node in the output tree, the "config" statement is ignored. If any node has a "when" statement that would evaluate to false, then this node MUST NOT be present in the output tree.
7.13.3.1. The output's Substatements
+--------------+---------+-------------+ | substatement | section | cardinality | +--------------+---------+-------------+ | anyxml | 7.10 | 0..n | | choice | 7.9 | 0..n | | container | 7.5 | 0..n | | grouping | 7.11 | 0..n | | leaf | 7.6 | 0..n | | leaf-list | 7.7 | 0..n | | list | 7.8 | 0..n | | typedef | 7.3 | 0..n | | uses | 7.12 | 0..n | +--------------+---------+-------------+7.13.4. XML Mapping Rules
An rpc node is encoded as a child XML element to the <rpc> element defined in [RFC4741]. The element's local name is the rpc's identifier, and its namespace is the module's XML namespace (see Section 7.1.3). Input parameters are encoded as child XML elements to the rpc node's XML element, in the same order as they are defined within the "input" statement. If the RPC operation invocation succeeded, and no output parameters are returned, the <rpc-reply> contains a single <ok/> element defined in [RFC4741]. If output parameters are returned, they are encoded as child elements to the <rpc-reply> element defined in [RFC4741], in the same order as they are defined within the "output" statement.
7.13.5. Usage Example
The following example defines an RPC operation: module rock { namespace "http://example.net/rock"; prefix "rock"; rpc rock-the-house { input { leaf zip-code { type string; } } } } A corresponding XML instance example of the complete rpc and rpc- reply: <rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <rock-the-house xmlns="http://example.net/rock"> <zip-code>27606-0100</zip-code> </rock-the-house> </rpc> <rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <ok/> </rpc-reply>