Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

RFC 9144 makes use of the fact that 2 new datastores have been defined in NMDA. These include:\

  • <intended>: which contains validated configuration data that a client application intends to be in effect
  • <operational>: which contains operational state data as well as configuration data that is actually in effect.

Intention of RFC 9144

Overview

The following page discusses about two proposed standards for Delta report:

Intention of RFC 9144

RFC 9144 YANG data model that defines RPCs intended to be used in conjunction with RFC 9144 YANG data model that defines RPCs intended to be used in conjunction with NETCONF [RFC6241] or RESTCONF [RFC8040]. These RPCs allow a client to request a server to compare two NMDA datastores and report any differences.

RFC 9144 Data Model and

...

RFC6902 JSON Patch format

The core of the RFC 9144 solution is a new management operation, <compare>, that compares the data tree contents of two datastores. The operation checks whether there are any differences in values or in data nodes that are contained in either datastore and returns any differences as output. The output is returned in the format specified in YANG Patch [RFC8072].

The current approach to Delta report generation follows the JSON patch format to report the delta as described in RFC6902. A JSON Patch document represents an array of objects, where each object contains exactly one operation, path and associated values. The operation can have following values: add, remove, replace, move, copy and test. The path represents the JSON patrh and the values contain the difference in source and target values.

Example JSON Patch document, transferred in an HTTP PATCH request:

Code Block
titleSample JSON Patch document
collapsetrue
PATCH /my/data HTTP/1.1
   Host: example.org
   Content-Length: 326
   Content-Type: application/json-patch+json
   If-Match: "abc123"

   [
     { "op": "test", "path": "/a/b/c", "value": "foo" },
     { "op": "remove", "path": "/a/b/c" },
     { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] },
     { "op": "replace", "path": "/a/b/c", "value": 42 },
     { "op": "move", "from": "/a/b/c", "path": "/a/b/d" },
     { "op": "copy", "from": "/a/b/d", "path": "/a/b/e" }
   ]

RFC 9144 Overview and example of RESTCONF

The YANG data model defines the <compare> operation as a new RPC. The operation takes the following input parameters:

  • source: the source or reference datastore
  • target: the datastore to be compared against the source datastore
  • filter-spec: a xpath based filter to specify the data nodes to be compared in a given datastore.  This allows a comparison operation to be applied only to a specific part of the datastore that is of interest, such as a particular subtree.
  • all: When set, this parameter indicates that all differences should be included, including differences pertaining to schema nodes that exist in only one of the datastores. When this parameter is not included, a prefiltering step is automatically applied to exclude data from the comparison that does not pertain to both datastores.
  • report-origin: this parameter is used to indicate whether to include origin or source data in delta report or not.

The operation provides the following output parameters:

  • differences: This parameter contains the list of differences. Those differences are encoded per the YANG Patch data model defined in [RFC8072]

Example Delta generated as part of RFC9144

Code Block
titleSample delta as per RFC9144
collapsetrue
{ "ietf-nmda-compare:output" : {
    "differences" : {
      "ietf-yang-patch:yang-patch" : {
        "patch-id" : "interface status",
        "comment" : "diff between intended (source) and operational",
        "edit" : [
          {
            "edit-id" : "1",
            "operation" : "replace",
            "target" : "/ietf-interfaces:interface=eth0/enabled",
            "value" : {
               "ietf-interfaces:interface/enabled" : "false"
            },
            "source-value" : {
               "ietf-interfaces:interface/enabled" : "true",
               "@ietf-interfaces:interface/enabled" : {
                 "ietf-origin:origin" : "ietf-origin:learned"
               }
             }
Code Block
titleStructure of ietf-nmda-compare. Source: RFC9144
collapsetrue
module: ietf-nmda-compare
  rpcs:
    +---x compare
       +---w input
       |  +---w source            identityref},
       |  +---w target {
            identityref
  "edit-id" : "2",
     |  +---w all?    "operation" : "create",
        empty
    "target"   |  +---w report-origin?: "/ietf-interfaces:interface=eth0/description",
     empty
       |  +---w (filter-spec)?
"value" : {
         |     +--:(subtree-filter)"ietf-interface:interface/description" : "ip interface"
       |     |}
  +---w subtree-filter?
       |}
     +--:(xpath-filter)
   ]
    |    }
    +---w xpath-filter?     yang:xpath1.0 {nc:xpath}?
  }
}

The approach RFC6902 approach to Delta report generation follows the JSON patch format. A JSON Patch document represents an array of objects, where each object contains exactly one operation, path and associated values. The operation can have following values: add, remove, replace, move, copy and test. The path represents the JSON patch and the values contain the difference in source and target values.

Brief summary of JSON patch can be found in the following page: CPS Delta

Example JSON Patch document, transferred in an HTTP PATCH request:

Code Block
titleSample JSON Patch document
collapsetrue
PATCH /my/data HTTP/1.1
   Host: example.org
   Content-Length: 326
   Content-Type: application/json-patch+json
   If-Match: "abc123"

   [
     { "op": "test", "path": "/a/b/c", "value": "foo" },
     { "op": "remove", "path": "/a/b/c" },
     { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] },
     { "op": "replace", "path": "/a/b/c", "value": 42 },
     { "op": "move", "from": "/a/b/c", "path": "/a/b/d" },
     { "op": "copy", "from": "/a/b/d", "path": "/a/b/e" }
   ]

RFC 9144 example using RESTCONF

The YANG data model defines the <compare> operation as a new RPC. The operation takes the following input parameters:

  • source: the source or reference datastore
  • target: the datastore to be compared against the source datastore
  • filter-spec: a xpath based filter to specify the data nodes to be compared in a given datastore.  This allows a comparison operation to be applied only to a specific part of the datastore that is of interest, such as a particular subtree.
  • all: When set, this parameter indicates that all differences should be included, including differences pertaining to schema nodes that exist in only one of the datastores. When this parameter is not included, a prefiltering step is automatically applied to exclude data from the comparison that does not pertain to both datastores.
  • report-origin: this parameter is used to indicate whether to include origin or source data in delta report or not.

The operation provides the following output parameters:

  • differences: This parameter contains the list of differences. Those differences are encoded per the YANG Patch data model defined in [RFC8072]
Code Block
titleStructure of ietf-nmda-compare. Source: RFC9144
collapsetrue
module: ietf-nmda-compare
  rpcs:
    +---x compare
     +--ro output
          +--ro (compare-response)?
             +--:(no-matches)
             |  +--ro no-matches?    empty
             +--:(differences)
                +--ro differences
                   +--ro yang-patch
                      +--ro patch-id    string
                      +--ro comment?    string
                      +--ro edit* [edit-id]
                         +--ro edit-id         string
                         +--ro operation       enumeration
                         +--ro-w targetinput
       |   target+--resource-offset
w source            identityref
          |  +---row point?target          target-resource-offset
  identityref
       |  +---w all?             +--ro where? empty
       |   enumeration
+---w report-origin?    empty
       |   +---w (filter-spec)?
       |     +--ro value:(subtree-filter)
       |     |  +---w subtree-filter?
       |     +--:(xpath-filter)
       |        +--ro-w sourcexpath-value?

RESTCONF Example

Sample YANG Model

Code Block
titleYANG Model
collapsetrue
container interfaces {
  description
    "Interface parameters.";
  list interface {
    key "name";filter?     yang:xpath1.0 {nc:xpath}?
       +--ro output
          +--ro (compare-response)?
    leaf name {
      type string; +--:(no-matches)
      description
       | "The name of the interface.";
    }
 +--ro no-matches?    empty
      leaf description {
      type string;
+--:(differences)
        description
        "A textual description of the interface.";
+--ro differences
        }
    leaf enabled {
      type boolean;+--ro yang-patch
      default "true";
      description
        "This leaf contains the configured, desired state of the +--ro patch-id    string
         interface.";
    }
  }
}

Sample Data

Code Block
titleIntended/Reference Data
collapsetrue
{
  "interfaces": {
    "interface": {
+--ro comment?    string
               "name": "eth0",
        "enabled": false,+--ro edit* [edit-id]
      "description": "ip interface"
    }
  }
}
Code Block
titleOperational/Comparand/Target Data
collapsetrue
{
  "interfaces": {
    "interface": {
             +--ro edit-id        "name": "eth0",
 string
         "enabled": true
    }
  }
}

Request in RESTCONF

Code Block
titlePOST Request
collapsetrue
POST /restconf/operations/ietf-nmda-compare:compare HTTP/1.1
Host: example.com
Content-Type: application/yang-data+json
Accept: application/yang-data+json

{ "ietf-nmda-compare:input" : {
   "source" : "ietf-datastores:operational",
   "target" : "ietf-datastores:intended",
   "report-origin" : null,
   "xpath-filter" : "/ietf-interfaces:interfaces"
   }
}

Response in RESTCONF

Code Block
titleResponse
collapsetrue
HTTP/1.1 200 OK
Date: Thu, 24 Jan 2019 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+json

{ "ietf-nmda-compare:output" : {
    "differences" : {
      "ietf-yang-patch:yang-patch" : {
           +--ro operation       enumeration
                         +--ro target          target-resource-offset
                         +--ro point?          "patch-id" : "interface status",
target-resource-offset
            "comment" : "diff between intended (source) and operational",
      +--ro where? "edit" : [
       enumeration
   {
            "edit-id" : "1",
            "operation" : "replace",+--ro value?
            "target" : "/ietf-interfaces:interface=eth0/enabled",
            "value" :+--ro source-value?

RESTCONF Example

Sample YANG Model

Code Block
titleYANG Model
collapsetrue
container interfaces {
  description
    "Interface parameters.";
  list interface {
    "ietf-interfaces:interface/enabled" : "false"
key "name";
    leaf name {
      type },string;
      description
      "source-value" :  "The name of the interface.";
    }
    leaf description {
      type string;
      description
      "ietf-interfaces:interface/enabled" : "true",
               "@ietf-interfaces:interface/enabled" : {
                 "ietf-origin:origin" : "ietf-origin:learned"
               }
             }
          },
          "A textual description of the interface.";
    }
    leaf enabled {
      type boolean;
      default "true";
      description
        "This leaf contains the configured, desired state of the
         interface.";
    }
  }
}

Sample Data

Code Block
titleIntended/Reference Data
collapsetrue
{
  "interfaces": {
    "interface": {
      "name": "eth0",
      "enabled": false,
      "description": "ip interface"
    }
  }
}


Code Block
titleOperational/Comparand/Target Data
collapsetrue
{
  "interfaces": {
    "interface": {
      "name": "eth0",
      "enabled": true
    }
  }
}

Request in RESTCONF

Code Block
titlePOST Request
collapsetrue
POST /restconf/operations/ietf-nmda-compare:compare HTTP/1.1
Host: example.com
Content-Type: application/yang-data+json
Accept: application/yang-data+json

{ "ietf-nmda-compare:input" : {
   "source" : "ietf-datastores:operational",
   "target" : "ietf-datastores:intended",
   "report-origin" : null,
   "xpath-filter" : "/ietf-interfaces:interfaces"
   }
}

Response in RESTCONF

Code Block
titleResponse
collapsetrue
HTTP/1.1 200 OK
Date: Thu, 24 Jan 2019 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+json

{ "ietf-nmda-compare:output" : {
    "differences" : {
      "ietf-yang-patch:yang-patch" : {
        "patch-id" : "interface status",
        "comment" : "diff between intended (source) and operational",
        "edit" : [
          {
            "edit-id" : "1",
            "operation" : "replace",
            "target" : "/ietf-interfaces:interface=eth0/enabled",
            "value" : {
               "ietf-interfaces:interface/enabled" : "false"
            },
            "source-value" : {
               "ietf-interfaces:interface/enabled" : "true",
               "@ietf-interfaces:interface/enabled" : {
                 "ietf-origin:origin" : "ietf-origin:learned"
               }
             }
          },
          {
            "edit-id" : "2",
            "operation" : "create",
            "target" : "/ietf-interfaces:interface=eth0/description",
            "value" : {
              "ietf-interface:interface/description" : "ip interface"
            }
          }
        ]
      }
    }
  }
}

Open Questions

  • Are there any major advantages of using RFC 9144?
  • Is it different than current approach? Can it be modified as per requirements of CPS? For example using xpath format
  • The documentation of RFC 9144 defines a POST operation to find the delta. Does this mean this approach intends to persist the Delta generated to a database? If so will it be an indefinite persistence of delta report or will the delta be removed from storage after a specific time period.

    Code Block
    titlePOST operation as defined in RFC 9144
    collapsetrue
    POST /restconf/operations/ietf-nmda-compare:compare HTTP/1.1
    Host: example.com
    Content-Type: application/yang-data+json
    Accept: application/yang-data+json
    
    { "ietf-nmda-compare:input" : {
       "source" : "ietf-datastores:operational",
       "target" : "ietf-datastores:intended",
       "report-origin" : null,
       "xpath-filter" : "/ietf-interfaces:interfaces"
       }
    }

    The current approach that is being used for development of Delta feature in CPS is a GET operation with no intention to persist the delta report. It is meant to return the delta in following JSON format.

    Code Block
    titleSample delta report format
    collapsetrue
    [
      {
        

...

  • "action": "ADD",
        "

...

  • xpath"

...

  • : "

...

  • /bookstore/categories/[@code=3]",
        

...

  • "payload": {
          "

...

  • code"

...

  • : 

...

  • 3,
    

...

  •       "

...

  • name"

...

  • : "

...

  • kidz"
        }
      },
      {
        "

...

  • action"

...

  • : 

...

  • "DELETE",
        "xpath": "/bookstore/categories/[@code=1]",
        "payload": {
         

...

  •  "code": 1,
          "name": "Fiction"
        }
      },
      {
        "action": "UPDATE",
       

...

  •  "xpath": "/bookstore/categories/[@code=2]",
        "payload": {
     

...

  •      

...

  • "name": "Comic"
        }
      }

...

  • 
    ]


  • RFC 9144 defines a yang data model which will be helpful when persisting the Delta Report, but if we go with the approach where the delta generated is not persisted then what will be the benefit of following the model as it is?

Open Questions

  • What are the advantages of using RFC 9144?
  • Any different than current approach? Can it be modified as per requirements of CPS? For example using xpath format
  • The documentation defines a POST operation to find the delta. Does this mean this approach intends to persist the Delta generated ti a database? If so will it be an indefinite persistence of delta report or will the delta be removed from storage after a specific time period.
  • The current approach is a GET operation with no intention to persist the delta report

  • Are we following any RFC specifications for PATCH operation?