Network Working Group A. Clemm
Internet-Draft A. Gonzalez Prieto
Intended status: Standards Track E. Voit
Expires: January 7, 2016 Cisco Systems
July 6, 2015

Subscribing to YANG datastore push updates
draft-clemm-netconf-yang-push-01.txt

Abstract

This document defines a subscription and push mechanism for YANG datastores. This mechanism allows client applications to request updates from a YANG datastore, which are then pushed by the server to the client per a subscription policy, without requiring additional client requests.

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 http://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 January 7, 2016.

Copyright Notice

Copyright (c) 2015 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.

This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The person(s) controlling the copyright in some of this material may not have granted the IETF Trust the right to allow modifications of such material outside the IETF Standards Process. Without obtaining an adequate license from the person(s) controlling the copyright in such materials, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process, except to format it for publication as an RFC or to translate it into languages other than English.


Table of Contents

1. Introduction

YANG [RFC6020] was originally designed for the Netconf protocol [RFC6241], which originally put most emphasis on configuration. However, YANG is not restricted to configuration data. YANG datastores, i.e. datastores that contain data modeled according using YANG, can contain configuration as well as operational data. It is therefore reasonable to expect that data in YANG datastores will increasingly be used to support applications that are not focused on managing configurations but that are, for example, related to service assurance.

Service assurance applications typically involve monitoring operational state of networks and devices; of particular interest are changes that this data undergoes over time. Likewise, there are applications in which data and objects from one datastore need to be made available both to applications in other systems and to remote datastores [I-D.voit-netmod-peer-mount-requirements] [I-D.clemm-netmod-mount]. This requires mechanisms that allow remote systems to become quickly aware of any updates to allow to validate and maintain cross-network integrity and consistency.

Traditional approaches to remote network state visibility rely heavily on polling. With polling, data is periodically explicitly retrieved by a client from a server to stay up-to-date.

There are various issues associated with polling-based management:

A more effective alternative is when an application can request to be automatically updated as necessary of current content of the datastore (such as a subtree, or data in a subtree that meets a certain filter condition), and in which the server that maintains the datastore subsequently pushes those updates. However, such a solution does not currently exist.

The need to perform polling-based management is typically considered an important shortcoming of management applications that rely on MIBs polled using SNMP [RFC1157]. However, without a provision to support a push-based alternative, there is no reason to believe that management applications that operate on YANG datastores using protocols such as NETCONF [RFC6241] or Restconf [I-D.ietf-netconf-restconf] will be any more effective, as they would follow the same request/response pattern.

While YANG allows the definition of notifications, such notifications are generally intended to indicate the occurrence of certain well-specified event conditions, such as a the onset of an alarm condition or the occurrence of an error. A capability to subscribe to and deliver event notifications has been defined in [RFC5277]. In addition, configuration change notifications have been defined in [RFC6470]. These change notifications pertain only to configuration information, not to operational state, and convey the root of the subtree to which changes were applied along with the edits, but not the modified data nodes and their values.

Accordingly, there is a need for a service that allows client applications to subscribe to updates of a YANG datastore and that allows the server to push those updates. The requirements for such a service are documented in [I-D.i2rs-pub-sub-requirements]. This document proposes a solution that features the following capabilities: [RFC5277] that allow to extend notification subscriptions to subscriptions for datastore updates. It also defines a notification that can be used to carry data updates and thus serve as push mechanism.

This document specifies a YANG data model to manage subscriptions to data in YANG datastores, and to configure associated filters and data streams. It defines extensions to RPCs defined in

2. Definitions and Acronyms

Data node: An instance of management information in a YANG datastore.

Data record: A record containing a set of one or more data node instances and their associated values.

Datastore: A conceptual store of instantiated management information, with individual data items represented by data nodes which are arranged in hierarchical manner.

Datastream: A continuous stream of data records, each including a set of updates, i.e. data node instances and their associated values.

Data subtree: An instantiated data node and the data nodes that are hierarchically contained within it.

NACM: NETCONF Access Control Model

NETCONF: Network Configuration Protocol

Push-update stream: A conceptual data stream of a datastore that streams the entire datastore contents continuously and perpetually.

RPC: Remote Procedure Call

SNMP: Simple Network Management Protocol

Subscription: A contract between a client ("subscriber") and a server ("publisher"), stipulating which information the client wishes to receive from the server (and which information the server has to provide to the client) without the need for further solicitation.

Subscription filter: A filter that contains evaluation criteria which are evaluated against YANG objects of a subscription. An update is only published if the object meets the specified filter criteria.

Subscription policy: A policy that specifies under what circumstances to push an update, e.g. whether updates are to be provided periodically or only whenever changes occur.

Update: A data item containing the current value of a data node.

Update trigger: A trigger, as specified by a subscription policy, that causes an update to be sent, respectively a data record to be generated. An example of a trigger is a change trigger, invoked when the value of a data node changes or a data node is created or deleted, or a time trigger, invoked after the laps of a periodic time interval.

URI: Uniform Resource Identifier

YANG: A data definition language for NETCONF

Yang-push: The subscription and push mechanism for YANG datastores that is specified in this document.

3. Solution Overview

This document specifies a solution that allows clients to subscribe to information updates in a YANG datastore, which are subsequently pushed from the server to the client.

Subscriptions are initiated by clients. Servers respond to a subscription request explicitly positively or negatively. Negative responses include information about why the subscription was not accepted, in order to facilitate converging on an acceptable set of subscription parameters. Once a subscription has been established, datastore push updates are pushed from the server to the subscribing client until the subscription ends.

Accordingly, the solution encompasses several components:

In addition, there are a number of additional considerations, such as the tie-in of the mechanisms with security mechanisms. Each of those aspects will be discussed in the following subsections.

3.1. Subscription Model

Yang-push subscriptions are defined using a data model. This model is based on the subscriptions defined in [RFC-5277], which is also reused in Restconf. The model is extended with several parameters, including a subscription type and a subscription ID.

A subscription refers to a datastream. The subscription model assumes the presence of a conceptual perpetual datastream "push-update" of continuous datastore updates. A subscription refers to this datastream and specifies filters that are to be applied to, it for example, to provide only those subsets of the information that match a filter criteria. In addition, a subscription specifies a subscription policy that defines the trigger when data records should be sent, for example at periodic intervals or whenever underlying data items change.

The complete set of subscription parameters is as follows:

It is conceivable that additional subscription parameters might be added in the future. This can be accomplished through augmentation of the subscription data model.

3.2. Negotiation of Subscription Policies

A subscription rejection can be caused by the inability of the server to provide a stream with the requested semantics. For example, a server may not be able to support "on-change" updates for operational data, or only support them for a limited set of data nodes. Likewise, a server may not be able to support a requested updated frequency, or a requested encoding.

Yang-push supports a simple negotiation between clients and servers for subscription parameters. The negotiation is limited to a single pair of subscription request and response. For negative responses, the server SHOULD include in the returned error what subscription parameters would have been accepted for the request. The returned acceptable parameters constitute suggestions that, when followed, increase the likelihood of success for subsequent requests. However, they are no guarantee that subsequent requests for this client or others will in fact be accepted.

In case a subscriber requests an encoding other than XML, and this encoding is not supported by the server, the server simply indicates in the response that the encoding is not supported.

3.3. On-Change Considerations

On-change subscriptions allow clients to subscribe to updates whenever changes to objects occur. As such, on-change subscriptions are of particular interest for data that changes relatively infrequently, yet that require applications to be notified with minimal delay when changes do occur.

On-change subscriptions tend to be more difficult to implement than periodic subscriptions. Specifically, on-change subscriptions may involve a notion of state to see if a change occurred between past and current state, or the ability to tap into changes as they occur in the underlying system. Accordingly, on-change subscriptions may not be supported by all implementation or for every object.

When an on-change subscription is requested for a datastream with a given subtree filter, where not all objects support on-change update triggers, the subscription request MUST be rejected. As a result, on-change subscription requests will tend to be directed at very specific, targeted subtrees with only few objects.

Any updates for an on-change subscription will include only objects for which a change was detected. To avoid flooding clients with repeated updates for fast-changing objects, or objects with oscillating values, an on-change subscription allows for the definition of a dampening period. Once an update for a given object is sent, no other updates for this particular object are sent until the end of the dampening period.

In order to avoid sending updates on objects whose values undergo only a negligible change, it is conceivable to attach additional parameters to an on-change subscription specifying a policy that states how large or "significant" a change has to be before an update is sent. A simple policy is a "delta-policy" that states, for integer-valued data nodes, the minimum difference between the current value and the value that was last reported that triggers an update. More sophisticated policies are conceivable, including policies specified in percentage terms or policies that take into account the rate of change. While not specified as part of this draft, such policies can be accommodated by augmenting the subscription data model accordingly.

3.4. Additional on-change update triggers

In conjunction with on-change update triggers, it is conceivable to further differentiate between the type of change, i.e. whether a change involves the addition of a new data node, the removal of a data node, or a value change.

For this purpose, an on-change qualifier is introduced that allows subscribers to specify which update triggers (create, delete, modify) to exclude if updates to all change types are not desired.

3.5. Data Encodings

Subscribed data is encoded in either XML or JSON format. A server MUST support XML encoding and MAY support JSON encoding. XML encoding rules for data nodes are defined in [RFC6020]. JSON encoding rules are defined in [I-D.ietf-netmod-yang-json]. This encoding is valid JSON, but also has special encoding rules to identify module namespaces and provide consistent type processing of YANG data.

It is conceivable that additional encodings may be supported as options in the future. This can be accomplished by augmenting the subscription data model with additional identity statements used to refer to the encodings.

3.6. Custom Datastreams

Optionally, it is possible to introduce other datastreams (beyond the datastore-push datastream) with custom semantics. Some datastreams can be custom configured. The support of this is tied to a separate feature. The configuration of a custom datastream specifies the trigger conditions under which new data records for the stream are generated, and which updates the corresponding data records contain. For example, the configuration of a datastream can specify which subsets of data nodes in a datastore the datastream should contain, which filter criteria the updates need to meet, and under what conditions to create updates - for example, periodically or whenever a data item changes.

A subscription that refers to a custom datastream can specify a set of filters, like for the "push-update" datastream. However, the policy as to when updates are triggered (periodically or on change) needs to be the same as the policy of the datastream and cannot be modified. It is not possible, for example, to define a custom datastream which creates on-change updates, yet subscribe to that datastream with periodic updates.

While conceptually similar, the choice between subscribing to datastream "push-update" or configuring and subscribing to a custom datastream can be thought of as analogous to the choice between operating a nozzle that is connected to a hose, or controlling the faucet (custom datastream). Operating the nozzle is for most uses simpler; however, the option to operate the faucet instead can provide additional flexibility in some scenarios.

3.7. Push Data Stream and Transport Mapping

Pushing data based on a subscription could be considered analogous to a response to a data retrieval request, e.g. a "get" request. However, contrary to such a request, multiple responses to the same request may get sent over a longer period of time.

A more suitable mechanism is therefore that of a notification. Contrary to notifications associated with alarms and unexpected event occurrences, push updates are solicited, i.e. tied tied to a particular subscription which triggered the notification. (An alternative conceptual model would consider a subscription an "opt-in" filter on a continuous stream of updates.)

The notification contains several parameters: [RFC5277]. Alternative transports are conceivable but outside the scope of this specification.

Notifications are sent using <notification> elements as defined in

The solution specified in this document uses notifications to communicate datastore updates. The contents of the notification includes a set of explicitly defined data nodes. For this purpose, a new generic notification is introduced, "push-update" notification. This notification is used to carry a data record with updates of datastore contents as specified by a subscription.

The update record consists of a data snippet that contains an instantiated datastore subtree with the subscribed contents. Data nodes that do not match filter criteria are removed. Likewise, in the case of a subscription with "on-change" subscription policy, data nodes that have not undergone change are omitted. The contents of the update record is equivalent to the contents that would be obtained had the same data been explicitly retrieved using e.g. a Netconf "get"-operation, with the same filters applied.

The contents of the notification conceptually represents the union of all data nodes in the yang modules supported by the server, excluding the following statements: "mandatory", "must", "min-elements", "max-elements", "when", and "default". However, in a YANG data model, it is not practical to model the precise data contained in the updates as part of the notification. This is because the specific data nodes supported depend on the implementing system and may even vary dynamically. Therefore, to capture this data, a single parameter that can represent any datastore contents is used, not parameters that represent data nodes one at a time.

The following is an example of push notification. It contains an update for subscription my-sub, including a subtree with root foo that contains a leaf, bar:

 
          
<?xml version="1.0" encoding="UTF-8"?>
<notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
   <subscription-id xmlns="urn:ietf:params:xml:ns:netconf:
      datastore-push:1.0">
         my-sub
   </subscription-id>
   <eventTime>2015-03-09T19:14:56Z</eventTime> 
   <datastore-contents xmlns="urn:ietf:params:xml:ns:netconf:
      datastore-push:1.0">
         <foo>
            <bar>some_string</bar>
         </foo>
   </datastore-contents>
</notification>

Figure 1: Push example

3.8. Subscription operations

There are several operations associated with subscriptions. At the most basic level, clients need to be able to create subscriptions, as well as delete subscriptions when they are no longer needed.

RFC 5277 specifies an operation to create subscriptions for event streams, <create-subscription>. This operation is leveraged and extended to create datastore-push subscriptions. The corresponding data model is defined in the "subscription-stream-policy" and "subscription-info" groupings of the YANG module defined in Section 4. Specifically:

To support datastore push, a server MUST support the interleave capability specified in [RFC5277]. This is required to allow for modification of what data is being subscribed to without needing to establish a separate Netconf session.

The example below illustrates a subscription for a periodic push of all data under a container called foo.

 
   <netconf:rpc message-id="101"
         xmlns:netconf="urn:ietf:params:xml:ns:netconf:base:1.0">
      <create-subscription
            xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
         <stream>push-update</stream>
         <subscription-id xmlns="urn:ietf:params:xml:ns:netconf:
            datastore-push:1.0">
               my-sub
         </subscription-id>
         <filter netconf:type="xpath"
               xmlns:ex="http://example.com/foo/1.0"
               select="/ex:foo"/>
         <period xmlns="urn:ietf:params:xml:ns:netconf:datastore-push:1.0">
               500
         </period>
         <encoding xmlns="urn:ietf:params:xml:ns:netconf:datastore-push:1.0">
            encode-xml
         </encoding>
      </create-subscription>
   </netconf:rpc>
             

Figure 2: Subscription example

A success response by the server implies that the server will be able to serve the subscription as requested. It constitutes a "promise" of the server to push updates to the subscriber along the parameters that were requested.

The server is not obliged to accept a request if there are any aspects of the request that it would not be able to meet. This includes any reason, including update interval periods that are too short (requiring more resources than the server could handle), a filter condition that is not supported, or a requested encoding that is not supported. Other failure reasons include specification of a subscription-id that is already in use (modify-subscription should be used to make changes to settings of existing subscriptions), or authorization failures (please refer also to section Section 3.10.1.)

The example below illustrates a subscription response, where an agent does not support frequent periodic updates, and suggests a different sampling rate to the client.

                 
   <rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
      <rpc-error>
         <error-type>application</error-type>
         <error-tag>operation-not-supported</error-tag>
         <error-severity>error</error-severity>
         <error-info>
            <supported-subscription xmlns="urn:ietf:params:xml:ns:
               netconf:datastore-push:1.0">
                  <period>3000</period>
           </supported-subscription>
         </error-info>
      </rpc-error>
   </rpc-reply>
             

Figure 3: Subscription negotiation example

RFC 5277 does not specify operations to delete subscriptions. Instead, it assumes that an event subscription is associated with its own Netconf session. When the session is torn down, the subscription is implicitly deleted. Likewise, there is no operation to modify a subscription. Modifying a subscription requires tearing down a Netconf session, starting a new one, and creating a new subscription. Furthermore, each session only supports a single subscription. Establishing multiple subscriptions requires multiple concurrent Netconf sessions.

To facilitate datastore-push subscriptions, an additional RPC is introduced, <delete-subscription>.

The <delete-subscription> operation takes as parameter a subscription ID. As a result of the operation, the subscription is removed and no more data records will be sent.

                 

   <netconf:rpc message-id="102"
         xmlns:netconf="urn:ietf:params:xml:ns:netconf:base:1.0">
      <delete-subscription
            xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
         <subscription-id xmlns="urn:ietf:params:xml:ns:netconf:
            datastore-push:1.0">
               my-sub
         </subscription-id>
      </delete-subscription>
   </netconf:rpc>
             

Figure 4: Subscription deletion

Finally, a separate operation to modify a subscription is introduced, <modify-subscription>. This operation takes the same parameters as <create-subscription>, but refers to an existing subscription. Of course, a subscription could also be deleted and another be created. However, modify operation avoids issues regarding the synchronization of creation and deletion operations, such as potential loss or duplication of updates. Also, a modify operation allows to simply extend an existing subscription beyond the initial subscription end time.

                 
   <netconf:rpc message-id="103"
         xmlns:netconf="urn:ietf:params:xml:ns:netconf:base:1.0">
      <modify-subscription
              xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
         <stream>push-update</stream>
         <subscription-id 
            xmlns="urn:ietf:params:xml:ns:netconf:datastore-push:1.0">
               my-sub
         </subscription-id>
         <filter netconf:type="xpath"
               xmlns:ex="http://example.com/foo/1.0"
                  select="/ex:foo"/>
         <period xmlns="urn:ietf:params:xml:ns:netconf:
            datastore-push:1.0">
               3000
         </period>
      </modify-subscription>
   </netconf:rpc>
       

Figure 5: Modify subscription

3.9. A YANG data model for management of datastore push subscriptions

Subscriptions as well as datastreams can be subjected to management themselves. For example, it is possible that a server may no longer be able to serve a subscription that it had previously accepted. Perhaps it has run out of resources, or internal errors may have occurred. When this is the case, a server needs to be able to temporarily suspend the subscription, or even to terminate it. More generally, the server should provide a means by which the status of subscriptions can be monitored. When custom datastreams are supported, those datastreams need to be configured and monitored as well.

For this purpose, a YANG data model is introduced, which is depicted in the following figure.

module: ietf-datastore-push
   +--rw streams {custom-streams}?
   |  +--rw stream* [stream-name]
   |     +--rw stream-name         string
   |     +--ro stream-status?      identityref
   |     +--rw subtree-filter?     subtree-filter
   |     +--rw xpath-filter?       yang:xpath1.0
   |     +--rw (update-trigger)?
   |        +--:(periodic)
   |        |  +--rw period?             yang:timeticks
   |        +--:(on-change)
   |           +--rw dampening-period    yang:timeticks
   |           +--rw excluded-change*    change-type
   |           +--rw (change-policy)?
   |              +--:(delta-policy)
   |                 +--rw delta?              uint32
   +--rw subscriptions
      +--ro datastore-push-subscription* [subscription-id]
         +--ro subscription-id        subscription-identifier
         +--ro subscription-status?   identityref
         +--ro stream?                string
         +--ro encoding?              encoding
         +--ro start-time?            yang:date-and-time
         +--ro stop-time?             yang:date-and-time
         +--ro subtree-filter?        subtree-filter
         +--ro xpath-filter?          yang:xpath1.0
         +--ro (update-trigger)?
            +--:(periodic)
            |  +--ro period?                yang:timeticks
            +--:(on-change)
               +--ro dampening-period       yang:timeticks
               +--ro excluded-change*       change-type
               +--ro (change-policy)?
                  +--:(delta-policy)
                     +--ro delta?                 uint32      
		    

Figure 6: Model structure

Each subscription is represented as a list element "datastore-push-subscription". The associated information includes an identifier for the subscription, a subscription status, as well as the various subscription paramters. The subscription status indicates whether the subscription is currently active and healthy, or if it is degraded in some form. Subscriptions are automatically removed from the list once they expire or are terminated. Because subscriptions are managed using their own set of operation primitives, they are read-only.

An optional feature, custom-streams, is introduced to allow for the configuration of custom datastreams. Custom datastreams are represented through a separate list, consisting of information used to configure those datastreams. This information consititutes mostly configuration information, with the exception of parameters used to indicate the status and health of the datastream.

In addition, a server needs to indicate any changes in status to the subscriber through a notification. Specifically, subscribers need to be informed of the following:

  • A subscription has been temporarily suspended (including the reason)
  • A subscription (that had been suspended earlier) is once again operational
  • A subscription has been abnormally terminated (including the reason)
  • A subscription has been modified (including the current set of subscription parameters in effect)

Finally, a server might provide additional information about subscriptions, such as statistics about the number of data updates that were sent. However, such information is currently outside the scope of this specification.

3.10. Other considerations

3.10.1. Authorization

A receiver of subscription data may only be sent updates for which they have proper authorization. Data that is being pushed therefore needs to be subjected to a filter that applies all corresponding rules applicable at the time of a specific pushed update, removing any non-authorized data as applicable.

The authorization model for data in YANG datastores is described in the Netconf Access Control Model [RFC6536]. However, some clarifications to that RFC are needed so that the desired access control behavior is applied to pushed updates.

One of these clarifications is that a subscription may only be established if the Subscriber has read access to the target data node.

          
                 +-------------+                 +-------------+
    subscription |  protocol   |                 |   target    |
    request -->  |  operation  | ------------->  |  data node  |
                 |  allowed?   |   datastore     |   access    |
                 +-------------+   or state      |  allowed?   |
                                   data access   +-------------+
 
        

Figure 7: Access control for subscription

Likewise if a subscriber no longer has read access permission to a target data node, the subscription must be abnormally terminated (with loss of access permission as the reason provided).

Another clarification to [RFC6536] is that each of the individual nodes in a pushed update must also go through access control filtering. This includes new nodes added since the last push update, as well as existing nodes. For each of these read access must be verified. The methods of doing this efficiently are left to implementation.

          
                   +-------------+      +-------------------+
    subscription   |  data node  |  yes |                   |  
    update  -->    |   access    | ---> | add data node     |
                   |  allowed?   |      | to update message |
                   +-------------+      +-------------------+
          

Figure 8: Access control for push updates

If there are read access control changes applied under the target node, no notifications indicating the fact that this has occurred need to be provided.

3.10.2. Additional subscription primitives

Other possible operations include the ability for a Subscriber to request the suspension/resumption of a Subscription with a Publisher. However, subscriber driven suspension is not viewed as essential at this time, as a simpler alternative is to remove a subscription and recreate it when needed.

It should be noted that this does not affect the ability of the Publisher to suspend a subscription. This can occur in cases the server is not able to serve the subscription for a certain period of time, and indicated by a corresponding notification.

3.10.3. Robustness and reliability considerations

Particularly in the case of on-change push updates, it is important that push updates do not get lost. However, datastore-push uses a secure and reliable transport. Notifications are not getting reordered, and in addition contain a time stamp. For those reasons, we believe that additional reliability mechanisms at the application level, such as sequence numbers for push updates, are not required.

3.10.4. Update size and fragmentation considerations

Depending on the subscription, the volume of updates can become quite large. There is no inherent limitation to the amount of data that can be included in a notification. That said, it may not always be practical to send the entire update in a single chunk. Implementations MAY therefore choose, at their discretion, to "chunk" updates and break them out into several update notifications.

3.10.5. Additional data streams

The conceptual data stream introduced in this specification, datastore-push, includes the entire YANG datastore in its scope. It is conceivable to introduce other data streams with more limited scope, for example:

  • operdata-push, a datastream containing all operational (read-only) data of a YANG datastore
  • operdata-nocounts-push, a datastream containing all operational (read-only) data with the exception of counters

Those data streams make particular sense for use cases involving service assurance (not relying on operational data), and for use cases requiring on-change update triggers which make no sense to support in conjunction with fast-changing counters. While it is possible to specify subtree filters on datastore-push to the same effect, having those data streams greatly simplifies articulating subscriptions in such scenarios.

3.10.6. Subscription persistency

This specification assumes that a subscriber will explicitly request a subscription before it receives any update. It does not foresee that a subscription can be in effect without a subscriber needing to enter a subscription first.

It is conceivable that scenarios exist in which subscriptions should be persisted and in effect simply constitute a part of a device's configuration, i.e. scenarios that require a device to simply start sending updates without requiring a subscription to be established first. While this possibility is not supported by this specification, there are several ways in which it can be addressed. One possibility involves adding a subscription configuration model, which allows to enter subscriptions as part of a configuration. Another possibility involves the introduction of a subscription proxy, a subscriber which acts as intermediary between the system whose updates are being subscribed to and the actual consuming application.

3.10.7. Implementation considerations

Implementation specifics are outside the scope of this specification. That said,it should be noted that monitoring of operational state changes inside a system can be associated with significant implementation challenges.

Even periodic retrieval of operational state alone, to be able to push it, can consume considerable system resources. Configuration data may in many cases be persisted in an actual database or a configuration file, where retrieval of the database content or the file itself is reasonably straightforward and computationally inexpensive. However, retrieval of operational data may, depending on the implementation, require invocation of APIs, possibly on an object-by-object basis, possibly involving additional internal interrupts, etc.

For those reasons, if is important for an implementation to understand what subscriptions it can or cannot support. It is far preferrable to decline a subscription request, than to accept it only to result in subsequent failure later.

Whether or not a subscription can be supported will in general be determined by a combination of several factors, including the subscription policy (on-change or periodic, with on-change in general being the more challenging of the two), the period in which to report changes (1 second periods will consume more resources than 1 hour periods), the amount of data in the subtree that is being subscribed to, and the number and combination of other subscriptions that are concurrently being serviced.

When providing access control to every node in a pushed update, it is possible to make and update efficient access control filters for an update. These filters can be set upon subscription and applied against a stream of updates. These filters need only be updated when (a) there is a new node added/removed from the subscribed tree with different permissions than its parent, or (b) read access permissions have been changed on nodes under the target node for the subscriber.

4. YANG module

<CODE BEGINS>
file "ietf-datastore-push@2015-07-06.yang"

module ietf-datastore-push {
  namespace "urn:ietf:params:xml:ns:yang:ietf-datastore-push";
  prefix datastore-push;

  import ietf-yang-types {
    prefix yang;
  }

  organization "IETF";
  contact
    "WG Web:   <http://tools.ietf.org/wg/netconf/>
     WG List:  <mailto:netconf@ietf.org>
     
     WG Chair: Juergen Schoenwaelder
               <mailto:j.schoenwaelder@jacobs-university.de>
     
     WG Chair: Kent Watsen 
               <mailto:kwatsen@juniper.net>
               
     WG Chair: Tom Nadeau
               <mailto:tnadeau@lucidvision.com>
               
     Editor:   Alexander Clemm
               <mailto:alex@cisco.com>
     
     Editor:   Alberto Gonzalez Prieto
               <mailto:albertgo@cisco.com>
     
     Editor:   Eric Voit
               <mailto:evoit@cisco.com>";
  description
    "This module contains conceptual YANG specifications
     for datastore push.";

  revision 2015-07-06 {
    description
      "Initial revision.";
    reference "Datastore push.";
  }

  feature custom-streams {
    description
      "This feature allows users to configure datastore update 
       streams in addition to the stream provided by default,
       datastore-push.";
  }

  identity subscription-stream-status {
    description
      "Base identity for the status of subscriptions and 
       datastreams.";
  }

  identity active {
    base subscription-stream-status;
    description
      "Status is active and healthy.";
  }

  identity inactive {
    base subscription-stream-status;
    description
      "Status is inactive, for example outside the 
       interval between start time and stop time.";
  }

  identity in-error {
    base subscription-stream-status;
    description
      "The status is in error or degraded, meaning that 
       stream and/or subscription are currently unable to provide 
       the negotiated updates.";
  }

  identity subscription-errors {
    description
      "Base identity for subscription errors.";
  }

  identity internal-error {
    base subscription-errors;
    description
      "Subscription failures caused by server internal error.";
  }

  identity no-resources {
    base subscription-errors;
    description
      "Lack of resources, e.g. CPU, memory, bandwidth";
  }

  identity other {
    base subscription-errors;
    description
      "Fallback reason - any other reason";
  }

  identity encodings {
    description
      "Base identity to represent data encodings";
  }

  identity encode-xml {
    base encodings;
    description
      "Encode data using XML";
  }

  identity encode-json {
    base encodings;
    description
      "Encode data using JSON";
  }

  typedef datastore-contents {
    type string;
    description
      "This type is be used to represent datastore contents, 
       including a filtered datastore subtree per a set of 
       subscription parameters. ";
  }

  typedef subtree-filter {
    type string;
    description
      "This type is used to define a subtree filter.  
       Its precise syntax is TBD.";
  }

  typedef subscription-identifier {
    type string {
      length "1 .. max";
    }
    description
      "A client-provided identifier for the subscription.";
  }

  typedef subscription-term-reason {
    type identityref {
      base subscription-errors;
    }
    description
      "Reason for a server to terminate a subscription.";
  }

  typedef subscription-susp-reason {
    type identityref {
      base subscription-errors;
    }
    description
      "Reason for a server to suspend a subscription.";
  }

  typedef encoding {
    type identityref {
      base encodings;
    }
    description
      "Specifies a data encoding, e.g. for a data subscription.";
  }

  typedef change-type {
    type enumeration {
      enum "create" {
        description
          "A new data node was created";
      }
      enum "delete" {
        description
          "A data node was deleted";
      }
      enum "modify" {
        description
          "The value of a data node has changed";
      }
    }
    description
      "Specifies different types of changes that may occur 
       to a datastore.";
  }

  grouping subscription-stream-policy {
    description
      "This grouping contains the parameters which describe 
       the policy which data is pushed as part of a 
       subscription or a data stream.";
    leaf subtree-filter {
      type subtree-filter;
      description
        "Datastore subtree of interest.";
    }
    leaf xpath-filter {
      type yang:xpath1.0;
      description
        "Xpath defining the data items of interest.";
    }
    choice update-trigger {
      description
        "Defines necessary conditions for sending an event  to 
         the subscriber.";
      case periodic {
        description
          "The agent is requested to notify periodically the 
           current values of the datastore or the subset 
           defined by the filter.";
        leaf period {
          type yang:timeticks;
          description
            "Elapsed time between notifications.";
        }
      }
      case on-change {
        description
          "The agent is requested to notify changes in 
           values in the datastore or a subset of it defined 
           by a filter.";
        leaf dampening-period {
          type yang:timeticks;
          mandatory true;
          description
            "Minimum amount of time that needs to have 
             passed since the last time an update was 
             provided.";
        }
        leaf-list excluded-change {
          type change-type;
          description
            "Use to restrict which changes trigger an update.
             For example, if modify is excluded, only creation and 
             deletion of objects is reported.";
        }
        choice change-policy {
          description
            "Policy describing necessary conditions for 
             sending an event to the subscriber.";
          case delta-policy {
            leaf delta {
              type uint32;
              description
                "For modified values of an integer-typed object, 
                 minimum difference between current and last 
                 report values that can trigger an update.";
            }
          }
        }
      }
    }
  }

  grouping subscription-info {
    description
      "This grouping describes basic information concerning a 
       subscription, without the subscription policy which is 
       defined separately to be shareable with the definition 
       of a datastream.";
    leaf stream {
      type string;
      description
        "The name of the stream subscribed to.";
    }
    leaf encoding {
      type encoding;
      default encode-xml;
      description
        "The type of encoding for the subscribed data.  
         Default is XML";
    }
    leaf start-time {
      type yang:date-and-time;
      description
        "Starting time for replays.";
      reference "RFC 5277, Section 2.1.1";
    }
    leaf stop-time {
      type yang:date-and-time;
      description
        "Time limit for events of interest.";
      reference "RFC 5277, Section 2.1.1";
    }
  }

  notification push-update {
    description
      "This notification contains an update from a datastore";
    leaf subscription-id {
      type subscription-identifier;
      mandatory true;
      description
        "This references the subscription because of which the 
         notification is sent.";
    }
    leaf datastore-contents {
      type datastore-contents;
      description
        "This contains datastore contents 
         per the subscription.";
    }
  }
  notification subscription-suspended {
    description
      "This notification indicates that a suspension of the 
       subscription by the server has occurred.  No further 
       datastore updates will be sent until subscription 
       resumes.";
    leaf subscription-id {
      type subscription-identifier;
      mandatory true;
      description
        "This references the affected subscription.";
    }
    leaf reason {
      type subscription-susp-reason;
      description
        "Provides a reason for why the subscription was 
         suspended.";
    }
  }
  notification subscription-resumed {
    description
      "This notification indicates that a subscription that had 
       previously been suspended has resumed. Datastore updates 
       will once again be sent.";
    leaf subscription-id {
      type subscription-identifier;
      mandatory true;
      description
        "This references the affected subscription.";
    }
  }
  notification subscription-modified {
    description
      "This notification indicates that a subscription has 
       been modified.  Datastore updates sent from this point 
       on will conform to the modified terms of the 
       subscription.";
    leaf subscription-id {
      type subscription-identifier;
      mandatory true;
      description
        "This references the affected subscription.";
    }
    uses subscription-info;
    uses subscription-stream-policy;
  }
  notification subscription-terminated {
    description
      "This notification indicates that a subscription has been 
       terminated.";
    leaf subscription-id {
      type subscription-identifier;
      mandatory true;
      description
        "This references the affected subscription.";
    }
    leaf reason {
      type subscription-term-reason;
      description
        "Provides a reason for why the subscription was 
         terminated.";
    }
  }
  container streams {
    if-feature custom-streams;
    description
      "This container contains management data for custom streams
       that are configured by a user.";
    list stream {
      key "stream-name";
      description
        "A user-definable stream.";
      leaf stream-name {
        type string;
        mandatory true;
        description
          "The name assigned to the stream.";
      }
      leaf stream-status {
        type identityref {
          base subscription-stream-status;
        }
        config false;
        description
          "The current status of the stream";
      }
      uses subscription-stream-policy;
    }
  }
  container subscriptions {
    description
      "Contains the list of currently active subscription,
       used for subscription management and monitoring purposes.
       Note that this concerns subscriptions that are in-effect.
       Configuration and setup of subscriptions occurs via separate 
       primitives, e.g. create-subscription, delete-subscription,
       and modify-subscription.";
    list datastore-push-subscription {
      key "subscription-id";
      config false;
      description
        "Content of a yang-push subscription.  
         Subscriptions are created using a dedicated RPC, hence
         they do not constitute configuration information.";
      leaf subscription-id {
        type subscription-identifier;
        description
          "Identifier to use for this subscription.";
      }
      leaf subscription-status {
        type identityref {
          base subscription-stream-status;
        }
        description
          "The status of the subscription.";
      }
      uses subscription-info;
      uses subscription-stream-policy;
    }
  }
}

<CODE ENDS> 
        

5. Security Considerations

Subscriptions could be used to attempt to overload servers of YANG datastores. For this reason, it is important that the server has the ability to decline a subscription request if it would deplete its resources. In addition, a server needs to be able to suspend an existing subscription when needed. When this occur, the subscription status is updated accordingly and the clients are notified. Likewise, requests for subscriptions need to be properly authorized.

A subscription could be used to retrieve data in subtrees that a client has not authorized access to. Therefore it is important that data pushed based on subscriptions is authorized in the same way that regular data retrieval operations are. Data being pushed to a client needs therefore to be filtered accordingly, just like if the data were being retrieved on-demand. The Netconf Authorization Control Model applies.

6. References

6.1. Normative References

[RFC1157] Case, J., Fedor, M., Schoffstall, M. and J. Davin, "Simple Network Management Protocol (SNMP)", STD 15, RFC 1157, May 1990.
[RFC5277] Chisholm, S. and H. Trevino, "NETCONF Event Notifications", RFC 5277, July 2008.
[RFC6020] Bjorklund, M., "YANG - A Data Modeling Language for the Network Configuration Protocol (NETCONF)", RFC 6020, October 2010.
[RFC6241] Enns, R., Bjorklund, M., Schoenwaelder, J. and A. Bierman, "Network Configuration Protocol (NETCONF)", RFC 6241, June 2011.
[RFC6470] Bierman, A., "Network Configuration Protocol (NETCONF) Base Notifications", RFC 5277, February 2012.
[RFC6536] Bierman, A. and M. Bjorklund, "Network Configuration Protocol (NETCONF) Access Control Model", RFC 6536, March 2012.

6.2. Informative References

[I-D.clemm-netmod-mount] Clemm, A., Medved, J. and E. Voit, "Mounting YANG-defined information from remote datastores", Internet-Draft draft-clemm-netmod-mount-03, April 2015.
[I-D.i2rs-pub-sub-requirements] Voit, E., Clemm, A. and A. Gonzalez Prieto, "Requirements for Subscription to YANG Datastores", Internet-Draft draft-ietf-i2rs-pub-sub-requirements-00, March 2015.
[I-D.ietf-netconf-restconf] Bierman, A., Bjorklund, M. and K. Watsen, "RESTCONF Protocol", I-D draft-ietf-netconf-restconf-06, June 2015.
[I-D.ietf-netmod-yang-json] Lhotka, L., "JSON Encoding of Data Modeled with YANG", Internet-Draft draft-ietf-netmod-yang-json-04, June 2015.
[I-D.voit-netmod-peer-mount-requirements] Voit, E., Clemm, A. and S. Mertens, "Requirements for Peer Mounting of YANG subtrees from Remote Datastores", Internet-Draft draft-voit-netmod-peer-mount-requirements-02, March 2015.

Authors' Addresses

Alexander Clemm Cisco Systems EMail: alex@cisco.com
Alberto Gonzalez Prieto Cisco Systems EMail: albertgo@cisco.com
Eric Voit Cisco Systems EMail: evoit@cisco.com