One document matched: draft-clemm-netconf-yang-push-01.xml
<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!-- One method to get references from the online citation libraries.
There has to be one entity for each item to be referenced.
An alternate method (rfc include) is described in the references. -->
<!ENTITY RFC1157 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.1157.xml">
<!ENTITY RFC6020 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6020.xml">
<!ENTITY RFC6241 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6241.xml">
<!ENTITY RFC6536 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6536.xml">
]>
<?rfc toc="yes"?>
<?rfc rfcedstyle="yes"?>
<?rfc subcompact="no" ?>
<?rfc symrefs="yes"?>
<rfc category="std" docName="draft-clemm-netconf-yang-push-01.txt"
ipr="pre5378Trust200902">
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<?rfc toc="yes" ?>
<?rfc compact="yes" ?>
<?rfc symrefs="yes" ?>
<?rfc sortrefs="yes"?>
<?rfc iprnotified="no" ?>
<?rfc strict="yes" ?>
<front>
<title abbrev="Datastore-Push">Subscribing to YANG datastore push
updates</title>
<author fullname="Alexander Clemm" initials="A." surname="Clemm">
<organization>Cisco Systems</organization>
<address>
<email>alex@cisco.com</email>
</address>
</author>
<author fullname="Alberto Gonzalez Prieto" initials="A."
surname="Gonzalez Prieto">
<organization>Cisco Systems</organization>
<address>
<email>albertgo@cisco.com</email>
</address>
</author>
<author fullname="Eric Voit" initials="E." surname="Voit">
<organization>Cisco Systems</organization>
<address>
<email>evoit@cisco.com</email>
</address>
</author>
<date day="6" month="July" year="2015"/>
<abstract>
<t>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.</t>
</abstract>
</front>
<middle>
<section title="Introduction">
<t>YANG <xref target="RFC6020"/> was originally designed for the Netconf
protocol <xref target="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.</t>
<t>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 <xref target="I-D.voit-netmod-peer-mount-requirements"/>
<xref target="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.</t>
<t>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.</t>
<t>There are various issues associated with polling-based management:
<list style="symbols">
<t>It introduces additional load on network, devices, and applications.
Each
polling cycle requires a separate yet arguably redundant request
that results in an interrupt, requires parsing, consumes
bandwidth.</t>
<t>It lacks robustness. Polling cycles may be missed, requests may
be delayed or get lost, often particularly in cases when the network
is under stress and hence exactly when the need for the data is the
greatest.</t>
<t>Data may be difficult to calibrate and compare. Polling requests
may undergo slight fluctuations, resulting in intervals of different
lengths which makes data hard to compare. Likewise, pollers may have
difficulty issuing requests that reach all devices at the same time,
resulting in offset polling intervals which again make data hard to
compare.</t>
</list> 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.</t>
<t>The need to perform polling-based management is typically considered
an important shortcoming of management applications that rely on MIBs
polled using SNMP <xref target="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 <xref target="RFC6241"/> or Restconf <xref
target="I-D.ietf-netconf-restconf"/> will be any more effective,
as they would follow the
same request/response pattern.</t>
<t>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 <xref
target="RFC5277"/>. In addition, configuration change notifications have
been defined in <xref target="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.</t>
<t>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 <xref target="I-D.i2rs-pub-sub-requirements"/>.
This document proposes
a solution that features the
following capabilities: <list style="symbols">
<t>A mechanism that allows clients to subscribe to automatic
datastore updates, and the means to manage those subscription. The
subscription allows clients to specify which data they are
interested in, and to provide optional filters with criteria that
data must meet for updates to be sent. Furthermore, subscription can
specify a policy that directs when updates are provided. For
example, a client may request to be updated periodically in certain
intervals, or whenever data changes occur.</t>
<t>The ability for a server to push back on requested subscription
parameters. Because not
every server may support every requested interval for every piece of
data, it is necessary for a server to be able to indicate whether or
not it is capable of supporting a requested subscription, and
possibly allow to negotiate subscription parameters.</t>
<t>A mechanism to communicate the updates themselves. For this,
the proposal leverages and extends existing YANG/Netconf/Restconf
mechanisms, defining special notifications that carry updates.</t>
</list> 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 <xref
target="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.</t>
</section>
<section title="Definitions and Acronyms">
<t>Data node: An instance of management information in a YANG
datastore.</t>
<t>Data record: A record containing a set of one or more data node
instances and their associated values.</t>
<t>Datastore: A conceptual store of instantiated management information,
with individual data items represented by data nodes which are arranged
in hierarchical manner.</t>
<t>Datastream: A continuous stream of data records, each including a set
of updates, i.e. data node instances and their associated values.</t>
<t>Data subtree: An instantiated data node and the data nodes that are
hierarchically contained within it.</t>
<t>NACM: NETCONF Access Control Model</t>
<t>NETCONF: Network Configuration Protocol</t>
<t>Push-update stream: A conceptual data stream of a datastore that
streams the entire datastore contents continuously and perpetually.</t>
<t>RPC: Remote Procedure Call</t>
<t>SNMP: Simple Network Management Protocol</t>
<t>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.</t>
<t>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.</t>
<t>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.</t>
<t>Update: A data item containing the current value of a data node.</t>
<t>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.</t>
<t>URI: Uniform Resource Identifier</t>
<t>YANG: A data definition language for NETCONF</t>
<t>Yang-push: The subscription and push mechanism for YANG datastores
that is specified in this document.</t>
</section>
<section title="Solution Overview">
<t>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.</t>
<t>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.</t>
<t>Accordingly, the solution encompasses several components: <list
style="symbols">
<t>The subscription model for configuration and management of the
subscriptions, with a set of associated services.</t>
<t>The ability to provide hints for acceptable subscription
parameters, in cases where
a subscription desired by a client cannot currently be served.</t>
<t>The stream of datastore push updates.</t>
</list> 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.</t>
<section title="Subscription Model">
<t>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.</t>
<t>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.</t>
<t>The complete set of subscription parameters is as follows: <list
style="symbols">
<t>The name of the stream being subscribe to. The subscription model
always assumes the presence of a perpetual and continuous stream
of updates. The stream is called "push-update". However, as
mentioned, it is possible to subscribe to other datastreams, such
as custom datastreams which can be separately configured.</t>
<t>Optional filter(s), describing the subset of data items in the
stream's data records that are of interest to the subscriber. The
server should only send to the subscriber the data items that
match the filter(s), when present. The absence of a filter
indicates that all data items from the stream are of interest to
the subscriber and all data records must be sent in their entirety
to the subscriber. Two filtering mechanisms are provided: subtree
filtering and Xpath filtering, with the semantics described in
[RFC 5277 Section 3.6]. (Additional filter types can be added
through extensions.)</t>
<t>An identifier for the subscription.</t>
<t>An optional start time. Used to trigger replays starting at the
provided time. Its semantics are those in [RFC 5277].</t>
<t>An optional stop time. Used to limit temporarily the events of
interest. Its semantics are those in [RFC 5277].</t>
<t>For subscriptions to "push-update", a subscription policy
definition regarding the update trigger to send new updates. The
trigger can be periodic or based on change. For periodic
subscriptions, the trigger is defined by a parameter that
defines the interval with which
updates are to be pushed. For on-change subscriptions,
the trigger occurs when a change in the subscribed information
is detected. On-change subscriptions have more complex semantics
that is guided by additional parameters. One parameter specifies
the dampening period, i.e. the interval that must pass before
a successive update for the same data node is sent. Other parameters
allow to restrict the types of changes for which updates are sent
(changes to object values, object creation or deletion events), and
to specify the magnitude of change that must occur before an update
is triggered.
Please refer also to
<xref target="on-change"/> and
<xref target="Addl-on-change-triggers"/>.
</t>
<t>An encoding for the data in the push updates, e.g. XML
or JSON.</t>
</list></t>
<t>It is conceivable that additional subscription parameters might be
added in the future. This can be accomplished through augmentation
of the subscription data model.</t>
</section>
<section title="Negotiation of Subscription Policies">
<t>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. </t>
<t>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.</t>
<t>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.
</t>
</section>
<section anchor="on-change" title="On-Change Considerations">
<t>
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.
</t>
<t>
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.
</t>
<t>
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.
</t>
<t>
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.
</t>
<t>
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.
</t>
</section>
<section anchor="Addl-on-change-triggers"
title="Additional on-change update triggers">
<t>
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.
</t>
<t>
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.
</t>
</section>
<section title="Data Encodings">
<t> 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
<xref target="RFC6020"/>. JSON encoding rules are defined in
<xref target="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.</t>
<t>
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. </t>
</section>
<section title="Custom Datastreams">
<t>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.</t>
<t>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.</t>
<t>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.</t>
</section>
<section title="Push Data Stream and Transport Mapping">
<t>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.</t>
<t>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.)</t>
<t>The notification contains several parameters: <list style="symbols">
<t>A subscription correlator, referencing the name of the
subscription on whose behalf the notification is sent.</t>
<t>A data node that contains a representation of the datastore
subtree containing the updates. The subtree is filtered per access
control rules to contain only data that the subscriber is
authorized to see. Also, depending on the subscription type, i.e.,
specifically for on-change subscriptions, the subtree contains
only the data nodes that contain actual changes. (This can be
simply a node of type string or, for XML-based encoding,
anyxml.)</t>
</list> Notifications are sent using <notification> elements
as defined in <xref target="RFC5277"/>. Alternative transports are
conceivable but outside the scope of this specification.</t>
<t>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.</t>
<t>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.</t>
<t>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.</t>
<t>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:</t>
<figure align="center" anchor="push-example" title="Push example">
<artwork align="left">
<?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>
</artwork>
</figure>
</section>
<section title="Subscription operations">
<t>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.</t>
<t>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 <xref target="YANG-module"/>. Specifically:
<list style="symbols">
<t>
An additional parameter is added to allow for the specification of
trigger policy. If the trigger is periodic, a parameter specifies
the period with which updates are to occur. If the trigger is on change,
a parameter specifies a dampening period that defines how much time must
pass before another update for a data node is sent, once an update for
that data node is sent. Additional optional parameters can further refine
trigger behavior, such as restrictions on the types of changes for which
updates are to be sent.
</t>
<t>
An additional parameter is added to allow to specify, as an option,
the desired
encoding of the data payload.
</t>
</list>
</t>
<t>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.</t>
<t>The example below illustrates a subscription for a periodic push of
all data under a container called foo.</t>
<figure align="center" anchor="subscription-example"
title="Subscription example">
<artwork align="left">
<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>
</artwork>
</figure>
<t>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.
</t>
<t>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 <xref target="Authorization"/>.)
</t>
<t>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.</t>
<figure align="center" anchor="subscription-negotiation-example"
title="Subscription negotiation example">
<artwork align="left">
<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>
</artwork>
</figure>
<t>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.</t>
<t>To facilitate datastore-push subscriptions, an additional RPC is
introduced, <delete-subscription>.</t>
<t>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.</t>
<figure align="center" anchor="subscription-deletion"
title="Subscription deletion">
<artwork align="left">
<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>
</artwork>
</figure>
<t>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.</t>
<figure align="center" anchor="subscription-modification"
title="Modify subscription">
<artwork align="left">
<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>
</artwork>
</figure>
</section>
<section title="A YANG data model for management of datastore push subscriptions">
<t>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.</t>
<t>For this purpose, a YANG data model is introduced, which is
depicted in the following figure.</t>
<figure align="center" anchor="model-structure"
title="Model structure">
<artwork align="left">
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
</artwork>
</figure>
<t>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.</t>
<t>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.</t>
<t>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: <list style="symbols">
<t>A subscription has been temporarily suspended (including the
reason)</t>
<t>A subscription (that had been suspended earlier) is once again
operational</t>
<t>A subscription has been abnormally terminated (including the
reason)</t>
<t>A subscription has been modified (including the current set of
subscription parameters in effect)</t>
</list> 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.</t>
</section>
<section title="Other considerations">
<section anchor="Authorization" title="Authorization">
<t>
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.
</t>
<t>The authorization model for data in YANG datastores is described
in the Netconf Access Control Model <xref target="RFC6536"/>.
However, some clarifications to that RFC are needed so that the
desired access control behavior is applied to pushed updates.
</t>
<t>
One of these clarifications is that a subscription may only be
established if the Subscriber has read access to the target data node.
</t>
<figure align="center" anchor="access-control-subscription"
title="Access control for subscription">
<artwork align="left">
+-------------+ +-------------+
subscription | protocol | | target |
request --> | operation | -------------> | data node |
| allowed? | datastore | access |
+-------------+ or state | allowed? |
data access +-------------+
</artwork>
</figure>
<t>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).
</t>
<t>Another clarification to <xref target="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.
</t>
<figure align="center" anchor="access-control-push-update"
title="Access control for push updates">
<artwork align="left">
+-------------+ +-------------------+
subscription | data node | yes | |
update --> | access | ---> | add data node |
| allowed? | | to update message |
+-------------+ +-------------------+
</artwork>
</figure>
<t>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. </t>
</section>
<section title="Additional subscription primitives">
<t>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.
</t>
<t>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.</t>
</section>
<section title="Robustness and reliability considerations">
<t>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.</t>
</section>
<section title="Update size and fragmentation considerations">
<t>
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.
</t>
</section>
<section title="Additional data streams">
<t>
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:
<list style="symbols">
<t>operdata-push, a datastream containing all operational (read-only) data
of a YANG datastore</t>
<t>operdata-nocounts-push, a datastream containing all operational
(read-only) data with the exception of counters</t>
</list>
</t>
<t>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.
</t>
</section>
<section title="Subscription persistency">
<t>
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.
</t>
<t>
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.
</t>
</section>
<section anchor="implementation-considerations"
title="Implementation considerations">
<t>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.</t>
<t>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.</t>
<t>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.</t>
<t>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.</t>
<t>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.
</t>
</section>
</section>
</section>
<section anchor="YANG-module" title="YANG module">
<t><figure>
<artwork>
<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>
</artwork>
</figure></t>
</section>
<section title="Security Considerations">
<t>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.</t>
<t>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.</t>
</section>
</middle>
<back>
<references title="Normative References">
&RFC1157;
<reference anchor="RFC5277">
<front>
<title>NETCONF Event Notifications</title>
<author fullname="Sharon Chisholm" initials="S" surname="Chisholm">
<organization/>
</author>
<author fullname="Hector Trevino" initials="H" surname="Trevino">
<organization/>
</author>
<date month="July" year="2008"/>
</front>
<seriesInfo name="RFC" value="5277"/>
</reference>
<reference anchor="RFC6470">
<front>
<title>Network Configuration Protocol (NETCONF) Base
Notifications</title>
<author fullname="Andy Bierman" initials="A" surname="Bierman">
<organization/>
</author>
<date month="February" year="2012"/>
</front>
<seriesInfo name="RFC" value="5277"/>
</reference>
&RFC6020;
&RFC6241;
&RFC6536;
</references>
<references title="Informative References">
<reference anchor="I-D.ietf-netconf-restconf">
<front>
<title>RESTCONF Protocol</title>
<author fullname="A. Bierman" initials="A." surname="Bierman">
<organization/>
</author>
<author fullname="M. Bjorklund" initials="M." surname="Bjorklund">
<organization/>
</author>
<author fullname="K. Watsen" initials="K." surname="Watsen">
<organization/>
</author>
<date month="June" year="2015"/>
</front>
<seriesInfo name="I-D" value="draft-ietf-netconf-restconf-06"/>
</reference>
<reference anchor="I-D.i2rs-pub-sub-requirements">
<front>
<title>Requirements for Subscription to YANG Datastores</title>
<author fullname="Eric Voit" initials="E" surname="Voit">
<organization/>
</author>
<author fullname="Alexander Clemm" initials="A" surname="Clemm">
<organization/>
</author>
<author fullname="Alberto Gonzalez Prieto" initials="A"
surname="Gonzalez Prieto">
<organization/>
</author>
<date day="3" month="March" year="2015"/>
</front>
<seriesInfo name="Internet-Draft"
value="draft-ietf-i2rs-pub-sub-requirements-00"/>
<format target="http://www.ietf.org/internet-drafts/draft-ietf-i2rs-pub-sub-requirements-00.txt"
type="TXT"/>
</reference>
<reference anchor="I-D.voit-netmod-peer-mount-requirements">
<front>
<title>Requirements for Peer Mounting of YANG subtrees from Remote
Datastores</title>
<author fullname="Eric Voit" initials="E" surname="Voit">
<organization/>
</author>
<author fullname="Alexander Clemm" initials="A" surname="Clemm">
<organization/>
</author>
<author fullname="Sander Mertens" initials="S" surname="Mertens">
<organization/>
</author>
<date day="9" month="March" year="2015"/>
</front>
<seriesInfo name="Internet-Draft"
value="draft-voit-netmod-peer-mount-requirements-02"/>
<format target="http://www.ietf.org/internet-drafts/draft-voit-netmod-peer-mount-requirements-02.txt"
type="TXT"/>
</reference>
<reference anchor="I-D.clemm-netmod-mount">
<front>
<title>Mounting YANG-defined information from remote
datastores</title>
<author fullname="Alexander Clemm" initials="A" surname="Clemm">
<organization/>
</author>
<author fullname="Jan Medved" initials="J" surname="Medved">
<organization/>
</author>
<author fullname="Eric Voit" initials="E" surname="Voit">
<organization/>
</author>
<date day="10" month="April" year="2015"/>
</front>
<seriesInfo name="Internet-Draft" value="draft-clemm-netmod-mount-03"/>
<format target="http://www.ietf.org/internet-drafts/draft-clemm-netmod-mount-03.txt"
type="TXT"/>
</reference>
<reference anchor="I-D.ietf-netmod-yang-json">
<front>
<title>JSON Encoding of Data Modeled with YANG</title>
<author fullname="Ladislav Lhotka" initials="L" surname="Lhotka">
<organization/>
</author>
<date day="12" month="June" year="2015"/>
</front>
<seriesInfo name="Internet-Draft" value="draft-ietf-netmod-yang-json-04"/>
<format target="http://www.ietf.org/internet-drafts/draft-ietf-netmod-yang-json-04.txt"
type="TXT"/>
</reference>
<!--
&I-D.ietf-netmod-interfaces-cfg;
-->
</references>
</back>
</rfc>
| PAFTECH AB 2003-2026 | 2026-04-23 20:34:48 |