From 286455ad4cb16e0251c39d0eaa759b9297411e51 Mon Sep 17 00:00:00 2001 From: Retype GitHub Action Date: Wed, 25 Sep 2024 10:36:27 +0000 Subject: [PATCH] Refreshes Retype-generated documentation. Process triggered by Jozefiel. --- 404.html | 8 +- frinx-device-inventory/blueprints/index.html | 10 +-- frinx-device-inventory/inventory/index.html | 10 +-- frinx-machine/api-docs/index.html | 8 +- frinx-machine/getting-started/index.html | 8 +- frinx-machine/installation/basic/index.html | 29 +++--- .../custom-worker-deployment/index.html | 10 +-- .../create-kind-cluster/index.html | 12 +-- .../frinx-machine-customization/index.html | 31 +++---- .../docker-registry-secret/index.html | 10 +-- .../installation/oauth2-proxy/index.html | 26 ++---- frinx-machine/monitoring/index.html | 8 +- .../add-to-inventory-and-install/index.html | 10 +-- .../use-cases/create-l2-vpn-p2p/index.html | 8 +- .../index.html | 8 +- .../use-cases/create-workflow/index.html | 8 +- frinx-machine/use-cases/dashboard/index.html | 8 +- .../device-configure-loopback/index.html | 8 +- frinx-machine/use-cases/index.html | 10 +-- .../index.html | 8 +- .../architecture/index.html | 8 +- .../developer-guide/index.html | 8 +- .../introduction/index.html | 8 +- frinx-resource-manager/pools/index.html | 8 +- frinx-resource-manager/user-guide/index.html | 8 +- .../developer-guide/architecture/index.html | 8 +- .../cli-translation-unit/index.html | 10 +-- frinx-uniconfig/developer-guide/index.html | 8 +- .../developer-guide/metrics/index.html | 10 +-- .../native-cli-units/index.html | 10 +-- .../netconf-translation-unit/index.html | 10 +-- .../index.html | 8 +- .../index.html | 8 +- .../translation-units-docs/index.html | 8 +- .../translation-units-in-general/index.html | 8 +- frinx-uniconfig/generated-api-libs/index.html | 8 +- frinx-uniconfig/getting-started/index.html | 8 +- frinx-uniconfig/glossary-of-terms/index.html | 8 +- frinx-uniconfig/q_a/index.html | 10 +-- frinx-uniconfig/release-notes/index.html | 8 +- .../release-notes/uniconfig-4.2.10/index.html | 8 +- .../release-notes/uniconfig-4.2.3/index.html | 8 +- .../release-notes/uniconfig-4.2.4/index.html | 8 +- .../release-notes/uniconfig-4.2.5/index.html | 8 +- .../release-notes/uniconfig-4.2.6/index.html | 8 +- .../release-notes/uniconfig-4.2.7/index.html | 8 +- .../release-notes/uniconfig-4.2.8/index.html | 8 +- .../release-notes/uniconfig-4.2.9/index.html | 8 +- .../release-notes/uniconfig-5.0.1/index.html | 8 +- .../release-notes/uniconfig-5.0.10/index.html | 8 +- .../release-notes/uniconfig-5.0.11/index.html | 8 +- .../release-notes/uniconfig-5.0.12/index.html | 8 +- .../release-notes/uniconfig-5.0.13/index.html | 8 +- .../release-notes/uniconfig-5.0.14/index.html | 8 +- .../release-notes/uniconfig-5.0.15/index.html | 8 +- .../release-notes/uniconfig-5.0.16/index.html | 8 +- .../release-notes/uniconfig-5.0.17/index.html | 8 +- .../release-notes/uniconfig-5.0.18/index.html | 8 +- .../release-notes/uniconfig-5.0.19/index.html | 8 +- .../release-notes/uniconfig-5.0.2/index.html | 8 +- .../release-notes/uniconfig-5.0.20/index.html | 8 +- .../release-notes/uniconfig-5.0.21/index.html | 8 +- .../release-notes/uniconfig-5.0.22/index.html | 8 +- .../release-notes/uniconfig-5.0.23/index.html | 8 +- .../release-notes/uniconfig-5.0.24/index.html | 8 +- .../release-notes/uniconfig-5.0.25/index.html | 8 +- .../release-notes/uniconfig-5.0.3/index.html | 8 +- .../release-notes/uniconfig-5.0.4/index.html | 8 +- .../release-notes/uniconfig-5.0.5/index.html | 8 +- .../release-notes/uniconfig-5.0.6/index.html | 8 +- .../release-notes/uniconfig-5.0.7/index.html | 8 +- .../release-notes/uniconfig-5.0.8/index.html | 8 +- .../release-notes/uniconfig-5.0.9/index.html | 8 +- .../release-notes/uniconfig-5.1.0/index.html | 8 +- .../release-notes/uniconfig-5.1.1/index.html | 8 +- .../release-notes/uniconfig-5.1.10/index.html | 8 +- .../release-notes/uniconfig-5.1.11/index.html | 8 +- .../release-notes/uniconfig-5.1.12/index.html | 8 +- .../release-notes/uniconfig-5.1.13/index.html | 8 +- .../release-notes/uniconfig-5.1.14/index.html | 8 +- .../release-notes/uniconfig-5.1.15/index.html | 8 +- .../release-notes/uniconfig-5.1.16/index.html | 8 +- .../release-notes/uniconfig-5.1.17/index.html | 8 +- .../release-notes/uniconfig-5.1.18/index.html | 8 +- .../release-notes/uniconfig-5.1.19/index.html | 8 +- .../release-notes/uniconfig-5.1.2/index.html | 8 +- .../release-notes/uniconfig-5.1.20/index.html | 8 +- .../release-notes/uniconfig-5.1.21/index.html | 8 +- .../release-notes/uniconfig-5.1.22/index.html | 8 +- .../release-notes/uniconfig-5.1.23/index.html | 8 +- .../release-notes/uniconfig-5.1.3/index.html | 8 +- .../release-notes/uniconfig-5.1.4/index.html | 8 +- .../release-notes/uniconfig-5.1.5/index.html | 8 +- .../release-notes/uniconfig-5.1.6/index.html | 8 +- .../release-notes/uniconfig-5.1.7/index.html | 8 +- .../release-notes/uniconfig-5.1.8/index.html | 8 +- .../release-notes/uniconfig-5.1.9/index.html | 8 +- .../release-notes/uniconfig-5.2.0/index.html | 8 +- .../release-notes/uniconfig-5.2.1/index.html | 8 +- .../release-notes/uniconfig-5.2.2/index.html | 8 +- .../release-notes/uniconfig-5.2.3/index.html | 8 +- .../release-notes/uniconfig-5.2.4/index.html | 8 +- .../release-notes/uniconfig-5.2.5/index.html | 8 +- .../release-notes/uniconfig-5.2.6/index.html | 8 +- .../release-notes/uniconfig-5.2.7/index.html | 8 +- .../release-notes/uniconfig-6.0.0/index.html | 8 +- .../release-notes/uniconfig-6.0.1/index.html | 8 +- .../release-notes/uniconfig-6.0.2/index.html | 8 +- .../release-notes/uniconfig-6.0.3/index.html | 8 +- .../release-notes/uniconfig-6.0.4/index.html | 8 +- .../release-notes/uniconfig-6.0.5/index.html | 8 +- .../release-notes/uniconfig-6.0.6/index.html | 8 +- .../release-notes/uniconfig-6.0.7/index.html | 8 +- .../release-notes/uniconfig-6.0.8/index.html | 8 +- .../release-notes/uniconfig-6.0.9/index.html | 8 +- .../release-notes/uniconfig-6.1.0/index.html | 8 +- .../release-notes/uniconfig-6.1.1/index.html | 8 +- .../release-notes/uniconfig-6.1.2/index.html | 8 +- .../release-notes/uniconfig-6.1.3/index.html | 8 +- .../release-notes/uniconfig-6.1.4/index.html | 8 +- .../release-notes/uniconfig-6.1.5/index.html | 8 +- .../release-notes/uniconfig-6.1.6/index.html | 8 +- .../release-notes/uniconfig-7.0.0/index.html | 8 +- .../release-notes/uniconfig-7.0.1/index.html | 8 +- frinx-uniconfig/supported-devices/index.html | 8 +- .../configuration-datasets/aaa/index.html | 10 +-- .../configuration-datasets/acl/acl/index.html | 10 +-- .../acl/acl_interfaces/index.html | 10 +-- .../bcast-containment/index.html | 10 +-- .../cable/cable_downstream_profile/index.html | 10 +-- .../cable/cable_fiber_node/index.html | 10 +-- .../cable/cable_rpd/index.html | 10 +-- .../configuration-datasets/cdp/index.html | 10 +-- .../configuration-datasets/evc/index.html | 10 +-- .../configuration-datasets/evpn/index.html | 10 +-- .../configuration-datasets/fdp/index.html | 10 +-- .../configuration-datasets/hsrp/index.html | 8 +- .../configuration-datasets/index.html | 8 +- .../interfaces/bridge_interface/index.html | 10 +-- .../interfaces/cable_interface/index.html | 10 +-- .../interfaces/ethernet_interface/index.html | 10 +-- .../interfaces/l2vlan_interface/index.html | 10 +-- .../interfaces/l3vlan_interface/index.html | 10 +-- .../interfaces/lag_interface/index.html | 10 +-- .../interfaces/wideband_interface/index.html | 10 +-- .../ipsec/ipsec/index.html | 10 +-- .../configuration-datasets/l2-cft/index.html | 10 +-- .../configuration-datasets/logging/index.html | 8 +- .../netflow/netflow_interfaces/index.html | 10 +-- .../l2p2p/connection_point/index.html | 10 +-- .../l2vpn/connection_point_l2vpn/index.html | 10 +-- .../network-instances/l2vsi/l2vsi/index.html | 10 +-- .../l2vsi/l2vsicp/index.html | 10 +-- .../network_instance_l3vpn_bgp/index.html | 10 +-- .../network_instance_l3vpn_ospf/index.html | 10 +-- .../mpls/mpls_ldp/index.html | 10 +-- .../mpls/mpls_rsvp/index.html | 10 +-- .../network-instances/mpls/mpls_te/index.html | 10 +-- .../mpls/mpls_tunnel/index.html | 10 +-- .../network_instance/index.html | 10 +-- .../pf_interfaces/index.html | 10 +-- .../protocols/bgp/index.html | 10 +-- .../protocols/isis/index.html | 10 +-- .../protocols/ospf/index.html | 10 +-- .../protocols/ospfv3/index.html | 10 +-- .../protocols/static/index.html | 10 +-- .../network-instances/vlans/vlan/index.html | 10 +-- .../configuration-datasets/oam/index.html | 10 +-- .../privilege/index.html | 10 +-- .../configuration-datasets/probes/index.html | 10 +-- .../configuration-datasets/qos/index.html | 10 +-- .../relay-agent/index.html | 10 +-- .../routing-policy/routing-policy/index.html | 10 +-- .../configuration-datasets/snmp/index.html | 10 +-- .../configuration-datasets/stp/index.html | 10 +-- .../configuration-datasets/system/index.html | 10 +-- .../ietf_l2p2p_local_to_oc/index.html | 10 +-- .../ietf_l2p2p_remote_to_oc/index.html | 10 +-- .../ietf_l2vpn_to_oc/index.html | 10 +-- .../ietf_l3vpn_to_oc/index.html | 10 +-- .../translation-units-docs/index.html | 10 +-- .../operational-datasets/cdp/index.html | 10 +-- .../operational-datasets/index.html | 8 +- .../interfaces/index.html | 10 +-- .../operational-datasets/lldp/index.html | 10 +-- .../protocols/bgp_rib/index.html | 10 +-- .../protocols/bgp_summary/index.html | 10 +-- .../protocols/ospf_summary/index.html | 10 +-- .../operational-datasets/platform/index.html | 10 +-- .../operational-datasets/system/index.html | 10 +-- .../translation-framework-101/index.html | 8 +- .../user-guide/basic-concepts/index.html | 8 +- frinx-uniconfig/user-guide/index.html | 8 +- .../user-guide/monitoring/index.html | 10 +-- .../network-management-protocols/index.html | 8 +- .../uniconfig-installing/index.html | 10 +-- .../uniconfig-native_cli/index.html | 10 +-- .../uniconfig_cli/index.html | 10 +-- .../uniconfig_gnmi/index.html | 10 +-- .../uniconfig_gnmi/iosxr7/index.html | 10 +-- .../uniconfig_gnmi/nokia/index.html | 10 +-- .../uniconfig_gnmi/sonic/index.html | 10 +-- .../uniconfig_netconf/calix/index.html | 10 +-- .../uniconfig_netconf/index.html | 10 +-- .../uniconfig_netconf/iosxr/index.html | 10 +-- .../uniconfig_netconf/junos/index.html | 10 +-- .../uniconfig_netconf/ocnos/index.html | 10 +-- .../uniconfig_netconf/sros/index.html | 10 +-- .../uniconfig_snmp/index.html | 10 +-- .../index.html | 10 +-- .../data-flows/index.html | 8 +- .../data-security-models/index.html | 10 +-- .../operational-procedures/index.html | 8 +- .../operational-procedures/logging/index.html | 10 +-- .../operational-procedures/openapi/index.html | 8 +- .../postgres-tls/index.html | 10 +-- .../thread-pools/index.html | 8 +- .../operational-procedures/tls/index.html | 10 +-- .../uniconfig-clustering/index.html | 10 +-- .../uniconfig-properties/index.html | 10 +-- .../performance_characteristics/index.html | 8 +- frinx-uniconfig/user-guide/sdk/index.html | 10 +-- .../admin-state/index.html | 10 +-- .../build-and-commit-model/index.html | 10 +-- .../device-discovery/index.html | 10 +-- .../dryrun-manager/index.html | 10 +-- .../immediate-commit-model/index.html | 10 +-- .../uniconfig-operations/index.html | 8 +- .../application-jsonb-filtering/index.html | 10 +-- .../database-jsonb-filtering/index.html | 8 +- .../jsonb-filtering/index.html | 8 +- .../kafka-notifications/index.html | 10 +-- .../index.html | 10 +-- .../uniconfig-operations/restconf/index.html | 10 +-- .../snapshot-manager/index.html | 8 +- .../obtain_snapshot_metadata/index.html | 10 +-- .../rpc_create-snapshot/index.html | 10 +-- .../rpc_delete-snapshot/index.html | 10 +-- .../index.html | 10 +-- .../subtree-manager/index.html | 8 +- .../subtree-manager/rpc_bulk-edit/index.html | 10 +-- .../rpc_calculate-subtree-diff/index.html | 10 +-- .../index.html | 10 +-- .../rpc_copy-many-to-one/index.html | 10 +-- .../rpc_copy-one-to-many/index.html | 10 +-- .../rpc_copy-one-to-one/index.html | 10 +-- .../templates-manager/index.html | 10 +-- .../rpc_apply-template/index.html | 10 +-- .../rpc_create-multiple-templates/index.html | 10 +-- .../rpc_get-template-info/index.html | 10 +-- .../rpc_get-template-nodes/index.html | 10 +-- .../rpc_upgrade-template/index.html | 10 +-- .../transaction-log/index.html | 8 +- .../rpc_revert-changes/index.html | 10 +-- .../transaction-tracker/index.html | 10 +-- .../uniconfig-node-manager/index.html | 8 +- .../rpc_bulk-get/index.html | 10 +-- .../rpc_calculate-diff/index.html | 10 +-- .../rpc_calculate-git-like-diff/index.html | 10 +-- .../rpc_checked-commit/index.html | 10 +-- .../rpc_commit/index.html | 10 +-- .../rpc_compare-config/index.html | 10 +-- .../rpc_connect-node/index.html | 10 +-- .../rpc_disconnect-node/index.html | 10 +-- .../rpc_health/index.html | 10 +-- .../rpc_is-in-sync/index.html | 10 +-- .../rpc_replace-config-with-oper/index.html | 10 +-- .../rpc_sync-from-network/index.html | 10 +-- .../rpc_sync-to-network/index.html | 10 +-- .../rpc_validate/index.html | 10 +-- .../index.html | 10 +-- .../index.html | 10 +-- .../index.html | 10 +-- .../index.html | 10 +-- .../index.html | 10 +-- .../uniconfig-properties/index.html | 8 +- .../rpc_read-properties/index.html | 10 +-- .../rpc_update-properties/index.html | 10 +-- .../uniconfig-queries/index.html | 10 +-- .../uniconfig-shell/index.html | 10 +-- .../unistore-api/index.html | 10 +-- .../uniconfig-operations/utilities/index.html | 8 +- .../utilities/openapi-diff/index.html | 10 +-- .../utilities/yang-packager/index.html | 10 +-- .../yang-patch/index.html | 10 +-- .../introduction/index.html | 8 +- .../python-sdk/development/index.html | 83 ++++-------------- .../python-sdk/frinx-python-sdk/index.html | 10 +-- frinx-workflow-manager/python-sdk/index.html | 8 +- .../python-sdk/services-python-api/index.html | 10 +-- .../services-python-workers/index.html | 10 +-- .../python-sdk/workflow-builder/index.html | 10 +-- .../workflow-builder/index.html | 8 +- index.html | 8 +- resources/js/config.js | 2 +- resources/js/search.json | 2 +- sitemap.xml.gz | Bin 3031 -> 3032 bytes 297 files changed, 1371 insertions(+), 1432 deletions(-) diff --git a/404.html b/404.html index 3e1b99b89..8bd8a6e18 100644 --- a/404.html +++ b/404.html @@ -6,7 +6,7 @@ - + @@ -31,11 +31,11 @@ - + - + - +
diff --git a/frinx-device-inventory/blueprints/index.html b/frinx-device-inventory/blueprints/index.html index 1f075f744..0fbe7a68a 100644 --- a/frinx-device-inventory/blueprints/index.html +++ b/frinx-device-inventory/blueprints/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
diff --git a/frinx-device-inventory/inventory/index.html b/frinx-device-inventory/inventory/index.html index 94f113822..10cd21609 100644 --- a/frinx-device-inventory/inventory/index.html +++ b/frinx-device-inventory/inventory/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
diff --git a/frinx-machine/api-docs/index.html b/frinx-machine/api-docs/index.html index dad4ebbaa..f33868cca 100644 --- a/frinx-machine/api-docs/index.html +++ b/frinx-machine/api-docs/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
diff --git a/frinx-machine/getting-started/index.html b/frinx-machine/getting-started/index.html index e02c84431..a42e4e76b 100644 --- a/frinx-machine/getting-started/index.html +++ b/frinx-machine/getting-started/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
diff --git a/frinx-machine/installation/basic/index.html b/frinx-machine/installation/basic/index.html index d16f96ba3..84b116397 100644 --- a/frinx-machine/installation/basic/index.html +++ b/frinx-machine/installation/basic/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
@@ -338,7 +338,7 @@

Install the FRINX Machine using Helm:

-
helm install -n frinx frinx-machine frinx/frinx-machine
+
helm install -n frinx frinx-machine frinx/frinx-machine --timeout 10m

Verify the installation by checking the pods in the frinx namespace:

@@ -380,17 +380,22 @@

Step 6: Access the UI

-

Add the following entries to your /etc/hosts file:

+

To access ui, use krakend-nginx ingress hostname.

+
+
kubectl get ingress -n frinx
+
+

You should see output similar to:

+
+
NAME            CLASS   HOSTS                      ADDRESS        PORTS   AGE
+krakend-nginx   nginx   krakend.127.0.0.1.nip.io   192.168.49.2   80      56m
+
+

In case of minikube is required to add the following entries to your /etc/hosts file:

# /etc/hosts
 ...
 192.168.49.2 krakend.127.0.0.1.nip.io fm.127.0.0.1.nip.io
-

Enable the KrakenD ingress for the FRINX Machine:

-
-
helm upgrade --install -n frinx frinx-machine frinx/frinx-machine --set krakend.ingress.enabled=true
-
-

Visit Frinx Machine page in your browser on https://krakend.127.0.0.1.nip.io/frinxui

+

and visit Frinx Machine page in your browser on https://krakend.127.0.0.1.nip.io/frinxui

diff --git a/frinx-machine/installation/custom-worker-deployment/index.html b/frinx-machine/installation/custom-worker-deployment/index.html index 83e587749..9503389fc 100644 --- a/frinx-machine/installation/custom-worker-deployment/index.html +++ b/frinx-machine/installation/custom-worker-deployment/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
diff --git a/frinx-machine/installation/customization/create-kind-cluster/index.html b/frinx-machine/installation/customization/create-kind-cluster/index.html index aa925012d..4cc4f3e5d 100644 --- a/frinx-machine/installation/customization/create-kind-cluster/index.html +++ b/frinx-machine/installation/customization/create-kind-cluster/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
@@ -326,7 +326,7 @@

Create a Cilium configuration file named cilium-helm-values.yaml with the following content:

# cilium-helm-values.yaml
-kubeProxyReplacement: strict
+kubeProxyReplacement: true
 k8sServiceHost: kind-control-plane 
 k8sServicePort: 6443 
 hostServices:
diff --git a/frinx-machine/installation/customization/frinx-machine-customization/index.html b/frinx-machine/installation/customization/frinx-machine-customization/index.html
index de6210887..7509b29d7 100644
--- a/frinx-machine/installation/customization/frinx-machine-customization/index.html
+++ b/frinx-machine/installation/customization/frinx-machine-customization/index.html
@@ -6,7 +6,7 @@
 
     
     
-    
+    
 
     
     
@@ -34,12 +34,12 @@
     
 
     
-    
+    
 
-    
+    
     
-    
-    
+    
+    
 
 
     
@@ -341,13 +341,13 @@

description: Kubernetes deployment of FRINX-machine icon: https://avatars.githubusercontent.com/u/23452093?s=200&v=4 type: application -version: 6.1.0 +version: 6.2.0 maintainers: - name: FRINX dependencies: - name: frinx-machine repository: https://FRINXio.github.io/helm-charts - version: 9.0.0

+ version: 10.0.1

This configuration sets up the basic information about the Helm chart and defines FRINX Machine as a dependency, pulling it from the specified repository.

    @@ -369,18 +369,9 @@

    # values.yaml
     frinx-machine:
       krakend:
    -    ingress:
    -      enabled: true
    -      className: nginx
    -      annotations:
    -        nginx.ingress.kubernetes.io/proxy-connect-timeout: "3600"
    -        nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    -        nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    -      hosts:
    -        - host: krakend.127.0.0.1.nip.io
    -          paths:
    -            - path: "/"
    -              pathType: ImplementationSpecific
    +    nginx:
    +      ingress:
    +        hostname: krakend.127.0.0.1.nip.io
     
       uniconfig:
         image:
    @@ -391,7 +382,7 @@ 

    repository: "frinxio/performance-monitor"

    -
  • krakend: Configures the Ingress settings for the KrakenD API Gateway. It enables the Ingress, sets the class to nginx, and includes custom annotations for proxy timeouts. The host is set to krakend.127.0.0.1.nip.io with the path /.

    +
  • krakend.nginx.ingress.hostname: Configures the Ingress settings for the KrakenD API Gateway.

  • uniconfig: Specifies the Docker image repository for the Uniconfig component.

  • diff --git a/frinx-machine/installation/docker-registry-secret/index.html b/frinx-machine/installation/docker-registry-secret/index.html index 1c2a69691..24b6e6d01 100644 --- a/frinx-machine/installation/docker-registry-secret/index.html +++ b/frinx-machine/installation/docker-registry-secret/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-machine/installation/oauth2-proxy/index.html b/frinx-machine/installation/oauth2-proxy/index.html index 1671f9c06..b86c56d52 100644 --- a/frinx-machine/installation/oauth2-proxy/index.html +++ b/frinx-machine/installation/oauth2-proxy/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    @@ -319,17 +319,6 @@

    enabled: true architecture: standalone - ingress: - enabled: true - className: nginx - hosts: - - "fm.127.0.0.1.nip.io" - annotations: - nginx.ingress.kubernetes.io/force-ssl-redirect: "true" - nginx.ingress.kubernetes.io/proxy-connect-timeout: "3600" - nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" - nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" - sessionStorage: type: redis redis: @@ -344,7 +333,7 @@

    # https://oauth2-proxy.github.io/oauth2-proxy/configuration/overview custom_sign_in_logo = "/tmp/frinx/frinx.png" - upstreams = ["http://krakend:8080"] + upstreams = "file:///dev/null" cookie_secure = true cookie_expire = 0 @@ -368,8 +357,9 @@

    ssl_insecure_skip_verify = false pass_access_token = false - + set_xauthrequest = true skip_jwt_bearer_tokens = true + reverse_proxy = true extraArgs: azure-graph-group-field: displayName diff --git a/frinx-machine/monitoring/index.html b/frinx-machine/monitoring/index.html index ee1a5c754..340975a6c 100644 --- a/frinx-machine/monitoring/index.html +++ b/frinx-machine/monitoring/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
    diff --git a/frinx-machine/use-cases/add-to-inventory-and-install/index.html b/frinx-machine/use-cases/add-to-inventory-and-install/index.html index 30380a20b..769768d57 100644 --- a/frinx-machine/use-cases/add-to-inventory-and-install/index.html +++ b/frinx-machine/use-cases/add-to-inventory-and-install/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-machine/use-cases/create-l2-vpn-p2p/index.html b/frinx-machine/use-cases/create-l2-vpn-p2p/index.html index 3594ff4a4..d02168231 100644 --- a/frinx-machine/use-cases/create-l2-vpn-p2p/index.html +++ b/frinx-machine/use-cases/create-l2-vpn-p2p/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
    diff --git a/frinx-machine/use-cases/create-loopback-all-in-uniconfig/index.html b/frinx-machine/use-cases/create-loopback-all-in-uniconfig/index.html index 17f0d1363..f5cbd4af7 100644 --- a/frinx-machine/use-cases/create-loopback-all-in-uniconfig/index.html +++ b/frinx-machine/use-cases/create-loopback-all-in-uniconfig/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
    diff --git a/frinx-machine/use-cases/create-workflow/index.html b/frinx-machine/use-cases/create-workflow/index.html index d4df823b8..6cce820f1 100644 --- a/frinx-machine/use-cases/create-workflow/index.html +++ b/frinx-machine/use-cases/create-workflow/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
    diff --git a/frinx-machine/use-cases/dashboard/index.html b/frinx-machine/use-cases/dashboard/index.html index 52f9779c6..4b68c7965 100644 --- a/frinx-machine/use-cases/dashboard/index.html +++ b/frinx-machine/use-cases/dashboard/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
    diff --git a/frinx-machine/use-cases/device-configure-loopback/index.html b/frinx-machine/use-cases/device-configure-loopback/index.html index fb8e7c739..9120f60d4 100644 --- a/frinx-machine/use-cases/device-configure-loopback/index.html +++ b/frinx-machine/use-cases/device-configure-loopback/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
    diff --git a/frinx-machine/use-cases/index.html b/frinx-machine/use-cases/index.html index 7c0c8a78b..bfd50eac8 100644 --- a/frinx-machine/use-cases/index.html +++ b/frinx-machine/use-cases/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-machine/use-cases/install-all-devices-from-inventory/index.html b/frinx-machine/use-cases/install-all-devices-from-inventory/index.html index d373a12a4..9a1cd3831 100644 --- a/frinx-machine/use-cases/install-all-devices-from-inventory/index.html +++ b/frinx-machine/use-cases/install-all-devices-from-inventory/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
    diff --git a/frinx-resource-manager/architecture/index.html b/frinx-resource-manager/architecture/index.html index b6a773c31..6f75524d5 100644 --- a/frinx-resource-manager/architecture/index.html +++ b/frinx-resource-manager/architecture/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
    diff --git a/frinx-resource-manager/developer-guide/index.html b/frinx-resource-manager/developer-guide/index.html index 101fb003c..0df630f14 100644 --- a/frinx-resource-manager/developer-guide/index.html +++ b/frinx-resource-manager/developer-guide/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-resource-manager/introduction/index.html b/frinx-resource-manager/introduction/index.html index 1b32f4b54..ea3cf3e9d 100644 --- a/frinx-resource-manager/introduction/index.html +++ b/frinx-resource-manager/introduction/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
    diff --git a/frinx-resource-manager/pools/index.html b/frinx-resource-manager/pools/index.html index ef12a8d55..2365ba4c2 100644 --- a/frinx-resource-manager/pools/index.html +++ b/frinx-resource-manager/pools/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
    diff --git a/frinx-resource-manager/user-guide/index.html b/frinx-resource-manager/user-guide/index.html index cbbcd5dfb..1eff4c910 100644 --- a/frinx-resource-manager/user-guide/index.html +++ b/frinx-resource-manager/user-guide/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/developer-guide/architecture/index.html b/frinx-uniconfig/developer-guide/architecture/index.html index 90aafee6a..634b557a2 100644 --- a/frinx-uniconfig/developer-guide/architecture/index.html +++ b/frinx-uniconfig/developer-guide/architecture/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/developer-guide/cli-translation-unit/index.html b/frinx-uniconfig/developer-guide/cli-translation-unit/index.html index a980cdc57..0a4a23478 100644 --- a/frinx-uniconfig/developer-guide/cli-translation-unit/index.html +++ b/frinx-uniconfig/developer-guide/cli-translation-unit/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/developer-guide/index.html b/frinx-uniconfig/developer-guide/index.html index d8cf9d3cd..e2d010058 100644 --- a/frinx-uniconfig/developer-guide/index.html +++ b/frinx-uniconfig/developer-guide/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/developer-guide/metrics/index.html b/frinx-uniconfig/developer-guide/metrics/index.html index 7dd9e11d2..4b7c76e79 100644 --- a/frinx-uniconfig/developer-guide/metrics/index.html +++ b/frinx-uniconfig/developer-guide/metrics/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/developer-guide/native-cli-units/index.html b/frinx-uniconfig/developer-guide/native-cli-units/index.html index 73dd2a830..a37f5eb92 100644 --- a/frinx-uniconfig/developer-guide/native-cli-units/index.html +++ b/frinx-uniconfig/developer-guide/native-cli-units/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/developer-guide/netconf-translation-unit/index.html b/frinx-uniconfig/developer-guide/netconf-translation-unit/index.html index 1593895db..0e378a045 100644 --- a/frinx-uniconfig/developer-guide/netconf-translation-unit/index.html +++ b/frinx-uniconfig/developer-guide/netconf-translation-unit/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/developer-guide/open-config-to-device-config-mapping/index.html b/frinx-uniconfig/developer-guide/open-config-to-device-config-mapping/index.html index 84ab7e14f..3ca96b5bf 100644 --- a/frinx-uniconfig/developer-guide/open-config-to-device-config-mapping/index.html +++ b/frinx-uniconfig/developer-guide/open-config-to-device-config-mapping/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/developer-guide/translation-unit-general-implementation/index.html b/frinx-uniconfig/developer-guide/translation-unit-general-implementation/index.html index b6adf207e..4936ccc8e 100644 --- a/frinx-uniconfig/developer-guide/translation-unit-general-implementation/index.html +++ b/frinx-uniconfig/developer-guide/translation-unit-general-implementation/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/developer-guide/translation-units-docs/index.html b/frinx-uniconfig/developer-guide/translation-units-docs/index.html index 2d07a8e27..a012b7672 100644 --- a/frinx-uniconfig/developer-guide/translation-units-docs/index.html +++ b/frinx-uniconfig/developer-guide/translation-units-docs/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/developer-guide/translation-units-in-general/index.html b/frinx-uniconfig/developer-guide/translation-units-in-general/index.html index dfe44f8d2..6218dd01b 100644 --- a/frinx-uniconfig/developer-guide/translation-units-in-general/index.html +++ b/frinx-uniconfig/developer-guide/translation-units-in-general/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/generated-api-libs/index.html b/frinx-uniconfig/generated-api-libs/index.html index c90b29beb..f687130cb 100644 --- a/frinx-uniconfig/generated-api-libs/index.html +++ b/frinx-uniconfig/generated-api-libs/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/getting-started/index.html b/frinx-uniconfig/getting-started/index.html index 60bcf6fd0..8a0ae9e0d 100644 --- a/frinx-uniconfig/getting-started/index.html +++ b/frinx-uniconfig/getting-started/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/glossary-of-terms/index.html b/frinx-uniconfig/glossary-of-terms/index.html index 5f33a30bc..47025d0c0 100644 --- a/frinx-uniconfig/glossary-of-terms/index.html +++ b/frinx-uniconfig/glossary-of-terms/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/q_a/index.html b/frinx-uniconfig/q_a/index.html index 07f36c6d3..6e5d07bc8 100644 --- a/frinx-uniconfig/q_a/index.html +++ b/frinx-uniconfig/q_a/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/release-notes/index.html b/frinx-uniconfig/release-notes/index.html index 03428dead..1ac688051 100644 --- a/frinx-uniconfig/release-notes/index.html +++ b/frinx-uniconfig/release-notes/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-4.2.10/index.html b/frinx-uniconfig/release-notes/uniconfig-4.2.10/index.html index a00daf724..77266739d 100644 --- a/frinx-uniconfig/release-notes/uniconfig-4.2.10/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-4.2.10/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-4.2.3/index.html b/frinx-uniconfig/release-notes/uniconfig-4.2.3/index.html index 50b9416a4..c35228cbf 100644 --- a/frinx-uniconfig/release-notes/uniconfig-4.2.3/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-4.2.3/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-4.2.4/index.html b/frinx-uniconfig/release-notes/uniconfig-4.2.4/index.html index 47c1365cd..79be3aa5f 100644 --- a/frinx-uniconfig/release-notes/uniconfig-4.2.4/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-4.2.4/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-4.2.5/index.html b/frinx-uniconfig/release-notes/uniconfig-4.2.5/index.html index 410fa717b..3ed83ab5e 100644 --- a/frinx-uniconfig/release-notes/uniconfig-4.2.5/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-4.2.5/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-4.2.6/index.html b/frinx-uniconfig/release-notes/uniconfig-4.2.6/index.html index e23f5dc9c..b03c85035 100644 --- a/frinx-uniconfig/release-notes/uniconfig-4.2.6/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-4.2.6/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-4.2.7/index.html b/frinx-uniconfig/release-notes/uniconfig-4.2.7/index.html index 3f0112795..97ac65ea5 100644 --- a/frinx-uniconfig/release-notes/uniconfig-4.2.7/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-4.2.7/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-4.2.8/index.html b/frinx-uniconfig/release-notes/uniconfig-4.2.8/index.html index 98a811f5f..1d6113b9b 100644 --- a/frinx-uniconfig/release-notes/uniconfig-4.2.8/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-4.2.8/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-4.2.9/index.html b/frinx-uniconfig/release-notes/uniconfig-4.2.9/index.html index ba4b2d65e..2a5907f0a 100644 --- a/frinx-uniconfig/release-notes/uniconfig-4.2.9/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-4.2.9/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.1/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.1/index.html index ab4fee2a9..809a95448 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.1/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.1/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.10/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.10/index.html index 0e4f17821..317874f38 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.10/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.10/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.11/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.11/index.html index 6954c2590..1f1d06acd 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.11/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.11/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.12/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.12/index.html index 4037de5fa..aeb207043 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.12/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.12/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.13/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.13/index.html index aaf2f6fd7..d348ff843 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.13/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.13/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.14/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.14/index.html index e0c59b676..8dea6fea8 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.14/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.14/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.15/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.15/index.html index dacffe48b..b1c633d00 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.15/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.15/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.16/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.16/index.html index 8669fd1d5..966bec21c 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.16/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.16/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.17/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.17/index.html index 28f56e635..7c3b01345 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.17/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.17/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.18/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.18/index.html index a27c4dbc4..36147d84f 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.18/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.18/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.19/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.19/index.html index f74667c42..cc2e1cd0c 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.19/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.19/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.2/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.2/index.html index 730e815c9..f59c20577 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.2/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.2/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.20/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.20/index.html index 408652ff7..4472beaba 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.20/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.20/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.21/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.21/index.html index 265f7f412..60722409a 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.21/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.21/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.22/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.22/index.html index 65beda8a3..b5b7e058e 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.22/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.22/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.23/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.23/index.html index 3c94d2070..9ebf27b62 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.23/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.23/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.24/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.24/index.html index 415cb5ec8..378c39206 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.24/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.24/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.25/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.25/index.html index 169eae532..64171b34c 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.25/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.25/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.3/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.3/index.html index 8d9257bae..5725b956e 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.3/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.3/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.4/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.4/index.html index d5b548ea8..733931faa 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.4/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.4/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.5/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.5/index.html index 1287828a5..a0bd66969 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.5/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.5/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.6/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.6/index.html index 6175fddb2..ccfb1afae 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.6/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.6/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.7/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.7/index.html index e4b4853f0..14f2209aa 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.7/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.7/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.8/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.8/index.html index 69e1791c3..373676d2a 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.8/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.8/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.0.9/index.html b/frinx-uniconfig/release-notes/uniconfig-5.0.9/index.html index 07e6b2bef..f6939c1a8 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.0.9/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.0.9/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.0/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.0/index.html index eec15669e..c7bce5fc6 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.0/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.0/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.1/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.1/index.html index 3380637ad..7a8f33ba2 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.1/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.1/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.10/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.10/index.html index 9c8ef5d02..6ed97d533 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.10/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.10/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.11/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.11/index.html index a56759344..9ff24b331 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.11/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.11/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.12/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.12/index.html index 09bc298b3..a97d0d3f0 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.12/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.12/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.13/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.13/index.html index 0e6080939..beaad271f 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.13/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.13/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.14/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.14/index.html index cd03c85a2..9b16ca742 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.14/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.14/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.15/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.15/index.html index 2fd11111c..6e1c75d07 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.15/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.15/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.16/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.16/index.html index 823696f77..98b19e34d 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.16/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.16/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.17/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.17/index.html index b7d9e8921..c72cf5dad 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.17/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.17/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.18/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.18/index.html index 43e36d817..7a9ed1128 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.18/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.18/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.19/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.19/index.html index 3c8008e3d..23ab1ace8 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.19/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.19/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.2/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.2/index.html index 86c466850..fff696527 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.2/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.2/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.20/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.20/index.html index 9cdf628f6..de0de026e 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.20/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.20/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.21/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.21/index.html index c1382bf04..01f5c1fde 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.21/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.21/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.22/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.22/index.html index 167fd76ab..883408256 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.22/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.22/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.23/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.23/index.html index 53a485849..d2399637a 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.23/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.23/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.3/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.3/index.html index 92d612a04..1cc4ec68b 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.3/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.3/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.4/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.4/index.html index bed9bfbff..da11871af 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.4/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.4/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.5/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.5/index.html index 9d3e5ece1..654949d56 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.5/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.5/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.6/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.6/index.html index 664c7838e..908daa068 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.6/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.6/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.7/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.7/index.html index 97f2ced40..b2cdf34fc 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.7/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.7/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.8/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.8/index.html index 3d15a9111..afec96384 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.8/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.8/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.1.9/index.html b/frinx-uniconfig/release-notes/uniconfig-5.1.9/index.html index e64ccf635..96908268a 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.1.9/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.1.9/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.2.0/index.html b/frinx-uniconfig/release-notes/uniconfig-5.2.0/index.html index e0d991980..426fd443b 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.2.0/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.2.0/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.2.1/index.html b/frinx-uniconfig/release-notes/uniconfig-5.2.1/index.html index e1325650d..f91122da6 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.2.1/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.2.1/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.2.2/index.html b/frinx-uniconfig/release-notes/uniconfig-5.2.2/index.html index ff5f02243..21f4f4c52 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.2.2/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.2.2/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.2.3/index.html b/frinx-uniconfig/release-notes/uniconfig-5.2.3/index.html index 9713739bc..d728266a1 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.2.3/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.2.3/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.2.4/index.html b/frinx-uniconfig/release-notes/uniconfig-5.2.4/index.html index 28744f7c6..ea2736f8c 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.2.4/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.2.4/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.2.5/index.html b/frinx-uniconfig/release-notes/uniconfig-5.2.5/index.html index 67f093f53..21569985e 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.2.5/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.2.5/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.2.6/index.html b/frinx-uniconfig/release-notes/uniconfig-5.2.6/index.html index 77fbf0718..90464e614 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.2.6/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.2.6/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-5.2.7/index.html b/frinx-uniconfig/release-notes/uniconfig-5.2.7/index.html index 43f3d0081..5b58bbcee 100644 --- a/frinx-uniconfig/release-notes/uniconfig-5.2.7/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-5.2.7/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.0.0/index.html b/frinx-uniconfig/release-notes/uniconfig-6.0.0/index.html index 007705ec0..fda80b256 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.0.0/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.0.0/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.0.1/index.html b/frinx-uniconfig/release-notes/uniconfig-6.0.1/index.html index 8bbaa7370..942972f1a 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.0.1/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.0.1/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.0.2/index.html b/frinx-uniconfig/release-notes/uniconfig-6.0.2/index.html index 366fefe4f..25c929ba6 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.0.2/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.0.2/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.0.3/index.html b/frinx-uniconfig/release-notes/uniconfig-6.0.3/index.html index 6a38cb659..bd9401203 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.0.3/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.0.3/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.0.4/index.html b/frinx-uniconfig/release-notes/uniconfig-6.0.4/index.html index e09ef9827..5d0a21de3 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.0.4/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.0.4/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.0.5/index.html b/frinx-uniconfig/release-notes/uniconfig-6.0.5/index.html index 2181aae94..df6044130 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.0.5/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.0.5/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.0.6/index.html b/frinx-uniconfig/release-notes/uniconfig-6.0.6/index.html index e28910b40..727f57aaa 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.0.6/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.0.6/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.0.7/index.html b/frinx-uniconfig/release-notes/uniconfig-6.0.7/index.html index f8993a392..17fb535f1 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.0.7/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.0.7/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.0.8/index.html b/frinx-uniconfig/release-notes/uniconfig-6.0.8/index.html index 487bad3e9..7d2e612ff 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.0.8/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.0.8/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.0.9/index.html b/frinx-uniconfig/release-notes/uniconfig-6.0.9/index.html index 55903fa00..a209d16f8 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.0.9/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.0.9/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.1.0/index.html b/frinx-uniconfig/release-notes/uniconfig-6.1.0/index.html index 21ed727f2..602a9328f 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.1.0/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.1.0/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.1.1/index.html b/frinx-uniconfig/release-notes/uniconfig-6.1.1/index.html index 7581d0309..9e2dd2f64 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.1.1/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.1.1/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.1.2/index.html b/frinx-uniconfig/release-notes/uniconfig-6.1.2/index.html index ea0136a6c..e747c7ace 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.1.2/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.1.2/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.1.3/index.html b/frinx-uniconfig/release-notes/uniconfig-6.1.3/index.html index 648089f1d..b0ab0181e 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.1.3/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.1.3/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.1.4/index.html b/frinx-uniconfig/release-notes/uniconfig-6.1.4/index.html index 84cca18b0..03f055186 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.1.4/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.1.4/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.1.5/index.html b/frinx-uniconfig/release-notes/uniconfig-6.1.5/index.html index cd7120a16..371ecf374 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.1.5/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.1.5/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-6.1.6/index.html b/frinx-uniconfig/release-notes/uniconfig-6.1.6/index.html index ba60930a7..0d2d1e3c4 100644 --- a/frinx-uniconfig/release-notes/uniconfig-6.1.6/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-6.1.6/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-7.0.0/index.html b/frinx-uniconfig/release-notes/uniconfig-7.0.0/index.html index b5bd52abd..a001b8f96 100644 --- a/frinx-uniconfig/release-notes/uniconfig-7.0.0/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-7.0.0/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/release-notes/uniconfig-7.0.1/index.html b/frinx-uniconfig/release-notes/uniconfig-7.0.1/index.html index 601e46e58..dba150627 100644 --- a/frinx-uniconfig/release-notes/uniconfig-7.0.1/index.html +++ b/frinx-uniconfig/release-notes/uniconfig-7.0.1/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/supported-devices/index.html b/frinx-uniconfig/supported-devices/index.html index 2e90b7275..7a1a9243d 100644 --- a/frinx-uniconfig/supported-devices/index.html +++ b/frinx-uniconfig/supported-devices/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/aaa/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/aaa/index.html index 8aff57f49..d427dbfd8 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/aaa/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/aaa/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/acl/acl/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/acl/acl/index.html index eba0d626c..95c7b41cf 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/acl/acl/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/acl/acl/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/acl/acl_interfaces/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/acl/acl_interfaces/index.html index bd37f641f..e5d841914 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/acl/acl_interfaces/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/acl/acl_interfaces/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/bcast-containment/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/bcast-containment/index.html index 59110267a..9983d914e 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/bcast-containment/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/bcast-containment/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/cable/cable_downstream_profile/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/cable/cable_downstream_profile/index.html index 127d014e6..2a99f4c15 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/cable/cable_downstream_profile/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/cable/cable_downstream_profile/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/cable/cable_fiber_node/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/cable/cable_fiber_node/index.html index f09934bf9..bbb43dd6f 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/cable/cable_fiber_node/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/cable/cable_fiber_node/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/cable/cable_rpd/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/cable/cable_rpd/index.html index e804fb7d5..47d44c8c6 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/cable/cable_rpd/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/cable/cable_rpd/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/cdp/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/cdp/index.html index 95b71c5bd..cf0b25f4d 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/cdp/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/cdp/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/evc/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/evc/index.html index 5905ee0a9..c622effd1 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/evc/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/evc/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/evpn/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/evpn/index.html index 07d6f870e..64c17de20 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/evpn/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/evpn/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/fdp/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/fdp/index.html index 88e1dda41..be510c34f 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/fdp/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/fdp/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/hsrp/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/hsrp/index.html index aed5f97c5..186f6735f 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/hsrp/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/hsrp/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/index.html index a2f49b525..83e0a6826 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/bridge_interface/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/bridge_interface/index.html index c9afd75f0..3ab8f3f92 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/bridge_interface/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/bridge_interface/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/cable_interface/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/cable_interface/index.html index c77193788..64226da2e 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/cable_interface/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/cable_interface/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/ethernet_interface/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/ethernet_interface/index.html index e857b8676..bfb2642ba 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/ethernet_interface/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/ethernet_interface/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/l2vlan_interface/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/l2vlan_interface/index.html index dea745076..ba6562df2 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/l2vlan_interface/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/l2vlan_interface/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/l3vlan_interface/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/l3vlan_interface/index.html index 187cc6078..0e883c3ea 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/l3vlan_interface/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/l3vlan_interface/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/lag_interface/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/lag_interface/index.html index e555de4cb..d9e525f14 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/lag_interface/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/lag_interface/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/wideband_interface/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/wideband_interface/index.html index ba8d4a164..5d9a84f9f 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/wideband_interface/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/interfaces/wideband_interface/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/ipsec/ipsec/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/ipsec/ipsec/index.html index f407f8a0c..e40695114 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/ipsec/ipsec/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/ipsec/ipsec/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/l2-cft/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/l2-cft/index.html index 13d87d45a..4ad737ffe 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/l2-cft/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/l2-cft/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/logging/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/logging/index.html index 343d6dcc1..7e1a9fc58 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/logging/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/logging/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/netflow/netflow_interfaces/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/netflow/netflow_interfaces/index.html index 72ac35712..9e483d511 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/netflow/netflow_interfaces/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/netflow/netflow_interfaces/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l2p2p/connection_point/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l2p2p/connection_point/index.html index 545c2296c..c86e54f45 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l2p2p/connection_point/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l2p2p/connection_point/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l2vpn/connection_point_l2vpn/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l2vpn/connection_point_l2vpn/index.html index b8f75a18d..c55f9e786 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l2vpn/connection_point_l2vpn/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l2vpn/connection_point_l2vpn/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l2vsi/l2vsi/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l2vsi/l2vsi/index.html index be6464370..a05a91dd3 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l2vsi/l2vsi/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l2vsi/l2vsi/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l2vsi/l2vsicp/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l2vsi/l2vsicp/index.html index 7b536f246..b28ace027 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l2vsi/l2vsicp/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l2vsi/l2vsicp/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l3vpn/network_instance_l3vpn_bgp/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l3vpn/network_instance_l3vpn_bgp/index.html index 4761d44c2..9841786e9 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l3vpn/network_instance_l3vpn_bgp/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l3vpn/network_instance_l3vpn_bgp/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l3vpn/network_instance_l3vpn_ospf/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l3vpn/network_instance_l3vpn_ospf/index.html index 46c18babc..39f1f67ae 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l3vpn/network_instance_l3vpn_ospf/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/l3vpn/network_instance_l3vpn_ospf/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/mpls/mpls_ldp/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/mpls/mpls_ldp/index.html index ab0868448..4e41263ad 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/mpls/mpls_ldp/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/mpls/mpls_ldp/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/mpls/mpls_rsvp/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/mpls/mpls_rsvp/index.html index b6ca9953a..6f0136173 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/mpls/mpls_rsvp/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/mpls/mpls_rsvp/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/mpls/mpls_te/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/mpls/mpls_te/index.html index ce5e3511d..b2a083861 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/mpls/mpls_te/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/mpls/mpls_te/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/mpls/mpls_tunnel/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/mpls/mpls_tunnel/index.html index b89fd7539..a6cc7d11f 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/mpls/mpls_tunnel/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/mpls/mpls_tunnel/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/network_instance/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/network_instance/index.html index 08beff146..7a2440417 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/network_instance/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/network_instance/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/policy-forwarding/pf_interfaces/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/policy-forwarding/pf_interfaces/index.html index a9bb69c79..41aa8354e 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/policy-forwarding/pf_interfaces/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/policy-forwarding/pf_interfaces/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/bgp/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/bgp/index.html index a7d7a85a1..58818b05e 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/bgp/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/bgp/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/isis/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/isis/index.html index 3eefc6c68..ac7024588 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/isis/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/isis/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/ospf/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/ospf/index.html index 2fb81276a..0e487ac86 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/ospf/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/ospf/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/ospfv3/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/ospfv3/index.html index c43daf73c..5e00f4368 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/ospfv3/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/ospfv3/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/static/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/static/index.html index 54ca35db3..618df6062 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/static/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/protocols/static/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/vlans/vlan/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/vlans/vlan/index.html index 015b0bd77..56551d7df 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/vlans/vlan/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/network-instances/vlans/vlan/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/oam/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/oam/index.html index cb7c0692e..47cd8e10e 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/oam/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/oam/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/privilege/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/privilege/index.html index bbdb0ab95..80974f7dc 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/privilege/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/privilege/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/probes/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/probes/index.html index a039df527..aa78182bf 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/probes/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/probes/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/qos/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/qos/index.html index 115ca12c7..2c8cd6de9 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/qos/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/qos/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/relay-agent/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/relay-agent/index.html index a562a5da3..b0036c9c8 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/relay-agent/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/relay-agent/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/routing-policy/routing-policy/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/routing-policy/routing-policy/index.html index 6f21b45a4..263629d81 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/routing-policy/routing-policy/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/routing-policy/routing-policy/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/snmp/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/snmp/index.html index aea74efcf..57eca3435 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/snmp/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/snmp/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/stp/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/stp/index.html index 82e1262cb..f8b0b725e 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/stp/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/stp/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/configuration-datasets/system/index.html b/frinx-uniconfig/translation-units-docs/configuration-datasets/system/index.html index a3945e718..80bcc6dc5 100644 --- a/frinx-uniconfig/translation-units-docs/configuration-datasets/system/index.html +++ b/frinx-uniconfig/translation-units-docs/configuration-datasets/system/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/ietf-to-oc-mapping/ietf_l2p2p_local_to_oc/index.html b/frinx-uniconfig/translation-units-docs/ietf-to-oc-mapping/ietf_l2p2p_local_to_oc/index.html index dd489dd80..6cd0160d9 100644 --- a/frinx-uniconfig/translation-units-docs/ietf-to-oc-mapping/ietf_l2p2p_local_to_oc/index.html +++ b/frinx-uniconfig/translation-units-docs/ietf-to-oc-mapping/ietf_l2p2p_local_to_oc/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/ietf-to-oc-mapping/ietf_l2p2p_remote_to_oc/index.html b/frinx-uniconfig/translation-units-docs/ietf-to-oc-mapping/ietf_l2p2p_remote_to_oc/index.html index eafb8e680..3f587108c 100644 --- a/frinx-uniconfig/translation-units-docs/ietf-to-oc-mapping/ietf_l2p2p_remote_to_oc/index.html +++ b/frinx-uniconfig/translation-units-docs/ietf-to-oc-mapping/ietf_l2p2p_remote_to_oc/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/ietf-to-oc-mapping/ietf_l2vpn_to_oc/index.html b/frinx-uniconfig/translation-units-docs/ietf-to-oc-mapping/ietf_l2vpn_to_oc/index.html index 9db986c18..d60b58e5e 100644 --- a/frinx-uniconfig/translation-units-docs/ietf-to-oc-mapping/ietf_l2vpn_to_oc/index.html +++ b/frinx-uniconfig/translation-units-docs/ietf-to-oc-mapping/ietf_l2vpn_to_oc/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/ietf-to-oc-mapping/ietf_l3vpn_to_oc/index.html b/frinx-uniconfig/translation-units-docs/ietf-to-oc-mapping/ietf_l3vpn_to_oc/index.html index 1d441689d..43c253d3e 100644 --- a/frinx-uniconfig/translation-units-docs/ietf-to-oc-mapping/ietf_l3vpn_to_oc/index.html +++ b/frinx-uniconfig/translation-units-docs/ietf-to-oc-mapping/ietf_l3vpn_to_oc/index.html @@ -6,7 +6,7 @@ - + @@ -31,12 +31,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/index.html b/frinx-uniconfig/translation-units-docs/index.html index ea383bf65..e4c7a16ef 100644 --- a/frinx-uniconfig/translation-units-docs/index.html +++ b/frinx-uniconfig/translation-units-docs/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/operational-datasets/cdp/index.html b/frinx-uniconfig/translation-units-docs/operational-datasets/cdp/index.html index b9cbc80b8..181a1fde9 100644 --- a/frinx-uniconfig/translation-units-docs/operational-datasets/cdp/index.html +++ b/frinx-uniconfig/translation-units-docs/operational-datasets/cdp/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/operational-datasets/index.html b/frinx-uniconfig/translation-units-docs/operational-datasets/index.html index f4cc555ca..3ca8d7cc2 100644 --- a/frinx-uniconfig/translation-units-docs/operational-datasets/index.html +++ b/frinx-uniconfig/translation-units-docs/operational-datasets/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/translation-units-docs/operational-datasets/interfaces/index.html b/frinx-uniconfig/translation-units-docs/operational-datasets/interfaces/index.html index 9009dc036..937e6f08f 100644 --- a/frinx-uniconfig/translation-units-docs/operational-datasets/interfaces/index.html +++ b/frinx-uniconfig/translation-units-docs/operational-datasets/interfaces/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/operational-datasets/lldp/index.html b/frinx-uniconfig/translation-units-docs/operational-datasets/lldp/index.html index 38e296e62..a38dd51c5 100644 --- a/frinx-uniconfig/translation-units-docs/operational-datasets/lldp/index.html +++ b/frinx-uniconfig/translation-units-docs/operational-datasets/lldp/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/operational-datasets/network-instances/protocols/bgp_rib/index.html b/frinx-uniconfig/translation-units-docs/operational-datasets/network-instances/protocols/bgp_rib/index.html index 871c3eba6..0ac4577bd 100644 --- a/frinx-uniconfig/translation-units-docs/operational-datasets/network-instances/protocols/bgp_rib/index.html +++ b/frinx-uniconfig/translation-units-docs/operational-datasets/network-instances/protocols/bgp_rib/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/operational-datasets/network-instances/protocols/bgp_summary/index.html b/frinx-uniconfig/translation-units-docs/operational-datasets/network-instances/protocols/bgp_summary/index.html index 54bddd73e..a6fdfce18 100644 --- a/frinx-uniconfig/translation-units-docs/operational-datasets/network-instances/protocols/bgp_summary/index.html +++ b/frinx-uniconfig/translation-units-docs/operational-datasets/network-instances/protocols/bgp_summary/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/operational-datasets/network-instances/protocols/ospf_summary/index.html b/frinx-uniconfig/translation-units-docs/operational-datasets/network-instances/protocols/ospf_summary/index.html index 8890f62f1..d5560ed84 100644 --- a/frinx-uniconfig/translation-units-docs/operational-datasets/network-instances/protocols/ospf_summary/index.html +++ b/frinx-uniconfig/translation-units-docs/operational-datasets/network-instances/protocols/ospf_summary/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/operational-datasets/platform/index.html b/frinx-uniconfig/translation-units-docs/operational-datasets/platform/index.html index 82db55d80..c4d68418e 100644 --- a/frinx-uniconfig/translation-units-docs/operational-datasets/platform/index.html +++ b/frinx-uniconfig/translation-units-docs/operational-datasets/platform/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/operational-datasets/system/index.html b/frinx-uniconfig/translation-units-docs/operational-datasets/system/index.html index 08ea5ef79..8055a595c 100644 --- a/frinx-uniconfig/translation-units-docs/operational-datasets/system/index.html +++ b/frinx-uniconfig/translation-units-docs/operational-datasets/system/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/translation-units-docs/translation-framework-101/index.html b/frinx-uniconfig/translation-units-docs/translation-framework-101/index.html index c745975e1..8192cf2c1 100644 --- a/frinx-uniconfig/translation-units-docs/translation-framework-101/index.html +++ b/frinx-uniconfig/translation-units-docs/translation-framework-101/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/basic-concepts/index.html b/frinx-uniconfig/user-guide/basic-concepts/index.html index eeaef67b0..d685337c9 100644 --- a/frinx-uniconfig/user-guide/basic-concepts/index.html +++ b/frinx-uniconfig/user-guide/basic-concepts/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/index.html b/frinx-uniconfig/user-guide/index.html index ac01ddb62..c5ed1fcd7 100644 --- a/frinx-uniconfig/user-guide/index.html +++ b/frinx-uniconfig/user-guide/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/monitoring/index.html b/frinx-uniconfig/user-guide/monitoring/index.html index 59ee22761..9904badbc 100644 --- a/frinx-uniconfig/user-guide/monitoring/index.html +++ b/frinx-uniconfig/user-guide/monitoring/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/network-management-protocols/index.html b/frinx-uniconfig/user-guide/network-management-protocols/index.html index 35d1e203c..38e2ebc85 100644 --- a/frinx-uniconfig/user-guide/network-management-protocols/index.html +++ b/frinx-uniconfig/user-guide/network-management-protocols/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig-installing/index.html b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig-installing/index.html index 8c1b8a97a..a5dcec9f4 100644 --- a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig-installing/index.html +++ b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig-installing/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig-native_cli/index.html b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig-native_cli/index.html index 9e0384ed8..7e464755d 100644 --- a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig-native_cli/index.html +++ b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig-native_cli/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_cli/index.html b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_cli/index.html index 626fe5882..321e8c59b 100644 --- a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_cli/index.html +++ b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_cli/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/index.html b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/index.html index e9d3845fb..09678f855 100644 --- a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/index.html +++ b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/iosxr7/index.html b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/iosxr7/index.html index 2a2f55fbb..3fbdff1c3 100644 --- a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/iosxr7/index.html +++ b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/iosxr7/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/nokia/index.html b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/nokia/index.html index aa1b4d787..9723c4428 100644 --- a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/nokia/index.html +++ b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/nokia/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/sonic/index.html b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/sonic/index.html index 443914f7b..356ed1eba 100644 --- a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/sonic/index.html +++ b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/sonic/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/calix/index.html b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/calix/index.html index f4394e47d..d5db90c59 100644 --- a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/calix/index.html +++ b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/calix/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/index.html b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/index.html index f109d2136..3d49bb714 100644 --- a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/index.html +++ b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/iosxr/index.html b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/iosxr/index.html index 2ddcf3040..2edb71ec4 100644 --- a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/iosxr/index.html +++ b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/iosxr/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/junos/index.html b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/junos/index.html index 65cdd7a85..ecbe1604e 100644 --- a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/junos/index.html +++ b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/junos/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/ocnos/index.html b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/ocnos/index.html index da2209815..394af78ba 100644 --- a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/ocnos/index.html +++ b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/ocnos/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/sros/index.html b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/sros/index.html index ee5487c95..8cf10ebc9 100644 --- a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/sros/index.html +++ b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_netconf/sros/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_snmp/index.html b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_snmp/index.html index 7b0e6a34f..78dafbdaa 100644 --- a/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_snmp/index.html +++ b/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_snmp/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/network-management-protocols/updating-installation-parameters/index.html b/frinx-uniconfig/user-guide/network-management-protocols/updating-installation-parameters/index.html index 88052d61b..98a4f48c2 100644 --- a/frinx-uniconfig/user-guide/network-management-protocols/updating-installation-parameters/index.html +++ b/frinx-uniconfig/user-guide/network-management-protocols/updating-installation-parameters/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/operational-procedures/data-flows/index.html b/frinx-uniconfig/user-guide/operational-procedures/data-flows/index.html index 573175d21..4018aa619 100644 --- a/frinx-uniconfig/user-guide/operational-procedures/data-flows/index.html +++ b/frinx-uniconfig/user-guide/operational-procedures/data-flows/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/operational-procedures/data-security-models/index.html b/frinx-uniconfig/user-guide/operational-procedures/data-security-models/index.html index c9fe326d8..80b33efe8 100644 --- a/frinx-uniconfig/user-guide/operational-procedures/data-security-models/index.html +++ b/frinx-uniconfig/user-guide/operational-procedures/data-security-models/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/operational-procedures/index.html b/frinx-uniconfig/user-guide/operational-procedures/index.html index 63f5038ab..a0ab9c30b 100644 --- a/frinx-uniconfig/user-guide/operational-procedures/index.html +++ b/frinx-uniconfig/user-guide/operational-procedures/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/operational-procedures/logging/index.html b/frinx-uniconfig/user-guide/operational-procedures/logging/index.html index eed3a1f2f..a2e00dc75 100644 --- a/frinx-uniconfig/user-guide/operational-procedures/logging/index.html +++ b/frinx-uniconfig/user-guide/operational-procedures/logging/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/operational-procedures/openapi/index.html b/frinx-uniconfig/user-guide/operational-procedures/openapi/index.html index 4cd4cf857..baa67942a 100644 --- a/frinx-uniconfig/user-guide/operational-procedures/openapi/index.html +++ b/frinx-uniconfig/user-guide/operational-procedures/openapi/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/operational-procedures/postgres-tls/index.html b/frinx-uniconfig/user-guide/operational-procedures/postgres-tls/index.html index 416962d83..d8208270c 100644 --- a/frinx-uniconfig/user-guide/operational-procedures/postgres-tls/index.html +++ b/frinx-uniconfig/user-guide/operational-procedures/postgres-tls/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/operational-procedures/thread-pools/index.html b/frinx-uniconfig/user-guide/operational-procedures/thread-pools/index.html index 59ade3edb..21faa6b1e 100644 --- a/frinx-uniconfig/user-guide/operational-procedures/thread-pools/index.html +++ b/frinx-uniconfig/user-guide/operational-procedures/thread-pools/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/operational-procedures/tls/index.html b/frinx-uniconfig/user-guide/operational-procedures/tls/index.html index c07e92fc7..5e65349b0 100644 --- a/frinx-uniconfig/user-guide/operational-procedures/tls/index.html +++ b/frinx-uniconfig/user-guide/operational-procedures/tls/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/operational-procedures/uniconfig-clustering/index.html b/frinx-uniconfig/user-guide/operational-procedures/uniconfig-clustering/index.html index 9e0f18853..d0d46ff61 100644 --- a/frinx-uniconfig/user-guide/operational-procedures/uniconfig-clustering/index.html +++ b/frinx-uniconfig/user-guide/operational-procedures/uniconfig-clustering/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/operational-procedures/uniconfig-properties/index.html b/frinx-uniconfig/user-guide/operational-procedures/uniconfig-properties/index.html index 40d07523a..c137cb380 100644 --- a/frinx-uniconfig/user-guide/operational-procedures/uniconfig-properties/index.html +++ b/frinx-uniconfig/user-guide/operational-procedures/uniconfig-properties/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/performance-and-scale/performance_characteristics/index.html b/frinx-uniconfig/user-guide/performance-and-scale/performance_characteristics/index.html index 4323b8fad..0f29b034f 100644 --- a/frinx-uniconfig/user-guide/performance-and-scale/performance_characteristics/index.html +++ b/frinx-uniconfig/user-guide/performance-and-scale/performance_characteristics/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/sdk/index.html b/frinx-uniconfig/user-guide/sdk/index.html index 5fa4cca34..65c84e655 100644 --- a/frinx-uniconfig/user-guide/sdk/index.html +++ b/frinx-uniconfig/user-guide/sdk/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/admin-state/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/admin-state/index.html index c37335e43..6a11dd712 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/admin-state/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/admin-state/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/build-and-commit-model/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/build-and-commit-model/index.html index 0cd6aad35..0cbd4d8fe 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/build-and-commit-model/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/build-and-commit-model/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/device-discovery/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/device-discovery/index.html index e535e602a..9a19b9dbc 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/device-discovery/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/device-discovery/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/dryrun-manager/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/dryrun-manager/index.html index 76ada4e02..da1590cb4 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/dryrun-manager/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/dryrun-manager/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/immediate-commit-model/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/immediate-commit-model/index.html index 97a3d2088..b0ada7654 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/immediate-commit-model/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/immediate-commit-model/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/index.html index 6ed7f2f9f..64e97e0cf 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/jsonb-filtering/application-jsonb-filtering/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/jsonb-filtering/application-jsonb-filtering/index.html index 69bdfd81f..3d2f8539b 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/jsonb-filtering/application-jsonb-filtering/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/jsonb-filtering/application-jsonb-filtering/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/jsonb-filtering/database-jsonb-filtering/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/jsonb-filtering/database-jsonb-filtering/index.html index f62a99035..9c0c88e3f 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/jsonb-filtering/database-jsonb-filtering/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/jsonb-filtering/database-jsonb-filtering/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/jsonb-filtering/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/jsonb-filtering/index.html index 33fd73622..7719b5afe 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/jsonb-filtering/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/jsonb-filtering/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/kafka-notifications/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/kafka-notifications/index.html index 3d9ae9621..917eceeb2 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/kafka-notifications/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/kafka-notifications/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/operational-data-about-transactions/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/operational-data-about-transactions/index.html index 286b2b16e..4d8388e9b 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/operational-data-about-transactions/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/operational-data-about-transactions/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/restconf/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/restconf/index.html index a6571e013..41986bf4b 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/restconf/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/restconf/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/index.html index 030864555..4c113f9b0 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/obtain_snapshot_metadata/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/obtain_snapshot_metadata/index.html index 99074f2b4..adf4325f6 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/obtain_snapshot_metadata/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/obtain_snapshot_metadata/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/rpc_create-snapshot/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/rpc_create-snapshot/index.html index 35f12aec4..882f43a59 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/rpc_create-snapshot/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/rpc_create-snapshot/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/rpc_delete-snapshot/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/rpc_delete-snapshot/index.html index 59916d58e..1e8723750 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/rpc_delete-snapshot/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/rpc_delete-snapshot/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/rpc_replace-config-with-snapshot/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/rpc_replace-config-with-snapshot/index.html index 1aeaae44d..73a8e7a54 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/rpc_replace-config-with-snapshot/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/snapshot-manager/rpc_replace-config-with-snapshot/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/index.html index c28c0cf7c..3cc8518ea 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_bulk-edit/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_bulk-edit/index.html index 1e417cf4a..aad350ac9 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_bulk-edit/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_bulk-edit/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_calculate-subtree-diff/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_calculate-subtree-diff/index.html index 03b076b00..01f5f72ca 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_calculate-subtree-diff/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_calculate-subtree-diff/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_calculate-subtree-git-like-diff/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_calculate-subtree-git-like-diff/index.html index 4e68ab2f8..4c4cf0b6f 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_calculate-subtree-git-like-diff/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_calculate-subtree-git-like-diff/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_copy-many-to-one/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_copy-many-to-one/index.html index 462d5a3ef..dcc30d351 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_copy-many-to-one/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_copy-many-to-one/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_copy-one-to-many/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_copy-one-to-many/index.html index 87f4191b3..1284aab1b 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_copy-one-to-many/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_copy-one-to-many/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_copy-one-to-one/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_copy-one-to-one/index.html index ea0081b2e..5e2d51944 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_copy-one-to-one/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/subtree-manager/rpc_copy-one-to-one/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/index.html index c4fed804b..55118f058 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_apply-template/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_apply-template/index.html index 994e470e2..81dba6039 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_apply-template/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_apply-template/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_create-multiple-templates/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_create-multiple-templates/index.html index 4ef45fcbb..8b88a4f8e 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_create-multiple-templates/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_create-multiple-templates/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_get-template-info/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_get-template-info/index.html index 72fd60c88..5bf91b104 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_get-template-info/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_get-template-info/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_get-template-nodes/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_get-template-nodes/index.html index 4b1738134..528a3ad84 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_get-template-nodes/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_get-template-nodes/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_upgrade-template/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_upgrade-template/index.html index ecd7d8805..3cb7eebdb 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_upgrade-template/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/templates-manager/rpc_upgrade-template/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/transaction-log/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/transaction-log/index.html index 6c9c08c90..1eb3addd7 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/transaction-log/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/transaction-log/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/transaction-log/rpc_revert-changes/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/transaction-log/rpc_revert-changes/index.html index cb26d2a44..7936bce7f 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/transaction-log/rpc_revert-changes/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/transaction-log/rpc_revert-changes/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/transaction-log/transaction-tracker/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/transaction-log/transaction-tracker/index.html index 817e4ee3c..656db215c 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/transaction-log/transaction-tracker/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/transaction-log/transaction-tracker/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/index.html index 46dac257b..6691dc650 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_bulk-get/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_bulk-get/index.html index 3dfa7e873..15a6c9e38 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_bulk-get/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_bulk-get/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_calculate-diff/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_calculate-diff/index.html index 6a9b54d0d..44f0becdb 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_calculate-diff/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_calculate-diff/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_calculate-git-like-diff/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_calculate-git-like-diff/index.html index be520eab1..a759f2da9 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_calculate-git-like-diff/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_calculate-git-like-diff/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_checked-commit/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_checked-commit/index.html index 9b5da84a5..2f1ad877d 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_checked-commit/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_checked-commit/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_commit/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_commit/index.html index eb34aad06..8b9e306ba 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_commit/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_commit/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_compare-config/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_compare-config/index.html index 6e2368f76..54748e074 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_compare-config/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_compare-config/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_connect-node/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_connect-node/index.html index 179807003..17c3d9f31 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_connect-node/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_connect-node/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_disconnect-node/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_disconnect-node/index.html index cd6c02b5c..ece7bd590 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_disconnect-node/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_disconnect-node/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_health/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_health/index.html index 11c7ef964..78961207f 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_health/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_health/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_is-in-sync/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_is-in-sync/index.html index 03ddffc28..45108fc6f 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_is-in-sync/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_is-in-sync/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_replace-config-with-oper/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_replace-config-with-oper/index.html index b01370848..5883224f7 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_replace-config-with-oper/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_replace-config-with-oper/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_sync-from-network/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_sync-from-network/index.html index 57eb29f5b..c892f326a 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_sync-from-network/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_sync-from-network/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_sync-to-network/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_sync-to-network/index.html index f7e057f75..2b3577d55 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_sync-to-network/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_sync-to-network/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_validate/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_validate/index.html index 6c7e8b265..7c953dfa4 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_validate/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_validate/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_check_installed_devices/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_check_installed_devices/index.html index 3da7c4278..c63b21240 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_check_installed_devices/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_check_installed_devices/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_check_nodes_connection/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_check_nodes_connection/index.html index 044fd793b..e6bf8f051 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_check_nodes_connection/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_check_nodes_connection/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_get_installed_devices/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_get_installed_devices/index.html index c807f2cfc..5a1872387 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_get_installed_devices/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_get_installed_devices/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_install_multiple_nodes/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_install_multiple_nodes/index.html index 340605dd5..80b8b294b 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_install_multiple_nodes/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_install_multiple_nodes/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_uninstall_multiple_nodes/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_uninstall_multiple_nodes/index.html index 9380e25d5..c05af36f4 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_uninstall_multiple_nodes/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_uninstall_multiple_nodes/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-properties/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-properties/index.html index 3c60c9813..8984b78fe 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-properties/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-properties/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-properties/rpc_read-properties/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-properties/rpc_read-properties/index.html index ddda568ca..10976c24d 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-properties/rpc_read-properties/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-properties/rpc_read-properties/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-properties/rpc_update-properties/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-properties/rpc_update-properties/index.html index d0fe9b808..a1d159103 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-properties/rpc_update-properties/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-properties/rpc_update-properties/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-queries/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-queries/index.html index eab0d0ec4..d8ce25cc8 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-queries/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-queries/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-shell/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-shell/index.html index c70de31fd..675c66400 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-shell/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/uniconfig-shell/index.html @@ -6,7 +6,7 @@ - + @@ -36,12 +36,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/unistore-api/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/unistore-api/index.html index a966ae75f..8ff5bec89 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/unistore-api/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/unistore-api/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/utilities/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/utilities/index.html index 1bcc95b61..ca66560df 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/utilities/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/utilities/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/utilities/openapi-diff/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/utilities/openapi-diff/index.html index 390a63f9f..9b93051c4 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/utilities/openapi-diff/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/utilities/openapi-diff/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/utilities/yang-packager/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/utilities/yang-packager/index.html index e26179896..472a52cb1 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/utilities/yang-packager/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/utilities/yang-packager/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-uniconfig/user-guide/uniconfig-operations/yang-patch/index.html b/frinx-uniconfig/user-guide/uniconfig-operations/yang-patch/index.html index 0bac7fc02..41dd5f97f 100644 --- a/frinx-uniconfig/user-guide/uniconfig-operations/yang-patch/index.html +++ b/frinx-uniconfig/user-guide/uniconfig-operations/yang-patch/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
    diff --git a/frinx-workflow-manager/introduction/index.html b/frinx-workflow-manager/introduction/index.html index 31f554a48..38785bb95 100644 --- a/frinx-workflow-manager/introduction/index.html +++ b/frinx-workflow-manager/introduction/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
    diff --git a/frinx-workflow-manager/python-sdk/development/index.html b/frinx-workflow-manager/python-sdk/development/index.html index 67f27bb41..fde5e4b9e 100644 --- a/frinx-workflow-manager/python-sdk/development/index.html +++ b/frinx-workflow-manager/python-sdk/development/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,11 @@ - + - + - - +
    @@ -266,6 +265,7 @@

  • Helm: Make sure that Helm is installed. Follow the Helm installation guide if necessary.
  • Python: Make sure that your environment have Python ^3.10 interpretter installed.
  • Poetry: Make sure that you have installed Poetry. Follow the Poetry installation guide if necessary.
  • +
  • Mirrord: Make sure that you have installed Mirrord. Follow the mirrord installation quide if necessary

@@ -273,7 +273,7 @@

Step 1: Start Frinx Machine

-

Install Frinx Machine with ingress enabled +

Install Frinx Machine

@@ -291,7 +291,7 @@

- + frinx-workers-boilerplate
@@ -301,62 +301,6 @@

-

Make sure you have enabled workflow-manager and krakend ingress, because it's required for local development.

-
-
frinx-machine:
-  krakend:
-    ingress:s
-      enabled: true
-      className: nginx
-      annotations:
-        # force-ssl-redirect must be disabled in case you are using a self-signed certificate
-        # nginx.ingress.kubernetes.io/force-ssl-redirect: "true" 
-        nginx.ingress.kubernetes.io/proxy-connect-timeout: "3600"
-        nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
-        nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
-      hosts:
-        - host: krakend.127.0.0.1.nip.io
-          paths:
-            - path: "/"
-              pathType: ImplementationSpecific
-
-  workflow-manager:
-    ingress:
-      enabled: true
-      hosts:
-        - host: workflow-manager.127.0.0.1.nip.io
-          paths:
-            - path: "/"
-              pathType: ImplementationSpecific
-
-  uniconfig:
-    image:
-      repository: "frinxio/uniconfig"
-
-  performance-monitor:
-    image:
-      repository: "frinxio/performance-monitor"
-
-

In case, you using minikube, get minikube ip

-
-
minikube ip
-
-192.168.49.2
-
-

add map that ip with ingres hosts to your /etc/hosts

-
-
#/etc/hosts
-192.168.49.2 krakend.127.0.0.1.nip.io
-192.168.49.2 workflow-manager.127.0.0.1.nip.io
-
-

To verify ingresses

-
-
$kubectl get ingress -n frinx 
-
-NAME               CLASS   HOSTS                                                                          ADDRESS        PORTS   AGE
-conductor-server   nginx   workflow-manager.127.0.0.1.nip.io                                              192.168.49.2   80      161m
-krakend            nginx   krakend.127.0.0.1.nip.io                                                       192.168.49.2   80      161m
-

# @@ -368,7 +312,7 @@

- + frinx-workers-boilerplate
@@ -378,6 +322,15 @@

+ +

+ # + Step 3: Local development with Mirrord +

+
+

Mirrord is great tool, which simplifies development of workflows on local/remove kubernetes cluster. +Is only needed to install it to the IDE (CLI), set connection to the correct kubeconfig/namespace and run python worker in targetless pod. +No more need to workaround connection via ingress.

# @@ -464,6 +417,6 @@

- + diff --git a/frinx-workflow-manager/python-sdk/frinx-python-sdk/index.html b/frinx-workflow-manager/python-sdk/frinx-python-sdk/index.html index c82334b7a..9ab992950 100644 --- a/frinx-workflow-manager/python-sdk/frinx-python-sdk/index.html +++ b/frinx-workflow-manager/python-sdk/frinx-python-sdk/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
diff --git a/frinx-workflow-manager/python-sdk/index.html b/frinx-workflow-manager/python-sdk/index.html index b4c489e62..f8a9ae93b 100644 --- a/frinx-workflow-manager/python-sdk/index.html +++ b/frinx-workflow-manager/python-sdk/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
diff --git a/frinx-workflow-manager/python-sdk/services-python-api/index.html b/frinx-workflow-manager/python-sdk/services-python-api/index.html index 8f272a750..9b9996eee 100644 --- a/frinx-workflow-manager/python-sdk/services-python-api/index.html +++ b/frinx-workflow-manager/python-sdk/services-python-api/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
diff --git a/frinx-workflow-manager/python-sdk/services-python-workers/index.html b/frinx-workflow-manager/python-sdk/services-python-workers/index.html index 31abed8a9..3a75ffa8a 100644 --- a/frinx-workflow-manager/python-sdk/services-python-workers/index.html +++ b/frinx-workflow-manager/python-sdk/services-python-workers/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
diff --git a/frinx-workflow-manager/python-sdk/workflow-builder/index.html b/frinx-workflow-manager/python-sdk/workflow-builder/index.html index f30e3c734..4bcf75f61 100644 --- a/frinx-workflow-manager/python-sdk/workflow-builder/index.html +++ b/frinx-workflow-manager/python-sdk/workflow-builder/index.html @@ -6,7 +6,7 @@ - + @@ -34,12 +34,12 @@ - + - + - - + +
diff --git a/frinx-workflow-manager/workflow-builder/index.html b/frinx-workflow-manager/workflow-builder/index.html index c0740b89a..69d497540 100644 --- a/frinx-workflow-manager/workflow-builder/index.html +++ b/frinx-workflow-manager/workflow-builder/index.html @@ -6,7 +6,7 @@ - + @@ -36,11 +36,11 @@ - + - + - +
diff --git a/index.html b/index.html index 4a86e4e44..1792754dd 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ - + @@ -34,11 +34,11 @@ - + - + - +
diff --git a/resources/js/config.js b/resources/js/config.js index 2c6ead53f..6b37b8b3e 100644 --- a/resources/js/config.js +++ b/resources/js/config.js @@ -1 +1 @@ -var __DOCS_CONFIG__ = {"id":"4dEF5yIWyTJrUKD95Pi7JZuXRF0P22d424","key":"gJ1CYKOAFiwyL/6YtPRFsJ6ptUt9FeR1LNmk4gxIYH0.GcwGgcn5FrOj9kjm4VtNpZkEQKbacJ7d80shfNA3FJ8eFysJMJrNk2AkIIdXyP6fSLn2hOltBaaNuEeaB1I4iw.108207","base":"/","host":"docs.frinx.io","version":"1.0.0","useRelativePaths":true,"documentName":"index.html","appendDocumentName":false,"trailingSlash":true,"preloadSearch":false,"cacheBustingToken":"2.4.0.780412816665","cacheBustingStrategy":"query","sidebarFilterPlaceholder":"Filter","toolbarFilterPlaceholder":"Filter","showSidebarFilter":true,"filterNotFoundMsg":"No member names found containing the query \"{query}\"","maxHistoryItems":15,"homeIcon":"","access":[{"value":"public","label":"Public"},{"value":"protected","label":"Protected"}],"toolbarLinks":[{"id":"fields","label":"Fields"},{"id":"properties","label":"Properties","shortLabel":"Props"},{"id":"methods","label":"Methods"},{"id":"events","label":"Events"}],"sidebar":[{"n":"/","l":"Welcome","s":""},{"n":"frinx-machine","l":"Frinx Machine","c":false,"i":[{"n":"getting-started","l":"FRINX Machine introduction","s":""},{"n":"api-docs","l":"API Gateway","s":""},{"n":"installation","l":"Kubernetes installation","c":false,"i":[{"n":"docker-registry-secret","l":"Docker Registry Secret"},{"n":"basic","l":"Helm Installation Guide"},{"n":"customization","l":"Advanced Helm Chart Installation","c":false,"i":[{"n":"create-kind-cluster","l":"Cluster installation"},{"n":"frinx-machine-customization","l":"Helm Chart Installation Guide with customization"}]},{"n":"custom-worker-deployment","l":"Custom worker deployment"},{"n":"oauth2-proxy","l":"Authorization and authentification"}],"s":""},{"n":"use-cases","l":"Demo Use Cases","i":[{"n":"dashboard","l":"Dashboard"},{"n":"add-to-inventory-and-install","l":"Add a device to inventory and install it"},{"n":"install-all-devices-from-inventory","l":"Install all devices from inventory"},{"n":"device-configure-loopback","l":"Device configure loopback"},{"n":"create-loopback-all-in-uniconfig","l":"Create loopback all in uniconfig"},{"n":"create-workflow","l":"Create workflow"},{"n":"create-l2-vpn-p2p","l":"Creating a Layer 2 VPN Point-​to-​Point Connection"}],"s":""},{"n":"monitoring","l":"Monitoring with Grafana","s":""}],"s":""},{"n":"frinx-uniconfig","l":"Frinx Uni​Config","c":false,"i":[{"n":"getting-started","l":"Getting started","s":""},{"n":"user-guide","l":"User Guide","i":[{"n":"basic-concepts","l":"Basic Concepts"},{"n":"network-management-protocols","l":"Device Installation","i":[{"n":"uniconfig-installing","l":"Device Installation"},{"n":"uniconfig_cli","l":"Uni​Config CLI"},{"n":"uniconfig_gnmi","l":"Uni​Config g​NMI","i":[{"n":"iosxr7","l":"Ios​XR 7 device"},{"n":"nokia","l":"NOKIA device"},{"n":"sonic","l":"SO​Ni​C device"}]},{"n":"uniconfig_netconf","l":"Uni​Config NETCONF","i":[{"n":"calix","l":"Calix devices"},{"n":"iosxr","l":"Cisco IOS XR devices"},{"n":"ocnos","l":"IP Infusion Oc​NOS Devices"},{"n":"junos","l":"Juniper Junos devices"},{"n":"sros","l":"Nokia SROS devices"}]},{"n":"uniconfig_snmp","l":"Uni​Config SNMP"},{"n":"updating-installation-parameters","l":"Updating installation parameters"},{"n":"uniconfig-native_cli","l":"Uni​Config-​native CLI"}]},{"n":"uniconfig-operations","l":"Uni​Config Operations","i":[{"n":"jsonb-filtering","l":"JSONB Filtering","i":[{"n":"application-jsonb-filtering","l":"Application JSONB Filtering"},{"n":"database-jsonb-filtering","l":"Database JSONB Filtering"}]},{"n":"snapshot-manager","l":"Snapshot Manager","i":[{"n":"obtain_snapshot_metadata","l":"Obtaining snapshots-​metadata"},{"n":"rpc_create-snapshot","l":"RPC create-​snapshot"},{"n":"rpc_delete-snapshot","l":"RPC delete-​snapshot"},{"n":"rpc_replace-config-with-snapshot","l":"RPC replace-​config-​with-​snapshot"}]},{"n":"subtree-manager","l":"Subtree Manager","i":[{"n":"rpc_bulk-edit","l":"RPC bulk-​edit"},{"n":"rpc_calculate-subtree-diff","l":"RPC calculate-​subtree-​diff"},{"n":"rpc_calculate-subtree-git-like-diff","l":"RPC calculate-​subtree-​git-​like-​diff"},{"n":"rpc_copy-many-to-one","l":"RPC copy-​many-​to-​one"},{"n":"rpc_copy-one-to-many","l":"RPC copy-​one-​to-​many"},{"n":"rpc_copy-one-to-one","l":"RPC copy-​one-​to-​one"}]},{"n":"templates-manager","l":"Templates Manager","i":[{"n":"rpc_apply-template","l":"Apply template"},{"n":"rpc_create-multiple-templates","l":"RPC create-​multiple-​templates"},{"n":"rpc_get-template-info","l":"RPC get-​template-​info"},{"n":"rpc_get-template-nodes","l":"RPC get-​template-​nodes"},{"n":"rpc_upgrade-template","l":"Upgrading template to latest yang repository"}]},{"n":"transaction-log","l":"Transaction Log","i":[{"n":"rpc_revert-changes","l":"RPC revert-​changes"},{"n":"transaction-tracker","l":"Transaction tracker"}]},{"n":"uniconfig-node-manager","l":"Uni​Config Node Manager","i":[{"n":"rpc_bulk-get","l":"RPC bulk-​get"},{"n":"rpc_calculate-diff","l":"RPC calculate-​diff"},{"n":"rpc_calculate-git-like-diff","l":"RPC calculate-​git-​like-​diff"},{"n":"uniconfig_check_installed_devices","l":"RPC check-​installed-​nodes"},{"n":"uniconfig_check_nodes_connection","l":"RPC check-​nodes-​connection"},{"n":"rpc_checked-commit","l":"RPC checked-​commit"},{"n":"rpc_commit","l":"RPC commit"},{"n":"rpc_compare-config","l":"RPC compare-​config"},{"n":"rpc_connect-node","l":"RPC connect-​node"},{"n":"rpc_disconnect-node","l":"RPC disconnect-​node"},{"n":"uniconfig_get_installed_devices","l":"RPC get-​installed-​nodes"},{"n":"rpc_health","l":"RPC health"},{"n":"uniconfig_install_multiple_nodes","l":"RPC install-​multiple-​nodes"},{"n":"rpc_is-in-sync","l":"RPC is-​in-​sync"},{"n":"rpc_replace-config-with-oper","l":"RPC replace-​config-​with-​operational"},{"n":"rpc_sync-from-network","l":"RPC sync-​from-​network"},{"n":"rpc_sync-to-network","l":"RPC sync-​to-​network"},{"n":"uniconfig_uninstall_multiple_nodes","l":"RPC uninstall-​multiple-​nodes"},{"n":"rpc_validate","l":"RPC validate"}]},{"n":"uniconfig-properties","l":"Uni​Config properties","i":[{"n":"rpc_read-properties","l":"RPC read-​properties"},{"n":"rpc_update-properties","l":"RPC update-​properties"}]},{"n":"utilities","l":"Utilities","i":[{"n":"openapi-diff","l":"Difference between Open​API specifications"},{"n":"yang-packager","l":"YANG packager"}]},{"n":"admin-state","l":"Admin State"},{"n":"build-and-commit-model","l":"Build-​and-​Commit Model"},{"n":"device-discovery","l":"Device discovery"},{"n":"dryrun-manager","l":"Dry-​run manager"},{"n":"immediate-commit-model","l":"Immediate Commit Model"},{"n":"kafka-notifications","l":"Kafka Notifications"},{"n":"operational-data-about-transactions","l":"Operational data about transactions"},{"n":"restconf","l":"Uni​Config - Sending and receiving data (RESTCONF)"},{"n":"uniconfig-queries","l":"Uni​Config Queries"},{"n":"uniconfig-shell","l":"Uni​Config shell"},{"n":"unistore-api","l":"Uni​Store API"},{"n":"yang-patch","l":"YANG Patch Operations"}]},{"n":"operational-procedures","l":"Operational Procedures","i":[{"n":"data-flows","l":"Data flows and transformations"},{"n":"data-security-models","l":"Data Security Models"},{"n":"logging","l":"Logging framework"},{"n":"openapi","l":"Open​API"},{"n":"thread-pools","l":"Thread pools"},{"n":"postgres-tls","l":"TLS encryption for Postgres database"},{"n":"tls","l":"TLS-​based Authentication"},{"n":"uniconfig-clustering","l":"Uni​Config Clustering"},{"n":"uniconfig-properties","l":"Uniconfig properties"}]},{"n":"performance-and-scale","l":"Performance and scale","c":false,"i":[{"n":"performance_characteristics","l":"Performance characteristics"}]},{"n":"monitoring","l":"Monitoring"},{"n":"sdk","l":"Uni​Config Client (SDK)"}]},{"n":"developer-guide","l":"Developer Guide","i":[{"n":"architecture","l":"Architecture"},{"n":"translation-units-in-general","l":"Translation Units in general"},{"n":"translation-units-docs","l":"Translation Units Documentation for FRINX Uniconfig"},{"n":"open-config-to-device-config-mapping","l":"Open​Config to device config mapping"},{"n":"translation-unit-general-implementation","l":"Developing a new translation unit"},{"n":"cli-translation-unit","l":"Implementing CLI Translation Unit"},{"n":"netconf-translation-unit","l":"NETCONF Unified Translation Unit"},{"n":"native-cli-units","l":"Native-​CLI translation units"},{"n":"metrics","l":"Metrics"}]},{"n":"release-notes","l":"Release notes","i":[{"n":"uniconfig-5.0.7","l":"Uniconfig 5.​0.​7 Release Notes"},{"n":"uniconfig-5.0.6","l":"Uni​Config 5.​0.​6"},{"n":"uniconfig-5.0.5","l":"Uni​Config 5.​0.​5"},{"n":"uniconfig-5.0.4","l":"Uni​Config 5.​0.​4"},{"n":"uniconfig-5.0.3","l":"Uni​Config 5.​0.​3"},{"n":"uniconfig-5.0.2","l":"Uni​Config 5.​0.​2"},{"n":"uniconfig-5.0.1","l":"Uni​Config 5.​0.​1"},{"n":"uniconfig-4.2.10","l":"Uni​Config 4.​2.​10"},{"n":"uniconfig-4.2.9","l":"Uni​Config 4.​2.​9"},{"n":"uniconfig-4.2.8","l":"Uni​Config 4.​2.​8"},{"n":"uniconfig-4.2.7","l":"Uni​Config 4.​2.​7"},{"n":"uniconfig-4.2.6","l":"Uni​Config 4.​2.​6"},{"n":"uniconfig-4.2.5","l":"Uni​Config 4.​2.​5"},{"n":"uniconfig-4.2.4","l":"Uni​Config 4.​2.​4"},{"n":"uniconfig-4.2.3","l":"Uni​Config 4.​2.​3"},{"n":"uniconfig-5.0.8","l":"Uniconfig 5.​0.​8 Release Notes"},{"n":"uniconfig-5.0.9","l":"Uniconfig 5.​0.​9 Release Notes"},{"n":"uniconfig-5.0.10","l":"Uniconfig 5.​0.​10 Release Notes"},{"n":"uniconfig-5.0.11","l":"Uniconfig 5.​0.​11 Release Notes"},{"n":"uniconfig-5.0.12","l":"Uniconfig 5.​0.​12 Release Notes"},{"n":"uniconfig-5.0.13","l":"Uniconfig 5.​0.​13 Release Notes"},{"n":"uniconfig-5.0.14","l":"Uniconfig 5.​0.​14 Release Notes"},{"n":"uniconfig-5.0.15","l":"Uniconfig 5.​0.​15 Release Notes"},{"n":"uniconfig-5.0.16","l":"Uniconfig 5.​0.​16 Release Notes"},{"n":"uniconfig-5.0.17","l":"Uniconfig 5.​0.​17 Release Notes"},{"n":"uniconfig-5.0.18","l":"Uniconfig 5.​0.​18 Release Notes"},{"n":"uniconfig-5.0.19","l":"Uniconfig 5.​0.​19 Release Notes"},{"n":"uniconfig-5.0.20","l":"Uniconfig 5.​0.​20 Release Notes"},{"n":"uniconfig-5.0.21","l":"Uniconfig 5.​0.​21 Release Notes"},{"n":"uniconfig-5.0.22","l":"Uniconfig 5.​0.​22 Release Notes"},{"n":"uniconfig-5.0.23","l":"Uniconfig 5.​0.​23 Release Notes"},{"n":"uniconfig-5.0.24","l":"Uniconfig 5.​0.​24 Release Notes"},{"n":"uniconfig-5.0.25","l":"Uniconfig 5.​0.​25 Release Notes"},{"n":"uniconfig-5.1.0","l":"Uniconfig 5.​1.​0 Release Notes"},{"n":"uniconfig-5.1.1","l":"Uniconfig 5.​1.​1 Release Notes"},{"n":"uniconfig-5.1.2","l":"Uniconfig 5.​1.​2 Release Notes"},{"n":"uniconfig-5.1.3","l":"Uniconfig 5.​1.​3 Release Notes"},{"n":"uniconfig-5.1.4","l":"Uniconfig 5.​1.​4 Release Notes"},{"n":"uniconfig-5.1.5","l":"Uniconfig 5.​1.​5 Release Notes"},{"n":"uniconfig-5.1.6","l":"Uniconfig 5.​1.​6 Release Notes"},{"n":"uniconfig-5.1.7","l":"Uniconfig 5.​1.​7 Release Notes"},{"n":"uniconfig-5.1.8","l":"Uniconfig 5.​1.​8 Release Notes"},{"n":"uniconfig-5.1.9","l":"Uniconfig 5.​1.​9 Release Notes"},{"n":"uniconfig-5.1.10","l":"Uniconfig 5.​1.​10 Release Notes"},{"n":"uniconfig-5.1.11","l":"Uniconfig 5.​1.​11 Release Notes"},{"n":"uniconfig-5.1.12","l":"Uniconfig 5.​1.​12 Release Notes"},{"n":"uniconfig-5.1.13","l":"Uniconfig 5.​1.​13"},{"n":"uniconfig-5.1.14","l":"Uniconfig 5.​1.​14"},{"n":"uniconfig-5.1.15","l":"Uniconfig 5.​1.​15"},{"n":"uniconfig-5.1.16","l":"Uniconfig 5.​1.​16"},{"n":"uniconfig-5.1.17","l":"Uniconfig 5.​1.​17"},{"n":"uniconfig-5.1.18","l":"Uniconfig 5.​1.​18"},{"n":"uniconfig-5.1.19","l":"Uniconfig 5.​1.​19"},{"n":"uniconfig-5.1.20","l":"Uniconfig 5.​1.​20"},{"n":"uniconfig-5.1.21","l":"Uniconfig 5.​1.​21"},{"n":"uniconfig-5.1.22","l":"Uniconfig 5.​1.​22"},{"n":"uniconfig-5.1.23","l":"Uniconfig 5.​1.​23"},{"n":"uniconfig-5.2.0","l":"Uniconfig 5.​2.​0 Release Notes"},{"n":"uniconfig-5.2.1","l":"Uniconfig 5.​2.​1"},{"n":"uniconfig-5.2.2","l":"Uniconfig 5.​2.​2"},{"n":"uniconfig-5.2.3","l":"Uniconfig 5.​2.​3"},{"n":"uniconfig-5.2.4","l":"Uniconfig 5.​2.​4"},{"n":"uniconfig-5.2.5","l":"Uniconfig 5.​2.​5"},{"n":"uniconfig-5.2.6","l":"Uniconfig 5.​2.​6"},{"n":"uniconfig-5.2.7","l":"Uniconfig 5.​2.​7"},{"n":"uniconfig-6.0.0","l":"Uniconfig 6.​0.​0"},{"n":"uniconfig-6.0.1","l":"Uniconfig 6.​0.​1"},{"n":"uniconfig-6.0.2","l":"Uniconfig 6.​0.​2"},{"n":"uniconfig-6.0.3","l":"Uniconfig 6.​0.​3"},{"n":"uniconfig-6.0.4","l":"Uniconfig 6.​0.​4"},{"n":"uniconfig-6.0.5","l":"Uniconfig 6.​0.​5"},{"n":"uniconfig-6.0.6","l":"Uniconfig 6.​0.​6"},{"n":"uniconfig-6.0.7","l":"Uniconfig 6.​0.​7"},{"n":"uniconfig-6.0.8","l":"Uniconfig 6.​0.​8"},{"n":"uniconfig-6.0.9","l":"Uniconfig 6.​0.​9"},{"n":"uniconfig-6.1.0","l":"Uniconfig 6.​1.​0"},{"n":"uniconfig-6.1.1","l":"Uniconfig 6.​1.​1"},{"n":"uniconfig-6.1.2","l":"Uniconfig 6.​1.​2"},{"n":"uniconfig-6.1.3","l":"Uniconfig 6.​1.​3"},{"n":"uniconfig-6.1.4","l":"Uniconfig 6.​1.​4"},{"n":"uniconfig-6.1.5","l":"Uniconfig 6.​1.​5"},{"n":"uniconfig-6.1.6","l":"Uniconfig 6.​1.​6"},{"n":"uniconfig-7.0.0","l":"Uniconfig 7.​0.​0"},{"n":"uniconfig-7.0.1","l":"Uniconfig 7.​0.​1"}]},{"n":"translation-units-docs","l":"Translation Units","i":[{"n":"ietf-to-oc-mapping","l":"Ietf to oc mapping","c":false,"i":[{"n":"ietf_l2p2p_local_to_oc","l":"IETF L​2​VPN YANG"},{"n":"ietf_l2p2p_remote_to_oc","l":"IETF L​2​VPN YANG"},{"n":"ietf_l2vpn_to_oc","l":"IETF L​2​VPN YANG"},{"n":"ietf_l3vpn_to_oc","l":"IETF L​3​VPN YANG"}]},{"n":"configuration-datasets","l":"Interfaces","i":[{"n":"acl","l":"Acl","c":false,"i":[{"n":"acl_interfaces","l":"Access Control List"},{"n":"acl","l":"Access Control List"}]},{"n":"cable","l":"Cable","c":false,"i":[{"n":"cable_downstream_profile","l":"cable DOWNSTREAM CONTROLLER-​PROFILE"},{"n":"cable_fiber_node","l":"cable FIBER-​NODE"},{"n":"cable_rpd","l":"cable RPD"}]},{"n":"interfaces","l":"Interfaces","c":false,"i":[{"n":"bridge_interface","l":"BRIDGE interface"},{"n":"cable_interface","l":"CABLE interface"},{"n":"ethernet_interface","l":"Ethernet interface"},{"n":"l2vlan_interface","l":"L​2​VLAN interface"},{"n":"l3vlan_interface","l":"L​3 VLAN interface"},{"n":"lag_interface","l":"Link Aggregation Group (bundle) interface"},{"n":"wideband_interface","l":"WIDEBAND interface"}]},{"n":"ipsec","l":"Ipsec","c":false,"i":[{"n":"ipsec","l":"Internet Protocol Security (I​Psec)"}]},{"n":"netflow","l":"Netflow","c":false,"i":[{"n":"netflow_interfaces","l":"Net​Flow"}]},{"n":"network-instances","l":"Network instances","c":false,"i":[{"n":"l2p2p","l":"L​2​p​2​p","c":false,"i":[{"n":"connection_point","l":"L​2​P​2​P configuration"}]},{"n":"l2vpn","l":"L​2​vpn","c":false,"i":[{"n":"connection_point_l2vpn","l":"L​2​VPN (VPLS with BGP autodiscovery) configuration"}]},{"n":"l2vsi","l":"L​2​vsi","c":false,"i":[{"n":"l2vsicp","l":"L​2​VSI (L​2 virtual switch instance virtual circuit)"},{"n":"l2vsi","l":"L​2​VSI (L​2 virtual switch instance)"}]},{"n":"l3vpn","l":"L​3​vpn","c":false,"i":[{"n":"network_instance_l3vpn_bgp","l":"L​3​VPN configuration (BGP as CE-​PE protocol)"},{"n":"network_instance_l3vpn_ospf","l":"L​3​VPN configuration (OSPF as CE-​PE protocol)"}]},{"n":"mpls","l":"Mpls","c":false,"i":[{"n":"mpls_ldp","l":"Multiprotocol Label Switching - Label Distribution Protocol (MPLS LDP)"},{"n":"mpls_rsvp","l":"Multiprotocol Label Switching - Resource Reservation Protocol (MPLS RSVP)"},{"n":"mpls_te","l":"Multiprotocol Label Switching - Traffic Engineering (MPLS-​TE)"},{"n":"mpls_tunnel","l":"Multiprotocol Label Switching - Tunnel"}]},{"n":"policy-forwarding","l":"Policy forwarding","c":false,"i":[{"n":"pf_interfaces","l":"Interface policy configuration"}]},{"n":"protocols","l":"Protocols","c":false,"i":[{"n":"bgp","l":"Border Gateway Protocol (BGP)"},{"n":"isis","l":"Intermediate System to Intermediate System (IS-​IS)"},{"n":"ospf","l":"Open Shortest Path First (OSPF)"},{"n":"ospfv3","l":"Open Shortest Path First v​3 (OSP​Fv​3)"},{"n":"static","l":"Static Route"}]},{"n":"vlans","l":"Vlans","c":false,"i":[{"n":"vlan","l":"VLAN"}]},{"n":"network_instance","l":"Configure network instance (VRF)"}]},{"n":"routing-policy","l":"Routing policy","c":false,"i":[{"n":"routing-policy","l":"Routing Policy"}]},{"n":"aaa","l":"AAA - Authentication Authorization Accounting"},{"n":"bcast-containment","l":"Broadcast-​Containment (Broadcast-​containment filters)"},{"n":"cdp","l":"Configure CDP interfaces"},{"n":"fdp","l":"Configure FDP interfaces"},{"n":"stp","l":"Configure STP interfaces"},{"n":"oam","l":"Ethernet OAM / Ethernet CFM"},{"n":"evc","l":"Ethernet Virtual Circuit (EVC)"},{"n":"evpn","l":"Ethernet Virtual Private Network (EVPN)"},{"n":"hsrp","l":"Hot Standby Router Protocol (HSRP)"},{"n":"l2-cft","l":"L​2-​Cft (Layer 2 Control Frame Forwarding)"},{"n":"logging","l":"Logging (syslog)"},{"n":"privilege","l":"Privilege"},{"n":"probes","l":"Probes"},{"n":"qos","l":"Quality of Service"},{"n":"relay-agent","l":"Relay Agent"},{"n":"snmp","l":"Simple Network Management Protocol (SNMP)"},{"n":"system","l":"System-​wide services and functions"}]},{"n":"operational-datasets","l":"Network Instances","i":[{"n":"network-instances","l":"Network instances","c":false,"i":[{"n":"protocols","l":"Protocols","c":false,"i":[{"n":"bgp_summary","l":"BGP global + neighbors"},{"n":"bgp_rib","l":"BGP RIB"},{"n":"ospf_summary","l":"Show router ospf type, ID, interfaces"}]}]},{"n":"interfaces","l":"Interfaces"},{"n":"platform","l":"Platform"},{"n":"cdp","l":"Show CDP interfaces and neighbors"},{"n":"lldp","l":"Show LLDP interfaces and neighbors"},{"n":"system","l":"System"}]},{"n":"translation-framework-101","l":"Table of Contents"}]},{"n":"q_a","l":"FAQ","s":""},{"n":"glossary-of-terms","l":"Glossary of terms"},{"n":"supported-devices","l":"List of Supported Devices"}],"s":""},{"n":"frinx-workflow-manager","l":"Workflow Manager","c":false,"i":[{"n":"introduction","l":"FRINX Workflow Manager introduction"},{"n":"python-sdk","l":"Python SDK","i":[{"n":"frinx-python-sdk","l":"Frinx Python SDK"},{"n":"services-python-api","l":"Frinx Servives Python API"},{"n":"services-python-workers","l":"Frinx Servives Python Workers"},{"n":"workflow-builder","l":"Python workflow builder"},{"n":"development","l":"Developent environment"}],"s":""},{"n":"workflow-builder","l":"UI Workflow Builder"}],"s":""},{"n":"frinx-device-inventory","l":"Device Inventory","c":false,"i":[{"n":"blueprints","l":"Device Blueprints"},{"n":"inventory","l":"Device Inventory"}],"s":""},{"n":"frinx-resource-manager","l":"Resource Manager","c":false,"i":[{"n":"introduction","l":"FRINX Resource Manager introduction"},{"n":"user-guide","l":"User Guide"},{"n":"pools","l":"Pools"},{"n":"architecture","l":"Resource Manager architecture"},{"n":"developer-guide","l":"Developer Guide"}],"s":""}],"search":{"mode":0,"minChars":2,"maxResults":20,"placeholder":"Search","hotkeys":["/"],"noResultsFoundMsg":"Sorry, no results found.","recognizeLanguages":true,"languages":[0],"preload":false}}; +var __DOCS_CONFIG__ = {"id":"qBTPZ9ldprAu+OSMJ5695tphsSnwPLiC5w","key":"Y33WMsYxjCO6setxaJdcCykByGFM1a9mTjG1fwaECmY.VldYbU7mYDDk+Rz2Tm9IP1/hP4ocMjeyeQo7LK0aFflIhvAR+DrMjsSTdTQjYCSOmssQhpx/dlP75Ig01W/N4g.108205","base":"/","host":"docs.frinx.io","version":"1.0.0","useRelativePaths":true,"documentName":"index.html","appendDocumentName":false,"trailingSlash":true,"preloadSearch":false,"cacheBustingToken":"2.4.0.780575774113","cacheBustingStrategy":"query","sidebarFilterPlaceholder":"Filter","toolbarFilterPlaceholder":"Filter","showSidebarFilter":true,"filterNotFoundMsg":"No member names found containing the query \"{query}\"","maxHistoryItems":15,"homeIcon":"","access":[{"value":"public","label":"Public"},{"value":"protected","label":"Protected"}],"toolbarLinks":[{"id":"fields","label":"Fields"},{"id":"properties","label":"Properties","shortLabel":"Props"},{"id":"methods","label":"Methods"},{"id":"events","label":"Events"}],"sidebar":[{"n":"/","l":"Welcome","s":""},{"n":"frinx-machine","l":"Frinx Machine","c":false,"i":[{"n":"getting-started","l":"FRINX Machine introduction","s":""},{"n":"api-docs","l":"API Gateway","s":""},{"n":"installation","l":"Kubernetes installation","c":false,"i":[{"n":"docker-registry-secret","l":"Docker Registry Secret"},{"n":"basic","l":"Helm Installation Guide"},{"n":"customization","l":"Advanced Helm Chart Installation","c":false,"i":[{"n":"create-kind-cluster","l":"Cluster installation"},{"n":"frinx-machine-customization","l":"Helm Chart Installation Guide with customization"}]},{"n":"custom-worker-deployment","l":"Custom worker deployment"},{"n":"oauth2-proxy","l":"Authorization and authentification"}],"s":""},{"n":"use-cases","l":"Demo Use Cases","i":[{"n":"dashboard","l":"Dashboard"},{"n":"add-to-inventory-and-install","l":"Add a device to inventory and install it"},{"n":"install-all-devices-from-inventory","l":"Install all devices from inventory"},{"n":"device-configure-loopback","l":"Device configure loopback"},{"n":"create-loopback-all-in-uniconfig","l":"Create loopback all in uniconfig"},{"n":"create-workflow","l":"Create workflow"},{"n":"create-l2-vpn-p2p","l":"Creating a Layer 2 VPN Point-​to-​Point Connection"}],"s":""},{"n":"monitoring","l":"Monitoring with Grafana","s":""}],"s":""},{"n":"frinx-uniconfig","l":"Frinx Uni​Config","c":false,"i":[{"n":"getting-started","l":"Getting started","s":""},{"n":"user-guide","l":"User Guide","i":[{"n":"basic-concepts","l":"Basic Concepts"},{"n":"network-management-protocols","l":"Device Installation","i":[{"n":"uniconfig-installing","l":"Device Installation"},{"n":"uniconfig_cli","l":"Uni​Config CLI"},{"n":"uniconfig_gnmi","l":"Uni​Config g​NMI","i":[{"n":"iosxr7","l":"Ios​XR 7 device"},{"n":"nokia","l":"NOKIA device"},{"n":"sonic","l":"SO​Ni​C device"}]},{"n":"uniconfig_netconf","l":"Uni​Config NETCONF","i":[{"n":"calix","l":"Calix devices"},{"n":"iosxr","l":"Cisco IOS XR devices"},{"n":"ocnos","l":"IP Infusion Oc​NOS Devices"},{"n":"junos","l":"Juniper Junos devices"},{"n":"sros","l":"Nokia SROS devices"}]},{"n":"uniconfig_snmp","l":"Uni​Config SNMP"},{"n":"updating-installation-parameters","l":"Updating installation parameters"},{"n":"uniconfig-native_cli","l":"Uni​Config-​native CLI"}]},{"n":"uniconfig-operations","l":"Uni​Config Operations","i":[{"n":"jsonb-filtering","l":"JSONB Filtering","i":[{"n":"application-jsonb-filtering","l":"Application JSONB Filtering"},{"n":"database-jsonb-filtering","l":"Database JSONB Filtering"}]},{"n":"snapshot-manager","l":"Snapshot Manager","i":[{"n":"obtain_snapshot_metadata","l":"Obtaining snapshots-​metadata"},{"n":"rpc_create-snapshot","l":"RPC create-​snapshot"},{"n":"rpc_delete-snapshot","l":"RPC delete-​snapshot"},{"n":"rpc_replace-config-with-snapshot","l":"RPC replace-​config-​with-​snapshot"}]},{"n":"subtree-manager","l":"Subtree Manager","i":[{"n":"rpc_bulk-edit","l":"RPC bulk-​edit"},{"n":"rpc_calculate-subtree-diff","l":"RPC calculate-​subtree-​diff"},{"n":"rpc_calculate-subtree-git-like-diff","l":"RPC calculate-​subtree-​git-​like-​diff"},{"n":"rpc_copy-many-to-one","l":"RPC copy-​many-​to-​one"},{"n":"rpc_copy-one-to-many","l":"RPC copy-​one-​to-​many"},{"n":"rpc_copy-one-to-one","l":"RPC copy-​one-​to-​one"}]},{"n":"templates-manager","l":"Templates Manager","i":[{"n":"rpc_apply-template","l":"Apply template"},{"n":"rpc_create-multiple-templates","l":"RPC create-​multiple-​templates"},{"n":"rpc_get-template-info","l":"RPC get-​template-​info"},{"n":"rpc_get-template-nodes","l":"RPC get-​template-​nodes"},{"n":"rpc_upgrade-template","l":"Upgrading template to latest yang repository"}]},{"n":"transaction-log","l":"Transaction Log","i":[{"n":"rpc_revert-changes","l":"RPC revert-​changes"},{"n":"transaction-tracker","l":"Transaction tracker"}]},{"n":"uniconfig-node-manager","l":"Uni​Config Node Manager","i":[{"n":"rpc_bulk-get","l":"RPC bulk-​get"},{"n":"rpc_calculate-diff","l":"RPC calculate-​diff"},{"n":"rpc_calculate-git-like-diff","l":"RPC calculate-​git-​like-​diff"},{"n":"uniconfig_check_installed_devices","l":"RPC check-​installed-​nodes"},{"n":"uniconfig_check_nodes_connection","l":"RPC check-​nodes-​connection"},{"n":"rpc_checked-commit","l":"RPC checked-​commit"},{"n":"rpc_commit","l":"RPC commit"},{"n":"rpc_compare-config","l":"RPC compare-​config"},{"n":"rpc_connect-node","l":"RPC connect-​node"},{"n":"rpc_disconnect-node","l":"RPC disconnect-​node"},{"n":"uniconfig_get_installed_devices","l":"RPC get-​installed-​nodes"},{"n":"rpc_health","l":"RPC health"},{"n":"uniconfig_install_multiple_nodes","l":"RPC install-​multiple-​nodes"},{"n":"rpc_is-in-sync","l":"RPC is-​in-​sync"},{"n":"rpc_replace-config-with-oper","l":"RPC replace-​config-​with-​operational"},{"n":"rpc_sync-from-network","l":"RPC sync-​from-​network"},{"n":"rpc_sync-to-network","l":"RPC sync-​to-​network"},{"n":"uniconfig_uninstall_multiple_nodes","l":"RPC uninstall-​multiple-​nodes"},{"n":"rpc_validate","l":"RPC validate"}]},{"n":"uniconfig-properties","l":"Uni​Config properties","i":[{"n":"rpc_read-properties","l":"RPC read-​properties"},{"n":"rpc_update-properties","l":"RPC update-​properties"}]},{"n":"utilities","l":"Utilities","i":[{"n":"openapi-diff","l":"Difference between Open​API specifications"},{"n":"yang-packager","l":"YANG packager"}]},{"n":"admin-state","l":"Admin State"},{"n":"build-and-commit-model","l":"Build-​and-​Commit Model"},{"n":"device-discovery","l":"Device discovery"},{"n":"dryrun-manager","l":"Dry-​run manager"},{"n":"immediate-commit-model","l":"Immediate Commit Model"},{"n":"kafka-notifications","l":"Kafka Notifications"},{"n":"operational-data-about-transactions","l":"Operational data about transactions"},{"n":"restconf","l":"Uni​Config - Sending and receiving data (RESTCONF)"},{"n":"uniconfig-queries","l":"Uni​Config Queries"},{"n":"uniconfig-shell","l":"Uni​Config shell"},{"n":"unistore-api","l":"Uni​Store API"},{"n":"yang-patch","l":"YANG Patch Operations"}]},{"n":"operational-procedures","l":"Operational Procedures","i":[{"n":"data-flows","l":"Data flows and transformations"},{"n":"data-security-models","l":"Data Security Models"},{"n":"logging","l":"Logging framework"},{"n":"openapi","l":"Open​API"},{"n":"thread-pools","l":"Thread pools"},{"n":"postgres-tls","l":"TLS encryption for Postgres database"},{"n":"tls","l":"TLS-​based Authentication"},{"n":"uniconfig-clustering","l":"Uni​Config Clustering"},{"n":"uniconfig-properties","l":"Uniconfig properties"}]},{"n":"performance-and-scale","l":"Performance and scale","c":false,"i":[{"n":"performance_characteristics","l":"Performance characteristics"}]},{"n":"monitoring","l":"Monitoring"},{"n":"sdk","l":"Uni​Config Client (SDK)"}]},{"n":"developer-guide","l":"Developer Guide","i":[{"n":"architecture","l":"Architecture"},{"n":"translation-units-in-general","l":"Translation Units in general"},{"n":"translation-units-docs","l":"Translation Units Documentation for FRINX Uniconfig"},{"n":"open-config-to-device-config-mapping","l":"Open​Config to device config mapping"},{"n":"translation-unit-general-implementation","l":"Developing a new translation unit"},{"n":"cli-translation-unit","l":"Implementing CLI Translation Unit"},{"n":"netconf-translation-unit","l":"NETCONF Unified Translation Unit"},{"n":"native-cli-units","l":"Native-​CLI translation units"},{"n":"metrics","l":"Metrics"}]},{"n":"release-notes","l":"Release notes","i":[{"n":"uniconfig-5.0.7","l":"Uniconfig 5.​0.​7 Release Notes"},{"n":"uniconfig-5.0.6","l":"Uni​Config 5.​0.​6"},{"n":"uniconfig-5.0.5","l":"Uni​Config 5.​0.​5"},{"n":"uniconfig-5.0.4","l":"Uni​Config 5.​0.​4"},{"n":"uniconfig-5.0.3","l":"Uni​Config 5.​0.​3"},{"n":"uniconfig-5.0.2","l":"Uni​Config 5.​0.​2"},{"n":"uniconfig-5.0.1","l":"Uni​Config 5.​0.​1"},{"n":"uniconfig-4.2.10","l":"Uni​Config 4.​2.​10"},{"n":"uniconfig-4.2.9","l":"Uni​Config 4.​2.​9"},{"n":"uniconfig-4.2.8","l":"Uni​Config 4.​2.​8"},{"n":"uniconfig-4.2.7","l":"Uni​Config 4.​2.​7"},{"n":"uniconfig-4.2.6","l":"Uni​Config 4.​2.​6"},{"n":"uniconfig-4.2.5","l":"Uni​Config 4.​2.​5"},{"n":"uniconfig-4.2.4","l":"Uni​Config 4.​2.​4"},{"n":"uniconfig-4.2.3","l":"Uni​Config 4.​2.​3"},{"n":"uniconfig-5.0.8","l":"Uniconfig 5.​0.​8 Release Notes"},{"n":"uniconfig-5.0.9","l":"Uniconfig 5.​0.​9 Release Notes"},{"n":"uniconfig-5.0.10","l":"Uniconfig 5.​0.​10 Release Notes"},{"n":"uniconfig-5.0.11","l":"Uniconfig 5.​0.​11 Release Notes"},{"n":"uniconfig-5.0.12","l":"Uniconfig 5.​0.​12 Release Notes"},{"n":"uniconfig-5.0.13","l":"Uniconfig 5.​0.​13 Release Notes"},{"n":"uniconfig-5.0.14","l":"Uniconfig 5.​0.​14 Release Notes"},{"n":"uniconfig-5.0.15","l":"Uniconfig 5.​0.​15 Release Notes"},{"n":"uniconfig-5.0.16","l":"Uniconfig 5.​0.​16 Release Notes"},{"n":"uniconfig-5.0.17","l":"Uniconfig 5.​0.​17 Release Notes"},{"n":"uniconfig-5.0.18","l":"Uniconfig 5.​0.​18 Release Notes"},{"n":"uniconfig-5.0.19","l":"Uniconfig 5.​0.​19 Release Notes"},{"n":"uniconfig-5.0.20","l":"Uniconfig 5.​0.​20 Release Notes"},{"n":"uniconfig-5.0.21","l":"Uniconfig 5.​0.​21 Release Notes"},{"n":"uniconfig-5.0.22","l":"Uniconfig 5.​0.​22 Release Notes"},{"n":"uniconfig-5.0.23","l":"Uniconfig 5.​0.​23 Release Notes"},{"n":"uniconfig-5.0.24","l":"Uniconfig 5.​0.​24 Release Notes"},{"n":"uniconfig-5.0.25","l":"Uniconfig 5.​0.​25 Release Notes"},{"n":"uniconfig-5.1.0","l":"Uniconfig 5.​1.​0 Release Notes"},{"n":"uniconfig-5.1.1","l":"Uniconfig 5.​1.​1 Release Notes"},{"n":"uniconfig-5.1.2","l":"Uniconfig 5.​1.​2 Release Notes"},{"n":"uniconfig-5.1.3","l":"Uniconfig 5.​1.​3 Release Notes"},{"n":"uniconfig-5.1.4","l":"Uniconfig 5.​1.​4 Release Notes"},{"n":"uniconfig-5.1.5","l":"Uniconfig 5.​1.​5 Release Notes"},{"n":"uniconfig-5.1.6","l":"Uniconfig 5.​1.​6 Release Notes"},{"n":"uniconfig-5.1.7","l":"Uniconfig 5.​1.​7 Release Notes"},{"n":"uniconfig-5.1.8","l":"Uniconfig 5.​1.​8 Release Notes"},{"n":"uniconfig-5.1.9","l":"Uniconfig 5.​1.​9 Release Notes"},{"n":"uniconfig-5.1.10","l":"Uniconfig 5.​1.​10 Release Notes"},{"n":"uniconfig-5.1.11","l":"Uniconfig 5.​1.​11 Release Notes"},{"n":"uniconfig-5.1.12","l":"Uniconfig 5.​1.​12 Release Notes"},{"n":"uniconfig-5.1.13","l":"Uniconfig 5.​1.​13"},{"n":"uniconfig-5.1.14","l":"Uniconfig 5.​1.​14"},{"n":"uniconfig-5.1.15","l":"Uniconfig 5.​1.​15"},{"n":"uniconfig-5.1.16","l":"Uniconfig 5.​1.​16"},{"n":"uniconfig-5.1.17","l":"Uniconfig 5.​1.​17"},{"n":"uniconfig-5.1.18","l":"Uniconfig 5.​1.​18"},{"n":"uniconfig-5.1.19","l":"Uniconfig 5.​1.​19"},{"n":"uniconfig-5.1.20","l":"Uniconfig 5.​1.​20"},{"n":"uniconfig-5.1.21","l":"Uniconfig 5.​1.​21"},{"n":"uniconfig-5.1.22","l":"Uniconfig 5.​1.​22"},{"n":"uniconfig-5.1.23","l":"Uniconfig 5.​1.​23"},{"n":"uniconfig-5.2.0","l":"Uniconfig 5.​2.​0 Release Notes"},{"n":"uniconfig-5.2.1","l":"Uniconfig 5.​2.​1"},{"n":"uniconfig-5.2.2","l":"Uniconfig 5.​2.​2"},{"n":"uniconfig-5.2.3","l":"Uniconfig 5.​2.​3"},{"n":"uniconfig-5.2.4","l":"Uniconfig 5.​2.​4"},{"n":"uniconfig-5.2.5","l":"Uniconfig 5.​2.​5"},{"n":"uniconfig-5.2.6","l":"Uniconfig 5.​2.​6"},{"n":"uniconfig-5.2.7","l":"Uniconfig 5.​2.​7"},{"n":"uniconfig-6.0.0","l":"Uniconfig 6.​0.​0"},{"n":"uniconfig-6.0.1","l":"Uniconfig 6.​0.​1"},{"n":"uniconfig-6.0.2","l":"Uniconfig 6.​0.​2"},{"n":"uniconfig-6.0.3","l":"Uniconfig 6.​0.​3"},{"n":"uniconfig-6.0.4","l":"Uniconfig 6.​0.​4"},{"n":"uniconfig-6.0.5","l":"Uniconfig 6.​0.​5"},{"n":"uniconfig-6.0.6","l":"Uniconfig 6.​0.​6"},{"n":"uniconfig-6.0.7","l":"Uniconfig 6.​0.​7"},{"n":"uniconfig-6.0.8","l":"Uniconfig 6.​0.​8"},{"n":"uniconfig-6.0.9","l":"Uniconfig 6.​0.​9"},{"n":"uniconfig-6.1.0","l":"Uniconfig 6.​1.​0"},{"n":"uniconfig-6.1.1","l":"Uniconfig 6.​1.​1"},{"n":"uniconfig-6.1.2","l":"Uniconfig 6.​1.​2"},{"n":"uniconfig-6.1.3","l":"Uniconfig 6.​1.​3"},{"n":"uniconfig-6.1.4","l":"Uniconfig 6.​1.​4"},{"n":"uniconfig-6.1.5","l":"Uniconfig 6.​1.​5"},{"n":"uniconfig-6.1.6","l":"Uniconfig 6.​1.​6"},{"n":"uniconfig-7.0.0","l":"Uniconfig 7.​0.​0"},{"n":"uniconfig-7.0.1","l":"Uniconfig 7.​0.​1"}]},{"n":"translation-units-docs","l":"Translation Units","i":[{"n":"ietf-to-oc-mapping","l":"Ietf to oc mapping","c":false,"i":[{"n":"ietf_l2p2p_local_to_oc","l":"IETF L​2​VPN YANG"},{"n":"ietf_l2p2p_remote_to_oc","l":"IETF L​2​VPN YANG"},{"n":"ietf_l2vpn_to_oc","l":"IETF L​2​VPN YANG"},{"n":"ietf_l3vpn_to_oc","l":"IETF L​3​VPN YANG"}]},{"n":"configuration-datasets","l":"Interfaces","i":[{"n":"acl","l":"Acl","c":false,"i":[{"n":"acl_interfaces","l":"Access Control List"},{"n":"acl","l":"Access Control List"}]},{"n":"cable","l":"Cable","c":false,"i":[{"n":"cable_downstream_profile","l":"cable DOWNSTREAM CONTROLLER-​PROFILE"},{"n":"cable_fiber_node","l":"cable FIBER-​NODE"},{"n":"cable_rpd","l":"cable RPD"}]},{"n":"interfaces","l":"Interfaces","c":false,"i":[{"n":"bridge_interface","l":"BRIDGE interface"},{"n":"cable_interface","l":"CABLE interface"},{"n":"ethernet_interface","l":"Ethernet interface"},{"n":"l2vlan_interface","l":"L​2​VLAN interface"},{"n":"l3vlan_interface","l":"L​3 VLAN interface"},{"n":"lag_interface","l":"Link Aggregation Group (bundle) interface"},{"n":"wideband_interface","l":"WIDEBAND interface"}]},{"n":"ipsec","l":"Ipsec","c":false,"i":[{"n":"ipsec","l":"Internet Protocol Security (I​Psec)"}]},{"n":"netflow","l":"Netflow","c":false,"i":[{"n":"netflow_interfaces","l":"Net​Flow"}]},{"n":"network-instances","l":"Network instances","c":false,"i":[{"n":"l2p2p","l":"L​2​p​2​p","c":false,"i":[{"n":"connection_point","l":"L​2​P​2​P configuration"}]},{"n":"l2vpn","l":"L​2​vpn","c":false,"i":[{"n":"connection_point_l2vpn","l":"L​2​VPN (VPLS with BGP autodiscovery) configuration"}]},{"n":"l2vsi","l":"L​2​vsi","c":false,"i":[{"n":"l2vsicp","l":"L​2​VSI (L​2 virtual switch instance virtual circuit)"},{"n":"l2vsi","l":"L​2​VSI (L​2 virtual switch instance)"}]},{"n":"l3vpn","l":"L​3​vpn","c":false,"i":[{"n":"network_instance_l3vpn_bgp","l":"L​3​VPN configuration (BGP as CE-​PE protocol)"},{"n":"network_instance_l3vpn_ospf","l":"L​3​VPN configuration (OSPF as CE-​PE protocol)"}]},{"n":"mpls","l":"Mpls","c":false,"i":[{"n":"mpls_ldp","l":"Multiprotocol Label Switching - Label Distribution Protocol (MPLS LDP)"},{"n":"mpls_rsvp","l":"Multiprotocol Label Switching - Resource Reservation Protocol (MPLS RSVP)"},{"n":"mpls_te","l":"Multiprotocol Label Switching - Traffic Engineering (MPLS-​TE)"},{"n":"mpls_tunnel","l":"Multiprotocol Label Switching - Tunnel"}]},{"n":"policy-forwarding","l":"Policy forwarding","c":false,"i":[{"n":"pf_interfaces","l":"Interface policy configuration"}]},{"n":"protocols","l":"Protocols","c":false,"i":[{"n":"bgp","l":"Border Gateway Protocol (BGP)"},{"n":"isis","l":"Intermediate System to Intermediate System (IS-​IS)"},{"n":"ospf","l":"Open Shortest Path First (OSPF)"},{"n":"ospfv3","l":"Open Shortest Path First v​3 (OSP​Fv​3)"},{"n":"static","l":"Static Route"}]},{"n":"vlans","l":"Vlans","c":false,"i":[{"n":"vlan","l":"VLAN"}]},{"n":"network_instance","l":"Configure network instance (VRF)"}]},{"n":"routing-policy","l":"Routing policy","c":false,"i":[{"n":"routing-policy","l":"Routing Policy"}]},{"n":"aaa","l":"AAA - Authentication Authorization Accounting"},{"n":"bcast-containment","l":"Broadcast-​Containment (Broadcast-​containment filters)"},{"n":"cdp","l":"Configure CDP interfaces"},{"n":"fdp","l":"Configure FDP interfaces"},{"n":"stp","l":"Configure STP interfaces"},{"n":"oam","l":"Ethernet OAM / Ethernet CFM"},{"n":"evc","l":"Ethernet Virtual Circuit (EVC)"},{"n":"evpn","l":"Ethernet Virtual Private Network (EVPN)"},{"n":"hsrp","l":"Hot Standby Router Protocol (HSRP)"},{"n":"l2-cft","l":"L​2-​Cft (Layer 2 Control Frame Forwarding)"},{"n":"logging","l":"Logging (syslog)"},{"n":"privilege","l":"Privilege"},{"n":"probes","l":"Probes"},{"n":"qos","l":"Quality of Service"},{"n":"relay-agent","l":"Relay Agent"},{"n":"snmp","l":"Simple Network Management Protocol (SNMP)"},{"n":"system","l":"System-​wide services and functions"}]},{"n":"operational-datasets","l":"Network Instances","i":[{"n":"network-instances","l":"Network instances","c":false,"i":[{"n":"protocols","l":"Protocols","c":false,"i":[{"n":"bgp_summary","l":"BGP global + neighbors"},{"n":"bgp_rib","l":"BGP RIB"},{"n":"ospf_summary","l":"Show router ospf type, ID, interfaces"}]}]},{"n":"interfaces","l":"Interfaces"},{"n":"platform","l":"Platform"},{"n":"cdp","l":"Show CDP interfaces and neighbors"},{"n":"lldp","l":"Show LLDP interfaces and neighbors"},{"n":"system","l":"System"}]},{"n":"translation-framework-101","l":"Table of Contents"}]},{"n":"q_a","l":"FAQ","s":""},{"n":"glossary-of-terms","l":"Glossary of terms"},{"n":"supported-devices","l":"List of Supported Devices"}],"s":""},{"n":"frinx-workflow-manager","l":"Workflow Manager","c":false,"i":[{"n":"introduction","l":"FRINX Workflow Manager introduction"},{"n":"python-sdk","l":"Python SDK","i":[{"n":"frinx-python-sdk","l":"Frinx Python SDK"},{"n":"services-python-api","l":"Frinx Servives Python API"},{"n":"services-python-workers","l":"Frinx Servives Python Workers"},{"n":"workflow-builder","l":"Python workflow builder"},{"n":"development","l":"Developent environment"}],"s":""},{"n":"workflow-builder","l":"UI Workflow Builder"}],"s":""},{"n":"frinx-device-inventory","l":"Device Inventory","c":false,"i":[{"n":"blueprints","l":"Device Blueprints"},{"n":"inventory","l":"Device Inventory"}],"s":""},{"n":"frinx-resource-manager","l":"Resource Manager","c":false,"i":[{"n":"introduction","l":"FRINX Resource Manager introduction"},{"n":"user-guide","l":"User Guide"},{"n":"pools","l":"Pools"},{"n":"architecture","l":"Resource Manager architecture"},{"n":"developer-guide","l":"Developer Guide"}],"s":""}],"search":{"mode":0,"minChars":2,"maxResults":20,"placeholder":"Search","hotkeys":["/"],"noResultsFoundMsg":"Sorry, no results found.","recognizeLanguages":true,"languages":[0],"preload":false}}; diff --git a/resources/js/search.json b/resources/js/search.json index bceccefbc..ca65abcd3 100644 --- a/resources/js/search.json +++ b/resources/js/search.json @@ -1 +1 @@ -[[{"i":"welcome-to-frinx-documentation","l":"Welcome to FRINX Documentation!","p":["The FRINX documentation site contains all FRINX projects, releases and documentation. Please, use search bar in the upper left corner to find specific issues and information that you demand."]},{"l":"FRINX Machine","p":["FRINX Machine provides a platform allowing easy definition, execution and monitoring of complex workflows using FRINX UniConfig."]},{"l":"FRINX UniConfig","p":["FRINX UniConfig is a suite of applications aimed at network configuration management."]},{"l":"FRINX Workflow Manager","p":["FRINX Workflow Manager allows customers to create automated and repeatable digital processes to build, grow and operate their digital communication infrastructure."]},{"l":"FRINX Resource Manager","p":["FRINX Resource Manager helps network operators and infrastructure engineers manage their physical and logical assets and resources."]}],[{"l":"FRINX Machine introduction","p":["In today's rapidly evolving digital landscape, efficient network management and automation are crucial for maintaining robust and scalable IT infrastructures. Frinx Machine emerges as a powerful solution tailored to meet these demands, providing an integrated platform designed to simplify and enhance network automation."]},{"i":"what-is-frinx-machine","l":"What is Frinx Machine?","p":["Frinx Machine is an advanced network automation platform delivering a comprehensive suite of tools for managing and automating network infrastructures. It is designed to streamline network operations, reduce complexity, and drive efficiency through a unified, scalable, and flexible approach.","Frinx Machine enabling seamless management of network configurations across multi-vendor environments. It provides a consistent interface for deploying and managing configurations, reducing the complexities associated with heterogeneous network devices."]},{"l":"FRINX Machine core components"},{"l":"High-Level Architecture","p":["The following diagram outlines the main functional components in the FRINX Machine solution:","FM Architecture"]},{"l":"UniConfig","p":["Connects to the devices in the network","Retrieves and stores configuration from devices","Pushes configuration data to devices","Builds diffs between actual and intended config to execute atomic configuration changes","Retrieves operational data from devices","Manages transactions across one or multiple devices","Translates between CLI, vendor native, and industry-standard data models (i.e. OpenConfig)","Reads and stores vendor native data models from mounted network devices (i.e YANG models)","Ensures high availability, reducing network outages and downtime","Executes commands on multiple devices simultaneously"]},{"i":"workflow-manager-conductor","l":"Workflow manager (Conductor)","p":["Atomic tasks are chained together into more complex workflows","Defines, executes and monitors workflows (via REST or UI)","Schedule workflow executions","We chose Netflix’s conductor workflow engine since it has been proven to be a highly scalable open-source technology that integrates very well with FRINX UniConfig. Further information about Conductor can be found at:","FRINXio conductor sources: https://github.com/FRINXio/conductor","FRINXio conductor community sources: https://github.com/FRINXio/conductor-community","Sources: https://github.com/conductor-oss/conductor","Docs: https://conductor-oss.github.io/conductor/index.html"]},{"l":"Device inventory","p":["Store all important devices information on one place","Maintain devices in all deployment zones from one place","Notify about changes in inventory via Kafka"]},{"l":"Topology discovery","p":["Acquires information from live network","Relying on UniConfig as its primary source of network information","Uses that information to build topology view(s):","Across multiple layers of the network","e.g. LLDP data to build physical topology view or routing data to build L3 view","Performs reconciliation across the layers in order to provide a unified topology view","Provides an API to query topologies","Provides Kafka notifications about changes in the topology","Consumes and stores device metadata events from Kafka topic"]},{"l":"Performance monitor","p":["Collects performance metrics about devices in a time-series based database","Relies on UniConfig as a producer of the performance metrics of devices.","Relies on Device Inventory as a producer of information about devices, such as device name, vendor, model, and version.","Unifies performance metrics and produces them to a Kafka broker.","Provides an API to query performance metrics of devices."]},{"i":"monitoring","l":"Monitoring:"},{"i":"loki--grafana--influxdb--telegraf---core-of-monitoring","l":"Loki + Grafana + Influxdb + Telegraf - core of Monitoring","p":["Loki: Efficient log aggregation and querying.","Telegraf: Data collection and reporting agent.","InfluxDB: High-performance time-series database.","Grafana: Powerful visualization and dashboard creation."]},{"i":"key-functions","l":"Key Functions:","p":["Collect logs and metrics from services to provide platform observability"]}],[{"l":"API Gateway","p":["Communication with FRINX Machine is facilitated through both a user-friendly UI and a robust REST API. All our services offer REST and GraphQL APIs, allowing seamless interaction for both users and automated systems.","Our architecture employs an API Gateway to consolidate all endpoints into a single, accessible location. Each service is assigned a unique path, simplifying access. To connect with a specific service, you only need to know the FM KrakenD/OAuth2-Proxy ingress host and the designated path for your desired service. This streamlined approach ensures efficient and straightforward communication with FRINX Machine."]},{"l":"Api Gateway diagram","p":["API Gateway"]},{"l":"Api Docs","p":["API documentation is accesibla via Frinx Machine installation"]}],[{"l":"Create Docker Registry Secret","p":["Create a kubernetes Docker registry secret for pulling images from private registry:","For more info about accessing private images, visit Download Frinx Uniconfig"]}],[{"l":"Helm Chart Installation Guide","p":["This guide provides the step-by-step instructions for installing FRINX Machine on a Kubernetes cluster using Helm charts."]},{"l":"Prerequisites","p":["Minikube: Make sure that Minikube is installed on your local machine. Follow the Minikube installation guide if necessary.","Helm: Make sure that Helm is installed. Follow the Helm installation guide if necessary."]},{"i":"step-1-start-minikube","l":"Step 1: Start Minikube"},{"i":"step-2-add-the-frinx-helm-repository","l":"Step 2: Add the FRINX Helm Repository","p":["Add the FRINX Helm repository and update the repository list:"]},{"i":"step-3-install-operators-and-crds","l":"Step 3: Install Operators and CRDs","p":["Install FRINX Machine operators and custom resource definitions (CRDs):","Verify the installation by checking the pods in the frinx namespace:","You should see output similar to:"]},{"i":"step-4-create-docker-registry-secret","l":"Step 4: Create Docker Registry Secret","p":["Please complete this step before continue Create docker regitry secret"]},{"i":"step-5-install-frinx-machine","l":"Step 5: Install FRINX Machine","p":["Install the FRINX Machine using Helm:","Verify the installation by checking the pods in the frinx namespace:","You should see output similar to:"]},{"i":"step-6-access-the-ui","l":"Step 6: Access the UI","p":["Add the following entries to your /etc/hosts file:","Enable the KrakenD ingress for the FRINX Machine:","Visit Frinx Machine page in your browser on https://krakend.127.0.0.1.nip.io/frinxui"]}],[{"l":"Setting Up a Kind Cluster with Cilium and NGINX Ingress Controller","p":["This guide will walk you through the process of deploying a Kubernetes (K8s) cluster using Kind (Kubernetes IN Docker), setting up the Cilium CNI (Container Network Interface), and deploying the NGINX Ingress Controller."]},{"l":"Prerequisites","p":["Kind: Make sure that Kind is installed on your local machine. Follow the Kind installation guide if necessary.","Helm: Make sure that Helm is installed. Follow the Helm installation guide if necessary.","Cilium: Make sure that Cilium system requirements are fullfiled. Follow the Cilium installation guide if necessary."]},{"l":"Deploy Kind cluster","p":["Create a Kind configuration file named kind-config.yaml with the following content:","This configuration sets up a Kind cluster with one control-plane node and three worker nodes. It also maps ports 80 and 443 from the host to the control-plane node, making the cluster ready for ingress traffic.","Deploy the cluster using Kind:","Verify the cluster is running:","You should see output indicating that the Kubernetes control plane and CoreDNS are running."]},{"l":"Deploy Cilium","p":["Create a Cilium configuration file named cilium-helm-values.yaml with the following content:","This configuration enables Cilium with kube-proxy replacement and various service options, including Hubble for network observability.","Install Cilium using Helm:","Check the status of the Cilium pods to ensure they are running:","You should see the Cilium and Hubble components running without issues."]},{"l":"Deploy NGINX Ingress Controller","p":["Deploy the NGINX Ingress Controller using the following command:","Verify the NGINX Ingress Controller is running:","You should see the NGINX Ingress Controller pod running."]}],[{"l":"Helm Chart Installation Guide with customization","p":["This guide provides the step-by-step instructions for installing FRINX Machine on a Kubernetes cluster using Helm charts with customization via helm dependency values."]},{"l":"Prerequisites","p":["Cluster: Make sure that you cluster is running.","Helm: Make sure that Helm is installed. Follow the Helm installation guide if necessary."]},{"i":"step-1-add-the-frinx-helm-repository","l":"Step 1: Add the FRINX Helm Repository","p":["Add the FRINX Helm repository and update the repository list:"]},{"i":"step-2-install-operators-and-crds","l":"Step 2: Install Operators and CRDs","p":["Install FRINX Machine operators and custom resource definitions (CRDs):","Verify the installation by checking the pods in the frinx namespace:","You should see output similar to:"]},{"i":"step-3-create-docker-registry-secret","l":"Step 3: Create Docker Registry Secret","p":["Please complete this step before continue Create docker regitry secret"]},{"i":"step-4-customize-frinx-machine","l":"Step 4: Customize FRINX Machine","p":["To customize the deployment of FRINX Machine, you need to create a folder that will contain the necessary Helm chart files: Chart.yaml and values.yaml. This folder will serve as the root for your customized Helm chart, with FRINX Machine as a dependency."]},{"l":"Create the Chart Configuration","p":["Create the Chart.yaml file:","This file contains the metadata for your Helm chart and specifies FRINX Machine as a dependency.","This configuration sets up the basic information about the Helm chart and defines FRINX Machine as a dependency, pulling it from the specified repository.","Check Dependency Chart Details:","For mapping the Helm chart release to the product release and more details on the FRINX Machine Helm chart, refer to the FRINX Machine Helm chart documentation on Artifact Hub."]},{"l":"Customize the Values","p":["Create the values.yaml file:","This file contains custom configurations for the FRINX Machine subcharts. Customization options are based on the documentation of each subchart, which can be found on Artifact Hub.","krakend: Configures the Ingress settings for the KrakenD API Gateway. It enables the Ingress, sets the class to nginx, and includes custom annotations for proxy timeouts. The host is set to krakend.127.0.0.1.nip.io with the path /.","uniconfig: Specifies the Docker image repository for the Uniconfig component.","performance-monitor: Specifies the Docker image repository for the Performance Monitor component."]},{"l":"Customize Subcharts","p":["Subchart Customization:","For more detailed customization possibilities, refer to the documentation for each dependency Helm chart version. This will provide information on all configurable parameters and how to adjust them to suit your deployment needs.","By following these steps, you can effectively customize the deployment of FRINX Machine using Helm. Ensure you refer to the individual subchart documentation on Artifact Hub for specific configuration options and further customization."]},{"i":"step-5-install-frinx-machine","l":"Step 5: Install FRINX Machine","p":["Install the FRINX Machine using Helm:","Verify the installation by checking the pods in the frinx namespace:","You should see output similar to:"]},{"i":"step-6-access-the-ui","l":"Step 6: Access the UI","p":["Visit Frinx Machine page in your browser on https://krakend.127.0.0.1.nip.io/frinxui"]}],[{"l":"Custom worker deployment","p":["To deploy a custom worker to Frinx Machine, utilize the generic worker Helm chart. Select the Helm chart version that corresponds with your application version, ensuring it is aligned with the Frinx Machine version.","You can find the necessary Helm chart at: Helm Chart for Frinx Workers."]},{"l":"Create the Chart Configuration","p":["Create the Chart.yaml file in new folder:"]},{"l":"Customize the Values","p":["Create the values.yaml file next to Chart.yaml:"]},{"l":"Deploy charts"},{"l":"Useful Links","p":["minikube image load","kind image load"]}],[{"l":"Authorization and authentification","p":["Follow official helm chart repository for oauth2-proxy. Don't forget to update the version to a more recent.","Follow oauth2-proxy official documentation to configure Azure AD."]},{"l":"Install Oauth2-Proxy"},{"l":"Configure RBAC","p":["Rbac functionality can be configured on subchart level.","https://artifacthub.io/packages/helm/frinx-helm-charts/krakend?modal=values&path=rbac","https://artifacthub.io/packages/helm/frinx-helm-charts/workflow-manager?modal=values&path=rbac","https://artifacthub.io/packages/helm/frinx-helm-charts/topology-discovery?modal=values&path=rbac","env: X_AUTH_USER_GROUP: * frinx-rbac-admin-role"]}],[{"l":"Demo Use Cases","p":["The following use cases demonstrate the basic usage of FRINX Machine. These examples will help you explore the platform's capabilities, including executing prepared workflows, creating custom workflows via the workflow builder, and manually managing your device inventory."]},{"l":"1. Executing Prepared Workflows","p":["Experience the power of automation by running pre-configured workflows.","Learn how to efficiently manage network tasks using automated processes."]},{"l":"2. Creating Custom Workflows","p":["Utilize the workflow builder to create and customize your workflows.","Tailor processes to your specific needs, enhancing operational efficiency."]},{"l":"3. Managing Device Inventory","p":["Add devices to your inventory manually, providing flexibility to experiment with different configurations.","This feature is particularly useful for testing and deploying your own networking devices."]},{"l":"4. Controlling Devices","p":["Manage devices in your inventory through the user interface (UI).","Execute operations using prepared workflows, ensuring streamlined control and management."]},{"l":"5. Configuring Network Services","p":["Set up L2VPNs between virtual devices, enhancing network connectivity and performance.","Create loopbacks on device interfaces either manually or through automated workflows, demonstrating the versatility of FRINX Machine.","These use cases serve as a starting point for exploring the extensive capabilities of FRINX Machine. They illustrate how the platform can be utilized for a variety of networking tasks, from basic device management to complex network configurations."]},{"l":"Install Demo Use Case workflows","p":["Use demo-worklows helm chart to run sample-topology and frinx-demo-workflows conducor worker."]},{"l":"Install Frinx Machine","p":["Make sure your Frinx Machine is running. Demo Use Cases"]},{"l":"Install Demo workflows and Sample Topology"}],[{"l":"FRINX Machine Demo Manual","p":["After logging into FRINX Machine, you can see the FRINX Machine dashboard:","FRINX Machine dashboard"]}],[{"l":"Add a device to inventory and install it"},{"l":"Adding device to inventory","p":["At the FRINX Machine Dashboard under Device Inventory section click on Add new device panel. The page with the form titled Add device opens.","Add device to inventory"]},{"l":"JSON examples","p":["New devices added to Device inventory are defined by JSON code snippets. (These snippets are part of UniConfig RPC connection-manager:install-node.) They are similar to Blueprints. This snippet is going to be filled into Mount parameters field.","Another way is to add a new device from blueprint: toggle the Use blueprint? switch in the form and choose the blueprint that you want to use from Select blueprint drop-down list.","Note: following snippets refer to devices present in sample-topology demo"]},{"i":"cisco-classic-ios-cli","l":"Cisco classic IOS (cli)"},{"i":"cisco-ios-xr-netconf","l":"Cisco IOS XR (netconf)"},{"i":"huawei-cli","l":"Huawei (cli)"},{"i":"calix-netconf","l":"CALIX (netconf)","p":["Note: this device is not present in sample-topology"]},{"i":"nokia-netconf","l":"Nokia (netconf)","p":["Note: this device is not present in sample-topology"]},{"i":"saos-6-cli","l":"SAOS 6 (cli)"},{"i":"saos-8-cli","l":"SAOS 8 (cli)"},{"l":"Install the new device from Inventory","p":["After the device is added we can install it to UniConfig. At the FRINX Machine Dashboard under Device Inventory section click on Explore & configure devices panel. The page titled Devices opens - it lists all devices from Device inventory.","Click blue Install button located on the row next to a device which you want to install - after successful installation button will change to green button with the text Installed.","Install device from inventory","If you follow instruction properly, your devices are now listed in Device inventory and installed, ready to be operated through Frinx Machine."]}],[{"l":"Install all devices from inventory","p":["When Device Inventory contains a lot of devices, it can be tedious to install them one by one. To make things easier, there is a workflow which allows to install all devices present in the inventory.","Follow these instructions to use the workflow:","At the FRINX Machine Dashboard under Workflow Manage section click on Explore workflows panel. The page titled Workflow definitions opens. Use Search workflow by name input box and fill in Install_all_from_inventory and click Search button.","Search for workflow Install_all_from_inventory","The list of workflows narrows down to two items - workflows Install_all_from_inventory and Uninstall_all_from_inventory. Click blue Execute button (blue play icon) located on the row next to the workflow. The form titled with the name of workflow Install_all_from_inventory appears and optionally you can fill in the input parameter labels which allows to select a subset of devices to install. (You can specify a device label while adding devices to Device Inventory.) We want to install all uninstalled devices - do not fill in the input labels and click Execute workflow button. As a result to the left of the Execute workflow button will appear the link Executed workflow in detail.","Execute workflow Install_all_from_inventory","After you click the link Executed workflow in detail you will be navigated to a page with details of the executed workflow - it displays individual tasks for this workflow, it is possible to click whatever task and examine its inputs and outputs, whether it was successful or unsuccessful etc.","Note: Similarily you can use workflow Uninstall_all_from_inventory to uninstall all devices at once."]}],[{"l":"Device configure loopback"},{"l":"Demo Config Manager UI","p":["Using the Demo Config Manager:","On the FRINX Machine main page, select Explore & configure devices.","Make sure that the device you want to configure is installed. If not, select Install first.","For this demo, we use the IOS01 device. Locate the device in the list and select the corresponding gear icon on the right. (If you see a message saying Transaction expired, select Refresh).","Device Inventory - Devices - list of devices","For the Loopback0 interface, change the enabled status to false.","Select Save to save your changes.","To review your changes, select Calculate diff.","To view the set of commands used for the change, select Dry run.","To apply changes to the device, select Commit to network. You can also see the changes in the Operational data store.","Device Inventory - configure device IOS01","To revert changes made to the device configuration:","Select Transactions.","Select the Revert icon for your transaction.","Select Revert changes."]}],[{"l":"Create loopback all in uniconfig"},{"i":"demo-creating-a-loopback-address-on-devices-stored-in-the-inventory","l":"Demo: Creating a loopback address on devices stored in the inventory","p":["This workflow creates a loopback interface on all devices installed in the inventory or on all devices filtered by labels. Labels are markers that serve as a differentiator.","Check if all devices are installed. You can install them manually or by executing the Install_all_from_inventory / 1 workflow.","FRINX Machine dashboard","On the main page, select Explore workflows. In the Search by keyword column, enter loopback. The Create_loopback_all_in_uniconfig / 1 workflow will appear in the list. Under Actions, select the corresponding Run button for the workflow.","Under loopback_id, insert 77 and select Execute. Click on the link that appears.","All tasks were executed correctly and are completed.","On the results page, you will see five individual tasks:"]},{"l":"INVENTORY_get_all_devices_as_dynamic_fork_tasks","p":["This workflow displays a list of all devices in the inventory or devices filtered by label. It parses the output in the correct format for the dynamic fork, which creates a number of tasks depending on the number of devices in the inventory."]},{"l":"SUB_WORKFLOW","p":["This is the dynamic fork sub-workflow. In this case, it creates UNICONFIG_write_structured_device_data for every individual device in the inventory. You can then get detailed information on the progress and succession of every device."]},{"l":"UNICONFIG_calculate_diff","p":["This remote procedure call creates a difference between the actual UniConfig topology devices and the intended UniConfig topology nodes."]},{"l":"UNICONFIG_dryrun_commit","p":["This remote procedure call resolves the difference between actual and intended device configurations. After all changes are applied, the cli-dryrun journal is read and a remote procedure call output is created and returned."]},{"l":"UNICONFIG_commit","p":["This is the final task that actually commits the intended configuration to the devices."]}],[{"l":"Create workflow"},{"l":"Demo workflow UI basics","p":["Workflow Builder is a graphical interface for Workflow Manager and is used to create, modify and manage workflows.","Workflows are groups of tasks and/or sub-workflows that can be used, for example, to install or delete devices, create loopback interfaces on devices, send messages and much more. You can create your own workflows or edit existing ones by adding or removing tasks or sub-workflows.","Every task and sub-workflow placed in a workflow has a unique reference alias, and no two workflows can share a name and version."]},{"l":"How to create a new custom workflow","p":["A translation of what is happening here: \"If the identified device is of the type saos, then extract the name from the output message of the previous task, change the letters to uppercase, extract the version from the output message of the previous task, glue them together and add _1(because that is how devices are named in this demo topology\".","Above every task or workflow there are two icons:","As above, if we enter the username and password directly, the workflow will not ask for credentials at startup.","decision task: Makes a different kind of decision from the lambda task discussed above. This task works like a switch on a track, sending the train one way or another. The data needed to make a decision is supplied by the lambda task.","Device_identification task:","Enter details for the new workflow. Under Name, enter a name for your workflow (note that this name cannot be changed later). The Description is for additional information about the workflow and can be left empty. Label can help you to find your workflow later under Explore workflows, but can also be left empty. Select Save changes when ready.","Enter the following into the body:","Finding your new workflow and running it with multiple different inputs such as 10 000, 10 002, 10 012, etc.","For different ports, you can see different devices with other run commands in memory.","FRINX Machine dashboard","FRINX Machine dashboard FRINX Machine dashboard","If the input value for decision is other, it directs the flow towards device_identification. If the input value is false, it directs the flow towards terminate. This corresponds to the way we connected the cells in the workflow builder.","In the Input parameters tab and the Lambda value field, enter: ${workflow.input.port}. This indicates that the task should work with what was entered in the port field in the input of this workflow. (We will cover this later, in section 7.)","In the Input parameters tab under management_ip, enter sample-topology. This is the name of the topology in this installation, whereas in production you would use a real name. For port, enter ${workflow.input.port}. If you enter a port number manually, the workflow will not ask for one when started (the same goes for management_ip and other fields). However, we want the user to be able to select a port they are interested in, as we did with the lambda task in section 4.","In the Input parameters tab, delete the default parameter foo. For the param parameter, enter ${lambda_IkSu.output.result.value}. (Note that IkSu is an automatically generated reference alias that you must edit to match the one generated for you.) What ${lambda_IkSu.output.result.value} means is to take the value from lambda_xyzq which is in the output, find the result in the output and the value in it.","In the Input parameters tab, enter COMPLETED(or FAILED, at your discretion) in the Termination status field. You can enter whatever message you want in the Expected workflow output field (for example, Device not supported.)","In the Script expression field, enter a small function which we described above.","In this case, if the specified port is both greater than or equal to 10000 and less than 10005, the status chosen is keep working. Otherwise, the status is end. This status is the output of the lambda and the input for the next task or sub-workflow.","lambda task: Makes a decision on which status to choose based on the embedded port. In this example we will only consider ports 10000–10004, and others are ignored. The lambda task lets you enter a small code (lambda - function without name) into the workflow builder.","Like we mentioned above, in this demo workflow we will assume that login credentials are the same everywhere.","Next steps:","Now we can add more tasks. In the left column under System tasks, we can add another lambda. In the Workflows section, you can find Read_journal_cli_device. Let us place them next to each other after Device_identification and concatenate them:","Now we can create a new workflow from scratch:","password: ${workflow.input.password}","Read_journal_cli_device: In the Input parameters tab under device_id, enter ${lambda_ZW66.output.result}.","Remove/Expand:","Save and run your workflow.","Second lambda: Enter ${Device_identificationRef_f7I6.output} as the lambda value, meaning \"take the output from the previous Device_identification task and use that\".","Select Create on the main page of FRINX Machine.","Sub-workflows are similar to classic workflows, but inside of another workflow. The workflow that we are creating can also be used as a building block for another workflow, becoming a sub-workflow itself. In this manner, we can layer and reuse previously created workflows.","terminated task:","The form - Create new workflow","The output from Read_journal_cli_device is concatenated with END, as is the output from terminated. Thus we have closed our custom workflow.","Under System tasks, click the + sign for the lambda, decision and terminate tasks. Under Workflows, click the + sign for Device_identification. Tasks and sub-workflows are added on top of each other on the canvas and can be dragged around. To connect all parts of the workflow, hover over IN and OUT where the + sign appears. Connect the parts as follows: START- lambda- decision- (other) to Device_identification and default to terminate. Each task and workflow has a reference alias after its name, which works as unique a identifier.","Update:","username and password: For this demo, we assume that the following login credentials are used on all devices: username: frinx and password: frinx","username: ${workflow.input.username}","When working with devices using different login credentials, you need to be able to change or enter them at startup. This can be achieved in the same way as with the port parameter:","Workflow builder UI - Actions - Save workflow Workflow builder UI - clicked Save and execute button - form for the workflow","Workflow builder UI - adding more tasks","Workflow builder UI - create or update workflow","Workflow builder UI - final workflow design Workflow builder UI - final workflow design","Workflow builder UI - icon Edit task","Workflow builder UI - icon Edit task clicked - form for editing of desision task","Workflow builder UI - icon Edit task clicked - form for editing of lambda task","Workflow builder UI - icon Edit task clicked - form for editing of second lambda task","Workflow builder UI - icon Edit task clicked - form for editing of second subworkflow","Workflow builder UI - icon Edit task clicked - form for editing of subworkflow","Workflow builder UI - icon Edit task clicked - form for editing of terminate task","Workflow builder UI - icon Menu"]}],[{"l":"Creating a Layer 2 VPN Point-to-Point Connection","p":["This section details how to find and execute a prebuilt workflow that creates a Layer 2 VPN Point-to-Point connection within Workflow Manager."]},{"l":"Navigating through Workflow Manager","p":["From the FRINX Machine Dashboard you can either under section Workflow Manager click panel Explore workflows or select the menu tab in the upper left-hand corner and click the menu item Workflow manager.","On the page Workflow definitions fill in search box Search workflow by name the name of workflow: Create_L2VPN_P2P_OC_uniconfig and click Search button or scroll down to find it in the list of prebuilt worflows.","Frinx Machine Dashboard","Workflows definitions page","Once you have located the workflow press the Play button located to the right of the workflow, this will open the form with the title Create_L2VPN_P2P_OC_uniconfig- the workflow configuration window."]},{"l":"Configuring the Workflow","p":["The configuring form for workflow Create_L2VPN_P2P_OC_uniconfig contains inputs pre-filled with following data:","Workflow Create_L2VPN_P2P_OC_uniconfig: L2 VPN Configuration","Once you have completed, press the Execute workflow button, to the left of the Execute workflow button will appear the link Executed workflow in detail. Click on this link Executed workflow in detail to see the details of the executed workflow.","Executed workflow in detail - Link"]},{"l":"Output of the Executed Workflow","p":["You can see the detail of executed workflow after clicking link Executed workflow in detail immediatelly after executing of workflow. If you do not use this opportunity you can navigate to Executed workflows page and to find executed workflow in the list of executed workflows.(From the FRINX Machine Dashboard under section Workflow Manager click panel Executed workflows)","Select the workflow Create_L2VPN_P2P_OC_uniconfig to see the output from all of the tasks completed within this workflow.","Executed Workflow Details","This following sections are available within the output window or on the page with details for executed workflow:","Task Details: This tab gives a detailed list of the individual tasks (ordered list of tasks - task type) executed within the conductor, a log of each tasks start time and end time, and a status of 'Completed' or 'Failed'. If task is a workflow (that is the parent workflow is calling another workflow) we refer to is as subworkflow and there is an icon which navigate us to display a detailed list of the individual tasks from which consist the subworkflow.","Input/Output: This tab contains Workflow Input which can be e.g. inputs for some API call and Workflow Output which can be e.g. result from some API call.","JSON: This tab gives a detailed output in JSON format of all executed tasks from which consist the workflow. Click the Unescape button to make the output more user-friendly to read.","Edit Rerun: This tab allows you to change the inputs of the previously executed workflow and execute the new instance by clicking of Rerun button.","Execution Flow: A structured map from the conductor lays out the path of tasks executed from start to finish, any forks in the path are also shown here.","Task Details: As we already explained this tab lists tasks from which the workflow consists - if you click on any of the tasks you will receive a pop-up window that contains these tabs:","Summary: Provide a summary for executed task e.g. Task Ref. Name, Description, Input, Output...","JSON: JSON output of the completed task with that goes into greater detail. about the task execution. Click the Unescape button to make the output more user-friendly to read.","Logs: Log status.","Pop-up window can be exited via clicking close-task-details icon."]},{"l":"Sub-Workflows","p":["Within the original Details of Create_L2VPN_P2P_OC_uniconfig window you will see a sub-workflow.","Sub-Workflow","This sub-workflow is an embedded task that makes a separate API call to Slack to notify a pre-defined user group that the workflow has been executed and whether it has succeeded or failed."]}],[{"l":"Grafana","p":["Grafana is an open source visualization and analytics software. It allows to query, visualize, alert on, and explore metrics, logs, and traces no matter where they are stored.","Grafana Login page","By default, Grafana can be accessed at localhost:3000 or 127.0.0.1:3000","Default credentials are:","Username: frinx Password: frinx123!"]},{"l":"Monitoring","p":["Grafana in FRINX Machine monitors multitude of metrics. At this time, these are:","Device monitoring","FRINX Machine logs","Node monitoring","SSL monitoring","UniConfig-controller monitoring","Workflows monitoring"]},{"l":"Device Monitoring","p":["This dashboard displays data on a specific installed device/node."]},{"l":"FRINX Machine Logs","p":["This dashboard monitors all services running in FRINX Machine. You can filter by individual services, and also look for a specific value.","Logs Monitoring"]},{"l":"FRINX Machine Node Monitoring","p":["This dashboard monitors the state of VM/System where FRINX Machine is running. It reports info like CPU utilisation, Memory utilisation, Disk usage, Up-time etc.","Node Monitoring"]},{"l":"UniConfig Controller Monitoring","p":["This dashboard keeps track of various UniConfig transactions. It displays number of transactions at a given time."]},{"l":"Workflows Monitoring","p":["Collecting data on workflows is being worked on."]}],[{"l":"FRINX UniConfig introduction","p":["The purpose of UniConfig is to manage the configuration state and retrieve the operational state of physical and virtual networking devices.","UniConfig provides a single API for many different devices in the network. It can be run as an application on bare metal in a VM or a container, stand-alone, or as part of our automation solution, FRINX Machine. UniConfig has a built-in data store that can be run in-memory or with an external database.","UniConfig features"]},{"l":"UniConfig key features","p":["A \"Lazy CLI\" feature to suspend and resume connections without having to maintain keepalives","Allows for diffs to be built between actual and intended execution of atomic configuration changes","Can execute commands in parallel on multiple devices","Can read and store proprietary data models from network devices that follow the YANG data model","Choose between NETCONF or RESTCONF to connect to devices","Data export and import via blacklist and whitelist functions","Execute & Read API- Unstructured data via SSH and Telnet","Execute & Read capable API: Like Ansible, TCL Scripting or similar products, strings can be passed and received through SSH or Telnet via REST API. UniConfig provides the authentication and transportation of data without interpreting it.","High availability","Offers the ability to do a dry-commit to evaluate the functionality of a configuration before it is executed on devices","OpenConfig API– Translation provided by our open source device library","OpenConfig API: An API that is translated into device-specific CLI or YANG data models. The installation of \"translation units\" on devices is required. FRINX provides an open-source library of devices from a variety of network vendors. The open-source framework allows anyone to contribute or consume the contents of the expanding list of supported network devices.","Provides snapshots of previous configurations for rollback","Provides subtree filtering capabilities in NETCONF","Provides templates for device configuration","Pushes configuration data to devices via NETCONF, CLI or gNMI","Python microservices are used to integrate with the FRINX machine","Retrieves and stores current startup and running configuration from mounted network devices","Retrieves operational data from devices via NETCONF, CLI or gNMI","Subscribe to gNMI notifications","Subscribe to NETCONF notifications via web sockets","Support for 3-phase commit by using NETCONF confirmed-commit","Support for gNOI","Support for YANG 1.1 and Tail-f actions","Supports PostgreSQL as an external database","The ability to log specific devices as needed","The UniConfig client allows for simple, full-service access to UniConfig features","The UniConfig UI allows users to interact with the network controller using a web-based user interface","Transactions can be managed on one or multiple devices","Translates between CLI, native model and standard data models (i.e., OpenConfig) via our open-source device library","UniConfig allows users to communicate with their network infrastructure in four different ways:","UniConfig Native API– Direct access to vendor specific YANG data models that are native to the connected devices as well as UniConfig functions (diff, commit, snapshots, etc.)","UniConfig Native API: Vendor-specific YANG data models are absorbed by UniConfig to allow configuration of mounted devices. UniConfig maps vendor-specific \"native\" models into it's data store to provide stateful configuration capabilities to applications and users.","UniConfig Native CLI API– Programmatic access to the CLI without the need for translation units (experimental)","UniConfig Native CLI API: Allows for programmatic interaction with a device's CLI via the API and without the use of 'translation units'. Only a schema file is needed. (This option is currently experimental. Contact FRINX for more information.)","UniConfig solution"]},{"l":"UniConfig in a Docker container"},{"l":"Download and activate FRINX UniConfig","p":["To download, activate and start UniConfig in a Docker container:"]},{"l":"Stop the container","p":["To stop the container:"]},{"l":"UniConfig as a Java process in a VM or on a host"},{"l":"Download FRINX UniConfig","p":["To download UniConfig, please contact: marketing@elisapolystar.com","By downloading, you accept the FRINX software agreement."]},{"l":"Activate FRINX UniConfig","p":["To activate UniConfig, unzip the file, open the directory and run the following command:","For more information on the different arguments, run the startup script with the -h flag"]},{"l":"OpenAPI","p":["UniConfig distributions contain a .yaml file that generates a list of all usable RPCs and their examples. You can view it locally or on our hosted version that always shows the latest OpenAPI version.","The file can be found here:","See OpenAPI for more information."]}],[{"l":"User guide","p":["The UniConfig user guide includes the following sections:"]},{"l":"Basic concepts","p":["Explanations of basic concepts, principles and mechanisms within UniConfig."]},{"l":"Device installation","p":["Explains the device installation process. Covers the basic mechanisms that take place during installation, and explains parameters with examples of install requests. Also covers the differences between CLI, NETCONF and gNMI API."]},{"l":"UniConfig operations","p":["Lists various APIs used to interact with UniConfig."]},{"l":"Operational procedures","p":["Lists various procedures that can be used with UniConfig."]},{"l":"Performance and scale","p":["Describes the performance of UniConfig in various scale scenarios."]},{"l":"Monitoring","p":["Describes UniConfig performance metrics."]},{"i":"uniconfig-client-sdk","l":"UniConfig Client (SDK)","p":["UniConfig provides a full-blown Java-based SDK. All UniConfig operations available over RESTCONF are also available when using the SDK."]}],[{"l":"Basic Concepts","p":["UniConfig is a network controller that enables network operators to automate simple and complex procedures in their heterogeneous networks. UniConfig uses CLI, NETCONF and gNMI to connect to network devices and provides a RESTCONF interface on its northbound to provide an API to applications. UniConfig users use clients in various programming languages to communicate from their applications with the controller. FRINX provides a Java client and python workers to integrate with its workflow automation in FRINX Machine. Other clients can be generated from the OpenAPI documentation of the UniConfig API.","UniConfig is stateless and stores all state information before and after transactions in a PostgreSQL database. UniConfig provides transaction capabilities on its northbound API, so that multiple clients can interact with UniConfig at the same time in a well-structured way. In addition, transactions are also supported towards all network devices independent of the capabilities of these devices. Transactions can be rolled back on error automatically and on user demand by specifying a transaction ID from the transaction log. Clients can use an “immediate commit” model (changes sent to the controller get applied to the devices immediately) or a “build and commit” model (changes are staged on the controller until a commit operation pushes all changes in a transaction to one or multiple devices).","To support N+1 redundancy and horizontal scale (meaning adding more controller instances allows the system to serve more network devices and more clients) UniConfig can be deployed together with a load balancer(E.g.: Traefik). The combination of a state-less load balancer and multiple UniConfig instances achieves high availability and supports many network devices and client applications to configure the network.","An open-source device library allows users to connect UniConfig to CLI devices that do not support SDN protocols like NETCONF and gNMI. This library is open to users, independent software vendors and any 3rd party to contribute to and use to achieve their automation goals.","Finally, the UniConfig shell, allows users to interact with all UniConfig operations and the connected devices in a model driven way through CLI.","UniConfig runs in containers, VMs or as application and can be deployed stand-alone or as part of the \"FRINX Machine\" network automation solution."]}],[{"l":"Device installation"},{"i":"device-installation-1","l":"Device installation","p":["Guide to installation mechanisms along with CLI, NETCONF and gNMI examples."]},{"l":"UniConfig CLI","p":["The CLI southbound plugin allows UniConfig to communicate with CLI devices that do not support NETCONF or other programmatic APIs. The CLI service module uses YANG models and implements a translation logic to send and receive structured data to and from CLI devices."]},{"l":"UniConfig Netconf","p":["NETCONF is an Internet Engineering Task Force (IETF) protocol used to configure and monitor devices in the network. It can create, recover, update and delete configurations of network devices.","NETCONF operations are overlaid on the Remote Procedure Call (RPC) layer and may be described in either XML or JSON."]},{"l":"UniConfig-native CLI","p":["UniConfig-native CLI allows you to configure CLI-enabled devices using YANG models that describe configuration commands.","In a UniConfig-native CLI deployment, translation units are defined only by YANG models and device-specific characteristics used for parsing and serializing commands. Readers and writers are automatically created and provided to the translation registry (i.e., the user does not need to write them individually).","YANG models can be constructed by following well-defined rules explained in the Developer guide."]},{"l":"UniConfig gNMI","p":["The gRPC Network Management Interface (gNMI) is used to configure and monitor devices in the network. It can create, update, and delete configurations of network devices as well as susbcriptions to telemetry streams.","gNMI operations are performed via Remote Procedure Call (RPC) developed by Google. All gNMI messages within gRPC service definition are defined as protocol buffers (proto3)."]},{"l":"UniConfig gNOI","p":["The gRPC Network Operations Interface (gNOI) is used to execute operational commands on network devices. The gNOI protocol supports certificate management, bootstrapping and OS installation service.","All gNOI messages within gRPC service definition are defined as protocol buffers (proto3).","Network management protocols are used in the southbound API of the UniConfig Lighty distribution to install and communicate with devices.","The following protocols are currently supported:","NETCONF (Network Configuration Protocol)","SSH / TELNET","gNMI/gNOI (Network Management/Operations interface)"]}],[{"l":"Device installation","p":["Installing is the process of loading device information into UniConfig database. This information is saved in PostgreSQL database and used whenever transaction occurs. When the transaction is finished the connection to device is closed again, until next transaction.","These are the steps of installation process:","creation of UniConfig transaction","creation of mountpoint - connection to device","loading configuration and metadata from mountpoint","closing mountpoint and connection to device","storing synced configuration and metadata to database","closing UniConfig transaction","Node can be installed only once (you will receive error if node has already been installed).","You can specify if you would like to install node on the UniConfig layer. Default value is 'true':","Only 1 node with the same node-id can be installed on UniConfig layer.","It is synchronous: it succeeds only after node is successfully installed it fails in other cases – max-connection-attempts is automatically set to value '1', if different value is not provided in RPC input, database or config file.","Following sections provide deeper explanation of parameters needed for installation, along with example install requests.","Overview of our OpenAPI along with all parameters and expected returns can be found here."]},{"l":"Default parameters","p":["All install parameters (CLI/NETCONF) are set in database when Uniconfig is initializing. Values of these parameters are equal to specific yang model default values. These parameters are used when they are missing in RPC request.","Priority of using install parameters :","Parameter set in install RPC request","Parameter set in database","Default parameter from yang model","Priority of initial writing default parameters into database:","Database already contains default parameters","User defines default parameters into config file","Default values from yang schema file will be saved","Default parameters can be managed (read/update) using RESTCONF/Uniconfig shell with UniConfig Cloud Config.","Default parameters can also be defined in the application.properties.json file located in the config directory.","RPC request - read CLI default parameters:"]},{"l":"Installing CLI device","p":["Install node RPC","List of basic connection parameters that are used for identification of remote device. All of these parameters are mandatory.","node-id- Name of node that represents device in the topology.","cli-topology:host- IP address or domain-name of target device that runs SSH or Telnet server.","cli-topology:port- TCP port on which the SSH or Telnet server on remote device is listening to incoming connections. Standard SSH port is '22', standard Telnet port is '23'.","cli-topology:transport-type- Application protocol used for communication with device - supported options are 'ssh' and 'telnet'.","cli-topology:device-type- Device type that is used for selection of translation units that maps device configuration to OpenConfig models. Supported devices can be found","cli-topology:device-version- Version of device. Use a specific version or * for a generic one. * enables only basic read and write management without the support of OpenConfig models. Here.","cli-topology:username- Username for accessing of CLI management line.","cli-topology:password- Password assigned to username.","uniconfig-config:install-uniconfig-node-enabled- Whether node should be installed to UniConfig and unified layers. By default, this flag is set to 'true'."]},{"l":"Authentication parameters","p":["List of authentication parameters used for identification of remote user utilized for configuration of the device. Username and password parameters are mandatory.","cli-topology:username- Username for accessing of CLI management line.","cli-topology:password- Password assigned to username.","List of parameters that can be used for adjusting of reconnection strategy. None of these parameters is mandatory - if they are not set, default values are set. There are two exclusive groups of parameters based on selected reconnection strategy - you can define only parameters from single group. By default, keepalive strategy is used."]},{"l":"Connection parameters","p":["Following parameters adjust maintaining of CLI session state. None of these parameters are mandatory (default values will be used).","cli-topology:max-connection-attempts- Maximum number of initial connection attempts(default value: 1, non-positive value or null is interpreted as infinity). If there are unstable devices in the network it might be useful to provide max-connection-attempts higher than the default value. It would try to connect n times before throwing an ssh connection exception.","cli-topology:max-connection-attempts-install- Maximum number of initial connection attempts during install process (default value: 1, non-positive value or null is interpreted as infinity). If there are unstable devices in the network it might be useful to provide max-connection-attempts-install higher than the default value. It would try to connect n times before throwing an ssh connection exception.","cli-topology:max-reconnection-attempts- Maximum number of reconnection attempts(default value: 0, non-positive value or null is interpreted as infinity). It is used when open and established session dropped. max-reconnection-attempts is not that necessary to set. Uniconfig does not keep idle sessions open longer than it is necessary."]},{"l":"Storing failed installations","p":["The following parameter allows the user to store the installation in case the device is in some way unreachable.","uniconfig-config:store-failed-installation- If enabled, it will ensure that even if the device is unreachable, it will be stored in the node table in the database. If not set, the default value is false.","When the user sets the flag to true, an additional column called installation-status will be populated with a boolean flag (either SUCCESSFUL for a successful installation, or FAILED for a failed one). This lets the user know that there has been some problem and that the device was not installed correctly. The mount-point information of that node will be stored (unlike with the default value). With this info already stored, the user does not need to reinstall the device, as all the connection information is present in the UniConfig database. Syncing the device or calling a GET Request will try to reconnect to the device and if it is successful, the configuration data will be saved in the datastore and the request will then finish. The installation-status will then change to SUCCESSFUL. The installed device will then behave normally as if the installation was successful in the first place. If the device is still unreachable, the flag will stay FAILED.","This is useful when many devices are being installed in batches and the user doesn't know if they are up or not."]},{"l":"Installing without mount","p":["The following parameter lets you store node metadata into the UniConfig database without mounting the node:","uniconfig-config:store-without-mount- When enabled, skip the mount procedure and store node metadata into the UniConfig database with installation status FAILED. The default value is false.","This flag is primarily intended for scenarios where you want UniConfig to be aware of a specific node that is not yet up and reachable. Once the device is up, you can simply call the sync-from-network RPC to load the configuration. Additionally, this can reduce the lifetime of the install-node RPC, as it does not need to wait for connection failure."]},{"l":"Keepalive strategies","p":["1. Keepalive reconnection strategy","cli-topology:keepalive-delay- Delay between sending of keepalive messages over CLI session. The value should not be set higher than the execution of the longest operation. Default value: 60 seconds.","cli-topology:keepalive-timeout- This parameter defines how much time the CLI layer should wait for a response to keepalive message before the session is closed. Default value: 60 seconds.","cli-topology:keepalive-initial-delay- This parameter defines how much time CLI layer waits for establishment of new CLI session before the first reconnection attempt is launched. Default value: 120 seconds.","The keepalive parameters have two main functions:","keep the idle session open","timeout commands which would block the session forever"]},{"l":"Example of using the connection and keepalive parameters together","p":["For this example let us assume that we are dealing with a prod-like device, which would mean that some devices might have a large config. We would set these parameters:","Connection attempts would give us more flexibility if we work with unstable devices. It would try to ssh 3 times instead of 1 (default value). We should also keep in mind that the process of connecting to a device would take longer because of extra ssh attempts.","Keepalive commands can be set less than time of the installation, because keepalive commands can fit in between of the installation process. An important thing to keep in mind is to set sum of keepalive-delay and keepalive-timeout parameters higher than time of execution of the configuration show command. Otherwise, it could time out during writing out of the configuration to the console. For each type of device it is a different command ( configuration show brief for Ciena devices, show run for Cisco devices, etc.). Assumption is that it should not take more than 240 seconds (sum of keepalive params) to show the whole configuration. This can be appropriately adjusted to our circumstances.","2. Lazy reconnection strategy","command-timeout- Maximal time (in seconds) for command execution. If a command cannot be executed on a device in this time, the execution is considered a failure. Default value: 60 seconds.","connection-establish-timeout- Maximal time (in seconds) for connection establishment. If a connection attempt fails in this time, the attempt is considered a failure. Default value: 60 seconds.","connection-lazy-timeout- Maximal time (in seconds) for connection to keep alive. If no activity was detected in the session and the timeout has been reached, connection will be stopped. Default value: 60 seconds."]},{"l":"Journaling parameters","p":["The following parameters relate with tracing of executed commands. It is not required to set these parameters.","cli-topology:journal-size- Size of the cli mount-point journal. Journal keeps track of executed commands and makes them available for users/apps for debugging purposes. Value 0 disables journaling(it is default value).","cli-topology:dry-run-journal-size- Creates dry-run mount-point and defines number of commands in command history for dry-run mount-point. Value 0 disables dry-run functionality (it is default value).","cli-topology:journal-level- Sets how much information should be stored in the journal. Option 'command-only' stores only the actual commands executed on device. Option 'extended' records additional information such as: transaction life-cycle, which handlers were invoked etc."]},{"l":"Parsing parameters","p":["Parsing strategies are used for:","Recognizing of structure in cached device configuration that is represented in textual format.","Extraction of target sections from structured format of device configuration.","Parsing engine can be configured on creation of mountpoint by specification of parsing-engine leaf value. Currently, there are three supported CLI parsing strategies: tree-parser(default strategy), batch-parser and one-line-parser.","Both batch-parser and tree-parser depend on current implementation of'CliFlavour' which defines device-specific CLI patterns. For example, if 'CliFlavour' doesn't correctly specify format of 'show configuration' command, then neither batch-parser or tree-parser is applied and commands are sent directly to device."]},{"l":"Tree-parser","p":["It is set as default parsing engine in case you choose to not use'parsing-engine' parameter.","Running-configuration is mapped into the tree structure before the first command lookup is executed from translation unit. Afterwards, this tree can be reused in the same transaction for faster lookup process (for example, one 'sync-from-network' task is executed in one transaction).","Tree-parser is faster than batch-parser in most cases because device configuration must be traversed only once and searching for target section in parsed tree structure has only logarithmic time complexity. The longer the device configuration is, the better performance improvement is achieved using this parsing strategy.","Both batch-parser and tree-parser should be capable to parse the same device configurations (in other words, tree-parser doesn't have any functional restrictions in comparison to batch-parser)."]},{"l":"Batch-parser","p":["Running-configuration must be traversed from the beginning each time when new target section is extracted from the configuration (such lookup process is launched from CLI translation units).","Internally, this parser uses regular expressions to recognize structure of configuration and find target section. From this reason, if configuration is long, this batch-parser becomes ineffective to extract sections that are placed near the end of device configuration.","Batch-parser should be used only as fallback strategy in the case when tree-parser fails."]},{"l":"One-line-parser","p":["CLI parsing engine that stores configuration in the cache in the form of blocks and then uses grep function for parsing running-configuration"]},{"l":"Cisco IOX XR Example request"},{"l":"Junos Example request"},{"l":"Uninstalling CLI device","p":["Uninstall node RPC"]},{"l":"Example request"},{"l":"Installing Netconf device"},{"l":"Identification of remote device","p":["List of basic connection parameters that are used for identification of remote device. Only tcp-only parameter must not be specified in input of the request.","node-id- Name of node that represents device / mount-point in the topology.","netconf-node-topology:host- IP address or domain-name of target device that runs NETCONF server.","netconf-node-topology:port- TCP port on which NETCONF server is listening to incoming connections.","netconf-node-topology:tcp-only- If it is set to 'true', NETCONF session is created directly on top of TCP connection. Otherwise,'SSH' is used as carriage protocol. By default, this parameter is set to 'false'."]},{"i":"authentication-parameters-1","l":"Authentication parameters","p":["Parameters used for configuration of the basic authentication method against NETCONF server. These parameters must be specified in the input request.","network-topology:username- Name of the user that has permission to access device using NETCONF management line.","network-topology:password- Password to the user in non-encrypted format.","There are also other authentication parameters if different authentication method is used - for example, key-based authentication requires specification of key-id. All available authentication parameters can be found in netconf-node-topology.yang under netconf-node-credentials grouping."]},{"l":"Session timers","p":["The following parameters adjust timers that are related with maintaining of NETCONF session state. None of these parameters are mandatory(default values will be used).","netconf-node-topology:initial-connection-timeout- Specifies timeout in seconds after which initial connection to the NETCONF server must be established (default value: 20 s).","netconf-node-topology:request-transaction-timeout- Timeout for blocking RPC operations within transactions (default value: 60 s).","netconf-node-topology:max-connection-attempts- Maximum number of connection attempts (default value: 1, non-positive value or null is interpreted as infinity).","netconf-node-topology:max-reconnection-attempts- Maximum number of reconnection attempts. It is used when ongoing session dropped (default value: 0, non-positive value or null is interpreted as infinity).","netconf-node-topology:between-attempts-timeout- Initial timeout between reconnection attempts (default value: 2 s).","netconf-node-topology:reconnenction-attempts-multiplier- Multiplier between subsequent delays of reconnection attempts (default value: 1.5).","netconf-node-topology:keepalive-delay- Delay between sending of keepalive RPC messages (default value: 120 sec).","netconf-node-topology:confirm-commit-timeout- The timeout for confirming the configuration by \"confirming-commit\" that was configured by \"confirmed-commit\". Configuration will be automatically reverted by device if the \"confirming-commit\" is not issued within the timeout period. This parameter has effect only on NETCONF nodes. (default value: 600 sec)."]},{"l":"Capabilities","p":["Parameters related to capabilities are often used when NETCONF device doesn't provide list of YANGs. Both parameters are optional.","netconf-node-topology:yang-module-capabilities- Set a list of capabilities to override capabilities provided in device's hello message. It can be used for devices that do not report any yang modules in their hello message.","netconf-node-topology:non-module-capabilities- Set a list of non-module based capabilities to override or merge non-module capabilities provided in device's hello message. It can be used for devices that do not report or incorrectly report non-module-based capabilities in their hello message.","Instead of defining netconf-node-topology:yang-module-capabilities, we can just define folder with yang schemas netconf-node-topology:schema-cache-directory: folder-name. For more information about using the netconf-node-topology:schema-cache-directory parameter, see RST Other parameters."]},{"l":"UniConfig-native","p":["Parameters related to installation of NETCONF or CLI nodes with uniconfig-native support.","uniconfig-config:uniconfig-native-enabled- Whether uniconfig-native should be used for installation of NETCONF or CLI node. By default, this flag is set to 'false'.","uniconfig-config:install-uniconfig-node-enabled- Whether node should be installed to UniConfig and unified layers. By default, this flag is set to 'true'.","uniconfig-config:sequence-read-active- Force sequential data reading when mounting a device. If set to 'true', sync-from-network is done in parallel. The default value is 'false'.","uniconfig-config:whitelist- List of root YANG entities that should be read.","uniconfig-config:blacklist- List of root YANG entities that should not be read from NETCONF device due to incompatibility with uniconfig-native or other malfunctions in YANG schemas. This parameter has effect only on NETCONF nodes.","uniconfig-config:validation-enabled- Whether validation RPC should be used before submitting configuration of node. By default, this flag is set to 'true'. This parameter has effect only on NETCONF nodes.","uniconfig-config:confirmed-commit-enabled- Whether confirmed-commit RPC should be used before submitting configuration of node. By default, this flag is set to 'true'. This parameter has effect only on NETCONF nodes.","uniconfig-config:store-failed-installation- Whether the installation should be stored in the database if it fails (e.g. is unreachable). The node will be 'installed' even though it failed and the user has 2 options:","uninstall the device and reinstall it.","call sync-from-network to sync the data from the device."]},{"l":"Flags","p":["Non-mandatory flag parameters that can be added to mount-request.","netconf-node-topology:enabled-strict-parsing- Default value of enabled-strict-parsing parameter is set to 'true'. This may inflicts in throwing exception during parsing of received NETCONF messages in case of unknown elements. If this parameter is set to 'false', then parser should ignore unknown elements and not throw exception during parsing.","netconf-node-topology:enabled-notifications- Default value of enabled-notifications is set to 'true'. If it is set to 'true' and NETCONF device supports notifications, NETCONF mountpoint will expose NETCONF notification and subscription services.","netconf-node-topology:reconnect-on-changed-schema- Default value of reconnect-on-changed-schema is set to 'false'. If it is set to 'true', NETCONF notifications are supported by device, and NETCONF notifications are enabled ('enabled-notifications' flag), the connector would auto disconnect/reconnect when schemas are changed in the remote device. The connector subscribes (right after connect) to base netconf notifications and listens for netconf-capability-change notification","netconf-node-topology:streaming-session- Default value of streaming-session parameter is set to 'false'. NETCONF session is created and optimized for receiving of NETCONF notifications from remote server."]},{"l":"Other parameters","p":["Other non-mandatory parameters that can be added to mount-request.","netconf-node-topology:schema-cache-directory- This parameter can be used for two cases:","Explicitly set name of NETCONF cache directory. If it is not set, the name of the schema cache directory is derived from device capabilities during mounting process.","Direct usage of the 'custom' NETCONF cache directory stored in the UniConfig 'cache' directory by name. This 'custom' directory must exist, must not be empty and also can not use the 'netconf-node-topology:yang-module-capabilities' parameter, because capability names will be generated from yang schemas stored in the 'custom' directory.","netconf-node-topology:dry-run-journal-size- Creates dry-run mount-point and defines number of NETCONF RPCs in history for dry-run mount-point. Value 0 disables dry-run functionality (it is default value).","netconf-node-topology:custom-connector-factory- Specification of the custom NETCONF connector factory. For example, if device doesn't support candidate data-store, this parameter should be set to 'netconf-customization-alu-ignore-candidate' string (default value is \"default\").","netconf-node-topology:edit-config-test-option- Specification of the test-option parameter in the netconf edit-config message. Possible values are 'set', 'test-then-set' or 'test-only'. If the edit-config-test-option is not explicitly specified in the mount request, then the default value will be used ('test-then-set'). See RFC-6241 for more information about this feature.","netconf-node-topology:concurrent-rpc-limit- Defines maximum number of concurrent RPCs, where 0 indicates no limit (it is default value).","There are additional install parameters in our OpenAPI, they can all be found here."]},{"l":"Example netconf request"},{"l":"Uninstalling Netconf device"},{"i":"example-request-1","l":"Example request"},{"l":"Installing gNMI device"},{"l":"Identifying remote device","p":["Basic connection parameters used to identify a remote device:","node-id- Name of the node that represents the device/mountpoint in the topology.","gnmi-topology:host- IP address or domain name of the target device running the gNMI server.","gnmi-topology:port- TCP port where the gNMI server is listening to incoming connections.","gnmi-topology:device-type- Specific device type, which enables some device-specific behavior. By default, this parameter is not specified.","gnmi-topology:connection-type- If specified, an insecure connection is created. The insecure connection is available only for DEBUG reasons. To establish a gRPC connection without TLS, choose the insecure connection type PLAINTEXT. The connection type PLAINTEXT indicates that the target should skip the signature verification steps if a secure connection is used.","gnmi-topology:keystore-id- If specified, a secure connection is created. Also requires keystore-id(identifier of the keystore), which is defined in the gnmi-certificate-storage model.","Only one of the parameters keystore-id and connection-type can be specified."]},{"i":"authentication-parameters-2","l":"Authentication parameters","p":["Parameters to configure the basic authentication method against a gNMI server. These parameters must be specified in the input request inside the gnmi-topology:credentials container:","gnmi-topology:username- Username with permission to access the device using gNMI.","gnmi-topology:password- Password for username."]},{"i":"session-timers-1","l":"Session timers","p":["The following parameters adjust timers related to maintaining gNMI session state. None of these parameters are mandatory (default values are used if not specified):","gnmi-topology:request-timeout- Timeout (in seconds) for each gNMI request. The request times out if not completed in time. The default value is 30."]},{"i":"flags-1","l":"Flags","p":["Non-mandatory flag parameters that can be added to a mount request:","gnmi-topology:enabled-notifications- If set to true and the gNMI device supports notifications, the gNMI mountpoint will expose GNMI notification and subscription services. The default value is true."]},{"i":"other-parameters-1","l":"Other parameters","p":["Other non-mandatory parameters that can be added to a mount request:","gnmi-topology:dry-run-journal-size- Size of the dry-run gNMI mountpoint journal. The dry-run journal captures gNMI operations that would be executed when reading/writing a configuration. However, the operations are not actually sent to the device. The default value is 0."]},{"l":"Extension parameters","p":["Other extended non-mandatory parameters that can be added to a mount-request inside of the extensions-parameters container."]},{"l":"gNMI parameters","p":["gnmi-topology:use-model-name-prefix- Some devices require a module prefix in the first element name of the gNMI request path (for example, interfaces -> openconfig-interfaces:interfaces). The default value is false."]},{"i":"uniconfig-native-1","l":"UniConfig-native","p":["Parameters related to installing gNMI nodes with uniconfig-native support:","uniconfig-config:uniconfig-native-enabled- Whether or not uniconfig-native should be used for installing of NETCONF, CLI or gNMI nodes. The default value is false.","uniconfig-config:sequence-read-active- Forces reading of data sequentially when mounting a device. If set to true, sync-from-network is done in parallel. The default value is false.","uniconfig-config:whitelist- List of root YANG entities that should be read.","uniconfig-config:store-failed-installation- Whether or not the installation is stored in the database if it fails (e.g., unreachable). The node is \"installed\" even though it fails, and the user has two options:","Uninstall the device and reinstall it.","Call sync-from-network to sync the data from the device.","An important install parameter is gnmi-topology:schema-cache-directory: folder-name. It specifies a folder name in the cache directory with the YANG schemas needed to install a device. If this parameter is not specified, user can create default-capability.json file inside of mentioned cache directory and UniConfig will dynamically resolve correct cache directory for given node. This json file must have all capabilities that device supports. Format of default-capability.json:"]},{"l":"Update paths","p":["This is a non-mandatory parameter that specifies a list of paths for which UniConfig will process intended changes as a gNMI SET message - Update operation. Paths are specified in regexp format.","More information about update paths feature: https://docs.frinx.io/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/#update-paths."]},{"l":"Replace paths","p":["This is a non-mandatory parameter that specifies a list of paths for which UniConfig will process intended changes as a gNMI SET message - Replace operation.","A specific replace diff implementation in UniConfig checks and merges all changes according to the specified replace-paths, and ensures that the gNMI SET message has the same path as the one specified in replace-paths in the install request.","Paths are specified in common RESTful URL format, but list entries can be compiled as a regexp pattern if specified with the $ sign after the = sign.","More information about the replace paths feature: https://docs.frinx.io/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/#replace-paths."]},{"l":"Remove module name paths","p":["This is a non-mandatory parameter that specifies a list of paths for which UniConfig removes the module name of specified list entry keys. (For example, protocol=openconfig-policy-types:BGP,bgp, remove-module-name-path = network-instances/network-instance=$.*/protocols/protocol).","The path format is the same as for replace-paths."]},{"l":"All type paths","p":["This is a non-mandatory parameter that specifies a list of paths for which UniConfig provides a GET request with the ALL data type.","The path format is the same as for replace-paths.","This feature only applies to the SONiC device type."]},{"l":"Dependency paths","p":["This is a non-mandatory parameter that specifies list of paths for which UniConfig will check and order the intended changes.","The format of dependency paths:","before- path without keys that is ordered before the path specified in after.","after- path without keys that is ordered after the path specified in before.","More information about dependency paths: https://docs.frinx.io/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/#dependency-paths."]},{"i":"example-request-2","l":"Example request"},{"l":"Uninstalling gNMI device"},{"i":"example-request-3","l":"Example request"},{"l":"Installing SNMP agent"},{"l":"Identification of remote agent","p":["List of basic connection parameters that are used for identification of remote agent.","node-id- Name of node that represents device / mount-point in the topology.","snmp-topology:host- IP address or domain-name of target device where SNMP agent is running.","snmp-topology:port- SNMP port on which SNMP agent is listening to incoming connections."]},{"l":"SNMP parameters","p":["snmp-topology:transport-type- UniConfig currently supports UDP for SNMP communication, with plans to add TCP support in the future.","snmp-topology:snmp-version- UniConfig currently supports V1 and V2c version of the SNMP, with plans to add V3 support in the future.","snmp-topology:connection-retries- Sets the number of retries to be performed before a request is timed out. Default value is 0.","snmp-topology:request-timeout- Timeout in milliseconds before a confirmed request is resent or timed out. Default value is 3000.","snmp-topology:get-bulk-size- The maximum number of values that can be returned in a single response to the get-bulk operation. Default value is 50."]},{"i":"authentication-parameters-3","l":"Authentication parameters","p":["snmp-topology:community-string- UniConfig currently supports only security string as authentication method that is used with V1 and V2c."]},{"l":"Others","p":["snmp-topology:mib-repository- Name of the MIB repository that contains MIB files."]},{"i":"example-request-4","l":"Example request"},{"l":"Uninstalling SNMP agent"},{"i":"example-request-5","l":"Example request"}],[{"l":"UniConfig CLI"},{"l":"Introduction","p":["The CLI southbound plugin enables the Frinx UniConfig to communicate with CLI devices that do not speak NETCONF or any other programmatic API. The CLI service module uses YANG models and implements a translation logic to send and receive structured data to and from CLI devices. This allows applications to use a service model or unified device model to communicate with a broad range of network platforms and SW revisions from different vendors.","Much like the NETCONF southbound plugin, the CLI southbound plugin enables fully model-driven, transactional device management for internal and external OpenDaylight applications. In fact, the applications are completely unaware of underlying transport and can manage devices over the CLI plugin in the same exact way as over NETCONF.","Once we have installed the device, we can present an abstract, model-based network device and service interface to applications and users. For example, we can parse the output of an IOS command and return structured data.","CLI southbound plugin"]},{"l":"Architecture","p":["This section provides an architectural overview of the plugin, focusing on the main components."]},{"l":"CLI topology","p":["The CLI topology is a dedicated topology instance where users and applications can:","install a CLI device,","uninstall a device,","check the state of connection,","read/write data from/to a device,","execute RPCs on a device.","This topology can be seen as an equivalent of topology-netconf, providing the same features for netconf devices. The topology APIs are YANG APIs based on the ietf-topology model. Similarly to netconf topology, CLI topology augments the model with some basic configuration data and also some state to monitor mountpoints."]},{"l":"CLI mountpoint","p":["The plugin relies on MD-SAL and its concept of mountpoints to expose management of a CLI device. By exposing a mountpoint into MD-SAL, it enables the CLI topology to actually access the device's data in a structured/YANG manner. Components of such a mountpoint can be divided into 3 distinct layers:","Service layer - implementation of MD-SAL APIs delegating execution to transport layer.","Translation layer - a generic and extensible translation layer. The actual translation between YANG and CLI takes place in the extensions. The resulting CLI commands are then delegated to transport layer.","Transport layer - implementation of various transport protocols used for actual communication with network devices.","The following diagram shows the layers of a CLI mountpoint:"]},{"l":"Translation layer","p":["The CLI southbound plugin is as generic as possible. However, the device-specific translation code (from YANG data -\\ CLI commands and vice versa), needs to be encapsulated in a device-specific translation plugin. E.g. Cisco IOS specific translation code needs to be implemented by Cisco IOS translation plugin before FRINX UniConfig can manage IOS devices. These translation plugins in conjunction with the generic translation layer allow for a CLI mountpoint to be created."]},{"l":"Device specific translation plugin","p":["Device specific translation plugin is a set of:","YANG models","Data handlers","RPC implementations","that actually","defines the model/structure of the data in FRINX UniConfig","implements the translation between YANG data and device CLI in a set of handlers","(optionally) implements the translation between YANG RPCs and device CLI","The plugin itself is responsible for defining the mapping between YANG and CLI. However, the translation layer into which it plugs in is what handles the heavy lifting for it e.g. transactions, rollback, config data storage etc. Additionally, the SPIs of the translation layer are very simple to implement because the translation plugin only needs to focus on the translations between YANG <-\\ CLI."]},{"l":"Units","p":["In order to enable better extensibility of the translation plugin and also to allow the separation of various aspects of a device's configuration, a plugin can be split into multiple units. Where a unit is actually just a subset of a plugin's models, handlers and RPCs.","A single unit will usually cover a particular aspect of device management e.g. the interface management unit.","Units can be completely independent or they can build on each other, but in the end (in the moment where a device is being installed) they form a single translation plugin.","Each unit has to be registered under a specific device type(s) e.g. an interface management unit could be registered for various versions of the IOS device type. When installing an IOS device, the CLI southbound plugin collects all the units registered for the IOS device type and merges them into a single plugin enabling full management.","The following diagram shows an IOS device translation plugin split into multiple units:","IOS translation plugin"]},{"l":"Transport layer","p":["For now, two transport protocols are supported:","SSH","Telnet","They implement the same APIs, which enables the translation layer of the CLI plugin to be completely independent of the underlying protocol in use. Deciding which transport will be used to manage a particular device is simply a matter of install-request configuration.","The transport layer can be specified using install-request'cli-topology:transport-type' parameter."]},{"l":"Data processing","p":["There are 2 types of data depending on data-store in which data is stored:","Config","Operational","This section details how these data types map to CLI commands.","Just as there are 2 types of data, there are 2 streams of data in the CLI southbound plugin:","It represents user/application intended configuration for the device.","Translation plugins/units need to handle this configuration in data handlers as C(reate), U(pdate) and D(elete) operations. R(ead) pulls this config data from the device and updates the cache on its way back.","Config data","It represents actual configuration on the device, optionally statistics from the device.","Translation plugins/units need to pull these data out of the device when R(ead) operation is requested.","Operational data","RPCs stand on their own and can encapsulate any command(s) on the device."]},{"l":"RPCs provided by CLI layer","p":["There are multiple RPCs that can be used to send commands to a CLI session and optionally wait for command output. The CLI layer also provides one additional RPC for computing configuration coverage by cli-units. To use all of these RPCs, it is required to have an installed CLI device in the 'Connected' state."]},{"i":"rpc-execute-and-read","l":"RPC: Execute-and-read"},{"l":"Description","p":["Execution of the sequence of commands specified in the input. These commands must be separated by the new line - then, each of the command is executed separately.","After all commands are executed, it is assumed, that the original command prompt (prompt that was set before execution of this RPC) appears on the remote terminal.","If the input contains only single command, output of this RPC will contain only output of this command. If input contains multiple commands separated by newline, output of this RPC will be built from command prompts (except the prompt of the first command), input commands and outputs returned from remote terminal."]},{"l":"Example","p":["Following RPC demonstrates listing of all interfaces with configured IP addresses plus listing of available routing protocols that can be enabled from global configuration mode. Since the last entered command is placed in configuration mode (for example, starting with'Router(config)#'), it is required to return back to Privileged EXEC mode (for example, starting with 'Router#') using 'end' command and'no' confirmation to not save changes. Also, 'wait-for-output-timer' is configured to 2 seconds - CLI layer waits for command output returned from device up to 2 seconds.","Remember that the last command prompt must equal to original prompt otherwise CLI session fails on timeout and CLI mountpoint must be recreated.","RPC reply with unescaped output string (output can be easily unescaped with 'printf' linux application):","Description of RPC-request input body fields:","command(mandatory) - The list of commands that are sent to device. Commands must be separated by newline character. Every command-line is executed separately.","wait-for-output-timer(optional) - By default (if this parameter is not set or set to 0), outputs from entered commands are collected after caught echo of the next typed command in CLI session (or command prompt, if the command is the last one from input sequence). Then, the collected output contains output of the previous command + echo of the current command that hasn't been executed by sending newline character yet. This process is simplified by setting'wait-for-output-timer' value. In this case,'waiting-for-command-echo' procedure is not applied, rather next command is executed only after specified number of seconds after which the reply from CLI session should already be available (if it won't be available, then command output will be read after execution of the next command - outputs can be messed up).","error-check(optional) - By default, UC does not check for errors in commands. If error-handling is enabled and an error occurs, RPC will fail."]},{"l":"Wait-for-echo behaviour","p":["The comparison between described wait-for-echo approaches can be demonstrated in the steps of processing 2 command-lines:","'wait-for-output-timer' is not set or it set to value 0","write command 1","wait for command 1 echo","hit enter","write command 2","wait for command 2 echo","read until command prompt appears","'wait-for-output-timer' is specified in request","read output until timeout expires","Even if the 'wait-for-output-timer' is configured, the last output must equal to original command-prompt."]},{"i":"rpc-execute-and-expect","l":"RPC: Execute-and-expect"},{"i":"description-1","l":"Description","p":["It is a form of the 'execute-and-read' RPC that additionally may contain 'expect(..)' patterns used for waiting for specific outputs/prompts. It can be used for execution of interactive commands that require multiple subsequent inputs with different preceding prompts.","The body of 'expect(..)' pattern must be specified by Java-based regular expression typed between the brackets (see https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html","documentation about regular expressions used in Java language).","'expect(..)' pattern can only be used for testing of previous command line output including next command prompt. From this reason, it is also a suitable tool for testing of specific command prompts.","'expect(..)' pattern must be specified on the distinct line. If multiple 'expect(..)' patterns are chained on neighboring lines, then all of them must match previous output (patterns are joined using logical AND operation).","Output of this RPC reflects the whole dialogue between Frinx UniConfig client and remote terminal except the initial command-prompt.","'wait-for-output-timer' parameter can also be specified in this RPC","but in this case, it applies only for non-interactive commands - commands that are not followed by 'expect(..)' pattern. It is possible to mix interactive and non-interactive commands in input command snippet.","If 'expect' pattern doesn't match previous output, Execute-and-expect RPC will fail on timeout (fixed 3 seconds) for reading next input and CLI session will drop immediately."]},{"i":"example-1","l":"Example","p":["The following RPC requests shows execution of interactive command for copying of file from TFTP server. The CLI prompt subsequently ask for source filename and destination filename. These prompts are asserted by'expect(..) pattern. The last 'expect(..) pattern just waits for confirmation about number of copied bytes.","RPC reply with unescaped output string (output can be easily unescaped with 'printf' linux application):","Backslash is a special character that must be escaped in JSON body. From this reason, in the previous example, there are two backslashes proceeding regular-expression constructs.","If 'execute-and-expect' command field doesn't contain any 'expect(..)' patterns, it will be evaluated in the same way like 'execute-and-read' RPC."]},{"i":"rpc-execute-and-read-until","l":"RPC: Execute-and-read-until"},{"i":"description-2","l":"Description","p":["It is form of the 'execute-and-read' RPC that allows to explicitly specify 'last-output' that CLI expect at the end of commands executions (after the last command has been sent to device).","If explicitly specified 'last' output is not found at the end of the output, again, the session will be dropped and recreated similarly to behaviour of 'execute-and-read' RPC."]},{"i":"example-2","l":"Example","p":["The following request shows sending of the configuration snippet for disabling of automatic network summary (RIP routing protocol). After executing of these commands, command prompt is switched to'RP/0/0/CPU0:XR5(config-rip)#' - it is not the same like initial command prompt 'RP/0/0/CPU0:XR5#'. From this reason it is required to return back to initial command prompt by sending of additional commands or specification of 'last-output' as it is demonstrated in this example.","RPC reply with unescaped output string (output can be easily unescaped with 'printf' linux application):","Set 'last-output' is saved within current CLI session - if you send next 'execute-and-read' RPC, it is assumed that the initial and last output is newly configured 'last-output'."]},{"i":"rpc-execute","l":"RPC: Execute"},{"i":"description-3","l":"Description","p":["Simple execution of single or multiple commands on remote terminal. Multiple commands must be separated by newline in the input. The outputs from commands are not collected - output of this RPC contains only status message.","This RPC can be used in cases where it is not necessary to obtain outputs of entered commands.","After all commands are executed, the last output is not checked against expected output."]},{"i":"example-3","l":"Example","p":["The following example demonstrates 'execute' RPC on creation of simple static route and committing of made change.","RPC reply - output contains just status message:"]},{"i":"rpc-config-coverage","l":"RPC: config-coverage"},{"i":"description-4","l":"Description","p":["RPC reads the entire device configuration, determines the coverage of the configuration by translation units and returns simple or complex output. The user can define a preferred output in RPC input. The default is simple output.","Simple output contains one string that consists of all lines of the device configuration. Each line starts with '+' if it is covered or'-' if not and ends with a '\\n' marker.","Complex output contains a list of commands. Each entry in the list includes the following fields:","'covered', which indicates whether the entire command is covered or not. Can be either 'true' or 'false'.","'non-parsable-parts', which is visible only if the entire command is not covered. Contains a list of those command parts that are not covered. If no parts of the command are covered, only contains the word 'ALL'.","'command', which includes the entire command."]},{"l":"Simple output example","p":["RPC reply:"]},{"l":"Complex output example","p":["RPC reply:"]}],[{"l":"UniConfig gNMI"},{"l":"Introduction","p":["The gNMI (gRPC Network Management Interface) southbound plugin allows UniConfig to communicate with devices via gNMI. It provides a mechanism to install, manipulate and delete the configuration of a network device, and to view operational data.","The plugin follows a fully model-driven approach similar to the CLI and NETCONF southbound plugins. The main difference is that it uses the protocol buffer (proto3) instead of YANG for service structure modeling within its RPCs, like the gRPC protocol does. Note that the YANG schemas are still necessary for config data modelling on the UniConfig side."]},{"l":"gNMI southbound plugin","p":["The gNMI southbound plugin is capable of connecting to remote gNMI devices and exposing their datastores (CONFIG, STATE) as MD-SAL mount points. These mountpoints allow applications and remote users (over RESTCONF) to interact with the mounted devices.","A new gNMI session is created by mounting a gNMI device. The session is responsible for establishing a connection via gRPC ManagedChannel. Once a connection is established, the gNMI southbound plugin reads device capabilities using the Capabilities RPC. A new schema context is built from the capabilities (once the schema context is built, it is cached for the next runs) and all necessary services are created (DOMDataBroker, DOMRpcService, DOMNotification/Subscription service).","When all this is done, the gNMI southbound plugin marks the connection status of the particular device as READY so that the UniConfig layer can handle it."]},{"l":"Important features","p":["When a gNMI device is installed, it is possible to:","Read (gNMI GET) and create/update/delete (gNMI SET) the configuration of the device via the following:","UniConfig topology","gNMI souhtbound topology (using yang-ext:mount)","yang-patch operations over UniConfig/gNMI souhtbound topology (using yang-ext:mount)","Manipulate a device via gNOI RPCs","Use the gNMI SET update operation for specific paths","Use the gNMI SET replace operation for specific paths","Order config changes (replace/delete operations) according to dependency paths","Remove module-name from list keys for specific paths","Read from ALL datastore for specific paths","Subscribe to telemetry streaming for specific paths (gNMI Subscribe)","Store failed installations","Enable the logging-broker for gNMI messages (SET/GET)","Use the DryRunCommit feature"]},{"l":"gNOI","p":["The gNOI (gRPC Network Operations Interface) defines gRPC-based microservices for executing operational commands on network devices. By default, the gNMI southbound plugin is capable of executing Certification, File, System and OS RPCs according to protobuf files ( https://github.com/openconfig/gnoi).","Apart from common ones, it is also possible to invoke SONiC-type gNOI RPCs by specifying gnmi-topology:device-type : sonic inside the connection-parameters container in the install request. It is necessary to have the gnoi-sonic@2023-03-17.yang schema model in the cache directory for this specific node to invoke it via RESTCONF.","Example- gNOI RPC invocation"]},{"l":"Update paths","p":["The update paths feature tells the gNMI southbound plugin to process the intended config changes (calculated from UniConfig diff) as a gNMI SET message - Update operation.","The plugin essentially checks if config change paths are relative to any of the update paths listed in the installation request. (For example, if you have a config change at a/b/c/d that is relative to the update-path a/b/c).","The main purpose of this feature is to send a gNMI SET message with the correct operation mode that the device supports for the specific subtree. Paths are in regexp format."]},{"l":"Replace paths","p":["The replace paths feature is a little different from update paths. With replace paths, the UniConfig topology first calculates changes using own diff implementation and, if a path is specified in the replace-paths list in the install request, adjusts the calculated diffs and groups them accordingly.","If there is a config change at a/b/c/d and a/b/c/e, and the replace path is specified as a/b/c, the diff calculation adjustment marks the two changes as one on the path a/b/c. In this structure it is passed to the gNMI southbound topology, where it is processed as a gNMI SET message - Replace operation.","If a config is deleted using the DELETE REST operation on a path that is relative to some of the replace paths, it is processed as a gNMI SET message - Delete operation. Essentially, it is skipped by the replace paths feature.","This feature can also be used only in the gNMI southbound plugin, for example, if we send a config change via yang-patch operation over the gNMI topology (so it goes outside of the UniConfig diff). In this scenario, it only checks if the config change path is relative to one of the replace-paths.","The main purpose of the replace paths feature is to send gNMI SET messages with the correct operation mode that the device supports for a specific subtree.","The paths are in common RESTful URL format, but a list entry can be compiled as a regexp pattern if specified with $ sign after the = sign. The list entry key is then specified like this: interface=$.*[Ee]thernet?[0-9]+."]},{"l":"Dependency paths","p":["The dependency paths feature helps network devices to order committed config changes if the device cannot handle this. For example, deleting an interface from the network-instance first and then deleting it from the interfaces container. This is done in the gNMI southbound topology, and it orders changes marked for the Replace/Delete operation. Config changes are sorted from their paths according to rules specified in the dependency paths.","The rule format for dependency paths:","before- path without keys that is ordered before the path specified in after.","after- path without keys that is ordered after the path specified in before."]},{"l":"gNMI logging-broker","p":["For more information about the gNMI logging-broker, see Supported logging settings."]},{"l":"Telemetry streaming","p":["Creating a subscription","If a time range is specified, it is part of the Subscribe request. If the device does not support time ranges on its server side, the gNMI southbound plugin can handle them. Note that if the timestamp of the received message is outside of the specified time range, the message is not saved to the database or published to the Kafka topic.","If the specified path is marked as disabled for the ON_CHANGE mode in YANG schemas, the gNMI southbound plugin fails with a log message stating that the path is marked as disabled for the subscription.","notifications.enabled=true","notifications.kafka.embedded-kafka.enabled=true(or its own Kafka, in which case kafka-servers needs to be adjusted)","notifications.kafka.gnmi-notifications-enabled=true","notifications.kafka.gnmi-notifications-topic-name=gnmi-notifications","Receiving notifications","Saving notifications to a database or publishing them to Kafka topic","Subscriptions are created in the gNMI southbound plugin using the Subscribe RPC from the gNMI service defined in the proto3 file. The gNMI southbound plugin can subscribe to wildcarded paths as well as multiple paths at once. It supports only the STREAM subscription mode with SAMPLE, ON_CHANGE and TARGET_DEFINED stream mode.","Subscriptions are created independently from node installation. The result of the install-node RPC relates only to node installation, and that RPC will only invoke the telemetry stream subscription process.","Telemetry streaming in UniConfig is divided into three parts:","The install request must specify the parameters necessary to create a subscription for a specific device. Mandatory fields are stream-name(a marker for the particular subscription) and paths(a list of paths to which the gNMI souhtbound plugin will be subscribed, with at least one path). Non-mandatory fields specify a time range of the subscription or subscription mode. Both start-time and stop-time are in RFC3339 format. Subscription mode can be SAMPLE, ON_CHANGE or TARGET_DEFINED","The session is open until it is closed either on the UniConfig side (releasing the subscription) or the device side (error). The result of telemetry streaming can be seen in the specified Kafka topic or in the notification database table.","To create subscriptions, the following are required in application.properties:","UniConfig with gNMI southbound plugin supports gNMI telemetry streaming - receiving the state of data on a target."]},{"l":"DryRun commit","p":["For more information about dryrun commit, see Dry-run manager.","It also supports the gNMI southbound topology, which is accessible only if the parameter gnmi-topology:dry-run-journal-size is set to be higher than 0."]},{"l":"gNMI testtool","p":["The gNMI testtool is a GO language server-side simulator capable of configuring OpenConfig YANG schemas via gNMI. It currently supports openconfig-interfaces, openconfig-system, openconfig-openflow, controlling operations over gNOI and telemetry streaming.","The tool is used for scale-testing purposes to simulate the interactions of thousands of devices with UniConfig.","Examples:","UniConfig gNMI"]}],[{"l":"IosXR 7 device"},{"l":"Install device","p":["A IosXR7 device can be installed through gNMI with the following request:"]},{"l":"Uninstall device","p":["To uninstall a device:"]}],[{"l":"NOKIA device"},{"l":"Install device","p":["A Nokia device can be installed through gNMI with the following request:"]},{"l":"Uninstall device","p":["To uninstall a device:"]}],[{"l":"SONiC device"},{"l":"Install device","p":["SONiC devices can be installed through gNMI with the following request:"]},{"l":"Uninstall device","p":["To uninstall a device:"]}],[{"l":"UniConfig NETCONF"},{"l":"Overview","p":["NETCONF is an Internet Engineering Task Force (IETF) protocol used for configuration and monitoring of devices in a network. It can be used to“create, recover, update, and delete configurations of network devices”. The base NETCONF protocol is described in RFC-6241.","NETCONF operations are overlaid on the Remote Procedure Call (RPC) layer and may be described in either XML or JSON."]},{"l":"NETCONF southbound plugin"},{"l":"Introduction to southbound plugin and netconf-connectors","p":["The NETCONF southbound plugin is capable of connecting to remote NETCONF devices and exposing their configuration/operational datastores, RPCs and notifications as MD-SAL mount points. These mount points allow applications and remote users (over RESTCONF) to interact with the mounted devices.","In terms of RFCs, the southbound plugin supports:","Network Configuration Protocol (NETCONF) - RFC-6241","NETCONF Event Notifications - RFC-5277","YANG Module for NETCONF Monitoring - RFC-6022","YANG Module Library - draft-ietf-netconf-yang-library-06","NETCONF is fully model-driven (utilizing the YANG modelling language) so in addition to the above RFCs, it supports any data/RPC/notifications described by a YANG model that is implemented by the device.","By mounting of NETCONF device a new netconf-connector is created. This connector is responsible for:","keeping state of NETCONF session between NETCONF client that resides on FRINX UniConfig distribution and NETCONF server (remote network device)","sending / receiving of NETCONF RPCs that are used for reading / configuration of network device","interpreting of NETCONF RPCs by mapping of their content using loaded device-specific YANG schemas","There are 2 ways for configuring a new netconf-connector: NETCONF or RESTCONF. This guide focuses on using RESTCONF."]},{"l":"Spawning of netconf-connectors while the controller is running","p":["To configure a new netconf-connector (NETCONF mount-point) you need to create a node in configuration data-store under 'topology-netconf'. Adding of new node under NETCONF topology automatically triggers data-change-event that at the end triggers mounting process of the NETCONF device. The following example shows how to mount device with node name 'example' (make sure that the same node name is specified in URI and request body under 'node-id' leaf).","This spawns a new netconf-connector with name 'example' which tries to connect to the NETCONF device at '192.168.1.100' and port '22'. Both username and password are set to 'test' and SSH is used as channel for transporting of NETCONF RPCs (if 'tcp-only' leaf is set to 'true', NETCONF application protocol is running directly on top of the TCP protocol).","Right after the new netconf-connector is created, NETCONF layer writes some useful metadata into the operational data-store of MD-SAL under the network-topology subtree. This metadata can be found at:","Information about connection status, device capabilities, etc. can be found there.","You can check the configuration of device by accessing of'yang-ext:mount' container that is created under every mounted NETCONF node. The new netconf-connector will now be present there. Just invoke:","The response will contain the whole configuration of NETCONF device. You can fetch smaller slice of configuration using more specific URLs under'yang-ext:mount' too."]},{"i":"authentification-with-privatepublic-key","l":"Authentification with private/public key","p":["This type of authentification is used when you want to connect to the NETCONF device via private/public key, it is necessary to save public key into device, then put private key into UniConfig and when trying to configure NETCONF mount-point to connect via ssh key and not password.","To accomplish that, follow these steps :","1. Generate private/public key-pair on your local machine","2. Change .pub format into .bin format","3. Copy public key into device directory. Password of the device will be required.","4.(Optional) Check if the public key is on device","5. Import public key to device","6. Log in with private key to device NETCONF subsystem. Passphrase for key will be required.","7. Start UniConfig and insert keystore with private key into it.","RPC request:","8. Create mount-point with key-id","Delete public key","Login to device, remove rsa public key and after that, it is also possible to delete key from device directory."]},{"l":"PKI Data persistence in NETCONF","p":["PKI data is used for authentication of NETCONF sessions with the provided RSA private key. The corresponding public key must be stored on the device side.","Keys are identified using a unique 'key-id'. This key identifier can be specified in the NETCONF installation request.","Keys can be managed using the 'remove-keystore-entry' and 'add-keystore-entry' operations. These RPC calls are part of the UniConfig transaction. Changes are not applied until they are committed by the user or the immediate commit model is used to invoke the operation.","Keys are stored in the UniConfig database. In a clustered environment, all nodes share the same set of keys."]},{"l":"Registration of the new key","p":["The following request demonstrates how to register a new RSA private key with a key-id of 'key1'. The private key must be specified in the PKCS#8 format. The passphrase is optional and must be specified only if the private key is encrypted.","Multiple keys can be registered at once if the user provides a list of the 'key-credential' in the input."]},{"l":"Removing of the existing key","p":["The following example shows how to remove the existing key 'key1' from UniConfig. It is possible to remove multiple keys at once."]},{"l":"Reading list of the existing keys","p":["The following example shows how to read list of the existing keys from UniConfig.","Note: Both 'passphrase' and 'private-key' are additionally encrypted by the UniConfig encryption system to protect confidential data."]},{"l":"Keepalive settings","p":["If the NETCONF session haven't been created yet, the session is tried to be established only within maximum connection timeout. If this timeout expires before NETCONF session is established, underlay NETCONF channel is closed (reconnection strategy will not be started). After the NETCONF session has been successfully created, there are two techniques how the connection state is kept alive:","TCP acknowledgements- NETCONF is running on top of the TCP protocol that can handle dropped packets by decreasing of window size and resending of lost TCP segments. Working TCP connection doesn't imply working state of the application layer (NETCONF session) - keepalive messages are required too.","Explicit NETCONF keepalive messages- Keepalive messages test whether NETCONF server is alive - server responds to keepalive messages within NETCONF RPC timeout.","If TCP connection is dropped or NETCONF server doesn't respond within keepalive timeout, NETCONF launches reconnection strategy. To summarize it all, there are 3 configurable parameters that can be set in mount-request:","Initial connection timeout [seconds]- Specifies timeout in milliseconds after which initial connection to the NETCONF server must be established. By default, the value is set 20 s.","Keepalive delay [seconds]- Delay between sending of keepalive RPC messages to the NETCONF server. Keepalive messages test state of the NETCONF session (application layer) - whether remote side is able to respond to RPC messages. Default keepalive delay is 120 seconds.","Request transaction timeout [seconds]- Timeout for blocking RPC operations within transactions. Southbound plugin stops to wait for RPC reply after this timeout expires. By default, it is set to 60 s.","Example with set keepalive parameters at creation of NETCONF mount-point(connection timeout, keepalive delay and request timeout):"]},{"l":"Reconnection strategy","p":["Reconnection strategies are used for recovering of the lost connection to the NETCONF server. The behaviour of the reconnection can be described by 3 configurable mount-request parameters:","Maximum number of connection attempts [count]- Maximum number of initial connection retries. This is used when no connection is yet established for given node inside uniconfig transaction; when it is reached, the NETCONF won't try to connect to device anymore. By default, this value is set to 1, non-positive value or null is interpreted as infinity.","Maximum number of reconnection attempts [count]- Maximum number of reconnection retries. This is used when connection was already successfully established and ongoing (not yet closed), but it dropped (from device side); when it is reached, the NETCONF won't try to reconnect to device anymore. By default, this value is set to 0, non-positive value or null is interpreted as infinity.","Initial timeout between attempts [seconds]- The first timeout between reconnection attempts in milliseconds. The default timeout value is set to 2000 ms.","Reconnection attempts multiplier [factor]- After each reconnection attempt, the delay between reconnection attempts is multiplied by this factor. By default, it is set to 1.5. This means that the next delay between attempts will be 3 s, then it will be 4,5 s, etc.","Example with set reconnection parameters at creation of NETCONF mount-point - maximum connection attempts, initial delay between attempts and sleep factor:"]},{"l":"Local NETCONF cache repositories","p":["The netconf-connector in OpenDaylight relies on'ietf-netconf-monitoring' support when connecting to remote NETCONF device. The 'ietf-netconf-monitoring' feature allows netconf-connector to list and download all YANG schemas that are used by the device. These YANG schemas are afterwards used by NETCONF southbound plugin for interpretation of RPCs. The following rules apply for maintaining of local NETCONF cache repositories:","By default, for each device type, the separate local repository is prepared.","All NETCONF repositories are backed up by separate sub-directory under 'cache' directory of UniConfig Distribution.","NETCONF device types are distinguished by unique set of YANG source identifiers - module names and revision numbers. For example, if 2 NETCONF devices differ only in revision of one YANG schema, these NETCONF devices are recognized to have different device types.","Format of the name of generated NETCONF cache directory at runtime is 'schema_id', where 'id' represents unique integer computed from hash of all source identifiers. This generation of cache directory name is launched only at mounting of new NETCONF device and only if another directory with the same set of source identifiers haven't been registered yet.","You can still manually provide NETCONF cache directories with another format before starting of UniConfig Distribution or at runtime - such directories don't have to follow 'schema_id' format.","The NETCONF repository can be registered in 3 ways:","Implicitly by mounting of NETCONF device that has NETCONF monitoring capability and another devices with the same type hasn't already been mounted.","At booting of FRINX UniConfig distribution, all existing sub-directories of 'cache' root directory are registered as separate NETCONF repositories.","At runtime, by invocation of 'schema-resources:register-repository' RPC.","Already registered schema repositories can be listed using following request:","It should return list of ODL nodes in cluster with list of all loaded repositories. Each repository have associated list of source identifiers. See the following example of GET request output:"]},{"l":"Local Netconf default cache repository","p":["Before booting of FRINX UniConfig, the user can put the 'default' repository in the ‘cache’ directory. This directory should contain the most frequently missing sources. As mentioned above, if the device supports ‘ietf-netconf-monitoring’ and there is no directory in the'cache' with all sources that the device requires, then NETCONF will generate directory with name ‘schema_id’, where ‘id’ represents unique integer. The generated repository may not contain all required schemas because device may not provide them. In such case, the missing sources will be searched in the 'default' repository and if sources will be located there, generated repository will be supplemented by the missing sources. In general, there are 2 situations that can occur:","Missing imports","The device requires and provides a resource which for its work requires additional resources that are not covered by provided resources.","Source that is not covered by provided sources","The device requires but does not provide a specific source.","note Using the 'default' directory in the 'cache' directory is optional."]},{"l":"Connecting to a device not supporting NETCONF monitoring","p":["NETCONF connector can only communicate with a device if it knows the set of used schemas (or at least a subset). However, some devices use YANG models internally but do not support NETCONF monitoring. Netconf-connector can also communicate with these devices, but you must load required YANG models manually. In general, there are 2 situations you might encounter:","NETCONF device does not support 'ietf-netconf-monitoring' but it does list all its YANG models as capabilities in HELLO message","This could be a device that internally uses, for example,'ietf-inet-types' YANG model with revision '2010-09-24'. In the HELLO message, that is sent from this device, there is this capability reported as the following string (other YANG schemas can be reported as capabilities in the similar format):","The format of the capability string is following:","[NAMESPACE] - Namespace that is specified in the YANG schema.","[MODULE_NAME] - Name of the YANG module.","[REVISION] - The newest revision that is specified in the YANG schema (it should be specified as the first one in the file). note Revision number is not mandatory (YANG model doesn't have to contain revision number) - then, the capability is specified without the'&' and revision too. For such devices you have to side load all device YANG models into separate sub-directory under 'cache' directory (you can choose random name for this directory, but directory must contain only YANG files of one device type).","NETCONF device does not support 'ietf-netconf-monitoring' and it does NOT list its YANG models as capabilities in HELLO message","Compared to device that lists its YANG models in HELLO message, in this case there would be no specified capabilities in the HELLO message. This type of device basically provides no information about the YANG schemas it uses so its up to the user of OpenDaylight to properly configure netconf-connector for this device. Netconf-connector has an optional configuration attribute called'yang-module-capabilities' and this attribute can contain a list of'yang-module-based' capabilities. By setting this configuration attribute, it is possible to override the 'yang-module-based' capabilities reported in HELLO message of the device. To do this, we need to mount NETCONF device or modify the configuration of existing netconf-connector by adding the configuration snippet with explicitly specified capabilities (it needs to be added next to the address, port, username etc. configuration elements). The following example shows explicit specification of 6 capabilities:","Remember to also put the YANG schemas into the cache folder like in the case 1."]},{"l":"Registration or refreshing of NETCONF cache repository using RPC","p":["This RPC can be used for registration of new NETCONF cache repository or updating of NETCONF cache repository. This is useful when user wants to add new NETCONF cache repository at runtime of FRINX UniConfig distribution for device that doesn't support 'ietf-netconf-monitoring' feature. It can also be used for refreshing of repository contents (YANG schemas) at runtime.","The following example shows how to register a NETCONF repository with name 'example-repository'. The name of the provided repository must equal to name of the directory which contains YANG schemas.","If the repository registration or refreshing process ends successfully, the output contains just set 'status' leaf with 'success' value:","On the other side, if the directory with input 'repository-name' does not exist, directory doesn't contain any YANG files, or schema context cannot be built using provided YANG sources the response body will contain 'failed' 'status' and set 'error-message'. For example, non-existing directory name produces following response:","Constraints:","Only the single repository can be registered using one RPC request.","Removal of registered repositories is not supported for now."]},{"l":"Reconfiguring netconf-connector while the controller is running","p":["It is possible to change the configuration of an already mounted NETCONF device while the whole controller is running. This example will continue where the last left off and will change the configuration for the existing netconf-connector after it was spawned. Using one RESTCONF request, we will change both username and password for the netconf-connector.","To update an existing netconf-connector you need to send following request to RESTCONF:","Since a PUT is a replace operation, the whole configuration must be specified along with the new values for username and password. This should result in a '2xx' response and the instance of netconf-connector called 'example' will be reconfigured to use username 'bob' and password'passwd'. New configuration can be verified by executing:","With new configuration, the old connection will be closed and a new one established."]},{"l":"Destroying of netconf-connector","p":["Using RESTCONF one can also destroy an instance of a netconf-connector - NETCONF connection will be dropped and all resources associated with NETCONF mount-point on NETCONF layer will be cleaned (both CONFIGURATION and OPERATIONAL data-store information). To do this, simply issue a request to following URL:","The last element of the URL is the name of the mount-point."]},{"l":"NETCONF TESTTOOL"},{"l":"Testtool overview","p":["NETCONF testtool is the Java application that:","Can be used for simulation of 1 or more NETCONF devices (it is suitable for scale testing).","Uses core implementation of NETCONF NORTHBOUND server.","Provides broad configuration options of simulated devices.","Supports YANG notifications.","NETCONF testtool is available at netconf repository of ODL( into config/ folder of FRINX UniConfig distribution, this file contains xml paths that should be ignored while removing duplicate nodes from the netconf message","Optional:","put file namespaceBlacklist.txt into config/ folder of FRINX UniConfig distribution, this file contains xml namespaces of the nodes that should be removed from the netconf message","Now UniConfig can be started."]},{"l":"Install SROS device","p":["To install the SROS device run:","Where:","sros: is the name of the device","10.19.0.18: is the IP address of the device","830: is the port number of the device","USERNAME: is the username to access the device","PASSWORD: is the respective password","\"uniconfig-config:uniconfig-native-enabled\": allows to enable installing through UniConfig Native","\"uniconfig-config:install-uniconfig-node-enabled\": allows to disable installing to uniconfig and unified layers","\"uniconfig-config:path\": allows to specify a list of root elements from models present on device to be ignored by UniConfig Native","In case of success the return code is 201."]},{"l":"Check if SROS device is connected","p":["To check if the device is properly connected run:","In case of success the return code is 200, and the response body contains something similar to:"]},{"l":"Check if SROS device configuration is available in UniConfig","p":["To check if the SROS device configuration has been properly loaded in the UniConfig config datastore, run:","In case of success the return code is 200 and the response body contains something similar to:"]}],[{"l":"UniConfig SNMP"},{"l":"Introduction","p":["The SNMP (Simple Network Management Protocol) southbound plugin allows UniConfig to communicate with an SNMP agent, which is a software module installed on network devices. It collects information about the status, performance, and configuration of these devices.","The SNMP southbound plugin follows a fully model-driven approach, similar to CLI or NETCONF southbound plugins. However, the difference lies in the fact that, instead of YANG, it uses MIB (Management Information Base) for data modeling."]},{"l":"Architecture","p":["This section provides an architectural overview of the plugin."]},{"l":"SNMP topology","p":["The SNMP topology is a dedicated topology instance where users and applications can:","Install an SNMP agent","Uninstall an agent","Read device configuration settings or performance metrics"]},{"l":"SNMP mountpoint","p":["The plugin relies on MD-SAL and its concept of mountpoints to expose information about a device. By exposing a mountpoint in MD-SAL, it allows the SNMP topology to access device information in a structured form."]},{"l":"Local SNMP MIB repositories","p":["It is necessary to provide the /mibs directory that contains the following:","repository- a directory that contains mib files. You can use any name.","mib.metadata file - With this file we inform UniConfig that we have added, removed, or modified an MIB file in the repository. Simply insert the repository name and any arbitrary string, and UniConfig will update the relevant context for the particular repository.","Example - mib.metadata file"]},{"l":"Example request","p":["UniConfig currently supports the read operation, with plans to add support for the write operation in the future."]},{"l":"GET request"}],[{"l":"Updating installation parameters","p":["During device installation, UniConfig creates a mountpoint for the device and stores it in the database. The mountpoint contains all parameters set in the installation request.","UniConfig includes a feature to update mountpoint parameters, which can be used for NETCONF, CLI and gNMI nodes."]},{"l":"Show installation parameters","p":["Parameters for installed devices can be shown using a GET request on the node, which returns the current node settings. Make sure to specify the right topology. See below for examples.","By default, the NETCONF, CLI and gNMI topologies have the password parameter encrypted. This can be changed in the corresponding YANG schema by adding or removing the frinx-encrypt:encrypt extension flag.","CLI node","Output:","NETCONF node","gNMI node"]},{"l":"Update installation parameters","p":["To update node installation parameters, use a PUT request with an updated request body copied from the GET request in the previous section. Single parameters can also be updated with a direct PUT call to the specific parameter.","If the password parameter is set to be encrypted, changing it will encrypt the input value.","CLI node","Update multiple parameters:","host","dry-run-journal-size","journal-size","Update a single parameter:","NETCONF node","keepalive-delay","After these changes have been made, use the GET requests in the Show installation parameters section above to see that the parameters have actually been changed. You can also use the GET request for a single parameter."]}],[{"l":"UniConfig-native CLI"},{"l":"Introduction","p":["UniConfig-native CLI allows user configuration of CLI-enabled devices using YANG models that describe configuration commands. In UniConfig-native CLI deployment translation units are defined only by YANG models and device-specific characteristics that are used for parsing and serialization of commands. Afterwards, readers and writers are automatically created and provided to translation registry - user doesn't write them individually. YANG models can be constructed by following of well-defined rules that are explained in Developer Guide.","Summarized characteristics of UniConfig-native CLI:","modelling of device configuration using YANG models,","automatic provisioning of readers and writers by generic translation unit,","simple translation units per device type that must define device-characteristics and set of YANG models."]},{"l":"Installation","p":["CLI device can be installed as native-CLI device by adding'uniconfig-config:uniconfig-native-enabled' flag with 'true' value into the mount request (by default, this flag is set to 'false'). It is also required to use tree parsing engine that is enabled by default. All other mount request parameters that can be applied for classic CLI mountpoints can also be used in native-CLI configuration with the same meaning.","The following example shows how to mount Cisco IOS XR 5.3.4 device as native-CLI device with enabled dry-run functionality:","After mounting of CLI node finishes, you can verify CLI mountpoint by fetching its Operational datastore:","You can see that there are some native models included in the'available-capabilities' plus basic mandatory capabilities for CLI mountpoints. Number of supported native capabilities depends on number of written models that are included in native-CLI translation unit for IOS XR 5.3.4, in this case. The only common capability for all native-CLI mountpoints is' http://frinx.io/yang/native/extensions?module=cli-native-extensions'. Sample list of native capabilities:","The synced configuration on UniConfig layer can be verified in the same way as for all types of devices:","Since sample device configuration contains both ACL and interface configuration and native-CLI IOS XR 5.* covers this configuration, the synced data looks like the next output:","The previous sample output corresponds to the following parts of the configuration on the device:"]},{"l":"Architecture","p":["The following section describes building blocks and automated processes that take place in UniConfig-native CLI."]},{"l":"Modules","p":["The following UML diagram shows dependencies between modules from which UniConfig native-cli is built. The core of the system is represented by'native-cli-unit' module in CLI layer that depends on CLI API for registration of units and readers and writers API. On the other side there are CLI-units that extend 'GenericCliNativeUnit'.","Dependencies","Description of modules:","utils-unit and translation-registry-api/spi: CLI layer API which native-cli units depend on. It defines interface for CLI readers/writers, translation unit collector that can be used for registration of native-CLI unit, and common 'TranslateUnit' interface.","native-cli-unit: It is responsible for automatic provisioning and registration of readers and writers (handlers) based on YANG modules that are defined in specific translation units. Readers and writers are initialized only for root container and list schema nodes defined in YANG models. All specific native-CLI units must be derived from abstract class 'GenericCliNativeUnit'.","ios-xr-5-native and junos-17-native: Specific native-CLI units derived from 'GenericCliNativeUnit'. To make native-CLI unit working, it must implement methods that provides list of YANG modules, list of root data object interface, supported device versions, unit name, and CLI flavour."]},{"l":"Registration of handlers","p":["Registration of native-CLI handlers is described by following sequence diagram in detail.","Handlers","Description of the process:","Searching for root schema node: Extraction of the root list and container schema nodes from nodes that are augmented to UniConfig topology.","Building of device template information: Extraction of device template information from imported template YANG modules. This template contains command used for displaying of whole device configuration, format of configuration command, and format of delete command.","Initialization of handlers: Creation of native-CLI config readers and writers or native-CLI list readers and writers in case of list schema nodes.","Registration of handlers: Registration of readers and writers in reader and writer registries. Readers are registered as generic config readers, whereas writers are registered as wildcarded subtree writers.","Since native-CLI readers are not registered as subtree readers, it is possible to directly read only root elements from CLI mountpoint. This constraint is caused by unsupported wildcarded subtree readers in Honeycomb framework."]},{"l":"Functionality of readers","p":["Config readers and config list readers in UniConfig-native CLI are implemented as generic readers that parse device configuration into structuralized format based on registered native-CLI YANG models. These readers are initialized and registered per root data schema node that is supported in native-CLI. The next sequence diagram shows process taken by generic reader on calling 'readCurrentAttributes(..)' method.","Readers","Description of the process:","Creation of the configuration tree: It represents current device configuration by sending of 'show' command which is responsible for displaying of whole device configuration.","Transformation of configuration tree: It is transformed into binding-independent NormalizedNode using 'ConfigTreeStreamReader' component.","Conversion into binding-aware format: Conversion of binding-independent NormalizedNode into binding-aware DataObject and population of DataObject builder by fields from built DataObject.","Configuration is parsed into structuralized form before it is actually transformed into NormalizedNodes (step 1) because of more modular and easier approach. Configuration tree consists of 3 types of nodes:","Command nodes: They are represented by the last identifiers of the commands (command word). These nodes don't have any children nodes.","Section nodes: These nodes are represented by the command word / identifier that opens a new configuration section. Section nodes can have multiple children nodes.","Connector nodes: Connector nodes are similar to section nodes with identifier and multiple possible children nodes. However, they don't open a new configuration section; they represent just one intermediary word in command line.","Example - parsing of interface commands into the tree structure:","Parsing","Detailed description of algorithm for transformation of configuration tree into DOM objects:","Transformation","If some commands are not covered by native-CLI YANG models, the parsing of configuration in readers will not fail - unsupported nodes will be skipped."]},{"l":"Functionality of writers","p":["Config writers and config list writers are responsible for serialization of structuralized data from datastore into series of configuration or delete command lines that are compatible with target device. Native CLI writers are also registered only for root schema nodes on the same paths as readers. The next sequence diagram shows process taken by generic writer on calling 'writeCurrentAttributes(..)' or'deleteCurrentAttributes(..)' method.","Writers","Description of the process:","Conversion into binding-independent format: Conversion of binding-aware DataObject into binding-independent NormalizedNode format. Binding-independent format is more suited for automated traversal and building when the target class types of nodes are not known before compilation of YANG schemas is done.","Generation of command lines: NormalizedNode is serialized using stream writer into configuration buckets that are afterwards serialized into separated command lines. Conversion of configuration buckets into command lines can be customized by different strategies. Currently only the primitive strategy is used - it creates for each leaf command argument the full command line from top root - nesting into configuration modes is not supported. This step is described in detail by next activity diagram.","Generation of configuration or delete command lines: It is done by application of configuration or delete template on command line - for example, JUNOS devices use prefix 'set' for applying of the configuration and prefix 'delete' for removal of configuration from device.","Squashing of command lines into single snippet: This is only optimization step - all command lines are joined together with newline separator.","Sending of command to the device(blocking operation).","Configuration buckets are created as intermediary step because of the modularity and flexibility for application of different serialization strategies in future. There are 3 types of created buckets that are wired with respective schema nodes:","Leaf bucket: Bucket that doesn't have any children but it has a value in addition to the identifier. It is created from LeafNode.","Composite bucket: Bucket with identifier and possibly multiple children buckets. It can be used for following types of DOM nodes: ContainerNode or MapEntryNode.","Delegating bucket: Bucket that doesn't have any identifier, it just delegates configuration to its children buckets. It can be used for nodes that are described by ChoiceNode or MapNode.","Command serialization","The current implementation processes updates in default way - the whole actual configuration is removed and then the whole updated configuration is written back to device. This strategy can cause slow down of the commit operation in case of longer configuration and because of this reason it is addressed as one of the future improvements."]}],[{"l":"UniConfig Operations"},{"i":"sending-and-receiving-data-restconf","l":"Sending and receiving data (RESTCONF)","p":["RESTCONF represents REST API to access datastores and UniConfig operations."]},{"l":"UniConfig Node Manager API","p":["The responsibility of this component is to maintain configuration on devices based on intended configuration. Each device and its configuration is represented as a node in the uniconfig topology and the configuration of this node is described by using OpenConfig YANG models. The Northbound API of Uniconfig Manager (UNM) is RPC driven and provides functionality for commit with automatic rollback and synchronization of configuration from the network."]},{"l":"Device discovery","p":["This component is used to check reachable devices in a network. The manager checks the reachability via the ICMP protocol. Afterwards, the manager is able to check whether various TCP/UDP ports are open or not."]},{"l":"Dry-run Manager API","p":["The manager provides functionality showing CLI commands which would be sent to network element."]},{"l":"Snapshot Manager API","p":["The snapshot manager creates and deletes uniconfig snapshots of actual uniconfig topology. Multiple snapshots can be created in the system."]},{"l":"Subtree Manager API","p":["The subtree manager copies (merge/replace) subtrees between source and target paths."]},{"l":"Templates Manager API","p":["This component is responsible for application of templates into UniConfig nodes."]},{"l":"Transaction Log API","p":["This component is responsible for tracking transactions."]},{"l":"UniConfig Queries","p":["Using this component it is possible to invoke JSONB-path queries on top of the stored configuration."]},{"i":"dedicated-transaction-immediate-commit-model","l":"Dedicated transaction (Immediate Commit Model)","p":["The immediate commit creates new transactions for every call of an RPC. The transaction is then closed so no lingering data will occur."]},{"l":"Utilities","p":["This sub-directory contains UniConfig utilities."]}],[{"l":"JSONB Filtering","p":["Jsonb-filter is a query parameter that is used for filtering data based on one or more parameters. This filter is an effective mechanism for filtering a list of items. Using the jsonb-filter we can retrieve only those list items that meet the defined conditions.","Currently, we have two options of how to use the JSONB filtering functionality."]},{"l":"Database JSONB Filtering","p":["The query parameter is located in the URI. This option is faster because filtering is happening on the database side but this filtering has fewer features."]},{"l":"Application JSONB Filtering","p":["A new Content-Type is added. The query parameter is added in the body. Additional query parameters can be chained (sort by, limit, fields). This request is sent as a POST request. This filtering adds more features, but it is happening on the UniConfig application side which will be slower than the database filtering."]}],[{"l":"Application JSONB Filtering","p":["Application JSONB filtering supports either the dot notation:","or the bracket–notation:"]},{"l":"Jsonb-filter expression","p":["Every filter operation is sent using a POST request. Additionally, a new Content-Type header has been made for application JSONB Filtering. An example can be seen below:","The filter is located in the body of the request, not in the URI. Since it is located in the body, there is no need to escape characters. The body structure looks like this:","If the user wants to filter the list elements based on name, the query filter would look like this:","By default, the filter returns the same output structure as when calling a GET request. There is an option to add the whole parent structure, where the body will look like this:","This will filter out all the elements in the list whose name is foo."]},{"l":"Operators","p":["..",".","[?()]","['' (, '')]","[ (, )]","[start:end]","@","*","$","Array index or indexes.","Array slice operator.","Bracket-notated child or children.","Deep scan. Available anywhere a name is required.","Description","Dot-notated child.","Filter expression. Expression must evaluate to a boolean value.","Operator","Operators mentioned in the table below are used to construct a path.","The current node being processed by a filter predicate.","The root element to query. This starts all path expressions.","Wildcard. Available anywhere a name or numeric are required."]},{"l":"Functions","p":["add an item to the json path output array","append(X)","avg()","concat(X)","Description","Double","Functions can be called at the end of the query path. The input to the function is the output of the path expression. The function output is dictated by the function itself.","Integer","keys()","length()","like input","max()","min()","Operator","Output Type","Provides a concatinated version of the path output with a new item","Provides the average value of an array of numbers","Provides the length of an array","Provides the max value of an array of numbers","Provides the min value of an array of numbers","Provides the property keys (An alternative for terminal tilde ~)","Provides the standard deviation value of an array of numbers","Provides the sum value of an array of numbers","Set","stddev()","sum()"]},{"l":"Filter Operators","p":["!=","<","<=","==","=~",">",">=","A double quote: [?(@.name == \"foo\")]","A single quote: [?(@.name == 'foo')]","anyof","Description","empty","Filters are logical expressions used to filter arrays. A typical filter would be [?(@.age > 18)] where @ represents the current element being processed. More complex filters can be created with logical operators && and ||. String literals must be enclosed by:","in","left (array or string) should be empty","left does not exists in right","left exists in right [?(@.size in ['S', 'M'])]","left has an intersection with right [?(@.sizes anyof ['M', 'L'])]","left has no intersection with right [?(@.sizes noneof ['M', 'L'])]","left is a subset of right [?(@.sizes subsetof ['S', 'M', 'L'])]","left is equal to right (note that 1 is not equal to '1')","left is greater than or equal to right","left is greater than right","left is less or equal to right","left is less than right","left is not equal to right","left matches regular expression [?(@.name =~ /foo.*?/i)]","nin","noneof","Operator","size","size of left (array or string) should match right","subsetof"]},{"l":"Jsonb-filter examples","p":["$..interface[?(@.speed <= $['fast'])]","$..interface[?(@.type =~/.* Csmacd/i)]","$..name","$.ietf-interfaces:interfaces..type","$.ietf-interfaces:interfaces.*","$.ietf-interfaces:interfaces.interface.length()","$.ietf-interfaces:interfaces.interface[-2:]","$.ietf-interfaces:interfaces.interface[-2]","$.ietf-interfaces:interfaces.interface[:2]","$.ietf-interfaces:interfaces.interface[?(@.enabled)]","$.ietf-interfaces:interfaces.interface[?(@.speed >= 10)]","$.ietf-interfaces:interfaces.interface[*].name","$.ietf-interfaces:interfaces.interface[0,1]","$.ietf-interfaces:interfaces.interface[1:2]","$.ietf-interfaces:interfaces.interface[2:]","$.ietf-interfaces:interfaces.interface[2]","All interfaces from index 0 (inclusive) until index 2 (exclusive)","All interfaces from index 1 (inclusive) until index 2 (exclusive)","All interfaces matching regex (ignore case)","All interfaces that are not 'fast'","All interfaces that have the enabled element","All interfaces whose speed is greater or equal than 10","All names","All things under interfaces","Description","Interface number two from tail","JsonPath","Suppose we have the following data, and we want to do some filtering on them.","The first two books","The last two interfaces","The names of all interfaces","The number of interfaces","The second to last book","The third interface","The type of everything"]}],[{"l":"Database JSONB Filtering","p":["The example of using the jsonb-filter query parameter: parent-path?jsonb-filter=expression","PostgreSQL documentation: JSON Functions and Operators"]},{"l":"Jsonb-filter expression","p":["!","!=","{$/Cisco-IOS-XR-ifmgr-cfg:interface-configurations/interface-configuration=%28%23act,GigabitEthernet0/0/0/2%29}","{$/frinx-openconfig-interfaces:interfaces/interface=%28%23MgmtEth0/RP0/CPU0/0%29}","&&","<","<=","<>","==",">",">=","||","Absolute path","Boolean AND","Boolean NOT","Boolean OR","Composite key:","Description","Equality operator","exists","false","Greater-than operator","Greater-than-or-equal-to operator","In this case, a path must be prefixed with $. This path must start with a top-level parent container","In this case, the path must be prefixed with <@>. This path is relative to the parent-path","is unknown","Less-than operator","Less-than-or-equal-to operator","like_regex","Non-equality operator","Non-equality operator (same as !=)","null","Operator","Path","Relative path","Single key:","Sometimes especially absolute paths can contain a key of some item with special characters. In this case it is necessary wrap this key in a special syntax (#example-key-name) and also encode these wrapping symbols - %28%23example-key-name%29. If the key is a composite key, it is necessary to wrap the whole key with these symbols. If the user is not sure if the path contains special characters, it is always recommended to use this special syntax.","starts with","Tests whether the first operand matches the regular expression given by the second operand","The base expression must contain path, operator and value. The jsonb-filter can contain one or more expressions joined with AND(&&) or OR (||) operator. if the && operator is used it must be encoded.","The last element of the jsonb-filter expression is a value based on which the user wants to filter the data.","The path to the data that the users want to filter. The path can be:","true","Value","Value used to perform a comparison with JSON false literal","Value used to perform a comparison with JSON null value","Value used to perform a comparison with JSON true literal","Value/Predicate Description","When the path is constructed then the user can use one of the operators in the table below"]},{"l":"Jsonb-filter examples","p":["1. Examples of using the relative paths in the jsonb-filter","Example of filtering the list of interfaces based on the enabled parameter where the equality operator is used as the operator","Example of filtering the list of interfaces based on the mtu parameter where the less-than is used as the operator","Example of filtering the list of interfaces based on the name parameter where the like_regex is used as the operator","Example of filtering the list of interfaces where a combination of expressions is used","Example of filtering the list of interfaces where the exists operator is used","2. Example of using the absolute path in the jsonb-filter","Example of filtering the list of interfaces based on the name parameter where equality operator is used as the operator. Interface name\"GigabitEthernet0/0/0/2\" is a key value that contains slashes. For this reason, it is necessary to wrap this key into wrapping symbols(#GigabitEthernet0/0/0/) and also encode these symbols%28%23GigabitEthernet0/0/0/2%29."]}],[{"l":"Snapshot Manager","p":["The snapshot manager creates and deletes UniConfig snapshots of actual UniConfig topology. Multiple snapshots can be created in the system.","Snapshots may be used for manual rollback. Manual rollback enables simple reconfiguration of the entire network using one of the previous states saved in snapshots. That means that UniConfig nodes in config datastore are replaced with UniConfig snapshot nodes."]},{"l":"Create snapshot"},{"l":"Delete snapshot"},{"l":"Replace config with snapshot"},{"l":"Obtain snapshot metadata"}],[{"l":"Obtaining snapshots-metadata","p":["Snapshots metadata contains a list of created snapshots with the date of creation and a list of nodes."]}],[{"l":"RPC create-snapshot","p":["This RPC creates a snapshot of nodes in the UniConfig topology. The snapshot can be used later for manual rollback.","RPC input contains the name of the snapshot topology and nodes that the snapshot will contain. RPC output describes the result of the operation and matches all input nodes.","The RPC cannot be called with an empty list of target nodes. If a node fails for any reason, the entire RPC fails."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains the name for the topology snapshot and nodes that the snapshot contains. RPC output contains the result of operation."]},{"l":"Failed example","p":["RPC input includes nodes that will be contained in the snapshot, but a snapshot name is missing. RPC output contains the result of the operation."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains a name for the topology snapshot and a node that will be contained in the snapshot. The node has not been mounted. RPC output contains the result of the operation."]},{"i":"failed-example-2","l":"Failed example","p":["RPC input does not contain target nodes, so the RPC cannot be executed."]}],[{"l":"RPC delete-snapshot","p":["This RPC removes a snapshot from the Configuration datastore of the UniConfig transaction.","RPC input contains the name of the snapshot topology to be removed. RPC output contains the result of the operation."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains the name of the snapshot topology to be removed. RPC output contains the result of the operation."]},{"l":"Failed example","p":["RPC input contains the name of the snapshot topology to be removed. The snapshot name specified does not exist. RPC output contains the result of the operation."]}],[{"l":"RPC replace-config-with-snapshot","p":["This RPC replaces nodes in the UniConfig topology of the Configuration datastore with selected nodes from a specified snapshot.","RPC input contains the name of the snapshot topology and target nodes that should replace UniConfig nodes in the Configuration datastore. RPC output describes the result of the operation and matches all input nodes.","This RPC cannot be called with an empty target-nodes list. If a node fails for any reason, the entire RPC fails."]},{"l":"Examples"},{"l":"Successful example","p":["RPC input contains the name of the snapshot topology that should replace nodes in the UniConfig topology of the Configuration datastore, as well as a list of nodes from that snapshot. RPC output contains the result of the operation."]},{"l":"Failed example","p":["RPC input contains the name of the snapshot topology that should replace nodes in the UniConfig topology of the Configuration datastore, as well as a list of nodes from that snapshot. This particular snapshot ( snapshot2) has not been created yet.","RPC output contains the result of the operation."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains the name of the snapshot topology that should replace nodes in the UniConfig topology of the Configuration datastore, as well as a list of nodes from that snapshot. RPC input is missing the snapshot name. RPC output contains the result of the operation."]},{"i":"failed-example-2","l":"Failed example","p":["RPC input contains the name of the snapshot topology that should replace nodes in the UniConfig topology of the Configuration datastore, as well as a list of nodes from that snapshot. One node is missing in snapshot1 ( IOSXRN). RPC output contains the result of the operation."]},{"i":"failed-example-3","l":"Failed example","p":["RPC input does not contain target nodes, so the RPC can not be executed."]}],[{"l":"Subtree Manager","p":["The subtree manager copies (merge/replace) subtrees between source and target paths in Configuration or Operational datastore of UniConfig. When one of these RPCs is called, Subtree Manager (SM) reads the configuration from the source path and according to type of operation(merge / replace), copies the subtree data to target path. Target path is a parent path UNDER which data is copied. SM also distinguishes type of source / target datastore.","All RPCs support merging/replacing of configuration between two different schemas ('version drop' feature). This feature is handy, when it is necessary to copy some configuration between two mounted nodes that are described by slightly different YANG schemas. The following changes between schemas are tolerated:","Skipping non-existing composite nodes and leaves,","Adjusting namespace and revision in node identifiers, only name of nodes must match with target schema,","Moving nodes between choice and augmentation schema nodes,","Adjusting value format to target type definition of leaf or leaf-list schema node."]},{"l":"RPC copy-one-to-one","p":["Provides a list of supported operations on subscriptions, includes request examples and workflow diagrams."]},{"l":"RPC copy-one-to-many","p":["Provides a list of supported operations on subscriptions, includes request examples and workflow diagrams."]},{"l":"RPC copy-many-to-one","p":["Provides a list of supported operations on subscriptions, includes request examples and workflow diagrams."]},{"l":"RPC calculate-subtree-diff","p":["Provides a list of supported operations on subscriptions, includes request examples and workflow diagrams."]},{"l":"RPC calculate-subtree-git-like-diff","p":["Provides a list of supported operations on subscriptions, includes request examples and workflow diagrams."]},{"l":"RPC bulk-edit","p":["Applies multiple modifications to a list of target nodes. RPC bulk-edit"]}],[{"l":"RPC bulk-edit","p":["The bulk-edit operation modifies multiple configuration subtrees under multiple target nodes in the uniconfig, templates or unistore topology. The same modifications are applied to all target nodes.","The operation is executed atomically so that either all modifications are applied on all target nodes successfully, or the operation fails and the configuration is not touched in the UniConfig transaction. This RPC also benefits from parallel processing of changes per target node."]},{"l":"RPC input","p":["RPC input specifies a list of target nodes and a list of modifications to be applied to target nodes.","RPC input fields:","topology-id(mandatory): Identifier for the topology that contains all target nodes. Currently supported topologies are uniconfig, templates and unistore.","node-id(optional): List of target nodes identifiers residing in the specified topology. If this field is not specified or is left empty, the RPC is executed on all available nodes in the specified topology.","edit(mandatory with at least one entry): List of modifications. Each modification is uniquely identified by the path key. Modifications are applied in the user-defined order.","Parameters for the edit field:","path(mandatory): Path encoded using the RFC-8040 format. Specified as a relative path to the root configuration container. If this leaf contains a single character /, the path points to the whole configuration. If this path contains a list node without key, the operation is applied to all list node elements.","operation(mandatory): Operation to be executed on the specified path. Supported operations are merge, replace, and remove. Merge and replace operations also require the data input.","data(optional): Content of the replaced or merged data without wrapping parent element. The last element of the path is not declared in. See other cases for examples of how to specify the content of this leaf.","Supported operations:","merge: The supplied value is merged with the target data node.","replace: The supplied value is used to replace the target data node.","remove: Delete target node if it exists."]},{"l":"RPC output","p":["RPC output contains the global status of the executed operation and per-node status.","Fields in the node-result entry:","error-type: Error type.","error-tag: Error tag.","error-message: Reason for the failure. Included in output only if RPC execution failed on target node.","error-info: Additional information about the error, such as node identification."]},{"l":"RPC examples"},{"l":"Successful example","p":["The following request demonstrates the application of six (6) modifications to four (4) templates:","Replace the value of the description leaf.","Remove the snmp container.","Replace the whole ssh container.","Merge the configuration of the routing-protocol list entry.","Merge the whole tree list with the specified multiple list entries.","Replace the leaf-list services with the provided array of strings.","All modifications have been successfully written into the UniConfig transaction."]},{"l":"Failed example","p":["RPC input does not contain the mandatory topology-id field."]},{"i":"failed-example-1","l":"Failed example","p":["This example demonstrates the execution of a bulk-edit operation that fails on parsing one of the paths using YANG schemas of the R2 device.","There is one error message in the result for R2. Note that no modifications are written to R1 because another node (R2) failed during execution of the operation."]}],[{"l":"RPC calculate-subtree-diff","p":["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 calculate-subtree-dif"]},{"l":"RPC examples"},{"i":"successful-example-computed-difference","l":"Successful example: Computed difference","p":["RPC input contains a path to two different testtool devices with different YANG schemas.","RPC output contains a list of statements representing the diff."]},{"i":"successful-example-no-difference","l":"Successful example: No difference","p":["The following output demonstrates a situation with no changes between specified subtrees."]},{"i":"failed-example-invalid-value-in-input-field","l":"Failed example: Invalid value in input field","p":["RPC input contains an improperly defined datastore ( AAA).","RPC output describes the allowed values ( CONFIGURATION and OPERATIONAL)."]},{"i":"failed-example-missing-mandatory-field","l":"Failed example: Missing mandatory field","p":["RPC input does not contain the mandatory source path."]},{"i":"failed-example-pointing-to-different-schema-node","l":"Failed example: Pointing to different schema node","p":["RPC input contains source and target paths that do not point to the same schema node."]}],[{"l":"RPC calculate-subtree-git-like-diff","p":["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 formatted in git-like style. The changes are grouped by root entities in the configuration."]},{"l":"RPC Examples"},{"i":"successful-example-computed-difference","l":"Successful example: Computed difference","p":["RPC input includes the path to two interfaces on different nodes. Both data locations are placed in the CONFIGURATION datastore.","RPC output contains a list of all changes. Multiple changes that occur under the same root element are merged together."]},{"i":"successful-example-no-difference","l":"Successful example: No difference","p":["The following output demonstrates a situation with no changes between specified subtrees."]},{"i":"failed-example-missing-mandatory-field","l":"Failed example: Missing mandatory field","p":["RPC input does not contain the mandatory target path."]}],[{"l":"RPC copy-many-to-one","p":["This RPC is used to perform operations with a configuration from multiple source paths to a single target path.","RPC input contains the following:","type of operation: merge or replace","type of source datastore: CONFIGURATION or OPERATIONAL","type of target datastore: CONFIGURATION or OPERATIONAL","list of source paths in RFC-8040 URI format","target path in RFC-8040 URI format (target path denotes parent entities under which the configuration is copied)","Target datastore is an optional input field. By default, it is the same as source datastore. All other input fields are mandatory.","RPC output describes the result of the operation. If one path fails, the entire operation fails and the datastore is not modified (i.e., all modifications are performed in a single atomic transaction)."]},{"l":"RPC examples"},{"l":"Successful example","p":["This example demonstrates the execution of the copy-many-to-one RPC with three (3) source paths.","Data described by these source paths ( snmp, access, and ntp containers under three different nodes) are copied under the root system:system container ( dev04 node)."]},{"l":"Failed example","p":["This example shows a failed copy-many-to-one RPC operation. One of the source paths points to a non-existing schema node ( invalid:invalid)."]}],[{"l":"RPC copy-one-to-many","p":["This RPC is used to perform operations with a configuration from a single source path to multiple target paths.","RPC input contains the following:","type of operation: merge or replace","type of source datastore: CONFIGURATION or OPERATIONAL","type of target datastore: CONFIGURATION or OPERATIONAL","source path in RFC-8040 URI format","list of target paths in RFC-8040 URI format (target paths denote parent entities under the which configuration is copied)","Target datastore is an optional input field. By default, it is the same as source datastore. All other input fields are mandatory.","RPC output describes the result of the operation. If one path fails, the entire RPC fails and the datastore is not modified (i.e., all modifications are performed in a single atomic transaction)."]},{"l":"RPC examples"},{"l":"Successful example","p":["This example demonstrates merging the ethernet interface configuration from a single source to the following interfaces:","eth-0/2(node dev02)","eth-0/3(node dev02)","eth-0/100(node dev03)","eth-0/200(node dev03)"]},{"l":"Failed example","p":["This example shows a failed copy-one-to-many RPC operation.","Both target paths are invalid, since the ext list schema nodes does not contain the interfaces:interfaces child container."]}],[{"l":"RPC copy-one-to-one","p":["This RPC is used to perform operations with a configuration from a single source path to a single target path.","RPC input contains the following:","type of operation: merge or replace","type of source datastore: CONFIGURATION or OPERATIONAL","type of target datastore: CONFIGURATION or OPERATIONAL","source path in RFC-8040 URI format","target path in RFC-8040 URI format (target path denotes parent entities under which the configuration is copied)","Target datastore is an optional input field. By default, it is the same as the source datastore. All other fields are mandatory.","RPC output describes the result of the operation. If the RPC fails, no changes are made to the target datastore."]},{"l":"RPC examples"},{"l":"Successful example","p":["This example demonstrates how to copy the entire org:orgs container from dev01 to the dev02 node under the uniconfig topology using the replace operation."]},{"l":"Failed example","p":["This example shows a failed copy-one-to-one operation.","RPC input contains the source datastore (same as the target datastore), merge operation, source path, and target path. The target path is invalid because it does not contain the org:orgs container in the schema tree."]}],[{"l":"Templates Manager"},{"l":"Overview","p":["Templates can be utilised to reuse some configuration and more easily apply this configuration into target UniConfig nodes.","Basic properties of templates in UniConfig:","All templates are stored under the templates topology and each template is represented by a separate node list entry.","The entire template configuration is placed under the frinx-uniconfig-topology:configuration container in the Configuration datastore. Because of this, the configuration of a template can be accessed and modified in the same way as a UniConfig node.","Templates are validated against a single schema context. The schema context is selected when a template is created using the uniconfig-schema-repository query parameter. The value of the query parameter defines the name of the schema repository that is placed under the UniConfig distribution in the form of the directory.","Currently implemented template features:","Variables- Used for template parametrisation.","Tags- Used to select an operation that is applied to the specific subtree when the template is applied to a UniConfig node.","Schema validation of leaves and leaf-lists is adjusted so that it can accept both string with variables and original YANG type.","RPC apply-template","RPC create-multiple-templates","RPC get-template-info","RPC get-template-nodes","RPC upgrade-template"]},{"l":"Latest-schema","p":["Latest-schema defines the name of the schema repository whose built schema context is used for template validation.","Latest-schema is used only if the uniconfig-schema-repository query parameter is not defined when creating the template. If the query parameter is defined, latest-schema is ignored."]},{"l":"Configuring latest-schema","p":["Latest-schema can be set using a PUT request. It is placed in the Config datastore. The name of the directory must point to an existing schema repository placed under the UniConfig distribution.","GET request can be used to check if latest-schema is placed in the config datastore."]},{"l":"Auto-upgrading latest-schema","p":["Latest-schema can be automatically upgraded by UniConfig after installing a new YANG repository. YANG repository is installed after deploying of new type of NETCONF/GRPC device or after manual invocation of RPC for loading of new YANG repository from directory.","In order to enable auto-upgrading process, latestSchemaReferenceModuleName must be specified in the application.properties file:","After new YANG repository is installed, UniConfig will look for revision of the latestSchemaReferenceModuleName module in the repository. If the revision found is more recent than the last cached revision, UniConfig will automatically write identifier of the fresh repository into 'latest-schema' configuration. Afterward, 'latest-schema' is used by UniConfig the same way as it would be written manually via RESTCONF."]},{"l":"Variables","p":["Using variables it is possible to parametrise values in the template. Structural parametrisation is not currently supported.","Properties:","Format of the variable: '{$variable-id}'.","Variables can be set to each leaf and leaf-list in the template.","Single leaf or leaf-list may contain multiple variables.","Key of the list can also contain variable.","Variables are substituted by provided values at the application of template to UniConfig node.","It is possible to escape characters of the variable pattern ('$','{', '}'), so they will be interpreted as value and not part of the variable.","Variable identifier may contain any UTF-8 characters. Characters'$', '{', '}' must be escaped, if they are part of the variable identifier."]},{"l":"Examples with variables","p":["A. Leaf with one variable","Application of following values to variables 'var-a' and 'var-b':'var-a' = ['10', '20', '30'], 'var-b' = ['50', '70', '60'].","Application of values - 'var-x': 'next', 'var-y': '7', 'var-1': '10','var-2': '9'. Leaf 'leaf-a' has 'string' type and 'leaf-b' has 'int32' type.","Application of values '10' and 'false' to 'var-1', and 'var-2'. Leaf'leaf-a' has 'int32' type and 'leaf-b' has 'boolean' type.","B. Leaf with multiple variables","Both variables must be substituted by the same number of values.","C. Leaf-list with one variable","D. Leaf-list with multiple variables","E. Leaf-list with entry that contains multiple variables","F. Leaves and leaf-lists with escaped special characters","If leaf-list is marked as \"ordered-by user\", then the order of leaf-list elements is preserved during substitution process.","It is possible to substitute both variables with one or multiple variables.","Leaf 'leaf-a' contains 2 variables and surrounding text that is not part of any variable.","Leaf 'leaf-b' contains 2 variable without additional text - substituted values of these variables are concatenated at application of template.","Leaf-list 'leaf-list-a' contains 2 variables inside one leaf-list entry: 'var-a' and 'var-b'.","Leaf-list 'leaf-list-a' contains 2 variables with identifiers'var-a' and 'var-2'. String \"str3\" represents constant value.","Leaf-list 'leaf-list-a' contains variable with identifier 'var-x'.","Substitution of 'var-1' by 'prefix' and 'var-{2}' by '10':","Substitution of 'var-a' with texts 'str1', 'str2' and 'var-b' with'str4' results in ('string' type):","Substitution of 'var-x' with numbers '10', '20', '30' results in('int32' type):","The following example demonstrates escaping of special characters outside the variable identifier (leaf-list 'leaf-list-a') and inside the variable identifier (leaf 'leaf-a').","The following example shows 2 leaves with 2 variables: 'var-1' and'var-2'.","This variable can be substituted by one or multiple values. If multiple values are provided in the apply-template RPC, they are'unwrapped' to the leaf-list in form of next leaf-list entries.","Unescaped identifier of the leaf 'leaf-a': 'var-{2}'."]},{"l":"Tags","p":["By default, all templates have assigned 'merge' tag to the root'configuration' container - if template doesn't explicitly define next tags in the data-tree, then the whole template is merged to target UniConfig node configuration at execution of apply-template RPC. However, it is possible to set custom tags to data-tree elements of the template.","Properties:","Tags are represented in UniConfig using node attributes with the following identifier: 'template-tags:operation'.","In RESTCONF, attributes are encoded using special notation that is explained in the 'RESTCONF' user guide.","Tags are inherited through the data-tree of the template. If data-tree element doesn't define any tag, then it is inherited from parent element.","Only single tag can be applied to one data node.","Tags can be applied to following YANG structures: container, list, leaf-list, leaf, list entry, leaf-list entry.","Currently, the following tags are supported:","merge: Merges with a node if it exists, otherwise creates the node.","replace: Replaces a node if it exists, otherwise creates the node.","delete: Deletes the node.","create: Creates a node. The node can not already exist. An error is raised if the node exists.","update: Merges with a node if it exists. If it does not exist, it will not be created."]},{"l":"Examples with tags","p":["A. Tags applied to container, list, and leaf","Template with name 'user_template' that contains 'merge', 'replace', and 'create' tags:","Description of all operations in the correct order that are done based on the defined tags:","Container 'configuration' will be merged to target UniConfig node(implicit root operation).","Container 'system:system' will be updated - its content is merged only, if it has already been created.","The whole list 'users' will be replaced in the target UniConfig node.","Leaf named 'password' will be created at the target UniConfig node - it cannot exist under 'users' list entry, otherwise the error will be raised.","B: Tags applied to leaf-list, leaf-list entry, and list entry:","The following JSON represents content of sample template with multiple tags:","'replace' tag is applied to single list 'my-list' entry","'merge' tag is applied to whole 'leaf-list-a' leaf-list","'create' tag is applied to whole 'leaf-list-b' leaf-list","'delete' tag is applied to single leaf-list 'leaf-list-b' entry with value '10'"]},{"l":"Creating a template","p":["A new template can be created by sending PUT request to new template node under 'templates' topology with populated 'configuration' container. Name of the template equals to name of the 'node' list entry. This RESTCONF call must contain specified schema cache repository using the 'uniconfig-schema-repository' query parameter in order to successfully match sent data-tree with correct schema context (it is usually associated with some type of NETCONF device)."]},{"l":"Example","p":["The following example shows creation of new template with name'interface_template' using 'schemas_1' schema repository. The body of the PUT request contains whole 'configuration' container."]},{"i":"readupdatedelete-template","l":"Read/update/delete template","p":["All CRUD operations with templates can be done using standard RESTCONF PUT/DELETE/POST/PLAIN PATCH methods. As long as template contains some data under 'configuration' container, next RESTCONF calls, that work with templates, don't have to contain 'uniconfig-schema-repository' query parameter, since type of the device is already known."]},{"i":"examples---restconf-operations","l":"Examples - RESTCONF operations","p":["Reading specific subtree under 'interface_template' - unit with name'{$unit-id}' that is placed under interface with name'eth-0/{$interface-id}'.","Changing 'update' tag of the 'address' list entry to 'create' tag using PLAIN-PATCH RESTCONF method."]}],[{"l":"Apply template","p":["Apply tags- Streams the data-tree of the template and recursively applies data to the target UniConfig node based on tags set on data elements. The UniConfig node configuration is updated only in the Configuration datastore.","error-info- Additional information related to the error. For example, node identification and topology identification.","error-message- Description of the error that occurred when the template was applied.","error-tag- Error tag, also determines HTTP status code.","error-type- Error type.","Failed response: Returns HTTP status code 400– 500 and an error with the following fields:","leaf-list-values- List of values that can only be used with leaf-lists. Special characters (\\$, {, }) must be escaped.","leaf-value- Scalar value of the variable. Special characters (\\$, {,}) must be escaped.","Processing template configuration","Read template- Reads a template configuration from the templates topology in the Configuration datastore.","RPC apply-template","RPC input fields:","RPC output fields:","String-substitution- Substitutes variables with provided or default values. If no values are provided for some variables and leafs/leaf-lists, uses default values. If some variables cannot be substituted (for example, if no input value is specified for a variable), returns an error.","Successful response: Returns HTTP status code 200 with no fields.","template-node-id- Name of the existing input template.","The apply-templates RPC is used to apply templates to UniConfig nodes.","The following diagrams illustrate the process in more detail:","The procedure contains the following steps:","uniconfig-node- List of target UniConfig nodes to which the template is applied ( uniconfig-node-id is the key).","uniconfig-node-id- Target UniConfig node identifier.","variable- List of variables and substituted values that must be used when the template is applied to a UniConfig node. Variables must be set per target UniConfig node, as it is common that values of variables are different between devices. The variable-id leaf represents the key of this list.","variable-id- Unescaped variable identifier.","Version-drop- Converts a template into a target schema context used by the target UniConfig node. Also drops unsupported data from the input template. Because of this, the template can be applied to different versions of devices with different revisions of YANG schemas but with similar structure. Version-drop is also aware of the ignoredDataOnWriteByExtensions RESTCONF filtering mechanism."]},{"l":"RPC examples"},{"l":"Successful example","p":["Successful applying the SERVICE_GROUP template to two UniConfig nodes (R1 and R2)."]},{"l":"Failed example","p":["Failed to apply the TEMP1 template: Template does not exist."]},{"i":"failed-example-1","l":"Failed example","p":["Failed to apply the template REDUNDANCY_TEMPLATE to two UniConfig nodes (R1 and R2): Missing values for required variables."]},{"i":"failed-example-2","l":"Failed example","p":["Failed to apply the template redundancy_template to a UniConfig node (dev1): Invalid type of substituted variable value (failed regex constraint)."]}],[{"l":"RPC create-multiple-templates","p":["This RPC can be used to create one or more new templates.","Templates are parsed and written in parallel for better performance. If specified templates already exist, their configuration is replaced. Execution of the RPC is atomic, meaning that either all templates are successfully created or no changes are made to the UniConfig transaction.","RPC input fields:","template-name- Name of the created template.","yang-repository- YANG schema repository used to parse template configuration. The default value is latest.","template-configuration- The entire template configuration.","tags- List of template tags written on the specified paths in all created templates. A specified tag type must be prefixed with the template-tags module name based on RFC-8040 formatting of identityref.","RPC output fields:","Successful response: Returns HTTP status code 200 with no fields.","Failed response: Returns HTTP status code 400– 500 and an error with the following fields:","error-type- Error type.","error-tag- Error tag, also determines HTTP status code.","error-message- Description of the error that occurred when the template was applied.","error-info- Additional information related to the error. For example, node identification, topology identification.","Mandatory fields are template-name and template-configuration."]},{"l":"RPC examples"},{"l":"Successful example","p":["Successfully creating templates."]},{"i":"successful-example-1","l":"Successful example","p":["Creating two templates with separately specified template tags:","replace tag is added to /acl/category and /services/group=default/types elements","create tag is added to /services element"]},{"l":"Failed example","p":["Cannot find the specified YANG schema repository."]},{"i":"failed-example-1","l":"Failed example","p":["Failed to parse template configuration."]}],[{"l":"RPC get-template-info","p":["This RPC shows information about all variables in the specified template. The RPC input must contain a template name."]},{"l":"RPC examples"},{"l":"Creating a template"},{"l":"Successful example"}],[{"l":"RPC get-template-nodes","p":["This RPC returns all templates from a template topology. No input body is required."]},{"l":"RPC examples"},{"l":"Successful example","p":["There are no templates in the template topology."]},{"i":"successful-example-1","l":"Successful example","p":["There is a template called test-template in the template topology."]}],[{"l":"Upgrading template to latest yang repository","p":["error-info: Additional information related to the error. For example: node identification, topology identification.","error-message: Description of the error that occurred during application of template.","error-tag: Tag of the error, also determining HTTP status code.","error-type: Type of the error.","Failed response: Returns HTTP status code 400-500 and an error with the following fields:","No fields are used, only HTTP response codes [200 - OK, 404 - Fail]","Read template- Reads a template configuration from the templates topology in the Configuration datastore.","Removal of previous template / writing new template- If upgraded-template-name is not specified in the RPC input, the previous template is deleted and replaced by a new one. If specified, the previous template will not be deleted.","RPC input fields:","RPC output fields:","Successful response: Returns HTTP status code 200 with no fields.","template-name: Name of the existing input template. This field is mandatory.","Templates can be upgraded to the latest YANG repository using the upgrade-template RPC.","This procedure consists of the following steps:","upgraded-template-name: Name of upgraded/new template. This field is optional.","Version-drop- Converts a template into a target schema context created by the specified yang-repository. Because of this feature, it is possible to change templates between different versions of devices with different revisions of YANG schemas but with similar structure. Version-drop is also aware of the ignoredDataOnWriteByExtensions RESTCONF filtering mechanism.","yang-repository: Name of YANG repository against which version-dropping is used. This field is optional. If no yang-repository is specified, the latest yang repository is used."]},{"l":"RPC examples"},{"l":"Successful example"},{"l":"Auto-upgrading templates","p":["This feature is used to automatically upgrade all stored templates that use the old YANG repository to the latest YANG repository with help from the version-drop procedure. For the auto-upgrade process to succeed, the latest YANG repository must already be configured. The upgrade process must be explicitly enabled in the configuration file and occurs when UniConfig is started.","Additionally, there is an option to back up templates before the upgrade with the standard rotation procedure. The names of backed-up templates follow the pattern ' backup', where '' represents the name of the original template and'' represents the backup index. The most recent backup index is always '0' and older ones are rotated by incrementing the corresponding index. If a backed-up template reaches the configured limit (maximum number of backups), it is permanently removed from the database.","Available settings ('application.properties'):","enabledTemplatesUpgrading- Enable the auto-upgrading process at UniConfig startup. If disabled, the other setting is ignored.","backupTemplatesLimit- Maximum number of stored backup templates. If exceeded, older templates are removed during the rotation procedure. If set to 0, templates are not backed up at all."]}],[{"l":"Transaction Log","p":["The transaction log consists of a transaction tracker and a revert-changes RPC. The transaction tracker stores information called transaction-metadata about performed transactions into the operational snapshot. Whereas revert-changes RPC can be used to revert changes that have been made in a specific transaction. A user only need to have ID of transaction for that. One or more transactions can be reverted using one revert-changes RPC."]},{"l":"RPC revert-changes"},{"l":"Transaction tracker"}],[{"l":"RPC revert-changes","p":["This RPC is used to revert previously configured changes. To revert one or more transactions, their transaction ids must be included in the body of the RPC. The transaction id is part of transaction metadata created by the transaction tracker after the commit/checked-commit RPC.","This RPC only updates data in the CONFIGURATION snapshot. To write reverted data to the device, use RPC commit after RPC revert-changes."]},{"l":"Ignore non-existing nodes","p":["When reverting multiple transactions, some transaction metadata may contain nodes that do not currently exist in UniConfig. In this case, the RPC fails.","There are two options for handling non-existing nodes:","Remove transactions that contain non-existing nodes from the request body.","Add the ignore-non-existing-nodes parameter to the RPC request body with a value of true(the default value is false).","If the ignore-non-existing-nodes parameter is not specified, the default value is used."]},{"l":"RPC examples"},{"l":"Successful examples","p":["To revert a transaction, we need to find its ID. Let's use a GET request to display all stored transaction metadata.","Revert changes for a single transaction.","Revert changes for multiple transactions.","Revert changes for multiple transactions. The transaction with id 2c4c1eb5-185a-4204-8021-2ea05ba2c2c1 contains the non-existing node R1. Since the ignore-non-existing-nodes parameter is set to true, the RPC is successful."]},{"l":"Failed example","p":["The request contains a non-existing transaction in the request body.","Reverting changes for multiple transactions. The transaction metadata with id 2c4c1eb5-185a-4204-8021-2ea05ba2c2c1 contains a non-existing node. Since the ignore-non-existing-nodes parameter is set to false, the RPC fails."]}],[{"l":"Transaction tracker","p":["The transaction tracker is responsible for saving transaction metadata to the Operational snapshot after a successfully executed commit or checked-commit RPC. Transaction metadata contains information about performed transactions, such as the following:","transaction-id- Identifier for transaction.","type-of-commit-time- Timestamp for either last-commit-time(if the transaction was successful) or failed-commit-time(if the transaction failed). If multiple devices are configured, last-commit-time contains a timestamp for the last update on the last device.","metadata- Items in this field represent nodes configured in the transaction. Each item contains a diff item with additional information.","diff- Items in this field are specific changes. Each item contains a path to changes, data before the change and data after the change. For failed transactions, this information is not included.","topology- Which topology the node is installed on. Either uniconfig or unistore.","Data-before is visible only if data was updated or deleted. Data-after is visible only if data was updated or created.","transaction-tracker]"]},{"l":"Configuration","p":["By default, UniConfig stores transaction metadata. Their removal depends only on the transactions.max-transaction-age parameter."]},{"l":"Show transaction-metadata","p":["The response to this GET request contains all stored transaction metadata, transaction ids and other items such as node id, updated data before and after update, etc."]}],[{"l":"UniConfig Node Manager","p":["If configuration fails for one device, UNM executes an automatic rollback where the previous configuration is restored on all modified devices.","RPC bulk-get","RPC calculate-diff","RPC calculate-git-like-diff","RPC check-installed-nodes","RPC check-nodes-connection","RPC checked-commit","RPC commit","RPC compare-config","RPC get-installed-nodes","RPC health","RPC install-multiple-nodes","RPC is-in-sync","RPC replace-config-with-operational","RPC sync-from-network","RPC uninstall-multiple-nodes","RPC validate","See below for additional information on individual RPCs:","Synchronization from the network reads configurations from devices and stores them as actual states in the Operational datastore.","The northbound API of the UniConfig Manager (UNM) is RPC-driven and provides commit functionality with automatic rollback and synchronization of configurations from the network.","This component is responsible for maintaining the configuration on devices based on their intended configuration. Each device and its configuration are represented as a node in the UniConfig topology. The node's configuration is described using OpenConfig YANG models.","When a commit is called, UNM creates a diff based on the intended state in the Config datastore and the actual state in the Operational datastore. This diff is used as the basis for device configuration. UNM prepares a network-wide transaction that uses unified mountpoints for communication with different types of devices. An additional git-like diff RPC is used to display all changes grouped under root elements in a git-like style."]}],[{"l":"RPC bulk-get","p":["This RPC provides multiple get operations on multiple nodes, paths and contents. It is possible to get data from 'Operational' datastore of UniConfig topology if no content is specified, otherwise data is retrieved from the device directly (over mount-point). Operation is executed over actual/existing UniConfig transaction (immediate-commit model / manual user transaction). Each GET operation is executed in parallel. For mount-point read, it is enough to have node installed on southbound topology (if multiple mount-points with the same node-id exist, user need to specify also connection-type) or just stored in uniconfig database.","RPC input contains a list of node inputs where each consists of mandatory fields such as node-id(UniConfig node identifier) and path, which points to specific subtree. Optional fields are content, connection-type and ignore-missing-data-error. Content determines that the call will be over mount-point to target device datastore config, operational, state, all, where state, all are only for gnmi node. Connection type is needed only in a scenario where multiple southbound mount-points are defined with the same node-id. If data-missing error is not wanted, user may add ignore-missing-data-error and set it to true (default is false) which will display empty config in data leaf.","If get operation on any nodes failed (node is not installed, connection lost, data is not present, ...) the response will display only failed nodes in common RFC8040 errors container. In a success case, the result is structured in node-results format. Each node-result consists of node-id, content(if over mount-point) path and data that contains wanted subtree config."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains valid nodes that are installed in UniConfig topology. Bulk-get will read config on following paths from UniConfig operational datastore."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input contains valid nodes, from which Ri is installed in UniConfig topology, and R2 is installed as southbound only. Bulk-get will read config on following paths from following content target datastores."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input contains two nodes, where R1 is successful and R2 does not provide any config on given path, but ignore-missing-data-error is present."]},{"l":"Failed example","p":["RPC input contains valid node R1 and an invalid node R2, which is not installed in uniconfig topology and content is not specified for that node."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains one node with node-id R1 that has two mount-points (one is mounted over cli and the other over netconf) and no connection-type is specified."]},{"i":"failed-example-2","l":"Failed example","p":["RPC input contains one node with node-id R3 that is not installed in uniconfig under any southbound topology."]},{"i":"failed-example-3","l":"Failed example","p":["If RPC input does not contain any node inputs"]}],[{"l":"RPC calculate-diff","p":["This RPC creates a diff between actual and intended UniConfig topology nodes.","RPC input contains a list of UniConfig nodes for calculating the diff. RPC output contains a list of statements representing the diff. It also matches all input nodes.","If the RPC is called with an empty list of target nodes, a diff is calculated for each node modified in the UniConfig transaction. If a node fails for any reason, the entire RPC fails."]},{"l":"RPC Examples"},{"l":"Successful Example","p":["RPC input contains two target nodes and output contains a list of statements representing the diff."]},{"i":"successful-example-1","l":"Successful Example","p":["If RPC input does not specify any target nodes, calculate-diff is invoked for all nodes touched by the transaction.","or"]},{"i":"successful-example-2","l":"Successful Example","p":["RPC input contains a target node and there is no diff."]},{"l":"Failed Example","p":["RPC input contains a target node that is not installed. RPC output describes the result of the calculate-diff RPC."]},{"i":"failed-example-1","l":"Failed Example","p":["RPC input contains two target nodes, one of which (R2) is not installed. RPC output describes the result of the calculate-diff RPC."]},{"i":"failed-example-2","l":"Failed Example","p":["If RPC input does not contain target nodes and no nodes have been touched, the request results in an error.","or"]}],[{"l":"RPC calculate-git-like-diff","p":["This RPC creates a diff between actual and intended UniConfig topology nodes.","RPC input contains a list of UniConfig nodes to calculate the diff. RPC output contains a list of statements that represent the diff in a git-like style.","If RPC input contains no target nodes, all nodes touched in the transaction are checked. If any node fails, the entire RPC fails."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains two target nodes. RPC output contains a list of statements representing the diff."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input contains no target nodes, therefore all nodes touched in the transaction are checked. RPC output contains a list of all changes on different paths. Multiple changes that occur under the same path are merged together."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input contains a target node and there is no diff."]},{"l":"Failed example","p":["RPC input contains a target node that is not installed. RPC output describes the result of the calculate-diff RPC."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains two target nodes, one of which (R1) is not installed. RPC output describes the result of the calculate-git-like-diff RPC."]},{"i":"failed-example-2","l":"Failed example","p":["If RPC input does not contain target nodes and no nodes have been touched, the request results in an error."]}],[{"l":"RPC check-installed-nodes","p":["This RPC checks if devices specified in the input are installed by looking for the database content of each device. If content is found, the device is installed.","Output of the RPC contains only a list of devices that are present in the UniConfig database. List of devices contains:","topology-id - identifier of the topology in which the device is installed","node-id - device identifier","uniconfig-layer - boolean value indicating whether the device is installed in the UniConfig layer"]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains a device, while no devices are installed."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input contains two devices (R1 and R2), one of which (R1) is installed."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input contains two devices (R1 and R2), both of which are installed."]},{"l":"Failed example","p":["RPC input does not specify any nodes."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input is missing the target-nodes container."]}],[{"l":"RPC check-nodes-connection","p":["This RPC checks if specified devices are reachable (health-check). This is done by session creation, single request execution (most lightweight one), session cleanup.","RPC input specifies target-nodes on which UniConfig checks connection. Each target-node is executed in parallel and whole RPC is outside the uniconfig transaction concept. Output describes only failed health-check operations. Input may also contain connection-timeout which is overall timeout for operation -> establishing session amd single request to device. This timeout is applied individually per each target-node (default value is 5 seconds)."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input specify a device R1 without specifying connection-timeout parameter."]},{"l":"Failed example","p":["RPC input specifies device R1 (reachable), R2 (not reachable). Input also contains connection-timeout parameter set for 3 seconds. Operation was successful only for device R1. Output describes output for failed device R2."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input specifies device R1 which is not installed."]}],[{"l":"RPC checked-commit","p":["This RPC is the trigger for executing the checked configuration. A checked commit is similar to an RPC commit, but it also checks that nodes are in sync with the network before it starts configuration. The RPC fails if any node is out of sync.","RPC output describes the result of the commit and matches all modified nodes in the UniConfig transaction. If a node fails for any reason, the entire RPC fails.","Compared to the commit RPC, there is an additional step between steps 1 and 3:","Lock and validate configured nodes","Check if nodes are in sync with the state on devices","Write configuration to device","Validate configuration","Confirmed commit","Confirming commit (submit configuration)","The following diagram illustrates the check, assuming that configuration fingerprints in the transaction datastore and device are equal.","Fingerprint-based validation is different between steps 1 and 2. For step 1, the goal is to validate if another transaction has already changed the same node by comparing fingerprints in the UniConfig transaction and the database. Step 2 checks that the fingerprint in the transaction is equal to the fingerprint on the device (i.e., if another system or a user directly via the CLI has updated the device configuration since the beginning of the transaction)."]},{"l":"RPC examples"},{"l":"Successful example","p":["The configuration of nodes R1 and R2 has been modified in the transaction. Both nodes are in sync with the actual state on the device.","RPC input invokes all touched nodes."]},{"l":"Failed example","p":["The configuration of nodes R1 and R2 has been modified in the transaction. Both R1 and R2 are in sync with the actual state on the device. Node R1 has failed due to incorrect configuration.","RPC output describes the result of the checked-commit RPC."]},{"i":"failed-example-1","l":"Failed example","p":["The configuration of node R1 has been changed in the transaction. Node R1 is in sync with the actual state on the device. Node R1 has failed on the changed fingerprint.","RPC output describes the result of the checked-commit."]},{"i":"failed-example-2","l":"Failed example","p":["Node R2 has lost connection."]},{"i":"failed-example-3","l":"Failed example","p":["If RPC input does not contain target nodes and no nodes have been touched, the request results in an error."]}],[{"l":"RPC commit","p":["1. Lock and validate configured nodes","2. Write configuration to device","3. Validate configuration","4. Confirmed commit","5. Confirming commit (submit configuration)","Commit invokes all nodes touched in the transaction. There are no target nodes in the RPC input. Steps 3 and 4 only apply to nodes that support these operations.","Configuration phase","Confirmed commit","Confirmed commit: Lock the device configuration so that no other transaction can touch the device. This phase can be skipped with the do-confirmed-commit flag.","Confirming commit","Confirming commit (submit configuration): Persist all changes on devices and in the PostgreSQL database. The UniConfig transaction is closed.","If a node fails for any reason, the entire RPC fails. After the commit RPC, the UniConfig transaction is closed regardless of the result.","If one of the nodes uses a confirmed commit (step 4) that does not fail, it is necessary to issue the submitted configuration (step 5) within the timeout period. Otherwise the node configuration issued by the confirmed commit is reverted to its state before the confirmed commit (i.e., confirmed commit makes only temporary configuration changes). The default timeout period is 600 seconds(10 minutes), which can be changed in the installation request.","Lock and validate configured nodes: Lock all modified nodes using PostgreSQL advisory locks and validate fingerprints. If another transaction attempts to commit overlapping nodes or another transaction has already changed one of the nodes, commit will fail at this step.","Locking nodes","Rollback operation","Rollback: Restore the configuration to its previous state if the configuration process fails. When configuring multiple devices in a single transaction and the process fails on one particular device, the rollback procedure is applied to all touched devices. This is done with the auto rollback procedure, which is by enabled by default. The procedure can be disabled with the do-rollback flag in the RPC input, in which case only failed devices are rolled back.","The configuration of nodes consists of the following phases:","The external application stores the intended configuration under nodes in the UniConfig topology. The trigger for executing the configuration is an RPC commit. RPC output describes the result of the commit.","The following diagrams describe all five commit steps in more detail:","The next diagram shows the rollback procedure that must be executed after a failed commit on nodes that have already been configured and do not support the candidate datastore.","The skip-unreachable-nodes flag controls whether unreachable nodes are skipped when the RPC commit is sent. When set to true, nodes that are not reachable are skipped and others are configured. The default value is false.","Validate configuration: Validate the written configuration from the view of constraints and consistency. This phase can be skipped with the do-validate flag.","Validation phase","Write configuration to device: Push calculated changes onto the device without committing these changes."]},{"l":"RPC examples"},{"l":"Successful example","p":["UniConfig commits nodes R1 and R2 that have been changed in the actual transaction."]},{"i":"successful-example-1","l":"Successful example","p":["Nodes R1 and R2 have been changed. RPC input includes the flag to disable the confirmed-commit phase. UniConfig commits all touched nodes."]},{"i":"successful-example-2","l":"Successful example","p":["If there are no touched nodes, the request finishes successfully."]},{"l":"Failed example","p":["Node R1 has failed because it failed the validation step."]},{"i":"failed-example-1","l":"Failed example","p":["Node R1 has failed because the confirmed commit failed. The validation step is skipped because of the do-validate flag."]},{"i":"failed-example-2","l":"Failed example","p":["Node R1 has failed because of the time delay between confirmed commit and submitted configuration."]},{"i":"failed-example-3","l":"Failed example","p":["Node R1 has failed due to incorrect configuration."]},{"i":"failed-example-4","l":"Failed example","p":["Node R1 has lost connection."]},{"i":"failed-example-5","l":"Failed example","p":["Node R1 has failed because of incorrect configuration. In this case validation, confirm-commit and auto-rollback are disabled.","Since auto-rollback is disabled, configuration of R1 was successful. However, this can only be done if the validation and confirm-commit phases were successful or skipped; otherwise configuration of the R1 device would also fail."]},{"i":"failed-example-6","l":"Failed example","p":["Configuration of nodes R1 and R2 have been modified in the transaction, and both are in sync with the actual state on the device. Connection to node R2 has been lost. RPC input has the flag to skip unreachable nodes set to true.","The result of the commit RPC describes success for node R1 and includes a list of unreachable nodes."]}],[{"l":"RPC compare-config","p":["This RPC is a combination of the sync-from-network and calculate-diff RPCs. If one of those RPCs fails, this one also fails with no changes made.","The purpose of this RPC is to synchronise configurations from network devices to UniConfig nodes in the Configuration datastore of the UniConfig transaction.","RPC input contains a list of UniConfig nodes whose configuration is compared to the actual configuration in the transaction. RPC output describes the result of the RPC and matches all input nodes with a list of statements representing the diff."]},{"l":"RPC examples"},{"l":"Successful example"},{"i":"successful-example-1","l":"Successful example","p":["If RPC input does not specify target nodes, the configuration of all nodes touched in the transaction is compared to the synced device configuration."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input includes a target node and there is no diff."]},{"l":"Failed example","p":["RPC input has two target nodes, one of which (R2) is not installed. The output describes the result of sync-from-network."]},{"i":"failed-example-1","l":"Failed example","p":["If RPC input does not contain target nodes and there are no touched nodes, the request results in an error."]}],[{"l":"RPC connect-node","p":["This RPC creates a connection to a device that is already installed. The connection is created outside of a transaction, so that the connection stays up even without active transactions.","Note that the transaction used in this RPC is created internally, so that no user-created transactions are used.","The connect-node RPC also supports connections to stream nodes. These are possible only if a stream node is already defined in the install-node RPC. The most common use case is when a subscription stream is disconnected and a reconnection is required.","The connect-node RPC only works on local Uniconfig nodes in a cluster."]},{"l":"RPC parameters","p":["node-id(mandatory) - ID of a node. In case of a stream node, the node consists of a device node and a stream name ( device node_stream name, for example R1_NETCONF).","max-connection-attempts- Maximum number of connection attempts. The default value is 1.","between-attempts-timeout- Timeout between connection attempts in seconds. The default value is 60 seconds."]},{"l":"CLI Shell","p":["The connect-node RPC is also included in UniConfig shell. As it takes node-id as input, the shell only suggests nodes that are relevant to this RPC (nodes that are installed in UniConfig but are not yet connected)."]},{"l":"RPC examples","p":["For all examples, assume that the install RPC request included the following parameters:"]},{"i":"successful-example---request-for-a-device-node","l":"Successful example - Request for a device node"},{"i":"successful-example---request-for-a-stream-node","l":"Successful example - Request for a stream node","p":["Note that waiting for a stream node to be connected is currently not supported. This means that even if the response code is 200, the connection is not necessarily successful as well. To test if the connection is successful or in the process of connecting, call the RPC again (see example below) or examine the UniConfig logs."]},{"i":"failed-example---node-is-already-connected","l":"Failed example - Node is already connected"},{"i":"failed-example---node-is-in-the-process-of-connecting","l":"Failed example - Node is in the process of connecting"},{"i":"failed-example---node-does-not-exist","l":"Failed example - Node does not exist"}],[{"l":"RPC disconnect-node","p":["This RPC closes connection to a device. If a node is associated with multiple transactions, it will be removed from all of them.","Note that the transaction used in this RPC is created internally, so that no user-created transactions are used.","The disconnect-node RPC also supports disconnecting stream nodes.","Note that the disconnect-node RPC only works on local Uniconfig nodes in a cluster."]},{"l":"RPC parameters","p":["node-id(mandatory) - ID of a node. In case of a stream node, the node consists of a device node and a stream name ( device node_stream name, for example R1_NETCONF)."]},{"l":"UniConfig shell","p":["The disconnect-node RPC is also included in UniConfig shell. As it takes node-id as input, the shell only suggests nodes that are relevant to this RPC (nodes that are already connected)."]},{"l":"RPC examples","p":["For all examples, assume that the install RPC request included the following parameters:"]},{"i":"successful-example---request-for-a-device-node","l":"Successful example - Request for a device node"},{"i":"successful-example---request-for-a-stream-node","l":"Successful example - Request for a stream node"},{"i":"failed-example---node-not-connected","l":"Failed example - Node not connected","p":["The specified node is not connected or does not exist in the database."]},{"i":"failed-example---node-does-not-exist","l":"Failed example - Node does not exist"}],[{"l":"RPC get-installed-nodes","p":["This RPC returns all installed devices from a specified topology.","If no topology is specified, the output may contain devices from multiple topologies (CLI, NETCONF, gNMI). In this case, devices must be installed with the install request parameter uniconfig-config:install-uniconfig-node-enabled set to true. If no topology is specified, the RPC looks for nodes installed in the UNICONFIG topology by default."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input does not specify a topology, and device R1 is installed in the NETCONF topology. If the install request includes the parameter“uniconfig-config:install-uniconfig-node-enabled”:“true”, the device is installed in the UNICONFIG topology instead."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input does not specify a topology, and device R1 is installed in the NETCONF topology. If the install request includes the parameter“uniconfig-config:install-uniconfig-node-enabled”:“false”, the device is not installed in the UNICONFIG topology."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input specifies the GNMI topology, and device R1 is installed in that topology."]},{"i":"successful-example-3","l":"Successful example","p":["RPC input specifies the CLI topology, but no devices are installed in that topology."]}],[{"l":"RPC health","p":["This RPC checks if UniConfig is running. If database persistence is enabled, it also checks the database connection."]},{"l":"RPC examples","p":["RPC input is empty. RPC output contains the result of the operation.","Response if database persistence is enabled and the database connection is valid:","Response if database persistence is enabled and database connection is not valid:"]}],[{"l":"RPC install-multiple-nodes","p":["This RPC installs multiple devices at once using the default install-node RPC. Devices are installed independently in parallel.","If two nodes are being installed and one node fails, the second node is still installed. If at least one node fails, the RPC response describes the result for failed nodes only."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains two devices (R1 and R2)."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input contains two devices (R1 and R2). Device R2 uses two different protocols."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input contains two devices (R1 and R2). Device R2 is already installed using the CLI protocol."]},{"l":"Failed Example","p":["RPC input does not specify a node-id."]},{"i":"failed-example-1","l":"Failed Example","p":["RPC input contains two devices with the same node-id."]}],[{"l":"RPC is-in-sync","p":["This RPC is used to verify that specified nodes are in sync with the current state in the Operational datastore of the UniConfig transaction.","Verification is performed by comparing configuration fingerprints. The configuration fingerprint on the device is compared with the last configuration fingerprint saved in the Operational datastore. A fingerprint is usually represented by a configuration timestamp or the last transaction ID.","The is-in-sync feature is supported only for device types that have implemented translation units for the frinx-configuration-metadata OpenConfig module (using CLI units, NETCONF units or UniConfig-native metadata units).","RPC input contains a list of UniConfig nodes for which verification should be performed (the target-nodes field). The response contains the operation status for each node specified in the input. If the operation fails, it is because the specified node has not been successfully installed, the connection is lost or UniConfig does not support reading the configuration fingerprint from that specific device type. Calling the RPC with an empty list of target nodes invokes the RPC for each node modified in the UniConfig transaction.","Possible RPC outputs per target node:","status field with value complete and is-in-sync boolean flag set: The is-in-sync feature is supported and configuration fingerprints have been successfully compared.","status field with value fail, error-type field with value no-connection and corresponding error-message: The unified mountpoint does not exist because the connection was lost or the node is not mounted.","status field with value fail, error-type field with value uniconfig-error and corresponding error-message: Reading the fingerprint from the Operational datastore or unified mountpoint has failed, or parsing configuration metadata is not supported for the device type.","Executing RPC is-in-sync does not modify the Operational datastore. The configuration fingerprint stored in the Operational datastore is not updated. Use RPC sync-from-network to update the last configuration fingerprint and the actual configuration state."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains valid nodes for which synchronization status should be checked (R1 is synced, R2 is not synced)."]},{"i":"successful-example-1","l":"Successful example","p":["If RPC input contains no target nodes, all touched nodes are invoked."]},{"l":"Failed example","p":["RPC input contains an invalid node (R1), which does not support fingerprint comparisons (metadata translation unit has not been implemented for this device)."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains two nodes. Node R1 is valid and synced, R2 is not installed. If one node is invalid, the UniConfig operation fails with an error entry in the response."]},{"i":"failed-example-2","l":"Failed example","p":["If RPC input does not contain any target nodes and there are no touched nodes, the request results in an error."]}],[{"l":"RPC replace-config-with-operational","p":["This RPC replaces UniConfig topology nodes in the Configuration datastore with nodes from the Operational datastore.","RPC input contains a list of UniConfig nodes to replace. RPC output describes the result of the operation and matches all input nodes.","If the RPC is invoked with an empty list of target nodes, the operation is invoked for all nodes modified in the UniConfig transaction. If any node fails, the entire RPC also fails."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input has two target nodes. RPC output contains the result of the operation."]},{"i":"successful-example-1","l":"Successful Example","p":["If RPC input does not contain target nodes, the configuration of all touched nodes is replaced by the operational state."]},{"l":"Failed example","p":["RPC input contains a list of target nodes. Node R1 has not been installed. RPC output contains the result of the operation."]},{"i":"failed-example-1","l":"Failed example","p":["If RPC input does not contain any target nodes and there are no any touched nodes, the request results in an error."]}],[{"l":"RPC sync-from-network","p":["This RPC synchronizes configurations from network devices to UniConfig nodes in the Operational datastore of the UniConfig transaction.","RPC input contains a list of UniConfig nodes whose configuration should be refreshed within the network. RPC output describes the result and matches all input nodes.","Calling the RPC with an empty list of target nodes syncs the configuration of all nodes modified in the UniConfig transaction. If any node fails, the entire RPC also fails.","If the network device was installed as southbound-only (with the uniconfig-config:install-uniconfig-node-enabled parameter set to false), the RPC syncs the device to the UniConfig topology and rewrites the above-mentioned parameter to true."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains nodes whose configuration should be refreshed.","If RPC input contains no target nodes, all nodes touched in the transaction are synced."]},{"l":"Failed example","p":["RPC input contains a list of nodes whose configuration should be refreshed. Node R2 is not installed."]},{"i":"failed-example-1","l":"Failed example","p":["If RPC input does not contain any target nodes and there are no touched nodes, the request results in an error."]}],[{"l":"RPC sync-to-network","p":["This RPC is a combination of the sync-from-network and commit RPCs. If one of those RPCs fails, this RPC also fails without making any changes.","The purpose of this RPC is to synchronize configurations from UniConfig nodes in the Configuration datastore of the UniConfig transaction to network devices.","RPC input contains a list of UniConfig nodes to be updated on a network device. RPC output describes the results and matches all input nodes.","Calling this RPC with an empty list of target nodes syncs the configuration of all nodes modified in the UniConfig transaction. If any node fails, the entire RPC also fails. The admin-state of UniConfig nodes specified in the input must be set to unlocked."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains a list of nodes to be updated on the corresponding network device."]},{"i":"successful-example-1","l":"Successful example","p":["If RPC input contains no target nodes, the operation is invoked for all nodes touched in the transaction."]},{"l":"Failed example","p":["If the admin-state for some input nodes is not set to unlocked, the request results in an error that includes a list of nodes with the wrong state."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains one node with an incorrect admin-state."]},{"i":"failed-example-2","l":"Failed example","p":["RPC input contains two nodes. Node R1 is valid and R2 has not been installed. If at least one node is invalid, the entire operation fails."]},{"i":"failed-example-3","l":"Failed example","p":["If RPC input contains no target nodes and there are no touched nodes, the request results in an error."]}],[{"l":"RPC uninstall-multiple-nodes","p":["This RPC uninstalls multiple devices at once using the default uninstall-node RPC. Devices are uninstalled independently in parallel.","If two nodes are being uninstalled and one node fails, the second node is still uninstalled. If at least one node fails, the response describes the result for failed nodes only."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains two devices (R1 and R2)."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input contains two devices (R1 and R2). Device R2 is installed on two different protocols."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input contains two devices (R1 and R2). Device R2 is already uninstalled on the CLI protocol."]},{"l":"Failed example","p":["RPC input does not specify a node-id."]}],[{"l":"RPC validate","p":["The external application stores the intended configuration under nodes in the UniConfig topology. The configuration can be checked for validity. This RPC is the trigger for validating a configuration.","RPC input contains a list of UniConfig nodes whose configuration should be validated. RPC output describes the result of the validation and matches all input nodes.","If the RPC is called with an empty list of target nodes, all nodes modified in the UniConfig transaction are validated.","The configuration of nodes follows these steps:","Open transaction to device","Write configuration","Validate configuration","Close transaction","If any node fails in step 3 (validation), the entire RPC also fails.","Validation (step 3) only applies to nodes that support this operation.","The diagram below illustrates the RPC:"]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input has two target nodes. RPC output describes the result of successful validation."]},{"i":"successful-example-1","l":"Successful example","p":["If RPC input does not specify any target nodes, all nodes touched in the transaction are validated."]},{"l":"Failed example","p":["RPC input has one target node. RPC output describes the result of the validation. In this case, the node has failed because validation has failed."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains two nodes. Node R1 is valid and R2 is not installed. If at least one node is invalid, the entire operation fails."]},{"i":"failed-example-2","l":"Failed example","p":["If RPC input does not contain any target nodes and there are no touched nodes, the request results in an error."]}],[{"l":"UniConfig properties","p":["UniConfig properties are application properties used to configure the application. They can be separated into three groups:","Runtime mutable properties can be modified in runtime (using the update-properties RPC), their changes take effect in runtime and the properties are persisted in the database.","Database persisted properties include all runtime mutable properties and some additional properties. These properties are stored in the database, which is always their primary source. With UniConfig Cloud Config, they remain constant across UniConfig instances in the same cluster and cannot be overridden via the application properties file.","Regular UniConfig properties comprise all the remaining properties. These properties can always be changed using the application.properties file and can differ between UniConfig instances.","Database persisted properties can be changed or read in application runtime without restarting UniConfig by using UniConfig Cloud Config and the following RPCs:","RPC read-properties","RPC update-properties"]}],[{"l":"RPC read-properties","p":["This RPC reads default properties from the database. If a specified property key does not exist in the database, the key is returned under Ignored keys. The RPC works the same whether UniConfig Cloud Config is enabled or disabled.","read","If UniConfig Cloud Config is disabled, this RPC reads property values from the database. These values may differ from values in the application instance."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains default property keys."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input contains properties that are not default properties or are private(crypto keys and crypto types)."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input consists of properties that do not exist in the database."]}],[{"l":"RPC update-properties","p":["The update-properties RPC is used to update property values. If UniConfig Cloud Config is enabled, it also calls Refresh Bus Endpoint to update properties in runtime for all connected UniConfig instances.","The RPC only updates default properties, except for crypto properties for which there are separate RPCs ( change-encryption-status and change-encryption-keys).","RPC sequence diagram with UniConfig Cloud Config enabled:","update-with-ucc","If UniConfig Cloud Config is disabled, the RPC only updates property values in the the database. The application instance continues to use the old property values, which can cause confusion.","Additionally, if a new UniConfig instance is started after properties have been updated, that instance will use the updated property values from the database. UniConfig instances will therefore use different values for the same property, as described in the diagram below.","We recommend that you use this RPC with UniConfig Cloud Config. The exception is callbacks.access-token, which is always up to date.","RPC sequence diagram with UniConfig Cloud Config disabled:","update-without-ucc"]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains the default properties with correct values."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input contains the crypto default property."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input contains an incorrect property name."]},{"l":"Failed example","p":["RPC input contains default properties with incorrect values."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains default properties with incorrect values."]}],[{"l":"Utilities","p":["Utilities are simple programs that are part of the UniConfig distribution. After unpacking and building the distribution, utilities can be found in the 'utils' subdirectory."]},{"l":"YANG Packager"},{"l":"Difference between OpenAPI specifications"}],[{"l":"Difference between OpenAPI specifications","p":["The Uniconfig distribution includes a program for checking the difference between OpenAPI specifications. After building and unpacking the distribution, you can find the program in the utils directory as a shell script called show_swagger_diff.sh.","The program uses OpenAPI-diff to generate OpenAPI differences."]},{"l":"Usage","p":["The ./show_swagger_diff.sh script contains four arguments. Each one has its own identifier, so you can give arguments in any order. All arguments are optional as default values are included for each one.","--former, -f /path/to/former/yaml/files- Path to previous OpenAPI specifications (.yaml files). The default path is openapi_diff/old.","--new, -n /path/to/new/yaml/files- Path to new OpenAPI specifications (.yaml files). The default path is openapi_diff/new.","--output, -o /path/to/output- Path to HTML output file with differences. The default path is openapi_diff.","-s- Silent printing, includes less information.","The script also includes a simple help facility. There are two ways to view the help text:","./show_swagger_diff.sh -h","./show_swagger_diff.sh --help","The script only accepts YAML files."]},{"l":"Example use case"},{"l":"Default usage","p":["This example shows basic usage of the script with and without optional arguments. Open a terminal and the ../utils directory, and run the following command:","Alternatively:"]},{"l":"Usage with non-existent input path","p":["This example shows basic usage of the script where some specified input directories do not exist. Open a terminal and the ../utils directory, and run the following command:"]}],[{"l":"YANG packager"},{"l":"Introduction","p":["YANG packager is a simple program which is part of the UniConfig distribution. User can finds it in the utils/ directory after building and unpacking the UniConfig distribution. User can use it by simple shell script called'convertYangsToUniconfigSchema.sh'. YANG packager is responsible for:","validation of user-provided YANG files","copying valid YANG files to the user-defined directory","informing the user about conversion process"]},{"l":"Usage","p":["-d /path/to/default- optional argument. Sometimes some YANG files need additional dependencies that are not provided in source directories. In this case it is possible to use path to the 'default' directory which contains additional YANG files. If there is this missing YANG file, YANG packager will use it.","-enableSwagger- optional argument. Path to file that enables OpenAPI generation.","-g- optional argument. Path to directory where generated Java sources with constants from YANG elements are saved. By default, generation of Java files is disabled.","-i /path/to/sources- required argument. User has two options for where the path can be directed:","-jd- optional argument. Flag that enables to generate java documentation on data elements.","-o /path/to/output-directory- required argument. User can define path where he wants to save valid YANG files. If the output directory exists, it will be replaced by a new one.","-pn- optional argument. Custom package name of generated classes.","-px- optional argument. Flag that enables prefix for generated constants names inside generated classes.","-r- optional argument. Selection of repositories inside source directory with files or file with defined names of directories which contains files, from which constants will be generated.","-s /path/to/skip-list- optional argument. User can define YANG file names in text file that he does not want to include in conversion process. This file must only contain module names without revision and .yang suffix.","-to-file- optional argument. When user uses this flag, then YANG packager also saves the debug output to a file. This file can be found on a same path as output-directory. It will contain suffix '-info' in its name. If the output directory is called 'output-directory', then the file will be called 'output-directory-info'.","./convertYangsToUniconfigSchema --help","./convertYangsToUniconfigSchema -h","Bash script ./convertYangsToUniconfigSchema also includes simple help facility. There are two options how to show the help text:","If compilation process detected some invalid YANG files then output directory will not be created. In this case, user has to fix invalid YANG files or use a combination of \"-d\" and \"-s\" arguments.","Script ./convertYangsToUniconfigSchema contains four arguments. Each one has its own identifier so user can use any order of arguments. Two arguments are required, namely the path to resources that contain YANG files and the path to the output directory where user wants to copy all valid YANG files. Other three arguments are optional. First one is the path to the\"default\" directory which contains some default YANG files, second one is the path to the \"skip-list\" and last one is a \"-to-file\" flag, which user can use when he wants to write a debug output to file.","The user is responsible for the validity of YANG files in the default directory. These files are not checked by YANG package.","to the directory that contains YANG files and other sub-directories with YANG files","to the text-file that contains defined names of directories. These defined directories have to be stored on the same path as text-file."]},{"l":"Example use-case"},{"l":"Basic usage 1","p":["This is basic usage of the script where only mandatory arguments are used. In this case, there is a directory with YANG files used as source. All files in source directory are valid YANG files. Open a terminal, go to the ../utils directory and run command:"]},{"l":"Basic usage 2","p":["This is basic usage of the script where only mandatory arguments are used. In this case, there is directory with YANG files used as source. Source directory also contains one invalid YANG file with missing import. Open a terminal, go to the ../utils directory and run command:"]},{"l":"Basic usage 3","p":["This is basic usage of the script where only mandatory arguments are used. In this case, there is directory with YANG files used as source. Source directory also contains one non-yang file. Open a terminal, go to the ../utils directory and run command:"]},{"l":"Usage with default directory","p":["This is usage with path to default directory that contains one YANG file openconfig-mpls. Source directory also contains one invalid YANG file 'cisco-xr-openconfig-mpls-deviations.yang' with missing import 'openconfig-mpls'. This missing import is loaded from default directory. Open a terminal, go to the ../utils directory and run command:"]},{"l":"Usage with skip-list","p":["This is usage with path to skip-list text file that contains one YANG file name cisco-xr-openconfig-mpls-deviations. This YANG file will not be included in the conversion process. Open a terminal, go to the ../utils directory and run command:"]},{"l":"Usage with text-file as a source","p":["In this example a path to text-file with defined names of source directories is used.","Open a terminal, go to the ../utils directory and run command:"]},{"i":"usage-with--to-file-flag","l":"Usage with -to-file flag","p":["This is usage where output is also printed to file. User can find output information file on the path /path/to/output-info.","Open a terminal, go to the ../utils directory and run command:"]},{"i":"usage-with-text-file-as-a-source-and--to-file-flag","l":"Usage with text-file as a source and -to-file flag","p":["In this example a path to text-file with defined names of source directories is used and also flag for print outputs to files. User can find output information files on paths /path/to/output/directory-1-info and /path/to/output/directory-2-info","Open a terminal, go to the ../utils and run command:","Content of text-file"]},{"i":"usage-with--enableswagger-flag","l":"Usage with '-enableSwagger' flag","p":["In this example a path to a text-file with defined names of source directories is used. A flag to print outputs to files and a flag to enable swagger for OpenAPI files generation. The swagger configuration file is located at ../utils/config/swagger-config.json. Swagger output file / files are generated per directory, and they are located in the output directory. The user can find output information files on paths /path/to/output/directory-1-info and /path/to/output/directory-2-info.","Open a terminal, go to the ../utils directory. Run the command:","Additional parameters are available for swagger generation that further customise the OpenAPI file / files. These parameters are located at the beginning of the page.","The output then looks like this:"]},{"i":"error---source-directory-does-not-exist","l":"Error - source directory does not exist","p":["User-defined source directory does not exist.","Open a terminal, go to the ../utils directory and run command:"]},{"i":"error---source-directory-is-empty","l":"Error - source directory is empty","p":["User-defined source directory is empty. Open a terminal, go to the ../utils directory and run command:"]},{"i":"error---sources-defined-in-text-file","l":"Error - sources defined in text-file","p":["One directory defined in the text-file is empty and other one does not exist.","Open a terminal, go to the ../utils and run command:","Content of text-file"]}],[{"l":"Admin State","p":["Admin state is used to lock, unlock or southbound-lock devices. Modification of data on those devices is allowed or forbidden accordingly.","Three different states are currently supported:","LOCKED - When a device is administratively locked, it is not possible to modify its configuration and no changes are ever pushed to the device.","UNLOCKED - The device is assumed to be operational. For all changes, an attempt is made to send them southbound. This is the default state for newly created devices.","SOUTHBOUND_LOCKED - It is possible to configure the device, but no changes are sent to the device. Useful when pre-provisioning devices.","The admin state is automatically added to the device during installation. You can specify an admin state for a device as follows:","uniconfig-config:admin-state: unlocked","An RPC is available for changing admin state after installation."]},{"l":"RPC example","p":["RPC input contains the device name and intended admin state."]},{"i":"rpc-example-1","l":"RPC example","p":["GET request to get the actual state of the device."]},{"l":"RPC failed example","p":["The device is in the locked admin state, and the user attempts to modify data on the device."]}],[{"l":"Build-and-Commit Model","p":["The Build-and-Commit model is based on explicitly creating a transaction, invoking operations in the scope of this transaction and, finally, committing or closing the transaction. The transaction represents a session between client and UniConfig instance.","Using explicitly created transactions has multiple advantages in comparison to the Immediate Commit Model:","Multiple operations and modifications can be invoked in a single transaction while keeping transactions isolated.","Most UniConfig operations, such as calculate-diff and commit, have no use in the Immediate Commit Model. They are valuable only if the Build-and-Commit Model is used.","The transaction allows a client to identify if it still communicates with the same UniConfig instance (this property is usable in the clustered deployment). If the UniConfig instance does not know about the transaction, the request fails because the transaction expired, is closed or was never created in the first place."]},{"l":"Configuration","p":["Configurations related to UniConfig transactions are placed in the config/application.properties file under the transactions container."]},{"l":"Optimistic locking mechanism","p":["Race conditions between transactions that are committed in parallel and contain changes to the same nodes (uniconfig, unistore, snapshot or template nodes) are solved using the optimistic locking mechanism. The configuration of a node can be modified in parallel from two transactions, but only the first committed transaction will succeed. The commit for the second transaction will fail.","UniConfig uses two different techniques to detect conflicts during commit or checked-commit operations:","Comparing configuration fingerprints- The fingerprint value for an altered node is updated at the end of the commit operation. At the beginning of a commit operation, UniConfig compares the value of the actual fingerprint in the database with the value of the fingerprint read before the first CRUD operation done in the transaction and the last synced fingerprint (updated after execution of the sync-from-network RPC). If the actual fingerprint in the database is equal to the fingerprint read before the first CRUD operation or the last synced fingerprint, the commit operation can continue. Otherwise, an error is returned without touching any devices in the network.","Per-node advisory locks- Comparison of configuration fingerprints is reliable if transactions are committed one after another. However, such serialization cannot be achieved in the clustered environment as UniConfig instances are not coordinated. If two transactions are committed at the same time and both assume that configuration fingerprints haven't been updated by another transaction, both transactions may start to push changes to network devices simultaneously. To prevent this scenario, UniConfig locks the node in the PostgresSQL database using transaction-level advisory locks at the beginning of the commit operation. If another transaction tries to lock the same node, its attempt will fail, and the second transaction cannot enter the critical section but will fail. Locks are automatically released at the end of the transaction( commit RPC closes the transaction).","All possible scenarios are captured in the following diagrams.","Optimistic locking"]},{"l":"Dynamic mountpoints","p":["Mountpoints are created only when UniConfig needs to read / write some data from / to device and lifecycle of mountpoint is bounded by lifecycles of transactions that use the mountpoint. If some mountpoint is not used by any transaction, then UniConfig automatically closes this mountpoint - associated operational data on southbound layer and connection to device are removed.","The first diagram demonstrates mounting of 2 devices which are used by 1 transaction - after this transaction is closed, both mountpoints are closed. The second diagram shows scenario in which 2 transactions share 1 of 2 mountpoints - after the first transaction is closed, 1 of the mountpoints is not closed since the second transaction still may communicate with corresponding device."]},{"l":"Creation of transaction","p":["Transaction can be created using create-transaction RPC. RPC doesn't specify input body and also returns response without body. Response additionally contains Set-Cookie header with UNICONFIGTXID key and corresponding value - transaction identifier that conforms RFC-4122 Universally Unique IDentifier (UUID) format.","Process of transaction creation is depicted by following sequence diagram.","create-transaction RPC","UniConfig is performing following steps after calling create-transaction RPC:","Creation of connection to database system - Connection is created with disabled auto-commit - enabling transactional features. UniConfig uses 'read committed' isolation level.","Creation of database transaction - It provides access to remote PostgreSQL database. Using database transaction it is possible to read committed data, read uncommitted changes created by this transaction and write modifications to database. Data read at the first access to some resource is cached to datastore transaction - when some component tries to access the same resource again, it is read only from datastore transaction. Data is written to database transaction at invocation of commit/checked-commit RPC.","Creation of datastore read-write transaction - It provides access to OPER and CONFIG datastores bound to this transaction. Datastore is used only as a cache between application and PostgreSQL database, and it resides only in the memory allocated to UniConfig process. Datastore transaction is never committed - cache is trashed at the end of the transaction life.","Registration of transaction - Transaction is always bound to 1 specific UniConfig instance."]},{"l":"Successful example","p":["The following request shows successful creation of UniConfig transaction. Response contains Set-Cookie header with UNICONFIGTXID key and value."]},{"l":"Failed example","p":["The most common reason for failed creation of UniConfig transaction is reached maximum number of open transactions that is limited by('maxDbPoolSize' - 'maxInternalDbConnections') database connection pool setting. In that case, UniConfig returns response with 500 status code."]},{"l":"Transaction idle-timeout","p":["Create-transaction RPC can be used with optional query parameter called timeout. This parameter is used to override global idle timeout for transaction created by this RPC call. After transaction inactivity for specified time transaction will be automatically cleaned. Value of this parameter is whole number and defines time in seconds."]},{"l":"Dedicated session to device","p":["By default, UniConfig shares a southbound session to a network device if multiple UniConfig transactions use the same device via the same management protocol. This behaviour can be disabled using the dedicatedDeviceSession query parameter, which accepts a boolean value. Afterwards the UniConfig transaction will create a dedicated session to the device, which is used only by one transaction and is closed immediately after committing or closing the transaction.","Dedicated sessions to a device are useful when:","The evice is not able to process requests in parallel via the same session.","The device is able to process requests in parallel via same session, but does not process them in parallel, decreasing processing performance."]},{"l":"Audit parameters","p":["Uniconfig can pass audit parameters to network devices when a Uniconfig transaction is committed.","Following implementations are currently supported on southbound:","Tailf confD extension (NETCONF)","On the northbound, the parameters are exposed as HTTP headers:","AUDIT_USER","AUDIT_COMMENT"]},{"l":"Invocation of CRUD operation in transaction","p":["CRUD operations for modification or reading node configuration can be invoked in the specific transaction by appending UNICONFIGTXID (key) with UUID of transaction (value) to Cookie headers. In that case, operation will be invoked only in the scope of single transaction - changes are not visible to other transactions until this transaction is successfully committed.","Next diagram describes execution of CRUD operation from RESTCONF API. It shows also difference between datastore and database transaction - data is read from database only at the first access to some data (for example, node configuration). After that, this configuration is cached inside temporary datastore transaction - goal is to improve performance by limiting transferring data between UniConfig and PostgreSQL. Next access to same configuration can be evaluated under in-memory datastore.","Invocation of CRUD"]},{"i":"successful-example-1","l":"Successful example","p":["The following request demonstrates reading of some configuration from uniconfig topology, junos node in the transaction with ID'd7ff736e-8efa-4cc5-9d27-b7f560a76ff3'."]},{"i":"failed-example-1","l":"Failed example","p":["Trying to use non-existing UniConfig transaction results in 422 status code (Unprocessable Entity)."]},{"l":"Invocation of RPC operation in transaction","p":["RPC operation can be invoked in the specific transaction the same way as CRUD operation - by specification of UNICONFIGTXID in the Cookie header.","There are few differences between CRUD and RPC operations from the view of transactions:","Commit, checked-commit, and close-transaction RPCs can state of the transaction. Create-transaction RPC is reserved for creation of transaction.","Not all RPC operations that are exposed by UniConfig use dedicated transactions - in that case, these RPCs just ignore explicitly specified transaction and either don't work with transactions at all or create transaction internally (examples: install-node, uninstall-node RPC).","There are also transaction-aware operations that directly leverage properties of transactions. For example, if some UniConfig RPC is invoked with empty list of target nodes, then operation is automatically applied to all modified nodes in the transaction(calculate-diff RPC with empty target nodes computes diff for all modified nodes in the transaction).","Following diagram shows execution of random RPC in the specified transaction.","Invocation of RPC"]},{"i":"successful-example-2","l":"Successful example","p":["Invocation of calculate-diff RPC in the transaction which contains modifications done on the 'junos' node."]},{"i":"failed-example-2","l":"Failed example","p":["Invocation of calculate-diff RPC with transaction ID that has wrong format."]},{"l":"Closing transaction","p":["There are 2 options how transaction can be closed:","close-transaction RPC - Explicit closing of transaction that results in dropping of all changes done in the transaction.","commit/checked-commit RPC - After execution of commit operation, transaction is automatically closed (despite of commit result). Behaviour of commit and checked commit RPC is described in better detail under the 'UniConfig Node Manager' section.","Close-transaction RPC doesn't contain body, only Cookie header with UNICONFIGTXID property pointing to transaction that user would like to close. Response contains information if transaction has been successfully closed.","Following sequence diagrams describe close-transaction procedure. It is split into 2 diagrams to improve readability and to reuse some parts from other diagrams.","close-transaction RPC","Clean orphaned mountpoints","Briefly depicted most important actions:","Loading UniConfig transaction from registry by provided transaction ID that is extracted from Cookie header.","Closing connection to database.","Cancellation of database transaction.","Cancellation of datastore read-write transaction.","Unregistration of transaction from local registry.","Unmounting nodes that are not referenced by any UniConfig transaction - connection to device is closed and representing southbound / Unified mountpoints are removed together with state data.","After transaction is closed, it cannot be used by any other operation - user must create a new transaction in order to use build-and-commit model."]},{"i":"successful-example-3","l":"Successful example","p":["Closing existing transaction using close-transaction RPC. Response doesn't body, only status code 200."]},{"i":"failed-example-3","l":"Failed example","p":["If transaction has already been closed, user will receive response with JSON body containing error message."]},{"l":"Transaction cleaner","p":["Transaction cleaner is used for automatic closing of transactions that are open longer then specified timeout value ('transactionIdleTimeOut' or 'maxTransactionAge' setting in the configuration). Transaction resets her time setting 'transactionIdleTimeOut' after invoking CRUD, RPC operation, and is still valid for time specified in value of setting. This mechanism effectively suppresses application-level errors - open transactions are not closed at the end of the workflow.","Next sequence diagram describes cleaning process. Referenced diagram'Close transaction' is placed in the previous 'Closing transaction' section."]},{"l":"Use cases"},{"l":"Modification of different devices in separate transactions","p":["1. Installation of 2 devices - ‘xr6_1’ and ‘xr6_2’ (without transaction ID)","2. Creation of 2 uniconfig transactions: let’s name them TX1 and TX2","3. Modification of ‘xr6_1’ uniconfig configuration inside TX1","4. Modification of ‘xr6_2’ uniconfig configuration inside TX2","5. Verification if TX1 and TX2 are isolated","6. Committing TX1 and TX2 using uniconfig-manager:commit RPC","7. Verification of committed data","8. Verification if TX1 and TX2 are closed","All 3 responses - Status 200 OK with returned expected data. Similar verification can be done on 'xr6_2'.","Both responses should return Status 404 Not Found:","Creation of new Loopback79 interface - cookie header contains UNICONFIGTXID of TX2:","Creation of new Loopback97 interface in the TX1 - cookie header contains UNICONFIGTXID of TX1:","It is not required to specify target nodes in the input because UniConfig transaction tracks modified nodes:","Response - Status 422 Unprocessable Entity:","Response:","Since there aren't any conflicts between modifications in the committed transactions, both RPCs should succeed. Expected responses:","The first response contains transaction-id of TX1 that can be used in the subsequent requests that belong to TX1:","The first second contains transaction-id of TX2 that can be used in the subsequent requests that belong to TX2:","Trying to read some data in the TX1:","Trying to read some data in the TX2:","TX1 doesn't see modifications done in TX2 and vice-versa:","Verification if configuration was correctly committed to devices (direct read under yang-ext:mount) and if datastore was updated (GET request without transaction ID):","Verification if TX1 contains created interface (Cookie header contains UNICONFIGTXID of TX1):","Verification if TX2 contains created interface (Cookie header contains UNICONFIGTXID of TX2):"]},{"l":"Modification of sub-tree on same device in separate transactions","p":["1. Installation of device ‘xr6_1’","2. Preparation of configuration on 'xr6_1'","3. Creation of 2 uniconfig transactions: let’s name them TX1 and TX2","4. Modification of ‘xr6_1’ uniconfig configuration inside TX1","5. Modification of ‘xr6_1’ uniconfig configuration inside TX2","6. Commit TX1","7. Commit TX2","8. Verification of committed data in TX1 / non-committed data in TX2","9. Verification if TX1 and TX2 are closed","Changing description of interface Loopback97 to 'next loopback': - there is a conflict with TX1 which also tries to create/replace the configuration of the same interface:","Changing description of interface Loopback97 to 'test loopback':","Commit TX1 without target nodes - it should fail because the same node has already been modified by different transaction that has already been committed:","Commit TX2 without target nodes - it should pass:","Creation of Loopback97 interface with some initial description:","Creation of the uniconfig transaction TX1:","Creation of the uniconfig transaction TX2:","Respective responses:","Response - Status 500 with error message:","Response:","Trying to read some data in the transaction:","Verification if committed changes in TX1 were applied to datastore and device:"]}],[{"l":"Device discovery","p":["/opt/uniconfig-frinx/config/application.properties","~/FRINX-machine/config/uniconfig/frinx/uniconfig/config/application.properties","addressCheckLimit- Maximum number of addresses checked. If a request contains more addresses, it will not be successful.","Execute the ifconfig command in the terminal and look for an interface. If you are using a VPN, the interface is often called tun0. If not, look for a different interface. From the interface, copy the inet address and paste it into the file.","For testing, you need to add your IP address to the configuration JSON file. The configuration file is located at:","If you specify the range using a network statement, the network address and broadcast address are not included in the discovery process. If you specify the range via range statements, make sure that only hosts addresses are included in the specified range.","initial-pool-size- Thread pool used by the executor.","keepalive-time- Time before the execution of a specified task is timed out (in seconds).","max-pool-size- Size of the executor. If the request contains a large number of addresses, consider raising the value.","network: 192.168.1.0/24","RPC input consists of a list of all IP addresses to check (IPv4 or IPv6, a single IP address or a network with a prefix, or a range of IP addresses). Additionally, it contains the TCP/UDP ports that should be checked if they are open or not on the given addresses.","RPC output shows if the IP addresses are reachable via the ICMP protocol. For every IP address, a list of open TCP/UPD ports is also included.","start-ipv4-address: 192.168.1.1, end-ipv4-address: 192.168.1.254","The device-discovery RPC is used to verify reachable devices in a network. You can either check a single IP address in IPv4 format, a network or a range of addresses. Additionally, you can specify a port or range of ports (TCP or UDP) that are checked if they are open. The ICMP protocol is used to check the availability of devices.","The previous snippet contains the following additional parameters:","To discover hosts and ports in listening state in a network, do not add the network and broadcast address of that network. For example, to check the network 192.168.1.0/24, use one of the following:","When running UniConfig stand-alone, the config file is in the config folder:"]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains a network with the /29 prefix. Addresses in the network and desired ports are checked for availability.","RPC output contains reachable addresses in the network and all open TCP/UDP ports."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input contains a range of addresses. Addresses and desired ports are checked for availability.","RPC output contains reachable addresses and all open TCP/UDP ports."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input contains the host name and ports to be checked for availability.","RPC output shows if the host is reachable and all open TCP/UDP ports."]},{"l":"Failed example","p":["RPC input contains two addresses that are incorrectly wrapped."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains an IP range where the starting point is greater than the end point."]},{"i":"unsupported-operation---example","l":"Unsupported operation - example","p":["RPC input contains a network in IPv6 format that is currently not supported."]}],[{"l":"Dry-run manager"},{"l":"RPC dryrun-commit","p":["This RPC resolves the diff between the actual and intended configurationz of nodes by using the UniConfig Node Manager.","Changes to CLI nodes are applied using the cli-dryrun mountpoint, which only stores translated CLI commands to the cli-dry-run journal. After all changes are applied, the cli-dryrun journal is read and an RPC output is created and returned. This works similarly with NETCONF devices, but produces NETCONF messages as output instead of CLI commands.","RPC input contains a list of UniConfig nodes for which to execute the dry run.","RPC output describes the results of the operation and matches all input nodes. It also contains a list of commands and NETCONF messages for the given nodes.","If the RPC is called with an empty list of target nodes, the dryrun operation is executed on all modified nodes in the UniConfig transaction. If a node fails for any reason, the entire RPC fails.","RPC dryrun commit"]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input does not contain the target node. RPC output contains a list of commands that would be sent to the device if the RPC commit or checked-commit was called."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input does not contain any target nodes. Dryrun is executed with all modified nodes."]},{"i":"successful-example-2","l":"Successful example","p":["If there are no touched nodes, the request finishes successfully."]},{"l":"Failed example","p":["Node R1 has failed due to incorrect configuration."]},{"i":"failed-example-1","l":"Failed example","p":["Node R1 has failed because it does not support dry-run functionality."]},{"i":"failed-example-2","l":"Failed example","p":["Node R1 has lost connection."]}],[{"l":"Immediate Commit Model","p":["The immediate commit creates new transactions for every call of an RPC. The transaction is then closed so that no lingering data remains.","The sequential diagram below illustrates how the process works for reading data(GET request).","Get Request","Similarly, the following diagram illustrates the process for putting data (PUT request).","Put Request","The key difference in the two diagrams is that editing data (PUT, PATCH, DELETE, POST) and RPC calls in the database must be committed, hence there is an additional call of the commit RPC. This commit ensures that the transaction is closed. For reading data, it is necessary to close the transaction in a different manner, because no data was changed and calling a commit is not necessary.","When calling the sync-from-network RPC, it internally calls the replace-config-with-operational RPC. Note that this only works when using the Immediate Commit Model."]},{"l":"Configuration","p":["Configurations related to UniConfig transactions are placed in the config/application.properties file. You can also turn off the Immediate Commit Model and use the Build and Commit Model instead."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains a new interface that is added to the existing ones.","After putting the data into the database, they are automatically committed and can be viewed."]},{"l":"Failed example","p":["RPC input contains a value that is not supported."]}],[{"l":"Kafka Notifications","p":["NETCONF and gNMI devices produce notifications, which UniConfig can collect to create its own UniConfig notifications about specific events. Notifications from both NETCONF and gNMI devices and UniConfig are published using Kafka.","The following notification types are available:","NETCONF notifications","gNMI notifications","Notifications about transactions","Audit logs (RESTCONF notifications)","Data change events","Connection notifications","Each notification type is stored in its own topic in Kafka. Additionally, all notifications are stored in one table in the database.","notifications-in-cluster"]},{"l":"Kafka","p":["Apache Kafka is a publish–subscribe-based, durable messaging system that sends messages between processes, applications and servers. Within Kafka, you can define topics (categories) and applications can add, process and reprocess records.","In our particular case, UniConfig publishes notifications. Each type of notification is stored in a separate topic and can therefore be subscribed to independently. The names of topics and connection data are configurable in the application.properties file."]},{"l":"NETCONF notifications","p":["RFC 5277 defines a mechanism where a NETCONF client indicates an interest in receiving event notifications from a NETCONF server by subscribing to event notifications. The NETCONF server sends a reply about whether the subscription request was successful and, if so, starts sending event notifications to the NETCONF client as events occur within the system. Event notifications are sent until either the NETCONF session or the subscription is terminated.","NETCONF notifications are categorized as so-called streams. The subscriber can choose which streams to receive. The default stream is NETCONF."]},{"l":"gNMI notifications","p":["The gNMI specification defines a mechanism where the gNMI client indicates an interest in receiving updates about the state of data instances via a subscribe RPC. If the subscription is successfully created, the gNMI server replies with the state of data instances according to specified paths.","The session remains open until it UniConfig closes it (releasing the subscription) or an error occurs on the device side. However, UniConfig will try to recreate the session.","The following fields are mandatory for the install-node request:","stream-name","paths"]},{"l":"Notifications about transactions","p":["This type of notification is generated after each commit in UniConfig.","It contains the following:","transaction id","calculate diff result","commit result"]},{"i":"audit-logs-restconf-notifications","l":"Audit logs (RESTCONF notifications)","p":["Below are three examples of notifications with the response body and the calculation difference result.","body","comment","Example 1- Created data","Example 2- Deleted data","Example 3- Updated data","http method","It contains the following:","label","query parameters","request data","response data","source address","source port","status code","The response body can be included or excluded from notifications with the includeResponseBody parameter in the application.properties file. Similarly, the calculation difference result is included if the parameter includeCalculateDiffResult parameter is set to true in application.properties.","This type of notification is generated after each RESTCONF operation.","transaction id","uri","user id"]},{"l":"Shell notifications","p":["This type of notification is generated after each shell operation. It contains the following:","transaction id","request data","source address","source port","prompt","executed command","response data","output"]},{"l":"Data change events","p":["A subscription step is required before data change events are generated and published into Kafka.","With the subscription, a user can specify which subtrees are observed for data changes. Afterwards, data change events are generated by UniConfig instances when a transaction is committed and the committed changes contain subscribed subtrees.","A sample data change event captured by Kafka console consumer:","For data change events, streamName is always DCE and the identifier for the YANG notification is data-change-event.","The body contains the following:","subscription-id- Identifier for the subscription that triggers the generation of a data change event. The subscription identifier makes it easier to associate subscriptions and received data change events compared to using a combination of multiple fields such as node identifier, topology identifier and subtree path.","transaction-id- Identifier for the committed transaction that triggered the data change event after commit or checked-commit UniConfig operations.","edit- List of captured modifications done in the committed transaction.","Fields under edit:","subtree-path- Relative path to the data-tree element where the data change occurred. The path is relative to the subtree path specified during subscription.","data-before- JSON representation of subtree data before changes were made. If this field is not specified, data-after represents created data.","data-after- JSON representation of subtree data including the changes. If this field is not specified, data-before represents removed data.","operation- Operation type for the data change event.","node-id- Node identifier for the data change event.","topology-id- Topology identifier for the node. Either uniconfig or unistore."]},{"l":"Connection notifications","p":["Connection notification are generated whenever the status of a node changes. For connection notifications, streamName is always CONNECTION and the identifier for the YANG notification is connection-notification.","Contains the following:","topology id","node id","connection status","connection message","Supported topologies are cli, netconf and gnmi.","Sample connection notifications captured by Kafka console consumer:","CLI disconnect notification:","NETCONF connect notification:","gNMI connect notification:"]},{"l":"Database entities","p":["body - Full notification body in JSON format","creation time - Time when the subscription was created","end time - End time for collecting notifications","event time - Time when the notification was generated","Example- Request for reading Kafka settings using RESTCONF:","Example- Request for reading notifications using RESTCONF:","Example- Request for reading subscriptions using RESTCONF:","identifier - Name of the YANG notification for NETCONF or path to the received config top node for gNMI","node id - Identifier for the NETCONF/gNMI device or, for other types of notifications, the UniConfig instance","node id - Identifier for the NETCONF/gNMI node where notifications are collected","notification table","settings table","start time - Start time for collecting notifications","stream name - Name of the notification stream","stream name - NETCONF/gNMI stream name","subscription table","The following three tables in the database are related to notifications:","The notification table is where notifications are stored. It contains the following columns:","The settings table contains two columns: identifier and config. Records with the kafka identifier contain configurations for Kafka that can be modified at runtime.","The subscription table is used to track NETCONF and gNMI notification subscriptions. It contains the following columns:","UniConfig instance id - Identifier for the UniConfig instance that collects notifications from the NETCONF/gNMI device"]},{"l":"NETCONF subscriptions","p":["A subscription is required to receive NETCONF notifications from a NETCONF device.","Subscriptions are created with an installation request:","Subscriptions to notification streams are defined as a list with the name stream. There is one record for each stream.","The only mandatory parameter is stream-name. Other parameters are optional:","start-time- Must be specified to enable replay and should start at the specified time.","stop-time- Used with the optional replay feature to indicate the newest notifications of interest. If no stop time is specified, notifications will continue until the subscription is terminated. Must be used with and set to be later than start-time. Values in the future are valid.","If a new subscription to a stream is created, all existing subscriptions to the stream are terminated."]},{"l":"gNMI subscriptions","p":["A subscription is required to receive gNMI notifications from a gNMI device.","Subscriptions are created with an installation request:","Subscriptions to notification streams are defined as a list with the name stream. There is one record for each stream.","There are two required parameters, stream-name and paths. Other parameters are optional:","start-time- Start time for telemetry streaming.","stop-time- Telemetry streaming stops if the timestamp of the notification is later than this time. If no stop time is specified, notifications will continue until the subscription is terminated. Must be used with and set to be later than start-time. Values in the future are valid."]},{"i":"monitoring-system---processing-netconfgnmi-subscriptions","l":"Monitoring system - processing NETCONF/gNMI subscriptions","p":["In UniConfig, subscriptions to NETCONF and gNMI notifications are processed in an infinite loop within the monitoring system.","An iteration of the monitoring system loop consists of following steps:","Check global setting for NETCONF/gNMI notifications.","If turned off, release all NETCONF/gNMI subscriptions and end current iteration.","Release cancelled subscriptions.","Query free subscriptions from DB, and for each one:","Create a notification session (create mountpoint and register listeners).","Lock the subscription (set UniConfig instance).","There is a hard limit on the number of sessions that a single UniConfig node can handle. If the limit is reached, the UniConfig node refuses any additional subscriptions.","The loop interval, hard subscription limit and maximum number of subscriptions processed per interval can be set in the application.properties file."]},{"l":"Dedicated NETCONF session for subscription","p":["A NETCONF device may have the interleave capability that indicates support for interleaving other NETCONF operations within a notification subscription. This means that the NETCONF server can receive, process and respond to NETCONF requests on a session with an active notification subscription.","As not all devices include support for this capability, the common approach for devices with and without interleave capability is to track notifications with a separate NETCONF session. To support this functionality, UniConfig creates a separate NETCONF session with a separate mountpoint for every subscription. These mountpoints and sessions are automatically terminated when the corresponding subscription is closed.","monitoring-system"]},{"l":"Subscriptions to data change events"},{"l":"Create a new subscription","p":["BASE: Represents only a direct change of the node on the subtree-path, such as replacement of a node, addition or deletion.","data-change-scope- Data-tree scope that specifies how granular data change events should be captured and propagated to Kafka. There are three options:","Delete an existing subscription","Display information about a created subscription using the RPC","Example- Create a duplicate subscription to the device1 node in the uniconfig topology, and to the whole /interfaces configuration subtree:","Example- Create a subscription to the device1 node in the uniconfig topology, and to the whole /interfaces configuration subtree:","Example- Create a subscription to the uniconfig topology and to the whole/interfaces configuration subtree:","node-id- Identifier for the node from which data change events are generated. If not specified, a global subscription is created and data change events are generated for all nodes under the topology. This field is optional.","ONE: Represent a change (an addition, replacement or deletion) of the node on the subtree-path or one of its direct child elements.","RPC input contains the following:","RPC output contains only the generated subscription identifier in UUID format. This identifier represents a token that can be used for the following:","Sort received Kafka messages","Subscriptions to data change events are created using the create-data-change-subscription RPC. After a subscription is created, UniConfig listens to data change events on selected nodes and subtrees and distributes the corresponding messages to a dedicated Kafka topic.","subtree-path- Path to the subtree from which the user would like to receive data change events. The default value is /, which captures data change events from the entire node configuration.","SUBTREE: Represents a change of the node or any of its child nodes, direct and nested. This scope is a superset of ONE and BASE. This is the default value.","topology-id- Identifier for the topology where the specified node is placed."]},{"l":"Remove a subscription","p":["Existing subscriptions can be removed using the delete-data-change-subscription RPC and the provided subscription-id. After a subscription is removed, UniConfig stops generating new data change events related to the subscribed path.","RPC input contains only the subscription-id, which is a unique identifier for the subscription to data change events.","RPC output does not contain a body. The RPC returns a 404 error if no subscription exists for the provided identifier.","Example- Remove a subscription:","Successful example:","Failed example:"]},{"l":"Show information about a subscription","p":["The show-subscription-data RPC is used to display information about a created subscription.","RPC input contains an identifier for the target subscription.","RPC output for existing subscriptions contains the following:","topology-id","node-id","subtree-path","data-change-scope","These are the same fields that can be specified as input for the create-data-change-subscription RPC.","If no subscription exists with the specified ID, the RPC returns a 404 status code with a standard RESTCONF error container.","Successful example:","Failed example:","It is also possible to fetch all created subscriptions under a specific node or topology by sending a GET request to the data-change-subscriptions list under the node list item (operational data).","Example- Two subscriptions under the device1 node"]},{"l":"Configuration","p":["All notifications, as well as the monitoring system, can be enabled or disabled using the enabled flag.","All settings related to Kafka are grouped under kafka property. For authentication, there are the username and password properties. For the Kafka connection, there is the kafka-servers property which contains a list of Kafka servers as a combination of broker-host and broker-listening-port. The broker host can be either an IP address or hostname.","archive-url- Where to download Kafka from","Audit log settings are under the audit-logs property. Currently there is only one flag, include-response-body, which is used to enable or disable logging the body of RESTCONF responses.","audit-logs-enabled","audit-logs-topic-name- Topic name for audit logs","blocking-timeout- How long the send() method and the creation of a connection for reading metadata methods will block (in milliseconds).","clean-data-before-start- Whether or not to clear Kafka config before start","Configurations for notifications are in the application.properties file, under the notifications property.","Configure the names of all topics for every notification type by using the following flags:","data-change-events-enabled","data-change-events-topic-name- Topic name for data change events","data-dir- Kafka data directory","delivery-timeout- Upper bound on the time to report success or failure after a call to send() returns (in milliseconds). Sets a limit on the total time that a record will be delayed prior to sending, the time to wait for acknowledgement from the broker (if expected) and the time allowed for retriable send failures.","Enable or disable each type of notification independently of others by using the following flags:","enabled- Enable or disable embedded Kafka","install-dir- Where Kafka files should be placed","Kafka settings are also stored in the database. This way they can be changed at runtime using RESTCONF or UniConfig shell. Kafka setting are stored in the settings table.","max-age- Maximum age of a record in the notifications table (in hours). Records older than this value are deleted. The default value is 100.","max-count- Maximum number of records in the notifications table. If the number of records exceeds this value, the oldest record in the table is deleted. The default value is 10,000.","max-netconf-subscriptions-hard-limit- Maximum number of subscriptions that a single UniConfig node can handle.","max-subscriptions-per-interval- The maximum number of free subscriptions that can be acquired in a single iteration of the monitoring system loop. If the number of free subscriptions is smaller than this value, all free subscriptions are processed. If the number of free subscriptions is larger than this value, only the specified number of subscriptions are acquired. The rest can be acquired during the next iterations of the monitoring system loop or by other UniConfing instances in the cluster. The default value is 10.","max-thread-pool-size- Maximum thread pool size in the executor.","netconf-notifications-enabled","netconf-notifications-topic-name- Topic name for NETCONF notifications","optimal-subscriptions-approaching-margin- Lower margin to calculate optimal range start. The default value is 0.05.","optimal-subscriptions-reached-margin- Upper margin to calculate optimal range end. The default value is 0.10.","Properties related to message timeout to Kafka:","Properties related to the monitoring system in clustered environments:","Properties related to the monitoring system:","Properties related to the thread pool executor required to send messages to Kafka:","Properties used to limit the number of records in the notifications table in the database:","queue-capacity- Maximum capacity for the work queue in the executor.","rebalance-on-UC-node-going-down-grace-period- Grace period for a UniConfig node going down (in seconds). Other nodes will not restart subscriptions until the grace period has passed after a dead Uniconfig node was last seen. The default value is 120.","request-timeout- How long the producer waits for acknowledgement of a request (in milliseconds). If no acknowledgement is received before the timeout period has passed, the producer resends the request or, if retries are exhausted, fails the request.","subscriptions-monitoring-interval- How often the monitoring system loop is run and how often it attempts to acquire free subscriptions (in seconds). The default value is 5.","The entire configuration looks like this:","These properties are under notification-db-treshold. Both are implemented using database triggers. Triggers are running on inserts to the notifications table.","transaction-notifications-enabled","transactions-topic-name- Topic name for transactions about notifications","You can also to set up embedded Kafka using these setting grouped under the embeddedKafka property:"]},{"i":"kafka-client---example","l":"Kafka client - Example","p":["To read notifications from Kafka, you can use the command line consumer.","Run the following command in the Kafka installation directory:","It is important to properly set up the hostname, port and topic name.","Output after a NETCONF notification is created:"]}],[{"l":"Operational data about transactions"},{"l":"Operational data about transactions","p":["To have a better overview of UniConfig transactions, there are operational data about all open transactions.","Data about transactions contain:","identifier (uuid)","creation time","last access time","idle timeout","hard timeout","list of changed nodes (incl. topologies)","additional context (random string, text column)","Data about transactions can be read using RESTCONF:","Example data about transactions:"]}],[{"i":"uniconfig---sending-and-receiving-data-restconf","l":"UniConfig - Sending and receiving data (RESTCONF)","p":["The RESTCONF protocol is described in RFC 8040. Put simply, RESTCONF represents a REST API for accessing datastores and UniConfig operations."]},{"l":"Datastores","p":["There are two datastores:","Config: Contains data representing the intended state. Possible to read and write via RESTCONF.","Operational: Contains data representing the actual state. Possible only to read via RESTCONF.","Each request must start with the URI /rests/. By default, RESTCONF listens on port 8181 for HTTP requests."]},{"l":"REST Operations","p":["RESTCONF supports: OPTIONS, GET, PUT, POST, PATCH, and DELETE operations. Request and response data can be either in the XML or JSON format.","XML structures according to YANG are defined at: XML-YANG.","JSON structures are defined at: JSON-YANG.","Data in the request must set the Content-Type field correctly in the HTTP header with the allowed value of the media type. The media type of the requested data must be set in the Accept field. Get the media types for each resource by calling the OPTIONS operation.","Most of the paths use Instance Identifier. is used in the explanation of the operations and must adhere to these rules:","Identifier must start with :> where is a name of the YANG module and is the name of a node in the module. If the next node name is placed in the same namespace as the previous one, it is sufficient to just use after the first definition of:. Each has to be separated by /."," can represent a data node which is a list node, container, leaf, or leaf-list YANG built-in type. If the data node is a list, there must be defined ordered keys of the list behind the data node name, for example, =,. ..","The following example shows how reserved characters are percent-encoded within a key value. The value of \"key1\" contains a comma, single-quote, double-quote, colon, double-quote, space, and forward slash (,'\":\" /). Note that double-quote is not a reserved character and does not need to be percent-encoded. The value of \"key2\" is the empty string, and the value of \"key3\" is the string \"foo\".","Example URL: /rests/data/example-top:top/list1=%2C%27\"%3A\"%20%2F,,foo","The format : has to be used in this case as well. Module A has node A1. Module B augments node A1 by adding node X. Module C augments node A1 by adding node X. For clarity, it has to be known which node is X (for example: C:X)."]},{"l":"Mount point","p":["The purpose of yang-ext:mount container is to access southbound mountpoint, when the node is already installed in Uniconfig (After install-node RPC). It exposes operations for reading device data which can only be done under connection-specific topology (cli/netconf) with defined node-id in URI. In this case, the URI has to be in the format/ yang-ext:mount/. The first is the path to a mount point and the second is the path to subtree behind the mount point. An URI can end in a mount point itself by using /yang-ext:mount. In this case, if there is no content parameter, whole operational and configuration data will be read.","Examples of retrieving data behind yang-ext:mount","In this request, we are using parameter content=config, this means we are reading candidate NETCONF datastore. Value config of parameter content is translated into get-config NETCONF RPC.","In this request we are using parameter content=nonconfig, which means that we are reading running NETCONF datastore. Value nonconfig is translated into get NETCONF RPC. We can compare it with data directly from device using show running-config command.","Examples of invocation of yang actions behind yang-ext:mount.","Invocation of yang action -> List available firmware packages on disk","Invocation of yang action -> Erase running-config-then load","To completely understand installing of node see Device installation."]},{"l":"HTTP methods"},{"i":"options-rests","l":"OPTIONS /rests","p":["Returns the XML description of the resources with the required request and response media types in Web Application Description Language (WADL)."]},{"i":"get-restsdataidentifiercontentconfig","l":"GET /rests/data/?content=config","p":["Returns a data node from the Config datastore."," points to a data node that must be retrieved.","Value 'config' represents default value of content query parameter - it doesn't have to be specified, if user would like to read intended/uncommitted changes from Config datastore.","Request GET '/rests/data/' would return the same data."]},{"i":"get-restsdataidentifiercontentnonconfig","l":"GET /rests/data/?content=nonconfig","p":["Returns the value of the data node from the Operational datastore."," points to a data node that must be retrieved."]},{"i":"get-restsdataidentifiercontentall","l":"GET /rests/data/?content=all","p":["Returns a data node from both Config and Operational datastores. The outputs from both datastores are merged into one output."," points to a data node that must be retrieved."]},{"i":"put-restsdataidentifier","l":"PUT /rests/data/","p":["Updates or creates data in the Config datastore and returns the state about success."," points to a data node that must be stored.","Content type does not have to be specified in URI - it can only be the Configuration datastore."]},{"i":"post-restsdataidentifier","l":"POST /rests/data/","p":["Creates the data if it does not exist in the Config datastore, and returns the state about success."," points to a data node where data must be stored.","The root element of data must have the namespace (data is in XML) or module name (data is in JSON)."]},{"i":"post-restsdata","l":"POST /rests/data","p":["Creates the data if it does not exist under data root.","In the following example, the 'toaster' module is the root container in YANG (it doesn't have any parent). This example also makes it clear that URI doesn't contain 'toaster' node in comparison to a PUT request that must contain the name of the created node in URI."]},{"i":"delete-restsdataidentifier","l":"DELETE /rests/data/","p":["Removes the data node in the Config datastore and returns the state about success."," points to a data node that must be removed."]},{"i":"patch-restsdataidentifier","l":"PATCH /rests/data/","p":["The patch request merges the contents of the message-body with the target resource in the Configuration datastore (content-type query parameter is not specified)."," points to a data node on which PATCH operations is invoked.","This request is implemented by Plain PATCH functionality, see more details on the following page: RFC-8040 documentation - Plain PATCH operation.","Plain patch can be used to create or update, but not delete, a child resource within the target resource. Any pre-existing data which is not explicitly overwritten will be preserved. This means that if you store a container, its child entities will also merge recursively.","The following example shows the PATCH request used for modification of Ethernet interface IP address and two connection settings. Note that other settings under system:system container are left untouched including other leaves under 'connection' container and 'ethernet' list item."]},{"i":"patch-restsdataidentifierapply-tagstrue","l":"PATCH /rests/data/?apply-tags=true","p":["The patch request with parameter apply-tags=true allows to use tags.","Tags allows us to use differrent operation for separate elements instead of merging whole content as without tags.","The following tags are supported: merge, replace, delete, create and update.","Usage of these tags are explained in Templates manager : here.","The following example shows PATCH request used for modification of interfaces on IOS XE device including creating, deleting, and replacing interface configuration."]},{"i":"post-restsoperationsmodulenamerpcname","l":"POST /rests/operations/:","p":["Invokes RPC on the specified path.",": - is the name of the module and is the name of the RPC in this module.","The Root element of the data sent to RPC must have the name “input”.","The result has the status code and optionally retrieved data having the root element “output”.","The answer from the server could be:","GET /rests/operations request can be used to retrieve all available RPCs that are registered in distribution.","More information is available in the RESTCONF RFC 8040."]},{"i":"post-restsdatapath-to-operation","l":"POST /rests/data/","p":["Invokes action on the specified path in the data tree.","Placeholder represents data path to operation definition that is specified under composite data schema node in YANG (only containers and lists may contain action definition).","Content query parameter doesn't have to be specified (it will be ignored), action is represented equally in Operational and Config datastore.","Both RFC-8040 (YANG 1.1) and TAIL-F actions are supported. TAIL-F actions can be placed in both YANG 1.0 and YANG 1.1 schemas. There aren't any differences in the invocation of these types of actions using RESTCONF API.","The body of the action invocation request may contain a root 'input' container. If the action definition has no specified input container, it is not required to specify the body in the request.","The response contains the status code and optionally retrieved data having the root element 'output'.","Currently, FRINX UniConfig only supports invocation of actions under NETCONF mountpoint, must contain'yang-ext:mount' container.","Structure of 'input' and 'output' elements are the same as the structure of these containers when we invoke YANG RPC.","Assume the following YANG snippet with root container named'interfaces':","Invocation of the action named 'compute-stats' that is placed under the'interfaces' container of NETCONF mountpoint:","Difference between RPCs and actions: Actions are bound to a data tree and they can be placed under containers and lists (they cannot be specified as root entities in YANG schema). RPCs are not placed in the data tree and for this reason, they can only be specified as root entities in the YANG schema."]},{"l":"Selecting Data","p":["For selecting and identifying data is good to use query parameter fields. This parameter has to be used only with the GET method. The response body is output filtered by field-expression as the value of fields parameter."]},{"l":"Fields","p":["The response body is the output filtered by the field-expression as a value of the fields parameter.","The example of using the fields parameter: path?fields=field_expression","There are several rules, that need to be followed:","For filtering more than one field of the same parent, \";\" needs to be used. Example : path?fields=field1;field2, where field1 and field2 has the same parent, which is the very last part of the path.","For nesting, \"/\" needs to be used. Example : path?fields=field1;pathField/field2, where field1 and field2 has not the same parent, but pathField is on the same level as field1.","This is a different approach to do nesting, however, the difference between \"(\" and \"/\" is that once we use \"/\" for specifying some field, we cannot identify another field from the upper layers.","This is the case where pathField1 and pathField2 have the same parent, this is not allowed, because once we use \";\" it is expected to specify fields on the same layer as field1","Examples: With 2 approaches (nesting, sub-selecting)","Example of filtering the entire configuration of all interfaces (name, with the config):","Example of filtering all names of interfaces and all names of configs of interfaces:","Example of filtering all names of interfaces with type from the config of interfaces:"]},{"l":"Data filtering","p":["To filter data based on specific values, use the jsonb-filter query parameter. This parameter can only be used with the GET method.","For more information, see JSONB filtering."]},{"l":"Pagination","p":["To filter data even further, you can use pagination with the GET method.","There are three parameters related to pagination, which can be combined or used individually:","offset- The starting point in a list for data rendering, based on the index list of entry values. Indexing begins at 0, so that offset=2 would start rendering at the third entry. The specified offset index entry is included in the output.","limit- The number of node values displayed in a GET request. Specifies the maximum count for entries included in the response, starting with the entry defined by the offset parameter (if provided).","fetch=count- Retrieves the total number of child nodes under a specific node. Instead of returning node values, provides a count of how many child nodes exist under the specified node.","Note that pagination only works for list nodes.","Example- Using one individual pagination parameter:","Example- Using two pagination parameters simultaneously:","Example- Using the fetch=count parameter:","Response body for the fetch=count parameter with a path from the previous example:"]},{"l":"Sorting","p":["This utility helps us to sort list data from GET request according to our needs in ascending or descending order.","To sort some data, use a query parameter called sortby that will include at least one identifier of child leaf and sort direction. The first part of the value represents leaf identifier, the second part enclosed in brackets represents sort direction ('asc' or 'desc'). If there are multiple leaves based on which sorting is done, they are separated by semicolon.","Sorting, just like pagination, can only be used on list nodes.","The example of using sortby parameter with 1 value (sorting by the value of 'name' leaf):","The example of using sortby parameter with 2 values (sorting by values of 'name' and 'revision' leaves, in that order):","The example of using sortby and pagination simultaneously:","It is possible to specify module-name as part of the leaf identifier. Module-name must be specified only if there are multiple children leaves with the same identifier but specified from different namespaces. Example:","In the case of union types specified on leaf nodes, sorting is done in the blocks that are ordered by the following strategy:","leaves without value","empty type","boolean type","random numeric type","types that can be represented by JSON string"]},{"l":"Inserting"},{"l":"Insert query parameter","p":["The 'insert' query parameter can be used to specify how an item should be inserted within an list or leaf-list. This parameter is only supported for the POST and PUT methods. It is also only supported if the target list or leaf-list is marked as 'ordered-by user' in YANG model.","The allowed values for 'insert' query parameter:","Value","Description","first","Insert the new item as the new first entry.","last","Insert the new item as the new last entry (default value).","before","Insert the new item before the insertion point, as specified by the value of the 'point' query parameter.","after","Insert the new data after the insertion point, as specified by the value of the \"point\" parameter.","If the values 'before' or 'after' are used, then a 'point' query parameter for the 'insert' query parameter MUST also be present."]},{"l":"Point query parameter","p":["The 'point' query parameter is used to specify the insertion point for an item that is being created or moved within an'ordered-by user' list or leaf-list. Like the 'insert' query parameter, 'point' query parameter is only supported for the POST and PUT methods and also if the target list or leaf-list is marked as 'ordered-by user' in YANG model. The value of the 'point' query parameter is a string that indicates the key of the insertion point item. If the key is composite, the key items must be separated by a comma."]},{"l":"Examples","p":["Next five examples show usage of 'insert' and 'point' query parameters for leaf-list. First example shows how leaf-list looks before update. There are no differences in the use of the list and leaf-list."]},{"l":"List before update"},{"l":"Insert item at the top of the list"},{"l":"Insert item at the bottom of the list"},{"l":"Insert item after specific item"},{"l":"Insert item before specific item"},{"l":"Retrieving data"},{"l":"With-defaults query parameter","p":["All data nodes are reported, including any data nodes with YANG default in scheme, which are not set by client are reported.","Data nodes set to its YANG schema default value are not reported.","Data nodes set to its YANG schema default value by the client are reported.","Description","Example Data Set By User:","Example YANG Module:","explicit","report-all","The 'with-defaults' query parameter is used to specify how information about default data nodes is returned in response to GET requests on data resources. The response body is output filtered by value of with-defaults parameter.","The allowed values for 'with-defaults' query parameter:","The example of using the with-defaults query parameter: path?with-defaults or path?with-defaults=value","trim","Using with-defaults without value is equivalent to value 'report-all'.","Value","Value Explicit","Value Report-All or Without Value","Value Trim"]},{"l":"JSON Attributes","p":["Node attributes can be encoded in JSON by wrapping all the attributes in the '@' container and values or arrays in the '#' JSON element. This notation is inspired by one that is used in the 'js2xmlparser' open-source tool (conversion between JSON and XML structures): js2xmlparser","RESTCONF supports both serialization and deserialization of attributes, GET response shows all set attributes in the read data-tree and PUT/POST/PLAIN PATCH methods can be used for the writing of data nodes with attributes. Warning: attributes cannot be directly addressed using RESTCONF URI that would contain the '@' element in the path, because attributes are always bound to some data node, they are not represented by distinct nodes in the data-tree.","Reserved '@' container may contain multiple attributes. Each attribute is encoded in the same fashion as leaf nodes, there is an identifier of the attribute and attribute value.","Format of the attribute that is defined in the [module]:","Format of the attribute that is defined in the same module as the parent data entity:"]},{"i":"example---leaf-with-attributes","l":"Example - leaf with attributes","p":["Leaf without attributes:","The same leaf with set 2 attributes: 'm1:attribute-1' and'm1:attribute-2':"]},{"i":"example-container-with-attributes","l":"Example: Container with Attributes","p":["A container without attributes:","The same container with set 2 attributes: 'm1:switch' and'm2:multiplier':"]},{"i":"example-leaf-list-with-attributes","l":"Example: Leaf-list with Attributes","p":["Leaf-list without attributes:","The same leaf with set 1 attribute: 'mx:split':"]},{"i":"example-leaf-list-entry-with-attributes","l":"Example: Leaf-list Entry with Attributes","p":["Leaf-list without attributes:","Two leaf-list entries, leaf-list entry with value '10' has one attribute with identifier 'm1:prefix'. The second leaf-list entry '20' doesn't have any attributes assigned."]},{"i":"example-list-with-attributes","l":"Example: List with Attributes","p":["List without attributes:","The same list with applied single attribute: 'constraints:length'."]},{"i":"example-list-entry-with-attributes","l":"Example: List Entry with Attributes","p":["List with two list entries without attributes:","The same list entries, the first list entry doesn't contain any attribute, but the second list entry contains 2 attributes: 'm1:switch' and 'm2:multiplier'."]},{"l":"Device Schema Filters","p":["By default, all input and output data produced by RESTCONF for the selected device is fully compliant with its YANG models. Any violation of the YANG schema definitions will result in an error. Some of these restrictions can be addressed by adding the 'schemaFilters' configuration parameter for the RESTCONF."]},{"l":"Configuration Options Overview","p":["Following configuration options for 'schemaFilters' make RESTCONF processing less restrictive:"]},{"l":"Configuration Example","p":["The following example demonstrates how to enable schema filters for selected extensions and make RESTCONF ignore unknown definitions and definitions with a 'deprecated status' attribute."]},{"i":"unhide-parameter-for-readwrite-operations","l":"Unhide Parameter for READ/WRITE Operations","p":["RESTCONF supports the 'unhide' query parameter for the GET requests to include hidden definitions into the response and for PUT/POST/PATCH requests to accept hidden definitions in the input. This parameter value can be populated with a comma-separated list of extensions to unhide or the keyword 'all' to include all possible hidden definitions in the response.","Example of using the 'unhide' parameter for the GET and PUT/POST/PATCH requests.","Using unhide with a list of extensions","Using unhide parameter to unhide all hidden definitions"]},{"l":"Leafref validation","p":["According to YANG standard there are constraints for leafrefs. These constraints are not validated by default. Leafref validation can be enabled using checkForReferences query parameter with value set to true."]},{"i":"example","l":"Example:"},{"l":"Using leafref validation"},{"l":"Example output of failed validation","p":["If checkForReferences parameter is set to false or is not provided UniConfig will not perform leafref validation and there will be no leafref validation error."]},{"l":"Hide Empty Data Nodes","p":["Query parameter 'hideEmptyDataNodes' is used to hide empty composite data-tree nodes in response to GET call. Data nodes that contain only attribute tag are considered to be empty too. Default value is 'false' - empty nodes are displayed in the GET response."]},{"i":"example-1","l":"Example"},{"l":"Escaping keys in URI","p":["Following characters must be escaped, if they are contained in a list key value:':', '/', '?', '#', '[', ']', '@', '!', '$', '&', ''', '(', ')', '*', '+', ',', ';', '='.","There are 2 ways how to escape special characters in a key value: by encoding reserved UTF-8 characters using '%HH' patten or using key delimiter.","Using key delimiter should be the preferred way of dealing with reserved characters in keys since it avoids various issues with URL parsing constraints imposed by the web server."]},{"l":"Encoding reserved characters","p":["RESTCONF RFC-8040 natively allows to specify reserved characters in a key value, if they are encoded using'%HH' pattern, where 'HH' refers to hexadecimal representation of UTF-8 character.","Starting with Uniconfig 7.0.0, it is not possible to URL-encode / as %2F because the web server will throw away the request due to stricter URL parsing rules.","The following request demonstrates encoding of special characters in the 'ge0/0/1' interface name, which does not work anymore starting with Uniconfig 7.0.0.","You should use the following request:","Mappings between special characters and UTF-8 codes can be found on following site: https://www.urlencoder.org/"]},{"l":"Demarcate key using delimiter","p":["UniConfig lets you specify a key delimiter used to demarcate list key values. Once defined, all special characters inside the key are automatically escaped.","The delimiter is enabled by default. It can be defined in the config/application.properties file:","The following request demonstrates the demarcation of an interface named ge0/0/1 using the %22 delimiter."]},{"l":"Hide Attributes","p":["Query parameter 'hideAttributes' is used to hide composite data-tree nodes attributes in response to GET call. Default value is 'false' - nodes attributes are displayed in the GET response."]},{"i":"example-2","l":"Example"},{"i":"callbacks-http-client","l":"Callbacks (http-client)","p":["Callbacks include sending GET (call-point) and POST (action) requests to the remote server. They are implemented mainly for UniConfig Shell, but can also be used by RESTCONF for UniStore nodes by using the URI prefix:"]},{"i":"examples-1","l":"Examples","p":["Example - call-point invocation in RESTCONF","Response:","Example - action invocation in RESTCONF","Callbacks must be configured before use. For more details, see Callbacks."]}],[{"l":"UniConfig Queries","p":["This module is responsible for execution of queries on the configuration of some device, template, UniStore node, or snapshot."]},{"l":"RPC query-config","p":["UniConfig exposes filtering and selection API using RPC 'query-config'. Filtering and selection of configuration is done only on the database side - UniConfig receives already narrowed configuration with only selected data. Since query is evaluated by the database, this feature works only with already committed data (operational data).","The following sequence diagram captures the whole process of RPC execution in detail.","Execution of RPC query-config"]},{"l":"RPC input fields","p":["topology-id: Identifier of network-topology/topology list entry. Currently, supported topologies, under which this RPC can be used, are: 'uniconfig', 'templates', 'unistore', and snapshot topologies.","node-id: Identifier of specific network-topology/node list entry whose configuration is filtered using specified jsonb-path-query.","jsonb-path-query: JSONB-path query used for selection and filtering of subtrees in the node configuration stored in the PostgreSQL. JSONB-path must start from root \"frinx-uniconfig-topology:configuration\" container(it is always represented by absolute path).","JSONB-path query syntax is specified by PostgreSQL. You can find detailed description of all features with examples on the following link (version 14): https://www.postgresql.org/docs/14/functions-json.html#FUNCTIONS-SQLJSON-PATH"]},{"l":"RPC output fields","p":["config: List of selected and filtered JSON objects. Note that database may return multiple list entries, if the last element in the JSONB-path is represented by list/leaf-list YANG schema node. In other cases, only one or no JSON object is displayed on output based on fulfilling the filtering and selection criteria."]},{"i":"example-selection-of-json-object","l":"Example: selection of JSON object","p":["The following request demonstrated execution of simple selection query under the 'dev01' from 'uniconfig' topology. Response contains 1 JSON object - 'ssh' container.","JSONB-path query should always start with $.\"frinx-uniconfig-topology:configuration\" pattern because 'configuration' represents wrapping element for all root data elements that are stored in database.","Be aware that PostgreSQL requires escaping of special characters in the identifiers of JSON elements. For example,':' and '-' represent special characters. Because of this behaviour, it is always safer to put double quotes around all identifiers as it is done in this example."]},{"i":"example-filtering-list-of-json-objects","l":"Example: filtering list of JSON objects","p":["The next query demonstrates filtering of 'address' JSON objects using predicate based on 'ipv4-address'(the first octet must have a value '80'). Addresses under all 'controller' list entries are filtered. In this example, response contains multiple JSON objects representing 'address' list entries."]},{"i":"example-selection-of-leaf-list-content","l":"Example: selection of leaf-list content","p":["The next request shows selection of all addresses under ethernet interfaces with type 'vxlan' and 'enabled' flag set to 'true'. Response will contain aggregated array of strings, because 'address' is represented by leaf-list."]},{"i":"example-non-existing-node","l":"Example: non-existing node","p":["If node with specified identifier doesn't exist under target topology, RPC will return 400 with corresponding error message."]},{"i":"example-syntax-error","l":"Example: syntax error","p":["In case of invalid form of input 'jsonb-path-query', UniConfig will return 400 status code with error-message describing syntax error."]}],[{"l":"UniConfig shell","p":["UniConfig shell is a command-line interface for Uniconfig. Accessible over SSH, it allows users to interact with Uniconfig features including the following:","Read operational data of devices","Manipulate device configurations","Manipulate configuration templates","Manipulate data stored in Unistore","Invoke device or UniConfig operations","Manipulate global UniConfig settings","Uniconfig shell is model-driven, therefore its interface is mostly auto-generated from YANG schemas (e.g., tree structure of data-nodes or available RPC/action operations)."]},{"l":"Configuration","p":["UniConfig shell is disabled by default. To enable it, set the configuration parameter cli-shell.ssh-server.enabled to true in the application.properties file.","All available settings and descriptions are listed below:","After starting UniConfig, the SSH server listens for connections on port 2022 and the loopback interface. UniConfig Shell has two connection timeouts:","Authorization timeout, after which the connection is closed if the other party has not been authenticated (in seconds). The default value is 120 seconds.","Idle timeout, after which the connection is closed if idle (in seconds). The default value is 600 seconds."]},{"l":"Navigating in the shell","p":["Every command line starts with a command prompt that ends with the character. The identifier of the command prompt changes based on the current shell mode and the state of execution in this mode.","The exit and quit commands are available in all shell modes:","exit returns the state to the parent state","quit returns the state to the nearest parent mode (e.g., configuration mode, root mode, operational show mode). If the current state of the shell represents some mode, quit and exit have the same effect of returning to the parent mode.","Typed commands are sent to UniConfig using the ENTER key. UniConfig processes the command and may send a response to the console depending on the command. All commands are processed synchronously, meaning that multiple commands cannot be executed in parallel in the same SSH session.","CTRL-A and CTRL-E move the cursor to the beginning or end of the current line.","CTRL-L clears the shell screen.","Arrow keys UP/DOWN load previous commands in the command history.","CTRL-C cancels the current line and moves to a new blank line.","TAB loads suggestions in the current context. Hit TAB again to navigate through suggested commands using the arrow keys and select using ENTER. Leave the submode with suggestions using the shortcut CTRL-E. The text in brackets contains a description of the next command.","If the output is longer than the length of the command line window, it is displayed with scrolling capability. Use ENTER to display the next line and SPACE to display the next page. Use the q key to leave scrolling mode. You can only scroll only in one direction, towards the end of the output.","Scrolling through long output"]},{"l":"Root mode","p":["Root mode is the initial mode after successful authentication.","Example: Log into UniConfig shell:","The exit command is used to exit the UniConfig shell interface altogether(disconnecting SSH client).","Example - Exit UniConfig shell:","Currently, only username/password single-user authentication is supported as configured in the application.properties file."]},{"l":"Accessing sub-modes","p":["Root mode acts as a gateway to open the configuration and show modes.","Example - Switch to configuration mode:"]},{"l":"Show command history","p":["The show-history command is used to display a list of N last invoked commands. This command is also available in configuration mode.","Example - Show the last five executed commands:","Note that the list of invoked commands persists across UniConfig restarts and SSH connections."]},{"l":"Unhide and hide operations","p":["The following commands are used to unhide and hide attributes in application properties:","unhide-get is used to unhide an attribute hidden in application properties for read purposes (restconf.schema-filters.hidden-data-on-read-by-extensions).","unhide-set is used to unhide an attribute hidden in application properties for write purposes (restconf.schema-filters.ignored-data-on-write-by-extensions).","hide-get is used to hide attributes that were unhidden with unhide-get.","hide-set is used to hide attributes that were unhidden with unhide-set.","When unhide is set for a GET or SET operation, the request URL for the operation contains the unhide query parameter. In the following example, the unhide parameter is set to all:","http://localhost:8181/rests/data/network-topology:network-topology/topology=uniconfig/node=vnf21/configuration?unhide=all","This is also available for callbacks. Request and set operations for callbacks uses restconf.schema-filters.ignored-data-on-write-by-extensions and show operations uses restconf.schema-filters.hidden-data-on-read-by-extensions.","The command also gives confirmation that the attribute was added to or removed from the unhidden list.","When unhide-get or hide-get are called without parameters, the output contains a list of all unhidden parameters. The same applies to unhide-set and hide-set.","When used with the parameter all, the unhide operation applies to all parameters defined in application properties for read or write purposes."]},{"l":"Examples","p":["Example- Attempt to show hidden callbacks field details with unhide","Example- Attempt to show hidden callbacks field details without unhide","Example- Attempt to set hidden callbacks field reset-password with unhide","Example- Attempt to set hidden callbacks field reset-password without unhide","Example- Attempt to request hidden callbacks field unlock-user with unhide","Example- Attempt to request hidden callbacks field unlock-user without unhide"]},{"l":"Configuration mode","p":["Configuration mode provides access to the following:","CRUD operations on top of persisted UniConfig, UniStore and template nodes","CRUD operations on top of persisted UniConfig settings","UniConfig RPC operations such as commit or calculate-diff","After opening configuration mode, a new UniConfig transaction is created. All operations invoked in configuration mode are executed in the scope of the created transaction. The transaction is automatically closed after leaving configuration mode ( exit or quit command).","If commit or checked-commit are invoked, the transaction is automatically refreshed. The user stays in configuration mode with a newly created transaction.","Commands like SET, SHOW and DELETE are now available only on a specific device and are not accessible in root configuration mode."]},{"l":"Show configuration","p":["The show operation is used to display selected subtrees.","The subtree path can be constructed interactively with the help of shell suggestions/auto-completion mechanism. Construction of the path works the same way for SET, SHOW and DELETE operations.","Example- Display the configuration of a selected container:","First move into a specific topology on a specific device:","After this, the show operation is available:"]},{"l":"Delete configuration","p":["The delete operation removes a selected subtree.","Example- Remove a container:","First move to a specific topology on a specific device:","After this, the delete operation is available:","Quit to configuration mode, commit using request mode and return to the device on the topology:"]},{"l":"Set configuration","p":["The set operation can be used for the following:","Set the value of a single leaf.","Set the values of multiple leaves in a single shell operation.","Set a list of values for a leaf-list.","Replace the entire subtree using a JSON snippet.","Example- Set the value of a single leaf:","Example- Set values for multiple leaves under the hold-time container:","A JSON snippet can be written to a selected data-tree node by entering the json sub-mode. In this sub-mode, you can type multiple lines that represent a well-formed JSON document. At the end, confirm the set operation using the pattern w!+ newline, or cancel the set operation with the pattern q!+ newline.","Example- Replace configuration of an interface using a JSON snippet:","Example- Leave json sub-mode without executing set operation:"]},{"l":"Execute UniConfig operation","p":["The request command is used to execute UniConfig operations such as commit or calculate-diff in the UniConfig transaction:","The command is available in configuration mode","You can fill in input parameters and values interactively or via provided JSON snippet","Example- Execute UniConfig RPCs in the scope of the open UniConfig transaction:"]},{"l":"Request operational mode","p":["This command has been merged with request configuration mode and is now available only in configuration mode.","Request mode allows users to:","Invoke selected UniConfig requests that read or alter UniConfig settings.","Invoke RPCs or actions provided by network devices or other southbound mountpoints.","Input parameters and values can be filled in interactively or via a provided JSON snippet. The transaction is passed from configuration mode.","Example- Invoke RPC execute-and-read with typed input parameters:","Example- Execute the same RPC execute-and-read using input JSON:","UniConfig shell does not support interactive typing of input arguments for an RPC/action that contains the list YANG element. Such operations must be executed using input JSON."]},{"l":"Show operational mode","p":["Show mode allows users to:","Display operational data about UniConfig itself (e.g., logging status, list of open transactions or list of acquired subscriptions)","Display operational data of network devices","After opening show mode, a new UniConfig transaction is opened. The transaction is closed when you leave this mode.","Example- Display configuration of selected subtree:","Example- Display selected system configuration:"]},{"l":"Pipe operations","p":["UniConfig shell supports pipe operations similar to Unix shell/bash pipes. When a command is followed by the pipe sign (|), the output of the command is passed to the selected pipe operation.","Example:","Supported pipe operations are:","grep- Show only lines that match supplied regex","match- Same as grep, but can be used with optional parameters to also show lines before and after matched lines","context-match- Same as grep, but also shows parent structure","brief- Display root elements in short table format","hide-empty-data-nodes- Hide data nodes without child nodes","hide-attributes- Hide attributes of data nodes"]},{"l":"Redirecting output","p":["The output of an executed command can be redirected to a file using the sign followed by a filename.","Example:","In this case, output in the console is empty but the content of the output.txt file is a follows:"]},{"l":"Aliases","p":["You can define aliases in UniConfig shell. A json file named shell-aliases is included in the UniConfig distribution for this purpose. After unpacking the UniConfig distribution, the file can be found under Uniconfig/distribution/packaging/zip/target/uniconfig-x.x.x/config. The file contains some sample aliases."]},{"l":"Alias creation","p":["Aliases cannot be created dynamically, only before Uniconfig is started. The following rules apply:","The alias name must be unique and cannot contain whitespaces.","The command can contain a wildcard (*). In this case, the user is prompted to add a value.","The alias is only visible in the mode where it was defined.","Example- Execute the alias diff xr5:","Example- Execute the alias lbr:","Example- Execute the alias shh:"]},{"l":"Callbacks","p":["Callbacks include sending POST and GET requests to the remote server and invoking user scripts from the UniConfig shell.","The following is required to use callbacks:","Necessary YANG modules - YANG modules that are required by the callbacks.","Configuration - Enable callbacks in config/application.properties and set the remote server and access token.","Update repository - Add the necessary YANG modules from step 1 into at least one YANG repository in the cache directory, and either define remote endpoints and scripts in a YANG file or create a new one for callbacks. For a definition of remote endpoints, use the frinx-callpoint@2022-06-22.yang extension.","UniStore node - Create a UniStore node using the YANG repository containing the necessary YANG modules from step 1 and a YANG file with defined endpoints and scripts.","In UniConfig shell, step 4 is optional as UniConfig creates dummy UniStore nodes for all repositories that meet the conditions in step 3. In this case, the dummy UniStore node name is identical to the YANG repository name.","In RestConf, step 4 is mandatory."]},{"l":"Necessary YANG modules","p":["The following YANG modules are required:","frinx-callpoint@2022-06-22.yang(not needed for scripts)","tailf-common@2018-11-12.yang","tailf-meta-extensions@2017-03-08.yang","tailf-cli-extensions@2018-09-15.yang"]},{"i":"configuration-1","l":"Configuration","p":["By default, callbacks are disabled and the host and port for the remote server are empty in config/application.properties.","To enable callbacks, set the configuration parameter callbacks/enabled to true. It is also necessary to set the host and port for the remote server and store an access token in the UniConfig database.","The host and port for the remote server can be set in three ways:","Before starting Uniconfig, in the config/application.properties file. The port number is optional:","After starting UniConfig, with a PUT request:","After starting UniConfig, with cli-shell:","The access token can be stored in the UniConfig database in one of two ways:","Available settings and descriptions for callbacks are listed below:"]},{"l":"Update repository","p":["First, create or update the YANG repository by using the frinx-callpoint@2022-06-22.yang extension displayed in the following snippet. There is only one extension, url, with the argument point."]},{"i":"add-call-point-get-request","l":"Add call-point (GET request)","p":["The following snippet shows how to create a call-point in the frinx-test YANG file by using the frinx-callpoint@2022-06-22.yang extension.","The argument of the url extension is /data/from/remote, which is appended to the end of the remote server URI configured in config/application.properties. Thus the final address for the remote call-point is https://remote.server.io/data/from/remote."]},{"i":"add-action-post-request","l":"Add action (POST request)","p":["The following snippet shows how to create an action in the frinx-test YANG file by using the frinx-callpoint@2022-06-22.yang extension. You must also import tailf-common.yang.","The action consists of:","The action name, defined by tailf:action.","The suffix for the remote endpoint, defined by fcal:url.","The input that contains body of the request. This part is optional."]},{"l":"Add script","p":["The following snippet shows how to create a script in the frinx-test YANG file by using tailf-common.yang. It is not necessary to import the frinx-callpoint@2022-06-22.yang extension.","The script consists of:","The script name, defined by tailf:action.","The path to the script, defined by tailf:exec.","Arguments for the script, defined by tailf:exec.","Arguments can be dynamic (i.e., the user can pass values to them) or static(flags). Follow these conventions when creating arguments:","Each argument must contain a name (for example, -n, -j).","Dynamic arguments must be enclosed in $(...)(for example, $(name)).","Flags are simple words without whitespace (for example, VIP, UPPER, upper)."]},{"l":"UniStore node","p":["A UniStore node can be created by RestConf or UniConfig shell. If a repository is explicitly defined by the query parameter?uniconfig-schema-repository=repository-name, this repository must contain all necessary YANG modules. If a repository name is not defined when the UniStore node is created, all necessary YANG modules must be in the latest schema repository."]},{"i":"examples-1","l":"Examples","p":["Example- Invoke callpoint in shell:","Example- Invoke action in shell:","Example- Execute user script in shell:"]}],[{"l":"UniStore API","p":["UniStore nodes are used to store and manage various settings and configurations inside UniConfig. The difference between UniStore and UniConfig nodes is that UniConfig nodes are backed by a real/network device, whereas UniStore nodes do not correspond to real devices. In the case of UniStore nodes, UniConfig is used only to manage the configuration and its persistence into the PostgreSQL DBMS.","UniStore nodes have the following characteristics:","UniStore nodes are not backed by \"real\" devices or southbound mountpoints. They are used only to store configurations which are committed to the PostgreSQL DBMS.","The configuration of a UniStore node can be read, created, removed and updated in the same way as UniConfig topology nodes. You can use the the same set of CRUD RESTCONF operations and supported UniConfig RPCs for operation purposes.","UniStore nodes are placed in a dedicated unistore topology under network-topology nodes. The whole configuration is placed under the configuration container.","The UniStore configuration is modelled by user-provided YANG schemas that can be loaded into UniConfig. When creating a new UniStore node, you must provide the name of a YANG repository so that UniConfig knows how to parse the configuration ( uniconfig-schema-repository query parameter).","UniConfig operations that are supported for UniStore nodes:","All RESTCONF CRUD operations","commit / checked-commit RPC","calculate-diff RPC (including git-like-diff flavor)","subtree-manager RPCs","replace-config-with-oper RPC","revert-changes RPC (transaction-log feature)","The node ID of a UniStore node must be unique among all UniConfig and UniStore nodes."]},{"l":"Commit operation","p":["Actions performed with UniStore nodes during a commit operation:","Verify configuration fingerprint. If another UniConfig transaction has already changed one of the UniStore nodes touched in the current transaction, the commit operation fails.","Calculate diff operation across all changed UniStore nodes.","Write intended configuration into the UniConfig transaction.","Replace the actual configuration with the intended configuration in the UniConfig transaction.","Update last configuration fingerprint to the UUID of the committed transaction.","Write transaction log into transaction.","Commit UniConfig transaction. Cached changes are sent to the PostgreSQL DBMS."]},{"l":"Example use case"},{"l":"Prepare YANG repository","p":["A YANG repository is required for UniConfig to model the UniStore node configuration. A UniStore node can only be modeled by one YANG repository.","To provide a YANG repository to UniConfig, copy the directory containing the YANG files under the cache parent directory. From there, it is loaded either at startup or in runtime with the register-repository RPC.","As an example, assume that cache contains the system YANG repository with a simple YANG module:"]},{"l":"Create UniStore node","p":["The following request shows how a new Unistore node ( global) is created using the provided JSON payload and the name of the YANG repository used to parse the payload (query parameter uniconfig-schema-repository). Note that the YANG repository must be specified only when the UniStore node is initialized."]},{"l":"Read content of UniStore node","p":["The following sample shows how to read the content of a UniStore node using a regular GET request. The query parameter content is set to config, indicating that the UniStore node is cached only in the Configuration datastore of the transaction (the Operational datastore is empty at this time)."]},{"i":"calculate-diff-rpc-created-node","l":"Calculate-diff RPC (created node)","p":["The calculate-diff operation is also supported for UniStore nodes. The following request shows the diff for all touched nodes in the current transaction, including UniStore nodes. As the UniStore node was just created, the diff output only contains created-data with the entire root settings container."]},{"l":"Persistence of UniStore nodes","p":["For UniStore nodes, the commit RPC is used to confirm the changes that have been made and to store them in the PostgreSQL DBMS. As described in the previous section, the commit operation stores the UniStore node configuration and transaction log in the DBMS and does not touch network devices.","Changes to UniStore and UniConfig nodes can be combined in the same transaction and can be committed simultaneously."]},{"l":"Read committed configuration","p":["Since the configuration was committed in the previous step, it is also visible in the Operational datastore of the newly created transaction. The actual state can be read by appending the content=nonconfig query parameter to a GET request, as shown in the following example:"]},{"l":"Verify configuration fingerprint","p":["The configuration fingerprint is part of the optimistic locking mechanism. By comparing fingerprints from the beginning of the transaction and from the commit operation, it is possible to see if another UniConfig transaction has already modified the affected UniStore node. For Unistore nodes, the fingerprint is always updated to match the transaction id (UUID) of the last committed transaction containing the UniStore node."]},{"l":"Modify configuration","p":["The same RESTCONF CRUD operations that can be applied to UniConfig nodes are also relevant to UniStore nodes. The following request demonstrates how to merge multiple fields using the PATCH operation."]},{"i":"calculate-diff-rpc-updated-node","l":"Calculate-diff RPC (updated node)","p":["The second calculate-diff RPC shows more granular changes made to an existing UniStore node, which includes the create-data and updated-data entries."]},{"l":"Display content of transaction log","p":["Committed transactions, including all metadata such as serialized diff output or transaction ID, can be displayed by reading the transactions-metadata container in the Operational datastore. Information about successfully committed UniStore nodes is also displayed. This can be used to revert changes using the transaction ID displayed in the transaction log."]},{"l":"Remove UniStore node","p":["A UniStore node can be removed either by sending a DELETE request to the entire node list entry or configuration container, or by removing all configuration child entities. In each case, the UniStore node is removed after changes are confirmed using the commit RPC."]}],[{"l":"YANG Patch Operations","p":["Yang Patch is used for modification of subtrees under configuration. Advantages of YANG Patch in comparison to other RESTCONF operations:","YANG Patch may contain multiple edits with different operations applied to different subtrees","all edits inside YANG Patch are applied atomically - either all edits are successful or PATCH operation will fail and configuration will not be modified","supported reordering of lists (move operation) and inserting of list entry to specific position in the list(insert operation)","UniConfig supports all RFC-specified operations inside edits:","CREATE","REPLACE","MERGE","MOVE","INSERT","DELETE","REMOVE","RENAME","Using these operations, the user is able to reorder lists, create new data, remove data, or update specific data.","For more information, please refer to the official documentation of the RFC YANG patch"]},{"l":"RPC Examples"},{"l":"Creation of list entries","p":["The request creates new list entries in the tvi list. If the data exist, return an error."]},{"l":"Moving list entry","p":["The request moves an existing list entry on a user defined position."]},{"l":"Inserting new list entry","p":["The request inserts new list entries on a user defined position."]},{"l":"Inserting new leaf-list entry","p":["The request inserts a new leaf-list entry on a user defined position."]},{"l":"Replacing list entry","p":["The request replaces an existing value in a list entry."]},{"l":"Merging configuration","p":["The request merges an existing value in a list entry."]},{"l":"Delete list entry","p":["The request deletes a list entry. If the data is missing, returns an error."]},{"l":"Removing list entry","p":["The request removes a list entry."]},{"l":"Renaming list entry","p":["The request renames a list entry key."]},{"l":"Failed deleting of list entry","p":["The request to delete a list entry that is not present."]},{"l":"Sending Patch request with invalid structure","p":["The request is missing some data."]}],[{"l":"Operational Procedures"},{"l":"Logging","p":["The UniConfig distribution uses Logback as its logging framework. Logback is the successor to the log4j framework with many improvements, such as more options for configuration, better performance, and context-based separation of logs. Context-based separation of logs is used widely in UniConfig to achieve per-device logging based on the set marker in the logs."]},{"l":"TLS","p":["TLS is a widely adopted security protocol designed to facilitate privacy and data security for communications over the Internet. TLS authentication is disabled in the default version of UniConfig."]},{"l":"TLS for Postgres database","p":["By default, UniConfig communicates with the database without TLS and traffic is therefore unencrypted. When the database is deployed separately from UniConfig, we recommend that you enable TLS encryption."]},{"l":"OpenAPI","p":["The UniConfig distribution contains a '.yaml' file that generates list of all usable RPCs with examples. You can view it either locally or on our hosted version, which always shows the latest OpenAPI version."]},{"l":"Data Security Models","p":["UniConfig supports encryption and hashing of values in RESTCONF and UniConfig shell API, as well as managing confidential data during transfers between the UniConfig database and network devices."]},{"l":"UniConfig Clustering","p":["The UniConfig stateless architecture allows deployment of the system in a cluster to ensure horizontal scalability and high-availability properties."]},{"l":"Thread pools","p":["UniConfig uses thread pools in several places. They can be configured in the application.properties file."]},{"i":"data-flows--transformations","l":"Data flows & transformations","p":["There are multiple paths and transformations of data within Uniconfig. The following section provides more information on some of the more common paths.","Thread pools"]}],[{"l":"Data flows and transformations","p":["Architecture","Flows","CLI, direct to device, plaintext interface","CLI, direct from device, configuration data read","CLI, direct from device, operational data read","CLI, direct to device, configuration data write","Netconf, direct from device, configuration data read","Netconf, direct from device, operational data read","Netconf, direct to device, configuration data write","Uniconfig, cached intent configuration, data read","Uniconfig, cached applied configuration, data read","Uniconfig, applying intent to a device","Uniconfig, synchronizing applied configuration from network"]},{"l":"Architecture","p":["CLI- Southbound plugin for managing devices over CLI (SSH).","Data flow architecture","gNMI- Southbound plugin for managing devices over gNMI (SSH).","JSON YANG RFC provides information on how JSON is used.","NETCONF- Southbound plugin for managing devices over Netconf (SSH).","Northbound","Restconf RFC provides detailed information on YANG-based REST API specifics.","Restconf- REST API for Uniconfig.","SNMP- // TBD","Southbound","The following diagram outlines the basic architecture for this purpose. It gives a simplified overview and only includes a subset of components, but serves as a baseline for illustrating various data flows.","The following main components are included:","The Uniconfig core consists of many different components/features. A good place to start is the build-and-commit model in Uniconfig.","Uniconfig CLI shell- CLI interface for Uniconfig. Similar capabilities as RESTCONF, but intended for users who prefer CLI access.","Uniconfig core","Uniconfig java SDK documentation provides an overview.","Uniconfig Java SDK- Java SDK for Uniconfig. Uses Restconf internally.","Uniconfig restconf documentation provides an overview.","Uniconfig shell documentation provides an overview."]},{"l":"Flows"},{"i":"cli-direct-to-device-plaintext-interface","l":"CLI, direct to device, plaintext interface","p":["Flow for reading/writing arbitrary commands to a CLI device.","The User sends an HTTP POST REST (rpc) request to Uniconfig.","URL specifies Uniconfig defined execute-and-read or execute-and-expect RPC.","URL must specify the following:","topology=cli- CLI-managed device","node=nodeID- specific managed device","Restconf invokes an asynchronous RPC on the southbound layer, but blocks until it completes.","The CLI layer invokes a generic implementation of the plaintext access RPC and returns output from the device as is.","Restconf receives the data from the CLI layer and completes the request.","Restconf example:","To send an arbitrary command to a device and receive a response:","To send a sequence of commands (ssh expect style) and receive a response:","Flow diagram:","Data flow architecture"]},{"i":"cli-direct-from-device-configuration-data-read","l":"CLI, direct from device, configuration data read","p":["?content=config- to specify only configuration data must be read from device (if not present, defaults to config)","CLI readers send specific commands to the device and parse the output into an internal DOM data structure.","Data flow architecture","Flow diagram:","Flow for reading structured (YANG-model based) configuration data from a device over CLI. The data is always retrieved from the device with no cache involved.","node=nodeID- specific managed device","Restconf component parses the URL and validates it against openconfig YANG models.","Restconf example:","Restconf invokes an asynchronous read from the southbound layer, but blocks until it completes.","Restconf receives the data from CLI layer, serializes them into JSON and completes the request.","The CLI layer finds appropriate an CLI driver (cli units) and invokes all readers registered for a specific path provided in the URL.","The user sends an HTTP GET REST request to Uniconfig.","To get configuration data for all interfaces:","topology=cli- CLI-managed device","URL must conform to openconfig data models used for all CLI devices.","URL must specify the following:"]},{"i":"cli-direct-from-device-operational-data-read","l":"CLI, direct from device, operational data read","p":["Flow for reading structured (YANG-model based) operational data from a device over CLI. The data is always retrieved from the device with no cache involved.","This flow is identical to CLI, direct from device, configuration data read flow. The difference is that this READ returns a combination of configuration and operational data ! To invoke operational data read, use ?content=nonconfig in the URL, the rest of URL is no different","Warning! Be careful when requesting operation data from devices. The data can be massive and the act of reading such data can cause issues on device itself. Always be as specific as possible, i.e., use the most specific (longest) URL possible.","Restconf example:","To get configuration and operational data for all interfaces:","Flow diagram:","Data flow architecture"]},{"i":"cli-direct-to-device-configuration-data-write","l":"CLI, direct to device, configuration data write","p":["?content=config- only configuration data is read from the device","CLI writers send specific commands to the device and check the output for errors.","Data flow architecture","Flow diagram:","Flow for writing structured (YANG-model based) configuration data to a device over CLI. The data is transformed and sent directly to a device.","node=nodeID- specific managed device","Note: We do not recommend writing directly to a device. The preferred option is to use Uniconfig core to build an intent and commit the changes to the network.","Restconf component parses the URL and the payload and validates them against openconfig YANG models.","Restconf example:","Restconf invokes an asynchronous write on the southbound layer, but blocks until it completes.","Restconf receives a success or failed response from the CLI layer and maps it to the appropriate status code.","The CLI layer finds the appropriate CLI driver (cli units) and invokes all writers registered for a specific path provided in the URL.","The payload must contain valid JSON that correspondos to the URL points within the YANG model.","The user sends an HTTP PUT or POST REST request into Uniconfig.","To configure a new Loopback999 interface:","topology=cli- CLI-managed device","URL and payload need to conform to openconfig data models used for all CLI devices.","URL must specify the following:"]},{"i":"netconf-direct-from-device-configuration-data-read","l":"Netconf, direct from device, configuration data read","p":["?content=config- only configuration data is read from the device (if not given, defaults to config)","Data flow architecture","Flow diagram:","Flow for reading structured (YANG-model based) configuration data from a device over Netconf. The data is always retrieved from the device with no cache involved.","node=nodeID- specific managed device","Restconf component parses the URL and validates it against vendor-specific YANG models.","Restconf example:","Restconf invokes an asynchronous read from the southbound layer, but blocks until it completes.","Restconf receives the data from the Netconf layer, serializes them into JSON and completes the request","The Netconf layer serializes the path (URL) into a get-config request with a filter, sends it to the device and parses the output into an internal DOM data structure.","The User sends an HTTP GET REST request to Uniconfig.","To get Loopback999 interface configuration using IOS XR vendor models:","topology=topology-netconf- Netconf-managed device","URL must conform to vendor-specific YANG data models used by the device.","URL must specify the following:","Which models are used depends on the device. Many vendor-specific models can be found on GitHub."]},{"i":"netconf-direct-from-device-operational-data-read","l":"Netconf, direct from device, operational data read","p":["Flow for reading structured (YANG-model based) operational data from a device over Netconf. The data is always retrieved from the device with no cache involved.","This flow is identical to the Netconf, direct from device, configuration data read flow. The difference is that this READ returns a combination of configuration and operational data by using get netconf RPC instead of get-config! To invoke operational data read, use ?content=nonconfig in the URL","Warning! Be careful when requesting operation data from devices. The data can be massive and the act of reading such data can cause issues on device itself. Always be as specific as possible, i.e., use the most specific (longest) URL possible.","Restconf example:","To get operational data for all interfaces using IOS XR vendor models:","Flow diagram:","Data flow architecture"]},{"i":"netconf-direct-to-device-configuration-data-write","l":"Netconf, direct to device, configuration data write","p":["Flow for writing structured (YANG-model based) configuration data to a device over Netconf. The data is transformed and sent directly to a device.","Note: We do not recommend writing directly to a device. The preferred option is to use Uniconfig core to build an intent and commit the changes to the network.","Restconf example:","To configure Loopback999 interface configuration using IOS XR vendor models:","Flow diagram:","Data flow architecture"]},{"i":"uniconfig-cached-intent-configuration-data-read","l":"Uniconfig, cached intent configuration, data read","p":["?content=config- only intent data is read for a device (if not given, defaults to config == intent)","An ad-hoc uniconfig transaction is started.","Data flow architecture","Flow diagram:","Flow for reading structured (YANG-model based), cached intent configuration data (not applied to network) for a device, regardless of its management protocol. The data is retrieved from in-memory cache (or a database, if not available in memory).","For more information about transactions, see Build and commit mode or Immediate commit model.","node=nodeID- specific managed device","Restconf component parses the URL and validates it against device-specific YANG models.","Restconf example:","Restconf invokes an asynchronous read from uniconfig core, but blocks until it completes.","Restconf receives the data from Uniconfig core, serializes them into JSON and completes the request.","The ad-hoc transaction is closed.","The user sends an HTTP GET REST request to Uniconfig.","This is typically a very quick operation compared to reading directly from a device.","To get Loopback999 interface cached intent configuration using IOS XR vendor models:","To get Loopback999 interface cached intent configuration using openconfig models for a device over CLI:","topology=uniconfig- device cached in uniconfig","Transactions can be started automatically by Uniconfig or controlled by the user.","Uniconfig core reads in-memory cached intent (or loads the latest version of data from the database).","URL must conform to models used for that specific device, whether standard or vendor-specific models.","URL must specify the following:"]},{"i":"uniconfig-cached-applied-configuration-data-read","l":"Uniconfig, cached applied configuration, data read","p":["?content=nonconfig- only applied data is read for a device (if not given, defaults to config == intent)","An ad-hoc uniconfig transaction is started.","Data flow architecture","Flow diagram:","Flow for reading structured (YANG-model based), cached configuration data (already applied to the network) for a device, regardless of its management protocol. The data is retrieved from in-memory cache (or a database, if not available in memory).","For more information about transactions, see Build and commit mode or Immediate commit model.","node=nodeID- specific managed device","Restconf component parses the URL and validates it against device-specific YANG models.","Restconf example:","Restconf invokes an asynchronous read from Uniconfig core, but blocks until it completes.","Restconf receives the data from Uniconfig core, serializes them into JSON and completes the request.","The ad-hoc transaction is closed.","The user sends an HTTP GET REST request to Uniconfig.","This is typically a quick operation compared to reading directly from a device.","To get Loopback999 interface cached intent configuration using IOS XR vendor models:","To get Loopback999 interface cached intent configuration using openconfig models for a device over CLI:","topology=uniconfig- device cached in uniconfig","Transactions can be started automatically by Uniconfig or controlled by the user.","Uniconfig core reads in-memory cached, already applied configuration (or loads the latest version of data from a database).","URL must conform to models used for that specific device, whether standard or vendor-specific models.","URL must specify the following:"]},{"i":"uniconfig-applying-intent-to-a-device","l":"Uniconfig, applying intent to a device","p":["Flow for writing structured (YANG-model based) configuration data to Uniconfig's intent. Intent is typically modified for multiple devices. When modifications are completed, a commit is issued to apply the changes to the network. Automated rollback may kick in when a failure occurs.","For more information on this flow, see Build and commit mode or Immediate commit model.","Note: Uniconfig core builds on top of \"direct to device data flows\" and everything south of Uniconfig core is identical to those (direct to device) data flows. For example, Uniconfig core uses the Netconf, direct to device, configuration data write flow to apply configurations to Netconf devices when performing a commit.","Restconf example:","To configure two devices in a single transaction:","Flow diagram:","Data flow architecture"]},{"i":"uniconfig-synchronizing-applied-configuration-from-network","l":"Uniconfig, synchronizing applied configuration from network","p":["An ad-hoc uniconfig transaction is started.","Data flow architecture","Flow diagram:","Flow for synchronizing/updating an applied configuration from a network device. This is useful especially when the configuration is changed in the network directly (outside of Uniconfig). Once the configuration is synchronized, those direct changes can be accepted or reverted in Uniconfig.","For more information about transactions, see Build and commit mode or Immediate commit model.","For more information on this flow, see Sync from network.","Payload must specify a list of devices to be synchronized.","Restconf example:","Restconf invokes an asynchronous RPC in Uniconfig core, but blocks until it completes.","Restconf receives a success or failed response from Uniconfig core and maps it to the appropriate status code and response.","The ad-hoc transaction is committed.","The user sends an HTTP GET REST request to Uniconfig.","To synchronize two devices from the network:","Transactions can be started automatically by Uniconfig or controlled by the user.","Uniconfig core performs direct from device configuration data read flows for each device in parallel.","Uniconfig core stores the new configuration in the applied configuration cache and in the database.","Uniconfig has a mechanism to verify whether a device is out of sync based on the last commit timestamp. A full configuration is performed only if out of sync.","URL specifies Uniconfig defined sync-from-network RPC."]}],[{"l":"Data Security Models","p":["UniConfig supports encryption and hashing of leaf/leaf-list values via SSH and RESTCONF API. The following sections describe the supported security models in depth."]},{"l":"Data encryption","p":["UniConfig uses asymmetric encryption to ensure confidentiality of selected leaf and leaf-list values. Currently only RSA ciphers are supported, both global UniConfig and device-level key-pairs. Encryption is supported for the uniconfig, unistore, and templates topologies."]},{"l":"Global-device encryption architecture","p":["Both the UniConfig and device sides use PKI for data encryption:","UniConfig side: All selected leaves are encrypted using a global public key when the data enters UniConfig via RESTCONF API or UniConfig SSH shell API. Afterwards, the data is stored in the database in encrypted format. UniConfig also has access to a private key used internally for decrypting data that is already encrypted.","Device side: The device exposes a public key, which UniConfig uses to re-encrypt data before it is sent to the device ( commit and checked-commit operations). However, the device does not expose its private key, and UniConfig is therefore not able to detect changes to encrypted data (updated leaves/leaf-lists) but can only detect if data was removed or created. Because of this, UniConfig assumes that encrypted data read from the device was encrypted using the same public key as that used by UniConfig.","The figure below depicts data transformations performed on UniConfig interfaces:","Global-device encryption model"]},{"l":"Global-only encryption architecture","p":["In contrast to the global-device encryption architecture, this model uses only a global key-pair to encrypt data. Devices contain only plaintext data.","A public key is used to encrypt data received via RESTCONF, UniConfig shell API and when syncing configurations from device to UniConfig transaction( sync-from-network operation).","A private key is used to decrypt encrypted data before forwarding this configuration to a device ( commit and checked-commit operations).","The figure below depicts data transformations performed on UniConfig interfaces:","Global-only encryption model","Reading operational data directly from the device (GET under yang-ext:mount) shows data in unencrypted format. Application gateways should restrict access to mountpoints for such use cases."]},{"l":"YANG support","p":["Leaves and leaf-lists whose values should be encrypted must be marked using a YANG extension with no parameters. Currently, only leaves of the string type are supported (direct/indirect with custom type definitions), as encrypted values are base64 encoded. Also, be aware that type constraints must accept encrypted values.","Example- YANG module that defines one encrypt extension:","Using the extension in the config module:","Oftentimes it is not possible to modify existing YANG files, as they are already deployed on a device (for example, a device running with a NETCONF server). In this case, you can still mark which leaves should be encrypted using an additional YANG module that contains deviations.","Example","Afterwards, there are two options to couple this module with modules from the device (NETCONF):","Explicitly specifying the side-loaded module in the install-node request using the netconf-node-topology:yang-module-capabilities settings. See Device installation section below for more information.","Automatically detecting the side-loaded module - UniConfig looks for the specific capability on the NETCONF server, inherits its revision and looks for a side-loaded module with a specific name and inherited revision (see Configuration section below). This option is preferred if the deployment contains multiple versions of devices and the list of encrypted paths is different on each version."]},{"l":"Configuration","p":["The global RSA key-pair is stored inside PEM-encoded files in the rsa directory under UniConfig root. The private key must be named encrypt_key and the public key encrypt_key.pub. If these files are not provided, UniConfig automatically generates its own key-pair with a length of 2048 bits. All UniConfig instances in the cluster must use the same key-pair.","Encryption settings are stored in the config/application.properties file.","Example:","encrypt-enabled- If false, encryption is disabled regardless of other settings or install-node parameters. If true, encryption is enabled. The default value is true.","encrypt-extension-id- If not specified, encryption is disabled regardless of other settings or install-node parameters. Uses the format[module-name]:[extension-name], which specifies the extension used to mark encrypted leaves/leaf-lists in YANG modules. The corresponding YANG module containing this extension can be part of device/unistore YANG schemas or, alternatively, can be side-loaded during installation of the NETCONF device as an imported module from the default repository.","netconf-reference-module- Name of the module that the NETCONF client looks for during the mounting process. If UniConfig finds a module with this name in the list of received capabilities, it uses its revision in the lookup process for the correct YANG module with encrypted paths (using deviations).","netconf-encrypted-paths-module-name- Name of the module which contains deviations with paths to encrypted leaves/leaf-lists. There can be multiple revisions of this file prepared in the default NETCONF repository. The NETCONF client in UniConfig chooses the correct revision based on the netconf-reference-module-name setting. Together, netconf-reference-module-name and netconf-encrypted-paths-module-name can be used to autoload encrypted paths for different versions of devices.","If the default YANG repository contains a module with encrypted-paths and without defined YANG revision, and the device does not already provide encryption capability, the encrypted-paths module is used as last resort during device installation ( netconfReferenceModuleName and matching of revisions are ignored)."]},{"l":"Change encryption status","p":["using the following parameter:","Encryption can be enabled or disabled using the following parameter:","The value of this parameter can be changed with the change-encryption-status RPC request.","The following request can be used to enable encryption:","After this command is called, all UniConfig instances will set this parameter using the notification service to the value sent via RPC (in this case, true).","Correspondingly, the following request can be used to disable encryption:","The following request is used to check the current encryption status:","To check the functionality of this RPC after calling the install-device RPC, you can request the password for the node:","If encryption is enabled, the password is returned encrypted.","If encryption is disabled, the password is returned as plaintext."]},{"i":"change-encryption-keys-private-and-public","l":"Change encryption keys (private and public)","p":["If it is necessary to change the encryption keys, use the change-encryption-keys RPC.","The process of changing encryption keys requires rebooting one of the UniConfig instances or enabling a new instance of UniConfig after calling the change-encryption-keys RPC. Rotation of encrypted data in the database for new encryption keys occurs if UniConfig is started after the change-encryption-keys RPC is executed. During key rotation, if some data in the database cannot be decrypted with the old key, those data will remain unchanged.","The default value of the new-encryption-cipher-type parameter is RSA, so there is no need to add this parameter to the request body.","To check if UniConfig must be restarted or if a new UniConfig instance must be added, run the following query:","After key rotation and when UniConfig is started, data encrypted with the old key is overwritten with the new encryption keys and all other UniConfig instances in the cluster will use the new keys for encryption.","During key rotation, UniConfig reads and updates encrypted configurations in batches. The size of these batches is set by the following parameter:"]},{"l":"Device installation","p":["There are two settings related to encryption in the install-node RPC request:","uniconfig-config:device-crypto- Specifies a path to the public key on the device:","public-key-path- Leaf with RFC-8040 path. If a path to the public key is specified and exists on the device, the global-device encryption model is used. Otherwise, the global-only encryption model is used.","public-key-cipher-type- Cipher type (RSA is used by default).","netconf-node-topology:yang-module-capabilities- If autoloading of YANG modules with encrypted paths is not used and the device itself does not specify encrypted leaves, it is necessary to side-load the YANG module with encrypted paths. This parameter is relevant only for NETCONF nodes. Side-loaded modules must be expressed in the format of NETCONF capabilities.","The following request shows an install-node request that specifies a path to the public key and the side-loaded YANG module encrypted-paths with revision 2021-12-15 and namespace urn:ietf:params:xml:ns:yang:encrypted-paths.","During installation, UniConfig tries to download the public key from the device. The public key can be verified using a GET request:"]},{"l":"Format for encrypted data","p":["Encrypted values are stored and displayed via RESTCONF or UniConfig shell with the rsa_ prefix. The prefix is used by UniConfig to see if posted data needs to be encrypted or is encrypted already.","The encrypted string is encoded using Base64 encoding."]},{"i":"example-global-device-model","l":"Example: Global-device model","p":["This example shows encryption of values marked by the frinx-encrypt:encrypt extension on both UniConfig server side and device side. The NETCONF device directly exposes the frinx-encrypt YANG module and leaves with applied extension (side-loading of encrypted paths is not necessary).","YANG model used for simulating the YANG device:"]},{"i":"example-global-only-model","l":"Example: Global-only model","p":["This example shows encryption of values marked by the frinx-encrypt:encrypt extension only on the UniConfig server side. The NETCONF device directly exposes the frinx-encrypt YANG module and leaves with applied extension (side-loading of encrypted paths is not necessary).","The YANG model used for simulation of the YANG device is the same as in the previous example."]},{"l":"Data hashing","p":["UniConfig supports the iana-crypt-hash YANG model for specificying hashed values in the data-tree using the type definition crypt-hash. Hashing works in the uniconfig and unistore topologies.","Only NETCONF devices are currently supported, as CLI cannot be natively used to report device capabilities that would contain supported the hashing function."]},{"l":"Architecture","p":["Hashing is done only in the RESTCONF layer after writing data that contains leaves/leaf-lists with the crypt-hash type. Afterwards, UniConfig stores, uses, and writes to the device only the hashed representation of these values.","Hashing model"]},{"i":"yang-support-1","l":"YANG support","p":["YANG module iana-crypt-hash: http://www.iana.org/assignments/yang-parameters/iana-crypt-hash@2014-08-06.yang","All three hash functions are implemented ( MD5, SHA-256 and SHA-512). For the uniconfig topology, the hashing function is selected based on the reported feature in the NETCONF capability. For the unistore topology, UniConfig enforces the SHA-512 hashing function."]},{"i":"device-installation-1","l":"Device installation","p":["Hashing is enabled by default on NETCONF devices that report the iana-crypt-hash model-based capability. It is not necessary to add the entry setting in the install-node request.","After successfully installing the device, you can check the loaded hashing function that will be used to store hashed values. Use the following GET request:"]},{"i":"example-hashing-input-values","l":"Example: Hashing input values","p":["This example demonstrates hashing input values with the crypt-hash type using the RESTCONF API."]}],[{"l":"Logging framework","p":["UniConfig uses the Logback logging framework. Logback is the successor to the log4j framework with many improvements, such as more options for configuration, better performance and context-based separation of logs. The latter is used widely in UniConfig to achieve per-device logging based on the set marker in the logs."]},{"l":"Logback configuration","p":["Logback configuration is placed in the config/logback.xml file under the UniConfig distribution. For more information, see Logback configuration.","This section describes parts of the configuration in the context of UniConfig."]},{"l":"Appenders","p":["The following appenders are used:","STDOUT- Print logs to the console.","logs- Write all logs to the output file at log/logs.log. A rolling file appender is applied.","netconf-notifications, netconf-messages, netconf-events, cli-messages and gnmi-messages- Sifting appenders that split logs per node ID set in the marker of the logs. Logs are written to different subdirectories under the log directory, and are identified by their node ID. A rolling file appender is applied.","restconf- Appender used to write RESTCONF messages to the log/restconf.log file. A rolling file appender is applied.","gnmi- Appender used to write logs related to the gNMI topology."]},{"l":"Loggers","p":["There are two groups of loggers:","Package-level logging brokers: Loggers used to write general messages to the console and a single output file.","Default logging level: INFO. For debugging purposes, it can be useful to change the logging level to TRACE or DEBUG.","Layers covered: UniConfig, Unified, Controller, RESTCONF, CLI, NETCONF, gNMI.","Appenders used: STDOUT and logs.","Loggers used for logging brokers: These loggers should not be changed since the state of logging can be changed using RPC calls. Classpaths point to specific classes that represent implementations of logging brokers.","Logging level is set to TRACE.","Appenders used: netconf-notifications, netconf-messages, netconf-events, cli-messages, gnmi-messages and restconf."]},{"l":"Update configuration","p":["Logback is configured to scan for changes in its configuration file and automatically reconfigure itself when the configuration file changes. The default scanning frequency is 5 seconds."]},{"l":"Example configuration","p":["In the logback.xml file, you can edit the level of logging for each UniConfig component:"]},{"l":"Logging levels","p":["The following logging levels are available:"]},{"l":"INFO","p":["This is the recommended logging level for production environments.","INFO messages describe the behavior of applications (for example, if a particular service starts or stops, or something is added to the database). During typical operations, these log entries are nothing to worry about and no follow-up actions are necessary."]},{"l":"DEBUG","p":["The DEBUG level gives verbose diagnostic information that includes more detail than is necessary to use the application. This logging level is used to diagnose, troubleshoot, or test an application to ensure that it runs smoothly."]},{"l":"TRACE","p":["The TRACE level captures all detail about the application's behavior. It is mostly diagnostic and is more granular than DEBUG. This log level is used in situations where you need to see exactly what happened in your application."]},{"l":"Logging brokers","p":["The logging broker represents a configurable controller that logs one logical group of messages from a single classpath. Logging multiple messages from the same classpath simplifies the configuration of loggers in Logback, since only one logger per broker must be specified.","The logging broker is controlled using RESTCONF RPCs. There are several operations that can trigger logging for the whole broker or only for specified node IDs. The logger configuration in the logback file assigned to the broker should not be changed.","The following subsections describe available logging brokers:"]},{"l":"RESTCONF","p":["Used to log authenticated HTTP requests and responses; information about URI, source, HTTP method, query parameters, HTTP headers and body.","Per-device logging cannot be enabled for this broker. All logs are saved to the log/restconf.log file.","It is possible to specify HTTP headers whose content is masked the in logs with asterisks (*). This is useful if some headers contain private data (such as Authorization or a Cookie headers). Hidden HTTP headers are marked using header identifiers.","It is also possible to configure HTTP methods for which communication (requests and responses) is not logged to a file.","Requests and responses are paired using a unique message-id attribute, which is not part of the HTTP request but is generated on the RESTCONF server.","Requests and responses contain Uniconfig transactions for easier matching with log transactions.","Example- Request and corresponding response (same message-id):"]},{"l":"CLI messages","p":["Used to log all CLI requests and responses.","CLI requests and responses are paired with a unique message-id attribute.","Supports per-device logging. Logs for CLI messages are stored under the log/cli-messages directory and named according to the pattern [node-id].log.","Example- Send POST RPC to install a CLI device and pair requests with corresponding responses (same message-id):"]},{"l":"NETCONF Messages","p":["Used to log all NETCONF messages, incoming and outgoing, except for NETCONF notifications (a separate broker handles notifications).","NETCONF RPCs and responses can be matched using the message-id attribute placed in the RPC header.","Supports per-device logging. Logs for NETCONF messages are stored in the log/netconf-messages directory and named according to the pattern [node-id].log.","Example- Send NETCONF GET RPC and receive a response:","The number 641 represents the session ID read from the NETCONF hello message. If multiple sessions are created between the NETCONF server and client that are logically grouped under the same node ID, logs from multiple sessions are stored in the same logging file. This is necessary to distinguish between the sessions. Multiple NETCONF sessions between the UniConfig and NETCONF server are created for each subscription to the NETCONF stream."]},{"l":"NETCONF Notifications","p":["Used to log incoming NETCONF notifications.","Supports per-device logging. Logs for NETCONF notifications are stored in the log/netconf-notifications directory and named according to the pattern [node-id].log.","Example- Receiving two notifications:"]},{"l":"NETCONF Events","p":["Used to log session-related information about establishing or closing a NETCONF session from the view of the NETCONF client placed in UniConfig.","These logs do not contain full printouts of sent or received NETCONF messages.","Supports per-device logging. Logs for NETCONF events are stored in the log/netconf-events directory and according to the pattern [node-id].log.","Example:"]},{"l":"gNMI Messages","p":["Used to log all gNMI SET/GET messages, incoming or outgoing, except for gNMI notifications.","Support per-device logging. Logs for gNMI messages are stored in the log/gnmi-messages directory and named according to the pattern [node-id].log.","Example- Send gNMI SET request and receive a response:"]},{"l":"Supported logging settings","p":["`restconf-logging:hidden-http-headers`` - List of HTTP headers (names of headers) whose content is hidden in the logs. Names of headers are case-insensitive.","broker-identifier- Unique identifier for the logging broker. The following brokers are supported: netconf\\_messages, restconf, netconf\\_notifications, netconf\\_events, and cli\\_messages.","Current logging broker settings are stored in the Operational datastore under the logging-status root container.","enabled-devices- If is-logging-enabled-on-all-devices is set to false, logs are generated only for devices specified in this list. Acts as a simple filtering mechanism based on the whitelist. A blacklist approach is not supported, as it is not possible to set is-logging-enabled-on-all-devices to true and specify devices for which logging feature is disabled. This setting is not supported for the restconf logging broker.","Global settings common for all logging brokers:","gnmi-logging:message-types- gNMI message types that are logged. Names of message types must be specified in uppercase.","GNMI-specific settings:","hidden-types- The value of leafs or leaf-lists using one of the types specified is masked in the logs with asterisks (*). Useful for hiding passwords and other confidential data in logs.","is-logging-broker-enabled- Specifies if the logging broker is enabled or not. If the broker is disabled, no logging messages are generated.","is-logging-enabled-on-all-devices- If set to true, logs are separated into distinct files in the scope of all devices. If set to false, logging is enabled only for devices listed in the enabled-devices leaf-list/array. This setting is not supported for the restconf logging broker as RESTCONF currently does not differentiate the node ID in requests or responses.","Logging settings are encapsulated inside multiple list entries ( broker list). Each entry contains settings for one logging broker.","Response:","restconf-logging:hidden-http-methods- HTTP requests and associated HTTP responses are not logged if the request's HTTP method is included in this list. Names of HTTP methods must be specified in uppercase.","RESTCONF-specific settings:","Settings placed under a single logging entry:","The following example shows a GET query that displays the logging broker settings:"]},{"l":"Initial configuration","p":["By default, all logging brokers are disabled and logging is disabled on all devices. To enable per-device logging, you must explicitly specify a list of devices. Additionally, RESTCONF-specific filtering is not configured, all HTTP requests and responses are fully logged and no content is dismissed. By default, only the SET gNMI message type is set to be logged.","The initial logging configuration can be adjusted by adding the logging-controller configuration to the config/application.properties file. The structure of this configuration section conforms to the YANG structure described by the logging and restconf-logging modules. It is possible to copy the state of the Operational datastore under logging-status into the logging-controller node.","The following properties snippet shows the sample configuration logging-controller. The logging brokers netconf\\_messages and netconf\\_notifications are enabled, ( netconf\\_messages for all devices and netconf\\_notifications only for xr6 and xr7 devices).","If unknown parameters are specified in a configuration file, they are ignored and a warning is logged."]},{"l":"Control logging using RPC calls","p":["As logging settings are stored in the Operational datastore, it is possible to adjust these settings in runtime only using RPC calls. The following subsections describe available RPCs."]},{"l":"Enable logging broker","p":["This RPC is used to enable the logging broker, which is then available to write logs. RPC input contains only the name of the logging broker ( broker-identifier).","Example- Enable logging broker with the restconf identifier:","The output shows a successful response:"]},{"l":"Disable logging broker","p":["This RPC is used to disable a logging broker, which will no longer write any logs regardless of other settings. RPC input contains only the name of the logging broker.","Example- Disable logging broker with the restconf identifier:","The output shows a successful response:"]},{"l":"Enable default device logging","p":["This RPC is used to set the default device logging to true. Logs are written for all devices without filtering based on node ID.","RPC input contains only the name of the logging broker ( broker-identifier). Invoking this RPC clears the leaf-list enabled-devices.","Example- Enable default device logging in the netconf\\_messages logging broker:","The output shows a successful response:"]},{"l":"Disable default device logging","p":["This RPC is used to set the default device logging to false. Logs are written only for devices named in the enabled-devices leaf-list. If enabled-devices does not contain a node ID, logging in the corresponding broker is effectively turned off.","RPC input contains only the name of the logging broker ( broker-identifier).","Example- Disable default device logging in the netconf\\_messages logging broker:","The output shows a positive response:"]},{"l":"Enable device logging","p":["This RPC is used to enable logging for specified devices identified by node IDs. RPC input contains the name of the logging broker ( broker-identifier) and a list of node IDs ( device-list).","Example- Enable logging for devices with node IDs node1, node2, and node3 in the netconf\\_events logging broker:","The output shows a successful response:"]},{"l":"Disable device logging","p":["This RPC is used to turn off logging for specified devices identified by node IDs. RPC input contains the name of the logging broker ( broker-identifier) and a list of node IDs ( device-list).","Example- Disable logging for device with node ID node1 in the netconf\\_events logging broker:","The output shows a successful response:"]},{"l":"Set global hidden types","p":["This RPC is used to set identifiers of hidden YANG type definitions. Values of leaves and leaf-lists described by these types are masked in output logs. Overwrites all previously configured hidden types. An empty list of hidden types will disable filtering of data values. Filtering applies to all logs, including RESTCONF logs.","Example- Set three (3) hidden types:","The output shows a successful response:"]},{"l":"Set Hidden HTTP Headers","p":["This RPC is used to overwrite the list of HTTP headers whose content is hidden in the output of RESTCONF logs. Only affects the restconf logging broker.","HTTP headers in both requests and responses are masked. The list of hidden headers denotes header identifiers. The identifier of hidden headers is still included in output logs, but their content is masked with asterisks (*).","Example- Hide the content of Authorization and Cookie HTTP headers:","The output shows a successful response:"]},{"l":"Set hidden HTTP methods","p":["This RPC is used to overwrite the list of HTTP methods. RESTCONF communication, which may include invoking hidden HTTP methods, is not displayed in output logs.","Both requests and responses with hidden HTTP methods are excluded from the log files. Only affects the restconf logging broker.","Example- Hide GET and PATCH communication in RESTCONF logs:","The output shows a successful response:"]},{"l":"Set gNMI message types","p":["This RPC is used to overwrite the list of supported gNMI message types. Only affects the logging of gNMI messages.","Example- Set 'SET' and 'GET' message types:","The output shows a successful response:"]}],[{"l":"OpenAPI","p":["The OpenAPI file located in the openapi folder contains all the RPCs and data manipulating requests (CRUD operations), and their respective examples. A shell script (named start_uniconfig_swagger.sh) was created that automatically checks if the file is present and runs it in a docker container where the Swagger API runs, and opens the file containing all the RPCs and data manipulating requests. After running the shell script, open any browser and type localhost in the URL bar.","Overview of our OpenAPI along with all parameters and expected returns can be found here","The website should look like on the screenshot below:","openapi website","Alternatively, you can look at our live instance of the site that always displays latest version of the API."]}],[{"l":"Thread pools","p":["There are several thread pools that can be configured in UniConfig:","Jetty server,","Task executor,","Notifications,","SSH Client,","NetConf topology,","CLI topology."]},{"l":"Jetty server","p":["Jetty server is used to aggregate connectors (HTTP request receivers) and request handlers. Connectors use the thread pool methods to run jobs that will eventually call the handle method.","Available parameters to configure:","jetty.max-threads=200","The maximum number of threads available in the jetty server. The default value is 200.","jetty.min-threads=8","The minimum number of threads available in the jetty server. The default value is 80.","jetty.idle-timeout=60","Threads that are idle for longer than this period (in seconds) can be stopped. The default value is 60.","If any of these parameters are left empty (e.g. jetty.max-threads=), the default value is used."]},{"l":"Task Executor","p":["The task executor is used to execute operations (internal operations or RPCs), either synchronously or asynchronously, on given nodes or devices.","task-executor.max-queue-capacity=10000","The maximum queue capacity for postponed tasks. The default value is 10000.","task-executor.max-cpu-load=0.9","The maximum CPU load for executing tasks. Load is expressed as a ratio so that 1.0 corresponds to 100% load, 0.9 to 90%, etc. The default value is 0.9.","task-executor.default-thread-count=","The efault thread count used for executing tasks. The default value is the number of available processors * 2.","task-executor.max-thread-count=","The maximum thread count used for executing tasks. The default value is default-thread-count* 20.","task-executor.keepalive-time=60","The time in seconds before the execution of a specified task is timed out. The default value is 60.","If any of these parameters are left empty (e.g. task-executor.default-thread-count=), the default value is used."]},{"l":"Notifications","p":["A NetConf related thread pool that handles notification subscriptions (acquiring of subscriptions, release of subscriptions, etc.).","notifications.thread-parameters.monitoring-executor-initial-pool-size=","The initial thread count used by the monitoring executor. The default value is the number of available processors.","notifications.thread-parameters.monitoring-executor-maximum-pool-size=","The maximum thread count used by the monitoring executor. The default value is initial-pool-size* 4.","notifications.thread-parameters.monitoring-executor-keepalive-time=60","The time in seconds before the execution of a specified task is timed out in the monitoring executor. The default value is 60.","If any of these parameters are left empty (e.g. notifications.thread-parameters.monitoring-executor-initial-pool-size=), the default value is used."]},{"l":"SSH Client","p":["SSH Client uses a thread pool that handles communication with devices. This thread pool is shared between NetConf and CLI topologies.","ssh-client.default-timeout=-1","Timeout for SSH connections (in seconds). If set to a negative value, timeouts are disabled. The default value is -1.","ssh-client.heartbeat-interval=30","The interval (in seconds) at which the client pings the server to check if the connection is still alive. The default value is 30.","ssh-client.heartbeat-reply-wait=60","Indicates if the heartbeat request expects a reply. Time (in seconds) to wait for a reply, a non-positive value means that no reply is expected. The default value is 60.","ssh-client.heartbeat-request=keepalive@sshd.apache.org","The heartbeat request that is sent to the server. The default value is keepalive@sshd.apache.org.","ssh-client.ssh-default-nio-workers=8","The amount of non-blocking workers that handle communication messages. The default value is 8.","If any of these parameters are left empty (e.g. ssh-client.ssh-default-nio-workers=), the default value is used."]},{"l":"NetConf Topology","p":["NetConf topology thread pools are used to connect to NetConf devices and keep the connection alive.","netconf-topology-parameters.fixed-thread-pool-thread-count=2","The fixed thread pool thread count in the NetConf topology. Used to read device capabilities and schema set up. The default value is 2.","netconf-topology-parameters.scheduled-thread-pool-thread-count=2","The scheduled thread pool thread count in the NetConf topology. Used to schedule keepalive messages. The default value is 2.","If any of these parameters are left empty (e.g. netconf-topology-parameters.fixed-thread-pool-thread-count=), the default value is used."]},{"l":"CLI Topology","p":["CLI topology thread pools are used to connect to CLI devices and keep the connection alive.","cli-topology-parameters.keepalive-thread-count=","The thread pool count dedicated ONLY to keepalive and reconnect scheduling. The default is either 2 or the number of available processors, whichever is higher.","cli-topology-parameters.init-executor-thread-timeout=120","If any thread is unused for this period (in seconds), it is stopped and recreated in the future if necessary.","cli-topology-parameters.init-executor-thread-count=","The maximum, number of threads for the flexible thread pool executor. This thread pool is used to process events and asynchronous locking of the CLI layer. The default is the number of available processors * 8.","If any of these parameters are left empty (e.g. cli-topology-parameters.keepalive-thread-count=), the default value is used."]}],[{"l":"TLS encryption for Postgres database","p":["By default, communications with the database are unencrypted. In deployments where UniConfig is running separately from the database, network traffic may be visible to outside parties.","The sections below describe how to enable TLS encryption for communications with the database."]},{"l":"Generate self-signed certificate using OpenSSL","p":["If you have already generated your SSL keys, you must convert them to the correct format. See Convert SSL keys to correct format","If not, you must first generate your keys."]},{"l":"Convert SSL keys to correct format","p":["The correct format for SSL keys is as follows:","The command for converting the keys may differ based on the format of your existing keys. They can be converted using OpenSSL version 1.1.1 with the openssl command.","The OpenSSL documentation provides examples for most common cases:","To convert to PKCS-8 DER binary format, see PKCS-8.","To convert to PKCS-12 format, see PKCS-12."]},{"l":"Enable TLS for database connections","p":["Edit the configuration file at the following path relative to the UniConfig root directory:","Modify the connection section within the dbPersistence section:","Example:","TLS-related fields include the following:","db-persistence.connection.enabled-tls- Set to true to enable TLS encryption. The default value is false.","db-persistence.connection.tls-client-cert- Specify the relative path from the root UniConfig directory to the Client certificate.","db-persistence.connection.tls-client-key- Specify the relative path from the root UniConfig directory to the Client key. Can be PKCS-12 or PKCS-8 format.","db-persistence.connection.tls-ca-cert- Specify the relative path from the root UniConfig directory to the root CA certificate.","db-persistence.connection.ssl-password- If the file specified in db-persistence.connection.tls-client-key is encrypted with a password, specify the password here. Required for PKCS-12 keys and for encrypted PKCS-8 keys. Ignored for unencrypted keys.","Do not forget to adjust other database connection parameters accordingly."]}],[{"l":"TLS-based Authentication","p":["TLS authentication is disabled in the default version of UniConfig.","To enable TLS for RESTCONF, perform the following two steps:","Set up key-store and trust-store to hold all keys and certificates. If authentication of individual clients is not required, trust-store is also not required. Key-store must always be initialized.","Enable TLS in UniConfig via the application.properties configuration file."]},{"l":"Set key-store and trust-store","p":["To prepare key-store and trust-store:","In the UniConfig root directory, create a new directory that will contain key-store and, optionally, trust-store files. For example:","Create a new key-store. There are two options depending on whether you already own the certificate that you want to use for identification of UniConfig on the RESTCONF layer:","Create a new key-store with the generated RSA key-pair (the example below uses a length of 2048 and validity of 365 days). After executing the following command, the prompt will ask you for information about the currently generated certificate that is pushed into the newly generated key-store secured by a password (this secret will be used later in the configuration file - make sure that you remember it).","Create a new key-store with the already-generated RSA key-pair (your certificate that you want to use for authentication in ODL).","(Optional step) Create a new trust-store using an existing certificate (an empty trust-store cannot be created). If you have multiple client certificates, they can be pushed to trust-store by executing the same command multiple times (the alias must be unique for each of the imported certificates). For example:","You can easily convert OPENSSL PEM certificates to the DER format supported by keytool:","If your application must own the distribution's certificate, you can export the certificate from the generated key-pair that we have pushed into the keystore(PKCS12 or OPENSSL format):"]},{"l":"Enable TLS in UniConfig","p":["After preparing key-store and trust-store, you need to point UniConfig to these storages and explicitly enable TLS via a flag.","Modify the following configuration file at a path relative to the UniConfig root directory:","Next, edit the TLS configuration section, un-commenting and editing the relevant properties.","The example snippet below enables TLS authentication, disables user-based authentication (hence trust-store is not required) and points UniConfig to the key-store file created in the previous section:","If your deployment requires authentication for individual RESTCONF users, trust-store is required and you need to set server.ssl.client-auth=need","JVM provides secure defaults, which you can override by specifying included cipher suites and TLS versions.","The following example configuration includes support for TLS 1.2 and TLS 1.3 with some of the most common and strongest ciphers available:","SNI (Server Name Indication) is disabled by default. To enable it, uncomment the line below:"]}],[{"l":"UniConfig Clustering"},{"l":"Introduction","p":["UniConfig can be easily deployed in a cluster owing to its stateless architecture and transaction isolation:","Stateless architecture - UniConfig nodes in the cluster do not keep any state that needs to be communicated directly to other UniConfig nodes in the cluster. All network-topology configuration and state information is stored inside a PostgreSQL database that must be reachable from all UniConfig nodes in the same zone. All UniConfig nodes share the same database, making the database the single source of truth for the cluster.","Transaction isolation - Load-balancing is based on mapping UniConfig transactions to UniConfig nodes in a cluster (transactions are sticky). One UniConfig transaction cannot span multiple UniConfig nodes in a cluster. Southbound sessions used for device management are ephemeral, i.e., they are created when UniConfig needs to access a device on the network (like pushing configuration updates) and are closed as soon as a UniConfig transaction is committed or closed.","There are several advantages to clustered deployment of UniConfig nodes:","Horizontal scalability - Increasing the number of units that can process UniConfig transactions in parallel. A single UniConfig node tends to have limited processing and networking resources - this constraint can be mitigated by increasing the number of nodes in the cluster. The more UniConfig nodes in the cluster, the more transactions can be executed in parallel. The number of connected UniConfig nodes in the cluster can also be adjusted at runtime.","High availability - A single UniConfig node does not represent a single point of failure. If a UniConfig node crashes, only transactions processed by the corresponding node are cancelled. The application can retry a failed transaction, which will be processed by the next node in the cluster.","There also are a couple limitations to be considered:","Parallel execution of transactions is subject to a locking mechanism, whereby two transactions cannot manipulate the same device at the same time.","A single transaction is always executed by a single UniConfig node. This means that the scope of a single transaction is limited by the number of devices and their configurations that a single Uniconfig node can handle."]},{"l":"Deployments"},{"l":"Single-zone deployment","p":["In a single-zone deployment, all managed network devices are reachable by all UniConfig nodes in the cluster zone. Components of a single-zone deployment and connections between them are illustrated in the diagram below.","Deployment with single zone","Included components:","UniConfig controllers - Network controllers that use a common PostgreSQL system for persistence of data, communicate with network devices using NETCONF/GNMi/CLI management protocols and propagate notifications into Kafka topics (UniConfig nodes act only as Kafka producers). UniConfig nodes do not communicate with each other directly, their operations can only be coordinated using data stored in the database.","Database storage - PostgreSQL is used for persistence of network-topology configuration, mountpoints settings and selected operational data. The PostgreSQL database can also be deployed in the cluster (outside of scope).","Message and notification channels - The Kafka cluster is used to propagate notifications generated by UniConfig itself (e.g., audit and transaction notifications) or from network devices and only propagated by UniConfig controllers.","Load-balancers - Load-balancers are used to distribute transactions (HTTP traffic) and SSH sessions from applications to UniConfig nodes. From the point of view of the load-balancer, all UniConfig nodes in the cluster are equal. Currently only a round-robin load-balancing strategy is supported.","Managed network devices - Devices that are managed using NETCONF/GNMi/CLI protocols by UniConfig nodes or generate notifications to UniConfig nodes. Sessions between UniConfig nodes and devices are either on-demand/emphemeral(configuration of devices) or long-term (distribution of notifications over streams).","HTTP/SSH clients and Kafka consumers - Application layer, such as workflow management systems or end-user systems. The RESTCONF API is exposed using the HTTP protocol, the SSH server exposes UniConfig shell and Kafka brokers allow Kafka consumers to listen to events on subscribed topics."]},{"l":"Multi-zone deployment","p":["This type of deployment has multiple zones that manage separate sets of devices for the following reasons:","Network reachability issues - Groups of devices are reachable, and thus manageable, only from some part of the network (zone) but not from others","Logical separation - Different scaling strategies or requirements for different zones.","Legal issues - Some devices must be managed separately with split storage because of, for example, regional restrictions.","The following diagrams represents a sample deployment with two zones:","Zone 1 contains three UniConfig nodes.","Zone 2 contains only two UniConfig nodes.","Multiple zones can share a single Kafka cluster, but database instances must be be split (can be running in a single Postgres server).","Deployment with multiple zones","Description of multi-zone areas:","Applications - The application layer is responsible for managing mapping between network segments and UniConfig zones. Typically this is achieved by deploying/using an additional inventory database that contains device <-> zone mappings, and based on this information the application decides which zone to use.","Isolated zones - A zone contains one or more UniConfig nodes, load-balancers and managed network devices. Clusters in isolated zones do not share information.","PostgreSQL databases - It is necessary to use a dedicated database per zone.","Kafka cluster - A Kafka cluster can be shared by multiple clusters in different zones, or alternatively there can be a single Kafka cluster per zone. Notifications from different zones can be safely pushed to common topics, as there can be no conflicts between Kafka publishers. However, it is also possible to achieve isolation of published messages in a shared Kafka deployment by setting different topic names in different zones."]},{"l":"Load-balancer operation","p":["Load-balancers are responsible for allocating UniConfig transactions to one of the UniConfig nodes in the cluster. This is done by forwarding requests without a UniConfig transaction header to one of the UniConfig nodes (using round-robin strategy) and afterwards appending a backed identifier to the create-transaction RPC response in the form of an additional Cookie header('sticky session' concept). Afterwards, the application is responsible for assuring that all requests belonging to the same transaction contain the same backend identifier.","The application is responsible for preserving transaction and backend identifier cookies throughout the transaction's lifetime.","The following sequence diagram captures the process of creating and using two UniConfig transactions with a focus on load-balancer operation.","Load-balancing UniConfig transactions","The first create-transaction RPC is forwarded to the first UniConfig node(applying round-robin strategy), because it does not contain the uniconfig_server_id key in the Cookie header. The response contains both the UniConfig transaction ID ( UNICONFIGTXID) and uniconfig_server_id that represents a 'sticky cookie'. The uniconfig_server_id cookie header is appended to the response by the load-balancer.","The next request that belongs to the created transaction contains the same UNICONFIGTXID and uniconfig_server_id. The load balancer uses uniconfig_server_id to forward this request to the correct UniConfig node.","The last application request again represents the create-transaction RPC. This time the request is forwarded to the next registered UniConfig node in the cluster according to the round-robin strategy."]},{"l":"Configuration"},{"l":"UniConfig configuration","p":["All UniConfig nodes in the cluster should be configured using the same parameters. There are several important sections in the config/application.properties file that relate to the clustered environment."]},{"l":"Database connection settings","p":["This section contains information on how to connect to a PostgreSQL database as well as connection pool settings. It is located under the dbPersistence.connection properties object.","Example with essential settings:","Make sure that [number of UniConfig nodes in cluster] * [maxDbPoolSize] does not exceed the maximum allowed number of open transactions and open connections on the PostgreSQL side. Note that maxDbPoolSize also caps the maximum number of open UniConfig transactions (1 UniConfig transaction == 1 database transaction== 1 connection to database)."]},{"l":"UniConfig node identification","p":["By default, UniConfig node names are generated randomly. This behavior can be modified by setting db-persistence.uniconfig-instance.instance-name. The instance name is leveraged, for example, in the clustering of stream subscriptions.","Example:"]},{"l":"Kafka and notification properties","p":["This section contains properties related to connections to Kafka brokers, Kafka publisher timeouts, authentication, subscription allocation and rebalancing settings.","Example with essential properties:"]},{"l":"Load-balancer configuration","p":["The following YAML code represents a sample Traefik configuration that can be used in the clustered UniConfig deployment (deployment with a single Traefik node). There is one registered entry-point with the uniconfig identifier on port 8181.","Next, you need to configure UniConfig docker containers with Traefik labels. UniConfig nodes are automatically detected by a Traefik container as uniconfig service providers. There is also a URI prefix (/rests), the name of the\"sticky cookie\" ( uniconfig_server_id) and the server port number ( 8181) where the UniConfig web server listens to incoming HTTP requests.","Values for all Traefik labels should be the same on all nodes in the cluster. Scaling of the UniConfig service in the cluster (for example, using Docker Swarm tools) is simple when container settings do not change.","A similar configuration to the one presented using Traefik can also be achieved using other load-balancer tools, such as HAProxy."]},{"l":"Clustering of NETCONF subscriptions and notifications","p":["When a device is installed with the stream property set, subscriptions for all provided streams are created in database. These subscriptions are always created with the UniConfig instance id set to null, so they can be acquired by any UniConfig from the cluster.","Each UniConfig instance in a cluster uses its own monitoring system to acquire free subscriptions. The monitoring system uses a specialized transaction to lock subscriptions, which prevents other UniConfig instances from locking the same subscriptions. While locking a subscription, the UniConfig instance writes its id into the subscription table for the currently locked subscription, which indicates that this subscription is already acquired by this UniConfig instance. Other instances of UniConfig will then see that this subscription is not available."]},{"l":"Optimal subscription count and rebalancing","p":["With multiple UniConfig instances working in a cluster, each instance calculates an optimal range of subscriptions to manage.","Based on the optimal range and number of currently opened subscriptions, each UniConfig node (while performing a monitoring system iteration) decides whether it should:","Acquire additional subscriptions until the optimal range is reached.","Once the optimal range is reached, stay put and not acquire any additional subscriptions.","Release some of its subscriptions to trigger rebalancing until the optimal range is reached.","If an instance goes down, all of its subscriptions are immediately released and the optimal ranges of other living nodes are adjusted. Managed network devices, and thus subscriptions, are reopened by the rest of the cluster.","Note that there is a grace period before other nodes take over the subscriptions. Therefore, if a node goes down and then back up in quick succession, it will restart the subscriptions on its own.","The following example illustrates a timeline for a three-node cluster and how many subscriptions are handled by each node:","notifications-in-cluster-rebalancing","The hard limit still applies in clustered environments. It is never exceeded regardless of the optimal range."]}],[{"l":"Uniconfig properties","p":["UniConfig can be extensively configured using application properties located in the application.properties file.","Application properties can be separated into three groups:","Runtime mutable properties can be modified in runtime (using the update-properties RPC), their changes take effect in runtime and the properties are persisted in the database.","Database persisted properties include all runtime mutable properties and some additional properties. These properties are stored in the database, which is always their primary source. With UniConfig Cloud Config, they remain constant across UniConfig instances in the same cluster and cannot be overridden via the application.properties file.","Regular UniConfig properties comprise all the remaining properties. These properties can always be changed using application.properties and can differ between UniConfig instances.","Database persisted properties include the following property prefixes:","crypto","schema-settings","callbacks","notifications.kafka","netconf-default-parameters","gnmi-default-parameters","cli-default-parameters","These properties are stored in the properties table and are also known as default properties. They can be read and updated using the read-properties RPC and update-properties RPC.","After UniConfig is started, if default properties are found in the database, UniConfig will use the values in the database. For properties not found in the database, values from the first UniConfig instance after startup are used (by the application.properties file or environment variables) and saved in the database for the next UniConfig instances."]},{"l":"UniConfig Cloud Config","p":["UniConfig Cloud Config is used to retain the same property values between distributed UniConfig instances connected via a message broker. It is largely the same technology as Spring Cloud Config with JDBC backend and Spring Cloud Bus. The main difference is that UniConfig Cloud Config Server and Cloud Config Client are in the same project, while Spring requires a separate Cloud Config Server application.","By calling a special signal (the Refresh Bus Endpoint call) during runtime, the system sets the same value for persisted properties in all UniConfig instances. The signal is called immediately after mutable properties are modified using the update-properties RPC. The specific UniConfig instance calling the signal sends Kafka events containing the changed properties, while other instances read those properties from the database and use the refresh endpoint to update them in runtime."]},{"l":"UniConfig startup with UniConfig Cloud Config","p":["UniConfig startup with UniConfig Cloud Config: startup-with-ucc","Before starting UniConfig, enable Cloud Config by using the following properties:","On startup, UniConfig checks the database for any default properties to configure:","If default properties are found in the database, UniConfig manually refreshes its property values to use those in the database.","If no default properties are found, UniConfig uses its existing properties and, once loaded, saves them in the database for the next UniConfig instances.","At the end of Spring initialisation, the Refresh Bus Endpoint is called. This refreshes default properties with the database values for all UniConfig instances connected via the Kafka refresh topic. A second refresh during the UniConfig startup cycle is required if several instances were started simultaneously and the database contains no property values to synchronize for properties (especially encryption keys).","At application runtime, if the update-properties RPC is used with default properties on input, UniConfig updates the properties in the database. It also calls the Refresh Bus Endpoint, which reloads properties for all UniConfig instances connected via Kafka."]},{"l":"UniConfig startup without UniConfig Cloud Config","p":["UniConfig startup without UniConfig Cloud Config: startup-without-ucc","Before starting UniConfig, disable Cloud Config by using the following properties:","On startup, UniConfig checks the database for any default properties to configure:","If default properties are found in the database, UniConfig manually refreshes its property values to those in the database.","If no default properties are found, UniConfig uses its existing properties and, once loaded, saves them in the database for the next UniConfig instances.","At the end of Spring initialisation, the Refresh Bus Endpoint is not called.","At application runtime, if the update-properties RPC is used with default properties on input, Uniconfig updates the properties in the database but not inside the application. This will therefore only affect the next UniConfig instance started after the properties are updated."]}],[{"l":"Performance characteristics","p":["This page contains reference performance characteristics for Uniconfig.","We try to answer the question how fast can a certain number of devices with a certain amount of configuration be installed and fully synced by","a single Uniconfig instance","3-node Uniconfig deployment with load balancer","The unit of measurement is: Number of configuration lines / per single CPU core / per minute. This number can then be roughly applied to any other similar device being installed by uniconfig."]},{"l":"CLI devices","p":["There are 2 main families of CLI devices: those using Cisco style configuration (configuration in sections) and devices that use one-line style of configuration (without sections) such as Ciena SAOS 8.","It is important to distinguish performance characteristics of these 2 families."]},{"l":"Tree-like style of configuration","p":["Cisco style of confituration (IOS, IOS-XR etc.)","// TBD"]},{"i":"one-line-style-of-configuration-devices-saos-performance-tests","l":"One-line style of configuration devices (SAOS) performance tests","p":["Important caveats:","Measurement were performed on simulated devices = no device overhead","Measurement were performed on a local network = no network overhead","Measured on Uniconfig version 5.0.12","Simulated devices were of two flawors: half with small configuration and the half with big configuration","Tests:","Single node deployment of Uniconfig resources: CPU 4 cores and RAM 4 GB","3 node deployment of Uniconfig - resources per node: CPU 4 cores and RAM 4 GB","3 node deployment of Uniconfig - resources per node: CPU 6 cores and RAM 4 GB"]},{"i":"device-installation--synchronization","l":"Device installation & synchronization"},{"i":"test-a---one-node-uniconfig","l":"Test A - one node Uniconfig","p":["Devices running SAOS operating system (Ciena) and similar","Inputs: 375 x SAOS 6 devices configuration: 8834 json lines = 1510 cli config lines (brief config)","375 x SAOS 8 devices configuration: 277375 json lines = 30705 cli config lines (brief config)","Evaluation: 750 devices were registered in 7.5 hours on single node Uniconfig using 4 cores Average one device instalation duration = (7.5 * 60 minutes) / 750 devices = 0.6 minutes Average number of json lines per device = (8834 + 277375)/2 = 143104 lines lines of json / per core / per minute = 143104 lines / 4 cores / 0.6 minutes = 59626 Average number of cli lines per device = (1510 + 30705)/2 = 16107,5 lines lines of cli / per core / per minute = 16107,5 lines / 4 cores / 0.6 minutes = 6711","Installation & sync rate:","59,626 lines of json / per core / per minute","or","6,711 lines of raw cli configuration / per core / per minute","A single uniconfig node is capable of installing (and fully syncing) 100 Ciena (SAOS 8) devices with 15k lines of configuration(~ 123k lines of formatted json in Uniconfig) in 55 minutes using 4 CPU cores","Recommended batch size for parallel installation in such case would be about 50 devices per batch as the parallelism is limited by the number of available cores."]},{"i":"test-b---3-nodes-of-uniconfig-with-load-balancer","l":"Test B - 3 nodes of Uniconfig with load balancer","p":["Devices running SAOS operating system (Ciena) and similar","Inputs: 750 x SAOS 6 devices configuration: 8834 json lines = 1510 cli config lines (brief config)","750 x SAOS 8 devices configuration: 277375 json lines = 30705 cli config lines (brief config)","Evaluation for 4 core deployment: 1500 devices were registered in 5.5 hours on 3 node Uniconfig deployment each using 4 cores Average one device instalation duration = (5.5 * 60 minutes) / 1500 devices = 0.22 minutes Average number of json lines per device = (8834 + 277375)/2 = 143104 lines lines of json / per core / per minute = 143104 lines / 3 4 cores / 0.22 minutes = 54206 Average number of cli lines per device = (1510 + 30705)/2 = 16107,5 lines lines of cli / per core / per minute = 16107,5 lines / 3 4 cores / 0.22 minutes = 6101","Installation & sync rate:","54,206 lines of json / per core / per minute","or","6,101 lines of raw cli configuration / per core / per minute","A 3 nodes of uniconfig with loadbalancer are capable of installing (and fully syncing) 100 Ciena (SAOS 8) devices with 15k lines of configuration(~ 123k lines of formatted json in Uniconfig) in 19 minutes using 12 CPU cores","Recommended batch size for parallel installation in such case would be about 150 devices per batch as the parallelism is limited by the number of available cores."]},{"i":"test-c---3-nodes-of-uniconfig-with-load-balancer","l":"Test C - 3 nodes of Uniconfig with load balancer","p":["Devices running SAOS operating system (Ciena) and similar","Inputs: 750 x SAOS 6 devices configuration: 8834 json lines = 1510 cli config lines (brief config)","750 x SAOS 8 devices configuration: 277375 json lines = 30705 cli config lines (brief config)","Evaluation for 6 core deployment: 1500 devices were registered in 3.7 hours on 3 node Uniconfig deployment each using 6 cores Average one device instalation duration = (3.7 * 60 minutes) / 1500 devices = 0.148 minutes Average number of json lines per device = (8834 + 277375)/2 = 143104 lines lines of json / per core / per minute = 143104 lines / 3 6 cores / 0.148 minutes = 53717 Average number of cli lines per device = (1510 + 30705)/2 = 16107,5 lines lines of cli / per core / per minute = 16107,5 lines / 3 6 cores / 0.148 minutes = 6046","Installation & sync rate:","53,717 lines of json / per core / per minute","or","6,046 lines of raw cli configuration / per core / per minute","A 3 nodes of uniconfig with loadbalancer are capable of installing (and fully syncing) 100 Ciena (SAOS 8) devices with 15k lines of configuration(~ 123k lines of formatted json in Uniconfig) in 13 minutes using 18 CPU cores","Recommended batch size for parallel installation in such case would be about 150 devices per batch as the parallelism is limited by the number of available cores."]},{"l":"Netconf devices","p":["We use netconf-testtool to simulate devices.","Important caveats:","Measurement were performed on simulated devices = no device overhead","Measured on Uniconfig version 5.2.1","Simulated devices were with small configuration (~ 200 json lines)","Tests:","Single node deployment of Uniconfig resources: CPU 12 cores and RAM 4 GB"]},{"i":"device-installation--synchronization-1","l":"Device installation & synchronization"},{"i":"test-a---one-node-uniconfig-1","l":"Test A - one node Uniconfig","p":["Inputs: 5000 x Netconf devices simulated: 203 json lines","Evaluation 1: 5000 devices were registered in 16.5 minutes on single node Uniconfig using 12 cores Average one device instalation duration = 16.5 minutes / 5000 devices = 0,0033 minutes Average number of json lines per device = 203 lines lines of json / per core / per minute = 203 lines / 12 cores / 0,0033 minutes = 5126","Installation & sync rate:","5,126 lines of json / per core / per minute","A single uniconfig node is capable of installing (and fully syncing) 5000 netconf devices with config of 0.2k lines each of formatted json (in Uniconfig) in 16.5 minutes using 12 CPU cores","5 threads were used and connection-manager:install-multiple-nodes RPC was used (with 20 devices each).","Evaluation 2: 5000 devices were updated in 12.4 minutes on single node Uniconfig using 12 cores Update process consisted of RPCs: Create transaction, Apply template, Calculate diff, Commit After apply template each configuration was increased from 203 to 1282 json lines Average one device update duration = 12.4 minutes / 5000 devices = 0,00248 minutes Average number of json lines per device = 1282 lines lines of json / per core / per minute = 1282 lines / 12 cores / 0,00248 minutes = 43077","Update rate:","43,077 lines of json / per core / per minute","A single uniconfig node is capable of updating (and fully syncing) 5000 netconf devices with initial config of 0.2k json lines each (of formatted json in Uniconfig) in 12.4 minutes using 12 CPU cores After update each device has config of 1.2k json lines each","20 threads were used. No delay among successive updating RPCs"]}],[{"l":"Monitoring"},{"l":"Monitoring using Metrics","p":["UniConfig exposes multiple metrics for traffic and performance monitoring.","Output is generated in two formats:","Plaintext log messages, located in the metrics.log file in the log directory at the root of the distribution.","Raw data in CSV format, located the in metrics directory at the root of the distribution. CSV files can be further processed by third-party visualization tools."]},{"l":"Types of metrics","p":["Gauge - Reports the instantaneous value at a point in time (for example, queue size).","Meter - Measures the total count for event occurences, total mean rate and mean rates for time windows of the past 1, 5 or 15 minutes"]},{"l":"List of notable metrics exposed by UniConfig","p":["Gauges","io.frinx.uniconfig.manager.impl.task.TaskExecutorImpl.queue_size- Number of tasks in the queue waiting for execution","org.apache.sshd.server.SshServer.active_sessions- Number of active CLI sessions","org.opendaylight.controller.uniconfig.transaction.manager.api.UniconfigTransactionManager.open_transaction_count- Number of open transactions","Meters","org.opendaylight.yangtools.yang.common.RpcResult.rpc_invoke- All RPCs invoked by UniConfig","org.opendaylight.controller.uniconfig.transaction.manager.impl.UniconfigTransactionManagerImpl.transaction_invoke- All transactions invoked in UniConfig","io.frinx.uniconfig.shell.cli.SshTerminal.cli_message- All commands invoked in UniConfig shell"]},{"l":"Configuration","p":["Configuration is performed via a section in the application.properties file:"]},{"l":"Example output","p":["metrics/org.opendaylight.controller.uniconfig.transaction.manager.impl.UniconfigTransactionManagerImpl.transaction_invoke.csv:","log/metrics.log:"]}],[{"i":"uniconfig-client-sdk","l":"UniConfig Client (SDK)","p":["Uniconfig client SDK is implemented in Java 17 and uses Uniconfig's RESTconf API.","The SDK provides following advantages over raw RESTconf:","SDK is versioned and tied tied to a specific Uniconfig release","Every version is tested","Type safety","Additional features on top of basic RESTconf facade such as:","Integration with Kafka (notification listener)","Client side diff (to calculate diff between 2 versions of config)","etc."]},{"l":"Basic device configuration management","p":["An example of a simple read & write use case on top of a single device called vnf."]},{"l":"Integration with Kafka","p":["Uniconfig SDK implements a kafka listener that taps into Uniconfig notifications streams and allows the client to consume the notifications easily. Notifications available through Uniconfig are: Device notifications, alerts and telemetry but also Uniconfig generated notifications in the audit log topic. For further information see Uniconfig notifications (kafka)."]},{"l":"Client side diff","p":["Uniconfig SDK offers a diff calculation feature that can calculate a delta between a before device configuration state and after configuration state. This diff is then transformed into a patch operation and sent to Uniconfig's RESTconf API.","Client side diff calculation is useful in specific cases, where a substential amount of configuration data is avalable and modified outside of Uniconfig. Typically, the entire after state would have to be pushed into Uniconfig and Uniconfig would calculate its own diff internally. By calculating on the client side, it is possilble to reduce the network communication between client and Uniconfig (as less data has to be sent) and to reduce how much diff calculation Uniconfig has to do itself (shifting it to the client side).","This feature leverages the same implementation of diff calculation that is used withing Uniconfig itself and requires YANG schemas to be present for the computation.","Example usage:","Notable features of client side diff:","Requires YANG schemas in order to work","JSON data have to conform to those YANG models","Allows for templated values to be present in the JSON","Produces a single PATCH operation containing all changes detected. See YANG patch in Uniconfig","Changes detected: Create, Update, Delete, Reorder (lists and leaf-lists)","Uses the same implementation as Uniconfig's calculate-diff"]}],[{"l":"Developer Guide","p":["This guide provides instructions on how to extend UniConfig to support more devices, commands and operations.","Guides on how to extend UniConfig to support a new device or new commands:","Architecture","Translation Units in general","Translation Units Documentation for FRINX Uniconfig","OpenConfig to device config mapping","Developing a new translation unit","Implementing CLI Translation Unit","NETCONF Unified Translation Unit","Native-CLI translation units","Metrics"]}],[{"l":"Architecture"},{"l":"Pre-requisite reading","p":["Honeycomb design documentation:","https://wiki.fd.io/view/Honeycomb https://docs.fd.io/honeycomb/1.18.04/release-notes-aggregator/release_notes.html","CLI plugin available presentations:","https://www.dropbox.com/sh/ry2ru5vizv7st8u/AAAntbCRHb1yS_NmEpbXG1WBa?dl=0"]},{"l":"Building on honeycomb","p":["The essential idea behind the southbound plugins comes from Honeycomb. Honeycomb defines, implements and uses the same pipeline and the same framework to handle data. The APIs, some implementations and also SPIs used in the southbound plugin's translation layer come from Honeycomb. However, the southbound plugin creates multiple instances of Honeycomb components and encapsulates them behind a mount point.","The following series of diagrams shows the evolution from Opendaylight to Honeycomb and back into Opendaylight as a mountpoint:","High level Opendaylight overview with its concept of a Mountpoint:","ODL","High level Honeycomb overview:","HC","Honeycomb core (custom MD-SAL implementation) overview:","Honeycomb's core","How Honeycomb is encapsulated as a mount point in Opendaylight:","Honeycomb's core as mountpoint"]},{"l":"Major components","p":["The following diagram shows the major components of the southbound plugin and their relationships:","CLI plugin components"]},{"l":"Modules","p":["The following diagram shows project modules and their dependencies:","CLI plugin modules"]}],[{"l":"Translation Units in general"},{"l":"Module structure","p":["Translation unit is a self contained project which implements a mapping between OpenConfig based YANG models and device specific configuration. It is used by the FRINX ODL to perform translation between device specific configuration model and standard (OpenConfig) models. A unit usually consists of:","Handlers","Readers","Writers","TranslateUnit implementation","RPCs"]},{"l":"Handlers","p":["Each complex node in YANG (container, list, augment...) should have a dedicated handler (Reader, Writer)","This enables extensibility, readability and the framework can easily filter and process the data this way","Unless there is a need to also handle child nodes, in which case register the handler using subtreeAdd method from the registries","There are 2 types of handlers: Readers (Read operation) and Writers(Create, Update, Delete operation)","One can implement just the readers or both readers and writers for YANG models. Writers must have counterpart readers because of reconciliation.","Readers and Writers should use the InstanceIdentifier parameter they receive in readCurrentAttributes or writeCurrentAttributes methods to find information about keys for their parent nodes. E.g. Reader registered under ID: /interfaces/interface/config will always receive keyed version of that ID: /interface/interface[Loopback0]/config. So it can use method firstKeyOf on InstanceIdentifier to get the keys.","RWUtils class contains methods for InstanceIdentifier manipulation.","Readers and writers can be easily tested and it is necessary to provide unit tests for all of them. It's important to cover readCurrentAttributes and writeCurrentAttributes with all possible scenarios (all data there, no data there, partial data there...)","Writers may use Preconditions.checkArgument() before accessing the device. Fail of the precondition check does not invoke default rollback(opposite operation) on the writer where precondition is located."]},{"l":"Base Handlers","p":["When a handler for the same YANG node is implemented to conform various devices, it tends to lead to a lot of boilerplate and duplicate code. Therefore, we should implement a base handler for such handlers. How does it work:","create a base-project (if there isn't any) to group base handlers(e.g. for an interface handler, choose interface-baseproject)","each base handler needs to be abstract and implement same interfaces as the original handler","extract common functionality in the base handler. Common functionality means that it will conform the majority of the original handlers. If a handler does not share the extracted functionality, it needs to override original interface methods, to hide the extracted functionality.","let original handlers extend base abstract handler"]}],[{"l":"Translation Units Documentation for FRINX Uniconfig"},{"l":"Auto-generated documentation","p":["A documentation to translation-units that is generated automatically from the source code and javadocs can be found here. This documentation is useful to check actual implementations, whether a functionality is implemented for a particular device and by which protocol (netconf or cli)."]},{"l":"Manual documentation","p":["This repository contains documentation for all available translation units. A translation unit is a piece of code that includes handlers to read from or write to a specific device (e.g. Cisco IOS classic router) and facilitates the translation in OpenConfig models. The purpose of this documentation is to see which commands can be read and set and how they map to the respective YANG models. Every section has a README file that provides an overview of all show and configuration commands that are supported."]},{"l":"OPERATIONAL datasets","p":["Go to operational datasets","Show commands are commands that usually on Cisco device start with'show'. The aim is to obtain data from the router."]},{"l":"URL","p":["GET operation issued on operational datastore"]},{"l":"OPENCONFIG YANG","p":["In case of show commands this section is a sample output of a particular show command."]},{"l":"OS COMMANDS","p":["In this section we list the actual router commands with sample outputs, where the data obtained and transformed into OpenConfig YANG is marked as bold. We list show commands and outputs for each supported device OS.","IOS XR | IOS Classic/XE | Junos"]},{"l":"DEVICE YANG","p":["In case of CLI units, the unit parses the output of the CLI command directly into OC YANG. In case of Netconf units, the output is mapped to OC YANG through Device YANG (YANG model supported by the device). In case of Netconf units, the YANG is also written in documentation. This section is a link to XML unit test input testing this operation."]},{"l":"UNIT","p":["Link to github code where this show command is implemented along with unit version range."]},{"l":"CONFIGURATION datasets","p":["Go to config datasets"]},{"i":"url-1","l":"URL","p":["PUT operation with given URL will result in creating of data in config datastore DELETE operation with given URL will result in removing data in config datastore"]},{"i":"openconfig-yang-1","l":"OPENCONFIG YANG","p":["In case of configuration commands, this section represents the HTTP body in PUT operation"]},{"i":"os-commands-1","l":"OS COMMANDS","p":["In this section we list the actual router commands that are mapped to the OpenConfig YANG model. Data transformed into OpenConfig YANG is marked as bold. We list commands for each supported device OS.","IOS XR | IOS Classic/XE | Junos"]},{"i":"device-yang-1","l":"DEVICE YANG","p":["In case of Netconf units, the device yang represents command sent to the device in device YANG model. This section is a link to XML unit test input testing this configuration."]},{"i":"unit-1","l":"UNIT","p":["Link to github code where this config command is implemented along with unit version range."]}],[{"l":"OpenConfig to device config mapping"},{"l":"Finding mapping between device and the model","p":["Preferred YANG models for device config and operational data are OpenConfig models.","These models usually represent configuration part in container config and operational part in container state. Operational data is config data + operational data.","YANG models used in UniConfig framework need to be located in https://github.com/FRINXio/openconfig. In case the desired functionality is not modeled yet, you can create new YANG with its own structure or it can augment existing OpenConfig models. Guideline, how to write OpenConfig models can be found at http://www.openconfig.net/docs/style-guide/."]},{"l":"Choosing the right YANG models","p":["Before writing a custom YANG model for a unit, it is important to check whether such a model doesn't already exist. There are plenty of YANG models available, modeling many aspects of network device management. The biggest groups of models are:","OpenConfig https://github.com/openconfig/public/tree/master/release/models","IETF https://github.com/YangModels/yang/tree/master/standard/ietf","It is usually wiser to choose an existing YANG model instead of developing a custom one. Also, it is very important to check for existing units already implemented for a device. If there are any, the best approach will most likely be to use YANG models from the same family as existing units use."]},{"l":"Existing documentation","p":["There is translation-units-docs page as a single point of truth for mapping. Use`` notation for variables in the templates. This notation is postman compatible."]}],[{"l":"Developing a new translation unit","p":[".pom file of the unit","add your unit as a dependency to artifacts/pom","dependencies","handlers (readers/writers)","https://github.com/FRINXio/cli-units","https://github.com/FRINXio/unitopo-units","name of the unit should be in format device-domain-unit(e.g. ios-interface-unit, xr-acl-unit)","package name should be in format io.frinxcli|netconf., device name and domain (e.g. io.frinx.cli.unit.ios.interface)","point to correct unit parent","The easiest way how to develop a new transaction unit is to copy existing one and change what you need to make it work. E.g. if you are creating an interface translation unit, the best way is to copy existing interface translation unit for some other device, that is already implemented. You can find existing units on github:","This section provides a tutorial for developing a new translation unit.","Unit class","unit tests","What you need to add:","What you need to change:","What your unit needs to contain:"]},{"i":"best-practices-for-handlers-readerswriters","l":"Best practices for handlers (readers/writers)","p":["All comments are in English","All defined exceptions can be thrown from the code","All new dependencies and imports are actually used","All variables/methods are actually used","Before pushing the code make sure:","Chunk","Code has correct spacing","Commented out code","Comments are appropriate to the code behavior","Constants","Do not push code that contains following:","Double blank lines","java regexes","New classes/interfaces have the correct license header","New classes/interfaces/yang model have correct date","Reflection","Show commands","Static imports","Trailing whitespaces or tabs"]}],[{"l":"Implementing CLI Translation Unit","p":["CLI Translation units are located in https://github.com/FRINXio/cli-units repository. Java is used in CLI translation units."]},{"l":"Init Unit","p":["Init translation unit does not contain readers and writers but it only contains implementation of TranslateUnit. There should be only one init translation unit per device type. Purpose of the init TU is to setup CLI prompt and define rollback strategy.","The implementation of TranslateUnit needs to override methods:","SessionInitializationStrategy getInitializer(@Nonnull final RemoteDeviceId id, @Nonnull final CliNode cliNodeConfiguration)","Implement and return device specific SessionInitializationStrategy where:","Setup device CLI terminal with attributes like width and length allowing to display infinite output.","Enter desired CLI mode which will be used as default - every reader and writer gets CLI prompt in this state (e.g. EXEC mode for IOS, config mode for IOS-XR, cli mode for Junos)","These methods may be overridden if necessary:","getPreCommitHook()- method that is invoked before actual commit is written into device. For example this method can enter configuration mode.","getCommitHook()- method that invokes actual commit and should catch any error on commit. Also it should handle any post-commit actions when the commit was successful.","getPostFailedHook()- method that is invoked when commit fails. Should implement aborts or revert strategies.","getErrorPatterns()- method returning Java Patterns with regular expressions that match device specific error patterns.","getCommitErrorPattern()- method returning Java Patterns with regular expressions that match device specific error patterns that can be returned by the device after issuing commit."]},{"l":"Translate Unit","p":["Handlers(readers/writers) need to be registered in this method. Parameter context.getTransport() returns Cli object containing methods for communication with a device via CLI - should be passed to readers/writers.","Implementation of TranslateUnit must be registered into TranslationUnitCollector and must specify device type and device version during registration. Snippet below shows registration of IosXRInterfaceUnit for device type \"ios xr\" all versions.","Implementation of TranslateUnit must implement these methods:","Instance-identifier in generic reader/writer must be without keys pointing to the target composite node used in implemented reader/writer.","Instance-identifiers for YANG container and list (not for augmentations and nodes behind augmentations) are automatically generated to IIDs class (used in examples bellow) during build of openconfig project.","Return RPC services implemented in the translation unit. Parameter context.getTransport() returns Cli object containing methods for communication with a device via CLI - may need to be passed to RPC implementations. Default implementation returns empty Set.","Return unique string among all translation units which will be used as ID for the translation unit (e.g. \"IOS XR Interface (Openconfig) translate unit\")","Return YANG models containing composite nodes handled by handlers(readers/writers). Default implementation returns empty Set if no handlers are implemented.","Set getRpcs(@Nonnull Context context)","Set getYangSchemas()","Set getSupportedVersions()","String getUnitName()","This method should also registers for general Openconfig checks:","This method should return specific device version that work with this handler.","Translate unit class must implement interface io.frinx.cli.unit.utils.AbstractUnit. Naming convention for translate unit class is device-type+openconfig-domain+Unit (e.g. IosXrInterfaceUnit). Translate unit class is usually instantiated, initialized and closed from Blueprint.","void provideHandlers()"]},{"l":"Ordering of handlers","p":["As the example shows, the ip address command must be executed after the interface command.","Registration of Ipv4ConfigWriter by using the addAfter method ensures that the OpenConfig ip address data is translated after OpenConfig interface data. That means CLI commands are executed in the desired order.","rRegistry.add","rRegistry.addNoop","rRegistry.subtreeAdd","The following sample shows a CLI translation unit with dependency between 2 writers. The unit is dedicated for interface configuration on a Cisco IOS device.","This example uses method subtreeAddAfter instead of subtreeAdd. Last parameter in this method shows dependency on writer registered under IIDs.IN_IN_CONFIG.","Use for writers handling data of whole composite node subtrees. This ensures that if only a child node is updated, the writer gets triggered. Method subtreeAdd requires a set of IIDs for all handled children, the IIDs must start from the reader itself, not from root.","Use to register noop writers","Use when a reader implementation also fills composite child nodes of target composite node. Method subtreeAdd requires a set of IIDs for all handled children.","Use when common GenericConfigListReader, GenericConfigReader,* GenericOperListReader or GenericOperReader need to be registered.","Use when common GenericListWriter or GenericWriter are registered.","VRF writer should be between them. If the order is not expressed during registration, commands might be executed on device in an unpredictable/invalid order.","wRegistry.add","wRegistry.subtreeAdd","Writers are stored in a linear structure and are invoked in order of registration. When registering a writer a relationship with another writer or set of writers can be expressed using addBefore, addAfter, subtreeAddBefore, subtreeAddAfter methods. E.g. InterfaceWriter and VRFInterfaceWriter should have a relationship: InterfaceWriter -> VRFInterfaceWriter so that first an interface is created and only then assigned to VRF."]},{"l":"Device registration","p":["In TranslateUnit we had just created, e.g. MplsUnitXR4.java, we have to register device as a constant located../iosxr/init/IosXrDevices.java containing device type and version as described in TranslateUnit documentation.","This unit can reuse all writers/readers from existing ones, except the writer (or other handler) we want to alter or create (in our example writer for tunnel configuration). We have to create a new writer with desired behaviour and add it into provideWriters method."]},{"l":"Readers","p":["Readers are handlers responsible for reading and parsing the data coming from a device","There are 2 types of readers: Reader and ListReader. Reader can be used to handle container or augmentation nodes and ListReader should handle list nodes from YANG.","Both types need to implement readCurrentAttributes to fill the builder with appropriate values","ListReader needs to also implement getAllIds() where it retrieves a key for each item to be present in current list. After the list is received, framework will invoke readCurrentAttributes for each item from getAllIds","Readers should always use overloaded blockingRead method which takes in the ReadContext since that method performs caching internally","Use full version of commands e.g. show running-config interface instead of sh run int"]},{"l":"Reading of CLI and device configuration","p":["CLI readers maintain translation between device and yang models. We're sending read commands to the device and outputs are cached. This process is shown below.","Reading CLI conf from device"]},{"i":"reading-of-configuration-from-cli-network-device---different-scenarios","l":"Reading of configuration from CLI network device - different scenarios","p":["The diagram below shows four specific scenarios:","Configuration is read using show running-config pattern for the first time","Another configuration is read using running-config pattern","cache can be used","BGP configuration/state is read using \"show route bgp 100\"","the running-config pattern is not used","BGP configuration/state is read using \"show route bgp 100\" again","cached can be used","Different scenarios"]},{"l":"Mandatory interfaces to implement","p":["Each reader needs to implement one of these interfaces based on type of target node in YANG. These interfaces also contain util methods which may be used for better manipulation with data. For more information about methods please read javadocs.","CliConfigListReader- implement this interface if target composite node in YANG is list and represents config data.","CliConfigReader- implement this interface if target composite node in YANG is container or augmentation and represents config data.","CliOperListReader- implement this interface if target composite node in YANG is list and represents operational data.","CliOperReader- implement this interface if target composite node in YANG is container or augmentation and represents operational data.","In cases where you want to invoke multiple readers on reading one YANG node, extend following abstract classes:","CompositeListReader- extend this abstract class if multiple list readers need to be invoked when reading specific list in YANG.","CompositeReader- extend this abstract class if multiple readers need to be invoked when reading specific node in YANG.","A practical example of their usage is reading network instance based on it's type. All child readers need to implement a check when the particular reader should be invoked or the parent reader should move on to the next reader.","For example child reader for bgp (located under protocol) needs to check if identifier in protocol has value BGP. Otherwise reader for bgp will be invoked even if protocol identifier is OSPF."]},{"l":"Util classes","p":["ParsingUtils- use methods of this util class if you want to parse plaintext to java object builder"]},{"l":"Plaintext parsing hints","p":["Use as specific regular expressions when parsing CLI output as possible.","For Cisco CLI devices avoid using section and other advanced formatting parameters. Only include, exclude and begin are allowed.","Use CONFIG data as the source of truth when parsing information from device. Except when parsing state containers (or containers explicitly marked as config false).","I.e. use show running-config | include router ospf instead of sh ospf when retrieving ospf routers list.","In some cases, it is not possible to just use config data e.g. sh run interface does not show any data for interfaces that have no configuration. In this case it is necessary to use operational information from e.g. show ip interface brief","Use following pattern when parsing multiline output from CLI, where it is difficult to extract lines and their relationships: i.e. when parsing configured BGP neighbors per address family following command can be used:","which results in:","This output can then be parsed by:","Remove newlines to get a single line of string","Replace \"router\" with \"\" to separate bgp routers per line","Find the line that matches required router bgp","Take that line and replace \"address-family\" with \"-family\" to get address-family neighbors per line"]},{"l":"Base Readers","p":["Each base reader should contain abstract methods:","String getReadCommand()- each child reader should fill in the read command used to get information needed for this reader. Arguments may vary and they are used to be more specific in the read command (eg. when creating a command to gather information about a specific interface, you may want to pass interface name as argument).","Pattern getLine(>)- there may be more such methods and they are used to get the regular expression needed to parse output of the command (eg. in case of interface reader, you will create methods getDescriptionLine, getShutdownLine etc.)","Naming of the methods should be unified in order to be easily parsed by auto-generated documentation."]},{"l":"Writers","p":["A writer needs to implement all 3 methods: Write, Update, Delete in order to fully support default rollback mechanism of the framework","Time showed that update like 1. delete, 2. write is anti-pattern and should not be used. There is just one case where it is necessary: when re-writing list entry, you must first delete the previous entry, then write the new one, otherwise the previous entry would still be present and the new entry will be added to the list.","A writer can properly work only if there is a reader for the same composite node.","A writer should check whether the command it executed was handled by the device properly (by checking the output) and if not throw one of the Write/Update/Delete FailedException","Chunk templating framework is preferred to use in writers. It gives us:","Null safety","if/loop etc. inside templates","Default values and many more","Use full version of commands e.g. configure terminal instead of conf t"]},{"i":"mandatory-interfaces-to-implement-1","l":"Mandatory interfaces to implement","p":["Each writer needs to implement one of these interfaces based on type of target node in YANG. Unlike mandatory interfaces for reading, only interfaces for writing config data are available (because it is not possible to write operational data). These interfaces also contain util methods which may be used for better manipulation with data. For more information about methods please read javadocs.","All writers override updateCurrentAttributes method and avoid delete/write combination, unless specified in a comment.","CliListWriter- implement this interface if target composite node in YANG is list. An implementation needs to be registered as GenericListWriter.","CliWriter- implement this interface if target composite node in YANG is container or augmentation. An implementation needs to be registered as GenericWriter.","CompositeWriter- extend this abstract class when multiple writers need to be invoked on one YANG node. The writers need to implement a check whether or not should they be invoked."]},{"l":"Base Writers","p":["Each base writer should contain abstract methods:","String updateTemplate(Config before, Config after) this method returns Chunk template used for writing and updating data on the device.","String deleteTemplate(Config data) this method returns Chunk template used for deleting data from device.","If updating data is done differently than writing new data, method String writeTemplate(Config data) might be used as well."]},{"l":"Chunk Templates","p":["Each original writer transformed to use a base writer should have all it's templates written in Chunk. We extended Chunk to achieve easier manipulation with data. There is now a new filter called update. It's usage is following:","\"{$data|update(mtu,mtu $data.mtu, no mtu)}\"","$data represents the data structure on which we check if it was updated from the previous state.","mtu first argument represents the name of the field that should be checked within the $data","$data.mtu second argument represents the actual string that will be sent to the device if the value of the field named in first argument was changed or didn't exist before","no mtu third argument represents the actual string that will be sent to the device if the value of the field named in first argument was deleted","optional true fourth argument, if present, lets the filter know it should send both outputs to the device, first the delete string(third argument) then the update string (second argument)","Update filter does not send any of the strings to the device, if the value did not change.","When using this filter in updateTemplate method, you must use fT() method (format template) with one pair of the arguments being \"before\", before to let the template know what data represents the previous state.","Unfortunately, Opendaylight generates boolean fields instead of Boolean and Chunk does not work with boolean fields in the same way as any other object fields. Therefore for boolean values (eg. shutdown), you cannot use update filter and checking for changes needs to be done in a traditional way."]}],[{"l":"NETCONF Unified Translation Unit","p":["Unified translation units are located in https://github.com/FRINXio/unitopo-units repository.","Kotlin is used as preferred programming language in NETCONF translation units because it provides type aliases and better null-safety."]},{"l":"TranslateUnit","p":["Translate unit class must implement interface io.frinx.unitopo.registry.spi.TranslateUnit. Naming convention for translate unit class is just name Unit. Translate unit class is usually instantiated, initialized and closed from Blueprint.","Implementation of TranslateUnit must be registered into TranslationUnitCollector and must provide set of supported underlay YANG models. Snippet below shows registration of Unit for junos device version 17.3.","Implementation of TranslateUnit must implement these methods:","toString(): String","Return unique string among all translation units which will be used as ID for the translation unit (e.g. \"IOS XR Interface (OpenConfig) translate unit\")","getYangSchemas(): Set","Return YANG models containing composite nodes handled by handlers(readers/writers). It must return empty Set if no handlers are implemented.","getUnderlayYangSchemas(): Set","Return YANG module informations about underlay models used in the translation unit. These YANG modules describes configuration of NETCONF capable device.","getRpcs(underlayAccess: UnderlayAccess): Set>","Return RPC services implemented in the translation unit. Default implementation returns an emptySet. Parameter underlayAccess represents object containing methods for communication with a device via NETCONF and should be passed to readers/writers.","provideHandlers(rRegistry: ModifiableReaderRegistryBuilder, wRegistry: ModifiableWriterRegistryBuilder, underlayAccess: UnderlayAccess): Unit","Handlers(readers/writers) need to be registered in this method. underlayAccess represents object containing methods for communication with a device via NETCONF and should be passed to readers/writers.","How to register readers/writers is described in CLI Translation Unit "]},{"l":"Readers","p":["Readers are handlers responsible for reading and parsing the data coming from a device.","There are 2 types of readers: Reader and ListReader. Reader can be used to handle container or argument nodes and ListReader should handle list nodes from YANG.","Both types need to implement readCurrentAttributes to fill the builder with appropriate values","ListReader needs to also implement getAllIds() where it retrieves a key for each item to be present in current list. After the list is received, framework will invoke readCurrentAttributes for each item from getAllIds"]},{"l":"Mandatory interfaces to implement","p":["Each reader needs to implement one of these interfaces based on type of target node in YANG.For more information about methods please read javadocs.","ConfigListReaderCustomizer- implement this interface if target composite node in YANG is list and represents config data.","ConfigReaderCustomizer- implement this interface if target composite node in YANG is container or augmentation and represents config data.","OperListReaderCustomizer- implement this interface if target composite node in YANG is list and represents operational data.","OperReaderCustomizer- implement this interface if target composite node in YANG is container or augmentation and represents operational data."]},{"l":"Base Readers","p":["Each base reader for netconf readers should be generic. The generic marks the data element within device YANG that is being parsed into. The base reader should contain abstract methods:","fun readIid(): InstanceIdentifier- each child reader should fill in the device specific InstanceIdentifier that points to the information needed for this reader. Arguments may vary and they are used to be more specific IID (e.g. when creating an IID to gather information about a specific interface, you may want to pass interface name as argument).","fun readData(data: T?, configBuilder: ConfigBuilder, )","this method is used to transform OpenConfig data (contained in ConfigBuilder) into device data (T) using .","Naming of the methods should be unified in order to be easily parsed by auto-generated documentation."]},{"l":"Writers","p":["A writer needs to implement all 3 methods: Write, Update, Delete in order to fully support default rollback mechanism of the framework","Time showed that update like 1. delete, 2. write is anti-pattern and should not be used. There is just one case where it is necessary: when re-writing list entry, you must first delete the previous entry, then write the new one, otherwise the previous entry would still be present and the new entry will be added to the list.","A writer can properly work only if there is a reader for the same composite node.","The framework provides safe methods to use when handling data on device:","safePut deletes or adds managed data. Does not touch data that was previously on the device and is not handled by the writer.","safeMerge stores just the changed data into device. Does not touch data that was previously on the device and is not handled by the writer.","safeDelete removes data from the device only if the managed node does not contain any other information (even one not handled by the writer)"]},{"i":"mandatory-interfaces-to-implement-1","l":"Mandatory interfaces to implement","p":["Each writer needs to implement one of these interfaces based on type of target node in YANG. Unlike mandatory interfaces for reading, only interfaces for writing config data are available (because it is not possible to write operational data). For more information about methods please read javadocs.","ListWriterCustomizer- implement this interface if target composite node in YANG is list. An implementation needs to be registered as GenericListWriter.","WriterCustomizer- implement this interface if target composite node in YANG is container or augmentation. An implementation needs to be registered as GenericWriter."]},{"l":"Base Writers","p":["Each base writer should be generic and contain abstract methods:","fun getIid(id: InstanceIdentifier): InstanceIdentifier-this method returns InstanceIdentifier that points to a node where data should be written","fun getData(data: Config): T- this method transforms OpenConfig data into device specific data (T)"]}],[{"l":"Native-CLI translation units"},{"l":"Modules structure","p":["The following text block displays a structure of native-cli units that are placed under root 'cli-native-units' module with 2 device types - ios-xr-5 and junos-17. There are also init units under 'ios-xr' and'junos' directories - they are still required to be implemented, however they are already part of classic translation units. The first identifier corresponds to directory name, the second identifier placed in brackets corresponds to module name. All modules are represented by 'pom.xml' files.","Description of the modules:","cli-native-units: Root module that groups all native-CLI-only modules. Submodules are specified per device-type.","unit-parent: Parent unit common for all unit modules (for example 'ios-xr-5-native-unit' and 'junos-17-native-unit'): it specifies common imports. It doesn't need any modification when a new device-type is added.","ios-xr-5-native and junos-17-native: These modules just group unit and models submodules for specific device-types. Each supported device type should have its separated module.","ios-xr-5-native-models and junos-17-native-models: They contain all YANG schemas under \"src/main/yang\" directory - device-template YANG schemas and native-CLI YANG schemas. They are described in next sections in detail.","ios-xr-5-native-unit and junos-17-native-unit: Implementations of native-CLI translation units - these modules contain only single Java file under 'io.frinx.cli.cnative.iosxr5' or'io.frinx.cli.cnative.junos17' package that is responsible for registration of YANGs and providing of device-specific information. More information can be found in the next section.","ios-xr-cli-init-unit and junos-cli-unit-unit: Reused initialization units that are required to be registered as native-cli translation units too. These units can be shared by both classic units which require implementations of handlers and native-CLI units. It is achieved by extending of'AbstractUnitWithNativeSupport' abstract class."]},{"l":"Implementation of units"},{"l":"Device-specific units","p":["All device-specific native-CLI units must extend 'GenericCliNativeUnit' abstract class. Description of the implemented methods:","getYangSchemas(): Returned set must contain all device-specific native-CLI schemas that are placed under models module except device-template YANG module that doesn't have to be placed to this set.","getRootInterfaces(): Returned list must contain all classes of root lists and containers (classes generated by MD-SAL generators from YANG schemas) - it simplifies transition between binding-aware and binding-independent worlds.","getSupportedVersions(): Set of supported device versions - it is used for identification of translation units.","getUnitName(): Name of the translation unit - it has only descriptive purposes.","getCliFlavour()(optional): By default, Cisco IOS CLI flavour is used. CLI flavour describes formatting of device running / candidate configuration that is used during parsing of configuration into the tree. Non-Cisco devices should override this method and provide custom CLI flavour in order to make native-CLI readers work (see next example with comments that describe CLI flavour parameters).","Example: Implementation of JUNOS 17 native-CLI unit:"]},{"l":"Init units","p":["Rules for implementation of init units are same for native-CLI and classic units - see documentation: \"Implementing CLI Translation Unit\", subsection \"Init Unit\". The only difference is in the extended class - if an init unit must be registered as both native-CLI and classic translation unit (the most usual scenario), then init unit must extend'AbstractUnitWithNativeSupport' and not just 'AbstractUnit' abstract class."]},{"l":"Device-template YANG model","p":["These YANG schemas are used for describing of device-specific patterns that are required for successful communication with remote CLI. Device-template YANG schema doesn't contain any data schema nodes, it consists only from YANG extensions that are declared in the'cli-native-extensions' model. Multiple native-CLI YANG models can import the same device-template model.","Sample device-template model for IOS XR 5.* devices:","Description of the supported extensions that can be used in a device-template:","show-command: Command used for displaying of the whole running / candidate configuration. It is used for initial population of the device configuration tree that is transformed into DOM format in native-CLI readers. The default string is \"show running-config\".","config-pattern: Template used for 'set' commands that apply a new configuration or update an existing configuration. It must contain '#' placeholder that is replaced by actual command that is going to be sent to remote CLI in native-CLI writers. Default string is \"#\" (without any prefix).","delete-pattern: Template used for 'delete' commands that remove some configuration from a device. It must contain '#' placeholder that is replaced by actual delete command that is going to be sent to remote CLI in native-CLI writers. Default string is\"no #\"."]},{"l":"Native-CLI YANG model","p":["These YANG models are used for modelling of device configuration. Currently supported schema nodes include containers, lists, choice nodes, and leaves with different types. Groupings can also be freely used for organization of YANG structure. The following subsections explain general structure of the native-CLI YANG model and application of different schema nodes for modelling of device configuration with examples.","Augmentations are currently not supported in native-CLI models (except the augmentations into UniConfig configuration container which is required)."]},{"l":"Structure","p":["The following YANG snippet shows structure that should all native-CLI YANG schemas follow (variable parts are marked by square brackets):","Description of variables:","[device-type]: Type of the device for which this YANG models some part of the configuration. Examples: junos17, xr5 (if it is necessary, more specific versions can be typed).","[entity]: Part of the configuration that is modelled by this YANG. Examples: interfaces, firewall, acl.","[prefix]: Prefix that is usually an abbreviation derived from the name of the model.","[template-model]: Name of the imported device-template module. Only a single device-template module can be imported, otherwise the whole module is marked as invalid and it is skipped. Afterwards, revision-date and prefix must be selected too.","[revision] with [description]: Date of the YANG modification with description, what was changed in the specific revision. Multiple revisions can be added incrementally as YANG schema is modified.","[root-grouping]: Identifier of the root grouping that contains single root container or list. Multiple root groupings are allowed when multiple root containers are lists are required. For each root grouping there must be a separate augmentation into 'configuration' container.","Importing of the device-template model is not necessary at all - in that case, the default device template is applied - Cisco IOS XR template."]},{"l":"Containers","p":["Containers are used for representations of nodes in configuration which can have at least one child node but there is only one instance of configuration that is placed under this node. For example, let assume the following two lines in the XR 5.3.4 configuration of access-lists:","In this snippet, ipv6 is modelled by container schema node with the same identifier, because 'ipv6' command word is a root node and it can contain only single instance of list with identifier access-list:","It is also possible to wrap multiple containers in a chain. For example, the following command line:","can be modelled by following containers:"]},{"l":"Lists","p":["Similarly to containers, lists also represent command words that may have multiple children nodes. However, nodes represented by lists can have multiple instances in the configuration where individual instances are represented by one or multiple keys. Values of keys are represented by command nodes that follow list command word. For example, let consider following configuration of XR 5.3.4 interfaces:","In this case, 'interface' can be modelled as list schema node with'interface' identifier. It has a one key - interface name (possible values, based on the example, are 'MgmtEth0/0/CPU0/0', GigabitEthernet0/0/0/0, GigabitEthernet0/0/0/1, and GigabitEthernet0/0/0/2).","Name of the leaves that represent list keys are not important. Only an order of keys, in case of multiple keys, has a significance from the view of association between configuration and YANG model.","The second example presents a scenario in which a list with multiple keys must be used (IOS XR 5.3.4 access-lists):","There are two keys - name of the access-list and sequence number of the access-list entry that must be unique in scope of the single access-list. Because of this, access-list can be modelled by following list schema node:"]},{"l":"Choices","p":["Identifiers of list, container, or leaf schema nodes are always derived from words identifying parts of the command lines. Choice schema nodes are modelled differently - they are only used for modelling of multiple non-overlapping sets of children commands. Both identifier of choice schema node and case nodes are not important (names of the case schema nodes are usually chosen based on logical option they represent). Choices are handy, if it is required to add YANG-based constraint on combinations of entered commands - wrong combinations of command would fail on device anyway.","For example, the JUNOS 17 allows configuration of different interface types:","In this example, 'hold-time' is a configuration that can be applied only on physical interfaces. On the other side, LACP can be configured only on the bundle interfaces. Because of this logical separation, it has a sense to differ between physical and bundle interfaces in YANG (common settings can be placed directly under 'interfaces' list):"]},{"l":"Leaves","p":["Leaves are used for representation of command parts that don't have next children subcommands. Command node can be represented by one or more words depending on the type of the leaf. The following types of leaves are currently supported:","1. Empty: Empty leaf can be used for commands without any value(there is only one command word that identifies leaf). For example, JUNOS 17 interface 'disable' command:","can be modelled as leaf with empty type:","2. Types with primitive value: Supported primitive types include boolean, string, decimal, int8, int16, int32, int64, uint8, uint16, uint32, and uint64. All of these types can be used for commands that has a single string, boolean, or numeric value (types constrained by a range). The following commands can be modelled as one of these types(different JUNOS 17 damping settings):","YANG representation of leaves 'half-life' and 'suppress':","3. Enumeration- If there are multiple but finite set of possible strings assignable to the command, then the enumeration type should be used. Let consider the following variations of the 'mode' command (IOS XR 5.3.4 LACP configuration):","In this example, 'mode' is modelled as leaf with type enumeration with three possible values:","4. Bits: This type of leaf can be used in scenarios in which there are multiple possible values assignable to the command (similarly to enumeration), but they are not mutually exclusive - different values can be combined in a chain of strings. Consider the following options how to configure Unicast Reverse Path Forwarding on IOS XR 5.3.4:","The part of the command line starting by word 'any' can continue with random combination of options 'allow-self-ping' and 'allow-default' with random ordering too. Because of this reason, leaf with identifier 'any' has bits type:","5. Blob-data- It is a special type of leaf defined in'cli-native-extensions' that can be used for the whole command section with a random structure. It is handy for the parts of the configuration that are too complicated to be represented by different YANG structures. Internally, 'blob-data' is a type definition derived from string type. For example, JUNOS 17 firewall rules fulfils high complexity:","Commands 'from' and 'then' can be represented by leaves with'blob-type':"]}],[{"l":"Metrics"},{"l":"Monitoring Uniconfig performance","p":["Micrometer Metrics is the framework of choice to monitor performance."]},{"l":"Registry naming","p":["All the metrics are currently stored in the global registry. It can be accessed like so:"]},{"l":"Metric types","p":["All the available metric types can be seen in the documentation."]},{"l":"Naming convention","p":["There are various best practice articles on how to name metrics but one thing is common: It should be clear what is measured."]},{"l":"Adding new metrics"},{"l":"Adding a Counter","p":["Obtain a Counter and then increment all the method calls you want to measure."]},{"l":"Adding a Gauge","p":["Here we create a Gauge that returns Integer value, access is synchronized in this case to avoid race conditions."]},{"l":"Tags","p":["Tags are currently not available in the version 4.2.x, although support for them is planned for future major release."]},{"l":"Reporters","p":["Metrics are available at /actuator/prometheus endpoint."]}],[{"l":"Release notes","p":["Release notes for UniConfig 4.2.10","Release notes for UniConfig 4.2.3","Release notes for UniConfig 4.2.4","Release notes for UniConfig 4.2.5","Release notes for UniConfig 4.2.6","Release notes for UniConfig 4.2.7","Release notes for UniConfig 4.2.8","Release notes for UniConfig 4.2.9","Release notes for UniConfig 5.0.1","Release notes for UniConfig 5.0.10","Release notes for UniConfig 5.0.11","Release notes for UniConfig 5.0.12","Release notes for UniConfig 5.0.13","Release notes for UniConfig 5.0.14","Release notes for UniConfig 5.0.15","Release notes for UniConfig 5.0.16","Release notes for UniConfig 5.0.17","Release notes for UniConfig 5.0.18","Release notes for UniConfig 5.0.19","Release notes for UniConfig 5.0.2","Release notes for UniConfig 5.0.20","Release notes for UniConfig 5.0.21","Release notes for UniConfig 5.0.22","Release notes for UniConfig 5.0.23","Release notes for UniConfig 5.0.24","Release notes for UniConfig 5.0.25","Release notes for UniConfig 5.0.3","Release notes for UniConfig 5.0.4","Release notes for UniConfig 5.0.5","Release notes for UniConfig 5.0.6","Release notes for UniConfig 5.0.7","Release notes for UniConfig 5.0.8","Release notes for UniConfig 5.0.9","Release notes for UniConfig 5.1.0","Release notes for UniConfig 5.1.1","Release notes for UniConfig 5.1.10","Release notes for UniConfig 5.1.11","Release notes for UniConfig 5.1.12","Release notes for UniConfig 5.1.13","Release notes for UniConfig 5.1.14","Release notes for UniConfig 5.1.15","Release notes for UniConfig 5.1.16","Release notes for UniConfig 5.1.17","Release notes for UniConfig 5.1.18","Release notes for UniConfig 5.1.19","Release notes for UniConfig 5.1.2","Release notes for UniConfig 5.1.20","Release notes for UniConfig 5.1.21","Release notes for UniConfig 5.1.22","Release notes for UniConfig 5.1.23","Release notes for UniConfig 5.1.3","Release notes for UniConfig 5.1.4","Release notes for UniConfig 5.1.5","Release notes for UniConfig 5.1.6","Release notes for UniConfig 5.1.7","Release notes for UniConfig 5.1.8","Release notes for UniConfig 5.1.9","Release notes for UniConfig 5.2.0","Release notes for UniConfig 5.2.1","Release notes for UniConfig 5.2.2","Release notes for UniConfig 5.2.3","Release notes for UniConfig 5.2.4","Release notes for UniConfig 5.2.5","Release notes for UniConfig 5.2.6","Release notes for UniConfig 5.2.7","Release notes for UniConfig 6.0.0","Release notes for UniConfig 6.0.1","Release notes for UniConfig 6.0.2","Release notes for UniConfig 6.0.3","Release notes for UniConfig 6.0.4","Release notes for UniConfig 6.0.5","Release notes for UniConfig 6.0.6","Release notes for UniConfig 6.0.7","Release notes for UniConfig 6.0.8","Release notes for UniConfig 6.0.9","Release notes for UniConfig 6.1.0","Release notes for UniConfig 6.1.1","Release notes for UniConfig 6.1.2","Release notes for UniConfig 6.1.3","Release notes for UniConfig 6.1.4","Release notes for UniConfig 6.1.5","Release notes for UniConfig 6.1.6","Release notes for UniConfig 7.0.0","Release notes for UniConfig 7.0.1"]}],[{"i":"uniconfig-507-release-notes","l":"Uniconfig 5.0.7 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implementation of context-match shell operation"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed establishing of NETCONF stream sessions","Fixed NetconfDeviceCommunicatorTest","Fixed Uniconfig client json parser tests","Fix building history output","Fixed execution of YANG action under some list entry from shell","Fixed ordering transaction log by date","Fixed types of the network-instance/interfaces","Making subscription monitoring loop more robust","Cli session closed/disconnected","Fixed removing of data-change-event subscription","Fixed merging template attribute to replaced node","CLI shell: harmonised composite key delimiter input"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Updated netconf-node-topology:concurrent-rpc-limit parameter","Refactored global DOMSchemaService","Optimization of calculate-diff RPC","Swagger and YangPackager improvements","Fix all owasp sec issues level 8","Upgrade sshd libs to version 2.8.0","Upgrade and cleanup usage of jaxb","Upgrade jetty/jersey/jax-rs dependencies","Reorganisation of NETCONF connection parameters"]}],[{"i":"uniconfig-506","l":"UniConfig 5.0.6"},{"i":"new-features","l":"✅ New Features"},{"l":"Expose operational data about transactions","p":["It would improve visibility what transactions are open on uniconfig instance - when these transactions have been open and what nodes have been changed in the transaction.","Transaction data:","identifier (uuid)","trace id / different parameter (once we support tracing)","creation time","last access time","idle timeout, hard timeout","list of changed nodes (incl. topologies)","additional context (random string, text column)"]},{"l":"Implement metric collection and reporting in Uniconfig","p":["Collect and report metrics such as:","TX pre minute","RPC calls per minute","Task execution queue size","Netconf msg sent count","CLI command sent count","…","Reporting part could be just logging the state of metrics for the time being"]},{"i":"collect-open-transactions-data-in-collect_diag_infosh","l":"Collect open transactions data in collect_diag_info.sh","p":["Please enhance debug collection script to collect details of following","Open Transaction , Read or Read-Write and if possible module which has opened the transaction","For example, this is how NCS displays.","This could help in debugging slowness issues caused if there is any transaction leak."]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements"},{"l":"Set OWASP dependency check plugin to level 9","p":["decrease owasp level to 9 (in distribution/packaging/zip pom)","fix all dependency issues so that uniconfig will successfully build"]},{"i":"cli-uc-shell---show-transaction-log-in-ordered-list--add-brief-option","l":"CLI UC shell - show transaction log in ordered list & add \"brief option\"","p":["Currently we display the transaction log as a json without ordering. We should assume that the transaction log can become very large and should still be manageable to display. Hence we are proposing the following improvements:","always show the transaction log as an ordered list. Order by transaction timestamp. The most recent transaction should be at the bottom of the list.","add a \"brief\" option to that command and display only one line per transaction log. Similar like this"]},{"i":"bug-fixes","l":"❌ Bug Fixes"},{"l":"OpenAPI .yaml file generating incorrectly","p":["Build, Collaborate & Integrate APIs | SwaggerHub","cli-unit-general API yaml seems incorrectly generated, URIs are wrong"]},{"i":"syst_-data-change-subscriptionscontentnonconfig-not-working","l":"SYST_ data-change-subscriptions?content=nonconfig not working","p":["Based on documentation Kafka notifications","test:","test here https://gerrit.frinx.io/c/system-tests/+/13155"]}],[{"i":"uniconfig-505","l":"UniConfig 5.0.5"},{"i":"improvements","l":"\uD83D\uDCA1 Improvements"},{"l":"Reconfigure swagger generator for versa to produce desired depths for all APIs","p":["Since we need to create APIs with depth 4, I have noticed APIs are created to the last container when the depth of yang is less than 4. Can you make API is not generated for the last container, for example 2nd API in the below not required as “global” is the leaf container. This change will reduce size of yaml file and number of APIs"]},{"i":"bug-fixes","l":"❌ Bug Fixes"},{"l":"Uniconfig transaction is not thread-safe","p":["It is not safe to use same uniconfig transaction simultaneously by multiple user-side threads because underlying database connection/transaction is not thread-safe in case of PostgreSQL driver and UniConfig is not doing any additional synchronisation.","Read: Chapter 10. Using the Driver in a Multithreaded or a Servlet Environment","Behaviour that was also observed in UniConfig (it is Oracle DB, but symptoms are similar): Working with multiple threads sharing a single connection"]},{"i":"failed-to-find-node--in-the-topology-uniconfig","l":"Failed to find node '' in the topology 'uniconfig'","p":["It happened already a couple of times when a workflow task failed during the execution of getting data from the device. In VFZ we have a specific task for this operation called uniconfig_read_structured_device_data which gets a specific config from the device","During this execution, there were other devices running in the parallel executing the same task and 2 read_and_execute_rpc_cli tasks too.","The device had the records in the node and mounpoint tables in the UC DB.","DONE, MOVE TO 5.0.4"]}],[{"i":"uniconfig-504","l":"UniConfig 5.0.4"},{"i":"new-features","l":"✅ New Features"},{"l":"Adding option to use json-path also for selection of some subtrees","p":["Currently, jsonpath language can be used in UniConfig only for filtering of data. However, the language itself allows also to select some data using provided json-path.","We need to expose this functionality in UniConfig API using some query parameter (the similar way as it is done for filtering) and also expose this functionality in the uniconfig-client."]},{"i":"shell-scrolling-output---more--","l":"Shell: scrolling output (--more--)","p":["Long UniConfig shell output should be displayed using some scrolling mechanism (equivalent to ‘more' or 'less’ linux tools)."]},{"i":"add-show-history-command-to-uniconfig-shell","l":"Add 'show history' command to uniconfig-shell","p":["It should display last N commands that were executed in the shell. Syntax:","Parameter 'max-number-of-output-commands' should be optional.","This command should be available from both operational and configuration modes."]},{"l":"Add support for aliases inside uniconfig shell","p":["There should be some configuration file in the config directory that will contain defined aliases. It should support also place-holders/variables for both values and arrays.","Supporting autocomplete on aliases."]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements"},{"l":"Improve maven plugin for generation Java classes","p":["yang packager: generate sources only for latest repository","settings: package name - option to change it","setting: disable prefix + javadoc on data-elements"]},{"i":"bug-fixes","l":"❌ Bug Fixes"},{"l":"NETCONF sessions used for receiving NETCONF notifications stop working","p":["UniConfig does not use keepalive messages for checking, if NETCONF session used for receiving of NETCONF notifications is still alive and triggering reconnection procedure. As a consequence, if connection is dropped without explicit TCP interruption, then UC will not find it out and doesn’t try to re-create connection. However, device is using some form of TCP keepalive messages - device will drop connection after some time.","FIX: Uniconfig is enables and tracks keepalive messages also for NETCONF sessions that are used for NETCONF streams"]},{"l":"Optimisation of jsonb-filtering","p":["It seems that jsonb-filtering causes reading of whole configuration from PG into UC even if it should not be necessary:","checking existence of the node - currently it works by using DOM ‘exists’ operation that reads whole configuration from DB","deriving uniconfig-native prefix / YANG repository - it is derived from configuration, not from DB metadata","FIX: stopping verification of node, if jsonb-filer is used. It required reading of whole config from DB to Uniconfig what making the call much slower."]},{"i":"uc-shell-after-configrequest-commit-the-prompt-was-changed-unexpectedly-from-request-to-config","l":"Uc shell: after config/request commit the prompt was changed unexpectedly from request> to config>","p":["Previous behaviour:","After fix:"]},{"i":"uc-shell-config-mode--show-or-delete---create-object-option-should-be-removed","l":"Uc shell: config mode / show or delete - CREATE OBJECT option should be removed","p":["Previous behaviour:","e.g. here (create new template) should not be present here. Similarly others places in program. Behaviour like this is not expected by user.","After fix:"]},{"i":"uniconfig-503-prints-out-error-on-start","l":"Uniconfig 5.0.3 prints out error on start","p":["Fix: error message in the log was displayed when notifications were set to false in the lighty-uniconfig-config.json file. This error message is no longer displayed."]},{"l":"Flyway migration failed","p":["Migration of data in the database when switching to another version throws error causing that uniconfig is unable to start."]},{"l":"Yang patch operation does not work correctly with leaf list","p":["There are several issues with yang patch when operating on leaf-lists. In particular I have found issues with the insert operation and the merge operation.","Merge operation case:","If the leaf list does not exist, then the merge operation pass without problems. However, if the leaf list does already exist, then the merge fails with following error message:","Insert operation case:"]},{"l":"PATCH operation does not work with some paths and target combination","p":["Overview RestConf PATCH operation does not work with certain combination of URL and target","Details","Request URL ( is the UniConfig host, is the id under which the Sonic device is installed):","http:///rests/data/network-topology:network-topology/topology=uniconfig/node=/frinx-uniconfig-topology:configuration/openconfig-interfaces:interfaces/interface=Ethernet52","Method: PATCH Request body:","Produce this response:","Request body:","Produce empty response body with error code 500. UniConfig logs have this record:"]},{"l":"Portchannel trunk-vlans replace","p":["When one trunk vlan is already set on porchannel, then put request to change trunk vlans list returns:","Unsupported type of node …","Current workaround is deleting whole list of trunk-vlans, after that single put request to add removed and new trunk-vlans.","Postman collection is attached. Replace can be also done using this gnmic command:"]}],[{"i":"uniconfig-503","l":"UniConfig 5.0.3"},{"i":"new-features","l":"✅ New Features"},{"l":"Adding failed transactions into transaction log","p":["Description","Previously, only successfully committed transactions have been written into transaction log.","Added state to transaction log entry that determines, if transaction has been successfully or not committed - both successful and failed transactions are part of transaction log.","Documentation","Transaction Log | Frinx Docs","API","Added ‘status' leaf and split ‘commit-time’ into ‘last-commit-time’ and 'failed-commit-time’ (YANG module transaction-log):"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements"},{"l":"Integrated OWASP dependency check tool into UniConfig","p":["3-rd party libraries are check against security issues during building of UniConfig distribution. If there are some issues with security level higher than configured threshold, built will fail.","Set security threshold level to 10 and fixed corresponding critical errors."]},{"i":"bug-fixes","l":"❌ Bug Fixes"},{"i":"fixed-updating-of-leaf-list-content-orderedunordered-on-netconf-device","l":"Fixed updating of leaf-list content (ordered/unordered) on NETCONF device","p":["Unordered leaf-list must be updated using following steps:","removing all items that are not in the updated list","inserting all items that are only in the updated list","There was 1 bug: step 1. never happened.","Ordered leaf-list must be updated using following steps:","inserting/moving new/existing items in the correct order (using ordering parameters) [1]","removal of all items that are not in the updated list [2]","There was 1 bug - all items were removed and afterwards re-inserted without usage of special positional attributes - it created conflict on NETCONF layer between edits and thus splitting of NETCONF traffic into 2 edit-config messages."]},{"i":"device-discovery-32-prefix-changed-to-inclusive","l":"Device discovery /32 prefix changed to inclusive","p":["User must be able to ping network with prefix /32 - it must be rendered as single host (special case)."]},{"i":"uniconfig-shell---exit---it-is-expected-to-hit-enter-twice","l":"UniConfig shell - exit - it is expected to hit enter twice","p":["Previous behaviour:","After fix, UniConfig will print user some message, that one more is expected to leave SSH session."]}],[{"i":"uniconfig-502","l":"UniConfig 5.0.2"},{"i":"new-features","l":"✅ New Features"},{"l":"Upgrading templates","p":["Added ‘upgrade-template' RPC into 'template-manager’ YANG module:","API","Both settings are related to auto-upgrading process - they don’t influence execution of RPC which can be still done manually.","Configuration","Description","Documentation","if it fails, we will return standard RESTCONF RFC-8040 error container","Implemented automation of the upgrading process - calling of this RPC automatically at initialisation of UniConfig for all templates present in the DB that don’t use the latest repository.","Implemented RPC for upgrading template to specific YANG repository.","output template name (optional, default value = input template name)","RPC input:","RPC output:","Supplemented template configuration by 2 new settings (lighty-uniconfig-config.json) - enabledTemplatesUpgrading and maxBackupTemplateAge.","template name (mandatory)","Templates Manager| Frinx Docs","without body, just status message","YANG repository name (optional, default value = latest YANG repository)"]},{"l":"Connection notifications","p":["Description","Connection notifications are generated after state of southbound CLI/NETCONF/GNMI node is updated - either status message or connection status.","Notifications are published into dedicated Kafka topic.","They are useful especially for debugging connection issues between UniConfig and network devices.","Documentation","Kafka Notifications | Frinx Docs","API","Structure of notifications are described following YANG module 'connection-notifications':","Added settings used for configuration of Kafka topic and enabled/disabled state (YANG module kafka-brokers):","Configuration","Supplemented corresponding settings into in the lighty-uniconfig-config.json file (by default, these notifications are enabled if globally notification system is enabled):"]},{"l":"Configurable transaction idle-timeout","p":["Description","Introduced new transaction parameter that can be used at creation of new transaction and overrides global idle-timeout.","After inactivity of the transaction, it is automatically closed and an exception will be thrown if user tries to invoke some operation on the transaction.","Documentation","Example request with timeout parameter | Frinx Docs","API","Format of the query parameter 'timeout':","Uniconfig-client","Introduced TransactionParameters class - object of this class can be provided at creation of new transaction. By default, transaction-specific idle-timeout is disabled - global idle-timeout is used."]},{"l":"Added option to disable validation phase at commit","p":["Description","UniConfig uses 3-phase commit procedure - validation, confirmed-commit, confirming-commit. Validation is currently always executed on nodes that support validation and have been installed with enabled validation.","This feature introduces flag in the commit RPC using which user can control execution of validation phase.","Documentation","RPC commit | Frinx Docs","API","Added 'do-validate' field into commit RPC input (checked-commit does not supported this feature for now):","Uniconfig-client","In the uniconfig-client validation is 'disabled' by default (opposite behaviour in comparison to RESTCONF API).","Exposed new method in DOMReadWriteTx interface:"]},{"l":"Modification of connection parameters after the first installation without uninstallation","p":["Description","After some CLI/NETCONF device has already been installed, it is possible to update some connection / mount parameters (for example, ‘host' or 'password’).","User can read and update connection parameters under ‘cli' or 'topology-netconf’ topology, under specific network-topology nodes.","Afterwards, UniConfig will use updated connection parameters at the next creation of connection to device.","NETCONF sessions used for receiving of NETCONF notifications are also updated at the next monitoring iteration.","Documentation","Updating installation parameters | Frinx Docs","Uniconfig-client","Example:"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements"},{"l":"Improved aggregation of NETCONF messages","p":["Non-overlapping edit-config messages are already aggregated into one edit-config message that is sent to NETCONF server. However, this aggregation was primitive - it just serialised all modified subtrees and stacked them under root element without considering option, that paths to these subtrees may overlap.","After this improvement, edit-config message will contain compressed subtree structures without duplicated ‘wrapper’ elements."]},{"i":"added-session-id-to-netconf-logs-netconf-messages","l":"Added session-id to NETCONF logs (netconf-messages)","p":["Description","Previously, only internal Netty’s channel-id was displayed in the logs.","After this improvement, NETCONF-specific session-id, returned from device during exchanging of capabilities, will be used.","Documentation","Logging Framework | Frinx Docs","Making connection-manager unit tests more robust","Preventing random failures because of multi-threaded environment.","Improve error message if device/template doesn't exist","If device/template or another node doesn’t exist, UniConfig should return user-friendly error message that corresponding node doesn’t exist and not some YANG-related error.","Creation of new node with specified YANG repository is still allowed.","Error message before the fix:","Error message after the fix:"]},{"i":"bug-fixes","l":"❌ Bug Fixes"},{"l":"Fixed YANG packager that does not catch broken submodules","p":["Description","Fixed reporting of two kinds of issues related to YANG submodules:","Submodules contain statement “belongs-to” some parent. That parent should contain statement “include”. When parent does not contain this statement, uniconfig marks submodule as broken.","When submodule contains “belongs-to” statement, but parent does not exists.","Improved error message output from YANG packager utility.","Documentation","Device Discovery | Frinx Docs"]},{"i":"fixed-device-discovery-behaviour-for-network-with-31-prefix","l":"Fixed device-discovery behaviour for network with /31 prefix","p":["Description","Use cases:","192.168.1.0/32 - returns empty output, there aren’t any usable hosts that can be reached","192.168.1.0/31 - special case, device-discovery component should verify two hosts - .1 and .2","192.168.1.0/30 - returns 192.168.1.1, 192.168.1.2","Documentation","Device Discovery | Frinx Docs"]},{"i":"fixed-calculate-diff-operation-augmentation-nodes","l":"Fixed calculate-diff operation (augmentation nodes)","p":["Augmentation nodes have been skipped and unwrapped during reading of data from device. It resulted in the failed / incorrect calculation of diff on UniConfig layer.","After this fix, UniConfig skips only those augmentation nodes that contain only non-config data nodes (YANG 'config false' statement)."]}],[{"i":"uniconfig-501","l":"UniConfig 5.0.1"},{"i":"new-features","l":"✅ New Features"},{"i":"propagation-of-data-change-events-from-uniconfig--unistore-configuration","l":"Propagation of data-change-events from ‘uniconfig' / 'unistore’ configuration","p":["Description","Implemented propagation of data-change-events into distinct Kafka topic. Data-change-events are currently supported per-node in ‘uniconfig' and 'unistore' network-topologies.","Using subscription, user specifies observed subtrees against data-changes. Afterwards, data-change-events are generated by UniConfig instances after some transaction is committed and committed changes contain subscribed subtrees.","API","Created new YANG module that defines data-change-events structure in form of YANG notifications and RPC calls for manipulation / reading of subscriptions:","Documentation","Kafka Notifications | Frinx Docs","Configuration","Added settings into lighty-uniconfig-config.json file:","dataChangeEventsEnabled- turning on/off generation and distribution of data-change-events (by default, they are enabled)","dataChangeEventsTopicName- name of the Kafka topic (default identifier is 'data-change-events')","Java client","Example, how to use data-change-events as triggers for callback inside UniConfig Java client:"]},{"l":"Added config option to disable immediate-commit model","p":["Description","Immediate-commit model is in some cases dangerous, because changes are automatically committed to managed network devices.","Added option to disable immediate-commit model globally.","Configuration","New setting 'isImmediateCommitEnabled' in the lighty-uniconfig-config.json:","Default value is 'true'."]},{"l":"Calling replace-config-with-oper after sync-from-network in the immediate-commit-model","p":["In the immediate-commit-model, if user called sync-from-network operation, it behaved as 'sync-to-network' operation:","reading configuration from device","resolving diff between actual (device) and intended state (last saved configuration in database)","sending resolved diff to operation - reverting changes, that have been done on device side","This dangerous if network device is configured manually by user or another tool.","Fixed by calling replace-config-with-oper operation after called-sync-from-network operation and before committing temporary transaction created in the immediate-commit model session. It will result in storing of loaded configuration to database without performing any action on managed devices.","This change alters only immediate-commit model. Build-and-commit model stays unaltered."]},{"l":"Making default CLI connection parameters configurable","p":["Description","There are couple of CLI connection parameters with some default values defined in cli-topology YANG module that can be specified at installation of device.","This feature allows user to adjust these default parameters without repetitive adjustment in the install-node RPC request.","Priority of using install parameters:","Parameter set in install RPC request","Default parameter set in database","Default parameter from YANG model","Documentation","Device installation | Frinx Docs","API","Exposed default CLI settings into distinct container that is accessible using RESTCONF API (module cli-topology):","Exposed settings in the UniConfig shell - configuration mode / settings container."]},{"l":"Making default NETCONF connection parameters configurable","p":["Description","There are couple of NETCONF connection parameters with some default values defined in netconf-topology YANG module that can be specified at installation of device.","This feature allows user to adjust these default parameters without repetitive adjustment in the install-node RPC request.","Priority of using install parameters:","Parameter set in install RPC request","Default parameter set in database","Default parameter from YANG model","Documentation","Device installation | Frinx Docs","API","Exposed default NETCONF settings into distinct container that is accessible using RESTCONF API (module netconf-node-topology):","Exposed settings in the UniConfig shell - configuration mode / settings container."]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements"},{"l":"Improved displaying of children nodes of DataNode in Java client","p":["Children nodes were organised under multiple levels of Map objects - it was not readable especially when user was debugging code.","Now, children nodes are displayed directly under simple List collection:"]},{"l":"Added YANG-based documentation to Java client","p":["Added JavaDoc description to DataNode and DataNodePath sub-classes, how they are used in comparison to YANG schema tree.","Example:"]},{"l":"Removed redundant module-name prefixes from built paths in Java client","p":["RFC-8040 specifies that module-name prefix must be added only to the first augmented elements (transition to different namespace).","Previously it worked non-optimally - module name was added to all elements of the path:","After improvement:"]},{"l":"Added option to enable PostgreSQL driver logs in UniConfig","p":["Description","Logging connections and communication between UniConfig and PostgreSQL can be handy in case of debugging of some errors.","Configuration","To log detailed information about executed queries and PG connections, user should set org.postgresql logger level to DEBUG or TRACE."]},{"l":"Added transaction-id also to both RESTCONF requests and responses","p":["Description","UniConfig transaction-id simplifies debugging of executed RESTCONF operations.","Example (added 'Uniconfig transaction' property):","Documentation","Logging Framework | Frinx Docs"]},{"l":"Hiding sensitive data in logs","p":["In the UniConfig logs are shown sensitive data like PostgreSQL DB credentials, etc. This is a potential security hole.","Example:","Fixed by hiding JSON configuration parsing details from logs."]},{"i":"bug-fixes","l":"❌ Bug Fixes"},{"l":"Fixed invocation of device-discovery RPC multiple times","p":["RPC response contained also results from previous RPC invocation.","Fixed by isolation of RPC results."]},{"i":"fixed-setting-of-max-connection-attempts-during-device-installation-clinetconf","l":"Fixed setting of max-connection attempts during device installation (CLI/NETCONF)","p":["Description","Removed max-connection-attempts parameter from install-node RPC. It was clashing with parameters from southbound layers and introducing confusion.","Fixed switched loading of max-connection-attempts and max-reconnection-attempts on NETCONF layer. It resulted in the infinite initial maximum connections attempts (by default, there should be 1 attempt).","Setting default max-connection-attempts to 1 in YANG model (both CLI and NETCONF layers).","Documentation","Updated document: Device installation| Frinx Docs","API","connection-manager - removed leaf max-connection-attempts:","cli-topology - setting max-connection-attempts default value to 1:","netconf-node-topology - setting max-connection-attempts default value to 1:"]},{"l":"Fixed stuck UniConfig API because of interrupted SQL operation","p":["Description","Default socket-read-timeout for the PostgreSQL driver is 0 - UniConfig is waiting forever for result of some query. This causes blocking of other UniConfig operations on specific node, if connection between UniConfig and PG is dropped during execution of some query.","Fixed by exposing socketReadTimeout parameter and setting its default value to 20 seconds.","Configuration","Added socketReadTimeout to database connection settings (lighty-uniconfig-config.json):"]},{"l":"Fixed propagation of error on disabled templates","p":["If templates are disabled, then user will get direct error message with 400 status code. Previously it failed on some parsing error or it didn’t fail at all and UniConfig just ignored unknown data.","Example:"]},{"i":"fixed-pki-authentication-to-netconf-device-negative-cases","l":"Fixed PKI authentication to NETCONF device (negative cases)","p":["PKI authentication on device - attempt to install device with reference to not existing private key","Previously it failed with error:","After fix it will fail with error message that private key with specified identifier doesn’t exist.","PKI authentication on device - registering the password protected key with RPC netconf-keystore:add-keystore-entry - but providing bad password","Fixed by validation of input password against key-store.","If it is invalid, UniConfig will return error immediately and will not try to register such private key and afterwards use it during mounting process."]},{"i":"netconf-edit-config-operation-with-insert-attribute-failed-because-of-aggregated--messages","l":"NETCONF edit-config operation with insert attribute failed because of aggregated messages","p":["When insert attribute was used with value before/after, there was problem with NETCONF messages ordering in the aggregated message.","Fixed by assuring that list entry specified by insert attribute is placed before actual list entry in the edit-config message sent to NETCONF server."]}],[{"i":"uniconfig-4210","l":"UniConfig 4.2.10"},{"i":"new-features","l":"✅ New Features"},{"l":"Aggregation of all edit-config NETCONF messages into one edit-config message","p":["Each modification in the transaction was expressed using one edit-config message on southbound layer.","This approach was not optimal:","it generated more network traffic than needed","it could introduce errors, if device checks some references before committing configuration","After this patch, all NETCONF edit-config RPCs in the transaction are aggregated into single edit-config RPC with common parent element."]},{"i":"capturing-changes-in-ordered-listleaf-list-using-calculate-diff-rpc","l":"Capturing changes in ordered list/leaf-list using calculate-diff RPC","p":["Currently, changed order of list entries inside ordered list/leaf-list is displayed as updated whole list with all list entries - not optimal solution.","Added new list to calculate-diff RPC output that captures changes in the ordering of list or leaf-list elements. Such changes are not displayed under created/removed/updated containers."]},{"l":"Validation of leaf-refs","p":["Validation of leaf-ref YANG constraints that are affected by some create/delete/update operation:","Supported following leaf-ref paths:","absolute paths","relative paths","paths with 'current()' XPATH function","Added new RESTCONF query parameter into put/patch/delete operations - checkForReferences.","Implementation conforms RFC 7950 - The YANG 1.1 Data Modeling Language"]},{"l":"Encryption of leaves selected by paths","p":["UniConfig uses asymmetric encryption for ensuring confidentiality of selected leaf and leaf-list values. Currently, only RSA ciphers are supported (both global UniConfig and device-level key-pairs). Encryption is supported in ‘uniconfig’, ‘unistore’, and ‘templates’ topologies.","Global-device encryption architecture - both UniConfig and device uses PKI for encryption of data:","Global-device encryption architecture","In comparison to Global-device encryption architecture this model uses only global key-pair for encryption of data. Devices contain only plaintext data."]},{"i":"implementation-of-crypt-hash-type-from-iana-crypt-hash-yang-module","l":"Implementation of ‘crypt-hash' type from 'iana-crypt-hash’ YANG module","p":["UniConfig supports 'iana-crypt-hash' YANG model for specification of hashed values in data-tree using type definition 'crypt-hash'. Hashing works in the 'uniconfig' and 'unistore' topologies. Only NETCONF devices are currently supported because CLI cannot be natively used for reporting of device capabilities that would contain supported hashing function.","Hashing is done only in the RESTCONF layer after writing some data that contains leaves/leaf-lists with 'crypt-hash' type. Afterwards, UniConfig stores, uses, and writes to device only hashed representation of these values.","All 3 hash functions are implemented - 'MD5', 'SHA-256', 'SHA-512'. In case of 'uniconfig' topology, hashing function is selected based on reported feature in the NETCONF capability, in case of 'unistore' topology, UniConfig enforces 'SHA-512' hashing function.","Hashing model"]},{"l":"Using the latest schema at creation of template","p":["Adding configuration into UniConfig that tracks identifier of the UniConfig repository that must be used at creation of new template, if user doesn’t explicitly specify identifier of this repository using ‘schema-cache-directory’ query parameter."]},{"l":"Rebalancing of notifications cluster at runtime","p":["Random distribution of subscriptions to NETCONF notifications streams and turning on/off UniConfig instances may lead to scenario when one of the UniConfig instances in the cluster contain most of the subscriptions while others unequally smaller number.","Fixed by automatic redistribution of already created subscriptions on UniConfig instances and introduction of limits, how many subscriptions can be allocated on the one UniConfig instance in the cluster.","Cluster rebalancing"]},{"l":"Configuration","p":["Added new parameters under “notifications“ element in the lighty-uniconfig-config.json file:"]},{"l":"Implementation of RFC-8072 PATCH operation","p":["Invocation of PATCH that may contain multiple edits.","All edits are invoked sequentially and atomically as single operation.","Supported sub-operations per edit: create, delete, insert, merge, move, replace, remove.","More detailed description: RFC 8072 - YANG Patch Media Type"]},{"i":"added-missing-protocols-to-l2-for-ios-xe-cli-units","l":"Added missing protocols to L2 for IOS XE (cli-units)","p":["Parsing of following protocols:","elmi","pagp","udld","ptppd"]},{"l":"UniConfig whitelist","p":["specification of top-level containers/lists which configuration is synced from device (no other configuration is read from device)","opposite of existing blacklist functionality","either blacklist or whitelist can be specified, not both","API","updated YANG model that defines whitelist/blacklist:","Install-node RPC example (input body):"]},{"l":"UniConfig client thread model","p":["make uniconfig-client thread safe (using client from multiple threads)","making HTTP connection pools configurable (max connections, …)","API:","Introduced connection pool settings:","Introduced UniConfig server settings:","Example:"]},{"l":"Distribution of NETCONF notifications to Kafka","p":["NETCONF devices are capable of generating NETCONF notifications. UniConfig is able to collect these notifications and creates its own UniConfig notifications about specific events. Kafka is used for publishing of these notifications from NETCONF devices and UniConfig. Currently there are these types of notifications: - NETCONF notifications - notifications about transactions - audit logs (RESTCONF notifications).","NETCONF notifications - Kafka","API","Added subscription API to install-node request - 'stream' container. Example (subscription to 2 NETCONF streams - ‘NETCONF' and 'system’):","Added root list 'netconf-subscription' which contains all active subscriptions.","Corresponding YANG model:","Configuration","Provided initial configuration that can put into lighty-uniconfig-config.json:","Uniconfig-client","Example:"]},{"l":"Dynamic configuration of Kafka brokers","p":["Location of Kafka brokers and other Kafka settings must be configurable using RESTCONF API.","Persistence of this configuration in the database. All UniConfig instances must use same settings.","Option to change/read these settings using CRUD RESTCONF operations.","Configuration that is placed in the configuration file must be used only as initial configuration.","API","RESTCONF API used for reading and modification of all Kafka settings is described by following YANG model:"]},{"i":"installationuninstallation-of-multiple-devices-in-one-rpc","l":"Installation/Uninstallation of multiple devices in one RPC","p":["Added RPCs for installation or uninstallation of multiple devices in the single RPC call. The advantage of this approach in comparison to install-node/uninstall-node RPC is that UniConfig can schedule installation tasks in parallel.","Up to 20 devices can be installed at once.","API","Added RPCs into connection-manager YANG module:"]},{"l":"Added list of node-ids into snapshot-metadata","p":["Added list of node-ids, that are inside particular snapshot, into snapshot-metadata.","API","Added ‘nodes' leaf-list (’snapshot-manager.yang'):"]},{"i":"api","l":"\uD83D\uDCBB API","p":["Added following element into calculate-diff RPC output:","Added checkForReferences query parameter.","Default value is false - if it is set to 'true', then validation is done before application of modification into data-tree."]},{"l":"Introduction of transaction idle-timeout","p":["Idle timeout is more useful/practical than existing ‘absolute’ timeout, especially for long-running workflows - it will minimise the chance that transaction will be dropped after some operation started.","Transaction idle timer is refreshed after transaction is retrieved from registry (-> at invocation of some operation from RESTCONF).","Timed-out transaction is cleaned using existing cleaner.","Idle timeout is configurable only globally (config file).","Absolute timeout is not removed - it coexist with added idle-timeout."]},{"i":"configuration-1","l":"Configuration","p":["Updated configuration section in lighty-uniconfig-config.json- added 'transactionIdleTimeout’ property:"]},{"l":"Install-node RPC","p":["Added new parameters (uniconfig-config:crypto) into install-node RPC:","'uniconfig-config:crypto' - It allows to specify path to public key on device - ‘public-key-path’ (leaf with RFC-8040 path) and cipher type (by default, RSA is used) - ‘public-key-cipher-type’. If path to public key is specified and it exists on device, then Global-device encryption model is used. Otherwise, Global-only encryption model is selected.","'netconf-node-topology:yang-module-capabilities' - If auto-loading of YANG module with encrypted paths is not used and device itself doesn’t specify encrypted leaves, then it is necessary to side-load YANG module with encrypted paths. This parameter is relevant only on NETCONF nodes. Side-loaded modules must be expressed in the format of NETCONF capabilities."]},{"i":"configuration-2","l":"Configuration","p":["Global RSA key-pair is stored inside PEM-encoded files in the ‘rsa’ directory under UniConfig root. Name of the private key must be ‘encrypt_key’ and name of the public key must be ‘encrypt_key.pub’. If user doesn’t provide these files, UniConfig will automatically generate its own key-pair with length of 2048 bits. All UniConfig instances in the cluster must use the same key-pair.","Encryption settings are stored in the ‘config/lighty-uniconfig-config.json’ file under ‘crypto’ root object.","'encryptExtensionId' - If this setting is not defined, then encryption is disabled despite of other settings or install-node parameters. The value must have the format [module-name]:[extension-name] and specifies extension used for marking of encrypted leaves/leaf-lists in YANG modules. Corresponding YANG module, that contain this extension, can be part of device/unistore YANG schemas or it can be side-loaded during installation of NETCONF device as imported module from ‘default’ repository.","'netconfReferenceModuleName' - Name of the module for which NETCONF client looks for during mounting process. If UniConfig finds module with this name in the list of received capabilities, then it uses its revision in the lookup process for correct YANG module with encrypted paths (using deviations).","'netconfEncryptedPathsModuleName' - Name of the module which contains deviations with paths to encrypted leaves/leaf-lists. There could be multiple revisions of this file prepared in the ‘default’ NETCONF repository. NETCONF client in the UniConfig chooses the correct revision based on ‘netconfReferenceModuleName’ setting. Together, ‘netconfReferenceModuleName’ and ‘netconfEncryptedPathsModuleName’ can be used for auto-loading of encrypted paths for different versions of devices."]},{"l":"Uniconfig-client API","p":["Added InstallDeviceWithEnabledEncryption example:"]},{"i":"supported-ordered-listleaf-list-operations-restconf--netconf","l":"Supported ordered list/leaf-list operations (RESTCONF & NETCONF)","p":["RESTCONF RFC-8040 supports 2 additional query parameters for PUT and POST methods - ‘insert' and 'point’, see:","RFC 8040 - section 4.8.5","RFC 8040 - section 4.8.6","Using these parameters, it is possible to place list entry to specific position in the list. The 'insert' query parameter can be used to specify how an item should be inserted within an list or leaf-list. The 'point' query parameter is used to specify the insertion point for an item that is being created or moved within an 'ordered-by user' list or leaf-list. Like the 'insert' query parameter.","In the NETCONF client, UniConfig uses edit-config 'insert' attribute to put list entry to the specific position, see:","RFC 6020 - YANG"]},{"l":"API","p":["Introduction of schema for keeping information about the latest YANG repository identifier.","It is configurable using RESTCONF."]},{"i":"introduction-of-rename-patch-operation","l":"Introduction of 'rename' patch operation","p":["This PATCH operation can be used for changing values of one/multiple keys that identify some list entry. In the RESTCONF API it was not possible to directly update values of keys.","New PATCH operation with identifier 'rename'.","‘target’: identifier of original list entry","'point': new identifier of list entry"]},{"l":"Separate UniConfig errors to more type","p":["Updated 'frinx-type' YANG module (previously there were processing-error and no-connection error types)."]},{"i":"implementation-of-rfc-8072-patch-operation-1","l":"Implementation of RFC-8072 PATCH operation","p":["Example:"]},{"i":"added-missing-protocols-to-l2-for-ios-xe-cli-units-1","l":"Added missing protocols to L2 for IOS XE (cli-units)","p":["Added enumerations into 'frinx-cisco-if-extension' YANG module (openconfig):"]},{"l":"YANG packager","p":["implemented tool for validation and loading of YANG repository","API:","User can find corresponding script it in the utils/ directory (part of distribution).","Script './convertYangsToUniconfigSchema' contains four arguments. Each one has its own identifier so user can use any order of arguments.","Two arguments are required, namely the path to resources that contain YANG files and the path to the output directory where user wants to copy all valid YANG files. Other three arguments are optional. First one is the path to the \"default\" directory which contains some default YANG files, second one is the path to the \"skip-list\" and last one is a \"-to-file\" flag, which user can use when he wants to write a debug output to file.","-i /path/to/sources - required argument. User has two options for where the path can be directed:","to the directory that contains YANG files and other sub-directories with YANG files","to the text-file that contains defined names of directories. These defined directories have to be stored on the same path as text-file.","-o /path/to/output-directory - required argument. User can define path where he wants to save valid YANG files. Output directory must not exist.","-d /path/to/default - optional argument. Sometimes some YANG files need additional dependencies that are not provided in source directories. In this case it is possible to use path to the 'default' directory which contains additional YANG files. If there is this missing YANG file, YANG packager will use it.","-s /path/to/skip-list - optional argument. User can define YANG file names in text file that he does not want to include in conversion process. This file must only contain module names without revision and .yang suffix.","-to-file - optional argument. When user uses this flag, then YANG packager also saves the debug output to a file. This file can be found on a same path as 'output-directory'. It will contain suffix '-info' in its name. If the output directory is called 'output-directory', then the file will be called 'output-directory-info'."]},{"l":"UniConfig notifications about RESTCONF requests","p":["Publishing all RESTCONF traffic into PostgreSQL ‘notification' relation and Kafka 'restconf-notifications’ topic.","API","Created YANG model for RESTCONF notifications:","Configuration:"]},{"i":"bug-fixes","l":"❌ Bug Fixes"},{"l":"Fixed UniConfig rollback for CLI devices","p":["Rollback operation after failed commit, that included some CLI devices, was not working at all.","Fixed by re-implementation of the rollback process."]},{"l":"Filtering operational data from read NETCONF device configuration","p":["There are some devices that report both configuration and operational data via gRPC even if UniConfig reads only configuration data.","Fixed by explicit removal of operational data elements from read configuration before writing this configuration into database."]},{"l":"Fixed capturing of command response from Telnet session","p":["The size of internal buffer was hard-coded - now it is flexible based on number of received bytes from Telnet session. It caused trimming of command output in the execute-and-read RPC response."]},{"l":"Fixed deadlocks caused by superfluous synchronisation in transaction manager","p":["Synchronisation of component that is responsible for loading/creation/closing of transactions was unnecessary constrained - it resulted in dead-locks, especially when one UniConfig transaction was accessed asynchronously from different threads."]},{"l":"Fixed lost ordering of list elements after reading of some data","p":["If user read both ‘configuration' and ‘operational’ list elements using RESTCONF API (’content=all' query parameter), order of elements was lost during merging of these two sets.","After fix, configuration elements are displayed first, then operational-only elements are displayed."]},{"l":"Fixed interrupted ping command executed by Device Discovery service","p":["If user executed device discovery RPC with more IP addresses than the capacity of internal thread pool, some scheduled ping tasks were cancelled by timeout process.","Removed timeout from thread pool - tasks wait in the queue without time limit."]},{"l":"Fixed deadlock between transaction closing and UniConfig operation","p":["Procedure for closing transaction is called either explicitly using close-transaction RPC or automatically from transaction cleaner.","If at the same time some transaction is used in the invoked UniConfig operation, then it may lead to the deadlock - using transaction that was expired and is being closed.","Fixed by synchronisation of there events in the transaction manager."]},{"i":"get-template-info-operation-must-be-part-of-read-only-transaction-uniconfig-client","l":"Get-template-info operation must be part of read-only transaction (uniconfig-client)","p":["This operation was only part of read-write transaction."]},{"i":"when-notifications-are-enabled-uniconfig-log-is-getting-filled-with-psqlexception-continuously","l":"When notifications are enabled, uniconfig log is getting filled with PSQLException continuously","p":["Subscription table was not locked in the loop used for acquiring free subscription to NETCONF streams. Instead, pg_locks system view was locked. It led to various issues with permissions.","Fixed by not locking instances in the pg_locks view, but only instances in the subscription table."]},{"l":"Installation of device with bad password getting wrong behavior","p":["Error message was not correctly propagated into RPC install-node output.","Fixed - it will contain error message “mountpoint was not succesfully created“."]},{"l":"Fixed ignoring of unknown elements received from NETCONF device","p":["Even if ‘strict-parsing' was set ‘false’, sometimes NETCONF client didn’t ignore unknown elements that were placed under parent node of type 'list'."]},{"l":"Fixed downloading of schemas from NETCONF server running on netconf-testtool","p":["Downloading of schemas from simulated device (netconf-testtool) didn't work at all. User had to provide YANG schemas of simulated device manually to UniConfig ‘cache’ directory."]},{"l":"Fixed JSONB filtering for UniStore topology","p":["JSONB filtering feature didn’t work on configuration under unistore nodes"]},{"l":"Fixed calculate-diff RPC with updated root leaves","p":["Calculate-diff RPC failed if there were some updated/created/removed root leaves."]},{"l":"Fixed disconnecting CLI because of invalid characters in the prompt","p":["If the commands that are executed are too long, an incorrect character will appear which prevents the CLI from processing the prompt and causes the application to hang.","Fixed by ignoring of such characters during parsing of returned command prompts from device."]},{"l":"Fixed closing of UniConfig transaction after failed commit operation","p":["If commit RPC failed unexpectedly (500 status code), then UniConfig transaction was not closed and stayed hanging and blocking other transactions that would do modifications on the same nodes.","Fixed by closing UniConfig transaction always at the end of commit RPC if it was not closed by operation itself."]},{"l":"Fixed handling of incorrect input pagination parameters","p":["Returning 400 error message if input is not correctly formatted.","Example:"]},{"l":"Fixed providing of multiple slf4j bindings on classpath","p":["Keeping only one slf4j implementation on classpath, so there aren’t any conflicts."]},{"l":"Stop closing of configuration mode in the UniConfig shell after each commit operation","p":["State before:","State after:"]},{"l":"Fixed writing of augmentation data at commit operation to southbound layer","p":["This is a regression introduced during implementation of “validation” and “confirmed commit” features. Fixed by wrapping of augmentation nodes to non-mixin parent containers."]},{"l":"Fixed validate RPC output with empty input","p":["After modification of multiple nodes in the transaction, validate RPC with empty input:","Returns back only:","But it must contain all modified nodes."]},{"l":"Fixed ordering of entries in the transaction-log","p":["Committed transactions must be sorted by time when transaction was committed. Previously, the order was random."]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements"},{"l":"Removed old draft-02 RESTCONF implementation","p":["We stopped using old RESTCONF implementation.","Only new RESTCONF RFC-8040 is supported."]},{"i":"configuration-3","l":"Configuration","p":["Removed “jsonRestconfServiceType“ setting from “lighty-uniconfig-config.json”:"]},{"l":"Removed option to turn off transactions","p":["This setting was confusing, because turned on transactions still support both immediate-commit-model and build-and-commit models."]},{"i":"configuration-4","l":"Configuration","p":["Removed “uniconfigTransactionEnabled“ from configuration file:"]},{"i":"improved-invalid-nesting-of-data-error-message","l":"Improved 'Invalid nesting of data' error message","p":["This error occurred without and descriptive message, if user put some list without specification of correct brackets in the input JSON body.","Improved error message - it points to the place/element at which error occurred (parent element)."]},{"l":"Removed AutoSyncService","p":["This component was responsible for automatic reading of some configuration after pushing configuration to device.","However such process was not very visible to user, it could cause issues - we decided to remove it, so similar functionality must be implemented on application layer."]},{"l":"Specification of default directory in the YANG packager utility","p":["The packager script expected to have ‘default’ as the name of the default directory. It must be able to accept any file name after -d parameter."]},{"i":"separate-uniconfig-errors-to-more-type-1","l":"Separate UniConfig errors to more type","p":["Introduction of more granular error types that are returned in the response messages of UniConfig RPC operations.","User should be able to identify in what component/layer of UniConfig, the error occurred."]},{"i":"enabledisable-notifications-per-topic","l":"Enable/disable notifications per topic","p":["Previously it was only possible to enable/disable notifications globally (all topics).","Added option per topic to enable/disable notifications.","Added 3 new leaves that are placed under “kafka-settings“ container","API","Confiruration","Initial configuration can be specified from lighty-uniconfig-config.json file:"]},{"l":"Renamed elements in notification system","p":["Goal - improved readability.","subscription list → netconf-subscription","topic name restconf-notifications → audit-logs","API","Updated subscription list and YANG module name:","Renamed restconf-notifications module:","Updated topic name for RESTCONF notifications:","Configuration","Updated topic name and corresponding field name:"]},{"l":"Removed AAA","p":["Removed AAA code from UniConfig.","AAA was used for:","RESTCONF authentication (basic) - not needed, it can be provided by application gateway","encryption in NETCONF - moved corresponding functionality to NETCONF module","user identification - not needed, this functionality will be covered by tracing logs","API","Removed “user-id“ from “audit-logs“ module:","Removed “username” from “transaction-log” module:"]},{"i":"uniconfig-shell-ability-to-configure-multiple-leafs-with-single-set-operation","l":"UniConfig shell: Ability to configure multiple leafs with single SET operation","p":["If there are multiple leaves under same container/list, user should be able to configure them in the single command line.","API:","Sample YANG model:","Commands for setting client-alive-interval and client-alive-count-max:","New approach:"]},{"l":"Removing unused UniConfig monitoring system","p":["Removing of following field from UniConfig instance DB relation - backup-instance.","Removing periodical monitoring of UniConfig instances (component in the UniConfig layer) and taking leadership over nodes in the cluster.","Removing unused DB business API services that were used in the [1] and [2].","Configuration","Before changes:","After changes (removed multiple settings):"]},{"l":"Removed old UniStore implementation","p":["UniStore was previously implemented separately from UniConfig. Now it is integrated into UniConfig with distinct topology identifier 'unistore'."]},{"l":"Using cached thread-pool in the device-discovery service","p":["There was a fixed thread-pool that kept all the threads open all the time.","Using cached thread-pool with a small initial thread amount and higher max thread amount e.g. CPU_COUNT * 8."]},{"i":"configuration-5","l":"Configuration","p":["Added “maxPoolSize“ setting to configuration file:"]},{"i":"display-only-sub-structure-with-show-command-in-uniconfig-shell","l":"Display only sub-structure with \"show\" command in UniConfig shell","p":["Before patch:","After patch (just displaying what's there inside settings/system accordingly):"]},{"l":"Providing default UniStore node id in the UniConfig shell","p":["When we create a new UniStore node we manually had to give it a node-id. Say, we are configuring ssh now, it needs to be a generic command which doesn't expect the node-id to be given by the user.","Before patch ('new' is the node identifier):","After patch:","Configuration:","Default UniStore node identifier can be configured in the lighty-uniconfig-config.json (default value is 'system'):"]},{"l":"Removed unused Maven plugins","p":["Removed unused Maven plugins that are executed during build process and thus making building longer."]},{"l":"Removed AspectJ from UniConfig","p":["AspectJ makes code more error-prone and complex for debugging - removed usage of this library in the RESTCONF and dependencies."]},{"i":"documentation-additions","l":"\uD83D\uDCDC Documentation additions"},{"i":"validation-of-leaf-refs-1","l":"Validation of leaf-refs","p":["Validation of leaf-ref YANG constraints that are affected by some create/delete/update operation:","leafref-validation"]},{"l":"idle-timeout","p":["Introduced transaction idle-timeout","Updated configuration section in ‘“lighty-uniconfig-config.json” - added 'transactionIdleTimeout’ property:"]},{"l":"Encryption","p":["UniConfig uses asymmetric encryption for ensuring confidentiality of selected leaf and leaf-list values."]},{"i":"insert--point","l":"Insert & Point","p":["RESTCONF RFC-8040 supports 2 additional query parameters for PUT and POST methods - ‘insert' and 'point’"]},{"l":"Hashing","p":["UniConfig supports 'iana-crypt-hash' YANG model for specification of hashed values in data-tree using type definition 'crypt-hash'."]},{"l":"Templates","p":["Added information about usage of the templates"]},{"i":"rename-patch-oper","l":"Rename patch oper.","p":["This PATCH operation can be used for changing values of one/multiple keys that identify some list entry.","Rename"]},{"l":"Kafka clustering","p":["Random distribution of subscriptions to NETCONF notifications streams and turning on/off UniConfig instances may lead to scenario when one of the UniConfig instances in the cluster contain most of the subscriptions while others unequally smaller number."]},{"l":"YANG Patch","p":["Invocation of PATCH that may contain multiple edits."]},{"i":"uniconfig-whitelist-1","l":"UniConfig whitelist","p":["List of root YANG entities that should be read. This parameter has effect only on NETCONF nodes.","Whitelist"]},{"i":"yang-packager-1","l":"YANG Packager","p":["Implemented tool for validation and loading of YANG repository"]},{"l":"Install multiple nodes","p":["Added RPCs for installation or uninstallation of multiple devices in the single RPC call. The advantage of this approach in comparison to install-node/uninstall-node RPC is that UniConfig can schedule installation tasks in parallel.","Uninstall multiple nodes"]},{"l":"Snapshot-metadata","p":["Added list of node-ids, that are inside particular snapshot, into snapshot-metadata."]}],[{"i":"uniconfig-429","l":"UniConfig 4.2.9"},{"l":"UniConfig","p":["[BUG FIXES]","[IMPROVEMENTS]","[NEW FEATURES]","added GNMi southbound protocol","added node list into snapshot-metadata - it contains information about nodes that are captured using snapshot - documentation: https://docs.frinx.io/frinx-uniconfig/UniConfig/user-guide/uniconfig-operations/snapshot-manager/obtain_snapshot_metadata/obtain-snapshot-metadata.html","don't fail dry-run commit if there aren't any changed nodes","fixed behaviour of validate RPC","fixed calculate-diff with changed root leaf","fixed calculate-diff: uniconfig-native branch didn't work fine with updated leaf nodes under choice nodes","fixed comparison and updating of configuration fingerprints(synchronization issues between DB and UniConfig cache)","fixed DeviceDiscovery: parsing of NULL hostname","fixed displaying whole list content using UniConfig shell","fixed dry-run commit - it closed transaction if list of target nodes was empty","fixed replace-conf-with-oper - NullPointerException","fixed transaction leak (CLI shell)","fixed using of UniConfig on machines with less than 4 CPU cores","get-template-info RPC: showing information about all variables in specified template","implementation of git-like diff that shows diff output with git-like marks - documentation: https://docs.frinx.io/frinx-uniconfig/UniConfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_calculate-git-like-diff/calculate-git-like-diff.html","implemented RPC to verify install status for a set of node-ids - documentation: https://docs.frinx.io/frinx-uniconfig/UniConfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_check_installed_devices/check-installed-devices.html","improved apply-template RPC: added type safety - application of value to variable with specified type","install-multiple-nodes / uninstall-multiple-nodes (RPC) - option to install/uninstall multiple devices using one request - documentation: https://docs.frinx.io/frinx-uniconfig/UniConfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_install_multiple_nodes/install-multiple-nodes.html","introduced unistore topology for storing settings / 'dummy' device configuration - supported commit (persistence of unistore nodes), replace-config-with-oper, and calculate-diff operations - documentation: https://docs.frinx.io/frinx-uniconfig/UniConfig/user-guide/uniconfig-operations/unistore-api/unistore.html","logging of transaction ID","UniConfig shell - prompt user for commit if they leave config mode after changes were made"]},{"l":"CLI","p":["[NEW FEATURES]","logging CLI request and responses (logging broker) - documentation: https://docs.frinx.io/frinx-uniconfig/UniConfig/user-guide/operational-procedures/logging/logging.html#cli-messages","[BUG FIXES]","fixed closing of CLI mountpoint created using lazy CLI strategy","fixed propagation of error message from mount process into install-node RPC output"]},{"l":"RESTCONF","p":["[NEW FEATURES]","immediate commit model - automatic creation of new transaction per user request - documentation: https://docs.frinx.io/frinx-uniconfig/UniConfig/user-guide/uniconfig-operations/immediate-commit-model/immediate-commit-model.html","support HTTP2 on server side","[BUG FIXES]","fixed displaying of candidate nodes from non-existing augmentations","fixed unclosed/leaked UniConfig transaction","fixed parsing of multi-level fields query parameter","[IMPROVEMENTS]","making module-name prefix optional in value of fields query parameter"]},{"l":"NETCONF","p":["[NEW FEATURES]","exposed strictParsing parameter into NETCONF mountpoint - ignoring unknown elements received from NETCONF server - documentation: https://gerrit.frinx.io/c/Frinx-docs/+/11724","sorting of list elements by one or multiple fields - documentation: https://docs.frinx.io/frinx-uniconfig/UniConfig/user-guide/uniconfig-operations/restconf/restconf.html#sorting","[IMPROVEMENTS]","reducing logs generated by NETCONF cache loader","updated naming of pagination query parameter"]},{"l":"TRANSLATION-UNITS-FRAMEWORK","p":["[IMPROVEMENTS]","sending list size hint to translation unit writers"]},{"l":"CONTROLLER","p":["[IMPROVEMENTS]","logging creation/closing of UniConfig transaction","removed transaction-log limit from database","[BUG FIXES]","handling of errors that occur in readers/writers","fixed reading snapshot-metadata from database","fixed JSONB filtering: parsing of embedded paths"]},{"l":"SWAGGER","p":["[NEW FEATURES]","added option to ignore config nodes in order to produce oper only documentation","added range constraints to leaves","enable Maven swagger generator for uniconfig native models","[IMPROVEMENTS]","removed swagger path generator for old restconf","[BUG FIXES]","fixed description generator for leaves"]},{"l":"NETCONF TRANSLATION UNITS","p":["[BUG FIXES]","re-enabled XR-6 models","fixed XR-6 interface configuration writer (MTU)","[IMPROVEMENTS]","decreased surefire heap to 2G","optimization: stop recreation of NetconfAccessHelper","set max heap to 4G when running unit-tests to avoid outOfMem exception when running tests"]},{"l":"CLI TRANSLATION UNITS","p":["[Huawei]","created units: login banner, HTTP commands, sysname command, VLAN, telnet and ssh, user-interfaces, RADIUS, QoS, ipv6 and traffic-filter commands","fixed: mounting Huawei device","[SAOS6]","created units: local/remote interfaces, deleting VLAN and physical interface","fixed: reading metadata, ordering of commands for adding network instances","improved: the way to determine if the ring is major or sub ring","[SAOS8]","fixed: reading interface sub_ports, reading metadata","[IOS/IOS-XE]","fixed: deleting all service instances, reading metadata, prefix-lists with 0 entries not reconciled ipvpn, handling invalid MTU value, parsing ACL set"]}],[{"i":"uniconfig-428","l":"UniConfig 4.2.8"},{"l":"UniConfig","p":["[NEW FEATURES]","UniConfig shell: basic CRUD operations (configuration/operations mode), RPC calls, YANG actions.","Validate RPC: validation of NETCONF configuration by target device.","Device discovery RPC: searching for open TCP/UDP ports on target hosts ICMP reachability.","[IMPROVEMENTS]","Simplification of UniConfig RPCs in the transaction: RPCs(is-in-sync, commit, checked-commit, replace-config-with-operational, calculate-diff, sync-from-network, dryrun-commit) should work now with empty input. If the input is empty, operation will be invoked on all touched nodes.","[FIXES]","Unified representation of empty snapshot metadata - it will return 404.","Propagation of southbound error message to Uniconfig layer after failed installation."]},{"l":"CONTROLLER","p":["[NEW FEATURES]","Auto-generation of local UniConfig instance name, if it is not set in the configuration file.","[FIXES]","Fixed persistence of templates: fixed extraction of node-id from path.","Fixed omitting of module-name from URI: skip openconfig/native-CLI augmentations from created UniConfig-native schema.","Fixed parent module lookup when resolving leafrefs- parent module was mapped not to parent, but the submodule itself.","Fixed parsing of source-ids from YANG files- don't inherit revision from parent module.","[IMPROVEMENTS]","Improved error message on failed building of schema context.","Optimized YANG schema cache: Removed in-memory schema cache listener that was caching bulky AST form of all sources. Caching of them is not valuable anymore because there is only 1 schema context per device-type."]},{"l":"SWAGGER","p":["[FIXES]","Removed trailing slash from generated URIs (conforming RFC-8040 format).","Fixed importing of 4.0.0-alpha-1-SNAPSHOT (maven-core).","[IMPROVEMENTS]","Stop emitting operational nodes in swagger.","Adding snapshots-metadata and tx-log to generated swagger-api."]},{"l":"CLI","p":["[FIXES]","Fixed initialization of SSH session: Enforced following order of messages in SSH client - Protocol (SSH-2.0-APACHE-SSHD-2.4.0), Protocol (SSH-2.0-Cisco-1.25), Key Exchange Init, Key Exchange Init(some devices don't accept switching Protocol and Key Exchange Init messages).","Fixed setting infinite number of reconnection attempts."]},{"l":"NETCONF","p":["[NEW FEATURES]","NETCONF PKI data persistence: persistence of crypto information in the file-system.","[FIXES]","Capturing error message from SSH session initialization process.","Fixed setting infinite number of reconnection attempts.","Fixed self-reconnection of NETCONF session (issue with keepalive timer).","Fixed netconf testtool in mdsal-persistent-mode - do not share Datastore across all devices.","Fixed overwriting IETF schemas by UniConfig shcemas in netconf-testtool.","[IMPROVEMENTS]","Removed unused netconf-ssh classes.","Improving the way of printing NETCONF reconnection attempts.","Testtool: Enable manipulation of operational data over NETCONF."]},{"l":"RESTCONF","p":["[NEW FEATURES]","Pagination: get-count, limit, and start-index query parameters.","[FIXES]","Fixed adding schema-respoitory parameter to PATCH operation.","Fixed serialization of identityref key value."]},{"l":"CLI TRANSLATION UNITS","p":["[FIXES]","[IMPROVEMENTS]","[NEW FEATURES]","Huawei: Add caching for \"display current-configuration\" command.","Huawei: created TU for AAA.","Huawei: created TU for ACL.","Huawei: created TU for physical, VLAN interfaces, sub-interfaces.","Huawei: created TU for trunk and access VLANs.","Huawei: Read interfaces of Huawei devices with \"display interface brief\".","Huawei: Updated parsing of output for L3-VRF.","IOS XE: Fixed missing some information about route maps for IOS.","IOS XE: Fixed sending \"dot1q 1-4094\" to IOS XE devices.","SAOS6: All interfaces cannot be marked as Ethernet.","SAOS6: Changed name for l2vlan interface to \"cpu_subintf_\" l2vlan name.","SAOS6: Fixed creation of sub-port on EthernetCsmacd interfaces.","SAOS6: Reading all interfaces from ciena devices using command\"interface show\"."]},{"l":"NETCONF TRANSLATION UNITS","p":["[FIXES]","Fixed importing ietf-inet-types - there are multiple revisions available in the UniConfig.","[IMPROVEMENTS]","Speed up device model build by disabling various maven plugins."]},{"l":"OPENCONFIG","p":["frinx-huawei-network-instance-extension - added network-instance extension.","frinx-saos-if-extension - added ipv4 and ipv6 address extension.","frinx-cisco-if-extension - the dot1q value type is changed from int to string and the range is saved as a string.","frinx-acl-extension - ACL for huawei devices","frinx-openconfig-aaa, frinx-openconfig-aaa-radius, frinx-openconfig-aaa-tacacs, frinx-openconfig-aaa-types, frinx-huawei-aaa-extension - added aaa and radius modules from openconfig.","frinx-huawei-if-extension - added yang for huawei interface and sub-interface extensions.","frinx-openconfig-bgp-types, frinx-openconfig-extensions -fixed bug with community set values."]}],[{"i":"uniconfig-427","l":"UniConfig 4.2.7"},{"l":"Uniconfig","p":["[FIXES]","[IMPROVEMENTS]","[NEW FEATURES]","Added UniConfig transaction-id as fingerprint for devices not supporting it.","Adjusted persistence of mount information - node with the same ID may be present in both CLI/NETCONF topologies - and node only from one topology at the same time can be used for installation on UniConfig layer (configuration is synced and parsed).","Changed native-CLI architecture - UniConfig calls native-CLI readers/writers directly using BI API - BA translation layer provided by Honeycomb is redundant.","Fixed calculate-diff - Removing the whole list node with all list entries.","Fixed commit output: if the configuration of one of the nodes fails at any phase, then the outputs for all nodes will always contain a rollback flag.","Fixed creation/removal of dry-run Unified mountpoint - synchronization problems.","Fixed dry-run commit - Dry-run commit should trash journal of nodes that haven't been 'touched'.","Fixed losing of some tags in DOM nodes (application of template)","Fixed reading of uniconfig-native flag - unboxing of null Boolean to boolean.","Fixed rollback operation after commit/checked-commit.","Fixed sync-from-network for unavailable nodes - Comparison of config fingerprints failed for nodes that are unavailable because reading of fingerprint failed.","Fixed transfering of template tag from template to uniconfig topology at apply-template RPC (it should not happen).","Fixed version-drop in copy RPC.","Fixed writing ordered-map nodes during string substitution process(application of template).","Handling reordering of list entries in the calculate-diff - instead of sending delete+replace operations to the southbound layer.","Implementation of get-installed-nodes RPC: used for listing installed UniConfig nodes.","Implementation of revert-changes RPC: reverting transaction that is stored in transaction-log and identified by unique UUID.","Implementation of transaction-tracker (transaction-log): tracking of successfully committed data.","Improved error messages - using serialized form of YangInstanceIdentifier in logs or error messages, if possible.","Improved error messages during application of template.","Improving the existing algorithm that collapses diff from honeycomb(parallel streams).","Integration of fingerprint validation to templates - writing of fingerprint of modified templates to database and verification of fingerprint before commit.","Introduction of install-node, uninstall-node, mount-node, and unmount-node RPCs - a new way to install nodes into UniConfig with split concepts of installation and mounting. Mounting is always done on demand and the mountpoint is alive as long as some transaction is using this mountpoint.","Introduction of UniConfig transactions - dedicated/shared transactions concept: multiple users can use UniConfig safely from isolated transactions. UniConfig RPCs are part of UniConfig transactions - information about transaction-id is passed from the RESTCONF layer into the UniConfig layer.","Making UniConfig instance stateless - data is separated from UniConfig (PostgreSQL database) and UniConfig doesn't keep persistent connection to devices. Data and connection recovery is not done by UniConfig instances anymore (coordination, monitoring, and recovery process is not orchestrated by UniConfig). From the view of data-tree, UniConfig is used only as a cache layer on top of PostgreSQL database and caching is done only in the scope of transaction.","Mark sync operation failed on empty config.","Removed data-tree cache layers on CLI and NETCONF layers - UniConfig directly writes data to CLI/NETCONF mountpoints - it simplifies syncing process too.","Removed snapshot limit - it is not used anymore since snapshots are stored in the database and this database should manage its storage limits.","Removed unused Karaf features.","UniConfig shell prototype: SSH server, RPC operations, simple read operation.","Using commit RPC for committing snapshots and templates.","Using distributed advisory locks provided by PostgreSQL for locking of UniConfig nodes during commit/checked-commit operation. If another transaction perfors commit at the same time, it will fail before execution of the second commit.","Validation of conflicts between different transactions: added data-tree and config fingerprint validation before commit / checked-commit RPC invocation."]},{"l":"Controller","p":["[FIXES]","[IMPROVEMENTS]","[NEW FEATURES]","Added synchronization when generating BA->BI codecs.","Added workaround for 'metadata not available' data-tree bug.","Allow positional information in YangInstanceIdentifier (useful for operations under ordered lists).","Allow users to specify attributes without module-name (template tags).","Breaking PUT modifications to specific modifications in the data-tree: improving 'optimistic lock' granularity.","Ensuring parents by merge: avoiding ridiculous errors when data-tree allows to write data to nodes which parent is missing.","Exposed simple container merge utility.","Extending RPC service by custom parameters that can be passed from RPC caller to RPC implementation.","Fixed creation of DocumentedException from XML (document may include redundant namespaces).","Fixed data-tree modifications: merge->put->delete operation chain.","Fixed disappeared tag from template data-tree.","Fixed leaked DB connection on health-check operation.","Fixed order in which database writers are called (adding priority to DatabaseWriter API).","Fixed race-conditions in 3-phase datastore commit.","Fixed searching for fallback context on nodes that were not mounted(uniconfig-native).","Fixed storing of the default schema repository into PostgreSQL.","Generalisation of NETCONF repository into YANG repository.","Implemented standalone DOM broker - stopping to use clustered/distributed DOM brokers.","Integration of Flyway library to Uniconfig: easier upgrading of database schema and migration of data.","Integration of JSONB filtering of configuration on the level of DAOs.","Integration of UniConfig transaction manager with database and datastore transactions - used for management of shared/dedicated transactions.","Introduction of embedded PostgreSQL for testing purposes - it can be enabled from the UniConfig configuration file.","Making the database layer more thread safe (using 'SELECT FOR UPDATE' in some queries).","Optimized creation of uniconfig-native schemas.","Persistence of logging configuration in PostgreSQL.","Persistence of snapshots in PostgreSQL.","Persistence of templates in PostgreSQL.","Persistence of transaction-log in PostgreSQL.","Preserving order of list/leaf-leaf elements in the data-tree.","Removed unnecessary dependencies of xtend maven plugin.","Removed unused Karaf features.","Replaced asynchronous DB API by synchronous DB API - JDBC connections are synchronous.","Separated persistence of UniConfig nodes and representing mountpoints.","Stop submitting datastore transactions - it must be closed - datastore is used only as cache.","Validation and locking of templates and UniConfig nodes on the level of UniConfig transaction."]},{"l":"Swagger","p":["[FIXES]","Fixed bug caused by swagger-uniconfig-go.","[IMPROVEMENTS]","Make openAPI generated for uniconfig more useful.","Added Unified layer models to swagger dependencies."]},{"l":"Translation units framework","p":["[NEW FEATURES]","Added native-CLI binding-independent API.","[IMPROVEMENTS]","Removed unused artifacts.","Optimized chunk cache - do not store entire writer in chunk cache, so GC can take care of writers as soon as possible.","Detection of complex reordering of list entries in diff output.","[FIXES]","Fixed commit rollback failing: the bug was caused by an attempt to execute an inverse command of an unsuccessful command."]},{"l":"CLI","p":["[IMPROVEMENTS]","Removed unused Karaf features.","Exposed binding-independent data support to native-CLI API.","Exposed services for direct device access to MP.","[FIXES]","Replace maxConnectionAttempts with maxReconnectionAttempts when reconnecting to the device after the first connection attempt is successful.","Replaced transactionChain (not working correctly) with direct dataBroker transactions.","Fixed device type checking - when a device was mounted with the wrong type, the generic symbol (\"\") was implicitly used as the type. The device was installed on all layers, but uniconfig/configuration was empty. Now we have to use correct device type or.","Fixed disabled CLI journaling (default value)."]},{"l":"NETCONF","p":["[NEW FEATURES]","Added maxReconnectionAttempts functionality into NETCONF client.","[IMPROVEMENTS]","Removed unused Karaf features.","Improved error message from parsing of NETCONF RPC response.","Removed akka actor dependency from NetconfCacheLoader.","Enable md-sal persistence accross sessions in NETCONF testtool.","[FIXES]","Fixed writing of netconf namespace prefix ('Namespace urn:ietf:params:xml:ns:netconf:base:1.0 was not bound, please fix the caller').","Fixed reading of the whole list/leaf-list from the device - it was reading the whole parent structure, not only the dedicated list.","Moving state to unable-to-connect after failed schema context building from device YANGs.","status is written to datastore, because mount-node RPC relies on OPER information only.","Fixed deadlock that may occur on removal of Unified MP."]},{"l":"RESTCONF","p":["[NEW FEATURES]","Added support for RESTCONF PATCH method that includes tags.","Integration of UniConfig dedicated/shared transaction to RESTCONF - cookie with transaction-id property, create-transaction RPC, and close-transaction RPC.","Introduction of jsonb-filter query parameter used for filtering of data committed to database.","[IMPROVEMENTS]","Removed unused Karaf features.","Using RFC8040 format for errors thrown from the transaction system.","[FIXES]","Fixed RESTCONF response/request logging.","Fixed reading of all available RPC operations.","Fixed NPE that is caused by Subject.getPrincipal() - extraction of authentication data from AAA.","Fixed serialization of ordered leaf list with attributes.","Fixed connection leak - read-only transaction was not always closed.","Fixed parsing of elements without module name: If there are some conflicts between children elements - multiple elements with the same name but in different modules exist - then we should return a proper error message.","Fixed use of fields query parameters with uniconfig-native nodes."]},{"l":"NETCONF translation units","p":["[IMPROVEMENTS]","Removed unused Karaf features.","[FIXES]","Fixed writer dependency in XR623 ISIS translation unit.","Ignored 'ios-xr lacp period 200' command - only 'lacp period short' is supported."]},{"l":"CLI translation units","p":["[FIXES]","[IMPROVEMENTS]","[NEW FEATURES]","Huawei: additions - global config reader and writer for bgp, neighbor config reader and writer, new augmentation fields for global and neighbor configurations.","Huawei: translation units - interfaces.","IOS XE: added ios-xe 15 and 17 to ios-xe module.","IOS XE: additions - media-type command, port-security commands, BDI type recognition, ethernet cfm mip command, cft commands, commands for bgp, prefix-list command, fhrp delay, bfd-template, split-horizon group in bridge-domain, added fallOverMode for vrf neighbor, IPv6 prefix-lists with prefix lengths, routing-policy, ipv6 vrrp, added synchronization and moved default-information in BGP, table-map, ip community-list command, redistribute command, bgp and interface commands, ipv6 commands, rewrite command, snmp trap, support for multiple l2protocols,.","IOS XE: created a distinct module for IOS-XE in cli-units.","IOS XE: fixed writing interface config, fixed unwanted lldp/cdp/switchport vlan commands commands, fixed IPv6 config writer template, fixed mounting of IOS XE (configuration metadata), fixed bridge-domain regex, fixed reading VLANs, fixed storm-control regex, fixed NPE in GlobalAfiSafiConfigWriter, fixed BgpAfiSafiChecks, fixed CommunityListConfigReader and L3VrfReader, fixed IndexOutOfBoundsException in BgpActionsConfigReader.","IOS XE: make sure all 'GigabitEthernet' interfaces are treated as physical, don't send unnecessary commands in interface unit, only send storm-control commands when needed, moved service instances and encapsulation in service instance in ios-xe/interface, edit readers and writers for bridge-domain, edited LLDP to not parse when default is set, speed up mounting","IOS XE: translation units - SNMP, LACP, privilege command, interfaces, l2protocol, evc, route-map, bgp and network-instance modules, vrf definition, fhrp version, ip commands, neighbor, ethernet cfm mip, negotiation auto.","IOS-XR: delete methods should always be readBefore, fixed calling get on a null value, fixed delete of mpls-te.","Movef service-policy from IOS/interface to IOS/QoS.","Removed unused Karaf features.","SAOS6: fixed virtual-circuit ethernet delete, fixed reading Virtual Ring data, fixed reading the range of vlans in virtual ring commands, reading default interface.","SAOS6: translation units: Ingress ACL.","SAOS6: use the same template for service as for profile schedulers.","SAOS6/8: added quotes into description.","SASO6: additions - commands for delete untagged attributes, unset description command, parsing ranges in ring protection.","SONiC: created init and interfaces unit."]},{"l":"Openconfig","p":["created frinx-openconfig-evc module","created frinx-privilege module","fixed Openconfig bug with nested augmentations (fixed resolving augmentations path)","frinx-bfd-extension: bfd-template-config","frinx-bgp-extension: added bgp extension for Huawei device, local-as-group, route-maps in redistribute commands, BGP neighbor, table-map in BGP, synchronization and moved default-information in BGP, added bgp fall-over mode, neighbor as-override, default-information originate,","frinx-cisco-if-extension: added negotiation auto, added support for multiple l2protocols, added support for rewert commands, vrf forwarding, ip commands, fixed L2protocol description, split-horizon group in bridge-domain, chaed bridge-domain type to string, fhrp delay, fixed bad order of augmentation in frinx-cisco-if-extension.yang, bridge-domain, added grouping for L2protocol for Service instance, added grouping for L2protocol for Service instance, move encapsulation in service instance, move service instances, created augmentation for service instances, cft cisco specific commands, added port-security,","frinx-cisco-ipvsix-extension: added yang extension for global ipv6 commands.","frinx-cisco-routing-policy-extension: prefix lengths in prefix-list, sequence-id, forwarding-action, route-map","frinx-cisco-vrrp-extension: added ipv6 vrrp augmentation, added vrrp-group augmentation,","frinx-oam: added ethernet cfm mip","frinx-openconfig-bgp-policy-extension: added community-list type,","frinx-openconfig-bgp-types: extracted typedefs for community union type.","frinx-openconfig-fhrp: fhrp version","frinx-openconfig-lacp: added ON lacp mode","frinx-qos-extension: moved service-policy from IOS/interface to IOS/QoS","frinx-snmp: added snmp-view config","removed unused Karaf features from openconfig"]}],[{"i":"uniconfig-426","l":"UniConfig 4.2.6"},{"i":"uniconfig","l":"UniConfig:","p":["new feature: introduced 3-phase commit - integration of validation and confirmed-commit features - here","new feature: templates can be used for reusing of some configuration and afterwards easier application of this configuration into target UniConfig nodes - storing of templates in UniConfig, modification of templates including tags using RESTCONF operations, and application of templats to target UniConfig nodes using apply-template RPC","new feature: added copy-subtrees RPCs - merge or replace whole subtrees: copy-one-to-one, copy-one-to-many, copy-many-to-one","new feature: added calculate-subtree-diff RPC - calcution of diff between two subtress in datastore","new feature: implemented uniconfig healthcheck - RPC checks UniConfig and database connection","fixed auto-sync service","fixed creation of Unified mountpoint for CLI device without available translation units - using only 'generic' units in this case"]},{"i":"controller","l":"CONTROLLER:","p":["improvement: removed 'native_prefix' from 'node' database relation - it is replaced by NETCONF repository name","fixed MDSAL union codec - it didn't work with boolean subtype"]},{"i":"cli","l":"CLI:","p":["fixed unmounting of CLI device: the case when mounting process hasn't successfully finished yet"]},{"i":"netconf","l":"NETCONF:","p":["new feature: NETCONF validate RPC and confirmed-commit RPC exposed by extension of DOM transaction","improvement: mounting NETCONF device with explicitly set NETCONF repository name that must be used - using this approach, it is not necessary to explicitly override/merge capabilities in the mount request - here","improvement: replacing uniconfig-native fingerprint by'schema-cache-directory' in NETCONF operational data","fixed mounting SROS device with specified ignoreNodes/namespaceBlacklist - here","fixed: unmounting of NETCONF device which mounting process hasn't finished yet","fixed: increased maximum NETCONF chunk size to 32*1024*1024"]},{"i":"restconf","l":"RESTCONF:","p":["new feature: introduced 'uniconfig-schema-repository' query parameter - explicitly set name of the schema using which input/output data is validated","new feature: JSON attributes - option to encode XML-like attributes into JSON structure: - here"]},{"i":"cli-translation-units","l":"CLI TRANSLATION UNITS:","p":["IOS: fix - QoS translation unit, added port-channel into interface type","IOS: added translation units - storm-control, standard ACL","IOS: refactoring - allowed vlans on trunk interface","SAOS: fixed translation units - statistics augmentation, command ordering, ethernet config reader/writer, ordering of VLAN and VC, order of CPE commands","SAOS: fixed initialization - committing configuration during initialization"]},{"i":"openconfig","l":"OPENCONFIG:","p":["frinx-acl-extension: added support for standard ACL","moved statistics from frinx-saos-vlan-extension to frinx-saos-vc-extension","frinx-cisco-if-extension: added storm control","frinx-qos-extension: extended and fixed support for IOS QoS"]},{"i":"known-issues","l":"Known Issues:","p":["The error message needs to be fixed to inform user about the name clash and how to fix it","ODL did not started if cache folder for SROS16 device is applied","BGP: NullPointerException occurs when configure network instances for XE","NETCONF: Junos 18 is can't be mounted by netconf Xrv6.2.3 device has been locked and session went down after specific set of commands","CLI: Performance issues when is more than 400 devices connected","RPC: Commit and Checked commit issues when invalid configuration has been applied to one router Transaction has been locked during checked commit no rollback when invalid configuration has been configured to one router"]}],[{"i":"uniconfig-425","l":"UniConfig 4.2.5"},{"i":"uniconfig","l":"UniConfig:","p":["new feature: show-connection-status RPC: it can be used for verification of status of selected nodes on CLI, NETCONF, Unified, and Uniconfig layers - here","new feature: filtering of data that is read from NETCONF mountpoint based on YANG extension that can be placed in the mount request ('uniconfig-config:extension' parameter) https://docs.frinx.io/frinx-odl-distribution/oxygen/user-guide/network-management-protocols/uniconfig_mounting/mounting-process.html#example-mounting-of-uniconfig-native-netconf-device","new feature: is-in-sync RPC: verification if UniConfig Operation datastore is in sync with device - here","new feature: introduced 'install-uniconfig-node-enabled' mount request parameter - option to not install node in the Unified and UniConfig layers - node would be installed only in the southbound layer - here","new feature: introduced uniconfig-native translation units used for reading and parsing of only configuration fingerprint","improvement: calculate diff for uniconfig-native nodes diff output shows difference also on the level of leaves and leaf-lists(better granularity)","fixed setting of maximum snapshot limit (passing 0 in input)","fixed uniconfig-native - mounting node using CLI and afterwards using NETCONF uniconfig-native didn't work as expected","fixed caching of read operational data: improved performance for nodes that are mounted via NETCONF translation units"]},{"i":"cli","l":"CLI:","p":["new component: creation of CLI flavour for SAOS devices for successfull reading and parsing of device configuration","new component: \"one-line-parser\" CLI parsing engine that uses grep function for parsing running-configuration","fixed synchronization of UniConfig operations (for example, commit RPC) and CLI RPCs (for example, execute-and-read)"]},{"i":"netconf","l":"NETCONF:","p":["new feature: added support for invocation of YANG 1.1 actions and TAILF actions - here","new feature: NETCONF edit-config test option - controlling validation of sent edit-config messages on NETCONF server - here","new feature: introduced 'default' NETCONF cache repository that can be used for side-loading of missing/fixed YANG schemas that are invalid/not provided by NETCONF device - here","new feature: introduced logging of whole NETCONF communcation - per-device NETCONF messages, notifications, and system events - here","improvement: added NETCONF cache directory (NETCONF repostory) into Operational datastore of NETCONF node","fixed authentication in NETCONF testtool (key-pair provider)","fixed parsing of NETCONF replies that contains multiple RPC errors(severity of error was not correctly considered)","fixed creation of NETCONF mountpoint - it was not blocking, so higher layers haven't caught events in the correct order","fixed loading of NETCONF cache repository into Operational datastore","synchronization issues","fixed propagation of user-friendly error messages from NETCONF layer into UniConfig RPC output"]},{"i":"restconf","l":"RESTCONF:","p":["new feature: subscription to NETCONF device notifications via websockets - here","new feature: invocation of YANG 1.1 actions and TAILF actions - here","new feature: invocation of PLAIN PATCH operation - here","new feature: schema filtering based on YANG extensions and deprecated YANG statement - reading and modification of data - here","new feature: introduced logging of whole RESTCONF communcation with option to hide fields with selected YANG type - here","improvement: improved RESTCONF error messages in case of invalid URI - displaying possible children nodes","fixed reading of whole list under augmentation/choice node"]},{"i":"controller","l":"CONTROLLER:","p":["new feature: introduced PostgreSQL persistence system for UniConfig nodes: persisting node configuration and NETCONF repositories into DBS with recovery system in the cluster - here","upgrade: using TrieMap dependency for data-tree implementation"]},{"i":"distribution","l":"DISTRIBUTION:","p":["added support for Java 11: compilation of all projects using JDK 11 and also running of UniConfig distribution using JRE 11","fixed invocation of UniConfig with \"--help\" argument","changed logging framework from log4j to logback","added \"--debug\" parameter for opening debug session"]},{"i":"translation-units","l":"TRANSLATION UNITS:","p":["fixed invocation of subtree writers based on wildcard path"]},{"i":"netconf-translation-units","l":"NETCONF TRANSLATION UNITS:","p":["XR6: added L3VPNIPV4UNICAST afi-safi type","XR6: fixed BGP neighbor reader","JUNOS17: fixed LACP units"]},{"i":"cli-translation-units","l":"CLI TRANSLATION UNITS:","p":["SAOS: create readers and writers for logical-ring","SAOS: fixed sending of commit command, parsing of port range, dependencies between writers, parsing of connection point key, interface subport writer, registering of interface writer, hardening update commands, L2VSICP writer, getAllIds in PortReader","IOS: added translation units: QoS, interface statistics, service-policy, VLAN, routing-policy","IOS: modified translation units: added next parameters into BGP, switchport mode options: dot1q && access, BGP neighbor version, SPEED parameter, ICMP type into ACL entry","IOS-XR: fixed LACP bugs: 'mode on' configuration is now explicit, subinterfaces were wrongly added to list of LAG interfaces","Arista: added init unit","Cubro: added CLI flavour"]},{"i":"openconfig","l":"OPENCONFIG:","p":["frinx-qos-extension: added support for CoS and DSCP in QoS","frinx-cisco-if-extension: added switchport mode options: dot1q, access","frinx-bgp-extension: added BGP neighbor version support","frinx-if-ethernet-extension: added interface SPEED parameter","frinx-cisco-if-extension: added port-type, snmp-trap-link-status, switchport-mode, switchport-access-vlan, switchport-trunk-allowed-vlan-add, ip-redirects, ip-unreachables, ip-proxy-arp, service-policy","created SAOS model extension (frinx-saos-virtual-ring-extension)","created Cisco BGP model extension (frinx-cisco-bgp-extension)","fixed frinx-bgp-extension YANG","fixed auto-generated yang docs"]},{"i":"known-issues","l":"Known Issues:","p":["The error message needs to be fixed to inform user about the name clash and how to fix it. ODL does not start if cache folder for SROS16 device is applied","BGP: - NullPointerException occurs when configure network instances for XE","NETCONF: - Junos 18 is can't be mounted by netconf - Xrv6.2.3 device has been locked after specific set of commands","CLI: - Performance issues when is more than 400 devices connected"]}],[{"i":"uniconfig-424","l":"UniConfig 4.2.4"},{"i":"uniconfig","l":"UniConfig:","p":["Added uniconfig node status- each node is in one of these states: installing, installed, failed","Added unified node status- each node is in one of these states: installing, installed, failed","bugfixing"]},{"l":"UniConfig Native","p":["UniConfig Native for CLI- new experimental feature allowing to communicate with devices in a native way using hand-written YANG models","Added sequence-read-active param- this forces UniConfig to read root configuration elements sequentially."]},{"l":"CLI","p":["Introduced RPC execute-and-expect- It is a form of the‘execute-and-read’ RPC that additionally may contain ‘expect(..)’ patterns used for waiting for specific outputs/prompts. It can be used for execution of interactive commands that require multiple subsequent inputs with different preceding prompts.","Introduced Tree-parser as CLI parsing strategy- device configuration is parsed into a tree. It provides faster lookup operations for reads.","Introduced native CLI- feature allows to define YANG models instead of translation units. YANG models need to be created based on device specific CLI commands"]},{"l":"OpenConfig","p":["added various extensions for Ciena TUs"]},{"l":"NETCONF","p":["bugfixing"]},{"l":"Translation units","p":["Added CLI translation units for Ciena SAOS6 and SAOS8","bugfixing"]}],[{"i":"uniconfig-423","l":"UniConfig 4.2.3"},{"i":"uniconfig","l":"UniConfig:","p":["create Lighty based distribution- removal of Apache Karaf altogether, this distribution is based on lighty.io","RPC input/output rework","Unification of RPC inputs/outputs","Prevent any network wide operations if no node id has been passed- All RPCs MUST specify node-id of nodes they are affecting","new UniConfig transactions- create-transaction, cancel-transaction are used in HA deployments","bugfixing"]},{"l":"UniConfig Native","p":["separate schema contexts based on device type- it allows to mount devices with same YANG models but different revisions"]},{"l":"Lighty","p":["adding of AAA support","adding of TLS support"]},{"l":"RESTCONF","p":["update to RFC-8040 based RESTCONF- only this version runs by default","usage of schema context based on device type for data parsing","creation of custom UniConfig JSON/XML parsers/serializers"]},{"l":"OpenConfig","p":["added models: ipsec, frinx-if-ethernet-extension","added various extensions for Brocade TUs"]},{"l":"NETCONF","p":["run-time loading of netconf cache repositories","division of netconf cache based on device type","creation of schema context from netconf-cache","bugfixing"]},{"l":"Translation Units","p":["bugfixing"]},{"l":"Known Issues","p":["JSON response for GET snapshots of UniConfig-native nodes contain generated prefix \"uniconfig--\" (e.g. native-529687306-Cisco-IOS-XR-ifmgr-cfg:interface-configurations). This issue does not have an impact on RPC replace-config-with-snapshot."]}],[{"i":"uniconfig-508-release-notes","l":"Uniconfig 5.0.8 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Created TU for Arris(CER) device","Install-node without mounting/syncing configuration from device","Option to divide OpenAPI files into modules"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Uniconfig-client: increased default HTTP response read timeout","Fixed NETCONF connection timeout","Fixed number of NETCONF reconnection attempts","Fixed waiting for NETCONF dry-run mountpoint","Fixed reading of default NETCONF parameters","Added 'get-template-info' RPC to oper mode (shell)","Huawei install DB parsing issue","Fixed memory visibility issues in MountpointRegistry","Fixed parsing junos xml configuration","Fixed parsing xml configuration with reordered lists items","Fixed list of available RPCs in UniConfig Shell"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Optimization of calc-diff RPC after replace-config-with-oper RPC","Install-node without mounting/syncing configuration from device improvements","Added missing attributes to SAOS6 Interface","Remove OSS index checks from owasp","Generate release notes during merge job"]}],[{"i":"uniconfig-509-release-notes","l":"Uniconfig 5.0.9 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implemented dedicated device sessions","Implementation of device locking states","Implementation of speed attribute for saos6 and saos8 (#21)","Expose kafka producer settings into java client","Added option to use list key delimiter in URI","Implementation of pm instances for port queue groups in saos8 (#11)","Expose kafka producer settings","Implementation of default vlans for saos6 (#10)","Implementation of auto-neg attribute for both saos6 and saos8 (#9)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed ordering of data inside transaction on SONiC device","Fix ignoring empty key","Fix serialization of keyDefinitions","Cleaned and fixed locking of nodes in uniconfig RPCs","Fixed generation of NETCONF message-id","Fixed JSOB filtering - creation of jsonpath and parsing output"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Updated writer template for saos6 and saos8 (#32)","Implementation of speed attribute for saos6 and saos8 (#21)","fix showing list entries in cli suggestions"]}],[{"i":"uniconfig-5010-release-notes","l":"Uniconfig 5.0.10 Release Notes"},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed removing native prefix from snapshots (#57)","Fixed parsing GNMi GET response (augmentation content)","Fixed parsing result from immediate-commit model","Fixed lost list ordering after apply-template RPC"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Add a parameter so empty GET response returns 204"]}],[{"i":"uniconfig-5011-release-notes","l":"Uniconfig 5.0.11 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Remove namespace from response (#77)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["uc shell: update simple value and list value simultaneously","uc shell: transaction log ordering","VHD-162 Fixed Issue with With-Defaults param. (#68)","Serialization of int64, uint64, decimal types as string type","Changed order of executing remove and add vlans for saos6 (#75)","Fixed NETCONF reconnection attempts after connection timeout","Removed parent-node-id from NETCONF layer","Fixed synchronization of NETCONF session timeout"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Fixed ordering of data inside transactions for SONiC device","Implementation of common commands of relay agent for saos8 (#78)","Implementation of common commands of relay agent for saos6 (#70)","UC shell: autocompletion of nodes (#36)","Fix parallelism in apply-template RPC (#73)","Implementation of relay-agent sub-port command for saos8 (#47)","Changed default value of content query parameter to 'config'","Add sshd package to logback.xml with INFO level (#67)"]}],[{"i":"uniconfig-5012-release-notes","l":"Uniconfig 5.0.12 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Inclusion of unhide query parameter in PUT/POST/PATCH requests","Sync-to-network RPC"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Swagger - remove input container (#113)","Fix unhide param for write operations","Fixed default value of speed in ios (#95)","Changed isEmpty to null check (#96)","Fixed default value of speed in ios-xe (#88)"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Swagger - Fix authorizations (#114)","change behavior of execute-and-expect RPC (#112)","Swagger - configurable description and toggle servers","Enabled TCP keepalive mechanism in JDBC connection","Added 'database-connection-client-port' to 'transactions-data'","Swagger - generating adjustmens","Using hideEmptyDataNodes parameter per request (#94)","updated write template of interface config for ios xe devices for use-cases where no changes are requested from the user (#91)","Improve schema context caching for gnmi devices"]}],[{"i":"uniconfig-5013-release-notes","l":"Uniconfig 5.0.13 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Add jsonb-filter in UC client","Automation of adding release notes to documetation","API for bulk addition of templates","Implementation of callbacks","Implementation of publishing shell notifications to kafka","JSONB filtering core","Upgrade-from-network as part of sync-from-network"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Cancellation of initial NETCONF RPCs after request timeout","Fixed parsing XML-endoded leaf with instance-identifier to list","Fixed synchronization of notification listeners","Releasing subscription that is bound to tangling mountpoint","Fixed construction of output with set with-defaults param","Fix gnmi unknown augmentations"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Implementing HideAttributes query-parameter per request. - Introduced query parameter HidesAttribute. Default value is 'false'. Hides all composite data-tree nodes attributes to the GET response.","Stop acquiring subscription that was released in the same iteration","Fixed and refactored DOMMountPointService implementation","Add support for template leaf hashing","Improved code and API of create-multiple-templates RPC","Implemented frinx-types:json-element in the JSON deserializer","Swagger - Grouping requests","Swagger - Remove patch operation","Bump Mockito and get rid of Powermock","Swagger: inclusion of action endpoints","YangPackager does not catch broken submodules","Refresh schema context for netconf southbound if device was upgraded","Make mountpoint service call listeners from different thread"]}],[{"i":"uniconfig-5014-release-notes","l":"Uniconfig 5.0.14 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Added a flag to disable confirmed-commit phase in commit RPC (#181)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Adding 'rsa_' prefix to encrypted data","Changed the way to get config metadata for ios xe devices","Disable html escaping in callbacks output","Fix adding release notes to documentation repository","Fix Flyway when using SSL encryption","Fix of incorrect UC behavior when on limit with DB connections","Fix parsing of sslPassword parameter","Fix setting of DbConnectionConfig parameters","Fixed creation of aug with admin-state leaf","Fixed detection and recovery from cyclic dependency error in YANGs (#161)","Fixed duplicate module lookup in path deserializer (RESTCONF) (#150)","Fixed encryption (#170)","Fixed parsing NETCONF action response","Fixed recovery of Cipher object","Fixed SAOS Qos TU writer","Jsonb-filter multiple schemas bugfix","Make tailf:info revision independent","Updated config metadata pattern in reader for ios xe devices (#174)"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Internal delete for trunk-vlans","JSONB-filter improvement"]}],[{"i":"uniconfig-5015-release-notes","l":"Uniconfig 5.0.15 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implementation of bulk-edit RPC"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixes for trunk-vlans handling"]},{"i":"api","l":"\uD83D\uDCBB API","p":["Defined API for bulk-edit RPC"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Do not use common fork join pool in DOMMountpointService"]}],[{"i":"uniconfig-5016-release-notes","l":"Uniconfig 5.0.16 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Added create-multiple-templates RPC to uniconfig-client","Added option to specify tags in create-multiple-templates RPC","Swagger: Grouping of RPCs and tailf:actions","Encrypt/Decrypt of password for gnmi/netconf/cli topologies"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Data-change-events: make node-id optional","Displaying the default unistore node in shell for callbacks","Fix Guava dependency in POM","Fix replace-list ordering","Fix using ignoredNamespaces from swagger-config","Fixed merging template tags into merge node in the same TX","Fixed parsing nodes with attributes","Fixed regex for trimming path in TransactionTrackerUtils (#241)","Fixed submitting changes to database if there are failed nodes and do-rollback is false (#227)","Fixed writing of unkeyed list entry node","Remove duplicate yang models","Removed non-working option to create unistore node in request and show states","Revert \"Install-node without mounting/syncing configuration from device\"","Swagger - fix list container wrapping","Swagger: Fix behavior of basePath and server generation","Swagger: Fix top level containers not generating","Wrap requests to make them RFC 8040 compliant"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Adjusted logging of keepalive messages (stream sessions)","Made amount of max parallel installs customizable (#204)","Made error message user-friendly when user enter nonexistent node-id","Make create-multiple-templates RPC 'atomic'","Mapped \"gig\" to SpeedType.Gigabit","Netconf rpc timeout (#257)","Optimization of callbacks","Refactored stream writers used by RESTCONF","Removed last pieces of CheckedFuture and old unused MDSAL-API","Removed unused jettison dependency","Replaced CheckedFuture by FluentFuture - DOM read transaction","Replaced CheckedFuture by FluentFuture - DOM store read transaction","Replaced CheckedFuture by FluentFuture - DOMRpcImplementation","Replaced CheckedFuture by FluentFuture - DOMRpcService","Replaced CheckedFuture by FluentFuture: TX submit()","Resolving CVE security issues between level 6 and 0","Set UNICONFIGTX cookie to entire domain not just /rests/","Specified create/close-transaction RPCs in YANG","Support upgrading of YANG repository content (#233)","Suppress CVE-2022-38752","Suppressing logs generated by received unknown requests (SSH)","Used FluentFuture in binding ReadTransaction"]}],[{"i":"uniconfig-5017-release-notes","l":"Uniconfig 5.0.17 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Swagger - filter path CRUD customization","Implemented invalid schema repository cleaner","Units-coverage RPC"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Commit fails if one of the touched node was uninstalled","Swagger - fix CRUD filter generation","Triggered commit hook if revert is successful","Fixed decryption of passwords in CLI layer (#301)","Add support for fetch=count with jsonpath filtering (#282)","Fix suppressed Jackson CVEs","Bump Apache commons-text to 1.10.0","Swagger - Fix GET operation generation for list nodes","Bump protobuf-java to 3.21.7","Changed order of executed commands for saos8 (#280)","Additional fix for dce global subscription in client.","Improve JSON parser error message","Changed the way of getting vlan name and egress-tpid","Localhost throws 500","Swagger: Fix operational API generation"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Replacing parallelStreams with more predictable alternatives","Swagger - add option to disable GET request generation for concrete list nodes","Add request timeout to gnmi session","Create modulesWithIgnoredNamespace list","Support install-multiple-nodes for gnmi","Swagger: Add content query parameter"]}],[{"i":"uniconfig-5018-release-notes","l":"Uniconfig 5.0.18 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implemented TU for collecting all the information in NTP MCS for Saos6 and Saos8 (#420)","Implemented low priority fields for collecting inventory for SAOS6 CEN(ring) (#341)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Swagger: Fix generation of arguments in path","Fixed cleanup of existing MP during mount-node RPC","Swagger: fix generation of choice nodes","Fixed encryption of sensitive info passed via template variables (#326)","fix Jsonb filter element filtering","Swagger - Fix request generation","Fixed passing leaf-list in shell callbacks"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Fix Logback and cleanup POMs","Swagger: Custom operational path","Improved reporting of parsing issues in RESTCONF","Swagger - Improve start file","Changed order of some commands for SAOS8 (#348)","Swagger: generate augmentations in respective modules","Expose request-timeout parameter","Bump dependency-check to 7.3.0","readEntireConfig toString returns plain content","Reading mount configuration in the uniconfig-client"]}],[{"i":"uniconfig-5019-release-notes","l":"Uniconfig 5.0.19 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Fixed hardcoded part and added one more if condition to receiver transceiver data for IOS-XE (#493)","Stable XR6 XR66 devices (#471)","Implementation of storing failed installations into DB (stable 5.0.x)","Implemented TU for adding/removing users for Saos6 (#438)","Implemented TU for collecting transceiver information for IOS-XE (#439)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Downgraded sshd to 2.8.0","Fix uninstall -> install transition","Swagger: fix generation of operational APIs (5.0.X)","Fix CVEs","Fixed reading public key from NETCONF device (NPE)","Fixed distribution of mount failure from GNMi layer","Swagger: Fix path filtering"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["expose gnmi parameters","add overallStatus to multiple-nodes-rpc-output","Improved error message when connection cannot be created","Exposed DOMMountPointService configuration","Optimization of mountpoint notifications","Added logs into DOM Mountpoint Service"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Configurable re-sending cli commands","Fixed mount point creation for CLI topology","Removed unified-topology.yang","Refactored unified layer and mounting/unmounting process - updates","Refactored unified layer and mounting/unmounting process","Added logging level for shell to the logback.xml"]}],[{"i":"uniconfig-5020-release-notes","l":"Uniconfig 5.0.20 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Support for GetInstalledNodes in UC client - 5.0.x","Add getJSONOutput to UniConfig client","Added some commands for collecting data for IOS-XE (#515)","Skip unreachable nodes at commit"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed leafref version-drop","Suppress Netty FP CVEs","Fixed quit command in the shell","Fixed pattern handling and XPath extension parsing","Fixed parsing of seconds in XR native metadata unit","Swagger: fix generation of action nodes (5.0.X)","Swagger: fix no key lists generation (5.0.X)","Fixed locking of nodes from TX with enabled dedicated sessions (#523)","Fix bug in bulk edit operation","Swagger: fix generation of operation children from config container"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Change overallStatus when skiping unreachable nodes","handle user parameters input in GnmiDefaultParametersService","Removed 'reconcile' mountpoint parameter (#572)","Disable verification of supported query parameters (5.0.x) (#549)","Swagger: toggle generation of POST apis for containers","Bulk-edit rpc improvements"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Swagger: fix npe in custom operational path (5.0.X)","Added only-vlan parser, upgraded trunk-vlans for huawei (#528)","Callbacks authentication"]}],[{"i":"uniconfig-5021-release-notes","l":"Uniconfig 5.0.21 Release Notes"},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Add migration for removing node-extension:reconcile"]}],[{"i":"uniconfig-5022-release-notes","l":"Uniconfig 5.0.22 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["make replace request on correct node for gnmi","Add GetTemplateNodes RPC and add support to Client","Implemented some new commands for Huawei TU (#580)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed encryption of leaves marked using deviations","Fix vulnerabilities by changing base docker image","Stop cleaning YANG repos associated to persisted nodes","Swagger: fix actions using custom operational path","Suppressed CVE-2021-4277 (#612)","Fix CVE-2021-37533"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Swagger: mandatory indicator","Improved registration of unexpected YANGs downloaded from device","Add compare-config RPC.","Changed logging level: Unable to map identifier to capability","Skipping unknown fields in GET request","Added an RPC input to enable error handling for execute-and-read RPC (#662)","Fetch Kafka settings to client.","add gnmi protocol to get-installed-nodes RPC","Swagger: add drop-down for topology-id parameter"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["PUT and DELETE operations for callbacks"]}],[{"i":"uniconfig-5023-release-notes","l":"Uniconfig 5.0.23 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implementation of RPD TUs for CER(Arris)","Implementation of Cable-Mac Oper TUs for CER(Arris)","Replace paths feature","Implementation of cable-upstream TUs for CER(Arris)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Added new control to check if cached prompt is invalid (#809)","Fixed writer of cable upstream interface","Added new control to check if cached prompt is invalid (#633)","Fix delete request in replace-paths","Fixed schema context building","Java based migration for huawei config","Bulk-edit - removed the version comparison before version drop procedure","Bump dependencycheck.version, update suppress for CVE-2022-41915, CVE-2022-41881"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Swagger: regular expressions with example values","Extended TreeConfigParser to handle arris device's behavior for cable-upstreams","Change isInstalled method implementation in uniconfig-client","JRE-17 compatibility","Added read option to bulk-edit RPC","Bump sshd to 2.9.2","Prefer 'latest' repository in latest repository update process","Change status code if transaction is not valid. (#711)"]}],[{"i":"uniconfig-5024-release-notes","l":"Uniconfig 5.0.24 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implemented RPD related commands to fiber-node TU for Arris Commscope","Swagger: difference between OpenAPI specifications"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed RPD related writers for Arris Commscope","Fixed update templates in CableInterfaceUpstreamConfigWriter for Arris Commscope","Fixed callback leaf-list input parameter (#948)","Added a verification to check if lineIndex is lower than total number of parsed lines for multiline commands","Fixed CLI SSH KEX initialization","Fixed data decryption during apply-template RPC","Fixed regex for \"show cable modem\" command (#897)","Generate action names in java constants"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Swagger: shorter operational path"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Implementation of RPD TUs for CER(Arris) (#819)"]}],[{"i":"uniconfig-5025-release-notes","l":"Uniconfig 5.0.25 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Subtree-based resolution of conflicts between committed nodes (#989)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fix: Duplicate module name in Yang schemas","Fixed update template to update fiber node for Arris Commscope","Fixed uninstall node rpc","Fixed parsing leaf-list into JSONObject","Fixed construction of Tree (callbacks system test)","Fixed problem with re-write data of transaction by other transaction (#1032)","Fixed method to add unistore FP","Fix deriving of DB reader path","fix read only lock in uniconfig task executor (#981)","Fixed overriding of default mount settings by uniconfig-client"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["cli-shell set callback... suggest only commands that contain input body","Setting default spin/park time in notification router config","Optimised sending of internal notifications","Optimised lookup in modified uniconfig-topology & network-topology modules","Optimise detection of updated mount data in notification monitoring system","Add additional logs to precondition checks in SchemaContextUtil","Subtree-based resolution of conflicts between committed nodes (#989)","Improved the processing time of sync RPC for ios devices","Optimisation of single transaction-log entry reading","Added dedicated reader for single transaction-log entry","Add batching process for parallel reading of config"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Optimalization of handling saos devices"]}],[{"i":"uniconfig-510-release-notes","l":"Uniconfig 5.1.0 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Support for GetInstalledNodes in UC client","Add getJSONOutput to UniConfig client","Added some commands for collecting data for IOS-XE (#527)","Skip unreachable nodes at commit","Fixed hardcoded part and added one more if condition to receiver transceiver data for IOS-XE (#490)","added implementation of XR6 and XR6.6 devices as native units","Implementation of storing failed installations into DB (main)","Implemented TU for adding/removing users for Saos6 (#360)","Implemented TU for collecting transceiver information for IOS-XE (#437)","Implemented TU for collecting all the information in NTP MCS for Saos6 and Saos8 (#352)","Implemented low priority fields for collecting inventory for SAOS6 CEN(ring) (#341)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Add migration for removing node-extension:reconcile","Bump units versions to 5.1.0-SNAPSHOT","Downgraded sshd to 2.8.0","Fix : bad package for GnmiDefaultParametersService","Fix bug in bulk edit operation","Fix CVE-2021-37533","Fix CVEs","fix Jsonb filter element filtering","Fix Logback and cleanup POMs","Fix uninstall -> install transition","Fixed cleanup of existing MP during mount-node RPC","Fixed distribution of mount failure from GNMi layer","Fixed encryption of sensitive info passed via template variables (#326)","Fixed hardcoded part and added one more if condition to receiver transceiver data for IOS-XE (#490)","Fixed leafref version-drop","Fixed locking of nodes from TX with enabled dedicated sessions (#522)","Fixed parsing of seconds in XR native metadata unit","Fixed passing leaf-list in shell callbacks","Fixed pattern handling and XPath extension parsing","Fixed quit command in the shell","Fixed reading public key from NETCONF device (NPE)","Fixed reconcile SQL migration file","Fixed synchronization in datastore transaction","Stop reporting metrics into log/logs.log and stdout (#598)","Suppress Netty FP CVEs","Swagger - Fix request generation","Swagger: fix generation of action nodes","Swagger: Fix generation of arguments in path","Swagger: fix generation of choice nodes","Swagger: fix generation of operation children from config container","Swagger: fix generation of operational APIs","Swagger: fix no key lists generation","Swagger: Fix path filtering"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["add overallStatus to multiple-nodes-rpc-output","Added logs into DOM Mountpoint Service","Bulk-edit rpc improvements","Bump dependency-check to 7.3.0","Bump logback","Change overallStatus when skiping unreachable nodes","Changed order of some commands for SAOS8 (#348)","Disable verification of supported query parameters (5.1.x) (#550)","expose gnmi parameters","Expose request-timeout parameter","Exposed DOMMountPointService configuration","handle user parameters input in GnmiDefaultParametersService","Improved error message when connection cannot be created","Improved reporting of parsing issues in RESTCONF","Optimization of mountpoint notifications","readEntireConfig toString returns plain content","Reading mount configuration in the uniconfig-client","Removed 'reconcile' mountpoint parameter (#573)","Swagger - Improve start file","Swagger: Custom operational path","Swagger: generate augmentations in respective modules","Swagger: toggle generation of POST apis for containers"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Swagger: fix npe in custom operational path","Added only-vlan parser, upgraded trunk-vlans for huawei (#444)","Callbacks authentication","Configurable re-sending cli commands","Fixed mount point creation for CLI topology","Removed unified-topology.yang","Refactored unified layer and mounting/unmounting process - updates","Refactored unified layer and mounting/unmounting process","Added logging level for shell to the logback.xml"]}],[{"i":"uniconfig-511-release-notes","l":"Uniconfig 5.1.1 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["make replace request on correct node for gnmi","Implemented some new commands for Huawei TU (#580) (#639)","Add GetTemplateNodes RPC and add support to Client","Implementation of MIB parser using ANTLR grammar"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed NPE for JSONCodecFactoryLoader","Fixed deserialization of uniconfig instance record read from DB (#700)","Fixed encryption of leaves marked using deviations","Fix vulnerabilities by changing base docker image","Stop cleaning YANG repos associated to persisted nodes","Swagger: fix actions using custom operational path","Suppressed CVE-2021-4277 (#613)"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Swagger: mandatory indicator","Improved registration of unexpected YANGs downloaded from device","Add compare-config RPC.","Changed logging level: Unable to map identifier to capability","Skipping unknown fields in GET request","Added an RPC input to enable error handling for execute-and-read RPC (#668)","Fetch Kafka settings to client.","gnmi support for upgrade-from-network RPC","add gnmi protocol to get-installed-nodes RPC","Swagger: add drop-down for topology-id parameter"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["PUT and DELETE operations for callbacks"]}],[{"i":"uniconfig-512-release-notes","l":"Uniconfig 5.1.2 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implementation of RPD TUs for CER(Arris)","Implementation of Cable-Mac Oper TUs for CER(Arris)","Replace paths feature","Implementation of cable-upstream TUs for CER(Arris)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Added new control to check if cached prompt is invalid (#812)","Fixed writer of cable upstream interface","Fix delete request in replace-paths","Fixed schema context building","Changed log level in mockito-configuration to INFO","Fix wrong groupIds","Java based migration for huawei config","Bulk-edit - removed the version comparison before version drop procedure","Bump dependencycheck.version, update suppress for CVE-2022-41915, CVE-2022-41881"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Add Dependency Upgrades to release notes","Added calc-diff result to audit logs","Added read option to bulk-edit RPC","Adopt Mockito 5","Bump dependency-check, cleanup unused suppressions","Bump sshd to 2.9.2","Change isInstalled method implementation in uniconfig-client","Change status code if transaction is not valid. (#699)","Enable dependabot updates","Extended TreeConfigParser to handle arris device's behavior for cable-upstreams","Migrate codebase to Java 17 & bump dependencies & clean maven structure","Prefer 'latest' repository in latest repository update process","README - Update Running from IDE section","Remove license server","Remove license token from README.md and run_uniconfig.sh script.","Replace com.google.common.base.Optional with java.util.Optional","Swagger: regular expressions with example values","Unify antlr4 version","Update README.md running uniconfig from IDE","Updated list of supported Unicode blocks (RegexUtils)"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["Bump antlr4-maven-plugin from 4.10.1 to 4.11.1","Bump byte-buddy.version from 1.12.22 to 1.13.0","Bump commons-dbcp2 from 2.7.0 to 2.9.0","Bump commons-lang3 from 3.7 to 3.12.0","Bump disruptor from 3.3.10 to 3.4.4","Bump embedded-postgres from 1.2.10 to 2.0.3","Bump grpc.version from 1.51.1 to 1.53.0","Bump httpclient from 4.5.13 to 4.5.14","Bump jackson-bom from 2.14.1 to 2.14.2","Bump jna.version from 4.5.0 to 5.13.0","Bump maven-enforcer-plugin from 3.1.0 to 3.2.1","Bump netty.version from 4.1.86.Final to 4.1.89.Final","Bump objenesis from 2.1 to 3.3","Bump okhttp.version from 4.9.1 to 4.10.0","Bump org.eclipse.jdt.annotation from 2.1.0 to 2.2.700","Bump perfmark-api from 0.25.0 to 0.26.0","Bump properties-maven-plugin from 1.0.0 to 1.1.0"]}],[{"i":"uniconfig-513-release-notes","l":"Uniconfig 5.1.3 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Swagger: difference between OpenAPI specifications"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fix UC not starting when using standalone database - binding","Fix UC not starting when using standalone database","Fix & rewrite calc-diff to new format","Fixed regex for \"show cable modem\" command (#898)","Generate action names in java constants"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Migrate to JUnit5","Removed unused JMX classes"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Implementation of RPD TUs for CER(Arris) (#862)"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["Bump actions/setup-python from 4.3.0 to 4.5.0 (#760)","Bump actions/upload-artifact from 3.1.1 to 3.1.2","Bump annotations from 3.0.1 to 3.0.1u2","Bump antlr4.version from 4.11.1 to 4.12.0","Bump async-http-client from 1.9.24 to 1.9.40","Bump AutoModality/action-clean from 1.1.0 to 1.1.1","Bump byte-buddy.version from 1.13.0 to 1.14.0","Bump commons-cli from 1.4 to 1.5.0","Bump commons-compress from 1.21 to 1.22","Bump commons-fileupload from 1.3.3 to 1.5","Bump crypt4j from 1.0.0 to 1.0.1","Bump docker/build-push-action from 2 to 4 (#761)","Bump docker/login-action from 2.0.0 to 2.1.0 (#762)","Bump dokka-maven-plugin from 1.5.30 to 1.7.20","Bump embedded-postgres-binaries-linux-amd64 from 13.2.0 to 13.10.0","Bump embedded-postgres-binaries-linux-amd64 from 13.2.0 to 15.2.0","Bump exec-maven-plugin from 1.5.0 to 3.1.0","Bump flyway-core from 7.8.1 to 9.15.0","Bump flyway-core from 9.15.0 to 9.15.1","Bump future-converter-java8-guava from 0.3.0 to 1.2.0","Bump gson from 2.9.0 to 2.10.1","Bump jackson-databind from 2.14.1 to 2.14.2","Bump jakarta.servlet-api from 5.0.0 to 6.0.0","Bump jakarta.ws.rs-api from 3.0.0 to 3.1.0","Bump janino from 2.6.1 to 3.1.9","Bump jaxb-impl from 3.0.2 to 4.0.2","Bump jaxen from 1.1.6 to 2.0.0","Bump jersey.version from 3.0.8 to 3.1.1","Bump jetty-bom from 11.0.11 to 11.0.13","Bump jline.version from 3.21.0 to 3.22.0","Bump jmh-core.version from 1.21 to 1.36","Bump joelwmale/webhook-action from 2.1.0 to 2.3.2 (#759)","Bump jsonassert from 1.5.0 to 1.5.1","Bump junit-jupiter-api from 5.9.1 to 5.9.2","Bump ktlint from 0.24.0 to 0.31.0","Bump maven-assembly-plugin from 3.4.2 to 3.5.0","Bump maven-deploy-plugin from 3.0.0 to 3.1.0","Bump maven-failsafe-plugin from 3.0.0-M8 to 3.0.0-M9","Bump maven-invoker-plugin from 3.4.0 to 3.5.0","Bump maven-jar-plugin from 3.0.2 to 3.3.0","Bump maven-javadoc-plugin from 3.4.1 to 3.5.0","Bump maven-resources-plugin from 3.0.1 to 3.3.0","Bump maven.surefire.version from 3.0.0-M8 to 3.0.0-M9","Bump metrics-core from 4.2.12 to 4.2.16","Bump opentelemetry-api from 1.9.0 to 1.23.1","Bump postgresql from 42.5.1 to 42.5.4","Bump protobuf-maven-plugin from 0.5.1 to 0.6.1","Bump protobuf.version from 3.21.7 to 3.22.0","Bump sevntu-checks from 1.43.0 to 1.44.1","Bump spring-jdbc from 5.3.24 to 5.3.25 (#855)","Bump spring.boot.version from 2.7.6 to 2.7.8","Bump spring.boot.version from 2.7.8 to 2.7.9","Bump stax2-api from 3.1.4 to 4.2.1","Bump stCarolas/setup-maven from 4.3 to 4.5","Bump swagger-core from 2.2.4 to 2.2.8","Bump swagger-parser from 1.0.31 to 1.0.64","Bump triemap from 1.1.0 to 1.2.0","Bump truth.version from 0.36 to 1.1.3","Bump value from 2.9.2 to 2.9.3"]}],[{"i":"uniconfig-514-release-notes","l":"Uniconfig 5.1.4 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implementation of MIB repository & context","Implemented RPD related commands to fiber-node TU for Arris Commscope"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed RPD related writers for Arris Commscope","Fixed update templates in CableInterfaceUpstreamConfigWriter for Arris Commscope","Fix calc-diff when data is in LeafNode","Fix subtree calc-diff in audit log when data has not changed","Fixed callback leaf-list input parameter (#949)","Added a verification to check if lineIndex is lower than total number of parsed lines for multiline commands","Fixed CLI SSH KEX initialization","Fixed data decryption during apply-template RPC"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Swagger: shorter operational path"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump dokka-maven-plugin from 1.7.20 to 1.8.10","build(deps-dev): bump maven-plugin-annotations from 3.7.1 to 3.8.1","build(deps): bump json from 20220924 to 20230227","build(deps): bump dependency-check-maven from 8.1.0 to 8.1.2","Bump reflections from 0.9.11 to 0.10.2","Bump maven-compiler-plugin from 3.10.1 to 3.11.0","Bump jetty-bom from 11.0.13 to 11.0.14","Bump maven-plugin-plugin from 3.7.1 to 3.8.1","Bump metrics-core from 4.2.16 to 4.2.17","Bump spotbugs-maven-plugin from 4.7.3.0 to 4.7.3.2","Bump maven-dependency-plugin from 3.1.1 to 3.5.0","Bump checkstyle from 10.7.0 to 10.8.0","Bump maven-antrun-plugin from 1.8 to 3.1.0"]}],[{"i":"uniconfig-515-release-notes","l":"Uniconfig 5.1.5 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implement rate limiting (#1061)","Add DOMRpcService for gNOI","Subtree-based resolution of conflicts between committed nodes (#1008)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fix audit-log diff feature (#1056)","Fixed update template to update fiber node for Arris Commscope","Fix: Duplicate module name in Yang schemas","Fixed reading config until timeout (#1067)","Fixed uninstall node rpc","Fixed parsing leaf-list into JSONObject","Fixed construction of Tree (callbacks system test)","Fixed problem with re-write data of transaction by other transaction (#1031)","Fixed method to add unistore FP","Fix bug with audit log while calling commit RPC (#1007)","Fix deriving of DB reader path","Add missing sslpassword configuration parameter (#990)","fix read only lock in uniconfig task executor (#982)","Fixed overriding of default mount settings by uniconfig-client"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Swagger: Migrate unit tests to v3","Added topology-id to DCE notification","cli-shell set callback... suggest only commands that contain input body","Setting default spin/park time in notification router config","Optimised sending of internal notifications","Optimised lookup in modified uniconfig-topology & network-topology modules","Optimise detection of updated mount data in notification monitoring system","Add additional logs to precondition checks in SchemaContextUtil","Subtree-based resolution of conflicts between committed nodes (#1008)","Improved the processing time of sync RPC for ios devices","Optimisation of single transaction-log entry reading","Added dedicated reader for single transaction-log entry","Add batching process for parallel reading of config"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Arris CER interface bugfix (#1086)","Optimalization of handling saos devices"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump flyway-core from 9.15.1 to 9.15.2","build(deps-dev): bump flyway-core from 9.15.2 to 9.16.0 (#1012)","build(deps-dev): bump flyway-core from 9.16.0 to 9.16.1 (#1052)","build(deps-dev): bump swagger-parser from 1.0.64 to 1.0.65 (#1074)","build(deps): bump byte-buddy.version from 1.14.0 to 1.14.1","build(deps): bump byte-buddy.version from 1.14.1 to 1.14.2 (#1003)","build(deps): bump checkstyle from 10.8.0 to 10.8.1 (#988)","build(deps): bump checkstyle from 10.8.1 to 10.9.2 (#1028)","build(deps): bump checkstyle from 10.9.2 to 10.9.3 (#1073)","build(deps): bump commons-compress from 1.22 to 1.23.0 (#1059)","build(deps): bump dependency-check-maven from 8.1.2 to 8.2.1 (#1062)","build(deps): bump grpc.version from 1.53.0 to 1.54.0 (#1071)","build(deps): bump jline.version from 3.22.0 to 3.23.0","build(deps): bump maven-deploy-plugin from 3.1.0 to 3.1.1 (#1072)","build(deps): bump maven-failsafe-plugin from 3.0.0-M9 to 3.0.0 (#1011)","build(deps): bump maven-help-plugin from 3.3.0 to 3.4.0 (#1025)","build(deps): bump maven-install-plugin from 3.1.0 to 3.1.1 (#1075)","build(deps): bump maven-release-plugin from 3.0.0-M7 to 3.0.0 (#1037)","build(deps): bump maven.core.version from 3.9.0 to 3.9.1 (#1027)","build(deps): bump maven.surefire.version from 3.0.0-M9 to 3.0.0 (#1013)","build(deps): bump metrics-core from 4.2.17 to 4.2.18 (#1038)","build(deps): bump mockito-core from 5.1.1 to 5.2.0 (#987)","build(deps): bump netty.version from 4.1.89.Final to 4.1.90.Final (#1010)","build(deps): bump opentelemetry-api from 1.23.1 to 1.24.0 (#999)","build(deps): bump postgresql from 42.5.4 to 42.6.0 (#1026)","build(deps): bump protobuf.version from 3.22.0 to 3.22.1","build(deps): bump protobuf.version from 3.22.1 to 3.22.2 (#1000)","build(deps): bump spotbugs-maven-plugin from 4.7.3.2 to 4.7.3.3 (#1070)","build(deps): bump spring-jdbc from 5.3.25 to 5.3.26 (#1036)","build(deps): bump spring.boot.version from 2.7.9 to 2.7.10 (#1069)","build(deps): bump swagger-core from 2.2.8 to 2.2.9 (#1039)"]}],[{"i":"uniconfig-516-release-notes","l":"Uniconfig 5.1.6 Release Notes"},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Saos 8 command order fix.","Fixed execution order of commands for sub-port creation","Fixed a bug that causes cli closed error if config output and prompt has same length","Fix dryrun mount node task.","diff improvements (#1107)","Swagger: fix union type with patterns","Disable NETCONF level keepalive mechanism in streaming session","Fixed onEmpty section in templates for rpd ds and us conns for Arris Commscope","Fixed a bug that causes cli closed error for saos devices when commit or execute RPCs are triggered"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Refactoring ServiceInstanceWriter","Adjusted log levels of common logs","Swagger: filterPath improvement","diff improvements (#1107)","Rewrite kafka configs (#1105)"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["JSON input in Uniconfig shell problem fix","Shell logger","Create and publish Netconf test tool image to DockerHub"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump flyway-core from 9.16.1 to 9.16.3 (#1139)","build(deps): bump actions/upload-artifact from 3.1.1 to 3.1.2 (#1131)","build(deps): bump bouncycastle.version from 1.72 to 1.73 (#1138)","build(deps): bump byte-buddy.version from 1.14.2 to 1.14.3","build(deps): bump byte-buddy.version from 1.14.3 to 1.14.4","build(deps): bump grpc.version from 1.54.0 to 1.54.1 (#1134)","build(deps): bump jetty-bom from 11.0.14 to 11.0.15 (#1127)","build(deps): bump jline.version from 3.22.0 to 3.23.0 (#998)","build(deps): bump json-path from 2.7.0 to 2.8.0 (#1093)","build(deps): bump kotlin.version from 1.8.10 to 1.8.20","build(deps): bump maven-enforcer-plugin from 3.2.1 to 3.3.0 (#1114)","build(deps): bump maven-invoker-plugin from 3.5.0 to 3.5.1 (#1115)","build(deps): bump maven-resources-plugin from 3.3.0 to 3.3.1","build(deps): bump netty.version from 4.1.90.Final to 4.1.91.Final (#1113)","build(deps): bump opentelemetry-api from 1.24.0 to 1.25.0 (#1135)","build(deps): bump protobuf.version from 3.22.2 to 3.22.3","build(deps): bump spotbugs-maven-plugin from 4.7.3.3 to 4.7.3.4 (#1126)","build(deps): bump triemap from 1.2.0 to 1.3.0"]}],[{"i":"uniconfig-517-release-notes","l":"Uniconfig 5.1.7 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Lazy loading/unloading of native schema contexts (#1171)","Creation of MIB context to SchemaContext adapter (#1169)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed lazy apply-template","Fixed a bug that causes cli closed error if config output's length is less than prompt's length after config output is trimmed","Fix Swagger regex example generation","Fixed loading of schema context from swagger directory","Make request max size configurable for gnmi devices","Integrate encryption in create-multiple-templates RPC.","Fixed UniconfigTransactionsMediator initialization (#1181)","Remove TestNG (#1159)","Fix UC stuck when CPU is full and queue is empty (#1168)"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Support for gnmi in shell","Implementation of idle timeout print in CLI (#1172)","Lazy loading/unloading of native schema contexts (#1171)","Improved the processing time of sync RPC for ios/iosxe devices","Unify movement in shell (#1005)","Enabled cable-upstream writer for interfaces that has number/number/number pattern as name","Improved apply-template RPC (#1111)"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Add lazy loading to shell"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump flyway-core from 9.16.3 to 9.17.0 (#1177)","build(deps-dev): bump maven-plugin-annotations from 3.8.1 to 3.8.2 (#1152)","build(deps): bump checkstyle from 10.9.3 to 10.10.0 (#1176)","build(deps): bump jackson-bom from 2.14.2 to 2.15.0 (#1158)","build(deps): bump jackson-databind from 2.14.2 to 2.15.0 (#1153)","build(deps): bump jakarta.activation-api from 2.1.1 to 2.1.2 (#1178)","build(deps): bump jgrapht.version from 1.5.1 to 1.5.2","build(deps): bump junit.jupiter.version from 5.9.2 to 5.9.3 (#1175)","build(deps): bump kotlin.version from 1.8.20 to 1.8.21 (#1174)","build(deps): bump maven-checkstyle-plugin from 3.2.1 to 3.2.2 (#1157)","build(deps): bump maven-plugin-plugin from 3.8.1 to 3.8.2 (#1154)","build(deps): bump maven-project-info-reports-plugin from 3.4.2 to 3.4.3 (#1145)","build(deps): bump mockito.core.version from 5.2.0 to 5.3.1 (#1156)","build(deps): bump netty.version from 4.1.91.Final to 4.1.92.Final (#1173)","build(deps): bump okhttp.version from 4.10.0 to 4.11.0 (#1155)","build(deps): bump protobuf.version from 3.22.3 to 3.22.4"]}],[{"i":"uniconfig-518-release-notes","l":"Uniconfig 5.1.8 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Add change-encryption-status rpc (#1259) - UNIC-1090","Added some commands for collecting slot data for IOS-XE - VZ-734"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Swagger: Fix path filtering ignoring cruds in lists - UNIC-1315","Fix failing shell tests (#1285)","Compare decrypted strings in calculate-diff procedure (#1266) - UNIC-1173","Changed execution order of commands for CPE ZTP provision for SAOS8"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Improved error output when two transactions want to update same data … (#1238)","Swagger: Improve OpenAPI difference calculation - UNIC-1298","Provide option for reading mount-point info - UNIC-1097","Refactored InstanceIdentifierContext (#1249) - UNIC-1211","Add option to gnmi-topology to read specific data - PANT-72","Add unsuported keys for cli connection (#1203)","Add JIRA tag to release notes - UNIC-1243","Optimize LeafRef context build. - UNIC-988","Build LeafRef Tree in background. - UNIC-988","Separated reader/writer for IUCs from main classes for Arris Commscope","Unify annotation usage in uniconfig codebase","support error info (#1201) - UNIC-1136","Rewrite RestConf module DI (#1202) - UNIC-1101"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Create a new set of installation parameters"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump flyway-core from 9.17.0 to 9.19.1","build(deps-dev): bump maven-plugin-annotations from 3.8.2 to 3.9.0 (#1265)","build(deps-dev): bump swagger-parser from 1.0.65 to 1.0.66","build(deps): bump antlr4.version from 4.12.0 to 4.13.0 (#1256)","build(deps): bump build-helper-maven-plugin from 3.3.0 to 3.4.0","build(deps): bump checkstyle from 10.10.0 to 10.11.0 (#1254)","build(deps): bump checkstyle from 10.11.0 to 10.12.0","build(deps): bump embedded-postgres from 2.0.3 to 2.0.4 (#1270)","build(deps): bump embedded-postgres-binaries-linux-amd64 from 13.10.0 to 13.11.0 (#1274)","build(deps): bump git-commit-id-maven-plugin from 5.0.0 to 6.0.0","build(deps): bump grpc.version from 1.54.1 to 1.55.1 (#1199)","build(deps): bump guice.version from 5.1.0 to 7.0.0 (#1253)","build(deps): bump jackson-bom from 2.15.0 to 2.15.1","build(deps): bump jackson-databind from 2.15.0 to 2.15.1 (#1264)","build(deps): bump jersey.version from 3.1.1 to 3.1.2","build(deps): bump json-smart from 2.4.10 to 2.4.11","build(deps): bump kotlinx-coroutines-core from 1.6.4 to 1.7.0 (#1198)","build(deps): bump kotlinx-coroutines-core from 1.7.0 to 1.7.1","build(deps): bump maven-assembly-plugin from 3.5.0 to 3.6.0 (#1272)","build(deps): bump maven-checkstyle-plugin from 3.2.2 to 3.3.0","build(deps): bump maven-failsafe-plugin from 3.0.0 to 3.1.0 (#1196)","build(deps): bump maven-plugin-plugin from 3.8.2 to 3.9.0","build(deps): bump maven-remote-resources-plugin from 3.0.0 to 3.1.0","build(deps): bump maven-source-plugin from 3.2.1 to 3.3.0 (#1271)","build(deps): bump maven-surefire-plugin from 3.0.0 to 3.1.0 (#1197)","build(deps): bump maven.core.version from 3.9.1 to 3.9.2 (#1215)","build(deps): bump netty.version from 4.1.92.Final to 4.1.93.Final","build(deps): bump opentelemetry-api from 1.25.0 to 1.26.0 (#1195)","build(deps): bump protobuf.version from 3.22.4 to 3.23.0","build(deps): bump protobuf.version from 3.23.0 to 3.23.1 (#1273)","build(deps): bump spring-jdbc from 6.0.8 to 6.0.9","build(deps): bump spring.boot.version from 3.0.6 to 3.0.7 (#1269)","build(deps): bump sshd.version from 2.9.2 to 2.10.0","build(deps): bump swagger-core from 2.2.9 to 2.2.10","build(deps): bump triemap from 1.3.0 to 1.3.1"]}],[{"i":"uniconfig-519-release-notes","l":"Uniconfig 5.1.9 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["DOMDataBroker for SNMP (#1299) - UNIC-1200","UNIC-1200","Integration of southbound RESTCONF RPC service to UniConfig shell (#1310) - UNIC-1310"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fix unreachable ports for device discovery RPC - UNIC-1322","Certificate Manager servers not getting created in appliance context - fixed output - UNIC-1309","Fix removing of exception from error-info/error-message - PANT-78","Add MapNode serialization to gNMI Update - UNIC-1323"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Changeable thread parameters - UNIC-1250","Swagger: Added html output to diff generation - UNIC-1324"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump flyway-core from 9.19.1 to 9.19.4","build(deps-dev): bump swagger-parser from 1.0.66 to 1.0.67","build(deps): bump byte-buddy.version from 1.14.4 to 1.14.5","build(deps): bump commons-io from 2.11.0 to 2.12.0","build(deps): bump commons-io from 2.12.0 to 2.13.0","build(deps): bump dependency-check-maven from 8.2.1 to 8.3.1","build(deps): bump dokka-maven-plugin from 1.8.10 to 1.8.20","build(deps): bump grpc.version from 1.55.1 to 1.56.0","build(deps): bump guava.version from 31.1-jre to 32.0.0-jre","build(deps): bump guava.version from 32.0.0-jre to 32.0.1-jre","build(deps): bump jackson-bom from 2.15.1 to 2.15.2","build(deps): bump jackson-databind from 2.15.1 to 2.15.2","build(deps): bump jaxb-runtime from 4.0.2 to 4.0.3","build(deps): bump kafka-clients from 3.4.0 to 3.4.1","build(deps): bump kafka-clients from 3.4.1 to 3.5.0","build(deps): bump kotlin.version from 1.8.21 to 1.8.22","build(deps): bump maven-dependency-plugin from 3.5.0 to 3.6.0","build(deps): bump maven-failsafe-plugin from 3.1.0 to 3.1.2","build(deps): bump maven-project-info-reports-plugin from 3.4.3 to 3.4.4","build(deps): bump maven-project-info-reports-plugin from 3.4.4 to 3.4.5","build(deps): bump maven-release-plugin from 3.0.0 to 3.0.1","build(deps): bump maven-surefire-plugin from 3.1.0 to 3.1.2","build(deps): bump metrics-core from 4.2.18 to 4.2.19","build(deps): bump opentelemetry-api from 1.26.0 to 1.27.0","build(deps): bump protobuf.version from 3.23.1 to 3.23.2","build(deps): bump swagger-core from 2.2.10 to 2.2.11","build(deps): bump swagger-core from 2.2.11 to 2.2.12","build(deps): bump truth.version from 1.1.3 to 1.1.4"]}],[{"i":"uniconfig-5110-release-notes","l":"Uniconfig 5.1.10 Release Notes"},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Get API returns 3 response for single request (#1396) - VHD-324","Fixed too long error output in NETCONF LOG message - UNIC-649","UNIC-1319 Issue with Netconf install WorkFlow - fix logs for testing workflows - UNIC-1319","Upgrade Template didn't load repository - UNIC-1334","Save yang repository in transaction - VHD-324"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["store netconf keys in db (#1380) - VHD-326","maven cleanup (#1379) - UNIC-1291","Removed unused code from sal-dom-spi and dependencies","Extract shell actions to use RestconfDOMActionService (#1346) - UNIC-1313"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Parse and fill datastore with initial JSON file in MDSAL mode"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump flyway-core from 9.19.4 to 9.20.0","build(deps): bump actions/setup-python from 4.5.0 to 4.6.1","build(deps): bump bouncycastle.version from 1.73 to 1.74","build(deps): bump bouncycastle.version from 1.74 to 1.75","build(deps): bump checkstyle from 10.12.0 to 10.12.1","build(deps): bump commons-codec from 1.15 to 1.16.0","build(deps): bump docker/login-action from 2.1.0 to 2.2.0","build(deps): bump grpc.version from 1.56.0 to 1.56.1 (#1390)","build(deps): bump guava.version from 32.0.1-jre to 32.1.1-jre (#1388)","build(deps): bump janino from 3.1.9 to 3.1.10 (#1389)","build(deps): bump json from 20230227 to 20230618","build(deps): bump maven-clean-plugin from 3.2.0 to 3.3.1","build(deps): bump maven-invoker-plugin from 3.5.1 to 3.6.0","build(deps): bump maven-shade-plugin from 3.4.1 to 3.5.0","build(deps): bump metainf-services from 1.9 to 1.11 (#1375)","build(deps): bump mockito.core.version from 5.3.1 to 5.4.0","build(deps): bump netty-handler in /commons/parents/odlparent","build(deps): bump spotbugs-maven-plugin from 4.7.3.4 to 4.7.3.5","build(deps): bump spring-jdbc from 6.0.9 to 6.0.10","build(deps): bump spring.boot.version from 3.0.7 to 3.0.8","build(deps): bump sshd.version from 2.9.2 to 2.10.0 (#1251)","build(deps): bump swagger-core from 2.2.12 to 2.2.14","build(deps): bump truth.version from 1.1.4 to 1.1.5"]}],[{"i":"uniconfig-5111-release-notes","l":"Uniconfig 5.1.11 Release Notes"},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Swagger: Fix generation of operational data from Uniconfig schemas (#1444) - UNIC-1280","Fixed unmounting of node that is in connecting state - UNIC-1281"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Changing use case of prompt stylization - UNIC-977","Enabling and cleaning up SHELL checkstyles (#1451) - UNIC-1345","Unifying, renaming and increasing readability of UC-shell - UNIC-977","Add mutable transaction to Shell (#1399) - UNIC-1312","Swagger: Unit tests - UNIC-1186","Removed sal-common-impl module","Merged mdsal-dom-spi to sal-dom-spi module (5.1.x) (#1417)","add ValueCase to gnmi codec - UNIC-1113"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Read All data type on specific paths"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump org.apache.kafka:kafka-clients from 3.5.0 to 3.5.1 (#1476)","build(deps): bump maven.core.version from 3.9.2 to 3.9.3 (#1358)"]}],[{"i":"uniconfig-5112-release-notes","l":"Uniconfig 5.1.12 Release Notes"},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["fix_regex_matching_of_identity - UNIC-1375"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Shell explicit show in config state (#1484) (#1503) - UNIC-1325","Shell caching data - 5.1.x-stable (#1496) - UNIC-1357"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Swagger: Code cleanup - 5.1.x-stable (#1489)"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump org.codehaus.mojo:properties-maven-plugin from 1.1.0 to 1.2.0 (#1522)"]}],[{"i":"uniconfig-5113","l":"Uniconfig 5.1.13"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["Fix key delimiter in URI","Swagger: Fix RPCs placed after mountpoint (#1582)","[UNIC-1410] Fix tx cleanup when request fails","[UNIC-1413] Fixed updating snapshot in immediate-commit model (#1629)","[UNIC-1420] Fix cli ssh session reconnect","[UNIC-1425] Fix crypto bug (#1664)","[UNIC-1352, UNIC-1254] Fix cluster issues (#1670)","[UNIC-1340] Fixed releasing of used YANG modules from memory (#1667)","[UNIC-1429] Fix replace is sent using delete operation","[UNIC-1432] Swagger: Fix generation of post list endpoints (#1674)","[UNIC-1430] - fix replace yang-patch for gnmi mountpoint","[UNIC-1404] UniConfig Shell - fix system augmentation","Fixed loading of YANG from path in client diff tool"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1394] Client side diff","[UNIC-1402] UC Shell - default callbacks repository (#1701)"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-981] UniconfigShell: Remove explicit show submode from root mod…","[UNIC-1411] Add mapping to request/response log message","[UNIC-1394] Add overloaded build methods to client side diff","[UNIC-1394] exclude gnmi depenendecies from java client","[UNIC-1401] UniConfig Shell - one line SET / DELETE command (#1621)","[UNIC-1403] Unified format of shell audit logs (#1658)","[PANT-83] add logs for pant83 - STABLE"]},{"i":"api-changes","l":"\uD83D\uDDA5️ API Changes","p":["add gnmi-messages logging broker"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["Fix Jetty CVEs","5.1.x-stable - Maven 3.9.5"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["5.1.13-SNAPSHOT","UniconfigShell: Improving suggestions menu","[FI-1693] Remove Jenkins-test from merge workflow","Release 5.1.13"]}],[{"i":"uniconfig-5114","l":"Uniconfig 5.1.14"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1429] Fix replace operation in GNMI set","[UNIC-1471] : Fix sync fail after failed installation was stored STABLE","[UNIC-1474] Improve performance of YANG repository loading process during mounting process (#1785)","UniConfig Shell - fix prompt callbacks bug","[UNIC-1492] - Fix rate-limiting","Fixed loading of gNMI YANG repository during MountNodeTask","[UNIC-1471] Add schema-cache storing into sync impl","Prevented sending no description command if there is no change for rpd description","Gnmi sb netconf cache loader stable","[UNIC-1494] - add migration for replace-paths","Fix get fallback schema context in cli shell.","Fix settings / callbacks cache"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1075] Uniconfig shell hide / unhide command implementation"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1408] UniConfig Shell - adjust cached data (#1745)","[UNIC-1405] UniConfig shell: set nested JSON data (#1752)","Improved logging (#1798)"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Suppress CVEs","[UNIC-1475] changing information about expired transaction in root mode","Release 5.1.14"]}],[{"i":"uniconfig-5115","l":"Uniconfig 5.1.15"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1481] Add With-Default to Java client","[UNIC-1490] - Fix delete requests not send"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1028] Connect/Disconnect node RPC"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1487] Uniconfig Shell: prompt mode should be the same after config transaction expiration"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump kotlin.version from 1.9.0 to 1.9.20"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["New snapshot release 5.1.15","Do not generate release notes","[UNIC-1488] Uniconfig Shell: add option to refresh the transaction"]}],[{"i":"uniconfig-5116","l":"Uniconfig 5.1.16"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1517] Fix pagination","[UNIC-1521] Fix reading list nodes in augmentations","[UNIC-1422] Fixed transaction is closed issue","[UNIC-1512] Fix ordering of operations on gnmi topology","Cover more errors in connect node RPC responses"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1486] + [UNIC-1509] - Skip yang constraints","[UNIC-1507] : One uniconfig tx for (un)install-multiple-nodes RPC"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1514] Add support CER device version 12.*(#1903)","Fixed logging in TaskExecutorImpl"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Release new snapshot version 5.1.16-SNAPSHOT","Release workflow stable","Add distributionSuffix property","Build distro without units on release (#1955)","Release 5.1.16."]}],[{"i":"uniconfig-5117","l":"Uniconfig 5.1.17"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1526] - increase gnmi executor queue size","[UNIC-1534] Swagger: fix bad types for numeric attributes (#2018)","[UNIC-1537] - Fix failing install sync stable","[UNIC-1547] Fix sync-from-network RPC","[UNIC-1557] Fix MountPointListenerException","CVE-2023-51074 stable"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1533] - skip length & range constraints","Support tailf's comment and label audit params in netconf southbound"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Stable task executor refactoring","[UNIC-1505] - Parallel syncFromNetwork (stable)","[UNIC-1102] Improve logging for schema context building"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["Bump Spring Boot to 3.1.6","Bump owasp-dependency-check","Bump logback.classic.version from 1.4.8 to 1.4.14"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.1.17-SNAPSHOT.","Rename UniConfig distribution name from bin to without TU","[UNIC-1453] UniConfig Shell - one-liner show/set/delete for callbacks…","Suppress logback","[UNIC-1539] Fix some typos","Maven 3.9.6","Revert \"[UNIC-1547] Fix sync-from-network RPC (#2044)\"","Revert \"Revert \"[UNIC-1547] Fix sync-from-network RPC (#2044)\" (#2050)\"","Suppress sshd vulnerability and old vulnerabilities.","Release 5.1.17."]}],[{"i":"uniconfig-5118","l":"Uniconfig 5.1.18"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["add missing docker dependency","[UNIC-1573] CLI shell: Fix Connect/Disconnect RPC suggestions","UniConfig Shell - fixing show mode bugs","[UNIC-1550] - mount/unmount synchronization (#2061)","[UNIC-1481] Fix with-defaults query parameter"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1499] Swagger: disable generation of POST list entries"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.1.18-SNAPSHOT.","Add default values to connect-node RPC","Fixed InterfaceRpdStateReader and CableMacReader for CER devices","Release 5.1.18."]}],[{"i":"uniconfig-5119","l":"Uniconfig 5.1.19"},{"i":"whats-changed","l":"What's Changed"},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1583] Add timeout property for Uniconfig Shell","Created CableModemReader and CableModemStateReader for CER devices"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Add postpone reason to task execution error on timeout"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.1.19-SNAPSHOT.","Release 5.1.19."]}],[{"i":"uniconfig-5120","l":"Uniconfig 5.1.20"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["Fixed removing mac-address command issue in InterfaceRpdConfigWriter","[UNIC-1601] Fix loading fallback context.","Get-template-nodes replace module in var."]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1122] DCE duplicate subscription check.","Rate limiting for user uniconfig transactions"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["Security - bump dependencies and cleanup suppressions","Security - bump commons-compress to 1.26.0"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.1.20-SNAPSHOT.","Fix testtool tag","Release 5.1.20"]}],[{"i":"uniconfig-5121","l":"Uniconfig 5.1.21"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1604] Fix synchronous RPCs - stable","[UNIC-1620] UC Shell: Fix leaf-list parsing (#2244)","[UNIC-1629] Fix replace-paths grouping distinct list entries","[UNIC-1664] Fix confirm-commit race-conditions","[UNIC-1680] Fix dryrun-commit mount/unmount process"]},{"i":"new-features","l":"✅ New Features","p":["Made local-priority attribute optional in RpdPtpPortConfigWriter"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1626] Add missing request tags into client.","Add Docker dependencies for collect_diag_info script","Added one more command into the update template to remove RPD connection from fiber-node","Move dependency-check into separate maven profile"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.1.21-SNAPSHOT.","Release 5.1.21","Bump to 5.1.22-SNAPSHOT.","Fix release workflow"]}],[{"i":"uniconfig-5122","l":"Uniconfig 5.1.22"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["Fixed write template in InterfaceRpdConfigWriter","Added previous mac-address into the command for removing it","Fixed get-installed-nodes bug that throws error when uninstall-node and get-installed-nodes RPC are executed at the same time in same topology type"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Prevented sending command for rpd-index, ucam and dcam attributes if there is no change for CER rpd interfaces"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["Security - update dependencies"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["upgrade embedded kafka version in application properties","Release 5.1.22"]}],[{"i":"uniconfig-5123","l":"Uniconfig 5.1.23"},{"i":"whats-changed","l":"What's Changed"},{"i":"new-features","l":"✅ New Features","p":["Added 13.* version support for ARRIS devices"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["Embedded Postgres 16"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.1.23-SNAPSHOT."]}],[{"i":"uniconfig-520-release-notes","l":"Uniconfig 5.2.0 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Parse NOTIFICATION-TYPE from MIB schemas. (#1545) - UNIC-1382","Add rpc change-encryption-keys (#1441) - UNIC-1239","support for gnmi-notifications - Notification + Subscription service (#1109) - UNIC-1184","UNIC-1308","SNMP topology (#1438) - UNIC-1202","UNIC-1202"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["fix_regex_matching_of_identity - UNIC-1375","Fixed generation of commit diff notifications","Fix identityRef parsing (#1502) - UNIC-1356","Swagger: Fix generation of operational data from Uniconfig schemas - UNIC-1280","Fixed unmounting of node that is in connecting state - UNIC-1281"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Add gnmi subscription parameters (#1505) - UNIC-1369","Add mutable transaction to Shell (#1399) - UNIC-1312","add ValueCase to gnmi codec - UNIC-1113","Caching of calculate-diff response in transaction","Changing use case of prompt stylization - UNIC-977","Cleanup dependencies in uniconfig module (#1542) - UNIC-1381","Constants refactoring (#1511) - UNIC-1257","Enabling and cleaning up SHELL checkstyles (#1451) - UNIC-1345","fix connection manager (#1532)","Merged mdsal-dom-api into sal-dom-api module (#1543)","Merged mdsal-dom-spi to sal-dom-spi module (#1415)","Prevented sending command for rpd-index, ucam and dcam attributes if there is no change for CER rpd interfaces","Removed sal-common-impl module (#1426)","Shell caching data (#1480) - UNIC-1357","Shell explicit show in config state (#1484) - UNIC-1325","SNMP refactoring of snmp-topology (#1472) - UNIC-1343","Swagger: Unit tests - UNIC-1186","UNIC-1369","Unifying, renaming and increasing readability of UC-shell - UNIC-977"]},{"i":"api","l":"\uD83D\uDCBB API","p":["Refactor connection-manager RPCs (#1423) - UNIC-1283"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Read All data type on specific paths"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump org.apache.commons:commons-lang3 from 3.12.0 to 3.13.0 (#1523)","build(deps-dev): bump org.flywaydb:flyway-core from 9.20.0 to 9.21.0 (#1474)","build(deps-dev): bump org.flywaydb:flyway-core from 9.21.0 to 9.21.1 (#1520)","build(deps): bump bouncycastle.version from 1.75 to 1.76 (#1521)","build(deps): bump ch.qos.logback:logback-classic from 1.4.6 to 1.4.8 (#1483)","build(deps): bump ch.qos.logback:logback-classic from 1.4.8 to 1.4.9 (#1562)","build(deps): bump com.google.guava:guava from 32.1.1-jre to 32.1.2-jre (#1557)","build(deps): bump com.puppycrawl.tools:checkstyle from 10.12.1 to 10.12.2 (#1561)","build(deps): bump grpc.version from 1.56.1 to 1.57.0 (#1517)","build(deps): bump grpc.version from 1.57.0 to 1.57.1 (#1559)","build(deps): bump jersey.version from 3.1.2 to 3.1.3 (#1518)","build(deps): bump jmh-core.version from 1.36 to 1.37 (#1558)","build(deps): bump json-smart from 2.4.11 to 2.5.0 (#1404)","build(deps): bump kotlin.version from 1.8.22 to 1.9.0 (#1391)","build(deps): bump kotlinx-coroutines-core from 1.7.1 to 1.7.2 (#1392)","build(deps): bump maven.core.version from 3.9.2 to 3.9.3 (#1358)","build(deps): bump maven.core.version from 3.9.3 to 3.9.4 (#1560)","build(deps): bump netty.version from 4.1.94.Final to 4.1.95.Final (#1477)","build(deps): bump netty.version from 4.1.95.Final to 4.1.96.Final (#1516)","build(deps): bump opentelemetry-api from 1.27.0 to 1.28.0 (#1406)","build(deps): bump org.apache.kafka:kafka-clients from 3.5.0 to 3.5.1 (#1476)","build(deps): bump org.codehaus.mojo:properties-maven-plugin from 1.1.0 to 1.2.0 (#1522)","build(deps): bump org.jetbrains.kotlinx:kotlinx-coroutines-core from 1.7.2 to 1.7.3 (#1519)","build(deps): bump org.junit.jupiter:junit-jupiter from 5.9.3 to 5.10.0 (#1479)","build(deps): bump org.xmlunit:xmlunit-legacy from 2.6.1 to 2.9.1 (#1478)","build(deps): bump protobuf.version from 3.23.2 to 3.23.4 (#1395)","build(deps): bump spring-jdbc from 6.0.10 to 6.0.11 (#1434)","build(deps): bump spring.boot.version from 3.1.1 to 3.1.2 (#1475)","build(deps): bump swagger-core from 2.2.14 to 2.2.15 (#1405)"]}],[{"i":"uniconfig-521","l":"Uniconfig 5.2.1"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1273] Use Jetty embedded server","[UNIC-1340] Fixed releasing of used YANG modules from memory","[UNIC-1352, UNIC-1254] Fix cluster issues","[UNIC-1365] Gnmi stream fixes","[UNIC-1390] Swagger: Fix RPCs placed after mountpoint","[UNIC-1395] Fix key delimiter in URI","[UNIC-1399] Fix issues with shell","[UNIC-1399] Switch shell terminal back to JNA","[UNIC-1404] UniConfig Shell - fix system augmentation","[UNIC-1410] Fix tx cleanup when request fails","[UNIC-1410] Fix_tx_closing","[UNIC-1413] Fixed updating snapshot in immediate-commit model","[UNIC-1420] Fix cli ssh session reconnect","[UNIC-1423] Fix identityRef as listEntry key in templatesg","[UNIC-1425] Fix crypto bug","[UNIC-1429] Fix replace is sent using delete operation","[UNIC-1430] Fix replace yang-patch for gnmi mountpoint","[UNIC-1432] Swagger: Fix generation of post list endpoints","[UNIC-1446] Fix SpotBugs violations - Reliance on default encoding","[UNIC-1447] Fix SpotBugs violations - Multithreaded correctness","[UNIC-1448] Fix SpotBugs violations - Use a localized version of String.toUpperCase() and String.toLowerCase()","[UNIC-1451] Fix SpotBugs violations - Correctness","[UNIC-1463] Remove duplicates from Set","Add git registry to dependabot.yml","Additional fix to calculate diff rpc","Cleanup test resources properly","Data-change-events publisher fix","Fix calculate diff rpc","Fix immediate commit model and submit successfull nodes.","Fix mapEntryNodes in gnmi notifications","Fix reading of actual YANG repository from mountpoint data","Fix show UC status script","Fix show_uniconfig_status script.","Fix skip of unreachable-nodes.","Fix SNMP Notification bean creation","Fixed DateTime format in the transaction-log","Fixed loading of YANG from path in client diff tool (#1747)","Prevented sending no description command if there is no change for rpd description","Registry attempt no.2","SNMP adjust exception","SNMP Node id is incorrectly parsed"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1394] Client side diff","[UNIC-1373] Implemented dryrun-commit for GNMI topology","[UNIC-1398] SNMP notifications","[UNIC-1402] UC Shell - default callbacks repository","[UNIC-1218] Add dynamic property module"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[PANT-83] add logs for pant83","[UNIC-1154] Integrate JOOQ into database access layer","[UNIC-1218] Rewrite database connection pool and connection properties","[UNIC-1223] ODL parent cleanup","[UNIC-1242] Remove PR links from the uploaded release notes","[UNIC-1242] Unify generation of release notes","[UNIC-1245] Replacing Guava future by CompletableFuture","[UNIC-1258] Fix issues reported by SpotBugs","[UNIC-1273] Adjust bootstrapping of web containers","[UNIC-1370] Adjust notification result parsing","[UNIC-1386] Map correct ObjectTypes to NotificationTypes","[UNIC-1391] Add SNMP notifications to SchemaContext","[UNIC-1394] Add overloaded build methods to client side diff","[UNIC-1394] Remove gnmi dependencies from java client","[UNIC-1401] UniConfig Shell - one line SET / DELETE command","[UNIC-1403] Unified format of shell audit logs","[UNIC-1411] Add mapping to request/response log message (#1630)","[UNIC-1412] change gnmi packaging","[UNIC-1435] Refactor transaction-log to JOOQ style","[UNIC-1441] SNMP config classes","[UNIC-1449] Fix SpotBugs violations - Performance","[UNIC-1463] Fix SpotBugs violations - Code vulnerabilities","[UNIC-980] UniconfigShell: Improving suggestions menu","[UNIC-981] UniconfigShell: Remove explicit show submode from root mode"]},{"i":"api-changes","l":"\uD83D\uDDA5️ API Changes","p":["[UNIC-1289] Refactor RPCs: revert-changes, query-config, device-discovery","[UNIC-1380] Add gnmi-messages logging broker","[UNIC-1287] Refactor snapshot-manager RPCs","[UNIC-1282] Refactoring uniconfig manager RPCs"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["[UNIC-1223] Align an embedded kafka version with the clients provided by Spring","build(deps): bump actions/checkout from 3 to 4","build(deps): bump actions/setup-python from 4.6.1 to 4.7.1","build(deps): bump actions/upload-artifact from 3.1.2 to 3.1.3","build(deps): bump antlr4.version from 4.13.0 to 4.13.1","build(deps): bump com.github.gantsign.maven:ktlint-maven-plugin from 1.16.0 to 2.0.0","build(deps): bump com.github.gantsign.maven:ktlint-maven-plugin from 2.0.0 to 3.0.0","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.7.3.5 to 4.7.3.6","build(deps): bump com.puppycrawl.tools:checkstyle from 10.12.2 to 10.12.3","build(deps): bump com.puppycrawl.tools:checkstyle from 10.12.3 to 10.12.4","build(deps): bump commons-io:commons-io from 2.13.0 to 2.14.0","build(deps): bump commons-net:commons-net from 3.9.0 to 3.10.0","build(deps): bump docker/build-push-action from 4 to 5","build(deps): bump docker/login-action from 2.2.0 to 3.0.0","build(deps): bump grpc.version from 1.57.1 to 1.57.2","build(deps): bump grpc.version from 1.57.2 to 1.58.0","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.15 to 2.2.16","build(deps): bump io.zonky.test.postgres:embedded-postgres-binaries-linux-amd64 from 13.11.0 to 13.12.0","build(deps): bump kotlin.version from 1.9.0 to 1.9.10","build(deps): bump org.apache.commons:commons-compress from 1.23.0 to 1.24.0","build(deps): bump org.apache.maven.plugins:maven-enforcer-plugin from 3.3.0 to 3.4.0","build(deps): bump org.apache.maven.plugins:maven-enforcer-plugin from 3.4.0 to 3.4.1","build(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.5.0 to 3.6.0","build(deps): bump org.apache.maven.plugins:maven-shade-plugin from 3.5.0 to 3.5.1","build(deps): bump org.immutables:value from 2.9.3 to 2.10.0","build(deps): bump org.jetbrains.dokka:dokka-maven-plugin from 1.8.20 to 1.9.0","build(deps): bump org.json:json from 20230618 to 20231013","build(deps): bump org.owasp:dependency-check-maven from 8.3.1 to 8.4.0","build(deps): bump org.springframework.cloud:spring-cloud-dependencies from 2022.0.3 to 2022.0.4","build(deps): bump protobuf.version from 3.23.4 to 3.24.0","build(deps): bump protobuf.version from 3.24.0 to 3.24.1","build(deps): bump protobuf.version from 3.24.1 to 3.24.2","build(deps): bump protobuf.version from 3.24.2 to 3.24.3","build(deps): bump protobuf.version from 3.24.3 to 3.24.4","build(deps): bump spring.boot.version from 3.1.2 to 3.1.3","build(deps): bump spring.boot.version from 3.1.3 to 3.1.4","Maven 3.9.5"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["5.2.1-SNAPSHOT","[FI-1693] Remove Jenkins-test from merge workflow","Workflows: update cluster IP from 10.19.0.67 to 10.19.0.242 and","Workflows: remove VPN to FRINX for postgresDB.","Workflows: update path to new VM of postgresDB.","Workflows: update path and remove FRINX VPN for embeded tests.","Removed forgotten LOG","Release 5.2.1"]}],[{"i":"uniconfig-522","l":"Uniconfig 5.2.2"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1405] UniConfig shell: set nested JSON data","[UNIC-1429] Fix replace operation in GNMI set (MAIN)","[UNIC-1450] Spotbugs fixes - Bad practice","[UNIC-1471] : Fix sync fails after failed installation was stored in DB","[UNIC-1471] Add schema-cache storing into sync impl","[UNIC-1474] Improve performance of YANG repository loading process during mounting process","[UNIC-1475]: generalizing information about expired transaction","[UNIC-1494] - add migration for replace-paths","Add fix for reading duplicate properties","Caching request body copier","Fix bad migration embedded kafka properties from old UC version to new","Fix exception in loading yang schemas","Fix get fallback schema context in cli shell.","Fix update property value to null bug","Removed the forgotten callbacks-models dependencies","Set forgotten crypto properties in creation crypto config.","UniConfig Shell - fix prompt callbacks bug","Use a Set instead of a List in MibRepository"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1075] Uniconfig shell hide / unhide command implementation","[UNIC-1028] Connect/Disconnect node RPC"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1408] UniConfig Shell - adjust cached data","[UNIC-1374] Fixed sending install-node RPC request without mandatory fields","[UNIC-1445] Refactor yang-repo to JOOQ style","Refactoring Properties","Add spotbugs-maven-plugin configuration","Optimize DB read-only transaction","Improved logging","Add Google ErrorProne plugin","[UNIC-1487] return to the same mode when transaction expires"]},{"i":"api-changes","l":"\uD83D\uDDA5️ API Changes","p":["[UNIC-1290] Refactor data-change-events RPCs"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump com.github.spotbugs:spotbugs-annotations from 4.7.3 to 4.8.0","build(deps): bump com.google.guava:guava from 32.1.2-jre to 32.1.3-jre","build(deps): bump org.codehaus.woodstox:stax2-api from 4.2.1 to 4.2.2","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.16 to 2.2.17","build(deps): bump com.fasterxml.jackson.core:jackson-databind from 2.15.2 to 2.15.3","build(deps): bump org.apache.maven.plugins:maven-plugin-plugin from 3.9.0 to 3.10.1","build(deps): bump org.jetbrains.dokka:dokka-maven-plugin from 1.9.0 to 1.9.10","build(deps): bump io.github.git-commit-id:git-commit-id-maven-plugin from 6.0.0 to 7.0.0","build(deps-dev): bump org.apache.maven.plugin-tools:maven-plugin-annotations from 3.9.0 to 3.10.1","build(deps): bump grpc.version from 1.58.0 to 1.59.0","build(deps): bump spring.boot.version from 3.1.4 to 3.1.5","build(deps): bump sshd.version from 2.10.0 to 2.11.0","build(deps): bump org.owasp:dependency-check-maven from 8.4.0 to 8.4.2"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Rename distro/uniconfig-modules/uniconfig to main","Prepared sample docker compose file","Move main.jar into the root","Set kafka enabled to false","Properties overhaul","Suppress CVEs","Use NetconfCacheLoader in gnmi-sb instead of custom yang parsing","Fix binding empty properties","Rewrite client to new properties RPC","Fix dependency management for starting UniConfig","Release 5.2.2"]}],[{"i":"uniconfig-523","l":"Uniconfig 5.2.3"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["zero_dividing_tx_logs_for_notifications","[UNIC-1452] SpotBugs - Dodgy code","Fix ErrorProne ERROR level violations - part 1","[UNIC-1481] Add With-Default to Java client","[UNIC-1490] - Fix delete requests not send","Fix connect/disconnect RPCs","[UNIC-1503] - Fix DB migrations","[UNIC-1503] Fix db migration V26","[UNIC-1498] ErrorProne ERROR level fixes","Fix revisions in static variables"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1484] SNMP - security models"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["optimize hide unhide","[UNIC-1480] Refactor unistore-node to JOOQ style","[UNIC-1488] Uniconfig Shell: add option to refresh the transaction","Cleanup jline packaging","Moved JSONB/NormalizedNode translation for UniconfigInstance from DB …","[UNIC-1419] Java 21","Expose Kafka Producer compression setting"]},{"i":"api-changes","l":"\uD83D\uDDA5️ API Changes","p":["[UNIC-1285] Refactoring template manager rpcs","[UNIC-1286] Refactoring subtree manager RPCs","[UNIC-1461] Return http status code 204 in rpc","[UNIC-1454] Bump revision date in updated YANG models."]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump commons-io:commons-io from 2.14.0 to 2.15.0","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.17 to 2.2.18","build(deps): bump org.apache.maven.plugins:maven-surefire-plugin from 3.1.2 to 3.2.1","build(deps): bump org.apache.maven.plugins:maven-checkstyle-plugin from 3.3.0 to 3.3.1","build(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.6.0 to 3.6.1","build(deps): bump org.codehaus.mojo:properties-maven-plugin from 1.2.0 to 1.2.1","build(deps): bump org.apache.maven.plugins:maven-failsafe-plugin from 3.1.2 to 3.2.1","build(deps): bump commons-cli:commons-cli from 1.5.0 to 1.6.0","build(deps): bump kotlin.version from 1.9.10 to 1.9.20","build(deps): bump protobuf.version from 3.24.4 to 3.25.0"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["New snapshot release 5.2.3","README.md - fix render issues on GitHub","Workflows: remove from cluster tests kafka option.","Release version 5.2.3"]}],[{"i":"uniconfig-524","l":"Uniconfig 5.2.4"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1517] Fix pagination","Fix getting fallback schema token.","[UNIC-1453] UniConfig Shell - one-liner show/set/delete for callbacks","Fix UC not start","[UNIC-1422] Fixed transaction is closed issue","Fix failing cli shell tests","[UNIC-1521] Fix reading list nodes in augmentations (#1946)","Fix SNMP v2c notifications","[UNIC-1512] Fix ordering of operations on gnmi topology","Add handling for successful rpc with status code 204.","Cover more errors in connect node RPC responses"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1486] [UNIC-1509] Skip yang constraints","[UNIC-1507] : One uniconfig tx for (un)install-multiple-nodes RPC"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1514] Add support CER device version 12.*","[DEP-616] UDP loadbalancer with ip transparency for SNMP notifications","[UNIC-1407] Adjust LOGs in Uniconfig shell","[UNIC-1438] Refactoring sal-fallback-provider / fallback-schema-service","[UNIC-1495] Refactor mountpoint to JOOQ style","Add new Release workflow","[UNIC-1502] SNMP v3 notifications","[UNIC-1454] Bump revision date in updated logging YANG models.","Remove object cache"]},{"i":"api-changes","l":"\uD83D\uDDA5️ API Changes","p":["[UNIC-1288] Refactor logging and restconf-logging RPCs","Fix generic status code to specific status code for Subtree RPCs."]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump com.github.spotbugs:spotbugs-annotations from 4.8.0 to 4.8.1","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.7.3.6 to 4.8.1.0","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.18 to 2.2.19","build(deps-dev): bump org.apache.maven.plugin-tools:maven-plugin-annotations from 3.10.1 to 3.10.2","build(deps): bump org.apache.maven.plugins:maven-plugin-plugin from 3.10.1 to 3.10.2","build(deps): bump io.zonky.test.postgres:embedded-postgres-binaries-linux-amd64 from 13.12.0 to 13.13.0","build(deps): bump org.jetbrains:annotations from 24.0.1 to 24.1.0","build(deps): bump bouncycastle.version from 1.76 to 1.77","build(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.1.0 to 3.1.1","build(deps): bump protobuf.version from 3.25.0 to 3.25.1","build(deps): bump com.puppycrawl.tools:checkstyle from 10.12.4 to 10.12.5","build(deps): bump org.owasp:dependency-check-maven from 8.4.2 to 8.4.3","build(deps): bump org.apache.commons:commons-compress from 1.24.0 to 1.25.0"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Add distributionSuffix property","Add name to release workflow","Allow double quotes in release notes body","Build distro without units on release","Dispatch on wf completion instead","Fix PAT usage","Fix release workflow","Fix SNMP bean creation","Fixed logging in TaskExecutorImpl","Forgot to remove these","Forgot to remove this one as well","Merge publish release notes into release wf as a separate job","README - Update release process","Release 5.2.4.","Release new snapshot version 5.2.4-SNAPSHOT","Update release.yml","Use PAT in release workflow","Workflows: add cache for embeded test and remove all docker images","Workflows: add new test to embeded workflow - skip_yang_constraints.","Workflows: disable delete_customers_license_server.yml","Workflows: enable immutable and mutable cluster tests.","Workflows: fix typo for embeded tests.","Workflows: fix typo in embededDB_cross_versions workflow."]}],[{"i":"uniconfig-525","l":"Uniconfig 5.2.5"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1526] - increase gnmi executor queue size","Fix callbacks","Fix sync empty target-nodes response","[UNIC-1538] Fixed check-installed-nodes RPC","FR-63 Fix parsing of SROS CLI prompt in the transaction mode","[UNIC-1534] Swagger: fix bad types for numeric attributes","Fixed command for disabling pagination on SROS","[UNIC-1539] Fix some typos in descriptions","[UNIC-1537] - fix (un)install-multiple","Fix CLI Shell command length counter","[UNIC-1547] Fix sync-from-network RPC","[UNIC-1557] Fix MountPointListenerException","[UNIC-1550] - mount/unmount synchronization"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1533] - skip length & range constraints","[UNIC-1383] Create logging broker for GNMI notifications","Support tailf's comment and label audit params in netconf southbound"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1477] Unify HTTP clients","Refactor TaskExecutor","[UNIC-1505] - Parallel syncFromNetwork","[UNIC-963] Convert List to Map in GNMI","[UNIC-1102] Improve logging for schema context building","[UNIC-1541] Refactor DCE to JOOQ style","[UNIC-1472] CLI shell - Support multiple list entries","[UNIC-1549] Refactor netconf-key-credential to JOOQ style"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump actions/setup-java from 3 to 4","build(deps): bump actions/setup-python from 4.7.1 to 5.0.0","build(deps): bump com.fasterxml.jackson.core:jackson-databind from 2.15.3 to 2.16.0","build(deps): bump com.github.spotbugs:spotbugs-annotations from 4.8.1 to 4.8.2","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.1.0 to 4.8.2.0","build(deps): bump com.puppycrawl.tools:checkstyle from 10.12.5 to 10.12.6","build(deps): bump commons-io:commons-io from 2.15.0 to 2.15.1","build(deps): bump grpc.version from 1.59.0 to 1.59.1","build(deps): bump grpc.version from 1.59.1 to 1.60.0","build(deps): bump io.zonky.test:embedded-postgres from 2.0.4 to 2.0.5","build(deps): bump io.zonky.test:embedded-postgres from 2.0.5 to 2.0.6","build(deps): bump io.zonky.test.postgres:embedded-postgres-binaries-linux-amd64 from 13.13.0 to 13.13.1","build(deps): bump maven.core.version from 3.9.5 to 3.9.6","build(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.2 to 3.6.3","build(deps): bump org.apache.maven.plugins:maven-project-info-reports-plugin from 3.4.5 to 3.5.0","build(deps): bump org.codehaus.mojo:build-helper-maven-plugin from 3.4.0 to 3.5.0","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 1.9.20 to 1.9.21","build(deps): bump org.owasp:dependency-check-maven from 8.4.3 to 9.0.4","Bump org.springframework.boot from 3.1.6 to 3.1.7","Bump Spring Boot to 3.1.6","Use latest maven plugins"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["[UNIC-1523] Refactor notifications and subscriptions to JOOQ style","[UNIC-1531] Use Java 17 as a target","[UNIC-1539] Fix some typos","[UNIC-1542] Refactor Session to JOOQ style","Bump to 5.2.5-SNAPSHOT.","Cluster notification","CVE-2023-51074 suppress","fix_sync_from_network_tests","Fixed creation of NormalizedNode from read NetconfKeyCredential","Fixed usage of JOOQ enumerations","Node jooq","Release 5.2.5.","Rename UniConfig distribution name from bin to without TU","Revert \"[UNIC-1533] - skip length & range constraints\"","Revert \"[UNIC-1547] Fix sync-from-network RPC (#2043)\"","Revert \"build(deps): bump com.fasterxml.jackson.core:jackson-databind from 2.15.3 to 2.16.0 (#1962)\"","Revert \"Revert \"[UNIC-1547] Fix sync-from-network RPC (#2043)\" (#2049)\"","Suppress logback","Suppress sshd vulnerability"]}],[{"i":"uniconfig-526","l":"Uniconfig 5.2.6"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1527] - fixing show mode bugs","add missing docker dependency","[UNIC-1573] CLI shell: Fix Connect/Disconnect RPC suggestions","[UNIC-1576] - Fix retrieving of augmentation node","[UNIC-1574] Fix remove patch operation","[UNIC-1481] Fix with-defaults query parameter"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1545] - Sync southbound nodes"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1499] Swagger: disable generation of POST list entries","[UNIC-1551] Refactor Snapshot and SnapshotNode to JOOQ","[UNIC-1567] - unify error-info property"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.2.6-SNAPSHOT.","Change default value for connect-node RPC","[UNIC-1581] Fix client update and read properties structure","Release 5.2.6."]}],[{"i":"uniconfig-527","l":"Uniconfig 5.2.7"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["Fix protocol issues after refactoring.","Fix protocol issues after refactoring in cli shell.","Fix another protocol issues after refactoring.","Fix sturtup UniConfig","Fixed InterfaceRpdStateReader and CableMacReader for CER devices","[UNIC-1587] Incomplete document fix","[UNIC-1568] Fix sync connection fail handling","Fix version in restconf dependencies","Fix logging controller issue caused by previous refactoring.","Added migration for node.encryption_public_key","[UNIC-1610] Fix bulk-edit in cluster"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1583] Add timeout property for UniConfig Shell","Created CableModemReader and CableModemStateReader for CER devices","[UNIC-1589] - Install skip mount"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1569] Refactor template to JOOQ style","Change protocol table to Enum.","Add postpone reason to task execution error on timeout","[UNIC-1578] Support IPv6 addressing","[UNIC-1384] Refactoring of SNMP read operation"]},{"i":"documentation","l":"\uD83D\uDDD2️ Documentation","p":["[UNIC-1596] Expose OpenAPI documentation for Uniconfig models"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump actions/download-artifact from 3.0.2 to 4.1.1","build(deps): bump actions/upload-artifact from 3.1.3 to 4.2.0","Upgrade Spring Boot version","build(deps): bump dawidd6/action-download-artifact from 2 to 3","build(deps): bump actions/upload-artifact from 4.2.0 to 4.3.0","build(deps): bump com.github.spotbugs:spotbugs-annotations from 4.8.2 to 4.8.3","build(deps): bump org.apache.maven.plugins:maven-failsafe-plugin from 3.2.2 to 3.2.5","build(deps): bump org.apache.maven.plugins:maven-surefire-plugin from 3.2.2 to 3.2.5","build(deps): bump org.owasp:dependency-check-maven from 9.0.4 to 9.0.9","build(deps): bump actions/upload-artifact from 4.3.0 to 4.3.1","build(deps): bump actions/download-artifact from 4.1.1 to 4.1.2"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.2.7-SNAPSHOT.","workflows: Update README.md","Release 5.2.7."]}],[{"i":"uniconfig-600","l":"Uniconfig 6.0.0"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["Fix Dependency check 9.0.x renamed parameter","Fixed removing mac-address command issue in InterfaceRpdConfigWriter","[UNIC-1609] UC Shell - fix data loading","[UNIC-1601] Fix loading fallback context.","[UNIC-1604] - Fix synchronous RPCs","Fix install result processing + mount synchronization","[VHD-358] Fix parsing mountpoint in client.","[UNIC-1625] - Adding 2 new parameters for device installation via Netconf"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1122] DCE duplicate subscription check.","Cleanup yang-packager packaging","[UNIC-1341] Replace AAA encryption service with UniConfig encryption service","Cleanup testtool","Minimize testtool shaded JAR","Rate limiting for user uniconfig transactions","[UNIC-1615] Add exception message to apply template rpc error in client."]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump org.apache.maven.plugin-tools:maven-plugin-annotations from 3.10.2 to 3.11.0","build(deps): bump com.github.curious-odd-man:rgxgen from 1.4 to 2.0","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.2.0 to 4.8.3.1","build(deps): bump com.google.errorprone:error_prone_core from 2.23.0 to 2.24.1","build(deps): bump com.google.errorprone:error_prone_core from 2.24.1 to 2.25.0","build(deps): bump com.google.guava:guava from 32.1.3-jre to 33.0.0-jre","build(deps): bump com.lmax:disruptor from 3.4.4 to 4.0.0","build(deps): bump com.puppycrawl.tools:checkstyle from 10.12.6 to 10.13.0","build(deps): bump grpc.version from 1.60.0 to 1.61.1","build(deps): bump io.perfmark:perfmark-api from 0.26.0 to 0.27.0","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.19 to 2.2.20","build(deps): bump io.zonky.test.postgres:embedded-postgres-binaries-linux-amd64 from 13.13.1 to 13.14.0","build(deps): bump org.apache.commons:commons-compress from 1.25.0 to 1.26.0","build(deps): bump org.apache.maven.plugins:maven-compiler-plugin from 3.11.0 to 3.12.1","build(deps): bump org.apache.maven.plugins:maven-plugin-plugin from 3.10.2 to 3.11.0","build(deps): bump org.apache.maven.plugins:maven-shade-plugin from 3.5.1 to 3.5.2","build(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.1.1 to 3.2.0","build(deps): bump org.immutables:value from 2.10.0 to 2.10.1","build(deps): bump org.javassist:javassist from 3.29.2-GA to 3.30.2-GA","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 1.9.21 to 1.9.22","build(deps): bump org.json:json from 20231013 to 20240205","build(deps): bump org.snmp4j:snmp4j from 3.7.7 to 3.7.8","build(deps): bump org.springframework.boot:spring-boot-dependencies from 3.1.8 to 3.1.9","build(deps): bump protobuf.version from 3.25.1 to 3.25.2","build(deps): bump protobuf.version from 3.25.2 to 3.25.3","build(deps): bump sshd.version from 2.11.0 to 2.12.1","Bump stCarolas/setup-maven from v4.5 to v5"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.2.8-SNAPSHOT.","Cleanup unused suppression rules","Update embedded kafka version","workflows: prepare for uniconfig main branch version 6.0.0","Release 6.0.0","Update release.yml"]}],[{"i":"uniconfig-601","l":"Uniconfig 6.0.1"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1586] Fix jsonb filter data util.","[UNIC-1603] Gnmi - Fix getting closest parent for augmentation node.","[UNIC-1611] Add missing return statement.","[UNIC-1612] Fix serialization path in in json filter serializer","[UNIC-1620] UC Shell: Fix leaf-list parsing","[UNIC-1629] Fix replace-paths grouping distinct list entries","[UNIC-1631] Fix EscapedKeysUriFormatter","[UNIC-1663] Revert fix lazy apply template","[UNIC-1667] Add gnmi models to OpenAPI docs","[UNIC-1679] Fix IOS XR parsing","[UNIC-1682] Fix augmentation nodes overwriting each other","[VHD-377] Change qname 'crypto' to 'device-crypto'.","[VHD-377] Rename mountpoint paramater crypto to device-crypto","[VHD-380] Add missing RequestErrorTag.INVALID_TRANSACTION to client side.","Fix casting of UDE","Fix handling of fingerprint read in checked-commit","Fix mount-node task rate-limiting"]},{"i":"new-features","l":"✅ New Features","p":["Made local-priority attribute optional in RpdPtpPortConfigWriter","[UNIC-1684] - Add read and update properties client implementation"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1626] Add missing request tags into client.","[UNIC-1614] Adjust Connect/Disconnect RPC for better user experience","[UNIC-1616] - add node-id into error-info by default","Add logs to warn user when MIB repository metadata is missing","Add Docker dependencies for collect_diag_info script","[UNIC-1643] Add gnmi subscription parameters","Added one more command into the update template to remove RPD connection from fiber-node","Update gitignore","[UNIC-1606] Skip yang-patch exist check operation","[VHD-363] Improving response if there is no content with using count.","Add EdDSA dependency","Separate vulnerability scanning into a workflow","Add slack notification to vulnscan workflow","Fix notification URL","Fix vulnscan ids"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump actions/download-artifact from 4.1.2 to 4.1.4","build(deps): bump args4j:args4j from 2.33 to 2.37","build(deps): bump com.github.gantsign.maven:ktlint-maven-plugin from 3.0.0 to 3.1.1","build(deps): bump com.github.gantsign.maven:ktlint-maven-plugin from 3.1.1 to 3.2.0","build(deps): bump com.google.errorprone:error_prone_core from 2.25.0 to 2.26.1","build(deps): bump com.google.guava:guava from 33.0.0-jre to 33.1.0-jre","build(deps): bump com.puppycrawl.tools:checkstyle from 10.13.0 to 10.14.0","build(deps): bump com.puppycrawl.tools:checkstyle from 10.14.0 to 10.14.2","build(deps): bump docker/login-action from 3.0.0 to 3.1.0","build(deps): bump grpc.version from 1.61.1 to 1.62.2","build(deps): bump io.github.git-commit-id:git-commit-id-maven-plugin from 7.0.0 to 8.0.1","build(deps): bump io.github.git-commit-id:git-commit-id-maven-plugin from 8.0.1 to 8.0.2","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.20 to 2.2.21","build(deps): bump org.apache.commons:commons-compress from 1.26.0 to 1.26.1","build(deps): bump org.apache.maven.plugins:maven-assembly-plugin from 3.6.0 to 3.7.0","build(deps): bump org.apache.maven.plugins:maven-assembly-plugin from 3.7.0 to 3.7.1","build(deps): bump org.apache.maven.plugins:maven-compiler-plugin from 3.12.1 to 3.13.0","build(deps): bump org.apache.maven.plugins:maven-remote-resources-plugin from 3.1.0 to 3.2.0","build(deps): bump org.jetbrains.dokka:dokka-maven-plugin from 1.9.10 to 1.9.20","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 1.9.22 to 1.9.23","build(deps): bump org.json:json from 20240205 to 20240303","build(deps): bump org.owasp:dependency-check-maven from 9.0.9 to 9.0.10","build(deps): bump org.springdoc:springdoc-openapi-starter-webmvc-ui from 2.3.0 to 2.4.0","build(deps): bump org.springframework.boot:spring-boot-dependencies from 3.1.9 to 3.1.10"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.1-SNAPSHOT.","Fix collect_diag_info.sh","Fix logging class","Update vulnscan.yml","Release 6.0.1"]}],[{"i":"uniconfig-602","l":"Uniconfig 6.0.2"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["Fixed write template in InterfaceRpdConfigWriter","[UNIC-1668] Cleanup UNICONFIGTXID cookie properly","Fix transaction cookie cleanup","[UNIC-1687] Swagger - fix schema for empty yang type","Added previous mac-address into the command for removing it","[UNIC-1626] Renaming error tags to its full name.","[UNIC-1582] Fix SROS installation","[UNIC-1665] Unhide shell command for callbacks fix","[UNIC-1686] - CLI: show mount point not working","[UNIC-1678] - Fix Long type serialization in uc-client","[UNIC-1678] - Fix Database jsonb filter on templates","[UNIC-1678] add unit test for uint32 serialization"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1675] Dynamic capability resolving"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1673] Add user details into audit logs","Add date to log timestamp","Add set for servlet context path in java client.","Adjust connect/disconnect RPCs response messages for user readability"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump actions/setup-python from 5.0.0 to 5.1.0","build(deps): bump org.owasp:dependency-check-maven from 9.0.10 to 9.1.0","build(deps): bump commons-io:commons-io from 2.15.1 to 2.16.0","build(deps): bump org.apache.maven.plugins:maven-source-plugin from 3.3.0 to 3.3.1","build(deps): bump org.apache.maven.plugins:maven-invoker-plugin from 3.6.0 to 3.6.1","build(deps-dev): bump org.apache.maven.plugin-tools:maven-plugin-annotations from 3.11.0 to 3.12.0","build(deps): bump org.apache.maven.plugins:maven-plugin-plugin from 3.11.0 to 3.12.0","build(deps): bump org.snmp4j:snmp4j from 3.7.8 to 3.8.0","Use codehaus.plexus-build-api","build(deps): bump org.jline:jline from 3.22.0 to 3.25.1","build(deps): bump grpc.version from 1.62.2 to 1.63.0","build(deps): bump bouncycastle.version from 1.77 to 1.78"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.2-SNAPSHOT.","Fix vulnscan notification on fail","Fix notification status","Fix release workflow","Add snmp models to OpenApi docs","Release 6.0.2"]}],[{"i":"uniconfig-603","l":"Uniconfig 6.0.3"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1415] Fix gnmi subscription session cleanup","Fix IOS XR parsing","[UNIC-1469] Fix commit no rollback","Add logs for device-discovery","[UNIC-1700] Fix problem with reading data that are marked in YANG as deprecated","[UNIC-896] With-default query parameter fix","Additional logs for SNMP","Fix getting protocol value","[UNIC-1699] Fix datastore synchronization","[UNIC-1726] Improve Union codec error reporting","[UNIC-1724] Uniconfig shell Unhide operations for callbacks SET and Request"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1708] Check node connection rpc","[UNIC-1709] Gnmi HealthCheckService","[UNIC-1711] Add SnmpHealthCheckService","[UNIC-1712] Netconf HealthCheckService"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Add shell user into AUDIT_USER header when creating tx","[UNIC-1685] OpenApi: Add error container to response schema","Rename Check-node-connection RPC","Fix dependency convergence issues","Embedded Kafka - stable archive URL","Remove protobuf .proto files from gnmi-proto","[VHD-389] Fix creating subscription to streams.","[UNIC-1713] Stream connection notifications","Cleanup leaking test dependencies from distribution","[UNIC-1223] Remove duplicate dependency declarations","[UNIC-1223] Cleanup dependency version declarations"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump org.apache.maven.plugin-tools:maven-plugin-annotations from 3.12.0 to 3.13.0","build(deps): bump act10ns/slack from 2.0.0 to 2.1.0","build(deps): bump actions/download-artifact from 4.1.4 to 4.1.7","build(deps): bump actions/upload-artifact from 4.3.1 to 4.3.3","build(deps): bump bouncycastle.version from 1.78 to 1.78.1","build(deps): bump com.github.spotbugs:spotbugs-annotations from 4.8.3 to 4.8.4","build(deps): bump com.github.spotbugs:spotbugs-annotations from 4.8.4 to 4.8.5","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.3.1 to 4.8.4.0","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.4.0 to 4.8.5.0","build(deps): bump com.google.errorprone:error_prone_annotations from 2.26.1 to 2.27.0","build(deps): bump com.google.errorprone:error_prone_annotations from 2.27.0 to 2.27.1","build(deps): bump com.google.errorprone:error_prone_core from 2.26.1 to 2.27.0","build(deps): bump com.google.errorprone:error_prone_core from 2.27.0 to 2.27.1","build(deps): bump com.google.guava:guava from 33.1.0-jre to 33.2.0-jre","build(deps): bump com.puppycrawl.tools:checkstyle from 10.14.2 to 10.16.0","build(deps): bump commons-cli:commons-cli from 1.6.0 to 1.7.0","build(deps): bump commons-io:commons-io from 2.16.0 to 2.16.1","build(deps): bump io.zonky.test:embedded-postgres from 2.0.6 to 2.0.7","build(deps): bump jline.version from 3.25.1 to 3.26.1","build(deps): bump org.apache.maven.plugins:maven-jar-plugin from 3.3.0 to 3.4.1","build(deps): bump org.apache.maven.plugins:maven-plugin-plugin from 3.12.0 to 3.13.0","build(deps): bump org.apache.maven.plugins:maven-shade-plugin from 3.5.2 to 3.5.3","build(deps): bump org.checkerframework:checker-qual from 3.42.0 to 3.43.0","build(deps): bump org.snmp4j:snmp4j from 3.8.0 to 3.8.2","build(deps): bump org.springdoc:springdoc-openapi-starter-webmvc-ui from 2.4.0 to 2.5.0","build(deps): bump org.springframework.boot:spring-boot-dependencies f… …rom 3.1.10 to 3.1.11","Use org.ow2.asm:asm-bom"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.3-SNAPSHOT.","Remove unused field from ManageNodeTask","Add missing nodes to UniConfig OpenApi doc","[UNIC-1717] Fix gnmi failed subscription","[UNIC-1718] Rollback removing AAA encryption service","Release 6.0.3"]}],[{"i":"uniconfig-604","l":"Uniconfig 6.0.4"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1728] Fix reading of sample VNF config from netconf-testtool","Add missing dependencies to testtool","Swagger - add missing namespace when node is augmenting on deeper level","SwaggerUI - show extensions","Fix gnmi missing schemaContext handling","Swagger - fix required statement","Swagger - fix url parameters","Docker Compose - add NET_RAW capability","[UNIC-966] Fix create and update operation in PATCH","Fix update tag in PATCH and apply-template","[UNIC-1657] Set found subtree isSelected to true.","[UNIC-1746] Swagger: fix custom operational path","[UNIC-1737] Fix synchronization of datastore from DatabaseDOMDataBroker","Fix sending netconf or gnmi mount body with param schema-cache-directory set to \"\" (empty string)","[UNIC-1744] UC Shell: Fix show on choice nodes"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1710] CLI health-check","Added 13.* version support for ARRIS devices"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Switch to Exificient","[UNIC-397] Improve error message for keys in payload.","[UNIC-1038] Rewrite Dockerfile","[UNIC-1735] Improve gnmi list deserialization","Refactor crypto mount parameter to device-crypto in java client side.","Cleanup dependencies","Swagger - use oneOf for choice nodes"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump com.puppycrawl.tools:checkstyle from 10.16.0 to 10.17.0","build(deps): bump commons-cli:commons-cli from 1.7.0 to 1.8.0","build(deps): bump grpc.version from 1.63.0 to 1.64.0","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.21 to 2.2.22","build(deps): bump maven.core.version from 3.9.6 to 3.9.7","build(deps): bump org.apache.commons:commons-compress from 1.26.1 to 1.26.2","build(deps): bump org.apache.maven.plugins:maven-invoker-plugin from 3.6.1 to 3.7.0","build(deps): bump org.codehaus.mojo:build-helper-maven-plugin from 3.5.0 to 3.6.0","build(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.2.0 to 3.3.0","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 1.9.23 to 1.9.24","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 1.9.24 to 2.0.0","build(deps): bump org.owasp:dependency-check-maven from 9.1.0 to 9.2.0","build(deps): bump org.springframework.boot:spring-boot-dependencies from 3.1.11 to 3.1.12","Docker scout CVE fixes","Embedded PostgreSQL 16","Remove unused dependency - objenesis","Revert \"Use Embedded Postgres version 16 (#2419)\"","Update wrapper script and mvnw to version 3.3.1","Use Embedded Postgres version 16"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.4-SNAPSHOT.","Clean up constants","Update dependabot.yml","Revert protocol uppercase back to lowercase.","Fix typo"]}],[{"i":"uniconfig-605","l":"Uniconfig 6.0.5"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1739] - Fix advisory session unlocking (#2467)","[UNIC-1743] Create calculate-diff-shell rpc. (#2468)","[UNIC-1751] Fix mount operation duplication in the same tx (#2460)","[UNIC-1753] Multiple gnmi notification fixes for IOS Xr7 (#2483)","[UNIC-1754] Fix yang-patch rfc8040 error response (#2489)","[UNIC-1756] Fix wrong snmp connection establishment","[UNIC-1758] Database error: Failed to update node YANG repository because repository does not exist in DB","[UNIC-1763] Swagger: Fix generation of action nodes and tags (#2525)","[UNIC-1771] Refresh schemactx","[UNIC-883] Fix DB tx exception handling","Fix augmentation qname handling","Fix cli session closeup","Fix default reading properties (#2527)","Fix traefik changing URL query param from ; to & (#2514)","Fixed JUNOS version 13 installation","Swagger - add module name to choice schema node definition (#2541)","Swagger: Fix missing cli topology in path parameters (#2480)"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Add banner to logs (#2509)"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Fix verify and merge wfs","Bump to 6.0.5-SNAPSHOT.","[UNIC-1764] Support to optionally wrap cases in choice node (#2539)","Release 6.0.5."]}],[{"i":"uniconfig-606","l":"Uniconfig 6.0.6"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1778] Fix journal size dispatch","Fix merge concurrency group","[UNIC-1775] Improve generic PromptResolutionStrategy","[UNIC-1781] Skip nested constraints in union type (#2573)","Interrupt task when its tx has been expired (#2589)","[UNIC-1789] Complex types constraints skipping (#2592)","[UNIC-1784] Fix checked-commit no rollback (#2593)"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump maven.core.version from 3.9.7 to 3.9.8 (#2529)","build(deps): bump org.owasp:dependency-check-maven from 9.2.0 to 10.0.0","Bump odc to 10.0.2"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.6-SNAPSHOT.","Release 6.0.6."]}],[{"i":"uniconfig-607","l":"Uniconfig 6.0.7"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1798] - Complex changes in SkipConstraintJSONCodecFactory (#2607)","Fix cleaning expired tasks"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.7-SNAPSHOT.","Release 6.0.7."]}],[{"i":"uniconfig-608","l":"Uniconfig 6.0.8"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1801] Fix health-check clash with un/mounting process","[UNIC-1804] Fix transaction timestamp","[UNIC-1808] Commit fail on metadata update","[UNIC-1814] Fix template auto-upgrade"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1812] Implement casa init unit."]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.8-SNAPSHOT.","Release 6.0.8."]}],[{"i":"uniconfig-609","l":"Uniconfig 6.0.9"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1823] Add path to error for invalid value (#2667)"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.9-SNAPSHOT.","Release 6.0.9."]}],[{"i":"uniconfig-610","l":"Uniconfig 6.1.0"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1728] Fix reading of sample VNF config from netconf-testtool","Add missing dependencies to testtool","Swagger - add missing namespace when node is augmenting on deeper level","SwaggerUI - show extensions","Fix gnmi missing schemaContext handling","Swagger - fix required statement","Swagger - fix url parameters","Docker Compose - add NET_RAW capability","[UNIC-966] Fix create and update operation in PATCH","Fix update tag in PATCH and apply-template","[UNIC-1657] Set found subtree isSelected to true.","[UNIC-1746] Swagger: fix custom operational path","[UNIC-1737] Fix synchronization of datastore from DatabaseDOMDataBroker","Fix sending netconf or gnmi mount body with param schema-cache-directory set to \"\" (empty string)","[UNIC-1744] UC Shell: Fix show on choice nodes"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1710] CLI health-check","Added 13.* version support for ARRIS devices"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Switch to Exificient","[UNIC-397] Improve error message for keys in payload.","[UNIC-1038] Rewrite Dockerfile","[UNIC-1735] Improve gnmi list deserialization","Refactor crypto mount parameter to device-crypto in java client side.","Cleanup dependencies","Swagger - use oneOf for choice nodes"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump com.puppycrawl.tools:checkstyle from 10.16.0 to 10.17.0","build(deps): bump commons-cli:commons-cli from 1.7.0 to 1.8.0","build(deps): bump grpc.version from 1.63.0 to 1.64.0","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.21 to 2.2.22","build(deps): bump maven.core.version from 3.9.6 to 3.9.7","build(deps): bump org.apache.commons:commons-compress from 1.26.1 to 1.26.2","build(deps): bump org.apache.maven.plugins:maven-invoker-plugin from 3.6.1 to 3.7.0","build(deps): bump org.codehaus.mojo:build-helper-maven-plugin from 3.5.0 to 3.6.0","build(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.2.0 to 3.3.0","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 1.9.23 to 1.9.24","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 1.9.24 to 2.0.0","build(deps): bump org.owasp:dependency-check-maven from 9.1.0 to 9.2.0","build(deps): bump org.springframework.boot:spring-boot-dependencies from 3.1.11 to 3.1.12","Docker scout CVE fixes","Embedded PostgreSQL 16","Remove unused dependency - objenesis","Revert \"Use Embedded Postgres version 16 (#2419)\"","Update wrapper script and mvnw to version 3.3.1","Use Embedded Postgres version 16"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.4-SNAPSHOT.","Clean up constants","Update dependabot.yml","Revert protocol uppercase back to lowercase.","Fix typo","Release 6.1.0."]}],[{"i":"uniconfig-611","l":"Uniconfig 6.1.1"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1739] - Fix advisory session unlocking","[UNIC-1751] Fix mount operation duplication in the same tx","[UNIC-1753] Multiple gnmi notification fixes for IOS Xr7","[UNIC-1754] Fix yang-patch rfc8040 error response","[UNIC-1756] Fix wrong snmp connection establishment","[UNIC-1758] Database error: Failed to update node YANG repository because repository does not exist in DB","[UNIC-1763] Swagger: Fix generation of action nodes and tags","[UNIC-1771] Fix register-repository","[UNIC-883] Fix DB tx exception handling","Fix 'End of input' exception on netconf session.close()","Fix augmentation qname handling","Fix cli session closeup","Fix default reading properties","Fix traefik changing URL query param from ; to &","Fixed JUNOS version 13 installation (#2485)","Support check-nodes-connection for southbound only","Swagger: Fix missing cli topology in path parameters","Swagger: Fix missing snmp topology in path parameters"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1580] - Integration of 'fields' query parameter into NETCONF subtree filtering","[UNIC-1762] Bulk-get RPC"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1743] Create calculate-diff-shell rpc.","Add banner to logs","[UNIC-1761] Fix time range in gnmi streaming","[UNIC-1400] Refactor and extract uniconfig diff","Package logback cluster configuration","Swagger - add module name to choice schema node definition"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump org.apache.maven.plugin-tools:maven-plugin-annotations from 3.13.0 to 3.13.1","build(deps): bump com.github.spotbugs:spotbugs-annotations from 4.8.5 to 4.8.6","build(deps): bump com.google.errorprone:error_prone_annotations from 2.27.1 to 2.28.0","build(deps): bump com.google.errorprone:error_prone_core from 2.27.1 to 2.28.0","build(deps): bump com.google.guava:guava from 33.2.0-jre to 33.2.1-jre","build(deps): bump commons-net:commons-net from 3.10.0 to 3.11.0","build(deps): bump commons-net:commons-net from 3.11.0 to 3.11.1","build(deps): bump docker/build-push-action from 5 to 6","build(deps): bump docker/login-action from 3.1.0 to 3.2.0","build(deps): bump io.github.git-commit-id:git-commit-id-maven-plugin from 8.0.2 to 9.0.0","build(deps): bump jline.version from 3.26.1 to 3.26.2","build(deps): bump maven.core.version from 3.9.7 to 3.9.8","build(deps): bump org.apache.maven.plugins:maven-checkstyle-plugin from 3.3.1 to 3.4.0","build(deps): bump org.apache.maven.plugins:maven-clean-plugin from 3.3.2 to 3.4.0","build(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.6.1 to 3.7.0","build(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.7.0 to 3.7.1","build(deps): bump org.apache.maven.plugins:maven-enforcer-plugin from 3.4.1 to 3.5.0","build(deps): bump org.apache.maven.plugins:maven-failsafe-plugin from 3.2.5 to 3.3.0","build(deps): bump org.apache.maven.plugins:maven-jar-plugin from 3.4.1 to 3.4.2","build(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.3 to 3.7.0","build(deps): bump org.apache.maven.plugins:maven-plugin-plugin from 3.13.0 to 3.13.1","build(deps): bump org.apache.maven.plugins:maven-project-info-reports-plugin from 3.5.0 to 3.6.0","build(deps): bump org.apache.maven.plugins:maven-release-plugin from 3.0.1 to 3.1.0","build(deps): bump org.apache.maven.plugins:maven-shade-plugin from 3.5.3 to 3.6.0","build(deps): bump org.apache.maven.plugins:maven-surefire-plugin from 3.2.5 to 3.3.0","build(deps): bump org.checkerframework:checker-qual from 3.43.0 to 3.44.0"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.1.1-SNAPSHOT.","[UNIC-1764] Support to optionally wrap cases in choice node","Release 6.1.1."]}],[{"i":"uniconfig-612","l":"Uniconfig 6.1.2"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1778] Fix journal size dispatch","[UNIC-1775] Improve generic PromptResolutionStrategy","Fix class cast exception when getting direct child.","Fix UC Shell remove redundant findNode step.","[UNIC-1781] Skip nested constraints in union type","Interrupt task when its tx has been expired","[UNIC-1789] Complex types constraints skipping","[UNIC-1784] Fix checked-commit no rollback"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Added a path field to notification","[UNIC-1783] - Adjust bulk-get output"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump actions/download-artifact from 4.1.7 to 4.1.8","build(deps): bump actions/setup-python from 5.1.0 to 5.1.1","build(deps): bump actions/upload-artifact from 4.3.3 to 4.3.4","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.5.0 to 4.8.6.1","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.6.1 to 4.8.6.2","build(deps): bump grpc.version from 1.64.0 to 1.65.0","build(deps): bump grpc.version from 1.65.0 to 1.65.1","build(deps): bump io.github.git-commit-id:git-commit-id-maven-plugin from 9.0.0 to 9.0.1","build(deps): bump org.apache.maven.plugins:maven-failsafe-plugin from 3.3.0 to 3.3.1","build(deps): bump org.apache.maven.plugins:maven-project-info-reports-plugin from 3.6.0 to 3.6.1","build(deps): bump org.apache.maven.plugins:maven-project-info-reports-plugin from 3.6.1 to 3.6.2","build(deps): bump org.apache.maven.plugins:maven-release-plugin from 3.1.0 to 3.1.1","build(deps): bump org.apache.maven.plugins:maven-surefire-plugin from 3.3.0 to 3.3.1","build(deps): bump org.checkerframework:checker-qual from 3.44.0 to 3.45.0","build(deps): bump org.owasp:dependency-check-maven from 10.0.0 to 10.0.2","build(deps): bump org.owasp:dependency-check-maven from 9.2.0 to 10.0.0","build(deps): bump org.springdoc:springdoc-openapi-starter-webmvc-ui from 2.5.0 to 2.6.0","build(deps): bump tech.pantheon.triemap:triemap from 1.3.1 to 1.3.2"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.1.2-SNAPSHOT.","Switch vulnscan workflow stable branch","Remove mdsal-binding-util","Update spotbugs-exclude.xml","Release 6.1.2."]}],[{"i":"uniconfig-613","l":"Uniconfig 6.1.3"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1798] - Complex changes in SkipConstraintJSONCodecFactory","Fix cleaning expired tasks"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump sshd.version from 2.12.1 to 2.13.1","build(deps): bump com.google.errorprone:error_prone_annotations from 2.28.0 to 2.29.2","build(deps): bump com.google.errorprone:error_prone_core from 2.28.0 to 2.29.2","build(deps): bump jline.version from 3.26.2 to 3.26.3","build(deps): bump org.owasp:dependency-check-maven from 10.0.2 to 10.0.3","build(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.7.0 to 3.8.0","build(deps): bump docker/login-action from 3.2.0 to 3.3.0","Update Kafka to 3.7.1","build(deps): bump io.zonky.test.postgres:embedded-postgres-binaries-linux-amd64 from 16.2.0 to 16.3.0"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.1.3-SNAPSHOT.","Release 6.1.3."]}],[{"i":"uniconfig-614","l":"Uniconfig 6.1.4"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1801] Fix health-check clash with un/mounting process","[UNIC-1804] Fix transaction timestamp","[UNIC-1813] Fix replace-config-with-snapshot","[UNIC-1808] Commit fail on metadata update","[UNIC-1811] Fix loading yang repository in bulk-get cluster","[UNIC-1814] Fix template auto-upgrade (#2648)","Change log level in GlobalDOMSchemaServiceImpl"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1786] Open prometheus endpoint in actuator.","[UNIC-1786] Rewrite UniConfig metrics to micrometer.","[UNIC-1806] TopologyNode based data-broker","[UNIC-1812] Implement casa init unit.","[UNIC-1803] Local Uniconfig deployment in minikube(kubernets cluster)"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump antlr4.version from 4.13.1 to 4.13.2","build(deps): bump sshd.version from 2.13.1 to 2.13.2","build(deps): bump org.checkerframework:checker-qual from 3.45.0 to 3.46.0","build(deps): bump actions/upload-artifact from 4.3.4 to 4.3.5","build(deps): bump com.google.errorprone:error_prone_annotations from 2.29.2 to 2.30.0","build(deps): bump actions/upload-artifact from 4.3.5 to 4.3.6","build(deps): bump org.apache.commons:commons-compress from 1.26.2 to 1.27.0","build(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.3.0 to 3.4.0","build(deps): bump com.google.errorprone:error_prone_core from 2.29.2 to 2.30.0","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 2.0.0 to 2.0.10","build(deps): bump io.zonky.test.postgres:embedded-postgres-binaries-linux-amd64 from 16.3.0 to 16.4.0","build(deps): bump grpc.version from 1.65.1 to 1.66.0"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.1.4-SNAPSHOT.","Readme update regarding topology-node data brokers","Release 6.1.4."]}],[{"i":"uniconfig-615","l":"Uniconfig 6.1.5"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1823] Add path to error for invalid value","Fix show_uniconfig_status.sh","[UNIC-1618] Attempt to install vnf20 device (10.103.5.202) with snmp v3 fail","[UNIC-1817] Fix synchronization of collecting nested tx db writers","[UNIC-961] Option to add tag to leaf without providing value"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1805] Rewrite Uniconfig healthcheck using Spring Boot actuator.","[UNIC-1732] Asynchronous apply-template RPC","Clean up code related to old health rpc impl.","Fix error exposing internal info","Move checking db into readiness health indicator.","Reimplementing rpc health with spring healthcheck logic"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump commons-cli:commons-cli from 1.8.0 to 1.9.0","build(deps): bump com.google.guava:guava from 33.2.1-jre to 33.3.0-jre","build(deps): bump org.apache.maven.plugins:maven-surefire-plugin from 3.3.1 to 3.4.0","build(deps): bump org.apache.maven.plugins:maven-failsafe-plugin from 3.3.1 to 3.4.0","build(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.4.0 to 3.4.1","build(deps): bump org.apache.maven.plugins:maven-plugin-plugin from 3.13.1 to 3.14.0","build(deps-dev): bump org.apache.maven.plugin-tools:maven-plugin-annotations from 3.13.1 to 3.14.0","build(deps): bump maven.core.version from 3.9.8 to 3.9.9","build(deps): bump org.apache.maven.plugins:maven-project-info-reports-plugin from 3.6.2 to 3.7.0","build(deps): bump com.puppycrawl.tools:checkstyle from 10.17.0 to 10.18.0","build(deps): bump org.apache.maven.plugins:maven-checkstyle-plugin from 3.4.0 to 3.5.0","build(deps): bump org.apache.maven.plugins:maven-invoker-plugin from 3.7.0 to 3.8.0","build(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.7.1 to 3.8.0","build(deps): bump org.apache.commons:commons-compress from 1.27.0 to 1.27.1","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 2.0.10 to 2.0.20"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.1.5-SNAPSHOT.","[UNIC-1820] - Fix local-as command for IOS device","Release 6.1.5."]},{"l":"New Contributors"}],[{"i":"uniconfig-616","l":"Uniconfig 6.1.6"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["Fix EscapedKeysUriFormatter","[UNIC-1830] Fix constraint check skip for clients","Add TUs for \"default-route-distance\" container (#2712)","[UNIC-1837] Remove exception throwing when auto templates-upgrader fails","[UNIC-1839] Remove key from list edit in bulk edit rpc."]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1828] Log template name and optionally path to config(if presen…"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Fix verify and merge workflows","Bump to 6.1.6-SNAPSHOT.","Fix find_changed_code_verify.sh for stable","Fix find_changed_code_merge.sh for stable","Release 6.1.6."]}],[{"i":"uniconfig-700","l":"Uniconfig 7.0.0"},{"i":"whats-changed","l":"What's Changed"},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["7.0.x","Fix wfs","Prepare for new stable branch and new main branch with v7 of uniconfig","Release 7.0.0.","Fix release.yml","Update release.yml"]}],[{"i":"uniconfig-701","l":"Uniconfig 7.0.1"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1830] Fix constraint check skip for clients","[UNIC-1828] Log template name and optionally path to config(if present in the origin exception)","Add TUs for \"default-route-distance\" container","[UNIC-1835] Fix configuration meter filter","[UNIC-1837] Remove exception throwing when auto templates-upgrader fails","[UNIC-1839] Remove key from list edit in bulk edit rpc."]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Move the metrics initialization before the initialization of beans that register metrics to ensure the filter is applied first."]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["Add dependency management for version declarations of missing maven p…","build(deps-dev): bump org.apache.maven.plugin-tools:maven-plugin-annotations from 3.14.0 to 3.15.0","build(deps): bump actions/setup-python from 5.1.1 to 5.2.0","build(deps): bump actions/upload-artifact from 4.3.6 to 4.4.0","build(deps): bump com.github.gantsign.maven:ktlint-maven-plugin from 3.2.0 to 3.3.0","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.6.2 to 4.8.6.3","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.6.3 to 4.8.6.4","build(deps): bump com.google.errorprone:error_prone_annotations from 2.30.0 to 2.31.0","build(deps): bump com.google.errorprone:error_prone_annotations from 2.31.0 to 2.32.0","build(deps): bump com.google.errorprone:error_prone_core from 2.30.0 to 2.31.0","build(deps): bump com.google.errorprone:error_prone_core from 2.31.0 to 2.32.0","build(deps): bump com.google.protobuf:protobuf-java from 3.25.3 to 3.25.5 in /commons/parents/odlparent","build(deps): bump com.puppycrawl.tools:checkstyle from 10.18.0 to 10.18.1","build(deps): bump commons-io:commons-io from 2.16.1 to 2.17.0","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.22 to 2.2.23","build(deps): bump jline.version from 3.26.3 to 3.27.0","build(deps): bump org.apache.maven.plugins:maven-failsafe-plugin from 3.4.0 to 3.5.0","build(deps): bump org.apache.maven.plugins:maven-help-plugin from 3.4.1 to 3.5.0","build(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.8.0 to 3.10.0","build(deps): bump org.apache.maven.plugins:maven-plugin-plugin from 3.14.0 to 3.15.0","build(deps): bump org.apache.maven.plugins:maven-surefire-plugin from 3.4.0 to 3.5.0","build(deps): bump org.checkerframework:checker-qual from 3.46.0 to 3.47.0","build(deps): bump org.owasp:dependency-check-maven from 10.0.3 to 10.0.4","build(deps): bump org.springframework.boot:spring-boot-dependencies from 3.3.3 to 3.3.4"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 7.0.1-SNAPSHOT","dependency-check - Suppress FP and clean up unused rule","Document stable branch creation process","Improve logback for kubernetes clustered deployment","Add profiling image of Uniconfig","Release 7.0.1."]}],[{"l":"Translation Units","p":["This repository contains documentation for all available translation units for the FRINX ODL CLI service module. A translation unit is a piece of code that includes handlers to read from or write to a specific device (e.g. Cisco IOS classic router) and facilitates the translation in OpenConfig models. The purpose of this documentation is to see which commands can be read and set and how they map to the respective YANG models. Every section has a README file that provides an overview of all show and configuration commands that are supported. Multiple translation units are finally packaged together and made available as a karaf feature that can be installed at runtime."]},{"l":"Table of Contents","p":["URL","URL Operations","GET","PUT","DELETE","OPERATIONAL datasets","OPENCONFIG YANG","OS COMMANDS","DEVICE YANG","UNIT","CONFIGURATION datasets"]},{"l":"URL","p":["can be either cli or unified","each list item argument MUST be followed by list key. Usually the key is mapped to just one leaf (identifier, name, etc.), but in some cases, the key is created using more leafs. In this case, in the URL, the keys follow each other in order specified by YANG.","Each URL has a base format:","Example:","for each container or list in YANG model, there MUST be an argument in the URL","if the URL is tied with a body, the top-level element in the body must be the last element in the URL","Let's say you want to be even more specific and list details just about one particular interface. You can view the data by adding 'interface=' to the URL.","Let's say you want to list all areas in a specific OSPF. To obtain this data, you can trim the part: '/area=/interfaces' from the URL.","mountpoint name","network-instances argument is a list. We want to specify one item from that list (specific network instance), therefore the URL continues with ‘network-instance'. The key in network-instance is the identifier '' (e.g. vrf1) which follows the list item argument. Complex key is needed for protocol argument. The key is protocol-type followed by process-id. (frinx-openconfig-policy-types:OSPF, )","same for 'area='","Simplified example:","The general steps in creating the URL are following:","the top level argument must contain the name of the model. The name of the model must also be specified for YANG identities.","the URL contains an identity which is a part of a key for protocol list. This identity is prefixed by model name: ‘frinx-openconfig-policy-types:OSPF’","The URL will always point to either operational or config datastore and to the node we want to get the information from. You can always check if the particular device is registered by issuing GET on :","top-level argument contains also YANG model name: ‘frinx-openconfig-network-instance’","URLs are modular. By changing the URL you can move along the YANG data tree.","very specific URL listing interfaces under one specific area in OSPF under specific VRF","You can create a minimalistic YANG tree out of the URL:"]},{"l":"URL Operations","p":["Each show command supports only one http operation: GET ."]},{"l":"GET","p":["GET operation can be issued on both config/operational datastore. Config datastore reflects how the device is configured. Operational datastore reflects the state of the device. In most cases the information is the same.","Example of a case where the information is not the same (the only difference in requests is config vs operational):","Configuration commands support PUT for create/replace data. This operation requires HTTP body, which contains openconfig YANG model of the configuration you want to send to the router. Another operation supported by configuration commands is DELETE, which removes data from the device. Both operations need to be issued on config datastore.","For modifications of the data, you can use also PATCH method, that does not replace the entire data structure, only the parts that are different.","Example:","We want to create a new BGP neighbor:","The IOS command is:"]},{"l":"PUT","p":["BODY:","WARNING: PUT operation does not merge data. In this example if you have already configured some BGP neighbors, this request will REMOVE all of them and create just the one described in the PUT body. The solution is to first issue GET, copy existing configuration and add/change items there, or use PATCH method.","If we want to DELETE a BGP neighbor, the body is not needed, the URL needs to be specific to the neighbor we want to delete:"]},{"l":"DELETE","p":["This operation will issue following command:","DELETE operation always removes the last argument of the URL."]},{"l":"OPERATIONAL datasets","p":["Go to operational datasets","Show commands are commands that usually on Cisco device start with 'show'. The aim is to obtain data from the router."]},{"i":"url-1","l":"URL","p":["GET operation issued on operational datastore"]},{"l":"OPENCONFIG YANG","p":["In case of show commands this section is a sample output of a particular show command."]},{"l":"OS COMMANDS","p":["In this section we list the actual router commands with sample outputs, where the data obtained and transformed into Openconfig YANG is marked as bold. We list show commands and outputs for each supported device OS.","IOS XR | IOS Classic/XE | Junos | SAOS"]},{"l":"DEVICE YANG","p":["In case of CLI units, the unit parses the output of the CLI command directly into OC YANG. In case of Netconf units, the output is mapped to OC YANG through Device YANG (YANG model supported by the device). In case of Netconf units, the YANG is also written in documentation. This section is a link to XML unit test input testing this operation."]},{"l":"UNIT","p":["Link to github code where this show commmand is implemented along with unit version range."]},{"l":"CONFIGURATION datasets","p":["Go to configuration datasets"]},{"i":"url-2","l":"URL","p":["PUT operation with given URL will result in creating of data in config datastore DELETE operation with given URL will result in removing data in config datastore"]},{"i":"openconfig-yang-1","l":"OPENCONFIG YANG","p":["In case of configuration commands, this section represents the HTTP body in PUT operation"]},{"i":"os-commands-1","l":"OS COMMANDS","p":["In this section we list the actual router commands that are mapped to the Openconfig YANG model. Data transformed into Openconfig YANG is marked as bold. We list commands for each supported device OS.","IOS XR | IOS Classic/XE | Junos | SAOS"]},{"i":"device-yang-1","l":"DEVICE YANG","p":["In case od Netconf units, the device yang represents command sent to the device in device YANG model. This section is a link to XML unit test input testing this configuration."]},{"i":"unit-1","l":"UNIT","p":["Link to github code where this config commmand is implemented along with unit version range."]}],[{"l":"IETF L2VPN YANG"},{"l":"Scenario"},{"i":"l2p2pvpws","l":"L2P2P/VPWS","p":["l2vpn-instance/type == vpws-instance-type only two endpoints"]},{"l":"Local-Local","p":["connection between two local ports on a host (pe-node-id`s of endpoints match)"]},{"i":"ietf--yang","l":"IETF YANG"},{"l":"OPENCONFIG YANG"},{"l":"pe01"}],[{"l":"IETF L2VPN YANG"},{"l":"Scenario"},{"i":"l2p2pvpws","l":"L2P2P/VPWS","p":["l2vpn-instance/type == vpws-instance-type only two endpoints"]},{"l":"Local-Remote","p":["connection between local and remote hosts (pe-node-id`s of endpoints do not match)"]},{"i":"ietf--yang","l":"IETF YANG"},{"l":"OPENCONFIG YANG"},{"l":"pe01"},{"l":"PE2"}],[{"l":"IETF L2VPN YANG"},{"l":"Scenario"},{"i":"l2p2pvpls","l":"L2P2P/VPLS","p":["l2vpn-instance/type == vpls-instance-type Two or more endpoints"]},{"i":"ietf--yang","l":"IETF YANG"},{"l":"OPENCONFIG YANG"},{"l":"pe01"},{"l":"pe02"},{"l":"pe03"}],[{"l":"IETF L3VPN YANG"},{"l":"IETF YANG"},{"l":"OPENCONFIG YANG"}],[{"i":"#","p":["Access control","ACL","ACL interfaces","BGP","CDP","connection point","connection point l2vpn","Discovery protocols","Ethernet interface","Ethernet OAM","Ethernet Virtual Circuit","Ethernet Virtual Private Network","EVC","EVPN","FDP","Hot Standby Router Protocol","HSRP","Interfaces","Internet Protocol Security","IPsec","IS-IS","L2P2P","L2VPN","L3 VLAN interface","L3VPN","l3vpn with BGP","l3vpn with OSPF","LAG interface","Monitoring","MPLS","MPLS LDP","MPLS TE","MPLS TE RSVP","MPLS Tunnel","NetFlow","NetFlow interfaces","Network Instance","Network Instances","OSPF","OSPFv3","PF interfaces","Policy Forwarding","Probes","Protocols","Quality of Service","Routing Policy","SNMP","Spanning Tree Protocol","STP","SYSLOG"]},{"l":"Interfaces"},{"l":"Ethernet interface"},{"l":"LAG interface"},{"l":"L3 VLAN interface"},{"l":"Network Instances"},{"l":"Network Instance"},{"l":"Protocols"},{"l":"BGP"},{"l":"OSPF"},{"l":"OSPFv3"},{"l":"IS-IS"},{"l":"MPLS"},{"l":"MPLS TE"},{"l":"MPLS Tunnel"},{"l":"MPLS TE RSVP"},{"l":"MPLS LDP"},{"l":"Policy Forwarding"},{"l":"PF interfaces"},{"l":"L2P2P"},{"l":"connection point"},{"l":"L2VPN"},{"l":"connection point l2vpn"},{"l":"L3VPN"},{"l":"l3vpn with BGP"},{"l":"l3vpn with OSPF"},{"l":"Discovery protocols"},{"l":"CDP"},{"l":"FDP"},{"l":"Monitoring"},{"l":"SNMP"},{"l":"SYSLOG"},{"l":"Probes"},{"l":"Ethernet OAM"},{"l":"Hot Standby Router Protocol"},{"l":"HSRP"},{"l":"Access control"},{"l":"ACL"},{"l":"ACL interfaces"},{"l":"Spanning Tree Protocol"},{"l":"STP"},{"l":"Routing Policy"},{"i":"routing-policy-1","l":"Routing Policy"},{"l":"NetFlow"},{"l":"NetFlow interfaces"},{"l":"Quality of Service"},{"i":"quality-of-service-1","l":"Quality of Service"},{"l":"Ethernet Virtual Private Network"},{"i":"ethernet-virtual-private-network-1","l":"Ethernet Virtual Private Network"},{"l":"Internet Protocol Security"},{"l":"IPsec"}],[{"l":"Access Control List"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534-ios-xr-662","l":"Cisco IOS XR 5.3.4, IOS XR 6.6.2"},{"l":"CLI"},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xe-1542s","l":"Cisco IOS XE 15.4(2)S"},{"i":"cli-1","l":"CLI"},{"l":"Examples"},{"i":"unit-1","l":"Unit","p":["Link to github : xe-unit"]},{"i":"junos-141x53-d408","l":"Junos 14.1X53-D40.8"},{"i":"cli-2","l":"CLI"},{"i":"unit-2","l":"Unit","p":["Link to github : junos-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-3","l":"CLI"},{"i":"unit-3","l":"Unit","p":["Link to github : junos-unit"]},{"i":"junos-182r1-s21","l":"Junos 18.2R1-S2.1"},{"i":"cli-4","l":"CLI","p":["iacl_intf_index, iacl_subintf_index is a conversion of set ."]},{"i":"unit-4","l":"Unit","p":["Link to github : junos-unit"]}],[{"l":"Access Control List"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"l":"Cisco IOS Classic"},{"l":"CLI","p":["ipv4|ipv6 is a conversion of* eq|neq|range * is a conversion of or , operation is selected by entered port range *eq|neq|range * is a conversion of or , operatioons is selected by entered port range | acl option could be defined by enumeration named options or by number in range 0-255 ** is a conversion of , when true, value is \"established\", when false, there is empty value \"\""]},{"l":"Examples"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"i":"cli-1","l":"CLI","p":["ipv4|ipv6 is a conversion of"]},{"i":"examples-1","l":"Examples"},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-662","l":"Cisco IOS XR 6.6.2"},{"i":"cli-2","l":"CLI","p":["ipv4|ipv6 is a conversion of"]},{"i":"examples-2","l":"Examples"},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xe-1542s","l":"Cisco IOS XE 15.4(2)S"},{"i":"cli-3","l":"CLI","p":["** is a conversion of , when true, value is \"established\", when false, there is empty value \"\""]},{"i":"examples-3","l":"Examples"},{"i":"unit-2","l":"Unit","p":["Link to github : xe-unit"]},{"i":"junos-141x53-d408","l":"Junos 14.1X53-D40.8"},{"i":"cli-4","l":"CLI"},{"i":"unit-3","l":"Unit","p":["Link to github : junos-unit"]},{"i":"ciena-saos-614","l":"Ciena SAOS 6.14"},{"i":"cli-5","l":"CLI","p":["conversion is ACCEPT = allow, DROP = deny* access-list disable profile * is a conversion of frinx-acl-extension:enabled set to false. Default value is true."]},{"i":"unit-4","l":"Unit","p":["Link to github : [saos-unit]"]}],[{"l":"cable DOWNSTREAM CONTROLLER-PROFILE"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"IOS XE 16"},{"l":"CLI","p":["can be either a single number or a list of numbers (0 31 which represents all the values from 0 to 31)"]},{"l":"Unit","p":["Link to github : ios-xe-unit"]}],[{"l":"cable FIBER-NODE"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"IOS XE 16"},{"l":"CLI","p":["and are in commands input with whitespace dividing name and number (Downstream-Cable 1/0/16)"]},{"l":"Unit","p":["Link to github : ios-xe-unit"]}],[{"l":"cable RPD"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"IOS XE 16"},{"l":"CLI","p":["and are in commands input with whitespace dividing name and number (Downstream-Cable 1/0/16)","no principal is a conversion of set false principal is a conversion of set true"]},{"l":"Unit","p":["Link to github : ios-xe-unit"]}],[{"l":"BRIDGE interface"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"IOS 12"},{"l":"CLI","p":["is parsed from example is BDI10 -> is 10","no shutdown is a conversion of set true shutdown is a conversion of set false no snmp trap link-status is a conversion of set false snmp trap link-status is a conversion of set true"]},{"l":"Unit","p":["Link to github : ios-unit"]}],[{"l":"CABLE interface"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"IOS XE 16"},{"l":"CLI","p":["are read from all lines and input into one attribute \"rf-channels\" and are in commands input with whitespace dividing name and number (Downstream-Cable 1/0/16)"]},{"l":"Unit","p":["Link to github : ios-xe-unit"]}],[{"l":"Ethernet interface"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI","p":["is a conversion of no shutdown is a conversion of set true shutdown is a conversion of set false switchport port-security is a conversion of set true no switchport port-security is a conversion of set false can be \"protect\", \"restrict\" or \"shutdown\" can be \"absolute\" or \"inactivity\" switchport port-security aging static is a conversion of set true no switchport port-security aging static is a conversion of set false lldp transmit is a conversion of set true no lldp transmit is a conversion of set false lldp receive is a conversion of set true no lldp receive is a conversion of set false negotiation auto is a conversion of set true no negotiation auto is a conversion of set false cdp enable is a conversion of set true no cdp enable is a conversion of set false is parsed from example is Port-channel3 -> is 3 mode on is a conversion of set to frinx-openconfig-lacp:ON can be \"default\" or \"rj45\" or \"sfp\" can be \"broadcast\" or \"multicast\" or \"unicast\"","is conversion of"]},{"l":"Unit","p":["Link to github : ios-unit"]},{"i":"cisco-ios-xe-15-16-17","l":"Cisco IOS XE 15, 16, 17"},{"i":"cli-1","l":"CLI","p":["is a conversion of no shutdown is a conversion of set true shutdown is a conversion of set false normal is a conversion of \"\" set \"NORMAL\" fast is a conversion of \"\" set \"FAST\" lldp transmit is a conversion of set true no lldp transmit is a conversion of set false lldp receive is a conversion of set true no lldp receive is a conversion of set false negotiation auto is a conversion of set true no negotiation auto is a conversion of set false is parsed from example is Port-channel3 -> is 3 mode on is a conversion of set to frinx-openconfig-lacp:ON can be \"default\" or \"rj45\" or \"sfp\" can be \"broadcast\" or \"multicast\" or \"unicast\" service instance trunk ethernet is conversion of set true* service instance ethernet * is conversion of set false* encapsulation untagged , dot1q * is conversion of set true* encapsulation dot1q * is conversion of set false can be \"ingress\" or \"egress\" can be \"pop\" or \"push\" or \"translate\" can be \"tunnel\" or \"peer\" or \"forward\" can be \"cdp\" or \"vtp\" or \"lacp\" or \"lldp\" or \"mmrp\" or \"mvrp\" or \"stp\" or \"RB\" or \"RC\" or \"RD\" or \"RF\""]},{"i":"unit-1","l":"Unit","p":["Link to github : ios-xe-unit"]},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"i":"cli-2","l":"CLI","p":["is parsed from example is Bundle-Ether100 -> is 100","no shutdown is a conversion of set true shutdown is a conversion of set false is a conversion of no dampening is a conversion of set false lacp period short is a conversion of set to frinx-openconfig-lacp:FAST no lacp period short is a conversion of set to frinx-openconfig-lacp:SLOW if is not specified then command bundle id mode on is used mode active is a conversion of set to frinx-openconfig-lacp:ACTIVE mode passive is a conversion of set to frinx-openconfig-lacp:PASSIVE ipv6 nd suppress-ra is a conversion of set true","is conversion of"]},{"i":"unit-2","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-623","l":"Cisco IOS XR 6.2.3"},{"i":"cli-3","l":"CLI","p":["is parsed from example is Bundle-Ether100 -> is 100","no shutdown is a conversion of set true shutdown is a conversion of set false no dampening is a conversion of set false lacp period short is a conversion of set to frinx-openconfig-lacp:FAST no lacp period short is a conversion of set to frinx-openconfig-lacp:SLOW if is not specified then command bundle id mode on is used mode active is a conversion of set to frinx-openconfig-lacp:ACTIVE mode passive is a conversion of set to frinx-openconfig-lacp:PASSIVE","is conversion of"]},{"i":"cisco-ios-xr-661","l":"Cisco IOS XR 6.6.1"},{"i":"cli-4","l":"CLI","p":["is parsed from example is Bundle-Ether100 -> is 100","no shutdown is a conversion of set true shutdown is a conversion of set false is a conversion of no dampening is a conversion of set false lacp period short is a conversion of set to frinx-openconfig-lacp:FAST no lacp period short is a conversion of set to frinx-openconfig-lacp:SLOW if is not specified then command bundle id mode on is used mode active is a conversion of set to frinx-openconfig-lacp:ACTIVE mode passive is a conversion of set to frinx-openconfig-lacp:PASSIVE","is conversion of"]},{"i":"unit-3","l":"Unit","p":["Link to github : xr-unit"]},{"i":"junos-141x53-d408","l":"Junos 14.1X53-D40.8"},{"i":"cli-5","l":"CLI","p":["vlan-tagging is a conversion of set TPID_0X8100 delete interfaces disable is a conversion of set true set interfaces disable is conversion of set false","set interfaces unit disable is conversion of set false delete interfaces unit disable is a conversion of set true"]},{"i":"unit-4","l":"Unit","p":["Link to github : junos-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-6","l":"CLI","p":["is parsed from example is ae100 -> is 100","delete interfaces disable is a conversion of set true set interfaces disable is conversion of set false"]},{"i":"unit-5","l":"Unit","p":["Link to github : junos-unit"]},{"i":"junos-182r1-s21","l":"Junos 18.2R1-S2.1"},{"i":"cli-7","l":"CLI","p":["delete interfaces disable is a conversion of set true set interfaces disable is conversion of set false In the case of set interfaces ms-x/x/x, set iana-if-type:other instead of iana-if-type:ethernetCsmacd","delete interfaces unit disable is a conversion of set true set interfaces unit disable is conversion of set false"]},{"i":"unit-6","l":"Unit","p":["Link to github : junos-unit"]},{"i":"brocade-v560ft163","l":"Brocade (V5.6.0fT163)"},{"i":"cli-8","l":"CLI","p":["enable is a conversion of set true disable is a conversion of set false"]},{"i":"unit-7","l":"Unit","p":["Link to github : brocade-unit"]},{"i":"huawei-ne5000e-v800r009c10spc310","l":"Huawei NE5000E (V800R009C10SPC310)"},{"i":"cli-9","l":"CLI","p":["is conversion of \"\" inbound, outbound is a conversions of \"\" trust dscp is a conversion of \"\" set true"]},{"i":"unit-8","l":"Unit","p":["Link to github : huawei-unit"]},{"i":"dasan-nos-sfurr56p5","l":"Dasan NOS SFU.RR.5.6p5"},{"i":"cli-10","l":"CLI","p":["is parsed from example is Ethernet1/1 -> is 1/1","is parsed from example is Bundle-Ether100 -> is 100","* port enable * is a conversion of set true* port disable * is a conversion of set false lacp port timeout short is a conversion of set to frinx-openconfig-lacp:FAST no lacp port timeout short is a conversion of set to frinx-openconfig-lacp:SLOW"]},{"i":"unit-9","l":"Unit","p":["Link to github : dasan-unit"]},{"i":"ciena-saos-614","l":"Ciena SAOS 6.14"},{"i":"cli-11","l":"CLI","p":["* port enable port * is a conversion of set true* port disable port * is a conversion of set false can be \"default\" or \"rj45\" or \"sfp\" vs-ingress-filter on is a conversion of set true vs-ingress-filter off is a conversion of set false can be \"all\", \"tagged-only\", \"untagged-only\" can be \"Default-RCOS\" or \"NNI-NNI\" forward-unlearned on is a conversion of set true forward-unlearned off is a conversion of set false resolved-cos-remark-l2 true is a conversion of set true resolved-cos-remark-l2 false is a conversion of set false","from usual range (max 4094)","can be \"all\" or \"vlan-tpid\"","l2-cft enable port is a conversion of set to true l2-cft disable port is a conversion of set to false","rstp enable port is a conversion of set to true rstp disable port is a conversion of set to false mstp enable port is a conversion of set to true mstp disable port is a conversion of set to false","port set port auto-neg on is a conversion of set to true port set port auto-neg off is a conversion of set to false can be auto, ten, hundred, gigabit, ten-gig"]},{"i":"unit-10","l":"Unit","p":["Link to github : saos-unit"]},{"l":"Ciena SAOS 8"},{"i":"cli-12","l":"CLI","p":["can be between 0 and 96","port set port auto-neg on is a conversion of set to true port set port auto-neg off is a conversion of set to false can be auto, ten, hundred, gigabit, ten-gig, forty-gig, hundred-gig"]},{"i":"unit-11","l":"Unit","p":["Link to github : saos-unit"]},{"i":"arris-cer-arris-e6000","l":"Arris CER (Arris E6000)"},{"i":"cli-13","l":"CLI","p":["no shutdown is a conversion of set true shutdown is a conversion of set false"]},{"i":"unit-12","l":"Unit","p":["Link to github : cer-unit"]}],[{"l":"L2VLAN interface"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"Ciena SAOS8"},{"l":"CLI"},{"l":"Unit","p":["Link to github : saos-unit"]}],[{"l":"L3 VLAN interface"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"dasan-nos-sfurr56p5","l":"Dasan NOS SFU.RR.5.6p5"},{"l":"CLI","p":["is parsed from example is Vlan10 -> is 10","no shutdown is a conversion of set true shutdown is a conversion of set false no ip redirects is a conversion of set false ip redirects is a conversion of set true"]},{"l":"Unit","p":["Link to github : dasan-unit"]}],[{"i":"link-aggregation-group-bundle-interface","l":"Link Aggregation Group (bundle) interface"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"Cisco IOS XE","p":["track shutdown is a conversion of set true no track shutdown is a conversion of set false"]},{"l":"Unit","p":["Link to github : ios-unit"]},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)","p":["is conversion of"]},{"i":"unit-1","l":"Unit","p":["Link to github : ios-unit"]},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI","p":["is parsed from example is Bundle-Ether100 -> is 100","no shutdown is a conversion of set true shutdown is a conversion of set false is conversion of no dampening is a conversion of set false ipv6 nd suppress-ra is a conversion of set true"]},{"i":"unit-2","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-623","l":"Cisco IOS XR 6.2.3"},{"i":"cli-1","l":"CLI","p":["is parsed from example is Bundle-Ether100 -> is 100","no shutdown is a conversion of set true shutdown is a conversion of set false is conversion of no dampening is a conversion of set false ipv6 enable is a conversion of set true no ipv6 enable is a conversion of set false","is conversion of"]},{"i":"unit-3","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-661","l":"Cisco IOS XR 6.6.1"},{"i":"cli-2","l":"CLI","p":["is parsed from example is Bundle-Ether100 -> is 100 is parsed from example is aa:bb:cc:dd:ee:ff -> aabb.ccdd.eeff is parsed from example is aa:bb:cc:dd:ee:ff -> aabb.ccdd.eeff","is conversion of no shutdown is a conversion of set true shutdown is a conversion of set false no dampening is a conversion of set false","is parsed from example is Bundle-Ether100 -> is 100","is conversion of"]},{"i":"unit-4","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-662","l":"Cisco IOS XR 6.6.2"},{"i":"cli-3","l":"CLI","p":["is parsed from example is Bundle-Ether100 -> is 100","no shutdown is a conversion of set true shutdown is a conversion of set false is conversion of ethernet cfm is a conversion of set to true no ethernet cfm is a conversion of set to false"]},{"i":"unit-5","l":"Unit","p":["Link to github : xr-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-4","l":"CLI","p":["is parsed from example is ae100 -> is 100","delete interface ae disable is a conversion of set true set interface ae disable is conversion of set false","Device does not support damping on LAG interface."]},{"i":"unit-6","l":"Unit","p":["Link to github : junos-unit"]},{"i":"junos-182r1-s21","l":"Junos 18.2R1-S2.1"},{"i":"cli-5","l":"CLI","p":["is parsed from example is ae100 -> is 100","delete interface ae disable is a conversion of set true set interface ae disable is conversion of set false","inner_vlan_tag, outer_vlan_tag is a conversion of set . delete interface ae unit disable is a conversion of set true set interface ae unit disable is conversion of set false rpm_ifc_index , rpm_subintf_index is a conversion of set ."]},{"i":"unit-7","l":"Unit","p":["Link to github : junos-unit"]},{"i":"huawei-ne5000e-v800r009c10spc310","l":"Huawei NE5000E (V800R009C10SPC310)"},{"i":"cli-6","l":"CLI","p":["is conversion of"]},{"i":"unit-8","l":"Unit","p":["Link to github : huawei-unit"]},{"i":"dasan-nos-sfurr56p5","l":"Dasan NOS SFU.RR.5.6p5"},{"i":"cli-7","l":"CLI","p":["is parsed from example is Bundle-Ether100 -> is 100 and prefix is Bundle-Ether Dasan supports two kinds of prefixes (Prefix is settled by lag type)","If the prefix of is 'Trunk', lag type is port trunking","If the prefix of is 'Bundle-Ether', lag type is lacp","vlan add br t/ tagged is only supported by port trunking vlan add br t/ untagged is only supported by port trunking"]},{"i":"unit-9","l":"Unit","p":["Link to github : dasan-unit"]},{"l":"Ciena SAOS8"},{"i":"cli-8","l":"CLI","p":["classifier-precedence is used as **. This field is mandatory in Ciena and unique withing parent-port. bin_count can be from \"0\" to \"96\". Default value is \"32\". when ** is set to true, then vlan-untagged-data is used in the the sub-port command. there is not possible to set vlan-untagged-data and vtag-stack both."]},{"i":"unit-10","l":"Unit","p":["Link to github : saos-unit"]},{"l":"Arris CER"},{"i":"cli-9","l":"CLI"},{"i":"unit-11","l":"Unit","p":["Link to github : cer-unit"]}],[{"l":"WIDEBAND interface"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"IOS XE 16"},{"l":"CLI"},{"l":"Unit","p":["Link to github : ios-xe-unit"]}],[{"i":"internet-protocol-security-ipsec","l":"Internet Protocol Security (IPsec)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"nokia-sros-160","l":"NOKIA SROS 16.0"},{"l":"CLI","p":["no shutdown is a conversion of set to true shutdown is a conversion of set to false"]}],[{"l":"NetFlow"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI","p":["Assumption is that monitor map and sampler map configuration already exist on a device."]},{"l":"Unit","p":["Link to github : xr-unit"]}],[{"l":"L2P2P configuration"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"cisco-ios-vios-1562t","l":"Cisco IOS (VIOS 15.6(2)T)"},{"l":"CLI","p":["If connection points remote and local without subif","If connection points remote and local with subif","If both connection points are type local without subif","If both connection points are type local with subif"]},{"l":"Unit","p":["Link to github : ios-unit"]},{"i":"cisco-ios-xr-513-612","l":"CISCO IOS XR (5.1.3) (6.1.2)"},{"i":"cli-1","l":"CLI","p":["If connection point type remote","If connection point type local without subif","If connection point type local with subif (for XRv 5.1.3)","If connection point type local with subif (for XRv 6.1.2)","If both connection points are local we can use the same translation code as above .. the combined output will look like this example:"]},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]},{"i":"brocade-v560ft163","l":"Brocade (V5.6.0fT163)"},{"i":"cli-2","l":"CLI","p":["If connection point type remote","If connection point type local without subif","If both connection points are type local","With subif","If both connection points are type local without subif"]},{"i":"unit-2","l":"Unit","p":["Link to github : brocade-unit"]}],[{"i":"l2vpn-vpls-with-bgp-autodiscovery-configuration","l":"L2VPN (VPLS with BGP autodiscovery) configuration"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"cisco-ios-not-fully-tested-yet--vios-does-not-support-vpls","l":"Cisco IOS (not fully tested yet ... vIOS does not support VPLS)"},{"l":"CLI","p":["If connection point type remote","If connection point type local without subif","If connection point type local with subif"]},{"l":"Unit","p":["NOT IMPLEMENTED"]},{"i":"cisco-ios-xr-513-612","l":"CISCO IOS XR (5.1.3) (6.1.2)"},{"i":"cli-1","l":"CLI","p":["If connection point type remote","If connection point type local without subif","If connection point type local with subif (for XRv 5.1.3)","If connection point type local with subif (for XRv 6.1.2)"]},{"i":"unit-1","l":"Unit","p":["NOT IMPLEMENTED"]}],[{"i":"l2vsi-l2-virtual-switch-instance-virtual-circuit","l":"L2VSI (L2 virtual switch instance virtual circuit)","p":["Interconnects L2VSI with a vlan-based upstream path"]},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"ciena-saos-614","l":"Ciena SAOS 6.14"},{"l":"CLI","p":["statistics on is a conversion of set true statistics off is a conversion of set false"]},{"l":"Unit"}],[{"i":"l2vsi-l2-virtual-switch-instance","l":"L2VSI (L2 virtual switch instance)"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"ciena-saos-614","l":"Ciena SAOS 6.14"},{"l":"CLI","p":["can have values *l2-cft tagged-pvst-l2pt enable vs * is a conversion of \"tagged-pvst-l2pt\" field set to true *l2-cft tagged-pvst-l2pt disable vs * is a conversion of \"tagged-pvst-l2pt\" field set to false"]},{"l":"Ciena SAOS 8"},{"i":"cli-1","l":"CLI","p":["cpu-subinterface command is sent, if the type of the interface added is iana-if-type:l2vlan","sub-port command is sent, if the type of the interface added is iana-if-type:ieee8023adLag","** in this case needs to have form . This can be derived from : https://github.com/FRINXio/translation-units-docs/blob/master/Configuration%20datasets/interfaces/lag_interface.md"]}],[{"i":"l3vpn-configuration-bgp-as-ce-pe-protocol","l":"L3VPN configuration (BGP as CE-PE protocol)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["CONSTRAINTS Network-instance with name must exist before defined-sets or both must be created in the same transaction. Delete must be executed in reverse order or in the same transaction. Policy -route-target-import and -route-target-export must exist on device before are used in network-instance."]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-513-612","l":"CISCO IOS XR (5.1.3) (6.1.2)"},{"l":"CLI"},{"i":"cisco-ios-xr-661","l":"CISCO IOS XR (6.6.1)"},{"i":"cli-1","l":"CLI","p":["summary-only is a conversion of \"frinx-bgp-extension:summary-only\" set true"]},{"i":"cisco-ios-vios-1562t","l":"Cisco IOS (VIOS 15.6(2)T)"},{"i":"cli-2","l":"CLI"},{"i":"junos-182r1-s21","l":"Junos 18.2R1-S2.1"},{"i":"cli-3","l":"CLI"},{"i":"huawei-ne5000e-v800r009c10spc310","l":"Huawei NE5000E (V800R009C10SPC310)"},{"i":"cli-4","l":"CLI","p":["1 to 100000 is conversion of set \"frinx-huawei-network-instance-extension:prefix-limit-from\" 1 to 100 is conversion of set \"frinx-huawei-network-instance-extension:prefix-limit-to\""]},{"l":"Unit","p":["Link to github : huawei-unit"]}],[{"i":"l3vpn-configuration-ospf-as-ce-pe-protocol","l":"L3VPN configuration (OSPF as CE-PE protocol)"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-513-612","l":"CISCO IOS XR (5.1.3) (6.1.2)"},{"l":"CLI"},{"i":"cisco-ios-xr-623","l":"CISCO IOS XR (6.2.3)"},{"i":"cli-1","l":"CLI"},{"i":"cisco-ios-xr-661","l":"CISCO IOS XR (6.6.1)"},{"i":"cli-2","l":"CLI"},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-vios-1562t","l":"Cisco IOS (VIOS 15.6(2)T)"},{"i":"cli-3","l":"CLI"},{"i":"junos-141x53-d408","l":"Junos 14.1X53-D40.8"},{"i":"cli-4","l":"CLI","p":["virtual-router is a conversion of set L3VRF delete routing-instances protocols ospf area interface disable is a conversion of set true set routing-instances protocols ospf area interface disable is a conversion of set false set routing-instances protocols ospf area interface authentication is a conversion of set true delete routing-instances protocols ospf area interface authentication is a conversion of set false"]},{"i":"junos-182r1-s21","l":"Junos 18.2R1-S2.1"},{"i":"cli-5","l":"CLI"}],[{"i":"multiprotocol-label-switching---label-distribution-protocol-mpls-ldp","l":"Multiprotocol Label Switching - Label Distribution Protocol (MPLS LDP)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models","extensions to MPLS YANG model"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI","p":["\"enabled\" MUST be set to true when any ldp-configuration is pushed","\"enabled\" set to false, will ignore any additional configuration in the PUT request and will result in 'no mpls ldp'"]},{"l":"Unit","p":["Link to github : xr-unit"]}],[{"i":"multiprotocol-label-switching---resource-reservation-protocol-mpls-rsvp","l":"Multiprotocol Label Switching - Resource Reservation Protocol (MPLS RSVP)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models","extensions to MPLS YANG model"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4","p":["setting to default results in 'bandwidth' meaning setting default device bandwidth","setting to numeric value results in 'bandwith < number>","transformation: input bandwith in bps, in XR router as Kbps"]},{"l":"CLI"},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10","p":["transformation: k,m,g from JUNOS router translates to thousand, million, billion"]},{"i":"cli-1","l":"CLI"},{"i":"unit-1","l":"Unit","p":["Link to github : junos-unit"]}],[{"i":"multiprotocol-label-switching---traffic-engineering-mpls-te","l":"Multiprotocol Label Switching - Traffic Engineering (MPLS-TE)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models","extensions to MPLS YANG model"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI","p":["\"enabled\" MUST be set to true when any te-configuration is pushed","\"enabled\" set to false, will ignore any additional configuration in the PUT request and will result in 'no mpls traffic-eng'"]},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-1","l":"CLI"},{"i":"unit-1","l":"Unit","p":["Link to github : junos-unit"]}],[{"i":"multiprotocol-label-switching---tunnel","l":"Multiprotocol Label Switching - Tunnel"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models","extensions to MPLS YANG model"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI","p":["autoroute announce is a conversion of set true no autoroute announce is a conversion of set false load-share is not supported on virtual platform CISCO IOS-XR mpls_tunnel_destination is optional parameter metric absolute command is only valid if autoroute announce is set"]},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-1","l":"CLI","p":["* set protocols mpls label-switched-path * is a conversion of set true mpls_tunnel_destination is mandatory parameter"]},{"i":"unit-1","l":"Unit","p":["Link to github : junos-unit"]}],[{"l":"Interface policy configuration"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["policy-forwarding YANG model","extensions to policy-forwarding YANG model"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534-ios-xr-662","l":"Cisco IOS XR 5.3.4, IOS XR 6.6.2"},{"l":"CLI"},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-623","l":"Cisco IOS XR 6.2.3"},{"i":"cli-1","l":"CLI"},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-661","l":"Cisco IOS XR 6.6.1"},{"i":"cli-2","l":"CLI"},{"i":"unit-2","l":"Unit","p":["Link to github : xr-unit"]},{"i":"junos-141x53-d408","l":"Junos 14.1X53-D40.8"},{"i":"cli-3","l":"CLI","p":["pf_intf_index, pf_subintf_index is a conversion of set ."]},{"i":"unit-3","l":"Unit","p":["Link to github : junos-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-4","l":"CLI"},{"i":"unit-4","l":"Unit","p":["Link to github : junos-unit"]}],[{"i":"border-gateway-protocol-bgp","l":"Border Gateway Protocol (BGP)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI","p":["ipv4 unicast is a conversion of set IPV4_UNICAST ipv6 unicast is a conversion of set IPV6_UNICAST remove-private-AS is a conversion of default-originte is a conversion of next-hop-self is a conversion of if value is \"nexthopself\" no shutdown is a conversion of set true shutdown is a conversion of set false ipv4 unicast is a conversion of set IPV4_UNICAST ipv6 unicast is a conversion of set IPV6_UNICAST vpnv4 unicast is a conversion of set L3VPN_IPV4_UNICAST"]},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-661-via-netconf","l":"Cisco IOS XR 6.6.1 (via NetConf)"},{"i":"cli-1","l":"CLI","p":["l2vpn evpn is a conversion of set L2VPN_EVPN remove-private-AS is a conversion of default-originte is a conversion of next-hop-self is a conversion of if value is \"nexthopself\" no shutdown is a conversion of set true shutdown is a conversion of set false l2vpn evpn is a conversion of set L2VPN_EVPN"]},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-661-no-netconf","l":"Cisco IOS XR 6.6.1 (no NetConf)"},{"i":"cli-2","l":"CLI","p":["vpnv4 unicast is a conversion of set L3VPN_IPV4_UNICAST"]},{"i":"unit-2","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-662","l":"Cisco IOS XR 6.6.2"},{"i":"cli-3","l":"CLI","p":["ipv4 unicast is a conversion of set IPV4_UNICAST ipv6 unicast is a conversion of set IPV6_UNICAST remove-private-AS is a conversion of default-originte is a conversion of ipv4 unicast is a conversion of set IPV4_UNICAST ipv6 unicast is a conversion of set IPV6_UNICAST"]},{"i":"unit-3","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xe-031301s","l":"Cisco IOS XE 03.13.01.S","p":["bgp log-neighbor-changes is a conversion of set true no bgp log-neighbor-changes is a conversion of set false default-information originate is a conversion of set true no default-information originate is a conversion of set false neighbor as-override is a conversion of set true neighbor fall-over bfd is a conversion of set true transport connection-mode passive is a conversion of set true route-reflector-client is a conversion of set true remove-private-as is a conversion of set \"frinx-openconfig-bgp-types:PRIVATE_AS_REMOVE_ALL\" no-prepend is a conversion of set true replace-as is a conversion of set true neighbor version 4 is a conversion of set \"frinx-bgp-extension:VERSION_4\" auto-summary is a conversion of set true no auto-summary is a conversion of set false* redistribute connected route-map * is a conversion of set true no redistribute connected is a conversion of set false* redistribute static route-map * is a conversion of set true no redistribute static is a conversion of set false synchronization is a conversion of set true no synchronization is a conversion of set false"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-4","l":"CLI","p":["activate is a conversion of set true deactivate is a conversion of set false"]},{"i":"unit-4","l":"Unit","p":["Link to github : junos-unit"]},{"i":"huawei-ne5000e-v800r009c10spc310","l":"Huawei NE5000E (V800R009C10SPC310)"},{"i":"cli-5","l":"CLI","p":["auto-discovery is conversion of set \"frinx-bgp-extension:transport\" keepalive is conversion of set \"timer_mode\" 0-21845 is conversion of set \"time_before\" 3-65535 is conversion of set \"timer_after\" direct, static is conversions of set \"import_route\""]},{"i":"unit-5","l":"Unit","p":["Link to github : huawei-unit"]}],[{"i":"intermediate-system-to-intermediate-system-is-is","l":"Intermediate System to Intermediate System (IS-IS)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-623","l":"Cisco IOS XR 6.2.3"},{"l":"CLI","p":["point-to-point is a conversion of set POINT_TO_POINT","value frinx-openconfig-isis-types:IPV6 is to be converted to ipv6 value frinx-openconfig-isis-types:UNICAST is to be converted to unicast value LEVEL_1 is to be converted to level-1 value LEVEL_2 is to be converted to level-2 value LEVEL_1_2 is to be converted to level-1-2"]},{"i":"cisco-ios-xr-661cli","l":"Cisco IOS XR 6.6.1(CLI)"},{"i":"cli-1","l":"CLI","p":["value frinx-isis-extension:NOT_SET is to be converted to max-link-metric value frinx-isis-extension:LEVEL_1 is to be converted to max-link-metric level 1 value frinx-isis-extension:LEVEL_2 is to be converted to max-link-metric level 2","value frinx-openconfig-isis-types:IPV6 is to be converted to ipv6 value frinx-openconfig-isis-types:UNICAST is to be converted to unicast","is converted from .","if is LEVEL_1, then is set as level-1","if is LEVEL_2, then is set as level-2","if is LEVEL_1_2, then is set as level-1-2"]}],[{"i":"open-shortest-path-first-ospf","l":"Open Shortest Path First (OSPF)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands","p":["include-stub is a conversion of MAX_METRIC_INCLUDE_STUB in the include list of the max-metric-timer external-lsa is a conversion of MAX_METRIC_INCLUDE_TYPE2_EXTERNAL in the include list of the max-metric-timer summary-lsa is a conversion of MAX_METRIC_SUMMARY_LSA in the include list of the max-metric-timer"]},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI","p":["bfd fast-detect is a conversion of set true bfd fast-detect disable is a conversion of set false mpls ldp sync is a conversion of set true mpls ldp sync disabled is a conversion of set false passive enable is a conversion of set true passive disabled is a conversion of set false","** value MAX_METRIC_ON_SYSTEM_BOOT is to be converted to on-startup** value MAX_METRIC_ON_SWITCHOVER is to be converted to on-switchover"]},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-662","l":"Cisco IOS XR 6.6.2"},{"i":"cli-1","l":"CLI"},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]},{"i":"junos-141x53-d408","l":"Junos 14.1X53-D40.8"},{"i":"cli-2","l":"CLI","p":["delete protocols ospf area interface disable is a conversion of set true set protocols ospf area interface disable is a conversion of set false"]},{"i":"unit-2","l":"Unit","p":["Link to github : junos-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-3","l":"CLI"},{"i":"unit-3","l":"Unit","p":["Link to github : junos-unit"]}],[{"i":"open-shortest-path-first-v3-ospfv3","l":"Open Shortest Path First v3 (OSPFv3)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI","p":["value STUB_ROUTER_MAX_METRIC is to be converted to max-metric value STUB_ROUTER_R_BIT is to be converted to r-bit value STUB_ROUTER_V6_BIT is to be converted to v6-bit"]},{"l":"Unit","p":["Link to github : xr-unit"]}],[{"l":"Static Route"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"IOS 12"},{"l":"CLI","p":["ipv4 unicast is a conversion of set IPV4_UNICAST ipv6 unicast is a conversion of set IPV6_UNICAST is parsed from is parsed from"]},{"l":"Unit","p":["Link to github : ios-unit"]},{"i":"cisco-ios-xr-662","l":"Cisco IOS XR 6.6.2"},{"i":"cli-1","l":"CLI","p":["ipv4 unicast is a conversion of set IPV4_UNICAST ipv6 unicast is a conversion of set IPV6_UNICAST is parsed from is parsed from"]},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]}],[{"l":"VLAN"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI","p":["no shutdown is a conversion of set ACTIVE shutdown is a conversion of set SUSPENDED"]},{"i":"dasan-nos-sfurr56p5","l":"Dasan NOS SFU.RR.5.6p5"},{"i":"cli-1","l":"CLI","p":["if is true","if is false"]},{"l":"Ciena SAOS 614"},{"i":"cli-2","l":"CLI","p":["should be pure numeric, converted from oc-vlan-types:TPID_TYPES from openconfig enable is a conversion of to true disable is a conversion of to false is an enumeration trust-mode - options are client-trusted, server-trusted, dualrole-trusted and untrusted"]}],[{"i":"configure-network-instance-vrf","l":"Configure network instance (VRF)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI"},{"l":"Unit","p":["Link to github : ios-unit"]},{"l":"Configure default network instance"},{"i":"url-1","l":"URL"},{"i":"openconfig-yang-1","l":"OPENCONFIG YANG","p":["YANG models","vlans definition - vlans policy-forwarding definition - policy-forwarding protocols definition - protocols interface-name is a conversion of each interface name for this network-instance cisco-ipv6-config is a conversion of global ipv6 configuration for device and consist of: unicast-routing and cef whose values can only be true or false"]},{"i":"os-commands-1","l":"OS Commands"},{"i":"cisco-ios-classic-1524s5","l":"Cisco IOS Classic (15.2(4)S5)"},{"i":"cli-1","l":"CLI"}],[{"l":"Routing Policy"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"cisco-ios-12-ios-15-ios-xe-15-ios-xe-16-ios-xe-17","l":"Cisco IOS 12, IOS 15, IOS XE 15, IOS XE 16, IOS XE 17","p":["permit is a conversion of set to frinx-cisco-routing-policy-extension:PERMIT deny is a conversion of set to frinx-cisco-routing-policy-extension:DENY","permit is a conversion of set to community-member deny is a conversion of set to frinx-openconfig-bgp-policy-extension:community-member-deny","permit is a conversion of set to frinx-cisco-routing-policy-extension:PERMIT deny is a conversion of set to frinx-cisco-routing-policy-extension:DENY set community (no-export) is a conversion of set to frinx-openconfig-bgp-types:NO_EXPORT set community (no-advertise) is a conversion of set to frinx-openconfig-bgp-types:NO_ADVERTISE* match tag * is a tag element in match clause set to frinx-cisco-routing-policy-extension:tags"]},{"i":"cisco-ios-xr-534-ios-xr-662","l":"Cisco IOS XR 5.3.4, IOS XR 6.6.2"},{"l":"CLI","p":["is parsed from .","If is \"exact\", then is not set.","If matches to pattern of .., then is set as \"le ge \".","* destination in * is a conversion of set to ANY* not destination in * is a conversion of set to INVERT","as-path length le is a conversion of set to frinx-openconfig-policy-types:ATTRIBUTE_LE as-path length ge is a conversion of set to frinx-openconfig-policy-types:ATTRIBUTE_GE as-path length eq is a conversion of set to frinx-openconfig-policy-types:ATTRIBUTE_EQ","community match-any is a conversion of set to ANY community match-every is a conversion of set to ALL","drop is a conversion of set to REJECT_ROUTE done is a conversion of set to ACCEPT_ROUTE pass is a conversion of set to PASS_ROUTE","set community (no-export) is a conversion of set to frinx-openconfig-bgp-types:NO_EXPORT set community (no-advertise) is a conversion of set to frinx-openconfig-bgp-types:NO_ADVERTISE set community (local-as) is a conversion of set to frinx-openconfig-bgp-types:NO_EXPORT_SUBCONFED","* as-path in * is a conversion of set to ANY* not as-path in * is a conversion of set to INVERT"]},{"l":"Examples"},{"i":"junos-141x53-d408","l":"Junos 14.1X53-D40.8"},{"i":"cli-1","l":"CLI"},{"i":"examples-1","l":"Examples"}],[{"i":"aaa---authentication-authorization-accounting","l":"AAA - Authentication Authorization Accounting"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"huawei-ne5000e-v800r009c10spc310","l":"Huawei NE5000E (V800R009C10SPC310)"},{"l":"CLI","p":["local, radius is conversions of set to \"authentication-method\" local, radius is conversions of set to \"accounting-method\" start-fail is conversion of set to \"fail-policy\" online is conversion of set to \"fail-policy-mode\" telnet, terminal, ssh, ftp is conversions of set to \"frinx-huawei-aaa-extension:service-type\" 1-15 is conversion of set to \"frinx-huawei-aaa-extension:privilege-level\""]},{"l":"Unit","p":["Link to GitHub : huawei-unit"]},{"l":"SAOS 6"},{"i":"cli-1","l":"CLI","p":["limited, admin, super, diag is conversion of set to \"frinx-ciena-aaa-extension:access-level\""]},{"i":"unit-1","l":"Unit","p":["Link to GitHub : saos6-unit"]}],[{"i":"broadcast-containment-broadcast-containment-filters","l":"Broadcast-Containment (Broadcast-containment filters)"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"ciena-saos-614","l":"Ciena SAOS 6.14"},{"l":"CLI","p":["enable is conversion of set true disable is conversion of set false"]},{"l":"Unit"}],[{"l":"Configure CDP interfaces"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI","p":["cdp enable is conversion of \"enabled\": true no cdp enable is conversion of \"enabled\": false"]},{"l":"Unit","p":["Link to github : ios-unit"]},{"i":"cisco-ios-xr-xrv-513-and-xrv-612-tested","l":"Cisco IOS XR (XRv 5.1.3 and XRv 6.1.2 tested)"},{"i":"cli-1","l":"CLI","p":["cdp is conversion of \"enabled\": true no cdp is conversion of \"enabled\": false"]},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]},{"i":"brocade-v560ft163","l":"Brocade (V5.6.0fT163)"},{"i":"cli-2","l":"CLI","p":["cdp enable is conversion of \"enabled\": true no cdp enable is conversion of \"enabled\": false"]},{"i":"unit-2","l":"Unit","p":["Link to github : brocade-unit"]}],[{"l":"Configure FDP interfaces"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"i":"brocade-v560ft163","l":"Brocade (V5.6.0fT163)"},{"l":"CLI","p":["fdp enable is conversion of \"enabled\": true no fdp enable is conversion of \"enabled\": false"]},{"l":"Unit","p":["NOT IMPLEMENTED"]}],[{"l":"Configure STP interfaces"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Commands"},{"i":"brocade-v560ft163","l":"Brocade (V5.6.0fT163)"},{"l":"CLI","p":["If /stp/interfaces/interface/ exists","If /interfaces/interface/ exists and /stp/interfaces/interface/ does not exist"]},{"l":"Unit","p":["NOT IMPLEMENTED"]}],[{"i":"ethernet-oam--ethernet-cfm","l":"Ethernet OAM / Ethernet CFM"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-662","l":"Cisco IOS XR 6.6.2"},{"l":"CLI","p":["ethernet cfm is a conversion of set to true no ethernet cfm is a conversion of set to false efd is a conversion of set to true no efd is a conversion of set to false"]},{"l":"Unit","p":["Link to github : xr-unit"]}],[{"i":"ethernet-virtual-circuit-evc","l":"Ethernet Virtual Circuit (EVC)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xe-16","l":"Cisco IOS XE 16.*"},{"l":"CLI","p":["* ethernet evc * is creating evc configuration with name* no ethernet evc * is deleting evc configuration with name"]},{"l":"Unit","p":["Link to github : ios-xe-evc-unit"]}],[{"i":"ethernet-virtual-private-network-evpn","l":"Ethernet Virtual Private Network (EVPN)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-661-via-netconf","l":"Cisco IOS XR 6.6.1 (via NetConf)"},{"l":"CLI","p":["evpn is a conversion of set to true no evpn is a conversion of set to false is parsed from example is Bundle-Ether100 -> is 100 is parsed from Bundle-Ether is a conversion of set to \"iana-if-type:ieee8023adLag\" mode port-active is a conversion of set to \"frinx-es-lb-mode:PORT-ACTIVE\" mode single-active is a conversion of set to \"frinx-es-lb-mode:SINGLE-ACTIVE\""]},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-661-no-netconf","l":"Cisco IOS XR 6.6.1 (no NetConf)"},{"i":"cli-1","l":"CLI","p":["evpn is a conversion of set true no evpn is a conversion of set false cost-out is a conversion of set true no cost-out is a conversion of set false or null"]},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]}],[{"i":"hot-standby-router-protocol-hsrp","l":"Hot Standby Router Protocol (HSRP)"},{"l":"URL"},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI"},{"l":"Unit","p":["Link to github : xr-unit"]}],[{"i":"l2-cft-layer-2-control-frame-forwarding","l":"L2-Cft (Layer 2 Control Frame Forwarding)"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"ciena-saos-614","l":"Ciena SAOS 6.14"},{"l":"CLI","p":["can be can be <802.1x | all-bridges-block | cisco-cdp | cisco-dtp | cisco-pagp | cisco-pvst | cisco-stp-uplink-fast | cisco-udld | cisco-vtp | elmi | esmc | garp-block | gmrp | gvrp | lacp | lacp-marker | lldp | oam | ptp-peer-delay | vlan-bridge | xstp> if == mef-ce1 -> can be also bridge-block if == mef-ce2 -> can be also can be "]},{"l":"Unit"}],[{"i":"logging-syslog","l":"Logging (syslog)"},{"l":"URL"},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI"},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-623","l":"Cisco IOS XR 6.2.3"},{"i":"cli-1","l":"CLI"},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-661","l":"Cisco IOS XR 6.6.1"},{"i":"cli-2","l":"CLI"},{"i":"unit-2","l":"Unit","p":["Link to github : xr-unit"]}],[{"l":"Privilege"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-12-15-16--ios-xe-15-16-17","l":"Cisco IOS 12, 15, 16 / IOS XE 15, 16, 17"},{"l":"CLI"},{"l":"Unit","p":["Link to github : ios-privilege-unit"]}],[{"l":"Probes"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"junos-182r1-s21","l":"Junos 18.2R1-S2.1"},{"l":"CLI","p":["set services rpm probe delegate-probes is a conversion of < delegate-probes> set true set services rpm probe test target address is a conversion of < target-type> set address"]},{"l":"Unit","p":["Link to github : junos-unit"]}],[{"l":"Quality of Service"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"i":"url-1","l":"URL"},{"i":"openconfig-yang-1","l":"OPENCONFIG YANG"},{"i":"url-2","l":"URL"},{"i":"openconfig-yang-2","l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"cisco-ios-12-15-16--ios-xe-15-16-17","l":"Cisco IOS 12, 15, 16 / IOS XE 15, 16, 17"},{"l":"CLI"},{"l":"Usage","p":["A term marks one or more conditions depending on the class-map type.","When class-map type: match-all, there is just one term, that MUST be called 'all'.","When class-map type: match-any, the terms are numbered from 1 ... number_of_conditions. In this case, the {{term_id}} marks the line, where the conditions specified in conditions is written."]},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"i":"cli-1","l":"CLI"},{"i":"usage-1","l":"Usage","p":["A term marks one or more conditions depending on the class-map type.","When class-map type: match-all, there is just one term, that MUST be called 'all'.","When class-map type: match-any, the terms are numbered from 1 ... number_of_conditions. In this case, the {{term_id}} marks the line, where the conditions specified in conditions is written.","Example:","will create 5 terms numbered from 1 to 5, where term 1 contains condition for qos-group, term 2 contains condition for mpls, etc.","Writing will occur in ascending order. Reading is the same, first condition is put into first term, etc."]},{"i":"huawei-ne5000e-v800r009c10spc310","l":"Huawei NE5000E (V800R009C10SPC310)"},{"i":"cli-2","l":"CLI"},{"l":"Unit","p":["Link to github : huawei-unit"]},{"i":"ciena-saos-614","l":"Ciena SAOS 6.14"},{"i":"cli-3","l":"CLI","p":["traffic-profiling enable is a conversion of {{qos_enabled}} set to true traffic-profiling disable is a conversion of {{qos_enabled}} set to false","{{scheduler_type}} can be port_policy- this issues traffic-profiling commands. The {{scheduler_seq}} will be always 0, there can be just one scheduler of this type.{{scheduler_type}} can be queue_group_policy- this issues traffic-services command. The {{scheduler_seq}} is represented by queue number."]}],[{"l":"Relay Agent"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"SAOS 6"},{"l":"CLI","p":["true or false is conversion of set to \"enable\" rid-string, device-hostname, device-mac is conversion of set to \"remote_id_type\" true or false is conversion of set to \"replace-option82\""]},{"l":"Unit","p":["Link to GitHub : saos6-unit"]},{"l":"SAOS 8"},{"i":"cli-1","l":"CLI","p":["true or false is conversion of set to \"enable\" rid-string, device-hostname, device-mac is conversion of set to \"remote_id_type\" true or false is conversion of set to \"replace-option82\""]},{"i":"unit-1","l":"Unit","p":["Link to GitHub : saos8-unit"]}],[{"i":"simple-network-management-protocol-snmp","l":"Simple Network Management Protocol (SNMP)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"i":"url-1","l":"URL"},{"i":"openconfig-yang-1","l":"OPENCONFIG YANG"},{"i":"url-2","l":"URL"},{"i":"openconfig-yang-2","l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI"},{"l":"Unit","p":["Link to github : ios-unit"]},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"i":"cli-1","l":"CLI","p":["By default enabled on all interfaces. To disable, use:","To enable disabled interfaces use:","enabled:true is a conversion of snmp set enabled","enabled:false is a conversion of snmp set disabled"]},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-2","l":"CLI"},{"i":"unit-2","l":"Unit","p":["Link to github : junos-unit"]}],[{"l":"System-wide services and functions"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"IOS XE ASR920"},{"l":"CLI"},{"l":"Unit","p":["Link to github : [ios-xe-unit]"]}],[{"i":"#","p":["Network Instances","Protocols","BGP summary","BGP RIB","OSPF summary","Discovery protocols","CDP","LLDP"]},{"l":"Network Instances"},{"l":"Protocols"},{"l":"BGP summary"},{"l":"BGP RIB"},{"l":"OSPF summary"},{"l":"Discovery protocols"},{"l":"CDP"},{"l":"LLDP"}],[{"i":"bgp-global--neighbors","l":"BGP global + neighbors"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI"},{"l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : ios-unit"]},{"i":"cisco-xr-612","l":"Cisco XR 6.1.2"},{"l":"Netconf"},{"l":"Device YANG","p":["Link to github : xml-sample"]},{"i":"unit-1","l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : xr-unit"]}],[{"l":"BGP RIB"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI","p":["'*' (valid route) translates to \"valid-route\" : true'i' (internal) translates to \"origin\": \"i\""]},{"l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : ios-unit"]}],[{"i":"show-router-ospf-type-id-interfaces","l":"Show router ospf type, ID, interfaces"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI","p":["Supporting command to determine OPSF - VRF relationships:","Supporting command to show interfaces"]},{"l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : ios-unit"]},{"i":"cisco-xr-612","l":"Cisco XR 6.1.2"},{"l":"Netconf"},{"l":"Device YANG","p":["Link to github : xml-sample"]},{"i":"unit-1","l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : xr-unit"]}],[{"l":"Interfaces"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"CER Arris devices"},{"l":"CLI"},{"l":"Unit","p":["Link to GitHub : cer-unit"]}],[{"l":"Platform"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"Cisco IOS Classic"},{"l":"CLI"},{"l":"Unit","p":["Link to GitHub : ios-unit"]},{"i":"cisco-ios-xe-15-16-17","l":"Cisco IOS XE 15, 16, 17"},{"i":"cli-1","l":"CLI"},{"i":"unit-1","l":"Unit","p":["Link to GitHub : ios-xe-unit"]},{"l":"Ciena SAOS 6"},{"i":"cli-2","l":"CLI"},{"i":"unit-2","l":"Unit","p":["Link to GitHub : saos6-unit"]},{"l":"Ciena SAOS 8"},{"i":"cli-3","l":"CLI"},{"i":"unit-3","l":"Unit","p":["Link to GitHub : saos8-unit"]},{"l":"CER Arris devices"},{"i":"cli-4","l":"CLI"},{"i":"unit-4","l":"Unit","p":["Link to GitHub : cer-unit"]}],[{"l":"Show CDP interfaces and neighbors"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI"},{"l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : ios-unit"]},{"i":"cisco-xr-612","l":"Cisco XR 6.1.2"},{"l":"Netconf"},{"l":"Device YANG","p":["Link to github : xml-sample"]},{"i":"unit-1","l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : xr-unit"]}],[{"l":"Show LLDP interfaces and neighbors"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI"},{"l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : ios-unit"]},{"i":"cisco-xr-612","l":"Cisco XR 6.1.2"},{"l":"Netconf"},{"l":"Device YANG","p":["Link to github : xml-sample"]},{"i":"unit-1","l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : xr-unit"]}],[{"l":"System"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"Ciena SAOS 6"},{"l":"CLI"},{"l":"Unit","p":["Link to GitHub : saos6-unit"]},{"l":"Ciena SAOS 8"},{"i":"cli-1","l":"CLI"},{"i":"unit-1","l":"Unit","p":["Link to GitHub : saos8-unit"]}],[{"l":"Table of Contents","p":["=================","Base Handlers","Base readers","Base writers","Best practices for handlers (readers/writers)","Chunk templates","CLI Init Translation Unit","CLI Translation Unit","Device registration","Documentation","Finding mapping between device and the model","Handlers","Mandatory interfaces to implement","Module structure","NETCONF Unified Translation Unit","OpenConfig to device config mapping","Plaintext parsing hints","Readers","TranslateUnit","Translation Framework","Translation units for different device versions","Translation Units in general","Util classes","Writers"]},{"l":"Translation Framework","p":["The translation framework allows translation units to:","Add YANG model into the system","Register Handlers for all or a subset of nodes defined in the YANG model","Register the entire unit into the system, which is then able to perform"]},{"l":"OpenConfig to device config mapping"},{"l":"Finding mapping between device and the model","p":["Preferred YANG models for device config and operational data are OpenConfig models.","These models usually represents configuration part in container config and operational part in container state. Operational data is config data + operational data.","This site http://ops.openconfig.net/branches/master/ may be used for better browsing in OpenConfig YANG models. Another option is to generate YANG tree representation by using generate_html.sh in https://github.com/FRINXio/openconfig.","YANG models used in UniConfig framework need to be located in https://github.com/FRINXio/openconfig. In case the desired functionality is not modeled yet, you can create new YANG with its own structure or it can augment existing OpenConfig models. Guideline, how to write OpenConfig models can be found at http://www.openconfig.net/docs/style-guide/."]},{"l":"Documentation","p":["There is translation-units-docs page as a single point of truth for mapping. Use __ notation for variables in the templates. This notation is postman compatible."]},{"l":"Translation Units in general"},{"l":"Module structure","p":["Translation unit is a self contained project which implements a mapping between OpenConfig based YANG models and device specific configuration. It is used by the FRINX ODL to perform translation between device specific configuration model and standard (OpenConfig) models. A unit usually consists of:","Handlers","Readers","Writers","TranslateUnit implementation","RPCs"]},{"l":"Handlers","p":["Each complex node in YANG (container, list, augment...) should have a dedicated handler (Reader, Writer)","This enables extensibility, readability and the framework can easily filter and process the data this way","Unless there is a need to also handle child nodes, in which case register the handler using subtreeAdd method from the registries","There are 2 types of handlers: Readers (Read operation) and Writers (Create, Update, Delete operation)","One can implement just the readers or both readers and writers for YANG models. Writers must have counterpart readers because of reconciliation.","Readers and Writers should use the InstanceIdentifier parameter they receive in readCurrentAttributes or writeCurrentAttributes methods to find information about keys for their parent nodes. E.g. Reader registered under ID: /interfaces/interface/config will always receive keyed version of that ID: /interface/interface[Loopback0]/config. So it can use method firstKeyOf on InstanceIdentifier to get the keys.","RWUtils class contains methods for InstanceIdentifier manipulation.","Readers and writers can be easily tested and it is necessary to provide unit tests for all of them. It's important to cover readCurrentAttributes and writeCurrentAttributes with all possible scenarios (all data there, no data there, partial data there...)","Writers may use Preconditions.checkArgument() before accessing the device. Fail of the precondition check does not invoke default rollback (opposite operation) on the writer where precondition is located."]},{"l":"Base Handlers","p":["When a handler for the same YANG node is implemented to conform various devices, it tends to lead to a lot of boilerplate and duplicate code. Therefore, we should implement a base handler for such handlers. How does it work:","create a base-project (if there isn't any) to group base handlers (eg. for an interface handler, choose interface-base project)","each base handler needs to be abstract and implement same interfaces as the original handler","extract common functionality in the base handler. Common functionality means that it will conform the majority of the original handlers. If a handler does not share the extracted functionality, it needs to override original interface methods, to hide the extracted functionality.","let original handlers extend base abstract handler"]},{"l":"CLI Translation Unit","p":["CLI Translation units are located in https://github.com/FRINXio/cli-units repository. JAVA is used in CLI translation units."]},{"l":"Readers","p":["Readers are handlers responsible for reading and parsing the data coming from a device","There are 2 types of readers: Reader and ListReader. Reader can be used to handle container or augmentation nodes and ListReader should handle list nodes from YANG.","Both types need to implement readCurrentAttributes to fill the builder with appropriate values","ListReader needs to also implement getAllIds() where it retrieves a key for each item to be present in current list. After the list is received, framework will invoke readCurrentAttributes for each item from getAllIds","Readers should always use overloaded blockingRead method which takes in the ReadContext since that method performs caching internally","Use full version of commands e.g. show running-config interface instead of sh run int"]},{"l":"Mandatory interfaces to implement","p":["Each reader needs to implement one of these interfaces based on type of target node in YANG. These interfaces also contain util methods which may be used for better manipulation with data. For more information about methods please read javadocs.","CliConfigListReader- implement this interface if target composite node in YANG is list and represents config data.","CliConfigReader- implement this interface if target composite node in YANG is container or augmentation and represents config data.","CliOperListReader- implement this interface if target composite node in YANG is list and represents operational data.","CliOperReader- implement this interface if target composite node in YANG is container or augmentation and represents operational data.","In cases where you want to invoke multiple readers on reading one YANG node, extend following abstract classes:","CompositeListReader- extend this abstract class if multiple list readers need to be invoked when reading specific list in YANG.","CompositeReader- extend this abstract class if multiple readers need to be invoked when reading specific node in YANG.","A practical example of their usage is reading network instance based on it's type. All child readers need to implement a check when the particular reader should be invoked or the parent reader should move on to the next reader.","For example child reader for bgp (located under protocol) needs to check if identifier in protocol has value BGP. Otherwise reader for bgp will be invoked even if protocol identifier is OSPF."]},{"l":"Util classes","p":["ParsingUtils- use methods of this util class if you want to parse plaintext to java object builder"]},{"l":"Plaintext parsing hints","p":["Use as specific regular expressions when parsing CLI output as possible","For Cisco CLI devices avoid using section and other advanced formatting parameters. Only | include | exclude and | begin are allowed.","Use CONFIG data as the source of truth when parsing information from device. Except when parsing state containers (or containers explicitly marked as config false).","I.e. use sh run| include router ospf instead of sh ospf when retrieving ospf routers list.","In some cases, it is not possible to just use config data e.g. sh run interface does not show any data for interfaces that have no configuration. In this case it is necessary to use operational information from e.g. sh ip int brief","Use following pattern when parsing multiline output from CLI, where it is difficult to extract lines and their relationships","I.e. when parsing configured BGP neighbors per address family following command can be used: ** sh run | include router bgp| address-family|^ neighbor which results in:","This output can then be parsed by:","Remove newlines to get a single line of string","Replace \"router\" with \"\\nrouter\" to separate bgp routers per line","Find the line that matches required router bgp","Take that line and replace \"address-family\" with \"\\naddress-family\" to get address-family neighbors per line"]},{"l":"Base Readers","p":["Each base reader should contain abstract methods:","String getReadCommand()- each child reader should fill in the read command used to get information needed for this reader. Arguments may vary and they are used to be more specific in the read command (eg. when creating a command to gather information about a specific interface, you may want to pass interface name as argument).","Pattern getLine(\\args>)- there may be more such methods and they are used to get the regular expression needed to parse output of the command (eg. in case of interface reader, you will create methods getDescriptionLine, getShutdownLine etc.)","Note: naming of the methods should be unified in order to be easily parsed by auto-generated documentation."]},{"l":"Writers","p":["A writer needs to implement all 3 methods: Write, Update, Delete in order to fully support default rollback mechanism of the framework","Time showed that update like 1. delete, 2. write is anti-pattern and should not be used. There is just one case where it is necessary: when re-writing list entry, you must first delete the previous entry, then write the new one, otherwise the previous entry would still be present and the new entry will be added to the list.","A writer can properly work only if there is a reader for the same composite node","A writer should check whether the command it executed was handled by the device properly (by checking the output) and if not throw one of the Write/Update/Delete FailedException","Chunk templating framework is preferred to use in writers it gives us:","Null safety","if/loop etc. inside templates","Default values and many more","Use full version of commands e.g. configure terminal instead of conf t"]},{"i":"mandatory-interfaces-to-implement-1","l":"Mandatory interfaces to implement","p":["Each writer needs to implement one of these interfaces based on type of target node in YANG. Unlike mandatory interfaces for reading, only interfaces for writing config data are available (because it is not possible to write operational data). These interfaces also contain util methods which may be used for better manipulation with data. For more information about methods please read javadocs.","All writers override updateCurrentAttributes method and avoid delete/write combination, unless specified in a comment.","CliListWriter- implement this interface if target composite node in YANG is list. An implementation needs to be registered as GenericListWriter.","CliWriter- implement this interface if target composite node in YANG is container or augmentation. An implementation needs to be registered as GenericWriter.","CompositeWriter- extend this abstract class when multiple writers need to be invoked on one YANG node. The writers need to implement a check whether or not should they be invoked."]},{"l":"Base Writers","p":["Each base writer should contain abstract methods:","String updateTemplate(Config before, Config after)- this method returns Chunk template used for writing and updating data on the device.","String deleteTemplate(Config data)- this method returns Chunk template used for deleting data from device.","Note: if updating data is done differently than writing new data, method String writeTemplate(Config data) might be used as well."]},{"l":"Chunk Templates","p":["Each original writer transformed to use a base writer should have all it's templates written in Chunk. We extended Chunk to achieve easier manipulation with data. There is now a new filter called update. It's usage is following:","\"{$data|update(mtu,mtu `$data.mtu`\\n,no mtu\\n)}\"","$data represents the data structure on which we check if it was updated from the previous state.","mtu first argument represents the name of the field that should be checked within the $data","mtu `$data.mtu`\\n second argument represents the actual string that will be sent to the device if the value of the field named in first argument was changed or didn't exist before","no mtu\\n third argument represents the actual string that will be sent to the device if the value of the field named in first argument was deleted","optional true fourth argument, if present, lets the filter know it should send both outputs to the device, first the delete string (third argument) then the update string (second argument)","Update filter does not send any of the strings to the device, if the value did not change.","When using this filter in updateTemplate method, you must use fT() method (format template) with one pair of the arguments being \"before\", before to let the template know what data represents the previous state.","Note: unfortunately, Opendaylight generates boolean fields instead of Boolean and Chunk does not work with boolean fields in the same way as any other object fields. Therefore for boolean values (eg. shutdown), you cannot use update filter and checking for changes needs to be done in a traditional way."]},{"l":"TranslateUnit","p":["Blueprint example of injecting TranslationUnitCollector to IosXRInterfaceUnit:","Handlers(readers/writers) need to be registered in this method. Parameter context.getTransport() returns Cli object containing methods for communication with a device via CLI - should be passed to readers/writers.","Implementation of TranslateUnit must be registered into TranslationUnitCollector and must specify device type and device version during registration. Snippet below shows registration of IosXRInterfaceUnit for device type \"ios xr\" all versions starting with \"5\".","Implementation of TranslateUnit must implement these methods:","Instance-identifier in generic reader/writer must be without keys pointing to the target composite node used in implemented reader/writer.","Instance-identifiers for YANG container and list (not for augmentations and nodes behind augmentations) are automatically generated to IIDs class (used in examples bellow) during build of openconfig project.","Ordering of writers- writers are stored in a linear structure and are invoked in order of registration. When registering a writer a relationship with another writer or set of writers can be expressed using addBefore, addAfter, subtreeAddBefore, subtreeAddAfter methods. E.g. InterfaceWriter and VRFInterfaceWriter should have a relationship: InterfaceWriter -> VRFInterfaceWriter so that first an interface is created and only then assigned to VRF. Note: VRF writer should be between them. If the order is not expressed during registration, commands might be executed on device in an unpredictable/invalid order.","Return RPC services implemented in the translation unit. Parameter context.getTransport() returns Cli object containing methods for communication with a device via CLI - may need to be passed to RPC implementations.","Return unique string among all translation units which will be used as ID for the translation unit (e.g. \"IOS XR Interface (Openconfig) translate unit\")","Return YANG models containing composite nodes handled by handlers(readers/writers). Default implementation returns empty Set if no handlers are implemented.","rRegistry.add","rRegistry.addNoop","rRegistry.subtreeAdd","Set getYangSchemas()","Set getRpcs(@Nonnull Context context)","String toString()","This method should also register for general Openconfig checks:","Translate unit class must implement interface TranslateUnit. Naming convention for translate unit class is device-type+openconfig-domain+Unit (e.g. IosXrInterfaceUnit). Translate unit class is usually instantiated, initialized and closed from Blueprint.","Use for writers handling data of whole composite node subtrees. This ensures that if only a child node is updated, the writer gets triggered. Method subtreeAdd requires a set of IIDs for all handled children, the IIDs must start from the reader itself, not from root.","Use to register noop writers","Use when a reader implementation also fills composite child nodes of target composite node. Method subtreeAdd requires a set of IIDs for all handled children, the IIDs must start from the reader itself, not from root.","Use when common GenericConfigListReader, GenericConfigReader, GenericOperListReader or GenericOperReader need to be registered.","Use when common GenericListWriter or GenericWriter are registered.","void provideHandlers(@Nonnull ModifiableReaderRegistryBuilder rRegistry, @Nonnull ModifiableWriterRegistryBuilder wRegistry, @Nonnull Context context)","wRegistry.add","wRegistry.subtreeAdd"]},{"l":"CLI Init Translation Unit","p":["Init translation unit does not contain readers and writers but it only contains implementation of TranslateUnit. There should be only one init translation unit per device type. Purpose of the init TU is to setup CLI prompt and define rollback strategy.","The implementation of TranslateUnit needs to override methods:","SessionInitializationStrategy getInitializer(@Nonnull final RemoteDeviceId id, @Nonnull final CliNode cliNodeConfiguration)","Implement and return device specific SessionInitializationStrategy where:","Setup device CLI terminal with attributes like width and length allowing to display infinite output.","Enter desired CLI mode which will be used as default - every reader and writer gets CLI prompt in this state (e.g. EXEC mode for IOS, config mode for IOS-XR, cli mode for Junos)","String toString()","Return unique string among all translation units which will be used as ID for the registration of the translation unit (e.g. \"Junos cli init (FRINX) translate unit\").","These methods may be overridden if necessary:","getPreCommitHook()- method that is invoked before actual commit is written into device. For example this method can enter configuration mode.","getCommitHook()- method that invokes actual commit and should catch any error on commit. Also it should handle any post-commit actions when the commit was successful.","getPostFailedHook()- method that is invoked when commit fails. Should implement aborts or revert strategies.","Methods like getYangSchemas, getRpcs should return empty sets and method provideHandlers should return nothing, just use the read registry and write registry to register handlers.."]},{"l":"NETCONF Unified Translation Unit","p":["Unified translation units are located in https://github.com/FRINXio/unitopo-units repository.","Kotlin is used as prefered programming language in NETCONF translation units because it provides type aliases and better null-safety."]},{"i":"readers-1","l":"Readers","p":["Readers are handlers responsible for reading and parsing the data coming from a device","There are 2 types of readers: Reader and ListReader. Reader can be used to handle container or argument nodes and ListReader should handle list nodes from YANG.","Both types need to implement readCurrentAttributes to fill the builder with appropriate values","ListReader needs to also implement getAllIds() where it retrieves a key for each item to be present in current list. After the list is received, framework will invoke readCurrentAttributes for each item from getAllIds"]},{"i":"mandatory-interfaces-to-implement-2","l":"Mandatory interfaces to implement","p":["Each reader needs to implement one of these interfaces based on type of target node in YANG.For more information about methods please read javadocs.","ConfigListReaderCustomizer- implement this interface if target composite node in YANG is list and represents config data.","ConfigReaderCustomizer- implement this interface if target composite node in YANG is container or augmentation and represents config data.","OperListReaderCustomizer- implement this interface if target composite node in YANG is list and represents operational data.","OperReaderCustomizer- implement this interface if target composite node in YANG is container or augmentation and represents operational data."]},{"i":"base-readers-1","l":"Base Readers","p":["Each base reader for netconf readers should be generic. The generic marks the data element within device YANG that is being parsed into. The base reader should contain abstract methods:","fun readIid(): InstanceIdentifier- each child reader should fill in the device specific InstanceIdentifier that points to the information needed for this reader. Arguments may vary and they are used to be more specific IID (eg. when creating an IID to gather information about a specific interface, you may want to pass interface name as argument).","fun readData(data: T?, configBuilder: ConfigBuilder, )- this method is used to transform Openconfig data (contained in ConfigBuilder) into device data (T) using .","Note: naming of the methods should be unified in order to be easily parsed by auto-generated documentation."]},{"i":"writers-1","l":"Writers","p":["A writer needs to implement all 3 methods: Write, Update, Delete in order to fully support default rollback mechanism of the framework","Time showed that update like 1. delete, 2. write is anti-pattern and should not be used. There is just one case where it is necessary: when re-writing list entry, you must first delete the previous entry, then write the new one, otherwise the previous entry would still be present and the new entry will be added to the list.","A writer can properly work only if there is a reader for the same composite node","The framework provides safe methods to use when handling data on device:","safePut deletes or adds managed data. Does not touch data that was previously on the device and is not handled by the writer.","safeMerge stores just the changed data into device. Does not touch data that was previously on the device and is not handled by the writer.","safeDelete removes data from the device only if the managed node does not contain any other information (even one not handled by the writer).","This test demonstrates the usage of safe methods."]},{"i":"mandatory-interfaces-to-implement-3","l":"Mandatory interfaces to implement","p":["Each writer needs to implement one of these interfaces based on type of target node in YANG. Unlike mandatory interfaces for reading, only interfaces for writing config data are available (because it is not possible to write operational data). For more information about methods please read javadocs.","ListWriterCustomizer- implement this interface if target composite node in YANG is list. An implementation needs to be registered as GenericListWriter.","WriterCustomizer- implement this interface if target composite node in YANG is container or augmentation. An implementation needs to be registered as GenericWriter."]},{"i":"base-writers-1","l":"Base Writers","p":["Each base writer should be generic and contain abstract methods:","fun getIid(id: InstanceIdentifier): InstanceIdentifier- this method returns InstanceIdentifier that points to a node where data should be written","fun getData(data: Config): T- this method transforms Openconfig data into device specific data (T)"]},{"i":"translateunit-1","l":"TranslateUnit","p":["Translate unit class must implement interface TranslateUnit. Naming convention for translate unit class is just name Unit. Translate unit class is usually instantiated, initialized and closed from Blueprint.","Implementation of TranslateUnit must be registered into TranslationUnitCollector and must provide set of supported underlay YANG models. Snippet below shows registration of Unit for junos device version 17.3.","Blueprint example of injecting TranslationUnitCollector to Juniper173InterfaceUnit:","Implementation of TranslateUnit must implement these methods:","toString(): String","Return unique string among all translation units which will be used as ID for the translation unit (e.g. \"IOS XR Interface (Openconfig) translate unit\")","getYangSchemas(): Set","Return YANG models containing composite nodes handled by handlers(readers/writers). It must return empty Set if no handlers are implemented.","getUnderlayYangSchemas(): Set","Return YANG module informations about underlay models used in the translation unit. These YANG modules describes configuration of NETCONF capable device.","getRpcs(underlayAccess: UnderlayAccess): Set>","Return RPC services implemented in the translation unit. Default implementation returns an emptySet. Parameter underlayAccess represents object containing methods for communication with a device via NETCONF and should be passed to readers/writers.","provideHandlers(rRegistry: ModifiableReaderRegistryBuilder, wRegistry: ModifiableWriterRegistryBuilder, underlayAccess: UnderlayAccess): Unit","Handlers(readers/writers) need to be registered in this method. underlayAccess represents object containing methods for communication with a device via NETCONF and should be passed to readers/writers.","How to register readers/writers is described in CLI TranslateUnit"]},{"l":"Translation units for different device versions","p":["In case of needing to implement a new CLI Translation Unit for specific version of device we create a new TranslateUnit(e.g. located in iosxr/mpls).","In this case we use IOSXR4.* implementation as an example."]},{"l":"Device registration","p":["In TranslateUnit we had just created, e.g. MplsUnitXR4.java, we have to register device as a constant located ../iosxr/utils/IosXrDevices.java containing device type and version as described in TranslateUnit documentation.","This unit can reuse all writers/readers from existing ones, except the writer (or other handler) we want to alter or create (in our example writer for tunnel configuration). We have to create a new writer with desired behaviour and add it into provideWriters method."]},{"i":"handlers-1","l":"Handlers","p":["In our example, the newly created writer have to implement CliWriter interface as well as all the methods mentioned in Writers. With other handlers we proceed with same logic.","Similar process apply on every new implementation of different device version."]},{"l":"How to write extensions for OpenConfig"},{"i":"best-practices-for-handlers-readerswriters","l":"Best practices for handlers (readers/writers)","p":["All comments are in English","All defined exceptions can be thrown from the code","All new dependencies and imports are actually used","All variables/methods are actually used","Before pushing the code make sure:","Chunk","Code has correct spacing","Commented out code","Comments are appropriate to the code behavior","Constants","Do not push code that contains following:","Double blank lines","java regexes","New classes/interfaces have the correct license header","New classes/interfaces/yang model have correct date","Reflection","Show commands","Static imports","Trailing whitespaces or tabs"]}],[{"l":"FAQ"},{"i":"what-is-the-datastore-used-in-frinx-uniconfig-","l":"What is the datastore used in FRINX UniConfig ?","p":["UniConfig uses a custom in-memory database that is part of MD-SAL and is a very fast storage for YANG modeled data.","The datastore is used only for caching data in the scope of a single transaction. For persistence purposes, UniConfig uses a PostgreSQL database."]},{"i":"are-service-instances-stored-in-the-uniconfig-layer-of-frinx-","l":"Are service instances stored in the UniConfig layer of FRINX ?","p":["Only the \"outputs\" of a service are stored and managed by UniConfig (for example, a service that generates BGP config for 10 devices, which is pushed into UniConfig).","Services are responsible for managing their own configuration/operational state, and rely on the same database to store configuration or operational data."]},{"i":"how-does-frinx-deal-with-model-changes-","l":"How does FRINX deal with model changes ?","p":["OpenConfig models are compiled as part of UniConfig and can therefore be changed only before compilation.","On the other hand, NETCONF models can be dynamically loaded from a device and can also be manually updated using a dedicated RPC."]},{"i":"does-frinx-provide-auto-rollback-on-all-affected-devices-if-a-transaction-fails-on-one-or-more-devices-","l":"Does FRINX provide auto rollback on all affected devices if a transaction fails on one or more devices ?","p":["Yes, all onboarded devices have full rollback implemented.","You can also disable auto-rollback in UniConfig, so that successfully configured devices will keep their configuration. This is done by setting the do-rollback flag to False in the input for the commit RPC."]},{"i":"is-it-possible-to-display-differences-between-the-actual-device-configuration-and-the-operational-datastore-while-synchronizing-the-configuration-into-frinx-","l":"Is it possible to display differences between the actual device configuration and the operational datastore while synchronizing the configuration into FRINX ?","p":["Yes, follow these steps:","Sync (update operational).","Show diff.","Drop the changes from the device by replacing operational with config."]},{"i":"is-any-netconf-device-fully-supported-or-must-openconfig-be-mapped-to-netconf-as-well-","l":"Is any NETCONF device fully supported, or must OpenConfig be mapped to NETCONF as well ?","p":["You can either use the native device models (via UniConfig native) or existing translation units between OpenConfig and vendor models."]},{"i":"are-the-libraries-used-to-access-the-config-data-store-model-driven-","l":"Are the libraries used to access the Config Data Store, model driven ?","p":["UniConfig has a DataBroker interface and the concept of InstanceIdentifier. These are the model driven APIs for data access.","For more information, see MD-SAL basic concepts."]},{"i":"what-would-an-access-to-the-configuration-data-store-look-like-in-code-","l":"What would an access to the configuration data store look like in code ?","p":["A. To demonstrate the API, this example reads InterfaceConfigurations from CONF DS and puts it back to CONF DS.","B. This example reads InterfaceConfigurations from OPER DS."]},{"i":"is-it-possible-in-frinx-to-run-a-transaction-on-two-disjunct-sets-of-devices-simultaneously-","l":"Is it possible in FRINX to run a transaction on two disjunct sets of devices simultaneously ?","p":["UniConfig supports the build-and-commit model, which makes it possible to configure devices in isolated transactions and commit them in parallel. If there are conflicts between configured sets of devices, the second transaction that is committed will fail (however, this cannot happen on disjunct sets of devices)."]},{"i":"what-access-control-measures-does-frinx-offer-","l":"What access control measures does FRINX offer ?","p":["FRINX UniConfig supports local authentification, password authentification, public key authentification Token authentification, RADIUS-based authentification and subtree-based authentification via AAA Shiro project."]},{"i":"how-does-frinx-report-problems-with-device-interaction-","l":"How does FRINX report problems with device interaction ?","p":["If a device cannot be reached during a UniConfig transaction (after trying to re-establish the connection), a timeout occurs and the cause for the transaction failure is reported.","UniConfig also uses keepalive messages to continuously verify the connection to devices, using both NETCONF and CLI management protocols."]},{"i":"is-it-possible-to-backup-a-configuration-","l":"Is it possible to backup a configuration ?","p":["UniConfig stores all committed configurations for devices, templates, and snapshots in a PostgreSQL database. We suggest using existing techniques for backup that are also provided by PostgreSQL."]},{"i":"is-it-possible-to-enforce-policies-over-configuration-changes-","l":"Is it possible to enforce policies over configuration changes ?","p":["All customer-specific validations and policy enforcements can be implemented in layers above UniConfig."]},{"i":"which-languages-are-the-libraries-to-access-frinx-in","l":"Which languages are the libraries to access FRINX in?","p":["UniConfig is written in JAVA and Kotlin, which can use data objects generated from YANG. The RESTful API (RESTCONF) can be used with a language that implements the REST client (for example, Python)."]},{"i":"does-frinx-detect-if-a-cluster-node-is-down-on-its-own-or-does-it-rely-on-a-high-availability-framework-","l":"Does FRINX detect if a cluster node is down on its own, or does it rely on a high-availability framework ?","p":["A UniConfig instance is stateless, i.e., it does not persist any configuration in its datastore (PostgreSQL is used for persistence) and does not keep permanent connections (connections to devices are created on-demand in the transaction).","Because of its stateless architecture, UniConfig instances in the \"cluster\" do not need to communicate with each other and require no coordination. Keep in mind that requests belonging to the same transaction must be forwarded to the same UniConfig backend. For this purpose, you can use any HA component that supports sticky sessions based on cookies (for example, HA-proxy or Traefik)."]},{"i":"can-frinx-report-problems-to-a-network-monitoring-system-","l":"Can FRINX report problems to a network monitoring system ?","p":["FRINX UniConfig can propagate NETCONF notifications and internal UniConfig notifications or data-change-events from web sockets on the Northbound API."]},{"i":"is-additional-logging-available-in-uniconfig-","l":"Is additional logging available in UniConfig ?","p":["Yes. Each component writes logs at a different verbosity level (ERROR, WARN, INFO, DEBUG, TRACE). We use the logback framework for logging messages.","Logging can be adjusted by modifying the config/logback.xml file. This file can be updated also on runtime.","Another option to adjust logging for specific components is to use a logging controller. For more information, see Logging."]},{"i":"where-do-i-find-the-device-status-and-error-messages-when-installing-does-not-work-","l":"Where do I find the device status and error messages when installing does not work ?","p":["The install/uninstall process is performed automatically. The device is installed when UniConfig must read or write data from or to the device, and uninstalled at the end of the transaction if no other transaction is using the same installpoint. The install process is transparent, and the user need not care about the process outside of debugging purposes.","To get the status of the install process for all devices in the system, issue the following request. It shows the status and last connect attempt cause:","CLI devices:","NETCONF devices:","gNMI devices:"]},{"i":"what-exactly-happens-during-the-installation-process-","l":"What exactly happens during the installation process ?","p":["The entire installation process includes the following:","Open internal transaction.","Install device with input parameters (CLI or NETCONF).","Open IO session to device (TCP session with SSH and/or NETCONF on top of SSH session).","Expose mountpoint (via internal API and RESTCONF API).","Sync configuration from device.","Write configuration and store information in database.","Uninstall device.","Commit transaction."]},{"i":"why-cant-i-install-junos-devices-on-uniconfig-","l":"Why can't I install Junos devices on UniConfig ?","p":["If installing Junos devices is not possible, UniConfig may give this response :","To install Junos devices, set up a NetConf session that is compliant with RFC and Yang schemas ( rfc-compliant and yang-compliant) on the Junos device:"]}],[{"l":"Glossary of terms","p":["MD-SAL - Model driven service application layer https://docs.opendaylight.org/projects/mdsal/","OpenFlow - Communications protocol that exposes the forwarding plane of a network switch or router over the network https://en.wikipedia.org/wiki/OpenFlow","OpenDaylight - A modular open platform for customizing and automating networks https://www.opendaylight.org/","RESTCONF - HTTP-based protocol that provides a programmatic interface for accessing data defined in YANG, using the datastores defined in NETCONF https://tools.ietf.org/html/draft-ietf-netconf-restconf-12-","SDN (software-defined networking) - Management of network services through abstraction of higher-level functionality https://en.wikipedia.org/wiki/Software-defined_networking","NETCONF (Network Configuration Protocol) https://tools.ietf.org/html/rfc6241","Using the NETCONF Protocol over Secure Shell (SSH) https://tools.ietf.org/html/rfc6242","NETCONF Event Notifications https://tools.ietf.org/html/rfc5277","With-defaults Capability for NETCONF YANG https://tools.ietf.org/html/rfc6243","YANG - A Data Modeling Language for NETCONF https://tools.ietf.org/html/rfc6020","gNMI - gRPC Network Management Interface https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md","gNOI - gRPC Network Operations Interface https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/prog/configuration/175/b_175_programmability_cg/m_175_prog_gnoi_protocol.pdf"]}],[{"l":"List of Supported Devices","p":[".*","(mounted as .*)","(mounted as ios xr .*)","(mounted as Junos 14.*)","(mounted as sros .*)","1.*","12.*","13*/14*","14.*","15.*","16.*","16.*(and later)","17.*","18.*","2.*","3.*","4.*","5.*","6.*","6.6.1 (and later)","8.*","Arista","Brocade","Calix","Casa","Ciena","Cisco","CLI access via REST","CLI to OC translation","Cumulus","Cumulus Linux","Dasan","Device OS Type","Device Version","eos","For details of translation units see our Github: cli_units and unitopo_units.","Here you can find list of all the devices and features supported by Frinx UniConfig:","Huawei","ios classic","ios xe","ios xr","IP Infusion","ironware","Juniper","junos","Microsoft","Mikrotik","NETCONF access via REST","NETCONF to OC translation","nexus","Nokia","nos","OC = OpenConfig","OcNOS","SAOS","SonicOS","sros","Ubiquity","ubnt es","Vendor","vrp"]}],[{"l":"FRINX Workflow Manager introduction","p":["FRINX Workflow Manager allows customers to create automated, repeatable, digital processes to build, grow and operate their digital communication infrastructure. FRINX Workflow Manager is based on open-source components and enables infrastructure and network engineers to create and operate workflows to implement configuration changes and obtain operational data from their heterogeneous networks and clouds. Typical examples are the automation of services that span resources in the cloud and physical assets, the automation of slices and capacity increases in mobile networks, the interaction with CRM and inventory systems, the management of Internet and Infrastructure services and the automation of core network functions. Workflow Manager can be deployed standalone or as part of FRINX Machine.","FRINX Workflow Manager uses Netflix's Conductor for task/workflow orchestration. We recommend to take a look at their Documentation as an introduction to Tasks, Workflows, Definitions and an overall prerequisite to working with FRINX Workflow Manager."]}],[{"l":"Frinx Python SDK","p":["In this section, you will learn about Frinx Python SDK and how to use it together with prepared frinx-services-python-api/frinx-services-python-workers.","High-level Python SDK architecture"]}],[{"l":"Frinx Python SDK","p":["The FRINX Python SDK is a flexible tool designed to simplify interaction with the FRINX network automation solutions. This SDK provides a set of Python libraries and utilities that enable developers to easily integrate with FRINX's platform, streamline their network automation workflows, and leverage FRINX's capabilities to the fullest."]},{"l":"Project init","p":["For the beggining, you will need to create new python project. Example of simple project can be found here We recommend to use poetry as a package management tool and use package from pypi.org"]},{"i":"pyprojecttoml","l":"pyproject.toml"},{"l":"Worker definition","p":["In worker.py we want to create some piece of logic, which will be used in workflows to solve complex problems. Our worker has predefined interface, where you can define conductor task definitions, inputs and outpus. In method execute, you can implement your custom logic. For example call to our service, parse data from previous task or any other code you want."]},{"l":"Workflow definition","p":["Now let's use previous created worker in workflow."]},{"l":"Start worker","p":["Now implement conductor client, which registers our workflow and executes custom worker logic."]}],[{"l":"Frinx Servives Python API","p":["The FRINX Services Python API repository is a monorepo containing Pydantic API wrappers. These components are designed to facilitate rapid worker development, enabling developers to use a common source of API and track changes between service releases. If you find any incompatibilities, please create an issue on the GitHub repository.","For more details, visit the FRINX Services Python API documentation."]},{"l":"Package Importing","p":["To import the necessary FRINX API modules into your project, add the following entries to your pyproject.toml file:","Each package can be imported via frinx_api. Below is an example of how to create custom worker with imported API module:"]},{"l":"Example Usage","p":["CreateTransaction API wrapper can be found in the Uniconfig module.","In this example, the frinx-uniconfig-api dependency is imported into the project, and the CreateTransaction module is used to manage Uniconfig transactions. This approach allows you to use generated API instead of creating custom API implementation.","In this example, we used frinx-python-sdk and frinx-services-python-api to create conductor worker compatible with Frinx Machine 6.1.0 release. For more details, how to import and execute this worker, please visit SDK part."]},{"l":"Versioning","p":["We release versions for each component change or as a combination of services based on the FRINX Machine release. If you have deployed FRINX Machine 6.1.0, use tag 6.1.0. For specific dependency versions, use the custom tag/branch/revision as shown below:","By following these instructions, you can quickly integrate FRINX Services Python API into your project and start utilizing the provided functionalities to streamline your worker development."]}],[{"l":"Frinx Servives Python Workers","p":["The FRINX Services Python Workers repository contains a collection of commonly used workers and API wrappers. These components are designed to facilitate rapid workflow development, enabling developers to share tasks across projects and avoid redundant work. Contributions are welcome to help expand and improve the repository.","For more details, visit the FRINX Services Python Workers documentation."]},{"l":"Package Importing","p":["To import the necessary FRINX services into your project, add the following entries to your pyproject.toml file:","Each package can be imported via frinx_worker. Below is an example of how to use the UniconfigManager from the frinx-uniconfig-worker package:"]},{"l":"Example Usage","p":["UniconfigManager worker implementation can be found in the UniconfigManager module.","In this example, the frinx-uniconfig-worker dependency is imported into the project, and the UniconfigManager module is used to manage Uniconfig transactions. This approach allows you to use pre-built tasks instead of creating custom workers."]},{"l":"Versioning","p":["We release versions for each component change or as a combination of services based on the FRINX Machine release. If you have deployed FRINX Machine 6.1.0, use tag 6.1.0. For specific dependency versions, use the custom tag/branch/revision as shown below:","By following these instructions, you can quickly integrate FRINX Services Python Workers into your project and start utilizing the provided functionalities to streamline your workflow development."]}],[{"l":"Workflow builder","p":["In this part, you can find common implementation of various conductor tasks. It's pythonic representation of conductor operators and system tasks This implementation depends on frinx-python-sdk and uses Pydantic to serialize workflow definition to result in JSON format."]},{"l":"DECISION TASK"},{"l":"DO_WHILE TASK"},{"l":"DYNAMIC_FORK TASK"},{"l":"EVENT TASK"},{"l":"EXCLUSIVE_JOIN TASK","p":["A list of task reference names that this JOIN task will wait for completion"]},{"l":"FORK_JOIN TASK"},{"l":"HUMAN TASK"},{"l":"INLINE TASK","p":["INFO: expression wrapped into javascript function:"]},{"l":"JOIN TASK","p":["Read more on conductor-oss docs","A list of task reference names that this JOIN task will wait for completion"]},{"l":"JSON_JQ_TRANSFORM TASK"},{"l":"SET_VARIABLE TASK"},{"l":"SIMPLE TASK"},{"l":"START_WORKFLOW TASK","p":["Start Workflow is an operator task used to start another workflow from an existing workflow. Unlike a sub-workflow task, a start workflow task doesn’t create a relationship between the current workflow and the newly started workflow. That means it doesn’t wait for the started workflow to get completed."]},{"l":"INPUT PARAMETERS","p":["start_workflow:","StartWorkflowTaskInputParameters : StartWorkflowTaskPlainInputParameters|StartWorkflowTaskFromDefInputParameters","StartWorkflowTaskPlainInputParameters","StartWorkflowTaskFromDefInputParameters"]},{"l":"SUBWORKFLOW TASK","p":["SubWorkflowFromDefParam validate subworkflow and workflow inputs"]},{"l":"SWITCH TASK","p":["SwitchTaskValueParamInputParameters -> VALUE-PARAM","SwitchTaskInputParameters -> JAVASCRIPT","VALUE-PARAM evaluator type"]},{"l":"TERMINATE TASK"},{"l":"WAIT_DURATION TASK"},{"l":"WAIT_UNTIL TASK"}],[{"l":"Development environment","p":["This guide provides the step-by-step instructions for preparing develoment environment."]},{"l":"Prerequisites","p":["Cluster: Make sure that you cluster is running.","Helm: Make sure that Helm is installed. Follow the Helm installation guide if necessary.","Python: Make sure that your environment have Python ^ 3.10 interpretter installed.","Poetry: Make sure that you have installed Poetry. Follow the Poetry installation guide if necessary."]},{"i":"step-1-start-frinx-machine","l":"Step 1: Start Frinx Machine","p":["Install Frinx Machine with ingress enabled Developent environment","Check out gitops-boilerplate repository to run Frinx Machine locally frinx-workers-boilerplate","Make sure you have enabled workflow-manager and krakend ingress, because it's required for local development.","In case, you using minikube, get minikube ip","add map that ip with ingres hosts to your /etc/hosts","To verify ingresses"]},{"i":"step-2-clone-worker-example-repository","l":"Step 2: Clone worker-example repository","p":["Clone repository and follow instructions in README.md","frinx-workers-boilerplate"]},{"i":"step-3-deploy-to-cluster","l":"Step 3: Deploy to cluster","p":["Developent environment"]}],[{"l":"UI Workflow Builder","p":["Workflow Builder is the graphical interface for Workflow Manager and is used to create, modify and manage workflows."]},{"l":"Creating new workflow","p":["To create a new workflow click on the Create button in the Create workflow tab and fill in workflow general parameters. Then you can proceed with adding tasks .","Parameter Name is required and must be unique. Keep in mind that the name cannot be changed later. Other parameters are optional and can be changed anytime.","Create new workflow"]},{"l":"Editing existing workflow","p":["To edit an already existing workflow, find the workflow in the Definitions tab, click on it and then click on the Edit button. A diagram of the workflow will be rendered on the canvas. Now you can restructure the workflow, add new tasks, remove tasks or edit the workflow information and parameters.","Workflow edit"]},{"l":"Adding tasks","p":["To add new task on canvas, find the task in the left menu and click the + icon.","Add task"]},{"l":"Removing tasks","p":["To remove a task, click on the three dots next to a task and press the Remove task button.","Delete task"]},{"l":"Task parameters","p":["To edit or add task parameters, double-click on the task that is placed on the canvas. Input parameters can be declared as:","Input provided by user, e.g.:","Variable provided by other task, e.g.:","Statically defined, e.g.:","For full documentation of tasks see: https://netflix.github.io/conductor/configuration/taskdef/."]},{"l":"System tasks"},{"i":"fork--join","l":"Fork & Join","p":["The 'Fork' function is used to schedule a parallel set of tasks.","A Join task MUST follow Fork task.","Fork and Join"]},{"l":"Decision","p":["A decision task is similar to an if...else statement in a programming language. The task takes 2 parameters:","name of the parameter in the task input whose value will be evaluated (default is param)","value that will be compared with param(or other specified input variable)","If param and is equal to are evaluated as equal, the workflow will continue to If branch, otherwise the workflow will continue in else branch.","Else branch is optional and can be empty."]},{"l":"Lambda","p":["Lambda Task helps execute ad hoc logic at Workflow run-time, using javax & Nashorn Javascript evaluator engine. This is particularly helpful in running simple evaluations in the Conductor server, instead of creating Workers.","The task output can then be referenced in downstream tasks like:"]},{"l":"HTTP","p":["An HTTP system task is used to make calls to another microservice over HTTP. You can use GET, PUT, POST, DELETE Methods and also you can set your custom header."]},{"l":"TERMINATE","p":["Task that can terminate a workflow with a given status and modify the workflow's output with a given parameter. It can act as a \"return\" statement for conditions where you simply want to terminate your workflow. For example, if you have a decision where the first condition is met, you want to execute some tasks, otherwise you want to finish your workflow.","name","description","notes","terminationStatus","can only accept “COMPLETED” or “FAILED”","task cannot be optional","workflowOutput","Expected workflow output"]},{"l":"EVENT","p":["Event task provides ability to publish an event (message) to either Conductor or an external eventing system like SQS. Event tasks are useful for creating event based dependencies for workflows and tasks.","When producing an event with Conductor as sink, the event name follows the structure:"]},{"l":"WAIT","p":["A wait task is implemented as a gate that remains in IN_PROGRESS state unless marked as COMPLETED or FAILED by an external trigger. To use a wait task, set the task type as WAIT"]},{"l":"jsonJQ","p":["jsonJQ is like sed for JSON data - it is especially useful for filtering JSON data.","Example of jsonJQ query expression could be:","It searches through the whole config and under the\"Cisco-IOS-XR-ifmgr-cfg:interface-configurations\" model we find the interface with a description that the user inputs$. The task would return the name interface with fitting description."]},{"l":"Kafka publish","p":["Kafka is a distributed publish-subscribe messaging system and a robust queue that can handle a high volume of data and enables you to pass messages from one end-point to another.","Kafka"]},{"l":"Subworkflows","p":["Subworkflows act as a regular tasks inside a parent workflow. Subworkflows can be expanded to view the tasks they contain (or other nested subworkflows) by clicking the three dots next to the subworkflow and then clicking the Expand button. Expanded subworkflows can be then edited the same way as parent workflow.","Simple tasks differs in color shade from Subworkflow tasks and cannot be expanded.","Expand"]},{"l":"Linking tasks","p":["To connect tasks or subworkflows into execution flow, drag and drop respective Out and In endpoints on nodes, like this: Out-> In"]},{"l":"Unlinking tasks","p":["To remove the link, double-click on the link."]},{"l":"Adding workflow information","p":["To provide additional workflow information, click on Actions in the upper right-hand corner and then click Edit workflow."]},{"l":"Output parameters","p":["We can specify custom output parameters of a workflow, by using JSON templates to generate the output of the workflow. If not specified, the output is defined as the output of the last executed task.","Let's say we have a task with taskReferenceName: task1 which returns summary and we want output of the worklow to be output of this specific task only. The outputParameter value named e.g. finalResult will be:","For full documentation of workflow parameters and definition read https://netflix.github.io/conductor/configuration/workflowdef/."]},{"i":"defaults--description","l":"Defaults & Description","p":["Here, we can define default values and descriptions for workflow inputs. Each input value declared as ${workflow.input...} will appear in a dropdown list of available input parameters."]},{"l":"Save and execute workflow","p":["To Save workflow, click on the Actions button in the upper right corner and select Save workflow. Then you can find the workflow in the Explore workflows section under Definitions tab.","To Execute workflow directly from the builder, click on the Save and execute button in the upper right corner. You will be prompted to provide input parameters.","Executing workflow will also save the workflow."]},{"l":"Import and export of workflows","p":["To import workflow, click the setting icon and then select the Import button. Only valid JSON definition of the workflow will be imported.","Imported workflow will not be saved until you Save or Execute it.","Import/Export workflow","To export and save the workflow in JSON format into your filesystem, click on Export button.","In order to choose a location to which you want to export the workflow, you have to have it enabled in your browser settings. Default location is Downloads folder."]}],[{"l":"Device Blueprints","p":["Blueprints allow you to create a template that can be used for quick adding of devices. They are created with JSON snippets."]},{"l":"Creating new blueprint","p":["To create a new blueprint click on the Explore button in the Explore and configure device tab and then click the Blueprints tab in the top bar. Here you can Add blueprint.","Create blueprint"]},{"l":"Using a blueprint","p":["To use blueprint when adding a new device toggle the \"Blueprints\" switch in the form and choose the blueprint that you want to use.","Use Blueprint"]},{"l":"Blueprint examples"},{"i":"cisco-classic-ios-cli","l":"Cisco classic IOS (cli)"},{"i":"cisco-ios-xr-netconf","l":"Cisco IOS XR (netconf)"},{"i":"junos-cli","l":"JUNOS (cli)"},{"i":"calix-netconf","l":"CALIX (netconf)"},{"i":"nokia-netconf","l":"Nokia (netconf)"},{"i":"ciena-cli","l":"Ciena (cli)"}],[{"l":"Device Inventory","p":["Devices are stored in a Device Inventory. From here they can be dynamically installed and uninstalled."]},{"l":"Adding device to inventory","p":["To add new device to invetory, click on the Add device button in the Device inventory tab.","FM Install"]},{"l":"JSON examples","p":["To adding a new device toggle the \"Blueprints\" switch in the form and choose the blueprint that you want to use.","New devices are added by JSON code snippets. They are similar to Blueprints with one addition: device_id must be specified in the snippet."]},{"i":"cisco-classic-ios-cli","l":"Cisco classic IOS (cli)"},{"i":"cisco-ios-xr-netconf","l":"Cisco IOS XR (netconf)"},{"i":"junos-cli","l":"JUNOS (cli)"},{"i":"calix-netconf","l":"CALIX (netconf)"},{"i":"nokia-netconf","l":"Nokia (netconf)"},{"i":"ciena-cli","l":"Ciena (cli)"}],[{"l":"FRINX Resource Manager introduction","p":["FRINX Resource Manager was developed for network operators and infrastructure engineers to manage their physical and logical assets and resources. Examples for assets are locations, equipment, ports and services. Examples for resources are IP addresses, VLAN IDs and other consumables required for operating data services. Resource Manager was developed specifically to address the needs of network and infrastructure engineers working with communication networks. FRINX Resource Manager provides GUI and a GraphQL based API to create, read, update and delete assets. Resource Manager can be deployed standalone or as part of FRINX Machine."]},{"l":"Features","p":["Following list contains features inherent to Resource Manager."]},{"l":"Resource type management","p":["Example resource types:","Location","Name: Latitude","Name: Longitude","Name: name of the property","Name: RD","Name: vlan","Property type","Resource Manager is flexible enough to enable user defined resource types without requiring code compilation or any other non-runtime task. With regard to resource types, this requires keeping the schema flexible enough so that users can define their own types and properties and thus create their own model.","Resource type is a blueprint for how to represent a resource instance. A resource type is essentially a set of property types, where each property type defines:","Route distinguisher","Type: float","Type: int","Type: int, string, float etc.","Type: String","VLAN"]},{"l":"Resource management","p":["A resource is an instance of a resource type consisting of a number of properties.","Example resources based on resource types from previous section:","VLAN_1","Property","Name: vlan","Value: 44","Route distinguisher_1","Name: RD","Value: 0:64222\uD83D\uDCAF172.16.1.0","Location_1","Name: Latitude","Value: 0.0","Name: Longitude","Resource types"]},{"l":"Flexible design","p":["One of the main non-functional goals of the Resource Manager is flexibility. We are designing Resource Manager to support an array of use cases without the need for modifications. To achieve flexibility we are allowing:","Custom resource type definition without changes in the DB schema","Custom allocation logic without the need to modify the backend code","Custom pool grouping to represent logical network parts (subnet, region, datacenter etc.)"]},{"l":"RBAC","p":["Role Based Access Control is supported by Resource Manager.","A simple RBAC model is implemented where only super-users (based on their role and user groups) can manipulate resource types, resource pools and labels. Regular users will only be able to read the above entities, allocate and free resources.","Resource Manager does not manage list users/roles/groups and relies on external ID provider. Following headers are expected by Resource Manager graphQL server:"]}],[{"l":"User Guide"},{"l":"API","p":["See examples in api_tests."]},{"l":"UI","p":["See the Resource Manager frontend project on GitHub"]}],[{"l":"Pools","p":["A resource pool is an entity that allocates and deallocates resources for a single specific resource type. Resource pools are completely isolated from each other and there can be multiple resource pools for the same resource type even providing the same resource instances. Resource pools encapsulate the allocation logic and keep track of allocated resources. A pool instance should manage resources within the same network or logical network part (e.g. subnet, datacenter, region or the entire, global network).","Example pools:","IPv4 address pool allocating IP addresses from a range / subnet","VLAN pool allocating all available VLAN numbers 0 - 4096","Route distinguisher pool allocating route distinguishers from a specific, per customer, input","Depending on resource type and user’s requirements, pools need to be capable of allocating resources based on various criteria / algorithms. Currently, following pool types are supported by Resource Manager:"]},{"l":"SetPool","p":["Pool with statically allocated resources. Users have to define all the resources to be served in advance. The pool just provides one after another until each resource is in use.","This type of pool is suitable for cases where a set of resources to be served already exists.","Properties of SetPool","Config","Set of unique resources to provide","Name of the pool","Resource recycling - whether deallocated resources should be used again","Operational","Utilisation - % of pool capacity used"]},{"l":"SingletonPool","p":["SingletonPool serves just a single resource for every request.","This type of pool can be utilized in special uses cases such as serving a globally unique single AS number of an ISP. Instead of hardcoding the AS number as a constant in e.g. workflows, it can be “managed” and stored in the Resource Manager.","Properties of SingletonPool","Config","A single unique resources to provide","Name of the pool"]},{"l":"AllocatingPool","p":["a predefined set of resources cannot be used","AllocatingPool is a type of pool that enables algorithmical resource allocation. Instead of using a pre-allocated set of resources to simply distribute, it can create resources whenever asked for a new resource. This type of pool allows users to define a custom allocation logic, attach it to the pool and have use-case specific resource allocations available. Important feature of this pool type is the ability to accept new allocation logic from users in the form of a script without having to rebuild the Resource Manager in any way.","Allocation strategy - a script defining the allocation logic","Config","Example AllocationPools:","In general, anything that a user might need","Limit - hard limit on total number of resource that can be produced","Name of the pool","Operational","or in general whenever using an allocation script makes more sense then using a predefined set of resources","Pool providing all available VLAN numbers","Pool providing IPv4-mapped IPv6 addresses from a specific range / subnet","Pool providing just odd VLAN numbers","Pool providing random VLAN numbers","Pool providing Route Distinguishers that include customer specific information (which is passed as “additional input” as part of resource claim request)","Properties of AllocatingPool","resource creation requires additional inputs","Resource recycling - whether deallocated resources should be used again","This type of pool can be used when","Utilisation - % of pool limit used"]},{"l":"Nested pool","p":["Resource Manager allows to create nested pools. Nested pools provide possibility to create subgroups from already existing pools. With these subgroups it is easier to reason about topology."]},{"l":"How to create nested pool","p":["Process (in UI):","Create pool or open existing one","Allocate resource in newly created or existing pool","Open create pool page","Select parent from which nested pool should be created","Select allocated resource of parent from which nested pool will be taking resources","Fill other mandatory inputs","Push button to create nested pool","After successful submit newly created nested pool should be visible in pools list or in nested pools list in its parent detail page. Also it is possible to create nested pool from detail page of pool."]},{"l":"Allocation strategy overview","p":["Allocation strategy encapsulates the allocation logic and is always tied to (an) instance(s) of AllocatingPool. The strategy is defined in form of a script using Javascript (or similar) language and its responsibility is:","To produce a new (unique) resource instance based on a set of previously allocated resources and any additional, user submitted input.","Apart from a resource being unique, there are no other requirements on what the strategy needs to do. It gives users the freedom to implement any logic.","Allocation strategy can take any input provided in a structure named userInput. This input is provided by the user every time they claim a new resource.","Allocation strategy also gets access to a list of already allocated resources and any properties associated with the pool being utilized."]},{"l":"Pool hierarchies","p":["Resource Manager allows pools to be organized into hierarchies e.g."]},{"l":"Labels","p":["Labels enhance resource management by allowing a pool to be marked with a custom string. Multiple pools can have the same label forming a logical group of pools.","A group of pools under the same label can be dedicated to some logical part of a network (e.g. datacenter, subnet, region etc.).","A single pool should typically have only one label i.e. it should not be re-used across unrelated networks.","The following diagrams represent some of the configurations that can be achieved using Labels:"]},{"i":"configuration-pool-instance-per-label","l":"Configuration: Pool instance per Label","p":["Enables: Resource reuse in multiple networks","Instance per label"]},{"i":"configuration-pool-instance-under-multiple-labels","l":"Configuration: Pool instance under multiple labels","p":["Enables: Unique resources across different networks","Instance multiple labels"]},{"i":"configuration-pool-grouping","l":"Configuration: Pool grouping","p":["Enables: Dividing resource pools into groups based on network regions. Enables users to simply ask for a resource based on label name + resource type (removing the need to know specific pools)","Pool grouping"]},{"i":"configuration-multiple-pool-instances-under-the-same-label","l":"Configuration: Multiple pool instances under the same Label","p":["Enables: Resource pool expansion in case an existing pool runs out of resources. Serves as an alternative to existing pool reconfiguration. If multiple pools of the same type are grouped under the same label, the pools are drained of resources in the order they have been added to this group/label.","Multiple pool instances"]}],[{"l":"Resource Manager architecture","p":["Following diagram outlines the high level architecture of Resource Manager.","Architecture","User authentication and authorization as well as user and tenant management is outside of Resource Manager. Resource Manager is typically deployed behind an api-gateway that handles authentication and authorization relying on an external Identity Managmenet system.","The only aspect of tenancy management that needs to be handled by Resource Manager is: per tenant database creation and removal. Each tenant has its own database in database server."]},{"l":"Technology stack","p":["AAA","Also handles schema migration: creates or updates tables in DB according to ent schema","Backend server","Database","Ent is an ORM framework for go","Entgo.io","Gqlgen","Gqlgen is a graphql framework for go","GraphQL","Isolated and limited for safety and performance","Postgres","Primary API of Resource Manager will be exposed over GraphQL(over HTTP)","PSQL is the DB of choice, but thanks to ent framework hiding the interactions with the database, other SQL DB could be used in the future","RBAC rules can be defined as part of the schema","Resource Manager will rely on technologies used by the Inventory project currently residing at: https://github.com/facebookincubator/magma since both projects are similar and have similar requirements.","Separate process","Tenant and user management is out of scope of Resource Manager and will be handled by an external identity management system.","This section provides details on intended technologies to develop Resource Manager with.","WASM","Web assembly runs any user defined code executing allocation logic for user defined resource pools","Works well on top of entgo.io ORM"]},{"l":"Entity model","p":["Following diagram outlines the core entity model for Resource Manager:","Entities"]}],[{"l":"Developer Guide"},{"l":"Dependency on symphony","p":["Resource Manager currently depends on a project called symphony.","This project is not publicly accessible and without access to it, Resource Manager cannot be built. In that case, use pre built docker images from dockerhub."]},{"l":"Folder structure","p":["api-tests","core codebase for pools and resoruce allocation","ent- ORM schema and generated code for the DB","ent/schema","graph/graphhttp","graph/graphql","graphQL schema and generated code for graphQL server","graphQL server","integration tests","logging","logging framework","multitenancy, RBAC and DB connection management","ORM schema","pkg- helm chart for Resource Manager","pools","psql","psql DB connection provider","viewer"]},{"l":"Build","p":["It is advised to build Resource Manager as a docker image using Dockerfile and run it as a docker container.","The reason is that Resource Manager uses wasmer and pre built js and python engines for wasm. These are not part of the codebase and thus simply running Resource Manager would fail, unless you provide these resources e.g. by copying them out of Resource Manager built docker image.","Resource Manager utilizes wire to generate wiring code between major","components. Regenerating wiring is not part of standard build process ! After modifying any of the wire.go files perform:"]},{"l":"GraphQL schema","p":["Resource Manager exposes graphQL API and this is the schema."]},{"l":"Built in strategies","p":["Resource Manager provides a number of built in strategies for built in resource types and are loaded into Resource Manager at startup.","Built in strategies code base","Built in strategies unit tests","These strategies need to be tested/built and packaged for Resource Manager. This test/build process in scrips section of package.json while the packaging part can be found in generate.go.","Resource types associated with these strategies can be found in load_builtin_resources.go."]},{"l":"Unit tests"},{"l":"Integration tests"},{"l":"API tests","p":["There's a number of api tests available and can be executed using integration-test.sh. These tests need to be executed against Resource Manager running as a black box (ideally as a container)."]},{"l":"Wasmer","p":["There's a number of tests testing core components that require wasmer, quickjs and python packages to be available. It is recommended to run these tests in a docker container.","Example execution:"]},{"l":"Additional info"},{"l":"Telementry","p":["Support for tracing (distributed tracing). Streams data into a collector such as Jaeger. Default is Nop. See main parameters or telementry/config.go for further details to enable jaeger tracing"]},{"l":"Health","p":["Basic health info of the app (also checks if mysql connection is healthy)"]},{"l":"Metrics","p":["Prometheus style metrics are exposed at:"]}]] \ No newline at end of file +[[{"i":"welcome-to-frinx-documentation","l":"Welcome to FRINX Documentation!","p":["The FRINX documentation site contains all FRINX projects, releases and documentation. Please, use search bar in the upper left corner to find specific issues and information that you demand."]},{"l":"FRINX Machine","p":["FRINX Machine provides a platform allowing easy definition, execution and monitoring of complex workflows using FRINX UniConfig."]},{"l":"FRINX UniConfig","p":["FRINX UniConfig is a suite of applications aimed at network configuration management."]},{"l":"FRINX Workflow Manager","p":["FRINX Workflow Manager allows customers to create automated and repeatable digital processes to build, grow and operate their digital communication infrastructure."]},{"l":"FRINX Resource Manager","p":["FRINX Resource Manager helps network operators and infrastructure engineers manage their physical and logical assets and resources."]}],[{"l":"FRINX Machine introduction","p":["In today's rapidly evolving digital landscape, efficient network management and automation are crucial for maintaining robust and scalable IT infrastructures. Frinx Machine emerges as a powerful solution tailored to meet these demands, providing an integrated platform designed to simplify and enhance network automation."]},{"i":"what-is-frinx-machine","l":"What is Frinx Machine?","p":["Frinx Machine is an advanced network automation platform delivering a comprehensive suite of tools for managing and automating network infrastructures. It is designed to streamline network operations, reduce complexity, and drive efficiency through a unified, scalable, and flexible approach.","Frinx Machine enabling seamless management of network configurations across multi-vendor environments. It provides a consistent interface for deploying and managing configurations, reducing the complexities associated with heterogeneous network devices."]},{"l":"FRINX Machine core components"},{"l":"High-Level Architecture","p":["The following diagram outlines the main functional components in the FRINX Machine solution:","FM Architecture"]},{"l":"UniConfig","p":["Connects to the devices in the network","Retrieves and stores configuration from devices","Pushes configuration data to devices","Builds diffs between actual and intended config to execute atomic configuration changes","Retrieves operational data from devices","Manages transactions across one or multiple devices","Translates between CLI, vendor native, and industry-standard data models (i.e. OpenConfig)","Reads and stores vendor native data models from mounted network devices (i.e YANG models)","Ensures high availability, reducing network outages and downtime","Executes commands on multiple devices simultaneously"]},{"i":"workflow-manager-conductor","l":"Workflow manager (Conductor)","p":["Atomic tasks are chained together into more complex workflows","Defines, executes and monitors workflows (via REST or UI)","Schedule workflow executions","We chose Netflix’s conductor workflow engine since it has been proven to be a highly scalable open-source technology that integrates very well with FRINX UniConfig. Further information about Conductor can be found at:","FRINXio conductor sources: https://github.com/FRINXio/conductor","FRINXio conductor community sources: https://github.com/FRINXio/conductor-community","Sources: https://github.com/conductor-oss/conductor","Docs: https://conductor-oss.github.io/conductor/index.html"]},{"l":"Device inventory","p":["Store all important devices information on one place","Maintain devices in all deployment zones from one place","Notify about changes in inventory via Kafka"]},{"l":"Topology discovery","p":["Acquires information from live network","Relying on UniConfig as its primary source of network information","Uses that information to build topology view(s):","Across multiple layers of the network","e.g. LLDP data to build physical topology view or routing data to build L3 view","Performs reconciliation across the layers in order to provide a unified topology view","Provides an API to query topologies","Provides Kafka notifications about changes in the topology","Consumes and stores device metadata events from Kafka topic"]},{"l":"Performance monitor","p":["Collects performance metrics about devices in a time-series based database","Relies on UniConfig as a producer of the performance metrics of devices.","Relies on Device Inventory as a producer of information about devices, such as device name, vendor, model, and version.","Unifies performance metrics and produces them to a Kafka broker.","Provides an API to query performance metrics of devices."]},{"i":"monitoring","l":"Monitoring:"},{"i":"loki--grafana--influxdb--telegraf---core-of-monitoring","l":"Loki + Grafana + Influxdb + Telegraf - core of Monitoring","p":["Loki: Efficient log aggregation and querying.","Telegraf: Data collection and reporting agent.","InfluxDB: High-performance time-series database.","Grafana: Powerful visualization and dashboard creation."]},{"i":"key-functions","l":"Key Functions:","p":["Collect logs and metrics from services to provide platform observability"]}],[{"l":"API Gateway","p":["Communication with FRINX Machine is facilitated through both a user-friendly UI and a robust REST API. All our services offer REST and GraphQL APIs, allowing seamless interaction for both users and automated systems.","Our architecture employs an API Gateway to consolidate all endpoints into a single, accessible location. Each service is assigned a unique path, simplifying access. To connect with a specific service, you only need to know the FM KrakenD/OAuth2-Proxy ingress host and the designated path for your desired service. This streamlined approach ensures efficient and straightforward communication with FRINX Machine."]},{"l":"Api Gateway diagram","p":["API Gateway"]},{"l":"Api Docs","p":["API documentation is accesibla via Frinx Machine installation"]}],[{"l":"Create Docker Registry Secret","p":["Create a kubernetes Docker registry secret for pulling images from private registry:","For more info about accessing private images, visit Download Frinx Uniconfig"]}],[{"l":"Helm Chart Installation Guide","p":["This guide provides the step-by-step instructions for installing FRINX Machine on a Kubernetes cluster using Helm charts."]},{"l":"Prerequisites","p":["Minikube: Make sure that Minikube is installed on your local machine. Follow the Minikube installation guide if necessary.","Helm: Make sure that Helm is installed. Follow the Helm installation guide if necessary."]},{"i":"step-1-start-minikube","l":"Step 1: Start Minikube"},{"i":"step-2-add-the-frinx-helm-repository","l":"Step 2: Add the FRINX Helm Repository","p":["Add the FRINX Helm repository and update the repository list:"]},{"i":"step-3-install-operators-and-crds","l":"Step 3: Install Operators and CRDs","p":["Install FRINX Machine operators and custom resource definitions (CRDs):","Verify the installation by checking the pods in the frinx namespace:","You should see output similar to:"]},{"i":"step-4-create-docker-registry-secret","l":"Step 4: Create Docker Registry Secret","p":["Please complete this step before continue Create docker regitry secret"]},{"i":"step-5-install-frinx-machine","l":"Step 5: Install FRINX Machine","p":["Install the FRINX Machine using Helm:","Verify the installation by checking the pods in the frinx namespace:","You should see output similar to:"]},{"i":"step-6-access-the-ui","l":"Step 6: Access the UI","p":["To access ui, use krakend-nginx ingress hostname.","You should see output similar to:","In case of minikube is required to add the following entries to your /etc/hosts file:","and visit Frinx Machine page in your browser on https://krakend.127.0.0.1.nip.io/frinxui"]}],[{"l":"Setting Up a Kind Cluster with Cilium and NGINX Ingress Controller","p":["This guide will walk you through the process of deploying a Kubernetes (K8s) cluster using Kind (Kubernetes IN Docker), setting up the Cilium CNI (Container Network Interface), and deploying the NGINX Ingress Controller."]},{"l":"Prerequisites","p":["Kind: Make sure that Kind is installed on your local machine. Follow the Kind installation guide if necessary.","Helm: Make sure that Helm is installed. Follow the Helm installation guide if necessary.","Cilium: Make sure that Cilium system requirements are fullfiled. Follow the Cilium installation guide if necessary."]},{"l":"Deploy Kind cluster","p":["Create a Kind configuration file named kind-config.yaml with the following content:","This configuration sets up a Kind cluster with one control-plane node and three worker nodes. It also maps ports 80 and 443 from the host to the control-plane node, making the cluster ready for ingress traffic.","Deploy the cluster using Kind:","Verify the cluster is running:","You should see output indicating that the Kubernetes control plane and CoreDNS are running."]},{"l":"Deploy Cilium","p":["Create a Cilium configuration file named cilium-helm-values.yaml with the following content:","This configuration enables Cilium with kube-proxy replacement and various service options, including Hubble for network observability.","Install Cilium using Helm:","Check the status of the Cilium pods to ensure they are running:","You should see the Cilium and Hubble components running without issues."]},{"l":"Deploy NGINX Ingress Controller","p":["Deploy the NGINX Ingress Controller using the following command:","Verify the NGINX Ingress Controller is running:","You should see the NGINX Ingress Controller pod running."]}],[{"l":"Helm Chart Installation Guide with customization","p":["This guide provides the step-by-step instructions for installing FRINX Machine on a Kubernetes cluster using Helm charts with customization via helm dependency values."]},{"l":"Prerequisites","p":["Cluster: Make sure that you cluster is running.","Helm: Make sure that Helm is installed. Follow the Helm installation guide if necessary."]},{"i":"step-1-add-the-frinx-helm-repository","l":"Step 1: Add the FRINX Helm Repository","p":["Add the FRINX Helm repository and update the repository list:"]},{"i":"step-2-install-operators-and-crds","l":"Step 2: Install Operators and CRDs","p":["Install FRINX Machine operators and custom resource definitions (CRDs):","Verify the installation by checking the pods in the frinx namespace:","You should see output similar to:"]},{"i":"step-3-create-docker-registry-secret","l":"Step 3: Create Docker Registry Secret","p":["Please complete this step before continue Create docker regitry secret"]},{"i":"step-4-customize-frinx-machine","l":"Step 4: Customize FRINX Machine","p":["To customize the deployment of FRINX Machine, you need to create a folder that will contain the necessary Helm chart files: Chart.yaml and values.yaml. This folder will serve as the root for your customized Helm chart, with FRINX Machine as a dependency."]},{"l":"Create the Chart Configuration","p":["Create the Chart.yaml file:","This file contains the metadata for your Helm chart and specifies FRINX Machine as a dependency.","This configuration sets up the basic information about the Helm chart and defines FRINX Machine as a dependency, pulling it from the specified repository.","Check Dependency Chart Details:","For mapping the Helm chart release to the product release and more details on the FRINX Machine Helm chart, refer to the FRINX Machine Helm chart documentation on Artifact Hub."]},{"l":"Customize the Values","p":["Create the values.yaml file:","This file contains custom configurations for the FRINX Machine subcharts. Customization options are based on the documentation of each subchart, which can be found on Artifact Hub.","krakend.nginx.ingress.hostname: Configures the Ingress settings for the KrakenD API Gateway.","uniconfig: Specifies the Docker image repository for the Uniconfig component.","performance-monitor: Specifies the Docker image repository for the Performance Monitor component."]},{"l":"Customize Subcharts","p":["Subchart Customization:","For more detailed customization possibilities, refer to the documentation for each dependency Helm chart version. This will provide information on all configurable parameters and how to adjust them to suit your deployment needs.","By following these steps, you can effectively customize the deployment of FRINX Machine using Helm. Ensure you refer to the individual subchart documentation on Artifact Hub for specific configuration options and further customization."]},{"i":"step-5-install-frinx-machine","l":"Step 5: Install FRINX Machine","p":["Install the FRINX Machine using Helm:","Verify the installation by checking the pods in the frinx namespace:","You should see output similar to:"]},{"i":"step-6-access-the-ui","l":"Step 6: Access the UI","p":["Visit Frinx Machine page in your browser on https://krakend.127.0.0.1.nip.io/frinxui"]}],[{"l":"Custom worker deployment","p":["To deploy a custom worker to Frinx Machine, utilize the generic worker Helm chart. Select the Helm chart version that corresponds with your application version, ensuring it is aligned with the Frinx Machine version.","You can find the necessary Helm chart at: Helm Chart for Frinx Workers."]},{"l":"Create the Chart Configuration","p":["Create the Chart.yaml file in new folder:"]},{"l":"Customize the Values","p":["Create the values.yaml file next to Chart.yaml:"]},{"l":"Deploy charts"},{"l":"Useful Links","p":["minikube image load","kind image load"]}],[{"l":"Authorization and authentification","p":["Follow official helm chart repository for oauth2-proxy. Don't forget to update the version to a more recent.","Follow oauth2-proxy official documentation to configure Azure AD."]},{"l":"Install Oauth2-Proxy"},{"l":"Configure RBAC","p":["Rbac functionality can be configured on subchart level.","https://artifacthub.io/packages/helm/frinx-helm-charts/krakend?modal=values&path=rbac","https://artifacthub.io/packages/helm/frinx-helm-charts/workflow-manager?modal=values&path=rbac","https://artifacthub.io/packages/helm/frinx-helm-charts/topology-discovery?modal=values&path=rbac","env: X_AUTH_USER_GROUP: * frinx-rbac-admin-role"]}],[{"l":"Demo Use Cases","p":["The following use cases demonstrate the basic usage of FRINX Machine. These examples will help you explore the platform's capabilities, including executing prepared workflows, creating custom workflows via the workflow builder, and manually managing your device inventory."]},{"l":"1. Executing Prepared Workflows","p":["Experience the power of automation by running pre-configured workflows.","Learn how to efficiently manage network tasks using automated processes."]},{"l":"2. Creating Custom Workflows","p":["Utilize the workflow builder to create and customize your workflows.","Tailor processes to your specific needs, enhancing operational efficiency."]},{"l":"3. Managing Device Inventory","p":["Add devices to your inventory manually, providing flexibility to experiment with different configurations.","This feature is particularly useful for testing and deploying your own networking devices."]},{"l":"4. Controlling Devices","p":["Manage devices in your inventory through the user interface (UI).","Execute operations using prepared workflows, ensuring streamlined control and management."]},{"l":"5. Configuring Network Services","p":["Set up L2VPNs between virtual devices, enhancing network connectivity and performance.","Create loopbacks on device interfaces either manually or through automated workflows, demonstrating the versatility of FRINX Machine.","These use cases serve as a starting point for exploring the extensive capabilities of FRINX Machine. They illustrate how the platform can be utilized for a variety of networking tasks, from basic device management to complex network configurations."]},{"l":"Install Demo Use Case workflows","p":["Use demo-worklows helm chart to run sample-topology and frinx-demo-workflows conducor worker."]},{"l":"Install Frinx Machine","p":["Make sure your Frinx Machine is running. Demo Use Cases"]},{"l":"Install Demo workflows and Sample Topology"}],[{"l":"FRINX Machine Demo Manual","p":["After logging into FRINX Machine, you can see the FRINX Machine dashboard:","FRINX Machine dashboard"]}],[{"l":"Add a device to inventory and install it"},{"l":"Adding device to inventory","p":["At the FRINX Machine Dashboard under Device Inventory section click on Add new device panel. The page with the form titled Add device opens.","Add device to inventory"]},{"l":"JSON examples","p":["New devices added to Device inventory are defined by JSON code snippets. (These snippets are part of UniConfig RPC connection-manager:install-node.) They are similar to Blueprints. This snippet is going to be filled into Mount parameters field.","Another way is to add a new device from blueprint: toggle the Use blueprint? switch in the form and choose the blueprint that you want to use from Select blueprint drop-down list.","Note: following snippets refer to devices present in sample-topology demo"]},{"i":"cisco-classic-ios-cli","l":"Cisco classic IOS (cli)"},{"i":"cisco-ios-xr-netconf","l":"Cisco IOS XR (netconf)"},{"i":"huawei-cli","l":"Huawei (cli)"},{"i":"calix-netconf","l":"CALIX (netconf)","p":["Note: this device is not present in sample-topology"]},{"i":"nokia-netconf","l":"Nokia (netconf)","p":["Note: this device is not present in sample-topology"]},{"i":"saos-6-cli","l":"SAOS 6 (cli)"},{"i":"saos-8-cli","l":"SAOS 8 (cli)"},{"l":"Install the new device from Inventory","p":["After the device is added we can install it to UniConfig. At the FRINX Machine Dashboard under Device Inventory section click on Explore & configure devices panel. The page titled Devices opens - it lists all devices from Device inventory.","Click blue Install button located on the row next to a device which you want to install - after successful installation button will change to green button with the text Installed.","Install device from inventory","If you follow instruction properly, your devices are now listed in Device inventory and installed, ready to be operated through Frinx Machine."]}],[{"l":"Install all devices from inventory","p":["When Device Inventory contains a lot of devices, it can be tedious to install them one by one. To make things easier, there is a workflow which allows to install all devices present in the inventory.","Follow these instructions to use the workflow:","At the FRINX Machine Dashboard under Workflow Manage section click on Explore workflows panel. The page titled Workflow definitions opens. Use Search workflow by name input box and fill in Install_all_from_inventory and click Search button.","Search for workflow Install_all_from_inventory","The list of workflows narrows down to two items - workflows Install_all_from_inventory and Uninstall_all_from_inventory. Click blue Execute button (blue play icon) located on the row next to the workflow. The form titled with the name of workflow Install_all_from_inventory appears and optionally you can fill in the input parameter labels which allows to select a subset of devices to install. (You can specify a device label while adding devices to Device Inventory.) We want to install all uninstalled devices - do not fill in the input labels and click Execute workflow button. As a result to the left of the Execute workflow button will appear the link Executed workflow in detail.","Execute workflow Install_all_from_inventory","After you click the link Executed workflow in detail you will be navigated to a page with details of the executed workflow - it displays individual tasks for this workflow, it is possible to click whatever task and examine its inputs and outputs, whether it was successful or unsuccessful etc.","Note: Similarily you can use workflow Uninstall_all_from_inventory to uninstall all devices at once."]}],[{"l":"Device configure loopback"},{"l":"Demo Config Manager UI","p":["Using the Demo Config Manager:","On the FRINX Machine main page, select Explore & configure devices.","Make sure that the device you want to configure is installed. If not, select Install first.","For this demo, we use the IOS01 device. Locate the device in the list and select the corresponding gear icon on the right. (If you see a message saying Transaction expired, select Refresh).","Device Inventory - Devices - list of devices","For the Loopback0 interface, change the enabled status to false.","Select Save to save your changes.","To review your changes, select Calculate diff.","To view the set of commands used for the change, select Dry run.","To apply changes to the device, select Commit to network. You can also see the changes in the Operational data store.","Device Inventory - configure device IOS01","To revert changes made to the device configuration:","Select Transactions.","Select the Revert icon for your transaction.","Select Revert changes."]}],[{"l":"Create loopback all in uniconfig"},{"i":"demo-creating-a-loopback-address-on-devices-stored-in-the-inventory","l":"Demo: Creating a loopback address on devices stored in the inventory","p":["This workflow creates a loopback interface on all devices installed in the inventory or on all devices filtered by labels. Labels are markers that serve as a differentiator.","Check if all devices are installed. You can install them manually or by executing the Install_all_from_inventory / 1 workflow.","FRINX Machine dashboard","On the main page, select Explore workflows. In the Search by keyword column, enter loopback. The Create_loopback_all_in_uniconfig / 1 workflow will appear in the list. Under Actions, select the corresponding Run button for the workflow.","Under loopback_id, insert 77 and select Execute. Click on the link that appears.","All tasks were executed correctly and are completed.","On the results page, you will see five individual tasks:"]},{"l":"INVENTORY_get_all_devices_as_dynamic_fork_tasks","p":["This workflow displays a list of all devices in the inventory or devices filtered by label. It parses the output in the correct format for the dynamic fork, which creates a number of tasks depending on the number of devices in the inventory."]},{"l":"SUB_WORKFLOW","p":["This is the dynamic fork sub-workflow. In this case, it creates UNICONFIG_write_structured_device_data for every individual device in the inventory. You can then get detailed information on the progress and succession of every device."]},{"l":"UNICONFIG_calculate_diff","p":["This remote procedure call creates a difference between the actual UniConfig topology devices and the intended UniConfig topology nodes."]},{"l":"UNICONFIG_dryrun_commit","p":["This remote procedure call resolves the difference between actual and intended device configurations. After all changes are applied, the cli-dryrun journal is read and a remote procedure call output is created and returned."]},{"l":"UNICONFIG_commit","p":["This is the final task that actually commits the intended configuration to the devices."]}],[{"l":"Create workflow"},{"l":"Demo workflow UI basics","p":["Workflow Builder is a graphical interface for Workflow Manager and is used to create, modify and manage workflows.","Workflows are groups of tasks and/or sub-workflows that can be used, for example, to install or delete devices, create loopback interfaces on devices, send messages and much more. You can create your own workflows or edit existing ones by adding or removing tasks or sub-workflows.","Every task and sub-workflow placed in a workflow has a unique reference alias, and no two workflows can share a name and version."]},{"l":"How to create a new custom workflow","p":["A translation of what is happening here: \"If the identified device is of the type saos, then extract the name from the output message of the previous task, change the letters to uppercase, extract the version from the output message of the previous task, glue them together and add _1(because that is how devices are named in this demo topology\".","Above every task or workflow there are two icons:","As above, if we enter the username and password directly, the workflow will not ask for credentials at startup.","decision task: Makes a different kind of decision from the lambda task discussed above. This task works like a switch on a track, sending the train one way or another. The data needed to make a decision is supplied by the lambda task.","Device_identification task:","Enter details for the new workflow. Under Name, enter a name for your workflow (note that this name cannot be changed later). The Description is for additional information about the workflow and can be left empty. Label can help you to find your workflow later under Explore workflows, but can also be left empty. Select Save changes when ready.","Enter the following into the body:","Finding your new workflow and running it with multiple different inputs such as 10 000, 10 002, 10 012, etc.","For different ports, you can see different devices with other run commands in memory.","FRINX Machine dashboard","FRINX Machine dashboard FRINX Machine dashboard","If the input value for decision is other, it directs the flow towards device_identification. If the input value is false, it directs the flow towards terminate. This corresponds to the way we connected the cells in the workflow builder.","In the Input parameters tab and the Lambda value field, enter: ${workflow.input.port}. This indicates that the task should work with what was entered in the port field in the input of this workflow. (We will cover this later, in section 7.)","In the Input parameters tab under management_ip, enter sample-topology. This is the name of the topology in this installation, whereas in production you would use a real name. For port, enter ${workflow.input.port}. If you enter a port number manually, the workflow will not ask for one when started (the same goes for management_ip and other fields). However, we want the user to be able to select a port they are interested in, as we did with the lambda task in section 4.","In the Input parameters tab, delete the default parameter foo. For the param parameter, enter ${lambda_IkSu.output.result.value}. (Note that IkSu is an automatically generated reference alias that you must edit to match the one generated for you.) What ${lambda_IkSu.output.result.value} means is to take the value from lambda_xyzq which is in the output, find the result in the output and the value in it.","In the Input parameters tab, enter COMPLETED(or FAILED, at your discretion) in the Termination status field. You can enter whatever message you want in the Expected workflow output field (for example, Device not supported.)","In the Script expression field, enter a small function which we described above.","In this case, if the specified port is both greater than or equal to 10000 and less than 10005, the status chosen is keep working. Otherwise, the status is end. This status is the output of the lambda and the input for the next task or sub-workflow.","lambda task: Makes a decision on which status to choose based on the embedded port. In this example we will only consider ports 10000–10004, and others are ignored. The lambda task lets you enter a small code (lambda - function without name) into the workflow builder.","Like we mentioned above, in this demo workflow we will assume that login credentials are the same everywhere.","Next steps:","Now we can add more tasks. In the left column under System tasks, we can add another lambda. In the Workflows section, you can find Read_journal_cli_device. Let us place them next to each other after Device_identification and concatenate them:","Now we can create a new workflow from scratch:","password: ${workflow.input.password}","Read_journal_cli_device: In the Input parameters tab under device_id, enter ${lambda_ZW66.output.result}.","Remove/Expand:","Save and run your workflow.","Second lambda: Enter ${Device_identificationRef_f7I6.output} as the lambda value, meaning \"take the output from the previous Device_identification task and use that\".","Select Create on the main page of FRINX Machine.","Sub-workflows are similar to classic workflows, but inside of another workflow. The workflow that we are creating can also be used as a building block for another workflow, becoming a sub-workflow itself. In this manner, we can layer and reuse previously created workflows.","terminated task:","The form - Create new workflow","The output from Read_journal_cli_device is concatenated with END, as is the output from terminated. Thus we have closed our custom workflow.","Under System tasks, click the + sign for the lambda, decision and terminate tasks. Under Workflows, click the + sign for Device_identification. Tasks and sub-workflows are added on top of each other on the canvas and can be dragged around. To connect all parts of the workflow, hover over IN and OUT where the + sign appears. Connect the parts as follows: START- lambda- decision- (other) to Device_identification and default to terminate. Each task and workflow has a reference alias after its name, which works as unique a identifier.","Update:","username and password: For this demo, we assume that the following login credentials are used on all devices: username: frinx and password: frinx","username: ${workflow.input.username}","When working with devices using different login credentials, you need to be able to change or enter them at startup. This can be achieved in the same way as with the port parameter:","Workflow builder UI - Actions - Save workflow Workflow builder UI - clicked Save and execute button - form for the workflow","Workflow builder UI - adding more tasks","Workflow builder UI - create or update workflow","Workflow builder UI - final workflow design Workflow builder UI - final workflow design","Workflow builder UI - icon Edit task","Workflow builder UI - icon Edit task clicked - form for editing of desision task","Workflow builder UI - icon Edit task clicked - form for editing of lambda task","Workflow builder UI - icon Edit task clicked - form for editing of second lambda task","Workflow builder UI - icon Edit task clicked - form for editing of second subworkflow","Workflow builder UI - icon Edit task clicked - form for editing of subworkflow","Workflow builder UI - icon Edit task clicked - form for editing of terminate task","Workflow builder UI - icon Menu"]}],[{"l":"Creating a Layer 2 VPN Point-to-Point Connection","p":["This section details how to find and execute a prebuilt workflow that creates a Layer 2 VPN Point-to-Point connection within Workflow Manager."]},{"l":"Navigating through Workflow Manager","p":["From the FRINX Machine Dashboard you can either under section Workflow Manager click panel Explore workflows or select the menu tab in the upper left-hand corner and click the menu item Workflow manager.","On the page Workflow definitions fill in search box Search workflow by name the name of workflow: Create_L2VPN_P2P_OC_uniconfig and click Search button or scroll down to find it in the list of prebuilt worflows.","Frinx Machine Dashboard","Workflows definitions page","Once you have located the workflow press the Play button located to the right of the workflow, this will open the form with the title Create_L2VPN_P2P_OC_uniconfig- the workflow configuration window."]},{"l":"Configuring the Workflow","p":["The configuring form for workflow Create_L2VPN_P2P_OC_uniconfig contains inputs pre-filled with following data:","Workflow Create_L2VPN_P2P_OC_uniconfig: L2 VPN Configuration","Once you have completed, press the Execute workflow button, to the left of the Execute workflow button will appear the link Executed workflow in detail. Click on this link Executed workflow in detail to see the details of the executed workflow.","Executed workflow in detail - Link"]},{"l":"Output of the Executed Workflow","p":["You can see the detail of executed workflow after clicking link Executed workflow in detail immediatelly after executing of workflow. If you do not use this opportunity you can navigate to Executed workflows page and to find executed workflow in the list of executed workflows.(From the FRINX Machine Dashboard under section Workflow Manager click panel Executed workflows)","Select the workflow Create_L2VPN_P2P_OC_uniconfig to see the output from all of the tasks completed within this workflow.","Executed Workflow Details","This following sections are available within the output window or on the page with details for executed workflow:","Task Details: This tab gives a detailed list of the individual tasks (ordered list of tasks - task type) executed within the conductor, a log of each tasks start time and end time, and a status of 'Completed' or 'Failed'. If task is a workflow (that is the parent workflow is calling another workflow) we refer to is as subworkflow and there is an icon which navigate us to display a detailed list of the individual tasks from which consist the subworkflow.","Input/Output: This tab contains Workflow Input which can be e.g. inputs for some API call and Workflow Output which can be e.g. result from some API call.","JSON: This tab gives a detailed output in JSON format of all executed tasks from which consist the workflow. Click the Unescape button to make the output more user-friendly to read.","Edit Rerun: This tab allows you to change the inputs of the previously executed workflow and execute the new instance by clicking of Rerun button.","Execution Flow: A structured map from the conductor lays out the path of tasks executed from start to finish, any forks in the path are also shown here.","Task Details: As we already explained this tab lists tasks from which the workflow consists - if you click on any of the tasks you will receive a pop-up window that contains these tabs:","Summary: Provide a summary for executed task e.g. Task Ref. Name, Description, Input, Output...","JSON: JSON output of the completed task with that goes into greater detail. about the task execution. Click the Unescape button to make the output more user-friendly to read.","Logs: Log status.","Pop-up window can be exited via clicking close-task-details icon."]},{"l":"Sub-Workflows","p":["Within the original Details of Create_L2VPN_P2P_OC_uniconfig window you will see a sub-workflow.","Sub-Workflow","This sub-workflow is an embedded task that makes a separate API call to Slack to notify a pre-defined user group that the workflow has been executed and whether it has succeeded or failed."]}],[{"l":"Grafana","p":["Grafana is an open source visualization and analytics software. It allows to query, visualize, alert on, and explore metrics, logs, and traces no matter where they are stored.","Grafana Login page","By default, Grafana can be accessed at localhost:3000 or 127.0.0.1:3000","Default credentials are:","Username: frinx Password: frinx123!"]},{"l":"Monitoring","p":["Grafana in FRINX Machine monitors multitude of metrics. At this time, these are:","Device monitoring","FRINX Machine logs","Node monitoring","SSL monitoring","UniConfig-controller monitoring","Workflows monitoring"]},{"l":"Device Monitoring","p":["This dashboard displays data on a specific installed device/node."]},{"l":"FRINX Machine Logs","p":["This dashboard monitors all services running in FRINX Machine. You can filter by individual services, and also look for a specific value.","Logs Monitoring"]},{"l":"FRINX Machine Node Monitoring","p":["This dashboard monitors the state of VM/System where FRINX Machine is running. It reports info like CPU utilisation, Memory utilisation, Disk usage, Up-time etc.","Node Monitoring"]},{"l":"UniConfig Controller Monitoring","p":["This dashboard keeps track of various UniConfig transactions. It displays number of transactions at a given time."]},{"l":"Workflows Monitoring","p":["Collecting data on workflows is being worked on."]}],[{"l":"FRINX UniConfig introduction","p":["The purpose of UniConfig is to manage the configuration state and retrieve the operational state of physical and virtual networking devices.","UniConfig provides a single API for many different devices in the network. It can be run as an application on bare metal in a VM or a container, stand-alone, or as part of our automation solution, FRINX Machine. UniConfig has a built-in data store that can be run in-memory or with an external database.","UniConfig features"]},{"l":"UniConfig key features","p":["A \"Lazy CLI\" feature to suspend and resume connections without having to maintain keepalives","Allows for diffs to be built between actual and intended execution of atomic configuration changes","Can execute commands in parallel on multiple devices","Can read and store proprietary data models from network devices that follow the YANG data model","Choose between NETCONF or RESTCONF to connect to devices","Data export and import via blacklist and whitelist functions","Execute & Read API- Unstructured data via SSH and Telnet","Execute & Read capable API: Like Ansible, TCL Scripting or similar products, strings can be passed and received through SSH or Telnet via REST API. UniConfig provides the authentication and transportation of data without interpreting it.","High availability","Offers the ability to do a dry-commit to evaluate the functionality of a configuration before it is executed on devices","OpenConfig API– Translation provided by our open source device library","OpenConfig API: An API that is translated into device-specific CLI or YANG data models. The installation of \"translation units\" on devices is required. FRINX provides an open-source library of devices from a variety of network vendors. The open-source framework allows anyone to contribute or consume the contents of the expanding list of supported network devices.","Provides snapshots of previous configurations for rollback","Provides subtree filtering capabilities in NETCONF","Provides templates for device configuration","Pushes configuration data to devices via NETCONF, CLI or gNMI","Python microservices are used to integrate with the FRINX machine","Retrieves and stores current startup and running configuration from mounted network devices","Retrieves operational data from devices via NETCONF, CLI or gNMI","Subscribe to gNMI notifications","Subscribe to NETCONF notifications via web sockets","Support for 3-phase commit by using NETCONF confirmed-commit","Support for gNOI","Support for YANG 1.1 and Tail-f actions","Supports PostgreSQL as an external database","The ability to log specific devices as needed","The UniConfig client allows for simple, full-service access to UniConfig features","The UniConfig UI allows users to interact with the network controller using a web-based user interface","Transactions can be managed on one or multiple devices","Translates between CLI, native model and standard data models (i.e., OpenConfig) via our open-source device library","UniConfig allows users to communicate with their network infrastructure in four different ways:","UniConfig Native API– Direct access to vendor specific YANG data models that are native to the connected devices as well as UniConfig functions (diff, commit, snapshots, etc.)","UniConfig Native API: Vendor-specific YANG data models are absorbed by UniConfig to allow configuration of mounted devices. UniConfig maps vendor-specific \"native\" models into it's data store to provide stateful configuration capabilities to applications and users.","UniConfig Native CLI API– Programmatic access to the CLI without the need for translation units (experimental)","UniConfig Native CLI API: Allows for programmatic interaction with a device's CLI via the API and without the use of 'translation units'. Only a schema file is needed. (This option is currently experimental. Contact FRINX for more information.)","UniConfig solution"]},{"l":"UniConfig in a Docker container"},{"l":"Download and activate FRINX UniConfig","p":["To download, activate and start UniConfig in a Docker container:"]},{"l":"Stop the container","p":["To stop the container:"]},{"l":"UniConfig as a Java process in a VM or on a host"},{"l":"Download FRINX UniConfig","p":["To download UniConfig, please contact: marketing@elisapolystar.com","By downloading, you accept the FRINX software agreement."]},{"l":"Activate FRINX UniConfig","p":["To activate UniConfig, unzip the file, open the directory and run the following command:","For more information on the different arguments, run the startup script with the -h flag"]},{"l":"OpenAPI","p":["UniConfig distributions contain a .yaml file that generates a list of all usable RPCs and their examples. You can view it locally or on our hosted version that always shows the latest OpenAPI version.","The file can be found here:","See OpenAPI for more information."]}],[{"l":"User guide","p":["The UniConfig user guide includes the following sections:"]},{"l":"Basic concepts","p":["Explanations of basic concepts, principles and mechanisms within UniConfig."]},{"l":"Device installation","p":["Explains the device installation process. Covers the basic mechanisms that take place during installation, and explains parameters with examples of install requests. Also covers the differences between CLI, NETCONF and gNMI API."]},{"l":"UniConfig operations","p":["Lists various APIs used to interact with UniConfig."]},{"l":"Operational procedures","p":["Lists various procedures that can be used with UniConfig."]},{"l":"Performance and scale","p":["Describes the performance of UniConfig in various scale scenarios."]},{"l":"Monitoring","p":["Describes UniConfig performance metrics."]},{"i":"uniconfig-client-sdk","l":"UniConfig Client (SDK)","p":["UniConfig provides a full-blown Java-based SDK. All UniConfig operations available over RESTCONF are also available when using the SDK."]}],[{"l":"Basic Concepts","p":["UniConfig is a network controller that enables network operators to automate simple and complex procedures in their heterogeneous networks. UniConfig uses CLI, NETCONF and gNMI to connect to network devices and provides a RESTCONF interface on its northbound to provide an API to applications. UniConfig users use clients in various programming languages to communicate from their applications with the controller. FRINX provides a Java client and python workers to integrate with its workflow automation in FRINX Machine. Other clients can be generated from the OpenAPI documentation of the UniConfig API.","UniConfig is stateless and stores all state information before and after transactions in a PostgreSQL database. UniConfig provides transaction capabilities on its northbound API, so that multiple clients can interact with UniConfig at the same time in a well-structured way. In addition, transactions are also supported towards all network devices independent of the capabilities of these devices. Transactions can be rolled back on error automatically and on user demand by specifying a transaction ID from the transaction log. Clients can use an “immediate commit” model (changes sent to the controller get applied to the devices immediately) or a “build and commit” model (changes are staged on the controller until a commit operation pushes all changes in a transaction to one or multiple devices).","To support N+1 redundancy and horizontal scale (meaning adding more controller instances allows the system to serve more network devices and more clients) UniConfig can be deployed together with a load balancer(E.g.: Traefik). The combination of a state-less load balancer and multiple UniConfig instances achieves high availability and supports many network devices and client applications to configure the network.","An open-source device library allows users to connect UniConfig to CLI devices that do not support SDN protocols like NETCONF and gNMI. This library is open to users, independent software vendors and any 3rd party to contribute to and use to achieve their automation goals.","Finally, the UniConfig shell, allows users to interact with all UniConfig operations and the connected devices in a model driven way through CLI.","UniConfig runs in containers, VMs or as application and can be deployed stand-alone or as part of the \"FRINX Machine\" network automation solution."]}],[{"l":"Device installation"},{"i":"device-installation-1","l":"Device installation","p":["Guide to installation mechanisms along with CLI, NETCONF and gNMI examples."]},{"l":"UniConfig CLI","p":["The CLI southbound plugin allows UniConfig to communicate with CLI devices that do not support NETCONF or other programmatic APIs. The CLI service module uses YANG models and implements a translation logic to send and receive structured data to and from CLI devices."]},{"l":"UniConfig Netconf","p":["NETCONF is an Internet Engineering Task Force (IETF) protocol used to configure and monitor devices in the network. It can create, recover, update and delete configurations of network devices.","NETCONF operations are overlaid on the Remote Procedure Call (RPC) layer and may be described in either XML or JSON."]},{"l":"UniConfig-native CLI","p":["UniConfig-native CLI allows you to configure CLI-enabled devices using YANG models that describe configuration commands.","In a UniConfig-native CLI deployment, translation units are defined only by YANG models and device-specific characteristics used for parsing and serializing commands. Readers and writers are automatically created and provided to the translation registry (i.e., the user does not need to write them individually).","YANG models can be constructed by following well-defined rules explained in the Developer guide."]},{"l":"UniConfig gNMI","p":["The gRPC Network Management Interface (gNMI) is used to configure and monitor devices in the network. It can create, update, and delete configurations of network devices as well as susbcriptions to telemetry streams.","gNMI operations are performed via Remote Procedure Call (RPC) developed by Google. All gNMI messages within gRPC service definition are defined as protocol buffers (proto3)."]},{"l":"UniConfig gNOI","p":["The gRPC Network Operations Interface (gNOI) is used to execute operational commands on network devices. The gNOI protocol supports certificate management, bootstrapping and OS installation service.","All gNOI messages within gRPC service definition are defined as protocol buffers (proto3).","Network management protocols are used in the southbound API of the UniConfig Lighty distribution to install and communicate with devices.","The following protocols are currently supported:","NETCONF (Network Configuration Protocol)","SSH / TELNET","gNMI/gNOI (Network Management/Operations interface)"]}],[{"l":"Device installation","p":["Installing is the process of loading device information into UniConfig database. This information is saved in PostgreSQL database and used whenever transaction occurs. When the transaction is finished the connection to device is closed again, until next transaction.","These are the steps of installation process:","creation of UniConfig transaction","creation of mountpoint - connection to device","loading configuration and metadata from mountpoint","closing mountpoint and connection to device","storing synced configuration and metadata to database","closing UniConfig transaction","Node can be installed only once (you will receive error if node has already been installed).","You can specify if you would like to install node on the UniConfig layer. Default value is 'true':","Only 1 node with the same node-id can be installed on UniConfig layer.","It is synchronous: it succeeds only after node is successfully installed it fails in other cases – max-connection-attempts is automatically set to value '1', if different value is not provided in RPC input, database or config file.","Following sections provide deeper explanation of parameters needed for installation, along with example install requests.","Overview of our OpenAPI along with all parameters and expected returns can be found here."]},{"l":"Default parameters","p":["All install parameters (CLI/NETCONF) are set in database when Uniconfig is initializing. Values of these parameters are equal to specific yang model default values. These parameters are used when they are missing in RPC request.","Priority of using install parameters :","Parameter set in install RPC request","Parameter set in database","Default parameter from yang model","Priority of initial writing default parameters into database:","Database already contains default parameters","User defines default parameters into config file","Default values from yang schema file will be saved","Default parameters can be managed (read/update) using RESTCONF/Uniconfig shell with UniConfig Cloud Config.","Default parameters can also be defined in the application.properties.json file located in the config directory.","RPC request - read CLI default parameters:"]},{"l":"Installing CLI device","p":["Install node RPC","List of basic connection parameters that are used for identification of remote device. All of these parameters are mandatory.","node-id- Name of node that represents device in the topology.","cli-topology:host- IP address or domain-name of target device that runs SSH or Telnet server.","cli-topology:port- TCP port on which the SSH or Telnet server on remote device is listening to incoming connections. Standard SSH port is '22', standard Telnet port is '23'.","cli-topology:transport-type- Application protocol used for communication with device - supported options are 'ssh' and 'telnet'.","cli-topology:device-type- Device type that is used for selection of translation units that maps device configuration to OpenConfig models. Supported devices can be found","cli-topology:device-version- Version of device. Use a specific version or * for a generic one. * enables only basic read and write management without the support of OpenConfig models. Here.","cli-topology:username- Username for accessing of CLI management line.","cli-topology:password- Password assigned to username.","uniconfig-config:install-uniconfig-node-enabled- Whether node should be installed to UniConfig and unified layers. By default, this flag is set to 'true'."]},{"l":"Authentication parameters","p":["List of authentication parameters used for identification of remote user utilized for configuration of the device. Username and password parameters are mandatory.","cli-topology:username- Username for accessing of CLI management line.","cli-topology:password- Password assigned to username.","List of parameters that can be used for adjusting of reconnection strategy. None of these parameters is mandatory - if they are not set, default values are set. There are two exclusive groups of parameters based on selected reconnection strategy - you can define only parameters from single group. By default, keepalive strategy is used."]},{"l":"Connection parameters","p":["Following parameters adjust maintaining of CLI session state. None of these parameters are mandatory (default values will be used).","cli-topology:max-connection-attempts- Maximum number of initial connection attempts(default value: 1, non-positive value or null is interpreted as infinity). If there are unstable devices in the network it might be useful to provide max-connection-attempts higher than the default value. It would try to connect n times before throwing an ssh connection exception.","cli-topology:max-connection-attempts-install- Maximum number of initial connection attempts during install process (default value: 1, non-positive value or null is interpreted as infinity). If there are unstable devices in the network it might be useful to provide max-connection-attempts-install higher than the default value. It would try to connect n times before throwing an ssh connection exception.","cli-topology:max-reconnection-attempts- Maximum number of reconnection attempts(default value: 0, non-positive value or null is interpreted as infinity). It is used when open and established session dropped. max-reconnection-attempts is not that necessary to set. Uniconfig does not keep idle sessions open longer than it is necessary."]},{"l":"Storing failed installations","p":["The following parameter allows the user to store the installation in case the device is in some way unreachable.","uniconfig-config:store-failed-installation- If enabled, it will ensure that even if the device is unreachable, it will be stored in the node table in the database. If not set, the default value is false.","When the user sets the flag to true, an additional column called installation-status will be populated with a boolean flag (either SUCCESSFUL for a successful installation, or FAILED for a failed one). This lets the user know that there has been some problem and that the device was not installed correctly. The mount-point information of that node will be stored (unlike with the default value). With this info already stored, the user does not need to reinstall the device, as all the connection information is present in the UniConfig database. Syncing the device or calling a GET Request will try to reconnect to the device and if it is successful, the configuration data will be saved in the datastore and the request will then finish. The installation-status will then change to SUCCESSFUL. The installed device will then behave normally as if the installation was successful in the first place. If the device is still unreachable, the flag will stay FAILED.","This is useful when many devices are being installed in batches and the user doesn't know if they are up or not."]},{"l":"Installing without mount","p":["The following parameter lets you store node metadata into the UniConfig database without mounting the node:","uniconfig-config:store-without-mount- When enabled, skip the mount procedure and store node metadata into the UniConfig database with installation status FAILED. The default value is false.","This flag is primarily intended for scenarios where you want UniConfig to be aware of a specific node that is not yet up and reachable. Once the device is up, you can simply call the sync-from-network RPC to load the configuration. Additionally, this can reduce the lifetime of the install-node RPC, as it does not need to wait for connection failure."]},{"l":"Keepalive strategies","p":["1. Keepalive reconnection strategy","cli-topology:keepalive-delay- Delay between sending of keepalive messages over CLI session. The value should not be set higher than the execution of the longest operation. Default value: 60 seconds.","cli-topology:keepalive-timeout- This parameter defines how much time the CLI layer should wait for a response to keepalive message before the session is closed. Default value: 60 seconds.","cli-topology:keepalive-initial-delay- This parameter defines how much time CLI layer waits for establishment of new CLI session before the first reconnection attempt is launched. Default value: 120 seconds.","The keepalive parameters have two main functions:","keep the idle session open","timeout commands which would block the session forever"]},{"l":"Example of using the connection and keepalive parameters together","p":["For this example let us assume that we are dealing with a prod-like device, which would mean that some devices might have a large config. We would set these parameters:","Connection attempts would give us more flexibility if we work with unstable devices. It would try to ssh 3 times instead of 1 (default value). We should also keep in mind that the process of connecting to a device would take longer because of extra ssh attempts.","Keepalive commands can be set less than time of the installation, because keepalive commands can fit in between of the installation process. An important thing to keep in mind is to set sum of keepalive-delay and keepalive-timeout parameters higher than time of execution of the configuration show command. Otherwise, it could time out during writing out of the configuration to the console. For each type of device it is a different command ( configuration show brief for Ciena devices, show run for Cisco devices, etc.). Assumption is that it should not take more than 240 seconds (sum of keepalive params) to show the whole configuration. This can be appropriately adjusted to our circumstances.","2. Lazy reconnection strategy","command-timeout- Maximal time (in seconds) for command execution. If a command cannot be executed on a device in this time, the execution is considered a failure. Default value: 60 seconds.","connection-establish-timeout- Maximal time (in seconds) for connection establishment. If a connection attempt fails in this time, the attempt is considered a failure. Default value: 60 seconds.","connection-lazy-timeout- Maximal time (in seconds) for connection to keep alive. If no activity was detected in the session and the timeout has been reached, connection will be stopped. Default value: 60 seconds."]},{"l":"Journaling parameters","p":["The following parameters relate with tracing of executed commands. It is not required to set these parameters.","cli-topology:journal-size- Size of the cli mount-point journal. Journal keeps track of executed commands and makes them available for users/apps for debugging purposes. Value 0 disables journaling(it is default value).","cli-topology:dry-run-journal-size- Creates dry-run mount-point and defines number of commands in command history for dry-run mount-point. Value 0 disables dry-run functionality (it is default value).","cli-topology:journal-level- Sets how much information should be stored in the journal. Option 'command-only' stores only the actual commands executed on device. Option 'extended' records additional information such as: transaction life-cycle, which handlers were invoked etc."]},{"l":"Parsing parameters","p":["Parsing strategies are used for:","Recognizing of structure in cached device configuration that is represented in textual format.","Extraction of target sections from structured format of device configuration.","Parsing engine can be configured on creation of mountpoint by specification of parsing-engine leaf value. Currently, there are three supported CLI parsing strategies: tree-parser(default strategy), batch-parser and one-line-parser.","Both batch-parser and tree-parser depend on current implementation of'CliFlavour' which defines device-specific CLI patterns. For example, if 'CliFlavour' doesn't correctly specify format of 'show configuration' command, then neither batch-parser or tree-parser is applied and commands are sent directly to device."]},{"l":"Tree-parser","p":["It is set as default parsing engine in case you choose to not use'parsing-engine' parameter.","Running-configuration is mapped into the tree structure before the first command lookup is executed from translation unit. Afterwards, this tree can be reused in the same transaction for faster lookup process (for example, one 'sync-from-network' task is executed in one transaction).","Tree-parser is faster than batch-parser in most cases because device configuration must be traversed only once and searching for target section in parsed tree structure has only logarithmic time complexity. The longer the device configuration is, the better performance improvement is achieved using this parsing strategy.","Both batch-parser and tree-parser should be capable to parse the same device configurations (in other words, tree-parser doesn't have any functional restrictions in comparison to batch-parser)."]},{"l":"Batch-parser","p":["Running-configuration must be traversed from the beginning each time when new target section is extracted from the configuration (such lookup process is launched from CLI translation units).","Internally, this parser uses regular expressions to recognize structure of configuration and find target section. From this reason, if configuration is long, this batch-parser becomes ineffective to extract sections that are placed near the end of device configuration.","Batch-parser should be used only as fallback strategy in the case when tree-parser fails."]},{"l":"One-line-parser","p":["CLI parsing engine that stores configuration in the cache in the form of blocks and then uses grep function for parsing running-configuration"]},{"l":"Cisco IOX XR Example request"},{"l":"Junos Example request"},{"l":"Uninstalling CLI device","p":["Uninstall node RPC"]},{"l":"Example request"},{"l":"Installing Netconf device"},{"l":"Identification of remote device","p":["List of basic connection parameters that are used for identification of remote device. Only tcp-only parameter must not be specified in input of the request.","node-id- Name of node that represents device / mount-point in the topology.","netconf-node-topology:host- IP address or domain-name of target device that runs NETCONF server.","netconf-node-topology:port- TCP port on which NETCONF server is listening to incoming connections.","netconf-node-topology:tcp-only- If it is set to 'true', NETCONF session is created directly on top of TCP connection. Otherwise,'SSH' is used as carriage protocol. By default, this parameter is set to 'false'."]},{"i":"authentication-parameters-1","l":"Authentication parameters","p":["Parameters used for configuration of the basic authentication method against NETCONF server. These parameters must be specified in the input request.","network-topology:username- Name of the user that has permission to access device using NETCONF management line.","network-topology:password- Password to the user in non-encrypted format.","There are also other authentication parameters if different authentication method is used - for example, key-based authentication requires specification of key-id. All available authentication parameters can be found in netconf-node-topology.yang under netconf-node-credentials grouping."]},{"l":"Session timers","p":["The following parameters adjust timers that are related with maintaining of NETCONF session state. None of these parameters are mandatory(default values will be used).","netconf-node-topology:initial-connection-timeout- Specifies timeout in seconds after which initial connection to the NETCONF server must be established (default value: 20 s).","netconf-node-topology:request-transaction-timeout- Timeout for blocking RPC operations within transactions (default value: 60 s).","netconf-node-topology:max-connection-attempts- Maximum number of connection attempts (default value: 1, non-positive value or null is interpreted as infinity).","netconf-node-topology:max-reconnection-attempts- Maximum number of reconnection attempts. It is used when ongoing session dropped (default value: 0, non-positive value or null is interpreted as infinity).","netconf-node-topology:between-attempts-timeout- Initial timeout between reconnection attempts (default value: 2 s).","netconf-node-topology:reconnenction-attempts-multiplier- Multiplier between subsequent delays of reconnection attempts (default value: 1.5).","netconf-node-topology:keepalive-delay- Delay between sending of keepalive RPC messages (default value: 120 sec).","netconf-node-topology:confirm-commit-timeout- The timeout for confirming the configuration by \"confirming-commit\" that was configured by \"confirmed-commit\". Configuration will be automatically reverted by device if the \"confirming-commit\" is not issued within the timeout period. This parameter has effect only on NETCONF nodes. (default value: 600 sec)."]},{"l":"Capabilities","p":["Parameters related to capabilities are often used when NETCONF device doesn't provide list of YANGs. Both parameters are optional.","netconf-node-topology:yang-module-capabilities- Set a list of capabilities to override capabilities provided in device's hello message. It can be used for devices that do not report any yang modules in their hello message.","netconf-node-topology:non-module-capabilities- Set a list of non-module based capabilities to override or merge non-module capabilities provided in device's hello message. It can be used for devices that do not report or incorrectly report non-module-based capabilities in their hello message.","Instead of defining netconf-node-topology:yang-module-capabilities, we can just define folder with yang schemas netconf-node-topology:schema-cache-directory: folder-name. For more information about using the netconf-node-topology:schema-cache-directory parameter, see RST Other parameters."]},{"l":"UniConfig-native","p":["Parameters related to installation of NETCONF or CLI nodes with uniconfig-native support.","uniconfig-config:uniconfig-native-enabled- Whether uniconfig-native should be used for installation of NETCONF or CLI node. By default, this flag is set to 'false'.","uniconfig-config:install-uniconfig-node-enabled- Whether node should be installed to UniConfig and unified layers. By default, this flag is set to 'true'.","uniconfig-config:sequence-read-active- Force sequential data reading when mounting a device. If set to 'true', sync-from-network is done in parallel. The default value is 'false'.","uniconfig-config:whitelist- List of root YANG entities that should be read.","uniconfig-config:blacklist- List of root YANG entities that should not be read from NETCONF device due to incompatibility with uniconfig-native or other malfunctions in YANG schemas. This parameter has effect only on NETCONF nodes.","uniconfig-config:validation-enabled- Whether validation RPC should be used before submitting configuration of node. By default, this flag is set to 'true'. This parameter has effect only on NETCONF nodes.","uniconfig-config:confirmed-commit-enabled- Whether confirmed-commit RPC should be used before submitting configuration of node. By default, this flag is set to 'true'. This parameter has effect only on NETCONF nodes.","uniconfig-config:store-failed-installation- Whether the installation should be stored in the database if it fails (e.g. is unreachable). The node will be 'installed' even though it failed and the user has 2 options:","uninstall the device and reinstall it.","call sync-from-network to sync the data from the device."]},{"l":"Flags","p":["Non-mandatory flag parameters that can be added to mount-request.","netconf-node-topology:enabled-strict-parsing- Default value of enabled-strict-parsing parameter is set to 'true'. This may inflicts in throwing exception during parsing of received NETCONF messages in case of unknown elements. If this parameter is set to 'false', then parser should ignore unknown elements and not throw exception during parsing.","netconf-node-topology:enabled-notifications- Default value of enabled-notifications is set to 'true'. If it is set to 'true' and NETCONF device supports notifications, NETCONF mountpoint will expose NETCONF notification and subscription services.","netconf-node-topology:reconnect-on-changed-schema- Default value of reconnect-on-changed-schema is set to 'false'. If it is set to 'true', NETCONF notifications are supported by device, and NETCONF notifications are enabled ('enabled-notifications' flag), the connector would auto disconnect/reconnect when schemas are changed in the remote device. The connector subscribes (right after connect) to base netconf notifications and listens for netconf-capability-change notification","netconf-node-topology:streaming-session- Default value of streaming-session parameter is set to 'false'. NETCONF session is created and optimized for receiving of NETCONF notifications from remote server."]},{"l":"Other parameters","p":["Other non-mandatory parameters that can be added to mount-request.","netconf-node-topology:schema-cache-directory- This parameter can be used for two cases:","Explicitly set name of NETCONF cache directory. If it is not set, the name of the schema cache directory is derived from device capabilities during mounting process.","Direct usage of the 'custom' NETCONF cache directory stored in the UniConfig 'cache' directory by name. This 'custom' directory must exist, must not be empty and also can not use the 'netconf-node-topology:yang-module-capabilities' parameter, because capability names will be generated from yang schemas stored in the 'custom' directory.","netconf-node-topology:dry-run-journal-size- Creates dry-run mount-point and defines number of NETCONF RPCs in history for dry-run mount-point. Value 0 disables dry-run functionality (it is default value).","netconf-node-topology:custom-connector-factory- Specification of the custom NETCONF connector factory. For example, if device doesn't support candidate data-store, this parameter should be set to 'netconf-customization-alu-ignore-candidate' string (default value is \"default\").","netconf-node-topology:edit-config-test-option- Specification of the test-option parameter in the netconf edit-config message. Possible values are 'set', 'test-then-set' or 'test-only'. If the edit-config-test-option is not explicitly specified in the mount request, then the default value will be used ('test-then-set'). See RFC-6241 for more information about this feature.","netconf-node-topology:concurrent-rpc-limit- Defines maximum number of concurrent RPCs, where 0 indicates no limit (it is default value).","There are additional install parameters in our OpenAPI, they can all be found here."]},{"l":"Example netconf request"},{"l":"Uninstalling Netconf device"},{"i":"example-request-1","l":"Example request"},{"l":"Installing gNMI device"},{"l":"Identifying remote device","p":["Basic connection parameters used to identify a remote device:","node-id- Name of the node that represents the device/mountpoint in the topology.","gnmi-topology:host- IP address or domain name of the target device running the gNMI server.","gnmi-topology:port- TCP port where the gNMI server is listening to incoming connections.","gnmi-topology:device-type- Specific device type, which enables some device-specific behavior. By default, this parameter is not specified.","gnmi-topology:connection-type- If specified, an insecure connection is created. The insecure connection is available only for DEBUG reasons. To establish a gRPC connection without TLS, choose the insecure connection type PLAINTEXT. The connection type PLAINTEXT indicates that the target should skip the signature verification steps if a secure connection is used.","gnmi-topology:keystore-id- If specified, a secure connection is created. Also requires keystore-id(identifier of the keystore), which is defined in the gnmi-certificate-storage model.","Only one of the parameters keystore-id and connection-type can be specified."]},{"i":"authentication-parameters-2","l":"Authentication parameters","p":["Parameters to configure the basic authentication method against a gNMI server. These parameters must be specified in the input request inside the gnmi-topology:credentials container:","gnmi-topology:username- Username with permission to access the device using gNMI.","gnmi-topology:password- Password for username."]},{"i":"session-timers-1","l":"Session timers","p":["The following parameters adjust timers related to maintaining gNMI session state. None of these parameters are mandatory (default values are used if not specified):","gnmi-topology:request-timeout- Timeout (in seconds) for each gNMI request. The request times out if not completed in time. The default value is 30."]},{"i":"flags-1","l":"Flags","p":["Non-mandatory flag parameters that can be added to a mount request:","gnmi-topology:enabled-notifications- If set to true and the gNMI device supports notifications, the gNMI mountpoint will expose GNMI notification and subscription services. The default value is true."]},{"i":"other-parameters-1","l":"Other parameters","p":["Other non-mandatory parameters that can be added to a mount request:","gnmi-topology:dry-run-journal-size- Size of the dry-run gNMI mountpoint journal. The dry-run journal captures gNMI operations that would be executed when reading/writing a configuration. However, the operations are not actually sent to the device. The default value is 0."]},{"l":"Extension parameters","p":["Other extended non-mandatory parameters that can be added to a mount-request inside of the extensions-parameters container."]},{"l":"gNMI parameters","p":["gnmi-topology:use-model-name-prefix- Some devices require a module prefix in the first element name of the gNMI request path (for example, interfaces -> openconfig-interfaces:interfaces). The default value is false."]},{"i":"uniconfig-native-1","l":"UniConfig-native","p":["Parameters related to installing gNMI nodes with uniconfig-native support:","uniconfig-config:uniconfig-native-enabled- Whether or not uniconfig-native should be used for installing of NETCONF, CLI or gNMI nodes. The default value is false.","uniconfig-config:sequence-read-active- Forces reading of data sequentially when mounting a device. If set to true, sync-from-network is done in parallel. The default value is false.","uniconfig-config:whitelist- List of root YANG entities that should be read.","uniconfig-config:store-failed-installation- Whether or not the installation is stored in the database if it fails (e.g., unreachable). The node is \"installed\" even though it fails, and the user has two options:","Uninstall the device and reinstall it.","Call sync-from-network to sync the data from the device.","An important install parameter is gnmi-topology:schema-cache-directory: folder-name. It specifies a folder name in the cache directory with the YANG schemas needed to install a device. If this parameter is not specified, user can create default-capability.json file inside of mentioned cache directory and UniConfig will dynamically resolve correct cache directory for given node. This json file must have all capabilities that device supports. Format of default-capability.json:"]},{"l":"Update paths","p":["This is a non-mandatory parameter that specifies a list of paths for which UniConfig will process intended changes as a gNMI SET message - Update operation. Paths are specified in regexp format.","More information about update paths feature: https://docs.frinx.io/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/#update-paths."]},{"l":"Replace paths","p":["This is a non-mandatory parameter that specifies a list of paths for which UniConfig will process intended changes as a gNMI SET message - Replace operation.","A specific replace diff implementation in UniConfig checks and merges all changes according to the specified replace-paths, and ensures that the gNMI SET message has the same path as the one specified in replace-paths in the install request.","Paths are specified in common RESTful URL format, but list entries can be compiled as a regexp pattern if specified with the $ sign after the = sign.","More information about the replace paths feature: https://docs.frinx.io/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/#replace-paths."]},{"l":"Remove module name paths","p":["This is a non-mandatory parameter that specifies a list of paths for which UniConfig removes the module name of specified list entry keys. (For example, protocol=openconfig-policy-types:BGP,bgp, remove-module-name-path = network-instances/network-instance=$.*/protocols/protocol).","The path format is the same as for replace-paths."]},{"l":"All type paths","p":["This is a non-mandatory parameter that specifies a list of paths for which UniConfig provides a GET request with the ALL data type.","The path format is the same as for replace-paths.","This feature only applies to the SONiC device type."]},{"l":"Dependency paths","p":["This is a non-mandatory parameter that specifies list of paths for which UniConfig will check and order the intended changes.","The format of dependency paths:","before- path without keys that is ordered before the path specified in after.","after- path without keys that is ordered after the path specified in before.","More information about dependency paths: https://docs.frinx.io/frinx-uniconfig/user-guide/network-management-protocols/uniconfig_gnmi/#dependency-paths."]},{"i":"example-request-2","l":"Example request"},{"l":"Uninstalling gNMI device"},{"i":"example-request-3","l":"Example request"},{"l":"Installing SNMP agent"},{"l":"Identification of remote agent","p":["List of basic connection parameters that are used for identification of remote agent.","node-id- Name of node that represents device / mount-point in the topology.","snmp-topology:host- IP address or domain-name of target device where SNMP agent is running.","snmp-topology:port- SNMP port on which SNMP agent is listening to incoming connections."]},{"l":"SNMP parameters","p":["snmp-topology:transport-type- UniConfig currently supports UDP for SNMP communication, with plans to add TCP support in the future.","snmp-topology:snmp-version- UniConfig currently supports V1 and V2c version of the SNMP, with plans to add V3 support in the future.","snmp-topology:connection-retries- Sets the number of retries to be performed before a request is timed out. Default value is 0.","snmp-topology:request-timeout- Timeout in milliseconds before a confirmed request is resent or timed out. Default value is 3000.","snmp-topology:get-bulk-size- The maximum number of values that can be returned in a single response to the get-bulk operation. Default value is 50."]},{"i":"authentication-parameters-3","l":"Authentication parameters","p":["snmp-topology:community-string- UniConfig currently supports only security string as authentication method that is used with V1 and V2c."]},{"l":"Others","p":["snmp-topology:mib-repository- Name of the MIB repository that contains MIB files."]},{"i":"example-request-4","l":"Example request"},{"l":"Uninstalling SNMP agent"},{"i":"example-request-5","l":"Example request"}],[{"l":"UniConfig CLI"},{"l":"Introduction","p":["The CLI southbound plugin enables the Frinx UniConfig to communicate with CLI devices that do not speak NETCONF or any other programmatic API. The CLI service module uses YANG models and implements a translation logic to send and receive structured data to and from CLI devices. This allows applications to use a service model or unified device model to communicate with a broad range of network platforms and SW revisions from different vendors.","Much like the NETCONF southbound plugin, the CLI southbound plugin enables fully model-driven, transactional device management for internal and external OpenDaylight applications. In fact, the applications are completely unaware of underlying transport and can manage devices over the CLI plugin in the same exact way as over NETCONF.","Once we have installed the device, we can present an abstract, model-based network device and service interface to applications and users. For example, we can parse the output of an IOS command and return structured data.","CLI southbound plugin"]},{"l":"Architecture","p":["This section provides an architectural overview of the plugin, focusing on the main components."]},{"l":"CLI topology","p":["The CLI topology is a dedicated topology instance where users and applications can:","install a CLI device,","uninstall a device,","check the state of connection,","read/write data from/to a device,","execute RPCs on a device.","This topology can be seen as an equivalent of topology-netconf, providing the same features for netconf devices. The topology APIs are YANG APIs based on the ietf-topology model. Similarly to netconf topology, CLI topology augments the model with some basic configuration data and also some state to monitor mountpoints."]},{"l":"CLI mountpoint","p":["The plugin relies on MD-SAL and its concept of mountpoints to expose management of a CLI device. By exposing a mountpoint into MD-SAL, it enables the CLI topology to actually access the device's data in a structured/YANG manner. Components of such a mountpoint can be divided into 3 distinct layers:","Service layer - implementation of MD-SAL APIs delegating execution to transport layer.","Translation layer - a generic and extensible translation layer. The actual translation between YANG and CLI takes place in the extensions. The resulting CLI commands are then delegated to transport layer.","Transport layer - implementation of various transport protocols used for actual communication with network devices.","The following diagram shows the layers of a CLI mountpoint:"]},{"l":"Translation layer","p":["The CLI southbound plugin is as generic as possible. However, the device-specific translation code (from YANG data -\\ CLI commands and vice versa), needs to be encapsulated in a device-specific translation plugin. E.g. Cisco IOS specific translation code needs to be implemented by Cisco IOS translation plugin before FRINX UniConfig can manage IOS devices. These translation plugins in conjunction with the generic translation layer allow for a CLI mountpoint to be created."]},{"l":"Device specific translation plugin","p":["Device specific translation plugin is a set of:","YANG models","Data handlers","RPC implementations","that actually","defines the model/structure of the data in FRINX UniConfig","implements the translation between YANG data and device CLI in a set of handlers","(optionally) implements the translation between YANG RPCs and device CLI","The plugin itself is responsible for defining the mapping between YANG and CLI. However, the translation layer into which it plugs in is what handles the heavy lifting for it e.g. transactions, rollback, config data storage etc. Additionally, the SPIs of the translation layer are very simple to implement because the translation plugin only needs to focus on the translations between YANG <-\\ CLI."]},{"l":"Units","p":["In order to enable better extensibility of the translation plugin and also to allow the separation of various aspects of a device's configuration, a plugin can be split into multiple units. Where a unit is actually just a subset of a plugin's models, handlers and RPCs.","A single unit will usually cover a particular aspect of device management e.g. the interface management unit.","Units can be completely independent or they can build on each other, but in the end (in the moment where a device is being installed) they form a single translation plugin.","Each unit has to be registered under a specific device type(s) e.g. an interface management unit could be registered for various versions of the IOS device type. When installing an IOS device, the CLI southbound plugin collects all the units registered for the IOS device type and merges them into a single plugin enabling full management.","The following diagram shows an IOS device translation plugin split into multiple units:","IOS translation plugin"]},{"l":"Transport layer","p":["For now, two transport protocols are supported:","SSH","Telnet","They implement the same APIs, which enables the translation layer of the CLI plugin to be completely independent of the underlying protocol in use. Deciding which transport will be used to manage a particular device is simply a matter of install-request configuration.","The transport layer can be specified using install-request'cli-topology:transport-type' parameter."]},{"l":"Data processing","p":["There are 2 types of data depending on data-store in which data is stored:","Config","Operational","This section details how these data types map to CLI commands.","Just as there are 2 types of data, there are 2 streams of data in the CLI southbound plugin:","It represents user/application intended configuration for the device.","Translation plugins/units need to handle this configuration in data handlers as C(reate), U(pdate) and D(elete) operations. R(ead) pulls this config data from the device and updates the cache on its way back.","Config data","It represents actual configuration on the device, optionally statistics from the device.","Translation plugins/units need to pull these data out of the device when R(ead) operation is requested.","Operational data","RPCs stand on their own and can encapsulate any command(s) on the device."]},{"l":"RPCs provided by CLI layer","p":["There are multiple RPCs that can be used to send commands to a CLI session and optionally wait for command output. The CLI layer also provides one additional RPC for computing configuration coverage by cli-units. To use all of these RPCs, it is required to have an installed CLI device in the 'Connected' state."]},{"i":"rpc-execute-and-read","l":"RPC: Execute-and-read"},{"l":"Description","p":["Execution of the sequence of commands specified in the input. These commands must be separated by the new line - then, each of the command is executed separately.","After all commands are executed, it is assumed, that the original command prompt (prompt that was set before execution of this RPC) appears on the remote terminal.","If the input contains only single command, output of this RPC will contain only output of this command. If input contains multiple commands separated by newline, output of this RPC will be built from command prompts (except the prompt of the first command), input commands and outputs returned from remote terminal."]},{"l":"Example","p":["Following RPC demonstrates listing of all interfaces with configured IP addresses plus listing of available routing protocols that can be enabled from global configuration mode. Since the last entered command is placed in configuration mode (for example, starting with'Router(config)#'), it is required to return back to Privileged EXEC mode (for example, starting with 'Router#') using 'end' command and'no' confirmation to not save changes. Also, 'wait-for-output-timer' is configured to 2 seconds - CLI layer waits for command output returned from device up to 2 seconds.","Remember that the last command prompt must equal to original prompt otherwise CLI session fails on timeout and CLI mountpoint must be recreated.","RPC reply with unescaped output string (output can be easily unescaped with 'printf' linux application):","Description of RPC-request input body fields:","command(mandatory) - The list of commands that are sent to device. Commands must be separated by newline character. Every command-line is executed separately.","wait-for-output-timer(optional) - By default (if this parameter is not set or set to 0), outputs from entered commands are collected after caught echo of the next typed command in CLI session (or command prompt, if the command is the last one from input sequence). Then, the collected output contains output of the previous command + echo of the current command that hasn't been executed by sending newline character yet. This process is simplified by setting'wait-for-output-timer' value. In this case,'waiting-for-command-echo' procedure is not applied, rather next command is executed only after specified number of seconds after which the reply from CLI session should already be available (if it won't be available, then command output will be read after execution of the next command - outputs can be messed up).","error-check(optional) - By default, UC does not check for errors in commands. If error-handling is enabled and an error occurs, RPC will fail."]},{"l":"Wait-for-echo behaviour","p":["The comparison between described wait-for-echo approaches can be demonstrated in the steps of processing 2 command-lines:","'wait-for-output-timer' is not set or it set to value 0","write command 1","wait for command 1 echo","hit enter","write command 2","wait for command 2 echo","read until command prompt appears","'wait-for-output-timer' is specified in request","read output until timeout expires","Even if the 'wait-for-output-timer' is configured, the last output must equal to original command-prompt."]},{"i":"rpc-execute-and-expect","l":"RPC: Execute-and-expect"},{"i":"description-1","l":"Description","p":["It is a form of the 'execute-and-read' RPC that additionally may contain 'expect(..)' patterns used for waiting for specific outputs/prompts. It can be used for execution of interactive commands that require multiple subsequent inputs with different preceding prompts.","The body of 'expect(..)' pattern must be specified by Java-based regular expression typed between the brackets (see https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html","documentation about regular expressions used in Java language).","'expect(..)' pattern can only be used for testing of previous command line output including next command prompt. From this reason, it is also a suitable tool for testing of specific command prompts.","'expect(..)' pattern must be specified on the distinct line. If multiple 'expect(..)' patterns are chained on neighboring lines, then all of them must match previous output (patterns are joined using logical AND operation).","Output of this RPC reflects the whole dialogue between Frinx UniConfig client and remote terminal except the initial command-prompt.","'wait-for-output-timer' parameter can also be specified in this RPC","but in this case, it applies only for non-interactive commands - commands that are not followed by 'expect(..)' pattern. It is possible to mix interactive and non-interactive commands in input command snippet.","If 'expect' pattern doesn't match previous output, Execute-and-expect RPC will fail on timeout (fixed 3 seconds) for reading next input and CLI session will drop immediately."]},{"i":"example-1","l":"Example","p":["The following RPC requests shows execution of interactive command for copying of file from TFTP server. The CLI prompt subsequently ask for source filename and destination filename. These prompts are asserted by'expect(..) pattern. The last 'expect(..) pattern just waits for confirmation about number of copied bytes.","RPC reply with unescaped output string (output can be easily unescaped with 'printf' linux application):","Backslash is a special character that must be escaped in JSON body. From this reason, in the previous example, there are two backslashes proceeding regular-expression constructs.","If 'execute-and-expect' command field doesn't contain any 'expect(..)' patterns, it will be evaluated in the same way like 'execute-and-read' RPC."]},{"i":"rpc-execute-and-read-until","l":"RPC: Execute-and-read-until"},{"i":"description-2","l":"Description","p":["It is form of the 'execute-and-read' RPC that allows to explicitly specify 'last-output' that CLI expect at the end of commands executions (after the last command has been sent to device).","If explicitly specified 'last' output is not found at the end of the output, again, the session will be dropped and recreated similarly to behaviour of 'execute-and-read' RPC."]},{"i":"example-2","l":"Example","p":["The following request shows sending of the configuration snippet for disabling of automatic network summary (RIP routing protocol). After executing of these commands, command prompt is switched to'RP/0/0/CPU0:XR5(config-rip)#' - it is not the same like initial command prompt 'RP/0/0/CPU0:XR5#'. From this reason it is required to return back to initial command prompt by sending of additional commands or specification of 'last-output' as it is demonstrated in this example.","RPC reply with unescaped output string (output can be easily unescaped with 'printf' linux application):","Set 'last-output' is saved within current CLI session - if you send next 'execute-and-read' RPC, it is assumed that the initial and last output is newly configured 'last-output'."]},{"i":"rpc-execute","l":"RPC: Execute"},{"i":"description-3","l":"Description","p":["Simple execution of single or multiple commands on remote terminal. Multiple commands must be separated by newline in the input. The outputs from commands are not collected - output of this RPC contains only status message.","This RPC can be used in cases where it is not necessary to obtain outputs of entered commands.","After all commands are executed, the last output is not checked against expected output."]},{"i":"example-3","l":"Example","p":["The following example demonstrates 'execute' RPC on creation of simple static route and committing of made change.","RPC reply - output contains just status message:"]},{"i":"rpc-config-coverage","l":"RPC: config-coverage"},{"i":"description-4","l":"Description","p":["RPC reads the entire device configuration, determines the coverage of the configuration by translation units and returns simple or complex output. The user can define a preferred output in RPC input. The default is simple output.","Simple output contains one string that consists of all lines of the device configuration. Each line starts with '+' if it is covered or'-' if not and ends with a '\\n' marker.","Complex output contains a list of commands. Each entry in the list includes the following fields:","'covered', which indicates whether the entire command is covered or not. Can be either 'true' or 'false'.","'non-parsable-parts', which is visible only if the entire command is not covered. Contains a list of those command parts that are not covered. If no parts of the command are covered, only contains the word 'ALL'.","'command', which includes the entire command."]},{"l":"Simple output example","p":["RPC reply:"]},{"l":"Complex output example","p":["RPC reply:"]}],[{"l":"UniConfig gNMI"},{"l":"Introduction","p":["The gNMI (gRPC Network Management Interface) southbound plugin allows UniConfig to communicate with devices via gNMI. It provides a mechanism to install, manipulate and delete the configuration of a network device, and to view operational data.","The plugin follows a fully model-driven approach similar to the CLI and NETCONF southbound plugins. The main difference is that it uses the protocol buffer (proto3) instead of YANG for service structure modeling within its RPCs, like the gRPC protocol does. Note that the YANG schemas are still necessary for config data modelling on the UniConfig side."]},{"l":"gNMI southbound plugin","p":["The gNMI southbound plugin is capable of connecting to remote gNMI devices and exposing their datastores (CONFIG, STATE) as MD-SAL mount points. These mountpoints allow applications and remote users (over RESTCONF) to interact with the mounted devices.","A new gNMI session is created by mounting a gNMI device. The session is responsible for establishing a connection via gRPC ManagedChannel. Once a connection is established, the gNMI southbound plugin reads device capabilities using the Capabilities RPC. A new schema context is built from the capabilities (once the schema context is built, it is cached for the next runs) and all necessary services are created (DOMDataBroker, DOMRpcService, DOMNotification/Subscription service).","When all this is done, the gNMI southbound plugin marks the connection status of the particular device as READY so that the UniConfig layer can handle it."]},{"l":"Important features","p":["When a gNMI device is installed, it is possible to:","Read (gNMI GET) and create/update/delete (gNMI SET) the configuration of the device via the following:","UniConfig topology","gNMI souhtbound topology (using yang-ext:mount)","yang-patch operations over UniConfig/gNMI souhtbound topology (using yang-ext:mount)","Manipulate a device via gNOI RPCs","Use the gNMI SET update operation for specific paths","Use the gNMI SET replace operation for specific paths","Order config changes (replace/delete operations) according to dependency paths","Remove module-name from list keys for specific paths","Read from ALL datastore for specific paths","Subscribe to telemetry streaming for specific paths (gNMI Subscribe)","Store failed installations","Enable the logging-broker for gNMI messages (SET/GET)","Use the DryRunCommit feature"]},{"l":"gNOI","p":["The gNOI (gRPC Network Operations Interface) defines gRPC-based microservices for executing operational commands on network devices. By default, the gNMI southbound plugin is capable of executing Certification, File, System and OS RPCs according to protobuf files ( https://github.com/openconfig/gnoi).","Apart from common ones, it is also possible to invoke SONiC-type gNOI RPCs by specifying gnmi-topology:device-type : sonic inside the connection-parameters container in the install request. It is necessary to have the gnoi-sonic@2023-03-17.yang schema model in the cache directory for this specific node to invoke it via RESTCONF.","Example- gNOI RPC invocation"]},{"l":"Update paths","p":["The update paths feature tells the gNMI southbound plugin to process the intended config changes (calculated from UniConfig diff) as a gNMI SET message - Update operation.","The plugin essentially checks if config change paths are relative to any of the update paths listed in the installation request. (For example, if you have a config change at a/b/c/d that is relative to the update-path a/b/c).","The main purpose of this feature is to send a gNMI SET message with the correct operation mode that the device supports for the specific subtree. Paths are in regexp format."]},{"l":"Replace paths","p":["The replace paths feature is a little different from update paths. With replace paths, the UniConfig topology first calculates changes using own diff implementation and, if a path is specified in the replace-paths list in the install request, adjusts the calculated diffs and groups them accordingly.","If there is a config change at a/b/c/d and a/b/c/e, and the replace path is specified as a/b/c, the diff calculation adjustment marks the two changes as one on the path a/b/c. In this structure it is passed to the gNMI southbound topology, where it is processed as a gNMI SET message - Replace operation.","If a config is deleted using the DELETE REST operation on a path that is relative to some of the replace paths, it is processed as a gNMI SET message - Delete operation. Essentially, it is skipped by the replace paths feature.","This feature can also be used only in the gNMI southbound plugin, for example, if we send a config change via yang-patch operation over the gNMI topology (so it goes outside of the UniConfig diff). In this scenario, it only checks if the config change path is relative to one of the replace-paths.","The main purpose of the replace paths feature is to send gNMI SET messages with the correct operation mode that the device supports for a specific subtree.","The paths are in common RESTful URL format, but a list entry can be compiled as a regexp pattern if specified with $ sign after the = sign. The list entry key is then specified like this: interface=$.*[Ee]thernet?[0-9]+."]},{"l":"Dependency paths","p":["The dependency paths feature helps network devices to order committed config changes if the device cannot handle this. For example, deleting an interface from the network-instance first and then deleting it from the interfaces container. This is done in the gNMI southbound topology, and it orders changes marked for the Replace/Delete operation. Config changes are sorted from their paths according to rules specified in the dependency paths.","The rule format for dependency paths:","before- path without keys that is ordered before the path specified in after.","after- path without keys that is ordered after the path specified in before."]},{"l":"gNMI logging-broker","p":["For more information about the gNMI logging-broker, see Supported logging settings."]},{"l":"Telemetry streaming","p":["Creating a subscription","If a time range is specified, it is part of the Subscribe request. If the device does not support time ranges on its server side, the gNMI southbound plugin can handle them. Note that if the timestamp of the received message is outside of the specified time range, the message is not saved to the database or published to the Kafka topic.","If the specified path is marked as disabled for the ON_CHANGE mode in YANG schemas, the gNMI southbound plugin fails with a log message stating that the path is marked as disabled for the subscription.","notifications.enabled=true","notifications.kafka.embedded-kafka.enabled=true(or its own Kafka, in which case kafka-servers needs to be adjusted)","notifications.kafka.gnmi-notifications-enabled=true","notifications.kafka.gnmi-notifications-topic-name=gnmi-notifications","Receiving notifications","Saving notifications to a database or publishing them to Kafka topic","Subscriptions are created in the gNMI southbound plugin using the Subscribe RPC from the gNMI service defined in the proto3 file. The gNMI southbound plugin can subscribe to wildcarded paths as well as multiple paths at once. It supports only the STREAM subscription mode with SAMPLE, ON_CHANGE and TARGET_DEFINED stream mode.","Subscriptions are created independently from node installation. The result of the install-node RPC relates only to node installation, and that RPC will only invoke the telemetry stream subscription process.","Telemetry streaming in UniConfig is divided into three parts:","The install request must specify the parameters necessary to create a subscription for a specific device. Mandatory fields are stream-name(a marker for the particular subscription) and paths(a list of paths to which the gNMI souhtbound plugin will be subscribed, with at least one path). Non-mandatory fields specify a time range of the subscription or subscription mode. Both start-time and stop-time are in RFC3339 format. Subscription mode can be SAMPLE, ON_CHANGE or TARGET_DEFINED","The session is open until it is closed either on the UniConfig side (releasing the subscription) or the device side (error). The result of telemetry streaming can be seen in the specified Kafka topic or in the notification database table.","To create subscriptions, the following are required in application.properties:","UniConfig with gNMI southbound plugin supports gNMI telemetry streaming - receiving the state of data on a target."]},{"l":"DryRun commit","p":["For more information about dryrun commit, see Dry-run manager.","It also supports the gNMI southbound topology, which is accessible only if the parameter gnmi-topology:dry-run-journal-size is set to be higher than 0."]},{"l":"gNMI testtool","p":["The gNMI testtool is a GO language server-side simulator capable of configuring OpenConfig YANG schemas via gNMI. It currently supports openconfig-interfaces, openconfig-system, openconfig-openflow, controlling operations over gNOI and telemetry streaming.","The tool is used for scale-testing purposes to simulate the interactions of thousands of devices with UniConfig.","Examples:","UniConfig gNMI"]}],[{"l":"IosXR 7 device"},{"l":"Install device","p":["A IosXR7 device can be installed through gNMI with the following request:"]},{"l":"Uninstall device","p":["To uninstall a device:"]}],[{"l":"NOKIA device"},{"l":"Install device","p":["A Nokia device can be installed through gNMI with the following request:"]},{"l":"Uninstall device","p":["To uninstall a device:"]}],[{"l":"SONiC device"},{"l":"Install device","p":["SONiC devices can be installed through gNMI with the following request:"]},{"l":"Uninstall device","p":["To uninstall a device:"]}],[{"l":"UniConfig NETCONF"},{"l":"Overview","p":["NETCONF is an Internet Engineering Task Force (IETF) protocol used for configuration and monitoring of devices in a network. It can be used to“create, recover, update, and delete configurations of network devices”. The base NETCONF protocol is described in RFC-6241.","NETCONF operations are overlaid on the Remote Procedure Call (RPC) layer and may be described in either XML or JSON."]},{"l":"NETCONF southbound plugin"},{"l":"Introduction to southbound plugin and netconf-connectors","p":["The NETCONF southbound plugin is capable of connecting to remote NETCONF devices and exposing their configuration/operational datastores, RPCs and notifications as MD-SAL mount points. These mount points allow applications and remote users (over RESTCONF) to interact with the mounted devices.","In terms of RFCs, the southbound plugin supports:","Network Configuration Protocol (NETCONF) - RFC-6241","NETCONF Event Notifications - RFC-5277","YANG Module for NETCONF Monitoring - RFC-6022","YANG Module Library - draft-ietf-netconf-yang-library-06","NETCONF is fully model-driven (utilizing the YANG modelling language) so in addition to the above RFCs, it supports any data/RPC/notifications described by a YANG model that is implemented by the device.","By mounting of NETCONF device a new netconf-connector is created. This connector is responsible for:","keeping state of NETCONF session between NETCONF client that resides on FRINX UniConfig distribution and NETCONF server (remote network device)","sending / receiving of NETCONF RPCs that are used for reading / configuration of network device","interpreting of NETCONF RPCs by mapping of their content using loaded device-specific YANG schemas","There are 2 ways for configuring a new netconf-connector: NETCONF or RESTCONF. This guide focuses on using RESTCONF."]},{"l":"Spawning of netconf-connectors while the controller is running","p":["To configure a new netconf-connector (NETCONF mount-point) you need to create a node in configuration data-store under 'topology-netconf'. Adding of new node under NETCONF topology automatically triggers data-change-event that at the end triggers mounting process of the NETCONF device. The following example shows how to mount device with node name 'example' (make sure that the same node name is specified in URI and request body under 'node-id' leaf).","This spawns a new netconf-connector with name 'example' which tries to connect to the NETCONF device at '192.168.1.100' and port '22'. Both username and password are set to 'test' and SSH is used as channel for transporting of NETCONF RPCs (if 'tcp-only' leaf is set to 'true', NETCONF application protocol is running directly on top of the TCP protocol).","Right after the new netconf-connector is created, NETCONF layer writes some useful metadata into the operational data-store of MD-SAL under the network-topology subtree. This metadata can be found at:","Information about connection status, device capabilities, etc. can be found there.","You can check the configuration of device by accessing of'yang-ext:mount' container that is created under every mounted NETCONF node. The new netconf-connector will now be present there. Just invoke:","The response will contain the whole configuration of NETCONF device. You can fetch smaller slice of configuration using more specific URLs under'yang-ext:mount' too."]},{"i":"authentification-with-privatepublic-key","l":"Authentification with private/public key","p":["This type of authentification is used when you want to connect to the NETCONF device via private/public key, it is necessary to save public key into device, then put private key into UniConfig and when trying to configure NETCONF mount-point to connect via ssh key and not password.","To accomplish that, follow these steps :","1. Generate private/public key-pair on your local machine","2. Change .pub format into .bin format","3. Copy public key into device directory. Password of the device will be required.","4.(Optional) Check if the public key is on device","5. Import public key to device","6. Log in with private key to device NETCONF subsystem. Passphrase for key will be required.","7. Start UniConfig and insert keystore with private key into it.","RPC request:","8. Create mount-point with key-id","Delete public key","Login to device, remove rsa public key and after that, it is also possible to delete key from device directory."]},{"l":"PKI Data persistence in NETCONF","p":["PKI data is used for authentication of NETCONF sessions with the provided RSA private key. The corresponding public key must be stored on the device side.","Keys are identified using a unique 'key-id'. This key identifier can be specified in the NETCONF installation request.","Keys can be managed using the 'remove-keystore-entry' and 'add-keystore-entry' operations. These RPC calls are part of the UniConfig transaction. Changes are not applied until they are committed by the user or the immediate commit model is used to invoke the operation.","Keys are stored in the UniConfig database. In a clustered environment, all nodes share the same set of keys."]},{"l":"Registration of the new key","p":["The following request demonstrates how to register a new RSA private key with a key-id of 'key1'. The private key must be specified in the PKCS#8 format. The passphrase is optional and must be specified only if the private key is encrypted.","Multiple keys can be registered at once if the user provides a list of the 'key-credential' in the input."]},{"l":"Removing of the existing key","p":["The following example shows how to remove the existing key 'key1' from UniConfig. It is possible to remove multiple keys at once."]},{"l":"Reading list of the existing keys","p":["The following example shows how to read list of the existing keys from UniConfig.","Note: Both 'passphrase' and 'private-key' are additionally encrypted by the UniConfig encryption system to protect confidential data."]},{"l":"Keepalive settings","p":["If the NETCONF session haven't been created yet, the session is tried to be established only within maximum connection timeout. If this timeout expires before NETCONF session is established, underlay NETCONF channel is closed (reconnection strategy will not be started). After the NETCONF session has been successfully created, there are two techniques how the connection state is kept alive:","TCP acknowledgements- NETCONF is running on top of the TCP protocol that can handle dropped packets by decreasing of window size and resending of lost TCP segments. Working TCP connection doesn't imply working state of the application layer (NETCONF session) - keepalive messages are required too.","Explicit NETCONF keepalive messages- Keepalive messages test whether NETCONF server is alive - server responds to keepalive messages within NETCONF RPC timeout.","If TCP connection is dropped or NETCONF server doesn't respond within keepalive timeout, NETCONF launches reconnection strategy. To summarize it all, there are 3 configurable parameters that can be set in mount-request:","Initial connection timeout [seconds]- Specifies timeout in milliseconds after which initial connection to the NETCONF server must be established. By default, the value is set 20 s.","Keepalive delay [seconds]- Delay between sending of keepalive RPC messages to the NETCONF server. Keepalive messages test state of the NETCONF session (application layer) - whether remote side is able to respond to RPC messages. Default keepalive delay is 120 seconds.","Request transaction timeout [seconds]- Timeout for blocking RPC operations within transactions. Southbound plugin stops to wait for RPC reply after this timeout expires. By default, it is set to 60 s.","Example with set keepalive parameters at creation of NETCONF mount-point(connection timeout, keepalive delay and request timeout):"]},{"l":"Reconnection strategy","p":["Reconnection strategies are used for recovering of the lost connection to the NETCONF server. The behaviour of the reconnection can be described by 3 configurable mount-request parameters:","Maximum number of connection attempts [count]- Maximum number of initial connection retries. This is used when no connection is yet established for given node inside uniconfig transaction; when it is reached, the NETCONF won't try to connect to device anymore. By default, this value is set to 1, non-positive value or null is interpreted as infinity.","Maximum number of reconnection attempts [count]- Maximum number of reconnection retries. This is used when connection was already successfully established and ongoing (not yet closed), but it dropped (from device side); when it is reached, the NETCONF won't try to reconnect to device anymore. By default, this value is set to 0, non-positive value or null is interpreted as infinity.","Initial timeout between attempts [seconds]- The first timeout between reconnection attempts in milliseconds. The default timeout value is set to 2000 ms.","Reconnection attempts multiplier [factor]- After each reconnection attempt, the delay between reconnection attempts is multiplied by this factor. By default, it is set to 1.5. This means that the next delay between attempts will be 3 s, then it will be 4,5 s, etc.","Example with set reconnection parameters at creation of NETCONF mount-point - maximum connection attempts, initial delay between attempts and sleep factor:"]},{"l":"Local NETCONF cache repositories","p":["The netconf-connector in OpenDaylight relies on'ietf-netconf-monitoring' support when connecting to remote NETCONF device. The 'ietf-netconf-monitoring' feature allows netconf-connector to list and download all YANG schemas that are used by the device. These YANG schemas are afterwards used by NETCONF southbound plugin for interpretation of RPCs. The following rules apply for maintaining of local NETCONF cache repositories:","By default, for each device type, the separate local repository is prepared.","All NETCONF repositories are backed up by separate sub-directory under 'cache' directory of UniConfig Distribution.","NETCONF device types are distinguished by unique set of YANG source identifiers - module names and revision numbers. For example, if 2 NETCONF devices differ only in revision of one YANG schema, these NETCONF devices are recognized to have different device types.","Format of the name of generated NETCONF cache directory at runtime is 'schema_id', where 'id' represents unique integer computed from hash of all source identifiers. This generation of cache directory name is launched only at mounting of new NETCONF device and only if another directory with the same set of source identifiers haven't been registered yet.","You can still manually provide NETCONF cache directories with another format before starting of UniConfig Distribution or at runtime - such directories don't have to follow 'schema_id' format.","The NETCONF repository can be registered in 3 ways:","Implicitly by mounting of NETCONF device that has NETCONF monitoring capability and another devices with the same type hasn't already been mounted.","At booting of FRINX UniConfig distribution, all existing sub-directories of 'cache' root directory are registered as separate NETCONF repositories.","At runtime, by invocation of 'schema-resources:register-repository' RPC.","Already registered schema repositories can be listed using following request:","It should return list of ODL nodes in cluster with list of all loaded repositories. Each repository have associated list of source identifiers. See the following example of GET request output:"]},{"l":"Local Netconf default cache repository","p":["Before booting of FRINX UniConfig, the user can put the 'default' repository in the ‘cache’ directory. This directory should contain the most frequently missing sources. As mentioned above, if the device supports ‘ietf-netconf-monitoring’ and there is no directory in the'cache' with all sources that the device requires, then NETCONF will generate directory with name ‘schema_id’, where ‘id’ represents unique integer. The generated repository may not contain all required schemas because device may not provide them. In such case, the missing sources will be searched in the 'default' repository and if sources will be located there, generated repository will be supplemented by the missing sources. In general, there are 2 situations that can occur:","Missing imports","The device requires and provides a resource which for its work requires additional resources that are not covered by provided resources.","Source that is not covered by provided sources","The device requires but does not provide a specific source.","note Using the 'default' directory in the 'cache' directory is optional."]},{"l":"Connecting to a device not supporting NETCONF monitoring","p":["NETCONF connector can only communicate with a device if it knows the set of used schemas (or at least a subset). However, some devices use YANG models internally but do not support NETCONF monitoring. Netconf-connector can also communicate with these devices, but you must load required YANG models manually. In general, there are 2 situations you might encounter:","NETCONF device does not support 'ietf-netconf-monitoring' but it does list all its YANG models as capabilities in HELLO message","This could be a device that internally uses, for example,'ietf-inet-types' YANG model with revision '2010-09-24'. In the HELLO message, that is sent from this device, there is this capability reported as the following string (other YANG schemas can be reported as capabilities in the similar format):","The format of the capability string is following:","[NAMESPACE] - Namespace that is specified in the YANG schema.","[MODULE_NAME] - Name of the YANG module.","[REVISION] - The newest revision that is specified in the YANG schema (it should be specified as the first one in the file). note Revision number is not mandatory (YANG model doesn't have to contain revision number) - then, the capability is specified without the'&' and revision too. For such devices you have to side load all device YANG models into separate sub-directory under 'cache' directory (you can choose random name for this directory, but directory must contain only YANG files of one device type).","NETCONF device does not support 'ietf-netconf-monitoring' and it does NOT list its YANG models as capabilities in HELLO message","Compared to device that lists its YANG models in HELLO message, in this case there would be no specified capabilities in the HELLO message. This type of device basically provides no information about the YANG schemas it uses so its up to the user of OpenDaylight to properly configure netconf-connector for this device. Netconf-connector has an optional configuration attribute called'yang-module-capabilities' and this attribute can contain a list of'yang-module-based' capabilities. By setting this configuration attribute, it is possible to override the 'yang-module-based' capabilities reported in HELLO message of the device. To do this, we need to mount NETCONF device or modify the configuration of existing netconf-connector by adding the configuration snippet with explicitly specified capabilities (it needs to be added next to the address, port, username etc. configuration elements). The following example shows explicit specification of 6 capabilities:","Remember to also put the YANG schemas into the cache folder like in the case 1."]},{"l":"Registration or refreshing of NETCONF cache repository using RPC","p":["This RPC can be used for registration of new NETCONF cache repository or updating of NETCONF cache repository. This is useful when user wants to add new NETCONF cache repository at runtime of FRINX UniConfig distribution for device that doesn't support 'ietf-netconf-monitoring' feature. It can also be used for refreshing of repository contents (YANG schemas) at runtime.","The following example shows how to register a NETCONF repository with name 'example-repository'. The name of the provided repository must equal to name of the directory which contains YANG schemas.","If the repository registration or refreshing process ends successfully, the output contains just set 'status' leaf with 'success' value:","On the other side, if the directory with input 'repository-name' does not exist, directory doesn't contain any YANG files, or schema context cannot be built using provided YANG sources the response body will contain 'failed' 'status' and set 'error-message'. For example, non-existing directory name produces following response:","Constraints:","Only the single repository can be registered using one RPC request.","Removal of registered repositories is not supported for now."]},{"l":"Reconfiguring netconf-connector while the controller is running","p":["It is possible to change the configuration of an already mounted NETCONF device while the whole controller is running. This example will continue where the last left off and will change the configuration for the existing netconf-connector after it was spawned. Using one RESTCONF request, we will change both username and password for the netconf-connector.","To update an existing netconf-connector you need to send following request to RESTCONF:","Since a PUT is a replace operation, the whole configuration must be specified along with the new values for username and password. This should result in a '2xx' response and the instance of netconf-connector called 'example' will be reconfigured to use username 'bob' and password'passwd'. New configuration can be verified by executing:","With new configuration, the old connection will be closed and a new one established."]},{"l":"Destroying of netconf-connector","p":["Using RESTCONF one can also destroy an instance of a netconf-connector - NETCONF connection will be dropped and all resources associated with NETCONF mount-point on NETCONF layer will be cleaned (both CONFIGURATION and OPERATIONAL data-store information). To do this, simply issue a request to following URL:","The last element of the URL is the name of the mount-point."]},{"l":"NETCONF TESTTOOL"},{"l":"Testtool overview","p":["NETCONF testtool is the Java application that:","Can be used for simulation of 1 or more NETCONF devices (it is suitable for scale testing).","Uses core implementation of NETCONF NORTHBOUND server.","Provides broad configuration options of simulated devices.","Supports YANG notifications.","NETCONF testtool is available at netconf repository of ODL( into config/ folder of FRINX UniConfig distribution, this file contains xml paths that should be ignored while removing duplicate nodes from the netconf message","Optional:","put file namespaceBlacklist.txt into config/ folder of FRINX UniConfig distribution, this file contains xml namespaces of the nodes that should be removed from the netconf message","Now UniConfig can be started."]},{"l":"Install SROS device","p":["To install the SROS device run:","Where:","sros: is the name of the device","10.19.0.18: is the IP address of the device","830: is the port number of the device","USERNAME: is the username to access the device","PASSWORD: is the respective password","\"uniconfig-config:uniconfig-native-enabled\": allows to enable installing through UniConfig Native","\"uniconfig-config:install-uniconfig-node-enabled\": allows to disable installing to uniconfig and unified layers","\"uniconfig-config:path\": allows to specify a list of root elements from models present on device to be ignored by UniConfig Native","In case of success the return code is 201."]},{"l":"Check if SROS device is connected","p":["To check if the device is properly connected run:","In case of success the return code is 200, and the response body contains something similar to:"]},{"l":"Check if SROS device configuration is available in UniConfig","p":["To check if the SROS device configuration has been properly loaded in the UniConfig config datastore, run:","In case of success the return code is 200 and the response body contains something similar to:"]}],[{"l":"UniConfig SNMP"},{"l":"Introduction","p":["The SNMP (Simple Network Management Protocol) southbound plugin allows UniConfig to communicate with an SNMP agent, which is a software module installed on network devices. It collects information about the status, performance, and configuration of these devices.","The SNMP southbound plugin follows a fully model-driven approach, similar to CLI or NETCONF southbound plugins. However, the difference lies in the fact that, instead of YANG, it uses MIB (Management Information Base) for data modeling."]},{"l":"Architecture","p":["This section provides an architectural overview of the plugin."]},{"l":"SNMP topology","p":["The SNMP topology is a dedicated topology instance where users and applications can:","Install an SNMP agent","Uninstall an agent","Read device configuration settings or performance metrics"]},{"l":"SNMP mountpoint","p":["The plugin relies on MD-SAL and its concept of mountpoints to expose information about a device. By exposing a mountpoint in MD-SAL, it allows the SNMP topology to access device information in a structured form."]},{"l":"Local SNMP MIB repositories","p":["It is necessary to provide the /mibs directory that contains the following:","repository- a directory that contains mib files. You can use any name.","mib.metadata file - With this file we inform UniConfig that we have added, removed, or modified an MIB file in the repository. Simply insert the repository name and any arbitrary string, and UniConfig will update the relevant context for the particular repository.","Example - mib.metadata file"]},{"l":"Example request","p":["UniConfig currently supports the read operation, with plans to add support for the write operation in the future."]},{"l":"GET request"}],[{"l":"Updating installation parameters","p":["During device installation, UniConfig creates a mountpoint for the device and stores it in the database. The mountpoint contains all parameters set in the installation request.","UniConfig includes a feature to update mountpoint parameters, which can be used for NETCONF, CLI and gNMI nodes."]},{"l":"Show installation parameters","p":["Parameters for installed devices can be shown using a GET request on the node, which returns the current node settings. Make sure to specify the right topology. See below for examples.","By default, the NETCONF, CLI and gNMI topologies have the password parameter encrypted. This can be changed in the corresponding YANG schema by adding or removing the frinx-encrypt:encrypt extension flag.","CLI node","Output:","NETCONF node","gNMI node"]},{"l":"Update installation parameters","p":["To update node installation parameters, use a PUT request with an updated request body copied from the GET request in the previous section. Single parameters can also be updated with a direct PUT call to the specific parameter.","If the password parameter is set to be encrypted, changing it will encrypt the input value.","CLI node","Update multiple parameters:","host","dry-run-journal-size","journal-size","Update a single parameter:","NETCONF node","keepalive-delay","After these changes have been made, use the GET requests in the Show installation parameters section above to see that the parameters have actually been changed. You can also use the GET request for a single parameter."]}],[{"l":"UniConfig-native CLI"},{"l":"Introduction","p":["UniConfig-native CLI allows user configuration of CLI-enabled devices using YANG models that describe configuration commands. In UniConfig-native CLI deployment translation units are defined only by YANG models and device-specific characteristics that are used for parsing and serialization of commands. Afterwards, readers and writers are automatically created and provided to translation registry - user doesn't write them individually. YANG models can be constructed by following of well-defined rules that are explained in Developer Guide.","Summarized characteristics of UniConfig-native CLI:","modelling of device configuration using YANG models,","automatic provisioning of readers and writers by generic translation unit,","simple translation units per device type that must define device-characteristics and set of YANG models."]},{"l":"Installation","p":["CLI device can be installed as native-CLI device by adding'uniconfig-config:uniconfig-native-enabled' flag with 'true' value into the mount request (by default, this flag is set to 'false'). It is also required to use tree parsing engine that is enabled by default. All other mount request parameters that can be applied for classic CLI mountpoints can also be used in native-CLI configuration with the same meaning.","The following example shows how to mount Cisco IOS XR 5.3.4 device as native-CLI device with enabled dry-run functionality:","After mounting of CLI node finishes, you can verify CLI mountpoint by fetching its Operational datastore:","You can see that there are some native models included in the'available-capabilities' plus basic mandatory capabilities for CLI mountpoints. Number of supported native capabilities depends on number of written models that are included in native-CLI translation unit for IOS XR 5.3.4, in this case. The only common capability for all native-CLI mountpoints is' http://frinx.io/yang/native/extensions?module=cli-native-extensions'. Sample list of native capabilities:","The synced configuration on UniConfig layer can be verified in the same way as for all types of devices:","Since sample device configuration contains both ACL and interface configuration and native-CLI IOS XR 5.* covers this configuration, the synced data looks like the next output:","The previous sample output corresponds to the following parts of the configuration on the device:"]},{"l":"Architecture","p":["The following section describes building blocks and automated processes that take place in UniConfig-native CLI."]},{"l":"Modules","p":["The following UML diagram shows dependencies between modules from which UniConfig native-cli is built. The core of the system is represented by'native-cli-unit' module in CLI layer that depends on CLI API for registration of units and readers and writers API. On the other side there are CLI-units that extend 'GenericCliNativeUnit'.","Dependencies","Description of modules:","utils-unit and translation-registry-api/spi: CLI layer API which native-cli units depend on. It defines interface for CLI readers/writers, translation unit collector that can be used for registration of native-CLI unit, and common 'TranslateUnit' interface.","native-cli-unit: It is responsible for automatic provisioning and registration of readers and writers (handlers) based on YANG modules that are defined in specific translation units. Readers and writers are initialized only for root container and list schema nodes defined in YANG models. All specific native-CLI units must be derived from abstract class 'GenericCliNativeUnit'.","ios-xr-5-native and junos-17-native: Specific native-CLI units derived from 'GenericCliNativeUnit'. To make native-CLI unit working, it must implement methods that provides list of YANG modules, list of root data object interface, supported device versions, unit name, and CLI flavour."]},{"l":"Registration of handlers","p":["Registration of native-CLI handlers is described by following sequence diagram in detail.","Handlers","Description of the process:","Searching for root schema node: Extraction of the root list and container schema nodes from nodes that are augmented to UniConfig topology.","Building of device template information: Extraction of device template information from imported template YANG modules. This template contains command used for displaying of whole device configuration, format of configuration command, and format of delete command.","Initialization of handlers: Creation of native-CLI config readers and writers or native-CLI list readers and writers in case of list schema nodes.","Registration of handlers: Registration of readers and writers in reader and writer registries. Readers are registered as generic config readers, whereas writers are registered as wildcarded subtree writers.","Since native-CLI readers are not registered as subtree readers, it is possible to directly read only root elements from CLI mountpoint. This constraint is caused by unsupported wildcarded subtree readers in Honeycomb framework."]},{"l":"Functionality of readers","p":["Config readers and config list readers in UniConfig-native CLI are implemented as generic readers that parse device configuration into structuralized format based on registered native-CLI YANG models. These readers are initialized and registered per root data schema node that is supported in native-CLI. The next sequence diagram shows process taken by generic reader on calling 'readCurrentAttributes(..)' method.","Readers","Description of the process:","Creation of the configuration tree: It represents current device configuration by sending of 'show' command which is responsible for displaying of whole device configuration.","Transformation of configuration tree: It is transformed into binding-independent NormalizedNode using 'ConfigTreeStreamReader' component.","Conversion into binding-aware format: Conversion of binding-independent NormalizedNode into binding-aware DataObject and population of DataObject builder by fields from built DataObject.","Configuration is parsed into structuralized form before it is actually transformed into NormalizedNodes (step 1) because of more modular and easier approach. Configuration tree consists of 3 types of nodes:","Command nodes: They are represented by the last identifiers of the commands (command word). These nodes don't have any children nodes.","Section nodes: These nodes are represented by the command word / identifier that opens a new configuration section. Section nodes can have multiple children nodes.","Connector nodes: Connector nodes are similar to section nodes with identifier and multiple possible children nodes. However, they don't open a new configuration section; they represent just one intermediary word in command line.","Example - parsing of interface commands into the tree structure:","Parsing","Detailed description of algorithm for transformation of configuration tree into DOM objects:","Transformation","If some commands are not covered by native-CLI YANG models, the parsing of configuration in readers will not fail - unsupported nodes will be skipped."]},{"l":"Functionality of writers","p":["Config writers and config list writers are responsible for serialization of structuralized data from datastore into series of configuration or delete command lines that are compatible with target device. Native CLI writers are also registered only for root schema nodes on the same paths as readers. The next sequence diagram shows process taken by generic writer on calling 'writeCurrentAttributes(..)' or'deleteCurrentAttributes(..)' method.","Writers","Description of the process:","Conversion into binding-independent format: Conversion of binding-aware DataObject into binding-independent NormalizedNode format. Binding-independent format is more suited for automated traversal and building when the target class types of nodes are not known before compilation of YANG schemas is done.","Generation of command lines: NormalizedNode is serialized using stream writer into configuration buckets that are afterwards serialized into separated command lines. Conversion of configuration buckets into command lines can be customized by different strategies. Currently only the primitive strategy is used - it creates for each leaf command argument the full command line from top root - nesting into configuration modes is not supported. This step is described in detail by next activity diagram.","Generation of configuration or delete command lines: It is done by application of configuration or delete template on command line - for example, JUNOS devices use prefix 'set' for applying of the configuration and prefix 'delete' for removal of configuration from device.","Squashing of command lines into single snippet: This is only optimization step - all command lines are joined together with newline separator.","Sending of command to the device(blocking operation).","Configuration buckets are created as intermediary step because of the modularity and flexibility for application of different serialization strategies in future. There are 3 types of created buckets that are wired with respective schema nodes:","Leaf bucket: Bucket that doesn't have any children but it has a value in addition to the identifier. It is created from LeafNode.","Composite bucket: Bucket with identifier and possibly multiple children buckets. It can be used for following types of DOM nodes: ContainerNode or MapEntryNode.","Delegating bucket: Bucket that doesn't have any identifier, it just delegates configuration to its children buckets. It can be used for nodes that are described by ChoiceNode or MapNode.","Command serialization","The current implementation processes updates in default way - the whole actual configuration is removed and then the whole updated configuration is written back to device. This strategy can cause slow down of the commit operation in case of longer configuration and because of this reason it is addressed as one of the future improvements."]}],[{"l":"UniConfig Operations"},{"i":"sending-and-receiving-data-restconf","l":"Sending and receiving data (RESTCONF)","p":["RESTCONF represents REST API to access datastores and UniConfig operations."]},{"l":"UniConfig Node Manager API","p":["The responsibility of this component is to maintain configuration on devices based on intended configuration. Each device and its configuration is represented as a node in the uniconfig topology and the configuration of this node is described by using OpenConfig YANG models. The Northbound API of Uniconfig Manager (UNM) is RPC driven and provides functionality for commit with automatic rollback and synchronization of configuration from the network."]},{"l":"Device discovery","p":["This component is used to check reachable devices in a network. The manager checks the reachability via the ICMP protocol. Afterwards, the manager is able to check whether various TCP/UDP ports are open or not."]},{"l":"Dry-run Manager API","p":["The manager provides functionality showing CLI commands which would be sent to network element."]},{"l":"Snapshot Manager API","p":["The snapshot manager creates and deletes uniconfig snapshots of actual uniconfig topology. Multiple snapshots can be created in the system."]},{"l":"Subtree Manager API","p":["The subtree manager copies (merge/replace) subtrees between source and target paths."]},{"l":"Templates Manager API","p":["This component is responsible for application of templates into UniConfig nodes."]},{"l":"Transaction Log API","p":["This component is responsible for tracking transactions."]},{"l":"UniConfig Queries","p":["Using this component it is possible to invoke JSONB-path queries on top of the stored configuration."]},{"i":"dedicated-transaction-immediate-commit-model","l":"Dedicated transaction (Immediate Commit Model)","p":["The immediate commit creates new transactions for every call of an RPC. The transaction is then closed so no lingering data will occur."]},{"l":"Utilities","p":["This sub-directory contains UniConfig utilities."]}],[{"l":"JSONB Filtering","p":["Jsonb-filter is a query parameter that is used for filtering data based on one or more parameters. This filter is an effective mechanism for filtering a list of items. Using the jsonb-filter we can retrieve only those list items that meet the defined conditions.","Currently, we have two options of how to use the JSONB filtering functionality."]},{"l":"Database JSONB Filtering","p":["The query parameter is located in the URI. This option is faster because filtering is happening on the database side but this filtering has fewer features."]},{"l":"Application JSONB Filtering","p":["A new Content-Type is added. The query parameter is added in the body. Additional query parameters can be chained (sort by, limit, fields). This request is sent as a POST request. This filtering adds more features, but it is happening on the UniConfig application side which will be slower than the database filtering."]}],[{"l":"Application JSONB Filtering","p":["Application JSONB filtering supports either the dot notation:","or the bracket–notation:"]},{"l":"Jsonb-filter expression","p":["Every filter operation is sent using a POST request. Additionally, a new Content-Type header has been made for application JSONB Filtering. An example can be seen below:","The filter is located in the body of the request, not in the URI. Since it is located in the body, there is no need to escape characters. The body structure looks like this:","If the user wants to filter the list elements based on name, the query filter would look like this:","By default, the filter returns the same output structure as when calling a GET request. There is an option to add the whole parent structure, where the body will look like this:","This will filter out all the elements in the list whose name is foo."]},{"l":"Operators","p":["..",".","[?()]","['' (, '')]","[ (, )]","[start:end]","@","*","$","Array index or indexes.","Array slice operator.","Bracket-notated child or children.","Deep scan. Available anywhere a name is required.","Description","Dot-notated child.","Filter expression. Expression must evaluate to a boolean value.","Operator","Operators mentioned in the table below are used to construct a path.","The current node being processed by a filter predicate.","The root element to query. This starts all path expressions.","Wildcard. Available anywhere a name or numeric are required."]},{"l":"Functions","p":["add an item to the json path output array","append(X)","avg()","concat(X)","Description","Double","Functions can be called at the end of the query path. The input to the function is the output of the path expression. The function output is dictated by the function itself.","Integer","keys()","length()","like input","max()","min()","Operator","Output Type","Provides a concatinated version of the path output with a new item","Provides the average value of an array of numbers","Provides the length of an array","Provides the max value of an array of numbers","Provides the min value of an array of numbers","Provides the property keys (An alternative for terminal tilde ~)","Provides the standard deviation value of an array of numbers","Provides the sum value of an array of numbers","Set","stddev()","sum()"]},{"l":"Filter Operators","p":["!=","<","<=","==","=~",">",">=","A double quote: [?(@.name == \"foo\")]","A single quote: [?(@.name == 'foo')]","anyof","Description","empty","Filters are logical expressions used to filter arrays. A typical filter would be [?(@.age > 18)] where @ represents the current element being processed. More complex filters can be created with logical operators && and ||. String literals must be enclosed by:","in","left (array or string) should be empty","left does not exists in right","left exists in right [?(@.size in ['S', 'M'])]","left has an intersection with right [?(@.sizes anyof ['M', 'L'])]","left has no intersection with right [?(@.sizes noneof ['M', 'L'])]","left is a subset of right [?(@.sizes subsetof ['S', 'M', 'L'])]","left is equal to right (note that 1 is not equal to '1')","left is greater than or equal to right","left is greater than right","left is less or equal to right","left is less than right","left is not equal to right","left matches regular expression [?(@.name =~ /foo.*?/i)]","nin","noneof","Operator","size","size of left (array or string) should match right","subsetof"]},{"l":"Jsonb-filter examples","p":["$..interface[?(@.speed <= $['fast'])]","$..interface[?(@.type =~/.* Csmacd/i)]","$..name","$.ietf-interfaces:interfaces..type","$.ietf-interfaces:interfaces.*","$.ietf-interfaces:interfaces.interface.length()","$.ietf-interfaces:interfaces.interface[-2:]","$.ietf-interfaces:interfaces.interface[-2]","$.ietf-interfaces:interfaces.interface[:2]","$.ietf-interfaces:interfaces.interface[?(@.enabled)]","$.ietf-interfaces:interfaces.interface[?(@.speed >= 10)]","$.ietf-interfaces:interfaces.interface[*].name","$.ietf-interfaces:interfaces.interface[0,1]","$.ietf-interfaces:interfaces.interface[1:2]","$.ietf-interfaces:interfaces.interface[2:]","$.ietf-interfaces:interfaces.interface[2]","All interfaces from index 0 (inclusive) until index 2 (exclusive)","All interfaces from index 1 (inclusive) until index 2 (exclusive)","All interfaces matching regex (ignore case)","All interfaces that are not 'fast'","All interfaces that have the enabled element","All interfaces whose speed is greater or equal than 10","All names","All things under interfaces","Description","Interface number two from tail","JsonPath","Suppose we have the following data, and we want to do some filtering on them.","The first two books","The last two interfaces","The names of all interfaces","The number of interfaces","The second to last book","The third interface","The type of everything"]}],[{"l":"Database JSONB Filtering","p":["The example of using the jsonb-filter query parameter: parent-path?jsonb-filter=expression","PostgreSQL documentation: JSON Functions and Operators"]},{"l":"Jsonb-filter expression","p":["!","!=","{$/Cisco-IOS-XR-ifmgr-cfg:interface-configurations/interface-configuration=%28%23act,GigabitEthernet0/0/0/2%29}","{$/frinx-openconfig-interfaces:interfaces/interface=%28%23MgmtEth0/RP0/CPU0/0%29}","&&","<","<=","<>","==",">",">=","||","Absolute path","Boolean AND","Boolean NOT","Boolean OR","Composite key:","Description","Equality operator","exists","false","Greater-than operator","Greater-than-or-equal-to operator","In this case, a path must be prefixed with $. This path must start with a top-level parent container","In this case, the path must be prefixed with <@>. This path is relative to the parent-path","is unknown","Less-than operator","Less-than-or-equal-to operator","like_regex","Non-equality operator","Non-equality operator (same as !=)","null","Operator","Path","Relative path","Single key:","Sometimes especially absolute paths can contain a key of some item with special characters. In this case it is necessary wrap this key in a special syntax (#example-key-name) and also encode these wrapping symbols - %28%23example-key-name%29. If the key is a composite key, it is necessary to wrap the whole key with these symbols. If the user is not sure if the path contains special characters, it is always recommended to use this special syntax.","starts with","Tests whether the first operand matches the regular expression given by the second operand","The base expression must contain path, operator and value. The jsonb-filter can contain one or more expressions joined with AND(&&) or OR (||) operator. if the && operator is used it must be encoded.","The last element of the jsonb-filter expression is a value based on which the user wants to filter the data.","The path to the data that the users want to filter. The path can be:","true","Value","Value used to perform a comparison with JSON false literal","Value used to perform a comparison with JSON null value","Value used to perform a comparison with JSON true literal","Value/Predicate Description","When the path is constructed then the user can use one of the operators in the table below"]},{"l":"Jsonb-filter examples","p":["1. Examples of using the relative paths in the jsonb-filter","Example of filtering the list of interfaces based on the enabled parameter where the equality operator is used as the operator","Example of filtering the list of interfaces based on the mtu parameter where the less-than is used as the operator","Example of filtering the list of interfaces based on the name parameter where the like_regex is used as the operator","Example of filtering the list of interfaces where a combination of expressions is used","Example of filtering the list of interfaces where the exists operator is used","2. Example of using the absolute path in the jsonb-filter","Example of filtering the list of interfaces based on the name parameter where equality operator is used as the operator. Interface name\"GigabitEthernet0/0/0/2\" is a key value that contains slashes. For this reason, it is necessary to wrap this key into wrapping symbols(#GigabitEthernet0/0/0/) and also encode these symbols%28%23GigabitEthernet0/0/0/2%29."]}],[{"l":"Snapshot Manager","p":["The snapshot manager creates and deletes UniConfig snapshots of actual UniConfig topology. Multiple snapshots can be created in the system.","Snapshots may be used for manual rollback. Manual rollback enables simple reconfiguration of the entire network using one of the previous states saved in snapshots. That means that UniConfig nodes in config datastore are replaced with UniConfig snapshot nodes."]},{"l":"Create snapshot"},{"l":"Delete snapshot"},{"l":"Replace config with snapshot"},{"l":"Obtain snapshot metadata"}],[{"l":"Obtaining snapshots-metadata","p":["Snapshots metadata contains a list of created snapshots with the date of creation and a list of nodes."]}],[{"l":"RPC create-snapshot","p":["This RPC creates a snapshot of nodes in the UniConfig topology. The snapshot can be used later for manual rollback.","RPC input contains the name of the snapshot topology and nodes that the snapshot will contain. RPC output describes the result of the operation and matches all input nodes.","The RPC cannot be called with an empty list of target nodes. If a node fails for any reason, the entire RPC fails."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains the name for the topology snapshot and nodes that the snapshot contains. RPC output contains the result of operation."]},{"l":"Failed example","p":["RPC input includes nodes that will be contained in the snapshot, but a snapshot name is missing. RPC output contains the result of the operation."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains a name for the topology snapshot and a node that will be contained in the snapshot. The node has not been mounted. RPC output contains the result of the operation."]},{"i":"failed-example-2","l":"Failed example","p":["RPC input does not contain target nodes, so the RPC cannot be executed."]}],[{"l":"RPC delete-snapshot","p":["This RPC removes a snapshot from the Configuration datastore of the UniConfig transaction.","RPC input contains the name of the snapshot topology to be removed. RPC output contains the result of the operation."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains the name of the snapshot topology to be removed. RPC output contains the result of the operation."]},{"l":"Failed example","p":["RPC input contains the name of the snapshot topology to be removed. The snapshot name specified does not exist. RPC output contains the result of the operation."]}],[{"l":"RPC replace-config-with-snapshot","p":["This RPC replaces nodes in the UniConfig topology of the Configuration datastore with selected nodes from a specified snapshot.","RPC input contains the name of the snapshot topology and target nodes that should replace UniConfig nodes in the Configuration datastore. RPC output describes the result of the operation and matches all input nodes.","This RPC cannot be called with an empty target-nodes list. If a node fails for any reason, the entire RPC fails."]},{"l":"Examples"},{"l":"Successful example","p":["RPC input contains the name of the snapshot topology that should replace nodes in the UniConfig topology of the Configuration datastore, as well as a list of nodes from that snapshot. RPC output contains the result of the operation."]},{"l":"Failed example","p":["RPC input contains the name of the snapshot topology that should replace nodes in the UniConfig topology of the Configuration datastore, as well as a list of nodes from that snapshot. This particular snapshot ( snapshot2) has not been created yet.","RPC output contains the result of the operation."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains the name of the snapshot topology that should replace nodes in the UniConfig topology of the Configuration datastore, as well as a list of nodes from that snapshot. RPC input is missing the snapshot name. RPC output contains the result of the operation."]},{"i":"failed-example-2","l":"Failed example","p":["RPC input contains the name of the snapshot topology that should replace nodes in the UniConfig topology of the Configuration datastore, as well as a list of nodes from that snapshot. One node is missing in snapshot1 ( IOSXRN). RPC output contains the result of the operation."]},{"i":"failed-example-3","l":"Failed example","p":["RPC input does not contain target nodes, so the RPC can not be executed."]}],[{"l":"Subtree Manager","p":["The subtree manager copies (merge/replace) subtrees between source and target paths in Configuration or Operational datastore of UniConfig. When one of these RPCs is called, Subtree Manager (SM) reads the configuration from the source path and according to type of operation(merge / replace), copies the subtree data to target path. Target path is a parent path UNDER which data is copied. SM also distinguishes type of source / target datastore.","All RPCs support merging/replacing of configuration between two different schemas ('version drop' feature). This feature is handy, when it is necessary to copy some configuration between two mounted nodes that are described by slightly different YANG schemas. The following changes between schemas are tolerated:","Skipping non-existing composite nodes and leaves,","Adjusting namespace and revision in node identifiers, only name of nodes must match with target schema,","Moving nodes between choice and augmentation schema nodes,","Adjusting value format to target type definition of leaf or leaf-list schema node."]},{"l":"RPC copy-one-to-one","p":["Provides a list of supported operations on subscriptions, includes request examples and workflow diagrams."]},{"l":"RPC copy-one-to-many","p":["Provides a list of supported operations on subscriptions, includes request examples and workflow diagrams."]},{"l":"RPC copy-many-to-one","p":["Provides a list of supported operations on subscriptions, includes request examples and workflow diagrams."]},{"l":"RPC calculate-subtree-diff","p":["Provides a list of supported operations on subscriptions, includes request examples and workflow diagrams."]},{"l":"RPC calculate-subtree-git-like-diff","p":["Provides a list of supported operations on subscriptions, includes request examples and workflow diagrams."]},{"l":"RPC bulk-edit","p":["Applies multiple modifications to a list of target nodes. RPC bulk-edit"]}],[{"l":"RPC bulk-edit","p":["The bulk-edit operation modifies multiple configuration subtrees under multiple target nodes in the uniconfig, templates or unistore topology. The same modifications are applied to all target nodes.","The operation is executed atomically so that either all modifications are applied on all target nodes successfully, or the operation fails and the configuration is not touched in the UniConfig transaction. This RPC also benefits from parallel processing of changes per target node."]},{"l":"RPC input","p":["RPC input specifies a list of target nodes and a list of modifications to be applied to target nodes.","RPC input fields:","topology-id(mandatory): Identifier for the topology that contains all target nodes. Currently supported topologies are uniconfig, templates and unistore.","node-id(optional): List of target nodes identifiers residing in the specified topology. If this field is not specified or is left empty, the RPC is executed on all available nodes in the specified topology.","edit(mandatory with at least one entry): List of modifications. Each modification is uniquely identified by the path key. Modifications are applied in the user-defined order.","Parameters for the edit field:","path(mandatory): Path encoded using the RFC-8040 format. Specified as a relative path to the root configuration container. If this leaf contains a single character /, the path points to the whole configuration. If this path contains a list node without key, the operation is applied to all list node elements.","operation(mandatory): Operation to be executed on the specified path. Supported operations are merge, replace, and remove. Merge and replace operations also require the data input.","data(optional): Content of the replaced or merged data without wrapping parent element. The last element of the path is not declared in. See other cases for examples of how to specify the content of this leaf.","Supported operations:","merge: The supplied value is merged with the target data node.","replace: The supplied value is used to replace the target data node.","remove: Delete target node if it exists."]},{"l":"RPC output","p":["RPC output contains the global status of the executed operation and per-node status.","Fields in the node-result entry:","error-type: Error type.","error-tag: Error tag.","error-message: Reason for the failure. Included in output only if RPC execution failed on target node.","error-info: Additional information about the error, such as node identification."]},{"l":"RPC examples"},{"l":"Successful example","p":["The following request demonstrates the application of six (6) modifications to four (4) templates:","Replace the value of the description leaf.","Remove the snmp container.","Replace the whole ssh container.","Merge the configuration of the routing-protocol list entry.","Merge the whole tree list with the specified multiple list entries.","Replace the leaf-list services with the provided array of strings.","All modifications have been successfully written into the UniConfig transaction."]},{"l":"Failed example","p":["RPC input does not contain the mandatory topology-id field."]},{"i":"failed-example-1","l":"Failed example","p":["This example demonstrates the execution of a bulk-edit operation that fails on parsing one of the paths using YANG schemas of the R2 device.","There is one error message in the result for R2. Note that no modifications are written to R1 because another node (R2) failed during execution of the operation."]}],[{"l":"RPC calculate-subtree-diff","p":["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 calculate-subtree-dif"]},{"l":"RPC examples"},{"i":"successful-example-computed-difference","l":"Successful example: Computed difference","p":["RPC input contains a path to two different testtool devices with different YANG schemas.","RPC output contains a list of statements representing the diff."]},{"i":"successful-example-no-difference","l":"Successful example: No difference","p":["The following output demonstrates a situation with no changes between specified subtrees."]},{"i":"failed-example-invalid-value-in-input-field","l":"Failed example: Invalid value in input field","p":["RPC input contains an improperly defined datastore ( AAA).","RPC output describes the allowed values ( CONFIGURATION and OPERATIONAL)."]},{"i":"failed-example-missing-mandatory-field","l":"Failed example: Missing mandatory field","p":["RPC input does not contain the mandatory source path."]},{"i":"failed-example-pointing-to-different-schema-node","l":"Failed example: Pointing to different schema node","p":["RPC input contains source and target paths that do not point to the same schema node."]}],[{"l":"RPC calculate-subtree-git-like-diff","p":["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 formatted in git-like style. The changes are grouped by root entities in the configuration."]},{"l":"RPC Examples"},{"i":"successful-example-computed-difference","l":"Successful example: Computed difference","p":["RPC input includes the path to two interfaces on different nodes. Both data locations are placed in the CONFIGURATION datastore.","RPC output contains a list of all changes. Multiple changes that occur under the same root element are merged together."]},{"i":"successful-example-no-difference","l":"Successful example: No difference","p":["The following output demonstrates a situation with no changes between specified subtrees."]},{"i":"failed-example-missing-mandatory-field","l":"Failed example: Missing mandatory field","p":["RPC input does not contain the mandatory target path."]}],[{"l":"RPC copy-many-to-one","p":["This RPC is used to perform operations with a configuration from multiple source paths to a single target path.","RPC input contains the following:","type of operation: merge or replace","type of source datastore: CONFIGURATION or OPERATIONAL","type of target datastore: CONFIGURATION or OPERATIONAL","list of source paths in RFC-8040 URI format","target path in RFC-8040 URI format (target path denotes parent entities under which the configuration is copied)","Target datastore is an optional input field. By default, it is the same as source datastore. All other input fields are mandatory.","RPC output describes the result of the operation. If one path fails, the entire operation fails and the datastore is not modified (i.e., all modifications are performed in a single atomic transaction)."]},{"l":"RPC examples"},{"l":"Successful example","p":["This example demonstrates the execution of the copy-many-to-one RPC with three (3) source paths.","Data described by these source paths ( snmp, access, and ntp containers under three different nodes) are copied under the root system:system container ( dev04 node)."]},{"l":"Failed example","p":["This example shows a failed copy-many-to-one RPC operation. One of the source paths points to a non-existing schema node ( invalid:invalid)."]}],[{"l":"RPC copy-one-to-many","p":["This RPC is used to perform operations with a configuration from a single source path to multiple target paths.","RPC input contains the following:","type of operation: merge or replace","type of source datastore: CONFIGURATION or OPERATIONAL","type of target datastore: CONFIGURATION or OPERATIONAL","source path in RFC-8040 URI format","list of target paths in RFC-8040 URI format (target paths denote parent entities under the which configuration is copied)","Target datastore is an optional input field. By default, it is the same as source datastore. All other input fields are mandatory.","RPC output describes the result of the operation. If one path fails, the entire RPC fails and the datastore is not modified (i.e., all modifications are performed in a single atomic transaction)."]},{"l":"RPC examples"},{"l":"Successful example","p":["This example demonstrates merging the ethernet interface configuration from a single source to the following interfaces:","eth-0/2(node dev02)","eth-0/3(node dev02)","eth-0/100(node dev03)","eth-0/200(node dev03)"]},{"l":"Failed example","p":["This example shows a failed copy-one-to-many RPC operation.","Both target paths are invalid, since the ext list schema nodes does not contain the interfaces:interfaces child container."]}],[{"l":"RPC copy-one-to-one","p":["This RPC is used to perform operations with a configuration from a single source path to a single target path.","RPC input contains the following:","type of operation: merge or replace","type of source datastore: CONFIGURATION or OPERATIONAL","type of target datastore: CONFIGURATION or OPERATIONAL","source path in RFC-8040 URI format","target path in RFC-8040 URI format (target path denotes parent entities under which the configuration is copied)","Target datastore is an optional input field. By default, it is the same as the source datastore. All other fields are mandatory.","RPC output describes the result of the operation. If the RPC fails, no changes are made to the target datastore."]},{"l":"RPC examples"},{"l":"Successful example","p":["This example demonstrates how to copy the entire org:orgs container from dev01 to the dev02 node under the uniconfig topology using the replace operation."]},{"l":"Failed example","p":["This example shows a failed copy-one-to-one operation.","RPC input contains the source datastore (same as the target datastore), merge operation, source path, and target path. The target path is invalid because it does not contain the org:orgs container in the schema tree."]}],[{"l":"Templates Manager"},{"l":"Overview","p":["Templates can be utilised to reuse some configuration and more easily apply this configuration into target UniConfig nodes.","Basic properties of templates in UniConfig:","All templates are stored under the templates topology and each template is represented by a separate node list entry.","The entire template configuration is placed under the frinx-uniconfig-topology:configuration container in the Configuration datastore. Because of this, the configuration of a template can be accessed and modified in the same way as a UniConfig node.","Templates are validated against a single schema context. The schema context is selected when a template is created using the uniconfig-schema-repository query parameter. The value of the query parameter defines the name of the schema repository that is placed under the UniConfig distribution in the form of the directory.","Currently implemented template features:","Variables- Used for template parametrisation.","Tags- Used to select an operation that is applied to the specific subtree when the template is applied to a UniConfig node.","Schema validation of leaves and leaf-lists is adjusted so that it can accept both string with variables and original YANG type.","RPC apply-template","RPC create-multiple-templates","RPC get-template-info","RPC get-template-nodes","RPC upgrade-template"]},{"l":"Latest-schema","p":["Latest-schema defines the name of the schema repository whose built schema context is used for template validation.","Latest-schema is used only if the uniconfig-schema-repository query parameter is not defined when creating the template. If the query parameter is defined, latest-schema is ignored."]},{"l":"Configuring latest-schema","p":["Latest-schema can be set using a PUT request. It is placed in the Config datastore. The name of the directory must point to an existing schema repository placed under the UniConfig distribution.","GET request can be used to check if latest-schema is placed in the config datastore."]},{"l":"Auto-upgrading latest-schema","p":["Latest-schema can be automatically upgraded by UniConfig after installing a new YANG repository. YANG repository is installed after deploying of new type of NETCONF/GRPC device or after manual invocation of RPC for loading of new YANG repository from directory.","In order to enable auto-upgrading process, latestSchemaReferenceModuleName must be specified in the application.properties file:","After new YANG repository is installed, UniConfig will look for revision of the latestSchemaReferenceModuleName module in the repository. If the revision found is more recent than the last cached revision, UniConfig will automatically write identifier of the fresh repository into 'latest-schema' configuration. Afterward, 'latest-schema' is used by UniConfig the same way as it would be written manually via RESTCONF."]},{"l":"Variables","p":["Using variables it is possible to parametrise values in the template. Structural parametrisation is not currently supported.","Properties:","Format of the variable: '{$variable-id}'.","Variables can be set to each leaf and leaf-list in the template.","Single leaf or leaf-list may contain multiple variables.","Key of the list can also contain variable.","Variables are substituted by provided values at the application of template to UniConfig node.","It is possible to escape characters of the variable pattern ('$','{', '}'), so they will be interpreted as value and not part of the variable.","Variable identifier may contain any UTF-8 characters. Characters'$', '{', '}' must be escaped, if they are part of the variable identifier."]},{"l":"Examples with variables","p":["A. Leaf with one variable","Application of following values to variables 'var-a' and 'var-b':'var-a' = ['10', '20', '30'], 'var-b' = ['50', '70', '60'].","Application of values - 'var-x': 'next', 'var-y': '7', 'var-1': '10','var-2': '9'. Leaf 'leaf-a' has 'string' type and 'leaf-b' has 'int32' type.","Application of values '10' and 'false' to 'var-1', and 'var-2'. Leaf'leaf-a' has 'int32' type and 'leaf-b' has 'boolean' type.","B. Leaf with multiple variables","Both variables must be substituted by the same number of values.","C. Leaf-list with one variable","D. Leaf-list with multiple variables","E. Leaf-list with entry that contains multiple variables","F. Leaves and leaf-lists with escaped special characters","If leaf-list is marked as \"ordered-by user\", then the order of leaf-list elements is preserved during substitution process.","It is possible to substitute both variables with one or multiple variables.","Leaf 'leaf-a' contains 2 variables and surrounding text that is not part of any variable.","Leaf 'leaf-b' contains 2 variable without additional text - substituted values of these variables are concatenated at application of template.","Leaf-list 'leaf-list-a' contains 2 variables inside one leaf-list entry: 'var-a' and 'var-b'.","Leaf-list 'leaf-list-a' contains 2 variables with identifiers'var-a' and 'var-2'. String \"str3\" represents constant value.","Leaf-list 'leaf-list-a' contains variable with identifier 'var-x'.","Substitution of 'var-1' by 'prefix' and 'var-{2}' by '10':","Substitution of 'var-a' with texts 'str1', 'str2' and 'var-b' with'str4' results in ('string' type):","Substitution of 'var-x' with numbers '10', '20', '30' results in('int32' type):","The following example demonstrates escaping of special characters outside the variable identifier (leaf-list 'leaf-list-a') and inside the variable identifier (leaf 'leaf-a').","The following example shows 2 leaves with 2 variables: 'var-1' and'var-2'.","This variable can be substituted by one or multiple values. If multiple values are provided in the apply-template RPC, they are'unwrapped' to the leaf-list in form of next leaf-list entries.","Unescaped identifier of the leaf 'leaf-a': 'var-{2}'."]},{"l":"Tags","p":["By default, all templates have assigned 'merge' tag to the root'configuration' container - if template doesn't explicitly define next tags in the data-tree, then the whole template is merged to target UniConfig node configuration at execution of apply-template RPC. However, it is possible to set custom tags to data-tree elements of the template.","Properties:","Tags are represented in UniConfig using node attributes with the following identifier: 'template-tags:operation'.","In RESTCONF, attributes are encoded using special notation that is explained in the 'RESTCONF' user guide.","Tags are inherited through the data-tree of the template. If data-tree element doesn't define any tag, then it is inherited from parent element.","Only single tag can be applied to one data node.","Tags can be applied to following YANG structures: container, list, leaf-list, leaf, list entry, leaf-list entry.","Currently, the following tags are supported:","merge: Merges with a node if it exists, otherwise creates the node.","replace: Replaces a node if it exists, otherwise creates the node.","delete: Deletes the node.","create: Creates a node. The node can not already exist. An error is raised if the node exists.","update: Merges with a node if it exists. If it does not exist, it will not be created."]},{"l":"Examples with tags","p":["A. Tags applied to container, list, and leaf","Template with name 'user_template' that contains 'merge', 'replace', and 'create' tags:","Description of all operations in the correct order that are done based on the defined tags:","Container 'configuration' will be merged to target UniConfig node(implicit root operation).","Container 'system:system' will be updated - its content is merged only, if it has already been created.","The whole list 'users' will be replaced in the target UniConfig node.","Leaf named 'password' will be created at the target UniConfig node - it cannot exist under 'users' list entry, otherwise the error will be raised.","B: Tags applied to leaf-list, leaf-list entry, and list entry:","The following JSON represents content of sample template with multiple tags:","'replace' tag is applied to single list 'my-list' entry","'merge' tag is applied to whole 'leaf-list-a' leaf-list","'create' tag is applied to whole 'leaf-list-b' leaf-list","'delete' tag is applied to single leaf-list 'leaf-list-b' entry with value '10'"]},{"l":"Creating a template","p":["A new template can be created by sending PUT request to new template node under 'templates' topology with populated 'configuration' container. Name of the template equals to name of the 'node' list entry. This RESTCONF call must contain specified schema cache repository using the 'uniconfig-schema-repository' query parameter in order to successfully match sent data-tree with correct schema context (it is usually associated with some type of NETCONF device)."]},{"l":"Example","p":["The following example shows creation of new template with name'interface_template' using 'schemas_1' schema repository. The body of the PUT request contains whole 'configuration' container."]},{"i":"readupdatedelete-template","l":"Read/update/delete template","p":["All CRUD operations with templates can be done using standard RESTCONF PUT/DELETE/POST/PLAIN PATCH methods. As long as template contains some data under 'configuration' container, next RESTCONF calls, that work with templates, don't have to contain 'uniconfig-schema-repository' query parameter, since type of the device is already known."]},{"i":"examples---restconf-operations","l":"Examples - RESTCONF operations","p":["Reading specific subtree under 'interface_template' - unit with name'{$unit-id}' that is placed under interface with name'eth-0/{$interface-id}'.","Changing 'update' tag of the 'address' list entry to 'create' tag using PLAIN-PATCH RESTCONF method."]}],[{"l":"Apply template","p":["Apply tags- Streams the data-tree of the template and recursively applies data to the target UniConfig node based on tags set on data elements. The UniConfig node configuration is updated only in the Configuration datastore.","error-info- Additional information related to the error. For example, node identification and topology identification.","error-message- Description of the error that occurred when the template was applied.","error-tag- Error tag, also determines HTTP status code.","error-type- Error type.","Failed response: Returns HTTP status code 400– 500 and an error with the following fields:","leaf-list-values- List of values that can only be used with leaf-lists. Special characters (\\$, {, }) must be escaped.","leaf-value- Scalar value of the variable. Special characters (\\$, {,}) must be escaped.","Processing template configuration","Read template- Reads a template configuration from the templates topology in the Configuration datastore.","RPC apply-template","RPC input fields:","RPC output fields:","String-substitution- Substitutes variables with provided or default values. If no values are provided for some variables and leafs/leaf-lists, uses default values. If some variables cannot be substituted (for example, if no input value is specified for a variable), returns an error.","Successful response: Returns HTTP status code 200 with no fields.","template-node-id- Name of the existing input template.","The apply-templates RPC is used to apply templates to UniConfig nodes.","The following diagrams illustrate the process in more detail:","The procedure contains the following steps:","uniconfig-node- List of target UniConfig nodes to which the template is applied ( uniconfig-node-id is the key).","uniconfig-node-id- Target UniConfig node identifier.","variable- List of variables and substituted values that must be used when the template is applied to a UniConfig node. Variables must be set per target UniConfig node, as it is common that values of variables are different between devices. The variable-id leaf represents the key of this list.","variable-id- Unescaped variable identifier.","Version-drop- Converts a template into a target schema context used by the target UniConfig node. Also drops unsupported data from the input template. Because of this, the template can be applied to different versions of devices with different revisions of YANG schemas but with similar structure. Version-drop is also aware of the ignoredDataOnWriteByExtensions RESTCONF filtering mechanism."]},{"l":"RPC examples"},{"l":"Successful example","p":["Successful applying the SERVICE_GROUP template to two UniConfig nodes (R1 and R2)."]},{"l":"Failed example","p":["Failed to apply the TEMP1 template: Template does not exist."]},{"i":"failed-example-1","l":"Failed example","p":["Failed to apply the template REDUNDANCY_TEMPLATE to two UniConfig nodes (R1 and R2): Missing values for required variables."]},{"i":"failed-example-2","l":"Failed example","p":["Failed to apply the template redundancy_template to a UniConfig node (dev1): Invalid type of substituted variable value (failed regex constraint)."]}],[{"l":"RPC create-multiple-templates","p":["This RPC can be used to create one or more new templates.","Templates are parsed and written in parallel for better performance. If specified templates already exist, their configuration is replaced. Execution of the RPC is atomic, meaning that either all templates are successfully created or no changes are made to the UniConfig transaction.","RPC input fields:","template-name- Name of the created template.","yang-repository- YANG schema repository used to parse template configuration. The default value is latest.","template-configuration- The entire template configuration.","tags- List of template tags written on the specified paths in all created templates. A specified tag type must be prefixed with the template-tags module name based on RFC-8040 formatting of identityref.","RPC output fields:","Successful response: Returns HTTP status code 200 with no fields.","Failed response: Returns HTTP status code 400– 500 and an error with the following fields:","error-type- Error type.","error-tag- Error tag, also determines HTTP status code.","error-message- Description of the error that occurred when the template was applied.","error-info- Additional information related to the error. For example, node identification, topology identification.","Mandatory fields are template-name and template-configuration."]},{"l":"RPC examples"},{"l":"Successful example","p":["Successfully creating templates."]},{"i":"successful-example-1","l":"Successful example","p":["Creating two templates with separately specified template tags:","replace tag is added to /acl/category and /services/group=default/types elements","create tag is added to /services element"]},{"l":"Failed example","p":["Cannot find the specified YANG schema repository."]},{"i":"failed-example-1","l":"Failed example","p":["Failed to parse template configuration."]}],[{"l":"RPC get-template-info","p":["This RPC shows information about all variables in the specified template. The RPC input must contain a template name."]},{"l":"RPC examples"},{"l":"Creating a template"},{"l":"Successful example"}],[{"l":"RPC get-template-nodes","p":["This RPC returns all templates from a template topology. No input body is required."]},{"l":"RPC examples"},{"l":"Successful example","p":["There are no templates in the template topology."]},{"i":"successful-example-1","l":"Successful example","p":["There is a template called test-template in the template topology."]}],[{"l":"Upgrading template to latest yang repository","p":["error-info: Additional information related to the error. For example: node identification, topology identification.","error-message: Description of the error that occurred during application of template.","error-tag: Tag of the error, also determining HTTP status code.","error-type: Type of the error.","Failed response: Returns HTTP status code 400-500 and an error with the following fields:","No fields are used, only HTTP response codes [200 - OK, 404 - Fail]","Read template- Reads a template configuration from the templates topology in the Configuration datastore.","Removal of previous template / writing new template- If upgraded-template-name is not specified in the RPC input, the previous template is deleted and replaced by a new one. If specified, the previous template will not be deleted.","RPC input fields:","RPC output fields:","Successful response: Returns HTTP status code 200 with no fields.","template-name: Name of the existing input template. This field is mandatory.","Templates can be upgraded to the latest YANG repository using the upgrade-template RPC.","This procedure consists of the following steps:","upgraded-template-name: Name of upgraded/new template. This field is optional.","Version-drop- Converts a template into a target schema context created by the specified yang-repository. Because of this feature, it is possible to change templates between different versions of devices with different revisions of YANG schemas but with similar structure. Version-drop is also aware of the ignoredDataOnWriteByExtensions RESTCONF filtering mechanism.","yang-repository: Name of YANG repository against which version-dropping is used. This field is optional. If no yang-repository is specified, the latest yang repository is used."]},{"l":"RPC examples"},{"l":"Successful example"},{"l":"Auto-upgrading templates","p":["This feature is used to automatically upgrade all stored templates that use the old YANG repository to the latest YANG repository with help from the version-drop procedure. For the auto-upgrade process to succeed, the latest YANG repository must already be configured. The upgrade process must be explicitly enabled in the configuration file and occurs when UniConfig is started.","Additionally, there is an option to back up templates before the upgrade with the standard rotation procedure. The names of backed-up templates follow the pattern ' backup', where '' represents the name of the original template and'' represents the backup index. The most recent backup index is always '0' and older ones are rotated by incrementing the corresponding index. If a backed-up template reaches the configured limit (maximum number of backups), it is permanently removed from the database.","Available settings ('application.properties'):","enabledTemplatesUpgrading- Enable the auto-upgrading process at UniConfig startup. If disabled, the other setting is ignored.","backupTemplatesLimit- Maximum number of stored backup templates. If exceeded, older templates are removed during the rotation procedure. If set to 0, templates are not backed up at all."]}],[{"l":"Transaction Log","p":["The transaction log consists of a transaction tracker and a revert-changes RPC. The transaction tracker stores information called transaction-metadata about performed transactions into the operational snapshot. Whereas revert-changes RPC can be used to revert changes that have been made in a specific transaction. A user only need to have ID of transaction for that. One or more transactions can be reverted using one revert-changes RPC."]},{"l":"RPC revert-changes"},{"l":"Transaction tracker"}],[{"l":"RPC revert-changes","p":["This RPC is used to revert previously configured changes. To revert one or more transactions, their transaction ids must be included in the body of the RPC. The transaction id is part of transaction metadata created by the transaction tracker after the commit/checked-commit RPC.","This RPC only updates data in the CONFIGURATION snapshot. To write reverted data to the device, use RPC commit after RPC revert-changes."]},{"l":"Ignore non-existing nodes","p":["When reverting multiple transactions, some transaction metadata may contain nodes that do not currently exist in UniConfig. In this case, the RPC fails.","There are two options for handling non-existing nodes:","Remove transactions that contain non-existing nodes from the request body.","Add the ignore-non-existing-nodes parameter to the RPC request body with a value of true(the default value is false).","If the ignore-non-existing-nodes parameter is not specified, the default value is used."]},{"l":"RPC examples"},{"l":"Successful examples","p":["To revert a transaction, we need to find its ID. Let's use a GET request to display all stored transaction metadata.","Revert changes for a single transaction.","Revert changes for multiple transactions.","Revert changes for multiple transactions. The transaction with id 2c4c1eb5-185a-4204-8021-2ea05ba2c2c1 contains the non-existing node R1. Since the ignore-non-existing-nodes parameter is set to true, the RPC is successful."]},{"l":"Failed example","p":["The request contains a non-existing transaction in the request body.","Reverting changes for multiple transactions. The transaction metadata with id 2c4c1eb5-185a-4204-8021-2ea05ba2c2c1 contains a non-existing node. Since the ignore-non-existing-nodes parameter is set to false, the RPC fails."]}],[{"l":"Transaction tracker","p":["The transaction tracker is responsible for saving transaction metadata to the Operational snapshot after a successfully executed commit or checked-commit RPC. Transaction metadata contains information about performed transactions, such as the following:","transaction-id- Identifier for transaction.","type-of-commit-time- Timestamp for either last-commit-time(if the transaction was successful) or failed-commit-time(if the transaction failed). If multiple devices are configured, last-commit-time contains a timestamp for the last update on the last device.","metadata- Items in this field represent nodes configured in the transaction. Each item contains a diff item with additional information.","diff- Items in this field are specific changes. Each item contains a path to changes, data before the change and data after the change. For failed transactions, this information is not included.","topology- Which topology the node is installed on. Either uniconfig or unistore.","Data-before is visible only if data was updated or deleted. Data-after is visible only if data was updated or created.","transaction-tracker]"]},{"l":"Configuration","p":["By default, UniConfig stores transaction metadata. Their removal depends only on the transactions.max-transaction-age parameter."]},{"l":"Show transaction-metadata","p":["The response to this GET request contains all stored transaction metadata, transaction ids and other items such as node id, updated data before and after update, etc."]}],[{"l":"UniConfig Node Manager","p":["If configuration fails for one device, UNM executes an automatic rollback where the previous configuration is restored on all modified devices.","RPC bulk-get","RPC calculate-diff","RPC calculate-git-like-diff","RPC check-installed-nodes","RPC check-nodes-connection","RPC checked-commit","RPC commit","RPC compare-config","RPC get-installed-nodes","RPC health","RPC install-multiple-nodes","RPC is-in-sync","RPC replace-config-with-operational","RPC sync-from-network","RPC uninstall-multiple-nodes","RPC validate","See below for additional information on individual RPCs:","Synchronization from the network reads configurations from devices and stores them as actual states in the Operational datastore.","The northbound API of the UniConfig Manager (UNM) is RPC-driven and provides commit functionality with automatic rollback and synchronization of configurations from the network.","This component is responsible for maintaining the configuration on devices based on their intended configuration. Each device and its configuration are represented as a node in the UniConfig topology. The node's configuration is described using OpenConfig YANG models.","When a commit is called, UNM creates a diff based on the intended state in the Config datastore and the actual state in the Operational datastore. This diff is used as the basis for device configuration. UNM prepares a network-wide transaction that uses unified mountpoints for communication with different types of devices. An additional git-like diff RPC is used to display all changes grouped under root elements in a git-like style."]}],[{"l":"RPC bulk-get","p":["This RPC provides multiple get operations on multiple nodes, paths and contents. It is possible to get data from 'Operational' datastore of UniConfig topology if no content is specified, otherwise data is retrieved from the device directly (over mount-point). Operation is executed over actual/existing UniConfig transaction (immediate-commit model / manual user transaction). Each GET operation is executed in parallel. For mount-point read, it is enough to have node installed on southbound topology (if multiple mount-points with the same node-id exist, user need to specify also connection-type) or just stored in uniconfig database.","RPC input contains a list of node inputs where each consists of mandatory fields such as node-id(UniConfig node identifier) and path, which points to specific subtree. Optional fields are content, connection-type and ignore-missing-data-error. Content determines that the call will be over mount-point to target device datastore config, operational, state, all, where state, all are only for gnmi node. Connection type is needed only in a scenario where multiple southbound mount-points are defined with the same node-id. If data-missing error is not wanted, user may add ignore-missing-data-error and set it to true (default is false) which will display empty config in data leaf.","If get operation on any nodes failed (node is not installed, connection lost, data is not present, ...) the response will display only failed nodes in common RFC8040 errors container. In a success case, the result is structured in node-results format. Each node-result consists of node-id, content(if over mount-point) path and data that contains wanted subtree config."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains valid nodes that are installed in UniConfig topology. Bulk-get will read config on following paths from UniConfig operational datastore."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input contains valid nodes, from which Ri is installed in UniConfig topology, and R2 is installed as southbound only. Bulk-get will read config on following paths from following content target datastores."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input contains two nodes, where R1 is successful and R2 does not provide any config on given path, but ignore-missing-data-error is present."]},{"l":"Failed example","p":["RPC input contains valid node R1 and an invalid node R2, which is not installed in uniconfig topology and content is not specified for that node."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains one node with node-id R1 that has two mount-points (one is mounted over cli and the other over netconf) and no connection-type is specified."]},{"i":"failed-example-2","l":"Failed example","p":["RPC input contains one node with node-id R3 that is not installed in uniconfig under any southbound topology."]},{"i":"failed-example-3","l":"Failed example","p":["If RPC input does not contain any node inputs"]}],[{"l":"RPC calculate-diff","p":["This RPC creates a diff between actual and intended UniConfig topology nodes.","RPC input contains a list of UniConfig nodes for calculating the diff. RPC output contains a list of statements representing the diff. It also matches all input nodes.","If the RPC is called with an empty list of target nodes, a diff is calculated for each node modified in the UniConfig transaction. If a node fails for any reason, the entire RPC fails."]},{"l":"RPC Examples"},{"l":"Successful Example","p":["RPC input contains two target nodes and output contains a list of statements representing the diff."]},{"i":"successful-example-1","l":"Successful Example","p":["If RPC input does not specify any target nodes, calculate-diff is invoked for all nodes touched by the transaction.","or"]},{"i":"successful-example-2","l":"Successful Example","p":["RPC input contains a target node and there is no diff."]},{"l":"Failed Example","p":["RPC input contains a target node that is not installed. RPC output describes the result of the calculate-diff RPC."]},{"i":"failed-example-1","l":"Failed Example","p":["RPC input contains two target nodes, one of which (R2) is not installed. RPC output describes the result of the calculate-diff RPC."]},{"i":"failed-example-2","l":"Failed Example","p":["If RPC input does not contain target nodes and no nodes have been touched, the request results in an error.","or"]}],[{"l":"RPC calculate-git-like-diff","p":["This RPC creates a diff between actual and intended UniConfig topology nodes.","RPC input contains a list of UniConfig nodes to calculate the diff. RPC output contains a list of statements that represent the diff in a git-like style.","If RPC input contains no target nodes, all nodes touched in the transaction are checked. If any node fails, the entire RPC fails."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains two target nodes. RPC output contains a list of statements representing the diff."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input contains no target nodes, therefore all nodes touched in the transaction are checked. RPC output contains a list of all changes on different paths. Multiple changes that occur under the same path are merged together."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input contains a target node and there is no diff."]},{"l":"Failed example","p":["RPC input contains a target node that is not installed. RPC output describes the result of the calculate-diff RPC."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains two target nodes, one of which (R1) is not installed. RPC output describes the result of the calculate-git-like-diff RPC."]},{"i":"failed-example-2","l":"Failed example","p":["If RPC input does not contain target nodes and no nodes have been touched, the request results in an error."]}],[{"l":"RPC check-installed-nodes","p":["This RPC checks if devices specified in the input are installed by looking for the database content of each device. If content is found, the device is installed.","Output of the RPC contains only a list of devices that are present in the UniConfig database. List of devices contains:","topology-id - identifier of the topology in which the device is installed","node-id - device identifier","uniconfig-layer - boolean value indicating whether the device is installed in the UniConfig layer"]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains a device, while no devices are installed."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input contains two devices (R1 and R2), one of which (R1) is installed."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input contains two devices (R1 and R2), both of which are installed."]},{"l":"Failed example","p":["RPC input does not specify any nodes."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input is missing the target-nodes container."]}],[{"l":"RPC check-nodes-connection","p":["This RPC checks if specified devices are reachable (health-check). This is done by session creation, single request execution (most lightweight one), session cleanup.","RPC input specifies target-nodes on which UniConfig checks connection. Each target-node is executed in parallel and whole RPC is outside the uniconfig transaction concept. Output describes only failed health-check operations. Input may also contain connection-timeout which is overall timeout for operation -> establishing session amd single request to device. This timeout is applied individually per each target-node (default value is 5 seconds)."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input specify a device R1 without specifying connection-timeout parameter."]},{"l":"Failed example","p":["RPC input specifies device R1 (reachable), R2 (not reachable). Input also contains connection-timeout parameter set for 3 seconds. Operation was successful only for device R1. Output describes output for failed device R2."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input specifies device R1 which is not installed."]}],[{"l":"RPC checked-commit","p":["This RPC is the trigger for executing the checked configuration. A checked commit is similar to an RPC commit, but it also checks that nodes are in sync with the network before it starts configuration. The RPC fails if any node is out of sync.","RPC output describes the result of the commit and matches all modified nodes in the UniConfig transaction. If a node fails for any reason, the entire RPC fails.","Compared to the commit RPC, there is an additional step between steps 1 and 3:","Lock and validate configured nodes","Check if nodes are in sync with the state on devices","Write configuration to device","Validate configuration","Confirmed commit","Confirming commit (submit configuration)","The following diagram illustrates the check, assuming that configuration fingerprints in the transaction datastore and device are equal.","Fingerprint-based validation is different between steps 1 and 2. For step 1, the goal is to validate if another transaction has already changed the same node by comparing fingerprints in the UniConfig transaction and the database. Step 2 checks that the fingerprint in the transaction is equal to the fingerprint on the device (i.e., if another system or a user directly via the CLI has updated the device configuration since the beginning of the transaction)."]},{"l":"RPC examples"},{"l":"Successful example","p":["The configuration of nodes R1 and R2 has been modified in the transaction. Both nodes are in sync with the actual state on the device.","RPC input invokes all touched nodes."]},{"l":"Failed example","p":["The configuration of nodes R1 and R2 has been modified in the transaction. Both R1 and R2 are in sync with the actual state on the device. Node R1 has failed due to incorrect configuration.","RPC output describes the result of the checked-commit RPC."]},{"i":"failed-example-1","l":"Failed example","p":["The configuration of node R1 has been changed in the transaction. Node R1 is in sync with the actual state on the device. Node R1 has failed on the changed fingerprint.","RPC output describes the result of the checked-commit."]},{"i":"failed-example-2","l":"Failed example","p":["Node R2 has lost connection."]},{"i":"failed-example-3","l":"Failed example","p":["If RPC input does not contain target nodes and no nodes have been touched, the request results in an error."]}],[{"l":"RPC commit","p":["1. Lock and validate configured nodes","2. Write configuration to device","3. Validate configuration","4. Confirmed commit","5. Confirming commit (submit configuration)","Commit invokes all nodes touched in the transaction. There are no target nodes in the RPC input. Steps 3 and 4 only apply to nodes that support these operations.","Configuration phase","Confirmed commit","Confirmed commit: Lock the device configuration so that no other transaction can touch the device. This phase can be skipped with the do-confirmed-commit flag.","Confirming commit","Confirming commit (submit configuration): Persist all changes on devices and in the PostgreSQL database. The UniConfig transaction is closed.","If a node fails for any reason, the entire RPC fails. After the commit RPC, the UniConfig transaction is closed regardless of the result.","If one of the nodes uses a confirmed commit (step 4) that does not fail, it is necessary to issue the submitted configuration (step 5) within the timeout period. Otherwise the node configuration issued by the confirmed commit is reverted to its state before the confirmed commit (i.e., confirmed commit makes only temporary configuration changes). The default timeout period is 600 seconds(10 minutes), which can be changed in the installation request.","Lock and validate configured nodes: Lock all modified nodes using PostgreSQL advisory locks and validate fingerprints. If another transaction attempts to commit overlapping nodes or another transaction has already changed one of the nodes, commit will fail at this step.","Locking nodes","Rollback operation","Rollback: Restore the configuration to its previous state if the configuration process fails. When configuring multiple devices in a single transaction and the process fails on one particular device, the rollback procedure is applied to all touched devices. This is done with the auto rollback procedure, which is by enabled by default. The procedure can be disabled with the do-rollback flag in the RPC input, in which case only failed devices are rolled back.","The configuration of nodes consists of the following phases:","The external application stores the intended configuration under nodes in the UniConfig topology. The trigger for executing the configuration is an RPC commit. RPC output describes the result of the commit.","The following diagrams describe all five commit steps in more detail:","The next diagram shows the rollback procedure that must be executed after a failed commit on nodes that have already been configured and do not support the candidate datastore.","The skip-unreachable-nodes flag controls whether unreachable nodes are skipped when the RPC commit is sent. When set to true, nodes that are not reachable are skipped and others are configured. The default value is false.","Validate configuration: Validate the written configuration from the view of constraints and consistency. This phase can be skipped with the do-validate flag.","Validation phase","Write configuration to device: Push calculated changes onto the device without committing these changes."]},{"l":"RPC examples"},{"l":"Successful example","p":["UniConfig commits nodes R1 and R2 that have been changed in the actual transaction."]},{"i":"successful-example-1","l":"Successful example","p":["Nodes R1 and R2 have been changed. RPC input includes the flag to disable the confirmed-commit phase. UniConfig commits all touched nodes."]},{"i":"successful-example-2","l":"Successful example","p":["If there are no touched nodes, the request finishes successfully."]},{"l":"Failed example","p":["Node R1 has failed because it failed the validation step."]},{"i":"failed-example-1","l":"Failed example","p":["Node R1 has failed because the confirmed commit failed. The validation step is skipped because of the do-validate flag."]},{"i":"failed-example-2","l":"Failed example","p":["Node R1 has failed because of the time delay between confirmed commit and submitted configuration."]},{"i":"failed-example-3","l":"Failed example","p":["Node R1 has failed due to incorrect configuration."]},{"i":"failed-example-4","l":"Failed example","p":["Node R1 has lost connection."]},{"i":"failed-example-5","l":"Failed example","p":["Node R1 has failed because of incorrect configuration. In this case validation, confirm-commit and auto-rollback are disabled.","Since auto-rollback is disabled, configuration of R1 was successful. However, this can only be done if the validation and confirm-commit phases were successful or skipped; otherwise configuration of the R1 device would also fail."]},{"i":"failed-example-6","l":"Failed example","p":["Configuration of nodes R1 and R2 have been modified in the transaction, and both are in sync with the actual state on the device. Connection to node R2 has been lost. RPC input has the flag to skip unreachable nodes set to true.","The result of the commit RPC describes success for node R1 and includes a list of unreachable nodes."]}],[{"l":"RPC compare-config","p":["This RPC is a combination of the sync-from-network and calculate-diff RPCs. If one of those RPCs fails, this one also fails with no changes made.","The purpose of this RPC is to synchronise configurations from network devices to UniConfig nodes in the Configuration datastore of the UniConfig transaction.","RPC input contains a list of UniConfig nodes whose configuration is compared to the actual configuration in the transaction. RPC output describes the result of the RPC and matches all input nodes with a list of statements representing the diff."]},{"l":"RPC examples"},{"l":"Successful example"},{"i":"successful-example-1","l":"Successful example","p":["If RPC input does not specify target nodes, the configuration of all nodes touched in the transaction is compared to the synced device configuration."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input includes a target node and there is no diff."]},{"l":"Failed example","p":["RPC input has two target nodes, one of which (R2) is not installed. The output describes the result of sync-from-network."]},{"i":"failed-example-1","l":"Failed example","p":["If RPC input does not contain target nodes and there are no touched nodes, the request results in an error."]}],[{"l":"RPC connect-node","p":["This RPC creates a connection to a device that is already installed. The connection is created outside of a transaction, so that the connection stays up even without active transactions.","Note that the transaction used in this RPC is created internally, so that no user-created transactions are used.","The connect-node RPC also supports connections to stream nodes. These are possible only if a stream node is already defined in the install-node RPC. The most common use case is when a subscription stream is disconnected and a reconnection is required.","The connect-node RPC only works on local Uniconfig nodes in a cluster."]},{"l":"RPC parameters","p":["node-id(mandatory) - ID of a node. In case of a stream node, the node consists of a device node and a stream name ( device node_stream name, for example R1_NETCONF).","max-connection-attempts- Maximum number of connection attempts. The default value is 1.","between-attempts-timeout- Timeout between connection attempts in seconds. The default value is 60 seconds."]},{"l":"CLI Shell","p":["The connect-node RPC is also included in UniConfig shell. As it takes node-id as input, the shell only suggests nodes that are relevant to this RPC (nodes that are installed in UniConfig but are not yet connected)."]},{"l":"RPC examples","p":["For all examples, assume that the install RPC request included the following parameters:"]},{"i":"successful-example---request-for-a-device-node","l":"Successful example - Request for a device node"},{"i":"successful-example---request-for-a-stream-node","l":"Successful example - Request for a stream node","p":["Note that waiting for a stream node to be connected is currently not supported. This means that even if the response code is 200, the connection is not necessarily successful as well. To test if the connection is successful or in the process of connecting, call the RPC again (see example below) or examine the UniConfig logs."]},{"i":"failed-example---node-is-already-connected","l":"Failed example - Node is already connected"},{"i":"failed-example---node-is-in-the-process-of-connecting","l":"Failed example - Node is in the process of connecting"},{"i":"failed-example---node-does-not-exist","l":"Failed example - Node does not exist"}],[{"l":"RPC disconnect-node","p":["This RPC closes connection to a device. If a node is associated with multiple transactions, it will be removed from all of them.","Note that the transaction used in this RPC is created internally, so that no user-created transactions are used.","The disconnect-node RPC also supports disconnecting stream nodes.","Note that the disconnect-node RPC only works on local Uniconfig nodes in a cluster."]},{"l":"RPC parameters","p":["node-id(mandatory) - ID of a node. In case of a stream node, the node consists of a device node and a stream name ( device node_stream name, for example R1_NETCONF)."]},{"l":"UniConfig shell","p":["The disconnect-node RPC is also included in UniConfig shell. As it takes node-id as input, the shell only suggests nodes that are relevant to this RPC (nodes that are already connected)."]},{"l":"RPC examples","p":["For all examples, assume that the install RPC request included the following parameters:"]},{"i":"successful-example---request-for-a-device-node","l":"Successful example - Request for a device node"},{"i":"successful-example---request-for-a-stream-node","l":"Successful example - Request for a stream node"},{"i":"failed-example---node-not-connected","l":"Failed example - Node not connected","p":["The specified node is not connected or does not exist in the database."]},{"i":"failed-example---node-does-not-exist","l":"Failed example - Node does not exist"}],[{"l":"RPC get-installed-nodes","p":["This RPC returns all installed devices from a specified topology.","If no topology is specified, the output may contain devices from multiple topologies (CLI, NETCONF, gNMI). In this case, devices must be installed with the install request parameter uniconfig-config:install-uniconfig-node-enabled set to true. If no topology is specified, the RPC looks for nodes installed in the UNICONFIG topology by default."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input does not specify a topology, and device R1 is installed in the NETCONF topology. If the install request includes the parameter“uniconfig-config:install-uniconfig-node-enabled”:“true”, the device is installed in the UNICONFIG topology instead."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input does not specify a topology, and device R1 is installed in the NETCONF topology. If the install request includes the parameter“uniconfig-config:install-uniconfig-node-enabled”:“false”, the device is not installed in the UNICONFIG topology."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input specifies the GNMI topology, and device R1 is installed in that topology."]},{"i":"successful-example-3","l":"Successful example","p":["RPC input specifies the CLI topology, but no devices are installed in that topology."]}],[{"l":"RPC health","p":["This RPC checks if UniConfig is running. If database persistence is enabled, it also checks the database connection."]},{"l":"RPC examples","p":["RPC input is empty. RPC output contains the result of the operation.","Response if database persistence is enabled and the database connection is valid:","Response if database persistence is enabled and database connection is not valid:"]}],[{"l":"RPC install-multiple-nodes","p":["This RPC installs multiple devices at once using the default install-node RPC. Devices are installed independently in parallel.","If two nodes are being installed and one node fails, the second node is still installed. If at least one node fails, the RPC response describes the result for failed nodes only."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains two devices (R1 and R2)."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input contains two devices (R1 and R2). Device R2 uses two different protocols."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input contains two devices (R1 and R2). Device R2 is already installed using the CLI protocol."]},{"l":"Failed Example","p":["RPC input does not specify a node-id."]},{"i":"failed-example-1","l":"Failed Example","p":["RPC input contains two devices with the same node-id."]}],[{"l":"RPC is-in-sync","p":["This RPC is used to verify that specified nodes are in sync with the current state in the Operational datastore of the UniConfig transaction.","Verification is performed by comparing configuration fingerprints. The configuration fingerprint on the device is compared with the last configuration fingerprint saved in the Operational datastore. A fingerprint is usually represented by a configuration timestamp or the last transaction ID.","The is-in-sync feature is supported only for device types that have implemented translation units for the frinx-configuration-metadata OpenConfig module (using CLI units, NETCONF units or UniConfig-native metadata units).","RPC input contains a list of UniConfig nodes for which verification should be performed (the target-nodes field). The response contains the operation status for each node specified in the input. If the operation fails, it is because the specified node has not been successfully installed, the connection is lost or UniConfig does not support reading the configuration fingerprint from that specific device type. Calling the RPC with an empty list of target nodes invokes the RPC for each node modified in the UniConfig transaction.","Possible RPC outputs per target node:","status field with value complete and is-in-sync boolean flag set: The is-in-sync feature is supported and configuration fingerprints have been successfully compared.","status field with value fail, error-type field with value no-connection and corresponding error-message: The unified mountpoint does not exist because the connection was lost or the node is not mounted.","status field with value fail, error-type field with value uniconfig-error and corresponding error-message: Reading the fingerprint from the Operational datastore or unified mountpoint has failed, or parsing configuration metadata is not supported for the device type.","Executing RPC is-in-sync does not modify the Operational datastore. The configuration fingerprint stored in the Operational datastore is not updated. Use RPC sync-from-network to update the last configuration fingerprint and the actual configuration state."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains valid nodes for which synchronization status should be checked (R1 is synced, R2 is not synced)."]},{"i":"successful-example-1","l":"Successful example","p":["If RPC input contains no target nodes, all touched nodes are invoked."]},{"l":"Failed example","p":["RPC input contains an invalid node (R1), which does not support fingerprint comparisons (metadata translation unit has not been implemented for this device)."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains two nodes. Node R1 is valid and synced, R2 is not installed. If one node is invalid, the UniConfig operation fails with an error entry in the response."]},{"i":"failed-example-2","l":"Failed example","p":["If RPC input does not contain any target nodes and there are no touched nodes, the request results in an error."]}],[{"l":"RPC replace-config-with-operational","p":["This RPC replaces UniConfig topology nodes in the Configuration datastore with nodes from the Operational datastore.","RPC input contains a list of UniConfig nodes to replace. RPC output describes the result of the operation and matches all input nodes.","If the RPC is invoked with an empty list of target nodes, the operation is invoked for all nodes modified in the UniConfig transaction. If any node fails, the entire RPC also fails."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input has two target nodes. RPC output contains the result of the operation."]},{"i":"successful-example-1","l":"Successful Example","p":["If RPC input does not contain target nodes, the configuration of all touched nodes is replaced by the operational state."]},{"l":"Failed example","p":["RPC input contains a list of target nodes. Node R1 has not been installed. RPC output contains the result of the operation."]},{"i":"failed-example-1","l":"Failed example","p":["If RPC input does not contain any target nodes and there are no any touched nodes, the request results in an error."]}],[{"l":"RPC sync-from-network","p":["This RPC synchronizes configurations from network devices to UniConfig nodes in the Operational datastore of the UniConfig transaction.","RPC input contains a list of UniConfig nodes whose configuration should be refreshed within the network. RPC output describes the result and matches all input nodes.","Calling the RPC with an empty list of target nodes syncs the configuration of all nodes modified in the UniConfig transaction. If any node fails, the entire RPC also fails.","If the network device was installed as southbound-only (with the uniconfig-config:install-uniconfig-node-enabled parameter set to false), the RPC syncs the device to the UniConfig topology and rewrites the above-mentioned parameter to true."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains nodes whose configuration should be refreshed.","If RPC input contains no target nodes, all nodes touched in the transaction are synced."]},{"l":"Failed example","p":["RPC input contains a list of nodes whose configuration should be refreshed. Node R2 is not installed."]},{"i":"failed-example-1","l":"Failed example","p":["If RPC input does not contain any target nodes and there are no touched nodes, the request results in an error."]}],[{"l":"RPC sync-to-network","p":["This RPC is a combination of the sync-from-network and commit RPCs. If one of those RPCs fails, this RPC also fails without making any changes.","The purpose of this RPC is to synchronize configurations from UniConfig nodes in the Configuration datastore of the UniConfig transaction to network devices.","RPC input contains a list of UniConfig nodes to be updated on a network device. RPC output describes the results and matches all input nodes.","Calling this RPC with an empty list of target nodes syncs the configuration of all nodes modified in the UniConfig transaction. If any node fails, the entire RPC also fails. The admin-state of UniConfig nodes specified in the input must be set to unlocked."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains a list of nodes to be updated on the corresponding network device."]},{"i":"successful-example-1","l":"Successful example","p":["If RPC input contains no target nodes, the operation is invoked for all nodes touched in the transaction."]},{"l":"Failed example","p":["If the admin-state for some input nodes is not set to unlocked, the request results in an error that includes a list of nodes with the wrong state."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains one node with an incorrect admin-state."]},{"i":"failed-example-2","l":"Failed example","p":["RPC input contains two nodes. Node R1 is valid and R2 has not been installed. If at least one node is invalid, the entire operation fails."]},{"i":"failed-example-3","l":"Failed example","p":["If RPC input contains no target nodes and there are no touched nodes, the request results in an error."]}],[{"l":"RPC uninstall-multiple-nodes","p":["This RPC uninstalls multiple devices at once using the default uninstall-node RPC. Devices are uninstalled independently in parallel.","If two nodes are being uninstalled and one node fails, the second node is still uninstalled. If at least one node fails, the response describes the result for failed nodes only."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains two devices (R1 and R2)."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input contains two devices (R1 and R2). Device R2 is installed on two different protocols."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input contains two devices (R1 and R2). Device R2 is already uninstalled on the CLI protocol."]},{"l":"Failed example","p":["RPC input does not specify a node-id."]}],[{"l":"RPC validate","p":["The external application stores the intended configuration under nodes in the UniConfig topology. The configuration can be checked for validity. This RPC is the trigger for validating a configuration.","RPC input contains a list of UniConfig nodes whose configuration should be validated. RPC output describes the result of the validation and matches all input nodes.","If the RPC is called with an empty list of target nodes, all nodes modified in the UniConfig transaction are validated.","The configuration of nodes follows these steps:","Open transaction to device","Write configuration","Validate configuration","Close transaction","If any node fails in step 3 (validation), the entire RPC also fails.","Validation (step 3) only applies to nodes that support this operation.","The diagram below illustrates the RPC:"]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input has two target nodes. RPC output describes the result of successful validation."]},{"i":"successful-example-1","l":"Successful example","p":["If RPC input does not specify any target nodes, all nodes touched in the transaction are validated."]},{"l":"Failed example","p":["RPC input has one target node. RPC output describes the result of the validation. In this case, the node has failed because validation has failed."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains two nodes. Node R1 is valid and R2 is not installed. If at least one node is invalid, the entire operation fails."]},{"i":"failed-example-2","l":"Failed example","p":["If RPC input does not contain any target nodes and there are no touched nodes, the request results in an error."]}],[{"l":"UniConfig properties","p":["UniConfig properties are application properties used to configure the application. They can be separated into three groups:","Runtime mutable properties can be modified in runtime (using the update-properties RPC), their changes take effect in runtime and the properties are persisted in the database.","Database persisted properties include all runtime mutable properties and some additional properties. These properties are stored in the database, which is always their primary source. With UniConfig Cloud Config, they remain constant across UniConfig instances in the same cluster and cannot be overridden via the application properties file.","Regular UniConfig properties comprise all the remaining properties. These properties can always be changed using the application.properties file and can differ between UniConfig instances.","Database persisted properties can be changed or read in application runtime without restarting UniConfig by using UniConfig Cloud Config and the following RPCs:","RPC read-properties","RPC update-properties"]}],[{"l":"RPC read-properties","p":["This RPC reads default properties from the database. If a specified property key does not exist in the database, the key is returned under Ignored keys. The RPC works the same whether UniConfig Cloud Config is enabled or disabled.","read","If UniConfig Cloud Config is disabled, this RPC reads property values from the database. These values may differ from values in the application instance."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains default property keys."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input contains properties that are not default properties or are private(crypto keys and crypto types)."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input consists of properties that do not exist in the database."]}],[{"l":"RPC update-properties","p":["The update-properties RPC is used to update property values. If UniConfig Cloud Config is enabled, it also calls Refresh Bus Endpoint to update properties in runtime for all connected UniConfig instances.","The RPC only updates default properties, except for crypto properties for which there are separate RPCs ( change-encryption-status and change-encryption-keys).","RPC sequence diagram with UniConfig Cloud Config enabled:","update-with-ucc","If UniConfig Cloud Config is disabled, the RPC only updates property values in the the database. The application instance continues to use the old property values, which can cause confusion.","Additionally, if a new UniConfig instance is started after properties have been updated, that instance will use the updated property values from the database. UniConfig instances will therefore use different values for the same property, as described in the diagram below.","We recommend that you use this RPC with UniConfig Cloud Config. The exception is callbacks.access-token, which is always up to date.","RPC sequence diagram with UniConfig Cloud Config disabled:","update-without-ucc"]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains the default properties with correct values."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input contains the crypto default property."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input contains an incorrect property name."]},{"l":"Failed example","p":["RPC input contains default properties with incorrect values."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains default properties with incorrect values."]}],[{"l":"Utilities","p":["Utilities are simple programs that are part of the UniConfig distribution. After unpacking and building the distribution, utilities can be found in the 'utils' subdirectory."]},{"l":"YANG Packager"},{"l":"Difference between OpenAPI specifications"}],[{"l":"Difference between OpenAPI specifications","p":["The Uniconfig distribution includes a program for checking the difference between OpenAPI specifications. After building and unpacking the distribution, you can find the program in the utils directory as a shell script called show_swagger_diff.sh.","The program uses OpenAPI-diff to generate OpenAPI differences."]},{"l":"Usage","p":["The ./show_swagger_diff.sh script contains four arguments. Each one has its own identifier, so you can give arguments in any order. All arguments are optional as default values are included for each one.","--former, -f /path/to/former/yaml/files- Path to previous OpenAPI specifications (.yaml files). The default path is openapi_diff/old.","--new, -n /path/to/new/yaml/files- Path to new OpenAPI specifications (.yaml files). The default path is openapi_diff/new.","--output, -o /path/to/output- Path to HTML output file with differences. The default path is openapi_diff.","-s- Silent printing, includes less information.","The script also includes a simple help facility. There are two ways to view the help text:","./show_swagger_diff.sh -h","./show_swagger_diff.sh --help","The script only accepts YAML files."]},{"l":"Example use case"},{"l":"Default usage","p":["This example shows basic usage of the script with and without optional arguments. Open a terminal and the ../utils directory, and run the following command:","Alternatively:"]},{"l":"Usage with non-existent input path","p":["This example shows basic usage of the script where some specified input directories do not exist. Open a terminal and the ../utils directory, and run the following command:"]}],[{"l":"YANG packager"},{"l":"Introduction","p":["YANG packager is a simple program which is part of the UniConfig distribution. User can finds it in the utils/ directory after building and unpacking the UniConfig distribution. User can use it by simple shell script called'convertYangsToUniconfigSchema.sh'. YANG packager is responsible for:","validation of user-provided YANG files","copying valid YANG files to the user-defined directory","informing the user about conversion process"]},{"l":"Usage","p":["-d /path/to/default- optional argument. Sometimes some YANG files need additional dependencies that are not provided in source directories. In this case it is possible to use path to the 'default' directory which contains additional YANG files. If there is this missing YANG file, YANG packager will use it.","-enableSwagger- optional argument. Path to file that enables OpenAPI generation.","-g- optional argument. Path to directory where generated Java sources with constants from YANG elements are saved. By default, generation of Java files is disabled.","-i /path/to/sources- required argument. User has two options for where the path can be directed:","-jd- optional argument. Flag that enables to generate java documentation on data elements.","-o /path/to/output-directory- required argument. User can define path where he wants to save valid YANG files. If the output directory exists, it will be replaced by a new one.","-pn- optional argument. Custom package name of generated classes.","-px- optional argument. Flag that enables prefix for generated constants names inside generated classes.","-r- optional argument. Selection of repositories inside source directory with files or file with defined names of directories which contains files, from which constants will be generated.","-s /path/to/skip-list- optional argument. User can define YANG file names in text file that he does not want to include in conversion process. This file must only contain module names without revision and .yang suffix.","-to-file- optional argument. When user uses this flag, then YANG packager also saves the debug output to a file. This file can be found on a same path as output-directory. It will contain suffix '-info' in its name. If the output directory is called 'output-directory', then the file will be called 'output-directory-info'.","./convertYangsToUniconfigSchema --help","./convertYangsToUniconfigSchema -h","Bash script ./convertYangsToUniconfigSchema also includes simple help facility. There are two options how to show the help text:","If compilation process detected some invalid YANG files then output directory will not be created. In this case, user has to fix invalid YANG files or use a combination of \"-d\" and \"-s\" arguments.","Script ./convertYangsToUniconfigSchema contains four arguments. Each one has its own identifier so user can use any order of arguments. Two arguments are required, namely the path to resources that contain YANG files and the path to the output directory where user wants to copy all valid YANG files. Other three arguments are optional. First one is the path to the\"default\" directory which contains some default YANG files, second one is the path to the \"skip-list\" and last one is a \"-to-file\" flag, which user can use when he wants to write a debug output to file.","The user is responsible for the validity of YANG files in the default directory. These files are not checked by YANG package.","to the directory that contains YANG files and other sub-directories with YANG files","to the text-file that contains defined names of directories. These defined directories have to be stored on the same path as text-file."]},{"l":"Example use-case"},{"l":"Basic usage 1","p":["This is basic usage of the script where only mandatory arguments are used. In this case, there is a directory with YANG files used as source. All files in source directory are valid YANG files. Open a terminal, go to the ../utils directory and run command:"]},{"l":"Basic usage 2","p":["This is basic usage of the script where only mandatory arguments are used. In this case, there is directory with YANG files used as source. Source directory also contains one invalid YANG file with missing import. Open a terminal, go to the ../utils directory and run command:"]},{"l":"Basic usage 3","p":["This is basic usage of the script where only mandatory arguments are used. In this case, there is directory with YANG files used as source. Source directory also contains one non-yang file. Open a terminal, go to the ../utils directory and run command:"]},{"l":"Usage with default directory","p":["This is usage with path to default directory that contains one YANG file openconfig-mpls. Source directory also contains one invalid YANG file 'cisco-xr-openconfig-mpls-deviations.yang' with missing import 'openconfig-mpls'. This missing import is loaded from default directory. Open a terminal, go to the ../utils directory and run command:"]},{"l":"Usage with skip-list","p":["This is usage with path to skip-list text file that contains one YANG file name cisco-xr-openconfig-mpls-deviations. This YANG file will not be included in the conversion process. Open a terminal, go to the ../utils directory and run command:"]},{"l":"Usage with text-file as a source","p":["In this example a path to text-file with defined names of source directories is used.","Open a terminal, go to the ../utils directory and run command:"]},{"i":"usage-with--to-file-flag","l":"Usage with -to-file flag","p":["This is usage where output is also printed to file. User can find output information file on the path /path/to/output-info.","Open a terminal, go to the ../utils directory and run command:"]},{"i":"usage-with-text-file-as-a-source-and--to-file-flag","l":"Usage with text-file as a source and -to-file flag","p":["In this example a path to text-file with defined names of source directories is used and also flag for print outputs to files. User can find output information files on paths /path/to/output/directory-1-info and /path/to/output/directory-2-info","Open a terminal, go to the ../utils and run command:","Content of text-file"]},{"i":"usage-with--enableswagger-flag","l":"Usage with '-enableSwagger' flag","p":["In this example a path to a text-file with defined names of source directories is used. A flag to print outputs to files and a flag to enable swagger for OpenAPI files generation. The swagger configuration file is located at ../utils/config/swagger-config.json. Swagger output file / files are generated per directory, and they are located in the output directory. The user can find output information files on paths /path/to/output/directory-1-info and /path/to/output/directory-2-info.","Open a terminal, go to the ../utils directory. Run the command:","Additional parameters are available for swagger generation that further customise the OpenAPI file / files. These parameters are located at the beginning of the page.","The output then looks like this:"]},{"i":"error---source-directory-does-not-exist","l":"Error - source directory does not exist","p":["User-defined source directory does not exist.","Open a terminal, go to the ../utils directory and run command:"]},{"i":"error---source-directory-is-empty","l":"Error - source directory is empty","p":["User-defined source directory is empty. Open a terminal, go to the ../utils directory and run command:"]},{"i":"error---sources-defined-in-text-file","l":"Error - sources defined in text-file","p":["One directory defined in the text-file is empty and other one does not exist.","Open a terminal, go to the ../utils and run command:","Content of text-file"]}],[{"l":"Admin State","p":["Admin state is used to lock, unlock or southbound-lock devices. Modification of data on those devices is allowed or forbidden accordingly.","Three different states are currently supported:","LOCKED - When a device is administratively locked, it is not possible to modify its configuration and no changes are ever pushed to the device.","UNLOCKED - The device is assumed to be operational. For all changes, an attempt is made to send them southbound. This is the default state for newly created devices.","SOUTHBOUND_LOCKED - It is possible to configure the device, but no changes are sent to the device. Useful when pre-provisioning devices.","The admin state is automatically added to the device during installation. You can specify an admin state for a device as follows:","uniconfig-config:admin-state: unlocked","An RPC is available for changing admin state after installation."]},{"l":"RPC example","p":["RPC input contains the device name and intended admin state."]},{"i":"rpc-example-1","l":"RPC example","p":["GET request to get the actual state of the device."]},{"l":"RPC failed example","p":["The device is in the locked admin state, and the user attempts to modify data on the device."]}],[{"l":"Build-and-Commit Model","p":["The Build-and-Commit model is based on explicitly creating a transaction, invoking operations in the scope of this transaction and, finally, committing or closing the transaction. The transaction represents a session between client and UniConfig instance.","Using explicitly created transactions has multiple advantages in comparison to the Immediate Commit Model:","Multiple operations and modifications can be invoked in a single transaction while keeping transactions isolated.","Most UniConfig operations, such as calculate-diff and commit, have no use in the Immediate Commit Model. They are valuable only if the Build-and-Commit Model is used.","The transaction allows a client to identify if it still communicates with the same UniConfig instance (this property is usable in the clustered deployment). If the UniConfig instance does not know about the transaction, the request fails because the transaction expired, is closed or was never created in the first place."]},{"l":"Configuration","p":["Configurations related to UniConfig transactions are placed in the config/application.properties file under the transactions container."]},{"l":"Optimistic locking mechanism","p":["Race conditions between transactions that are committed in parallel and contain changes to the same nodes (uniconfig, unistore, snapshot or template nodes) are solved using the optimistic locking mechanism. The configuration of a node can be modified in parallel from two transactions, but only the first committed transaction will succeed. The commit for the second transaction will fail.","UniConfig uses two different techniques to detect conflicts during commit or checked-commit operations:","Comparing configuration fingerprints- The fingerprint value for an altered node is updated at the end of the commit operation. At the beginning of a commit operation, UniConfig compares the value of the actual fingerprint in the database with the value of the fingerprint read before the first CRUD operation done in the transaction and the last synced fingerprint (updated after execution of the sync-from-network RPC). If the actual fingerprint in the database is equal to the fingerprint read before the first CRUD operation or the last synced fingerprint, the commit operation can continue. Otherwise, an error is returned without touching any devices in the network.","Per-node advisory locks- Comparison of configuration fingerprints is reliable if transactions are committed one after another. However, such serialization cannot be achieved in the clustered environment as UniConfig instances are not coordinated. If two transactions are committed at the same time and both assume that configuration fingerprints haven't been updated by another transaction, both transactions may start to push changes to network devices simultaneously. To prevent this scenario, UniConfig locks the node in the PostgresSQL database using transaction-level advisory locks at the beginning of the commit operation. If another transaction tries to lock the same node, its attempt will fail, and the second transaction cannot enter the critical section but will fail. Locks are automatically released at the end of the transaction( commit RPC closes the transaction).","All possible scenarios are captured in the following diagrams.","Optimistic locking"]},{"l":"Dynamic mountpoints","p":["Mountpoints are created only when UniConfig needs to read / write some data from / to device and lifecycle of mountpoint is bounded by lifecycles of transactions that use the mountpoint. If some mountpoint is not used by any transaction, then UniConfig automatically closes this mountpoint - associated operational data on southbound layer and connection to device are removed.","The first diagram demonstrates mounting of 2 devices which are used by 1 transaction - after this transaction is closed, both mountpoints are closed. The second diagram shows scenario in which 2 transactions share 1 of 2 mountpoints - after the first transaction is closed, 1 of the mountpoints is not closed since the second transaction still may communicate with corresponding device."]},{"l":"Creation of transaction","p":["Transaction can be created using create-transaction RPC. RPC doesn't specify input body and also returns response without body. Response additionally contains Set-Cookie header with UNICONFIGTXID key and corresponding value - transaction identifier that conforms RFC-4122 Universally Unique IDentifier (UUID) format.","Process of transaction creation is depicted by following sequence diagram.","create-transaction RPC","UniConfig is performing following steps after calling create-transaction RPC:","Creation of connection to database system - Connection is created with disabled auto-commit - enabling transactional features. UniConfig uses 'read committed' isolation level.","Creation of database transaction - It provides access to remote PostgreSQL database. Using database transaction it is possible to read committed data, read uncommitted changes created by this transaction and write modifications to database. Data read at the first access to some resource is cached to datastore transaction - when some component tries to access the same resource again, it is read only from datastore transaction. Data is written to database transaction at invocation of commit/checked-commit RPC.","Creation of datastore read-write transaction - It provides access to OPER and CONFIG datastores bound to this transaction. Datastore is used only as a cache between application and PostgreSQL database, and it resides only in the memory allocated to UniConfig process. Datastore transaction is never committed - cache is trashed at the end of the transaction life.","Registration of transaction - Transaction is always bound to 1 specific UniConfig instance."]},{"l":"Successful example","p":["The following request shows successful creation of UniConfig transaction. Response contains Set-Cookie header with UNICONFIGTXID key and value."]},{"l":"Failed example","p":["The most common reason for failed creation of UniConfig transaction is reached maximum number of open transactions that is limited by('maxDbPoolSize' - 'maxInternalDbConnections') database connection pool setting. In that case, UniConfig returns response with 500 status code."]},{"l":"Transaction idle-timeout","p":["Create-transaction RPC can be used with optional query parameter called timeout. This parameter is used to override global idle timeout for transaction created by this RPC call. After transaction inactivity for specified time transaction will be automatically cleaned. Value of this parameter is whole number and defines time in seconds."]},{"l":"Dedicated session to device","p":["By default, UniConfig shares a southbound session to a network device if multiple UniConfig transactions use the same device via the same management protocol. This behaviour can be disabled using the dedicatedDeviceSession query parameter, which accepts a boolean value. Afterwards the UniConfig transaction will create a dedicated session to the device, which is used only by one transaction and is closed immediately after committing or closing the transaction.","Dedicated sessions to a device are useful when:","The evice is not able to process requests in parallel via the same session.","The device is able to process requests in parallel via same session, but does not process them in parallel, decreasing processing performance."]},{"l":"Audit parameters","p":["Uniconfig can pass audit parameters to network devices when a Uniconfig transaction is committed.","Following implementations are currently supported on southbound:","Tailf confD extension (NETCONF)","On the northbound, the parameters are exposed as HTTP headers:","AUDIT_USER","AUDIT_COMMENT"]},{"l":"Invocation of CRUD operation in transaction","p":["CRUD operations for modification or reading node configuration can be invoked in the specific transaction by appending UNICONFIGTXID (key) with UUID of transaction (value) to Cookie headers. In that case, operation will be invoked only in the scope of single transaction - changes are not visible to other transactions until this transaction is successfully committed.","Next diagram describes execution of CRUD operation from RESTCONF API. It shows also difference between datastore and database transaction - data is read from database only at the first access to some data (for example, node configuration). After that, this configuration is cached inside temporary datastore transaction - goal is to improve performance by limiting transferring data between UniConfig and PostgreSQL. Next access to same configuration can be evaluated under in-memory datastore.","Invocation of CRUD"]},{"i":"successful-example-1","l":"Successful example","p":["The following request demonstrates reading of some configuration from uniconfig topology, junos node in the transaction with ID'd7ff736e-8efa-4cc5-9d27-b7f560a76ff3'."]},{"i":"failed-example-1","l":"Failed example","p":["Trying to use non-existing UniConfig transaction results in 422 status code (Unprocessable Entity)."]},{"l":"Invocation of RPC operation in transaction","p":["RPC operation can be invoked in the specific transaction the same way as CRUD operation - by specification of UNICONFIGTXID in the Cookie header.","There are few differences between CRUD and RPC operations from the view of transactions:","Commit, checked-commit, and close-transaction RPCs can state of the transaction. Create-transaction RPC is reserved for creation of transaction.","Not all RPC operations that are exposed by UniConfig use dedicated transactions - in that case, these RPCs just ignore explicitly specified transaction and either don't work with transactions at all or create transaction internally (examples: install-node, uninstall-node RPC).","There are also transaction-aware operations that directly leverage properties of transactions. For example, if some UniConfig RPC is invoked with empty list of target nodes, then operation is automatically applied to all modified nodes in the transaction(calculate-diff RPC with empty target nodes computes diff for all modified nodes in the transaction).","Following diagram shows execution of random RPC in the specified transaction.","Invocation of RPC"]},{"i":"successful-example-2","l":"Successful example","p":["Invocation of calculate-diff RPC in the transaction which contains modifications done on the 'junos' node."]},{"i":"failed-example-2","l":"Failed example","p":["Invocation of calculate-diff RPC with transaction ID that has wrong format."]},{"l":"Closing transaction","p":["There are 2 options how transaction can be closed:","close-transaction RPC - Explicit closing of transaction that results in dropping of all changes done in the transaction.","commit/checked-commit RPC - After execution of commit operation, transaction is automatically closed (despite of commit result). Behaviour of commit and checked commit RPC is described in better detail under the 'UniConfig Node Manager' section.","Close-transaction RPC doesn't contain body, only Cookie header with UNICONFIGTXID property pointing to transaction that user would like to close. Response contains information if transaction has been successfully closed.","Following sequence diagrams describe close-transaction procedure. It is split into 2 diagrams to improve readability and to reuse some parts from other diagrams.","close-transaction RPC","Clean orphaned mountpoints","Briefly depicted most important actions:","Loading UniConfig transaction from registry by provided transaction ID that is extracted from Cookie header.","Closing connection to database.","Cancellation of database transaction.","Cancellation of datastore read-write transaction.","Unregistration of transaction from local registry.","Unmounting nodes that are not referenced by any UniConfig transaction - connection to device is closed and representing southbound / Unified mountpoints are removed together with state data.","After transaction is closed, it cannot be used by any other operation - user must create a new transaction in order to use build-and-commit model."]},{"i":"successful-example-3","l":"Successful example","p":["Closing existing transaction using close-transaction RPC. Response doesn't body, only status code 200."]},{"i":"failed-example-3","l":"Failed example","p":["If transaction has already been closed, user will receive response with JSON body containing error message."]},{"l":"Transaction cleaner","p":["Transaction cleaner is used for automatic closing of transactions that are open longer then specified timeout value ('transactionIdleTimeOut' or 'maxTransactionAge' setting in the configuration). Transaction resets her time setting 'transactionIdleTimeOut' after invoking CRUD, RPC operation, and is still valid for time specified in value of setting. This mechanism effectively suppresses application-level errors - open transactions are not closed at the end of the workflow.","Next sequence diagram describes cleaning process. Referenced diagram'Close transaction' is placed in the previous 'Closing transaction' section."]},{"l":"Use cases"},{"l":"Modification of different devices in separate transactions","p":["1. Installation of 2 devices - ‘xr6_1’ and ‘xr6_2’ (without transaction ID)","2. Creation of 2 uniconfig transactions: let’s name them TX1 and TX2","3. Modification of ‘xr6_1’ uniconfig configuration inside TX1","4. Modification of ‘xr6_2’ uniconfig configuration inside TX2","5. Verification if TX1 and TX2 are isolated","6. Committing TX1 and TX2 using uniconfig-manager:commit RPC","7. Verification of committed data","8. Verification if TX1 and TX2 are closed","All 3 responses - Status 200 OK with returned expected data. Similar verification can be done on 'xr6_2'.","Both responses should return Status 404 Not Found:","Creation of new Loopback79 interface - cookie header contains UNICONFIGTXID of TX2:","Creation of new Loopback97 interface in the TX1 - cookie header contains UNICONFIGTXID of TX1:","It is not required to specify target nodes in the input because UniConfig transaction tracks modified nodes:","Response - Status 422 Unprocessable Entity:","Response:","Since there aren't any conflicts between modifications in the committed transactions, both RPCs should succeed. Expected responses:","The first response contains transaction-id of TX1 that can be used in the subsequent requests that belong to TX1:","The first second contains transaction-id of TX2 that can be used in the subsequent requests that belong to TX2:","Trying to read some data in the TX1:","Trying to read some data in the TX2:","TX1 doesn't see modifications done in TX2 and vice-versa:","Verification if configuration was correctly committed to devices (direct read under yang-ext:mount) and if datastore was updated (GET request without transaction ID):","Verification if TX1 contains created interface (Cookie header contains UNICONFIGTXID of TX1):","Verification if TX2 contains created interface (Cookie header contains UNICONFIGTXID of TX2):"]},{"l":"Modification of sub-tree on same device in separate transactions","p":["1. Installation of device ‘xr6_1’","2. Preparation of configuration on 'xr6_1'","3. Creation of 2 uniconfig transactions: let’s name them TX1 and TX2","4. Modification of ‘xr6_1’ uniconfig configuration inside TX1","5. Modification of ‘xr6_1’ uniconfig configuration inside TX2","6. Commit TX1","7. Commit TX2","8. Verification of committed data in TX1 / non-committed data in TX2","9. Verification if TX1 and TX2 are closed","Changing description of interface Loopback97 to 'next loopback': - there is a conflict with TX1 which also tries to create/replace the configuration of the same interface:","Changing description of interface Loopback97 to 'test loopback':","Commit TX1 without target nodes - it should fail because the same node has already been modified by different transaction that has already been committed:","Commit TX2 without target nodes - it should pass:","Creation of Loopback97 interface with some initial description:","Creation of the uniconfig transaction TX1:","Creation of the uniconfig transaction TX2:","Respective responses:","Response - Status 500 with error message:","Response:","Trying to read some data in the transaction:","Verification if committed changes in TX1 were applied to datastore and device:"]}],[{"l":"Device discovery","p":["/opt/uniconfig-frinx/config/application.properties","~/FRINX-machine/config/uniconfig/frinx/uniconfig/config/application.properties","addressCheckLimit- Maximum number of addresses checked. If a request contains more addresses, it will not be successful.","Execute the ifconfig command in the terminal and look for an interface. If you are using a VPN, the interface is often called tun0. If not, look for a different interface. From the interface, copy the inet address and paste it into the file.","For testing, you need to add your IP address to the configuration JSON file. The configuration file is located at:","If you specify the range using a network statement, the network address and broadcast address are not included in the discovery process. If you specify the range via range statements, make sure that only hosts addresses are included in the specified range.","initial-pool-size- Thread pool used by the executor.","keepalive-time- Time before the execution of a specified task is timed out (in seconds).","max-pool-size- Size of the executor. If the request contains a large number of addresses, consider raising the value.","network: 192.168.1.0/24","RPC input consists of a list of all IP addresses to check (IPv4 or IPv6, a single IP address or a network with a prefix, or a range of IP addresses). Additionally, it contains the TCP/UDP ports that should be checked if they are open or not on the given addresses.","RPC output shows if the IP addresses are reachable via the ICMP protocol. For every IP address, a list of open TCP/UPD ports is also included.","start-ipv4-address: 192.168.1.1, end-ipv4-address: 192.168.1.254","The device-discovery RPC is used to verify reachable devices in a network. You can either check a single IP address in IPv4 format, a network or a range of addresses. Additionally, you can specify a port or range of ports (TCP or UDP) that are checked if they are open. The ICMP protocol is used to check the availability of devices.","The previous snippet contains the following additional parameters:","To discover hosts and ports in listening state in a network, do not add the network and broadcast address of that network. For example, to check the network 192.168.1.0/24, use one of the following:","When running UniConfig stand-alone, the config file is in the config folder:"]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains a network with the /29 prefix. Addresses in the network and desired ports are checked for availability.","RPC output contains reachable addresses in the network and all open TCP/UDP ports."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input contains a range of addresses. Addresses and desired ports are checked for availability.","RPC output contains reachable addresses and all open TCP/UDP ports."]},{"i":"successful-example-2","l":"Successful example","p":["RPC input contains the host name and ports to be checked for availability.","RPC output shows if the host is reachable and all open TCP/UDP ports."]},{"l":"Failed example","p":["RPC input contains two addresses that are incorrectly wrapped."]},{"i":"failed-example-1","l":"Failed example","p":["RPC input contains an IP range where the starting point is greater than the end point."]},{"i":"unsupported-operation---example","l":"Unsupported operation - example","p":["RPC input contains a network in IPv6 format that is currently not supported."]}],[{"l":"Dry-run manager"},{"l":"RPC dryrun-commit","p":["This RPC resolves the diff between the actual and intended configurationz of nodes by using the UniConfig Node Manager.","Changes to CLI nodes are applied using the cli-dryrun mountpoint, which only stores translated CLI commands to the cli-dry-run journal. After all changes are applied, the cli-dryrun journal is read and an RPC output is created and returned. This works similarly with NETCONF devices, but produces NETCONF messages as output instead of CLI commands.","RPC input contains a list of UniConfig nodes for which to execute the dry run.","RPC output describes the results of the operation and matches all input nodes. It also contains a list of commands and NETCONF messages for the given nodes.","If the RPC is called with an empty list of target nodes, the dryrun operation is executed on all modified nodes in the UniConfig transaction. If a node fails for any reason, the entire RPC fails.","RPC dryrun commit"]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input does not contain the target node. RPC output contains a list of commands that would be sent to the device if the RPC commit or checked-commit was called."]},{"i":"successful-example-1","l":"Successful example","p":["RPC input does not contain any target nodes. Dryrun is executed with all modified nodes."]},{"i":"successful-example-2","l":"Successful example","p":["If there are no touched nodes, the request finishes successfully."]},{"l":"Failed example","p":["Node R1 has failed due to incorrect configuration."]},{"i":"failed-example-1","l":"Failed example","p":["Node R1 has failed because it does not support dry-run functionality."]},{"i":"failed-example-2","l":"Failed example","p":["Node R1 has lost connection."]}],[{"l":"Immediate Commit Model","p":["The immediate commit creates new transactions for every call of an RPC. The transaction is then closed so that no lingering data remains.","The sequential diagram below illustrates how the process works for reading data(GET request).","Get Request","Similarly, the following diagram illustrates the process for putting data (PUT request).","Put Request","The key difference in the two diagrams is that editing data (PUT, PATCH, DELETE, POST) and RPC calls in the database must be committed, hence there is an additional call of the commit RPC. This commit ensures that the transaction is closed. For reading data, it is necessary to close the transaction in a different manner, because no data was changed and calling a commit is not necessary.","When calling the sync-from-network RPC, it internally calls the replace-config-with-operational RPC. Note that this only works when using the Immediate Commit Model."]},{"l":"Configuration","p":["Configurations related to UniConfig transactions are placed in the config/application.properties file. You can also turn off the Immediate Commit Model and use the Build and Commit Model instead."]},{"l":"RPC examples"},{"l":"Successful example","p":["RPC input contains a new interface that is added to the existing ones.","After putting the data into the database, they are automatically committed and can be viewed."]},{"l":"Failed example","p":["RPC input contains a value that is not supported."]}],[{"l":"Kafka Notifications","p":["NETCONF and gNMI devices produce notifications, which UniConfig can collect to create its own UniConfig notifications about specific events. Notifications from both NETCONF and gNMI devices and UniConfig are published using Kafka.","The following notification types are available:","NETCONF notifications","gNMI notifications","Notifications about transactions","Audit logs (RESTCONF notifications)","Data change events","Connection notifications","Each notification type is stored in its own topic in Kafka. Additionally, all notifications are stored in one table in the database.","notifications-in-cluster"]},{"l":"Kafka","p":["Apache Kafka is a publish–subscribe-based, durable messaging system that sends messages between processes, applications and servers. Within Kafka, you can define topics (categories) and applications can add, process and reprocess records.","In our particular case, UniConfig publishes notifications. Each type of notification is stored in a separate topic and can therefore be subscribed to independently. The names of topics and connection data are configurable in the application.properties file."]},{"l":"NETCONF notifications","p":["RFC 5277 defines a mechanism where a NETCONF client indicates an interest in receiving event notifications from a NETCONF server by subscribing to event notifications. The NETCONF server sends a reply about whether the subscription request was successful and, if so, starts sending event notifications to the NETCONF client as events occur within the system. Event notifications are sent until either the NETCONF session or the subscription is terminated.","NETCONF notifications are categorized as so-called streams. The subscriber can choose which streams to receive. The default stream is NETCONF."]},{"l":"gNMI notifications","p":["The gNMI specification defines a mechanism where the gNMI client indicates an interest in receiving updates about the state of data instances via a subscribe RPC. If the subscription is successfully created, the gNMI server replies with the state of data instances according to specified paths.","The session remains open until it UniConfig closes it (releasing the subscription) or an error occurs on the device side. However, UniConfig will try to recreate the session.","The following fields are mandatory for the install-node request:","stream-name","paths"]},{"l":"Notifications about transactions","p":["This type of notification is generated after each commit in UniConfig.","It contains the following:","transaction id","calculate diff result","commit result"]},{"i":"audit-logs-restconf-notifications","l":"Audit logs (RESTCONF notifications)","p":["Below are three examples of notifications with the response body and the calculation difference result.","body","comment","Example 1- Created data","Example 2- Deleted data","Example 3- Updated data","http method","It contains the following:","label","query parameters","request data","response data","source address","source port","status code","The response body can be included or excluded from notifications with the includeResponseBody parameter in the application.properties file. Similarly, the calculation difference result is included if the parameter includeCalculateDiffResult parameter is set to true in application.properties.","This type of notification is generated after each RESTCONF operation.","transaction id","uri","user id"]},{"l":"Shell notifications","p":["This type of notification is generated after each shell operation. It contains the following:","transaction id","request data","source address","source port","prompt","executed command","response data","output"]},{"l":"Data change events","p":["A subscription step is required before data change events are generated and published into Kafka.","With the subscription, a user can specify which subtrees are observed for data changes. Afterwards, data change events are generated by UniConfig instances when a transaction is committed and the committed changes contain subscribed subtrees.","A sample data change event captured by Kafka console consumer:","For data change events, streamName is always DCE and the identifier for the YANG notification is data-change-event.","The body contains the following:","subscription-id- Identifier for the subscription that triggers the generation of a data change event. The subscription identifier makes it easier to associate subscriptions and received data change events compared to using a combination of multiple fields such as node identifier, topology identifier and subtree path.","transaction-id- Identifier for the committed transaction that triggered the data change event after commit or checked-commit UniConfig operations.","edit- List of captured modifications done in the committed transaction.","Fields under edit:","subtree-path- Relative path to the data-tree element where the data change occurred. The path is relative to the subtree path specified during subscription.","data-before- JSON representation of subtree data before changes were made. If this field is not specified, data-after represents created data.","data-after- JSON representation of subtree data including the changes. If this field is not specified, data-before represents removed data.","operation- Operation type for the data change event.","node-id- Node identifier for the data change event.","topology-id- Topology identifier for the node. Either uniconfig or unistore."]},{"l":"Connection notifications","p":["Connection notification are generated whenever the status of a node changes. For connection notifications, streamName is always CONNECTION and the identifier for the YANG notification is connection-notification.","Contains the following:","topology id","node id","connection status","connection message","Supported topologies are cli, netconf and gnmi.","Sample connection notifications captured by Kafka console consumer:","CLI disconnect notification:","NETCONF connect notification:","gNMI connect notification:"]},{"l":"Database entities","p":["body - Full notification body in JSON format","creation time - Time when the subscription was created","end time - End time for collecting notifications","event time - Time when the notification was generated","Example- Request for reading Kafka settings using RESTCONF:","Example- Request for reading notifications using RESTCONF:","Example- Request for reading subscriptions using RESTCONF:","identifier - Name of the YANG notification for NETCONF or path to the received config top node for gNMI","node id - Identifier for the NETCONF/gNMI device or, for other types of notifications, the UniConfig instance","node id - Identifier for the NETCONF/gNMI node where notifications are collected","notification table","settings table","start time - Start time for collecting notifications","stream name - Name of the notification stream","stream name - NETCONF/gNMI stream name","subscription table","The following three tables in the database are related to notifications:","The notification table is where notifications are stored. It contains the following columns:","The settings table contains two columns: identifier and config. Records with the kafka identifier contain configurations for Kafka that can be modified at runtime.","The subscription table is used to track NETCONF and gNMI notification subscriptions. It contains the following columns:","UniConfig instance id - Identifier for the UniConfig instance that collects notifications from the NETCONF/gNMI device"]},{"l":"NETCONF subscriptions","p":["A subscription is required to receive NETCONF notifications from a NETCONF device.","Subscriptions are created with an installation request:","Subscriptions to notification streams are defined as a list with the name stream. There is one record for each stream.","The only mandatory parameter is stream-name. Other parameters are optional:","start-time- Must be specified to enable replay and should start at the specified time.","stop-time- Used with the optional replay feature to indicate the newest notifications of interest. If no stop time is specified, notifications will continue until the subscription is terminated. Must be used with and set to be later than start-time. Values in the future are valid.","If a new subscription to a stream is created, all existing subscriptions to the stream are terminated."]},{"l":"gNMI subscriptions","p":["A subscription is required to receive gNMI notifications from a gNMI device.","Subscriptions are created with an installation request:","Subscriptions to notification streams are defined as a list with the name stream. There is one record for each stream.","There are two required parameters, stream-name and paths. Other parameters are optional:","start-time- Start time for telemetry streaming.","stop-time- Telemetry streaming stops if the timestamp of the notification is later than this time. If no stop time is specified, notifications will continue until the subscription is terminated. Must be used with and set to be later than start-time. Values in the future are valid."]},{"i":"monitoring-system---processing-netconfgnmi-subscriptions","l":"Monitoring system - processing NETCONF/gNMI subscriptions","p":["In UniConfig, subscriptions to NETCONF and gNMI notifications are processed in an infinite loop within the monitoring system.","An iteration of the monitoring system loop consists of following steps:","Check global setting for NETCONF/gNMI notifications.","If turned off, release all NETCONF/gNMI subscriptions and end current iteration.","Release cancelled subscriptions.","Query free subscriptions from DB, and for each one:","Create a notification session (create mountpoint and register listeners).","Lock the subscription (set UniConfig instance).","There is a hard limit on the number of sessions that a single UniConfig node can handle. If the limit is reached, the UniConfig node refuses any additional subscriptions.","The loop interval, hard subscription limit and maximum number of subscriptions processed per interval can be set in the application.properties file."]},{"l":"Dedicated NETCONF session for subscription","p":["A NETCONF device may have the interleave capability that indicates support for interleaving other NETCONF operations within a notification subscription. This means that the NETCONF server can receive, process and respond to NETCONF requests on a session with an active notification subscription.","As not all devices include support for this capability, the common approach for devices with and without interleave capability is to track notifications with a separate NETCONF session. To support this functionality, UniConfig creates a separate NETCONF session with a separate mountpoint for every subscription. These mountpoints and sessions are automatically terminated when the corresponding subscription is closed.","monitoring-system"]},{"l":"Subscriptions to data change events"},{"l":"Create a new subscription","p":["BASE: Represents only a direct change of the node on the subtree-path, such as replacement of a node, addition or deletion.","data-change-scope- Data-tree scope that specifies how granular data change events should be captured and propagated to Kafka. There are three options:","Delete an existing subscription","Display information about a created subscription using the RPC","Example- Create a duplicate subscription to the device1 node in the uniconfig topology, and to the whole /interfaces configuration subtree:","Example- Create a subscription to the device1 node in the uniconfig topology, and to the whole /interfaces configuration subtree:","Example- Create a subscription to the uniconfig topology and to the whole/interfaces configuration subtree:","node-id- Identifier for the node from which data change events are generated. If not specified, a global subscription is created and data change events are generated for all nodes under the topology. This field is optional.","ONE: Represent a change (an addition, replacement or deletion) of the node on the subtree-path or one of its direct child elements.","RPC input contains the following:","RPC output contains only the generated subscription identifier in UUID format. This identifier represents a token that can be used for the following:","Sort received Kafka messages","Subscriptions to data change events are created using the create-data-change-subscription RPC. After a subscription is created, UniConfig listens to data change events on selected nodes and subtrees and distributes the corresponding messages to a dedicated Kafka topic.","subtree-path- Path to the subtree from which the user would like to receive data change events. The default value is /, which captures data change events from the entire node configuration.","SUBTREE: Represents a change of the node or any of its child nodes, direct and nested. This scope is a superset of ONE and BASE. This is the default value.","topology-id- Identifier for the topology where the specified node is placed."]},{"l":"Remove a subscription","p":["Existing subscriptions can be removed using the delete-data-change-subscription RPC and the provided subscription-id. After a subscription is removed, UniConfig stops generating new data change events related to the subscribed path.","RPC input contains only the subscription-id, which is a unique identifier for the subscription to data change events.","RPC output does not contain a body. The RPC returns a 404 error if no subscription exists for the provided identifier.","Example- Remove a subscription:","Successful example:","Failed example:"]},{"l":"Show information about a subscription","p":["The show-subscription-data RPC is used to display information about a created subscription.","RPC input contains an identifier for the target subscription.","RPC output for existing subscriptions contains the following:","topology-id","node-id","subtree-path","data-change-scope","These are the same fields that can be specified as input for the create-data-change-subscription RPC.","If no subscription exists with the specified ID, the RPC returns a 404 status code with a standard RESTCONF error container.","Successful example:","Failed example:","It is also possible to fetch all created subscriptions under a specific node or topology by sending a GET request to the data-change-subscriptions list under the node list item (operational data).","Example- Two subscriptions under the device1 node"]},{"l":"Configuration","p":["All notifications, as well as the monitoring system, can be enabled or disabled using the enabled flag.","All settings related to Kafka are grouped under kafka property. For authentication, there are the username and password properties. For the Kafka connection, there is the kafka-servers property which contains a list of Kafka servers as a combination of broker-host and broker-listening-port. The broker host can be either an IP address or hostname.","archive-url- Where to download Kafka from","Audit log settings are under the audit-logs property. Currently there is only one flag, include-response-body, which is used to enable or disable logging the body of RESTCONF responses.","audit-logs-enabled","audit-logs-topic-name- Topic name for audit logs","blocking-timeout- How long the send() method and the creation of a connection for reading metadata methods will block (in milliseconds).","clean-data-before-start- Whether or not to clear Kafka config before start","Configurations for notifications are in the application.properties file, under the notifications property.","Configure the names of all topics for every notification type by using the following flags:","data-change-events-enabled","data-change-events-topic-name- Topic name for data change events","data-dir- Kafka data directory","delivery-timeout- Upper bound on the time to report success or failure after a call to send() returns (in milliseconds). Sets a limit on the total time that a record will be delayed prior to sending, the time to wait for acknowledgement from the broker (if expected) and the time allowed for retriable send failures.","Enable or disable each type of notification independently of others by using the following flags:","enabled- Enable or disable embedded Kafka","install-dir- Where Kafka files should be placed","Kafka settings are also stored in the database. This way they can be changed at runtime using RESTCONF or UniConfig shell. Kafka setting are stored in the settings table.","max-age- Maximum age of a record in the notifications table (in hours). Records older than this value are deleted. The default value is 100.","max-count- Maximum number of records in the notifications table. If the number of records exceeds this value, the oldest record in the table is deleted. The default value is 10,000.","max-netconf-subscriptions-hard-limit- Maximum number of subscriptions that a single UniConfig node can handle.","max-subscriptions-per-interval- The maximum number of free subscriptions that can be acquired in a single iteration of the monitoring system loop. If the number of free subscriptions is smaller than this value, all free subscriptions are processed. If the number of free subscriptions is larger than this value, only the specified number of subscriptions are acquired. The rest can be acquired during the next iterations of the monitoring system loop or by other UniConfing instances in the cluster. The default value is 10.","max-thread-pool-size- Maximum thread pool size in the executor.","netconf-notifications-enabled","netconf-notifications-topic-name- Topic name for NETCONF notifications","optimal-subscriptions-approaching-margin- Lower margin to calculate optimal range start. The default value is 0.05.","optimal-subscriptions-reached-margin- Upper margin to calculate optimal range end. The default value is 0.10.","Properties related to message timeout to Kafka:","Properties related to the monitoring system in clustered environments:","Properties related to the monitoring system:","Properties related to the thread pool executor required to send messages to Kafka:","Properties used to limit the number of records in the notifications table in the database:","queue-capacity- Maximum capacity for the work queue in the executor.","rebalance-on-UC-node-going-down-grace-period- Grace period for a UniConfig node going down (in seconds). Other nodes will not restart subscriptions until the grace period has passed after a dead Uniconfig node was last seen. The default value is 120.","request-timeout- How long the producer waits for acknowledgement of a request (in milliseconds). If no acknowledgement is received before the timeout period has passed, the producer resends the request or, if retries are exhausted, fails the request.","subscriptions-monitoring-interval- How often the monitoring system loop is run and how often it attempts to acquire free subscriptions (in seconds). The default value is 5.","The entire configuration looks like this:","These properties are under notification-db-treshold. Both are implemented using database triggers. Triggers are running on inserts to the notifications table.","transaction-notifications-enabled","transactions-topic-name- Topic name for transactions about notifications","You can also to set up embedded Kafka using these setting grouped under the embeddedKafka property:"]},{"i":"kafka-client---example","l":"Kafka client - Example","p":["To read notifications from Kafka, you can use the command line consumer.","Run the following command in the Kafka installation directory:","It is important to properly set up the hostname, port and topic name.","Output after a NETCONF notification is created:"]}],[{"l":"Operational data about transactions"},{"l":"Operational data about transactions","p":["To have a better overview of UniConfig transactions, there are operational data about all open transactions.","Data about transactions contain:","identifier (uuid)","creation time","last access time","idle timeout","hard timeout","list of changed nodes (incl. topologies)","additional context (random string, text column)","Data about transactions can be read using RESTCONF:","Example data about transactions:"]}],[{"i":"uniconfig---sending-and-receiving-data-restconf","l":"UniConfig - Sending and receiving data (RESTCONF)","p":["The RESTCONF protocol is described in RFC 8040. Put simply, RESTCONF represents a REST API for accessing datastores and UniConfig operations."]},{"l":"Datastores","p":["There are two datastores:","Config: Contains data representing the intended state. Possible to read and write via RESTCONF.","Operational: Contains data representing the actual state. Possible only to read via RESTCONF.","Each request must start with the URI /rests/. By default, RESTCONF listens on port 8181 for HTTP requests."]},{"l":"REST Operations","p":["RESTCONF supports: OPTIONS, GET, PUT, POST, PATCH, and DELETE operations. Request and response data can be either in the XML or JSON format.","XML structures according to YANG are defined at: XML-YANG.","JSON structures are defined at: JSON-YANG.","Data in the request must set the Content-Type field correctly in the HTTP header with the allowed value of the media type. The media type of the requested data must be set in the Accept field. Get the media types for each resource by calling the OPTIONS operation.","Most of the paths use Instance Identifier. is used in the explanation of the operations and must adhere to these rules:","Identifier must start with :> where is a name of the YANG module and is the name of a node in the module. If the next node name is placed in the same namespace as the previous one, it is sufficient to just use after the first definition of:. Each has to be separated by /."," can represent a data node which is a list node, container, leaf, or leaf-list YANG built-in type. If the data node is a list, there must be defined ordered keys of the list behind the data node name, for example, =,. ..","The following example shows how reserved characters are percent-encoded within a key value. The value of \"key1\" contains a comma, single-quote, double-quote, colon, double-quote, space, and forward slash (,'\":\" /). Note that double-quote is not a reserved character and does not need to be percent-encoded. The value of \"key2\" is the empty string, and the value of \"key3\" is the string \"foo\".","Example URL: /rests/data/example-top:top/list1=%2C%27\"%3A\"%20%2F,,foo","The format : has to be used in this case as well. Module A has node A1. Module B augments node A1 by adding node X. Module C augments node A1 by adding node X. For clarity, it has to be known which node is X (for example: C:X)."]},{"l":"Mount point","p":["The purpose of yang-ext:mount container is to access southbound mountpoint, when the node is already installed in Uniconfig (After install-node RPC). It exposes operations for reading device data which can only be done under connection-specific topology (cli/netconf) with defined node-id in URI. In this case, the URI has to be in the format/ yang-ext:mount/. The first is the path to a mount point and the second is the path to subtree behind the mount point. An URI can end in a mount point itself by using /yang-ext:mount. In this case, if there is no content parameter, whole operational and configuration data will be read.","Examples of retrieving data behind yang-ext:mount","In this request, we are using parameter content=config, this means we are reading candidate NETCONF datastore. Value config of parameter content is translated into get-config NETCONF RPC.","In this request we are using parameter content=nonconfig, which means that we are reading running NETCONF datastore. Value nonconfig is translated into get NETCONF RPC. We can compare it with data directly from device using show running-config command.","Examples of invocation of yang actions behind yang-ext:mount.","Invocation of yang action -> List available firmware packages on disk","Invocation of yang action -> Erase running-config-then load","To completely understand installing of node see Device installation."]},{"l":"HTTP methods"},{"i":"options-rests","l":"OPTIONS /rests","p":["Returns the XML description of the resources with the required request and response media types in Web Application Description Language (WADL)."]},{"i":"get-restsdataidentifiercontentconfig","l":"GET /rests/data/?content=config","p":["Returns a data node from the Config datastore."," points to a data node that must be retrieved.","Value 'config' represents default value of content query parameter - it doesn't have to be specified, if user would like to read intended/uncommitted changes from Config datastore.","Request GET '/rests/data/' would return the same data."]},{"i":"get-restsdataidentifiercontentnonconfig","l":"GET /rests/data/?content=nonconfig","p":["Returns the value of the data node from the Operational datastore."," points to a data node that must be retrieved."]},{"i":"get-restsdataidentifiercontentall","l":"GET /rests/data/?content=all","p":["Returns a data node from both Config and Operational datastores. The outputs from both datastores are merged into one output."," points to a data node that must be retrieved."]},{"i":"put-restsdataidentifier","l":"PUT /rests/data/","p":["Updates or creates data in the Config datastore and returns the state about success."," points to a data node that must be stored.","Content type does not have to be specified in URI - it can only be the Configuration datastore."]},{"i":"post-restsdataidentifier","l":"POST /rests/data/","p":["Creates the data if it does not exist in the Config datastore, and returns the state about success."," points to a data node where data must be stored.","The root element of data must have the namespace (data is in XML) or module name (data is in JSON)."]},{"i":"post-restsdata","l":"POST /rests/data","p":["Creates the data if it does not exist under data root.","In the following example, the 'toaster' module is the root container in YANG (it doesn't have any parent). This example also makes it clear that URI doesn't contain 'toaster' node in comparison to a PUT request that must contain the name of the created node in URI."]},{"i":"delete-restsdataidentifier","l":"DELETE /rests/data/","p":["Removes the data node in the Config datastore and returns the state about success."," points to a data node that must be removed."]},{"i":"patch-restsdataidentifier","l":"PATCH /rests/data/","p":["The patch request merges the contents of the message-body with the target resource in the Configuration datastore (content-type query parameter is not specified)."," points to a data node on which PATCH operations is invoked.","This request is implemented by Plain PATCH functionality, see more details on the following page: RFC-8040 documentation - Plain PATCH operation.","Plain patch can be used to create or update, but not delete, a child resource within the target resource. Any pre-existing data which is not explicitly overwritten will be preserved. This means that if you store a container, its child entities will also merge recursively.","The following example shows the PATCH request used for modification of Ethernet interface IP address and two connection settings. Note that other settings under system:system container are left untouched including other leaves under 'connection' container and 'ethernet' list item."]},{"i":"patch-restsdataidentifierapply-tagstrue","l":"PATCH /rests/data/?apply-tags=true","p":["The patch request with parameter apply-tags=true allows to use tags.","Tags allows us to use differrent operation for separate elements instead of merging whole content as without tags.","The following tags are supported: merge, replace, delete, create and update.","Usage of these tags are explained in Templates manager : here.","The following example shows PATCH request used for modification of interfaces on IOS XE device including creating, deleting, and replacing interface configuration."]},{"i":"post-restsoperationsmodulenamerpcname","l":"POST /rests/operations/:","p":["Invokes RPC on the specified path.",": - is the name of the module and is the name of the RPC in this module.","The Root element of the data sent to RPC must have the name “input”.","The result has the status code and optionally retrieved data having the root element “output”.","The answer from the server could be:","GET /rests/operations request can be used to retrieve all available RPCs that are registered in distribution.","More information is available in the RESTCONF RFC 8040."]},{"i":"post-restsdatapath-to-operation","l":"POST /rests/data/","p":["Invokes action on the specified path in the data tree.","Placeholder represents data path to operation definition that is specified under composite data schema node in YANG (only containers and lists may contain action definition).","Content query parameter doesn't have to be specified (it will be ignored), action is represented equally in Operational and Config datastore.","Both RFC-8040 (YANG 1.1) and TAIL-F actions are supported. TAIL-F actions can be placed in both YANG 1.0 and YANG 1.1 schemas. There aren't any differences in the invocation of these types of actions using RESTCONF API.","The body of the action invocation request may contain a root 'input' container. If the action definition has no specified input container, it is not required to specify the body in the request.","The response contains the status code and optionally retrieved data having the root element 'output'.","Currently, FRINX UniConfig only supports invocation of actions under NETCONF mountpoint, must contain'yang-ext:mount' container.","Structure of 'input' and 'output' elements are the same as the structure of these containers when we invoke YANG RPC.","Assume the following YANG snippet with root container named'interfaces':","Invocation of the action named 'compute-stats' that is placed under the'interfaces' container of NETCONF mountpoint:","Difference between RPCs and actions: Actions are bound to a data tree and they can be placed under containers and lists (they cannot be specified as root entities in YANG schema). RPCs are not placed in the data tree and for this reason, they can only be specified as root entities in the YANG schema."]},{"l":"Selecting Data","p":["For selecting and identifying data is good to use query parameter fields. This parameter has to be used only with the GET method. The response body is output filtered by field-expression as the value of fields parameter."]},{"l":"Fields","p":["The response body is the output filtered by the field-expression as a value of the fields parameter.","The example of using the fields parameter: path?fields=field_expression","There are several rules, that need to be followed:","For filtering more than one field of the same parent, \";\" needs to be used. Example : path?fields=field1;field2, where field1 and field2 has the same parent, which is the very last part of the path.","For nesting, \"/\" needs to be used. Example : path?fields=field1;pathField/field2, where field1 and field2 has not the same parent, but pathField is on the same level as field1.","This is a different approach to do nesting, however, the difference between \"(\" and \"/\" is that once we use \"/\" for specifying some field, we cannot identify another field from the upper layers.","This is the case where pathField1 and pathField2 have the same parent, this is not allowed, because once we use \";\" it is expected to specify fields on the same layer as field1","Examples: With 2 approaches (nesting, sub-selecting)","Example of filtering the entire configuration of all interfaces (name, with the config):","Example of filtering all names of interfaces and all names of configs of interfaces:","Example of filtering all names of interfaces with type from the config of interfaces:"]},{"l":"Data filtering","p":["To filter data based on specific values, use the jsonb-filter query parameter. This parameter can only be used with the GET method.","For more information, see JSONB filtering."]},{"l":"Pagination","p":["To filter data even further, you can use pagination with the GET method.","There are three parameters related to pagination, which can be combined or used individually:","offset- The starting point in a list for data rendering, based on the index list of entry values. Indexing begins at 0, so that offset=2 would start rendering at the third entry. The specified offset index entry is included in the output.","limit- The number of node values displayed in a GET request. Specifies the maximum count for entries included in the response, starting with the entry defined by the offset parameter (if provided).","fetch=count- Retrieves the total number of child nodes under a specific node. Instead of returning node values, provides a count of how many child nodes exist under the specified node.","Note that pagination only works for list nodes.","Example- Using one individual pagination parameter:","Example- Using two pagination parameters simultaneously:","Example- Using the fetch=count parameter:","Response body for the fetch=count parameter with a path from the previous example:"]},{"l":"Sorting","p":["This utility helps us to sort list data from GET request according to our needs in ascending or descending order.","To sort some data, use a query parameter called sortby that will include at least one identifier of child leaf and sort direction. The first part of the value represents leaf identifier, the second part enclosed in brackets represents sort direction ('asc' or 'desc'). If there are multiple leaves based on which sorting is done, they are separated by semicolon.","Sorting, just like pagination, can only be used on list nodes.","The example of using sortby parameter with 1 value (sorting by the value of 'name' leaf):","The example of using sortby parameter with 2 values (sorting by values of 'name' and 'revision' leaves, in that order):","The example of using sortby and pagination simultaneously:","It is possible to specify module-name as part of the leaf identifier. Module-name must be specified only if there are multiple children leaves with the same identifier but specified from different namespaces. Example:","In the case of union types specified on leaf nodes, sorting is done in the blocks that are ordered by the following strategy:","leaves without value","empty type","boolean type","random numeric type","types that can be represented by JSON string"]},{"l":"Inserting"},{"l":"Insert query parameter","p":["The 'insert' query parameter can be used to specify how an item should be inserted within an list or leaf-list. This parameter is only supported for the POST and PUT methods. It is also only supported if the target list or leaf-list is marked as 'ordered-by user' in YANG model.","The allowed values for 'insert' query parameter:","Value","Description","first","Insert the new item as the new first entry.","last","Insert the new item as the new last entry (default value).","before","Insert the new item before the insertion point, as specified by the value of the 'point' query parameter.","after","Insert the new data after the insertion point, as specified by the value of the \"point\" parameter.","If the values 'before' or 'after' are used, then a 'point' query parameter for the 'insert' query parameter MUST also be present."]},{"l":"Point query parameter","p":["The 'point' query parameter is used to specify the insertion point for an item that is being created or moved within an'ordered-by user' list or leaf-list. Like the 'insert' query parameter, 'point' query parameter is only supported for the POST and PUT methods and also if the target list or leaf-list is marked as 'ordered-by user' in YANG model. The value of the 'point' query parameter is a string that indicates the key of the insertion point item. If the key is composite, the key items must be separated by a comma."]},{"l":"Examples","p":["Next five examples show usage of 'insert' and 'point' query parameters for leaf-list. First example shows how leaf-list looks before update. There are no differences in the use of the list and leaf-list."]},{"l":"List before update"},{"l":"Insert item at the top of the list"},{"l":"Insert item at the bottom of the list"},{"l":"Insert item after specific item"},{"l":"Insert item before specific item"},{"l":"Retrieving data"},{"l":"With-defaults query parameter","p":["All data nodes are reported, including any data nodes with YANG default in scheme, which are not set by client are reported.","Data nodes set to its YANG schema default value are not reported.","Data nodes set to its YANG schema default value by the client are reported.","Description","Example Data Set By User:","Example YANG Module:","explicit","report-all","The 'with-defaults' query parameter is used to specify how information about default data nodes is returned in response to GET requests on data resources. The response body is output filtered by value of with-defaults parameter.","The allowed values for 'with-defaults' query parameter:","The example of using the with-defaults query parameter: path?with-defaults or path?with-defaults=value","trim","Using with-defaults without value is equivalent to value 'report-all'.","Value","Value Explicit","Value Report-All or Without Value","Value Trim"]},{"l":"JSON Attributes","p":["Node attributes can be encoded in JSON by wrapping all the attributes in the '@' container and values or arrays in the '#' JSON element. This notation is inspired by one that is used in the 'js2xmlparser' open-source tool (conversion between JSON and XML structures): js2xmlparser","RESTCONF supports both serialization and deserialization of attributes, GET response shows all set attributes in the read data-tree and PUT/POST/PLAIN PATCH methods can be used for the writing of data nodes with attributes. Warning: attributes cannot be directly addressed using RESTCONF URI that would contain the '@' element in the path, because attributes are always bound to some data node, they are not represented by distinct nodes in the data-tree.","Reserved '@' container may contain multiple attributes. Each attribute is encoded in the same fashion as leaf nodes, there is an identifier of the attribute and attribute value.","Format of the attribute that is defined in the [module]:","Format of the attribute that is defined in the same module as the parent data entity:"]},{"i":"example---leaf-with-attributes","l":"Example - leaf with attributes","p":["Leaf without attributes:","The same leaf with set 2 attributes: 'm1:attribute-1' and'm1:attribute-2':"]},{"i":"example-container-with-attributes","l":"Example: Container with Attributes","p":["A container without attributes:","The same container with set 2 attributes: 'm1:switch' and'm2:multiplier':"]},{"i":"example-leaf-list-with-attributes","l":"Example: Leaf-list with Attributes","p":["Leaf-list without attributes:","The same leaf with set 1 attribute: 'mx:split':"]},{"i":"example-leaf-list-entry-with-attributes","l":"Example: Leaf-list Entry with Attributes","p":["Leaf-list without attributes:","Two leaf-list entries, leaf-list entry with value '10' has one attribute with identifier 'm1:prefix'. The second leaf-list entry '20' doesn't have any attributes assigned."]},{"i":"example-list-with-attributes","l":"Example: List with Attributes","p":["List without attributes:","The same list with applied single attribute: 'constraints:length'."]},{"i":"example-list-entry-with-attributes","l":"Example: List Entry with Attributes","p":["List with two list entries without attributes:","The same list entries, the first list entry doesn't contain any attribute, but the second list entry contains 2 attributes: 'm1:switch' and 'm2:multiplier'."]},{"l":"Device Schema Filters","p":["By default, all input and output data produced by RESTCONF for the selected device is fully compliant with its YANG models. Any violation of the YANG schema definitions will result in an error. Some of these restrictions can be addressed by adding the 'schemaFilters' configuration parameter for the RESTCONF."]},{"l":"Configuration Options Overview","p":["Following configuration options for 'schemaFilters' make RESTCONF processing less restrictive:"]},{"l":"Configuration Example","p":["The following example demonstrates how to enable schema filters for selected extensions and make RESTCONF ignore unknown definitions and definitions with a 'deprecated status' attribute."]},{"i":"unhide-parameter-for-readwrite-operations","l":"Unhide Parameter for READ/WRITE Operations","p":["RESTCONF supports the 'unhide' query parameter for the GET requests to include hidden definitions into the response and for PUT/POST/PATCH requests to accept hidden definitions in the input. This parameter value can be populated with a comma-separated list of extensions to unhide or the keyword 'all' to include all possible hidden definitions in the response.","Example of using the 'unhide' parameter for the GET and PUT/POST/PATCH requests.","Using unhide with a list of extensions","Using unhide parameter to unhide all hidden definitions"]},{"l":"Leafref validation","p":["According to YANG standard there are constraints for leafrefs. These constraints are not validated by default. Leafref validation can be enabled using checkForReferences query parameter with value set to true."]},{"i":"example","l":"Example:"},{"l":"Using leafref validation"},{"l":"Example output of failed validation","p":["If checkForReferences parameter is set to false or is not provided UniConfig will not perform leafref validation and there will be no leafref validation error."]},{"l":"Hide Empty Data Nodes","p":["Query parameter 'hideEmptyDataNodes' is used to hide empty composite data-tree nodes in response to GET call. Data nodes that contain only attribute tag are considered to be empty too. Default value is 'false' - empty nodes are displayed in the GET response."]},{"i":"example-1","l":"Example"},{"l":"Escaping keys in URI","p":["Following characters must be escaped, if they are contained in a list key value:':', '/', '?', '#', '[', ']', '@', '!', '$', '&', ''', '(', ')', '*', '+', ',', ';', '='.","There are 2 ways how to escape special characters in a key value: by encoding reserved UTF-8 characters using '%HH' patten or using key delimiter.","Using key delimiter should be the preferred way of dealing with reserved characters in keys since it avoids various issues with URL parsing constraints imposed by the web server."]},{"l":"Encoding reserved characters","p":["RESTCONF RFC-8040 natively allows to specify reserved characters in a key value, if they are encoded using'%HH' pattern, where 'HH' refers to hexadecimal representation of UTF-8 character.","Starting with Uniconfig 7.0.0, it is not possible to URL-encode / as %2F because the web server will throw away the request due to stricter URL parsing rules.","The following request demonstrates encoding of special characters in the 'ge0/0/1' interface name, which does not work anymore starting with Uniconfig 7.0.0.","You should use the following request:","Mappings between special characters and UTF-8 codes can be found on following site: https://www.urlencoder.org/"]},{"l":"Demarcate key using delimiter","p":["UniConfig lets you specify a key delimiter used to demarcate list key values. Once defined, all special characters inside the key are automatically escaped.","The delimiter is enabled by default. It can be defined in the config/application.properties file:","The following request demonstrates the demarcation of an interface named ge0/0/1 using the %22 delimiter."]},{"l":"Hide Attributes","p":["Query parameter 'hideAttributes' is used to hide composite data-tree nodes attributes in response to GET call. Default value is 'false' - nodes attributes are displayed in the GET response."]},{"i":"example-2","l":"Example"},{"i":"callbacks-http-client","l":"Callbacks (http-client)","p":["Callbacks include sending GET (call-point) and POST (action) requests to the remote server. They are implemented mainly for UniConfig Shell, but can also be used by RESTCONF for UniStore nodes by using the URI prefix:"]},{"i":"examples-1","l":"Examples","p":["Example - call-point invocation in RESTCONF","Response:","Example - action invocation in RESTCONF","Callbacks must be configured before use. For more details, see Callbacks."]}],[{"l":"UniConfig Queries","p":["This module is responsible for execution of queries on the configuration of some device, template, UniStore node, or snapshot."]},{"l":"RPC query-config","p":["UniConfig exposes filtering and selection API using RPC 'query-config'. Filtering and selection of configuration is done only on the database side - UniConfig receives already narrowed configuration with only selected data. Since query is evaluated by the database, this feature works only with already committed data (operational data).","The following sequence diagram captures the whole process of RPC execution in detail.","Execution of RPC query-config"]},{"l":"RPC input fields","p":["topology-id: Identifier of network-topology/topology list entry. Currently, supported topologies, under which this RPC can be used, are: 'uniconfig', 'templates', 'unistore', and snapshot topologies.","node-id: Identifier of specific network-topology/node list entry whose configuration is filtered using specified jsonb-path-query.","jsonb-path-query: JSONB-path query used for selection and filtering of subtrees in the node configuration stored in the PostgreSQL. JSONB-path must start from root \"frinx-uniconfig-topology:configuration\" container(it is always represented by absolute path).","JSONB-path query syntax is specified by PostgreSQL. You can find detailed description of all features with examples on the following link (version 14): https://www.postgresql.org/docs/14/functions-json.html#FUNCTIONS-SQLJSON-PATH"]},{"l":"RPC output fields","p":["config: List of selected and filtered JSON objects. Note that database may return multiple list entries, if the last element in the JSONB-path is represented by list/leaf-list YANG schema node. In other cases, only one or no JSON object is displayed on output based on fulfilling the filtering and selection criteria."]},{"i":"example-selection-of-json-object","l":"Example: selection of JSON object","p":["The following request demonstrated execution of simple selection query under the 'dev01' from 'uniconfig' topology. Response contains 1 JSON object - 'ssh' container.","JSONB-path query should always start with $.\"frinx-uniconfig-topology:configuration\" pattern because 'configuration' represents wrapping element for all root data elements that are stored in database.","Be aware that PostgreSQL requires escaping of special characters in the identifiers of JSON elements. For example,':' and '-' represent special characters. Because of this behaviour, it is always safer to put double quotes around all identifiers as it is done in this example."]},{"i":"example-filtering-list-of-json-objects","l":"Example: filtering list of JSON objects","p":["The next query demonstrates filtering of 'address' JSON objects using predicate based on 'ipv4-address'(the first octet must have a value '80'). Addresses under all 'controller' list entries are filtered. In this example, response contains multiple JSON objects representing 'address' list entries."]},{"i":"example-selection-of-leaf-list-content","l":"Example: selection of leaf-list content","p":["The next request shows selection of all addresses under ethernet interfaces with type 'vxlan' and 'enabled' flag set to 'true'. Response will contain aggregated array of strings, because 'address' is represented by leaf-list."]},{"i":"example-non-existing-node","l":"Example: non-existing node","p":["If node with specified identifier doesn't exist under target topology, RPC will return 400 with corresponding error message."]},{"i":"example-syntax-error","l":"Example: syntax error","p":["In case of invalid form of input 'jsonb-path-query', UniConfig will return 400 status code with error-message describing syntax error."]}],[{"l":"UniConfig shell","p":["UniConfig shell is a command-line interface for Uniconfig. Accessible over SSH, it allows users to interact with Uniconfig features including the following:","Read operational data of devices","Manipulate device configurations","Manipulate configuration templates","Manipulate data stored in Unistore","Invoke device or UniConfig operations","Manipulate global UniConfig settings","Uniconfig shell is model-driven, therefore its interface is mostly auto-generated from YANG schemas (e.g., tree structure of data-nodes or available RPC/action operations)."]},{"l":"Configuration","p":["UniConfig shell is disabled by default. To enable it, set the configuration parameter cli-shell.ssh-server.enabled to true in the application.properties file.","All available settings and descriptions are listed below:","After starting UniConfig, the SSH server listens for connections on port 2022 and the loopback interface. UniConfig Shell has two connection timeouts:","Authorization timeout, after which the connection is closed if the other party has not been authenticated (in seconds). The default value is 120 seconds.","Idle timeout, after which the connection is closed if idle (in seconds). The default value is 600 seconds."]},{"l":"Navigating in the shell","p":["Every command line starts with a command prompt that ends with the character. The identifier of the command prompt changes based on the current shell mode and the state of execution in this mode.","The exit and quit commands are available in all shell modes:","exit returns the state to the parent state","quit returns the state to the nearest parent mode (e.g., configuration mode, root mode, operational show mode). If the current state of the shell represents some mode, quit and exit have the same effect of returning to the parent mode.","Typed commands are sent to UniConfig using the ENTER key. UniConfig processes the command and may send a response to the console depending on the command. All commands are processed synchronously, meaning that multiple commands cannot be executed in parallel in the same SSH session.","CTRL-A and CTRL-E move the cursor to the beginning or end of the current line.","CTRL-L clears the shell screen.","Arrow keys UP/DOWN load previous commands in the command history.","CTRL-C cancels the current line and moves to a new blank line.","TAB loads suggestions in the current context. Hit TAB again to navigate through suggested commands using the arrow keys and select using ENTER. Leave the submode with suggestions using the shortcut CTRL-E. The text in brackets contains a description of the next command.","If the output is longer than the length of the command line window, it is displayed with scrolling capability. Use ENTER to display the next line and SPACE to display the next page. Use the q key to leave scrolling mode. You can only scroll only in one direction, towards the end of the output.","Scrolling through long output"]},{"l":"Root mode","p":["Root mode is the initial mode after successful authentication.","Example: Log into UniConfig shell:","The exit command is used to exit the UniConfig shell interface altogether(disconnecting SSH client).","Example - Exit UniConfig shell:","Currently, only username/password single-user authentication is supported as configured in the application.properties file."]},{"l":"Accessing sub-modes","p":["Root mode acts as a gateway to open the configuration and show modes.","Example - Switch to configuration mode:"]},{"l":"Show command history","p":["The show-history command is used to display a list of N last invoked commands. This command is also available in configuration mode.","Example - Show the last five executed commands:","Note that the list of invoked commands persists across UniConfig restarts and SSH connections."]},{"l":"Unhide and hide operations","p":["The following commands are used to unhide and hide attributes in application properties:","unhide-get is used to unhide an attribute hidden in application properties for read purposes (restconf.schema-filters.hidden-data-on-read-by-extensions).","unhide-set is used to unhide an attribute hidden in application properties for write purposes (restconf.schema-filters.ignored-data-on-write-by-extensions).","hide-get is used to hide attributes that were unhidden with unhide-get.","hide-set is used to hide attributes that were unhidden with unhide-set.","When unhide is set for a GET or SET operation, the request URL for the operation contains the unhide query parameter. In the following example, the unhide parameter is set to all:","http://localhost:8181/rests/data/network-topology:network-topology/topology=uniconfig/node=vnf21/configuration?unhide=all","This is also available for callbacks. Request and set operations for callbacks uses restconf.schema-filters.ignored-data-on-write-by-extensions and show operations uses restconf.schema-filters.hidden-data-on-read-by-extensions.","The command also gives confirmation that the attribute was added to or removed from the unhidden list.","When unhide-get or hide-get are called without parameters, the output contains a list of all unhidden parameters. The same applies to unhide-set and hide-set.","When used with the parameter all, the unhide operation applies to all parameters defined in application properties for read or write purposes."]},{"l":"Examples","p":["Example- Attempt to show hidden callbacks field details with unhide","Example- Attempt to show hidden callbacks field details without unhide","Example- Attempt to set hidden callbacks field reset-password with unhide","Example- Attempt to set hidden callbacks field reset-password without unhide","Example- Attempt to request hidden callbacks field unlock-user with unhide","Example- Attempt to request hidden callbacks field unlock-user without unhide"]},{"l":"Configuration mode","p":["Configuration mode provides access to the following:","CRUD operations on top of persisted UniConfig, UniStore and template nodes","CRUD operations on top of persisted UniConfig settings","UniConfig RPC operations such as commit or calculate-diff","After opening configuration mode, a new UniConfig transaction is created. All operations invoked in configuration mode are executed in the scope of the created transaction. The transaction is automatically closed after leaving configuration mode ( exit or quit command).","If commit or checked-commit are invoked, the transaction is automatically refreshed. The user stays in configuration mode with a newly created transaction.","Commands like SET, SHOW and DELETE are now available only on a specific device and are not accessible in root configuration mode."]},{"l":"Show configuration","p":["The show operation is used to display selected subtrees.","The subtree path can be constructed interactively with the help of shell suggestions/auto-completion mechanism. Construction of the path works the same way for SET, SHOW and DELETE operations.","Example- Display the configuration of a selected container:","First move into a specific topology on a specific device:","After this, the show operation is available:"]},{"l":"Delete configuration","p":["The delete operation removes a selected subtree.","Example- Remove a container:","First move to a specific topology on a specific device:","After this, the delete operation is available:","Quit to configuration mode, commit using request mode and return to the device on the topology:"]},{"l":"Set configuration","p":["The set operation can be used for the following:","Set the value of a single leaf.","Set the values of multiple leaves in a single shell operation.","Set a list of values for a leaf-list.","Replace the entire subtree using a JSON snippet.","Example- Set the value of a single leaf:","Example- Set values for multiple leaves under the hold-time container:","A JSON snippet can be written to a selected data-tree node by entering the json sub-mode. In this sub-mode, you can type multiple lines that represent a well-formed JSON document. At the end, confirm the set operation using the pattern w!+ newline, or cancel the set operation with the pattern q!+ newline.","Example- Replace configuration of an interface using a JSON snippet:","Example- Leave json sub-mode without executing set operation:"]},{"l":"Execute UniConfig operation","p":["The request command is used to execute UniConfig operations such as commit or calculate-diff in the UniConfig transaction:","The command is available in configuration mode","You can fill in input parameters and values interactively or via provided JSON snippet","Example- Execute UniConfig RPCs in the scope of the open UniConfig transaction:"]},{"l":"Request operational mode","p":["This command has been merged with request configuration mode and is now available only in configuration mode.","Request mode allows users to:","Invoke selected UniConfig requests that read or alter UniConfig settings.","Invoke RPCs or actions provided by network devices or other southbound mountpoints.","Input parameters and values can be filled in interactively or via a provided JSON snippet. The transaction is passed from configuration mode.","Example- Invoke RPC execute-and-read with typed input parameters:","Example- Execute the same RPC execute-and-read using input JSON:","UniConfig shell does not support interactive typing of input arguments for an RPC/action that contains the list YANG element. Such operations must be executed using input JSON."]},{"l":"Show operational mode","p":["Show mode allows users to:","Display operational data about UniConfig itself (e.g., logging status, list of open transactions or list of acquired subscriptions)","Display operational data of network devices","After opening show mode, a new UniConfig transaction is opened. The transaction is closed when you leave this mode.","Example- Display configuration of selected subtree:","Example- Display selected system configuration:"]},{"l":"Pipe operations","p":["UniConfig shell supports pipe operations similar to Unix shell/bash pipes. When a command is followed by the pipe sign (|), the output of the command is passed to the selected pipe operation.","Example:","Supported pipe operations are:","grep- Show only lines that match supplied regex","match- Same as grep, but can be used with optional parameters to also show lines before and after matched lines","context-match- Same as grep, but also shows parent structure","brief- Display root elements in short table format","hide-empty-data-nodes- Hide data nodes without child nodes","hide-attributes- Hide attributes of data nodes"]},{"l":"Redirecting output","p":["The output of an executed command can be redirected to a file using the sign followed by a filename.","Example:","In this case, output in the console is empty but the content of the output.txt file is a follows:"]},{"l":"Aliases","p":["You can define aliases in UniConfig shell. A json file named shell-aliases is included in the UniConfig distribution for this purpose. After unpacking the UniConfig distribution, the file can be found under Uniconfig/distribution/packaging/zip/target/uniconfig-x.x.x/config. The file contains some sample aliases."]},{"l":"Alias creation","p":["Aliases cannot be created dynamically, only before Uniconfig is started. The following rules apply:","The alias name must be unique and cannot contain whitespaces.","The command can contain a wildcard (*). In this case, the user is prompted to add a value.","The alias is only visible in the mode where it was defined.","Example- Execute the alias diff xr5:","Example- Execute the alias lbr:","Example- Execute the alias shh:"]},{"l":"Callbacks","p":["Callbacks include sending POST and GET requests to the remote server and invoking user scripts from the UniConfig shell.","The following is required to use callbacks:","Necessary YANG modules - YANG modules that are required by the callbacks.","Configuration - Enable callbacks in config/application.properties and set the remote server and access token.","Update repository - Add the necessary YANG modules from step 1 into at least one YANG repository in the cache directory, and either define remote endpoints and scripts in a YANG file or create a new one for callbacks. For a definition of remote endpoints, use the frinx-callpoint@2022-06-22.yang extension.","UniStore node - Create a UniStore node using the YANG repository containing the necessary YANG modules from step 1 and a YANG file with defined endpoints and scripts.","In UniConfig shell, step 4 is optional as UniConfig creates dummy UniStore nodes for all repositories that meet the conditions in step 3. In this case, the dummy UniStore node name is identical to the YANG repository name.","In RestConf, step 4 is mandatory."]},{"l":"Necessary YANG modules","p":["The following YANG modules are required:","frinx-callpoint@2022-06-22.yang(not needed for scripts)","tailf-common@2018-11-12.yang","tailf-meta-extensions@2017-03-08.yang","tailf-cli-extensions@2018-09-15.yang"]},{"i":"configuration-1","l":"Configuration","p":["By default, callbacks are disabled and the host and port for the remote server are empty in config/application.properties.","To enable callbacks, set the configuration parameter callbacks/enabled to true. It is also necessary to set the host and port for the remote server and store an access token in the UniConfig database.","The host and port for the remote server can be set in three ways:","Before starting Uniconfig, in the config/application.properties file. The port number is optional:","After starting UniConfig, with a PUT request:","After starting UniConfig, with cli-shell:","The access token can be stored in the UniConfig database in one of two ways:","Available settings and descriptions for callbacks are listed below:"]},{"l":"Update repository","p":["First, create or update the YANG repository by using the frinx-callpoint@2022-06-22.yang extension displayed in the following snippet. There is only one extension, url, with the argument point."]},{"i":"add-call-point-get-request","l":"Add call-point (GET request)","p":["The following snippet shows how to create a call-point in the frinx-test YANG file by using the frinx-callpoint@2022-06-22.yang extension.","The argument of the url extension is /data/from/remote, which is appended to the end of the remote server URI configured in config/application.properties. Thus the final address for the remote call-point is https://remote.server.io/data/from/remote."]},{"i":"add-action-post-request","l":"Add action (POST request)","p":["The following snippet shows how to create an action in the frinx-test YANG file by using the frinx-callpoint@2022-06-22.yang extension. You must also import tailf-common.yang.","The action consists of:","The action name, defined by tailf:action.","The suffix for the remote endpoint, defined by fcal:url.","The input that contains body of the request. This part is optional."]},{"l":"Add script","p":["The following snippet shows how to create a script in the frinx-test YANG file by using tailf-common.yang. It is not necessary to import the frinx-callpoint@2022-06-22.yang extension.","The script consists of:","The script name, defined by tailf:action.","The path to the script, defined by tailf:exec.","Arguments for the script, defined by tailf:exec.","Arguments can be dynamic (i.e., the user can pass values to them) or static(flags). Follow these conventions when creating arguments:","Each argument must contain a name (for example, -n, -j).","Dynamic arguments must be enclosed in $(...)(for example, $(name)).","Flags are simple words without whitespace (for example, VIP, UPPER, upper)."]},{"l":"UniStore node","p":["A UniStore node can be created by RestConf or UniConfig shell. If a repository is explicitly defined by the query parameter?uniconfig-schema-repository=repository-name, this repository must contain all necessary YANG modules. If a repository name is not defined when the UniStore node is created, all necessary YANG modules must be in the latest schema repository."]},{"i":"examples-1","l":"Examples","p":["Example- Invoke callpoint in shell:","Example- Invoke action in shell:","Example- Execute user script in shell:"]}],[{"l":"UniStore API","p":["UniStore nodes are used to store and manage various settings and configurations inside UniConfig. The difference between UniStore and UniConfig nodes is that UniConfig nodes are backed by a real/network device, whereas UniStore nodes do not correspond to real devices. In the case of UniStore nodes, UniConfig is used only to manage the configuration and its persistence into the PostgreSQL DBMS.","UniStore nodes have the following characteristics:","UniStore nodes are not backed by \"real\" devices or southbound mountpoints. They are used only to store configurations which are committed to the PostgreSQL DBMS.","The configuration of a UniStore node can be read, created, removed and updated in the same way as UniConfig topology nodes. You can use the the same set of CRUD RESTCONF operations and supported UniConfig RPCs for operation purposes.","UniStore nodes are placed in a dedicated unistore topology under network-topology nodes. The whole configuration is placed under the configuration container.","The UniStore configuration is modelled by user-provided YANG schemas that can be loaded into UniConfig. When creating a new UniStore node, you must provide the name of a YANG repository so that UniConfig knows how to parse the configuration ( uniconfig-schema-repository query parameter).","UniConfig operations that are supported for UniStore nodes:","All RESTCONF CRUD operations","commit / checked-commit RPC","calculate-diff RPC (including git-like-diff flavor)","subtree-manager RPCs","replace-config-with-oper RPC","revert-changes RPC (transaction-log feature)","The node ID of a UniStore node must be unique among all UniConfig and UniStore nodes."]},{"l":"Commit operation","p":["Actions performed with UniStore nodes during a commit operation:","Verify configuration fingerprint. If another UniConfig transaction has already changed one of the UniStore nodes touched in the current transaction, the commit operation fails.","Calculate diff operation across all changed UniStore nodes.","Write intended configuration into the UniConfig transaction.","Replace the actual configuration with the intended configuration in the UniConfig transaction.","Update last configuration fingerprint to the UUID of the committed transaction.","Write transaction log into transaction.","Commit UniConfig transaction. Cached changes are sent to the PostgreSQL DBMS."]},{"l":"Example use case"},{"l":"Prepare YANG repository","p":["A YANG repository is required for UniConfig to model the UniStore node configuration. A UniStore node can only be modeled by one YANG repository.","To provide a YANG repository to UniConfig, copy the directory containing the YANG files under the cache parent directory. From there, it is loaded either at startup or in runtime with the register-repository RPC.","As an example, assume that cache contains the system YANG repository with a simple YANG module:"]},{"l":"Create UniStore node","p":["The following request shows how a new Unistore node ( global) is created using the provided JSON payload and the name of the YANG repository used to parse the payload (query parameter uniconfig-schema-repository). Note that the YANG repository must be specified only when the UniStore node is initialized."]},{"l":"Read content of UniStore node","p":["The following sample shows how to read the content of a UniStore node using a regular GET request. The query parameter content is set to config, indicating that the UniStore node is cached only in the Configuration datastore of the transaction (the Operational datastore is empty at this time)."]},{"i":"calculate-diff-rpc-created-node","l":"Calculate-diff RPC (created node)","p":["The calculate-diff operation is also supported for UniStore nodes. The following request shows the diff for all touched nodes in the current transaction, including UniStore nodes. As the UniStore node was just created, the diff output only contains created-data with the entire root settings container."]},{"l":"Persistence of UniStore nodes","p":["For UniStore nodes, the commit RPC is used to confirm the changes that have been made and to store them in the PostgreSQL DBMS. As described in the previous section, the commit operation stores the UniStore node configuration and transaction log in the DBMS and does not touch network devices.","Changes to UniStore and UniConfig nodes can be combined in the same transaction and can be committed simultaneously."]},{"l":"Read committed configuration","p":["Since the configuration was committed in the previous step, it is also visible in the Operational datastore of the newly created transaction. The actual state can be read by appending the content=nonconfig query parameter to a GET request, as shown in the following example:"]},{"l":"Verify configuration fingerprint","p":["The configuration fingerprint is part of the optimistic locking mechanism. By comparing fingerprints from the beginning of the transaction and from the commit operation, it is possible to see if another UniConfig transaction has already modified the affected UniStore node. For Unistore nodes, the fingerprint is always updated to match the transaction id (UUID) of the last committed transaction containing the UniStore node."]},{"l":"Modify configuration","p":["The same RESTCONF CRUD operations that can be applied to UniConfig nodes are also relevant to UniStore nodes. The following request demonstrates how to merge multiple fields using the PATCH operation."]},{"i":"calculate-diff-rpc-updated-node","l":"Calculate-diff RPC (updated node)","p":["The second calculate-diff RPC shows more granular changes made to an existing UniStore node, which includes the create-data and updated-data entries."]},{"l":"Display content of transaction log","p":["Committed transactions, including all metadata such as serialized diff output or transaction ID, can be displayed by reading the transactions-metadata container in the Operational datastore. Information about successfully committed UniStore nodes is also displayed. This can be used to revert changes using the transaction ID displayed in the transaction log."]},{"l":"Remove UniStore node","p":["A UniStore node can be removed either by sending a DELETE request to the entire node list entry or configuration container, or by removing all configuration child entities. In each case, the UniStore node is removed after changes are confirmed using the commit RPC."]}],[{"l":"YANG Patch Operations","p":["Yang Patch is used for modification of subtrees under configuration. Advantages of YANG Patch in comparison to other RESTCONF operations:","YANG Patch may contain multiple edits with different operations applied to different subtrees","all edits inside YANG Patch are applied atomically - either all edits are successful or PATCH operation will fail and configuration will not be modified","supported reordering of lists (move operation) and inserting of list entry to specific position in the list(insert operation)","UniConfig supports all RFC-specified operations inside edits:","CREATE","REPLACE","MERGE","MOVE","INSERT","DELETE","REMOVE","RENAME","Using these operations, the user is able to reorder lists, create new data, remove data, or update specific data.","For more information, please refer to the official documentation of the RFC YANG patch"]},{"l":"RPC Examples"},{"l":"Creation of list entries","p":["The request creates new list entries in the tvi list. If the data exist, return an error."]},{"l":"Moving list entry","p":["The request moves an existing list entry on a user defined position."]},{"l":"Inserting new list entry","p":["The request inserts new list entries on a user defined position."]},{"l":"Inserting new leaf-list entry","p":["The request inserts a new leaf-list entry on a user defined position."]},{"l":"Replacing list entry","p":["The request replaces an existing value in a list entry."]},{"l":"Merging configuration","p":["The request merges an existing value in a list entry."]},{"l":"Delete list entry","p":["The request deletes a list entry. If the data is missing, returns an error."]},{"l":"Removing list entry","p":["The request removes a list entry."]},{"l":"Renaming list entry","p":["The request renames a list entry key."]},{"l":"Failed deleting of list entry","p":["The request to delete a list entry that is not present."]},{"l":"Sending Patch request with invalid structure","p":["The request is missing some data."]}],[{"l":"Operational Procedures"},{"l":"Logging","p":["The UniConfig distribution uses Logback as its logging framework. Logback is the successor to the log4j framework with many improvements, such as more options for configuration, better performance, and context-based separation of logs. Context-based separation of logs is used widely in UniConfig to achieve per-device logging based on the set marker in the logs."]},{"l":"TLS","p":["TLS is a widely adopted security protocol designed to facilitate privacy and data security for communications over the Internet. TLS authentication is disabled in the default version of UniConfig."]},{"l":"TLS for Postgres database","p":["By default, UniConfig communicates with the database without TLS and traffic is therefore unencrypted. When the database is deployed separately from UniConfig, we recommend that you enable TLS encryption."]},{"l":"OpenAPI","p":["The UniConfig distribution contains a '.yaml' file that generates list of all usable RPCs with examples. You can view it either locally or on our hosted version, which always shows the latest OpenAPI version."]},{"l":"Data Security Models","p":["UniConfig supports encryption and hashing of values in RESTCONF and UniConfig shell API, as well as managing confidential data during transfers between the UniConfig database and network devices."]},{"l":"UniConfig Clustering","p":["The UniConfig stateless architecture allows deployment of the system in a cluster to ensure horizontal scalability and high-availability properties."]},{"l":"Thread pools","p":["UniConfig uses thread pools in several places. They can be configured in the application.properties file."]},{"i":"data-flows--transformations","l":"Data flows & transformations","p":["There are multiple paths and transformations of data within Uniconfig. The following section provides more information on some of the more common paths.","Thread pools"]}],[{"l":"Data flows and transformations","p":["Architecture","Flows","CLI, direct to device, plaintext interface","CLI, direct from device, configuration data read","CLI, direct from device, operational data read","CLI, direct to device, configuration data write","Netconf, direct from device, configuration data read","Netconf, direct from device, operational data read","Netconf, direct to device, configuration data write","Uniconfig, cached intent configuration, data read","Uniconfig, cached applied configuration, data read","Uniconfig, applying intent to a device","Uniconfig, synchronizing applied configuration from network"]},{"l":"Architecture","p":["CLI- Southbound plugin for managing devices over CLI (SSH).","Data flow architecture","gNMI- Southbound plugin for managing devices over gNMI (SSH).","JSON YANG RFC provides information on how JSON is used.","NETCONF- Southbound plugin for managing devices over Netconf (SSH).","Northbound","Restconf RFC provides detailed information on YANG-based REST API specifics.","Restconf- REST API for Uniconfig.","SNMP- // TBD","Southbound","The following diagram outlines the basic architecture for this purpose. It gives a simplified overview and only includes a subset of components, but serves as a baseline for illustrating various data flows.","The following main components are included:","The Uniconfig core consists of many different components/features. A good place to start is the build-and-commit model in Uniconfig.","Uniconfig CLI shell- CLI interface for Uniconfig. Similar capabilities as RESTCONF, but intended for users who prefer CLI access.","Uniconfig core","Uniconfig java SDK documentation provides an overview.","Uniconfig Java SDK- Java SDK for Uniconfig. Uses Restconf internally.","Uniconfig restconf documentation provides an overview.","Uniconfig shell documentation provides an overview."]},{"l":"Flows"},{"i":"cli-direct-to-device-plaintext-interface","l":"CLI, direct to device, plaintext interface","p":["Flow for reading/writing arbitrary commands to a CLI device.","The User sends an HTTP POST REST (rpc) request to Uniconfig.","URL specifies Uniconfig defined execute-and-read or execute-and-expect RPC.","URL must specify the following:","topology=cli- CLI-managed device","node=nodeID- specific managed device","Restconf invokes an asynchronous RPC on the southbound layer, but blocks until it completes.","The CLI layer invokes a generic implementation of the plaintext access RPC and returns output from the device as is.","Restconf receives the data from the CLI layer and completes the request.","Restconf example:","To send an arbitrary command to a device and receive a response:","To send a sequence of commands (ssh expect style) and receive a response:","Flow diagram:","Data flow architecture"]},{"i":"cli-direct-from-device-configuration-data-read","l":"CLI, direct from device, configuration data read","p":["?content=config- to specify only configuration data must be read from device (if not present, defaults to config)","CLI readers send specific commands to the device and parse the output into an internal DOM data structure.","Data flow architecture","Flow diagram:","Flow for reading structured (YANG-model based) configuration data from a device over CLI. The data is always retrieved from the device with no cache involved.","node=nodeID- specific managed device","Restconf component parses the URL and validates it against openconfig YANG models.","Restconf example:","Restconf invokes an asynchronous read from the southbound layer, but blocks until it completes.","Restconf receives the data from CLI layer, serializes them into JSON and completes the request.","The CLI layer finds appropriate an CLI driver (cli units) and invokes all readers registered for a specific path provided in the URL.","The user sends an HTTP GET REST request to Uniconfig.","To get configuration data for all interfaces:","topology=cli- CLI-managed device","URL must conform to openconfig data models used for all CLI devices.","URL must specify the following:"]},{"i":"cli-direct-from-device-operational-data-read","l":"CLI, direct from device, operational data read","p":["Flow for reading structured (YANG-model based) operational data from a device over CLI. The data is always retrieved from the device with no cache involved.","This flow is identical to CLI, direct from device, configuration data read flow. The difference is that this READ returns a combination of configuration and operational data ! To invoke operational data read, use ?content=nonconfig in the URL, the rest of URL is no different","Warning! Be careful when requesting operation data from devices. The data can be massive and the act of reading such data can cause issues on device itself. Always be as specific as possible, i.e., use the most specific (longest) URL possible.","Restconf example:","To get configuration and operational data for all interfaces:","Flow diagram:","Data flow architecture"]},{"i":"cli-direct-to-device-configuration-data-write","l":"CLI, direct to device, configuration data write","p":["?content=config- only configuration data is read from the device","CLI writers send specific commands to the device and check the output for errors.","Data flow architecture","Flow diagram:","Flow for writing structured (YANG-model based) configuration data to a device over CLI. The data is transformed and sent directly to a device.","node=nodeID- specific managed device","Note: We do not recommend writing directly to a device. The preferred option is to use Uniconfig core to build an intent and commit the changes to the network.","Restconf component parses the URL and the payload and validates them against openconfig YANG models.","Restconf example:","Restconf invokes an asynchronous write on the southbound layer, but blocks until it completes.","Restconf receives a success or failed response from the CLI layer and maps it to the appropriate status code.","The CLI layer finds the appropriate CLI driver (cli units) and invokes all writers registered for a specific path provided in the URL.","The payload must contain valid JSON that correspondos to the URL points within the YANG model.","The user sends an HTTP PUT or POST REST request into Uniconfig.","To configure a new Loopback999 interface:","topology=cli- CLI-managed device","URL and payload need to conform to openconfig data models used for all CLI devices.","URL must specify the following:"]},{"i":"netconf-direct-from-device-configuration-data-read","l":"Netconf, direct from device, configuration data read","p":["?content=config- only configuration data is read from the device (if not given, defaults to config)","Data flow architecture","Flow diagram:","Flow for reading structured (YANG-model based) configuration data from a device over Netconf. The data is always retrieved from the device with no cache involved.","node=nodeID- specific managed device","Restconf component parses the URL and validates it against vendor-specific YANG models.","Restconf example:","Restconf invokes an asynchronous read from the southbound layer, but blocks until it completes.","Restconf receives the data from the Netconf layer, serializes them into JSON and completes the request","The Netconf layer serializes the path (URL) into a get-config request with a filter, sends it to the device and parses the output into an internal DOM data structure.","The User sends an HTTP GET REST request to Uniconfig.","To get Loopback999 interface configuration using IOS XR vendor models:","topology=topology-netconf- Netconf-managed device","URL must conform to vendor-specific YANG data models used by the device.","URL must specify the following:","Which models are used depends on the device. Many vendor-specific models can be found on GitHub."]},{"i":"netconf-direct-from-device-operational-data-read","l":"Netconf, direct from device, operational data read","p":["Flow for reading structured (YANG-model based) operational data from a device over Netconf. The data is always retrieved from the device with no cache involved.","This flow is identical to the Netconf, direct from device, configuration data read flow. The difference is that this READ returns a combination of configuration and operational data by using get netconf RPC instead of get-config! To invoke operational data read, use ?content=nonconfig in the URL","Warning! Be careful when requesting operation data from devices. The data can be massive and the act of reading such data can cause issues on device itself. Always be as specific as possible, i.e., use the most specific (longest) URL possible.","Restconf example:","To get operational data for all interfaces using IOS XR vendor models:","Flow diagram:","Data flow architecture"]},{"i":"netconf-direct-to-device-configuration-data-write","l":"Netconf, direct to device, configuration data write","p":["Flow for writing structured (YANG-model based) configuration data to a device over Netconf. The data is transformed and sent directly to a device.","Note: We do not recommend writing directly to a device. The preferred option is to use Uniconfig core to build an intent and commit the changes to the network.","Restconf example:","To configure Loopback999 interface configuration using IOS XR vendor models:","Flow diagram:","Data flow architecture"]},{"i":"uniconfig-cached-intent-configuration-data-read","l":"Uniconfig, cached intent configuration, data read","p":["?content=config- only intent data is read for a device (if not given, defaults to config == intent)","An ad-hoc uniconfig transaction is started.","Data flow architecture","Flow diagram:","Flow for reading structured (YANG-model based), cached intent configuration data (not applied to network) for a device, regardless of its management protocol. The data is retrieved from in-memory cache (or a database, if not available in memory).","For more information about transactions, see Build and commit mode or Immediate commit model.","node=nodeID- specific managed device","Restconf component parses the URL and validates it against device-specific YANG models.","Restconf example:","Restconf invokes an asynchronous read from uniconfig core, but blocks until it completes.","Restconf receives the data from Uniconfig core, serializes them into JSON and completes the request.","The ad-hoc transaction is closed.","The user sends an HTTP GET REST request to Uniconfig.","This is typically a very quick operation compared to reading directly from a device.","To get Loopback999 interface cached intent configuration using IOS XR vendor models:","To get Loopback999 interface cached intent configuration using openconfig models for a device over CLI:","topology=uniconfig- device cached in uniconfig","Transactions can be started automatically by Uniconfig or controlled by the user.","Uniconfig core reads in-memory cached intent (or loads the latest version of data from the database).","URL must conform to models used for that specific device, whether standard or vendor-specific models.","URL must specify the following:"]},{"i":"uniconfig-cached-applied-configuration-data-read","l":"Uniconfig, cached applied configuration, data read","p":["?content=nonconfig- only applied data is read for a device (if not given, defaults to config == intent)","An ad-hoc uniconfig transaction is started.","Data flow architecture","Flow diagram:","Flow for reading structured (YANG-model based), cached configuration data (already applied to the network) for a device, regardless of its management protocol. The data is retrieved from in-memory cache (or a database, if not available in memory).","For more information about transactions, see Build and commit mode or Immediate commit model.","node=nodeID- specific managed device","Restconf component parses the URL and validates it against device-specific YANG models.","Restconf example:","Restconf invokes an asynchronous read from Uniconfig core, but blocks until it completes.","Restconf receives the data from Uniconfig core, serializes them into JSON and completes the request.","The ad-hoc transaction is closed.","The user sends an HTTP GET REST request to Uniconfig.","This is typically a quick operation compared to reading directly from a device.","To get Loopback999 interface cached intent configuration using IOS XR vendor models:","To get Loopback999 interface cached intent configuration using openconfig models for a device over CLI:","topology=uniconfig- device cached in uniconfig","Transactions can be started automatically by Uniconfig or controlled by the user.","Uniconfig core reads in-memory cached, already applied configuration (or loads the latest version of data from a database).","URL must conform to models used for that specific device, whether standard or vendor-specific models.","URL must specify the following:"]},{"i":"uniconfig-applying-intent-to-a-device","l":"Uniconfig, applying intent to a device","p":["Flow for writing structured (YANG-model based) configuration data to Uniconfig's intent. Intent is typically modified for multiple devices. When modifications are completed, a commit is issued to apply the changes to the network. Automated rollback may kick in when a failure occurs.","For more information on this flow, see Build and commit mode or Immediate commit model.","Note: Uniconfig core builds on top of \"direct to device data flows\" and everything south of Uniconfig core is identical to those (direct to device) data flows. For example, Uniconfig core uses the Netconf, direct to device, configuration data write flow to apply configurations to Netconf devices when performing a commit.","Restconf example:","To configure two devices in a single transaction:","Flow diagram:","Data flow architecture"]},{"i":"uniconfig-synchronizing-applied-configuration-from-network","l":"Uniconfig, synchronizing applied configuration from network","p":["An ad-hoc uniconfig transaction is started.","Data flow architecture","Flow diagram:","Flow for synchronizing/updating an applied configuration from a network device. This is useful especially when the configuration is changed in the network directly (outside of Uniconfig). Once the configuration is synchronized, those direct changes can be accepted or reverted in Uniconfig.","For more information about transactions, see Build and commit mode or Immediate commit model.","For more information on this flow, see Sync from network.","Payload must specify a list of devices to be synchronized.","Restconf example:","Restconf invokes an asynchronous RPC in Uniconfig core, but blocks until it completes.","Restconf receives a success or failed response from Uniconfig core and maps it to the appropriate status code and response.","The ad-hoc transaction is committed.","The user sends an HTTP GET REST request to Uniconfig.","To synchronize two devices from the network:","Transactions can be started automatically by Uniconfig or controlled by the user.","Uniconfig core performs direct from device configuration data read flows for each device in parallel.","Uniconfig core stores the new configuration in the applied configuration cache and in the database.","Uniconfig has a mechanism to verify whether a device is out of sync based on the last commit timestamp. A full configuration is performed only if out of sync.","URL specifies Uniconfig defined sync-from-network RPC."]}],[{"l":"Data Security Models","p":["UniConfig supports encryption and hashing of leaf/leaf-list values via SSH and RESTCONF API. The following sections describe the supported security models in depth."]},{"l":"Data encryption","p":["UniConfig uses asymmetric encryption to ensure confidentiality of selected leaf and leaf-list values. Currently only RSA ciphers are supported, both global UniConfig and device-level key-pairs. Encryption is supported for the uniconfig, unistore, and templates topologies."]},{"l":"Global-device encryption architecture","p":["Both the UniConfig and device sides use PKI for data encryption:","UniConfig side: All selected leaves are encrypted using a global public key when the data enters UniConfig via RESTCONF API or UniConfig SSH shell API. Afterwards, the data is stored in the database in encrypted format. UniConfig also has access to a private key used internally for decrypting data that is already encrypted.","Device side: The device exposes a public key, which UniConfig uses to re-encrypt data before it is sent to the device ( commit and checked-commit operations). However, the device does not expose its private key, and UniConfig is therefore not able to detect changes to encrypted data (updated leaves/leaf-lists) but can only detect if data was removed or created. Because of this, UniConfig assumes that encrypted data read from the device was encrypted using the same public key as that used by UniConfig.","The figure below depicts data transformations performed on UniConfig interfaces:","Global-device encryption model"]},{"l":"Global-only encryption architecture","p":["In contrast to the global-device encryption architecture, this model uses only a global key-pair to encrypt data. Devices contain only plaintext data.","A public key is used to encrypt data received via RESTCONF, UniConfig shell API and when syncing configurations from device to UniConfig transaction( sync-from-network operation).","A private key is used to decrypt encrypted data before forwarding this configuration to a device ( commit and checked-commit operations).","The figure below depicts data transformations performed on UniConfig interfaces:","Global-only encryption model","Reading operational data directly from the device (GET under yang-ext:mount) shows data in unencrypted format. Application gateways should restrict access to mountpoints for such use cases."]},{"l":"YANG support","p":["Leaves and leaf-lists whose values should be encrypted must be marked using a YANG extension with no parameters. Currently, only leaves of the string type are supported (direct/indirect with custom type definitions), as encrypted values are base64 encoded. Also, be aware that type constraints must accept encrypted values.","Example- YANG module that defines one encrypt extension:","Using the extension in the config module:","Oftentimes it is not possible to modify existing YANG files, as they are already deployed on a device (for example, a device running with a NETCONF server). In this case, you can still mark which leaves should be encrypted using an additional YANG module that contains deviations.","Example","Afterwards, there are two options to couple this module with modules from the device (NETCONF):","Explicitly specifying the side-loaded module in the install-node request using the netconf-node-topology:yang-module-capabilities settings. See Device installation section below for more information.","Automatically detecting the side-loaded module - UniConfig looks for the specific capability on the NETCONF server, inherits its revision and looks for a side-loaded module with a specific name and inherited revision (see Configuration section below). This option is preferred if the deployment contains multiple versions of devices and the list of encrypted paths is different on each version."]},{"l":"Configuration","p":["The global RSA key-pair is stored inside PEM-encoded files in the rsa directory under UniConfig root. The private key must be named encrypt_key and the public key encrypt_key.pub. If these files are not provided, UniConfig automatically generates its own key-pair with a length of 2048 bits. All UniConfig instances in the cluster must use the same key-pair.","Encryption settings are stored in the config/application.properties file.","Example:","encrypt-enabled- If false, encryption is disabled regardless of other settings or install-node parameters. If true, encryption is enabled. The default value is true.","encrypt-extension-id- If not specified, encryption is disabled regardless of other settings or install-node parameters. Uses the format[module-name]:[extension-name], which specifies the extension used to mark encrypted leaves/leaf-lists in YANG modules. The corresponding YANG module containing this extension can be part of device/unistore YANG schemas or, alternatively, can be side-loaded during installation of the NETCONF device as an imported module from the default repository.","netconf-reference-module- Name of the module that the NETCONF client looks for during the mounting process. If UniConfig finds a module with this name in the list of received capabilities, it uses its revision in the lookup process for the correct YANG module with encrypted paths (using deviations).","netconf-encrypted-paths-module-name- Name of the module which contains deviations with paths to encrypted leaves/leaf-lists. There can be multiple revisions of this file prepared in the default NETCONF repository. The NETCONF client in UniConfig chooses the correct revision based on the netconf-reference-module-name setting. Together, netconf-reference-module-name and netconf-encrypted-paths-module-name can be used to autoload encrypted paths for different versions of devices.","If the default YANG repository contains a module with encrypted-paths and without defined YANG revision, and the device does not already provide encryption capability, the encrypted-paths module is used as last resort during device installation ( netconfReferenceModuleName and matching of revisions are ignored)."]},{"l":"Change encryption status","p":["using the following parameter:","Encryption can be enabled or disabled using the following parameter:","The value of this parameter can be changed with the change-encryption-status RPC request.","The following request can be used to enable encryption:","After this command is called, all UniConfig instances will set this parameter using the notification service to the value sent via RPC (in this case, true).","Correspondingly, the following request can be used to disable encryption:","The following request is used to check the current encryption status:","To check the functionality of this RPC after calling the install-device RPC, you can request the password for the node:","If encryption is enabled, the password is returned encrypted.","If encryption is disabled, the password is returned as plaintext."]},{"i":"change-encryption-keys-private-and-public","l":"Change encryption keys (private and public)","p":["If it is necessary to change the encryption keys, use the change-encryption-keys RPC.","The process of changing encryption keys requires rebooting one of the UniConfig instances or enabling a new instance of UniConfig after calling the change-encryption-keys RPC. Rotation of encrypted data in the database for new encryption keys occurs if UniConfig is started after the change-encryption-keys RPC is executed. During key rotation, if some data in the database cannot be decrypted with the old key, those data will remain unchanged.","The default value of the new-encryption-cipher-type parameter is RSA, so there is no need to add this parameter to the request body.","To check if UniConfig must be restarted or if a new UniConfig instance must be added, run the following query:","After key rotation and when UniConfig is started, data encrypted with the old key is overwritten with the new encryption keys and all other UniConfig instances in the cluster will use the new keys for encryption.","During key rotation, UniConfig reads and updates encrypted configurations in batches. The size of these batches is set by the following parameter:"]},{"l":"Device installation","p":["There are two settings related to encryption in the install-node RPC request:","uniconfig-config:device-crypto- Specifies a path to the public key on the device:","public-key-path- Leaf with RFC-8040 path. If a path to the public key is specified and exists on the device, the global-device encryption model is used. Otherwise, the global-only encryption model is used.","public-key-cipher-type- Cipher type (RSA is used by default).","netconf-node-topology:yang-module-capabilities- If autoloading of YANG modules with encrypted paths is not used and the device itself does not specify encrypted leaves, it is necessary to side-load the YANG module with encrypted paths. This parameter is relevant only for NETCONF nodes. Side-loaded modules must be expressed in the format of NETCONF capabilities.","The following request shows an install-node request that specifies a path to the public key and the side-loaded YANG module encrypted-paths with revision 2021-12-15 and namespace urn:ietf:params:xml:ns:yang:encrypted-paths.","During installation, UniConfig tries to download the public key from the device. The public key can be verified using a GET request:"]},{"l":"Format for encrypted data","p":["Encrypted values are stored and displayed via RESTCONF or UniConfig shell with the rsa_ prefix. The prefix is used by UniConfig to see if posted data needs to be encrypted or is encrypted already.","The encrypted string is encoded using Base64 encoding."]},{"i":"example-global-device-model","l":"Example: Global-device model","p":["This example shows encryption of values marked by the frinx-encrypt:encrypt extension on both UniConfig server side and device side. The NETCONF device directly exposes the frinx-encrypt YANG module and leaves with applied extension (side-loading of encrypted paths is not necessary).","YANG model used for simulating the YANG device:"]},{"i":"example-global-only-model","l":"Example: Global-only model","p":["This example shows encryption of values marked by the frinx-encrypt:encrypt extension only on the UniConfig server side. The NETCONF device directly exposes the frinx-encrypt YANG module and leaves with applied extension (side-loading of encrypted paths is not necessary).","The YANG model used for simulation of the YANG device is the same as in the previous example."]},{"l":"Data hashing","p":["UniConfig supports the iana-crypt-hash YANG model for specificying hashed values in the data-tree using the type definition crypt-hash. Hashing works in the uniconfig and unistore topologies.","Only NETCONF devices are currently supported, as CLI cannot be natively used to report device capabilities that would contain supported the hashing function."]},{"l":"Architecture","p":["Hashing is done only in the RESTCONF layer after writing data that contains leaves/leaf-lists with the crypt-hash type. Afterwards, UniConfig stores, uses, and writes to the device only the hashed representation of these values.","Hashing model"]},{"i":"yang-support-1","l":"YANG support","p":["YANG module iana-crypt-hash: http://www.iana.org/assignments/yang-parameters/iana-crypt-hash@2014-08-06.yang","All three hash functions are implemented ( MD5, SHA-256 and SHA-512). For the uniconfig topology, the hashing function is selected based on the reported feature in the NETCONF capability. For the unistore topology, UniConfig enforces the SHA-512 hashing function."]},{"i":"device-installation-1","l":"Device installation","p":["Hashing is enabled by default on NETCONF devices that report the iana-crypt-hash model-based capability. It is not necessary to add the entry setting in the install-node request.","After successfully installing the device, you can check the loaded hashing function that will be used to store hashed values. Use the following GET request:"]},{"i":"example-hashing-input-values","l":"Example: Hashing input values","p":["This example demonstrates hashing input values with the crypt-hash type using the RESTCONF API."]}],[{"l":"Logging framework","p":["UniConfig uses the Logback logging framework. Logback is the successor to the log4j framework with many improvements, such as more options for configuration, better performance and context-based separation of logs. The latter is used widely in UniConfig to achieve per-device logging based on the set marker in the logs."]},{"l":"Logback configuration","p":["Logback configuration is placed in the config/logback.xml file under the UniConfig distribution. For more information, see Logback configuration.","This section describes parts of the configuration in the context of UniConfig."]},{"l":"Appenders","p":["The following appenders are used:","STDOUT- Print logs to the console.","logs- Write all logs to the output file at log/logs.log. A rolling file appender is applied.","netconf-notifications, netconf-messages, netconf-events, cli-messages and gnmi-messages- Sifting appenders that split logs per node ID set in the marker of the logs. Logs are written to different subdirectories under the log directory, and are identified by their node ID. A rolling file appender is applied.","restconf- Appender used to write RESTCONF messages to the log/restconf.log file. A rolling file appender is applied.","gnmi- Appender used to write logs related to the gNMI topology."]},{"l":"Loggers","p":["There are two groups of loggers:","Package-level logging brokers: Loggers used to write general messages to the console and a single output file.","Default logging level: INFO. For debugging purposes, it can be useful to change the logging level to TRACE or DEBUG.","Layers covered: UniConfig, Unified, Controller, RESTCONF, CLI, NETCONF, gNMI.","Appenders used: STDOUT and logs.","Loggers used for logging brokers: These loggers should not be changed since the state of logging can be changed using RPC calls. Classpaths point to specific classes that represent implementations of logging brokers.","Logging level is set to TRACE.","Appenders used: netconf-notifications, netconf-messages, netconf-events, cli-messages, gnmi-messages and restconf."]},{"l":"Update configuration","p":["Logback is configured to scan for changes in its configuration file and automatically reconfigure itself when the configuration file changes. The default scanning frequency is 5 seconds."]},{"l":"Example configuration","p":["In the logback.xml file, you can edit the level of logging for each UniConfig component:"]},{"l":"Logging levels","p":["The following logging levels are available:"]},{"l":"INFO","p":["This is the recommended logging level for production environments.","INFO messages describe the behavior of applications (for example, if a particular service starts or stops, or something is added to the database). During typical operations, these log entries are nothing to worry about and no follow-up actions are necessary."]},{"l":"DEBUG","p":["The DEBUG level gives verbose diagnostic information that includes more detail than is necessary to use the application. This logging level is used to diagnose, troubleshoot, or test an application to ensure that it runs smoothly."]},{"l":"TRACE","p":["The TRACE level captures all detail about the application's behavior. It is mostly diagnostic and is more granular than DEBUG. This log level is used in situations where you need to see exactly what happened in your application."]},{"l":"Logging brokers","p":["The logging broker represents a configurable controller that logs one logical group of messages from a single classpath. Logging multiple messages from the same classpath simplifies the configuration of loggers in Logback, since only one logger per broker must be specified.","The logging broker is controlled using RESTCONF RPCs. There are several operations that can trigger logging for the whole broker or only for specified node IDs. The logger configuration in the logback file assigned to the broker should not be changed.","The following subsections describe available logging brokers:"]},{"l":"RESTCONF","p":["Used to log authenticated HTTP requests and responses; information about URI, source, HTTP method, query parameters, HTTP headers and body.","Per-device logging cannot be enabled for this broker. All logs are saved to the log/restconf.log file.","It is possible to specify HTTP headers whose content is masked the in logs with asterisks (*). This is useful if some headers contain private data (such as Authorization or a Cookie headers). Hidden HTTP headers are marked using header identifiers.","It is also possible to configure HTTP methods for which communication (requests and responses) is not logged to a file.","Requests and responses are paired using a unique message-id attribute, which is not part of the HTTP request but is generated on the RESTCONF server.","Requests and responses contain Uniconfig transactions for easier matching with log transactions.","Example- Request and corresponding response (same message-id):"]},{"l":"CLI messages","p":["Used to log all CLI requests and responses.","CLI requests and responses are paired with a unique message-id attribute.","Supports per-device logging. Logs for CLI messages are stored under the log/cli-messages directory and named according to the pattern [node-id].log.","Example- Send POST RPC to install a CLI device and pair requests with corresponding responses (same message-id):"]},{"l":"NETCONF Messages","p":["Used to log all NETCONF messages, incoming and outgoing, except for NETCONF notifications (a separate broker handles notifications).","NETCONF RPCs and responses can be matched using the message-id attribute placed in the RPC header.","Supports per-device logging. Logs for NETCONF messages are stored in the log/netconf-messages directory and named according to the pattern [node-id].log.","Example- Send NETCONF GET RPC and receive a response:","The number 641 represents the session ID read from the NETCONF hello message. If multiple sessions are created between the NETCONF server and client that are logically grouped under the same node ID, logs from multiple sessions are stored in the same logging file. This is necessary to distinguish between the sessions. Multiple NETCONF sessions between the UniConfig and NETCONF server are created for each subscription to the NETCONF stream."]},{"l":"NETCONF Notifications","p":["Used to log incoming NETCONF notifications.","Supports per-device logging. Logs for NETCONF notifications are stored in the log/netconf-notifications directory and named according to the pattern [node-id].log.","Example- Receiving two notifications:"]},{"l":"NETCONF Events","p":["Used to log session-related information about establishing or closing a NETCONF session from the view of the NETCONF client placed in UniConfig.","These logs do not contain full printouts of sent or received NETCONF messages.","Supports per-device logging. Logs for NETCONF events are stored in the log/netconf-events directory and according to the pattern [node-id].log.","Example:"]},{"l":"gNMI Messages","p":["Used to log all gNMI SET/GET messages, incoming or outgoing, except for gNMI notifications.","Support per-device logging. Logs for gNMI messages are stored in the log/gnmi-messages directory and named according to the pattern [node-id].log.","Example- Send gNMI SET request and receive a response:"]},{"l":"Supported logging settings","p":["`restconf-logging:hidden-http-headers`` - List of HTTP headers (names of headers) whose content is hidden in the logs. Names of headers are case-insensitive.","broker-identifier- Unique identifier for the logging broker. The following brokers are supported: netconf\\_messages, restconf, netconf\\_notifications, netconf\\_events, and cli\\_messages.","Current logging broker settings are stored in the Operational datastore under the logging-status root container.","enabled-devices- If is-logging-enabled-on-all-devices is set to false, logs are generated only for devices specified in this list. Acts as a simple filtering mechanism based on the whitelist. A blacklist approach is not supported, as it is not possible to set is-logging-enabled-on-all-devices to true and specify devices for which logging feature is disabled. This setting is not supported for the restconf logging broker.","Global settings common for all logging brokers:","gnmi-logging:message-types- gNMI message types that are logged. Names of message types must be specified in uppercase.","GNMI-specific settings:","hidden-types- The value of leafs or leaf-lists using one of the types specified is masked in the logs with asterisks (*). Useful for hiding passwords and other confidential data in logs.","is-logging-broker-enabled- Specifies if the logging broker is enabled or not. If the broker is disabled, no logging messages are generated.","is-logging-enabled-on-all-devices- If set to true, logs are separated into distinct files in the scope of all devices. If set to false, logging is enabled only for devices listed in the enabled-devices leaf-list/array. This setting is not supported for the restconf logging broker as RESTCONF currently does not differentiate the node ID in requests or responses.","Logging settings are encapsulated inside multiple list entries ( broker list). Each entry contains settings for one logging broker.","Response:","restconf-logging:hidden-http-methods- HTTP requests and associated HTTP responses are not logged if the request's HTTP method is included in this list. Names of HTTP methods must be specified in uppercase.","RESTCONF-specific settings:","Settings placed under a single logging entry:","The following example shows a GET query that displays the logging broker settings:"]},{"l":"Initial configuration","p":["By default, all logging brokers are disabled and logging is disabled on all devices. To enable per-device logging, you must explicitly specify a list of devices. Additionally, RESTCONF-specific filtering is not configured, all HTTP requests and responses are fully logged and no content is dismissed. By default, only the SET gNMI message type is set to be logged.","The initial logging configuration can be adjusted by adding the logging-controller configuration to the config/application.properties file. The structure of this configuration section conforms to the YANG structure described by the logging and restconf-logging modules. It is possible to copy the state of the Operational datastore under logging-status into the logging-controller node.","The following properties snippet shows the sample configuration logging-controller. The logging brokers netconf\\_messages and netconf\\_notifications are enabled, ( netconf\\_messages for all devices and netconf\\_notifications only for xr6 and xr7 devices).","If unknown parameters are specified in a configuration file, they are ignored and a warning is logged."]},{"l":"Control logging using RPC calls","p":["As logging settings are stored in the Operational datastore, it is possible to adjust these settings in runtime only using RPC calls. The following subsections describe available RPCs."]},{"l":"Enable logging broker","p":["This RPC is used to enable the logging broker, which is then available to write logs. RPC input contains only the name of the logging broker ( broker-identifier).","Example- Enable logging broker with the restconf identifier:","The output shows a successful response:"]},{"l":"Disable logging broker","p":["This RPC is used to disable a logging broker, which will no longer write any logs regardless of other settings. RPC input contains only the name of the logging broker.","Example- Disable logging broker with the restconf identifier:","The output shows a successful response:"]},{"l":"Enable default device logging","p":["This RPC is used to set the default device logging to true. Logs are written for all devices without filtering based on node ID.","RPC input contains only the name of the logging broker ( broker-identifier). Invoking this RPC clears the leaf-list enabled-devices.","Example- Enable default device logging in the netconf\\_messages logging broker:","The output shows a successful response:"]},{"l":"Disable default device logging","p":["This RPC is used to set the default device logging to false. Logs are written only for devices named in the enabled-devices leaf-list. If enabled-devices does not contain a node ID, logging in the corresponding broker is effectively turned off.","RPC input contains only the name of the logging broker ( broker-identifier).","Example- Disable default device logging in the netconf\\_messages logging broker:","The output shows a positive response:"]},{"l":"Enable device logging","p":["This RPC is used to enable logging for specified devices identified by node IDs. RPC input contains the name of the logging broker ( broker-identifier) and a list of node IDs ( device-list).","Example- Enable logging for devices with node IDs node1, node2, and node3 in the netconf\\_events logging broker:","The output shows a successful response:"]},{"l":"Disable device logging","p":["This RPC is used to turn off logging for specified devices identified by node IDs. RPC input contains the name of the logging broker ( broker-identifier) and a list of node IDs ( device-list).","Example- Disable logging for device with node ID node1 in the netconf\\_events logging broker:","The output shows a successful response:"]},{"l":"Set global hidden types","p":["This RPC is used to set identifiers of hidden YANG type definitions. Values of leaves and leaf-lists described by these types are masked in output logs. Overwrites all previously configured hidden types. An empty list of hidden types will disable filtering of data values. Filtering applies to all logs, including RESTCONF logs.","Example- Set three (3) hidden types:","The output shows a successful response:"]},{"l":"Set Hidden HTTP Headers","p":["This RPC is used to overwrite the list of HTTP headers whose content is hidden in the output of RESTCONF logs. Only affects the restconf logging broker.","HTTP headers in both requests and responses are masked. The list of hidden headers denotes header identifiers. The identifier of hidden headers is still included in output logs, but their content is masked with asterisks (*).","Example- Hide the content of Authorization and Cookie HTTP headers:","The output shows a successful response:"]},{"l":"Set hidden HTTP methods","p":["This RPC is used to overwrite the list of HTTP methods. RESTCONF communication, which may include invoking hidden HTTP methods, is not displayed in output logs.","Both requests and responses with hidden HTTP methods are excluded from the log files. Only affects the restconf logging broker.","Example- Hide GET and PATCH communication in RESTCONF logs:","The output shows a successful response:"]},{"l":"Set gNMI message types","p":["This RPC is used to overwrite the list of supported gNMI message types. Only affects the logging of gNMI messages.","Example- Set 'SET' and 'GET' message types:","The output shows a successful response:"]}],[{"l":"OpenAPI","p":["The OpenAPI file located in the openapi folder contains all the RPCs and data manipulating requests (CRUD operations), and their respective examples. A shell script (named start_uniconfig_swagger.sh) was created that automatically checks if the file is present and runs it in a docker container where the Swagger API runs, and opens the file containing all the RPCs and data manipulating requests. After running the shell script, open any browser and type localhost in the URL bar.","Overview of our OpenAPI along with all parameters and expected returns can be found here","The website should look like on the screenshot below:","openapi website","Alternatively, you can look at our live instance of the site that always displays latest version of the API."]}],[{"l":"Thread pools","p":["There are several thread pools that can be configured in UniConfig:","Jetty server,","Task executor,","Notifications,","SSH Client,","NetConf topology,","CLI topology."]},{"l":"Jetty server","p":["Jetty server is used to aggregate connectors (HTTP request receivers) and request handlers. Connectors use the thread pool methods to run jobs that will eventually call the handle method.","Available parameters to configure:","jetty.max-threads=200","The maximum number of threads available in the jetty server. The default value is 200.","jetty.min-threads=8","The minimum number of threads available in the jetty server. The default value is 80.","jetty.idle-timeout=60","Threads that are idle for longer than this period (in seconds) can be stopped. The default value is 60.","If any of these parameters are left empty (e.g. jetty.max-threads=), the default value is used."]},{"l":"Task Executor","p":["The task executor is used to execute operations (internal operations or RPCs), either synchronously or asynchronously, on given nodes or devices.","task-executor.max-queue-capacity=10000","The maximum queue capacity for postponed tasks. The default value is 10000.","task-executor.max-cpu-load=0.9","The maximum CPU load for executing tasks. Load is expressed as a ratio so that 1.0 corresponds to 100% load, 0.9 to 90%, etc. The default value is 0.9.","task-executor.default-thread-count=","The efault thread count used for executing tasks. The default value is the number of available processors * 2.","task-executor.max-thread-count=","The maximum thread count used for executing tasks. The default value is default-thread-count* 20.","task-executor.keepalive-time=60","The time in seconds before the execution of a specified task is timed out. The default value is 60.","If any of these parameters are left empty (e.g. task-executor.default-thread-count=), the default value is used."]},{"l":"Notifications","p":["A NetConf related thread pool that handles notification subscriptions (acquiring of subscriptions, release of subscriptions, etc.).","notifications.thread-parameters.monitoring-executor-initial-pool-size=","The initial thread count used by the monitoring executor. The default value is the number of available processors.","notifications.thread-parameters.monitoring-executor-maximum-pool-size=","The maximum thread count used by the monitoring executor. The default value is initial-pool-size* 4.","notifications.thread-parameters.monitoring-executor-keepalive-time=60","The time in seconds before the execution of a specified task is timed out in the monitoring executor. The default value is 60.","If any of these parameters are left empty (e.g. notifications.thread-parameters.monitoring-executor-initial-pool-size=), the default value is used."]},{"l":"SSH Client","p":["SSH Client uses a thread pool that handles communication with devices. This thread pool is shared between NetConf and CLI topologies.","ssh-client.default-timeout=-1","Timeout for SSH connections (in seconds). If set to a negative value, timeouts are disabled. The default value is -1.","ssh-client.heartbeat-interval=30","The interval (in seconds) at which the client pings the server to check if the connection is still alive. The default value is 30.","ssh-client.heartbeat-reply-wait=60","Indicates if the heartbeat request expects a reply. Time (in seconds) to wait for a reply, a non-positive value means that no reply is expected. The default value is 60.","ssh-client.heartbeat-request=keepalive@sshd.apache.org","The heartbeat request that is sent to the server. The default value is keepalive@sshd.apache.org.","ssh-client.ssh-default-nio-workers=8","The amount of non-blocking workers that handle communication messages. The default value is 8.","If any of these parameters are left empty (e.g. ssh-client.ssh-default-nio-workers=), the default value is used."]},{"l":"NetConf Topology","p":["NetConf topology thread pools are used to connect to NetConf devices and keep the connection alive.","netconf-topology-parameters.fixed-thread-pool-thread-count=2","The fixed thread pool thread count in the NetConf topology. Used to read device capabilities and schema set up. The default value is 2.","netconf-topology-parameters.scheduled-thread-pool-thread-count=2","The scheduled thread pool thread count in the NetConf topology. Used to schedule keepalive messages. The default value is 2.","If any of these parameters are left empty (e.g. netconf-topology-parameters.fixed-thread-pool-thread-count=), the default value is used."]},{"l":"CLI Topology","p":["CLI topology thread pools are used to connect to CLI devices and keep the connection alive.","cli-topology-parameters.keepalive-thread-count=","The thread pool count dedicated ONLY to keepalive and reconnect scheduling. The default is either 2 or the number of available processors, whichever is higher.","cli-topology-parameters.init-executor-thread-timeout=120","If any thread is unused for this period (in seconds), it is stopped and recreated in the future if necessary.","cli-topology-parameters.init-executor-thread-count=","The maximum, number of threads for the flexible thread pool executor. This thread pool is used to process events and asynchronous locking of the CLI layer. The default is the number of available processors * 8.","If any of these parameters are left empty (e.g. cli-topology-parameters.keepalive-thread-count=), the default value is used."]}],[{"l":"TLS encryption for Postgres database","p":["By default, communications with the database are unencrypted. In deployments where UniConfig is running separately from the database, network traffic may be visible to outside parties.","The sections below describe how to enable TLS encryption for communications with the database."]},{"l":"Generate self-signed certificate using OpenSSL","p":["If you have already generated your SSL keys, you must convert them to the correct format. See Convert SSL keys to correct format","If not, you must first generate your keys."]},{"l":"Convert SSL keys to correct format","p":["The correct format for SSL keys is as follows:","The command for converting the keys may differ based on the format of your existing keys. They can be converted using OpenSSL version 1.1.1 with the openssl command.","The OpenSSL documentation provides examples for most common cases:","To convert to PKCS-8 DER binary format, see PKCS-8.","To convert to PKCS-12 format, see PKCS-12."]},{"l":"Enable TLS for database connections","p":["Edit the configuration file at the following path relative to the UniConfig root directory:","Modify the connection section within the dbPersistence section:","Example:","TLS-related fields include the following:","db-persistence.connection.enabled-tls- Set to true to enable TLS encryption. The default value is false.","db-persistence.connection.tls-client-cert- Specify the relative path from the root UniConfig directory to the Client certificate.","db-persistence.connection.tls-client-key- Specify the relative path from the root UniConfig directory to the Client key. Can be PKCS-12 or PKCS-8 format.","db-persistence.connection.tls-ca-cert- Specify the relative path from the root UniConfig directory to the root CA certificate.","db-persistence.connection.ssl-password- If the file specified in db-persistence.connection.tls-client-key is encrypted with a password, specify the password here. Required for PKCS-12 keys and for encrypted PKCS-8 keys. Ignored for unencrypted keys.","Do not forget to adjust other database connection parameters accordingly."]}],[{"l":"TLS-based Authentication","p":["TLS authentication is disabled in the default version of UniConfig.","To enable TLS for RESTCONF, perform the following two steps:","Set up key-store and trust-store to hold all keys and certificates. If authentication of individual clients is not required, trust-store is also not required. Key-store must always be initialized.","Enable TLS in UniConfig via the application.properties configuration file."]},{"l":"Set key-store and trust-store","p":["To prepare key-store and trust-store:","In the UniConfig root directory, create a new directory that will contain key-store and, optionally, trust-store files. For example:","Create a new key-store. There are two options depending on whether you already own the certificate that you want to use for identification of UniConfig on the RESTCONF layer:","Create a new key-store with the generated RSA key-pair (the example below uses a length of 2048 and validity of 365 days). After executing the following command, the prompt will ask you for information about the currently generated certificate that is pushed into the newly generated key-store secured by a password (this secret will be used later in the configuration file - make sure that you remember it).","Create a new key-store with the already-generated RSA key-pair (your certificate that you want to use for authentication in ODL).","(Optional step) Create a new trust-store using an existing certificate (an empty trust-store cannot be created). If you have multiple client certificates, they can be pushed to trust-store by executing the same command multiple times (the alias must be unique for each of the imported certificates). For example:","You can easily convert OPENSSL PEM certificates to the DER format supported by keytool:","If your application must own the distribution's certificate, you can export the certificate from the generated key-pair that we have pushed into the keystore(PKCS12 or OPENSSL format):"]},{"l":"Enable TLS in UniConfig","p":["After preparing key-store and trust-store, you need to point UniConfig to these storages and explicitly enable TLS via a flag.","Modify the following configuration file at a path relative to the UniConfig root directory:","Next, edit the TLS configuration section, un-commenting and editing the relevant properties.","The example snippet below enables TLS authentication, disables user-based authentication (hence trust-store is not required) and points UniConfig to the key-store file created in the previous section:","If your deployment requires authentication for individual RESTCONF users, trust-store is required and you need to set server.ssl.client-auth=need","JVM provides secure defaults, which you can override by specifying included cipher suites and TLS versions.","The following example configuration includes support for TLS 1.2 and TLS 1.3 with some of the most common and strongest ciphers available:","SNI (Server Name Indication) is disabled by default. To enable it, uncomment the line below:"]}],[{"l":"UniConfig Clustering"},{"l":"Introduction","p":["UniConfig can be easily deployed in a cluster owing to its stateless architecture and transaction isolation:","Stateless architecture - UniConfig nodes in the cluster do not keep any state that needs to be communicated directly to other UniConfig nodes in the cluster. All network-topology configuration and state information is stored inside a PostgreSQL database that must be reachable from all UniConfig nodes in the same zone. All UniConfig nodes share the same database, making the database the single source of truth for the cluster.","Transaction isolation - Load-balancing is based on mapping UniConfig transactions to UniConfig nodes in a cluster (transactions are sticky). One UniConfig transaction cannot span multiple UniConfig nodes in a cluster. Southbound sessions used for device management are ephemeral, i.e., they are created when UniConfig needs to access a device on the network (like pushing configuration updates) and are closed as soon as a UniConfig transaction is committed or closed.","There are several advantages to clustered deployment of UniConfig nodes:","Horizontal scalability - Increasing the number of units that can process UniConfig transactions in parallel. A single UniConfig node tends to have limited processing and networking resources - this constraint can be mitigated by increasing the number of nodes in the cluster. The more UniConfig nodes in the cluster, the more transactions can be executed in parallel. The number of connected UniConfig nodes in the cluster can also be adjusted at runtime.","High availability - A single UniConfig node does not represent a single point of failure. If a UniConfig node crashes, only transactions processed by the corresponding node are cancelled. The application can retry a failed transaction, which will be processed by the next node in the cluster.","There also are a couple limitations to be considered:","Parallel execution of transactions is subject to a locking mechanism, whereby two transactions cannot manipulate the same device at the same time.","A single transaction is always executed by a single UniConfig node. This means that the scope of a single transaction is limited by the number of devices and their configurations that a single Uniconfig node can handle."]},{"l":"Deployments"},{"l":"Single-zone deployment","p":["In a single-zone deployment, all managed network devices are reachable by all UniConfig nodes in the cluster zone. Components of a single-zone deployment and connections between them are illustrated in the diagram below.","Deployment with single zone","Included components:","UniConfig controllers - Network controllers that use a common PostgreSQL system for persistence of data, communicate with network devices using NETCONF/GNMi/CLI management protocols and propagate notifications into Kafka topics (UniConfig nodes act only as Kafka producers). UniConfig nodes do not communicate with each other directly, their operations can only be coordinated using data stored in the database.","Database storage - PostgreSQL is used for persistence of network-topology configuration, mountpoints settings and selected operational data. The PostgreSQL database can also be deployed in the cluster (outside of scope).","Message and notification channels - The Kafka cluster is used to propagate notifications generated by UniConfig itself (e.g., audit and transaction notifications) or from network devices and only propagated by UniConfig controllers.","Load-balancers - Load-balancers are used to distribute transactions (HTTP traffic) and SSH sessions from applications to UniConfig nodes. From the point of view of the load-balancer, all UniConfig nodes in the cluster are equal. Currently only a round-robin load-balancing strategy is supported.","Managed network devices - Devices that are managed using NETCONF/GNMi/CLI protocols by UniConfig nodes or generate notifications to UniConfig nodes. Sessions between UniConfig nodes and devices are either on-demand/emphemeral(configuration of devices) or long-term (distribution of notifications over streams).","HTTP/SSH clients and Kafka consumers - Application layer, such as workflow management systems or end-user systems. The RESTCONF API is exposed using the HTTP protocol, the SSH server exposes UniConfig shell and Kafka brokers allow Kafka consumers to listen to events on subscribed topics."]},{"l":"Multi-zone deployment","p":["This type of deployment has multiple zones that manage separate sets of devices for the following reasons:","Network reachability issues - Groups of devices are reachable, and thus manageable, only from some part of the network (zone) but not from others","Logical separation - Different scaling strategies or requirements for different zones.","Legal issues - Some devices must be managed separately with split storage because of, for example, regional restrictions.","The following diagrams represents a sample deployment with two zones:","Zone 1 contains three UniConfig nodes.","Zone 2 contains only two UniConfig nodes.","Multiple zones can share a single Kafka cluster, but database instances must be be split (can be running in a single Postgres server).","Deployment with multiple zones","Description of multi-zone areas:","Applications - The application layer is responsible for managing mapping between network segments and UniConfig zones. Typically this is achieved by deploying/using an additional inventory database that contains device <-> zone mappings, and based on this information the application decides which zone to use.","Isolated zones - A zone contains one or more UniConfig nodes, load-balancers and managed network devices. Clusters in isolated zones do not share information.","PostgreSQL databases - It is necessary to use a dedicated database per zone.","Kafka cluster - A Kafka cluster can be shared by multiple clusters in different zones, or alternatively there can be a single Kafka cluster per zone. Notifications from different zones can be safely pushed to common topics, as there can be no conflicts between Kafka publishers. However, it is also possible to achieve isolation of published messages in a shared Kafka deployment by setting different topic names in different zones."]},{"l":"Load-balancer operation","p":["Load-balancers are responsible for allocating UniConfig transactions to one of the UniConfig nodes in the cluster. This is done by forwarding requests without a UniConfig transaction header to one of the UniConfig nodes (using round-robin strategy) and afterwards appending a backed identifier to the create-transaction RPC response in the form of an additional Cookie header('sticky session' concept). Afterwards, the application is responsible for assuring that all requests belonging to the same transaction contain the same backend identifier.","The application is responsible for preserving transaction and backend identifier cookies throughout the transaction's lifetime.","The following sequence diagram captures the process of creating and using two UniConfig transactions with a focus on load-balancer operation.","Load-balancing UniConfig transactions","The first create-transaction RPC is forwarded to the first UniConfig node(applying round-robin strategy), because it does not contain the uniconfig_server_id key in the Cookie header. The response contains both the UniConfig transaction ID ( UNICONFIGTXID) and uniconfig_server_id that represents a 'sticky cookie'. The uniconfig_server_id cookie header is appended to the response by the load-balancer.","The next request that belongs to the created transaction contains the same UNICONFIGTXID and uniconfig_server_id. The load balancer uses uniconfig_server_id to forward this request to the correct UniConfig node.","The last application request again represents the create-transaction RPC. This time the request is forwarded to the next registered UniConfig node in the cluster according to the round-robin strategy."]},{"l":"Configuration"},{"l":"UniConfig configuration","p":["All UniConfig nodes in the cluster should be configured using the same parameters. There are several important sections in the config/application.properties file that relate to the clustered environment."]},{"l":"Database connection settings","p":["This section contains information on how to connect to a PostgreSQL database as well as connection pool settings. It is located under the dbPersistence.connection properties object.","Example with essential settings:","Make sure that [number of UniConfig nodes in cluster] * [maxDbPoolSize] does not exceed the maximum allowed number of open transactions and open connections on the PostgreSQL side. Note that maxDbPoolSize also caps the maximum number of open UniConfig transactions (1 UniConfig transaction == 1 database transaction== 1 connection to database)."]},{"l":"UniConfig node identification","p":["By default, UniConfig node names are generated randomly. This behavior can be modified by setting db-persistence.uniconfig-instance.instance-name. The instance name is leveraged, for example, in the clustering of stream subscriptions.","Example:"]},{"l":"Kafka and notification properties","p":["This section contains properties related to connections to Kafka brokers, Kafka publisher timeouts, authentication, subscription allocation and rebalancing settings.","Example with essential properties:"]},{"l":"Load-balancer configuration","p":["The following YAML code represents a sample Traefik configuration that can be used in the clustered UniConfig deployment (deployment with a single Traefik node). There is one registered entry-point with the uniconfig identifier on port 8181.","Next, you need to configure UniConfig docker containers with Traefik labels. UniConfig nodes are automatically detected by a Traefik container as uniconfig service providers. There is also a URI prefix (/rests), the name of the\"sticky cookie\" ( uniconfig_server_id) and the server port number ( 8181) where the UniConfig web server listens to incoming HTTP requests.","Values for all Traefik labels should be the same on all nodes in the cluster. Scaling of the UniConfig service in the cluster (for example, using Docker Swarm tools) is simple when container settings do not change.","A similar configuration to the one presented using Traefik can also be achieved using other load-balancer tools, such as HAProxy."]},{"l":"Clustering of NETCONF subscriptions and notifications","p":["When a device is installed with the stream property set, subscriptions for all provided streams are created in database. These subscriptions are always created with the UniConfig instance id set to null, so they can be acquired by any UniConfig from the cluster.","Each UniConfig instance in a cluster uses its own monitoring system to acquire free subscriptions. The monitoring system uses a specialized transaction to lock subscriptions, which prevents other UniConfig instances from locking the same subscriptions. While locking a subscription, the UniConfig instance writes its id into the subscription table for the currently locked subscription, which indicates that this subscription is already acquired by this UniConfig instance. Other instances of UniConfig will then see that this subscription is not available."]},{"l":"Optimal subscription count and rebalancing","p":["With multiple UniConfig instances working in a cluster, each instance calculates an optimal range of subscriptions to manage.","Based on the optimal range and number of currently opened subscriptions, each UniConfig node (while performing a monitoring system iteration) decides whether it should:","Acquire additional subscriptions until the optimal range is reached.","Once the optimal range is reached, stay put and not acquire any additional subscriptions.","Release some of its subscriptions to trigger rebalancing until the optimal range is reached.","If an instance goes down, all of its subscriptions are immediately released and the optimal ranges of other living nodes are adjusted. Managed network devices, and thus subscriptions, are reopened by the rest of the cluster.","Note that there is a grace period before other nodes take over the subscriptions. Therefore, if a node goes down and then back up in quick succession, it will restart the subscriptions on its own.","The following example illustrates a timeline for a three-node cluster and how many subscriptions are handled by each node:","notifications-in-cluster-rebalancing","The hard limit still applies in clustered environments. It is never exceeded regardless of the optimal range."]}],[{"l":"Uniconfig properties","p":["UniConfig can be extensively configured using application properties located in the application.properties file.","Application properties can be separated into three groups:","Runtime mutable properties can be modified in runtime (using the update-properties RPC), their changes take effect in runtime and the properties are persisted in the database.","Database persisted properties include all runtime mutable properties and some additional properties. These properties are stored in the database, which is always their primary source. With UniConfig Cloud Config, they remain constant across UniConfig instances in the same cluster and cannot be overridden via the application.properties file.","Regular UniConfig properties comprise all the remaining properties. These properties can always be changed using application.properties and can differ between UniConfig instances.","Database persisted properties include the following property prefixes:","crypto","schema-settings","callbacks","notifications.kafka","netconf-default-parameters","gnmi-default-parameters","cli-default-parameters","These properties are stored in the properties table and are also known as default properties. They can be read and updated using the read-properties RPC and update-properties RPC.","After UniConfig is started, if default properties are found in the database, UniConfig will use the values in the database. For properties not found in the database, values from the first UniConfig instance after startup are used (by the application.properties file or environment variables) and saved in the database for the next UniConfig instances."]},{"l":"UniConfig Cloud Config","p":["UniConfig Cloud Config is used to retain the same property values between distributed UniConfig instances connected via a message broker. It is largely the same technology as Spring Cloud Config with JDBC backend and Spring Cloud Bus. The main difference is that UniConfig Cloud Config Server and Cloud Config Client are in the same project, while Spring requires a separate Cloud Config Server application.","By calling a special signal (the Refresh Bus Endpoint call) during runtime, the system sets the same value for persisted properties in all UniConfig instances. The signal is called immediately after mutable properties are modified using the update-properties RPC. The specific UniConfig instance calling the signal sends Kafka events containing the changed properties, while other instances read those properties from the database and use the refresh endpoint to update them in runtime."]},{"l":"UniConfig startup with UniConfig Cloud Config","p":["UniConfig startup with UniConfig Cloud Config: startup-with-ucc","Before starting UniConfig, enable Cloud Config by using the following properties:","On startup, UniConfig checks the database for any default properties to configure:","If default properties are found in the database, UniConfig manually refreshes its property values to use those in the database.","If no default properties are found, UniConfig uses its existing properties and, once loaded, saves them in the database for the next UniConfig instances.","At the end of Spring initialisation, the Refresh Bus Endpoint is called. This refreshes default properties with the database values for all UniConfig instances connected via the Kafka refresh topic. A second refresh during the UniConfig startup cycle is required if several instances were started simultaneously and the database contains no property values to synchronize for properties (especially encryption keys).","At application runtime, if the update-properties RPC is used with default properties on input, UniConfig updates the properties in the database. It also calls the Refresh Bus Endpoint, which reloads properties for all UniConfig instances connected via Kafka."]},{"l":"UniConfig startup without UniConfig Cloud Config","p":["UniConfig startup without UniConfig Cloud Config: startup-without-ucc","Before starting UniConfig, disable Cloud Config by using the following properties:","On startup, UniConfig checks the database for any default properties to configure:","If default properties are found in the database, UniConfig manually refreshes its property values to those in the database.","If no default properties are found, UniConfig uses its existing properties and, once loaded, saves them in the database for the next UniConfig instances.","At the end of Spring initialisation, the Refresh Bus Endpoint is not called.","At application runtime, if the update-properties RPC is used with default properties on input, Uniconfig updates the properties in the database but not inside the application. This will therefore only affect the next UniConfig instance started after the properties are updated."]}],[{"l":"Performance characteristics","p":["This page contains reference performance characteristics for Uniconfig.","We try to answer the question how fast can a certain number of devices with a certain amount of configuration be installed and fully synced by","a single Uniconfig instance","3-node Uniconfig deployment with load balancer","The unit of measurement is: Number of configuration lines / per single CPU core / per minute. This number can then be roughly applied to any other similar device being installed by uniconfig."]},{"l":"CLI devices","p":["There are 2 main families of CLI devices: those using Cisco style configuration (configuration in sections) and devices that use one-line style of configuration (without sections) such as Ciena SAOS 8.","It is important to distinguish performance characteristics of these 2 families."]},{"l":"Tree-like style of configuration","p":["Cisco style of confituration (IOS, IOS-XR etc.)","// TBD"]},{"i":"one-line-style-of-configuration-devices-saos-performance-tests","l":"One-line style of configuration devices (SAOS) performance tests","p":["Important caveats:","Measurement were performed on simulated devices = no device overhead","Measurement were performed on a local network = no network overhead","Measured on Uniconfig version 5.0.12","Simulated devices were of two flawors: half with small configuration and the half with big configuration","Tests:","Single node deployment of Uniconfig resources: CPU 4 cores and RAM 4 GB","3 node deployment of Uniconfig - resources per node: CPU 4 cores and RAM 4 GB","3 node deployment of Uniconfig - resources per node: CPU 6 cores and RAM 4 GB"]},{"i":"device-installation--synchronization","l":"Device installation & synchronization"},{"i":"test-a---one-node-uniconfig","l":"Test A - one node Uniconfig","p":["Devices running SAOS operating system (Ciena) and similar","Inputs: 375 x SAOS 6 devices configuration: 8834 json lines = 1510 cli config lines (brief config)","375 x SAOS 8 devices configuration: 277375 json lines = 30705 cli config lines (brief config)","Evaluation: 750 devices were registered in 7.5 hours on single node Uniconfig using 4 cores Average one device instalation duration = (7.5 * 60 minutes) / 750 devices = 0.6 minutes Average number of json lines per device = (8834 + 277375)/2 = 143104 lines lines of json / per core / per minute = 143104 lines / 4 cores / 0.6 minutes = 59626 Average number of cli lines per device = (1510 + 30705)/2 = 16107,5 lines lines of cli / per core / per minute = 16107,5 lines / 4 cores / 0.6 minutes = 6711","Installation & sync rate:","59,626 lines of json / per core / per minute","or","6,711 lines of raw cli configuration / per core / per minute","A single uniconfig node is capable of installing (and fully syncing) 100 Ciena (SAOS 8) devices with 15k lines of configuration(~ 123k lines of formatted json in Uniconfig) in 55 minutes using 4 CPU cores","Recommended batch size for parallel installation in such case would be about 50 devices per batch as the parallelism is limited by the number of available cores."]},{"i":"test-b---3-nodes-of-uniconfig-with-load-balancer","l":"Test B - 3 nodes of Uniconfig with load balancer","p":["Devices running SAOS operating system (Ciena) and similar","Inputs: 750 x SAOS 6 devices configuration: 8834 json lines = 1510 cli config lines (brief config)","750 x SAOS 8 devices configuration: 277375 json lines = 30705 cli config lines (brief config)","Evaluation for 4 core deployment: 1500 devices were registered in 5.5 hours on 3 node Uniconfig deployment each using 4 cores Average one device instalation duration = (5.5 * 60 minutes) / 1500 devices = 0.22 minutes Average number of json lines per device = (8834 + 277375)/2 = 143104 lines lines of json / per core / per minute = 143104 lines / 3 4 cores / 0.22 minutes = 54206 Average number of cli lines per device = (1510 + 30705)/2 = 16107,5 lines lines of cli / per core / per minute = 16107,5 lines / 3 4 cores / 0.22 minutes = 6101","Installation & sync rate:","54,206 lines of json / per core / per minute","or","6,101 lines of raw cli configuration / per core / per minute","A 3 nodes of uniconfig with loadbalancer are capable of installing (and fully syncing) 100 Ciena (SAOS 8) devices with 15k lines of configuration(~ 123k lines of formatted json in Uniconfig) in 19 minutes using 12 CPU cores","Recommended batch size for parallel installation in such case would be about 150 devices per batch as the parallelism is limited by the number of available cores."]},{"i":"test-c---3-nodes-of-uniconfig-with-load-balancer","l":"Test C - 3 nodes of Uniconfig with load balancer","p":["Devices running SAOS operating system (Ciena) and similar","Inputs: 750 x SAOS 6 devices configuration: 8834 json lines = 1510 cli config lines (brief config)","750 x SAOS 8 devices configuration: 277375 json lines = 30705 cli config lines (brief config)","Evaluation for 6 core deployment: 1500 devices were registered in 3.7 hours on 3 node Uniconfig deployment each using 6 cores Average one device instalation duration = (3.7 * 60 minutes) / 1500 devices = 0.148 minutes Average number of json lines per device = (8834 + 277375)/2 = 143104 lines lines of json / per core / per minute = 143104 lines / 3 6 cores / 0.148 minutes = 53717 Average number of cli lines per device = (1510 + 30705)/2 = 16107,5 lines lines of cli / per core / per minute = 16107,5 lines / 3 6 cores / 0.148 minutes = 6046","Installation & sync rate:","53,717 lines of json / per core / per minute","or","6,046 lines of raw cli configuration / per core / per minute","A 3 nodes of uniconfig with loadbalancer are capable of installing (and fully syncing) 100 Ciena (SAOS 8) devices with 15k lines of configuration(~ 123k lines of formatted json in Uniconfig) in 13 minutes using 18 CPU cores","Recommended batch size for parallel installation in such case would be about 150 devices per batch as the parallelism is limited by the number of available cores."]},{"l":"Netconf devices","p":["We use netconf-testtool to simulate devices.","Important caveats:","Measurement were performed on simulated devices = no device overhead","Measured on Uniconfig version 5.2.1","Simulated devices were with small configuration (~ 200 json lines)","Tests:","Single node deployment of Uniconfig resources: CPU 12 cores and RAM 4 GB"]},{"i":"device-installation--synchronization-1","l":"Device installation & synchronization"},{"i":"test-a---one-node-uniconfig-1","l":"Test A - one node Uniconfig","p":["Inputs: 5000 x Netconf devices simulated: 203 json lines","Evaluation 1: 5000 devices were registered in 16.5 minutes on single node Uniconfig using 12 cores Average one device instalation duration = 16.5 minutes / 5000 devices = 0,0033 minutes Average number of json lines per device = 203 lines lines of json / per core / per minute = 203 lines / 12 cores / 0,0033 minutes = 5126","Installation & sync rate:","5,126 lines of json / per core / per minute","A single uniconfig node is capable of installing (and fully syncing) 5000 netconf devices with config of 0.2k lines each of formatted json (in Uniconfig) in 16.5 minutes using 12 CPU cores","5 threads were used and connection-manager:install-multiple-nodes RPC was used (with 20 devices each).","Evaluation 2: 5000 devices were updated in 12.4 minutes on single node Uniconfig using 12 cores Update process consisted of RPCs: Create transaction, Apply template, Calculate diff, Commit After apply template each configuration was increased from 203 to 1282 json lines Average one device update duration = 12.4 minutes / 5000 devices = 0,00248 minutes Average number of json lines per device = 1282 lines lines of json / per core / per minute = 1282 lines / 12 cores / 0,00248 minutes = 43077","Update rate:","43,077 lines of json / per core / per minute","A single uniconfig node is capable of updating (and fully syncing) 5000 netconf devices with initial config of 0.2k json lines each (of formatted json in Uniconfig) in 12.4 minutes using 12 CPU cores After update each device has config of 1.2k json lines each","20 threads were used. No delay among successive updating RPCs"]}],[{"l":"Monitoring"},{"l":"Monitoring using Metrics","p":["UniConfig exposes multiple metrics for traffic and performance monitoring.","Output is generated in two formats:","Plaintext log messages, located in the metrics.log file in the log directory at the root of the distribution.","Raw data in CSV format, located the in metrics directory at the root of the distribution. CSV files can be further processed by third-party visualization tools."]},{"l":"Types of metrics","p":["Gauge - Reports the instantaneous value at a point in time (for example, queue size).","Meter - Measures the total count for event occurences, total mean rate and mean rates for time windows of the past 1, 5 or 15 minutes"]},{"l":"List of notable metrics exposed by UniConfig","p":["Gauges","io.frinx.uniconfig.manager.impl.task.TaskExecutorImpl.queue_size- Number of tasks in the queue waiting for execution","org.apache.sshd.server.SshServer.active_sessions- Number of active CLI sessions","org.opendaylight.controller.uniconfig.transaction.manager.api.UniconfigTransactionManager.open_transaction_count- Number of open transactions","Meters","org.opendaylight.yangtools.yang.common.RpcResult.rpc_invoke- All RPCs invoked by UniConfig","org.opendaylight.controller.uniconfig.transaction.manager.impl.UniconfigTransactionManagerImpl.transaction_invoke- All transactions invoked in UniConfig","io.frinx.uniconfig.shell.cli.SshTerminal.cli_message- All commands invoked in UniConfig shell"]},{"l":"Configuration","p":["Configuration is performed via a section in the application.properties file:"]},{"l":"Example output","p":["metrics/org.opendaylight.controller.uniconfig.transaction.manager.impl.UniconfigTransactionManagerImpl.transaction_invoke.csv:","log/metrics.log:"]}],[{"i":"uniconfig-client-sdk","l":"UniConfig Client (SDK)","p":["Uniconfig client SDK is implemented in Java 17 and uses Uniconfig's RESTconf API.","The SDK provides following advantages over raw RESTconf:","SDK is versioned and tied tied to a specific Uniconfig release","Every version is tested","Type safety","Additional features on top of basic RESTconf facade such as:","Integration with Kafka (notification listener)","Client side diff (to calculate diff between 2 versions of config)","etc."]},{"l":"Basic device configuration management","p":["An example of a simple read & write use case on top of a single device called vnf."]},{"l":"Integration with Kafka","p":["Uniconfig SDK implements a kafka listener that taps into Uniconfig notifications streams and allows the client to consume the notifications easily. Notifications available through Uniconfig are: Device notifications, alerts and telemetry but also Uniconfig generated notifications in the audit log topic. For further information see Uniconfig notifications (kafka)."]},{"l":"Client side diff","p":["Uniconfig SDK offers a diff calculation feature that can calculate a delta between a before device configuration state and after configuration state. This diff is then transformed into a patch operation and sent to Uniconfig's RESTconf API.","Client side diff calculation is useful in specific cases, where a substential amount of configuration data is avalable and modified outside of Uniconfig. Typically, the entire after state would have to be pushed into Uniconfig and Uniconfig would calculate its own diff internally. By calculating on the client side, it is possilble to reduce the network communication between client and Uniconfig (as less data has to be sent) and to reduce how much diff calculation Uniconfig has to do itself (shifting it to the client side).","This feature leverages the same implementation of diff calculation that is used withing Uniconfig itself and requires YANG schemas to be present for the computation.","Example usage:","Notable features of client side diff:","Requires YANG schemas in order to work","JSON data have to conform to those YANG models","Allows for templated values to be present in the JSON","Produces a single PATCH operation containing all changes detected. See YANG patch in Uniconfig","Changes detected: Create, Update, Delete, Reorder (lists and leaf-lists)","Uses the same implementation as Uniconfig's calculate-diff"]}],[{"l":"Developer Guide","p":["This guide provides instructions on how to extend UniConfig to support more devices, commands and operations.","Guides on how to extend UniConfig to support a new device or new commands:","Architecture","Translation Units in general","Translation Units Documentation for FRINX Uniconfig","OpenConfig to device config mapping","Developing a new translation unit","Implementing CLI Translation Unit","NETCONF Unified Translation Unit","Native-CLI translation units","Metrics"]}],[{"l":"Architecture"},{"l":"Pre-requisite reading","p":["Honeycomb design documentation:","https://wiki.fd.io/view/Honeycomb https://docs.fd.io/honeycomb/1.18.04/release-notes-aggregator/release_notes.html","CLI plugin available presentations:","https://www.dropbox.com/sh/ry2ru5vizv7st8u/AAAntbCRHb1yS_NmEpbXG1WBa?dl=0"]},{"l":"Building on honeycomb","p":["The essential idea behind the southbound plugins comes from Honeycomb. Honeycomb defines, implements and uses the same pipeline and the same framework to handle data. The APIs, some implementations and also SPIs used in the southbound plugin's translation layer come from Honeycomb. However, the southbound plugin creates multiple instances of Honeycomb components and encapsulates them behind a mount point.","The following series of diagrams shows the evolution from Opendaylight to Honeycomb and back into Opendaylight as a mountpoint:","High level Opendaylight overview with its concept of a Mountpoint:","ODL","High level Honeycomb overview:","HC","Honeycomb core (custom MD-SAL implementation) overview:","Honeycomb's core","How Honeycomb is encapsulated as a mount point in Opendaylight:","Honeycomb's core as mountpoint"]},{"l":"Major components","p":["The following diagram shows the major components of the southbound plugin and their relationships:","CLI plugin components"]},{"l":"Modules","p":["The following diagram shows project modules and their dependencies:","CLI plugin modules"]}],[{"l":"Translation Units in general"},{"l":"Module structure","p":["Translation unit is a self contained project which implements a mapping between OpenConfig based YANG models and device specific configuration. It is used by the FRINX ODL to perform translation between device specific configuration model and standard (OpenConfig) models. A unit usually consists of:","Handlers","Readers","Writers","TranslateUnit implementation","RPCs"]},{"l":"Handlers","p":["Each complex node in YANG (container, list, augment...) should have a dedicated handler (Reader, Writer)","This enables extensibility, readability and the framework can easily filter and process the data this way","Unless there is a need to also handle child nodes, in which case register the handler using subtreeAdd method from the registries","There are 2 types of handlers: Readers (Read operation) and Writers(Create, Update, Delete operation)","One can implement just the readers or both readers and writers for YANG models. Writers must have counterpart readers because of reconciliation.","Readers and Writers should use the InstanceIdentifier parameter they receive in readCurrentAttributes or writeCurrentAttributes methods to find information about keys for their parent nodes. E.g. Reader registered under ID: /interfaces/interface/config will always receive keyed version of that ID: /interface/interface[Loopback0]/config. So it can use method firstKeyOf on InstanceIdentifier to get the keys.","RWUtils class contains methods for InstanceIdentifier manipulation.","Readers and writers can be easily tested and it is necessary to provide unit tests for all of them. It's important to cover readCurrentAttributes and writeCurrentAttributes with all possible scenarios (all data there, no data there, partial data there...)","Writers may use Preconditions.checkArgument() before accessing the device. Fail of the precondition check does not invoke default rollback(opposite operation) on the writer where precondition is located."]},{"l":"Base Handlers","p":["When a handler for the same YANG node is implemented to conform various devices, it tends to lead to a lot of boilerplate and duplicate code. Therefore, we should implement a base handler for such handlers. How does it work:","create a base-project (if there isn't any) to group base handlers(e.g. for an interface handler, choose interface-baseproject)","each base handler needs to be abstract and implement same interfaces as the original handler","extract common functionality in the base handler. Common functionality means that it will conform the majority of the original handlers. If a handler does not share the extracted functionality, it needs to override original interface methods, to hide the extracted functionality.","let original handlers extend base abstract handler"]}],[{"l":"Translation Units Documentation for FRINX Uniconfig"},{"l":"Auto-generated documentation","p":["A documentation to translation-units that is generated automatically from the source code and javadocs can be found here. This documentation is useful to check actual implementations, whether a functionality is implemented for a particular device and by which protocol (netconf or cli)."]},{"l":"Manual documentation","p":["This repository contains documentation for all available translation units. A translation unit is a piece of code that includes handlers to read from or write to a specific device (e.g. Cisco IOS classic router) and facilitates the translation in OpenConfig models. The purpose of this documentation is to see which commands can be read and set and how they map to the respective YANG models. Every section has a README file that provides an overview of all show and configuration commands that are supported."]},{"l":"OPERATIONAL datasets","p":["Go to operational datasets","Show commands are commands that usually on Cisco device start with'show'. The aim is to obtain data from the router."]},{"l":"URL","p":["GET operation issued on operational datastore"]},{"l":"OPENCONFIG YANG","p":["In case of show commands this section is a sample output of a particular show command."]},{"l":"OS COMMANDS","p":["In this section we list the actual router commands with sample outputs, where the data obtained and transformed into OpenConfig YANG is marked as bold. We list show commands and outputs for each supported device OS.","IOS XR | IOS Classic/XE | Junos"]},{"l":"DEVICE YANG","p":["In case of CLI units, the unit parses the output of the CLI command directly into OC YANG. In case of Netconf units, the output is mapped to OC YANG through Device YANG (YANG model supported by the device). In case of Netconf units, the YANG is also written in documentation. This section is a link to XML unit test input testing this operation."]},{"l":"UNIT","p":["Link to github code where this show command is implemented along with unit version range."]},{"l":"CONFIGURATION datasets","p":["Go to config datasets"]},{"i":"url-1","l":"URL","p":["PUT operation with given URL will result in creating of data in config datastore DELETE operation with given URL will result in removing data in config datastore"]},{"i":"openconfig-yang-1","l":"OPENCONFIG YANG","p":["In case of configuration commands, this section represents the HTTP body in PUT operation"]},{"i":"os-commands-1","l":"OS COMMANDS","p":["In this section we list the actual router commands that are mapped to the OpenConfig YANG model. Data transformed into OpenConfig YANG is marked as bold. We list commands for each supported device OS.","IOS XR | IOS Classic/XE | Junos"]},{"i":"device-yang-1","l":"DEVICE YANG","p":["In case of Netconf units, the device yang represents command sent to the device in device YANG model. This section is a link to XML unit test input testing this configuration."]},{"i":"unit-1","l":"UNIT","p":["Link to github code where this config command is implemented along with unit version range."]}],[{"l":"OpenConfig to device config mapping"},{"l":"Finding mapping between device and the model","p":["Preferred YANG models for device config and operational data are OpenConfig models.","These models usually represent configuration part in container config and operational part in container state. Operational data is config data + operational data.","YANG models used in UniConfig framework need to be located in https://github.com/FRINXio/openconfig. In case the desired functionality is not modeled yet, you can create new YANG with its own structure or it can augment existing OpenConfig models. Guideline, how to write OpenConfig models can be found at http://www.openconfig.net/docs/style-guide/."]},{"l":"Choosing the right YANG models","p":["Before writing a custom YANG model for a unit, it is important to check whether such a model doesn't already exist. There are plenty of YANG models available, modeling many aspects of network device management. The biggest groups of models are:","OpenConfig https://github.com/openconfig/public/tree/master/release/models","IETF https://github.com/YangModels/yang/tree/master/standard/ietf","It is usually wiser to choose an existing YANG model instead of developing a custom one. Also, it is very important to check for existing units already implemented for a device. If there are any, the best approach will most likely be to use YANG models from the same family as existing units use."]},{"l":"Existing documentation","p":["There is translation-units-docs page as a single point of truth for mapping. Use`` notation for variables in the templates. This notation is postman compatible."]}],[{"l":"Developing a new translation unit","p":[".pom file of the unit","add your unit as a dependency to artifacts/pom","dependencies","handlers (readers/writers)","https://github.com/FRINXio/cli-units","https://github.com/FRINXio/unitopo-units","name of the unit should be in format device-domain-unit(e.g. ios-interface-unit, xr-acl-unit)","package name should be in format io.frinxcli|netconf., device name and domain (e.g. io.frinx.cli.unit.ios.interface)","point to correct unit parent","The easiest way how to develop a new transaction unit is to copy existing one and change what you need to make it work. E.g. if you are creating an interface translation unit, the best way is to copy existing interface translation unit for some other device, that is already implemented. You can find existing units on github:","This section provides a tutorial for developing a new translation unit.","Unit class","unit tests","What you need to add:","What you need to change:","What your unit needs to contain:"]},{"i":"best-practices-for-handlers-readerswriters","l":"Best practices for handlers (readers/writers)","p":["All comments are in English","All defined exceptions can be thrown from the code","All new dependencies and imports are actually used","All variables/methods are actually used","Before pushing the code make sure:","Chunk","Code has correct spacing","Commented out code","Comments are appropriate to the code behavior","Constants","Do not push code that contains following:","Double blank lines","java regexes","New classes/interfaces have the correct license header","New classes/interfaces/yang model have correct date","Reflection","Show commands","Static imports","Trailing whitespaces or tabs"]}],[{"l":"Implementing CLI Translation Unit","p":["CLI Translation units are located in https://github.com/FRINXio/cli-units repository. Java is used in CLI translation units."]},{"l":"Init Unit","p":["Init translation unit does not contain readers and writers but it only contains implementation of TranslateUnit. There should be only one init translation unit per device type. Purpose of the init TU is to setup CLI prompt and define rollback strategy.","The implementation of TranslateUnit needs to override methods:","SessionInitializationStrategy getInitializer(@Nonnull final RemoteDeviceId id, @Nonnull final CliNode cliNodeConfiguration)","Implement and return device specific SessionInitializationStrategy where:","Setup device CLI terminal with attributes like width and length allowing to display infinite output.","Enter desired CLI mode which will be used as default - every reader and writer gets CLI prompt in this state (e.g. EXEC mode for IOS, config mode for IOS-XR, cli mode for Junos)","These methods may be overridden if necessary:","getPreCommitHook()- method that is invoked before actual commit is written into device. For example this method can enter configuration mode.","getCommitHook()- method that invokes actual commit and should catch any error on commit. Also it should handle any post-commit actions when the commit was successful.","getPostFailedHook()- method that is invoked when commit fails. Should implement aborts or revert strategies.","getErrorPatterns()- method returning Java Patterns with regular expressions that match device specific error patterns.","getCommitErrorPattern()- method returning Java Patterns with regular expressions that match device specific error patterns that can be returned by the device after issuing commit."]},{"l":"Translate Unit","p":["Handlers(readers/writers) need to be registered in this method. Parameter context.getTransport() returns Cli object containing methods for communication with a device via CLI - should be passed to readers/writers.","Implementation of TranslateUnit must be registered into TranslationUnitCollector and must specify device type and device version during registration. Snippet below shows registration of IosXRInterfaceUnit for device type \"ios xr\" all versions.","Implementation of TranslateUnit must implement these methods:","Instance-identifier in generic reader/writer must be without keys pointing to the target composite node used in implemented reader/writer.","Instance-identifiers for YANG container and list (not for augmentations and nodes behind augmentations) are automatically generated to IIDs class (used in examples bellow) during build of openconfig project.","Return RPC services implemented in the translation unit. Parameter context.getTransport() returns Cli object containing methods for communication with a device via CLI - may need to be passed to RPC implementations. Default implementation returns empty Set.","Return unique string among all translation units which will be used as ID for the translation unit (e.g. \"IOS XR Interface (Openconfig) translate unit\")","Return YANG models containing composite nodes handled by handlers(readers/writers). Default implementation returns empty Set if no handlers are implemented.","Set getRpcs(@Nonnull Context context)","Set getYangSchemas()","Set getSupportedVersions()","String getUnitName()","This method should also registers for general Openconfig checks:","This method should return specific device version that work with this handler.","Translate unit class must implement interface io.frinx.cli.unit.utils.AbstractUnit. Naming convention for translate unit class is device-type+openconfig-domain+Unit (e.g. IosXrInterfaceUnit). Translate unit class is usually instantiated, initialized and closed from Blueprint.","void provideHandlers()"]},{"l":"Ordering of handlers","p":["As the example shows, the ip address command must be executed after the interface command.","Registration of Ipv4ConfigWriter by using the addAfter method ensures that the OpenConfig ip address data is translated after OpenConfig interface data. That means CLI commands are executed in the desired order.","rRegistry.add","rRegistry.addNoop","rRegistry.subtreeAdd","The following sample shows a CLI translation unit with dependency between 2 writers. The unit is dedicated for interface configuration on a Cisco IOS device.","This example uses method subtreeAddAfter instead of subtreeAdd. Last parameter in this method shows dependency on writer registered under IIDs.IN_IN_CONFIG.","Use for writers handling data of whole composite node subtrees. This ensures that if only a child node is updated, the writer gets triggered. Method subtreeAdd requires a set of IIDs for all handled children, the IIDs must start from the reader itself, not from root.","Use to register noop writers","Use when a reader implementation also fills composite child nodes of target composite node. Method subtreeAdd requires a set of IIDs for all handled children.","Use when common GenericConfigListReader, GenericConfigReader,* GenericOperListReader or GenericOperReader need to be registered.","Use when common GenericListWriter or GenericWriter are registered.","VRF writer should be between them. If the order is not expressed during registration, commands might be executed on device in an unpredictable/invalid order.","wRegistry.add","wRegistry.subtreeAdd","Writers are stored in a linear structure and are invoked in order of registration. When registering a writer a relationship with another writer or set of writers can be expressed using addBefore, addAfter, subtreeAddBefore, subtreeAddAfter methods. E.g. InterfaceWriter and VRFInterfaceWriter should have a relationship: InterfaceWriter -> VRFInterfaceWriter so that first an interface is created and only then assigned to VRF."]},{"l":"Device registration","p":["In TranslateUnit we had just created, e.g. MplsUnitXR4.java, we have to register device as a constant located../iosxr/init/IosXrDevices.java containing device type and version as described in TranslateUnit documentation.","This unit can reuse all writers/readers from existing ones, except the writer (or other handler) we want to alter or create (in our example writer for tunnel configuration). We have to create a new writer with desired behaviour and add it into provideWriters method."]},{"l":"Readers","p":["Readers are handlers responsible for reading and parsing the data coming from a device","There are 2 types of readers: Reader and ListReader. Reader can be used to handle container or augmentation nodes and ListReader should handle list nodes from YANG.","Both types need to implement readCurrentAttributes to fill the builder with appropriate values","ListReader needs to also implement getAllIds() where it retrieves a key for each item to be present in current list. After the list is received, framework will invoke readCurrentAttributes for each item from getAllIds","Readers should always use overloaded blockingRead method which takes in the ReadContext since that method performs caching internally","Use full version of commands e.g. show running-config interface instead of sh run int"]},{"l":"Reading of CLI and device configuration","p":["CLI readers maintain translation between device and yang models. We're sending read commands to the device and outputs are cached. This process is shown below.","Reading CLI conf from device"]},{"i":"reading-of-configuration-from-cli-network-device---different-scenarios","l":"Reading of configuration from CLI network device - different scenarios","p":["The diagram below shows four specific scenarios:","Configuration is read using show running-config pattern for the first time","Another configuration is read using running-config pattern","cache can be used","BGP configuration/state is read using \"show route bgp 100\"","the running-config pattern is not used","BGP configuration/state is read using \"show route bgp 100\" again","cached can be used","Different scenarios"]},{"l":"Mandatory interfaces to implement","p":["Each reader needs to implement one of these interfaces based on type of target node in YANG. These interfaces also contain util methods which may be used for better manipulation with data. For more information about methods please read javadocs.","CliConfigListReader- implement this interface if target composite node in YANG is list and represents config data.","CliConfigReader- implement this interface if target composite node in YANG is container or augmentation and represents config data.","CliOperListReader- implement this interface if target composite node in YANG is list and represents operational data.","CliOperReader- implement this interface if target composite node in YANG is container or augmentation and represents operational data.","In cases where you want to invoke multiple readers on reading one YANG node, extend following abstract classes:","CompositeListReader- extend this abstract class if multiple list readers need to be invoked when reading specific list in YANG.","CompositeReader- extend this abstract class if multiple readers need to be invoked when reading specific node in YANG.","A practical example of their usage is reading network instance based on it's type. All child readers need to implement a check when the particular reader should be invoked or the parent reader should move on to the next reader.","For example child reader for bgp (located under protocol) needs to check if identifier in protocol has value BGP. Otherwise reader for bgp will be invoked even if protocol identifier is OSPF."]},{"l":"Util classes","p":["ParsingUtils- use methods of this util class if you want to parse plaintext to java object builder"]},{"l":"Plaintext parsing hints","p":["Use as specific regular expressions when parsing CLI output as possible.","For Cisco CLI devices avoid using section and other advanced formatting parameters. Only include, exclude and begin are allowed.","Use CONFIG data as the source of truth when parsing information from device. Except when parsing state containers (or containers explicitly marked as config false).","I.e. use show running-config | include router ospf instead of sh ospf when retrieving ospf routers list.","In some cases, it is not possible to just use config data e.g. sh run interface does not show any data for interfaces that have no configuration. In this case it is necessary to use operational information from e.g. show ip interface brief","Use following pattern when parsing multiline output from CLI, where it is difficult to extract lines and their relationships: i.e. when parsing configured BGP neighbors per address family following command can be used:","which results in:","This output can then be parsed by:","Remove newlines to get a single line of string","Replace \"router\" with \"\" to separate bgp routers per line","Find the line that matches required router bgp","Take that line and replace \"address-family\" with \"-family\" to get address-family neighbors per line"]},{"l":"Base Readers","p":["Each base reader should contain abstract methods:","String getReadCommand()- each child reader should fill in the read command used to get information needed for this reader. Arguments may vary and they are used to be more specific in the read command (eg. when creating a command to gather information about a specific interface, you may want to pass interface name as argument).","Pattern getLine(>)- there may be more such methods and they are used to get the regular expression needed to parse output of the command (eg. in case of interface reader, you will create methods getDescriptionLine, getShutdownLine etc.)","Naming of the methods should be unified in order to be easily parsed by auto-generated documentation."]},{"l":"Writers","p":["A writer needs to implement all 3 methods: Write, Update, Delete in order to fully support default rollback mechanism of the framework","Time showed that update like 1. delete, 2. write is anti-pattern and should not be used. There is just one case where it is necessary: when re-writing list entry, you must first delete the previous entry, then write the new one, otherwise the previous entry would still be present and the new entry will be added to the list.","A writer can properly work only if there is a reader for the same composite node.","A writer should check whether the command it executed was handled by the device properly (by checking the output) and if not throw one of the Write/Update/Delete FailedException","Chunk templating framework is preferred to use in writers. It gives us:","Null safety","if/loop etc. inside templates","Default values and many more","Use full version of commands e.g. configure terminal instead of conf t"]},{"i":"mandatory-interfaces-to-implement-1","l":"Mandatory interfaces to implement","p":["Each writer needs to implement one of these interfaces based on type of target node in YANG. Unlike mandatory interfaces for reading, only interfaces for writing config data are available (because it is not possible to write operational data). These interfaces also contain util methods which may be used for better manipulation with data. For more information about methods please read javadocs.","All writers override updateCurrentAttributes method and avoid delete/write combination, unless specified in a comment.","CliListWriter- implement this interface if target composite node in YANG is list. An implementation needs to be registered as GenericListWriter.","CliWriter- implement this interface if target composite node in YANG is container or augmentation. An implementation needs to be registered as GenericWriter.","CompositeWriter- extend this abstract class when multiple writers need to be invoked on one YANG node. The writers need to implement a check whether or not should they be invoked."]},{"l":"Base Writers","p":["Each base writer should contain abstract methods:","String updateTemplate(Config before, Config after) this method returns Chunk template used for writing and updating data on the device.","String deleteTemplate(Config data) this method returns Chunk template used for deleting data from device.","If updating data is done differently than writing new data, method String writeTemplate(Config data) might be used as well."]},{"l":"Chunk Templates","p":["Each original writer transformed to use a base writer should have all it's templates written in Chunk. We extended Chunk to achieve easier manipulation with data. There is now a new filter called update. It's usage is following:","\"{$data|update(mtu,mtu $data.mtu, no mtu)}\"","$data represents the data structure on which we check if it was updated from the previous state.","mtu first argument represents the name of the field that should be checked within the $data","$data.mtu second argument represents the actual string that will be sent to the device if the value of the field named in first argument was changed or didn't exist before","no mtu third argument represents the actual string that will be sent to the device if the value of the field named in first argument was deleted","optional true fourth argument, if present, lets the filter know it should send both outputs to the device, first the delete string(third argument) then the update string (second argument)","Update filter does not send any of the strings to the device, if the value did not change.","When using this filter in updateTemplate method, you must use fT() method (format template) with one pair of the arguments being \"before\", before to let the template know what data represents the previous state.","Unfortunately, Opendaylight generates boolean fields instead of Boolean and Chunk does not work with boolean fields in the same way as any other object fields. Therefore for boolean values (eg. shutdown), you cannot use update filter and checking for changes needs to be done in a traditional way."]}],[{"l":"NETCONF Unified Translation Unit","p":["Unified translation units are located in https://github.com/FRINXio/unitopo-units repository.","Kotlin is used as preferred programming language in NETCONF translation units because it provides type aliases and better null-safety."]},{"l":"TranslateUnit","p":["Translate unit class must implement interface io.frinx.unitopo.registry.spi.TranslateUnit. Naming convention for translate unit class is just name Unit. Translate unit class is usually instantiated, initialized and closed from Blueprint.","Implementation of TranslateUnit must be registered into TranslationUnitCollector and must provide set of supported underlay YANG models. Snippet below shows registration of Unit for junos device version 17.3.","Implementation of TranslateUnit must implement these methods:","toString(): String","Return unique string among all translation units which will be used as ID for the translation unit (e.g. \"IOS XR Interface (OpenConfig) translate unit\")","getYangSchemas(): Set","Return YANG models containing composite nodes handled by handlers(readers/writers). It must return empty Set if no handlers are implemented.","getUnderlayYangSchemas(): Set","Return YANG module informations about underlay models used in the translation unit. These YANG modules describes configuration of NETCONF capable device.","getRpcs(underlayAccess: UnderlayAccess): Set>","Return RPC services implemented in the translation unit. Default implementation returns an emptySet. Parameter underlayAccess represents object containing methods for communication with a device via NETCONF and should be passed to readers/writers.","provideHandlers(rRegistry: ModifiableReaderRegistryBuilder, wRegistry: ModifiableWriterRegistryBuilder, underlayAccess: UnderlayAccess): Unit","Handlers(readers/writers) need to be registered in this method. underlayAccess represents object containing methods for communication with a device via NETCONF and should be passed to readers/writers.","How to register readers/writers is described in CLI Translation Unit "]},{"l":"Readers","p":["Readers are handlers responsible for reading and parsing the data coming from a device.","There are 2 types of readers: Reader and ListReader. Reader can be used to handle container or argument nodes and ListReader should handle list nodes from YANG.","Both types need to implement readCurrentAttributes to fill the builder with appropriate values","ListReader needs to also implement getAllIds() where it retrieves a key for each item to be present in current list. After the list is received, framework will invoke readCurrentAttributes for each item from getAllIds"]},{"l":"Mandatory interfaces to implement","p":["Each reader needs to implement one of these interfaces based on type of target node in YANG.For more information about methods please read javadocs.","ConfigListReaderCustomizer- implement this interface if target composite node in YANG is list and represents config data.","ConfigReaderCustomizer- implement this interface if target composite node in YANG is container or augmentation and represents config data.","OperListReaderCustomizer- implement this interface if target composite node in YANG is list and represents operational data.","OperReaderCustomizer- implement this interface if target composite node in YANG is container or augmentation and represents operational data."]},{"l":"Base Readers","p":["Each base reader for netconf readers should be generic. The generic marks the data element within device YANG that is being parsed into. The base reader should contain abstract methods:","fun readIid(): InstanceIdentifier- each child reader should fill in the device specific InstanceIdentifier that points to the information needed for this reader. Arguments may vary and they are used to be more specific IID (e.g. when creating an IID to gather information about a specific interface, you may want to pass interface name as argument).","fun readData(data: T?, configBuilder: ConfigBuilder, )","this method is used to transform OpenConfig data (contained in ConfigBuilder) into device data (T) using .","Naming of the methods should be unified in order to be easily parsed by auto-generated documentation."]},{"l":"Writers","p":["A writer needs to implement all 3 methods: Write, Update, Delete in order to fully support default rollback mechanism of the framework","Time showed that update like 1. delete, 2. write is anti-pattern and should not be used. There is just one case where it is necessary: when re-writing list entry, you must first delete the previous entry, then write the new one, otherwise the previous entry would still be present and the new entry will be added to the list.","A writer can properly work only if there is a reader for the same composite node.","The framework provides safe methods to use when handling data on device:","safePut deletes or adds managed data. Does not touch data that was previously on the device and is not handled by the writer.","safeMerge stores just the changed data into device. Does not touch data that was previously on the device and is not handled by the writer.","safeDelete removes data from the device only if the managed node does not contain any other information (even one not handled by the writer)"]},{"i":"mandatory-interfaces-to-implement-1","l":"Mandatory interfaces to implement","p":["Each writer needs to implement one of these interfaces based on type of target node in YANG. Unlike mandatory interfaces for reading, only interfaces for writing config data are available (because it is not possible to write operational data). For more information about methods please read javadocs.","ListWriterCustomizer- implement this interface if target composite node in YANG is list. An implementation needs to be registered as GenericListWriter.","WriterCustomizer- implement this interface if target composite node in YANG is container or augmentation. An implementation needs to be registered as GenericWriter."]},{"l":"Base Writers","p":["Each base writer should be generic and contain abstract methods:","fun getIid(id: InstanceIdentifier): InstanceIdentifier-this method returns InstanceIdentifier that points to a node where data should be written","fun getData(data: Config): T- this method transforms OpenConfig data into device specific data (T)"]}],[{"l":"Native-CLI translation units"},{"l":"Modules structure","p":["The following text block displays a structure of native-cli units that are placed under root 'cli-native-units' module with 2 device types - ios-xr-5 and junos-17. There are also init units under 'ios-xr' and'junos' directories - they are still required to be implemented, however they are already part of classic translation units. The first identifier corresponds to directory name, the second identifier placed in brackets corresponds to module name. All modules are represented by 'pom.xml' files.","Description of the modules:","cli-native-units: Root module that groups all native-CLI-only modules. Submodules are specified per device-type.","unit-parent: Parent unit common for all unit modules (for example 'ios-xr-5-native-unit' and 'junos-17-native-unit'): it specifies common imports. It doesn't need any modification when a new device-type is added.","ios-xr-5-native and junos-17-native: These modules just group unit and models submodules for specific device-types. Each supported device type should have its separated module.","ios-xr-5-native-models and junos-17-native-models: They contain all YANG schemas under \"src/main/yang\" directory - device-template YANG schemas and native-CLI YANG schemas. They are described in next sections in detail.","ios-xr-5-native-unit and junos-17-native-unit: Implementations of native-CLI translation units - these modules contain only single Java file under 'io.frinx.cli.cnative.iosxr5' or'io.frinx.cli.cnative.junos17' package that is responsible for registration of YANGs and providing of device-specific information. More information can be found in the next section.","ios-xr-cli-init-unit and junos-cli-unit-unit: Reused initialization units that are required to be registered as native-cli translation units too. These units can be shared by both classic units which require implementations of handlers and native-CLI units. It is achieved by extending of'AbstractUnitWithNativeSupport' abstract class."]},{"l":"Implementation of units"},{"l":"Device-specific units","p":["All device-specific native-CLI units must extend 'GenericCliNativeUnit' abstract class. Description of the implemented methods:","getYangSchemas(): Returned set must contain all device-specific native-CLI schemas that are placed under models module except device-template YANG module that doesn't have to be placed to this set.","getRootInterfaces(): Returned list must contain all classes of root lists and containers (classes generated by MD-SAL generators from YANG schemas) - it simplifies transition between binding-aware and binding-independent worlds.","getSupportedVersions(): Set of supported device versions - it is used for identification of translation units.","getUnitName(): Name of the translation unit - it has only descriptive purposes.","getCliFlavour()(optional): By default, Cisco IOS CLI flavour is used. CLI flavour describes formatting of device running / candidate configuration that is used during parsing of configuration into the tree. Non-Cisco devices should override this method and provide custom CLI flavour in order to make native-CLI readers work (see next example with comments that describe CLI flavour parameters).","Example: Implementation of JUNOS 17 native-CLI unit:"]},{"l":"Init units","p":["Rules for implementation of init units are same for native-CLI and classic units - see documentation: \"Implementing CLI Translation Unit\", subsection \"Init Unit\". The only difference is in the extended class - if an init unit must be registered as both native-CLI and classic translation unit (the most usual scenario), then init unit must extend'AbstractUnitWithNativeSupport' and not just 'AbstractUnit' abstract class."]},{"l":"Device-template YANG model","p":["These YANG schemas are used for describing of device-specific patterns that are required for successful communication with remote CLI. Device-template YANG schema doesn't contain any data schema nodes, it consists only from YANG extensions that are declared in the'cli-native-extensions' model. Multiple native-CLI YANG models can import the same device-template model.","Sample device-template model for IOS XR 5.* devices:","Description of the supported extensions that can be used in a device-template:","show-command: Command used for displaying of the whole running / candidate configuration. It is used for initial population of the device configuration tree that is transformed into DOM format in native-CLI readers. The default string is \"show running-config\".","config-pattern: Template used for 'set' commands that apply a new configuration or update an existing configuration. It must contain '#' placeholder that is replaced by actual command that is going to be sent to remote CLI in native-CLI writers. Default string is \"#\" (without any prefix).","delete-pattern: Template used for 'delete' commands that remove some configuration from a device. It must contain '#' placeholder that is replaced by actual delete command that is going to be sent to remote CLI in native-CLI writers. Default string is\"no #\"."]},{"l":"Native-CLI YANG model","p":["These YANG models are used for modelling of device configuration. Currently supported schema nodes include containers, lists, choice nodes, and leaves with different types. Groupings can also be freely used for organization of YANG structure. The following subsections explain general structure of the native-CLI YANG model and application of different schema nodes for modelling of device configuration with examples.","Augmentations are currently not supported in native-CLI models (except the augmentations into UniConfig configuration container which is required)."]},{"l":"Structure","p":["The following YANG snippet shows structure that should all native-CLI YANG schemas follow (variable parts are marked by square brackets):","Description of variables:","[device-type]: Type of the device for which this YANG models some part of the configuration. Examples: junos17, xr5 (if it is necessary, more specific versions can be typed).","[entity]: Part of the configuration that is modelled by this YANG. Examples: interfaces, firewall, acl.","[prefix]: Prefix that is usually an abbreviation derived from the name of the model.","[template-model]: Name of the imported device-template module. Only a single device-template module can be imported, otherwise the whole module is marked as invalid and it is skipped. Afterwards, revision-date and prefix must be selected too.","[revision] with [description]: Date of the YANG modification with description, what was changed in the specific revision. Multiple revisions can be added incrementally as YANG schema is modified.","[root-grouping]: Identifier of the root grouping that contains single root container or list. Multiple root groupings are allowed when multiple root containers are lists are required. For each root grouping there must be a separate augmentation into 'configuration' container.","Importing of the device-template model is not necessary at all - in that case, the default device template is applied - Cisco IOS XR template."]},{"l":"Containers","p":["Containers are used for representations of nodes in configuration which can have at least one child node but there is only one instance of configuration that is placed under this node. For example, let assume the following two lines in the XR 5.3.4 configuration of access-lists:","In this snippet, ipv6 is modelled by container schema node with the same identifier, because 'ipv6' command word is a root node and it can contain only single instance of list with identifier access-list:","It is also possible to wrap multiple containers in a chain. For example, the following command line:","can be modelled by following containers:"]},{"l":"Lists","p":["Similarly to containers, lists also represent command words that may have multiple children nodes. However, nodes represented by lists can have multiple instances in the configuration where individual instances are represented by one or multiple keys. Values of keys are represented by command nodes that follow list command word. For example, let consider following configuration of XR 5.3.4 interfaces:","In this case, 'interface' can be modelled as list schema node with'interface' identifier. It has a one key - interface name (possible values, based on the example, are 'MgmtEth0/0/CPU0/0', GigabitEthernet0/0/0/0, GigabitEthernet0/0/0/1, and GigabitEthernet0/0/0/2).","Name of the leaves that represent list keys are not important. Only an order of keys, in case of multiple keys, has a significance from the view of association between configuration and YANG model.","The second example presents a scenario in which a list with multiple keys must be used (IOS XR 5.3.4 access-lists):","There are two keys - name of the access-list and sequence number of the access-list entry that must be unique in scope of the single access-list. Because of this, access-list can be modelled by following list schema node:"]},{"l":"Choices","p":["Identifiers of list, container, or leaf schema nodes are always derived from words identifying parts of the command lines. Choice schema nodes are modelled differently - they are only used for modelling of multiple non-overlapping sets of children commands. Both identifier of choice schema node and case nodes are not important (names of the case schema nodes are usually chosen based on logical option they represent). Choices are handy, if it is required to add YANG-based constraint on combinations of entered commands - wrong combinations of command would fail on device anyway.","For example, the JUNOS 17 allows configuration of different interface types:","In this example, 'hold-time' is a configuration that can be applied only on physical interfaces. On the other side, LACP can be configured only on the bundle interfaces. Because of this logical separation, it has a sense to differ between physical and bundle interfaces in YANG (common settings can be placed directly under 'interfaces' list):"]},{"l":"Leaves","p":["Leaves are used for representation of command parts that don't have next children subcommands. Command node can be represented by one or more words depending on the type of the leaf. The following types of leaves are currently supported:","1. Empty: Empty leaf can be used for commands without any value(there is only one command word that identifies leaf). For example, JUNOS 17 interface 'disable' command:","can be modelled as leaf with empty type:","2. Types with primitive value: Supported primitive types include boolean, string, decimal, int8, int16, int32, int64, uint8, uint16, uint32, and uint64. All of these types can be used for commands that has a single string, boolean, or numeric value (types constrained by a range). The following commands can be modelled as one of these types(different JUNOS 17 damping settings):","YANG representation of leaves 'half-life' and 'suppress':","3. Enumeration- If there are multiple but finite set of possible strings assignable to the command, then the enumeration type should be used. Let consider the following variations of the 'mode' command (IOS XR 5.3.4 LACP configuration):","In this example, 'mode' is modelled as leaf with type enumeration with three possible values:","4. Bits: This type of leaf can be used in scenarios in which there are multiple possible values assignable to the command (similarly to enumeration), but they are not mutually exclusive - different values can be combined in a chain of strings. Consider the following options how to configure Unicast Reverse Path Forwarding on IOS XR 5.3.4:","The part of the command line starting by word 'any' can continue with random combination of options 'allow-self-ping' and 'allow-default' with random ordering too. Because of this reason, leaf with identifier 'any' has bits type:","5. Blob-data- It is a special type of leaf defined in'cli-native-extensions' that can be used for the whole command section with a random structure. It is handy for the parts of the configuration that are too complicated to be represented by different YANG structures. Internally, 'blob-data' is a type definition derived from string type. For example, JUNOS 17 firewall rules fulfils high complexity:","Commands 'from' and 'then' can be represented by leaves with'blob-type':"]}],[{"l":"Metrics"},{"l":"Monitoring Uniconfig performance","p":["Micrometer Metrics is the framework of choice to monitor performance."]},{"l":"Registry naming","p":["All the metrics are currently stored in the global registry. It can be accessed like so:"]},{"l":"Metric types","p":["All the available metric types can be seen in the documentation."]},{"l":"Naming convention","p":["There are various best practice articles on how to name metrics but one thing is common: It should be clear what is measured."]},{"l":"Adding new metrics"},{"l":"Adding a Counter","p":["Obtain a Counter and then increment all the method calls you want to measure."]},{"l":"Adding a Gauge","p":["Here we create a Gauge that returns Integer value, access is synchronized in this case to avoid race conditions."]},{"l":"Tags","p":["Tags are currently not available in the version 4.2.x, although support for them is planned for future major release."]},{"l":"Reporters","p":["Metrics are available at /actuator/prometheus endpoint."]}],[{"l":"Release notes","p":["Release notes for UniConfig 4.2.10","Release notes for UniConfig 4.2.3","Release notes for UniConfig 4.2.4","Release notes for UniConfig 4.2.5","Release notes for UniConfig 4.2.6","Release notes for UniConfig 4.2.7","Release notes for UniConfig 4.2.8","Release notes for UniConfig 4.2.9","Release notes for UniConfig 5.0.1","Release notes for UniConfig 5.0.10","Release notes for UniConfig 5.0.11","Release notes for UniConfig 5.0.12","Release notes for UniConfig 5.0.13","Release notes for UniConfig 5.0.14","Release notes for UniConfig 5.0.15","Release notes for UniConfig 5.0.16","Release notes for UniConfig 5.0.17","Release notes for UniConfig 5.0.18","Release notes for UniConfig 5.0.19","Release notes for UniConfig 5.0.2","Release notes for UniConfig 5.0.20","Release notes for UniConfig 5.0.21","Release notes for UniConfig 5.0.22","Release notes for UniConfig 5.0.23","Release notes for UniConfig 5.0.24","Release notes for UniConfig 5.0.25","Release notes for UniConfig 5.0.3","Release notes for UniConfig 5.0.4","Release notes for UniConfig 5.0.5","Release notes for UniConfig 5.0.6","Release notes for UniConfig 5.0.7","Release notes for UniConfig 5.0.8","Release notes for UniConfig 5.0.9","Release notes for UniConfig 5.1.0","Release notes for UniConfig 5.1.1","Release notes for UniConfig 5.1.10","Release notes for UniConfig 5.1.11","Release notes for UniConfig 5.1.12","Release notes for UniConfig 5.1.13","Release notes for UniConfig 5.1.14","Release notes for UniConfig 5.1.15","Release notes for UniConfig 5.1.16","Release notes for UniConfig 5.1.17","Release notes for UniConfig 5.1.18","Release notes for UniConfig 5.1.19","Release notes for UniConfig 5.1.2","Release notes for UniConfig 5.1.20","Release notes for UniConfig 5.1.21","Release notes for UniConfig 5.1.22","Release notes for UniConfig 5.1.23","Release notes for UniConfig 5.1.3","Release notes for UniConfig 5.1.4","Release notes for UniConfig 5.1.5","Release notes for UniConfig 5.1.6","Release notes for UniConfig 5.1.7","Release notes for UniConfig 5.1.8","Release notes for UniConfig 5.1.9","Release notes for UniConfig 5.2.0","Release notes for UniConfig 5.2.1","Release notes for UniConfig 5.2.2","Release notes for UniConfig 5.2.3","Release notes for UniConfig 5.2.4","Release notes for UniConfig 5.2.5","Release notes for UniConfig 5.2.6","Release notes for UniConfig 5.2.7","Release notes for UniConfig 6.0.0","Release notes for UniConfig 6.0.1","Release notes for UniConfig 6.0.2","Release notes for UniConfig 6.0.3","Release notes for UniConfig 6.0.4","Release notes for UniConfig 6.0.5","Release notes for UniConfig 6.0.6","Release notes for UniConfig 6.0.7","Release notes for UniConfig 6.0.8","Release notes for UniConfig 6.0.9","Release notes for UniConfig 6.1.0","Release notes for UniConfig 6.1.1","Release notes for UniConfig 6.1.2","Release notes for UniConfig 6.1.3","Release notes for UniConfig 6.1.4","Release notes for UniConfig 6.1.5","Release notes for UniConfig 6.1.6","Release notes for UniConfig 7.0.0","Release notes for UniConfig 7.0.1"]}],[{"i":"uniconfig-507-release-notes","l":"Uniconfig 5.0.7 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implementation of context-match shell operation"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed establishing of NETCONF stream sessions","Fixed NetconfDeviceCommunicatorTest","Fixed Uniconfig client json parser tests","Fix building history output","Fixed execution of YANG action under some list entry from shell","Fixed ordering transaction log by date","Fixed types of the network-instance/interfaces","Making subscription monitoring loop more robust","Cli session closed/disconnected","Fixed removing of data-change-event subscription","Fixed merging template attribute to replaced node","CLI shell: harmonised composite key delimiter input"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Updated netconf-node-topology:concurrent-rpc-limit parameter","Refactored global DOMSchemaService","Optimization of calculate-diff RPC","Swagger and YangPackager improvements","Fix all owasp sec issues level 8","Upgrade sshd libs to version 2.8.0","Upgrade and cleanup usage of jaxb","Upgrade jetty/jersey/jax-rs dependencies","Reorganisation of NETCONF connection parameters"]}],[{"i":"uniconfig-506","l":"UniConfig 5.0.6"},{"i":"new-features","l":"✅ New Features"},{"l":"Expose operational data about transactions","p":["It would improve visibility what transactions are open on uniconfig instance - when these transactions have been open and what nodes have been changed in the transaction.","Transaction data:","identifier (uuid)","trace id / different parameter (once we support tracing)","creation time","last access time","idle timeout, hard timeout","list of changed nodes (incl. topologies)","additional context (random string, text column)"]},{"l":"Implement metric collection and reporting in Uniconfig","p":["Collect and report metrics such as:","TX pre minute","RPC calls per minute","Task execution queue size","Netconf msg sent count","CLI command sent count","…","Reporting part could be just logging the state of metrics for the time being"]},{"i":"collect-open-transactions-data-in-collect_diag_infosh","l":"Collect open transactions data in collect_diag_info.sh","p":["Please enhance debug collection script to collect details of following","Open Transaction , Read or Read-Write and if possible module which has opened the transaction","For example, this is how NCS displays.","This could help in debugging slowness issues caused if there is any transaction leak."]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements"},{"l":"Set OWASP dependency check plugin to level 9","p":["decrease owasp level to 9 (in distribution/packaging/zip pom)","fix all dependency issues so that uniconfig will successfully build"]},{"i":"cli-uc-shell---show-transaction-log-in-ordered-list--add-brief-option","l":"CLI UC shell - show transaction log in ordered list & add \"brief option\"","p":["Currently we display the transaction log as a json without ordering. We should assume that the transaction log can become very large and should still be manageable to display. Hence we are proposing the following improvements:","always show the transaction log as an ordered list. Order by transaction timestamp. The most recent transaction should be at the bottom of the list.","add a \"brief\" option to that command and display only one line per transaction log. Similar like this"]},{"i":"bug-fixes","l":"❌ Bug Fixes"},{"l":"OpenAPI .yaml file generating incorrectly","p":["Build, Collaborate & Integrate APIs | SwaggerHub","cli-unit-general API yaml seems incorrectly generated, URIs are wrong"]},{"i":"syst_-data-change-subscriptionscontentnonconfig-not-working","l":"SYST_ data-change-subscriptions?content=nonconfig not working","p":["Based on documentation Kafka notifications","test:","test here https://gerrit.frinx.io/c/system-tests/+/13155"]}],[{"i":"uniconfig-505","l":"UniConfig 5.0.5"},{"i":"improvements","l":"\uD83D\uDCA1 Improvements"},{"l":"Reconfigure swagger generator for versa to produce desired depths for all APIs","p":["Since we need to create APIs with depth 4, I have noticed APIs are created to the last container when the depth of yang is less than 4. Can you make API is not generated for the last container, for example 2nd API in the below not required as “global” is the leaf container. This change will reduce size of yaml file and number of APIs"]},{"i":"bug-fixes","l":"❌ Bug Fixes"},{"l":"Uniconfig transaction is not thread-safe","p":["It is not safe to use same uniconfig transaction simultaneously by multiple user-side threads because underlying database connection/transaction is not thread-safe in case of PostgreSQL driver and UniConfig is not doing any additional synchronisation.","Read: Chapter 10. Using the Driver in a Multithreaded or a Servlet Environment","Behaviour that was also observed in UniConfig (it is Oracle DB, but symptoms are similar): Working with multiple threads sharing a single connection"]},{"i":"failed-to-find-node--in-the-topology-uniconfig","l":"Failed to find node '' in the topology 'uniconfig'","p":["It happened already a couple of times when a workflow task failed during the execution of getting data from the device. In VFZ we have a specific task for this operation called uniconfig_read_structured_device_data which gets a specific config from the device","During this execution, there were other devices running in the parallel executing the same task and 2 read_and_execute_rpc_cli tasks too.","The device had the records in the node and mounpoint tables in the UC DB.","DONE, MOVE TO 5.0.4"]}],[{"i":"uniconfig-504","l":"UniConfig 5.0.4"},{"i":"new-features","l":"✅ New Features"},{"l":"Adding option to use json-path also for selection of some subtrees","p":["Currently, jsonpath language can be used in UniConfig only for filtering of data. However, the language itself allows also to select some data using provided json-path.","We need to expose this functionality in UniConfig API using some query parameter (the similar way as it is done for filtering) and also expose this functionality in the uniconfig-client."]},{"i":"shell-scrolling-output---more--","l":"Shell: scrolling output (--more--)","p":["Long UniConfig shell output should be displayed using some scrolling mechanism (equivalent to ‘more' or 'less’ linux tools)."]},{"i":"add-show-history-command-to-uniconfig-shell","l":"Add 'show history' command to uniconfig-shell","p":["It should display last N commands that were executed in the shell. Syntax:","Parameter 'max-number-of-output-commands' should be optional.","This command should be available from both operational and configuration modes."]},{"l":"Add support for aliases inside uniconfig shell","p":["There should be some configuration file in the config directory that will contain defined aliases. It should support also place-holders/variables for both values and arrays.","Supporting autocomplete on aliases."]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements"},{"l":"Improve maven plugin for generation Java classes","p":["yang packager: generate sources only for latest repository","settings: package name - option to change it","setting: disable prefix + javadoc on data-elements"]},{"i":"bug-fixes","l":"❌ Bug Fixes"},{"l":"NETCONF sessions used for receiving NETCONF notifications stop working","p":["UniConfig does not use keepalive messages for checking, if NETCONF session used for receiving of NETCONF notifications is still alive and triggering reconnection procedure. As a consequence, if connection is dropped without explicit TCP interruption, then UC will not find it out and doesn’t try to re-create connection. However, device is using some form of TCP keepalive messages - device will drop connection after some time.","FIX: Uniconfig is enables and tracks keepalive messages also for NETCONF sessions that are used for NETCONF streams"]},{"l":"Optimisation of jsonb-filtering","p":["It seems that jsonb-filtering causes reading of whole configuration from PG into UC even if it should not be necessary:","checking existence of the node - currently it works by using DOM ‘exists’ operation that reads whole configuration from DB","deriving uniconfig-native prefix / YANG repository - it is derived from configuration, not from DB metadata","FIX: stopping verification of node, if jsonb-filer is used. It required reading of whole config from DB to Uniconfig what making the call much slower."]},{"i":"uc-shell-after-configrequest-commit-the-prompt-was-changed-unexpectedly-from-request-to-config","l":"Uc shell: after config/request commit the prompt was changed unexpectedly from request> to config>","p":["Previous behaviour:","After fix:"]},{"i":"uc-shell-config-mode--show-or-delete---create-object-option-should-be-removed","l":"Uc shell: config mode / show or delete - CREATE OBJECT option should be removed","p":["Previous behaviour:","e.g. here (create new template) should not be present here. Similarly others places in program. Behaviour like this is not expected by user.","After fix:"]},{"i":"uniconfig-503-prints-out-error-on-start","l":"Uniconfig 5.0.3 prints out error on start","p":["Fix: error message in the log was displayed when notifications were set to false in the lighty-uniconfig-config.json file. This error message is no longer displayed."]},{"l":"Flyway migration failed","p":["Migration of data in the database when switching to another version throws error causing that uniconfig is unable to start."]},{"l":"Yang patch operation does not work correctly with leaf list","p":["There are several issues with yang patch when operating on leaf-lists. In particular I have found issues with the insert operation and the merge operation.","Merge operation case:","If the leaf list does not exist, then the merge operation pass without problems. However, if the leaf list does already exist, then the merge fails with following error message:","Insert operation case:"]},{"l":"PATCH operation does not work with some paths and target combination","p":["Overview RestConf PATCH operation does not work with certain combination of URL and target","Details","Request URL ( is the UniConfig host, is the id under which the Sonic device is installed):","http:///rests/data/network-topology:network-topology/topology=uniconfig/node=/frinx-uniconfig-topology:configuration/openconfig-interfaces:interfaces/interface=Ethernet52","Method: PATCH Request body:","Produce this response:","Request body:","Produce empty response body with error code 500. UniConfig logs have this record:"]},{"l":"Portchannel trunk-vlans replace","p":["When one trunk vlan is already set on porchannel, then put request to change trunk vlans list returns:","Unsupported type of node …","Current workaround is deleting whole list of trunk-vlans, after that single put request to add removed and new trunk-vlans.","Postman collection is attached. Replace can be also done using this gnmic command:"]}],[{"i":"uniconfig-503","l":"UniConfig 5.0.3"},{"i":"new-features","l":"✅ New Features"},{"l":"Adding failed transactions into transaction log","p":["Description","Previously, only successfully committed transactions have been written into transaction log.","Added state to transaction log entry that determines, if transaction has been successfully or not committed - both successful and failed transactions are part of transaction log.","Documentation","Transaction Log | Frinx Docs","API","Added ‘status' leaf and split ‘commit-time’ into ‘last-commit-time’ and 'failed-commit-time’ (YANG module transaction-log):"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements"},{"l":"Integrated OWASP dependency check tool into UniConfig","p":["3-rd party libraries are check against security issues during building of UniConfig distribution. If there are some issues with security level higher than configured threshold, built will fail.","Set security threshold level to 10 and fixed corresponding critical errors."]},{"i":"bug-fixes","l":"❌ Bug Fixes"},{"i":"fixed-updating-of-leaf-list-content-orderedunordered-on-netconf-device","l":"Fixed updating of leaf-list content (ordered/unordered) on NETCONF device","p":["Unordered leaf-list must be updated using following steps:","removing all items that are not in the updated list","inserting all items that are only in the updated list","There was 1 bug: step 1. never happened.","Ordered leaf-list must be updated using following steps:","inserting/moving new/existing items in the correct order (using ordering parameters) [1]","removal of all items that are not in the updated list [2]","There was 1 bug - all items were removed and afterwards re-inserted without usage of special positional attributes - it created conflict on NETCONF layer between edits and thus splitting of NETCONF traffic into 2 edit-config messages."]},{"i":"device-discovery-32-prefix-changed-to-inclusive","l":"Device discovery /32 prefix changed to inclusive","p":["User must be able to ping network with prefix /32 - it must be rendered as single host (special case)."]},{"i":"uniconfig-shell---exit---it-is-expected-to-hit-enter-twice","l":"UniConfig shell - exit - it is expected to hit enter twice","p":["Previous behaviour:","After fix, UniConfig will print user some message, that one more is expected to leave SSH session."]}],[{"i":"uniconfig-502","l":"UniConfig 5.0.2"},{"i":"new-features","l":"✅ New Features"},{"l":"Upgrading templates","p":["Added ‘upgrade-template' RPC into 'template-manager’ YANG module:","API","Both settings are related to auto-upgrading process - they don’t influence execution of RPC which can be still done manually.","Configuration","Description","Documentation","if it fails, we will return standard RESTCONF RFC-8040 error container","Implemented automation of the upgrading process - calling of this RPC automatically at initialisation of UniConfig for all templates present in the DB that don’t use the latest repository.","Implemented RPC for upgrading template to specific YANG repository.","output template name (optional, default value = input template name)","RPC input:","RPC output:","Supplemented template configuration by 2 new settings (lighty-uniconfig-config.json) - enabledTemplatesUpgrading and maxBackupTemplateAge.","template name (mandatory)","Templates Manager| Frinx Docs","without body, just status message","YANG repository name (optional, default value = latest YANG repository)"]},{"l":"Connection notifications","p":["Description","Connection notifications are generated after state of southbound CLI/NETCONF/GNMI node is updated - either status message or connection status.","Notifications are published into dedicated Kafka topic.","They are useful especially for debugging connection issues between UniConfig and network devices.","Documentation","Kafka Notifications | Frinx Docs","API","Structure of notifications are described following YANG module 'connection-notifications':","Added settings used for configuration of Kafka topic and enabled/disabled state (YANG module kafka-brokers):","Configuration","Supplemented corresponding settings into in the lighty-uniconfig-config.json file (by default, these notifications are enabled if globally notification system is enabled):"]},{"l":"Configurable transaction idle-timeout","p":["Description","Introduced new transaction parameter that can be used at creation of new transaction and overrides global idle-timeout.","After inactivity of the transaction, it is automatically closed and an exception will be thrown if user tries to invoke some operation on the transaction.","Documentation","Example request with timeout parameter | Frinx Docs","API","Format of the query parameter 'timeout':","Uniconfig-client","Introduced TransactionParameters class - object of this class can be provided at creation of new transaction. By default, transaction-specific idle-timeout is disabled - global idle-timeout is used."]},{"l":"Added option to disable validation phase at commit","p":["Description","UniConfig uses 3-phase commit procedure - validation, confirmed-commit, confirming-commit. Validation is currently always executed on nodes that support validation and have been installed with enabled validation.","This feature introduces flag in the commit RPC using which user can control execution of validation phase.","Documentation","RPC commit | Frinx Docs","API","Added 'do-validate' field into commit RPC input (checked-commit does not supported this feature for now):","Uniconfig-client","In the uniconfig-client validation is 'disabled' by default (opposite behaviour in comparison to RESTCONF API).","Exposed new method in DOMReadWriteTx interface:"]},{"l":"Modification of connection parameters after the first installation without uninstallation","p":["Description","After some CLI/NETCONF device has already been installed, it is possible to update some connection / mount parameters (for example, ‘host' or 'password’).","User can read and update connection parameters under ‘cli' or 'topology-netconf’ topology, under specific network-topology nodes.","Afterwards, UniConfig will use updated connection parameters at the next creation of connection to device.","NETCONF sessions used for receiving of NETCONF notifications are also updated at the next monitoring iteration.","Documentation","Updating installation parameters | Frinx Docs","Uniconfig-client","Example:"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements"},{"l":"Improved aggregation of NETCONF messages","p":["Non-overlapping edit-config messages are already aggregated into one edit-config message that is sent to NETCONF server. However, this aggregation was primitive - it just serialised all modified subtrees and stacked them under root element without considering option, that paths to these subtrees may overlap.","After this improvement, edit-config message will contain compressed subtree structures without duplicated ‘wrapper’ elements."]},{"i":"added-session-id-to-netconf-logs-netconf-messages","l":"Added session-id to NETCONF logs (netconf-messages)","p":["Description","Previously, only internal Netty’s channel-id was displayed in the logs.","After this improvement, NETCONF-specific session-id, returned from device during exchanging of capabilities, will be used.","Documentation","Logging Framework | Frinx Docs","Making connection-manager unit tests more robust","Preventing random failures because of multi-threaded environment.","Improve error message if device/template doesn't exist","If device/template or another node doesn’t exist, UniConfig should return user-friendly error message that corresponding node doesn’t exist and not some YANG-related error.","Creation of new node with specified YANG repository is still allowed.","Error message before the fix:","Error message after the fix:"]},{"i":"bug-fixes","l":"❌ Bug Fixes"},{"l":"Fixed YANG packager that does not catch broken submodules","p":["Description","Fixed reporting of two kinds of issues related to YANG submodules:","Submodules contain statement “belongs-to” some parent. That parent should contain statement “include”. When parent does not contain this statement, uniconfig marks submodule as broken.","When submodule contains “belongs-to” statement, but parent does not exists.","Improved error message output from YANG packager utility.","Documentation","Device Discovery | Frinx Docs"]},{"i":"fixed-device-discovery-behaviour-for-network-with-31-prefix","l":"Fixed device-discovery behaviour for network with /31 prefix","p":["Description","Use cases:","192.168.1.0/32 - returns empty output, there aren’t any usable hosts that can be reached","192.168.1.0/31 - special case, device-discovery component should verify two hosts - .1 and .2","192.168.1.0/30 - returns 192.168.1.1, 192.168.1.2","Documentation","Device Discovery | Frinx Docs"]},{"i":"fixed-calculate-diff-operation-augmentation-nodes","l":"Fixed calculate-diff operation (augmentation nodes)","p":["Augmentation nodes have been skipped and unwrapped during reading of data from device. It resulted in the failed / incorrect calculation of diff on UniConfig layer.","After this fix, UniConfig skips only those augmentation nodes that contain only non-config data nodes (YANG 'config false' statement)."]}],[{"i":"uniconfig-501","l":"UniConfig 5.0.1"},{"i":"new-features","l":"✅ New Features"},{"i":"propagation-of-data-change-events-from-uniconfig--unistore-configuration","l":"Propagation of data-change-events from ‘uniconfig' / 'unistore’ configuration","p":["Description","Implemented propagation of data-change-events into distinct Kafka topic. Data-change-events are currently supported per-node in ‘uniconfig' and 'unistore' network-topologies.","Using subscription, user specifies observed subtrees against data-changes. Afterwards, data-change-events are generated by UniConfig instances after some transaction is committed and committed changes contain subscribed subtrees.","API","Created new YANG module that defines data-change-events structure in form of YANG notifications and RPC calls for manipulation / reading of subscriptions:","Documentation","Kafka Notifications | Frinx Docs","Configuration","Added settings into lighty-uniconfig-config.json file:","dataChangeEventsEnabled- turning on/off generation and distribution of data-change-events (by default, they are enabled)","dataChangeEventsTopicName- name of the Kafka topic (default identifier is 'data-change-events')","Java client","Example, how to use data-change-events as triggers for callback inside UniConfig Java client:"]},{"l":"Added config option to disable immediate-commit model","p":["Description","Immediate-commit model is in some cases dangerous, because changes are automatically committed to managed network devices.","Added option to disable immediate-commit model globally.","Configuration","New setting 'isImmediateCommitEnabled' in the lighty-uniconfig-config.json:","Default value is 'true'."]},{"l":"Calling replace-config-with-oper after sync-from-network in the immediate-commit-model","p":["In the immediate-commit-model, if user called sync-from-network operation, it behaved as 'sync-to-network' operation:","reading configuration from device","resolving diff between actual (device) and intended state (last saved configuration in database)","sending resolved diff to operation - reverting changes, that have been done on device side","This dangerous if network device is configured manually by user or another tool.","Fixed by calling replace-config-with-oper operation after called-sync-from-network operation and before committing temporary transaction created in the immediate-commit model session. It will result in storing of loaded configuration to database without performing any action on managed devices.","This change alters only immediate-commit model. Build-and-commit model stays unaltered."]},{"l":"Making default CLI connection parameters configurable","p":["Description","There are couple of CLI connection parameters with some default values defined in cli-topology YANG module that can be specified at installation of device.","This feature allows user to adjust these default parameters without repetitive adjustment in the install-node RPC request.","Priority of using install parameters:","Parameter set in install RPC request","Default parameter set in database","Default parameter from YANG model","Documentation","Device installation | Frinx Docs","API","Exposed default CLI settings into distinct container that is accessible using RESTCONF API (module cli-topology):","Exposed settings in the UniConfig shell - configuration mode / settings container."]},{"l":"Making default NETCONF connection parameters configurable","p":["Description","There are couple of NETCONF connection parameters with some default values defined in netconf-topology YANG module that can be specified at installation of device.","This feature allows user to adjust these default parameters without repetitive adjustment in the install-node RPC request.","Priority of using install parameters:","Parameter set in install RPC request","Default parameter set in database","Default parameter from YANG model","Documentation","Device installation | Frinx Docs","API","Exposed default NETCONF settings into distinct container that is accessible using RESTCONF API (module netconf-node-topology):","Exposed settings in the UniConfig shell - configuration mode / settings container."]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements"},{"l":"Improved displaying of children nodes of DataNode in Java client","p":["Children nodes were organised under multiple levels of Map objects - it was not readable especially when user was debugging code.","Now, children nodes are displayed directly under simple List collection:"]},{"l":"Added YANG-based documentation to Java client","p":["Added JavaDoc description to DataNode and DataNodePath sub-classes, how they are used in comparison to YANG schema tree.","Example:"]},{"l":"Removed redundant module-name prefixes from built paths in Java client","p":["RFC-8040 specifies that module-name prefix must be added only to the first augmented elements (transition to different namespace).","Previously it worked non-optimally - module name was added to all elements of the path:","After improvement:"]},{"l":"Added option to enable PostgreSQL driver logs in UniConfig","p":["Description","Logging connections and communication between UniConfig and PostgreSQL can be handy in case of debugging of some errors.","Configuration","To log detailed information about executed queries and PG connections, user should set org.postgresql logger level to DEBUG or TRACE."]},{"l":"Added transaction-id also to both RESTCONF requests and responses","p":["Description","UniConfig transaction-id simplifies debugging of executed RESTCONF operations.","Example (added 'Uniconfig transaction' property):","Documentation","Logging Framework | Frinx Docs"]},{"l":"Hiding sensitive data in logs","p":["In the UniConfig logs are shown sensitive data like PostgreSQL DB credentials, etc. This is a potential security hole.","Example:","Fixed by hiding JSON configuration parsing details from logs."]},{"i":"bug-fixes","l":"❌ Bug Fixes"},{"l":"Fixed invocation of device-discovery RPC multiple times","p":["RPC response contained also results from previous RPC invocation.","Fixed by isolation of RPC results."]},{"i":"fixed-setting-of-max-connection-attempts-during-device-installation-clinetconf","l":"Fixed setting of max-connection attempts during device installation (CLI/NETCONF)","p":["Description","Removed max-connection-attempts parameter from install-node RPC. It was clashing with parameters from southbound layers and introducing confusion.","Fixed switched loading of max-connection-attempts and max-reconnection-attempts on NETCONF layer. It resulted in the infinite initial maximum connections attempts (by default, there should be 1 attempt).","Setting default max-connection-attempts to 1 in YANG model (both CLI and NETCONF layers).","Documentation","Updated document: Device installation| Frinx Docs","API","connection-manager - removed leaf max-connection-attempts:","cli-topology - setting max-connection-attempts default value to 1:","netconf-node-topology - setting max-connection-attempts default value to 1:"]},{"l":"Fixed stuck UniConfig API because of interrupted SQL operation","p":["Description","Default socket-read-timeout for the PostgreSQL driver is 0 - UniConfig is waiting forever for result of some query. This causes blocking of other UniConfig operations on specific node, if connection between UniConfig and PG is dropped during execution of some query.","Fixed by exposing socketReadTimeout parameter and setting its default value to 20 seconds.","Configuration","Added socketReadTimeout to database connection settings (lighty-uniconfig-config.json):"]},{"l":"Fixed propagation of error on disabled templates","p":["If templates are disabled, then user will get direct error message with 400 status code. Previously it failed on some parsing error or it didn’t fail at all and UniConfig just ignored unknown data.","Example:"]},{"i":"fixed-pki-authentication-to-netconf-device-negative-cases","l":"Fixed PKI authentication to NETCONF device (negative cases)","p":["PKI authentication on device - attempt to install device with reference to not existing private key","Previously it failed with error:","After fix it will fail with error message that private key with specified identifier doesn’t exist.","PKI authentication on device - registering the password protected key with RPC netconf-keystore:add-keystore-entry - but providing bad password","Fixed by validation of input password against key-store.","If it is invalid, UniConfig will return error immediately and will not try to register such private key and afterwards use it during mounting process."]},{"i":"netconf-edit-config-operation-with-insert-attribute-failed-because-of-aggregated--messages","l":"NETCONF edit-config operation with insert attribute failed because of aggregated messages","p":["When insert attribute was used with value before/after, there was problem with NETCONF messages ordering in the aggregated message.","Fixed by assuring that list entry specified by insert attribute is placed before actual list entry in the edit-config message sent to NETCONF server."]}],[{"i":"uniconfig-4210","l":"UniConfig 4.2.10"},{"i":"new-features","l":"✅ New Features"},{"l":"Aggregation of all edit-config NETCONF messages into one edit-config message","p":["Each modification in the transaction was expressed using one edit-config message on southbound layer.","This approach was not optimal:","it generated more network traffic than needed","it could introduce errors, if device checks some references before committing configuration","After this patch, all NETCONF edit-config RPCs in the transaction are aggregated into single edit-config RPC with common parent element."]},{"i":"capturing-changes-in-ordered-listleaf-list-using-calculate-diff-rpc","l":"Capturing changes in ordered list/leaf-list using calculate-diff RPC","p":["Currently, changed order of list entries inside ordered list/leaf-list is displayed as updated whole list with all list entries - not optimal solution.","Added new list to calculate-diff RPC output that captures changes in the ordering of list or leaf-list elements. Such changes are not displayed under created/removed/updated containers."]},{"l":"Validation of leaf-refs","p":["Validation of leaf-ref YANG constraints that are affected by some create/delete/update operation:","Supported following leaf-ref paths:","absolute paths","relative paths","paths with 'current()' XPATH function","Added new RESTCONF query parameter into put/patch/delete operations - checkForReferences.","Implementation conforms RFC 7950 - The YANG 1.1 Data Modeling Language"]},{"l":"Encryption of leaves selected by paths","p":["UniConfig uses asymmetric encryption for ensuring confidentiality of selected leaf and leaf-list values. Currently, only RSA ciphers are supported (both global UniConfig and device-level key-pairs). Encryption is supported in ‘uniconfig’, ‘unistore’, and ‘templates’ topologies.","Global-device encryption architecture - both UniConfig and device uses PKI for encryption of data:","Global-device encryption architecture","In comparison to Global-device encryption architecture this model uses only global key-pair for encryption of data. Devices contain only plaintext data."]},{"i":"implementation-of-crypt-hash-type-from-iana-crypt-hash-yang-module","l":"Implementation of ‘crypt-hash' type from 'iana-crypt-hash’ YANG module","p":["UniConfig supports 'iana-crypt-hash' YANG model for specification of hashed values in data-tree using type definition 'crypt-hash'. Hashing works in the 'uniconfig' and 'unistore' topologies. Only NETCONF devices are currently supported because CLI cannot be natively used for reporting of device capabilities that would contain supported hashing function.","Hashing is done only in the RESTCONF layer after writing some data that contains leaves/leaf-lists with 'crypt-hash' type. Afterwards, UniConfig stores, uses, and writes to device only hashed representation of these values.","All 3 hash functions are implemented - 'MD5', 'SHA-256', 'SHA-512'. In case of 'uniconfig' topology, hashing function is selected based on reported feature in the NETCONF capability, in case of 'unistore' topology, UniConfig enforces 'SHA-512' hashing function.","Hashing model"]},{"l":"Using the latest schema at creation of template","p":["Adding configuration into UniConfig that tracks identifier of the UniConfig repository that must be used at creation of new template, if user doesn’t explicitly specify identifier of this repository using ‘schema-cache-directory’ query parameter."]},{"l":"Rebalancing of notifications cluster at runtime","p":["Random distribution of subscriptions to NETCONF notifications streams and turning on/off UniConfig instances may lead to scenario when one of the UniConfig instances in the cluster contain most of the subscriptions while others unequally smaller number.","Fixed by automatic redistribution of already created subscriptions on UniConfig instances and introduction of limits, how many subscriptions can be allocated on the one UniConfig instance in the cluster.","Cluster rebalancing"]},{"l":"Configuration","p":["Added new parameters under “notifications“ element in the lighty-uniconfig-config.json file:"]},{"l":"Implementation of RFC-8072 PATCH operation","p":["Invocation of PATCH that may contain multiple edits.","All edits are invoked sequentially and atomically as single operation.","Supported sub-operations per edit: create, delete, insert, merge, move, replace, remove.","More detailed description: RFC 8072 - YANG Patch Media Type"]},{"i":"added-missing-protocols-to-l2-for-ios-xe-cli-units","l":"Added missing protocols to L2 for IOS XE (cli-units)","p":["Parsing of following protocols:","elmi","pagp","udld","ptppd"]},{"l":"UniConfig whitelist","p":["specification of top-level containers/lists which configuration is synced from device (no other configuration is read from device)","opposite of existing blacklist functionality","either blacklist or whitelist can be specified, not both","API","updated YANG model that defines whitelist/blacklist:","Install-node RPC example (input body):"]},{"l":"UniConfig client thread model","p":["make uniconfig-client thread safe (using client from multiple threads)","making HTTP connection pools configurable (max connections, …)","API:","Introduced connection pool settings:","Introduced UniConfig server settings:","Example:"]},{"l":"Distribution of NETCONF notifications to Kafka","p":["NETCONF devices are capable of generating NETCONF notifications. UniConfig is able to collect these notifications and creates its own UniConfig notifications about specific events. Kafka is used for publishing of these notifications from NETCONF devices and UniConfig. Currently there are these types of notifications: - NETCONF notifications - notifications about transactions - audit logs (RESTCONF notifications).","NETCONF notifications - Kafka","API","Added subscription API to install-node request - 'stream' container. Example (subscription to 2 NETCONF streams - ‘NETCONF' and 'system’):","Added root list 'netconf-subscription' which contains all active subscriptions.","Corresponding YANG model:","Configuration","Provided initial configuration that can put into lighty-uniconfig-config.json:","Uniconfig-client","Example:"]},{"l":"Dynamic configuration of Kafka brokers","p":["Location of Kafka brokers and other Kafka settings must be configurable using RESTCONF API.","Persistence of this configuration in the database. All UniConfig instances must use same settings.","Option to change/read these settings using CRUD RESTCONF operations.","Configuration that is placed in the configuration file must be used only as initial configuration.","API","RESTCONF API used for reading and modification of all Kafka settings is described by following YANG model:"]},{"i":"installationuninstallation-of-multiple-devices-in-one-rpc","l":"Installation/Uninstallation of multiple devices in one RPC","p":["Added RPCs for installation or uninstallation of multiple devices in the single RPC call. The advantage of this approach in comparison to install-node/uninstall-node RPC is that UniConfig can schedule installation tasks in parallel.","Up to 20 devices can be installed at once.","API","Added RPCs into connection-manager YANG module:"]},{"l":"Added list of node-ids into snapshot-metadata","p":["Added list of node-ids, that are inside particular snapshot, into snapshot-metadata.","API","Added ‘nodes' leaf-list (’snapshot-manager.yang'):"]},{"i":"api","l":"\uD83D\uDCBB API","p":["Added following element into calculate-diff RPC output:","Added checkForReferences query parameter.","Default value is false - if it is set to 'true', then validation is done before application of modification into data-tree."]},{"l":"Introduction of transaction idle-timeout","p":["Idle timeout is more useful/practical than existing ‘absolute’ timeout, especially for long-running workflows - it will minimise the chance that transaction will be dropped after some operation started.","Transaction idle timer is refreshed after transaction is retrieved from registry (-> at invocation of some operation from RESTCONF).","Timed-out transaction is cleaned using existing cleaner.","Idle timeout is configurable only globally (config file).","Absolute timeout is not removed - it coexist with added idle-timeout."]},{"i":"configuration-1","l":"Configuration","p":["Updated configuration section in lighty-uniconfig-config.json- added 'transactionIdleTimeout’ property:"]},{"l":"Install-node RPC","p":["Added new parameters (uniconfig-config:crypto) into install-node RPC:","'uniconfig-config:crypto' - It allows to specify path to public key on device - ‘public-key-path’ (leaf with RFC-8040 path) and cipher type (by default, RSA is used) - ‘public-key-cipher-type’. If path to public key is specified and it exists on device, then Global-device encryption model is used. Otherwise, Global-only encryption model is selected.","'netconf-node-topology:yang-module-capabilities' - If auto-loading of YANG module with encrypted paths is not used and device itself doesn’t specify encrypted leaves, then it is necessary to side-load YANG module with encrypted paths. This parameter is relevant only on NETCONF nodes. Side-loaded modules must be expressed in the format of NETCONF capabilities."]},{"i":"configuration-2","l":"Configuration","p":["Global RSA key-pair is stored inside PEM-encoded files in the ‘rsa’ directory under UniConfig root. Name of the private key must be ‘encrypt_key’ and name of the public key must be ‘encrypt_key.pub’. If user doesn’t provide these files, UniConfig will automatically generate its own key-pair with length of 2048 bits. All UniConfig instances in the cluster must use the same key-pair.","Encryption settings are stored in the ‘config/lighty-uniconfig-config.json’ file under ‘crypto’ root object.","'encryptExtensionId' - If this setting is not defined, then encryption is disabled despite of other settings or install-node parameters. The value must have the format [module-name]:[extension-name] and specifies extension used for marking of encrypted leaves/leaf-lists in YANG modules. Corresponding YANG module, that contain this extension, can be part of device/unistore YANG schemas or it can be side-loaded during installation of NETCONF device as imported module from ‘default’ repository.","'netconfReferenceModuleName' - Name of the module for which NETCONF client looks for during mounting process. If UniConfig finds module with this name in the list of received capabilities, then it uses its revision in the lookup process for correct YANG module with encrypted paths (using deviations).","'netconfEncryptedPathsModuleName' - Name of the module which contains deviations with paths to encrypted leaves/leaf-lists. There could be multiple revisions of this file prepared in the ‘default’ NETCONF repository. NETCONF client in the UniConfig chooses the correct revision based on ‘netconfReferenceModuleName’ setting. Together, ‘netconfReferenceModuleName’ and ‘netconfEncryptedPathsModuleName’ can be used for auto-loading of encrypted paths for different versions of devices."]},{"l":"Uniconfig-client API","p":["Added InstallDeviceWithEnabledEncryption example:"]},{"i":"supported-ordered-listleaf-list-operations-restconf--netconf","l":"Supported ordered list/leaf-list operations (RESTCONF & NETCONF)","p":["RESTCONF RFC-8040 supports 2 additional query parameters for PUT and POST methods - ‘insert' and 'point’, see:","RFC 8040 - section 4.8.5","RFC 8040 - section 4.8.6","Using these parameters, it is possible to place list entry to specific position in the list. The 'insert' query parameter can be used to specify how an item should be inserted within an list or leaf-list. The 'point' query parameter is used to specify the insertion point for an item that is being created or moved within an 'ordered-by user' list or leaf-list. Like the 'insert' query parameter.","In the NETCONF client, UniConfig uses edit-config 'insert' attribute to put list entry to the specific position, see:","RFC 6020 - YANG"]},{"l":"API","p":["Introduction of schema for keeping information about the latest YANG repository identifier.","It is configurable using RESTCONF."]},{"i":"introduction-of-rename-patch-operation","l":"Introduction of 'rename' patch operation","p":["This PATCH operation can be used for changing values of one/multiple keys that identify some list entry. In the RESTCONF API it was not possible to directly update values of keys.","New PATCH operation with identifier 'rename'.","‘target’: identifier of original list entry","'point': new identifier of list entry"]},{"l":"Separate UniConfig errors to more type","p":["Updated 'frinx-type' YANG module (previously there were processing-error and no-connection error types)."]},{"i":"implementation-of-rfc-8072-patch-operation-1","l":"Implementation of RFC-8072 PATCH operation","p":["Example:"]},{"i":"added-missing-protocols-to-l2-for-ios-xe-cli-units-1","l":"Added missing protocols to L2 for IOS XE (cli-units)","p":["Added enumerations into 'frinx-cisco-if-extension' YANG module (openconfig):"]},{"l":"YANG packager","p":["implemented tool for validation and loading of YANG repository","API:","User can find corresponding script it in the utils/ directory (part of distribution).","Script './convertYangsToUniconfigSchema' contains four arguments. Each one has its own identifier so user can use any order of arguments.","Two arguments are required, namely the path to resources that contain YANG files and the path to the output directory where user wants to copy all valid YANG files. Other three arguments are optional. First one is the path to the \"default\" directory which contains some default YANG files, second one is the path to the \"skip-list\" and last one is a \"-to-file\" flag, which user can use when he wants to write a debug output to file.","-i /path/to/sources - required argument. User has two options for where the path can be directed:","to the directory that contains YANG files and other sub-directories with YANG files","to the text-file that contains defined names of directories. These defined directories have to be stored on the same path as text-file.","-o /path/to/output-directory - required argument. User can define path where he wants to save valid YANG files. Output directory must not exist.","-d /path/to/default - optional argument. Sometimes some YANG files need additional dependencies that are not provided in source directories. In this case it is possible to use path to the 'default' directory which contains additional YANG files. If there is this missing YANG file, YANG packager will use it.","-s /path/to/skip-list - optional argument. User can define YANG file names in text file that he does not want to include in conversion process. This file must only contain module names without revision and .yang suffix.","-to-file - optional argument. When user uses this flag, then YANG packager also saves the debug output to a file. This file can be found on a same path as 'output-directory'. It will contain suffix '-info' in its name. If the output directory is called 'output-directory', then the file will be called 'output-directory-info'."]},{"l":"UniConfig notifications about RESTCONF requests","p":["Publishing all RESTCONF traffic into PostgreSQL ‘notification' relation and Kafka 'restconf-notifications’ topic.","API","Created YANG model for RESTCONF notifications:","Configuration:"]},{"i":"bug-fixes","l":"❌ Bug Fixes"},{"l":"Fixed UniConfig rollback for CLI devices","p":["Rollback operation after failed commit, that included some CLI devices, was not working at all.","Fixed by re-implementation of the rollback process."]},{"l":"Filtering operational data from read NETCONF device configuration","p":["There are some devices that report both configuration and operational data via gRPC even if UniConfig reads only configuration data.","Fixed by explicit removal of operational data elements from read configuration before writing this configuration into database."]},{"l":"Fixed capturing of command response from Telnet session","p":["The size of internal buffer was hard-coded - now it is flexible based on number of received bytes from Telnet session. It caused trimming of command output in the execute-and-read RPC response."]},{"l":"Fixed deadlocks caused by superfluous synchronisation in transaction manager","p":["Synchronisation of component that is responsible for loading/creation/closing of transactions was unnecessary constrained - it resulted in dead-locks, especially when one UniConfig transaction was accessed asynchronously from different threads."]},{"l":"Fixed lost ordering of list elements after reading of some data","p":["If user read both ‘configuration' and ‘operational’ list elements using RESTCONF API (’content=all' query parameter), order of elements was lost during merging of these two sets.","After fix, configuration elements are displayed first, then operational-only elements are displayed."]},{"l":"Fixed interrupted ping command executed by Device Discovery service","p":["If user executed device discovery RPC with more IP addresses than the capacity of internal thread pool, some scheduled ping tasks were cancelled by timeout process.","Removed timeout from thread pool - tasks wait in the queue without time limit."]},{"l":"Fixed deadlock between transaction closing and UniConfig operation","p":["Procedure for closing transaction is called either explicitly using close-transaction RPC or automatically from transaction cleaner.","If at the same time some transaction is used in the invoked UniConfig operation, then it may lead to the deadlock - using transaction that was expired and is being closed.","Fixed by synchronisation of there events in the transaction manager."]},{"i":"get-template-info-operation-must-be-part-of-read-only-transaction-uniconfig-client","l":"Get-template-info operation must be part of read-only transaction (uniconfig-client)","p":["This operation was only part of read-write transaction."]},{"i":"when-notifications-are-enabled-uniconfig-log-is-getting-filled-with-psqlexception-continuously","l":"When notifications are enabled, uniconfig log is getting filled with PSQLException continuously","p":["Subscription table was not locked in the loop used for acquiring free subscription to NETCONF streams. Instead, pg_locks system view was locked. It led to various issues with permissions.","Fixed by not locking instances in the pg_locks view, but only instances in the subscription table."]},{"l":"Installation of device with bad password getting wrong behavior","p":["Error message was not correctly propagated into RPC install-node output.","Fixed - it will contain error message “mountpoint was not succesfully created“."]},{"l":"Fixed ignoring of unknown elements received from NETCONF device","p":["Even if ‘strict-parsing' was set ‘false’, sometimes NETCONF client didn’t ignore unknown elements that were placed under parent node of type 'list'."]},{"l":"Fixed downloading of schemas from NETCONF server running on netconf-testtool","p":["Downloading of schemas from simulated device (netconf-testtool) didn't work at all. User had to provide YANG schemas of simulated device manually to UniConfig ‘cache’ directory."]},{"l":"Fixed JSONB filtering for UniStore topology","p":["JSONB filtering feature didn’t work on configuration under unistore nodes"]},{"l":"Fixed calculate-diff RPC with updated root leaves","p":["Calculate-diff RPC failed if there were some updated/created/removed root leaves."]},{"l":"Fixed disconnecting CLI because of invalid characters in the prompt","p":["If the commands that are executed are too long, an incorrect character will appear which prevents the CLI from processing the prompt and causes the application to hang.","Fixed by ignoring of such characters during parsing of returned command prompts from device."]},{"l":"Fixed closing of UniConfig transaction after failed commit operation","p":["If commit RPC failed unexpectedly (500 status code), then UniConfig transaction was not closed and stayed hanging and blocking other transactions that would do modifications on the same nodes.","Fixed by closing UniConfig transaction always at the end of commit RPC if it was not closed by operation itself."]},{"l":"Fixed handling of incorrect input pagination parameters","p":["Returning 400 error message if input is not correctly formatted.","Example:"]},{"l":"Fixed providing of multiple slf4j bindings on classpath","p":["Keeping only one slf4j implementation on classpath, so there aren’t any conflicts."]},{"l":"Stop closing of configuration mode in the UniConfig shell after each commit operation","p":["State before:","State after:"]},{"l":"Fixed writing of augmentation data at commit operation to southbound layer","p":["This is a regression introduced during implementation of “validation” and “confirmed commit” features. Fixed by wrapping of augmentation nodes to non-mixin parent containers."]},{"l":"Fixed validate RPC output with empty input","p":["After modification of multiple nodes in the transaction, validate RPC with empty input:","Returns back only:","But it must contain all modified nodes."]},{"l":"Fixed ordering of entries in the transaction-log","p":["Committed transactions must be sorted by time when transaction was committed. Previously, the order was random."]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements"},{"l":"Removed old draft-02 RESTCONF implementation","p":["We stopped using old RESTCONF implementation.","Only new RESTCONF RFC-8040 is supported."]},{"i":"configuration-3","l":"Configuration","p":["Removed “jsonRestconfServiceType“ setting from “lighty-uniconfig-config.json”:"]},{"l":"Removed option to turn off transactions","p":["This setting was confusing, because turned on transactions still support both immediate-commit-model and build-and-commit models."]},{"i":"configuration-4","l":"Configuration","p":["Removed “uniconfigTransactionEnabled“ from configuration file:"]},{"i":"improved-invalid-nesting-of-data-error-message","l":"Improved 'Invalid nesting of data' error message","p":["This error occurred without and descriptive message, if user put some list without specification of correct brackets in the input JSON body.","Improved error message - it points to the place/element at which error occurred (parent element)."]},{"l":"Removed AutoSyncService","p":["This component was responsible for automatic reading of some configuration after pushing configuration to device.","However such process was not very visible to user, it could cause issues - we decided to remove it, so similar functionality must be implemented on application layer."]},{"l":"Specification of default directory in the YANG packager utility","p":["The packager script expected to have ‘default’ as the name of the default directory. It must be able to accept any file name after -d parameter."]},{"i":"separate-uniconfig-errors-to-more-type-1","l":"Separate UniConfig errors to more type","p":["Introduction of more granular error types that are returned in the response messages of UniConfig RPC operations.","User should be able to identify in what component/layer of UniConfig, the error occurred."]},{"i":"enabledisable-notifications-per-topic","l":"Enable/disable notifications per topic","p":["Previously it was only possible to enable/disable notifications globally (all topics).","Added option per topic to enable/disable notifications.","Added 3 new leaves that are placed under “kafka-settings“ container","API","Confiruration","Initial configuration can be specified from lighty-uniconfig-config.json file:"]},{"l":"Renamed elements in notification system","p":["Goal - improved readability.","subscription list → netconf-subscription","topic name restconf-notifications → audit-logs","API","Updated subscription list and YANG module name:","Renamed restconf-notifications module:","Updated topic name for RESTCONF notifications:","Configuration","Updated topic name and corresponding field name:"]},{"l":"Removed AAA","p":["Removed AAA code from UniConfig.","AAA was used for:","RESTCONF authentication (basic) - not needed, it can be provided by application gateway","encryption in NETCONF - moved corresponding functionality to NETCONF module","user identification - not needed, this functionality will be covered by tracing logs","API","Removed “user-id“ from “audit-logs“ module:","Removed “username” from “transaction-log” module:"]},{"i":"uniconfig-shell-ability-to-configure-multiple-leafs-with-single-set-operation","l":"UniConfig shell: Ability to configure multiple leafs with single SET operation","p":["If there are multiple leaves under same container/list, user should be able to configure them in the single command line.","API:","Sample YANG model:","Commands for setting client-alive-interval and client-alive-count-max:","New approach:"]},{"l":"Removing unused UniConfig monitoring system","p":["Removing of following field from UniConfig instance DB relation - backup-instance.","Removing periodical monitoring of UniConfig instances (component in the UniConfig layer) and taking leadership over nodes in the cluster.","Removing unused DB business API services that were used in the [1] and [2].","Configuration","Before changes:","After changes (removed multiple settings):"]},{"l":"Removed old UniStore implementation","p":["UniStore was previously implemented separately from UniConfig. Now it is integrated into UniConfig with distinct topology identifier 'unistore'."]},{"l":"Using cached thread-pool in the device-discovery service","p":["There was a fixed thread-pool that kept all the threads open all the time.","Using cached thread-pool with a small initial thread amount and higher max thread amount e.g. CPU_COUNT * 8."]},{"i":"configuration-5","l":"Configuration","p":["Added “maxPoolSize“ setting to configuration file:"]},{"i":"display-only-sub-structure-with-show-command-in-uniconfig-shell","l":"Display only sub-structure with \"show\" command in UniConfig shell","p":["Before patch:","After patch (just displaying what's there inside settings/system accordingly):"]},{"l":"Providing default UniStore node id in the UniConfig shell","p":["When we create a new UniStore node we manually had to give it a node-id. Say, we are configuring ssh now, it needs to be a generic command which doesn't expect the node-id to be given by the user.","Before patch ('new' is the node identifier):","After patch:","Configuration:","Default UniStore node identifier can be configured in the lighty-uniconfig-config.json (default value is 'system'):"]},{"l":"Removed unused Maven plugins","p":["Removed unused Maven plugins that are executed during build process and thus making building longer."]},{"l":"Removed AspectJ from UniConfig","p":["AspectJ makes code more error-prone and complex for debugging - removed usage of this library in the RESTCONF and dependencies."]},{"i":"documentation-additions","l":"\uD83D\uDCDC Documentation additions"},{"i":"validation-of-leaf-refs-1","l":"Validation of leaf-refs","p":["Validation of leaf-ref YANG constraints that are affected by some create/delete/update operation:","leafref-validation"]},{"l":"idle-timeout","p":["Introduced transaction idle-timeout","Updated configuration section in ‘“lighty-uniconfig-config.json” - added 'transactionIdleTimeout’ property:"]},{"l":"Encryption","p":["UniConfig uses asymmetric encryption for ensuring confidentiality of selected leaf and leaf-list values."]},{"i":"insert--point","l":"Insert & Point","p":["RESTCONF RFC-8040 supports 2 additional query parameters for PUT and POST methods - ‘insert' and 'point’"]},{"l":"Hashing","p":["UniConfig supports 'iana-crypt-hash' YANG model for specification of hashed values in data-tree using type definition 'crypt-hash'."]},{"l":"Templates","p":["Added information about usage of the templates"]},{"i":"rename-patch-oper","l":"Rename patch oper.","p":["This PATCH operation can be used for changing values of one/multiple keys that identify some list entry.","Rename"]},{"l":"Kafka clustering","p":["Random distribution of subscriptions to NETCONF notifications streams and turning on/off UniConfig instances may lead to scenario when one of the UniConfig instances in the cluster contain most of the subscriptions while others unequally smaller number."]},{"l":"YANG Patch","p":["Invocation of PATCH that may contain multiple edits."]},{"i":"uniconfig-whitelist-1","l":"UniConfig whitelist","p":["List of root YANG entities that should be read. This parameter has effect only on NETCONF nodes.","Whitelist"]},{"i":"yang-packager-1","l":"YANG Packager","p":["Implemented tool for validation and loading of YANG repository"]},{"l":"Install multiple nodes","p":["Added RPCs for installation or uninstallation of multiple devices in the single RPC call. The advantage of this approach in comparison to install-node/uninstall-node RPC is that UniConfig can schedule installation tasks in parallel.","Uninstall multiple nodes"]},{"l":"Snapshot-metadata","p":["Added list of node-ids, that are inside particular snapshot, into snapshot-metadata."]}],[{"i":"uniconfig-429","l":"UniConfig 4.2.9"},{"l":"UniConfig","p":["[BUG FIXES]","[IMPROVEMENTS]","[NEW FEATURES]","added GNMi southbound protocol","added node list into snapshot-metadata - it contains information about nodes that are captured using snapshot - documentation: https://docs.frinx.io/frinx-uniconfig/UniConfig/user-guide/uniconfig-operations/snapshot-manager/obtain_snapshot_metadata/obtain-snapshot-metadata.html","don't fail dry-run commit if there aren't any changed nodes","fixed behaviour of validate RPC","fixed calculate-diff with changed root leaf","fixed calculate-diff: uniconfig-native branch didn't work fine with updated leaf nodes under choice nodes","fixed comparison and updating of configuration fingerprints(synchronization issues between DB and UniConfig cache)","fixed DeviceDiscovery: parsing of NULL hostname","fixed displaying whole list content using UniConfig shell","fixed dry-run commit - it closed transaction if list of target nodes was empty","fixed replace-conf-with-oper - NullPointerException","fixed transaction leak (CLI shell)","fixed using of UniConfig on machines with less than 4 CPU cores","get-template-info RPC: showing information about all variables in specified template","implementation of git-like diff that shows diff output with git-like marks - documentation: https://docs.frinx.io/frinx-uniconfig/UniConfig/user-guide/uniconfig-operations/uniconfig-node-manager/rpc_calculate-git-like-diff/calculate-git-like-diff.html","implemented RPC to verify install status for a set of node-ids - documentation: https://docs.frinx.io/frinx-uniconfig/UniConfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_check_installed_devices/check-installed-devices.html","improved apply-template RPC: added type safety - application of value to variable with specified type","install-multiple-nodes / uninstall-multiple-nodes (RPC) - option to install/uninstall multiple devices using one request - documentation: https://docs.frinx.io/frinx-uniconfig/UniConfig/user-guide/uniconfig-operations/uniconfig-node-manager/uniconfig_install_multiple_nodes/install-multiple-nodes.html","introduced unistore topology for storing settings / 'dummy' device configuration - supported commit (persistence of unistore nodes), replace-config-with-oper, and calculate-diff operations - documentation: https://docs.frinx.io/frinx-uniconfig/UniConfig/user-guide/uniconfig-operations/unistore-api/unistore.html","logging of transaction ID","UniConfig shell - prompt user for commit if they leave config mode after changes were made"]},{"l":"CLI","p":["[NEW FEATURES]","logging CLI request and responses (logging broker) - documentation: https://docs.frinx.io/frinx-uniconfig/UniConfig/user-guide/operational-procedures/logging/logging.html#cli-messages","[BUG FIXES]","fixed closing of CLI mountpoint created using lazy CLI strategy","fixed propagation of error message from mount process into install-node RPC output"]},{"l":"RESTCONF","p":["[NEW FEATURES]","immediate commit model - automatic creation of new transaction per user request - documentation: https://docs.frinx.io/frinx-uniconfig/UniConfig/user-guide/uniconfig-operations/immediate-commit-model/immediate-commit-model.html","support HTTP2 on server side","[BUG FIXES]","fixed displaying of candidate nodes from non-existing augmentations","fixed unclosed/leaked UniConfig transaction","fixed parsing of multi-level fields query parameter","[IMPROVEMENTS]","making module-name prefix optional in value of fields query parameter"]},{"l":"NETCONF","p":["[NEW FEATURES]","exposed strictParsing parameter into NETCONF mountpoint - ignoring unknown elements received from NETCONF server - documentation: https://gerrit.frinx.io/c/Frinx-docs/+/11724","sorting of list elements by one or multiple fields - documentation: https://docs.frinx.io/frinx-uniconfig/UniConfig/user-guide/uniconfig-operations/restconf/restconf.html#sorting","[IMPROVEMENTS]","reducing logs generated by NETCONF cache loader","updated naming of pagination query parameter"]},{"l":"TRANSLATION-UNITS-FRAMEWORK","p":["[IMPROVEMENTS]","sending list size hint to translation unit writers"]},{"l":"CONTROLLER","p":["[IMPROVEMENTS]","logging creation/closing of UniConfig transaction","removed transaction-log limit from database","[BUG FIXES]","handling of errors that occur in readers/writers","fixed reading snapshot-metadata from database","fixed JSONB filtering: parsing of embedded paths"]},{"l":"SWAGGER","p":["[NEW FEATURES]","added option to ignore config nodes in order to produce oper only documentation","added range constraints to leaves","enable Maven swagger generator for uniconfig native models","[IMPROVEMENTS]","removed swagger path generator for old restconf","[BUG FIXES]","fixed description generator for leaves"]},{"l":"NETCONF TRANSLATION UNITS","p":["[BUG FIXES]","re-enabled XR-6 models","fixed XR-6 interface configuration writer (MTU)","[IMPROVEMENTS]","decreased surefire heap to 2G","optimization: stop recreation of NetconfAccessHelper","set max heap to 4G when running unit-tests to avoid outOfMem exception when running tests"]},{"l":"CLI TRANSLATION UNITS","p":["[Huawei]","created units: login banner, HTTP commands, sysname command, VLAN, telnet and ssh, user-interfaces, RADIUS, QoS, ipv6 and traffic-filter commands","fixed: mounting Huawei device","[SAOS6]","created units: local/remote interfaces, deleting VLAN and physical interface","fixed: reading metadata, ordering of commands for adding network instances","improved: the way to determine if the ring is major or sub ring","[SAOS8]","fixed: reading interface sub_ports, reading metadata","[IOS/IOS-XE]","fixed: deleting all service instances, reading metadata, prefix-lists with 0 entries not reconciled ipvpn, handling invalid MTU value, parsing ACL set"]}],[{"i":"uniconfig-428","l":"UniConfig 4.2.8"},{"l":"UniConfig","p":["[NEW FEATURES]","UniConfig shell: basic CRUD operations (configuration/operations mode), RPC calls, YANG actions.","Validate RPC: validation of NETCONF configuration by target device.","Device discovery RPC: searching for open TCP/UDP ports on target hosts ICMP reachability.","[IMPROVEMENTS]","Simplification of UniConfig RPCs in the transaction: RPCs(is-in-sync, commit, checked-commit, replace-config-with-operational, calculate-diff, sync-from-network, dryrun-commit) should work now with empty input. If the input is empty, operation will be invoked on all touched nodes.","[FIXES]","Unified representation of empty snapshot metadata - it will return 404.","Propagation of southbound error message to Uniconfig layer after failed installation."]},{"l":"CONTROLLER","p":["[NEW FEATURES]","Auto-generation of local UniConfig instance name, if it is not set in the configuration file.","[FIXES]","Fixed persistence of templates: fixed extraction of node-id from path.","Fixed omitting of module-name from URI: skip openconfig/native-CLI augmentations from created UniConfig-native schema.","Fixed parent module lookup when resolving leafrefs- parent module was mapped not to parent, but the submodule itself.","Fixed parsing of source-ids from YANG files- don't inherit revision from parent module.","[IMPROVEMENTS]","Improved error message on failed building of schema context.","Optimized YANG schema cache: Removed in-memory schema cache listener that was caching bulky AST form of all sources. Caching of them is not valuable anymore because there is only 1 schema context per device-type."]},{"l":"SWAGGER","p":["[FIXES]","Removed trailing slash from generated URIs (conforming RFC-8040 format).","Fixed importing of 4.0.0-alpha-1-SNAPSHOT (maven-core).","[IMPROVEMENTS]","Stop emitting operational nodes in swagger.","Adding snapshots-metadata and tx-log to generated swagger-api."]},{"l":"CLI","p":["[FIXES]","Fixed initialization of SSH session: Enforced following order of messages in SSH client - Protocol (SSH-2.0-APACHE-SSHD-2.4.0), Protocol (SSH-2.0-Cisco-1.25), Key Exchange Init, Key Exchange Init(some devices don't accept switching Protocol and Key Exchange Init messages).","Fixed setting infinite number of reconnection attempts."]},{"l":"NETCONF","p":["[NEW FEATURES]","NETCONF PKI data persistence: persistence of crypto information in the file-system.","[FIXES]","Capturing error message from SSH session initialization process.","Fixed setting infinite number of reconnection attempts.","Fixed self-reconnection of NETCONF session (issue with keepalive timer).","Fixed netconf testtool in mdsal-persistent-mode - do not share Datastore across all devices.","Fixed overwriting IETF schemas by UniConfig shcemas in netconf-testtool.","[IMPROVEMENTS]","Removed unused netconf-ssh classes.","Improving the way of printing NETCONF reconnection attempts.","Testtool: Enable manipulation of operational data over NETCONF."]},{"l":"RESTCONF","p":["[NEW FEATURES]","Pagination: get-count, limit, and start-index query parameters.","[FIXES]","Fixed adding schema-respoitory parameter to PATCH operation.","Fixed serialization of identityref key value."]},{"l":"CLI TRANSLATION UNITS","p":["[FIXES]","[IMPROVEMENTS]","[NEW FEATURES]","Huawei: Add caching for \"display current-configuration\" command.","Huawei: created TU for AAA.","Huawei: created TU for ACL.","Huawei: created TU for physical, VLAN interfaces, sub-interfaces.","Huawei: created TU for trunk and access VLANs.","Huawei: Read interfaces of Huawei devices with \"display interface brief\".","Huawei: Updated parsing of output for L3-VRF.","IOS XE: Fixed missing some information about route maps for IOS.","IOS XE: Fixed sending \"dot1q 1-4094\" to IOS XE devices.","SAOS6: All interfaces cannot be marked as Ethernet.","SAOS6: Changed name for l2vlan interface to \"cpu_subintf_\" l2vlan name.","SAOS6: Fixed creation of sub-port on EthernetCsmacd interfaces.","SAOS6: Reading all interfaces from ciena devices using command\"interface show\"."]},{"l":"NETCONF TRANSLATION UNITS","p":["[FIXES]","Fixed importing ietf-inet-types - there are multiple revisions available in the UniConfig.","[IMPROVEMENTS]","Speed up device model build by disabling various maven plugins."]},{"l":"OPENCONFIG","p":["frinx-huawei-network-instance-extension - added network-instance extension.","frinx-saos-if-extension - added ipv4 and ipv6 address extension.","frinx-cisco-if-extension - the dot1q value type is changed from int to string and the range is saved as a string.","frinx-acl-extension - ACL for huawei devices","frinx-openconfig-aaa, frinx-openconfig-aaa-radius, frinx-openconfig-aaa-tacacs, frinx-openconfig-aaa-types, frinx-huawei-aaa-extension - added aaa and radius modules from openconfig.","frinx-huawei-if-extension - added yang for huawei interface and sub-interface extensions.","frinx-openconfig-bgp-types, frinx-openconfig-extensions -fixed bug with community set values."]}],[{"i":"uniconfig-427","l":"UniConfig 4.2.7"},{"l":"Uniconfig","p":["[FIXES]","[IMPROVEMENTS]","[NEW FEATURES]","Added UniConfig transaction-id as fingerprint for devices not supporting it.","Adjusted persistence of mount information - node with the same ID may be present in both CLI/NETCONF topologies - and node only from one topology at the same time can be used for installation on UniConfig layer (configuration is synced and parsed).","Changed native-CLI architecture - UniConfig calls native-CLI readers/writers directly using BI API - BA translation layer provided by Honeycomb is redundant.","Fixed calculate-diff - Removing the whole list node with all list entries.","Fixed commit output: if the configuration of one of the nodes fails at any phase, then the outputs for all nodes will always contain a rollback flag.","Fixed creation/removal of dry-run Unified mountpoint - synchronization problems.","Fixed dry-run commit - Dry-run commit should trash journal of nodes that haven't been 'touched'.","Fixed losing of some tags in DOM nodes (application of template)","Fixed reading of uniconfig-native flag - unboxing of null Boolean to boolean.","Fixed rollback operation after commit/checked-commit.","Fixed sync-from-network for unavailable nodes - Comparison of config fingerprints failed for nodes that are unavailable because reading of fingerprint failed.","Fixed transfering of template tag from template to uniconfig topology at apply-template RPC (it should not happen).","Fixed version-drop in copy RPC.","Fixed writing ordered-map nodes during string substitution process(application of template).","Handling reordering of list entries in the calculate-diff - instead of sending delete+replace operations to the southbound layer.","Implementation of get-installed-nodes RPC: used for listing installed UniConfig nodes.","Implementation of revert-changes RPC: reverting transaction that is stored in transaction-log and identified by unique UUID.","Implementation of transaction-tracker (transaction-log): tracking of successfully committed data.","Improved error messages - using serialized form of YangInstanceIdentifier in logs or error messages, if possible.","Improved error messages during application of template.","Improving the existing algorithm that collapses diff from honeycomb(parallel streams).","Integration of fingerprint validation to templates - writing of fingerprint of modified templates to database and verification of fingerprint before commit.","Introduction of install-node, uninstall-node, mount-node, and unmount-node RPCs - a new way to install nodes into UniConfig with split concepts of installation and mounting. Mounting is always done on demand and the mountpoint is alive as long as some transaction is using this mountpoint.","Introduction of UniConfig transactions - dedicated/shared transactions concept: multiple users can use UniConfig safely from isolated transactions. UniConfig RPCs are part of UniConfig transactions - information about transaction-id is passed from the RESTCONF layer into the UniConfig layer.","Making UniConfig instance stateless - data is separated from UniConfig (PostgreSQL database) and UniConfig doesn't keep persistent connection to devices. Data and connection recovery is not done by UniConfig instances anymore (coordination, monitoring, and recovery process is not orchestrated by UniConfig). From the view of data-tree, UniConfig is used only as a cache layer on top of PostgreSQL database and caching is done only in the scope of transaction.","Mark sync operation failed on empty config.","Removed data-tree cache layers on CLI and NETCONF layers - UniConfig directly writes data to CLI/NETCONF mountpoints - it simplifies syncing process too.","Removed snapshot limit - it is not used anymore since snapshots are stored in the database and this database should manage its storage limits.","Removed unused Karaf features.","UniConfig shell prototype: SSH server, RPC operations, simple read operation.","Using commit RPC for committing snapshots and templates.","Using distributed advisory locks provided by PostgreSQL for locking of UniConfig nodes during commit/checked-commit operation. If another transaction perfors commit at the same time, it will fail before execution of the second commit.","Validation of conflicts between different transactions: added data-tree and config fingerprint validation before commit / checked-commit RPC invocation."]},{"l":"Controller","p":["[FIXES]","[IMPROVEMENTS]","[NEW FEATURES]","Added synchronization when generating BA->BI codecs.","Added workaround for 'metadata not available' data-tree bug.","Allow positional information in YangInstanceIdentifier (useful for operations under ordered lists).","Allow users to specify attributes without module-name (template tags).","Breaking PUT modifications to specific modifications in the data-tree: improving 'optimistic lock' granularity.","Ensuring parents by merge: avoiding ridiculous errors when data-tree allows to write data to nodes which parent is missing.","Exposed simple container merge utility.","Extending RPC service by custom parameters that can be passed from RPC caller to RPC implementation.","Fixed creation of DocumentedException from XML (document may include redundant namespaces).","Fixed data-tree modifications: merge->put->delete operation chain.","Fixed disappeared tag from template data-tree.","Fixed leaked DB connection on health-check operation.","Fixed order in which database writers are called (adding priority to DatabaseWriter API).","Fixed race-conditions in 3-phase datastore commit.","Fixed searching for fallback context on nodes that were not mounted(uniconfig-native).","Fixed storing of the default schema repository into PostgreSQL.","Generalisation of NETCONF repository into YANG repository.","Implemented standalone DOM broker - stopping to use clustered/distributed DOM brokers.","Integration of Flyway library to Uniconfig: easier upgrading of database schema and migration of data.","Integration of JSONB filtering of configuration on the level of DAOs.","Integration of UniConfig transaction manager with database and datastore transactions - used for management of shared/dedicated transactions.","Introduction of embedded PostgreSQL for testing purposes - it can be enabled from the UniConfig configuration file.","Making the database layer more thread safe (using 'SELECT FOR UPDATE' in some queries).","Optimized creation of uniconfig-native schemas.","Persistence of logging configuration in PostgreSQL.","Persistence of snapshots in PostgreSQL.","Persistence of templates in PostgreSQL.","Persistence of transaction-log in PostgreSQL.","Preserving order of list/leaf-leaf elements in the data-tree.","Removed unnecessary dependencies of xtend maven plugin.","Removed unused Karaf features.","Replaced asynchronous DB API by synchronous DB API - JDBC connections are synchronous.","Separated persistence of UniConfig nodes and representing mountpoints.","Stop submitting datastore transactions - it must be closed - datastore is used only as cache.","Validation and locking of templates and UniConfig nodes on the level of UniConfig transaction."]},{"l":"Swagger","p":["[FIXES]","Fixed bug caused by swagger-uniconfig-go.","[IMPROVEMENTS]","Make openAPI generated for uniconfig more useful.","Added Unified layer models to swagger dependencies."]},{"l":"Translation units framework","p":["[NEW FEATURES]","Added native-CLI binding-independent API.","[IMPROVEMENTS]","Removed unused artifacts.","Optimized chunk cache - do not store entire writer in chunk cache, so GC can take care of writers as soon as possible.","Detection of complex reordering of list entries in diff output.","[FIXES]","Fixed commit rollback failing: the bug was caused by an attempt to execute an inverse command of an unsuccessful command."]},{"l":"CLI","p":["[IMPROVEMENTS]","Removed unused Karaf features.","Exposed binding-independent data support to native-CLI API.","Exposed services for direct device access to MP.","[FIXES]","Replace maxConnectionAttempts with maxReconnectionAttempts when reconnecting to the device after the first connection attempt is successful.","Replaced transactionChain (not working correctly) with direct dataBroker transactions.","Fixed device type checking - when a device was mounted with the wrong type, the generic symbol (\"\") was implicitly used as the type. The device was installed on all layers, but uniconfig/configuration was empty. Now we have to use correct device type or.","Fixed disabled CLI journaling (default value)."]},{"l":"NETCONF","p":["[NEW FEATURES]","Added maxReconnectionAttempts functionality into NETCONF client.","[IMPROVEMENTS]","Removed unused Karaf features.","Improved error message from parsing of NETCONF RPC response.","Removed akka actor dependency from NetconfCacheLoader.","Enable md-sal persistence accross sessions in NETCONF testtool.","[FIXES]","Fixed writing of netconf namespace prefix ('Namespace urn:ietf:params:xml:ns:netconf:base:1.0 was not bound, please fix the caller').","Fixed reading of the whole list/leaf-list from the device - it was reading the whole parent structure, not only the dedicated list.","Moving state to unable-to-connect after failed schema context building from device YANGs.","status is written to datastore, because mount-node RPC relies on OPER information only.","Fixed deadlock that may occur on removal of Unified MP."]},{"l":"RESTCONF","p":["[NEW FEATURES]","Added support for RESTCONF PATCH method that includes tags.","Integration of UniConfig dedicated/shared transaction to RESTCONF - cookie with transaction-id property, create-transaction RPC, and close-transaction RPC.","Introduction of jsonb-filter query parameter used for filtering of data committed to database.","[IMPROVEMENTS]","Removed unused Karaf features.","Using RFC8040 format for errors thrown from the transaction system.","[FIXES]","Fixed RESTCONF response/request logging.","Fixed reading of all available RPC operations.","Fixed NPE that is caused by Subject.getPrincipal() - extraction of authentication data from AAA.","Fixed serialization of ordered leaf list with attributes.","Fixed connection leak - read-only transaction was not always closed.","Fixed parsing of elements without module name: If there are some conflicts between children elements - multiple elements with the same name but in different modules exist - then we should return a proper error message.","Fixed use of fields query parameters with uniconfig-native nodes."]},{"l":"NETCONF translation units","p":["[IMPROVEMENTS]","Removed unused Karaf features.","[FIXES]","Fixed writer dependency in XR623 ISIS translation unit.","Ignored 'ios-xr lacp period 200' command - only 'lacp period short' is supported."]},{"l":"CLI translation units","p":["[FIXES]","[IMPROVEMENTS]","[NEW FEATURES]","Huawei: additions - global config reader and writer for bgp, neighbor config reader and writer, new augmentation fields for global and neighbor configurations.","Huawei: translation units - interfaces.","IOS XE: added ios-xe 15 and 17 to ios-xe module.","IOS XE: additions - media-type command, port-security commands, BDI type recognition, ethernet cfm mip command, cft commands, commands for bgp, prefix-list command, fhrp delay, bfd-template, split-horizon group in bridge-domain, added fallOverMode for vrf neighbor, IPv6 prefix-lists with prefix lengths, routing-policy, ipv6 vrrp, added synchronization and moved default-information in BGP, table-map, ip community-list command, redistribute command, bgp and interface commands, ipv6 commands, rewrite command, snmp trap, support for multiple l2protocols,.","IOS XE: created a distinct module for IOS-XE in cli-units.","IOS XE: fixed writing interface config, fixed unwanted lldp/cdp/switchport vlan commands commands, fixed IPv6 config writer template, fixed mounting of IOS XE (configuration metadata), fixed bridge-domain regex, fixed reading VLANs, fixed storm-control regex, fixed NPE in GlobalAfiSafiConfigWriter, fixed BgpAfiSafiChecks, fixed CommunityListConfigReader and L3VrfReader, fixed IndexOutOfBoundsException in BgpActionsConfigReader.","IOS XE: make sure all 'GigabitEthernet' interfaces are treated as physical, don't send unnecessary commands in interface unit, only send storm-control commands when needed, moved service instances and encapsulation in service instance in ios-xe/interface, edit readers and writers for bridge-domain, edited LLDP to not parse when default is set, speed up mounting","IOS XE: translation units - SNMP, LACP, privilege command, interfaces, l2protocol, evc, route-map, bgp and network-instance modules, vrf definition, fhrp version, ip commands, neighbor, ethernet cfm mip, negotiation auto.","IOS-XR: delete methods should always be readBefore, fixed calling get on a null value, fixed delete of mpls-te.","Movef service-policy from IOS/interface to IOS/QoS.","Removed unused Karaf features.","SAOS6: fixed virtual-circuit ethernet delete, fixed reading Virtual Ring data, fixed reading the range of vlans in virtual ring commands, reading default interface.","SAOS6: translation units: Ingress ACL.","SAOS6: use the same template for service as for profile schedulers.","SAOS6/8: added quotes into description.","SASO6: additions - commands for delete untagged attributes, unset description command, parsing ranges in ring protection.","SONiC: created init and interfaces unit."]},{"l":"Openconfig","p":["created frinx-openconfig-evc module","created frinx-privilege module","fixed Openconfig bug with nested augmentations (fixed resolving augmentations path)","frinx-bfd-extension: bfd-template-config","frinx-bgp-extension: added bgp extension for Huawei device, local-as-group, route-maps in redistribute commands, BGP neighbor, table-map in BGP, synchronization and moved default-information in BGP, added bgp fall-over mode, neighbor as-override, default-information originate,","frinx-cisco-if-extension: added negotiation auto, added support for multiple l2protocols, added support for rewert commands, vrf forwarding, ip commands, fixed L2protocol description, split-horizon group in bridge-domain, chaed bridge-domain type to string, fhrp delay, fixed bad order of augmentation in frinx-cisco-if-extension.yang, bridge-domain, added grouping for L2protocol for Service instance, added grouping for L2protocol for Service instance, move encapsulation in service instance, move service instances, created augmentation for service instances, cft cisco specific commands, added port-security,","frinx-cisco-ipvsix-extension: added yang extension for global ipv6 commands.","frinx-cisco-routing-policy-extension: prefix lengths in prefix-list, sequence-id, forwarding-action, route-map","frinx-cisco-vrrp-extension: added ipv6 vrrp augmentation, added vrrp-group augmentation,","frinx-oam: added ethernet cfm mip","frinx-openconfig-bgp-policy-extension: added community-list type,","frinx-openconfig-bgp-types: extracted typedefs for community union type.","frinx-openconfig-fhrp: fhrp version","frinx-openconfig-lacp: added ON lacp mode","frinx-qos-extension: moved service-policy from IOS/interface to IOS/QoS","frinx-snmp: added snmp-view config","removed unused Karaf features from openconfig"]}],[{"i":"uniconfig-426","l":"UniConfig 4.2.6"},{"i":"uniconfig","l":"UniConfig:","p":["new feature: introduced 3-phase commit - integration of validation and confirmed-commit features - here","new feature: templates can be used for reusing of some configuration and afterwards easier application of this configuration into target UniConfig nodes - storing of templates in UniConfig, modification of templates including tags using RESTCONF operations, and application of templats to target UniConfig nodes using apply-template RPC","new feature: added copy-subtrees RPCs - merge or replace whole subtrees: copy-one-to-one, copy-one-to-many, copy-many-to-one","new feature: added calculate-subtree-diff RPC - calcution of diff between two subtress in datastore","new feature: implemented uniconfig healthcheck - RPC checks UniConfig and database connection","fixed auto-sync service","fixed creation of Unified mountpoint for CLI device without available translation units - using only 'generic' units in this case"]},{"i":"controller","l":"CONTROLLER:","p":["improvement: removed 'native_prefix' from 'node' database relation - it is replaced by NETCONF repository name","fixed MDSAL union codec - it didn't work with boolean subtype"]},{"i":"cli","l":"CLI:","p":["fixed unmounting of CLI device: the case when mounting process hasn't successfully finished yet"]},{"i":"netconf","l":"NETCONF:","p":["new feature: NETCONF validate RPC and confirmed-commit RPC exposed by extension of DOM transaction","improvement: mounting NETCONF device with explicitly set NETCONF repository name that must be used - using this approach, it is not necessary to explicitly override/merge capabilities in the mount request - here","improvement: replacing uniconfig-native fingerprint by'schema-cache-directory' in NETCONF operational data","fixed mounting SROS device with specified ignoreNodes/namespaceBlacklist - here","fixed: unmounting of NETCONF device which mounting process hasn't finished yet","fixed: increased maximum NETCONF chunk size to 32*1024*1024"]},{"i":"restconf","l":"RESTCONF:","p":["new feature: introduced 'uniconfig-schema-repository' query parameter - explicitly set name of the schema using which input/output data is validated","new feature: JSON attributes - option to encode XML-like attributes into JSON structure: - here"]},{"i":"cli-translation-units","l":"CLI TRANSLATION UNITS:","p":["IOS: fix - QoS translation unit, added port-channel into interface type","IOS: added translation units - storm-control, standard ACL","IOS: refactoring - allowed vlans on trunk interface","SAOS: fixed translation units - statistics augmentation, command ordering, ethernet config reader/writer, ordering of VLAN and VC, order of CPE commands","SAOS: fixed initialization - committing configuration during initialization"]},{"i":"openconfig","l":"OPENCONFIG:","p":["frinx-acl-extension: added support for standard ACL","moved statistics from frinx-saos-vlan-extension to frinx-saos-vc-extension","frinx-cisco-if-extension: added storm control","frinx-qos-extension: extended and fixed support for IOS QoS"]},{"i":"known-issues","l":"Known Issues:","p":["The error message needs to be fixed to inform user about the name clash and how to fix it","ODL did not started if cache folder for SROS16 device is applied","BGP: NullPointerException occurs when configure network instances for XE","NETCONF: Junos 18 is can't be mounted by netconf Xrv6.2.3 device has been locked and session went down after specific set of commands","CLI: Performance issues when is more than 400 devices connected","RPC: Commit and Checked commit issues when invalid configuration has been applied to one router Transaction has been locked during checked commit no rollback when invalid configuration has been configured to one router"]}],[{"i":"uniconfig-425","l":"UniConfig 4.2.5"},{"i":"uniconfig","l":"UniConfig:","p":["new feature: show-connection-status RPC: it can be used for verification of status of selected nodes on CLI, NETCONF, Unified, and Uniconfig layers - here","new feature: filtering of data that is read from NETCONF mountpoint based on YANG extension that can be placed in the mount request ('uniconfig-config:extension' parameter) https://docs.frinx.io/frinx-odl-distribution/oxygen/user-guide/network-management-protocols/uniconfig_mounting/mounting-process.html#example-mounting-of-uniconfig-native-netconf-device","new feature: is-in-sync RPC: verification if UniConfig Operation datastore is in sync with device - here","new feature: introduced 'install-uniconfig-node-enabled' mount request parameter - option to not install node in the Unified and UniConfig layers - node would be installed only in the southbound layer - here","new feature: introduced uniconfig-native translation units used for reading and parsing of only configuration fingerprint","improvement: calculate diff for uniconfig-native nodes diff output shows difference also on the level of leaves and leaf-lists(better granularity)","fixed setting of maximum snapshot limit (passing 0 in input)","fixed uniconfig-native - mounting node using CLI and afterwards using NETCONF uniconfig-native didn't work as expected","fixed caching of read operational data: improved performance for nodes that are mounted via NETCONF translation units"]},{"i":"cli","l":"CLI:","p":["new component: creation of CLI flavour for SAOS devices for successfull reading and parsing of device configuration","new component: \"one-line-parser\" CLI parsing engine that uses grep function for parsing running-configuration","fixed synchronization of UniConfig operations (for example, commit RPC) and CLI RPCs (for example, execute-and-read)"]},{"i":"netconf","l":"NETCONF:","p":["new feature: added support for invocation of YANG 1.1 actions and TAILF actions - here","new feature: NETCONF edit-config test option - controlling validation of sent edit-config messages on NETCONF server - here","new feature: introduced 'default' NETCONF cache repository that can be used for side-loading of missing/fixed YANG schemas that are invalid/not provided by NETCONF device - here","new feature: introduced logging of whole NETCONF communcation - per-device NETCONF messages, notifications, and system events - here","improvement: added NETCONF cache directory (NETCONF repostory) into Operational datastore of NETCONF node","fixed authentication in NETCONF testtool (key-pair provider)","fixed parsing of NETCONF replies that contains multiple RPC errors(severity of error was not correctly considered)","fixed creation of NETCONF mountpoint - it was not blocking, so higher layers haven't caught events in the correct order","fixed loading of NETCONF cache repository into Operational datastore","synchronization issues","fixed propagation of user-friendly error messages from NETCONF layer into UniConfig RPC output"]},{"i":"restconf","l":"RESTCONF:","p":["new feature: subscription to NETCONF device notifications via websockets - here","new feature: invocation of YANG 1.1 actions and TAILF actions - here","new feature: invocation of PLAIN PATCH operation - here","new feature: schema filtering based on YANG extensions and deprecated YANG statement - reading and modification of data - here","new feature: introduced logging of whole RESTCONF communcation with option to hide fields with selected YANG type - here","improvement: improved RESTCONF error messages in case of invalid URI - displaying possible children nodes","fixed reading of whole list under augmentation/choice node"]},{"i":"controller","l":"CONTROLLER:","p":["new feature: introduced PostgreSQL persistence system for UniConfig nodes: persisting node configuration and NETCONF repositories into DBS with recovery system in the cluster - here","upgrade: using TrieMap dependency for data-tree implementation"]},{"i":"distribution","l":"DISTRIBUTION:","p":["added support for Java 11: compilation of all projects using JDK 11 and also running of UniConfig distribution using JRE 11","fixed invocation of UniConfig with \"--help\" argument","changed logging framework from log4j to logback","added \"--debug\" parameter for opening debug session"]},{"i":"translation-units","l":"TRANSLATION UNITS:","p":["fixed invocation of subtree writers based on wildcard path"]},{"i":"netconf-translation-units","l":"NETCONF TRANSLATION UNITS:","p":["XR6: added L3VPNIPV4UNICAST afi-safi type","XR6: fixed BGP neighbor reader","JUNOS17: fixed LACP units"]},{"i":"cli-translation-units","l":"CLI TRANSLATION UNITS:","p":["SAOS: create readers and writers for logical-ring","SAOS: fixed sending of commit command, parsing of port range, dependencies between writers, parsing of connection point key, interface subport writer, registering of interface writer, hardening update commands, L2VSICP writer, getAllIds in PortReader","IOS: added translation units: QoS, interface statistics, service-policy, VLAN, routing-policy","IOS: modified translation units: added next parameters into BGP, switchport mode options: dot1q && access, BGP neighbor version, SPEED parameter, ICMP type into ACL entry","IOS-XR: fixed LACP bugs: 'mode on' configuration is now explicit, subinterfaces were wrongly added to list of LAG interfaces","Arista: added init unit","Cubro: added CLI flavour"]},{"i":"openconfig","l":"OPENCONFIG:","p":["frinx-qos-extension: added support for CoS and DSCP in QoS","frinx-cisco-if-extension: added switchport mode options: dot1q, access","frinx-bgp-extension: added BGP neighbor version support","frinx-if-ethernet-extension: added interface SPEED parameter","frinx-cisco-if-extension: added port-type, snmp-trap-link-status, switchport-mode, switchport-access-vlan, switchport-trunk-allowed-vlan-add, ip-redirects, ip-unreachables, ip-proxy-arp, service-policy","created SAOS model extension (frinx-saos-virtual-ring-extension)","created Cisco BGP model extension (frinx-cisco-bgp-extension)","fixed frinx-bgp-extension YANG","fixed auto-generated yang docs"]},{"i":"known-issues","l":"Known Issues:","p":["The error message needs to be fixed to inform user about the name clash and how to fix it. ODL does not start if cache folder for SROS16 device is applied","BGP: - NullPointerException occurs when configure network instances for XE","NETCONF: - Junos 18 is can't be mounted by netconf - Xrv6.2.3 device has been locked after specific set of commands","CLI: - Performance issues when is more than 400 devices connected"]}],[{"i":"uniconfig-424","l":"UniConfig 4.2.4"},{"i":"uniconfig","l":"UniConfig:","p":["Added uniconfig node status- each node is in one of these states: installing, installed, failed","Added unified node status- each node is in one of these states: installing, installed, failed","bugfixing"]},{"l":"UniConfig Native","p":["UniConfig Native for CLI- new experimental feature allowing to communicate with devices in a native way using hand-written YANG models","Added sequence-read-active param- this forces UniConfig to read root configuration elements sequentially."]},{"l":"CLI","p":["Introduced RPC execute-and-expect- It is a form of the‘execute-and-read’ RPC that additionally may contain ‘expect(..)’ patterns used for waiting for specific outputs/prompts. It can be used for execution of interactive commands that require multiple subsequent inputs with different preceding prompts.","Introduced Tree-parser as CLI parsing strategy- device configuration is parsed into a tree. It provides faster lookup operations for reads.","Introduced native CLI- feature allows to define YANG models instead of translation units. YANG models need to be created based on device specific CLI commands"]},{"l":"OpenConfig","p":["added various extensions for Ciena TUs"]},{"l":"NETCONF","p":["bugfixing"]},{"l":"Translation units","p":["Added CLI translation units for Ciena SAOS6 and SAOS8","bugfixing"]}],[{"i":"uniconfig-423","l":"UniConfig 4.2.3"},{"i":"uniconfig","l":"UniConfig:","p":["create Lighty based distribution- removal of Apache Karaf altogether, this distribution is based on lighty.io","RPC input/output rework","Unification of RPC inputs/outputs","Prevent any network wide operations if no node id has been passed- All RPCs MUST specify node-id of nodes they are affecting","new UniConfig transactions- create-transaction, cancel-transaction are used in HA deployments","bugfixing"]},{"l":"UniConfig Native","p":["separate schema contexts based on device type- it allows to mount devices with same YANG models but different revisions"]},{"l":"Lighty","p":["adding of AAA support","adding of TLS support"]},{"l":"RESTCONF","p":["update to RFC-8040 based RESTCONF- only this version runs by default","usage of schema context based on device type for data parsing","creation of custom UniConfig JSON/XML parsers/serializers"]},{"l":"OpenConfig","p":["added models: ipsec, frinx-if-ethernet-extension","added various extensions for Brocade TUs"]},{"l":"NETCONF","p":["run-time loading of netconf cache repositories","division of netconf cache based on device type","creation of schema context from netconf-cache","bugfixing"]},{"l":"Translation Units","p":["bugfixing"]},{"l":"Known Issues","p":["JSON response for GET snapshots of UniConfig-native nodes contain generated prefix \"uniconfig--\" (e.g. native-529687306-Cisco-IOS-XR-ifmgr-cfg:interface-configurations). This issue does not have an impact on RPC replace-config-with-snapshot."]}],[{"i":"uniconfig-508-release-notes","l":"Uniconfig 5.0.8 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Created TU for Arris(CER) device","Install-node without mounting/syncing configuration from device","Option to divide OpenAPI files into modules"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Uniconfig-client: increased default HTTP response read timeout","Fixed NETCONF connection timeout","Fixed number of NETCONF reconnection attempts","Fixed waiting for NETCONF dry-run mountpoint","Fixed reading of default NETCONF parameters","Added 'get-template-info' RPC to oper mode (shell)","Huawei install DB parsing issue","Fixed memory visibility issues in MountpointRegistry","Fixed parsing junos xml configuration","Fixed parsing xml configuration with reordered lists items","Fixed list of available RPCs in UniConfig Shell"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Optimization of calc-diff RPC after replace-config-with-oper RPC","Install-node without mounting/syncing configuration from device improvements","Added missing attributes to SAOS6 Interface","Remove OSS index checks from owasp","Generate release notes during merge job"]}],[{"i":"uniconfig-509-release-notes","l":"Uniconfig 5.0.9 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implemented dedicated device sessions","Implementation of device locking states","Implementation of speed attribute for saos6 and saos8 (#21)","Expose kafka producer settings into java client","Added option to use list key delimiter in URI","Implementation of pm instances for port queue groups in saos8 (#11)","Expose kafka producer settings","Implementation of default vlans for saos6 (#10)","Implementation of auto-neg attribute for both saos6 and saos8 (#9)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed ordering of data inside transaction on SONiC device","Fix ignoring empty key","Fix serialization of keyDefinitions","Cleaned and fixed locking of nodes in uniconfig RPCs","Fixed generation of NETCONF message-id","Fixed JSOB filtering - creation of jsonpath and parsing output"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Updated writer template for saos6 and saos8 (#32)","Implementation of speed attribute for saos6 and saos8 (#21)","fix showing list entries in cli suggestions"]}],[{"i":"uniconfig-5010-release-notes","l":"Uniconfig 5.0.10 Release Notes"},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed removing native prefix from snapshots (#57)","Fixed parsing GNMi GET response (augmentation content)","Fixed parsing result from immediate-commit model","Fixed lost list ordering after apply-template RPC"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Add a parameter so empty GET response returns 204"]}],[{"i":"uniconfig-5011-release-notes","l":"Uniconfig 5.0.11 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Remove namespace from response (#77)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["uc shell: update simple value and list value simultaneously","uc shell: transaction log ordering","VHD-162 Fixed Issue with With-Defaults param. (#68)","Serialization of int64, uint64, decimal types as string type","Changed order of executing remove and add vlans for saos6 (#75)","Fixed NETCONF reconnection attempts after connection timeout","Removed parent-node-id from NETCONF layer","Fixed synchronization of NETCONF session timeout"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Fixed ordering of data inside transactions for SONiC device","Implementation of common commands of relay agent for saos8 (#78)","Implementation of common commands of relay agent for saos6 (#70)","UC shell: autocompletion of nodes (#36)","Fix parallelism in apply-template RPC (#73)","Implementation of relay-agent sub-port command for saos8 (#47)","Changed default value of content query parameter to 'config'","Add sshd package to logback.xml with INFO level (#67)"]}],[{"i":"uniconfig-5012-release-notes","l":"Uniconfig 5.0.12 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Inclusion of unhide query parameter in PUT/POST/PATCH requests","Sync-to-network RPC"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Swagger - remove input container (#113)","Fix unhide param for write operations","Fixed default value of speed in ios (#95)","Changed isEmpty to null check (#96)","Fixed default value of speed in ios-xe (#88)"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Swagger - Fix authorizations (#114)","change behavior of execute-and-expect RPC (#112)","Swagger - configurable description and toggle servers","Enabled TCP keepalive mechanism in JDBC connection","Added 'database-connection-client-port' to 'transactions-data'","Swagger - generating adjustmens","Using hideEmptyDataNodes parameter per request (#94)","updated write template of interface config for ios xe devices for use-cases where no changes are requested from the user (#91)","Improve schema context caching for gnmi devices"]}],[{"i":"uniconfig-5013-release-notes","l":"Uniconfig 5.0.13 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Add jsonb-filter in UC client","Automation of adding release notes to documetation","API for bulk addition of templates","Implementation of callbacks","Implementation of publishing shell notifications to kafka","JSONB filtering core","Upgrade-from-network as part of sync-from-network"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Cancellation of initial NETCONF RPCs after request timeout","Fixed parsing XML-endoded leaf with instance-identifier to list","Fixed synchronization of notification listeners","Releasing subscription that is bound to tangling mountpoint","Fixed construction of output with set with-defaults param","Fix gnmi unknown augmentations"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Implementing HideAttributes query-parameter per request. - Introduced query parameter HidesAttribute. Default value is 'false'. Hides all composite data-tree nodes attributes to the GET response.","Stop acquiring subscription that was released in the same iteration","Fixed and refactored DOMMountPointService implementation","Add support for template leaf hashing","Improved code and API of create-multiple-templates RPC","Implemented frinx-types:json-element in the JSON deserializer","Swagger - Grouping requests","Swagger - Remove patch operation","Bump Mockito and get rid of Powermock","Swagger: inclusion of action endpoints","YangPackager does not catch broken submodules","Refresh schema context for netconf southbound if device was upgraded","Make mountpoint service call listeners from different thread"]}],[{"i":"uniconfig-5014-release-notes","l":"Uniconfig 5.0.14 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Added a flag to disable confirmed-commit phase in commit RPC (#181)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Adding 'rsa_' prefix to encrypted data","Changed the way to get config metadata for ios xe devices","Disable html escaping in callbacks output","Fix adding release notes to documentation repository","Fix Flyway when using SSL encryption","Fix of incorrect UC behavior when on limit with DB connections","Fix parsing of sslPassword parameter","Fix setting of DbConnectionConfig parameters","Fixed creation of aug with admin-state leaf","Fixed detection and recovery from cyclic dependency error in YANGs (#161)","Fixed duplicate module lookup in path deserializer (RESTCONF) (#150)","Fixed encryption (#170)","Fixed parsing NETCONF action response","Fixed recovery of Cipher object","Fixed SAOS Qos TU writer","Jsonb-filter multiple schemas bugfix","Make tailf:info revision independent","Updated config metadata pattern in reader for ios xe devices (#174)"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Internal delete for trunk-vlans","JSONB-filter improvement"]}],[{"i":"uniconfig-5015-release-notes","l":"Uniconfig 5.0.15 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implementation of bulk-edit RPC"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixes for trunk-vlans handling"]},{"i":"api","l":"\uD83D\uDCBB API","p":["Defined API for bulk-edit RPC"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Do not use common fork join pool in DOMMountpointService"]}],[{"i":"uniconfig-5016-release-notes","l":"Uniconfig 5.0.16 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Added create-multiple-templates RPC to uniconfig-client","Added option to specify tags in create-multiple-templates RPC","Swagger: Grouping of RPCs and tailf:actions","Encrypt/Decrypt of password for gnmi/netconf/cli topologies"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Data-change-events: make node-id optional","Displaying the default unistore node in shell for callbacks","Fix Guava dependency in POM","Fix replace-list ordering","Fix using ignoredNamespaces from swagger-config","Fixed merging template tags into merge node in the same TX","Fixed parsing nodes with attributes","Fixed regex for trimming path in TransactionTrackerUtils (#241)","Fixed submitting changes to database if there are failed nodes and do-rollback is false (#227)","Fixed writing of unkeyed list entry node","Remove duplicate yang models","Removed non-working option to create unistore node in request and show states","Revert \"Install-node without mounting/syncing configuration from device\"","Swagger - fix list container wrapping","Swagger: Fix behavior of basePath and server generation","Swagger: Fix top level containers not generating","Wrap requests to make them RFC 8040 compliant"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Adjusted logging of keepalive messages (stream sessions)","Made amount of max parallel installs customizable (#204)","Made error message user-friendly when user enter nonexistent node-id","Make create-multiple-templates RPC 'atomic'","Mapped \"gig\" to SpeedType.Gigabit","Netconf rpc timeout (#257)","Optimization of callbacks","Refactored stream writers used by RESTCONF","Removed last pieces of CheckedFuture and old unused MDSAL-API","Removed unused jettison dependency","Replaced CheckedFuture by FluentFuture - DOM read transaction","Replaced CheckedFuture by FluentFuture - DOM store read transaction","Replaced CheckedFuture by FluentFuture - DOMRpcImplementation","Replaced CheckedFuture by FluentFuture - DOMRpcService","Replaced CheckedFuture by FluentFuture: TX submit()","Resolving CVE security issues between level 6 and 0","Set UNICONFIGTX cookie to entire domain not just /rests/","Specified create/close-transaction RPCs in YANG","Support upgrading of YANG repository content (#233)","Suppress CVE-2022-38752","Suppressing logs generated by received unknown requests (SSH)","Used FluentFuture in binding ReadTransaction"]}],[{"i":"uniconfig-5017-release-notes","l":"Uniconfig 5.0.17 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Swagger - filter path CRUD customization","Implemented invalid schema repository cleaner","Units-coverage RPC"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Commit fails if one of the touched node was uninstalled","Swagger - fix CRUD filter generation","Triggered commit hook if revert is successful","Fixed decryption of passwords in CLI layer (#301)","Add support for fetch=count with jsonpath filtering (#282)","Fix suppressed Jackson CVEs","Bump Apache commons-text to 1.10.0","Swagger - Fix GET operation generation for list nodes","Bump protobuf-java to 3.21.7","Changed order of executed commands for saos8 (#280)","Additional fix for dce global subscription in client.","Improve JSON parser error message","Changed the way of getting vlan name and egress-tpid","Localhost throws 500","Swagger: Fix operational API generation"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Replacing parallelStreams with more predictable alternatives","Swagger - add option to disable GET request generation for concrete list nodes","Add request timeout to gnmi session","Create modulesWithIgnoredNamespace list","Support install-multiple-nodes for gnmi","Swagger: Add content query parameter"]}],[{"i":"uniconfig-5018-release-notes","l":"Uniconfig 5.0.18 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implemented TU for collecting all the information in NTP MCS for Saos6 and Saos8 (#420)","Implemented low priority fields for collecting inventory for SAOS6 CEN(ring) (#341)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Swagger: Fix generation of arguments in path","Fixed cleanup of existing MP during mount-node RPC","Swagger: fix generation of choice nodes","Fixed encryption of sensitive info passed via template variables (#326)","fix Jsonb filter element filtering","Swagger - Fix request generation","Fixed passing leaf-list in shell callbacks"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Fix Logback and cleanup POMs","Swagger: Custom operational path","Improved reporting of parsing issues in RESTCONF","Swagger - Improve start file","Changed order of some commands for SAOS8 (#348)","Swagger: generate augmentations in respective modules","Expose request-timeout parameter","Bump dependency-check to 7.3.0","readEntireConfig toString returns plain content","Reading mount configuration in the uniconfig-client"]}],[{"i":"uniconfig-5019-release-notes","l":"Uniconfig 5.0.19 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Fixed hardcoded part and added one more if condition to receiver transceiver data for IOS-XE (#493)","Stable XR6 XR66 devices (#471)","Implementation of storing failed installations into DB (stable 5.0.x)","Implemented TU for adding/removing users for Saos6 (#438)","Implemented TU for collecting transceiver information for IOS-XE (#439)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Downgraded sshd to 2.8.0","Fix uninstall -> install transition","Swagger: fix generation of operational APIs (5.0.X)","Fix CVEs","Fixed reading public key from NETCONF device (NPE)","Fixed distribution of mount failure from GNMi layer","Swagger: Fix path filtering"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["expose gnmi parameters","add overallStatus to multiple-nodes-rpc-output","Improved error message when connection cannot be created","Exposed DOMMountPointService configuration","Optimization of mountpoint notifications","Added logs into DOM Mountpoint Service"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Configurable re-sending cli commands","Fixed mount point creation for CLI topology","Removed unified-topology.yang","Refactored unified layer and mounting/unmounting process - updates","Refactored unified layer and mounting/unmounting process","Added logging level for shell to the logback.xml"]}],[{"i":"uniconfig-5020-release-notes","l":"Uniconfig 5.0.20 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Support for GetInstalledNodes in UC client - 5.0.x","Add getJSONOutput to UniConfig client","Added some commands for collecting data for IOS-XE (#515)","Skip unreachable nodes at commit"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed leafref version-drop","Suppress Netty FP CVEs","Fixed quit command in the shell","Fixed pattern handling and XPath extension parsing","Fixed parsing of seconds in XR native metadata unit","Swagger: fix generation of action nodes (5.0.X)","Swagger: fix no key lists generation (5.0.X)","Fixed locking of nodes from TX with enabled dedicated sessions (#523)","Fix bug in bulk edit operation","Swagger: fix generation of operation children from config container"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Change overallStatus when skiping unreachable nodes","handle user parameters input in GnmiDefaultParametersService","Removed 'reconcile' mountpoint parameter (#572)","Disable verification of supported query parameters (5.0.x) (#549)","Swagger: toggle generation of POST apis for containers","Bulk-edit rpc improvements"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Swagger: fix npe in custom operational path (5.0.X)","Added only-vlan parser, upgraded trunk-vlans for huawei (#528)","Callbacks authentication"]}],[{"i":"uniconfig-5021-release-notes","l":"Uniconfig 5.0.21 Release Notes"},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Add migration for removing node-extension:reconcile"]}],[{"i":"uniconfig-5022-release-notes","l":"Uniconfig 5.0.22 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["make replace request on correct node for gnmi","Add GetTemplateNodes RPC and add support to Client","Implemented some new commands for Huawei TU (#580)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed encryption of leaves marked using deviations","Fix vulnerabilities by changing base docker image","Stop cleaning YANG repos associated to persisted nodes","Swagger: fix actions using custom operational path","Suppressed CVE-2021-4277 (#612)","Fix CVE-2021-37533"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Swagger: mandatory indicator","Improved registration of unexpected YANGs downloaded from device","Add compare-config RPC.","Changed logging level: Unable to map identifier to capability","Skipping unknown fields in GET request","Added an RPC input to enable error handling for execute-and-read RPC (#662)","Fetch Kafka settings to client.","add gnmi protocol to get-installed-nodes RPC","Swagger: add drop-down for topology-id parameter"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["PUT and DELETE operations for callbacks"]}],[{"i":"uniconfig-5023-release-notes","l":"Uniconfig 5.0.23 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implementation of RPD TUs for CER(Arris)","Implementation of Cable-Mac Oper TUs for CER(Arris)","Replace paths feature","Implementation of cable-upstream TUs for CER(Arris)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Added new control to check if cached prompt is invalid (#809)","Fixed writer of cable upstream interface","Added new control to check if cached prompt is invalid (#633)","Fix delete request in replace-paths","Fixed schema context building","Java based migration for huawei config","Bulk-edit - removed the version comparison before version drop procedure","Bump dependencycheck.version, update suppress for CVE-2022-41915, CVE-2022-41881"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Swagger: regular expressions with example values","Extended TreeConfigParser to handle arris device's behavior for cable-upstreams","Change isInstalled method implementation in uniconfig-client","JRE-17 compatibility","Added read option to bulk-edit RPC","Bump sshd to 2.9.2","Prefer 'latest' repository in latest repository update process","Change status code if transaction is not valid. (#711)"]}],[{"i":"uniconfig-5024-release-notes","l":"Uniconfig 5.0.24 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implemented RPD related commands to fiber-node TU for Arris Commscope","Swagger: difference between OpenAPI specifications"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed RPD related writers for Arris Commscope","Fixed update templates in CableInterfaceUpstreamConfigWriter for Arris Commscope","Fixed callback leaf-list input parameter (#948)","Added a verification to check if lineIndex is lower than total number of parsed lines for multiline commands","Fixed CLI SSH KEX initialization","Fixed data decryption during apply-template RPC","Fixed regex for \"show cable modem\" command (#897)","Generate action names in java constants"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Swagger: shorter operational path"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Implementation of RPD TUs for CER(Arris) (#819)"]}],[{"i":"uniconfig-5025-release-notes","l":"Uniconfig 5.0.25 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Subtree-based resolution of conflicts between committed nodes (#989)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fix: Duplicate module name in Yang schemas","Fixed update template to update fiber node for Arris Commscope","Fixed uninstall node rpc","Fixed parsing leaf-list into JSONObject","Fixed construction of Tree (callbacks system test)","Fixed problem with re-write data of transaction by other transaction (#1032)","Fixed method to add unistore FP","Fix deriving of DB reader path","fix read only lock in uniconfig task executor (#981)","Fixed overriding of default mount settings by uniconfig-client"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["cli-shell set callback... suggest only commands that contain input body","Setting default spin/park time in notification router config","Optimised sending of internal notifications","Optimised lookup in modified uniconfig-topology & network-topology modules","Optimise detection of updated mount data in notification monitoring system","Add additional logs to precondition checks in SchemaContextUtil","Subtree-based resolution of conflicts between committed nodes (#989)","Improved the processing time of sync RPC for ios devices","Optimisation of single transaction-log entry reading","Added dedicated reader for single transaction-log entry","Add batching process for parallel reading of config"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Optimalization of handling saos devices"]}],[{"i":"uniconfig-510-release-notes","l":"Uniconfig 5.1.0 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Support for GetInstalledNodes in UC client","Add getJSONOutput to UniConfig client","Added some commands for collecting data for IOS-XE (#527)","Skip unreachable nodes at commit","Fixed hardcoded part and added one more if condition to receiver transceiver data for IOS-XE (#490)","added implementation of XR6 and XR6.6 devices as native units","Implementation of storing failed installations into DB (main)","Implemented TU for adding/removing users for Saos6 (#360)","Implemented TU for collecting transceiver information for IOS-XE (#437)","Implemented TU for collecting all the information in NTP MCS for Saos6 and Saos8 (#352)","Implemented low priority fields for collecting inventory for SAOS6 CEN(ring) (#341)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Add migration for removing node-extension:reconcile","Bump units versions to 5.1.0-SNAPSHOT","Downgraded sshd to 2.8.0","Fix : bad package for GnmiDefaultParametersService","Fix bug in bulk edit operation","Fix CVE-2021-37533","Fix CVEs","fix Jsonb filter element filtering","Fix Logback and cleanup POMs","Fix uninstall -> install transition","Fixed cleanup of existing MP during mount-node RPC","Fixed distribution of mount failure from GNMi layer","Fixed encryption of sensitive info passed via template variables (#326)","Fixed hardcoded part and added one more if condition to receiver transceiver data for IOS-XE (#490)","Fixed leafref version-drop","Fixed locking of nodes from TX with enabled dedicated sessions (#522)","Fixed parsing of seconds in XR native metadata unit","Fixed passing leaf-list in shell callbacks","Fixed pattern handling and XPath extension parsing","Fixed quit command in the shell","Fixed reading public key from NETCONF device (NPE)","Fixed reconcile SQL migration file","Fixed synchronization in datastore transaction","Stop reporting metrics into log/logs.log and stdout (#598)","Suppress Netty FP CVEs","Swagger - Fix request generation","Swagger: fix generation of action nodes","Swagger: Fix generation of arguments in path","Swagger: fix generation of choice nodes","Swagger: fix generation of operation children from config container","Swagger: fix generation of operational APIs","Swagger: fix no key lists generation","Swagger: Fix path filtering"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["add overallStatus to multiple-nodes-rpc-output","Added logs into DOM Mountpoint Service","Bulk-edit rpc improvements","Bump dependency-check to 7.3.0","Bump logback","Change overallStatus when skiping unreachable nodes","Changed order of some commands for SAOS8 (#348)","Disable verification of supported query parameters (5.1.x) (#550)","expose gnmi parameters","Expose request-timeout parameter","Exposed DOMMountPointService configuration","handle user parameters input in GnmiDefaultParametersService","Improved error message when connection cannot be created","Improved reporting of parsing issues in RESTCONF","Optimization of mountpoint notifications","readEntireConfig toString returns plain content","Reading mount configuration in the uniconfig-client","Removed 'reconcile' mountpoint parameter (#573)","Swagger - Improve start file","Swagger: Custom operational path","Swagger: generate augmentations in respective modules","Swagger: toggle generation of POST apis for containers"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Swagger: fix npe in custom operational path","Added only-vlan parser, upgraded trunk-vlans for huawei (#444)","Callbacks authentication","Configurable re-sending cli commands","Fixed mount point creation for CLI topology","Removed unified-topology.yang","Refactored unified layer and mounting/unmounting process - updates","Refactored unified layer and mounting/unmounting process","Added logging level for shell to the logback.xml"]}],[{"i":"uniconfig-511-release-notes","l":"Uniconfig 5.1.1 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["make replace request on correct node for gnmi","Implemented some new commands for Huawei TU (#580) (#639)","Add GetTemplateNodes RPC and add support to Client","Implementation of MIB parser using ANTLR grammar"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed NPE for JSONCodecFactoryLoader","Fixed deserialization of uniconfig instance record read from DB (#700)","Fixed encryption of leaves marked using deviations","Fix vulnerabilities by changing base docker image","Stop cleaning YANG repos associated to persisted nodes","Swagger: fix actions using custom operational path","Suppressed CVE-2021-4277 (#613)"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Swagger: mandatory indicator","Improved registration of unexpected YANGs downloaded from device","Add compare-config RPC.","Changed logging level: Unable to map identifier to capability","Skipping unknown fields in GET request","Added an RPC input to enable error handling for execute-and-read RPC (#668)","Fetch Kafka settings to client.","gnmi support for upgrade-from-network RPC","add gnmi protocol to get-installed-nodes RPC","Swagger: add drop-down for topology-id parameter"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["PUT and DELETE operations for callbacks"]}],[{"i":"uniconfig-512-release-notes","l":"Uniconfig 5.1.2 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implementation of RPD TUs for CER(Arris)","Implementation of Cable-Mac Oper TUs for CER(Arris)","Replace paths feature","Implementation of cable-upstream TUs for CER(Arris)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Added new control to check if cached prompt is invalid (#812)","Fixed writer of cable upstream interface","Fix delete request in replace-paths","Fixed schema context building","Changed log level in mockito-configuration to INFO","Fix wrong groupIds","Java based migration for huawei config","Bulk-edit - removed the version comparison before version drop procedure","Bump dependencycheck.version, update suppress for CVE-2022-41915, CVE-2022-41881"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Add Dependency Upgrades to release notes","Added calc-diff result to audit logs","Added read option to bulk-edit RPC","Adopt Mockito 5","Bump dependency-check, cleanup unused suppressions","Bump sshd to 2.9.2","Change isInstalled method implementation in uniconfig-client","Change status code if transaction is not valid. (#699)","Enable dependabot updates","Extended TreeConfigParser to handle arris device's behavior for cable-upstreams","Migrate codebase to Java 17 & bump dependencies & clean maven structure","Prefer 'latest' repository in latest repository update process","README - Update Running from IDE section","Remove license server","Remove license token from README.md and run_uniconfig.sh script.","Replace com.google.common.base.Optional with java.util.Optional","Swagger: regular expressions with example values","Unify antlr4 version","Update README.md running uniconfig from IDE","Updated list of supported Unicode blocks (RegexUtils)"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["Bump antlr4-maven-plugin from 4.10.1 to 4.11.1","Bump byte-buddy.version from 1.12.22 to 1.13.0","Bump commons-dbcp2 from 2.7.0 to 2.9.0","Bump commons-lang3 from 3.7 to 3.12.0","Bump disruptor from 3.3.10 to 3.4.4","Bump embedded-postgres from 1.2.10 to 2.0.3","Bump grpc.version from 1.51.1 to 1.53.0","Bump httpclient from 4.5.13 to 4.5.14","Bump jackson-bom from 2.14.1 to 2.14.2","Bump jna.version from 4.5.0 to 5.13.0","Bump maven-enforcer-plugin from 3.1.0 to 3.2.1","Bump netty.version from 4.1.86.Final to 4.1.89.Final","Bump objenesis from 2.1 to 3.3","Bump okhttp.version from 4.9.1 to 4.10.0","Bump org.eclipse.jdt.annotation from 2.1.0 to 2.2.700","Bump perfmark-api from 0.25.0 to 0.26.0","Bump properties-maven-plugin from 1.0.0 to 1.1.0"]}],[{"i":"uniconfig-513-release-notes","l":"Uniconfig 5.1.3 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Swagger: difference between OpenAPI specifications"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fix UC not starting when using standalone database - binding","Fix UC not starting when using standalone database","Fix & rewrite calc-diff to new format","Fixed regex for \"show cable modem\" command (#898)","Generate action names in java constants"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Migrate to JUnit5","Removed unused JMX classes"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Implementation of RPD TUs for CER(Arris) (#862)"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["Bump actions/setup-python from 4.3.0 to 4.5.0 (#760)","Bump actions/upload-artifact from 3.1.1 to 3.1.2","Bump annotations from 3.0.1 to 3.0.1u2","Bump antlr4.version from 4.11.1 to 4.12.0","Bump async-http-client from 1.9.24 to 1.9.40","Bump AutoModality/action-clean from 1.1.0 to 1.1.1","Bump byte-buddy.version from 1.13.0 to 1.14.0","Bump commons-cli from 1.4 to 1.5.0","Bump commons-compress from 1.21 to 1.22","Bump commons-fileupload from 1.3.3 to 1.5","Bump crypt4j from 1.0.0 to 1.0.1","Bump docker/build-push-action from 2 to 4 (#761)","Bump docker/login-action from 2.0.0 to 2.1.0 (#762)","Bump dokka-maven-plugin from 1.5.30 to 1.7.20","Bump embedded-postgres-binaries-linux-amd64 from 13.2.0 to 13.10.0","Bump embedded-postgres-binaries-linux-amd64 from 13.2.0 to 15.2.0","Bump exec-maven-plugin from 1.5.0 to 3.1.0","Bump flyway-core from 7.8.1 to 9.15.0","Bump flyway-core from 9.15.0 to 9.15.1","Bump future-converter-java8-guava from 0.3.0 to 1.2.0","Bump gson from 2.9.0 to 2.10.1","Bump jackson-databind from 2.14.1 to 2.14.2","Bump jakarta.servlet-api from 5.0.0 to 6.0.0","Bump jakarta.ws.rs-api from 3.0.0 to 3.1.0","Bump janino from 2.6.1 to 3.1.9","Bump jaxb-impl from 3.0.2 to 4.0.2","Bump jaxen from 1.1.6 to 2.0.0","Bump jersey.version from 3.0.8 to 3.1.1","Bump jetty-bom from 11.0.11 to 11.0.13","Bump jline.version from 3.21.0 to 3.22.0","Bump jmh-core.version from 1.21 to 1.36","Bump joelwmale/webhook-action from 2.1.0 to 2.3.2 (#759)","Bump jsonassert from 1.5.0 to 1.5.1","Bump junit-jupiter-api from 5.9.1 to 5.9.2","Bump ktlint from 0.24.0 to 0.31.0","Bump maven-assembly-plugin from 3.4.2 to 3.5.0","Bump maven-deploy-plugin from 3.0.0 to 3.1.0","Bump maven-failsafe-plugin from 3.0.0-M8 to 3.0.0-M9","Bump maven-invoker-plugin from 3.4.0 to 3.5.0","Bump maven-jar-plugin from 3.0.2 to 3.3.0","Bump maven-javadoc-plugin from 3.4.1 to 3.5.0","Bump maven-resources-plugin from 3.0.1 to 3.3.0","Bump maven.surefire.version from 3.0.0-M8 to 3.0.0-M9","Bump metrics-core from 4.2.12 to 4.2.16","Bump opentelemetry-api from 1.9.0 to 1.23.1","Bump postgresql from 42.5.1 to 42.5.4","Bump protobuf-maven-plugin from 0.5.1 to 0.6.1","Bump protobuf.version from 3.21.7 to 3.22.0","Bump sevntu-checks from 1.43.0 to 1.44.1","Bump spring-jdbc from 5.3.24 to 5.3.25 (#855)","Bump spring.boot.version from 2.7.6 to 2.7.8","Bump spring.boot.version from 2.7.8 to 2.7.9","Bump stax2-api from 3.1.4 to 4.2.1","Bump stCarolas/setup-maven from 4.3 to 4.5","Bump swagger-core from 2.2.4 to 2.2.8","Bump swagger-parser from 1.0.31 to 1.0.64","Bump triemap from 1.1.0 to 1.2.0","Bump truth.version from 0.36 to 1.1.3","Bump value from 2.9.2 to 2.9.3"]}],[{"i":"uniconfig-514-release-notes","l":"Uniconfig 5.1.4 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implementation of MIB repository & context","Implemented RPD related commands to fiber-node TU for Arris Commscope"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed RPD related writers for Arris Commscope","Fixed update templates in CableInterfaceUpstreamConfigWriter for Arris Commscope","Fix calc-diff when data is in LeafNode","Fix subtree calc-diff in audit log when data has not changed","Fixed callback leaf-list input parameter (#949)","Added a verification to check if lineIndex is lower than total number of parsed lines for multiline commands","Fixed CLI SSH KEX initialization","Fixed data decryption during apply-template RPC"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Swagger: shorter operational path"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump dokka-maven-plugin from 1.7.20 to 1.8.10","build(deps-dev): bump maven-plugin-annotations from 3.7.1 to 3.8.1","build(deps): bump json from 20220924 to 20230227","build(deps): bump dependency-check-maven from 8.1.0 to 8.1.2","Bump reflections from 0.9.11 to 0.10.2","Bump maven-compiler-plugin from 3.10.1 to 3.11.0","Bump jetty-bom from 11.0.13 to 11.0.14","Bump maven-plugin-plugin from 3.7.1 to 3.8.1","Bump metrics-core from 4.2.16 to 4.2.17","Bump spotbugs-maven-plugin from 4.7.3.0 to 4.7.3.2","Bump maven-dependency-plugin from 3.1.1 to 3.5.0","Bump checkstyle from 10.7.0 to 10.8.0","Bump maven-antrun-plugin from 1.8 to 3.1.0"]}],[{"i":"uniconfig-515-release-notes","l":"Uniconfig 5.1.5 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Implement rate limiting (#1061)","Add DOMRpcService for gNOI","Subtree-based resolution of conflicts between committed nodes (#1008)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fix audit-log diff feature (#1056)","Fixed update template to update fiber node for Arris Commscope","Fix: Duplicate module name in Yang schemas","Fixed reading config until timeout (#1067)","Fixed uninstall node rpc","Fixed parsing leaf-list into JSONObject","Fixed construction of Tree (callbacks system test)","Fixed problem with re-write data of transaction by other transaction (#1031)","Fixed method to add unistore FP","Fix bug with audit log while calling commit RPC (#1007)","Fix deriving of DB reader path","Add missing sslpassword configuration parameter (#990)","fix read only lock in uniconfig task executor (#982)","Fixed overriding of default mount settings by uniconfig-client"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Swagger: Migrate unit tests to v3","Added topology-id to DCE notification","cli-shell set callback... suggest only commands that contain input body","Setting default spin/park time in notification router config","Optimised sending of internal notifications","Optimised lookup in modified uniconfig-topology & network-topology modules","Optimise detection of updated mount data in notification monitoring system","Add additional logs to precondition checks in SchemaContextUtil","Subtree-based resolution of conflicts between committed nodes (#1008)","Improved the processing time of sync RPC for ios devices","Optimisation of single transaction-log entry reading","Added dedicated reader for single transaction-log entry","Add batching process for parallel reading of config"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Arris CER interface bugfix (#1086)","Optimalization of handling saos devices"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump flyway-core from 9.15.1 to 9.15.2","build(deps-dev): bump flyway-core from 9.15.2 to 9.16.0 (#1012)","build(deps-dev): bump flyway-core from 9.16.0 to 9.16.1 (#1052)","build(deps-dev): bump swagger-parser from 1.0.64 to 1.0.65 (#1074)","build(deps): bump byte-buddy.version from 1.14.0 to 1.14.1","build(deps): bump byte-buddy.version from 1.14.1 to 1.14.2 (#1003)","build(deps): bump checkstyle from 10.8.0 to 10.8.1 (#988)","build(deps): bump checkstyle from 10.8.1 to 10.9.2 (#1028)","build(deps): bump checkstyle from 10.9.2 to 10.9.3 (#1073)","build(deps): bump commons-compress from 1.22 to 1.23.0 (#1059)","build(deps): bump dependency-check-maven from 8.1.2 to 8.2.1 (#1062)","build(deps): bump grpc.version from 1.53.0 to 1.54.0 (#1071)","build(deps): bump jline.version from 3.22.0 to 3.23.0","build(deps): bump maven-deploy-plugin from 3.1.0 to 3.1.1 (#1072)","build(deps): bump maven-failsafe-plugin from 3.0.0-M9 to 3.0.0 (#1011)","build(deps): bump maven-help-plugin from 3.3.0 to 3.4.0 (#1025)","build(deps): bump maven-install-plugin from 3.1.0 to 3.1.1 (#1075)","build(deps): bump maven-release-plugin from 3.0.0-M7 to 3.0.0 (#1037)","build(deps): bump maven.core.version from 3.9.0 to 3.9.1 (#1027)","build(deps): bump maven.surefire.version from 3.0.0-M9 to 3.0.0 (#1013)","build(deps): bump metrics-core from 4.2.17 to 4.2.18 (#1038)","build(deps): bump mockito-core from 5.1.1 to 5.2.0 (#987)","build(deps): bump netty.version from 4.1.89.Final to 4.1.90.Final (#1010)","build(deps): bump opentelemetry-api from 1.23.1 to 1.24.0 (#999)","build(deps): bump postgresql from 42.5.4 to 42.6.0 (#1026)","build(deps): bump protobuf.version from 3.22.0 to 3.22.1","build(deps): bump protobuf.version from 3.22.1 to 3.22.2 (#1000)","build(deps): bump spotbugs-maven-plugin from 4.7.3.2 to 4.7.3.3 (#1070)","build(deps): bump spring-jdbc from 5.3.25 to 5.3.26 (#1036)","build(deps): bump spring.boot.version from 2.7.9 to 2.7.10 (#1069)","build(deps): bump swagger-core from 2.2.8 to 2.2.9 (#1039)"]}],[{"i":"uniconfig-516-release-notes","l":"Uniconfig 5.1.6 Release Notes"},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Saos 8 command order fix.","Fixed execution order of commands for sub-port creation","Fixed a bug that causes cli closed error if config output and prompt has same length","Fix dryrun mount node task.","diff improvements (#1107)","Swagger: fix union type with patterns","Disable NETCONF level keepalive mechanism in streaming session","Fixed onEmpty section in templates for rpd ds and us conns for Arris Commscope","Fixed a bug that causes cli closed error for saos devices when commit or execute RPCs are triggered"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Refactoring ServiceInstanceWriter","Adjusted log levels of common logs","Swagger: filterPath improvement","diff improvements (#1107)","Rewrite kafka configs (#1105)"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["JSON input in Uniconfig shell problem fix","Shell logger","Create and publish Netconf test tool image to DockerHub"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump flyway-core from 9.16.1 to 9.16.3 (#1139)","build(deps): bump actions/upload-artifact from 3.1.1 to 3.1.2 (#1131)","build(deps): bump bouncycastle.version from 1.72 to 1.73 (#1138)","build(deps): bump byte-buddy.version from 1.14.2 to 1.14.3","build(deps): bump byte-buddy.version from 1.14.3 to 1.14.4","build(deps): bump grpc.version from 1.54.0 to 1.54.1 (#1134)","build(deps): bump jetty-bom from 11.0.14 to 11.0.15 (#1127)","build(deps): bump jline.version from 3.22.0 to 3.23.0 (#998)","build(deps): bump json-path from 2.7.0 to 2.8.0 (#1093)","build(deps): bump kotlin.version from 1.8.10 to 1.8.20","build(deps): bump maven-enforcer-plugin from 3.2.1 to 3.3.0 (#1114)","build(deps): bump maven-invoker-plugin from 3.5.0 to 3.5.1 (#1115)","build(deps): bump maven-resources-plugin from 3.3.0 to 3.3.1","build(deps): bump netty.version from 4.1.90.Final to 4.1.91.Final (#1113)","build(deps): bump opentelemetry-api from 1.24.0 to 1.25.0 (#1135)","build(deps): bump protobuf.version from 3.22.2 to 3.22.3","build(deps): bump spotbugs-maven-plugin from 4.7.3.3 to 4.7.3.4 (#1126)","build(deps): bump triemap from 1.2.0 to 1.3.0"]}],[{"i":"uniconfig-517-release-notes","l":"Uniconfig 5.1.7 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Lazy loading/unloading of native schema contexts (#1171)","Creation of MIB context to SchemaContext adapter (#1169)"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fixed lazy apply-template","Fixed a bug that causes cli closed error if config output's length is less than prompt's length after config output is trimmed","Fix Swagger regex example generation","Fixed loading of schema context from swagger directory","Make request max size configurable for gnmi devices","Integrate encryption in create-multiple-templates RPC.","Fixed UniconfigTransactionsMediator initialization (#1181)","Remove TestNG (#1159)","Fix UC stuck when CPU is full and queue is empty (#1168)"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Support for gnmi in shell","Implementation of idle timeout print in CLI (#1172)","Lazy loading/unloading of native schema contexts (#1171)","Improved the processing time of sync RPC for ios/iosxe devices","Unify movement in shell (#1005)","Enabled cable-upstream writer for interfaces that has number/number/number pattern as name","Improved apply-template RPC (#1111)"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Add lazy loading to shell"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump flyway-core from 9.16.3 to 9.17.0 (#1177)","build(deps-dev): bump maven-plugin-annotations from 3.8.1 to 3.8.2 (#1152)","build(deps): bump checkstyle from 10.9.3 to 10.10.0 (#1176)","build(deps): bump jackson-bom from 2.14.2 to 2.15.0 (#1158)","build(deps): bump jackson-databind from 2.14.2 to 2.15.0 (#1153)","build(deps): bump jakarta.activation-api from 2.1.1 to 2.1.2 (#1178)","build(deps): bump jgrapht.version from 1.5.1 to 1.5.2","build(deps): bump junit.jupiter.version from 5.9.2 to 5.9.3 (#1175)","build(deps): bump kotlin.version from 1.8.20 to 1.8.21 (#1174)","build(deps): bump maven-checkstyle-plugin from 3.2.1 to 3.2.2 (#1157)","build(deps): bump maven-plugin-plugin from 3.8.1 to 3.8.2 (#1154)","build(deps): bump maven-project-info-reports-plugin from 3.4.2 to 3.4.3 (#1145)","build(deps): bump mockito.core.version from 5.2.0 to 5.3.1 (#1156)","build(deps): bump netty.version from 4.1.91.Final to 4.1.92.Final (#1173)","build(deps): bump okhttp.version from 4.10.0 to 4.11.0 (#1155)","build(deps): bump protobuf.version from 3.22.3 to 3.22.4"]}],[{"i":"uniconfig-518-release-notes","l":"Uniconfig 5.1.8 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Add change-encryption-status rpc (#1259) - UNIC-1090","Added some commands for collecting slot data for IOS-XE - VZ-734"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Swagger: Fix path filtering ignoring cruds in lists - UNIC-1315","Fix failing shell tests (#1285)","Compare decrypted strings in calculate-diff procedure (#1266) - UNIC-1173","Changed execution order of commands for CPE ZTP provision for SAOS8"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Improved error output when two transactions want to update same data … (#1238)","Swagger: Improve OpenAPI difference calculation - UNIC-1298","Provide option for reading mount-point info - UNIC-1097","Refactored InstanceIdentifierContext (#1249) - UNIC-1211","Add option to gnmi-topology to read specific data - PANT-72","Add unsuported keys for cli connection (#1203)","Add JIRA tag to release notes - UNIC-1243","Optimize LeafRef context build. - UNIC-988","Build LeafRef Tree in background. - UNIC-988","Separated reader/writer for IUCs from main classes for Arris Commscope","Unify annotation usage in uniconfig codebase","support error info (#1201) - UNIC-1136","Rewrite RestConf module DI (#1202) - UNIC-1101"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Create a new set of installation parameters"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump flyway-core from 9.17.0 to 9.19.1","build(deps-dev): bump maven-plugin-annotations from 3.8.2 to 3.9.0 (#1265)","build(deps-dev): bump swagger-parser from 1.0.65 to 1.0.66","build(deps): bump antlr4.version from 4.12.0 to 4.13.0 (#1256)","build(deps): bump build-helper-maven-plugin from 3.3.0 to 3.4.0","build(deps): bump checkstyle from 10.10.0 to 10.11.0 (#1254)","build(deps): bump checkstyle from 10.11.0 to 10.12.0","build(deps): bump embedded-postgres from 2.0.3 to 2.0.4 (#1270)","build(deps): bump embedded-postgres-binaries-linux-amd64 from 13.10.0 to 13.11.0 (#1274)","build(deps): bump git-commit-id-maven-plugin from 5.0.0 to 6.0.0","build(deps): bump grpc.version from 1.54.1 to 1.55.1 (#1199)","build(deps): bump guice.version from 5.1.0 to 7.0.0 (#1253)","build(deps): bump jackson-bom from 2.15.0 to 2.15.1","build(deps): bump jackson-databind from 2.15.0 to 2.15.1 (#1264)","build(deps): bump jersey.version from 3.1.1 to 3.1.2","build(deps): bump json-smart from 2.4.10 to 2.4.11","build(deps): bump kotlinx-coroutines-core from 1.6.4 to 1.7.0 (#1198)","build(deps): bump kotlinx-coroutines-core from 1.7.0 to 1.7.1","build(deps): bump maven-assembly-plugin from 3.5.0 to 3.6.0 (#1272)","build(deps): bump maven-checkstyle-plugin from 3.2.2 to 3.3.0","build(deps): bump maven-failsafe-plugin from 3.0.0 to 3.1.0 (#1196)","build(deps): bump maven-plugin-plugin from 3.8.2 to 3.9.0","build(deps): bump maven-remote-resources-plugin from 3.0.0 to 3.1.0","build(deps): bump maven-source-plugin from 3.2.1 to 3.3.0 (#1271)","build(deps): bump maven-surefire-plugin from 3.0.0 to 3.1.0 (#1197)","build(deps): bump maven.core.version from 3.9.1 to 3.9.2 (#1215)","build(deps): bump netty.version from 4.1.92.Final to 4.1.93.Final","build(deps): bump opentelemetry-api from 1.25.0 to 1.26.0 (#1195)","build(deps): bump protobuf.version from 3.22.4 to 3.23.0","build(deps): bump protobuf.version from 3.23.0 to 3.23.1 (#1273)","build(deps): bump spring-jdbc from 6.0.8 to 6.0.9","build(deps): bump spring.boot.version from 3.0.6 to 3.0.7 (#1269)","build(deps): bump sshd.version from 2.9.2 to 2.10.0","build(deps): bump swagger-core from 2.2.9 to 2.2.10","build(deps): bump triemap from 1.3.0 to 1.3.1"]}],[{"i":"uniconfig-519-release-notes","l":"Uniconfig 5.1.9 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["DOMDataBroker for SNMP (#1299) - UNIC-1200","UNIC-1200","Integration of southbound RESTCONF RPC service to UniConfig shell (#1310) - UNIC-1310"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Fix unreachable ports for device discovery RPC - UNIC-1322","Certificate Manager servers not getting created in appliance context - fixed output - UNIC-1309","Fix removing of exception from error-info/error-message - PANT-78","Add MapNode serialization to gNMI Update - UNIC-1323"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Changeable thread parameters - UNIC-1250","Swagger: Added html output to diff generation - UNIC-1324"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump flyway-core from 9.19.1 to 9.19.4","build(deps-dev): bump swagger-parser from 1.0.66 to 1.0.67","build(deps): bump byte-buddy.version from 1.14.4 to 1.14.5","build(deps): bump commons-io from 2.11.0 to 2.12.0","build(deps): bump commons-io from 2.12.0 to 2.13.0","build(deps): bump dependency-check-maven from 8.2.1 to 8.3.1","build(deps): bump dokka-maven-plugin from 1.8.10 to 1.8.20","build(deps): bump grpc.version from 1.55.1 to 1.56.0","build(deps): bump guava.version from 31.1-jre to 32.0.0-jre","build(deps): bump guava.version from 32.0.0-jre to 32.0.1-jre","build(deps): bump jackson-bom from 2.15.1 to 2.15.2","build(deps): bump jackson-databind from 2.15.1 to 2.15.2","build(deps): bump jaxb-runtime from 4.0.2 to 4.0.3","build(deps): bump kafka-clients from 3.4.0 to 3.4.1","build(deps): bump kafka-clients from 3.4.1 to 3.5.0","build(deps): bump kotlin.version from 1.8.21 to 1.8.22","build(deps): bump maven-dependency-plugin from 3.5.0 to 3.6.0","build(deps): bump maven-failsafe-plugin from 3.1.0 to 3.1.2","build(deps): bump maven-project-info-reports-plugin from 3.4.3 to 3.4.4","build(deps): bump maven-project-info-reports-plugin from 3.4.4 to 3.4.5","build(deps): bump maven-release-plugin from 3.0.0 to 3.0.1","build(deps): bump maven-surefire-plugin from 3.1.0 to 3.1.2","build(deps): bump metrics-core from 4.2.18 to 4.2.19","build(deps): bump opentelemetry-api from 1.26.0 to 1.27.0","build(deps): bump protobuf.version from 3.23.1 to 3.23.2","build(deps): bump swagger-core from 2.2.10 to 2.2.11","build(deps): bump swagger-core from 2.2.11 to 2.2.12","build(deps): bump truth.version from 1.1.3 to 1.1.4"]}],[{"i":"uniconfig-5110-release-notes","l":"Uniconfig 5.1.10 Release Notes"},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Get API returns 3 response for single request (#1396) - VHD-324","Fixed too long error output in NETCONF LOG message - UNIC-649","UNIC-1319 Issue with Netconf install WorkFlow - fix logs for testing workflows - UNIC-1319","Upgrade Template didn't load repository - UNIC-1334","Save yang repository in transaction - VHD-324"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["store netconf keys in db (#1380) - VHD-326","maven cleanup (#1379) - UNIC-1291","Removed unused code from sal-dom-spi and dependencies","Extract shell actions to use RestconfDOMActionService (#1346) - UNIC-1313"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Parse and fill datastore with initial JSON file in MDSAL mode"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump flyway-core from 9.19.4 to 9.20.0","build(deps): bump actions/setup-python from 4.5.0 to 4.6.1","build(deps): bump bouncycastle.version from 1.73 to 1.74","build(deps): bump bouncycastle.version from 1.74 to 1.75","build(deps): bump checkstyle from 10.12.0 to 10.12.1","build(deps): bump commons-codec from 1.15 to 1.16.0","build(deps): bump docker/login-action from 2.1.0 to 2.2.0","build(deps): bump grpc.version from 1.56.0 to 1.56.1 (#1390)","build(deps): bump guava.version from 32.0.1-jre to 32.1.1-jre (#1388)","build(deps): bump janino from 3.1.9 to 3.1.10 (#1389)","build(deps): bump json from 20230227 to 20230618","build(deps): bump maven-clean-plugin from 3.2.0 to 3.3.1","build(deps): bump maven-invoker-plugin from 3.5.1 to 3.6.0","build(deps): bump maven-shade-plugin from 3.4.1 to 3.5.0","build(deps): bump metainf-services from 1.9 to 1.11 (#1375)","build(deps): bump mockito.core.version from 5.3.1 to 5.4.0","build(deps): bump netty-handler in /commons/parents/odlparent","build(deps): bump spotbugs-maven-plugin from 4.7.3.4 to 4.7.3.5","build(deps): bump spring-jdbc from 6.0.9 to 6.0.10","build(deps): bump spring.boot.version from 3.0.7 to 3.0.8","build(deps): bump sshd.version from 2.9.2 to 2.10.0 (#1251)","build(deps): bump swagger-core from 2.2.12 to 2.2.14","build(deps): bump truth.version from 1.1.4 to 1.1.5"]}],[{"i":"uniconfig-5111-release-notes","l":"Uniconfig 5.1.11 Release Notes"},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["Swagger: Fix generation of operational data from Uniconfig schemas (#1444) - UNIC-1280","Fixed unmounting of node that is in connecting state - UNIC-1281"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Changing use case of prompt stylization - UNIC-977","Enabling and cleaning up SHELL checkstyles (#1451) - UNIC-1345","Unifying, renaming and increasing readability of UC-shell - UNIC-977","Add mutable transaction to Shell (#1399) - UNIC-1312","Swagger: Unit tests - UNIC-1186","Removed sal-common-impl module","Merged mdsal-dom-spi to sal-dom-spi module (5.1.x) (#1417)","add ValueCase to gnmi codec - UNIC-1113"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Read All data type on specific paths"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump org.apache.kafka:kafka-clients from 3.5.0 to 3.5.1 (#1476)","build(deps): bump maven.core.version from 3.9.2 to 3.9.3 (#1358)"]}],[{"i":"uniconfig-5112-release-notes","l":"Uniconfig 5.1.12 Release Notes"},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["fix_regex_matching_of_identity - UNIC-1375"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Shell explicit show in config state (#1484) (#1503) - UNIC-1325","Shell caching data - 5.1.x-stable (#1496) - UNIC-1357"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Swagger: Code cleanup - 5.1.x-stable (#1489)"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump org.codehaus.mojo:properties-maven-plugin from 1.1.0 to 1.2.0 (#1522)"]}],[{"i":"uniconfig-5113","l":"Uniconfig 5.1.13"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["Fix key delimiter in URI","Swagger: Fix RPCs placed after mountpoint (#1582)","[UNIC-1410] Fix tx cleanup when request fails","[UNIC-1413] Fixed updating snapshot in immediate-commit model (#1629)","[UNIC-1420] Fix cli ssh session reconnect","[UNIC-1425] Fix crypto bug (#1664)","[UNIC-1352, UNIC-1254] Fix cluster issues (#1670)","[UNIC-1340] Fixed releasing of used YANG modules from memory (#1667)","[UNIC-1429] Fix replace is sent using delete operation","[UNIC-1432] Swagger: Fix generation of post list endpoints (#1674)","[UNIC-1430] - fix replace yang-patch for gnmi mountpoint","[UNIC-1404] UniConfig Shell - fix system augmentation","Fixed loading of YANG from path in client diff tool"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1394] Client side diff","[UNIC-1402] UC Shell - default callbacks repository (#1701)"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-981] UniconfigShell: Remove explicit show submode from root mod…","[UNIC-1411] Add mapping to request/response log message","[UNIC-1394] Add overloaded build methods to client side diff","[UNIC-1394] exclude gnmi depenendecies from java client","[UNIC-1401] UniConfig Shell - one line SET / DELETE command (#1621)","[UNIC-1403] Unified format of shell audit logs (#1658)","[PANT-83] add logs for pant83 - STABLE"]},{"i":"api-changes","l":"\uD83D\uDDA5️ API Changes","p":["add gnmi-messages logging broker"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["Fix Jetty CVEs","5.1.x-stable - Maven 3.9.5"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["5.1.13-SNAPSHOT","UniconfigShell: Improving suggestions menu","[FI-1693] Remove Jenkins-test from merge workflow","Release 5.1.13"]}],[{"i":"uniconfig-5114","l":"Uniconfig 5.1.14"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1429] Fix replace operation in GNMI set","[UNIC-1471] : Fix sync fail after failed installation was stored STABLE","[UNIC-1474] Improve performance of YANG repository loading process during mounting process (#1785)","UniConfig Shell - fix prompt callbacks bug","[UNIC-1492] - Fix rate-limiting","Fixed loading of gNMI YANG repository during MountNodeTask","[UNIC-1471] Add schema-cache storing into sync impl","Prevented sending no description command if there is no change for rpd description","Gnmi sb netconf cache loader stable","[UNIC-1494] - add migration for replace-paths","Fix get fallback schema context in cli shell.","Fix settings / callbacks cache"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1075] Uniconfig shell hide / unhide command implementation"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1408] UniConfig Shell - adjust cached data (#1745)","[UNIC-1405] UniConfig shell: set nested JSON data (#1752)","Improved logging (#1798)"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Suppress CVEs","[UNIC-1475] changing information about expired transaction in root mode","Release 5.1.14"]}],[{"i":"uniconfig-5115","l":"Uniconfig 5.1.15"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1481] Add With-Default to Java client","[UNIC-1490] - Fix delete requests not send"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1028] Connect/Disconnect node RPC"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1487] Uniconfig Shell: prompt mode should be the same after config transaction expiration"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump kotlin.version from 1.9.0 to 1.9.20"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["New snapshot release 5.1.15","Do not generate release notes","[UNIC-1488] Uniconfig Shell: add option to refresh the transaction"]}],[{"i":"uniconfig-5116","l":"Uniconfig 5.1.16"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1517] Fix pagination","[UNIC-1521] Fix reading list nodes in augmentations","[UNIC-1422] Fixed transaction is closed issue","[UNIC-1512] Fix ordering of operations on gnmi topology","Cover more errors in connect node RPC responses"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1486] + [UNIC-1509] - Skip yang constraints","[UNIC-1507] : One uniconfig tx for (un)install-multiple-nodes RPC"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1514] Add support CER device version 12.*(#1903)","Fixed logging in TaskExecutorImpl"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Release new snapshot version 5.1.16-SNAPSHOT","Release workflow stable","Add distributionSuffix property","Build distro without units on release (#1955)","Release 5.1.16."]}],[{"i":"uniconfig-5117","l":"Uniconfig 5.1.17"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1526] - increase gnmi executor queue size","[UNIC-1534] Swagger: fix bad types for numeric attributes (#2018)","[UNIC-1537] - Fix failing install sync stable","[UNIC-1547] Fix sync-from-network RPC","[UNIC-1557] Fix MountPointListenerException","CVE-2023-51074 stable"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1533] - skip length & range constraints","Support tailf's comment and label audit params in netconf southbound"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Stable task executor refactoring","[UNIC-1505] - Parallel syncFromNetwork (stable)","[UNIC-1102] Improve logging for schema context building"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["Bump Spring Boot to 3.1.6","Bump owasp-dependency-check","Bump logback.classic.version from 1.4.8 to 1.4.14"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.1.17-SNAPSHOT.","Rename UniConfig distribution name from bin to without TU","[UNIC-1453] UniConfig Shell - one-liner show/set/delete for callbacks…","Suppress logback","[UNIC-1539] Fix some typos","Maven 3.9.6","Revert \"[UNIC-1547] Fix sync-from-network RPC (#2044)\"","Revert \"Revert \"[UNIC-1547] Fix sync-from-network RPC (#2044)\" (#2050)\"","Suppress sshd vulnerability and old vulnerabilities.","Release 5.1.17."]}],[{"i":"uniconfig-5118","l":"Uniconfig 5.1.18"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["add missing docker dependency","[UNIC-1573] CLI shell: Fix Connect/Disconnect RPC suggestions","UniConfig Shell - fixing show mode bugs","[UNIC-1550] - mount/unmount synchronization (#2061)","[UNIC-1481] Fix with-defaults query parameter"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1499] Swagger: disable generation of POST list entries"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.1.18-SNAPSHOT.","Add default values to connect-node RPC","Fixed InterfaceRpdStateReader and CableMacReader for CER devices","Release 5.1.18."]}],[{"i":"uniconfig-5119","l":"Uniconfig 5.1.19"},{"i":"whats-changed","l":"What's Changed"},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1583] Add timeout property for Uniconfig Shell","Created CableModemReader and CableModemStateReader for CER devices"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Add postpone reason to task execution error on timeout"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.1.19-SNAPSHOT.","Release 5.1.19."]}],[{"i":"uniconfig-5120","l":"Uniconfig 5.1.20"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["Fixed removing mac-address command issue in InterfaceRpdConfigWriter","[UNIC-1601] Fix loading fallback context.","Get-template-nodes replace module in var."]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1122] DCE duplicate subscription check.","Rate limiting for user uniconfig transactions"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["Security - bump dependencies and cleanup suppressions","Security - bump commons-compress to 1.26.0"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.1.20-SNAPSHOT.","Fix testtool tag","Release 5.1.20"]}],[{"i":"uniconfig-5121","l":"Uniconfig 5.1.21"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1604] Fix synchronous RPCs - stable","[UNIC-1620] UC Shell: Fix leaf-list parsing (#2244)","[UNIC-1629] Fix replace-paths grouping distinct list entries","[UNIC-1664] Fix confirm-commit race-conditions","[UNIC-1680] Fix dryrun-commit mount/unmount process"]},{"i":"new-features","l":"✅ New Features","p":["Made local-priority attribute optional in RpdPtpPortConfigWriter"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1626] Add missing request tags into client.","Add Docker dependencies for collect_diag_info script","Added one more command into the update template to remove RPD connection from fiber-node","Move dependency-check into separate maven profile"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.1.21-SNAPSHOT.","Release 5.1.21","Bump to 5.1.22-SNAPSHOT.","Fix release workflow"]}],[{"i":"uniconfig-5122","l":"Uniconfig 5.1.22"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["Fixed write template in InterfaceRpdConfigWriter","Added previous mac-address into the command for removing it","Fixed get-installed-nodes bug that throws error when uninstall-node and get-installed-nodes RPC are executed at the same time in same topology type"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Prevented sending command for rpd-index, ucam and dcam attributes if there is no change for CER rpd interfaces"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["Security - update dependencies"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["upgrade embedded kafka version in application properties","Release 5.1.22"]}],[{"i":"uniconfig-5123","l":"Uniconfig 5.1.23"},{"i":"whats-changed","l":"What's Changed"},{"i":"new-features","l":"✅ New Features","p":["Added 13.* version support for ARRIS devices"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["Embedded Postgres 16"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.1.23-SNAPSHOT."]}],[{"i":"uniconfig-520-release-notes","l":"Uniconfig 5.2.0 Release Notes"},{"i":"new-features","l":"✅ New Features","p":["Parse NOTIFICATION-TYPE from MIB schemas. (#1545) - UNIC-1382","Add rpc change-encryption-keys (#1441) - UNIC-1239","support for gnmi-notifications - Notification + Subscription service (#1109) - UNIC-1184","UNIC-1308","SNMP topology (#1438) - UNIC-1202","UNIC-1202"]},{"i":"bug-fixes","l":"❌ Bug Fixes","p":["fix_regex_matching_of_identity - UNIC-1375","Fixed generation of commit diff notifications","Fix identityRef parsing (#1502) - UNIC-1356","Swagger: Fix generation of operational data from Uniconfig schemas - UNIC-1280","Fixed unmounting of node that is in connecting state - UNIC-1281"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Add gnmi subscription parameters (#1505) - UNIC-1369","Add mutable transaction to Shell (#1399) - UNIC-1312","add ValueCase to gnmi codec - UNIC-1113","Caching of calculate-diff response in transaction","Changing use case of prompt stylization - UNIC-977","Cleanup dependencies in uniconfig module (#1542) - UNIC-1381","Constants refactoring (#1511) - UNIC-1257","Enabling and cleaning up SHELL checkstyles (#1451) - UNIC-1345","fix connection manager (#1532)","Merged mdsal-dom-api into sal-dom-api module (#1543)","Merged mdsal-dom-spi to sal-dom-spi module (#1415)","Prevented sending command for rpd-index, ucam and dcam attributes if there is no change for CER rpd interfaces","Removed sal-common-impl module (#1426)","Shell caching data (#1480) - UNIC-1357","Shell explicit show in config state (#1484) - UNIC-1325","SNMP refactoring of snmp-topology (#1472) - UNIC-1343","Swagger: Unit tests - UNIC-1186","UNIC-1369","Unifying, renaming and increasing readability of UC-shell - UNIC-977"]},{"i":"api","l":"\uD83D\uDCBB API","p":["Refactor connection-manager RPCs (#1423) - UNIC-1283"]},{"i":"other","l":"\uD83D\uDD27 Other","p":["Read All data type on specific paths"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump org.apache.commons:commons-lang3 from 3.12.0 to 3.13.0 (#1523)","build(deps-dev): bump org.flywaydb:flyway-core from 9.20.0 to 9.21.0 (#1474)","build(deps-dev): bump org.flywaydb:flyway-core from 9.21.0 to 9.21.1 (#1520)","build(deps): bump bouncycastle.version from 1.75 to 1.76 (#1521)","build(deps): bump ch.qos.logback:logback-classic from 1.4.6 to 1.4.8 (#1483)","build(deps): bump ch.qos.logback:logback-classic from 1.4.8 to 1.4.9 (#1562)","build(deps): bump com.google.guava:guava from 32.1.1-jre to 32.1.2-jre (#1557)","build(deps): bump com.puppycrawl.tools:checkstyle from 10.12.1 to 10.12.2 (#1561)","build(deps): bump grpc.version from 1.56.1 to 1.57.0 (#1517)","build(deps): bump grpc.version from 1.57.0 to 1.57.1 (#1559)","build(deps): bump jersey.version from 3.1.2 to 3.1.3 (#1518)","build(deps): bump jmh-core.version from 1.36 to 1.37 (#1558)","build(deps): bump json-smart from 2.4.11 to 2.5.0 (#1404)","build(deps): bump kotlin.version from 1.8.22 to 1.9.0 (#1391)","build(deps): bump kotlinx-coroutines-core from 1.7.1 to 1.7.2 (#1392)","build(deps): bump maven.core.version from 3.9.2 to 3.9.3 (#1358)","build(deps): bump maven.core.version from 3.9.3 to 3.9.4 (#1560)","build(deps): bump netty.version from 4.1.94.Final to 4.1.95.Final (#1477)","build(deps): bump netty.version from 4.1.95.Final to 4.1.96.Final (#1516)","build(deps): bump opentelemetry-api from 1.27.0 to 1.28.0 (#1406)","build(deps): bump org.apache.kafka:kafka-clients from 3.5.0 to 3.5.1 (#1476)","build(deps): bump org.codehaus.mojo:properties-maven-plugin from 1.1.0 to 1.2.0 (#1522)","build(deps): bump org.jetbrains.kotlinx:kotlinx-coroutines-core from 1.7.2 to 1.7.3 (#1519)","build(deps): bump org.junit.jupiter:junit-jupiter from 5.9.3 to 5.10.0 (#1479)","build(deps): bump org.xmlunit:xmlunit-legacy from 2.6.1 to 2.9.1 (#1478)","build(deps): bump protobuf.version from 3.23.2 to 3.23.4 (#1395)","build(deps): bump spring-jdbc from 6.0.10 to 6.0.11 (#1434)","build(deps): bump spring.boot.version from 3.1.1 to 3.1.2 (#1475)","build(deps): bump swagger-core from 2.2.14 to 2.2.15 (#1405)"]}],[{"i":"uniconfig-521","l":"Uniconfig 5.2.1"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1273] Use Jetty embedded server","[UNIC-1340] Fixed releasing of used YANG modules from memory","[UNIC-1352, UNIC-1254] Fix cluster issues","[UNIC-1365] Gnmi stream fixes","[UNIC-1390] Swagger: Fix RPCs placed after mountpoint","[UNIC-1395] Fix key delimiter in URI","[UNIC-1399] Fix issues with shell","[UNIC-1399] Switch shell terminal back to JNA","[UNIC-1404] UniConfig Shell - fix system augmentation","[UNIC-1410] Fix tx cleanup when request fails","[UNIC-1410] Fix_tx_closing","[UNIC-1413] Fixed updating snapshot in immediate-commit model","[UNIC-1420] Fix cli ssh session reconnect","[UNIC-1423] Fix identityRef as listEntry key in templatesg","[UNIC-1425] Fix crypto bug","[UNIC-1429] Fix replace is sent using delete operation","[UNIC-1430] Fix replace yang-patch for gnmi mountpoint","[UNIC-1432] Swagger: Fix generation of post list endpoints","[UNIC-1446] Fix SpotBugs violations - Reliance on default encoding","[UNIC-1447] Fix SpotBugs violations - Multithreaded correctness","[UNIC-1448] Fix SpotBugs violations - Use a localized version of String.toUpperCase() and String.toLowerCase()","[UNIC-1451] Fix SpotBugs violations - Correctness","[UNIC-1463] Remove duplicates from Set","Add git registry to dependabot.yml","Additional fix to calculate diff rpc","Cleanup test resources properly","Data-change-events publisher fix","Fix calculate diff rpc","Fix immediate commit model and submit successfull nodes.","Fix mapEntryNodes in gnmi notifications","Fix reading of actual YANG repository from mountpoint data","Fix show UC status script","Fix show_uniconfig_status script.","Fix skip of unreachable-nodes.","Fix SNMP Notification bean creation","Fixed DateTime format in the transaction-log","Fixed loading of YANG from path in client diff tool (#1747)","Prevented sending no description command if there is no change for rpd description","Registry attempt no.2","SNMP adjust exception","SNMP Node id is incorrectly parsed"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1394] Client side diff","[UNIC-1373] Implemented dryrun-commit for GNMI topology","[UNIC-1398] SNMP notifications","[UNIC-1402] UC Shell - default callbacks repository","[UNIC-1218] Add dynamic property module"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[PANT-83] add logs for pant83","[UNIC-1154] Integrate JOOQ into database access layer","[UNIC-1218] Rewrite database connection pool and connection properties","[UNIC-1223] ODL parent cleanup","[UNIC-1242] Remove PR links from the uploaded release notes","[UNIC-1242] Unify generation of release notes","[UNIC-1245] Replacing Guava future by CompletableFuture","[UNIC-1258] Fix issues reported by SpotBugs","[UNIC-1273] Adjust bootstrapping of web containers","[UNIC-1370] Adjust notification result parsing","[UNIC-1386] Map correct ObjectTypes to NotificationTypes","[UNIC-1391] Add SNMP notifications to SchemaContext","[UNIC-1394] Add overloaded build methods to client side diff","[UNIC-1394] Remove gnmi dependencies from java client","[UNIC-1401] UniConfig Shell - one line SET / DELETE command","[UNIC-1403] Unified format of shell audit logs","[UNIC-1411] Add mapping to request/response log message (#1630)","[UNIC-1412] change gnmi packaging","[UNIC-1435] Refactor transaction-log to JOOQ style","[UNIC-1441] SNMP config classes","[UNIC-1449] Fix SpotBugs violations - Performance","[UNIC-1463] Fix SpotBugs violations - Code vulnerabilities","[UNIC-980] UniconfigShell: Improving suggestions menu","[UNIC-981] UniconfigShell: Remove explicit show submode from root mode"]},{"i":"api-changes","l":"\uD83D\uDDA5️ API Changes","p":["[UNIC-1289] Refactor RPCs: revert-changes, query-config, device-discovery","[UNIC-1380] Add gnmi-messages logging broker","[UNIC-1287] Refactor snapshot-manager RPCs","[UNIC-1282] Refactoring uniconfig manager RPCs"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["[UNIC-1223] Align an embedded kafka version with the clients provided by Spring","build(deps): bump actions/checkout from 3 to 4","build(deps): bump actions/setup-python from 4.6.1 to 4.7.1","build(deps): bump actions/upload-artifact from 3.1.2 to 3.1.3","build(deps): bump antlr4.version from 4.13.0 to 4.13.1","build(deps): bump com.github.gantsign.maven:ktlint-maven-plugin from 1.16.0 to 2.0.0","build(deps): bump com.github.gantsign.maven:ktlint-maven-plugin from 2.0.0 to 3.0.0","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.7.3.5 to 4.7.3.6","build(deps): bump com.puppycrawl.tools:checkstyle from 10.12.2 to 10.12.3","build(deps): bump com.puppycrawl.tools:checkstyle from 10.12.3 to 10.12.4","build(deps): bump commons-io:commons-io from 2.13.0 to 2.14.0","build(deps): bump commons-net:commons-net from 3.9.0 to 3.10.0","build(deps): bump docker/build-push-action from 4 to 5","build(deps): bump docker/login-action from 2.2.0 to 3.0.0","build(deps): bump grpc.version from 1.57.1 to 1.57.2","build(deps): bump grpc.version from 1.57.2 to 1.58.0","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.15 to 2.2.16","build(deps): bump io.zonky.test.postgres:embedded-postgres-binaries-linux-amd64 from 13.11.0 to 13.12.0","build(deps): bump kotlin.version from 1.9.0 to 1.9.10","build(deps): bump org.apache.commons:commons-compress from 1.23.0 to 1.24.0","build(deps): bump org.apache.maven.plugins:maven-enforcer-plugin from 3.3.0 to 3.4.0","build(deps): bump org.apache.maven.plugins:maven-enforcer-plugin from 3.4.0 to 3.4.1","build(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.5.0 to 3.6.0","build(deps): bump org.apache.maven.plugins:maven-shade-plugin from 3.5.0 to 3.5.1","build(deps): bump org.immutables:value from 2.9.3 to 2.10.0","build(deps): bump org.jetbrains.dokka:dokka-maven-plugin from 1.8.20 to 1.9.0","build(deps): bump org.json:json from 20230618 to 20231013","build(deps): bump org.owasp:dependency-check-maven from 8.3.1 to 8.4.0","build(deps): bump org.springframework.cloud:spring-cloud-dependencies from 2022.0.3 to 2022.0.4","build(deps): bump protobuf.version from 3.23.4 to 3.24.0","build(deps): bump protobuf.version from 3.24.0 to 3.24.1","build(deps): bump protobuf.version from 3.24.1 to 3.24.2","build(deps): bump protobuf.version from 3.24.2 to 3.24.3","build(deps): bump protobuf.version from 3.24.3 to 3.24.4","build(deps): bump spring.boot.version from 3.1.2 to 3.1.3","build(deps): bump spring.boot.version from 3.1.3 to 3.1.4","Maven 3.9.5"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["5.2.1-SNAPSHOT","[FI-1693] Remove Jenkins-test from merge workflow","Workflows: update cluster IP from 10.19.0.67 to 10.19.0.242 and","Workflows: remove VPN to FRINX for postgresDB.","Workflows: update path to new VM of postgresDB.","Workflows: update path and remove FRINX VPN for embeded tests.","Removed forgotten LOG","Release 5.2.1"]}],[{"i":"uniconfig-522","l":"Uniconfig 5.2.2"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1405] UniConfig shell: set nested JSON data","[UNIC-1429] Fix replace operation in GNMI set (MAIN)","[UNIC-1450] Spotbugs fixes - Bad practice","[UNIC-1471] : Fix sync fails after failed installation was stored in DB","[UNIC-1471] Add schema-cache storing into sync impl","[UNIC-1474] Improve performance of YANG repository loading process during mounting process","[UNIC-1475]: generalizing information about expired transaction","[UNIC-1494] - add migration for replace-paths","Add fix for reading duplicate properties","Caching request body copier","Fix bad migration embedded kafka properties from old UC version to new","Fix exception in loading yang schemas","Fix get fallback schema context in cli shell.","Fix update property value to null bug","Removed the forgotten callbacks-models dependencies","Set forgotten crypto properties in creation crypto config.","UniConfig Shell - fix prompt callbacks bug","Use a Set instead of a List in MibRepository"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1075] Uniconfig shell hide / unhide command implementation","[UNIC-1028] Connect/Disconnect node RPC"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1408] UniConfig Shell - adjust cached data","[UNIC-1374] Fixed sending install-node RPC request without mandatory fields","[UNIC-1445] Refactor yang-repo to JOOQ style","Refactoring Properties","Add spotbugs-maven-plugin configuration","Optimize DB read-only transaction","Improved logging","Add Google ErrorProne plugin","[UNIC-1487] return to the same mode when transaction expires"]},{"i":"api-changes","l":"\uD83D\uDDA5️ API Changes","p":["[UNIC-1290] Refactor data-change-events RPCs"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump com.github.spotbugs:spotbugs-annotations from 4.7.3 to 4.8.0","build(deps): bump com.google.guava:guava from 32.1.2-jre to 32.1.3-jre","build(deps): bump org.codehaus.woodstox:stax2-api from 4.2.1 to 4.2.2","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.16 to 2.2.17","build(deps): bump com.fasterxml.jackson.core:jackson-databind from 2.15.2 to 2.15.3","build(deps): bump org.apache.maven.plugins:maven-plugin-plugin from 3.9.0 to 3.10.1","build(deps): bump org.jetbrains.dokka:dokka-maven-plugin from 1.9.0 to 1.9.10","build(deps): bump io.github.git-commit-id:git-commit-id-maven-plugin from 6.0.0 to 7.0.0","build(deps-dev): bump org.apache.maven.plugin-tools:maven-plugin-annotations from 3.9.0 to 3.10.1","build(deps): bump grpc.version from 1.58.0 to 1.59.0","build(deps): bump spring.boot.version from 3.1.4 to 3.1.5","build(deps): bump sshd.version from 2.10.0 to 2.11.0","build(deps): bump org.owasp:dependency-check-maven from 8.4.0 to 8.4.2"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Rename distro/uniconfig-modules/uniconfig to main","Prepared sample docker compose file","Move main.jar into the root","Set kafka enabled to false","Properties overhaul","Suppress CVEs","Use NetconfCacheLoader in gnmi-sb instead of custom yang parsing","Fix binding empty properties","Rewrite client to new properties RPC","Fix dependency management for starting UniConfig","Release 5.2.2"]}],[{"i":"uniconfig-523","l":"Uniconfig 5.2.3"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["zero_dividing_tx_logs_for_notifications","[UNIC-1452] SpotBugs - Dodgy code","Fix ErrorProne ERROR level violations - part 1","[UNIC-1481] Add With-Default to Java client","[UNIC-1490] - Fix delete requests not send","Fix connect/disconnect RPCs","[UNIC-1503] - Fix DB migrations","[UNIC-1503] Fix db migration V26","[UNIC-1498] ErrorProne ERROR level fixes","Fix revisions in static variables"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1484] SNMP - security models"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["optimize hide unhide","[UNIC-1480] Refactor unistore-node to JOOQ style","[UNIC-1488] Uniconfig Shell: add option to refresh the transaction","Cleanup jline packaging","Moved JSONB/NormalizedNode translation for UniconfigInstance from DB …","[UNIC-1419] Java 21","Expose Kafka Producer compression setting"]},{"i":"api-changes","l":"\uD83D\uDDA5️ API Changes","p":["[UNIC-1285] Refactoring template manager rpcs","[UNIC-1286] Refactoring subtree manager RPCs","[UNIC-1461] Return http status code 204 in rpc","[UNIC-1454] Bump revision date in updated YANG models."]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump commons-io:commons-io from 2.14.0 to 2.15.0","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.17 to 2.2.18","build(deps): bump org.apache.maven.plugins:maven-surefire-plugin from 3.1.2 to 3.2.1","build(deps): bump org.apache.maven.plugins:maven-checkstyle-plugin from 3.3.0 to 3.3.1","build(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.6.0 to 3.6.1","build(deps): bump org.codehaus.mojo:properties-maven-plugin from 1.2.0 to 1.2.1","build(deps): bump org.apache.maven.plugins:maven-failsafe-plugin from 3.1.2 to 3.2.1","build(deps): bump commons-cli:commons-cli from 1.5.0 to 1.6.0","build(deps): bump kotlin.version from 1.9.10 to 1.9.20","build(deps): bump protobuf.version from 3.24.4 to 3.25.0"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["New snapshot release 5.2.3","README.md - fix render issues on GitHub","Workflows: remove from cluster tests kafka option.","Release version 5.2.3"]}],[{"i":"uniconfig-524","l":"Uniconfig 5.2.4"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1517] Fix pagination","Fix getting fallback schema token.","[UNIC-1453] UniConfig Shell - one-liner show/set/delete for callbacks","Fix UC not start","[UNIC-1422] Fixed transaction is closed issue","Fix failing cli shell tests","[UNIC-1521] Fix reading list nodes in augmentations (#1946)","Fix SNMP v2c notifications","[UNIC-1512] Fix ordering of operations on gnmi topology","Add handling for successful rpc with status code 204.","Cover more errors in connect node RPC responses"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1486] [UNIC-1509] Skip yang constraints","[UNIC-1507] : One uniconfig tx for (un)install-multiple-nodes RPC"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1514] Add support CER device version 12.*","[DEP-616] UDP loadbalancer with ip transparency for SNMP notifications","[UNIC-1407] Adjust LOGs in Uniconfig shell","[UNIC-1438] Refactoring sal-fallback-provider / fallback-schema-service","[UNIC-1495] Refactor mountpoint to JOOQ style","Add new Release workflow","[UNIC-1502] SNMP v3 notifications","[UNIC-1454] Bump revision date in updated logging YANG models.","Remove object cache"]},{"i":"api-changes","l":"\uD83D\uDDA5️ API Changes","p":["[UNIC-1288] Refactor logging and restconf-logging RPCs","Fix generic status code to specific status code for Subtree RPCs."]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump com.github.spotbugs:spotbugs-annotations from 4.8.0 to 4.8.1","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.7.3.6 to 4.8.1.0","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.18 to 2.2.19","build(deps-dev): bump org.apache.maven.plugin-tools:maven-plugin-annotations from 3.10.1 to 3.10.2","build(deps): bump org.apache.maven.plugins:maven-plugin-plugin from 3.10.1 to 3.10.2","build(deps): bump io.zonky.test.postgres:embedded-postgres-binaries-linux-amd64 from 13.12.0 to 13.13.0","build(deps): bump org.jetbrains:annotations from 24.0.1 to 24.1.0","build(deps): bump bouncycastle.version from 1.76 to 1.77","build(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.1.0 to 3.1.1","build(deps): bump protobuf.version from 3.25.0 to 3.25.1","build(deps): bump com.puppycrawl.tools:checkstyle from 10.12.4 to 10.12.5","build(deps): bump org.owasp:dependency-check-maven from 8.4.2 to 8.4.3","build(deps): bump org.apache.commons:commons-compress from 1.24.0 to 1.25.0"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Add distributionSuffix property","Add name to release workflow","Allow double quotes in release notes body","Build distro without units on release","Dispatch on wf completion instead","Fix PAT usage","Fix release workflow","Fix SNMP bean creation","Fixed logging in TaskExecutorImpl","Forgot to remove these","Forgot to remove this one as well","Merge publish release notes into release wf as a separate job","README - Update release process","Release 5.2.4.","Release new snapshot version 5.2.4-SNAPSHOT","Update release.yml","Use PAT in release workflow","Workflows: add cache for embeded test and remove all docker images","Workflows: add new test to embeded workflow - skip_yang_constraints.","Workflows: disable delete_customers_license_server.yml","Workflows: enable immutable and mutable cluster tests.","Workflows: fix typo for embeded tests.","Workflows: fix typo in embededDB_cross_versions workflow."]}],[{"i":"uniconfig-525","l":"Uniconfig 5.2.5"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1526] - increase gnmi executor queue size","Fix callbacks","Fix sync empty target-nodes response","[UNIC-1538] Fixed check-installed-nodes RPC","FR-63 Fix parsing of SROS CLI prompt in the transaction mode","[UNIC-1534] Swagger: fix bad types for numeric attributes","Fixed command for disabling pagination on SROS","[UNIC-1539] Fix some typos in descriptions","[UNIC-1537] - fix (un)install-multiple","Fix CLI Shell command length counter","[UNIC-1547] Fix sync-from-network RPC","[UNIC-1557] Fix MountPointListenerException","[UNIC-1550] - mount/unmount synchronization"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1533] - skip length & range constraints","[UNIC-1383] Create logging broker for GNMI notifications","Support tailf's comment and label audit params in netconf southbound"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1477] Unify HTTP clients","Refactor TaskExecutor","[UNIC-1505] - Parallel syncFromNetwork","[UNIC-963] Convert List to Map in GNMI","[UNIC-1102] Improve logging for schema context building","[UNIC-1541] Refactor DCE to JOOQ style","[UNIC-1472] CLI shell - Support multiple list entries","[UNIC-1549] Refactor netconf-key-credential to JOOQ style"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump actions/setup-java from 3 to 4","build(deps): bump actions/setup-python from 4.7.1 to 5.0.0","build(deps): bump com.fasterxml.jackson.core:jackson-databind from 2.15.3 to 2.16.0","build(deps): bump com.github.spotbugs:spotbugs-annotations from 4.8.1 to 4.8.2","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.1.0 to 4.8.2.0","build(deps): bump com.puppycrawl.tools:checkstyle from 10.12.5 to 10.12.6","build(deps): bump commons-io:commons-io from 2.15.0 to 2.15.1","build(deps): bump grpc.version from 1.59.0 to 1.59.1","build(deps): bump grpc.version from 1.59.1 to 1.60.0","build(deps): bump io.zonky.test:embedded-postgres from 2.0.4 to 2.0.5","build(deps): bump io.zonky.test:embedded-postgres from 2.0.5 to 2.0.6","build(deps): bump io.zonky.test.postgres:embedded-postgres-binaries-linux-amd64 from 13.13.0 to 13.13.1","build(deps): bump maven.core.version from 3.9.5 to 3.9.6","build(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.2 to 3.6.3","build(deps): bump org.apache.maven.plugins:maven-project-info-reports-plugin from 3.4.5 to 3.5.0","build(deps): bump org.codehaus.mojo:build-helper-maven-plugin from 3.4.0 to 3.5.0","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 1.9.20 to 1.9.21","build(deps): bump org.owasp:dependency-check-maven from 8.4.3 to 9.0.4","Bump org.springframework.boot from 3.1.6 to 3.1.7","Bump Spring Boot to 3.1.6","Use latest maven plugins"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["[UNIC-1523] Refactor notifications and subscriptions to JOOQ style","[UNIC-1531] Use Java 17 as a target","[UNIC-1539] Fix some typos","[UNIC-1542] Refactor Session to JOOQ style","Bump to 5.2.5-SNAPSHOT.","Cluster notification","CVE-2023-51074 suppress","fix_sync_from_network_tests","Fixed creation of NormalizedNode from read NetconfKeyCredential","Fixed usage of JOOQ enumerations","Node jooq","Release 5.2.5.","Rename UniConfig distribution name from bin to without TU","Revert \"[UNIC-1533] - skip length & range constraints\"","Revert \"[UNIC-1547] Fix sync-from-network RPC (#2043)\"","Revert \"build(deps): bump com.fasterxml.jackson.core:jackson-databind from 2.15.3 to 2.16.0 (#1962)\"","Revert \"Revert \"[UNIC-1547] Fix sync-from-network RPC (#2043)\" (#2049)\"","Suppress logback","Suppress sshd vulnerability"]}],[{"i":"uniconfig-526","l":"Uniconfig 5.2.6"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1527] - fixing show mode bugs","add missing docker dependency","[UNIC-1573] CLI shell: Fix Connect/Disconnect RPC suggestions","[UNIC-1576] - Fix retrieving of augmentation node","[UNIC-1574] Fix remove patch operation","[UNIC-1481] Fix with-defaults query parameter"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1545] - Sync southbound nodes"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1499] Swagger: disable generation of POST list entries","[UNIC-1551] Refactor Snapshot and SnapshotNode to JOOQ","[UNIC-1567] - unify error-info property"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.2.6-SNAPSHOT.","Change default value for connect-node RPC","[UNIC-1581] Fix client update and read properties structure","Release 5.2.6."]}],[{"i":"uniconfig-527","l":"Uniconfig 5.2.7"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["Fix protocol issues after refactoring.","Fix protocol issues after refactoring in cli shell.","Fix another protocol issues after refactoring.","Fix sturtup UniConfig","Fixed InterfaceRpdStateReader and CableMacReader for CER devices","[UNIC-1587] Incomplete document fix","[UNIC-1568] Fix sync connection fail handling","Fix version in restconf dependencies","Fix logging controller issue caused by previous refactoring.","Added migration for node.encryption_public_key","[UNIC-1610] Fix bulk-edit in cluster"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1583] Add timeout property for UniConfig Shell","Created CableModemReader and CableModemStateReader for CER devices","[UNIC-1589] - Install skip mount"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1569] Refactor template to JOOQ style","Change protocol table to Enum.","Add postpone reason to task execution error on timeout","[UNIC-1578] Support IPv6 addressing","[UNIC-1384] Refactoring of SNMP read operation"]},{"i":"documentation","l":"\uD83D\uDDD2️ Documentation","p":["[UNIC-1596] Expose OpenAPI documentation for Uniconfig models"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump actions/download-artifact from 3.0.2 to 4.1.1","build(deps): bump actions/upload-artifact from 3.1.3 to 4.2.0","Upgrade Spring Boot version","build(deps): bump dawidd6/action-download-artifact from 2 to 3","build(deps): bump actions/upload-artifact from 4.2.0 to 4.3.0","build(deps): bump com.github.spotbugs:spotbugs-annotations from 4.8.2 to 4.8.3","build(deps): bump org.apache.maven.plugins:maven-failsafe-plugin from 3.2.2 to 3.2.5","build(deps): bump org.apache.maven.plugins:maven-surefire-plugin from 3.2.2 to 3.2.5","build(deps): bump org.owasp:dependency-check-maven from 9.0.4 to 9.0.9","build(deps): bump actions/upload-artifact from 4.3.0 to 4.3.1","build(deps): bump actions/download-artifact from 4.1.1 to 4.1.2"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.2.7-SNAPSHOT.","workflows: Update README.md","Release 5.2.7."]}],[{"i":"uniconfig-600","l":"Uniconfig 6.0.0"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["Fix Dependency check 9.0.x renamed parameter","Fixed removing mac-address command issue in InterfaceRpdConfigWriter","[UNIC-1609] UC Shell - fix data loading","[UNIC-1601] Fix loading fallback context.","[UNIC-1604] - Fix synchronous RPCs","Fix install result processing + mount synchronization","[VHD-358] Fix parsing mountpoint in client.","[UNIC-1625] - Adding 2 new parameters for device installation via Netconf"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1122] DCE duplicate subscription check.","Cleanup yang-packager packaging","[UNIC-1341] Replace AAA encryption service with UniConfig encryption service","Cleanup testtool","Minimize testtool shaded JAR","Rate limiting for user uniconfig transactions","[UNIC-1615] Add exception message to apply template rpc error in client."]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump org.apache.maven.plugin-tools:maven-plugin-annotations from 3.10.2 to 3.11.0","build(deps): bump com.github.curious-odd-man:rgxgen from 1.4 to 2.0","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.2.0 to 4.8.3.1","build(deps): bump com.google.errorprone:error_prone_core from 2.23.0 to 2.24.1","build(deps): bump com.google.errorprone:error_prone_core from 2.24.1 to 2.25.0","build(deps): bump com.google.guava:guava from 32.1.3-jre to 33.0.0-jre","build(deps): bump com.lmax:disruptor from 3.4.4 to 4.0.0","build(deps): bump com.puppycrawl.tools:checkstyle from 10.12.6 to 10.13.0","build(deps): bump grpc.version from 1.60.0 to 1.61.1","build(deps): bump io.perfmark:perfmark-api from 0.26.0 to 0.27.0","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.19 to 2.2.20","build(deps): bump io.zonky.test.postgres:embedded-postgres-binaries-linux-amd64 from 13.13.1 to 13.14.0","build(deps): bump org.apache.commons:commons-compress from 1.25.0 to 1.26.0","build(deps): bump org.apache.maven.plugins:maven-compiler-plugin from 3.11.0 to 3.12.1","build(deps): bump org.apache.maven.plugins:maven-plugin-plugin from 3.10.2 to 3.11.0","build(deps): bump org.apache.maven.plugins:maven-shade-plugin from 3.5.1 to 3.5.2","build(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.1.1 to 3.2.0","build(deps): bump org.immutables:value from 2.10.0 to 2.10.1","build(deps): bump org.javassist:javassist from 3.29.2-GA to 3.30.2-GA","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 1.9.21 to 1.9.22","build(deps): bump org.json:json from 20231013 to 20240205","build(deps): bump org.snmp4j:snmp4j from 3.7.7 to 3.7.8","build(deps): bump org.springframework.boot:spring-boot-dependencies from 3.1.8 to 3.1.9","build(deps): bump protobuf.version from 3.25.1 to 3.25.2","build(deps): bump protobuf.version from 3.25.2 to 3.25.3","build(deps): bump sshd.version from 2.11.0 to 2.12.1","Bump stCarolas/setup-maven from v4.5 to v5"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 5.2.8-SNAPSHOT.","Cleanup unused suppression rules","Update embedded kafka version","workflows: prepare for uniconfig main branch version 6.0.0","Release 6.0.0","Update release.yml"]}],[{"i":"uniconfig-601","l":"Uniconfig 6.0.1"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1586] Fix jsonb filter data util.","[UNIC-1603] Gnmi - Fix getting closest parent for augmentation node.","[UNIC-1611] Add missing return statement.","[UNIC-1612] Fix serialization path in in json filter serializer","[UNIC-1620] UC Shell: Fix leaf-list parsing","[UNIC-1629] Fix replace-paths grouping distinct list entries","[UNIC-1631] Fix EscapedKeysUriFormatter","[UNIC-1663] Revert fix lazy apply template","[UNIC-1667] Add gnmi models to OpenAPI docs","[UNIC-1679] Fix IOS XR parsing","[UNIC-1682] Fix augmentation nodes overwriting each other","[VHD-377] Change qname 'crypto' to 'device-crypto'.","[VHD-377] Rename mountpoint paramater crypto to device-crypto","[VHD-380] Add missing RequestErrorTag.INVALID_TRANSACTION to client side.","Fix casting of UDE","Fix handling of fingerprint read in checked-commit","Fix mount-node task rate-limiting"]},{"i":"new-features","l":"✅ New Features","p":["Made local-priority attribute optional in RpdPtpPortConfigWriter","[UNIC-1684] - Add read and update properties client implementation"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1626] Add missing request tags into client.","[UNIC-1614] Adjust Connect/Disconnect RPC for better user experience","[UNIC-1616] - add node-id into error-info by default","Add logs to warn user when MIB repository metadata is missing","Add Docker dependencies for collect_diag_info script","[UNIC-1643] Add gnmi subscription parameters","Added one more command into the update template to remove RPD connection from fiber-node","Update gitignore","[UNIC-1606] Skip yang-patch exist check operation","[VHD-363] Improving response if there is no content with using count.","Add EdDSA dependency","Separate vulnerability scanning into a workflow","Add slack notification to vulnscan workflow","Fix notification URL","Fix vulnscan ids"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump actions/download-artifact from 4.1.2 to 4.1.4","build(deps): bump args4j:args4j from 2.33 to 2.37","build(deps): bump com.github.gantsign.maven:ktlint-maven-plugin from 3.0.0 to 3.1.1","build(deps): bump com.github.gantsign.maven:ktlint-maven-plugin from 3.1.1 to 3.2.0","build(deps): bump com.google.errorprone:error_prone_core from 2.25.0 to 2.26.1","build(deps): bump com.google.guava:guava from 33.0.0-jre to 33.1.0-jre","build(deps): bump com.puppycrawl.tools:checkstyle from 10.13.0 to 10.14.0","build(deps): bump com.puppycrawl.tools:checkstyle from 10.14.0 to 10.14.2","build(deps): bump docker/login-action from 3.0.0 to 3.1.0","build(deps): bump grpc.version from 1.61.1 to 1.62.2","build(deps): bump io.github.git-commit-id:git-commit-id-maven-plugin from 7.0.0 to 8.0.1","build(deps): bump io.github.git-commit-id:git-commit-id-maven-plugin from 8.0.1 to 8.0.2","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.20 to 2.2.21","build(deps): bump org.apache.commons:commons-compress from 1.26.0 to 1.26.1","build(deps): bump org.apache.maven.plugins:maven-assembly-plugin from 3.6.0 to 3.7.0","build(deps): bump org.apache.maven.plugins:maven-assembly-plugin from 3.7.0 to 3.7.1","build(deps): bump org.apache.maven.plugins:maven-compiler-plugin from 3.12.1 to 3.13.0","build(deps): bump org.apache.maven.plugins:maven-remote-resources-plugin from 3.1.0 to 3.2.0","build(deps): bump org.jetbrains.dokka:dokka-maven-plugin from 1.9.10 to 1.9.20","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 1.9.22 to 1.9.23","build(deps): bump org.json:json from 20240205 to 20240303","build(deps): bump org.owasp:dependency-check-maven from 9.0.9 to 9.0.10","build(deps): bump org.springdoc:springdoc-openapi-starter-webmvc-ui from 2.3.0 to 2.4.0","build(deps): bump org.springframework.boot:spring-boot-dependencies from 3.1.9 to 3.1.10"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.1-SNAPSHOT.","Fix collect_diag_info.sh","Fix logging class","Update vulnscan.yml","Release 6.0.1"]}],[{"i":"uniconfig-602","l":"Uniconfig 6.0.2"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["Fixed write template in InterfaceRpdConfigWriter","[UNIC-1668] Cleanup UNICONFIGTXID cookie properly","Fix transaction cookie cleanup","[UNIC-1687] Swagger - fix schema for empty yang type","Added previous mac-address into the command for removing it","[UNIC-1626] Renaming error tags to its full name.","[UNIC-1582] Fix SROS installation","[UNIC-1665] Unhide shell command for callbacks fix","[UNIC-1686] - CLI: show mount point not working","[UNIC-1678] - Fix Long type serialization in uc-client","[UNIC-1678] - Fix Database jsonb filter on templates","[UNIC-1678] add unit test for uint32 serialization"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1675] Dynamic capability resolving"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1673] Add user details into audit logs","Add date to log timestamp","Add set for servlet context path in java client.","Adjust connect/disconnect RPCs response messages for user readability"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump actions/setup-python from 5.0.0 to 5.1.0","build(deps): bump org.owasp:dependency-check-maven from 9.0.10 to 9.1.0","build(deps): bump commons-io:commons-io from 2.15.1 to 2.16.0","build(deps): bump org.apache.maven.plugins:maven-source-plugin from 3.3.0 to 3.3.1","build(deps): bump org.apache.maven.plugins:maven-invoker-plugin from 3.6.0 to 3.6.1","build(deps-dev): bump org.apache.maven.plugin-tools:maven-plugin-annotations from 3.11.0 to 3.12.0","build(deps): bump org.apache.maven.plugins:maven-plugin-plugin from 3.11.0 to 3.12.0","build(deps): bump org.snmp4j:snmp4j from 3.7.8 to 3.8.0","Use codehaus.plexus-build-api","build(deps): bump org.jline:jline from 3.22.0 to 3.25.1","build(deps): bump grpc.version from 1.62.2 to 1.63.0","build(deps): bump bouncycastle.version from 1.77 to 1.78"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.2-SNAPSHOT.","Fix vulnscan notification on fail","Fix notification status","Fix release workflow","Add snmp models to OpenApi docs","Release 6.0.2"]}],[{"i":"uniconfig-603","l":"Uniconfig 6.0.3"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1415] Fix gnmi subscription session cleanup","Fix IOS XR parsing","[UNIC-1469] Fix commit no rollback","Add logs for device-discovery","[UNIC-1700] Fix problem with reading data that are marked in YANG as deprecated","[UNIC-896] With-default query parameter fix","Additional logs for SNMP","Fix getting protocol value","[UNIC-1699] Fix datastore synchronization","[UNIC-1726] Improve Union codec error reporting","[UNIC-1724] Uniconfig shell Unhide operations for callbacks SET and Request"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1708] Check node connection rpc","[UNIC-1709] Gnmi HealthCheckService","[UNIC-1711] Add SnmpHealthCheckService","[UNIC-1712] Netconf HealthCheckService"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Add shell user into AUDIT_USER header when creating tx","[UNIC-1685] OpenApi: Add error container to response schema","Rename Check-node-connection RPC","Fix dependency convergence issues","Embedded Kafka - stable archive URL","Remove protobuf .proto files from gnmi-proto","[VHD-389] Fix creating subscription to streams.","[UNIC-1713] Stream connection notifications","Cleanup leaking test dependencies from distribution","[UNIC-1223] Remove duplicate dependency declarations","[UNIC-1223] Cleanup dependency version declarations"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump org.apache.maven.plugin-tools:maven-plugin-annotations from 3.12.0 to 3.13.0","build(deps): bump act10ns/slack from 2.0.0 to 2.1.0","build(deps): bump actions/download-artifact from 4.1.4 to 4.1.7","build(deps): bump actions/upload-artifact from 4.3.1 to 4.3.3","build(deps): bump bouncycastle.version from 1.78 to 1.78.1","build(deps): bump com.github.spotbugs:spotbugs-annotations from 4.8.3 to 4.8.4","build(deps): bump com.github.spotbugs:spotbugs-annotations from 4.8.4 to 4.8.5","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.3.1 to 4.8.4.0","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.4.0 to 4.8.5.0","build(deps): bump com.google.errorprone:error_prone_annotations from 2.26.1 to 2.27.0","build(deps): bump com.google.errorprone:error_prone_annotations from 2.27.0 to 2.27.1","build(deps): bump com.google.errorprone:error_prone_core from 2.26.1 to 2.27.0","build(deps): bump com.google.errorprone:error_prone_core from 2.27.0 to 2.27.1","build(deps): bump com.google.guava:guava from 33.1.0-jre to 33.2.0-jre","build(deps): bump com.puppycrawl.tools:checkstyle from 10.14.2 to 10.16.0","build(deps): bump commons-cli:commons-cli from 1.6.0 to 1.7.0","build(deps): bump commons-io:commons-io from 2.16.0 to 2.16.1","build(deps): bump io.zonky.test:embedded-postgres from 2.0.6 to 2.0.7","build(deps): bump jline.version from 3.25.1 to 3.26.1","build(deps): bump org.apache.maven.plugins:maven-jar-plugin from 3.3.0 to 3.4.1","build(deps): bump org.apache.maven.plugins:maven-plugin-plugin from 3.12.0 to 3.13.0","build(deps): bump org.apache.maven.plugins:maven-shade-plugin from 3.5.2 to 3.5.3","build(deps): bump org.checkerframework:checker-qual from 3.42.0 to 3.43.0","build(deps): bump org.snmp4j:snmp4j from 3.8.0 to 3.8.2","build(deps): bump org.springdoc:springdoc-openapi-starter-webmvc-ui from 2.4.0 to 2.5.0","build(deps): bump org.springframework.boot:spring-boot-dependencies f… …rom 3.1.10 to 3.1.11","Use org.ow2.asm:asm-bom"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.3-SNAPSHOT.","Remove unused field from ManageNodeTask","Add missing nodes to UniConfig OpenApi doc","[UNIC-1717] Fix gnmi failed subscription","[UNIC-1718] Rollback removing AAA encryption service","Release 6.0.3"]}],[{"i":"uniconfig-604","l":"Uniconfig 6.0.4"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1728] Fix reading of sample VNF config from netconf-testtool","Add missing dependencies to testtool","Swagger - add missing namespace when node is augmenting on deeper level","SwaggerUI - show extensions","Fix gnmi missing schemaContext handling","Swagger - fix required statement","Swagger - fix url parameters","Docker Compose - add NET_RAW capability","[UNIC-966] Fix create and update operation in PATCH","Fix update tag in PATCH and apply-template","[UNIC-1657] Set found subtree isSelected to true.","[UNIC-1746] Swagger: fix custom operational path","[UNIC-1737] Fix synchronization of datastore from DatabaseDOMDataBroker","Fix sending netconf or gnmi mount body with param schema-cache-directory set to \"\" (empty string)","[UNIC-1744] UC Shell: Fix show on choice nodes"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1710] CLI health-check","Added 13.* version support for ARRIS devices"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Switch to Exificient","[UNIC-397] Improve error message for keys in payload.","[UNIC-1038] Rewrite Dockerfile","[UNIC-1735] Improve gnmi list deserialization","Refactor crypto mount parameter to device-crypto in java client side.","Cleanup dependencies","Swagger - use oneOf for choice nodes"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump com.puppycrawl.tools:checkstyle from 10.16.0 to 10.17.0","build(deps): bump commons-cli:commons-cli from 1.7.0 to 1.8.0","build(deps): bump grpc.version from 1.63.0 to 1.64.0","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.21 to 2.2.22","build(deps): bump maven.core.version from 3.9.6 to 3.9.7","build(deps): bump org.apache.commons:commons-compress from 1.26.1 to 1.26.2","build(deps): bump org.apache.maven.plugins:maven-invoker-plugin from 3.6.1 to 3.7.0","build(deps): bump org.codehaus.mojo:build-helper-maven-plugin from 3.5.0 to 3.6.0","build(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.2.0 to 3.3.0","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 1.9.23 to 1.9.24","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 1.9.24 to 2.0.0","build(deps): bump org.owasp:dependency-check-maven from 9.1.0 to 9.2.0","build(deps): bump org.springframework.boot:spring-boot-dependencies from 3.1.11 to 3.1.12","Docker scout CVE fixes","Embedded PostgreSQL 16","Remove unused dependency - objenesis","Revert \"Use Embedded Postgres version 16 (#2419)\"","Update wrapper script and mvnw to version 3.3.1","Use Embedded Postgres version 16"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.4-SNAPSHOT.","Clean up constants","Update dependabot.yml","Revert protocol uppercase back to lowercase.","Fix typo"]}],[{"i":"uniconfig-605","l":"Uniconfig 6.0.5"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1739] - Fix advisory session unlocking (#2467)","[UNIC-1743] Create calculate-diff-shell rpc. (#2468)","[UNIC-1751] Fix mount operation duplication in the same tx (#2460)","[UNIC-1753] Multiple gnmi notification fixes for IOS Xr7 (#2483)","[UNIC-1754] Fix yang-patch rfc8040 error response (#2489)","[UNIC-1756] Fix wrong snmp connection establishment","[UNIC-1758] Database error: Failed to update node YANG repository because repository does not exist in DB","[UNIC-1763] Swagger: Fix generation of action nodes and tags (#2525)","[UNIC-1771] Refresh schemactx","[UNIC-883] Fix DB tx exception handling","Fix augmentation qname handling","Fix cli session closeup","Fix default reading properties (#2527)","Fix traefik changing URL query param from ; to & (#2514)","Fixed JUNOS version 13 installation","Swagger - add module name to choice schema node definition (#2541)","Swagger: Fix missing cli topology in path parameters (#2480)"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Add banner to logs (#2509)"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Fix verify and merge wfs","Bump to 6.0.5-SNAPSHOT.","[UNIC-1764] Support to optionally wrap cases in choice node (#2539)","Release 6.0.5."]}],[{"i":"uniconfig-606","l":"Uniconfig 6.0.6"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1778] Fix journal size dispatch","Fix merge concurrency group","[UNIC-1775] Improve generic PromptResolutionStrategy","[UNIC-1781] Skip nested constraints in union type (#2573)","Interrupt task when its tx has been expired (#2589)","[UNIC-1789] Complex types constraints skipping (#2592)","[UNIC-1784] Fix checked-commit no rollback (#2593)"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump maven.core.version from 3.9.7 to 3.9.8 (#2529)","build(deps): bump org.owasp:dependency-check-maven from 9.2.0 to 10.0.0","Bump odc to 10.0.2"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.6-SNAPSHOT.","Release 6.0.6."]}],[{"i":"uniconfig-607","l":"Uniconfig 6.0.7"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1798] - Complex changes in SkipConstraintJSONCodecFactory (#2607)","Fix cleaning expired tasks"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.7-SNAPSHOT.","Release 6.0.7."]}],[{"i":"uniconfig-608","l":"Uniconfig 6.0.8"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1801] Fix health-check clash with un/mounting process","[UNIC-1804] Fix transaction timestamp","[UNIC-1808] Commit fail on metadata update","[UNIC-1814] Fix template auto-upgrade"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1812] Implement casa init unit."]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.8-SNAPSHOT.","Release 6.0.8."]}],[{"i":"uniconfig-609","l":"Uniconfig 6.0.9"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1823] Add path to error for invalid value (#2667)"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.9-SNAPSHOT.","Release 6.0.9."]}],[{"i":"uniconfig-610","l":"Uniconfig 6.1.0"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1728] Fix reading of sample VNF config from netconf-testtool","Add missing dependencies to testtool","Swagger - add missing namespace when node is augmenting on deeper level","SwaggerUI - show extensions","Fix gnmi missing schemaContext handling","Swagger - fix required statement","Swagger - fix url parameters","Docker Compose - add NET_RAW capability","[UNIC-966] Fix create and update operation in PATCH","Fix update tag in PATCH and apply-template","[UNIC-1657] Set found subtree isSelected to true.","[UNIC-1746] Swagger: fix custom operational path","[UNIC-1737] Fix synchronization of datastore from DatabaseDOMDataBroker","Fix sending netconf or gnmi mount body with param schema-cache-directory set to \"\" (empty string)","[UNIC-1744] UC Shell: Fix show on choice nodes"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1710] CLI health-check","Added 13.* version support for ARRIS devices"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Switch to Exificient","[UNIC-397] Improve error message for keys in payload.","[UNIC-1038] Rewrite Dockerfile","[UNIC-1735] Improve gnmi list deserialization","Refactor crypto mount parameter to device-crypto in java client side.","Cleanup dependencies","Swagger - use oneOf for choice nodes"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump com.puppycrawl.tools:checkstyle from 10.16.0 to 10.17.0","build(deps): bump commons-cli:commons-cli from 1.7.0 to 1.8.0","build(deps): bump grpc.version from 1.63.0 to 1.64.0","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.21 to 2.2.22","build(deps): bump maven.core.version from 3.9.6 to 3.9.7","build(deps): bump org.apache.commons:commons-compress from 1.26.1 to 1.26.2","build(deps): bump org.apache.maven.plugins:maven-invoker-plugin from 3.6.1 to 3.7.0","build(deps): bump org.codehaus.mojo:build-helper-maven-plugin from 3.5.0 to 3.6.0","build(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.2.0 to 3.3.0","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 1.9.23 to 1.9.24","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 1.9.24 to 2.0.0","build(deps): bump org.owasp:dependency-check-maven from 9.1.0 to 9.2.0","build(deps): bump org.springframework.boot:spring-boot-dependencies from 3.1.11 to 3.1.12","Docker scout CVE fixes","Embedded PostgreSQL 16","Remove unused dependency - objenesis","Revert \"Use Embedded Postgres version 16 (#2419)\"","Update wrapper script and mvnw to version 3.3.1","Use Embedded Postgres version 16"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.0.4-SNAPSHOT.","Clean up constants","Update dependabot.yml","Revert protocol uppercase back to lowercase.","Fix typo","Release 6.1.0."]}],[{"i":"uniconfig-611","l":"Uniconfig 6.1.1"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1739] - Fix advisory session unlocking","[UNIC-1751] Fix mount operation duplication in the same tx","[UNIC-1753] Multiple gnmi notification fixes for IOS Xr7","[UNIC-1754] Fix yang-patch rfc8040 error response","[UNIC-1756] Fix wrong snmp connection establishment","[UNIC-1758] Database error: Failed to update node YANG repository because repository does not exist in DB","[UNIC-1763] Swagger: Fix generation of action nodes and tags","[UNIC-1771] Fix register-repository","[UNIC-883] Fix DB tx exception handling","Fix 'End of input' exception on netconf session.close()","Fix augmentation qname handling","Fix cli session closeup","Fix default reading properties","Fix traefik changing URL query param from ; to &","Fixed JUNOS version 13 installation (#2485)","Support check-nodes-connection for southbound only","Swagger: Fix missing cli topology in path parameters","Swagger: Fix missing snmp topology in path parameters"]},{"i":"new-features","l":"✅ New Features","p":["[UNIC-1580] - Integration of 'fields' query parameter into NETCONF subtree filtering","[UNIC-1762] Bulk-get RPC"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1743] Create calculate-diff-shell rpc.","Add banner to logs","[UNIC-1761] Fix time range in gnmi streaming","[UNIC-1400] Refactor and extract uniconfig diff","Package logback cluster configuration","Swagger - add module name to choice schema node definition"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps-dev): bump org.apache.maven.plugin-tools:maven-plugin-annotations from 3.13.0 to 3.13.1","build(deps): bump com.github.spotbugs:spotbugs-annotations from 4.8.5 to 4.8.6","build(deps): bump com.google.errorprone:error_prone_annotations from 2.27.1 to 2.28.0","build(deps): bump com.google.errorprone:error_prone_core from 2.27.1 to 2.28.0","build(deps): bump com.google.guava:guava from 33.2.0-jre to 33.2.1-jre","build(deps): bump commons-net:commons-net from 3.10.0 to 3.11.0","build(deps): bump commons-net:commons-net from 3.11.0 to 3.11.1","build(deps): bump docker/build-push-action from 5 to 6","build(deps): bump docker/login-action from 3.1.0 to 3.2.0","build(deps): bump io.github.git-commit-id:git-commit-id-maven-plugin from 8.0.2 to 9.0.0","build(deps): bump jline.version from 3.26.1 to 3.26.2","build(deps): bump maven.core.version from 3.9.7 to 3.9.8","build(deps): bump org.apache.maven.plugins:maven-checkstyle-plugin from 3.3.1 to 3.4.0","build(deps): bump org.apache.maven.plugins:maven-clean-plugin from 3.3.2 to 3.4.0","build(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.6.1 to 3.7.0","build(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.7.0 to 3.7.1","build(deps): bump org.apache.maven.plugins:maven-enforcer-plugin from 3.4.1 to 3.5.0","build(deps): bump org.apache.maven.plugins:maven-failsafe-plugin from 3.2.5 to 3.3.0","build(deps): bump org.apache.maven.plugins:maven-jar-plugin from 3.4.1 to 3.4.2","build(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.3 to 3.7.0","build(deps): bump org.apache.maven.plugins:maven-plugin-plugin from 3.13.0 to 3.13.1","build(deps): bump org.apache.maven.plugins:maven-project-info-reports-plugin from 3.5.0 to 3.6.0","build(deps): bump org.apache.maven.plugins:maven-release-plugin from 3.0.1 to 3.1.0","build(deps): bump org.apache.maven.plugins:maven-shade-plugin from 3.5.3 to 3.6.0","build(deps): bump org.apache.maven.plugins:maven-surefire-plugin from 3.2.5 to 3.3.0","build(deps): bump org.checkerframework:checker-qual from 3.43.0 to 3.44.0"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.1.1-SNAPSHOT.","[UNIC-1764] Support to optionally wrap cases in choice node","Release 6.1.1."]}],[{"i":"uniconfig-612","l":"Uniconfig 6.1.2"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1778] Fix journal size dispatch","[UNIC-1775] Improve generic PromptResolutionStrategy","Fix class cast exception when getting direct child.","Fix UC Shell remove redundant findNode step.","[UNIC-1781] Skip nested constraints in union type","Interrupt task when its tx has been expired","[UNIC-1789] Complex types constraints skipping","[UNIC-1784] Fix checked-commit no rollback"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Added a path field to notification","[UNIC-1783] - Adjust bulk-get output"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump actions/download-artifact from 4.1.7 to 4.1.8","build(deps): bump actions/setup-python from 5.1.0 to 5.1.1","build(deps): bump actions/upload-artifact from 4.3.3 to 4.3.4","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.5.0 to 4.8.6.1","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.6.1 to 4.8.6.2","build(deps): bump grpc.version from 1.64.0 to 1.65.0","build(deps): bump grpc.version from 1.65.0 to 1.65.1","build(deps): bump io.github.git-commit-id:git-commit-id-maven-plugin from 9.0.0 to 9.0.1","build(deps): bump org.apache.maven.plugins:maven-failsafe-plugin from 3.3.0 to 3.3.1","build(deps): bump org.apache.maven.plugins:maven-project-info-reports-plugin from 3.6.0 to 3.6.1","build(deps): bump org.apache.maven.plugins:maven-project-info-reports-plugin from 3.6.1 to 3.6.2","build(deps): bump org.apache.maven.plugins:maven-release-plugin from 3.1.0 to 3.1.1","build(deps): bump org.apache.maven.plugins:maven-surefire-plugin from 3.3.0 to 3.3.1","build(deps): bump org.checkerframework:checker-qual from 3.44.0 to 3.45.0","build(deps): bump org.owasp:dependency-check-maven from 10.0.0 to 10.0.2","build(deps): bump org.owasp:dependency-check-maven from 9.2.0 to 10.0.0","build(deps): bump org.springdoc:springdoc-openapi-starter-webmvc-ui from 2.5.0 to 2.6.0","build(deps): bump tech.pantheon.triemap:triemap from 1.3.1 to 1.3.2"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.1.2-SNAPSHOT.","Switch vulnscan workflow stable branch","Remove mdsal-binding-util","Update spotbugs-exclude.xml","Release 6.1.2."]}],[{"i":"uniconfig-613","l":"Uniconfig 6.1.3"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1798] - Complex changes in SkipConstraintJSONCodecFactory","Fix cleaning expired tasks"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump sshd.version from 2.12.1 to 2.13.1","build(deps): bump com.google.errorprone:error_prone_annotations from 2.28.0 to 2.29.2","build(deps): bump com.google.errorprone:error_prone_core from 2.28.0 to 2.29.2","build(deps): bump jline.version from 3.26.2 to 3.26.3","build(deps): bump org.owasp:dependency-check-maven from 10.0.2 to 10.0.3","build(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.7.0 to 3.8.0","build(deps): bump docker/login-action from 3.2.0 to 3.3.0","Update Kafka to 3.7.1","build(deps): bump io.zonky.test.postgres:embedded-postgres-binaries-linux-amd64 from 16.2.0 to 16.3.0"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.1.3-SNAPSHOT.","Release 6.1.3."]}],[{"i":"uniconfig-614","l":"Uniconfig 6.1.4"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1801] Fix health-check clash with un/mounting process","[UNIC-1804] Fix transaction timestamp","[UNIC-1813] Fix replace-config-with-snapshot","[UNIC-1808] Commit fail on metadata update","[UNIC-1811] Fix loading yang repository in bulk-get cluster","[UNIC-1814] Fix template auto-upgrade (#2648)","Change log level in GlobalDOMSchemaServiceImpl"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1786] Open prometheus endpoint in actuator.","[UNIC-1786] Rewrite UniConfig metrics to micrometer.","[UNIC-1806] TopologyNode based data-broker","[UNIC-1812] Implement casa init unit.","[UNIC-1803] Local Uniconfig deployment in minikube(kubernets cluster)"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump antlr4.version from 4.13.1 to 4.13.2","build(deps): bump sshd.version from 2.13.1 to 2.13.2","build(deps): bump org.checkerframework:checker-qual from 3.45.0 to 3.46.0","build(deps): bump actions/upload-artifact from 4.3.4 to 4.3.5","build(deps): bump com.google.errorprone:error_prone_annotations from 2.29.2 to 2.30.0","build(deps): bump actions/upload-artifact from 4.3.5 to 4.3.6","build(deps): bump org.apache.commons:commons-compress from 1.26.2 to 1.27.0","build(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.3.0 to 3.4.0","build(deps): bump com.google.errorprone:error_prone_core from 2.29.2 to 2.30.0","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 2.0.0 to 2.0.10","build(deps): bump io.zonky.test.postgres:embedded-postgres-binaries-linux-amd64 from 16.3.0 to 16.4.0","build(deps): bump grpc.version from 1.65.1 to 1.66.0"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.1.4-SNAPSHOT.","Readme update regarding topology-node data brokers","Release 6.1.4."]}],[{"i":"uniconfig-615","l":"Uniconfig 6.1.5"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1823] Add path to error for invalid value","Fix show_uniconfig_status.sh","[UNIC-1618] Attempt to install vnf20 device (10.103.5.202) with snmp v3 fail","[UNIC-1817] Fix synchronization of collecting nested tx db writers","[UNIC-961] Option to add tag to leaf without providing value"]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1805] Rewrite Uniconfig healthcheck using Spring Boot actuator.","[UNIC-1732] Asynchronous apply-template RPC","Clean up code related to old health rpc impl.","Fix error exposing internal info","Move checking db into readiness health indicator.","Reimplementing rpc health with spring healthcheck logic"]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["build(deps): bump commons-cli:commons-cli from 1.8.0 to 1.9.0","build(deps): bump com.google.guava:guava from 33.2.1-jre to 33.3.0-jre","build(deps): bump org.apache.maven.plugins:maven-surefire-plugin from 3.3.1 to 3.4.0","build(deps): bump org.apache.maven.plugins:maven-failsafe-plugin from 3.3.1 to 3.4.0","build(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.4.0 to 3.4.1","build(deps): bump org.apache.maven.plugins:maven-plugin-plugin from 3.13.1 to 3.14.0","build(deps-dev): bump org.apache.maven.plugin-tools:maven-plugin-annotations from 3.13.1 to 3.14.0","build(deps): bump maven.core.version from 3.9.8 to 3.9.9","build(deps): bump org.apache.maven.plugins:maven-project-info-reports-plugin from 3.6.2 to 3.7.0","build(deps): bump com.puppycrawl.tools:checkstyle from 10.17.0 to 10.18.0","build(deps): bump org.apache.maven.plugins:maven-checkstyle-plugin from 3.4.0 to 3.5.0","build(deps): bump org.apache.maven.plugins:maven-invoker-plugin from 3.7.0 to 3.8.0","build(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.7.1 to 3.8.0","build(deps): bump org.apache.commons:commons-compress from 1.27.0 to 1.27.1","build(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 2.0.10 to 2.0.20"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 6.1.5-SNAPSHOT.","[UNIC-1820] - Fix local-as command for IOS device","Release 6.1.5."]},{"l":"New Contributors"}],[{"i":"uniconfig-616","l":"Uniconfig 6.1.6"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["Fix EscapedKeysUriFormatter","[UNIC-1830] Fix constraint check skip for clients","Add TUs for \"default-route-distance\" container (#2712)","[UNIC-1837] Remove exception throwing when auto templates-upgrader fails","[UNIC-1839] Remove key from list edit in bulk edit rpc."]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["[UNIC-1828] Log template name and optionally path to config(if presen…"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Fix verify and merge workflows","Bump to 6.1.6-SNAPSHOT.","Fix find_changed_code_verify.sh for stable","Fix find_changed_code_merge.sh for stable","Release 6.1.6."]}],[{"i":"uniconfig-700","l":"Uniconfig 7.0.0"},{"i":"whats-changed","l":"What's Changed"},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["7.0.x","Fix wfs","Prepare for new stable branch and new main branch with v7 of uniconfig","Release 7.0.0.","Fix release.yml","Update release.yml"]}],[{"i":"uniconfig-701","l":"Uniconfig 7.0.1"},{"i":"whats-changed","l":"What's Changed"},{"i":"bug-fixes","l":"\uD83D\uDC1E Bug Fixes","p":["[UNIC-1830] Fix constraint check skip for clients","[UNIC-1828] Log template name and optionally path to config(if present in the origin exception)","Add TUs for \"default-route-distance\" container","[UNIC-1835] Fix configuration meter filter","[UNIC-1837] Remove exception throwing when auto templates-upgrader fails","[UNIC-1839] Remove key from list edit in bulk edit rpc."]},{"i":"improvements","l":"\uD83D\uDCA1 Improvements","p":["Move the metrics initialization before the initialization of beans that register metrics to ensure the filter is applied first."]},{"i":"dependency-upgrades","l":"\uD83D\uDD28 Dependency Upgrades","p":["Add dependency management for version declarations of missing maven p…","build(deps-dev): bump org.apache.maven.plugin-tools:maven-plugin-annotations from 3.14.0 to 3.15.0","build(deps): bump actions/setup-python from 5.1.1 to 5.2.0","build(deps): bump actions/upload-artifact from 4.3.6 to 4.4.0","build(deps): bump com.github.gantsign.maven:ktlint-maven-plugin from 3.2.0 to 3.3.0","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.6.2 to 4.8.6.3","build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.6.3 to 4.8.6.4","build(deps): bump com.google.errorprone:error_prone_annotations from 2.30.0 to 2.31.0","build(deps): bump com.google.errorprone:error_prone_annotations from 2.31.0 to 2.32.0","build(deps): bump com.google.errorprone:error_prone_core from 2.30.0 to 2.31.0","build(deps): bump com.google.errorprone:error_prone_core from 2.31.0 to 2.32.0","build(deps): bump com.google.protobuf:protobuf-java from 3.25.3 to 3.25.5 in /commons/parents/odlparent","build(deps): bump com.puppycrawl.tools:checkstyle from 10.18.0 to 10.18.1","build(deps): bump commons-io:commons-io from 2.16.1 to 2.17.0","build(deps): bump io.swagger.core.v3:swagger-core from 2.2.22 to 2.2.23","build(deps): bump jline.version from 3.26.3 to 3.27.0","build(deps): bump org.apache.maven.plugins:maven-failsafe-plugin from 3.4.0 to 3.5.0","build(deps): bump org.apache.maven.plugins:maven-help-plugin from 3.4.1 to 3.5.0","build(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.8.0 to 3.10.0","build(deps): bump org.apache.maven.plugins:maven-plugin-plugin from 3.14.0 to 3.15.0","build(deps): bump org.apache.maven.plugins:maven-surefire-plugin from 3.4.0 to 3.5.0","build(deps): bump org.checkerframework:checker-qual from 3.46.0 to 3.47.0","build(deps): bump org.owasp:dependency-check-maven from 10.0.3 to 10.0.4","build(deps): bump org.springframework.boot:spring-boot-dependencies from 3.3.3 to 3.3.4"]},{"i":"other-changes","l":"\uD83D\uDD27 Other Changes","p":["Bump to 7.0.1-SNAPSHOT","dependency-check - Suppress FP and clean up unused rule","Document stable branch creation process","Improve logback for kubernetes clustered deployment","Add profiling image of Uniconfig","Release 7.0.1."]}],[{"l":"Translation Units","p":["This repository contains documentation for all available translation units for the FRINX ODL CLI service module. A translation unit is a piece of code that includes handlers to read from or write to a specific device (e.g. Cisco IOS classic router) and facilitates the translation in OpenConfig models. The purpose of this documentation is to see which commands can be read and set and how they map to the respective YANG models. Every section has a README file that provides an overview of all show and configuration commands that are supported. Multiple translation units are finally packaged together and made available as a karaf feature that can be installed at runtime."]},{"l":"Table of Contents","p":["URL","URL Operations","GET","PUT","DELETE","OPERATIONAL datasets","OPENCONFIG YANG","OS COMMANDS","DEVICE YANG","UNIT","CONFIGURATION datasets"]},{"l":"URL","p":["can be either cli or unified","each list item argument MUST be followed by list key. Usually the key is mapped to just one leaf (identifier, name, etc.), but in some cases, the key is created using more leafs. In this case, in the URL, the keys follow each other in order specified by YANG.","Each URL has a base format:","Example:","for each container or list in YANG model, there MUST be an argument in the URL","if the URL is tied with a body, the top-level element in the body must be the last element in the URL","Let's say you want to be even more specific and list details just about one particular interface. You can view the data by adding 'interface=' to the URL.","Let's say you want to list all areas in a specific OSPF. To obtain this data, you can trim the part: '/area=/interfaces' from the URL.","mountpoint name","network-instances argument is a list. We want to specify one item from that list (specific network instance), therefore the URL continues with ‘network-instance'. The key in network-instance is the identifier '' (e.g. vrf1) which follows the list item argument. Complex key is needed for protocol argument. The key is protocol-type followed by process-id. (frinx-openconfig-policy-types:OSPF, )","same for 'area='","Simplified example:","The general steps in creating the URL are following:","the top level argument must contain the name of the model. The name of the model must also be specified for YANG identities.","the URL contains an identity which is a part of a key for protocol list. This identity is prefixed by model name: ‘frinx-openconfig-policy-types:OSPF’","The URL will always point to either operational or config datastore and to the node we want to get the information from. You can always check if the particular device is registered by issuing GET on :","top-level argument contains also YANG model name: ‘frinx-openconfig-network-instance’","URLs are modular. By changing the URL you can move along the YANG data tree.","very specific URL listing interfaces under one specific area in OSPF under specific VRF","You can create a minimalistic YANG tree out of the URL:"]},{"l":"URL Operations","p":["Each show command supports only one http operation: GET ."]},{"l":"GET","p":["GET operation can be issued on both config/operational datastore. Config datastore reflects how the device is configured. Operational datastore reflects the state of the device. In most cases the information is the same.","Example of a case where the information is not the same (the only difference in requests is config vs operational):","Configuration commands support PUT for create/replace data. This operation requires HTTP body, which contains openconfig YANG model of the configuration you want to send to the router. Another operation supported by configuration commands is DELETE, which removes data from the device. Both operations need to be issued on config datastore.","For modifications of the data, you can use also PATCH method, that does not replace the entire data structure, only the parts that are different.","Example:","We want to create a new BGP neighbor:","The IOS command is:"]},{"l":"PUT","p":["BODY:","WARNING: PUT operation does not merge data. In this example if you have already configured some BGP neighbors, this request will REMOVE all of them and create just the one described in the PUT body. The solution is to first issue GET, copy existing configuration and add/change items there, or use PATCH method.","If we want to DELETE a BGP neighbor, the body is not needed, the URL needs to be specific to the neighbor we want to delete:"]},{"l":"DELETE","p":["This operation will issue following command:","DELETE operation always removes the last argument of the URL."]},{"l":"OPERATIONAL datasets","p":["Go to operational datasets","Show commands are commands that usually on Cisco device start with 'show'. The aim is to obtain data from the router."]},{"i":"url-1","l":"URL","p":["GET operation issued on operational datastore"]},{"l":"OPENCONFIG YANG","p":["In case of show commands this section is a sample output of a particular show command."]},{"l":"OS COMMANDS","p":["In this section we list the actual router commands with sample outputs, where the data obtained and transformed into Openconfig YANG is marked as bold. We list show commands and outputs for each supported device OS.","IOS XR | IOS Classic/XE | Junos | SAOS"]},{"l":"DEVICE YANG","p":["In case of CLI units, the unit parses the output of the CLI command directly into OC YANG. In case of Netconf units, the output is mapped to OC YANG through Device YANG (YANG model supported by the device). In case of Netconf units, the YANG is also written in documentation. This section is a link to XML unit test input testing this operation."]},{"l":"UNIT","p":["Link to github code where this show commmand is implemented along with unit version range."]},{"l":"CONFIGURATION datasets","p":["Go to configuration datasets"]},{"i":"url-2","l":"URL","p":["PUT operation with given URL will result in creating of data in config datastore DELETE operation with given URL will result in removing data in config datastore"]},{"i":"openconfig-yang-1","l":"OPENCONFIG YANG","p":["In case of configuration commands, this section represents the HTTP body in PUT operation"]},{"i":"os-commands-1","l":"OS COMMANDS","p":["In this section we list the actual router commands that are mapped to the Openconfig YANG model. Data transformed into Openconfig YANG is marked as bold. We list commands for each supported device OS.","IOS XR | IOS Classic/XE | Junos | SAOS"]},{"i":"device-yang-1","l":"DEVICE YANG","p":["In case od Netconf units, the device yang represents command sent to the device in device YANG model. This section is a link to XML unit test input testing this configuration."]},{"i":"unit-1","l":"UNIT","p":["Link to github code where this config commmand is implemented along with unit version range."]}],[{"l":"IETF L2VPN YANG"},{"l":"Scenario"},{"i":"l2p2pvpws","l":"L2P2P/VPWS","p":["l2vpn-instance/type == vpws-instance-type only two endpoints"]},{"l":"Local-Local","p":["connection between two local ports on a host (pe-node-id`s of endpoints match)"]},{"i":"ietf--yang","l":"IETF YANG"},{"l":"OPENCONFIG YANG"},{"l":"pe01"}],[{"l":"IETF L2VPN YANG"},{"l":"Scenario"},{"i":"l2p2pvpws","l":"L2P2P/VPWS","p":["l2vpn-instance/type == vpws-instance-type only two endpoints"]},{"l":"Local-Remote","p":["connection between local and remote hosts (pe-node-id`s of endpoints do not match)"]},{"i":"ietf--yang","l":"IETF YANG"},{"l":"OPENCONFIG YANG"},{"l":"pe01"},{"l":"PE2"}],[{"l":"IETF L2VPN YANG"},{"l":"Scenario"},{"i":"l2p2pvpls","l":"L2P2P/VPLS","p":["l2vpn-instance/type == vpls-instance-type Two or more endpoints"]},{"i":"ietf--yang","l":"IETF YANG"},{"l":"OPENCONFIG YANG"},{"l":"pe01"},{"l":"pe02"},{"l":"pe03"}],[{"l":"IETF L3VPN YANG"},{"l":"IETF YANG"},{"l":"OPENCONFIG YANG"}],[{"i":"#","p":["Access control","ACL","ACL interfaces","BGP","CDP","connection point","connection point l2vpn","Discovery protocols","Ethernet interface","Ethernet OAM","Ethernet Virtual Circuit","Ethernet Virtual Private Network","EVC","EVPN","FDP","Hot Standby Router Protocol","HSRP","Interfaces","Internet Protocol Security","IPsec","IS-IS","L2P2P","L2VPN","L3 VLAN interface","L3VPN","l3vpn with BGP","l3vpn with OSPF","LAG interface","Monitoring","MPLS","MPLS LDP","MPLS TE","MPLS TE RSVP","MPLS Tunnel","NetFlow","NetFlow interfaces","Network Instance","Network Instances","OSPF","OSPFv3","PF interfaces","Policy Forwarding","Probes","Protocols","Quality of Service","Routing Policy","SNMP","Spanning Tree Protocol","STP","SYSLOG"]},{"l":"Interfaces"},{"l":"Ethernet interface"},{"l":"LAG interface"},{"l":"L3 VLAN interface"},{"l":"Network Instances"},{"l":"Network Instance"},{"l":"Protocols"},{"l":"BGP"},{"l":"OSPF"},{"l":"OSPFv3"},{"l":"IS-IS"},{"l":"MPLS"},{"l":"MPLS TE"},{"l":"MPLS Tunnel"},{"l":"MPLS TE RSVP"},{"l":"MPLS LDP"},{"l":"Policy Forwarding"},{"l":"PF interfaces"},{"l":"L2P2P"},{"l":"connection point"},{"l":"L2VPN"},{"l":"connection point l2vpn"},{"l":"L3VPN"},{"l":"l3vpn with BGP"},{"l":"l3vpn with OSPF"},{"l":"Discovery protocols"},{"l":"CDP"},{"l":"FDP"},{"l":"Monitoring"},{"l":"SNMP"},{"l":"SYSLOG"},{"l":"Probes"},{"l":"Ethernet OAM"},{"l":"Hot Standby Router Protocol"},{"l":"HSRP"},{"l":"Access control"},{"l":"ACL"},{"l":"ACL interfaces"},{"l":"Spanning Tree Protocol"},{"l":"STP"},{"l":"Routing Policy"},{"i":"routing-policy-1","l":"Routing Policy"},{"l":"NetFlow"},{"l":"NetFlow interfaces"},{"l":"Quality of Service"},{"i":"quality-of-service-1","l":"Quality of Service"},{"l":"Ethernet Virtual Private Network"},{"i":"ethernet-virtual-private-network-1","l":"Ethernet Virtual Private Network"},{"l":"Internet Protocol Security"},{"l":"IPsec"}],[{"l":"Access Control List"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534-ios-xr-662","l":"Cisco IOS XR 5.3.4, IOS XR 6.6.2"},{"l":"CLI"},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xe-1542s","l":"Cisco IOS XE 15.4(2)S"},{"i":"cli-1","l":"CLI"},{"l":"Examples"},{"i":"unit-1","l":"Unit","p":["Link to github : xe-unit"]},{"i":"junos-141x53-d408","l":"Junos 14.1X53-D40.8"},{"i":"cli-2","l":"CLI"},{"i":"unit-2","l":"Unit","p":["Link to github : junos-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-3","l":"CLI"},{"i":"unit-3","l":"Unit","p":["Link to github : junos-unit"]},{"i":"junos-182r1-s21","l":"Junos 18.2R1-S2.1"},{"i":"cli-4","l":"CLI","p":["iacl_intf_index, iacl_subintf_index is a conversion of set ."]},{"i":"unit-4","l":"Unit","p":["Link to github : junos-unit"]}],[{"l":"Access Control List"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"l":"Cisco IOS Classic"},{"l":"CLI","p":["ipv4|ipv6 is a conversion of* eq|neq|range * is a conversion of or , operation is selected by entered port range *eq|neq|range * is a conversion of or , operatioons is selected by entered port range | acl option could be defined by enumeration named options or by number in range 0-255 ** is a conversion of , when true, value is \"established\", when false, there is empty value \"\""]},{"l":"Examples"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"i":"cli-1","l":"CLI","p":["ipv4|ipv6 is a conversion of"]},{"i":"examples-1","l":"Examples"},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-662","l":"Cisco IOS XR 6.6.2"},{"i":"cli-2","l":"CLI","p":["ipv4|ipv6 is a conversion of"]},{"i":"examples-2","l":"Examples"},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xe-1542s","l":"Cisco IOS XE 15.4(2)S"},{"i":"cli-3","l":"CLI","p":["** is a conversion of , when true, value is \"established\", when false, there is empty value \"\""]},{"i":"examples-3","l":"Examples"},{"i":"unit-2","l":"Unit","p":["Link to github : xe-unit"]},{"i":"junos-141x53-d408","l":"Junos 14.1X53-D40.8"},{"i":"cli-4","l":"CLI"},{"i":"unit-3","l":"Unit","p":["Link to github : junos-unit"]},{"i":"ciena-saos-614","l":"Ciena SAOS 6.14"},{"i":"cli-5","l":"CLI","p":["conversion is ACCEPT = allow, DROP = deny* access-list disable profile * is a conversion of frinx-acl-extension:enabled set to false. Default value is true."]},{"i":"unit-4","l":"Unit","p":["Link to github : [saos-unit]"]}],[{"l":"cable DOWNSTREAM CONTROLLER-PROFILE"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"IOS XE 16"},{"l":"CLI","p":["can be either a single number or a list of numbers (0 31 which represents all the values from 0 to 31)"]},{"l":"Unit","p":["Link to github : ios-xe-unit"]}],[{"l":"cable FIBER-NODE"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"IOS XE 16"},{"l":"CLI","p":["and are in commands input with whitespace dividing name and number (Downstream-Cable 1/0/16)"]},{"l":"Unit","p":["Link to github : ios-xe-unit"]}],[{"l":"cable RPD"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"IOS XE 16"},{"l":"CLI","p":["and are in commands input with whitespace dividing name and number (Downstream-Cable 1/0/16)","no principal is a conversion of set false principal is a conversion of set true"]},{"l":"Unit","p":["Link to github : ios-xe-unit"]}],[{"l":"BRIDGE interface"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"IOS 12"},{"l":"CLI","p":["is parsed from example is BDI10 -> is 10","no shutdown is a conversion of set true shutdown is a conversion of set false no snmp trap link-status is a conversion of set false snmp trap link-status is a conversion of set true"]},{"l":"Unit","p":["Link to github : ios-unit"]}],[{"l":"CABLE interface"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"IOS XE 16"},{"l":"CLI","p":["are read from all lines and input into one attribute \"rf-channels\" and are in commands input with whitespace dividing name and number (Downstream-Cable 1/0/16)"]},{"l":"Unit","p":["Link to github : ios-xe-unit"]}],[{"l":"Ethernet interface"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI","p":["is a conversion of no shutdown is a conversion of set true shutdown is a conversion of set false switchport port-security is a conversion of set true no switchport port-security is a conversion of set false can be \"protect\", \"restrict\" or \"shutdown\" can be \"absolute\" or \"inactivity\" switchport port-security aging static is a conversion of set true no switchport port-security aging static is a conversion of set false lldp transmit is a conversion of set true no lldp transmit is a conversion of set false lldp receive is a conversion of set true no lldp receive is a conversion of set false negotiation auto is a conversion of set true no negotiation auto is a conversion of set false cdp enable is a conversion of set true no cdp enable is a conversion of set false is parsed from example is Port-channel3 -> is 3 mode on is a conversion of set to frinx-openconfig-lacp:ON can be \"default\" or \"rj45\" or \"sfp\" can be \"broadcast\" or \"multicast\" or \"unicast\"","is conversion of"]},{"l":"Unit","p":["Link to github : ios-unit"]},{"i":"cisco-ios-xe-15-16-17","l":"Cisco IOS XE 15, 16, 17"},{"i":"cli-1","l":"CLI","p":["is a conversion of no shutdown is a conversion of set true shutdown is a conversion of set false normal is a conversion of \"\" set \"NORMAL\" fast is a conversion of \"\" set \"FAST\" lldp transmit is a conversion of set true no lldp transmit is a conversion of set false lldp receive is a conversion of set true no lldp receive is a conversion of set false negotiation auto is a conversion of set true no negotiation auto is a conversion of set false is parsed from example is Port-channel3 -> is 3 mode on is a conversion of set to frinx-openconfig-lacp:ON can be \"default\" or \"rj45\" or \"sfp\" can be \"broadcast\" or \"multicast\" or \"unicast\" service instance trunk ethernet is conversion of set true* service instance ethernet * is conversion of set false* encapsulation untagged , dot1q * is conversion of set true* encapsulation dot1q * is conversion of set false can be \"ingress\" or \"egress\" can be \"pop\" or \"push\" or \"translate\" can be \"tunnel\" or \"peer\" or \"forward\" can be \"cdp\" or \"vtp\" or \"lacp\" or \"lldp\" or \"mmrp\" or \"mvrp\" or \"stp\" or \"RB\" or \"RC\" or \"RD\" or \"RF\""]},{"i":"unit-1","l":"Unit","p":["Link to github : ios-xe-unit"]},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"i":"cli-2","l":"CLI","p":["is parsed from example is Bundle-Ether100 -> is 100","no shutdown is a conversion of set true shutdown is a conversion of set false is a conversion of no dampening is a conversion of set false lacp period short is a conversion of set to frinx-openconfig-lacp:FAST no lacp period short is a conversion of set to frinx-openconfig-lacp:SLOW if is not specified then command bundle id mode on is used mode active is a conversion of set to frinx-openconfig-lacp:ACTIVE mode passive is a conversion of set to frinx-openconfig-lacp:PASSIVE ipv6 nd suppress-ra is a conversion of set true","is conversion of"]},{"i":"unit-2","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-623","l":"Cisco IOS XR 6.2.3"},{"i":"cli-3","l":"CLI","p":["is parsed from example is Bundle-Ether100 -> is 100","no shutdown is a conversion of set true shutdown is a conversion of set false no dampening is a conversion of set false lacp period short is a conversion of set to frinx-openconfig-lacp:FAST no lacp period short is a conversion of set to frinx-openconfig-lacp:SLOW if is not specified then command bundle id mode on is used mode active is a conversion of set to frinx-openconfig-lacp:ACTIVE mode passive is a conversion of set to frinx-openconfig-lacp:PASSIVE","is conversion of"]},{"i":"cisco-ios-xr-661","l":"Cisco IOS XR 6.6.1"},{"i":"cli-4","l":"CLI","p":["is parsed from example is Bundle-Ether100 -> is 100","no shutdown is a conversion of set true shutdown is a conversion of set false is a conversion of no dampening is a conversion of set false lacp period short is a conversion of set to frinx-openconfig-lacp:FAST no lacp period short is a conversion of set to frinx-openconfig-lacp:SLOW if is not specified then command bundle id mode on is used mode active is a conversion of set to frinx-openconfig-lacp:ACTIVE mode passive is a conversion of set to frinx-openconfig-lacp:PASSIVE","is conversion of"]},{"i":"unit-3","l":"Unit","p":["Link to github : xr-unit"]},{"i":"junos-141x53-d408","l":"Junos 14.1X53-D40.8"},{"i":"cli-5","l":"CLI","p":["vlan-tagging is a conversion of set TPID_0X8100 delete interfaces disable is a conversion of set true set interfaces disable is conversion of set false","set interfaces unit disable is conversion of set false delete interfaces unit disable is a conversion of set true"]},{"i":"unit-4","l":"Unit","p":["Link to github : junos-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-6","l":"CLI","p":["is parsed from example is ae100 -> is 100","delete interfaces disable is a conversion of set true set interfaces disable is conversion of set false"]},{"i":"unit-5","l":"Unit","p":["Link to github : junos-unit"]},{"i":"junos-182r1-s21","l":"Junos 18.2R1-S2.1"},{"i":"cli-7","l":"CLI","p":["delete interfaces disable is a conversion of set true set interfaces disable is conversion of set false In the case of set interfaces ms-x/x/x, set iana-if-type:other instead of iana-if-type:ethernetCsmacd","delete interfaces unit disable is a conversion of set true set interfaces unit disable is conversion of set false"]},{"i":"unit-6","l":"Unit","p":["Link to github : junos-unit"]},{"i":"brocade-v560ft163","l":"Brocade (V5.6.0fT163)"},{"i":"cli-8","l":"CLI","p":["enable is a conversion of set true disable is a conversion of set false"]},{"i":"unit-7","l":"Unit","p":["Link to github : brocade-unit"]},{"i":"huawei-ne5000e-v800r009c10spc310","l":"Huawei NE5000E (V800R009C10SPC310)"},{"i":"cli-9","l":"CLI","p":["is conversion of \"\" inbound, outbound is a conversions of \"\" trust dscp is a conversion of \"\" set true"]},{"i":"unit-8","l":"Unit","p":["Link to github : huawei-unit"]},{"i":"dasan-nos-sfurr56p5","l":"Dasan NOS SFU.RR.5.6p5"},{"i":"cli-10","l":"CLI","p":["is parsed from example is Ethernet1/1 -> is 1/1","is parsed from example is Bundle-Ether100 -> is 100","* port enable * is a conversion of set true* port disable * is a conversion of set false lacp port timeout short is a conversion of set to frinx-openconfig-lacp:FAST no lacp port timeout short is a conversion of set to frinx-openconfig-lacp:SLOW"]},{"i":"unit-9","l":"Unit","p":["Link to github : dasan-unit"]},{"i":"ciena-saos-614","l":"Ciena SAOS 6.14"},{"i":"cli-11","l":"CLI","p":["* port enable port * is a conversion of set true* port disable port * is a conversion of set false can be \"default\" or \"rj45\" or \"sfp\" vs-ingress-filter on is a conversion of set true vs-ingress-filter off is a conversion of set false can be \"all\", \"tagged-only\", \"untagged-only\" can be \"Default-RCOS\" or \"NNI-NNI\" forward-unlearned on is a conversion of set true forward-unlearned off is a conversion of set false resolved-cos-remark-l2 true is a conversion of set true resolved-cos-remark-l2 false is a conversion of set false","from usual range (max 4094)","can be \"all\" or \"vlan-tpid\"","l2-cft enable port is a conversion of set to true l2-cft disable port is a conversion of set to false","rstp enable port is a conversion of set to true rstp disable port is a conversion of set to false mstp enable port is a conversion of set to true mstp disable port is a conversion of set to false","port set port auto-neg on is a conversion of set to true port set port auto-neg off is a conversion of set to false can be auto, ten, hundred, gigabit, ten-gig"]},{"i":"unit-10","l":"Unit","p":["Link to github : saos-unit"]},{"l":"Ciena SAOS 8"},{"i":"cli-12","l":"CLI","p":["can be between 0 and 96","port set port auto-neg on is a conversion of set to true port set port auto-neg off is a conversion of set to false can be auto, ten, hundred, gigabit, ten-gig, forty-gig, hundred-gig"]},{"i":"unit-11","l":"Unit","p":["Link to github : saos-unit"]},{"i":"arris-cer-arris-e6000","l":"Arris CER (Arris E6000)"},{"i":"cli-13","l":"CLI","p":["no shutdown is a conversion of set true shutdown is a conversion of set false"]},{"i":"unit-12","l":"Unit","p":["Link to github : cer-unit"]}],[{"l":"L2VLAN interface"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"Ciena SAOS8"},{"l":"CLI"},{"l":"Unit","p":["Link to github : saos-unit"]}],[{"l":"L3 VLAN interface"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"dasan-nos-sfurr56p5","l":"Dasan NOS SFU.RR.5.6p5"},{"l":"CLI","p":["is parsed from example is Vlan10 -> is 10","no shutdown is a conversion of set true shutdown is a conversion of set false no ip redirects is a conversion of set false ip redirects is a conversion of set true"]},{"l":"Unit","p":["Link to github : dasan-unit"]}],[{"i":"link-aggregation-group-bundle-interface","l":"Link Aggregation Group (bundle) interface"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"Cisco IOS XE","p":["track shutdown is a conversion of set true no track shutdown is a conversion of set false"]},{"l":"Unit","p":["Link to github : ios-unit"]},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)","p":["is conversion of"]},{"i":"unit-1","l":"Unit","p":["Link to github : ios-unit"]},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI","p":["is parsed from example is Bundle-Ether100 -> is 100","no shutdown is a conversion of set true shutdown is a conversion of set false is conversion of no dampening is a conversion of set false ipv6 nd suppress-ra is a conversion of set true"]},{"i":"unit-2","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-623","l":"Cisco IOS XR 6.2.3"},{"i":"cli-1","l":"CLI","p":["is parsed from example is Bundle-Ether100 -> is 100","no shutdown is a conversion of set true shutdown is a conversion of set false is conversion of no dampening is a conversion of set false ipv6 enable is a conversion of set true no ipv6 enable is a conversion of set false","is conversion of"]},{"i":"unit-3","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-661","l":"Cisco IOS XR 6.6.1"},{"i":"cli-2","l":"CLI","p":["is parsed from example is Bundle-Ether100 -> is 100 is parsed from example is aa:bb:cc:dd:ee:ff -> aabb.ccdd.eeff is parsed from example is aa:bb:cc:dd:ee:ff -> aabb.ccdd.eeff","is conversion of no shutdown is a conversion of set true shutdown is a conversion of set false no dampening is a conversion of set false","is parsed from example is Bundle-Ether100 -> is 100","is conversion of"]},{"i":"unit-4","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-662","l":"Cisco IOS XR 6.6.2"},{"i":"cli-3","l":"CLI","p":["is parsed from example is Bundle-Ether100 -> is 100","no shutdown is a conversion of set true shutdown is a conversion of set false is conversion of ethernet cfm is a conversion of set to true no ethernet cfm is a conversion of set to false"]},{"i":"unit-5","l":"Unit","p":["Link to github : xr-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-4","l":"CLI","p":["is parsed from example is ae100 -> is 100","delete interface ae disable is a conversion of set true set interface ae disable is conversion of set false","Device does not support damping on LAG interface."]},{"i":"unit-6","l":"Unit","p":["Link to github : junos-unit"]},{"i":"junos-182r1-s21","l":"Junos 18.2R1-S2.1"},{"i":"cli-5","l":"CLI","p":["is parsed from example is ae100 -> is 100","delete interface ae disable is a conversion of set true set interface ae disable is conversion of set false","inner_vlan_tag, outer_vlan_tag is a conversion of set . delete interface ae unit disable is a conversion of set true set interface ae unit disable is conversion of set false rpm_ifc_index , rpm_subintf_index is a conversion of set ."]},{"i":"unit-7","l":"Unit","p":["Link to github : junos-unit"]},{"i":"huawei-ne5000e-v800r009c10spc310","l":"Huawei NE5000E (V800R009C10SPC310)"},{"i":"cli-6","l":"CLI","p":["is conversion of"]},{"i":"unit-8","l":"Unit","p":["Link to github : huawei-unit"]},{"i":"dasan-nos-sfurr56p5","l":"Dasan NOS SFU.RR.5.6p5"},{"i":"cli-7","l":"CLI","p":["is parsed from example is Bundle-Ether100 -> is 100 and prefix is Bundle-Ether Dasan supports two kinds of prefixes (Prefix is settled by lag type)","If the prefix of is 'Trunk', lag type is port trunking","If the prefix of is 'Bundle-Ether', lag type is lacp","vlan add br t/ tagged is only supported by port trunking vlan add br t/ untagged is only supported by port trunking"]},{"i":"unit-9","l":"Unit","p":["Link to github : dasan-unit"]},{"l":"Ciena SAOS8"},{"i":"cli-8","l":"CLI","p":["classifier-precedence is used as **. This field is mandatory in Ciena and unique withing parent-port. bin_count can be from \"0\" to \"96\". Default value is \"32\". when ** is set to true, then vlan-untagged-data is used in the the sub-port command. there is not possible to set vlan-untagged-data and vtag-stack both."]},{"i":"unit-10","l":"Unit","p":["Link to github : saos-unit"]},{"l":"Arris CER"},{"i":"cli-9","l":"CLI"},{"i":"unit-11","l":"Unit","p":["Link to github : cer-unit"]}],[{"l":"WIDEBAND interface"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"IOS XE 16"},{"l":"CLI"},{"l":"Unit","p":["Link to github : ios-xe-unit"]}],[{"i":"internet-protocol-security-ipsec","l":"Internet Protocol Security (IPsec)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"nokia-sros-160","l":"NOKIA SROS 16.0"},{"l":"CLI","p":["no shutdown is a conversion of set to true shutdown is a conversion of set to false"]}],[{"l":"NetFlow"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI","p":["Assumption is that monitor map and sampler map configuration already exist on a device."]},{"l":"Unit","p":["Link to github : xr-unit"]}],[{"l":"L2P2P configuration"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"cisco-ios-vios-1562t","l":"Cisco IOS (VIOS 15.6(2)T)"},{"l":"CLI","p":["If connection points remote and local without subif","If connection points remote and local with subif","If both connection points are type local without subif","If both connection points are type local with subif"]},{"l":"Unit","p":["Link to github : ios-unit"]},{"i":"cisco-ios-xr-513-612","l":"CISCO IOS XR (5.1.3) (6.1.2)"},{"i":"cli-1","l":"CLI","p":["If connection point type remote","If connection point type local without subif","If connection point type local with subif (for XRv 5.1.3)","If connection point type local with subif (for XRv 6.1.2)","If both connection points are local we can use the same translation code as above .. the combined output will look like this example:"]},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]},{"i":"brocade-v560ft163","l":"Brocade (V5.6.0fT163)"},{"i":"cli-2","l":"CLI","p":["If connection point type remote","If connection point type local without subif","If both connection points are type local","With subif","If both connection points are type local without subif"]},{"i":"unit-2","l":"Unit","p":["Link to github : brocade-unit"]}],[{"i":"l2vpn-vpls-with-bgp-autodiscovery-configuration","l":"L2VPN (VPLS with BGP autodiscovery) configuration"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"cisco-ios-not-fully-tested-yet--vios-does-not-support-vpls","l":"Cisco IOS (not fully tested yet ... vIOS does not support VPLS)"},{"l":"CLI","p":["If connection point type remote","If connection point type local without subif","If connection point type local with subif"]},{"l":"Unit","p":["NOT IMPLEMENTED"]},{"i":"cisco-ios-xr-513-612","l":"CISCO IOS XR (5.1.3) (6.1.2)"},{"i":"cli-1","l":"CLI","p":["If connection point type remote","If connection point type local without subif","If connection point type local with subif (for XRv 5.1.3)","If connection point type local with subif (for XRv 6.1.2)"]},{"i":"unit-1","l":"Unit","p":["NOT IMPLEMENTED"]}],[{"i":"l2vsi-l2-virtual-switch-instance-virtual-circuit","l":"L2VSI (L2 virtual switch instance virtual circuit)","p":["Interconnects L2VSI with a vlan-based upstream path"]},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"ciena-saos-614","l":"Ciena SAOS 6.14"},{"l":"CLI","p":["statistics on is a conversion of set true statistics off is a conversion of set false"]},{"l":"Unit"}],[{"i":"l2vsi-l2-virtual-switch-instance","l":"L2VSI (L2 virtual switch instance)"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"ciena-saos-614","l":"Ciena SAOS 6.14"},{"l":"CLI","p":["can have values *l2-cft tagged-pvst-l2pt enable vs * is a conversion of \"tagged-pvst-l2pt\" field set to true *l2-cft tagged-pvst-l2pt disable vs * is a conversion of \"tagged-pvst-l2pt\" field set to false"]},{"l":"Ciena SAOS 8"},{"i":"cli-1","l":"CLI","p":["cpu-subinterface command is sent, if the type of the interface added is iana-if-type:l2vlan","sub-port command is sent, if the type of the interface added is iana-if-type:ieee8023adLag","** in this case needs to have form . This can be derived from : https://github.com/FRINXio/translation-units-docs/blob/master/Configuration%20datasets/interfaces/lag_interface.md"]}],[{"i":"l3vpn-configuration-bgp-as-ce-pe-protocol","l":"L3VPN configuration (BGP as CE-PE protocol)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["CONSTRAINTS Network-instance with name must exist before defined-sets or both must be created in the same transaction. Delete must be executed in reverse order or in the same transaction. Policy -route-target-import and -route-target-export must exist on device before are used in network-instance."]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-513-612","l":"CISCO IOS XR (5.1.3) (6.1.2)"},{"l":"CLI"},{"i":"cisco-ios-xr-661","l":"CISCO IOS XR (6.6.1)"},{"i":"cli-1","l":"CLI","p":["summary-only is a conversion of \"frinx-bgp-extension:summary-only\" set true"]},{"i":"cisco-ios-vios-1562t","l":"Cisco IOS (VIOS 15.6(2)T)"},{"i":"cli-2","l":"CLI"},{"i":"junos-182r1-s21","l":"Junos 18.2R1-S2.1"},{"i":"cli-3","l":"CLI"},{"i":"huawei-ne5000e-v800r009c10spc310","l":"Huawei NE5000E (V800R009C10SPC310)"},{"i":"cli-4","l":"CLI","p":["1 to 100000 is conversion of set \"frinx-huawei-network-instance-extension:prefix-limit-from\" 1 to 100 is conversion of set \"frinx-huawei-network-instance-extension:prefix-limit-to\""]},{"l":"Unit","p":["Link to github : huawei-unit"]}],[{"i":"l3vpn-configuration-ospf-as-ce-pe-protocol","l":"L3VPN configuration (OSPF as CE-PE protocol)"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-513-612","l":"CISCO IOS XR (5.1.3) (6.1.2)"},{"l":"CLI"},{"i":"cisco-ios-xr-623","l":"CISCO IOS XR (6.2.3)"},{"i":"cli-1","l":"CLI"},{"i":"cisco-ios-xr-661","l":"CISCO IOS XR (6.6.1)"},{"i":"cli-2","l":"CLI"},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-vios-1562t","l":"Cisco IOS (VIOS 15.6(2)T)"},{"i":"cli-3","l":"CLI"},{"i":"junos-141x53-d408","l":"Junos 14.1X53-D40.8"},{"i":"cli-4","l":"CLI","p":["virtual-router is a conversion of set L3VRF delete routing-instances protocols ospf area interface disable is a conversion of set true set routing-instances protocols ospf area interface disable is a conversion of set false set routing-instances protocols ospf area interface authentication is a conversion of set true delete routing-instances protocols ospf area interface authentication is a conversion of set false"]},{"i":"junos-182r1-s21","l":"Junos 18.2R1-S2.1"},{"i":"cli-5","l":"CLI"}],[{"i":"multiprotocol-label-switching---label-distribution-protocol-mpls-ldp","l":"Multiprotocol Label Switching - Label Distribution Protocol (MPLS LDP)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models","extensions to MPLS YANG model"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI","p":["\"enabled\" MUST be set to true when any ldp-configuration is pushed","\"enabled\" set to false, will ignore any additional configuration in the PUT request and will result in 'no mpls ldp'"]},{"l":"Unit","p":["Link to github : xr-unit"]}],[{"i":"multiprotocol-label-switching---resource-reservation-protocol-mpls-rsvp","l":"Multiprotocol Label Switching - Resource Reservation Protocol (MPLS RSVP)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models","extensions to MPLS YANG model"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4","p":["setting to default results in 'bandwidth' meaning setting default device bandwidth","setting to numeric value results in 'bandwith < number>","transformation: input bandwith in bps, in XR router as Kbps"]},{"l":"CLI"},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10","p":["transformation: k,m,g from JUNOS router translates to thousand, million, billion"]},{"i":"cli-1","l":"CLI"},{"i":"unit-1","l":"Unit","p":["Link to github : junos-unit"]}],[{"i":"multiprotocol-label-switching---traffic-engineering-mpls-te","l":"Multiprotocol Label Switching - Traffic Engineering (MPLS-TE)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models","extensions to MPLS YANG model"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI","p":["\"enabled\" MUST be set to true when any te-configuration is pushed","\"enabled\" set to false, will ignore any additional configuration in the PUT request and will result in 'no mpls traffic-eng'"]},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-1","l":"CLI"},{"i":"unit-1","l":"Unit","p":["Link to github : junos-unit"]}],[{"i":"multiprotocol-label-switching---tunnel","l":"Multiprotocol Label Switching - Tunnel"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models","extensions to MPLS YANG model"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI","p":["autoroute announce is a conversion of set true no autoroute announce is a conversion of set false load-share is not supported on virtual platform CISCO IOS-XR mpls_tunnel_destination is optional parameter metric absolute command is only valid if autoroute announce is set"]},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-1","l":"CLI","p":["* set protocols mpls label-switched-path * is a conversion of set true mpls_tunnel_destination is mandatory parameter"]},{"i":"unit-1","l":"Unit","p":["Link to github : junos-unit"]}],[{"l":"Interface policy configuration"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["policy-forwarding YANG model","extensions to policy-forwarding YANG model"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534-ios-xr-662","l":"Cisco IOS XR 5.3.4, IOS XR 6.6.2"},{"l":"CLI"},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-623","l":"Cisco IOS XR 6.2.3"},{"i":"cli-1","l":"CLI"},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-661","l":"Cisco IOS XR 6.6.1"},{"i":"cli-2","l":"CLI"},{"i":"unit-2","l":"Unit","p":["Link to github : xr-unit"]},{"i":"junos-141x53-d408","l":"Junos 14.1X53-D40.8"},{"i":"cli-3","l":"CLI","p":["pf_intf_index, pf_subintf_index is a conversion of set ."]},{"i":"unit-3","l":"Unit","p":["Link to github : junos-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-4","l":"CLI"},{"i":"unit-4","l":"Unit","p":["Link to github : junos-unit"]}],[{"i":"border-gateway-protocol-bgp","l":"Border Gateway Protocol (BGP)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI","p":["ipv4 unicast is a conversion of set IPV4_UNICAST ipv6 unicast is a conversion of set IPV6_UNICAST remove-private-AS is a conversion of default-originte is a conversion of next-hop-self is a conversion of if value is \"nexthopself\" no shutdown is a conversion of set true shutdown is a conversion of set false ipv4 unicast is a conversion of set IPV4_UNICAST ipv6 unicast is a conversion of set IPV6_UNICAST vpnv4 unicast is a conversion of set L3VPN_IPV4_UNICAST"]},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-661-via-netconf","l":"Cisco IOS XR 6.6.1 (via NetConf)"},{"i":"cli-1","l":"CLI","p":["l2vpn evpn is a conversion of set L2VPN_EVPN remove-private-AS is a conversion of default-originte is a conversion of next-hop-self is a conversion of if value is \"nexthopself\" no shutdown is a conversion of set true shutdown is a conversion of set false l2vpn evpn is a conversion of set L2VPN_EVPN"]},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-661-no-netconf","l":"Cisco IOS XR 6.6.1 (no NetConf)"},{"i":"cli-2","l":"CLI","p":["vpnv4 unicast is a conversion of set L3VPN_IPV4_UNICAST"]},{"i":"unit-2","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-662","l":"Cisco IOS XR 6.6.2"},{"i":"cli-3","l":"CLI","p":["ipv4 unicast is a conversion of set IPV4_UNICAST ipv6 unicast is a conversion of set IPV6_UNICAST remove-private-AS is a conversion of default-originte is a conversion of ipv4 unicast is a conversion of set IPV4_UNICAST ipv6 unicast is a conversion of set IPV6_UNICAST"]},{"i":"unit-3","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xe-031301s","l":"Cisco IOS XE 03.13.01.S","p":["bgp log-neighbor-changes is a conversion of set true no bgp log-neighbor-changes is a conversion of set false default-information originate is a conversion of set true no default-information originate is a conversion of set false neighbor as-override is a conversion of set true neighbor fall-over bfd is a conversion of set true transport connection-mode passive is a conversion of set true route-reflector-client is a conversion of set true remove-private-as is a conversion of set \"frinx-openconfig-bgp-types:PRIVATE_AS_REMOVE_ALL\" no-prepend is a conversion of set true replace-as is a conversion of set true neighbor version 4 is a conversion of set \"frinx-bgp-extension:VERSION_4\" auto-summary is a conversion of set true no auto-summary is a conversion of set false* redistribute connected route-map * is a conversion of set true no redistribute connected is a conversion of set false* redistribute static route-map * is a conversion of set true no redistribute static is a conversion of set false synchronization is a conversion of set true no synchronization is a conversion of set false"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-4","l":"CLI","p":["activate is a conversion of set true deactivate is a conversion of set false"]},{"i":"unit-4","l":"Unit","p":["Link to github : junos-unit"]},{"i":"huawei-ne5000e-v800r009c10spc310","l":"Huawei NE5000E (V800R009C10SPC310)"},{"i":"cli-5","l":"CLI","p":["auto-discovery is conversion of set \"frinx-bgp-extension:transport\" keepalive is conversion of set \"timer_mode\" 0-21845 is conversion of set \"time_before\" 3-65535 is conversion of set \"timer_after\" direct, static is conversions of set \"import_route\""]},{"i":"unit-5","l":"Unit","p":["Link to github : huawei-unit"]}],[{"i":"intermediate-system-to-intermediate-system-is-is","l":"Intermediate System to Intermediate System (IS-IS)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-623","l":"Cisco IOS XR 6.2.3"},{"l":"CLI","p":["point-to-point is a conversion of set POINT_TO_POINT","value frinx-openconfig-isis-types:IPV6 is to be converted to ipv6 value frinx-openconfig-isis-types:UNICAST is to be converted to unicast value LEVEL_1 is to be converted to level-1 value LEVEL_2 is to be converted to level-2 value LEVEL_1_2 is to be converted to level-1-2"]},{"i":"cisco-ios-xr-661cli","l":"Cisco IOS XR 6.6.1(CLI)"},{"i":"cli-1","l":"CLI","p":["value frinx-isis-extension:NOT_SET is to be converted to max-link-metric value frinx-isis-extension:LEVEL_1 is to be converted to max-link-metric level 1 value frinx-isis-extension:LEVEL_2 is to be converted to max-link-metric level 2","value frinx-openconfig-isis-types:IPV6 is to be converted to ipv6 value frinx-openconfig-isis-types:UNICAST is to be converted to unicast","is converted from .","if is LEVEL_1, then is set as level-1","if is LEVEL_2, then is set as level-2","if is LEVEL_1_2, then is set as level-1-2"]}],[{"i":"open-shortest-path-first-ospf","l":"Open Shortest Path First (OSPF)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands","p":["include-stub is a conversion of MAX_METRIC_INCLUDE_STUB in the include list of the max-metric-timer external-lsa is a conversion of MAX_METRIC_INCLUDE_TYPE2_EXTERNAL in the include list of the max-metric-timer summary-lsa is a conversion of MAX_METRIC_SUMMARY_LSA in the include list of the max-metric-timer"]},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI","p":["bfd fast-detect is a conversion of set true bfd fast-detect disable is a conversion of set false mpls ldp sync is a conversion of set true mpls ldp sync disabled is a conversion of set false passive enable is a conversion of set true passive disabled is a conversion of set false","** value MAX_METRIC_ON_SYSTEM_BOOT is to be converted to on-startup** value MAX_METRIC_ON_SWITCHOVER is to be converted to on-switchover"]},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-662","l":"Cisco IOS XR 6.6.2"},{"i":"cli-1","l":"CLI"},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]},{"i":"junos-141x53-d408","l":"Junos 14.1X53-D40.8"},{"i":"cli-2","l":"CLI","p":["delete protocols ospf area interface disable is a conversion of set true set protocols ospf area interface disable is a conversion of set false"]},{"i":"unit-2","l":"Unit","p":["Link to github : junos-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-3","l":"CLI"},{"i":"unit-3","l":"Unit","p":["Link to github : junos-unit"]}],[{"i":"open-shortest-path-first-v3-ospfv3","l":"Open Shortest Path First v3 (OSPFv3)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI","p":["value STUB_ROUTER_MAX_METRIC is to be converted to max-metric value STUB_ROUTER_R_BIT is to be converted to r-bit value STUB_ROUTER_V6_BIT is to be converted to v6-bit"]},{"l":"Unit","p":["Link to github : xr-unit"]}],[{"l":"Static Route"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"IOS 12"},{"l":"CLI","p":["ipv4 unicast is a conversion of set IPV4_UNICAST ipv6 unicast is a conversion of set IPV6_UNICAST is parsed from is parsed from"]},{"l":"Unit","p":["Link to github : ios-unit"]},{"i":"cisco-ios-xr-662","l":"Cisco IOS XR 6.6.2"},{"i":"cli-1","l":"CLI","p":["ipv4 unicast is a conversion of set IPV4_UNICAST ipv6 unicast is a conversion of set IPV6_UNICAST is parsed from is parsed from"]},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]}],[{"l":"VLAN"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI","p":["no shutdown is a conversion of set ACTIVE shutdown is a conversion of set SUSPENDED"]},{"i":"dasan-nos-sfurr56p5","l":"Dasan NOS SFU.RR.5.6p5"},{"i":"cli-1","l":"CLI","p":["if is true","if is false"]},{"l":"Ciena SAOS 614"},{"i":"cli-2","l":"CLI","p":["should be pure numeric, converted from oc-vlan-types:TPID_TYPES from openconfig enable is a conversion of to true disable is a conversion of to false is an enumeration trust-mode - options are client-trusted, server-trusted, dualrole-trusted and untrusted"]}],[{"i":"configure-network-instance-vrf","l":"Configure network instance (VRF)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI"},{"l":"Unit","p":["Link to github : ios-unit"]},{"l":"Configure default network instance"},{"i":"url-1","l":"URL"},{"i":"openconfig-yang-1","l":"OPENCONFIG YANG","p":["YANG models","vlans definition - vlans policy-forwarding definition - policy-forwarding protocols definition - protocols interface-name is a conversion of each interface name for this network-instance cisco-ipv6-config is a conversion of global ipv6 configuration for device and consist of: unicast-routing and cef whose values can only be true or false"]},{"i":"os-commands-1","l":"OS Commands"},{"i":"cisco-ios-classic-1524s5","l":"Cisco IOS Classic (15.2(4)S5)"},{"i":"cli-1","l":"CLI"}],[{"l":"Routing Policy"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"cisco-ios-12-ios-15-ios-xe-15-ios-xe-16-ios-xe-17","l":"Cisco IOS 12, IOS 15, IOS XE 15, IOS XE 16, IOS XE 17","p":["permit is a conversion of set to frinx-cisco-routing-policy-extension:PERMIT deny is a conversion of set to frinx-cisco-routing-policy-extension:DENY","permit is a conversion of set to community-member deny is a conversion of set to frinx-openconfig-bgp-policy-extension:community-member-deny","permit is a conversion of set to frinx-cisco-routing-policy-extension:PERMIT deny is a conversion of set to frinx-cisco-routing-policy-extension:DENY set community (no-export) is a conversion of set to frinx-openconfig-bgp-types:NO_EXPORT set community (no-advertise) is a conversion of set to frinx-openconfig-bgp-types:NO_ADVERTISE* match tag * is a tag element in match clause set to frinx-cisco-routing-policy-extension:tags"]},{"i":"cisco-ios-xr-534-ios-xr-662","l":"Cisco IOS XR 5.3.4, IOS XR 6.6.2"},{"l":"CLI","p":["is parsed from .","If is \"exact\", then is not set.","If matches to pattern of .., then is set as \"le ge \".","* destination in * is a conversion of set to ANY* not destination in * is a conversion of set to INVERT","as-path length le is a conversion of set to frinx-openconfig-policy-types:ATTRIBUTE_LE as-path length ge is a conversion of set to frinx-openconfig-policy-types:ATTRIBUTE_GE as-path length eq is a conversion of set to frinx-openconfig-policy-types:ATTRIBUTE_EQ","community match-any is a conversion of set to ANY community match-every is a conversion of set to ALL","drop is a conversion of set to REJECT_ROUTE done is a conversion of set to ACCEPT_ROUTE pass is a conversion of set to PASS_ROUTE","set community (no-export) is a conversion of set to frinx-openconfig-bgp-types:NO_EXPORT set community (no-advertise) is a conversion of set to frinx-openconfig-bgp-types:NO_ADVERTISE set community (local-as) is a conversion of set to frinx-openconfig-bgp-types:NO_EXPORT_SUBCONFED","* as-path in * is a conversion of set to ANY* not as-path in * is a conversion of set to INVERT"]},{"l":"Examples"},{"i":"junos-141x53-d408","l":"Junos 14.1X53-D40.8"},{"i":"cli-1","l":"CLI"},{"i":"examples-1","l":"Examples"}],[{"i":"aaa---authentication-authorization-accounting","l":"AAA - Authentication Authorization Accounting"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"huawei-ne5000e-v800r009c10spc310","l":"Huawei NE5000E (V800R009C10SPC310)"},{"l":"CLI","p":["local, radius is conversions of set to \"authentication-method\" local, radius is conversions of set to \"accounting-method\" start-fail is conversion of set to \"fail-policy\" online is conversion of set to \"fail-policy-mode\" telnet, terminal, ssh, ftp is conversions of set to \"frinx-huawei-aaa-extension:service-type\" 1-15 is conversion of set to \"frinx-huawei-aaa-extension:privilege-level\""]},{"l":"Unit","p":["Link to GitHub : huawei-unit"]},{"l":"SAOS 6"},{"i":"cli-1","l":"CLI","p":["limited, admin, super, diag is conversion of set to \"frinx-ciena-aaa-extension:access-level\""]},{"i":"unit-1","l":"Unit","p":["Link to GitHub : saos6-unit"]}],[{"i":"broadcast-containment-broadcast-containment-filters","l":"Broadcast-Containment (Broadcast-containment filters)"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"ciena-saos-614","l":"Ciena SAOS 6.14"},{"l":"CLI","p":["enable is conversion of set true disable is conversion of set false"]},{"l":"Unit"}],[{"l":"Configure CDP interfaces"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI","p":["cdp enable is conversion of \"enabled\": true no cdp enable is conversion of \"enabled\": false"]},{"l":"Unit","p":["Link to github : ios-unit"]},{"i":"cisco-ios-xr-xrv-513-and-xrv-612-tested","l":"Cisco IOS XR (XRv 5.1.3 and XRv 6.1.2 tested)"},{"i":"cli-1","l":"CLI","p":["cdp is conversion of \"enabled\": true no cdp is conversion of \"enabled\": false"]},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]},{"i":"brocade-v560ft163","l":"Brocade (V5.6.0fT163)"},{"i":"cli-2","l":"CLI","p":["cdp enable is conversion of \"enabled\": true no cdp enable is conversion of \"enabled\": false"]},{"i":"unit-2","l":"Unit","p":["Link to github : brocade-unit"]}],[{"l":"Configure FDP interfaces"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"i":"brocade-v560ft163","l":"Brocade (V5.6.0fT163)"},{"l":"CLI","p":["fdp enable is conversion of \"enabled\": true no fdp enable is conversion of \"enabled\": false"]},{"l":"Unit","p":["NOT IMPLEMENTED"]}],[{"l":"Configure STP interfaces"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Commands"},{"i":"brocade-v560ft163","l":"Brocade (V5.6.0fT163)"},{"l":"CLI","p":["If /stp/interfaces/interface/ exists","If /interfaces/interface/ exists and /stp/interfaces/interface/ does not exist"]},{"l":"Unit","p":["NOT IMPLEMENTED"]}],[{"i":"ethernet-oam--ethernet-cfm","l":"Ethernet OAM / Ethernet CFM"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-662","l":"Cisco IOS XR 6.6.2"},{"l":"CLI","p":["ethernet cfm is a conversion of set to true no ethernet cfm is a conversion of set to false efd is a conversion of set to true no efd is a conversion of set to false"]},{"l":"Unit","p":["Link to github : xr-unit"]}],[{"i":"ethernet-virtual-circuit-evc","l":"Ethernet Virtual Circuit (EVC)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xe-16","l":"Cisco IOS XE 16.*"},{"l":"CLI","p":["* ethernet evc * is creating evc configuration with name* no ethernet evc * is deleting evc configuration with name"]},{"l":"Unit","p":["Link to github : ios-xe-evc-unit"]}],[{"i":"ethernet-virtual-private-network-evpn","l":"Ethernet Virtual Private Network (EVPN)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-661-via-netconf","l":"Cisco IOS XR 6.6.1 (via NetConf)"},{"l":"CLI","p":["evpn is a conversion of set to true no evpn is a conversion of set to false is parsed from example is Bundle-Ether100 -> is 100 is parsed from Bundle-Ether is a conversion of set to \"iana-if-type:ieee8023adLag\" mode port-active is a conversion of set to \"frinx-es-lb-mode:PORT-ACTIVE\" mode single-active is a conversion of set to \"frinx-es-lb-mode:SINGLE-ACTIVE\""]},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-661-no-netconf","l":"Cisco IOS XR 6.6.1 (no NetConf)"},{"i":"cli-1","l":"CLI","p":["evpn is a conversion of set true no evpn is a conversion of set false cost-out is a conversion of set true no cost-out is a conversion of set false or null"]},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]}],[{"i":"hot-standby-router-protocol-hsrp","l":"Hot Standby Router Protocol (HSRP)"},{"l":"URL"},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI"},{"l":"Unit","p":["Link to github : xr-unit"]}],[{"i":"l2-cft-layer-2-control-frame-forwarding","l":"L2-Cft (Layer 2 Control Frame Forwarding)"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"ciena-saos-614","l":"Ciena SAOS 6.14"},{"l":"CLI","p":["can be can be <802.1x | all-bridges-block | cisco-cdp | cisco-dtp | cisco-pagp | cisco-pvst | cisco-stp-uplink-fast | cisco-udld | cisco-vtp | elmi | esmc | garp-block | gmrp | gvrp | lacp | lacp-marker | lldp | oam | ptp-peer-delay | vlan-bridge | xstp> if == mef-ce1 -> can be also bridge-block if == mef-ce2 -> can be also can be "]},{"l":"Unit"}],[{"i":"logging-syslog","l":"Logging (syslog)"},{"l":"URL"},{"l":"OS Configuration Commands"},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"l":"CLI"},{"l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-623","l":"Cisco IOS XR 6.2.3"},{"i":"cli-1","l":"CLI"},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]},{"i":"cisco-ios-xr-661","l":"Cisco IOS XR 6.6.1"},{"i":"cli-2","l":"CLI"},{"i":"unit-2","l":"Unit","p":["Link to github : xr-unit"]}],[{"l":"Privilege"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"cisco-ios-12-15-16--ios-xe-15-16-17","l":"Cisco IOS 12, 15, 16 / IOS XE 15, 16, 17"},{"l":"CLI"},{"l":"Unit","p":["Link to github : ios-privilege-unit"]}],[{"l":"Probes"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"i":"junos-182r1-s21","l":"Junos 18.2R1-S2.1"},{"l":"CLI","p":["set services rpm probe delegate-probes is a conversion of < delegate-probes> set true set services rpm probe test target address is a conversion of < target-type> set address"]},{"l":"Unit","p":["Link to github : junos-unit"]}],[{"l":"Quality of Service"},{"l":"URL"},{"l":"OPENCONFIG YANG"},{"i":"url-1","l":"URL"},{"i":"openconfig-yang-1","l":"OPENCONFIG YANG"},{"i":"url-2","l":"URL"},{"i":"openconfig-yang-2","l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"cisco-ios-12-15-16--ios-xe-15-16-17","l":"Cisco IOS 12, 15, 16 / IOS XE 15, 16, 17"},{"l":"CLI"},{"l":"Usage","p":["A term marks one or more conditions depending on the class-map type.","When class-map type: match-all, there is just one term, that MUST be called 'all'.","When class-map type: match-any, the terms are numbered from 1 ... number_of_conditions. In this case, the {{term_id}} marks the line, where the conditions specified in conditions is written."]},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"i":"cli-1","l":"CLI"},{"i":"usage-1","l":"Usage","p":["A term marks one or more conditions depending on the class-map type.","When class-map type: match-all, there is just one term, that MUST be called 'all'.","When class-map type: match-any, the terms are numbered from 1 ... number_of_conditions. In this case, the {{term_id}} marks the line, where the conditions specified in conditions is written.","Example:","will create 5 terms numbered from 1 to 5, where term 1 contains condition for qos-group, term 2 contains condition for mpls, etc.","Writing will occur in ascending order. Reading is the same, first condition is put into first term, etc."]},{"i":"huawei-ne5000e-v800r009c10spc310","l":"Huawei NE5000E (V800R009C10SPC310)"},{"i":"cli-2","l":"CLI"},{"l":"Unit","p":["Link to github : huawei-unit"]},{"i":"ciena-saos-614","l":"Ciena SAOS 6.14"},{"i":"cli-3","l":"CLI","p":["traffic-profiling enable is a conversion of {{qos_enabled}} set to true traffic-profiling disable is a conversion of {{qos_enabled}} set to false","{{scheduler_type}} can be port_policy- this issues traffic-profiling commands. The {{scheduler_seq}} will be always 0, there can be just one scheduler of this type.{{scheduler_type}} can be queue_group_policy- this issues traffic-services command. The {{scheduler_seq}} is represented by queue number."]}],[{"l":"Relay Agent"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"SAOS 6"},{"l":"CLI","p":["true or false is conversion of set to \"enable\" rid-string, device-hostname, device-mac is conversion of set to \"remote_id_type\" true or false is conversion of set to \"replace-option82\""]},{"l":"Unit","p":["Link to GitHub : saos6-unit"]},{"l":"SAOS 8"},{"i":"cli-1","l":"CLI","p":["true or false is conversion of set to \"enable\" rid-string, device-hostname, device-mac is conversion of set to \"remote_id_type\" true or false is conversion of set to \"replace-option82\""]},{"i":"unit-1","l":"Unit","p":["Link to GitHub : saos8-unit"]}],[{"i":"simple-network-management-protocol-snmp","l":"Simple Network Management Protocol (SNMP)"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"i":"url-1","l":"URL"},{"i":"openconfig-yang-1","l":"OPENCONFIG YANG"},{"i":"url-2","l":"URL"},{"i":"openconfig-yang-2","l":"OPENCONFIG YANG"},{"l":"OS Configuration Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI"},{"l":"Unit","p":["Link to github : ios-unit"]},{"i":"cisco-ios-xr-534","l":"Cisco IOS XR 5.3.4"},{"i":"cli-1","l":"CLI","p":["By default enabled on all interfaces. To disable, use:","To enable disabled interfaces use:","enabled:true is a conversion of snmp set enabled","enabled:false is a conversion of snmp set disabled"]},{"i":"unit-1","l":"Unit","p":["Link to github : xr-unit"]},{"i":"junos-173r110","l":"Junos 17.3R1.10"},{"i":"cli-2","l":"CLI"},{"i":"unit-2","l":"Unit","p":["Link to github : junos-unit"]}],[{"l":"System-wide services and functions"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"IOS XE ASR920"},{"l":"CLI"},{"l":"Unit","p":["Link to github : [ios-xe-unit]"]}],[{"i":"#","p":["Network Instances","Protocols","BGP summary","BGP RIB","OSPF summary","Discovery protocols","CDP","LLDP"]},{"l":"Network Instances"},{"l":"Protocols"},{"l":"BGP summary"},{"l":"BGP RIB"},{"l":"OSPF summary"},{"l":"Discovery protocols"},{"l":"CDP"},{"l":"LLDP"}],[{"i":"bgp-global--neighbors","l":"BGP global + neighbors"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI"},{"l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : ios-unit"]},{"i":"cisco-xr-612","l":"Cisco XR 6.1.2"},{"l":"Netconf"},{"l":"Device YANG","p":["Link to github : xml-sample"]},{"i":"unit-1","l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : xr-unit"]}],[{"l":"BGP RIB"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI","p":["'*' (valid route) translates to \"valid-route\" : true'i' (internal) translates to \"origin\": \"i\""]},{"l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : ios-unit"]}],[{"i":"show-router-ospf-type-id-interfaces","l":"Show router ospf type, ID, interfaces"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI","p":["Supporting command to determine OPSF - VRF relationships:","Supporting command to show interfaces"]},{"l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : ios-unit"]},{"i":"cisco-xr-612","l":"Cisco XR 6.1.2"},{"l":"Netconf"},{"l":"Device YANG","p":["Link to github : xml-sample"]},{"i":"unit-1","l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : xr-unit"]}],[{"l":"Interfaces"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"CER Arris devices"},{"l":"CLI"},{"l":"Unit","p":["Link to GitHub : cer-unit"]}],[{"l":"Platform"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"Cisco IOS Classic"},{"l":"CLI"},{"l":"Unit","p":["Link to GitHub : ios-unit"]},{"i":"cisco-ios-xe-15-16-17","l":"Cisco IOS XE 15, 16, 17"},{"i":"cli-1","l":"CLI"},{"i":"unit-1","l":"Unit","p":["Link to GitHub : ios-xe-unit"]},{"l":"Ciena SAOS 6"},{"i":"cli-2","l":"CLI"},{"i":"unit-2","l":"Unit","p":["Link to GitHub : saos6-unit"]},{"l":"Ciena SAOS 8"},{"i":"cli-3","l":"CLI"},{"i":"unit-3","l":"Unit","p":["Link to GitHub : saos8-unit"]},{"l":"CER Arris devices"},{"i":"cli-4","l":"CLI"},{"i":"unit-4","l":"Unit","p":["Link to GitHub : cer-unit"]}],[{"l":"Show CDP interfaces and neighbors"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI"},{"l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : ios-unit"]},{"i":"cisco-xr-612","l":"Cisco XR 6.1.2"},{"l":"Netconf"},{"l":"Device YANG","p":["Link to github : xml-sample"]},{"i":"unit-1","l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : xr-unit"]}],[{"l":"Show LLDP interfaces and neighbors"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Commands"},{"i":"cisco-ios-classic-1524s5--xe-1533s2","l":"Cisco IOS Classic (15.2(4)S5) / XE (15.3(3)S2)"},{"l":"CLI"},{"l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : ios-unit"]},{"i":"cisco-xr-612","l":"Cisco XR 6.1.2"},{"l":"Netconf"},{"l":"Device YANG","p":["Link to github : xml-sample"]},{"i":"unit-1","l":"Unit","p":["Unit version range: 3.1.1.rc1-frinx","Link to github : xr-unit"]}],[{"l":"System"},{"l":"URL"},{"l":"OPENCONFIG YANG","p":["YANG models"]},{"l":"OS Configuration Commands"},{"l":"Ciena SAOS 6"},{"l":"CLI"},{"l":"Unit","p":["Link to GitHub : saos6-unit"]},{"l":"Ciena SAOS 8"},{"i":"cli-1","l":"CLI"},{"i":"unit-1","l":"Unit","p":["Link to GitHub : saos8-unit"]}],[{"l":"Table of Contents","p":["=================","Base Handlers","Base readers","Base writers","Best practices for handlers (readers/writers)","Chunk templates","CLI Init Translation Unit","CLI Translation Unit","Device registration","Documentation","Finding mapping between device and the model","Handlers","Mandatory interfaces to implement","Module structure","NETCONF Unified Translation Unit","OpenConfig to device config mapping","Plaintext parsing hints","Readers","TranslateUnit","Translation Framework","Translation units for different device versions","Translation Units in general","Util classes","Writers"]},{"l":"Translation Framework","p":["The translation framework allows translation units to:","Add YANG model into the system","Register Handlers for all or a subset of nodes defined in the YANG model","Register the entire unit into the system, which is then able to perform"]},{"l":"OpenConfig to device config mapping"},{"l":"Finding mapping between device and the model","p":["Preferred YANG models for device config and operational data are OpenConfig models.","These models usually represents configuration part in container config and operational part in container state. Operational data is config data + operational data.","This site http://ops.openconfig.net/branches/master/ may be used for better browsing in OpenConfig YANG models. Another option is to generate YANG tree representation by using generate_html.sh in https://github.com/FRINXio/openconfig.","YANG models used in UniConfig framework need to be located in https://github.com/FRINXio/openconfig. In case the desired functionality is not modeled yet, you can create new YANG with its own structure or it can augment existing OpenConfig models. Guideline, how to write OpenConfig models can be found at http://www.openconfig.net/docs/style-guide/."]},{"l":"Documentation","p":["There is translation-units-docs page as a single point of truth for mapping. Use __ notation for variables in the templates. This notation is postman compatible."]},{"l":"Translation Units in general"},{"l":"Module structure","p":["Translation unit is a self contained project which implements a mapping between OpenConfig based YANG models and device specific configuration. It is used by the FRINX ODL to perform translation between device specific configuration model and standard (OpenConfig) models. A unit usually consists of:","Handlers","Readers","Writers","TranslateUnit implementation","RPCs"]},{"l":"Handlers","p":["Each complex node in YANG (container, list, augment...) should have a dedicated handler (Reader, Writer)","This enables extensibility, readability and the framework can easily filter and process the data this way","Unless there is a need to also handle child nodes, in which case register the handler using subtreeAdd method from the registries","There are 2 types of handlers: Readers (Read operation) and Writers (Create, Update, Delete operation)","One can implement just the readers or both readers and writers for YANG models. Writers must have counterpart readers because of reconciliation.","Readers and Writers should use the InstanceIdentifier parameter they receive in readCurrentAttributes or writeCurrentAttributes methods to find information about keys for their parent nodes. E.g. Reader registered under ID: /interfaces/interface/config will always receive keyed version of that ID: /interface/interface[Loopback0]/config. So it can use method firstKeyOf on InstanceIdentifier to get the keys.","RWUtils class contains methods for InstanceIdentifier manipulation.","Readers and writers can be easily tested and it is necessary to provide unit tests for all of them. It's important to cover readCurrentAttributes and writeCurrentAttributes with all possible scenarios (all data there, no data there, partial data there...)","Writers may use Preconditions.checkArgument() before accessing the device. Fail of the precondition check does not invoke default rollback (opposite operation) on the writer where precondition is located."]},{"l":"Base Handlers","p":["When a handler for the same YANG node is implemented to conform various devices, it tends to lead to a lot of boilerplate and duplicate code. Therefore, we should implement a base handler for such handlers. How does it work:","create a base-project (if there isn't any) to group base handlers (eg. for an interface handler, choose interface-base project)","each base handler needs to be abstract and implement same interfaces as the original handler","extract common functionality in the base handler. Common functionality means that it will conform the majority of the original handlers. If a handler does not share the extracted functionality, it needs to override original interface methods, to hide the extracted functionality.","let original handlers extend base abstract handler"]},{"l":"CLI Translation Unit","p":["CLI Translation units are located in https://github.com/FRINXio/cli-units repository. JAVA is used in CLI translation units."]},{"l":"Readers","p":["Readers are handlers responsible for reading and parsing the data coming from a device","There are 2 types of readers: Reader and ListReader. Reader can be used to handle container or augmentation nodes and ListReader should handle list nodes from YANG.","Both types need to implement readCurrentAttributes to fill the builder with appropriate values","ListReader needs to also implement getAllIds() where it retrieves a key for each item to be present in current list. After the list is received, framework will invoke readCurrentAttributes for each item from getAllIds","Readers should always use overloaded blockingRead method which takes in the ReadContext since that method performs caching internally","Use full version of commands e.g. show running-config interface instead of sh run int"]},{"l":"Mandatory interfaces to implement","p":["Each reader needs to implement one of these interfaces based on type of target node in YANG. These interfaces also contain util methods which may be used for better manipulation with data. For more information about methods please read javadocs.","CliConfigListReader- implement this interface if target composite node in YANG is list and represents config data.","CliConfigReader- implement this interface if target composite node in YANG is container or augmentation and represents config data.","CliOperListReader- implement this interface if target composite node in YANG is list and represents operational data.","CliOperReader- implement this interface if target composite node in YANG is container or augmentation and represents operational data.","In cases where you want to invoke multiple readers on reading one YANG node, extend following abstract classes:","CompositeListReader- extend this abstract class if multiple list readers need to be invoked when reading specific list in YANG.","CompositeReader- extend this abstract class if multiple readers need to be invoked when reading specific node in YANG.","A practical example of their usage is reading network instance based on it's type. All child readers need to implement a check when the particular reader should be invoked or the parent reader should move on to the next reader.","For example child reader for bgp (located under protocol) needs to check if identifier in protocol has value BGP. Otherwise reader for bgp will be invoked even if protocol identifier is OSPF."]},{"l":"Util classes","p":["ParsingUtils- use methods of this util class if you want to parse plaintext to java object builder"]},{"l":"Plaintext parsing hints","p":["Use as specific regular expressions when parsing CLI output as possible","For Cisco CLI devices avoid using section and other advanced formatting parameters. Only | include | exclude and | begin are allowed.","Use CONFIG data as the source of truth when parsing information from device. Except when parsing state containers (or containers explicitly marked as config false).","I.e. use sh run| include router ospf instead of sh ospf when retrieving ospf routers list.","In some cases, it is not possible to just use config data e.g. sh run interface does not show any data for interfaces that have no configuration. In this case it is necessary to use operational information from e.g. sh ip int brief","Use following pattern when parsing multiline output from CLI, where it is difficult to extract lines and their relationships","I.e. when parsing configured BGP neighbors per address family following command can be used: ** sh run | include router bgp| address-family|^ neighbor which results in:","This output can then be parsed by:","Remove newlines to get a single line of string","Replace \"router\" with \"\\nrouter\" to separate bgp routers per line","Find the line that matches required router bgp","Take that line and replace \"address-family\" with \"\\naddress-family\" to get address-family neighbors per line"]},{"l":"Base Readers","p":["Each base reader should contain abstract methods:","String getReadCommand()- each child reader should fill in the read command used to get information needed for this reader. Arguments may vary and they are used to be more specific in the read command (eg. when creating a command to gather information about a specific interface, you may want to pass interface name as argument).","Pattern getLine(\\args>)- there may be more such methods and they are used to get the regular expression needed to parse output of the command (eg. in case of interface reader, you will create methods getDescriptionLine, getShutdownLine etc.)","Note: naming of the methods should be unified in order to be easily parsed by auto-generated documentation."]},{"l":"Writers","p":["A writer needs to implement all 3 methods: Write, Update, Delete in order to fully support default rollback mechanism of the framework","Time showed that update like 1. delete, 2. write is anti-pattern and should not be used. There is just one case where it is necessary: when re-writing list entry, you must first delete the previous entry, then write the new one, otherwise the previous entry would still be present and the new entry will be added to the list.","A writer can properly work only if there is a reader for the same composite node","A writer should check whether the command it executed was handled by the device properly (by checking the output) and if not throw one of the Write/Update/Delete FailedException","Chunk templating framework is preferred to use in writers it gives us:","Null safety","if/loop etc. inside templates","Default values and many more","Use full version of commands e.g. configure terminal instead of conf t"]},{"i":"mandatory-interfaces-to-implement-1","l":"Mandatory interfaces to implement","p":["Each writer needs to implement one of these interfaces based on type of target node in YANG. Unlike mandatory interfaces for reading, only interfaces for writing config data are available (because it is not possible to write operational data). These interfaces also contain util methods which may be used for better manipulation with data. For more information about methods please read javadocs.","All writers override updateCurrentAttributes method and avoid delete/write combination, unless specified in a comment.","CliListWriter- implement this interface if target composite node in YANG is list. An implementation needs to be registered as GenericListWriter.","CliWriter- implement this interface if target composite node in YANG is container or augmentation. An implementation needs to be registered as GenericWriter.","CompositeWriter- extend this abstract class when multiple writers need to be invoked on one YANG node. The writers need to implement a check whether or not should they be invoked."]},{"l":"Base Writers","p":["Each base writer should contain abstract methods:","String updateTemplate(Config before, Config after)- this method returns Chunk template used for writing and updating data on the device.","String deleteTemplate(Config data)- this method returns Chunk template used for deleting data from device.","Note: if updating data is done differently than writing new data, method String writeTemplate(Config data) might be used as well."]},{"l":"Chunk Templates","p":["Each original writer transformed to use a base writer should have all it's templates written in Chunk. We extended Chunk to achieve easier manipulation with data. There is now a new filter called update. It's usage is following:","\"{$data|update(mtu,mtu `$data.mtu`\\n,no mtu\\n)}\"","$data represents the data structure on which we check if it was updated from the previous state.","mtu first argument represents the name of the field that should be checked within the $data","mtu `$data.mtu`\\n second argument represents the actual string that will be sent to the device if the value of the field named in first argument was changed or didn't exist before","no mtu\\n third argument represents the actual string that will be sent to the device if the value of the field named in first argument was deleted","optional true fourth argument, if present, lets the filter know it should send both outputs to the device, first the delete string (third argument) then the update string (second argument)","Update filter does not send any of the strings to the device, if the value did not change.","When using this filter in updateTemplate method, you must use fT() method (format template) with one pair of the arguments being \"before\", before to let the template know what data represents the previous state.","Note: unfortunately, Opendaylight generates boolean fields instead of Boolean and Chunk does not work with boolean fields in the same way as any other object fields. Therefore for boolean values (eg. shutdown), you cannot use update filter and checking for changes needs to be done in a traditional way."]},{"l":"TranslateUnit","p":["Blueprint example of injecting TranslationUnitCollector to IosXRInterfaceUnit:","Handlers(readers/writers) need to be registered in this method. Parameter context.getTransport() returns Cli object containing methods for communication with a device via CLI - should be passed to readers/writers.","Implementation of TranslateUnit must be registered into TranslationUnitCollector and must specify device type and device version during registration. Snippet below shows registration of IosXRInterfaceUnit for device type \"ios xr\" all versions starting with \"5\".","Implementation of TranslateUnit must implement these methods:","Instance-identifier in generic reader/writer must be without keys pointing to the target composite node used in implemented reader/writer.","Instance-identifiers for YANG container and list (not for augmentations and nodes behind augmentations) are automatically generated to IIDs class (used in examples bellow) during build of openconfig project.","Ordering of writers- writers are stored in a linear structure and are invoked in order of registration. When registering a writer a relationship with another writer or set of writers can be expressed using addBefore, addAfter, subtreeAddBefore, subtreeAddAfter methods. E.g. InterfaceWriter and VRFInterfaceWriter should have a relationship: InterfaceWriter -> VRFInterfaceWriter so that first an interface is created and only then assigned to VRF. Note: VRF writer should be between them. If the order is not expressed during registration, commands might be executed on device in an unpredictable/invalid order.","Return RPC services implemented in the translation unit. Parameter context.getTransport() returns Cli object containing methods for communication with a device via CLI - may need to be passed to RPC implementations.","Return unique string among all translation units which will be used as ID for the translation unit (e.g. \"IOS XR Interface (Openconfig) translate unit\")","Return YANG models containing composite nodes handled by handlers(readers/writers). Default implementation returns empty Set if no handlers are implemented.","rRegistry.add","rRegistry.addNoop","rRegistry.subtreeAdd","Set getYangSchemas()","Set getRpcs(@Nonnull Context context)","String toString()","This method should also register for general Openconfig checks:","Translate unit class must implement interface TranslateUnit. Naming convention for translate unit class is device-type+openconfig-domain+Unit (e.g. IosXrInterfaceUnit). Translate unit class is usually instantiated, initialized and closed from Blueprint.","Use for writers handling data of whole composite node subtrees. This ensures that if only a child node is updated, the writer gets triggered. Method subtreeAdd requires a set of IIDs for all handled children, the IIDs must start from the reader itself, not from root.","Use to register noop writers","Use when a reader implementation also fills composite child nodes of target composite node. Method subtreeAdd requires a set of IIDs for all handled children, the IIDs must start from the reader itself, not from root.","Use when common GenericConfigListReader, GenericConfigReader, GenericOperListReader or GenericOperReader need to be registered.","Use when common GenericListWriter or GenericWriter are registered.","void provideHandlers(@Nonnull ModifiableReaderRegistryBuilder rRegistry, @Nonnull ModifiableWriterRegistryBuilder wRegistry, @Nonnull Context context)","wRegistry.add","wRegistry.subtreeAdd"]},{"l":"CLI Init Translation Unit","p":["Init translation unit does not contain readers and writers but it only contains implementation of TranslateUnit. There should be only one init translation unit per device type. Purpose of the init TU is to setup CLI prompt and define rollback strategy.","The implementation of TranslateUnit needs to override methods:","SessionInitializationStrategy getInitializer(@Nonnull final RemoteDeviceId id, @Nonnull final CliNode cliNodeConfiguration)","Implement and return device specific SessionInitializationStrategy where:","Setup device CLI terminal with attributes like width and length allowing to display infinite output.","Enter desired CLI mode which will be used as default - every reader and writer gets CLI prompt in this state (e.g. EXEC mode for IOS, config mode for IOS-XR, cli mode for Junos)","String toString()","Return unique string among all translation units which will be used as ID for the registration of the translation unit (e.g. \"Junos cli init (FRINX) translate unit\").","These methods may be overridden if necessary:","getPreCommitHook()- method that is invoked before actual commit is written into device. For example this method can enter configuration mode.","getCommitHook()- method that invokes actual commit and should catch any error on commit. Also it should handle any post-commit actions when the commit was successful.","getPostFailedHook()- method that is invoked when commit fails. Should implement aborts or revert strategies.","Methods like getYangSchemas, getRpcs should return empty sets and method provideHandlers should return nothing, just use the read registry and write registry to register handlers.."]},{"l":"NETCONF Unified Translation Unit","p":["Unified translation units are located in https://github.com/FRINXio/unitopo-units repository.","Kotlin is used as prefered programming language in NETCONF translation units because it provides type aliases and better null-safety."]},{"i":"readers-1","l":"Readers","p":["Readers are handlers responsible for reading and parsing the data coming from a device","There are 2 types of readers: Reader and ListReader. Reader can be used to handle container or argument nodes and ListReader should handle list nodes from YANG.","Both types need to implement readCurrentAttributes to fill the builder with appropriate values","ListReader needs to also implement getAllIds() where it retrieves a key for each item to be present in current list. After the list is received, framework will invoke readCurrentAttributes for each item from getAllIds"]},{"i":"mandatory-interfaces-to-implement-2","l":"Mandatory interfaces to implement","p":["Each reader needs to implement one of these interfaces based on type of target node in YANG.For more information about methods please read javadocs.","ConfigListReaderCustomizer- implement this interface if target composite node in YANG is list and represents config data.","ConfigReaderCustomizer- implement this interface if target composite node in YANG is container or augmentation and represents config data.","OperListReaderCustomizer- implement this interface if target composite node in YANG is list and represents operational data.","OperReaderCustomizer- implement this interface if target composite node in YANG is container or augmentation and represents operational data."]},{"i":"base-readers-1","l":"Base Readers","p":["Each base reader for netconf readers should be generic. The generic marks the data element within device YANG that is being parsed into. The base reader should contain abstract methods:","fun readIid(): InstanceIdentifier- each child reader should fill in the device specific InstanceIdentifier that points to the information needed for this reader. Arguments may vary and they are used to be more specific IID (eg. when creating an IID to gather information about a specific interface, you may want to pass interface name as argument).","fun readData(data: T?, configBuilder: ConfigBuilder, )- this method is used to transform Openconfig data (contained in ConfigBuilder) into device data (T) using .","Note: naming of the methods should be unified in order to be easily parsed by auto-generated documentation."]},{"i":"writers-1","l":"Writers","p":["A writer needs to implement all 3 methods: Write, Update, Delete in order to fully support default rollback mechanism of the framework","Time showed that update like 1. delete, 2. write is anti-pattern and should not be used. There is just one case where it is necessary: when re-writing list entry, you must first delete the previous entry, then write the new one, otherwise the previous entry would still be present and the new entry will be added to the list.","A writer can properly work only if there is a reader for the same composite node","The framework provides safe methods to use when handling data on device:","safePut deletes or adds managed data. Does not touch data that was previously on the device and is not handled by the writer.","safeMerge stores just the changed data into device. Does not touch data that was previously on the device and is not handled by the writer.","safeDelete removes data from the device only if the managed node does not contain any other information (even one not handled by the writer).","This test demonstrates the usage of safe methods."]},{"i":"mandatory-interfaces-to-implement-3","l":"Mandatory interfaces to implement","p":["Each writer needs to implement one of these interfaces based on type of target node in YANG. Unlike mandatory interfaces for reading, only interfaces for writing config data are available (because it is not possible to write operational data). For more information about methods please read javadocs.","ListWriterCustomizer- implement this interface if target composite node in YANG is list. An implementation needs to be registered as GenericListWriter.","WriterCustomizer- implement this interface if target composite node in YANG is container or augmentation. An implementation needs to be registered as GenericWriter."]},{"i":"base-writers-1","l":"Base Writers","p":["Each base writer should be generic and contain abstract methods:","fun getIid(id: InstanceIdentifier): InstanceIdentifier- this method returns InstanceIdentifier that points to a node where data should be written","fun getData(data: Config): T- this method transforms Openconfig data into device specific data (T)"]},{"i":"translateunit-1","l":"TranslateUnit","p":["Translate unit class must implement interface TranslateUnit. Naming convention for translate unit class is just name Unit. Translate unit class is usually instantiated, initialized and closed from Blueprint.","Implementation of TranslateUnit must be registered into TranslationUnitCollector and must provide set of supported underlay YANG models. Snippet below shows registration of Unit for junos device version 17.3.","Blueprint example of injecting TranslationUnitCollector to Juniper173InterfaceUnit:","Implementation of TranslateUnit must implement these methods:","toString(): String","Return unique string among all translation units which will be used as ID for the translation unit (e.g. \"IOS XR Interface (Openconfig) translate unit\")","getYangSchemas(): Set","Return YANG models containing composite nodes handled by handlers(readers/writers). It must return empty Set if no handlers are implemented.","getUnderlayYangSchemas(): Set","Return YANG module informations about underlay models used in the translation unit. These YANG modules describes configuration of NETCONF capable device.","getRpcs(underlayAccess: UnderlayAccess): Set>","Return RPC services implemented in the translation unit. Default implementation returns an emptySet. Parameter underlayAccess represents object containing methods for communication with a device via NETCONF and should be passed to readers/writers.","provideHandlers(rRegistry: ModifiableReaderRegistryBuilder, wRegistry: ModifiableWriterRegistryBuilder, underlayAccess: UnderlayAccess): Unit","Handlers(readers/writers) need to be registered in this method. underlayAccess represents object containing methods for communication with a device via NETCONF and should be passed to readers/writers.","How to register readers/writers is described in CLI TranslateUnit"]},{"l":"Translation units for different device versions","p":["In case of needing to implement a new CLI Translation Unit for specific version of device we create a new TranslateUnit(e.g. located in iosxr/mpls).","In this case we use IOSXR4.* implementation as an example."]},{"l":"Device registration","p":["In TranslateUnit we had just created, e.g. MplsUnitXR4.java, we have to register device as a constant located ../iosxr/utils/IosXrDevices.java containing device type and version as described in TranslateUnit documentation.","This unit can reuse all writers/readers from existing ones, except the writer (or other handler) we want to alter or create (in our example writer for tunnel configuration). We have to create a new writer with desired behaviour and add it into provideWriters method."]},{"i":"handlers-1","l":"Handlers","p":["In our example, the newly created writer have to implement CliWriter interface as well as all the methods mentioned in Writers. With other handlers we proceed with same logic.","Similar process apply on every new implementation of different device version."]},{"l":"How to write extensions for OpenConfig"},{"i":"best-practices-for-handlers-readerswriters","l":"Best practices for handlers (readers/writers)","p":["All comments are in English","All defined exceptions can be thrown from the code","All new dependencies and imports are actually used","All variables/methods are actually used","Before pushing the code make sure:","Chunk","Code has correct spacing","Commented out code","Comments are appropriate to the code behavior","Constants","Do not push code that contains following:","Double blank lines","java regexes","New classes/interfaces have the correct license header","New classes/interfaces/yang model have correct date","Reflection","Show commands","Static imports","Trailing whitespaces or tabs"]}],[{"l":"FAQ"},{"i":"what-is-the-datastore-used-in-frinx-uniconfig-","l":"What is the datastore used in FRINX UniConfig ?","p":["UniConfig uses a custom in-memory database that is part of MD-SAL and is a very fast storage for YANG modeled data.","The datastore is used only for caching data in the scope of a single transaction. For persistence purposes, UniConfig uses a PostgreSQL database."]},{"i":"are-service-instances-stored-in-the-uniconfig-layer-of-frinx-","l":"Are service instances stored in the UniConfig layer of FRINX ?","p":["Only the \"outputs\" of a service are stored and managed by UniConfig (for example, a service that generates BGP config for 10 devices, which is pushed into UniConfig).","Services are responsible for managing their own configuration/operational state, and rely on the same database to store configuration or operational data."]},{"i":"how-does-frinx-deal-with-model-changes-","l":"How does FRINX deal with model changes ?","p":["OpenConfig models are compiled as part of UniConfig and can therefore be changed only before compilation.","On the other hand, NETCONF models can be dynamically loaded from a device and can also be manually updated using a dedicated RPC."]},{"i":"does-frinx-provide-auto-rollback-on-all-affected-devices-if-a-transaction-fails-on-one-or-more-devices-","l":"Does FRINX provide auto rollback on all affected devices if a transaction fails on one or more devices ?","p":["Yes, all onboarded devices have full rollback implemented.","You can also disable auto-rollback in UniConfig, so that successfully configured devices will keep their configuration. This is done by setting the do-rollback flag to False in the input for the commit RPC."]},{"i":"is-it-possible-to-display-differences-between-the-actual-device-configuration-and-the-operational-datastore-while-synchronizing-the-configuration-into-frinx-","l":"Is it possible to display differences between the actual device configuration and the operational datastore while synchronizing the configuration into FRINX ?","p":["Yes, follow these steps:","Sync (update operational).","Show diff.","Drop the changes from the device by replacing operational with config."]},{"i":"is-any-netconf-device-fully-supported-or-must-openconfig-be-mapped-to-netconf-as-well-","l":"Is any NETCONF device fully supported, or must OpenConfig be mapped to NETCONF as well ?","p":["You can either use the native device models (via UniConfig native) or existing translation units between OpenConfig and vendor models."]},{"i":"are-the-libraries-used-to-access-the-config-data-store-model-driven-","l":"Are the libraries used to access the Config Data Store, model driven ?","p":["UniConfig has a DataBroker interface and the concept of InstanceIdentifier. These are the model driven APIs for data access.","For more information, see MD-SAL basic concepts."]},{"i":"what-would-an-access-to-the-configuration-data-store-look-like-in-code-","l":"What would an access to the configuration data store look like in code ?","p":["A. To demonstrate the API, this example reads InterfaceConfigurations from CONF DS and puts it back to CONF DS.","B. This example reads InterfaceConfigurations from OPER DS."]},{"i":"is-it-possible-in-frinx-to-run-a-transaction-on-two-disjunct-sets-of-devices-simultaneously-","l":"Is it possible in FRINX to run a transaction on two disjunct sets of devices simultaneously ?","p":["UniConfig supports the build-and-commit model, which makes it possible to configure devices in isolated transactions and commit them in parallel. If there are conflicts between configured sets of devices, the second transaction that is committed will fail (however, this cannot happen on disjunct sets of devices)."]},{"i":"what-access-control-measures-does-frinx-offer-","l":"What access control measures does FRINX offer ?","p":["FRINX UniConfig supports local authentification, password authentification, public key authentification Token authentification, RADIUS-based authentification and subtree-based authentification via AAA Shiro project."]},{"i":"how-does-frinx-report-problems-with-device-interaction-","l":"How does FRINX report problems with device interaction ?","p":["If a device cannot be reached during a UniConfig transaction (after trying to re-establish the connection), a timeout occurs and the cause for the transaction failure is reported.","UniConfig also uses keepalive messages to continuously verify the connection to devices, using both NETCONF and CLI management protocols."]},{"i":"is-it-possible-to-backup-a-configuration-","l":"Is it possible to backup a configuration ?","p":["UniConfig stores all committed configurations for devices, templates, and snapshots in a PostgreSQL database. We suggest using existing techniques for backup that are also provided by PostgreSQL."]},{"i":"is-it-possible-to-enforce-policies-over-configuration-changes-","l":"Is it possible to enforce policies over configuration changes ?","p":["All customer-specific validations and policy enforcements can be implemented in layers above UniConfig."]},{"i":"which-languages-are-the-libraries-to-access-frinx-in","l":"Which languages are the libraries to access FRINX in?","p":["UniConfig is written in JAVA and Kotlin, which can use data objects generated from YANG. The RESTful API (RESTCONF) can be used with a language that implements the REST client (for example, Python)."]},{"i":"does-frinx-detect-if-a-cluster-node-is-down-on-its-own-or-does-it-rely-on-a-high-availability-framework-","l":"Does FRINX detect if a cluster node is down on its own, or does it rely on a high-availability framework ?","p":["A UniConfig instance is stateless, i.e., it does not persist any configuration in its datastore (PostgreSQL is used for persistence) and does not keep permanent connections (connections to devices are created on-demand in the transaction).","Because of its stateless architecture, UniConfig instances in the \"cluster\" do not need to communicate with each other and require no coordination. Keep in mind that requests belonging to the same transaction must be forwarded to the same UniConfig backend. For this purpose, you can use any HA component that supports sticky sessions based on cookies (for example, HA-proxy or Traefik)."]},{"i":"can-frinx-report-problems-to-a-network-monitoring-system-","l":"Can FRINX report problems to a network monitoring system ?","p":["FRINX UniConfig can propagate NETCONF notifications and internal UniConfig notifications or data-change-events from web sockets on the Northbound API."]},{"i":"is-additional-logging-available-in-uniconfig-","l":"Is additional logging available in UniConfig ?","p":["Yes. Each component writes logs at a different verbosity level (ERROR, WARN, INFO, DEBUG, TRACE). We use the logback framework for logging messages.","Logging can be adjusted by modifying the config/logback.xml file. This file can be updated also on runtime.","Another option to adjust logging for specific components is to use a logging controller. For more information, see Logging."]},{"i":"where-do-i-find-the-device-status-and-error-messages-when-installing-does-not-work-","l":"Where do I find the device status and error messages when installing does not work ?","p":["The install/uninstall process is performed automatically. The device is installed when UniConfig must read or write data from or to the device, and uninstalled at the end of the transaction if no other transaction is using the same installpoint. The install process is transparent, and the user need not care about the process outside of debugging purposes.","To get the status of the install process for all devices in the system, issue the following request. It shows the status and last connect attempt cause:","CLI devices:","NETCONF devices:","gNMI devices:"]},{"i":"what-exactly-happens-during-the-installation-process-","l":"What exactly happens during the installation process ?","p":["The entire installation process includes the following:","Open internal transaction.","Install device with input parameters (CLI or NETCONF).","Open IO session to device (TCP session with SSH and/or NETCONF on top of SSH session).","Expose mountpoint (via internal API and RESTCONF API).","Sync configuration from device.","Write configuration and store information in database.","Uninstall device.","Commit transaction."]},{"i":"why-cant-i-install-junos-devices-on-uniconfig-","l":"Why can't I install Junos devices on UniConfig ?","p":["If installing Junos devices is not possible, UniConfig may give this response :","To install Junos devices, set up a NetConf session that is compliant with RFC and Yang schemas ( rfc-compliant and yang-compliant) on the Junos device:"]}],[{"l":"Glossary of terms","p":["MD-SAL - Model driven service application layer https://docs.opendaylight.org/projects/mdsal/","OpenFlow - Communications protocol that exposes the forwarding plane of a network switch or router over the network https://en.wikipedia.org/wiki/OpenFlow","OpenDaylight - A modular open platform for customizing and automating networks https://www.opendaylight.org/","RESTCONF - HTTP-based protocol that provides a programmatic interface for accessing data defined in YANG, using the datastores defined in NETCONF https://tools.ietf.org/html/draft-ietf-netconf-restconf-12-","SDN (software-defined networking) - Management of network services through abstraction of higher-level functionality https://en.wikipedia.org/wiki/Software-defined_networking","NETCONF (Network Configuration Protocol) https://tools.ietf.org/html/rfc6241","Using the NETCONF Protocol over Secure Shell (SSH) https://tools.ietf.org/html/rfc6242","NETCONF Event Notifications https://tools.ietf.org/html/rfc5277","With-defaults Capability for NETCONF YANG https://tools.ietf.org/html/rfc6243","YANG - A Data Modeling Language for NETCONF https://tools.ietf.org/html/rfc6020","gNMI - gRPC Network Management Interface https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md","gNOI - gRPC Network Operations Interface https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/prog/configuration/175/b_175_programmability_cg/m_175_prog_gnoi_protocol.pdf"]}],[{"l":"List of Supported Devices","p":[".*","(mounted as .*)","(mounted as ios xr .*)","(mounted as Junos 14.*)","(mounted as sros .*)","1.*","12.*","13*/14*","14.*","15.*","16.*","16.*(and later)","17.*","18.*","2.*","3.*","4.*","5.*","6.*","6.6.1 (and later)","8.*","Arista","Brocade","Calix","Casa","Ciena","Cisco","CLI access via REST","CLI to OC translation","Cumulus","Cumulus Linux","Dasan","Device OS Type","Device Version","eos","For details of translation units see our Github: cli_units and unitopo_units.","Here you can find list of all the devices and features supported by Frinx UniConfig:","Huawei","ios classic","ios xe","ios xr","IP Infusion","ironware","Juniper","junos","Microsoft","Mikrotik","NETCONF access via REST","NETCONF to OC translation","nexus","Nokia","nos","OC = OpenConfig","OcNOS","SAOS","SonicOS","sros","Ubiquity","ubnt es","Vendor","vrp"]}],[{"l":"FRINX Workflow Manager introduction","p":["FRINX Workflow Manager allows customers to create automated, repeatable, digital processes to build, grow and operate their digital communication infrastructure. FRINX Workflow Manager is based on open-source components and enables infrastructure and network engineers to create and operate workflows to implement configuration changes and obtain operational data from their heterogeneous networks and clouds. Typical examples are the automation of services that span resources in the cloud and physical assets, the automation of slices and capacity increases in mobile networks, the interaction with CRM and inventory systems, the management of Internet and Infrastructure services and the automation of core network functions. Workflow Manager can be deployed standalone or as part of FRINX Machine.","FRINX Workflow Manager uses Netflix's Conductor for task/workflow orchestration. We recommend to take a look at their Documentation as an introduction to Tasks, Workflows, Definitions and an overall prerequisite to working with FRINX Workflow Manager."]}],[{"l":"Frinx Python SDK","p":["In this section, you will learn about Frinx Python SDK and how to use it together with prepared frinx-services-python-api/frinx-services-python-workers.","High-level Python SDK architecture"]}],[{"l":"Frinx Python SDK","p":["The FRINX Python SDK is a flexible tool designed to simplify interaction with the FRINX network automation solutions. This SDK provides a set of Python libraries and utilities that enable developers to easily integrate with FRINX's platform, streamline their network automation workflows, and leverage FRINX's capabilities to the fullest."]},{"l":"Project init","p":["For the beggining, you will need to create new python project. Example of simple project can be found here We recommend to use poetry as a package management tool and use package from pypi.org"]},{"i":"pyprojecttoml","l":"pyproject.toml"},{"l":"Worker definition","p":["In worker.py we want to create some piece of logic, which will be used in workflows to solve complex problems. Our worker has predefined interface, where you can define conductor task definitions, inputs and outpus. In method execute, you can implement your custom logic. For example call to our service, parse data from previous task or any other code you want."]},{"l":"Workflow definition","p":["Now let's use previous created worker in workflow."]},{"l":"Start worker","p":["Now implement conductor client, which registers our workflow and executes custom worker logic."]}],[{"l":"Frinx Servives Python API","p":["The FRINX Services Python API repository is a monorepo containing Pydantic API wrappers. These components are designed to facilitate rapid worker development, enabling developers to use a common source of API and track changes between service releases. If you find any incompatibilities, please create an issue on the GitHub repository.","For more details, visit the FRINX Services Python API documentation."]},{"l":"Package Importing","p":["To import the necessary FRINX API modules into your project, add the following entries to your pyproject.toml file:","Each package can be imported via frinx_api. Below is an example of how to create custom worker with imported API module:"]},{"l":"Example Usage","p":["CreateTransaction API wrapper can be found in the Uniconfig module.","In this example, the frinx-uniconfig-api dependency is imported into the project, and the CreateTransaction module is used to manage Uniconfig transactions. This approach allows you to use generated API instead of creating custom API implementation.","In this example, we used frinx-python-sdk and frinx-services-python-api to create conductor worker compatible with Frinx Machine 6.1.0 release. For more details, how to import and execute this worker, please visit SDK part."]},{"l":"Versioning","p":["We release versions for each component change or as a combination of services based on the FRINX Machine release. If you have deployed FRINX Machine 6.1.0, use tag 6.1.0. For specific dependency versions, use the custom tag/branch/revision as shown below:","By following these instructions, you can quickly integrate FRINX Services Python API into your project and start utilizing the provided functionalities to streamline your worker development."]}],[{"l":"Frinx Servives Python Workers","p":["The FRINX Services Python Workers repository contains a collection of commonly used workers and API wrappers. These components are designed to facilitate rapid workflow development, enabling developers to share tasks across projects and avoid redundant work. Contributions are welcome to help expand and improve the repository.","For more details, visit the FRINX Services Python Workers documentation."]},{"l":"Package Importing","p":["To import the necessary FRINX services into your project, add the following entries to your pyproject.toml file:","Each package can be imported via frinx_worker. Below is an example of how to use the UniconfigManager from the frinx-uniconfig-worker package:"]},{"l":"Example Usage","p":["UniconfigManager worker implementation can be found in the UniconfigManager module.","In this example, the frinx-uniconfig-worker dependency is imported into the project, and the UniconfigManager module is used to manage Uniconfig transactions. This approach allows you to use pre-built tasks instead of creating custom workers."]},{"l":"Versioning","p":["We release versions for each component change or as a combination of services based on the FRINX Machine release. If you have deployed FRINX Machine 6.1.0, use tag 6.1.0. For specific dependency versions, use the custom tag/branch/revision as shown below:","By following these instructions, you can quickly integrate FRINX Services Python Workers into your project and start utilizing the provided functionalities to streamline your workflow development."]}],[{"l":"Workflow builder","p":["In this part, you can find common implementation of various conductor tasks. It's pythonic representation of conductor operators and system tasks This implementation depends on frinx-python-sdk and uses Pydantic to serialize workflow definition to result in JSON format."]},{"l":"DECISION TASK"},{"l":"DO_WHILE TASK"},{"l":"DYNAMIC_FORK TASK"},{"l":"EVENT TASK"},{"l":"EXCLUSIVE_JOIN TASK","p":["A list of task reference names that this JOIN task will wait for completion"]},{"l":"FORK_JOIN TASK"},{"l":"HUMAN TASK"},{"l":"INLINE TASK","p":["INFO: expression wrapped into javascript function:"]},{"l":"JOIN TASK","p":["Read more on conductor-oss docs","A list of task reference names that this JOIN task will wait for completion"]},{"l":"JSON_JQ_TRANSFORM TASK"},{"l":"SET_VARIABLE TASK"},{"l":"SIMPLE TASK"},{"l":"START_WORKFLOW TASK","p":["Start Workflow is an operator task used to start another workflow from an existing workflow. Unlike a sub-workflow task, a start workflow task doesn’t create a relationship between the current workflow and the newly started workflow. That means it doesn’t wait for the started workflow to get completed."]},{"l":"INPUT PARAMETERS","p":["start_workflow:","StartWorkflowTaskInputParameters : StartWorkflowTaskPlainInputParameters|StartWorkflowTaskFromDefInputParameters","StartWorkflowTaskPlainInputParameters","StartWorkflowTaskFromDefInputParameters"]},{"l":"SUBWORKFLOW TASK","p":["SubWorkflowFromDefParam validate subworkflow and workflow inputs"]},{"l":"SWITCH TASK","p":["SwitchTaskValueParamInputParameters -> VALUE-PARAM","SwitchTaskInputParameters -> JAVASCRIPT","VALUE-PARAM evaluator type"]},{"l":"TERMINATE TASK"},{"l":"WAIT_DURATION TASK"},{"l":"WAIT_UNTIL TASK"}],[{"l":"Development environment","p":["This guide provides the step-by-step instructions for preparing develoment environment."]},{"l":"Prerequisites","p":["Cluster: Make sure that you cluster is running.","Helm: Make sure that Helm is installed. Follow the Helm installation guide if necessary.","Python: Make sure that your environment have Python ^ 3.10 interpretter installed.","Poetry: Make sure that you have installed Poetry. Follow the Poetry installation guide if necessary.","Mirrord: Make sure that you have installed Mirrord. Follow the mirrord installation quide if necessary"]},{"i":"step-1-start-frinx-machine","l":"Step 1: Start Frinx Machine","p":["Install Frinx Machine Developent environment","Check out gitops-boilerplate repository to run Frinx Machine locally frinx-workers-boilerplate"]},{"i":"step-2-clone-worker-example-repository","l":"Step 2: Clone worker-example repository","p":["Clone repository and follow instructions in README.md","frinx-workers-boilerplate"]},{"i":"step-3-local-development-with-mirrord","l":"Step 3: Local development with Mirrord","p":["Mirrord is great tool, which simplifies development of workflows on local/remove kubernetes cluster. Is only needed to install it to the IDE (CLI), set connection to the correct kubeconfig/namespace and run python worker in targetless pod. No more need to workaround connection via ingress."]},{"i":"step-3-deploy-to-cluster","l":"Step 3: Deploy to cluster","p":["Developent environment"]}],[{"l":"UI Workflow Builder","p":["Workflow Builder is the graphical interface for Workflow Manager and is used to create, modify and manage workflows."]},{"l":"Creating new workflow","p":["To create a new workflow click on the Create button in the Create workflow tab and fill in workflow general parameters. Then you can proceed with adding tasks .","Parameter Name is required and must be unique. Keep in mind that the name cannot be changed later. Other parameters are optional and can be changed anytime.","Create new workflow"]},{"l":"Editing existing workflow","p":["To edit an already existing workflow, find the workflow in the Definitions tab, click on it and then click on the Edit button. A diagram of the workflow will be rendered on the canvas. Now you can restructure the workflow, add new tasks, remove tasks or edit the workflow information and parameters.","Workflow edit"]},{"l":"Adding tasks","p":["To add new task on canvas, find the task in the left menu and click the + icon.","Add task"]},{"l":"Removing tasks","p":["To remove a task, click on the three dots next to a task and press the Remove task button.","Delete task"]},{"l":"Task parameters","p":["To edit or add task parameters, double-click on the task that is placed on the canvas. Input parameters can be declared as:","Input provided by user, e.g.:","Variable provided by other task, e.g.:","Statically defined, e.g.:","For full documentation of tasks see: https://netflix.github.io/conductor/configuration/taskdef/."]},{"l":"System tasks"},{"i":"fork--join","l":"Fork & Join","p":["The 'Fork' function is used to schedule a parallel set of tasks.","A Join task MUST follow Fork task.","Fork and Join"]},{"l":"Decision","p":["A decision task is similar to an if...else statement in a programming language. The task takes 2 parameters:","name of the parameter in the task input whose value will be evaluated (default is param)","value that will be compared with param(or other specified input variable)","If param and is equal to are evaluated as equal, the workflow will continue to If branch, otherwise the workflow will continue in else branch.","Else branch is optional and can be empty."]},{"l":"Lambda","p":["Lambda Task helps execute ad hoc logic at Workflow run-time, using javax & Nashorn Javascript evaluator engine. This is particularly helpful in running simple evaluations in the Conductor server, instead of creating Workers.","The task output can then be referenced in downstream tasks like:"]},{"l":"HTTP","p":["An HTTP system task is used to make calls to another microservice over HTTP. You can use GET, PUT, POST, DELETE Methods and also you can set your custom header."]},{"l":"TERMINATE","p":["Task that can terminate a workflow with a given status and modify the workflow's output with a given parameter. It can act as a \"return\" statement for conditions where you simply want to terminate your workflow. For example, if you have a decision where the first condition is met, you want to execute some tasks, otherwise you want to finish your workflow.","name","description","notes","terminationStatus","can only accept “COMPLETED” or “FAILED”","task cannot be optional","workflowOutput","Expected workflow output"]},{"l":"EVENT","p":["Event task provides ability to publish an event (message) to either Conductor or an external eventing system like SQS. Event tasks are useful for creating event based dependencies for workflows and tasks.","When producing an event with Conductor as sink, the event name follows the structure:"]},{"l":"WAIT","p":["A wait task is implemented as a gate that remains in IN_PROGRESS state unless marked as COMPLETED or FAILED by an external trigger. To use a wait task, set the task type as WAIT"]},{"l":"jsonJQ","p":["jsonJQ is like sed for JSON data - it is especially useful for filtering JSON data.","Example of jsonJQ query expression could be:","It searches through the whole config and under the\"Cisco-IOS-XR-ifmgr-cfg:interface-configurations\" model we find the interface with a description that the user inputs$. The task would return the name interface with fitting description."]},{"l":"Kafka publish","p":["Kafka is a distributed publish-subscribe messaging system and a robust queue that can handle a high volume of data and enables you to pass messages from one end-point to another.","Kafka"]},{"l":"Subworkflows","p":["Subworkflows act as a regular tasks inside a parent workflow. Subworkflows can be expanded to view the tasks they contain (or other nested subworkflows) by clicking the three dots next to the subworkflow and then clicking the Expand button. Expanded subworkflows can be then edited the same way as parent workflow.","Simple tasks differs in color shade from Subworkflow tasks and cannot be expanded.","Expand"]},{"l":"Linking tasks","p":["To connect tasks or subworkflows into execution flow, drag and drop respective Out and In endpoints on nodes, like this: Out-> In"]},{"l":"Unlinking tasks","p":["To remove the link, double-click on the link."]},{"l":"Adding workflow information","p":["To provide additional workflow information, click on Actions in the upper right-hand corner and then click Edit workflow."]},{"l":"Output parameters","p":["We can specify custom output parameters of a workflow, by using JSON templates to generate the output of the workflow. If not specified, the output is defined as the output of the last executed task.","Let's say we have a task with taskReferenceName: task1 which returns summary and we want output of the worklow to be output of this specific task only. The outputParameter value named e.g. finalResult will be:","For full documentation of workflow parameters and definition read https://netflix.github.io/conductor/configuration/workflowdef/."]},{"i":"defaults--description","l":"Defaults & Description","p":["Here, we can define default values and descriptions for workflow inputs. Each input value declared as ${workflow.input...} will appear in a dropdown list of available input parameters."]},{"l":"Save and execute workflow","p":["To Save workflow, click on the Actions button in the upper right corner and select Save workflow. Then you can find the workflow in the Explore workflows section under Definitions tab.","To Execute workflow directly from the builder, click on the Save and execute button in the upper right corner. You will be prompted to provide input parameters.","Executing workflow will also save the workflow."]},{"l":"Import and export of workflows","p":["To import workflow, click the setting icon and then select the Import button. Only valid JSON definition of the workflow will be imported.","Imported workflow will not be saved until you Save or Execute it.","Import/Export workflow","To export and save the workflow in JSON format into your filesystem, click on Export button.","In order to choose a location to which you want to export the workflow, you have to have it enabled in your browser settings. Default location is Downloads folder."]}],[{"l":"Device Blueprints","p":["Blueprints allow you to create a template that can be used for quick adding of devices. They are created with JSON snippets."]},{"l":"Creating new blueprint","p":["To create a new blueprint click on the Explore button in the Explore and configure device tab and then click the Blueprints tab in the top bar. Here you can Add blueprint.","Create blueprint"]},{"l":"Using a blueprint","p":["To use blueprint when adding a new device toggle the \"Blueprints\" switch in the form and choose the blueprint that you want to use.","Use Blueprint"]},{"l":"Blueprint examples"},{"i":"cisco-classic-ios-cli","l":"Cisco classic IOS (cli)"},{"i":"cisco-ios-xr-netconf","l":"Cisco IOS XR (netconf)"},{"i":"junos-cli","l":"JUNOS (cli)"},{"i":"calix-netconf","l":"CALIX (netconf)"},{"i":"nokia-netconf","l":"Nokia (netconf)"},{"i":"ciena-cli","l":"Ciena (cli)"}],[{"l":"Device Inventory","p":["Devices are stored in a Device Inventory. From here they can be dynamically installed and uninstalled."]},{"l":"Adding device to inventory","p":["To add new device to invetory, click on the Add device button in the Device inventory tab.","FM Install"]},{"l":"JSON examples","p":["To adding a new device toggle the \"Blueprints\" switch in the form and choose the blueprint that you want to use.","New devices are added by JSON code snippets. They are similar to Blueprints with one addition: device_id must be specified in the snippet."]},{"i":"cisco-classic-ios-cli","l":"Cisco classic IOS (cli)"},{"i":"cisco-ios-xr-netconf","l":"Cisco IOS XR (netconf)"},{"i":"junos-cli","l":"JUNOS (cli)"},{"i":"calix-netconf","l":"CALIX (netconf)"},{"i":"nokia-netconf","l":"Nokia (netconf)"},{"i":"ciena-cli","l":"Ciena (cli)"}],[{"l":"FRINX Resource Manager introduction","p":["FRINX Resource Manager was developed for network operators and infrastructure engineers to manage their physical and logical assets and resources. Examples for assets are locations, equipment, ports and services. Examples for resources are IP addresses, VLAN IDs and other consumables required for operating data services. Resource Manager was developed specifically to address the needs of network and infrastructure engineers working with communication networks. FRINX Resource Manager provides GUI and a GraphQL based API to create, read, update and delete assets. Resource Manager can be deployed standalone or as part of FRINX Machine."]},{"l":"Features","p":["Following list contains features inherent to Resource Manager."]},{"l":"Resource type management","p":["Example resource types:","Location","Name: Latitude","Name: Longitude","Name: name of the property","Name: RD","Name: vlan","Property type","Resource Manager is flexible enough to enable user defined resource types without requiring code compilation or any other non-runtime task. With regard to resource types, this requires keeping the schema flexible enough so that users can define their own types and properties and thus create their own model.","Resource type is a blueprint for how to represent a resource instance. A resource type is essentially a set of property types, where each property type defines:","Route distinguisher","Type: float","Type: int","Type: int, string, float etc.","Type: String","VLAN"]},{"l":"Resource management","p":["A resource is an instance of a resource type consisting of a number of properties.","Example resources based on resource types from previous section:","VLAN_1","Property","Name: vlan","Value: 44","Route distinguisher_1","Name: RD","Value: 0:64222\uD83D\uDCAF172.16.1.0","Location_1","Name: Latitude","Value: 0.0","Name: Longitude","Resource types"]},{"l":"Flexible design","p":["One of the main non-functional goals of the Resource Manager is flexibility. We are designing Resource Manager to support an array of use cases without the need for modifications. To achieve flexibility we are allowing:","Custom resource type definition without changes in the DB schema","Custom allocation logic without the need to modify the backend code","Custom pool grouping to represent logical network parts (subnet, region, datacenter etc.)"]},{"l":"RBAC","p":["Role Based Access Control is supported by Resource Manager.","A simple RBAC model is implemented where only super-users (based on their role and user groups) can manipulate resource types, resource pools and labels. Regular users will only be able to read the above entities, allocate and free resources.","Resource Manager does not manage list users/roles/groups and relies on external ID provider. Following headers are expected by Resource Manager graphQL server:"]}],[{"l":"User Guide"},{"l":"API","p":["See examples in api_tests."]},{"l":"UI","p":["See the Resource Manager frontend project on GitHub"]}],[{"l":"Pools","p":["A resource pool is an entity that allocates and deallocates resources for a single specific resource type. Resource pools are completely isolated from each other and there can be multiple resource pools for the same resource type even providing the same resource instances. Resource pools encapsulate the allocation logic and keep track of allocated resources. A pool instance should manage resources within the same network or logical network part (e.g. subnet, datacenter, region or the entire, global network).","Example pools:","IPv4 address pool allocating IP addresses from a range / subnet","VLAN pool allocating all available VLAN numbers 0 - 4096","Route distinguisher pool allocating route distinguishers from a specific, per customer, input","Depending on resource type and user’s requirements, pools need to be capable of allocating resources based on various criteria / algorithms. Currently, following pool types are supported by Resource Manager:"]},{"l":"SetPool","p":["Pool with statically allocated resources. Users have to define all the resources to be served in advance. The pool just provides one after another until each resource is in use.","This type of pool is suitable for cases where a set of resources to be served already exists.","Properties of SetPool","Config","Set of unique resources to provide","Name of the pool","Resource recycling - whether deallocated resources should be used again","Operational","Utilisation - % of pool capacity used"]},{"l":"SingletonPool","p":["SingletonPool serves just a single resource for every request.","This type of pool can be utilized in special uses cases such as serving a globally unique single AS number of an ISP. Instead of hardcoding the AS number as a constant in e.g. workflows, it can be “managed” and stored in the Resource Manager.","Properties of SingletonPool","Config","A single unique resources to provide","Name of the pool"]},{"l":"AllocatingPool","p":["a predefined set of resources cannot be used","AllocatingPool is a type of pool that enables algorithmical resource allocation. Instead of using a pre-allocated set of resources to simply distribute, it can create resources whenever asked for a new resource. This type of pool allows users to define a custom allocation logic, attach it to the pool and have use-case specific resource allocations available. Important feature of this pool type is the ability to accept new allocation logic from users in the form of a script without having to rebuild the Resource Manager in any way.","Allocation strategy - a script defining the allocation logic","Config","Example AllocationPools:","In general, anything that a user might need","Limit - hard limit on total number of resource that can be produced","Name of the pool","Operational","or in general whenever using an allocation script makes more sense then using a predefined set of resources","Pool providing all available VLAN numbers","Pool providing IPv4-mapped IPv6 addresses from a specific range / subnet","Pool providing just odd VLAN numbers","Pool providing random VLAN numbers","Pool providing Route Distinguishers that include customer specific information (which is passed as “additional input” as part of resource claim request)","Properties of AllocatingPool","resource creation requires additional inputs","Resource recycling - whether deallocated resources should be used again","This type of pool can be used when","Utilisation - % of pool limit used"]},{"l":"Nested pool","p":["Resource Manager allows to create nested pools. Nested pools provide possibility to create subgroups from already existing pools. With these subgroups it is easier to reason about topology."]},{"l":"How to create nested pool","p":["Process (in UI):","Create pool or open existing one","Allocate resource in newly created or existing pool","Open create pool page","Select parent from which nested pool should be created","Select allocated resource of parent from which nested pool will be taking resources","Fill other mandatory inputs","Push button to create nested pool","After successful submit newly created nested pool should be visible in pools list or in nested pools list in its parent detail page. Also it is possible to create nested pool from detail page of pool."]},{"l":"Allocation strategy overview","p":["Allocation strategy encapsulates the allocation logic and is always tied to (an) instance(s) of AllocatingPool. The strategy is defined in form of a script using Javascript (or similar) language and its responsibility is:","To produce a new (unique) resource instance based on a set of previously allocated resources and any additional, user submitted input.","Apart from a resource being unique, there are no other requirements on what the strategy needs to do. It gives users the freedom to implement any logic.","Allocation strategy can take any input provided in a structure named userInput. This input is provided by the user every time they claim a new resource.","Allocation strategy also gets access to a list of already allocated resources and any properties associated with the pool being utilized."]},{"l":"Pool hierarchies","p":["Resource Manager allows pools to be organized into hierarchies e.g."]},{"l":"Labels","p":["Labels enhance resource management by allowing a pool to be marked with a custom string. Multiple pools can have the same label forming a logical group of pools.","A group of pools under the same label can be dedicated to some logical part of a network (e.g. datacenter, subnet, region etc.).","A single pool should typically have only one label i.e. it should not be re-used across unrelated networks.","The following diagrams represent some of the configurations that can be achieved using Labels:"]},{"i":"configuration-pool-instance-per-label","l":"Configuration: Pool instance per Label","p":["Enables: Resource reuse in multiple networks","Instance per label"]},{"i":"configuration-pool-instance-under-multiple-labels","l":"Configuration: Pool instance under multiple labels","p":["Enables: Unique resources across different networks","Instance multiple labels"]},{"i":"configuration-pool-grouping","l":"Configuration: Pool grouping","p":["Enables: Dividing resource pools into groups based on network regions. Enables users to simply ask for a resource based on label name + resource type (removing the need to know specific pools)","Pool grouping"]},{"i":"configuration-multiple-pool-instances-under-the-same-label","l":"Configuration: Multiple pool instances under the same Label","p":["Enables: Resource pool expansion in case an existing pool runs out of resources. Serves as an alternative to existing pool reconfiguration. If multiple pools of the same type are grouped under the same label, the pools are drained of resources in the order they have been added to this group/label.","Multiple pool instances"]}],[{"l":"Resource Manager architecture","p":["Following diagram outlines the high level architecture of Resource Manager.","Architecture","User authentication and authorization as well as user and tenant management is outside of Resource Manager. Resource Manager is typically deployed behind an api-gateway that handles authentication and authorization relying on an external Identity Managmenet system.","The only aspect of tenancy management that needs to be handled by Resource Manager is: per tenant database creation and removal. Each tenant has its own database in database server."]},{"l":"Technology stack","p":["AAA","Also handles schema migration: creates or updates tables in DB according to ent schema","Backend server","Database","Ent is an ORM framework for go","Entgo.io","Gqlgen","Gqlgen is a graphql framework for go","GraphQL","Isolated and limited for safety and performance","Postgres","Primary API of Resource Manager will be exposed over GraphQL(over HTTP)","PSQL is the DB of choice, but thanks to ent framework hiding the interactions with the database, other SQL DB could be used in the future","RBAC rules can be defined as part of the schema","Resource Manager will rely on technologies used by the Inventory project currently residing at: https://github.com/facebookincubator/magma since both projects are similar and have similar requirements.","Separate process","Tenant and user management is out of scope of Resource Manager and will be handled by an external identity management system.","This section provides details on intended technologies to develop Resource Manager with.","WASM","Web assembly runs any user defined code executing allocation logic for user defined resource pools","Works well on top of entgo.io ORM"]},{"l":"Entity model","p":["Following diagram outlines the core entity model for Resource Manager:","Entities"]}],[{"l":"Developer Guide"},{"l":"Dependency on symphony","p":["Resource Manager currently depends on a project called symphony.","This project is not publicly accessible and without access to it, Resource Manager cannot be built. In that case, use pre built docker images from dockerhub."]},{"l":"Folder structure","p":["api-tests","core codebase for pools and resoruce allocation","ent- ORM schema and generated code for the DB","ent/schema","graph/graphhttp","graph/graphql","graphQL schema and generated code for graphQL server","graphQL server","integration tests","logging","logging framework","multitenancy, RBAC and DB connection management","ORM schema","pkg- helm chart for Resource Manager","pools","psql","psql DB connection provider","viewer"]},{"l":"Build","p":["It is advised to build Resource Manager as a docker image using Dockerfile and run it as a docker container.","The reason is that Resource Manager uses wasmer and pre built js and python engines for wasm. These are not part of the codebase and thus simply running Resource Manager would fail, unless you provide these resources e.g. by copying them out of Resource Manager built docker image.","Resource Manager utilizes wire to generate wiring code between major","components. Regenerating wiring is not part of standard build process ! After modifying any of the wire.go files perform:"]},{"l":"GraphQL schema","p":["Resource Manager exposes graphQL API and this is the schema."]},{"l":"Built in strategies","p":["Resource Manager provides a number of built in strategies for built in resource types and are loaded into Resource Manager at startup.","Built in strategies code base","Built in strategies unit tests","These strategies need to be tested/built and packaged for Resource Manager. This test/build process in scrips section of package.json while the packaging part can be found in generate.go.","Resource types associated with these strategies can be found in load_builtin_resources.go."]},{"l":"Unit tests"},{"l":"Integration tests"},{"l":"API tests","p":["There's a number of api tests available and can be executed using integration-test.sh. These tests need to be executed against Resource Manager running as a black box (ideally as a container)."]},{"l":"Wasmer","p":["There's a number of tests testing core components that require wasmer, quickjs and python packages to be available. It is recommended to run these tests in a docker container.","Example execution:"]},{"l":"Additional info"},{"l":"Telementry","p":["Support for tracing (distributed tracing). Streams data into a collector such as Jaeger. Default is Nop. See main parameters or telementry/config.go for further details to enable jaeger tracing"]},{"l":"Health","p":["Basic health info of the app (also checks if mysql connection is healthy)"]},{"l":"Metrics","p":["Prometheus style metrics are exposed at:"]}]] \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index db4d7190c64dd778dd0bca2954a285a5004b68b0..572539c3be3e338b1d2815904756c9cc557ea721 100644 GIT binary patch delta 3016 zcmV;(3pe!F7uXk&6n|u8j-5EERHar`de&dicXB6MSi&+LBq%^me82vJq}a~GsXVq2 zXpqE4a=f>I^Wt#$`PY3VPBu&%F6&>X=d-iZ6ISQ4;C1=y^gsXnO}?N0b@SzCqlIDi z#NAw*U#Dwp)sOl7?(S}8xMdYpW+rtxH~HGVG4sB0em1*4?SDS=<9=-`@#vFx7wu=x zudlD??bXwpFDEDdoBUt*O33`i-*4Op3YnYPO7r@D#^wCy++XYOqQ+LTxLKSnF3H(7 zS$zHH{OrfY)sM69|8@8ESG#+a=2COJy>UE$&Uf$p*UtOzebe{1FGy4KT-GaI&Ktut zDH~p}`L2;j#eX!l?y;Krvf-j2v@S?4tBPCVATjZI8fUX_i;z5S>FSn}T3Wv1dEbU0 zasGJ{70uVYW^-N}OND5``5SK?Bh5-~tlkpCa?LCP^3~NqkeAf(JZgk_W2~&moz(u> z7EB4btymq+V|{Tr*UWmrj!{iZ=HU{hrIoo9=3uP%M1P&|i<-@DN>brz81&|N|EOa@{r0Ko)V=ks=^@`zC!Q6x`8sOs zM@+1OTI$`1#(!bw#$ojHAY;BC-o*bDY{PRWx>wp6@4Hz5!9IvYY2lKtW89-BLQ1uy z`E9g_oonfI;|^#0(0P3@x*`Ye{iBtTcd_FX3xBdvHBk!{3DOtkN9)J?;hQsMF(P6N z*Em(&jdGIOI|7Hslv6vJR?IRTHL(}f=D$YPOS0m^p+|XMA@Kw7e!UI}c;8q%Ex+@4 zw92zCh#Mazr!$%G6nb7()7tby-`!=6*GDC*9Y=`C8yY<-N;52O_p-jVZQUQL~_B&Q!??RcFN6PNfEgNyK&>)J@$6i#)tTiVJ`p7 zY2H3_Au)6HdjzU$*PQi6QC2m=ayOkbe;=l&Vj${uwAt2q=j--%;$+zEyV1RxN=I5Q zxaDjY9?EY~@ntNLr_wHZfX>~~9Aq{@fq!Zym~-oWHUT>v>tAQiGf4~X*Rk0Jzl9+^YP_mg!F|va zy@ft3kA0(AGtADT!3Z4L1LG4Msft@)9)WJxn$dzN3Ce8`jbBM)OZS4<81cVq?qb3t z;qYR@BjNC3!Xtt3p3gAeWiYrH=Q0>vjBgnXZc?)09JJCL3~pkQ0TVY327eb5HVpO?C#Vx`=!L8($2!1;$ zl2UDb!`5$dmNjN8R2-}v8-GvAlbar^B)jT)<+%fm_OSVp?CzQh!IIe>DZ=X&pz?8q z#Bh67BVg93Qqy8T7Nh2MWR)R7$f)&@z_9lNtKS8Jstp3=@oEGC6KW2J7ZYm^hZhrU z4u=;LZ4QSQ6K)QN7ZYy|hZhrY4u=;LaSnzTl%^XFFDBv~4sT-m4S$qp5eV-Blm`$D zZc?Ln0m=gi1~~E*mczi?nS$`FSQNkX`G#E@%V2W@;@jb1VNOivE)=Ak$V`BGEw67V@m_T7L zxR^L$Fu0g7VKBIuC}9w|SFJ%muugXf=~pi7k!JnuScfYWuyCFjNL((8`o znH74gn;Poc2gQH5^TYQFp-b6Va*$?)5e`8~?HhkLZd`$sNN5ViO3etWl-*G1k8B-k z$I?p3yJ(($fA$EkH%@~{y`3*b!`wfuLDpW-;qlTo+J9vuZV4+uIZEU2RrDHgi`}U> z*7iAYJZc~s4&q8`*9C5x(7GVTnNp8hvwTgp(+W{JK{S&H6c;)lW01oJ*?YGQz28N^+~vf-k@gj5hfpSh3w zSCJreE{AM%&W0P3Lx4Px@UcRK)#D!o9ePUu0)OO3SKaagQeN~D>Qugu!YX|V#wJfe z(kgWdYy(ND8<&E@D4r2Htc^~7HV9dkpw+c8X*fr93Gx6&Wbqqwbl0c~0#pV(2nWvW zs;w-VJCjK%KM#CUCKhU;GWYMP$gIpHM%qI2%Rj_Ovr1Yv8A?utOohuudR&eO0Gf;T zCx3Ao&Ov5+MSWO_*)`L3TP~n)n-DoS@&v7?NsX2h;-w7B``@Whd2#gz<;RakK!}7G z92recn)yKL!{6*+)*zULNX|ZNUTIpfHWBpv43b_Rgu(H?X{ofuX=>jkeM|Px0$~^; zb@&KFEgS1hAEKn-`S$7CNXWgmK+@d-UVkwe7_(uzT_t;f4N4vi4cp(#G)7Df41JL0 zs(~^0MTLAOeJpT4?1)gzx;iv@^L-SSxkKeQ8vC=*VSNH1^lYW+X)&ruaDLK>McYLq zhItnxUtxyNm_c5?;ewTz;WeWD!vx(DH*Y`_dcwvFP8)G$nJxwEerJWebALv* zX0*zbmMb^f5acdG^*MlnfiViiBF%T~lNx7WgP? zB-HMlIk%*BF&%Qx11#<8*gW4Asm_$-7~LEjPoH)1lxMe+HbJ(2QSDjqtY2$emXIKB zLX4$RknH!kC|62!zcNr*K300#YzZdK53`Lk2)h@P1`8j5S%%#z5OG8Bj_Sf^$fy-K z4i_2WUBMcZO%f?RZuq3T4`yIR%x?oJlo*8Ji+bS?(=XF}2_YC_qs+Sr`VP!YQ&kkR zGc5?q_c*tPcfWIt933}7=QzFTk=u_^UmK4@Qrs@0%Hi?x!R~i5+&&~gk>X{jvPo~O z8d%Au_K8U|^IULZr87)rxt*?0`u86qf)|W=?DqDmh+5T~Z>E_G-0RRC1{{sM< K)Lc=--2ecf*T=5_ delta 3015 zcmV;&3pn)H7uOe%6o1sp96NSWkJPG4&-x4cPVPhtBP`QFLIuc)@7G_D6x(??mB$tW z4U*VMj`tRDUK|cT|GF#X=PlPpsOs0*Vs?J^nO98ZqAGr!{pX**$@jCru0Q>3v^3m) zb~jh%*V)F}`p0~JdwV-G!t#>VW~Ov8H*DkHn0engKc8Klb$_4vaksIheDKNJi}o{% ztE;Pdd-d%4)926roBUt*N-B2k?>FuPxngFv)}p$b2{r#Y_t*NnsIjHWub1b`OLBfi zmKXmlE`BV}e=HXNb@%mGyL)Rbloob(?Rfs2@89{ao%i4Ss_$=Kkfst$Rcleq8^bjz z8jRC)?VoMV zYpHf6ucCRZ&kpB`TMyVVs%XJITvBUg6;sk2jrE?W6MueDv)NBcDm@Lx^G0*y02f6> z(C;4mHq+KE>$q-`=3h-za z$BgY+_3wmAH-W=~Abu6e~KNX$2x4tz!9g{q_2d2UWxTc+5iy2q zoGR|7c9PmV0>{RbQ#+cL+;SZ?v1irhzeZInvKG>zM|oZ$@dNOFxe5vR&{#PwzxQ}_ z&9W|t8y_X7Gr9B>dR|u3%Jf6u-DQo}M+L7OM~KNA8a*mXGc0cRvg+*??{GXYWZW>S zYk$!64g2)(#|;r>En8^|^PPt!!lWRN$;6M^DK~#5MdS|b){S@f*xOkfAL2iTx%@My ztbOKEVdm=h2vpa;IqQw0tZbweZaQcFK1@%=K-BAKv#VI=>-KiyWY`_L(Y=~VM_M6; z6?`8aVmGMxGM30=X%{^}=k90$GMk`4HGh}fx%EDqfFFbu5&ET!8{tzzrMm>O zb-#_8K9?0$Ddv^B5j1KxfAF>(GuPaDBgwJoqm8*ROl>)4eHY8%;S`P>-a`q4v42E^ z!1bmbMwthLi!qgg!39~O;qYQC{cw0Oj#N0jiAjeA#$F1C7h{fw!;7)@!{Nm^Q{nI? zrrs8b>9=KK`fZt*ep^PU-`?)=F)1K4#@+YTIj&RTVN`|LLO3>?J_%wjl)1yiMCOi@j zFD5(^4lgD=5(w{NhVd?g!NoY2!Qf(i%V2Pmk_`*cN^>x{iAe@b+%yg0Tcim6J-w&sy}kZusHI=N9?SSmB=3*VU2>$@LLRccj&7?@G zdgmK+0A_!JDz8Kar4PCZ9`<4YpOVdmEDYiXgh2@MSg!a+O(*tvZnfe9d9z!4#TtH zcEZ!pcj1OpX(4A-41Y!mdmz(bFinmr!U@IqxLzXFY$L3bvW>>X?xAR3GM+Jk!eDSQ zal&A5F=4`Ba4}KBAaK9V&OuRtU~n-}fM9SjQGj4@F;ReEa1)ZdUtz^+gTYNm?s~Y1 z$z9CiOfa~ZwV6P0QG48i!HrO>z0+?)@VJP8hxb24duoqA&VOK1w4Tdw_Me;-$t{&4 zMIW!>AR&8S-z?@cSc|l7mk3 z(woEGxU3Xk^Ud*n%?ns_l zu6MerpssyT{Kq>#e6J9?QjH}?X;v8F5R}xR@pt3K6-bGMreLhnoS;hC4Tb*1)}eMR zt);q+=GpgWkBDmPG>Fo>`ARn2{nH9$?FAhk&uyb!HGlGk@Enw*H2z*iuK{=1or+^^ zp99CE2BP60u9bFO;HC+!a$=k*^`JFl8>*dFa5B|c)UlmoW)pXz-mU8z;;2;xrhhJj zo(KIxfVY(h1&0WPXh`*GrtO7E5o=GyikaI9-|?{tiHe^@(=qK~-Buxw>b@N5sP0G0 zC0)5;sDE+_%xoVf>dQXEwiIA_{LUan%`c(nX%tc!L-mfRwKKDHiRphRMAOu@(w650 zn7oaE=mmjyZ}x)1`4L*>4Q&6zARz0V-8kV5N_D;j6jpo!ao@0Ngv>D^6$H>H?&INA zBnX|$p&HHja6@tkkVg_eR*0~A{DYuFZwWwve1Gq%8_OZ(MK7UF<=ZH%)2Co;@)Q&; zQ>VbUkd(S{DbyInGa`qL(aFySsfq%$x;7>a=cukg9>9n!eq)aA8dX7n%76#qAh=z( zl|`8|nd;il1K*U%WxcF3_wT99tjZKd+CuZo-^EDtQdvG3N=}7Lh08^HTuul8%4GYK zIDZZ2AalK@KCHy;hU=;=7tps&h@2aFl2+5CMvDpYstsrT?^LKfyZVFj<3}SPWkL*2 zj3y_|d?5AyZ+0|m5X?d(XCF7OH7$9Y2)a0jq?ZR_aJp|=Ds6F^%6CcMlHIpJ7=}n4 zKEY6{#yZo7)Jh7rd;B&MaxX2Aba#MPOn(N(Y`AV$$?jo;k_SV>_V;p)5mN(0A7r^| zV9b3{A)iSf3*2`*A{4W(4o%*C8-*2fsQgA_e-=8dPXL6TtTa6?MimLp4?3}EyJ*BP z?~<@JX84R5Xd4U;TBicV)(j9U01~j2ZjP~w~<(TEP5m%P!O7iY^maAK5WPfW; z%dFOF?M54d+(n37%U7^lixt-yDuXl@R=Unpr*oudR$Al*#|EwfC3@)N61Y zE;7RVf;A|cBvN|9h)H)J%)pA6-xg9RF$lwF^}-*fU#7(hLNLTenKu*k9hjM>EGcGZ zS`e0Rac+(1elv_59XCPeG`;DOJB(3Z8&5z|+%BTZ;qmdo?sqcW-X%bh;$^6^Nw2IL zSgNM-iAghaCIzv|8K$b(%{I1_0CFQ&MBH=hOCxrbEy9p&|G2?){ptSz009600|295 JRZhg+002OR-`W5G