4. YANG Overview
This non-normative section is intended to give a high-level overview of YANG to first-time readers.4.1. Functional Overview
YANG is a language originally designed to model data for the NETCONF protocol. A YANG module defines hierarchies of data that can be used for NETCONF-based operations, including configuration, state data, RPCs, and notifications. This allows a complete description of all data sent between a NETCONF client and server. Although out of scope for this specification, YANG can also be used with protocols other than NETCONF. YANG models the hierarchical organization of data as a tree in which each node has a name, and either a value or a set of child nodes. YANG provides clear and concise descriptions of the nodes, as well as the interaction between those nodes. YANG structures data models into modules and submodules. A module can import definitions from other external modules and can include definitions from submodules. The hierarchy can be augmented, allowing one module to add data nodes to the hierarchy defined in another module. This augmentation can be conditional, with new nodes appearing only if certain conditions are met. YANG data models can describe constraints to be enforced on the data, restricting the presence or value of nodes based on the presence or value of other nodes in the hierarchy. These constraints are enforceable by either the client or the server. YANG defines a set of built-in types and has a type mechanism through which additional types may be defined. Derived types can restrict their base type's set of valid values using mechanisms like range or pattern restrictions that can be enforced by clients or servers. They can also define usage conventions for use of the derived type, such as a string-based type that contains a hostname.
YANG permits the definition of reusable groupings of nodes. The usage of these groupings can refine or augment the nodes, allowing it to tailor the nodes to its particular needs. Derived types and groupings can be defined in one module and used in either the same module or another module that imports it. YANG data hierarchy constructs include defining lists where list entries are identified by keys that distinguish them from each other. Such lists may be defined as either sorted by user or automatically sorted by the system. For user-sorted lists, operations are defined for manipulating the order of the list entries. YANG modules can be translated into an equivalent XML syntax called YANG Independent Notation (YIN) (Section 13), allowing applications using XML parsers and Extensible Stylesheet Language Transformations (XSLT) scripts to operate on the models. The conversion from YANG to YIN is semantically lossless, so content in YIN can be round-tripped back into YANG. YANG is an extensible language, allowing extensions to be defined by standards bodies, vendors, and individuals. The statement syntax allows these extensions to coexist with standard YANG statements in a natural way, while extensions in a YANG module stand out sufficiently for the reader to notice them. YANG resists the tendency to solve all possible problems, limiting the problem space to allow expression of data models for network management protocols such as NETCONF, not arbitrary XML documents or arbitrary data models. To the extent possible, YANG maintains compatibility with the Simple Network Management Protocol's (SNMP's) SMIv2 (Structure of Management Information version 2 [RFC2578] [RFC2579]). SMIv2-based MIB modules can be automatically translated into YANG modules for read-only access [RFC6643]. However, YANG is not concerned with reverse translation from YANG to SMIv2.
4.2. Language Overview
This section introduces some important constructs used in YANG that will aid in the understanding of the language specifics in later sections.4.2.1. Modules and Submodules
YANG data models are defined in modules. A module contains a collection of related definitions. A module contains three types of statements: module header statements, "revision" statements, and definition statements. The module header statements describe the module and give information about the module itself, the "revision" statements give information about the history of the module, and the definition statements are the body of the module where the data model is defined. A server may implement a number of modules, allowing multiple views of the same data or multiple views of disjoint subsections of the server's data. Alternatively, the server may implement only one module that defines all available data. A module may have portions of its definitions separated into submodules, based on the needs of the module designer. The external view remains that of a single module, regardless of the presence or size of its submodules. The "import" statement allows a module or submodule to reference definitions defined in other modules. The "include" statement is used in a module to identify each submodule that belongs to it.
4.2.2. Data Modeling Basics
YANG defines four main types of data nodes for data modeling. In each of the following subsections, the examples show the YANG syntax as well as a corresponding XML encoding. The syntax of YANG statements is defined in Section 6.3.4.2.2.1. Leaf Nodes
A leaf instance contains simple data like an integer or a string. It has exactly one value of a particular type and no child nodes. YANG Example: leaf host-name { type string; description "Hostname for this system."; } XML Encoding Example: <host-name>my.example.com</host-name> The "leaf" statement is covered in Section 7.6.4.2.2.2. Leaf-List Nodes
A leaf-list defines a sequence of values of a particular type. YANG Example: leaf-list domain-search { type string; description "List of domain names to search."; } XML Encoding Example: <domain-search>high.example.com</domain-search> <domain-search>low.example.com</domain-search> <domain-search>everywhere.example.com</domain-search> The "leaf-list" statement is covered in Section 7.7.
4.2.2.3. Container Nodes
A container is used to group related nodes in a subtree. A container has only child nodes and no value. A container may contain any number of child nodes of any type (leafs, lists, containers, leaf-lists, actions, and notifications). YANG Example: container system { container login { leaf message { type string; description "Message given at start of login session."; } } } XML Encoding Example: <system> <login> <message>Good morning</message> </login> </system> The "container" statement is covered in Section 7.5.
4.2.2.4. List Nodes
A list defines a sequence of list entries. Each entry is like a container and is uniquely identified by the values of its key leafs if it has any key leafs defined. A list can define multiple key leafs and may contain any number of child nodes of any type (including leafs, lists, containers, etc.). YANG Example: list user { key "name"; leaf name { type string; } leaf full-name { type string; } leaf class { type string; } } XML Encoding Example: <user> <name>glocks</name> <full-name>Goldie Locks</full-name> <class>intruder</class> </user> <user> <name>snowey</name> <full-name>Snow White</full-name> <class>free-loader</class> </user> <user> <name>rzell</name> <full-name>Rapun Zell</full-name> <class>tower</class> </user> The "list" statement is covered in Section 7.8.
4.2.2.5. Example Module
These statements are combined to define the module: // Contents of "example-system.yang" module example-system { yang-version 1.1; namespace "urn:example:system"; prefix "sys"; organization "Example Inc."; contact "joe@example.com"; description "The module for entities implementing the Example system."; revision 2007-06-09 { description "Initial revision."; } container system { leaf host-name { type string; description "Hostname for this system."; } leaf-list domain-search { type string; description "List of domain names to search."; } container login { leaf message { type string; description "Message given at start of login session."; }
list user { key "name"; leaf name { type string; } leaf full-name { type string; } leaf class { type string; } } } } }4.2.3. Configuration and State Data
YANG can model state data, as well as configuration data, based on the "config" statement. When a node is tagged with "config false", its subhierarchy is flagged as state data. If it is tagged with "config true", its subhierarchy is flagged as configuration data. Parent containers, lists, and key leafs are reported also, giving the context for the state data. In this example, two leafs are defined for each interface, a configured speed and an observed speed. list interface { key "name"; config true; leaf name { type string; } leaf speed { type enumeration { enum 10m; enum 100m; enum auto; } } leaf observed-speed { type uint32; config false; } }
The "config" statement is covered in Section 7.21.1.4.2.4. Built-In Types
YANG has a set of built-in types, similar to those of many programming languages, but with some differences due to special requirements of network management. The following table summarizes the built-in types discussed in Section 9: +---------------------+-------------------------------------+ | Name | Description | +---------------------+-------------------------------------+ | binary | Any binary data | | bits | A set of bits or flags | | boolean | "true" or "false" | | decimal64 | 64-bit signed decimal number | | empty | A leaf that does not have any value | | enumeration | One of an enumerated set of strings | | identityref | A reference to an abstract identity | | instance-identifier | A reference to a data tree node | | int8 | 8-bit signed integer | | int16 | 16-bit signed integer | | int32 | 32-bit signed integer | | int64 | 64-bit signed integer | | leafref | A reference to a leaf instance | | string | A character string | | uint8 | 8-bit unsigned integer | | uint16 | 16-bit unsigned integer | | uint32 | 32-bit unsigned integer | | uint64 | 64-bit unsigned integer | | union | Choice of member types | +---------------------+-------------------------------------+ The "type" statement is covered in Section 7.4.
4.2.5. Derived Types (typedef)
YANG can define derived types from base types using the "typedef" statement. A base type can be either a built-in type or a derived type, allowing a hierarchy of derived types. A derived type can be used as the argument for the "type" statement. YANG Example: typedef percent { type uint8 { range "0 .. 100"; } } leaf completed { type percent; } XML Encoding Example: <completed>20</completed> The "typedef" statement is covered in Section 7.3.4.2.6. Reusable Node Groups (grouping)
Groups of nodes can be assembled into reusable collections using the "grouping" statement. A grouping defines a set of nodes that are instantiated with the "uses" statement. YANG Example: grouping target { leaf address { type inet:ip-address; description "Target IP address."; } leaf port { type inet:port-number; description "Target port number."; } }
container peer { container destination { uses target; } } XML Encoding Example: <peer> <destination> <address>2001:db8::2</address> <port>830</port> </destination> </peer> The grouping can be refined as it is used, allowing certain statements to be overridden. In this example, the description is refined: container connection { container source { uses target { refine "address" { description "Source IP address."; } refine "port" { description "Source port number."; } } } container destination { uses target { refine "address" { description "Destination IP address."; } refine "port" { description "Destination port number."; } } } } The "grouping" statement is covered in Section 7.12.
4.2.7. Choices
YANG allows the data model to segregate incompatible nodes into distinct choices using the "choice" and "case" statements. The "choice" statement contains a set of "case" statements that define sets of schema nodes that cannot appear together. Each "case" may contain multiple nodes, but each node may appear in only one "case" under a "choice". The choice and case nodes appear only in the schema tree and not in the data tree. The additional levels of hierarchy are not needed beyond the conceptual schema. The presence of a case is indicated by the presence of one or more of the nodes within it. Since only one of the choice's cases can be valid at any time, when a node from one case is created in the data tree, all nodes from all other cases are implicitly deleted. The server handles the enforcement of the constraint, preventing incompatibilities from existing in the configuration. YANG Example: container food { choice snack { case sports-arena { leaf pretzel { type empty; } leaf beer { type empty; } } case late-night { leaf chocolate { type enumeration { enum dark; enum milk; enum first-available; } } } } }
XML Encoding Example: <food> <pretzel/> <beer/> </food> The "choice" statement is covered in Section 7.9.4.2.8. Extending Data Models (augment)
YANG allows a module to insert additional nodes into data models, including both the current module (and its submodules) and an external module. This is useful, for example, for vendors to add vendor-specific parameters to standard data models in an interoperable way. The "augment" statement defines the location in the data model hierarchy where new nodes are inserted, and the "when" statement defines the conditions when the new nodes are valid. When a server implements a module containing an "augment" statement, that implies that the server's implementation of the augmented module contains the additional nodes. YANG Example: augment /system/login/user { when "class != 'wheel'"; leaf uid { type uint16 { range "1000 .. 30000"; } } } This example defines a "uid" node that is valid only when the user's "class" is not "wheel".
If a module augments another module, the XML elements that are added to the encoding are in the namespace of the augmenting module. For example, if the above augmentation were in a module with prefix "other", the XML would look like: XML Encoding Example: <user> <name>alicew</name> <full-name>Alice N. Wonderland</full-name> <class>drop-out</class> <other:uid>1024</other:uid> </user> The "augment" statement is covered in Section 7.17.4.2.9. Operation Definitions
YANG allows the definition of operations. The operations' names, input parameters, and output parameters are modeled using YANG data definition statements. Operations on the top level in a module are defined with the "rpc" statement. Operations can also be tied to a container or list data node. Such operations are defined with the "action" statement. YANG Example for an operation at the top level: rpc activate-software-image { input { leaf image-name { type string; } } output { leaf status { type string; } } }
NETCONF XML Example: <rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <activate-software-image xmlns="http://example.com/system"> <image-name>example-fw-2.3</image-name> </activate-software-image> </rpc> <rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <status xmlns="http://example.com/system"> The image example-fw-2.3 is being installed. </status> </rpc-reply> YANG Example for an operation tied to a list data node: list interface { key "name"; leaf name { type string; } action ping { input { leaf destination { type inet:ip-address; } } output { leaf packet-loss { type uint8; } } } }
NETCONF XML Example: <rpc message-id="102" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <action xmlns="urn:ietf:params:xml:ns:yang:1"> <interface xmlns="http://example.com/system"> <name>eth1</name> <ping> <destination>192.0.2.1</destination> </ping> </interface> </action> </rpc> <rpc-reply message-id="102" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:sys="http://example.com/system"> <sys:packet-loss>60</sys:packet-loss> </rpc-reply> The "rpc" statement is covered in Section 7.14, and the "action" statement is covered in Section 7.15.4.2.10. Notification Definitions
YANG allows the definition of notifications. YANG data definition statements are used to model the content of the notification. YANG Example: notification link-failure { description "A link failure has been detected."; leaf if-name { type leafref { path "/interface/name"; } } leaf if-admin-status { type admin-status; } leaf if-oper-status { type oper-status; } }
NETCONF XML Example: <notification xmlns="urn:ietf:params:netconf:capability:notification:1.0"> <eventTime>2007-09-01T10:00:00Z</eventTime> <link-failure xmlns="urn:example:system"> <if-name>so-1/2/3.0</if-name> <if-admin-status>up</if-admin-status> <if-oper-status>down</if-oper-status> </link-failure> </notification> The "notification" statement is covered in Section 7.16.5. Language Concepts
5.1. Modules and Submodules
The module is the base unit of definition in YANG. A module defines a single data model. A module can also augment an existing data model with additional nodes. Submodules are partial modules that contribute definitions to a module. A module may include any number of submodules, but each submodule may belong to only one module. Developers of YANG modules and submodules are RECOMMENDED to choose names for their modules that will have a low probability of colliding with standard or other enterprise modules, e.g., by using the enterprise or organization name as a prefix for the module name. Within a server, all module names MUST be unique. A module uses the "include" statement to list all its submodules. A module, or submodule belonging to that module, can reference definitions in the module and all submodules included by the module. A module or submodule uses the "import" statement to reference external modules. Statements in the module or submodule can reference definitions in the external module using the prefix specified in the "import" statement. For backward compatibility with YANG version 1, a submodule MAY use the "include" statement to reference other submodules within its module, but this is not necessary in YANG version 1.1. A submodule can reference any definition in the module it belongs to and in all submodules included by the module. A submodule MUST NOT include different revisions of other submodules than the revisions that its module includes.
A module or submodule MUST NOT include submodules from other modules, and a submodule MUST NOT import its own module. The "import" and "include" statements are used to make definitions available from other modules: o For a module or submodule to reference definitions in an external module, the external module MUST be imported. o A module MUST include all its submodules. o A module, or submodule belonging to that module, MAY reference definitions in the module and all submodules included by the module. There MUST NOT be any circular chains of imports. For example, if module "a" imports module "b", "b" cannot import "a". When a definition in an external module is referenced, a locally defined prefix MUST be used, followed by a colon (":") and then the external identifier. References to definitions in the local module MAY use the prefix notation. Since built-in data types do not belong to any module and have no prefix, references to built-in data types (e.g., int32) cannot use the prefix notation. The syntax for a reference to a definition is formally defined by the rule "identifier-ref" in Section 14.5.1.1. Import and Include by Revision
Published modules evolve independently over time. In order to allow for this evolution, modules can be imported using specific revisions. Initially, a module imports the revisions of other modules that are current when the module is written. As future revisions of the imported modules are published, the importing module is unaffected and its contents are unchanged. When the author of the module is prepared to move to the most recently published revision of an imported module, the module is republished with an updated "import" statement. By republishing with the new revision, the authors explicitly indicate their acceptance of any changes in the imported module. For submodules, the issue is related but simpler. A module or submodule that includes submodules may specify the revision of the included submodules. If a submodule changes, any module or submodule that includes it by revision needs to be updated to reference the new revision.
For example, module "b" imports module "a". module a { yang-version 1.1; namespace "urn:example:a"; prefix "a"; revision 2008-01-01 { ... } grouping a { leaf eh { .... } } } module b { yang-version 1.1; namespace "urn:example:b"; prefix "b"; import a { prefix "p"; revision-date 2008-01-01; } container bee { uses p:a; } } When the author of "a" publishes a new revision, the changes may not be acceptable to the author of "b". If the new revision is acceptable, the author of "b" can republish with an updated revision in the "import" statement. If a module is not imported with a specific revision, it is undefined which revision is used.5.1.2. Module Hierarchies
YANG allows modeling of data in multiple hierarchies, where data may have more than one top-level node. Each top-level data node in a module defines a separate hierarchy. Models that have multiple top-level nodes are sometimes convenient and are supported by YANG.
5.1.2.1. NETCONF XML Encoding
NETCONF is capable of carrying any XML content as the payload in the <config> and <data> elements. The top-level nodes of YANG modules are encoded as child elements, in any order, within these elements. This encapsulation guarantees that the corresponding NETCONF messages are always well-formed XML documents. For example, an instance of: module example-config { yang-version 1.1; namespace "urn:example:config"; prefix "co"; container system { ... } container routing { ... } } could be encoded in NETCONF as: <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"> <!-- system data here --> </system> <routing xmlns="urn:example:config"> <!-- routing data here --> </routing> </config> </edit-config> </rpc>
5.2. File Layout
YANG modules and submodules are typically stored in files, one "module" or "submodule" statement per file. The name of the file SHOULD be of the form: module-or-submodule-name ['@' revision-date] ( '.yang' / '.yin' ) "module-or-submodule-name" is the name of the module or submodule, and the optional "revision-date" is the latest revision of the module or submodule, as defined by the "revision" statement (Section 7.1.9). The file extension ".yang" denotes that the contents of the file are written with YANG syntax (Section 6), and ".yin" denotes that the contents of the file are written with YIN syntax (Section 13). YANG parsers can find imported modules and included submodules via this convention.5.3. XML Namespaces
All YANG definitions are specified within a module. Each module is bound to a distinct XML namespace [XML-NAMES], which is a globally unique URI [RFC3986]. A NETCONF client or server uses the namespace during XML encoding of data. XML namespaces for modules published in RFC streams [RFC4844] MUST be assigned by IANA; see Section 14 in [RFC6020]. XML namespaces for private modules are assigned by the organization owning the module without a central registry. Namespace URIs MUST be chosen so they cannot collide with standard or other enterprise namespaces -- for example, by using the enterprise or organization name in the namespace. The "namespace" statement is covered in Section 7.1.3.5.3.1. YANG XML Namespace
YANG defines an XML namespace for NETCONF <edit-config> operations, <error-info> content, and the <action> element. The name of this namespace is "urn:ietf:params:xml:ns:yang:1".
5.4. Resolving Grouping, Type, and Identity Names
Grouping, type, and identity names are resolved in the context in which they are defined, rather than the context in which they are used. Users of groupings, typedefs, and identities are not required to import modules or include submodules to satisfy all references made by the original definition. This behaves like static scoping in a conventional programming language. For example, if a module defines a grouping in which a type is referenced, when the grouping is used in a second module, the type is resolved in the context of the original module, not the second module. There is no ambiguity if both modules define the type.5.5. Nested Typedefs and Groupings
Typedefs and groupings may appear nested under many YANG statements, allowing these to be lexically scoped by the statement hierarchy under which they appear. This allows types and groupings to be defined near where they are used, rather than placing them at the top level of the hierarchy. The close proximity increases readability. Scoping also allows types to be defined without concern for naming conflicts between types in different submodules. Type names can be specified without adding leading strings designed to prevent name collisions within large modules. Finally, scoping allows the module author to keep types and groupings private to their module or submodule, preventing their reuse. Since only top-level types and groupings (i.e., those appearing as substatements to a "module" or "submodule" statement) can be used outside the module or submodule, the developer has more control over what pieces of their module are presented to the outside world, supporting the need to hide internal information and maintaining a boundary between what is shared with the outside world and what is kept private. Scoped definitions MUST NOT shadow definitions at a higher scope. A type or grouping cannot be defined if a higher level in the statement hierarchy has a definition with a matching identifier. A reference to an unprefixed type or grouping, or one that uses the prefix of the current module, is resolved by locating the matching "typedef" or "grouping" statement among the immediate substatements of each ancestor statement.
5.6. Conformance
Conformance to a model is a measure of how accurately a server follows the model. Generally speaking, servers are responsible for implementing the model faithfully, allowing applications to treat servers that implement the model identically. Deviations from the model can reduce the utility of the model and increase the fragility of applications that use it. YANG modelers have three mechanisms for conformance: o the basic behavior of the model o optional features that are part of the model o deviations from the model We will consider each of these in sequence.5.6.1. Basic Behavior
The model defines a contract between a YANG-based client and server; this contract allows both parties to have faith that the other knows the syntax and semantics behind the modeled data. The strength of YANG lies in the strength of this contract.5.6.2. Optional Features
In many models, the modeler will allow sections of the model to be conditional. The server controls whether these conditional portions of the model are supported or valid for that particular server. For example, a syslog data model may choose to include the ability to save logs locally, but the modeler will realize that this is only possible if the server has local storage. If there is no local storage, an application should not tell the server to save logs. YANG supports this conditional mechanism using a construct called "feature". Features give the modeler a mechanism for making portions of the module conditional in a manner that is controlled by the server. The model can express constructs that are not universally present in all servers. These features are included in the model definition, allowing a consistent view and allowing applications to learn which features are supported and tailor their behavior to the server.
A module may declare any number of features, identified by simple strings, and may make portions of the module optional based on those features. If the server supports a feature, then the corresponding portions of the module are valid for that server. If the server doesn't support the feature, those parts of the module are not valid, and applications should behave accordingly. Features are defined using the "feature" statement. Definitions in the module that are conditional to the feature are noted by the "if-feature" statement. Further details are available in Section 7.20.1.5.6.3. Deviations
In an ideal world, all servers would be required to implement the model exactly as defined, and deviations from the model would not be allowed. But in the real world, servers are often not able or designed to implement the model as written. For YANG-based automation to deal with these server deviations, a mechanism must exist for servers to inform applications of the specifics of such deviations. For example, a BGP module may allow any number of BGP peers, but a particular server may only support 16 BGP peers. Any application configuring the 17th peer will receive an error. While an error may suffice to let the application know it cannot add another peer, it would be far better if the application had prior knowledge of this limitation and could prevent the user from starting down the path that could not succeed. Server deviations are declared using the "deviation" statement, which takes as its argument a string that identifies a node in the schema tree. The contents of the statement detail the manner in which the server implementation deviates from the contract as defined in the module. Further details are available in Section 7.20.3.
5.6.4. Announcing Conformance Information in NETCONF
This document defines the following mechanism for announcing conformance information. Other mechanisms may be defined by future specifications. A NETCONF server MUST announce the modules it implements (see Section 5.6.5) by implementing the YANG module "ietf-yang-library" defined in [RFC7895] and listing all implemented modules in the "/modules-state/module" list. The server also MUST advertise the following capability in the <hello> message (line breaks and whitespaces are used for formatting reasons only): urn:ietf:params:netconf:capability:yang-library:1.0? revision=<date>&module-set-id=<id> The parameter "revision" has the same value as the revision date of the "ietf-yang-library" module implemented by the server. This parameter MUST be present. The parameter "module-set-id" has the same value as the leaf "/modules-state/module-set-id" from "ietf-yang-library". This parameter MUST be present. With this mechanism, a client can cache the supported modules for a server and only update the cache if the "module-set-id" value in the <hello> message changes.5.6.5. Implementing a Module
A server implements a module if it implements the module's data nodes, RPCs, actions, notifications, and deviations. A server MUST NOT implement more than one revision of a module. If a server implements a module A that imports a module B, and A uses any node from B in an "augment" or "path" statement that the server supports, then the server MUST implement a revision of module B that has these nodes defined. This is regardless of whether module B is imported by revision or not.
If a server implements a module A that imports a module C without specifying the revision date of module C and the server does not implement C (e.g., if C only defines some typedefs), the server MUST list module C in the "/modules-state/module" list from "ietf-yang-library" [RFC7895], and it MUST set the leaf "conformance-type" to "import" for this module. If a server lists a module C in the "/modules-state/module" list from "ietf-yang-library" and there are other modules Ms listed that import C without specifying the revision date of module C, the server MUST use the definitions from the most recent revision of C listed for modules Ms. The reason for these rules is that clients need to be able to know the specific data model structure and types of all leafs and leaf-lists implemented in a server. For example, with these modules: module a { yang-version 1.1; namespace "urn:example:a"; prefix "a"; import b { revision-date 2015-01-01; } import c; revision 2015-01-01; feature foo; augment "/b:x" { if-feature foo; leaf y { type b:myenum; } } container a { leaf x { type c:bar; } } }
module b { yang-version 1.1; namespace "urn:example:b"; prefix "b"; revision 2015-01-01; typedef myenum { type enumeration { enum zero; } } container x { } } module b { yang-version 1.1; namespace "urn:example:b"; prefix "b"; revision 2015-04-04; revision 2015-01-01; typedef myenum { type enumeration { enum zero; // added in 2015-01-01 enum one; // added in 2015-04-04 } } container x { // added in 2015-01-01 container y; // added in 2015-04-04 } } module c { yang-version 1.1; namespace "urn:example:c"; prefix "c"; revision 2015-02-02; typedef bar { ... } }
module c { yang-version 1.1; namespace "urn:example:c"; prefix "c"; revision 2015-03-03; revision 2015-02-02; typedef bar { ... } } A server that implements revision "2015-01-01" of module "a" and supports feature "foo" can implement revision "2015-01-01" or "2015-04-04" of module "b". Since "b" was imported by revision, the type of leaf "/b:x/a:y" is the same, regardless of which revision of "b" the server implements. A server that implements module "a" but does not support feature "foo" does not have to implement module "b". A server that implements revision "2015-01-01" of module "a" picks any revision of module "c" and lists it in the "/modules-state/module" list from "ietf-yang-library". The following XML encoding example shows valid data for the "/modules-state/module" list for a server that implements module "a": <modules-state xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library"> <module-set-id>ee1ecb017370cafd</module-set-id> <module> <name>a</name> <revision>2015-01-01</revision> <namespace>urn:example:a</namespace> <feature>foo</feature> <conformance-type>implement</conformance-type> </module> <module> <name>b</name> <revision>2015-04-04</revision> <namespace>urn:example:b</namespace> <conformance-type>implement</conformance-type> </module>
<module> <name>c</name> <revision>2015-02-02</revision> <namespace>urn:example:c</namespace> <conformance-type>import</conformance-type> </module> </modules-state>5.7. Datastore Modification
Data models may allow the server to alter the configuration datastore in ways not explicitly directed via network management protocol messages. For example, a data model may define leafs that are assigned system-generated values when the client does not provide one. A formal mechanism for specifying the circumstances where these changes are allowed is out of scope for this specification.