Databases

A NETCONF database is conceptually represented as an XML instance document.

../_images/database_variants.png

There are 3 conceptual databases, which all share the exact same structure.

  • <candidate>: scratch-pad to gather edits to apply to <running> all at once

  • <running>: configuration data in effect

  • <startup>: configuration data for the next reboot

When the <running> configuration is saved to non-volatile storage, the top-level element of this document is the <config> container element.

The XML namespace of this element is the netconfd-pro module namespace, but a client application should expect that other server implementations may use a different namespace, such as the NETCONF namespace, or perhaps no namespace at all for this top-level element.

When database contents are returned in the <get>, <get-config>, or <copy-config> operations, the top-level container will be the <data> element in the NETCONF base namespace.

The top-level YANG module data structures that are present in the configuration will be present as child nodes of the <config> or <data> container node.

The exact databases that are present in the server are controlled by 3 capabilities:

The edit target in the server is set with the --target configuration parameter. This will select either the :candidate or :writable-running capabilities.

The server behavior for non-volatile storage of the <running> configuration is set with the --with-startup configuration parameter. The :startup capability will be supported if this parameter is set to 'true'.

The following diagram shows the 4 database usage modes that netconfd-pro supports:

Database Locking

It is strongly suggested that the <lock> and <unlock> operations be used whenever a database is being edited. All the databases on the server should be locked, not just one, because different operations are controlled by different locks. The only way to insure that the entire database transaction is done in isolation is to keep all the databases locked during the entire transaction.

The affected configurations should be locked during the entire transaction, and not released until the edits have been saved in non-volatile storage.

If the edit target is the <candidate> configuration, then the <candidate> and <running> configurations should be locked.

If the edit target is the <running> configuration, then the <running> and <startup> configurations should be locked.

Whenever the lock on the <candidate> configuration is released, a <discard-changes> operation is performed by the server. This is required by the NETCONF protocol.

Of the <candidate> configuration contains any edits, then a lock will fail with a 'resource-denied' error. In this case, a lock on the <candidate> configuration cannot be granted until the <discard-changes> operation is completed.

Using the <candidate> Database

The <candidate> database is available if the :candidate capability is advertised by the server.

The <lock> operation will fail on this database if there are any edits already pending in the <candidate>. If a 'lock-failed' error occurs and no session is holding a lock, then use the <discard-changes> operation to clear the <candidate> buffer of any edits.

Once all the edits have been made, the <validate> operation can be used to check if all database validation tests will pass. This step is optional.

Once the edits are completed, the <commit> operation is used to activate the configuration changes, and save them in non-volatile storage.

The <discard-changes> operation is used to clear any edits from this database.

Using the <running> Database

The <running> database is available at all times for reading.

If the :writable-running capability is advertised by the server, then this database will be available as the target for <edit-config> operations.

Edits to the <running> configuration will take affect right away, as each <edit-config> operation is completed.

Once all the edits are completed, the <copy-config> operation can be used to save the current <running> configuration to non-volatile storage, by setting the target of the <copy-config> operation to the <startup> configuration.

Using the <startup> Database

The <startup> database is available if the :startup capability is advertised by the server.

The <copy-config> operation can be used to save the contents of the <running> configuration to the <startup> configuration.

The <get-config> operation can be used to retrieve the contents of the <startup> configuration.

The <delete-config> operation can be used to delete the <startup> configuration. Only a superuser account is allowed to do this, by default.

Using the <factory-default> Database

The <factory-default> database is available if the ietf-factory-default.yang module is loaded by the server, enabled with the --with-factory-datastore CLI parameter.

  • This is a read-only conventional datastore

  • This datastore is not supported by the /netconf-state/datastores subtree defined in RFC 6022.

The datastore is only available for operation parameters that use the NMDA 'ds:datastore' base with an identityref data type.

  • The <compare-config> operation can be used for the 'source' and 'target' parameters.

  • The <get-data> operation can be used to retrieve the contents of the <factory-default> configuration, if the --with-nmda='true' setting is used.

    • The contents of this datastore are expected to be 'empty' unless a factory startup file is found (e.g., --startup-factory-file parameter set).

    • An empty datastore usually contains the module default NP containers, leaf, and leaf-list nodes.

Example: Compare <factory-default> to <running>

This example shows what configuration changes would be done if the factory configuration was loaded.

The yangcli-pro command:

compare-config source=factory-default target=running

The server may receive the following request:

<?xml version="1.0" encoding="UTF-8"?>
<rpc message-id="3"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <compare-config xmlns="urn:yumaworks:params:xml:ns:yang:yumaworks-compare">
  <source
   xmlns:fd="urn:ietf:params:xml:ns:yang:ietf-factory-default">fd:factory-default</source>
  <target
   xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores">ds:running</target>
 </compare-config>
</rpc>

The server may send the following reply:

<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="3"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <differences xmlns="urn:yumaworks:params:xml:ns:yang:yumaworks-compare">
  <yang-patch>
   <patch-id>compare-config</patch-id>
   <edit>
    <edit-id>E1</edit-id>
    <operation>delete</operation>
    <target>/yumaworks-event-stream:event-streams</target>
   </edit>
   <edit>
    <edit-id>E2</edit-id>
    <operation>delete</operation>
    <target>/ietf-netconf-acm:nacm/groups/group=guest</target>
   </edit>
   <edit>
    <edit-id>E3</edit-id>
    <operation>delete</operation>
    <target>/ietf-netconf-acm:nacm/groups/group=G200</target>
   </edit>
   <edit>
    <edit-id>E4</edit-id>
    <operation>delete</operation>
    <target>/ietf-netconf-acm:nacm/groups/group=G300</target>
   </edit>
  </yang-patch>
 </differences>
</rpc-reply>

Example Empty Factory Default Database

The yangcli-pro command:

get-data datastore=factory-default

The server may receive a 'get-data' operation as follows:

<?xml version="1.0" encoding="UTF-8"?>
<rpc message-id="2"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <get-data xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-nmda">
  <datastore
   xmlns:fd="urn:ietf:params:xml:ns:yang:ietf-factory-default">fd:factory-default</datastore>
 </get-data>
</rpc>

The server may send an empty reply as follows:

<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="2"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <data xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-nmda"></data>
</rpc-reply>

The :with-defaults capability (e.g. 'with-defaults' parameter must be used to retrieve the YANG default settings.

The yangcli-pro command:

get-data datastore=factory-default with-defaults=report-all

The server may receive a 'get-data' operation as follows:

<?xml version="1.0" encoding="UTF-8"?>
<rpc message-id="3"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <get-data xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-nmda">
  <datastore
   xmlns:fd="urn:ietf:params:xml:ns:yang:ietf-factory-default">fd:factory-default</datastore>
  <with-defaults>report-all</with-defaults>
 </get-data>
</rpc>

The server may send a reply as follows:

<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="3"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <data xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-nmda">
  <event-streams xmlns="http://yumaworks.com/ns/yumaworks-event-stream"/>
  <filters xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications"/>
  <nacm xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-acm">
   <enable-nacm>true</enable-nacm>
   <read-default>permit</read-default>
   <write-default>deny</write-default>
   <exec-default>permit</exec-default>
   <enable-external-groups>true</enable-external-groups>
   <groups/>
  </nacm>
  <templates xmlns="http://yumaworks.com/ns/yumaworks-templates"/>
 </data>
</rpc-reply>

Example Factory Default Database for NACM

This example shows a factory default startup file for an initial Access Control configuration with NACM.

The yangcli-pro command:

get-data datastore=factory-default

The server may receive a 'get-data' operation as follows:

<?xml version="1.0" encoding="UTF-8"?>
<rpc message-id="2"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <get-data xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-nmda">
  <datastore
   xmlns:fd="urn:ietf:params:xml:ns:yang:ietf-factory-default">fd:factory-default</datastore>
 </get-data>
</rpc>

The server may send a reply as follows:

<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="2"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <data xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-nmda">
  <nacm xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-acm">
   <groups>
    <group>
     <name>admin</name>
     <user-name>bob</user-name>
     <user-name>alice</user-name>
    </group>
   </groups>
   <rule-list>
    <name>admin-all</name>
    <group>admin</group>
    <rule>
     <name>rule-all</name>
     <module-name>*</module-name>
     <access-operations>*</access-operations>
     <action>permit</action>
     <comment>allow admin all access</comment>
    </rule>
   </rule-list>
  </nacm>
 </data>
</rpc-reply>

Comparing Databases

There is a standard 'compare' operation defined in 'ietf-nmda-compare' module defined in RFC 9144. This operation focuses on NMDA datastores, which does not address customer requirements for a compare operation.

The replacement <compare-config> operation focuses on configuration comparisons, and allows a backup file or URL file to be compared to a conventional datastore. It is defined in the yumaworks-compare.yang module, and is enabled by default with the --with-yumaworks-compare CLI parameter.

Database Compare Overview

Purpose:

  • Retrieve the differences to create a patch that could be applied to <target> so the result is equivalent to the <source>.

First Release: 25.10-4

Operation Structure:

compare-config <source> <target> [<filter>] [<compare-format>]

Output Structure:

One of the following objects is returned if there are no errors:

  • <no-matches> : empty leaf returned if the optional filter was used but did not match any nodes in both the source and target.

  • <differences> : container returned if a comparison was done.

Each parameter is designed as an extensible choice:

  • <source> : mandatory source datastore, backup, or URL for comparison

  • <target> : mandatory target datastore, backup, or URL for comparison

  • <filter> : optional filter to compare only the nodes that match the filter output.

  • <compare-format> : optional compare output format to select the type of differences report.

Supported Configuration Sources:

Supported Filter Types:

Supported Compare Formats:

Compare Example:

  • config A contains:

    /X=1
    /Y=1
    
  • config B contains:

    /X=2
    
  • compare source=A target=B

    merge /X value=1
    merge /Y value=1
    
  • compare source=B target=A

    merge /X value=2
    delete /Y
    

Usage Restrictions

There are some usage restrictions for this operation because it is complex to implement and can use a lot of memory resources while it is running. The 'TBD' features will be supported in a future release.

  • The 'operational' datastore is not supported

  • The 'intended' datastore is treated as 'running' until that datastore is supported in the server

  • The source and target must be different or an error is returned

  • The 'edit-config' and 'netconf-config-change' compare-format enumerations are not supported

  • insert and move edit operations are not supported yet

YANG Patch Compare Format

The default differences format is the YANG Patch structure defined in RFC 8072.

Example:

<yang-patch>
 <patch-id>compare-config</patch-id>
 <edit>
  <edit-id>E1</edit-id>
  <operation>delete</operation>
  <target>/yumaworks-event-stream:event-streams</target>
 </edit>
 <edit>
  <edit-id>E2</edit-id>
  <operation>delete</operation>
  <target>/ietf-netconf-acm:nacm</target>
 </edit>
</yang-patch>

The following implementation details apply to this report format:

  • The 'patch-id' leaf will be set to the string compare-config

  • The 'comment' leaf will not be present

  • The root of the patch is the datastore root '/'

  • Each 'undo' record in the edit transaction will be converted to a separate edit.

  • The order of edits found in the compare operation are preserved in the YANG Patch edit list

  • The 'edit-id' key leaf will be set to E1, E2, etc.

  • The 'operation' leaf will always be set to the effective operation, which may not exactly match specific 'nc:operation' values used to create the changes.

    • 'remove' will be shown as 'delete'

    • 'delete-all' and 'remove-all' are shown as individual 'delete' operations.

  • The 'target' leaf will always be set to the instance-identifier for the edited node.

  • The 'point' leaf will be set for an insert operation to the instance-identifier of the node inserted before or after.

  • The 'where' leaf will be set for an insert or move operation.

  • The 'value' node will be present unless the 'edit-op' is 'delete'

edit-config Compare Format

The 'edit-config' format is a 'config' element containing edit attributes:

Example:

<config>
 <event-streams
  xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
  nc:operation="delete"
  xmlns="http://yumaworks.com/ns/yumaworks-event-stream"/>
 <nacm
  xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
  nc:operation="delete"
  xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-acm"/>
</config>

The following implementation details apply to this report format:

  • The 'default-operation' leaf must be set to 'none'

  • An 'nc:operation' attribute will be present in each edit

  • Multiple related edits will be combined within the appropriate subtree, so container and list entries will not be repeated within the 'config' element.

Database Compare Examples

Example: No matches response returned if the filter does not select any nodes

The yangcli-pro command:

compare-config source=candidate target=running xpath-filter=/foo/not-found

The server may receive the operation:

<?xml version="1.0" encoding="UTF-8"?>
<rpc message-id="2"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <compare-config xmlns="urn:yumaworks:params:xml:ns:yang:yumaworks-compare">
  <source
   xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores">ds:candidate</source>
  <target
   xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores">ds:running</target>
  <xpath-filter>/foo/not-found</xpath-filter>
 </compare-config>
</rpc>

The server may send the following response:

<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="2"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <no-matches xmlns="urn:yumaworks:params:xml:ns:yang:yumaworks-compare"/>
</rpc-reply>

The yangcli-pro reply in JSON format:

{
  "yuma-netconf:rpc-reply": {
    "no-matches":[null]
  }
}

Example: Empty response returned if there are no differences

The yangcli-pro command:

compare-config source=candidate target=running

The server may receive the operation:

<?xml version="1.0" encoding="UTF-8"?>
<rpc message-id="4"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <compare-config xmlns="urn:yumaworks:params:xml:ns:yang:yumaworks-compare">
  <source
   xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores">ds:candidate</source>
  <target
   xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores">ds:running</target>
 </compare-config>
</rpc>

The server may send the following response:

<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="4"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <differences xmlns="urn:yumaworks:params:xml:ns:yang:yumaworks-compare"/>
</rpc-reply>

The yangcli-pro reply in JSON format:

{
  "yuma-netconf:rpc-reply": {
    "yumaworks-compare:differences": {
    }
  }
}

Example: Error returned because source and target are the same

The <source> and <target> must be different or an 'operation-not-supported' error will be returned.

Example yangcli-pro command:

compare-config source-backup=test1.xml target-backup=test1.xml

The server may receive the operation:

<?xml version="1.0" encoding="UTF-8"?>
<rpc message-id="5"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <compare-config xmlns="urn:yumaworks:params:xml:ns:yang:yumaworks-compare">
  <source-backup>test1.xml</source-backup>
  <target-backup>test1.xml</target-backup>
 </compare-config>
</rpc>

The server may send the following response:

<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="5" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
 xmlns:ypcmp="urn:yumaworks:params:xml:ns:yang:yumaworks-compare"
 xmlns:ncx="http://netconfcentral.org/ns/yuma-ncx"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <rpc-error>
  <error-type>protocol</error-type>
  <error-tag>operation-not-supported</error-tag>
  <error-severity>error</error-severity>
  <error-app-tag>no-support</error-app-tag>
  <error-path>/nc:rpc/ypcmp:compare-config/ypcmp:target-backup</error-path>
  <error-message xml:lang="en">operation not supported</error-message>
  <error-info>
   <error-number>273</error-number>
  </error-info>
 </rpc-error>
</rpc-reply>

The yangcli-pro reply in JSON format:

{
  "yuma-netconf:rpc-reply": {
    "rpc-error": [
      {
        "error-type":"protocol",
        "error-tag":"operation-not-supported",
        "error-severity":"error",
        "error-app-tag":"no-support",
        "error-path":"/nc:rpc/ypcmp:compare-config/ypcmp:target-backup",
        "error-message":"operation not supported",
        "error-info": {
          "error-number":"273"
        }
      }
    ]
  }
}

Example: Show edits in candidate that would be applied with commit

In this example, 3 separate edits are in the candidate config that have not been applied:

  • /event-streams/module-map created 2 module-map list entries

  • /nacm/groups/group created 1 group list entry

The yangcli-pro command:

compare-config source=candidate target=running

The server may receive the operation:

<?xml version="1.0" encoding="UTF-8"?>
<rpc message-id="10"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <compare-config xmlns="urn:yumaworks:params:xml:ns:yang:yumaworks-compare">
  <source
   xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores">ds:candidate</source>
  <target
   xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores">ds:running</target>
 </compare-config>
</rpc>

The server may send the following response:

<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="10"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <differences xmlns="urn:yumaworks:params:xml:ns:yang:yumaworks-compare">
  <yang-patch>
   <patch-id>compare-config</patch-id>
   <edit>
    <edit-id>E1</edit-id>
    <operation>create</operation>
    <target>/yumaworks-event-stream:event-streams/module-map=ietf-system</target>
    <value>
     <module-map xmlns="http://yumaworks.com/ns/yumaworks-event-stream">
      <module-name>ietf-system</module-name>
      <stream-name>system</stream-name>
     </module-map>
    </value>
   </edit>
   <edit>
    <edit-id>E2</edit-id>
    <operation>create</operation>
    <target>/yumaworks-event-stream:event-streams/module-map=yumaworks-system</target>
    <value>
     <module-map xmlns="http://yumaworks.com/ns/yumaworks-event-stream">
      <module-name>yumaworks-system</module-name>
      <stream-name>system</stream-name>
     </module-map>
    </value>
   </edit>
   <edit>
    <edit-id>E3</edit-id>
    <operation>create</operation>
    <target>/ietf-netconf-acm:nacm/groups/group=guest</target>
    <value>
     <group xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-acm">
      <name>guest</name>
      <user-name>guest</user-name>
      <user-name>guest2</user-name>
     </group>
    </value>
   </edit>
  </yang-patch>
 </differences>
</rpc-reply>

The yangcli-pro reply in JSON format:

{
  "yuma-netconf:rpc-reply": {
    "yumaworks-compare:differences": {
      "yang-patch": {
        "patch-id":"compare-config",
        "edit": [
          {
            "edit-id":"E1",
            "operation":"create",
            "target":"/yumaworks-event-stream:event-streams/module-map=ietf-system",
            "value": {
              "yumaworks-event-stream:module-map": {
                "module-name":"ietf-system",
                "stream-name":"system"
              }
            }
          },
          {
            "edit-id":"E2",
            "operation":"create",
            "target":"/yumaworks-event-stream:event-streams/module-map=yumaworks-system",
            "value": {
              "yumaworks-event-stream:module-map": {
                "module-name":"yumaworks-system",
                "stream-name":"system"
              }
            }
          },
          {
            "edit-id":"E3",
            "operation":"create",
            "target":"/ietf-netconf-acm:nacm/groups/group=guest",
            "value": {
              "ietf-netconf-acm:group": {
                "name":"guest",
                "user-name":"guest",
                "user-name":"guest2"
              }
            }
          }
        ]
      }
    }
  }
}

Example: Show edits in candidate using an XPath filter

The previous example is shown where only the changes to /nacm/groups are reported, by using the 'xpath-filter' parameter.

The yangcli-pro command:

compare-config source=candidate target=running xpath-filter=/nacm/groups

The server may receive the operation:

<?xml version="1.0" encoding="UTF-8"?>
<rpc message-id="12"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <compare-config xmlns="urn:yumaworks:params:xml:ns:yang:yumaworks-compare">
  <source
   xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores">ds:candidate</source>
  <target
   xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores">ds:running</target>
  <xpath-filter>/nacm/groups</xpath-filter>
 </compare-config>
</rpc>

The server may send the following response:

<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="12"
 xmlns:nacm="urn:ietf:params:xml:ns:yang:ietf-netconf-acm"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <differences xmlns="urn:yumaworks:params:xml:ns:yang:yumaworks-compare">
  <yang-patch>
   <patch-id>compare-config</patch-id>
   <edit>
    <edit-id>E1</edit-id>
    <operation>create</operation>
    <target>/ietf-netconf-acm:nacm/groups/group=guest</target>
    <value>
     <group xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-acm">
      <name>guest</name>
      <user-name>guest</user-name>
      <user-name>guest2</user-name>
     </group>
    </value>
   </edit>
  </yang-patch>
 </differences>
</rpc-reply>

The yangcli-pro reply in JSON format:

{
  "yuma-netconf:rpc-reply": {
    "yumaworks-compare:differences": {
      "yang-patch": {
        "patch-id":"compare-config",
        "edit": [
          {
            "edit-id":"E1",
            "operation":"create",
            "target":"/ietf-netconf-acm:nacm/groups/group=guest",
            "value": {
              "ietf-netconf-acm:group": {
                "name":"guest",
                "user-name":"guest",
                "user-name":"guest2"
              }
            }
          }
        ]
      }
    }
  }
}

Example: Show edits that would be applied if a backup file was restored

The backup file test3.xml was created with the <backup> operation before the edits in the previous example were committed to the 'running' datastore.

The yangcli-pro command:

compare-config source-backup=test3.xml target=running

The server may receive the operation:

<?xml version="1.0" encoding="UTF-8"?>
<rpc message-id="17"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <compare-config xmlns="urn:yumaworks:params:xml:ns:yang:yumaworks-compare">
  <source-backup>test3.xml</source-backup>
  <target
   xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores">ds:running</target>
 </compare-config>
</rpc>

The server may send the following response:

<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="17"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <differences xmlns="urn:yumaworks:params:xml:ns:yang:yumaworks-compare">
  <yang-patch>
   <patch-id>compare-config</patch-id>
   <edit>
    <edit-id>E1</edit-id>
    <operation>delete</operation>
    <target>/yumaworks-event-stream:event-streams/module-map=ietf-system</target>
   </edit>
   <edit>
    <edit-id>E2</edit-id>
    <operation>delete</operation>
    <target>/yumaworks-event-stream:event-streams/module-map=yumaworks-system</target>
   </edit>
   <edit>
    <edit-id>E3</edit-id>
    <operation>delete</operation>
    <target>/ietf-netconf-acm:nacm/groups/group=guest</target>
   </edit>
  </yang-patch>
 </differences>
</rpc-reply>

The yangcli-pro reply in JSON format:

{
  "yuma-netconf:rpc-reply": {
    "yumaworks-compare:differences": {
      "yang-patch": {
        "patch-id":"compare-config",
        "edit": [
          {
            "edit-id":"E1",
            "operation":"delete",
            "target":"/yumaworks-event-stream:event-streams/module-map=ietf-system"
          },
          {
            "edit-id":"E2",
            "operation":"delete",
            "target":"/yumaworks-event-stream:event-streams/module-map=yumaworks-system"
          },
          {
            "edit-id":"E3",
            "operation":"delete",
            "target":"/ietf-netconf-acm:nacm/groups/group=guest"
          }
        ]
      }
    }
  }
}