#
RPC calculate-subtree-diff
This RPC creates a diff between source topology subtrees and target topology subtrees.
Supported features include:
- Compare subtrees under the same network-topology node.
- Compare subtrees between different network-topology nodes that use same YANG schemas.
- Compare subtrees with different revisions of YANG schemas that are syntactically compatible (for example, different software versions of devices).
RPC input contains data-tree paths (source-path
and target-path
) and data locations
(source-datastore
and target-datastore
).
Data location is the enumeration of two possible values, OPERATIONAL
and CONFIGURATION
.
The default value for source-datastore
is OPERATIONAL
and the default value of
target-datastore
is CONFIGURATION
.
RPC output contains a list of differences between source and target subtrees.
#
RPC examples
#
Successful example: Computed difference
RPC input contains a path to two different testtool devices with different YANG schemas.
RPC output contains a list of statements representing the diff.
{
"root": {
"simple-root": {
"leaf-a": "leafA",
"leaf-b": "EDITED",
"ll": [
"str1",
"str2",
"str3"
],
"nested": {
"sample-y": false
}
},
"list-root": {
"branch-ab": 9999,
"top-list": [
{
"key-1": "ka",
"key-2": "kb",
"next-data": {
"switch-1": [
null
],
"switch-2": [
null
]
},
"nested-list": [
{
"identifier": "f1",
"foo": 1
},
{
"identifier": "f2",
"foo": 10
},
{
"identifier": "f3",
"foo": 20
}
]
},
{
"key-1": "kb",
"key-2": "ka",
"next-data": {
"switch-1": [
null
]
},
"nested-list": [
{
"identifier": "e1",
"foo": 1
},
{
"identifier": "e2",
"foo": 2
},
{
"identifier": "e3",
"foo": 3
}
]
},
{
"key-1": "kc",
"key-2": "ke",
"next-data": {
"switch-2": [
null
]
},
"nested-list": [
{
"identifier": "q1",
"foo": 13
},
{
"identifier": "q2",
"foo": 14
},
{
"identifier": "q3",
"foo": 15
}
]
}
]
},
"choice-root": {
"cb": [
{
"key-cb": "f1",
"next-bit": "asdfgh"
},
{
"key-cb": "f2",
"next-bit": "qwertz"
},
{
"key-cb": "f3",
"next-bit": "yxcvb"
},
{
"key-cb": "f4",
"next-bit": "poiuzz"
}
]
},
"augmented-root": {
"aug-c": {
"original-leaf": [
null
],
"test-augment:list-1": [
{
"leaf-x": "x1",
"leaf-y": "x1"
},
{
"leaf-x": "x2",
"leaf-y": "x1"
},
{
"leaf-x": "x3",
"leaf-y": "x1"
}
]
},
"aug-l": [
{
"my-key": "k1",
"test-augment:abc": {
"abc": false
}
},
{
"my-key": "k2",
"test-augment:abc": {
"abc": true
}
},
{
"my-key": "k3",
"test-augment:abc": {
"abc": false
}
}
]
}
}
}
{
"root": {
"simple-root": {
"leaf-a": "leafA",
"leaf-b": "leafB",
"ll": [
"str1",
"str2",
"EDITED"
],
"nested": {
"sample-y": false
}
},
"list-root": {
"branch-ab": 5,
"top-list": [
{
"key-1": "ka",
"key-2": "kb",
"next-data": {
"switch-1": [
null
],
"switch-2": [
null
]
},
"nested-list": [
{
"identifier": "f1",
"foo": 1
},
{
"identifier": "f2",
"foo": 10
},
{
"identifier": "f3",
"foo": 20
}
]
},
{
"key-1": "kb",
"key-2": "ka",
"next-data": {
"switch-1": [
null
]
},
"nested-list": [
{
"identifier": "e1",
"foo": 1
},
{
"identifier": "e2",
"foo": 2
},
{
"identifier": "e3",
"foo": 3
}
]
},
{
"key-1": "kc",
"key-2": "EDITED",
"next-data": {
"switch-2": [
null
]
},
"nested-list": [
{
"identifier": "q1",
"foo": 13
},
{
"identifier": "q2",
"foo": 14
},
{
"identifier": "q3",
"foo": 15
}
]
}
]
},
"choice-root": {
"cb": [
{
"key-cb": "f1",
"next-bit": "asdfgh"
},
{
"key-cb": "f2",
"next-bit": "qwertz"
},
{
"key-cb": "f3",
"next-bit": "yxcvb"
},
{
"key-cb": "f4",
"next-bit": "poiuzz"
}
]
},
"augmented-root": {
"aug-c": {
"original-leaf": [
null
],
"test-augment:list-1": [
{
"leaf-x": "x1",
"leaf-y": "x1"
},
{
"leaf-x": "EDITED",
"leaf-y": "x1"
},
{
"leaf-x": "x3",
"leaf-y": "x1"
}
]
},
"aug-l": [
{
"my-key": "k1",
"test-augment:abc": {
"abc": false
}
},
{
"my-key": "EDITED",
"test-augment:abc": {
"abc": true
}
},
{
"my-key": "k3",
"test-augment:abc": {
"abc": false
}
}
]
}
}
}
curl --location --request POST 'http://localhost:8181/rests/operations/subtree-manager:calculate-subtree-diff' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"source-path": "/network-topology:network-topology/topology=uniconfig/node=testtool/configuration/test-module:root",
"source-datastore": "OPERATIONAL",
"target-path": "/network-topology:network-topology/topology=uniconfig/node=testtool2/configuration/test-module-mod:root",
"target-datastore": "OPERATIONAL"
}
}'
{
"output": {
"updated-data": [
{
"path-intended": "/network-topology:network-topology/topology=uniconfig/node=testtool/frinx-uniconfig-topology:configuration/test-module:root/list-root/branch-ab",
"path-actual": "/network-topology:network-topology/topology=uniconfig/node=testtool2/frinx-uniconfig-topology:configuration/test-module-mod:root/list-root/branch-ab",
"data-actual": {
"test-module-mod:branch-ab": 5
},
"data-intended": {
"test-module:branch-ab": 9999
}
},
{
"path-intended": "/network-topology:network-topology/topology=uniconfig/node=testtool/frinx-uniconfig-topology:configuration/test-module:root/simple-root",
"path-actual": "/network-topology:network-topology/topology=uniconfig/node=testtool2/frinx-uniconfig-topology:configuration/test-module-mod:root/simple-root",
"data-actual": {
"test-module-mod:ll": [
"EDITED",
"str1",
"str2"
]
},
"data-intended": {
"test-module:ll": [
"str3",
"str2",
"str1"
]
}
},
{
"path-intended": "/network-topology:network-topology/topology=uniconfig/node=testtool/frinx-uniconfig-topology:configuration/test-module:root/simple-root/leaf-b",
"path-actual": "/network-topology:network-topology/topology=uniconfig/node=testtool2/frinx-uniconfig-topology:configuration/test-module-mod:root/simple-root/leaf-b",
"data-actual": {
"test-module-mod:leaf-b": "leafB"
},
"data-intended": {
"test-module:leaf-b": "EDITED"
}
}
],
"created-data": [
{
"path": "/network-topology:network-topology/topology=uniconfig/node=testtool2/frinx-uniconfig-topology:configuration/test-module-mod:root/augmented-root/aug-l=EDITED",
"data": {
"aug-l": [
{
"my-key": "EDITED",
"test-augment-mod:abc": {
"abc": true
}
}
]
}
},
{
"path": "/network-topology:network-topology/topology=uniconfig/node=testtool2/frinx-uniconfig-topology:configuration/test-module-mod:root/augmented-root/aug-c/test-augment-mod:list-1=EDITED",
"data": {
"list-1": [
{
"leaf-x": "EDITED",
"leaf-y": "x1"
}
]
}
},
{
"path": "/network-topology:network-topology/topology=uniconfig/node=testtool2/frinx-uniconfig-topology:configuration/test-module-mod:root/list-root/top-list=kc,EDITED",
"data": {
"top-list": [
{
"key-1": "kc",
"key-2": "EDITED",
"nested-list": [
{
"identifier": "q2",
"foo": 14
},
{
"identifier": "q1",
"foo": 13
},
{
"identifier": "q3",
"foo": 15
}
],
"next-data": {
"switch-2": [
null
]
}
}
]
}
}
],
"deleted-data": [
{
"path": "/network-topology:network-topology/topology=uniconfig/node=testtool/frinx-uniconfig-topology:configuration/test-module:root/list-root/top-list=kc,ke",
"data": {
"top-list": [
{
"key-1": "kc",
"key-2": "ke",
"nested-list": [
{
"identifier": "q2",
"foo": 14
},
{
"identifier": "q1",
"foo": 13
},
{
"identifier": "q3",
"foo": 15
}
],
"next-data": {
"switch-2": [
null
]
}
}
]
}
},
{
"path": "/network-topology:network-topology/topology=uniconfig/node=testtool/frinx-uniconfig-topology:configuration/test-module:root/augmented-root/aug-c/test-augment:list-1=x2",
"data": {
"list-1": [
{
"leaf-x": "x2",
"leaf-y": "x1"
}
]
}
},
{
"path": "/network-topology:network-topology/topology=uniconfig/node=testtool/frinx-uniconfig-topology:configuration/test-module:root/augmented-root/aug-l=k2",
"data": {
"aug-l": [
{
"my-key": "k2",
"test-augment:abc": {
"abc": true
}
}
]
}
}
]
}
}
#
Successful example: No difference
The following output demonstrates a situation with no changes between specified subtrees.
curl --location --request POST 'http://localhost:8181/rests/operations/subtree-manager:calculate-subtree-diff' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input" : {
"source-path": ["/network-topology:network-topology/network-topology:topology=uniconfig/network-topology:node=XR5/frinx-uniconfig-topology:configuration/frinx-openconfig-interfaces:interfaces/frinx-openconfig-interfaces:interface=GigabitEthernet0%2F0%2F0%2F0"],
"target-path": ["/network-topology:network-topology/network-topology:topology=uniconfig/network-topology:node=XR6/frinx-uniconfig-topology:configuration/frinx-openconfig-interfaces:interfaces/frinx-openconfig-interfaces:interface=GigabitEthernet0%2F0%2F0%2F0"],
"source-datastore": "CONFIGURATION",
"target-datastore": "CONFIGURATION"
}
}'
{
"output": {
}
}
#
Failed example: Invalid value in input field
RPC input contains an improperly defined datastore (AAA
).
RPC output describes the allowed values (CONFIGURATION
and OPERATIONAL
).
curl --location --request POST 'http://localhost:8181/rests/operations/subtree-manager:calculate-subtree-diff' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"source-path": "/network-topology:network-topology/topology=uniconfig/node=testtool/configuration/test-module:root",
"source-datastore": "AAA",
"target-path": "/network-topology:network-topology/topology=uniconfig/node=testtool2/configuration/test-module-mod:root",
"target-datastore": "OPERATIONAL"
}
}'
{
"errors": {
"error": [
{
"error-type": "protocol",
"error-tag": "malformed-message",
"error-message": "Error parsing input: Invalid value 'AAA' for enum type. Allowed values are: [CONFIGURATION, OPERATIONAL]",
"error-info": "Invalid value 'AAA' for enum type. Allowed values are: [CONFIGURATION, OPERATIONAL]"
}
]
}
}
#
Failed example: Missing mandatory field
RPC input does not contain the mandatory source path.
curl --location --request POST 'http://localhost:8181/rests/operations/subtree-manager:calculate-subtree-diff' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"target-path": "/network-topology:network-topology/topology=uniconfig/node=testtool2/configuration/test-module-mod:root",
"target-datastore": "OPERATIONAL"
}
}'
{
"errors": {
"error": [
{
"error-type": "application",
"error-tag": "invalid-value",
"error-message": "Field target-path is not specified in input request"
}
]
}
}
#
Failed example: Pointing to different schema node
RPC input contains source and target paths that do not point to the same schema node.
curl --location --request POST 'http://localhost:8181/rests/operations/subtree-manager:calculate-subtree-diff' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input" : {
"source-path": ["/network-topology:network-topology/network-topology:topology=uniconfig/network-topology:node=XR5/frinx-uniconfig-topology:configuration/frinx-openconfig-interfaces:interfaces/frinx-openconfig-interfaces:interface=GigabitEthernet0%2F0%2F0%2F0"],
"target-path": ["/network-topology:network-topology/network-topology:topology=uniconfig/network-topology:node=XR6/frinx-uniconfig-topology:configuration/Cisco-IOS-XR-ifmgr-cfg:interface-configurations/interface-configuration=act=GigabitEthernet0%2F0%2F0%2F0"],
"source-datastore": "CONFIGURATION",
"target-datastore": "CONFIGURATION"
}
}'
{
"errors": {
"error": [
{
"error-type": "application",
"error-tag": "invalid-value",
"error-message": "Source and target paths are not pointing to the same schema node"
}
]
}
}