Inline webSocketInitializer
[netconf.git] / docs / user-guide.rst
index c96551096642052d2c5539c82da73285837e8450..d0b8b62a4685de602f6849483e3b8b39428cd988 100644 (file)
@@ -56,8 +56,10 @@ the device.**
 Netconf-connector configuration
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-There are 2 ways for configuring netconf-connector: NETCONF or RESTCONF.
-This guide focuses on using RESTCONF.
+NETCONF connectors are configured directly through the usage of the
+network-topology model. You can configure new NETCONF connectors both
+through the NETCONF server for MD-SAL (port 2830) or RESTCONF. This guide
+focuses on RESTCONF.
 
 .. important::
 
@@ -101,104 +103,171 @@ This guide focuses on using RESTCONF.
      which is related to `draft-bierman-netconf-restconf-02
      <https://tools.ietf.org/html/draft-bierman-netconf-restconf-02>`__.
 
+    Examples in the `Spawning new NETCONF connectors`_ section include both bierman02 and rfc8040
+    formats
 
+Preconditions
+^^^^^^^^^^^^^
 
+1. OpenDaylight is running
 
-Default configuration
-^^^^^^^^^^^^^^^^^^^^^
+2. In Karaf, you must have the ``odl-netconf-topology`` or
+   ``odl-netconf-clustered-topology`` feature installed.
 
-The default configuration contains all the necessary dependencies (file:
-01-netconf.xml) and a single instance of netconf-connector (file:
-99-netconf-connector.xml) called **controller-config** which connects
-itself to the NETCONF northbound in OpenDaylight in a loopback fashion.
-The connector mounts the NETCONF server for config-subsystem in order to
-enable RESTCONF protocol for config-subsystem. This RESTCONF still goes
-via NETCONF, but using RESTCONF is much more user friendly than using
-NETCONF.
+3. Feature ``odl-restconf`` must be installed
 
-Spawning additional netconf-connectors while the controller is running
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Spawning new NETCONF connectors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Preconditions:
+To create a new NETCONF connector you need to send the following PUT request
+to RESTCONF:
 
-1. OpenDaylight is running
+.. list-table::
+   :widths: 1 5
 
-2. In Karaf, you must have the netconf-connector installed (at the Karaf
-   prompt, type: ``feature:install odl-netconf-connector-all``); the
-   loopback NETCONF mountpoint will be automatically configured and
-   activated
+   * - bierman02
+     - http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/new-netconf-device
+   * - rfc8040
+     - http://localhost:8181/rests/data/network-topology:network-topology/topology=topology-netconf/node=new-netconf-device
 
-3. Wait until log displays following entry:
-   RemoteDevice{controller-config}: NETCONF connector initialized
-   successfully
+You could use the same body to create the new  NETCONF connector with a POST
+without specifying the node in the URL:
 
-To configure a new netconf-connector you need to send following request
-to RESTCONF:
+.. list-table::
+   :widths: 1 5
 
-POST
-http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules
+   * - bierman02
+     - http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf
+   * - rfc8040
+     - http://localhost:8181/rests/data/network-topology:network-topology/topology=topology-netconf
+
+Payload:
+
+.. tabs::
+
+   .. tab:: XML
+
+      **Content-type:** ``application/xml``
+
+      **Accept:** ``application/xml``
+
+      **Authentication:** ``admin:admin``
+
+      .. code-block:: xml
+
+         <node xmlns="urn:TBD:params:xml:ns:yang:network-topology">
+           <node-id>new-netconf-device</node-id>
+           <host xmlns="urn:opendaylight:netconf-node-topology">127.0.0.1</host>
+           <port xmlns="urn:opendaylight:netconf-node-topology">17830</port>
+           <username xmlns="urn:opendaylight:netconf-node-topology">admin</username>
+           <password xmlns="urn:opendaylight:netconf-node-topology">admin</password>
+           <tcp-only xmlns="urn:opendaylight:netconf-node-topology">false</tcp-only>
+           <!-- non-mandatory fields with default values, you can safely remove these if you do not wish to override any of these values-->
+           <reconnect-on-changed-schema xmlns="urn:opendaylight:netconf-node-topology">false</reconnect-on-changed-schema>
+           <connection-timeout-millis xmlns="urn:opendaylight:netconf-node-topology">20000</connection-timeout-millis>
+           <max-connection-attempts xmlns="urn:opendaylight:netconf-node-topology">0</max-connection-attempts>
+           <between-attempts-timeout-millis xmlns="urn:opendaylight:netconf-node-topology">2000</between-attempts-timeout-millis>
+           <sleep-factor xmlns="urn:opendaylight:netconf-node-topology">1.5</sleep-factor>
+           <!-- keepalive-delay set to 0 turns off keepalives-->
+           <keepalive-delay xmlns="urn:opendaylight:netconf-node-topology">120</keepalive-delay>
+         </node>
+
+   .. tab:: JSON
+
+      **Content-type:** ``application/json``
+
+      **Accept:** ``application/json``
+
+      **Authentication:** ``admin:admin``
+
+      .. code-block:: json
+
+         {
+             "node": [
+                 {
+                     "node-id": "new-netconf-device",
+                     "netconf-node-topology:port": 17830,
+                     "netconf-node-topology:reconnect-on-changed-schema": false,
+                     "netconf-node-topology:connection-timeout-millis": 20000,
+                     "netconf-node-topology:tcp-only": false,
+                     "netconf-node-topology:max-connection-attempts": 0,
+                     "netconf-node-topology:username": "admin",
+                     "netconf-node-topology:password": "admin",
+                     "netconf-node-topology:sleep-factor": 1.5,
+                     "netconf-node-topology:host": "127.0.0.1",
+                     "netconf-node-topology:between-attempts-timeout-millis": 2000,
+                     "netconf-node-topology:keepalive-delay": 120
+                 }
+             ]
+         }
+
+Note that the device name in <node-id> element must match the last
+element of the restconf URL.
+
+Reconfiguring an existing connector
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The steps to reconfigure an existing connector are exactly the same as
+when spawning a new connector. The old connection will be disconnected
+and a new connector with the new configuration will be created. This needs
+to be done with a PUT request because the node already exists. A POST
+request will fail for that reason.
+
+Additionally, a PATCH request can be used to modify an existing
+configuration. Currently, only yang-patch (`RFC-8072 <https://tools.ietf.org/html/rfc8072>`__)
+is supported. The URL would be the same as the above PUT examples.
+Using JSON for the body, the headers needed for the request would
+be:
 
 Headers:
 
--  Accept application/xml
+-  Accept: application/yang.patch-status+json
 
--  Content-Type application/xml
+-  Content-Type: application/yang.patch+json
+
+Example JSON payload to modify the password entry:
 
 ::
 
-    <module xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-      <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">prefix:sal-netconf-connector</type>
-      <name>new-netconf-device</name>
-      <address xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">127.0.0.1</address>
-      <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">830</port>
-      <username xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</username>
-      <password xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</password>
-      <tcp-only xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">false</tcp-only>
-      <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
-        <name>global-event-executor</name>
-      </event-executor>
-      <binding-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
-        <name>binding-osgi-broker</name>
-      </binding-registry>
-      <dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
-        <name>dom-broker</name>
-      </dom-registry>
-      <client-dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
-        <name>global-netconf-dispatcher</name>
-      </client-dispatcher>
-      <processing-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
-        <name>global-netconf-processing-executor</name>
-      </processing-executor>
-      <keepalive-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:scheduled-threadpool</type>
-        <name>global-netconf-ssh-scheduled-executor</name>
-      </keepalive-executor>
-    </module>
-
-This spawns a new netconf-connector which tries to connect to (or mount)
-a NETCONF device at 127.0.0.1 and port 830. You can check the
-configuration of config-subsystem’s configuration datastore. The new
-netconf-connector will now be present there. Just invoke:
+    {
+      "ietf-restconf:yang-patch" : {
+        "patch-id" : "0",
+        "edit" : [
+          {
+            "edit-id" : "edit1",
+            "operation" : "merge",
+            "target" : "",
+            "value" : {
+             "node": [
+                {
+                 "node-id": "new-netconf-device",
+                 "netconf-node-topology:password" : "newpassword"
+                }
+             ]
+            }
+         }
+        ]
+      }
+    }
 
-GET
-http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules
+Deleting an existing connector
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-The response will contain the module for new-netconf-device.
+To remove an already configured NETCONF connector you need to send a
+DELETE request to the same PUT request URL that was used to create the
+device:
 
-Right after the new netconf-connector is created, it writes some useful
-metadata into the datastore of MD-SAL under the network-topology
-subtree. This metadata can be found at:
+.. list-table::
+   :widths: 1 5
 
-GET
-http://localhost:8181/restconf/operational/network-topology:network-topology/
+   * - bierman02
+     - http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/new-netconf-device
+   * - rfc8040
+     - http://localhost:8181/rests/data/network-topology:network-topology/topology=topology-netconf/node=new-netconf-device
 
-Information about connection status, device capabilities, etc. can be
-found there.
+.. note::
+
+    No body is needed to delete the node/device
 
 Connecting to a device not supporting NETCONF monitoring
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -248,206 +317,76 @@ yang-module-capabilities and this attribute can contain a list of "YANG
 module based" capabilities. So 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 modify the
-configuration of netconf-connector by adding this XML (It needs to be
-added next to the address, port, username etc. configuration elements):
-
-::
-
-    <yang-module-capabilities xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-      <capability xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&amp;revision=2010-09-24
-      </capability>
-    </yang-module-capabilities>
+configuration of netconf-connector like in the example below:
+
+.. tabs::
+
+   .. tab:: XML
+
+      **Content-type:** ``application/xml``
+
+      **Accept:** ``application/xml``
+
+      **Authentication:** ``admin:admin``
+
+      .. code-block:: xml
+
+         <node xmlns="urn:TBD:params:xml:ns:yang:network-topology">
+           <node-id>r5</node-id>
+           <host xmlns="urn:opendaylight:netconf-node-topology">127.0.0.1</host>
+           <port xmlns="urn:opendaylight:netconf-node-topology">8305</port>
+           <username xmlns="urn:opendaylight:netconf-node-topology">root</username>
+           <password xmlns="urn:opendaylight:netconf-node-topology">root</password>
+           <tcp-only xmlns="urn:opendaylight:netconf-node-topology">false</tcp-only>
+           <keepalive-delay xmlns="urn:opendaylight:netconf-node-topology">30</keepalive-delay>
+           <yang-module-capabilities xmlns="urn:opendaylight:netconf-node-topology">
+             <override>true</override>
+             <capability xmlns="urn:opendaylight:netconf-node-topology">
+               urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&amp;revision=2013-07-15
+             </capability>
+           </yang-module-capabilities>
+         </node>
+
+   .. tab:: JSON
+
+      **Content-type:** ``application/json``
+
+      **Accept:** ``application/json``
+
+      **Authentication:** ``admin:admin``
+
+      .. code-block:: json
+
+         {
+             "node": [
+                 {
+                     "node-id": "device",
+                     "netconf-node-topology:host": "127.0.0.1",
+                     "netconf-node-topology:password": "root",
+                     "netconf-node-topology:username": "root",
+                     "netconf-node-topology:yang-module-capabilities": {
+                         "override": true,
+                         "capability": [
+                             "urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2013-07-15"
+                         ]
+                     },
+                     "netconf-node-topology:port": 8305,
+                     "netconf-node-topology:tcp-only": false,
+                     "netconf-node-topology:keepalive-delay": 30
+                 }
+             ]
+         }
 
 **Remember to also put the YANG schemas into the cache folder.**
 
 .. note::
 
     For putting multiple capabilities, you just need to replicate the
-    capability xml element inside yang-module-capability element.
+    capability element inside yang-module-capability element.
     Capability element is modeled as a leaf-list. With this
     configuration, we would make the remote device report usage of
     ietf-inet-types in the eyes of netconf-connector.
 
-Reconfiguring Netconf-Connector While the Controller is Running
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-It is possible to change the configuration of a running module while the
-whole controller is running. This example will continue where the last
-left off and will change the configuration for the brand new
-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:
-
-PUT
-http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules/module/odl-sal-netconf-connector-cfg:sal-netconf-connector/new-netconf-device
-
-::
-
-    <module xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-      <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">prefix:sal-netconf-connector</type>
-      <name>new-netconf-device</name>
-      <username xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">bob</username>
-      <password xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">passwd</password>
-      <tcp-only xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">false</tcp-only>
-      <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
-        <name>global-event-executor</name>
-      </event-executor>
-      <binding-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
-        <name>binding-osgi-broker</name>
-      </binding-registry>
-      <dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
-        <name>dom-broker</name>
-      </dom-registry>
-      <client-dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
-        <name>global-netconf-dispatcher</name>
-      </client-dispatcher>
-      <processing-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
-        <name>global-netconf-processing-executor</name>
-      </processing-executor>
-      <keepalive-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:scheduled-threadpool</type>
-        <name>global-netconf-ssh-scheduled-executor</name>
-      </keepalive-executor>
-    </module>
-
-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 new-netconf-device will be reconfigured to use username bob and
-password passwd. New configuration can be verified by executing:
-
-GET
-http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules/module/odl-sal-netconf-connector-cfg:sal-netconf-connector/new-netconf-device
-
-With new configuration, the old connection will be closed and a new one
-established.
-
-Destroying Netconf-Connector While the Controller is Running
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Using RESTCONF one can also destroy an instance of a module. In case of
-netconf-connector, the module will be destroyed, NETCONF connection
-dropped and all resources will be cleaned. To do this, simply issue a
-request to following URL:
-
-DELETE
-http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules/module/odl-sal-netconf-connector-cfg:sal-netconf-connector/new-netconf-device
-
-The last element of the URL is the name of the instance and its
-predecessor is the type of that module (In our case the type is
-**sal-netconf-connector** and name **new-netconf-device**). The type and
-name are actually the keys of the module list.
-
-Netconf-connector configuration with MD-SAL
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-It is also possible to configure new NETCONF connectors directly through
-MD-SAL with the usage of the network-topology model. You can configure
-new NETCONF connectors both through the NETCONF server for MD-SAL (port
-2830) or RESTCONF. This guide focuses on RESTCONF.
-
-.. tip::
-
-    To enable NETCONF connector configuration through MD-SAL install
-    either the ``odl-netconf-topology`` or
-    ``odl-netconf-clustered-topology`` feature. We will explain the
-    difference between these features later.
-
-Preconditions
-^^^^^^^^^^^^^
-
-1. OpenDaylight is running
-
-2. In Karaf, you must have the ``odl-netconf-topology`` or
-   ``odl-netconf-clustered-topology`` feature installed.
-
-3. Feature ``odl-restconf`` must be installed
-
-4. Wait until log displays following entry:
-
-   ::
-
-       Successfully pushed configuration snapshot 02-netconf-topology.xml(odl-netconf-topology,odl-netconf-topology)
-
-   or until
-
-   ::
-
-       GET http://localhost:8181/restconf/operational/network-topology:network-topology/topology/topology-netconf/
-
-   returns a non-empty response, for example:
-
-   ::
-
-       <topology xmlns="urn:TBD:params:xml:ns:yang:network-topology">
-         <topology-id>topology-netconf</topology-id>
-       </topology>
-
-Spawning new NETCONF connectors
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-To create a new NETCONF connector you need to send the following request
-to RESTCONF:
-
-::
-
-    PUT http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/new-netconf-device
-
-Headers:
-
--  Accept: application/xml
-
--  Content-Type: application/xml
-
-Payload:
-
-::
-
-    <node xmlns="urn:TBD:params:xml:ns:yang:network-topology">
-      <node-id>new-netconf-device</node-id>
-      <host xmlns="urn:opendaylight:netconf-node-topology">127.0.0.1</host>
-      <port xmlns="urn:opendaylight:netconf-node-topology">17830</port>
-      <username xmlns="urn:opendaylight:netconf-node-topology">admin</username>
-      <password xmlns="urn:opendaylight:netconf-node-topology">admin</password>
-      <tcp-only xmlns="urn:opendaylight:netconf-node-topology">false</tcp-only>
-      <!-- non-mandatory fields with default values, you can safely remove these if you do not wish to override any of these values-->
-      <reconnect-on-changed-schema xmlns="urn:opendaylight:netconf-node-topology">false</reconnect-on-changed-schema>
-      <connection-timeout-millis xmlns="urn:opendaylight:netconf-node-topology">20000</connection-timeout-millis>
-      <max-connection-attempts xmlns="urn:opendaylight:netconf-node-topology">0</max-connection-attempts>
-      <between-attempts-timeout-millis xmlns="urn:opendaylight:netconf-node-topology">2000</between-attempts-timeout-millis>
-      <sleep-factor xmlns="urn:opendaylight:netconf-node-topology">1.5</sleep-factor>
-      <!-- keepalive-delay set to 0 turns off keepalives-->
-      <keepalive-delay xmlns="urn:opendaylight:netconf-node-topology">120</keepalive-delay>
-    </node>
-
-Note that the device name in <node-id> element must match the last
-element of the restconf URL.
-
-Reconfiguring an existing connector
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The steps to reconfigure an existing connector are exactly the same as
-when spawning a new connector. The old connection will be disconnected
-and a new connector with the new configuration will be created.
-
-Deleting an existing connector
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-To remove an already configured NETCONF connector you need to send the
-following:
-
-::
-
-    DELETE http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/new-netconf-device
-
 Connecting to a device supporting only NETCONF 1.0
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -506,7 +445,7 @@ developers can be found in the developers guide or in the official
 tutorial application **ncmount** that can be found in the coretutorials
 project:
 
--  https://github.com/opendaylight/coretutorials/tree/stable/beryllum/ncmount
+-  https://github.com/opendaylight/coretutorials/tree/master/ncmount
 
 Reading data from the device
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -862,12 +801,6 @@ particular mount point.
 NETCONF Call Home
 -----------------
 
-.. important::
-
-    The call home feature is experimental and will change in a future
-    release. In particular, the Yang models will change to those specified
-    in the `RFC 8071 <https://tools.ietf.org/html/rfc8071>`__
-
 Call Home Installation
 ~~~~~~~~~~~~~~~~~~~~~~
 
@@ -882,8 +815,10 @@ configuring Call Home & testing its functionality.
 
 .. note::
 
-    In order to test Call Home functionality we recommend Netopeer.
-    See `Netopeer Call Home <https://github.com/CESNET/netopeer/wiki/CallHome>`__ to learn how to enable call-home on Netopeer.
+    In order to test Call Home functionality we recommend Netopeer or
+    Netopeer2. See `Netopeer Call Home <https://github.com/CESNET/netopeer/wiki/CallHome>`__
+    or `Netopeer2 <https://github.com/CESNET/netopeer2>`__ to learn how to
+    enable call-home on Netopeer.
 
 Northbound Call-Home API
 ~~~~~~~~~~~~~~~~~~~~~~~~
@@ -894,12 +829,16 @@ following describes this configuration.
 Global Configuration
 ^^^^^^^^^^^^^^^^^^^^
 
+.. important::
+  The global configuration is not a part of the `RFC 8071
+  <https://tools.ietf.org/html/rfc8071>`__ and, therefore, subject to change.
+
 Configuring global credentials
 ''''''''''''''''''''''''''''''
 
-ODL Call-Home server allows user to configure global credentials, which
-will be used for devices which does not have device-specific credentials
-configured.
+ODL Call-Home server allows user to configure global credentials, which will be
+used for connected over SSH transport protocol devices which does not have
+device-specific credentials configured.
 
 This is done by creating
 ``/odl-netconf-callhome-server:netconf-callhome-server/global/credentials``
@@ -907,7 +846,7 @@ with username and passwords specified.
 
 *Configuring global username & passwords to try*
 
-.. code-block:: none
+.. code-block::
 
     PUT
     /restconf/config/odl-netconf-callhome-server:netconf-callhome-server/global/credentials HTTP/1.1
@@ -944,7 +883,7 @@ This is a debug feature and should not be used in production. Besides being an o
 security issue, this also causes the Call-Home Server to drastically increase its output
 to the log.
 
-.. code-block:: none
+.. code-block::
 
     POST
     /restconf/config/odl-netconf-callhome-server:netconf-callhome-server/global HTTP/1.1
@@ -962,8 +901,12 @@ to the log.
 Device-Specific Configuration
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Allowing Device & Configuring Name
-''''''''''''''''''''''''''''''''''
+Netconf Call Home server supports both of the secure transports used
+by the Network Configuration Protocol (NETCONF) - Secure Shell (SSH),
+and Transport Layer Security (TLS).
+
+Configure device to connect over SSH protocol
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Netconf Call Home Server uses device provided SSH server key (host key)
 to identify device. The pairing of name and server key is configured in
@@ -976,9 +919,76 @@ not found, the connection between the Call Home server and the device is dropped
 immediately. In either case, the device that connects to the Call home server
 leaves a record of its presence in the operational store.
 
+Configuring Device with Device-specific Credentials
+'''''''''''''''''''''''''''''''''''''''''''''''''''
+
+Adding specific device to the allowed list is done by creating
+``/odl-netconf-callhome-server:netconf-callhome-server/allowed-devices/device/{device}``
+with device-id and connection parameters inside the ssh-client-params container.
+
+*Configuring Device with Credentials*
+
+.. code-block::
+
+    PUT
+    /restconf/config/odl-netconf-callhome-server:netconf-callhome-server/allowed-devices/device/example HTTP/1.1
+    Content-Type: application/json
+    Accept: application/json
+
+.. code-block:: json
+
+    {
+      "device": {
+        "unique-id": "example",
+        "ssh-client-params": {
+          "credentials": {
+            "username": "example",
+            "passwords": [ "password" ]
+          },
+          "ssh-host-key": "AAAAB3NzaC1yc2EAAAADAQABAAABAQDHoH1jMjltOJnCt999uaSfc48ySutaD3ISJ9fSECe1Spdq9o9mxj0kBTTTq+2V8hPspuW75DNgN+V/rgJeoUewWwCAasRx9X4eTcRrJrwOQKzb5Fk+UKgQmenZ5uhLAefi2qXX/agFCtZi99vw+jHXZStfHm9TZCAf2zi+HIBzoVksSNJD0VvPo66EAvLn5qKWQD4AdpQQbKqXRf5/W8diPySbYdvOP2/7HFhDukW8yV/7ZtcywFUIu3gdXsrzwMnTqnATSLPPuckoi0V2jd8dQvEcu1DY+rRqmqu0tEkFBurlRZDf1yhNzq5xWY3OXcjgDGN+RxwuWQK3cRimcosH"
+        }
+      }
+    }
+
+Configuring Device with Global Credentials
+'''''''''''''''''''''''''''''''''''''''''''''''''''
+
+It is possible to omit 'username' and 'password' for ssh-client-params,
+in such case values from global credentials will be used.
+
 *Example of configuring device*
 
-.. code-block:: none
+.. code-block::
+
+    PUT
+    /restconf/config/odl-netconf-callhome-server:netconf-callhome-server/allowed-devices/device/example HTTP/1.1
+    Content-Type: application/json
+    Accept: application/json
+
+.. code-block:: json
+
+    {
+      "device": {
+        "unique-id": "example",
+        "ssh-client-params": {
+          "host-key": "AAAAB3NzaC1yc2EAAAADAQABAAABAQDHoH1jMjltOJnCt999uaSfc48ySutaD3ISJ9fSECe1Spdq9o9mxj0kBTTTq+2V8hPspuW75DNgN+V/rgJeoUewWwCAasRx9X4eTcRrJrwOQKzb5Fk+UKgQmenZ5uhLAefi2qXX/agFCtZi99vw+jHXZStfHm9TZCAf2zi+HIBzoVksSNJD0VvPo66EAvLn5qKWQD4AdpQQbKqXRf5/W8diPySbYdvOP2/7HFhDukW8yV/7ZtcywFUIu3gdXsrzwMnTqnATSLPPuckoi0V2jd8dQvEcu1DY+rRqmqu0tEkFBurlRZDf1yhNzq5xWY3OXcjgDGN+RxwuWQK3cRimcosH"
+        }
+      }
+    }
+
+Deprecated configuration models for devices accessed with SSH protocol
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+With `RFC 8071 <https://tools.ietf.org/html/rfc8071>`__ alignment and adding
+support for TLS transport following configuration models has been marked
+deprecated.
+
+Configuring Device with Global Credentials
+'''''''''''''''''''''''''''''''''''''''''''''''''''
+
+*Example of configuring device*
+
+.. code-block::
 
     PUT
     /restconf/config/odl-netconf-callhome-server:netconf-callhome-server/allowed-devices/device/example HTTP/1.1
@@ -1003,7 +1013,7 @@ device-specific configuration. Format is same as in global credentials.
 
 *Configuring Device with Credentials*
 
-.. code-block:: none
+.. code-block::
 
     PUT
     /restconf/config/odl-netconf-callhome-server:netconf-callhome-server/allowed-devices/device/example HTTP/1.1
@@ -1023,6 +1033,117 @@ device-specific configuration. Format is same as in global credentials.
       }
     }
 
+Configure device to connect over TLS protocol
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Netconf Call Home Server allows devices to use TLS transport protocol to
+establish a connection towards the NETCONF device. This communication
+requires proper setup to make two-way TLS authentication possible for client
+and server.
+
+The initial step is to configure certificates and keys for two-way TLS by
+storing them within the netconf-keystore.
+
+*Adding a client private key credential to the netconf-keystore*
+
+.. code-block::
+
+    POST
+    /rests/operations/netconf-keystore:add-keystore-entry HTTP/1.1
+    Content-Type: application/json
+    Accept: application/json
+
+.. code-block:: json
+
+  {
+    "input": {
+      "key-credential": [
+        {
+          "key-id": "example-client-key-id",
+          "private-key": "base64encoded-private-key",
+          "passphrase": "passphrase"
+        }
+      ]
+    }
+  }
+
+*Associate a private key with a client and CA certificates chain*
+
+.. code-block::
+
+    POST
+    /rests/operations/netconf-keystore:add-private-key HTTP/1.1
+    Content-Type: application/json
+    Accept: application/json
+
+.. code-block:: json
+
+  {
+    "input": {
+      "private-key": [
+        {
+          "name": "example-client-key-id",
+          "data": "key-data",
+          "certificate-chain": [
+            "certificate-data"
+          ]
+        }
+      ]
+    }
+  }
+
+*Add a list of trusted CA and server certificates*
+
+.. code-block::
+
+    POST
+    /rests/operations/netconf-keystore:add-trusted-certificate HTTP/1.1
+    Content-Type: application/json
+    Accept: application/json
+
+.. code-block:: json
+
+  {
+    "input": {
+      "trusted-certificate": [
+        {
+          "name": "example-ca-certificate",
+          "certificate": "ca-certificate-data"
+        },
+        {
+          "name": "example-server-certificate",
+          "certificate": "server-certificate-data"
+        }
+      ]
+    }
+  }
+
+In a second step, it is required to create an allowed device associated with
+a server certificate and client key. The server certificate will be used to
+identify and pin the NETCONF device during SSL handshake and should be unique
+among the allowed devices.
+
+*Add device configuration for TLS protocol to allowed devices list*
+
+.. code-block::
+
+    PUT
+    /restconf/config/odl-netconf-callhome-server:netconf-callhome-server/allowed-devices/device/example-device HTTP/1.1
+    Content-Type: application/json
+    Accept: application/json
+
+.. code-block:: json
+
+  {
+    "device": {
+      "unique-id": "example-device",
+      "tls-client-params": {
+        "key-id": "example-client-key-id",
+        "certificate-id": "example-server-certificate"
+      }
+    }
+  }
+
 Operational Status
 ^^^^^^^^^^^^^^^^^^
 
@@ -1070,3 +1191,378 @@ blueprint configuration file.
 The device **must** initiate the connection and the server will not try to re-establish the
 connection in case of a drop. By requirement, the server cannot assume it has connectivity
 to the device due to NAT or firewalls among others.
+
+Reading data with selected fields
+---------------------------------
+
+Overview
+~~~~~~~~
+
+If user would like to read only selected fields from NETCONF device, it is possible to use
+fields query parameter that is described by RFC-8040. RESTCONF parses content of query
+parameter into format that is accepted by NETCONF subtree filtering - filtering of data is done
+on NETCONF server, not on NETCONF client side. This approach optimizes network traffic load,
+because data in which user doesn't have interest, is not transferred over network.
+
+Next advantages:
+
+* using single RESTCONF request and single NETCONF RPC for reading multiple subtrees
+* possibility to read only selected fields under list node across multiple hierarchies
+  (it cannot be done without proper selection API)
+
+.. note::
+
+  More information about fields query parameter: `RFC 8071 <https://tools.ietf.org/html/rfc8040#section-4.8.3>`__
+
+Preparation of data
+~~~~~~~~~~~~~~~~~~~
+
+Mounting NETCONF device that runs on NETCONF testtool:
+
+.. code-block:: bash
+
+  curl --location --request PUT 'http://127.0.0.1:8181/rests/data/network-topology:network-topology/topology=topology-netconf/node=testtool' \
+  --header 'Authorization: Basic YWRtaW46YWRtaW4=' \
+  --header 'Content-Type: application/json' \
+  --data-raw '{
+      "node": [
+          {
+              "node-id": "testtool",
+              "netconf-node-topology:host": "127.0.0.1",
+              "netconf-node-topology:port": 36000,
+              "netconf-node-topology:keepalive-delay": 100,
+              "netconf-node-topology:tcp-only": false,
+              "netconf-node-topology:username": "admin",
+              "netconf-node-topology:password": "admin"
+          }
+      ]
+  }'
+
+Setting initial configuration on NETCONF device:
+
+.. code-block:: bash
+
+  curl --location --request PUT 'http://127.0.0.1:8181/rests/data/network-topology:network-topology/topology=topology-netconf/node=testtool/yang-ext:mount/test-module:root' \
+  --header 'Authorization: Basic YWRtaW46YWRtaW4=' \
+  --header 'Content-Type: application/json' \
+  --data-raw '{
+      "root": {
+          "simple-root": {
+              "leaf-a": "asddhg",
+              "leaf-b": "ffffff",
+              "ll": [
+                  "str1",
+                  "str2",
+                  "str3"
+              ],
+              "nested": {
+                  "sample-x": true,
+                  "sample-y": false
+              }
+          },
+          "list-root": {
+              "branch-ab": 5,
+              "top-list": [
+                  {
+                      "key-1": "ka",
+                      "key-2": "kb",
+                      "next-data": {
+                          "switch-1": [
+                              null
+                          ],
+                          "switch-2": [
+                              null
+                          ]
+                      },
+                      "nested-list": [
+                          {
+                              "identifier": "f1",
+                              "foo": 1
+                          },
+                          {
+                              "identifier": "f2",
+                              "foo": 10
+                          },
+                          {
+                              "identifier": "f3",
+                              "foo": 20
+                          }
+                      ]
+                  },
+                  {
+                      "key-1": "kb",
+                      "key-2": "ka",
+                      "next-data": {
+                          "switch-1": [
+                              null
+                          ]
+                      },
+                      "nested-list": [
+                          {
+                              "identifier": "e1",
+                              "foo": 1
+                          },
+                          {
+                              "identifier": "e2",
+                              "foo": 2
+                          },
+                          {
+                              "identifier": "e3",
+                              "foo": 3
+                          }
+                      ]
+                  },
+                  {
+                      "key-1": "kc",
+                      "key-2": "ke",
+                      "next-data": {
+                          "switch-2": [
+                              null
+                          ]
+                      },
+                      "nested-list": [
+                          {
+                              "identifier": "q1",
+                              "foo": 13
+                          },
+                          {
+                              "identifier": "q2",
+                              "foo": 14
+                          },
+                          {
+                              "identifier": "q3",
+                              "foo": 15
+                          }
+                      ]
+                  }
+              ]
+          }
+      }
+  }'
+
+Examples
+--------
+
+1. Reading whole leaf-list 'll' and leaf 'nested/sample-x' under 'simple-root' container.
+
+RESTCONF request:
+
+.. code-block:: bash
+
+    curl --location --request GET 'http://localhost:8181/rests/data/network-topology:network-topology/topology=topology-netconf/node=testtool/yang-ext:mount/test-module:root/simple-root?content=config&fields=ll;nested/sample-x' \
+    --header 'Authorization: Basic YWRtaW46YWRtaW4=' \
+    --header 'Cookie: JSESSIONID=node01h4w82eorc1k61866b71qjgj503.node0'
+
+Generated NETCONF RPC request:
+
+.. code-block:: xml
+
+    <rpc message-id="m-18" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+        <get-config>
+            <source>
+                <running/>
+            </source>
+            <filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree">
+                <root xmlns="urn:ietf:params:xml:ns:yang:test-model">
+                    <simple-root>
+                        <ll/>
+                        <nested>
+                            <sample-x/>
+                        </nested>
+                    </simple-root>
+                </root>
+            </filter>
+        </get-config>
+    </rpc>
+
+.. note::
+
+    Using fields query parameter it is also possible to read whole leaf-list or list without
+    necessity to specify value / key predicate (without reading parent entity). Such scenario
+    is not permitted in RFC-8040 paths alone - fields query parameter can be used as
+    workaround for this case.
+
+RESTCONF response:
+
+.. code-block:: json
+
+    {
+        "test-module:simple-root": {
+            "ll": [
+                "str3",
+                "str1",
+                "str2"
+            ],
+            "nested": {
+                "sample-x": true
+            }
+        }
+    }
+
+2. Reading all identifiers of 'nested-list' under all elements of 'top-list'.
+
+RESTCONF request:
+
+.. code-block:: bash
+
+    curl --location --request GET 'http://localhost:8181/rests/data/network-topology:network-topology/topology=topology-netconf/node=testtool/yang-ext:mount/test-module:root/list-root?content=config&fields=top-list(nested-list/identifier)' \
+    --header 'Authorization: Basic YWRtaW46YWRtaW4=' \
+    --header 'Cookie: JSESSIONID=node01h4w82eorc1k61866b71qjgj503.node0'
+
+Generated NETCONF RPC request:
+
+.. code-block:: xml
+
+    <rpc message-id="m-27" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+        <get-config>
+            <source>
+                <running/>
+            </source>
+            <filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree">
+                <root xmlns="urn:ietf:params:xml:ns:yang:test-model">
+                    <list-root>
+                        <top-list>
+                            <nested-list>
+                                <identifier/>
+                            </nested-list>
+                            <key-1/>
+                            <key-2/>
+                        </top-list>
+                    </list-root>
+                </root>
+            </filter>
+        </get-config>
+    </rpc>
+
+.. note::
+
+    NETCONF client automatically fetches values of list keys since they are required for correct
+    deserialization of NETCONF response and at the end serialization of response to RESTCONF
+    response (JSON/XML).
+
+RESTCONF response:
+
+.. code-block:: json
+
+    {
+        "test-module:list-root": {
+            "top-list": [
+                {
+                    "key-1": "ka",
+                    "key-2": "kb",
+                    "nested-list": [
+                        {
+                            "identifier": "f3"
+                        },
+                        {
+                            "identifier": "f2"
+                        },
+                        {
+                            "identifier": "f1"
+                        }
+                    ]
+                },
+                {
+                    "key-1": "kb",
+                    "key-2": "ka",
+                    "nested-list": [
+                        {
+                            "identifier": "e3"
+                        },
+                        {
+                            "identifier": "e2"
+                        },
+                        {
+                            "identifier": "e1"
+                        }
+                    ]
+                },
+                {
+                    "key-1": "kc",
+                    "key-2": "ke",
+                    "nested-list": [
+                        {
+                            "identifier": "q3"
+                        },
+                        {
+                            "identifier": "q2"
+                        },
+                        {
+                            "identifier": "q1"
+                        }
+                    ]
+                }
+            ]
+        }
+    }
+
+3. Reading value of leaf 'branch-ab' and all values of leaves 'switch-1' that are placed
+   under 'top-list' list elements.
+
+RESTCONF request:
+
+.. code-block:: bash
+
+    curl --location --request GET 'http://localhost:8181/rests/data/network-topology:network-topology/topology=topology-netconf/node=testtool/yang-ext:mount/test-module:root/list-root?content=config&fields=branch-ab;top-list/next-data/switch-1' \
+    --header 'Authorization: Basic YWRtaW46YWRtaW4=' \
+    --header 'Cookie: JSESSIONID=node01jx6o5thwae9t1ft7c2zau5zbz4.node0'
+
+Generated NETCONF RPC request:
+
+.. code-block:: xml
+
+    <rpc message-id="m-42" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+        <get-config>
+            <source>
+                <running/>
+            </source>
+            <filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree">
+                <root xmlns="urn:ietf:params:xml:ns:yang:test-model">
+                    <list-root>
+                        <branch-ab/>
+                        <top-list>
+                            <next-data>
+                                <switch-1/>
+                            </next-data>
+                            <key-1/>
+                            <key-2/>
+                        </top-list>
+                    </list-root>
+                </root>
+            </filter>
+        </get-config>
+    </rpc>
+
+RESTCONF response:
+
+.. code-block:: json
+
+    {
+        "test-module:list-root": {
+            "branch-ab": 5,
+            "top-list": [
+                {
+                    "key-1": "ka",
+                    "key-2": "kb",
+                    "next-data": {
+                        "switch-1": [
+                            null
+                        ]
+                    }
+                },
+                {
+                    "key-1": "kb",
+                    "key-2": "ka",
+                    "next-data": {
+                        "switch-1": [
+                            null
+                        ]
+                    }
+                },
+                {
+                    "key-1": "kc",
+                    "key-2": "ke"
+                }
+            ]
+        }
+    }