#
RPC commit
The external application stores the intended configuration under nodes in the UniConfig topology. The trigger for execution of configuration is an RPC commit. Output of the RPC describes the result of the commit and matches all modified nodes in the UniConfig transaction.
The configuration of nodes consists of the following phases:
- Lock and validate configured nodes - Locking all modified nodes using PostgreSQL advisory locks and validation of fingerprints - if another transaction tries to commit overlapping nodes or different transaction has already changed one of the nodes, then commit will fail at this step.
- Write configuration into device - Pushing calculated changes into device without committing of this changes.
- Validate configuration - Validation of written configuration from the view of constraints and consistency. This phase can be skipped with "do-validate" flag.
- Confirmed commit - It is used for locking of device configuration, so no other transaction can touch this device. This phase can be skipped with "do-confirmed-commit" flag.
- Confirming commit (submit configuration) - Persisting all changes on devices and in the PostgreSQL database. UniConfig transaction is closed.
- Rollback - It is used for restoring of configuration to previous state, if the configuration process fails.
When configuring more devices in a single transaction and the process fails on one particular device,
the rollback procedure will be applied to all touched devices. This is done by auto rollback procedure,
which is by default turned on. It can be switched off by setting up 'do-rollback' flag in input of
Commit RPC request. Then only failed devices will be rollbacked.
The 'skip-unreachable-nodes' flag controls whether unreachable nodes are skipped when the RPC commit is sent. If set to 'true', nodes that are not reachable are skipped and others are configured. The default value is 'false'.
The third and fourth phases take place only on the nodes that support these operations. If one node failed in the random phase for any reason the RPC will fail entirely. After commit RPC, UniConfig transaction is closed regardless of the commit result.
If one of the nodes uses a confirmed commit (phase 4), which does not fail, then it is necessary to issue the submitted configuration (phase 5) within the timeout period. Otherwise the node configuration issued by the confirmed commit will be reverted to its state before the confirmed commit (i.e. confirmed commit makes only temporary configuration changes). The timeout period is 600 seconds (10 minutes) by default, but the user can change it in the installation request.
Next diagram describe the first phase of commit RPC - locking of changes nodes in the PostgreSQL database and verification if other transaction has already committed overlapping nodes.
Next diagrams describe all 5 commit phases in detail:
1. Lock and validate configured nodes
2. Write configuration into device
3. Validate configuration
4. Confirmed commit
5. Confirming commit (submit configuration)
The last diagram shows rollback procedure that must be executed after failed commit on nodes that have already been configured and don't support 'candidate' datastore.
#
RPC Examples
#
Successful Example
RPC commit input has 2 target nodes and the output describes the result of the commit.
curl --location --request POST 'http://localhost:8181/rests/operations/uniconfig-manager:commit' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"target-nodes": {
"node": ["IOSXR","IOSXRN"]
}
}
}'
{
"output": {
"overall-status": "complete",
"node-results": {
"node-result": [
{
"node-id": "IOSXRN",
"configuration-status": "complete"
},
{
"node-id": "IOSXR",
"configuration-status": "complete"
}
]
}
}
}
#
Successful Example
If the RPC input does not contain the target nodes, all touched nodes will be invoked.
curl --location --request POST 'http://localhost:8181/rests/operations/uniconfig-manager:commit' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"output": {
"overall-status": "complete",
"node-results": {
"node-result": [
{
"node-id": "IOSXRN",
"configuration-status": "complete"
},
{
"node-id": "IOSXR",
"configuration-status": "complete"
}
]
}
}
}'
{
"output": {
"overall-status": "complete"
}
}
#
Successful Example
RPC commit input has 2 target nodes and the flag to disable confirmed-commit phase. The output describes the result of the commit.
curl --location --request POST 'http://localhost:8181/rests/operations/uniconfig-manager:commit' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"do-confirmed-commit": false,
"target-nodes": {
"node": ["IOSXR","IOSXRN"]
}
}
}'
{
"output": {
"overall-status": "complete",
"node-results": {
"node-result": [
{
"node-id": "IOSXRN",
"configuration-status": "complete"
},
{
"node-id": "IOSXR",
"configuration-status": "complete"
}
]
},
}
}
#
Failed Example
RPC commit input has 2 target nodes and the output describes the result of the commit. One node has failed because failed validation (IOSXRN).
curl --location --request POST 'http://localhost:8181/rests/operations/uniconfig-manager:commit' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"target-nodes": {
"node": ["IOSXR", "IOSXRN"]
}
}
}'
{
"output": {
"overall-status": "fail",
"node-results": {
"node-result": [
{
"node-id": "IOSXRN",
"configuration-status": "fail",
"error-message": "RemoteDevice{IOSXRN}: Validate failed. illegal reference /orgs/org[name='TESTING-PROVIDER']/traffic-identification/using-networks\n",
"error-type": "uniconfig-error",
"rollback-status": "complete"
},
{
"node-id": "IOSXR",
"configuration-status": "complete",
"rollback-status": "complete"
}
]
}
}
}
#
Failed Example
RPC commit input has 2 target nodes and the output describes the result of the commit. One node has failed because the confirmed commit failed (IOSXRN). Validation phase was skipped due to false "do-validate" flag.
curl --location --request POST 'http://localhost:8181/rests/operations/uniconfig-manager:commit' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"do-validate" : False,
"target-nodes": {
"node": ["IOSXR", "IOSXRN"]
}
}
}'
{
"output": {
"overall-status": "fail",
"node-results": {
"node-result": [
{
"node-id": "IOSXRN",
"configuration-status": "fail",
"error-message": "RemoteDevice{IOSXRN}: Confirmed commit failed. illegal reference /orgs/org[name='TESTING-PROVIDER']/traffic-identification/using-networks\n",
"error-type": "uniconfig-error",
"rollback-status": "complete"
},
{
"node-id": "IOSXR",
"configuration-status": "complete",
"rollback-status": "complete"
}
]
}
}
}
#
Failed Example
RPC commit input has 2 target nodes and the output describes the result of the commit. One node has failed because of the time delay between the confirmed commit and the submitted configuration (IOSXRN).
curl --location --request POST 'http://localhost:8181/rests/operations/uniconfig-manager:commit' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"target-nodes": {
"node": ["IOSXR", "IOSXRN"]
}
}
}'
{
"output": {
"overall-status": "fail",
"node-results": {
"node-result": [
{
"node-id": "IOSXRN",
"configuration-status": "fail",
"error-message": "RemoteDevice{IOSXRN}: time delay between confirmed and confirming commit was greater than 300 seconds, the configured changes were rolled back.\n",
"error-type": "uniconfig-error",
"rollback-status": "complete"
},
{
"node-id": "IOSXR",
"configuration-status": "complete",
"rollback-status": "complete"
}
]
}
}
}
#
Failed Example
RPC commit input has 2 target nodes and the output describes the result of the commit. One node has failed due to improper configuration (IOSXRN).
curl --location --request POST 'http://localhost:8181/rests/operations/uniconfig-manager:commit' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"target-nodes": {
"node": ["IOSXR","IOSXRN"]
}
}
}'
{
"output": {
"overall-status": "fail",
"node-results": {
"node-result": [
{
"node-id": "IOSXRN",
"configuration-status": "fail",
"error-message": "Supplied value \"GigabitEthernet0/0/0/1ghjfhjfhjfghj\" does not match required pattern \"^(([a-zA-Z0-9_]*\\d+/){3,4}\\d+)|(([a-zA-Z0-9_]*\\d+/){3,4}\\d+\\.\\d+)|(([a-zA-Z0-9_]*\\d+/){2}([a-zA-Z0-9_]*\\d+))|(([a-zA-Z0-9_]*\\d+/){2}([a-zA-Z0-9_]+))|([a-zA-Z0-9_-]*\\d+)|([a-zA-Z0-9_-]*\\d+\\.\\d+)|(mpls)|(dwdm)$\"\n",
"error-type": "uniconfig-error",
"rollback-status": "complete"
},
{
"node-id": "IOSXR",
"configuration-status": "complete",
"rollback-status": "complete"
}
]
}
}
}
#
Failed Example
RPC commit input has 3 target nodes and the output describes the result of the commit. One node has failed due ot improper configuration (IOSXR), the other has not been changed (IOSXRN), and the last has not been mounted yet (AAA).
curl --location --request POST 'http://localhost:8181/rests/operations/uniconfig-manager:commit' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"target-nodes": {
"node": ["IOSXR","IOSXRN","AAA"]
}
}
}'
{
"output": {
"overall-status": "fail",
"node-results": {
"node-result": [
{
"node-id": "AAA",
"error-type": "no-connection",
"error-message": "Node has not been mounted yet.",
"configuration-status": "fail"
},
{
"node-id": "IOSXRN",
"configuration-status": "fail",
"error-type": "uniconfig-error"
},
{
"node-id": "IOSXR",
"configuration-status": "fail",
"error-type": "uniconfig-error"
}
]
}
}
}
#
Failed Example
RPC commit input has 2 target nodes and the output describes the result of the commit. One node has failed due to improper configuration (IOSXRN), the other has not been changed (IOSXR).
curl --location --request POST 'http://localhost:8181/rests/operations/uniconfig-manager:commit' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"target-nodes": {
"node": ["IOSXR","IOSXRN"]
}
}
}'
{
"output": {
"overall-status": "fail",
"node-results": {
"node-result": [
{
"node-id": "IOSXR",
"configuration-status": "complete",
"rollback-status": "complete"
},
{
"node-id": "IOSXRN",
"configuration-status": "fail",
"error-message": "Illegal value for key: (http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg?revision=2017-09-07)interface-name, in: (http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg?revision=2017-09-07)interface-configuration[{(http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg?revision=2017-09-07)active=act, (http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg?revision=2017-09-07)interface-name=GigabitEthernet0/0/0/3}], actual value: GigabitEthernet0/0/0/3/ddd, expected value from key: GigabitEthernet0/0/0/3\n",
"error-type": "uniconfig-error",
"rollback-status": "complete"
}
]
}
}
}
#
Failed Example
RPC commit input has 2 target nodes and the output describes the result of the commit. One node has lost connection (IOSXR), the other has not been mounted yet (AAA).
curl --location --request POST 'http://localhost:8181/rests/operations/uniconfig-manager:commit' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"target-nodes": {
"node": ["IOSXR","AAA"]
}
}
}'
{
"output": {
"overall-status": "fail",
"node-results": {
"node-result": [
{
"node-id": "AAA",
"error-type": "no-connection",
"error-message": "Node has not been mounted yet.",
"configuration-status": "fail"
},
{
"node-id": "IOSXR",
"configuration-status": "fail",
"error-message": "Unified Mountpoint not found.",
"error-type": "no-connection"
}
]
}
}
}
#
Failed Example
RPC commit input has 2 target nodes and the output describes the result of the commit. One node has failed because of wrong configuration (R2). In this case validation, confirm-commit and auto-rollback was switched off. Because auto-rollback is switched off, configuration of R1 device was successful. However this can be done only, if validation and confirm-commit phase was successful or skipped, otherwise configuration of R1 device would also fail.
curl --location --request POST 'http://localhost:8181/rests/operations/uniconfig-manager:commit' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"target-nodes": {
"node": ["R1", "R2"]
},
"do-rollback" : false,
"do-validate" : false,
"do-confirmed-commit" : false
}
}'
{
"output": {
"node-results": {
"node-result": [
{
"node-id": "R1",
"configuration-status": "complete"
},
{
"node-id": "R2",
"configuration-status": "fail",
"error-message": "RemoteDevice{vnf212}: RPC during tx failed. Error messages: [/alias[name='^new']/expansion is not configured]\n",
"error-type": "uniconfig-error"
}
]
},
"overall-status": "fail"
}
}
#
Failed Example
If the RPC input does not contain the target nodes and there weren't any touched nodes, the request will result in an error.
curl --location --request POST 'http://localhost:8181/rests/operations/uniconfig-manager:commit' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"target-nodes": {
}
}
}'
{
"output": {
"error-message": "There aren't any nodes specified in input RPC and there aren't any touched nodes.",
"overall-status": "fail"
}
}
#
Failed Example
RPC commit input has two target nodes and the flag to skip unreachable nodes. The output describes the result of the commit.
curl --location --request POST 'http://localhost:8181/rests/operations/uniconfig-manager:commit' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"skip-unreachable-nodes": true,
"target-nodes": {
"node": ["dev1","dev2"]
}
}
}'
{
"output": {
"node-results": {
"node-result": [
{
"node-id": "dev1",
"configuration-status": "complete"
},
{
"node-id": "dev2",
"error-message": "Node dev2 is unreachable (skipped)",
"configuration-status": "fail"
}
]
},
"overall-status": "fail"
}
}