In YANG, when two modules reuse one interface-counters grouping through uses, whose namespace do the nodes get, and what can refine change?
answer
- a template defines no data
- copy first, then adjust
- bound where placed
- names resolved where written
- properties, not the type
basics
~20 sIn YANG, uses copies a grouping's nodes into the schema tree where it appears, bound to that module's namespace; refine then adjusts properties such as default, description, config, mandatory, presence, must, element counts or if-feature, but never a node's type.
solid answer
~50 sA `grouping` is a reusable block of nodes that defines nothing in the schema tree by itself; `uses` copies its nodes to the point of use, then applies any `refine` and `augment`. Two scopes are easy to confuse. Identifiers inside the grouping — prefixes, type names, nested grouping names — resolve where the grouping is *defined*. The copied data nodes, though, bind to the namespace of the module whose `uses` places them, so one counters grouping used in two modules yields two distinct sets of nodes in two namespaces, each encoded as if defined inline. `refine` tailors one copy: a new `default`, `description` or `reference`, a different `config` or `mandatory`, `presence` on a container, extra `must` or `if-feature`, other `min-elements` or `max-elements`. It cannot change a node's type; that needs a different grouping or, in an implementation, a deviation.
code
yang · 12 linesgrouping if-counters {
leaf in-octets { type uint64; }
leaf out-octets { type uint64; }
}
container statistics {
config false;
uses if-counters {
refine in-octets {
description "Octets received, including framing.";
}
}
}go deeper
Recall that a grouping is a reusable block of nodes and that uses copies it into a module; the grouping alone defines no data.
Explain the steps of uses: copy, refine, bind to the using module's namespace, encode as if inline, and the error when copied names clash with siblings.
Show the scoping subtleties: names resolve where the grouping is defined, nodes bind where used, and refine adjusts properties but never types.
Weigh shared groupings across a model family: they keep definitions consistent, but every change to one ripples into every module that uses it.
## A grouping is a template, not data A **grouping** (RFC 7950 §7.12) is a named, reusable block of schema nodes — leafs, containers, lists, choices. It is **not a data definition statement**: on its own it adds nothing to the schema tree and nothing to any datastore. RFC 7950 likens it to a structure or record in a programming language. A grouping defined at the top level of a module can be used by other modules that import it; a grouping MUST NOT reference itself, directly or through a chain of other groupings. A router's interface model might define an `if-counters` grouping with `in-octets`, `out-octets` and `discontinuity-time`, then use it for physical interfaces, for sub-interfaces and in a separate module for tunnel endpoints. ## What uses does, step by step The **uses** statement (§7.13) references a grouping by name. Its effect: 1. The grouping's nodes are **copied** into the current schema tree at the place of the `uses`. 2. The copy is then **updated** by any `refine` statements, and by any `augment` statements under the `uses`, which add nodes and are a subject of their own. 3. If the `uses` is not itself inside another grouping, the copied identifiers are **bound to the namespace of the current module**. 4. In XML, each node is **encoded as if it were defined inline**, even when the grouping came from another module with another namespace. The copied nodes must not clash with sibling names: RFC 7950 shows that adding a leaf `ip` beside a `uses` that already brings in `ip` is an error. ## Two scopes: where names resolve, where nodes live | question | answered at | example | |---|---|---| | what does a prefix or type name inside the grouping mean? | where the grouping is **defined** | `inet:ip-address` refers to the defining module's import | | which namespace do the data nodes have? | where the `uses` **places** them | `in-octets` under module B's container is B's node | | how is the node encoded? | as if defined inline | an XML element in B's namespace | So if module A defines `if-counters` and modules B and C both use it, B and C each get their **own** `in-octets` node in their own namespace. They share a definition, not data; a change to one copy's refinements does not touch the other. ## What refine can change The **refine** statement (§7.13.2) targets one node of the copy by a descendant schema node identifier and may: - give a leaf or choice a default value, or a new one; - give a leaf-list a set of default values, replacing any it had; - give any node a specialised `description` or `reference`; - give any node a different `config` value; - give a leaf, anydata, anyxml or choice a different `mandatory`; - give a container a `presence` statement; - add `must` expressions to a leaf, leaf-list, list, container, anydata or anyxml; - give a list or leaf-list a different `min-elements` or `max-elements`; - add `if-feature` expressions to most kinds of node; - refine extensions that allow it. ## What refine cannot change The list has no entry for a node's **type** or its **kind**: refine cannot turn a `uint64` counter into a string, or a leaf into a leaf-list. A module that needs a different type needs a different grouping. A server that cannot implement a published model as written declares that with a deviation, which belongs to conformance, not to reuse. ## Design guidance from RFC 9907 RFC 9907, the YANG authoring guidelines (obsoleting RFC 8407), adds rules for **reusable groupings** meant for other modules: - state the grouping's purpose clearly in its `description`; - do not reference data outside the grouping in any `path`, `must` or `when`, because an XPath written for one context may not be portable to another; - do not put a `default` on a leaf or choice, or a `config` on a data node, unless the value applies in every context the grouping could be used in. That last rule is why refine exists: the grouping stays neutral, and each `uses` sets `config`, defaults and descriptions for its own context. An RFC 8340 tree diagram can show a `uses` unexpanded, as a `-u` line naming the grouping.
- Why should a reusable grouping avoid a config statement on its nodes?A grouping may be used under configuration in one module and under state in another. RFC 9907 says not to include `config` on a data node unless the value applies in every possible context. Left neutral, each copy inherits `config` from where `uses` places it, or a `refine` sets it for that use.
- If a grouping imported from module A is used inside a container of module B, which module's import does a type name inside the grouping resolve against?Module A's. RFC 7950 resolves identifiers inside a grouping in the scope where the grouping is defined: prefixes, type names, grouping names and extensions. Only the data nodes' namespace changes, binding to module B when B's `uses` places them, so those references keep A's meaning without B repeating A's imports.
saying these in an interview costs you the question
- A grouping creates data nodes in the module that defines it.
- Two modules using one grouping share the same data nodes and values.
- refine can change a copied leaf's type.
- Prefixes inside a grouping resolve against the module that uses it.
- uses is plain text substitution, with no scoping rules of its own.