Internet-Draft | ECA YANG | November 2020 |
Wu, et al. | Expires 5 May 2021 | [Page] |
This document defines a YANG data model for Event Condition Action (ECA) policy management. The ECA policy YANG module provides the ability to delegate some network management functions to the server which can take simple and instant action when a trigger condition on the system state is met.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 5 May 2021.¶
Copyright (c) 2020 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 (https://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.¶
Traditional approaches for network to automatically perform corrective actions in response to network events have been largely built on centralized policy based management [RFC3198]. With centralized network management, the managed object state or operational state spanning across the devices needs to be retrieved by the client from various different servers. However there are issues associated with centralized network management:¶
A more effective alternative to centralized network management is to delegate network management functions to servers in the network and allow each server to monitor state changes of managed objects. Accordingly there is a need for a service to provide continuous performance monitoring, detect defects and failures, and take corrective action.¶
This document defines an ECA Policy management YANG data model. The ECA Policy YANG allows the client to move the network management task to the server, which provides the ability to control the configurations and monitor state parameters, and take simple and instant action on the server when a trigger condition on the system state is met.¶
The data model in this document is designed to be compliant with the Network Management Datastore Architecture (NMDA) [RFC8342].¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119]. In this document, these words will appear with that interpretation only when in ALL CAPS. Lower case uses of these words are not to be interpreted as carrying [RFC2119] significance.¶
The following terms are defined in [RFC7950] [RFC3178] and are not redefined here:¶
This document uses the following terms:¶
Condition can be seen as a logical test that, if satisfied or evaluated to be true, causes the action to be carried out.¶
Tree diagrams used in this document follow the notation defined in [RFC8340].¶
A ECA policy rule is read as: when event occurs in a situation where condition is true, then action is executed. Therefore ECA comprises three key elements: event, associated conditions, and actions. These three elements should be pushed down and configured on the server by the client. If the action is rejected by the server duing ECA policy execution, the action should be rolled back and cleaned up.¶
ECA policy variable (PV) generically represents datastore states that change (or "vary"), and that is set or evaluated by software. The value of ECA policy variable is used for modeling values and constants used in policy conditions and actions. In policy, conditions and actions can abstract information as "policy variables" to be evaluated in logical expressions, or set by actions, e.g., the policy condition has the semantics "variable matches value" while policy action has the semantics "set variable to value".¶
In ECA, two type of policy variables are defined, pv-source variable and pv-result variable. pv-source variable represents an XPath expression input, which contains one of four data types: Boolean, Number, String, and Node Set while pv-result variable represents the value of the result of an Policy Variable evaluation.¶
Each ECA policy variable has the following two attributes:¶
The following operations are allowed with/on a PV:¶
PVs could also be a source of information sent to the client in notification messages.¶
PVs could be also used in condition expressions.¶
The model structure for the Policy Variable is shown below:¶
+--rw policy-variables | +--rw policy-variable* [name] | +--rw name string | +--rw type identityref | +--rw (xpath-value-choice)? | +--:(policy-source) | | +--rw (pv-source) | | +--:(xpath-expr) | | | +--rw xpath-expr? yang:xpath1.0 | | +--:(scalar-constant) | | | +--rw scalar-constant? string | | +--:(nodeset-constant) | | +--rw nodeset-constant? <anydata> | +--:(policy-result) | +--rw (pv-result) | +--:(scalar-value) | | +--rw scalar-value? string | +--:(nodeset-value) | +--rw nodeset-value? <anydata>¶
The ECA Event is any subscribable event notification either explicitly defined in a YANG module (e.g., interface management model) supported by the server or a event stream conveyed to the server via YANG Push subscription. The ECA event are used to keep track of state of changes associated with one of multiple operational state data objects in the network device.¶
Each ECA Event can be classified into server event, datastore event, timer event, diagnostics event and has the following common attributes:¶
For server event, the following additional attributes are defined:¶
For datastore event, the following additional attributes are defined:¶
A client may define an event of interest by making use of YANG PUSH subscription. Specifically, the client may configure an ECA event according to the ECA model specifying the event's name, as well as the name of corresponding PUSH subscription. In this case, the server is expected to:¶
All events (specified in at least one ECA pushed to the server) are required to be constantly monitored by the server. One way to think of this is that the server subscribes to its own publications with respect to all events that are associated with at least one ECA.¶
The model structure for the ECA Event is shown below:¶
+--rw events | +--rw event* [event-name] | +--rw event-name string | +--rw event-type? identityref | +--rw policy-variable* -> /gncd/policy-variables/policy-variable/name | +--rw local-policy-variable* -> /gncd/ecas/eca/policy-variable/name | +--rw (type-choice)? | +--:(server-event) | | +--rw event-stream? string | | +--rw event-module? string | | +--rw event? <anydata> | +--:(datastore-event) | | +--rw datatore? string | | +--rw data-path? string | | +--rw data? <anydata> | +--:(timer-event) | +--:(diagnostics-event)¶
The ECA Condition is the logical expression that is specified in a form of Xpath expression and evaluated to TRUE or FALSE. The XPath expression specifies an arbitrary logical/mathematical expression; The elements of the ECA Condition expression are referred by the XPaths pointing to referred datastore states.¶
The ECA Condition expression in the form of XPath expression allows for specifying a condition of arbitrary complexity as a single string with an XPath expression, in which pertinent PVs and datastore states are referred to by their respective positions in the YANG tree.¶
ECA Conditions are associated with ECA Events and evaluated only within event threads triggered by the event detection.¶
When an ECA Condition is evaluated to TRUE, the associated ECA Action is executed.¶
The model structure for the condition is shown below:¶
+--rw conditions | +--rw condition* [name] | +--rw name string | +--rw (expression-choice)? | +--:(xpath) | +--rw condition-xpath? string¶
Policy variables are mapped to XPath variable bindings so they can be referenced in the XPath expression for a Condition.¶
XPath variables can be used in 2 main ways in an expression:¶
1) anchor of a path-expr $node-set-variable/child1/nested2 2) right-hand side of a primary-expr /foo[name = $scalar-variable]¶
It cannot be used in the middle of a path-expr¶
/interfaces/$node-set-variable/child1/nested2 // NOT OK¶
Since a variable is a primary expression it can be used in XPath expression constructions anywhere a primary-expr is allowed¶
$nodeset-variable1 | $ nodeset-variable2 ($min-length + $avg-length) < $last-length¶
The values of all available policy variables are updated by the server (if required) before the XPath expression is evaluated. The variable binding value MUST NOT change while the XPath expression is being evaluated. If multiple references to the same variable exist in an XPath expression, they MUST resolve to the same value in each instance.¶
Example: "/test1[name=$badfan] and /test2[name=$badfan]" The same value of 'badfan' is expected in each instance.¶
All XPath expressions used in ECA share the following XPath context definition.¶
Not all errors can be detected at configuration time. Error that occur while ECA logis is being evaluated will cause the server to generate an eca-exception notification.¶
If the ECA is scheduled one time, an exception to eca entry execution will be generated if the error occurs. If the ECA is scheduled periodically and duplicated exception notification is generated in the second period interval, ECA entry execution will be disabled automamtically and in addition eca entry disable exeception will be generated and sent to the local client.¶
identity eca-exception-reason { description "Base of all values for the 'reason' leaf in the eca-exception notification."; } identity varbind-unknown { base eca-exception-reason; description "The requested policy variable binding is not defined. The variable binding cannot be resolved in the XPath evaluation."; } identity func-invoke-error { base eca-exception-reason; description "The function call is invoked and return false output."; } identity rpc-call-error { base eca-exception-reason; description "The rpc call is invoked and return false output."; } identity eca-entry-disable { base eca-exception-reason; description "The ECA entry is disabled if the same exception occurs more than once in the periodical ECA."; } // Additional exceptions can be added as needed notification eca-exception { description "This notification is sent when some error occurs while the server is processing ECA logic."; leaf reason { type eca-exception-reason; } }¶
The ECA Action list consists of updates or invocations on local managed object attributes and a set of actions are defined as follows, which will be performed when the corresponding event is triggered:¶
Three points are worth noting:¶
The model structure for the actions is shown below:¶
+--rw actions | +--rw time-schedule! | | +--rw period? centiseconds | +--rw action* [name] | +--rw name string | +--rw action-element* [name] | | +--rw name string | | +--rw action-type? identityref | | +--rw (action-operation)? | | +--:(action) | | | +--rw next-period boolean | | | +--rw action-name? | | | -> /gnca/actions/action/name | | +--:(function-call) | | | +--rw function-call | | | +--rw func-name leafref | | | +--rw policy-source leafref | | | +--rw policy-result leafref | | | +--:(rpc-operation) | | | | +--rw rpc-operation | | | | +--rw rpc-name? string | | | | +--rw nc-action-xpath? string¶
An ECA container includes:¶
Note that this document currently focuses on one event with multiple conditions and actions case. How different ECAs do not impact each other if they share PVs and other components is not in the scope of this document at this moment.¶
A set of common event PVs need to be set for every invocation of condition or action logic:¶
$event-type (string) $event-name (string) For event-type = "server-event" $event-stream (string) $event-module (string) $event-name (string) $event (node-set) The condition can use these PVs directly in an expression An expression can access client-configured PVs of course $event/child[name=$some-global-var] > 10 For event-type = "datastore" $datastore (string) $data-path (string) $data (node-set) The data is defined to be a container with the requested data as child nodes $data/interface[type=$gigabit-eth] // (node-set is an array of data nodes, usually siblings) A standard func call should be defined to specify operation on policy variables and xpath expression and store func result. //Increment count by one each time increment-func is invoked boolean function increment-func(number count) //Decrement count by one each time decrement-func is invoked boolean function decrement-func(number count) //Exit the loop to monitor specific event boolean function exit-func() //Continue the loop to monitor the specific event boolean function continue-func() //set iteration variable as true if count variable is equal to or greater than 1 //set iteration variable as false if count variable is zero boolean function match-func (string expr,number count,boolean iteration) // check every 5 seconds until the same event occurs 2 times sustained-event("$event/child[type=$some-global-var]/descendant[$leaf1 > 10]", 5, 2) boolean function sustained-event (string expr, number interval, number count) test expression 'expr' once per 'interval'. Keep testing once per interval until true result reached, i.e., both xpath expression is evaluated to true and 'count' number of interval on specific data object has been tested true (e.g., the same event occurs 'count' times )Return true if condition tested true for count intervals; Returns false otherwise; // check the event record every 5 seconds and filter the event record with constraint of a specific descendant node to the event record root node filtered-event("$event/child/descendant[$leaf1 > 10]", "$event",5) boolean function filtered-event (string input-expr,string output-expr,number interval)test expression 'expr'once per 'interval' and generate event record output represented by 'output-expr' based on 'input-expr'. Note than 'output-expr'and 'input-expr'share the same root node; A standard rpc should be defined to specify the operation on the event stream // suppress the event stream corresponding to XPATH expression boolean rpc event-duplication-suppress(string expr)¶
The ECA XPath function library is expected to grow over time and additional standard or vendor function libraries should be possible. The server should provide a read-only list of ECA function libraries supported. How it is exposed to the client is beyond scope of this document.¶
+--rw eca-func-libs +--rw eca-function* [func-name] | +--rw func-name string +--rw eca-rpc* [rpc-name] | +--rw rpc-name string +--rw eca-name -> /gncd/ecas/eca/name¶
Note that ECA accesses specific datastores in the same way as YANG Push [RFC8641]. The difference is condition expression is introduced to further filter nodes in the node set and the policy variable is introduced to keep the intermediate states during the interaction between the local client and the server.¶
The following tree diagrams [RFC8340] provide an overview of the data model for the "ietf-eca" module.¶
module: ietf-eca +--rw gncd +--rw policy-variables | +--rw policy-variable* [name] | +--rw name string | +--rw type identityref | +--rw (xpath-value-choice)? | +--:(policy-source) | | +--rw (pv-source) | | +--:(xpath-expr) | | | +--rw xpath-expr? yang:xpath1.0 | | +--:(scalar-constant) | | | +--rw scalar-constant? string | | +--:(nodeset-constant) | | +--rw nodeset-constant? <anydata> | +--:(policy-result) | +--rw (pv-result) | +--:(scalar-value) | | +--rw scalar-value? string | +--:(nodeset-value) | +--rw nodeset-value? <anydata> +--rw events | +--rw event* [event-name] | +--rw event-name string | +--rw event-type? identityref | +--rw policy-variable* -> /gncd/policy-variables/policy-variable/name | +--rw local-policy-variable* -> /gncd/ecas/eca/policy-variable/name | +--rw (type-choice)? | +--:(server-event) | | +--rw event-stream? string | | +--rw event-module? string | | +--rw event? <anydata> | +--:(datastore-event) | | +--rw datatore? string | | +--rw data-path? string | | +--rw data? <anydata> | +--:(timer-event) | | +--rw start-time yang:date-and-time | | +--rw duration centiseconds | | +--rw repeat-option identityref | | +--rw repeat-time-len centiseconds | +--:(diagnostics-event) +--rw conditions | +--rw condition* [name] | +--rw name string | +--rw (expression-choice)? | +--:(xpath) | +--rw condition-xpath? string +--rw actions | +--rw time-schedule! | | +--rw period? centiseconds | +--rw action* [name] | +--rw name string | +--rw action-element* [name] | | +--rw name string | | +--rw action-type? identityref | | +--rw (action-operation)? | | | +--:(action) | | | | +--rw next-period boolean | | | | +--rw action-name? | | | | -> /gnca/actions/action/name | | | +--:(function-call) | | | | +--rw function-call | | | | +--rw func-name leafref | | | | +--rw policy-source leafref | | | | +--rw policy-result leafref | | | +--:(rpc-operation) | | | | +--rw rpc-operation | | | | +--rw rpc-name? string | | | | +--rw nc-action-xpath? string +--rw ecas | +--rw eca* [name] | +--rw name string | +--rw username string | +--rw event-name string | +--rw policy-variable* [name] | | +--rw name leafref | | +--rw is-static? boolean | +--rw condition-action* [name] | | +--rw name string | | +--rw condition* -> /gncd/conditions/condition/name | | +--rw action? -> /gncd/actions/action/name | +---x start | +---x stop | +---x next-action +--rw eca-func-libs +--rw eca-function* [func-name] | +--rw func-name string +--rw eca-rpc* [rpc-name] | +--rw rpc-name string +--rw eca-name -> /gncd/ecas/eca/name notifications: +---n eca-exception | +--ro reason? identityref +---n custom-notification +--ro eventTime yang:date-and-time +--ro event-type? identityref +--ro (type-choice)? | +--:(server-event) | | +--ro event-stream? string | | +--ro event-module? string | | +--ro policy-result leafref | +--:(datastore-event) | | +--ro datatore? string | | +--ro data-path? string | | +--ro policy-result leafref¶
<CODE BEGINS> file "ietf-eca@2019-10-28.yang"¶
module ietf-eca { yang-version 1.1; namespace "urn:ietf:params:xml:ns:yang:ietf-eca"; prefix gnca; import ietf-yang-types { prefix yang; } import ietf-netconf-acm { prefix nacm; reference "RFC8341: Network Configuration Access Control Model"; } organization "IETF Network Configuration (NETCONF) Working Group"; contact "WG Web: <http://tools.ietf.org/wg/netmod/> WG List: <mailto:netmod@ietf.org> Editor: Qin Wu <mailto:bill.wu@huawei.com> Editor: Igor Bryskin <mailto:Igor.Bryskin@huawei.com> Editor: Henk Birkholz <mailto:henk.birkholz@sit.fraunhofer.de> Editor: Xufeng Liu <mailto:xufeng.liu.ietf@gmail.com> Editor: Benoit Claise <mailto:bclaise@cisco.com> Editor: Andy Bierman <mailto:andy@yumaworks.com> Editor: Alexander Clemm <mailto:ludwig@clemm.org>"; description "Event Condition Action (ECA) model."; revision 2018-06-22 { description "Initial revision"; reference "RFC XXXX"; } identity argument-type { description "Possible values are: constant, variable, or datastore state."; } identity comparison-type { description "Possible values are: equal, not-equal, greater, greater-equal, less, less-equal."; } identity logical-operation-type { description "Possible values are: not, or, and."; } identity function-type { description "Possible values are: plus, minus, mult, divide, sustained-event."; } identity sustained-event { description "Identity for standard sustained-event function call, the input variables for sustained-event include string expr, number interval, number count. Keep testing expression 'expr'once per interval until false result reached.Return true if condition tested true for count intervals; Returns false otherwise."; } identity plus { description "Identity for standard plus function call, the input variables for plus function call include src policy argument and dst policy arugment."; } identity minus { description "Identity for standard minus function call, the input variables for plus function call include src policy argument and dst policy arugment."; } identity multiply { description "Identity for standard multiply function call, the input variables for multiply function call include src policy argument and dst policy arugment."; } identity divide { description "Identity for standard divide function call, the input variables for multiply function call include src policy argument and dst policy arugment."; } identity action-type { description "Possible values are: action, function-call, rpc."; } identity event-type { description "Base identity for Event Type."; } identity server-event { base event-type; description "Identity for server event."; } identity datastore-event { base event-type; description "Identity for datastore event."; } identity timer-event { base event-type; description "Identity for timer event."; } identity diagnostics-event { base event-type; description "Identity for diagnostics event."; } identity eca-exception-reason { description "Base of all values for the 'reason' leaf in the eca-exception notification."; } identity varbind-unknown { base eca-exception-reason; description "The requested policy variable binding is not defined. The variable binding cannot be resolved in the XPath evaluation."; } typedef centiseconds { type uint32; description "A period of time, measured in units of 0.01 seconds."; } typedef oper-status { type enumeration { enum completed { description "Completed with no error."; } enum running { description "Currently with no error."; } enum sleeping { description "Sleeping because of time schedule."; } enum stoped { description "Stopped by the operator."; } enum failed { description "Failed with errors."; } enum error-handling { description "Asking the operator to handle an error."; } } description "The operational status of an ECA execution."; } grouping scalar-value { leaf scalar-value { type string; description "Represents an XPath simple value that has an XPath type of Boolean, String, or Number. This value will be converted to an XPath type, as needed. A YANG value is encoded as a string using the same rules as the 'default' value for the data type. An eca-exception notification is generated if a scalar XPath value is used in a path expression, where a node-set is expected. Normally XPath will treat this result as an empty node-set, but this is an ECA programming error."; } } grouping nodeset-value { anydata nodeset-value { description "Represents an XPath node set. A 'node-set' anydata node with no child data nodes represents an empty node-set. Each child node in within this anydata structure represents a subtree that is present in the XPath node-set. An XPath node-set is not required to contain a top-level YANG data node. It is not required to contain an entire complete subtree. It is am implementation-specific manner how a representation of YANG 'anydata' nodes are mapped to specific YANG module schema definitions."; } } grouping scalar-constant { leaf scalar-constant { type string; description "Represents an XPath simple value that has an XPath type of Boolean, String, or Number. This value will be converted to an XPath type, as needed. A YANG value is encoded as a string using the same rules as the 'default' value for the data type. An eca-exception notification is generated if a scalar XPath value is used in a path expression, where a node-set is expected. Normally XPath will treat this result as an empty node-set, but this is an ECA programming error."; } } grouping nodeset-constant { anydata nodeset-constant { description "Represents an XPath node set. A 'node-set' anydata node with no child data nodes represents an empty node-set. Each child node in within this anydata structure represents a subtree that is present in the XPath node-set. An XPath node-set is not required to contain a top-level YANG data node. It is not required to contain an entire complete subtree. It is am implementation-specific manner how a representation of YANG 'anydata' nodes are mapped to specific YANG module schema definitions."; } } grouping pv-source { choice pv-source { mandatory true; description "A PV source represents an XPath result, which contains one of four data types: Boolean, Number, String, and Node Set. XPath defines mechanisms to covert values between these four types. The 'xpath-expr' leaf is used to assign the PV source to the result of an arbitrary XPath expression. The result of this expression evaluation is used internally as needed. The result may be any one of the XPath data types. The 'scalar-constant' leaf is used to represent a Boolean, String, or Number XPath constant value. The 'nodeset-constant' anydata structure is used to represent a constant XPath node-set."; leaf xpath-expr { type yang:xpath1.0; description "Contains an XPath expression that must be evaluated to produce an XPath value. [section X.X] describes the XPath execution environment used to process this object."; } case scalar-constant { uses scalar-constant; } case nodeset-constant { uses nodeset-constant; } } } grouping pv-result { choice pv-result { mandatory true; description "Represents the value of the result of an Policy Variable evaluation. The 'scalar-value' leaf is used to represent a Boolean, String, or Number XPath result value. The 'nodeset-value' anydata structure is used to represent an XPath node-set result."; case scalar-value { uses scalar-value; } case nodeset-value { uses nodeset-value; } } } grouping policy-variable-attributes { description "Defining the policy variable attributes, including name, type and value. These attributes are used as part of the Policy Variable (PV) definition."; leaf name { type string; description "A string to uniquely identify a Policy Variable (PV), either globally for a global PV, or within the soope of ECA for a local PV."; } choice xpath-value-choice { description "The type of a policy variable may be either a common primative type like boolean or a type from existing schema node referenced by an XPath string."; /*case scalar { uses scalar-value; } case nodeset { uses nodeset-value; }*/ case policy-source { uses pv-source; } case policy-result { uses pv-result; } } } grouping action-element-attributes { description "Grouping of action element attributes."; leaf action-type { type identityref { base action-type; } description "Identifies the action type."; } choice action-operation { description "The operation choices that an ECA Action can take."; case action { leaf next-period { type boolean; description "invoke the same eca recursively if the next period is set to true."; } leaf action-name { type leafref { path "/gncd/actions/action/name"; } description "The operation is to execute a configured ECA Action."; } } // action case function-call { container function-call { description "The operation is to call a function, which is of one of a few basic predefined types, such as plus, minus, multiply, devide, or remainder."; leaf function-name { type string; description "The name of function call to be called"; } leaf policy-source { type leafref { path "/gncd/policy-variables/policy-variable/name"; } description "The policy source."; } leaf policy-result { type leafref { path "/gncd/policy-variables/policy-variable/name"; } description "The policy result."; } } } // function-call case rpc-operation { container rpc-operation { description "The operation is to call an RPC, which is defined by a YANG module supported by the server."; leaf rpc-name { type string; description "The name of the YANG RPC or YANG action to be called."; } leaf nc-action-xpath { type string; description "The location where the YANG action is defined. This is used if and only if a YANG action is called. This leaf is not set when a YANG RPC is called."; } } } // rpc-operation /*case notify-operation { container notify-operation { description "The operation is to send a YANG notification."; leaf name { type string; description "Name of the subscribed YANG notification."; } list policy-variable { key "name"; description "A list of policy arguments carried in the notification message."; leaf name { type string; description "A string name used as the list key to form a list of policy arguments."; } } } }*/ } } grouping time-schedule-container { description "Grouping to define a container of a time schedule."; container time-schedule { presence "Presence indicates that the timer is enabled."; description "Specifying the time schedule to execute an ECA Action, or trigger an event."; leaf period { type centiseconds; description "Duration of time that should occur between periodic push updates, in units of 0.01 seconds."; } } } container gncd { nacm:default-deny-all; description "Top level container for Generalized Network Control Automation (gncd)."; container policy-variables { description "Container of global Policy Variables (PVs)."; list policy-variable { key "name"; description "A list of global Policy Variables (PVs), with a string name as the entry key."; uses policy-variable-attributes; } } container events { description "Container of ECA events."; list event { key "event-name"; description "A list of events used as the triggers of ECAs."; leaf event-name { type string; description "The name of the event."; } leaf event-type { type identityref { base event-type; } description "The type of the event."; } leaf-list policy-variable { type leafref { path "/gncd/policy-variables/" + "policy-variable/name"; } description "global policy variables, which are shared by all ECA scripts."; } leaf-list local-policy-variable { type leafref { path "/gncd/ecas/eca/policy-variable/name"; } description "local policy variables, which are kept within an ECA instance, and appears/ disappears with start/stop of the ECA execution."; } choice type-choice { description "The type of an event, including server event and datastore event."; case server-event { leaf event-stream { type string; description "The name of a subscribed stream ."; } leaf event-module { type string; description "The name of YANG data module associated with the subscribed stream."; } anydata event { description "This anydata value MUST Contain the absolute XPath expression identifying the element path to the node that is associated with subscribed stream."; } } case datastore-event { leaf datatore { type string; description "The name of a datatore from which applications subscribe to updates."; } leaf data-path { type string; description "The absolute XPath expression identifying the element path to the node that is associated with subscribed stream.."; } anydata data { description "This anydata value MUST Contain the node that is associated with the data path."; } } case timer-event { leaf start-time { type yang:date-and-time; description "This object specifies the scheduled start date/time to trigger timer event."; } leaf duration { type centiseconds; description "This object specifies duration of the timer event execution."; } leaf repeat-option { type centiseconds; description "This object indicate repeat option, e.g., repeat everyday, everyweek, everymoth,everyyear or every specfiied time length."; } leaf repeat-len { type centiseconds; description "This object specifies the time length in 0.01 seconds after which the timer event is executed for the duration."; } } case diagnostics-event; } } } container conditions { description "Container of ECA Conditions."; list condition { key "name"; description "A list of ECA Conditions."; leaf name { type string; description "A string name to uniquely identify an ECA Condition globally."; } choice expression-choice { description "The choices of expression format to specify a condition, which can be either a XPath string."; case xpath { leaf condition-xpath { type string; description "A XPath string, representing a logical expression, which can contain comparisons of datastore values and logical operations in the XPath format."; } } } } } container actions { description "Container of ECA Actions."; uses time-schedule-container { description "Specifying the time schedule to execute this ECA Action. If not specified, the ECA Action is executed one time immediately when it is called."; } list action { key "name"; description "A list of ECA Actions."; leaf name { type string; description "A string name to uniquely identify an ECA Action globally."; } list action-element { key "name"; description "A list of elements contained in an ECA Action. "; leaf name { type string; description "A string name to uniquely identify the action element within the scope of an ECA action."; } uses action-element-attributes; } } } container ecas { description "Container of ECAs."; list eca { key "name"; description "A list of ECAs"; leaf name { type string; description "A string name to uniquely identify an ECA globally."; } leaf username { type string; mandatory true; description "Name of the user for the session."; } leaf event-name { type string; mandatory true; description "The name of an event that triggers the execution of this ECA."; } list policy-variable { key "name"; description "A list of ECA local Policy Variables (PVs), with a string name as the entry key."; leaf name { type leafref { path "/gncd/policy-variables/policy-variable/name"; } } leaf is-static { type boolean; description "'true' if the PV is static; 'false' if the PV is dynamic. A dynamic PV appears/disappears with the start/stop of the ECA execution; a static PV exists as long as the ECA is configured."; } } list condition-action { key "name"; ordered-by user; description "A list of Condition-Actions, which are configured conditions each with associated actions to be executed if the condition is evaluated to TRUE. The server can do multiple action when the condition is true. If the next-period is set to true, condition-action will be executed recursively. It is also possbile to require multiple conditions to be true in order to do one action."; leaf name { type string; description "A string name uniquely identify a Condition-Action within this ECA."; } leaf-list condition { type leafref { path "/gncd/conditions/condition/name"; } description "The reference to a configured condition."; } leaf action { type leafref { path "/gncd/actions/action/name"; } description "The reference to a configured action."; } } action start { description "Start to execute this ECA. The start action is invoked by the local client when the event type is set to diagnostic event."; } action stop { description "Stop the execution of this ECA. The stop action is invoked by the local client when the event type is set to diagnostic event."; } action next-action { description "Resume the execution of this ECA to complete the next action. The next action is invoked by the local client when the event type is set to diagnostic event."; } } } container eca-func-libs { description "Container of ECA Function Libraries."; list eca-function { key func-name; description "A list of ECA standard function."; leaf func-name { type string; description "A string name to uniquely identify an ECA standard function."; } } list rpc-function { key rpc-name; description "A list of ECA standard function."; leaf rpc-name { type string; description "A string name to uniquely identify an ECA standard RPC."; } } leaf eca-name { type leafref { path "/gncd/ecas/eca/name"; } description "The reference to a configured ECA."; } } // eca-scripts } notification eca-exception { description "This notification is sent when some error occurs while the server is processing ECA logic."; leaf reason { type identityref { base eca-exception-reason; } } } notification custom-notification { description "This notification is sent when some error occurs while the server is processing ECA logic."; leaf eventTime { type yang:date-and-time; description "The event occurrence time"; } leaf event-type { type identityref { base event-type; } description "The type of the event."; } choice type-choice { description "The type of an event, including server event and datastore event."; case server-event { leaf event-stream { type string; description "The name of a subscribed stream ."; } leaf event-module { type string; description "The name of YANG data module associated with the subscribed stream."; } anydata event { description "This anydata value MUST Contain the absolute XPath expression identifying the element path to the node that is associated with subscribed stream."; } } case datastore-event { leaf datatore { type string; description "The name of a datatore from which applications subscribe to updates."; } leaf data-path { type string; description "The absolute XPath expression identifying the element path to the node that is associated with subscribed stream.."; } anydata data { description "This anydata value MUST Contain the node that is associated with the data path."; } } } } }¶
<CODE ENDS>¶
The YANG modules defined in this document MAY be accessed via the RESTCONF protocol [RFC8040] or NETCONF protocol ([RFC6241]). The lowest RESTCONF or NETCONF layer requires that the transport-layer protocol provides both data integrity and confidentiality, see Section 2 in [RFC8040] and [RFC6241]. The lowest NETCONF layer is the secure transport layer, and the mandatory-to-implement secure transport is Secure Shell (SSH)[RFC6242] . The lowest RESTCONF layer is HTTPS, and the mandatory-to-implement secure transport is TLS [RFC5246].¶
The NETCONF access control model [RFC6536] provides the means to restrict access for particular NETCONF or RESTCONF users to a preconfigured subset of all available NETCONF or RESTCONF protocol operations and content.¶
There are a number of data nodes defined in this YANG module that are writable/creatable/deletable (i.e., config true, which is the default). These data nodes may be considered sensitive or vulnerable in some network environments. Write operations (e.g., edit-config) to these data nodes without proper protection can have a negative effect on network operations. These are the subtrees and data nodes and their sensitivity/vulnerability:¶
This document registers two URIs in the IETF XML registry [RFC3688]. Following the format in [RFC3688], the following registrations are requested to be made:¶
--------------------------------------------------------------------- URI: urn:ietf:params:xml:ns:yang:ietf-eca Registrant Contact: The IESG. XML: N/A, the requested URI is an XML namespace. ---------------------------------------------------------------------¶
This document registers one YANG module in the YANG Module Names registry [RFC6020].¶
--------------------------------------------------------------------- Name: ietf-eca Namespace: urn:ietf:params:xml:ns:yang:ietf-eca Prefix: gnca Reference: RFC xxxx ---------------------------------------------------------------------¶
Igor Bryskin, Xufeng Liu, Alexander Clemm, Henk Birkholz, Tianran Zhou contributed to an earlier version of [GNCA]. We would like to thank the authors of that document on event response behaviors delegation for material that assisted in thinking that helped improve this document. We also would like to thanks Jonathan Hansford,Michale Wang, Xiaopeng Qin Yu Yang, Haoyu Song, Tianran Zhou,Aihua Guo,Nicola Sambo,Giuseppe Fioccola for valuable review on this document.¶
Andy Bierman YumaWorks Email: andy@yumaworks.com Alex Clemm Futurewei Email: ludwig@clemm.org Qiufang Ma Huawei Email: maqiufang1@huawei.com Chongfeng Xie China Telecom Email: xiechf@ctbri.com.cn Diego R. Lopez Telefonica Email:diego.r.lopez@telefonica.com¶
Here are two examples of Condition Expression:¶
(a) a condition that only includes data store states and constants, for example:¶
TE metric of Link L in Topology T greater than 100, it can be expressed as follows: "/nw:networks/nw:network[network-id='T']/nt:link[link-id='L']/tet:te\ /tet:te-link-attributes/tet:te-delay-metric > 100"¶
(b) a condition that also includes a Policy Variable, for example:¶
Allocated bandwidth of Link L in Topology T greater than 75% of what is stored in Policy Variable B, it can be expressed as follows: "/nw:networks/nw:network[network-id='T']/nt:link[link-id='L']/tet:te\ /tet:te-link-attributes/tet:max-resv-link-bandwidth\ > (ietf-eca:policy-variables/policy-variable[name='B']/value) * 0.75"¶
+---------------------------+ | Management System | +---------------------------+ | ECA | Model | | V +----------------------^-----+ | Managed Device | | | | | | //--\\ Condition--+ | | | Event| / \ | | | |----->|Actions | | \\--// \ / | | ---- | +----------------------------+¶
The management system designs a new ECA policy based on monitored objects in ietf-interfaces module that support threshold checking and pushes down the ECA policy to control interface behavior in the managed device that supports NETCONF/RESTCONF protocol operation, i.e.,scan all interfaces for a certain type every 5 seconds and check the counters or status, return an array of interface entries (XPath node-set) that match the search and suppress reporting of duplicated events if all conditions are evaluated into true. The XML example snippet is shown as below:¶
<gnca> <policy-variables> <policy-variable> <name>event-repeat-count</name> <scalar-constant>0</scalar-constant> </policy-variable> <policy-variable> <name>interface-statistics-event</name> <xpath-expr>if:interfaces/if:interface[if:type=if:gigabitEthernet, if:oper-status=down]</xpath-expr> </policy-variable> </policy-variables> <events> <event> <event-name>interface-self-monitoring</event-name> <event-type>server-event</event-type> <event-stream>NETCONF</event-stream> <event-module>ietf-interfaces</event-module> <event>if:interfaces/if:interface[if:type=if:gigabitEthernet]</event> </event> </events> <conditions> <condition> <name>if-monitoring-condition1</name> <condition-xpath>event[if:oper-status=down]</condition-xpath> </condition> <condition> <name>if-monitoring-condition2</name> <condition-xpath>event[if:oper-status!=down]</condition-xpath> </condition> <condition> <name>if-monitoring-condition3</name> <condition-xpath>event-repeat-count >1 </condition-xpath> </condition> <condition> <name>if-monitoring-condition4</name> <condition-xpath>event-repeat-count <=1 </condition-xpath> </condition> </conditions> <actions> <time-schedule> <period>5</period> </time-schedule> <action> <name>if-matched-statistics1</name> <action-element> <name>event-filter-action</name> <func-name>filtered-event</func-name> <policy-source>interface-statistics-event</policy-source> <policy-result>event</policy-result> </action-element> <action-element> <name>increment-action</name> <func-name>increment-function</func-name> <policy-source>event-repeat-count</policy-source> <policy-result>event-repeat-count</policy-result> </action-element> <action-element> <name>suppress-action</name> <rpc-operation> <name>suppress-notification</name> </rpc-operation> </action-element> <action-element> <name>continue-check-action</name> <func-name>match-function</func-name> <policy-source>interface-statistics-event</policy-source> <policy-source>event-repeat-count</policy-source> <policy-result>next-period</policy-result> </action-element> </action> <action> <name>if-matched-statistics2</name> <action-element> <name>event-filter-action</name> <func-name>filtered-event</func-name> <policy-source>interface-statistics-event</policy-source> <policy-result>event</policy-result> </action-element> <action-element> <name>increment-action</name> <func-name>increment-function</func-name> <policy-source>event-repeat-count</policy-source> <policy-result>event-repeat-count</policy-result> </action-element> <action-element> <name>continue-check-action</name> <func-name>match-function</func-name> <policy-source>interface-statistics-event</policy-source> <policy-source>event-repeat-count</policy-source> <policy-result>next-period</policy-result> </action-element> </action> <action> <name>if-matched-statistics3</name> <action-element> <name>decrement-action</name> <func-name>decrement-function</func-name> <policy-source>event-repeat-count</policy-source> <policy-result>event-repeat-count</policy-result> </action-element> <action-element> <name>exit-action</name> <func-name>exit-func</func-name> </action-element> </action> </actions> <ecas> <eca> <name>interface-eca-handling</name> <user-name>Bob</user-name> <event-name>interface-self-monitoring</event-name> <condition-action> <name>smart-filter1</name> <condition>if-monitoring-condition1</condition> <condition>if-monitoring-condition3</condition> <action> <name>if-matched-statistics1</name> <action-element> <name>event-filter-action</name> </action-element> <action-element> <name>increment-action</name> </action-element> <action-element> <name>suppress-action</name> </action-element> <action-element> <name>continue-check-action</name> </action-element> </action> </condition-action> <condition-action> <name>smart-filter2</name> <condition>if-monitoring-condition1</condition> <condition>if-monitoring-condition4</condition> <action> <name>if-matched-statistics2</name> <action-element> <name>event-filter-action</name> </action-element> <action-element> <name>increment-action</name> </action-element> <action-element> <name>continue-check-action</name> </action-element> </action> </condition-action> <condition-action> <name>smart-filter3</name> <condition>if-monitoring-condition2</condition> <action> <name>if-matched-statistics3</name> <action-element> <name>decrement-action</name> </action-element> <action-element> <name>exit-action</name> </action-element> </action> </condition-action> </eca> </ecas> <eca-func-libs> <eca-function> <func-name>filtered-event</func-name> </eca-function> <eca-function> <func-name>increment-function</func-name> </eca-function> <eca-function> <func-name>decrement-function</func-name> </eca-function> <eca-function> <func-name>exit-function</func-name> </eca-function> <eca-function> <func-name>match-function</func-name> </eca-function> <eca-rpc> <rpc-name>event-duplication-suppress</rpc-name> </eca-rpc> <eca-name>interface-eca-handling</eca-name> </eca-func-libs> </gnca> // This custom-notification is only sent when there is no duplicated event to occur. <custom-notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"> <eventTime>2016-11-21T13:51:00Z</eventTime> <event-type>server-event</event-type> <event-stream>NETCONF</event-stream> <event-module>ietf-interfaces</event-module> <event>if:interfaces/if:interface[if:type=if:gigabitEthernet]</event> <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces" xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type"> <interface> <name>GE0</name> <type>ianaift:gigabitEthernet</type> <enabled>false</enabled> </interface> ..... <interface> <name>GE1</name> <type>ianaift:gigabitEthernet</type> <enabled>true</enabled> ... </interface> ..... <interface> <name>GE2</name> <type>ianaift:gigabitEthernet</type> ... <enabled>true</enabled> </interface> </eca-report> </custom-notification>¶
In this example, the event name is set to 'interface-self-monitoring', the event type is set to 'server-event', the function name of ECA function libraries is set to 'sustained-event', 'increment-function','decrement-function','match-function','exit-function' the rpc name of ECA function libraries is set to 'event-duplication-suppress',the name of 'condition-action' is corresponding to standard function calls described above. The pseudo code of ECA logic can be described as follows:¶
count = 0; while { next-period = true} if(interface is down ) { event= filtered event;//eca exception will be notified to the local client if invoking filtered event fails count++; if(count > 1){ suppress event;//eca exception will be notified to the local client if invoking filtered event fails next-period = true; exit; }else if( count <= 1) { next-period = true; call custom-notification; continue; } }else if ( interface is not down){ next-period = false; count=0; exit; } }¶
Use a watchdog to dump the router log every 180 seconds to a flash. The XML example snippet is shown as below:¶
<gnca> <policy-variables> <policy-variable> <name>syslog-remote-info</name> <xpath-expr>syslog:syslog/syslog:actions/syslog:remote</xpath-expr> </policy-variable> </policy-variables> <events> <event> <event-name>log-dump-monitoring</event-name> <start-time>2020-10-21T13:51:00Z</start-time> <duration>12000</duration> <repeat-option>everyminutes<repeat-option> <repeat-time-length>3<repeat-time-length> </event> </events> <actions> <action> <name>log-dump-statistics</name> <action-element> <name>log-dump-action</name> <rpc-name>syslog-remote-output</rpc-name> <nc-action-xpath>syslog-remote-info</nc-action-xpath> </action-element> </action> </actions> <ecas> <eca> <name>log-dump-handling</name> <user-name>Bob</user-name> <event-name>log-dump-monitoring</event-name> <condition-action> <name>cron-log-monitoring</name> <action> <name>log-dump-statistics</name> <action-element> <name>syslog-remote-output</name> </action-element> </action> </condition-action> </eca> </ecas> <eca-func-libs> <eca-rpc> <rpc-name>syslog-remote-output</rpc-name> </eca-rpc> <eca-name>log-dump-handling</eca-name> </eca-func-libs> </gnca>¶
It is usually found that at times the CPU utilization spikes up for a very short period of time and at indeterminate times. ECA to be executed in the network device can be used to detect CPU utilization,e.g.,It is triggered when the CPU utilization goes above 60% and also output stack, cpu, fan statistics information to a flash. The XML example snippet is shown as below:¶
<gnca> <policy-variables> <policy-variable> <name>stack-info</name> <xpath-expr>hw:hardware/hw:components/hw:component[hw:class=stack]</xpath-expr> </policy-variable> <policy-variable> <name>fan-info</name> <xpath-expr>hw:hardware/hw:components/hw:component[hw:class=fan]</xpath-expr> </policy-variable> <policy-variable> <name>sensor-info</name> <xpath-expr>hw:hardware/hw:components/hw:component[hw:class=sensor]</xpath-expr> </policy-variable> </policy-variables> <events> <event> <event-name>cpu-util-monitoring</event-name> <event-type>server-event</event-type> <event-stream>NETCONF</event-stream> <event-module>ietf-hardware</event-module> <event>hw:hardware/hw:components/hw:component[hw:class=cpu]</event> </event> </events> <conditions> <condition> <name>cpu-utilization-condition</name> <condition-xpath>event/sensor-data[value>60,value-type=percentile]</condition-xpath> </condition> </conditions> <actions> <action> <name>cpu-info-filter</name> <action-element> <name>cpu-info-dump-action1</name> <func-name>filtered-event</func-name> <policy-source>event/sensor-data[value>60,value-type=percentile]</policy-source> <policy-result>stack-info</policy-result> </action-element> <action-element> <name>cpu-info-dump-action2</name> <func-name>filtered-event</func-name> <policy-source>event/sensor-data[value>60,value-type=percentile]</policy-source> <policy-result>fan-info</policy-result> </action-element> <action-element> <name>cpu-info-dump-action3</name> <func-name>filtered-event</func-name> <policy-source>event/sensor-data[value>60,value-type=percentile]</policy-source> <policy-result>sensor-info</policy-result> </action-element> </action> <action> <name>cpu-info-output</name> <action-element> <name>cpu-info-dump-action1</name> <rpc-name>cpu-log-dump</rpc-name> <nc-action-xpath>stack-info</nc-action-xpath> </action-element> <action-element> <name>cpu-info-dump-action2</name> <rpc-name>cpu-log-dump</rpc-name> <nc-action-xpath>fan-info</nc-action-xpath> </action-element> <action-element> <name>cpu-info-dump-action3</name> <rpc-name>cpu-log-dump</rpc-name> <nc-action-xpath>sensor-info</nc-action-xpath> </action-element> <action-element> <name>cpu-info-dump-action4</name> <rpc-name>cpu-log-dump</rpc-name> <nc-action-xpath>event/sensor-data[value>60,value-type=percentile]</nc-action-xpath> </action-element> </action> </actions> <ecas> <eca> <name>cpu-util-handling</name> <user-name>Bob</user-name> <event-name>cpu-util-monitoring</event-name> <condition-action> <name>cpu-log-monitoring</name> <condition>cpu-utilization-condition</condition> <action> <name>cpu-info-filter</name> <action-element> <name>cpu-info-dump-action1</name> </action-element> <action-element> <name>cpu-info-dump-action2</name> </action-element> <action-element> <name>cpu-info-dump-action3</name> </action-element> </action> </condition-action> <condition-action> <name>cpu-log-printing</name> <action> <name>cpu-info-output</name> <action-element> <name>cpu-info-dump-action1</name> </action-element> <action-element> <name>cpu-info-dump-action2</name> </action-element> <action-element> <name>cpu-info-dump-action3</name> </action-element> <action-element> <name>cpu-info-dump-action4</name> </action-element> </action> </condition-action> </eca> </ecas> <eca-func-libs> <eca-function> <func-name>filtered-event</func-name> </eca-function> <eca-rpc> <rpc-name>cpu-log-dump</rpc-name> </eca-rpc> <eca-name>cpu-util-handling</eca-name> </eca-func-libs> </gnca>¶
v09 - v10¶
v08 - v09¶
v07 - v08¶
v06 - v07¶
v05 - v06¶
v04 - v05¶
v02 - v03¶
v01 - v02¶
v00 - v01¶