module ietf-yang-push {
yang-version 1.1;
namespace "urn:ietf:params:xml:ns:yang:ietf-yang-push";
prefix yp;
import ietf-yang-types {
prefix yang;
}
import ietf-subscribed-notifications {
prefix sn;
}
import ietf-datastores {
prefix ds;
}
import ietf-restconf {
prefix rc;
}
organization "IETF";
contact
"WG Web:
WG List:
Editor: Alexander Clemm
Editor: Eric Voit
Editor: Alberto Gonzalez Prieto
Editor: Ambika Prasad Tripathy
Editor: Einar Nilsen-Nygaard
Editor: Andy Bierman
Editor: Balazs Lengyel
";
description
"This module contains YANG specifications for YANG push.";
revision 2018-02-23 {
description
"Initial revision.";
reference
"draft-ietf-netconf-yang-push-15";
}
/*
* FEATURES
*/
feature on-change {
description
"This feature indicates that on-change triggered subscriptions
are supported.";
}
/*
* IDENTITIES
*/
/* Error type identities for datastore subscription */
identity resynch-subscription-error {
description
"Problem found while attempting to fulfill an
'resynch-subscription' RPC request. ";
}
identity cant-exclude {
base sn:establish-subscription-error;
description
"Unable to remove the set of 'excluded-changes'. This means the
publisher is unable to restrict 'push-change-update's to just the
change types requested for this subscription.";
}
identity datastore-not-subscribable {
base sn:establish-subscription-error;
base sn:subscription-terminated-reason;
description
"This is not a subscribable datastore.";
}
identity no-such-subscription-resynch {
base resynch-subscription-error;
description
"Referenced subscription doesn't exist. This may be as a result of
a non-existent subscription ID, an ID which belongs to another
subscriber, or an ID for configured subscription.";
}
identity on-change-unsupported {
base sn:establish-subscription-error;
description
"On-change is not supported for any objects which are selectable
by this filter.";
}
identity on-change-synch-unsupported {
base sn:establish-subscription-error;
description
"Neither synch on start nor resynchronization are supported for
this subscription. This error will be used for two reasons. First
if an 'establish-subscription' RPC doesn't include
'no-synch-on-start', yet the publisher can't support sending a
'push-update' for this subscription for reasons other than
'on-change-unsupported' or 'synchronization-size'. And second, if
the 'resynch-subscription' RPC is invoked either for an existing
periodic subscription, or for an on-change subscription which
can't support resynchronization.";
}
identity period-unsupported {
base sn:establish-subscription-error;
base sn:modify-subscription-error;
base sn:subscription-suspended-reason;
description
"Requested time period is too short. This can be for both
periodic and on-change subscriptions (with or without
dampening.)
Hints suggesting alternative periods may be returned as
supplemental information when this expressed.";
}
identity result-too-big {
base sn:establish-subscription-error;
base sn:modify-subscription-error;
base sn:subscription-suspended-reason;
description
"Periodic or on-change push update datatrees exceed a maximum size
limit. Hints on estimated size of what was too big may be
returned as supplemental information when this expressed.";
}
identity synchronization-size {
base sn:establish-subscription-error;
base sn:modify-subscription-error;
base resynch-subscription-error;
base sn:subscription-suspended-reason;
description
"Synch-on-start or resynchronization datatree exceeds a maximum
size limit.
Where this identity is referenced as an 'error-app-tag' within an
RPC response, the response's 'error-info' may contain:";
}
identity unchanging-selection {
base sn:establish-subscription-error;
base sn:modify-subscription-error;
base sn:subscription-terminated-reason;
description
"Selection filter is unlikely to ever select datatree nodes. This
means that based on the subscriber's current access rights, the
publisher recognizes that the selection filter is unlikely to ever
select datatree nodes which change. Examples for this might be
that node or subtree doesn't exist, read access is not permitted
for a receiver, or static objects that only change at reboot have
been chosen.";
}
/*
* TYPE DEFINITIONS
*/
typedef change-type {
type enumeration {
enum "create" {
description
"Create a new data resource if it does not already exist. If
it already exists, replace it.";
}
enum "delete" {
description
"Delete a data resource if it already exists. If it does not
exist, take no action.";
}
enum "insert" {
description
"Insert a new user-ordered data resource";
}
enum "merge" {
description
"merge the edit value with the target data resource; create
if it does not already exist";
}
enum "move" {
description
"Reorder the target data resource";
}
enum "replace" {
description
"Replace the target data resource with the edit value";
}
enum "remove" {
description
"Remove a data resource if it already exists ";
}
}
description
"Specifies different types of datastore changes.";
reference
"RFC 8072 section 2.5, with a delta that it is valid for a
receiver to process an update record which performs a create
operation on a datastore node the receiver believes exists, or to
process a delete on a datastore node the receiver believes is
missing.";
}
typedef selection-filter-ref {
type leafref {
path "/sn:filters/yp:selection-filter/yp:identifier";
}
description
"This type is used to reference a selection filter.";
}
/*
* GROUP DEFINITIONS
*/
grouping datastore-criteria {
description
"A grouping to define criteria for which selected objects from
a targeted datastore should be included in push updates.";
leaf datastore {
type identityref {
base ds:datastore;
}
mandatory true;
description
"Datastore from which to retrieve data.";
}
uses selection-filter-objects;
}
grouping selection-filter-types {
description
"This grouping defines the types of selectors for objects from a
datastore.";
choice filter-spec {
description
"The content filter specification for this request.";
anydata datastore-subtree-filter {
if-feature "sn:subtree";
description
"This parameter identifies the portions of the
target datastore to retrieve.";
}
leaf datastore-xpath-filter {
if-feature "sn:xpath";
type yang:xpath1.0;
description
"This parameter contains an XPath expression identifying the
portions of the target datastore to retrieve.
If the expression returns a node-set, all nodes in the
node-set are selected by the filter. Otherwise, if the
expression does not return a node-set, the filter
doesn't select any nodes.
The expression is evaluated in the following XPath context:
o The set of namespace declarations are those in scope on
the 'xpath-filter' leaf element.
o The set of variable bindings is empty.
o The function library is the core function library, and
the XPath functions defined in section 10 in RFC 7950.
o The context node is the root node of the target
datastore.";
}
}
}
grouping selection-filter-objects {
description
"This grouping defines a selector for objects from a
datastore.";
choice selection-filter {
description
"The source of the selection filter applied to the subscription.
This will come either referenced from a global list, or be
provided within the subscription itself.";
case by-reference {
description
"Incorporate a filter that has been configured separately.";
leaf selection-filter-ref {
type selection-filter-ref;
mandatory true;
description
"References an existing selection filter which is to be
applied to the subscription.";
}
}
case within-subscription {
description
"Local definition allows a filter to have the same lifecycle
as the subscription.";
uses selection-filter-types;
}
}
}
grouping update-policy-modifiable {
description
"This grouping describes the datastore specific subscription
conditions that can be changed during the lifetime of the
subscription.";
choice update-trigger {
description
"Defines necessary conditions for sending an event record to
the subscriber.";
case periodic {
container periodic {
presence "indicates an periodic subscription";
description
"The publisher is requested to notify periodically the
current values of the datastore as defined by the selection
filter.";
leaf period {
type yang:timeticks;
mandatory true;
description
"Duration of time which should occur between periodic
push updates.";
}
leaf anchor-time {
type yang:date-and-time;
description
"Designates a timestamp before or after which a series of
periodic push updates are determined. The next update
will take place at a whole multiple interval from the
anchor time. For example, for an anchor time is set for
the top of a particular minute and a period interval of a
minute, updates will be sent at the top of every minute
this subscription is active.";
}
}
}
case on-change {
if-feature "on-change";
container on-change {
presence "indicates an on-change subscription";
description
"The publisher is requested to notify changes in values in
the datastore subset as defined by a selection filter.";
leaf dampening-period {
type yang:timeticks;
default 0;
description
"Specifies the minimum interval between the assembly of
successive update records for a single receiver of a
subscription. Whenever subscribed objects change, and a
dampening period interval (which may be zero) has elapsed
since the previous update record creation for a receiver,
then any subscribed objects and properties which have
changed since the previous update record will have their
current values marshalled and placed into a new update
record.";
}
}
}
}
}
grouping update-policy {
description
"This grouping describes the datastore specific subscription
conditions of a subscription.";
uses update-policy-modifiable {
augment "update-trigger/on-change/on-change" {
description
"Includes objects not modifiable once subscription is
established.";
leaf no-synch-on-start {
type empty;
description
"The presence of this object restricts an on-change
subscription from sending push-update notifications. When
present, pushing a full selection per the terms of the
selection filter MUST NOT be done for this subscription.
Only updates about changes, i.e. only push-change-update
notifications are sent. When absent (default behavior),
in order to facilitate a receiver's synchronization, a full
update is sent when the subscription starts using a
push-update notification. After that, push-change-update
notifications are exclusively sent unless the publisher
chooses to resynch the subscription via a new push-update
notification.";
}
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.";
}
}
}
}
grouping hints {
description
"Parameters associated with some error for a subscription made
upon a datastore.";
leaf period-hint {
type yang:timeticks;
description
"Returned when the requested time period is too short. This
hint can assert a viable period for either a periodic push
cadence or an on-change dampening interval.";
}
leaf filter-failure-hint {
type string;
description
"Information describing where and/or why a provided filter
was unsupportable for a subscription.";
}
leaf object-count-estimate {
type uint32;
description
"If there are too many objects which could potentially be
returned by the selection filter, this identifies the estimate
of the number of objects which the filter would potentially
pass.";
}
leaf object-count-limit {
type uint32;
description
"If there are too many objects which could be returned by the
selection filter, this identifies the upper limit of the
publisher's ability to service for this subscription.";
}
leaf kilobytes-estimate {
type uint32;
description
"If the returned information could be beyond the capacity of
the publisher, this would identify the data size which could
result from this selection filter.";
}
leaf kilobytes-limit {
type uint32;
description
"If the returned information would be beyond the capacity of
the publisher, this identifies the upper limit of the
publisher's ability to service for this subscription.";
}
}
/*
* RPCs
*/
rpc resynch-subscription {
if-feature "on-change";
description
"This RPC allows a subscriber of an active on-change
subscription to request a full push of objects in their current
state. A successful result would invoke a push-update of all
datastore objects that the subscriber is permitted to access.
This request may only come from the same subscriber using the
establish-subscription RPC.";
input {
leaf identifier {
type sn:subscription-id;
mandatory true;
description
"Identifier of the subscription that is to be resynched.";
}
}
}
rc:yang-data resynch-subscription-error {
container resynch-subscription-error {
description
"If a 'resynch-subscription' RPC fails, the subscription is not
resynched and the RPC error response MUST indicate the reason
for this failure. This yang-data MAY be inserted as structured
data within a subscription's RPC error response to indicate the
failure reason.";
leaf reason {
type identityref {
base resynch-subscription-error;
}
mandatory true;
description
"Indicates the reason why the publisher has declined a request
for subscription resynchronization.";
}
uses hints;
}
}
augment "/sn:establish-subscription/sn:input" {
description
"This augmentation adds additional subscription parameters that
apply specifically to datastore updates to RPC input.";
uses update-policy;
}
augment "/sn:establish-subscription/sn:input/sn:target" {
description
"This augmentation adds the datastore as a valid target
for the subscription to RPC input.";
case datastore {
description
"Information specifying the parameters of an request for a
datastore subscription.";
uses datastore-criteria;
}
}
rc:yang-data establish-subscription-error-datastore {
container establish-subscription-error-datastore {
description
"If any 'establish-subscription' RPC parameters are
unsupportable against the datastore, a subscription is not
created and the RPC error response MUST indicate the reason why
the subscription failed to be created. This yang-data MAY be
inserted as structured data within a subscription's RPC error
response to indicate the failure reason. This yang-data MUST be
inserted if hints are to be provided back to the subscriber.";
leaf reason {
type identityref {
base sn:establish-subscription-error;
}
description
"Indicates the reason why the subscription has failed to
be created to a targeted datastore.";
}
uses hints;
}
}
augment "/sn:modify-subscription/sn:input" {
description
"This augmentation adds additional subscription parameters
specific to datastore updates.";
uses update-policy-modifiable;
}
augment "/sn:modify-subscription/sn:input/sn:target" {
description
"This augmentation adds the datastore as a valid target
for the subscription to RPC input.";
case datastore {
description
"Information specifying the parameters of an request for a
datastore subscription.";
uses selection-filter-objects;
}
}
rc:yang-data modify-subscription-error-datastore {
container modify-subscription-error-datastore {
description
"This yang-data MAY be provided as part of a subscription's RPC
error response when there is a failure of a
'modify-subscription' RPC which has been made against a
datastore. This yang-data MUST be used if hints are to be
provides back to the subscriber.";
leaf reason {
type identityref {
base sn:modify-subscription-error;
}
description
"Indicates the reason why the subscription has failed to
be modified.";
}
uses hints;
}
}
/*
* NOTIFICATIONS
*/
notification push-update {
description
"This notification contains a push update, containing data
subscribed to via a subscription. This notification is sent for
periodic updates, for a periodic subscription. It can also be
used for synchronization updates of an on-change subscription.
This notification shall only be sent to receivers of a
subscription; it does not constitute a general-purpose
notification.";
leaf subscription-id {
type sn:subscription-id;
description
"This references the subscription which drove the notification
to be sent.";
}
leaf incomplete-update {
type empty;
description
"This is a flag which indicates that not all datastore nodes
subscribed to are included with this update. In other words,
the publisher has failed to fulfill its full subscription
obligations, and despite its best efforts is providing an
incomplete set of objects.";
}
anydata datastore-contents {
description
"This contains the updated data. It constitutes a snapshot
at the time-of-update of the set of data that has been
subscribed to. The format and syntax of the data
corresponds to the format and syntax of data that would be
returned in a corresponding get operation with the same
selection filter parameters applied.";
}
}
notification push-change-update {
if-feature "on-change";
description
"This notification contains an on-change push update. This
notification shall only be sent to the receivers of a
subscription; it does not constitute a general-purpose
notification.";
leaf subscription-id {
type sn:subscription-id;
description
"This references the subscription which drove the notification
to be sent.";
}
leaf incomplete-update {
type empty;
description
"The presence of this object indicates not all changes which
have occurred since the last update are included with this
update. In other words, the publisher has failed to
fulfill its full subscription obligations, for example in
cases where it was not able to keep up with a change burst.";
}
anydata datastore-changes {
description
"This contains the set of datastore changes needed
to update a remote datastore starting at the time of the
previous update, per the terms of the subscription. Changes
are encoded analogous to the syntax of a corresponding yang-
patch operation, i.e. a yang-patch operation applied to the
datastore implied by the previous update to result in the
current state.";
reference
"RFC 8072 section 2.5, with a delta that it is ok to receive
ability create on an existing node, or receive a delete on a
missing node.";
}
}
augment "/sn:subscription-started" {
description
"This augmentation adds many datastore specific objects to
the notification that a subscription has started.";
uses update-policy;
}
augment "/sn:subscription-started/sn:target" {
description
"This augmentation allows the datastore to be included as part
of the notification that a subscription has started.";
case datastore {
uses datastore-criteria {
refine "selection-filter/within-subscription" {
description
"Specifies where the selection filter, and where it came
from within the subscription and then populated within this
notification. If the 'selection-filter-ref' is populated,
the filter within the subscription came from the 'filters'
container. Otherwise it is populated in-line as part of the
subscription itself.";
}
}
}
}
augment "/sn:subscription-modified" {
description
"This augmentation adds many datastore specific objects to
the notification that a subscription has been modified.";
uses update-policy;
}
augment "/sn:subscription-modified/sn:target" {
description
"This augmentation allows the datastore to be included as part
of the notification that a subscription has been modified.";
case datastore {
uses datastore-criteria {
refine "selection-filter/within-subscription" {
description
"Specifies where the selection filter, and where it came
from within the subscription and then populated within this
notification. If the 'selection-filter-ref' is populated,
the filter within the subscription came from the 'filters'
container. Otherwise it is populated in-line as part of the
subscription itself.";
}
}
}
}
/*
* DATA NODES
*/
augment "/sn:filters" {
description
"This augmentation allows the datastore to be included as part
of the selection filtering criteria for a subscription.";
list selection-filter {
key "identifier";
description
"A list of pre-positioned filters that can be applied
to datastore subscriptions.";
leaf identifier {
type sn:filter-id;
description
"An identifier to differentiate between selection filters.";
}
uses selection-filter-types;
}
}
augment "/sn:subscriptions/sn:subscription" {
description
"This augmentation adds many datastore specific objects to a
subscription.";
uses update-policy;
}
augment "/sn:subscriptions/sn:subscription/sn:target" {
description
"This augmentation allows the datastore to be included as part
of the selection filtering criteria for a subscription.";
case datastore {
uses datastore-criteria;
}
}
}