Internet-Draft template May 2025
Ma, et al. Expires 29 November 2025 [Page]
Workgroup:
Network Modeling
Internet-Draft:
draft-xxx-netmod-yang-config-template-latest
Published:
Intended Status:
Standards Track
Expires:
Authors:
Q. Ma, Ed.
Huawei
R. Wills, Ed.
Cisco
D. Rajaram, Ed.
Nokia

YANG Templates

Abstract

NETCONF and RESTCONF protocols provide programmatic operation interfaces for accessing configuration data modeled by YANG. This document defines the use of YANG-based configuration template mechanism so that the configuration data could be defined as template and applied repeatedly to avoid the redundant definition of identical Configuration and ensure the consistency of it. This approach is convenient and efficient, because it minimizes duplication in the running datastore.

Discussion Venues

This note is to be removed before publishing as an RFC.

Discussion of this document takes place on the Network Modeling Working Group mailing list (netmod@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/netmod/.

Source for this draft and an issue tracker can be found at https://github.com/QiufangMa/template-mechanism.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 29 November 2025.

Table of Contents

1. Introduction

This document considers the case of a datastore that contains multiple subtrees with similar or identical nodes within them, such that the datastore contains repetitive data with limited variation. If a client has to repeatedly configure the same nodes for each subtree, this can become complex, error-prone, and mask the intent of the client.

This document proposes a solution to improve this, called "YANG templates", that results in a smaller running datastore even when the configuration in <running> is large.

A 'YANG template' is a fragment of configuration that the device is instructed to replicate multiple times to generate copies of the configuration. This allows repetitive subtrees of configuration to be written only once, in the template. Individual instantiations of a template can override the values of nodes where this is required, or add new instance-specific nodes.

NMDA [RFC8342] allows the configuration templates to be defined in <running> and expanded in <intended>, but it does not specify details about how configuration templates could be created and applied.

This document defines the use of configuration templates in the context of YANG-driven network management protocols such as NETCONF [RFC6241] and RESTCONF [RFC8040]. Configuration template could be used based on any existing YANG data models, this document doesn't make any assumption on the YANG data model design, i.e., it does not rely on the shared profile/group defined in the YANG data model.

1.1. Editorial Note (To be removed by RFC Editor)

Note to the RFC Editor: This section is to be removed prior to publication.

This document contains placeholder values that need to be replaced with finalized values at the time of publication. This note summarizes all of the substitutions that are needed. No other RFC Editor instructions are specified elsewhere in this document.

Please apply the following replacements:

  • XXXX --> the assigned RFC number for this draft

  • 2025-05-28 --> the actual date of the publication of this document

2. Conventions and Definitions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

The meanings of the symbols in tree diagrams are defined in [RFC8340].

This document uses the YANG terminology defined in Section 3 of [RFC7950].

Besides, this document defines the following terminology:

configuration template:

A chunk of reusable configuration data that could be applied to the configuration repeatedly, in order to simplify the delivery of network configuration and ensure the consistency of it. A configuration template may also be called "template" or "YANG template" throughout this document.

3. Requirements

This section describes the requirements that the YANG Templates solution must satisfy. These requirements were all discussed in the Interim Meetings, and a rough consensus was reached on each of them by the participants in the meetings. A general theme of the YANG Templates work is to come up with a "Minimal Viable Product" that is useful but not over-complicated. More advanced features could be considered as extensions in later drafts.

3.1. Defining and Managing Templates

Templates can be used with any YANG module. They contain nodes of configuration data, and are stored persistently in the running datastore of the device.

A client can view and manipulate a template, including the configuration inside it, by manipulating it in the <running> datastore. In this sense, a template and its contents behaves like any other subtree of configuration.

3.2. Applying Templates

A template can be applied to zero or more nodes in the <running> datastore. Each node can have zero or more templates applied to it, and the order they are applied is specified by the client. The order is important when determining the final intended configuration -- see the next section.

Templates can be applied at multiple points in the hierachy. The next section states the requirements when a node applies a template and it has an ancestor that also applies a template.

When viewing the <running> datastore, there is a mechanism to see which templates have been applied to each node, and in which order.

3.3. Producing the Intended Datastore

The device's <intended> datastore is the result of combining all the applications of templates together with non-template config. This is called "expanding out" the templates.

The intended configuration inside a subtree is the result of taking the relevant contents of every template applied to the subtree's root node and its ancestors, and combining it with the (non-template) data nodes inside the subtree.

A node inside a subtree may be present in multiple templates that have been applied, and/or it may be present as non-template config inside the subtree. The requirements for combining the templates and the non-template config together are as follows:

  • The value of a node in the <intended> configuration is determined by using precedence to decide where to take the value from.

  • Non-template config always has the highest precedence.

  • When templates are applied to multiple ancestors, the innermost ancestor takes precedence.

  • When multiple templates are applied to a particular node, the order of application (as indicated by the client when applying the templates) determines the precedence within that node.

Whenever the contents of a template is updated in <running>, the result of expanding out the template appears in <intended> and takes effect on the device.

3.4. Pattern Matching in Templates

The configuration inside a template definition can contain values for list keys that are simple regular expressions, using a limited subset of regular expression syntax. This controls which list entries that subtree of the template takes effect for when it is applied.

An example of this would be to have a template that is applied to a top-level "interfaces" container, but the template only takes effect for certain interface names that match the regular expression.

3.5. Off-box Template Expansion

If the client knows the contents of the <running> datastore (non- template config, template definitions and template applications), it must be possible for the client to calculate the result of template expansion.

In other words, the outcome of template expansion depends solely on the <running> datastore and not the state of the device.

4. YANG Template Solution

4.1. Defining Templates

A configuration template must first be defined before it can be applied Section 4.2. The creation, modification, and deletion of configuration templates are achieved by network management operations via NETCONF or RESTCONF protocols. The content of the configuration template must be an instantiated chunk of data starting from any level node in the module hierarchies.

The YANG data model of configuration templates is defined in Section 7.

4.1.1. Templates with Regular Expressions

TBC

For example, Figure 1 provides an interface configuration template that sets "type" as ethernetCsmacd and "mtu" as 1500 for interfaces named with the prefix "Ethernet":

<templates xmlns="urn:ietf:params:xml:ns:yang:ietf-config-template">
  <template>
    <id>ethernet-interface</id>
    <content>
      <interfaces xmlns="urn:example:interface">
        <interface>
          <name>^eth</name>
          <type>ethernetCsmacd</type>
          <mtu>1500</mtu>
          <description>template-set type and mtu for ethernet</description>
        </interface>
      </interfaces>
    </content>
  </template>
</templates>
Figure 1: Example of An Interface template

4.2. Applying Templates

One or more templates can be applied by configuration nodes explicitly provided by the client in the data tree at corresponding level.

If a configuration template is applied by a node in the data tree, it acts as if the configuration defined in the template is contained and is merged with the configuration provided explicitly at the corresponding level in the data tree with the explicitly provided configuration takes precedence.

Any modification to the YANG templates also applies where the template is applied.

4.2.1. The "apply-templates" Metadata

Template application is indicated by declaring the metadata object called "apply-templates" with the value of one or more space-seperated template identifiers. If the template is applied by a node in the data tree, the metadata object is added to that specific node.

The encoding of "apply-templates" metadata object follows the way defined in Section 5 of [RFC7952].

For example, the following interface configuration may be provided with the container node "interfaces" applying the template defined in Figure 1:

<interfaces xmlns="urn:example:interface"
  xmlns:ct="urn:ietf:params:xml:ns:yang:ietf-config-template"
  ct:apply-templates="ethernet-interface">
  <interface>
    <name>loopback0</name>
  <interface>
    <name>eth0</name>
  </interface>
  <interface>
    <name>eth1</name>
  </interface>
</interfaces>

And the above interface configuration renders the following expanded configuration:

<interfaces xmlns="urn:example:interface">
  <interface>
    <name>loopback0</name>
  <interface>
    <name>eth0</name>
    <type>ethernetCsmacd</type>
    <mtu>1500</mtu>
    <description>template-set type and mtu for ethernet</description>
  </interface>
  <interface>
    <name>eth1</name>
    <type>ethernetCsmacd</type>
    <mtu>1500</mtu>
    <description>template-set type and mtu for ethernet</description>
  </interface>
</interfaces>

4.3. Overriding Templates

It may be desired to override some configuration in a template when it is applied. This may be achieved by directly editing the applied configuration template, however, the applied template may have also been applied by other instance, and direct modification of the template may yield unexpected results.

This document allows a configuration template to be overridden by configuration explicitly provided by the client.If there is some configuration values that need to be modified, the desired value can be provided at the corresponding level when applying the configuation template. Configuration explicitly provided by the client always takes precedence over the same node defined in template.

For example, a client may configure physically present interfaces "eth0" and "eth1" inheriting the template defined in Figure 1, but the "mtu" value of "eth1" needs to be 9122, and the "description" value also needs to be modified accordingly:

<interfaces xmlns="urn:example:interface"
  xmlns:ct="urn:ietf:params:xml:ns:yang:ietf-config-template"
  ct:apply-templates="ethernet-interface">
  <interface>
    <name>loopback0</name>
  <interface>
    <name>eth0</name>
  </interface>
  <interface>
    <name>eth1</name>
    <mtu>9122</mtu>
    <description>MTU value is set explicitly</description>
  </interface>
</interfaces>

And the above interface configuration renders the following expanded configuration:

<interfaces xmlns="urn:example:interface">
  <interface>
    <name>loopback0</name>
  <interface>
    <name>eth0</name>
    <type>ethernetCsmacd</type>
    <mtu>1500</mtu>
    <description>template-set type and mtu for ethernet</description>
  </interface>
  <interface>
    <name>eth1</name>
    <type>ethernetCsmacd</type>
    <mtu>9122</mtu>
    <description>MTU value is set explicitly</description>
  </interface>
</interfaces>

4.5. Validity of Templates

The contents of the template alone is not always sufficient to enforce the constraints of the data model. Some constraints may depend on configuration outside of the templates to satisfy, e.g., a list may contain a mandatory leaf node which is not defined in the template but explicitly provided by the client. However, servers should parse the template and enforce the constraints if it is possible during the processing of template creation, e.g., servers may validate type constraints for the leaf, including those defined in the type's "range", "length", and "pattern" properties.

That said, if a template is applied in the configuration data tree, the results of the template configuration merging with configuration explicitly provided by the client MUST always be valid, as defined in Section 8.1 of [RFC7950].

5. Interaction with NMDA datastores

Some implementation may have predefined configuration templates for the convenience of clients, which are present in <system> (if implemented, see [I-D.ietf-netmod-system-config]). In addition, clients can always define their own templates in <running>. However, configuration template data defined by "ietf-template" YANG data model should not be visible in <operational> until being inherited by a node in the data tree.

If a node in the data tree inherits a configuration template, the configuration template does not expand in <running>, a read back of <running> returns what is sent by the client with the "stmt-extend" metadata attached to the specific node. Configuration template which is inherited or overridden by the node instance MUST be expanded in <intended>.

6. Interaction with Non-NMDA datastores

TBC

7. The "ietf-config-template" YANG Module

7.1. Data Model Overview

The following tree diagram [RFC8340] illustrates the "ietf-config-template" module:

module: ietf-config-template
  +--rw templates
     +--rw template* [id]
        +--rw id               string
        +--rw description?     string
        +--rw content?         <anydata>
        +--ro last-modified?   yang:timestamp
  • Editor's Note: Should we use the RFC7952 metadata annotation for the 'apply-templates' metadata here?

  • Editor's Note: the current definition of template configuration uses anydata, but this may not be able to be validated at template definition time because anydata is opaque.

7.2. YANG Module

<CODE BEGINS> file "ietf-template@2025-05-28.yang"

module ietf-config-template {
  yang-version 1.1;
  namespace "urn:ietf:params:xml:ns:yang:ietf-config-template";
  prefix ct;

  import ietf-yang-types {
    prefix yang;
    reference
      "RFC 6991: Common YANG Data Types";
  }

  organization
    "IETF NETMOD (Network Modeling) Working Group";
  contact
    "WG Web:   <https://datatracker.ietf.org/wg/netmod/>
     WG List:  <mailto:netmod@ietf.org>
     Author: Qiufang Ma
             <mailto:maqiufang1@huawei.com>";

  description
    "This module defines a template list with a RPC to expand
     the template.

     Copyright (c) 2025 IETF Trust and the persons identified
     as authors of the code. All rights reserved.

     Redistribution and use in source and binary forms, with
     or without modification, is permitted pursuant to, and
     subject to the license terms contained in, the Revised
     BSD License set forth in Section 4.c of the IETF Trust's
     Legal Provisions Relating to IETF Documents
     (https://trustee.ietf.org/license-info).

     This version of this YANG module is part of RFC XXXX
     (https://www.rfc-editor.org/info/rfcXXXX); see the RFC
     itself for full legal notices.

     The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL',
     'SHALL NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED',
     'NOT RECOMMENDED', 'MAY', and 'OPTIONAL' in this document
     are to be interpreted as described in BCP 14 (RFC 2119)
     (RFC 8174) when, and only when, they appear in all
     capitals, as shown here.";

   revision 2025-05-28 {
     description
       "Initial revision.";
     reference
       "RFC XXXX: YANG Templates";
   }

   container templates {
     description
       "Specifies the template parameters.";
     list template {
       key id;
       description
         "The list of templates managed on this device.";
       leaf id {
         type string;
         description
           "The identifier of the template that uniquely identifies a
            template.";
       }
       leaf description {
         type string;
         description
           "A textual description of the template.";
       }
       anydata content {
         description
           "inline template content.";
       }
       leaf last-modified {
         type yang:timestamp;
         config false;
         description
           "Timestamp when the template is modified last time.";
       }
     }
   }
}

<CODE ENDS>

8. Security Considerations

TODO Security

9. IANA Considerations

9.1. The "IETF XML" Registry

This document registers the following URI in the "IETF XML Registry" [RFC3688].

        URI: urn:ietf:params:xml:ns:yang:ietf-config-template
        Registrant Contact: The IESG.
        XML: N/A, the requested URI is an XML namespace.

9.2. The "YANG Module Names" Registry

This document registers the following YANG module in the "YANG Module Names" registry [RFC6020].

        name:               ietf-config-template
        namespace:          urn:ietf:params:xml:ns:yang:ietf-config-template
        prefix:             ct
        maintained by IANA? N
        reference:          RFC XXXX

10. References

10.1. Normative References

[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/rfc/rfc2119>.
[RFC3688]
Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688, DOI 10.17487/RFC3688, , <https://www.rfc-editor.org/rfc/rfc3688>.
[RFC6020]
Bjorklund, M., Ed., "YANG - A Data Modeling Language for the Network Configuration Protocol (NETCONF)", RFC 6020, DOI 10.17487/RFC6020, , <https://www.rfc-editor.org/rfc/rfc6020>.
[RFC6241]
Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed., and A. Bierman, Ed., "Network Configuration Protocol (NETCONF)", RFC 6241, DOI 10.17487/RFC6241, , <https://www.rfc-editor.org/rfc/rfc6241>.
[RFC7950]
Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language", RFC 7950, DOI 10.17487/RFC7950, , <https://www.rfc-editor.org/rfc/rfc7950>.
[RFC8040]
Bierman, A., Bjorklund, M., and K. Watsen, "RESTCONF Protocol", RFC 8040, DOI 10.17487/RFC8040, , <https://www.rfc-editor.org/rfc/rfc8040>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/rfc/rfc8174>.

10.2. Informative References

[I-D.ietf-netmod-system-config]
Ma, Q., Wu, Q., and C. Feng, "System-defined Configuration", Work in Progress, Internet-Draft, draft-ietf-netmod-system-config-12, , <https://datatracker.ietf.org/doc/html/draft-ietf-netmod-system-config-12>.
[RFC7952]
Lhotka, L., "Defining and Using Metadata with YANG", RFC 7952, DOI 10.17487/RFC7952, , <https://www.rfc-editor.org/rfc/rfc7952>.
[RFC8340]
Bjorklund, M. and L. Berger, Ed., "YANG Tree Diagrams", BCP 215, RFC 8340, DOI 10.17487/RFC8340, , <https://www.rfc-editor.org/rfc/rfc8340>.
[RFC8342]
Bjorklund, M., Schoenwaelder, J., Shafer, P., Watsen, K., and R. Wilton, "Network Management Datastore Architecture (NMDA)", RFC 8342, DOI 10.17487/RFC8342, , <https://www.rfc-editor.org/rfc/rfc8342>.

Appendix A. Usage Examples

TBC

This section provides some examples to show the use of templates. JSON encodings are used to not imply a preference in this document. The fictional data model used throughout this section is shown as follows:

module example-network-systime {
  yang-version 1.1;
  namespace "urn:example:network-system-time";
  prefix "ex-nesyst";

  import ietf-inet-types {
    prefix "inet";
  }

  list network-device {
    key device-id;
    leaf device-id {
      type string;
    }
    container ntp {
      leaf enabled {
        type boolean;
        mandatory true;
      }
      list server {
        ordered-by user;
        key name;
        leaf name {
          type string;
        }
        leaf-list alias {
          type string;
        }
        leaf address {
          type inet:host;
          mandatory true;
        }
        leaf port {
          type inet:port-number;
          default 123;
        }
      }
    }
  }
}

A.1. Creating Templates

The NTP configuration on multiple network devices may be consistent. To create a template for NTP configuration, the following template configuration might be sent to a SDN controller:

{
    "ietf-templates:templates": {
        "template": [
            {
                "id": "template-ntp",
                "content": {
                    "network-device": [
                        {
                            "ntp": {
                                "enabled": "true",
                                "server": [
                                    {
                                        "name": "ntp-server-1",
                                        "alias": [
                                            "primary"
                                        ],
                                        "address": "ntp.example-1.com"
                                    },
                                    {
                                        "name": "ntp-server-2",
                                        "alias": [
                                            "secondary"
                                        ],
                                        "address": "ntp.example-2.com"
                                    }
                                ]
                            }
                        }
                    ]
                }
            }
        ]
    }
}

A.2. Applying Templates

The operator may create another template with an additional NTP server instance when inheriting the template created in Appendix A.1. The configuration is shown as follows:

{
    "ietf-templates:templates": {
        "template": [
            {
                "id": "template-ntp2",
                "content": {
                    "network-device": [
                        {
                            "@": {
                                "ietf-template:stmt-extend": "template-ntp"
                            },
                            "ntp": {
                                "server": [
                                    {
                                        "name": "ntp-server-3",
                                        "alias": [
                                            "secondary"
                                        ],
                                        "address": "ntp.example-3.com"
                                    }
                                ]
                            }
                        }
                    ]
                }
            }
        ]
    }
}

The configuration of template "template-ntp2" renders the following expanded configuration:

{
    "ietf-templates:templates": {
        "template": [
            {
                "id": "template-ntp2",
                "content": {
                    "network-device": [
                        {
                            "ntp": {
                                "enabled": "true",
                                "server": [
                                    {
                                        "name": "ntp-server-1",
                                        "alias": [
                                            "primary"
                                        ],
                                        "address": "ntp.example-1.com",
                                        "prefer": true
                                    },
                                    {
                                        "name": "ntp-server-2",
                                        "alias": [
                                            "secondary"
                                        ],
                                        "address": "ntp.example-2.com"
                                    },
                                    {
                                        "name": "ntp-server-3",
                                        "alias": [
                                            "secondary"
                                        ],
                                        "address": "ntp.example-3.com"
                                    }
                                ]
                            }
                        }
                    ]
                }
            }
        ]
    }
}

the following shows the network-level ntp configuration using "template-ntp" and "template-ntp2" that may be sent to a SDN controller:

{
    "example-network-systime:network-device": [
        {
            "@": {
                "ietf-template:stmt-extend": "template-ntp"
            },
            "device-id": "ne-0"
        },
        {
            "@": {
                "ietf-template:stmt-extend": "template-ntp"
            },
            "device-id": "ne-1"
        },
        {
            "@": {
                "ietf-template:stmt-extend": "template-ntp2"
            },
            "device-id": "ne-2"
        },
        {
            "@": {
                "ietf-template:stmt-extend": "template-ntp2"
            },
            "device-id": "ne-3"
        }
    ]
}

And it renders the following expanded configuration:

{
    "example-network-systime:network-device": [
        {
            "device-id": "ne-0",
            "ntp": {
                "enabled": "true",
                "server": [
                    {
                        "name": "ntp-server-1",
                        "alias": [
                            "primary"
                        ],
                        "address": "ntp.example-1.com"
                    },
                    {
                        "name": "ntp-server-2",
                        "alias": [
                            "secondary"
                        ],
                        "address": "ntp.example-2.com"
                    }
                ]
            }
        },
        {
            "device-id": "ne-1",
            "ntp": {
                "enabled": "true",
                "server": [
                    {
                        "name": "ntp-server-1",
                        "alias": [
                            "primary"
                        ],
                        "address": "ntp.example-1.com"
                    },
                    {
                        "name": "ntp-server-2",
                        "alias": [
                            "secondary"
                        ],
                        "address": "ntp.example-2.com"
                    }
                ]
            }
        },
        {
            "device-id": "ne-2",
            "ntp": {
                "enabled": "true",
                "server": [
                    {
                        "name": "ntp-server-1",
                        "alias": [
                            "primary"
                        ],
                        "address": "ntp.example-1.com"
                    },
                    {
                        "name": "ntp-server-2",
                        "alias": [
                            "secondary"
                        ],
                        "address": "ntp.example-2.com"
                    },
                    {
                        "name": "ntp-server-3",
                        "alias": [
                            "secondary"
                        ],
                        "address": "ntp.example-3.com"
                    }
                ]
            }
        },
        {
            "device-id": "ne-3",
            "ntp": {
                "enabled": "true",
                "server": [
                    {
                        "name": "ntp-server-1",
                        "alias": [
                            "primary"
                        ],
                        "address": "ntp.example-1.com"
                    },
                    {
                        "name": "ntp-server-2",
                        "alias": [
                            "secondary"
                        ],
                        "address": "ntp.example-2.com"
                    },
                    {
                        "name": "ntp-server-3",
                        "alias": [
                            "secondary"
                        ],
                        "address": "ntp.example-3.com"
                    }
                ]
            }
        }
    ]
}

A.3. Overriding Templates

The client may override the template created in Appendix A.1 to specify the NTP server named "ntp-server-2" as the perferred one for device "ne-4":

{
    "example-network-systime:network-device": [
        {
            "@": {
                "ietf-template:stmt-extend": "template-ntp"
            },
            "device-id": "ne-4",
            "server": [
                {
                    "name": "ntp-server-1",
                    "alias": [
                        "primary",
                        "secondary"
                    ],
                    "@alias": [
                        {
                            "ietf-template:operation-tag": "delete"
                        }
                    ],
                    "address": "ntp.example-1.com"
                },
                {
                    "@": {
                        "ietf-template:operation-tag": "position-first"
                    },
                    "name": "ntp-server-2",
                    "alias": [
                        "primary",
                        "secondary"
                    ],
                    "@alias": [
                        null,
                        {
                            "ietf-template:operation-tag": "delete"
                        }
                    ],
                    "address": "ntp.example-2.com"
                }
            ]
        }
    ]
}

It is equivalent to the configuration as follows:

{
    "example-network-systime:network-device": [
        {
            "device-id": "ne-4",
            "ntp": {
                "enabled": "true",
                "server": [
                    {
                        "name": "ntp-server-2",
                        "alias": [
                            "primary"
                        ],
                        "address": "ntp.example-2.com"
                    },
                    {
                        "name": "ntp-server-1",
                        "alias": [
                            "secondary"
                        ],
                        "address": "ntp.example-1.com"
                    }
                ]
            }
        }
    ]
}

Acknowledgments

The author would like to thank Lou Berger, Jason Sterne, Kent Watsen, and Robert Wilton for comments and contributions made during interim meetings.

The author would like to acknowledge the following drafts and presenters for kick-starting discussions on Yang Templates:

Contributors

Qin Wu
Huawei
101 Software Avenue, Yuhua District
Jiangsu
210012
China

Authors' Addresses

Qiufang Ma (editor)
Huawei
101 Software Avenue, Yuhua District
Jiangsu
210012
China
Robert Wills (editor)
Cisco
United Kingdom
Deepak Rajaram (editor)
Nokia
India