Building a Kea testbed with NETCONF
  • 08 Aug 2024
  • 13 Minutes to read
  • Contributors
  • Dark
    Light
  • PDF

Building a Kea testbed with NETCONF

  • Dark
    Light
  • PDF

Article summary

NETCONF is a protocol defined by the IETF to “install, manipulate, and delete the configuration of network devices.” That sounds quite reasonable, but the installation is a bit more complex than it appears at first.

This article provides detailed instructions allowing a system administrator to install Kea, Sysrepo, and Netopeer2, for testing and proof-of-concept.

The base operating system is Ubuntu 24.04, but the same procedure should work with only minor changes on nearly all Linux distributions.

Please note that in the following examples, a "Demo User" with the username demouser is used. The userid is not a de-mouser for getting rid of rodents.

Most of the text in grey boxes:

shell commands here

can be selected and pasted into the Linux shell. Beware that there are some locations that use the ~demouser shell expansion; if you do not use the same username, the results will not be as expected.

If the text in the grey box is preceded by a dollar sign ($), the command is shown, followed by the output. For example:

$ ls
libnetconf2   libssh-0.8.6.tar.gz  Netopeer2-0.7-r1  v0.16-r3.tar.gz  v0.7-r1.tar.gz    v0.7-r1.tar.gz.2  zlib-1.2.11.tar.xz
libssh-0.8.6  libyang-0.16-r3      sysrepo-0.7.7     v0.7.8.tar.gz    v0.7-r1.tar.gz.1  zlib-1.2.11

This shows that the ls command was executed, and the following two lines were sample output.

Getting started

It is recommended that you do this work in a new, pristine working directory.

mkdir ~demouser/KeaNetconf
cd ~demouser/KeaNetconf

Installation

The software installs following this message are all done by building from source code. To ensure easy removal and reinstallation, especially in the event that Kea moves to other dependency versions, they are installed in custom directories.

Dependencies

The first thing to do is confirm that dependencies are met. Installing these from maintained repositories means that they can be upgraded automatically:

sudo apt-get install \
  autoconf automake bison cmake flex gcc g++ git gnupg \
  libboost-system-dev libpcap-dev libtool libssl-dev \
  liblog4cplus-dev make

Sysrepo and Netopeer are fast evolving projects that often break compatibility, with no stable releases.
Kea pins its NETCONF dependencies to ensure reliable behavior.
As of Kea 2.4.0, the versions for these dependencies are pinned as follows:

  • libyang v2.1.4
  • sysrepo v2.2.12
  • libyang-cpp v1.1.0 (git commit ae7d649ea75da081725c119dd553b2ef3121a6f8)
  • sysrepo-cpp v1.1.0 (git commit 02634174ffc60568301c3d9b9b7cf710cff6a586)
  • netopeer2 v2.2.28

libyang

libyang is a YANG (data modeling language for the definition of data sent over the NETCONF network configuration protocol) parser and toolkit written (and providing API) in C.
libyang is required by netopeer2 and sysrepo.

git clone https://github.com/CESNET/libyang.git
pushd libyang
git checkout v2.1.4
mkdir -p ./build
pushd ./build
cmake ..                                                \
  -DCMAKE_C_FLAGS='-Wno-incompatible-pointer-types'     \
  -DCMAKE_INSTALL_PREFIX='/opt/libyang'
make
sudo make install
popd
git clone https://github.com/CESNET/libyang-cpp.git
pushd libyang-cpp
git checkout ae7d649ea75da081725c119dd553b2ef3121a6f8
git apply <<EOF
diff --git a/src/Context.cpp b/src/Context.cpp
index b2fe887..add11cc 100644
--- a/src/Context.cpp
+++ b/src/Context.cpp
@@ -13,2 +13,3 @@
 #include <libyang/libyang.h>
+#include <algorithm>
 #include <span>
EOF
mkdir -p ./build
pushd ./build
export CMAKE_PREFIX_PATH='/opt/libyang'
cmake ..                                                \
  -DBUILD_TESTING=OFF                                   \
  -DCMAKE_INSTALL_PREFIX='/opt/libyang-cpp'
make
sudo make install
popd

sysrepo

sysrepo is a YANG-based configuration and operational state data store for Unix/Linux applications. As of the publication of this article, the newest version of sysrepo is 0.7.7.

git clone https://github.com/sysrepo/sysrepo.git
pushd sysrepo
git checkout v2.2.12
mkdir -p ./build
pushd ./build
export CMAKE_PREFIX_PATH='/opt/libyang'
cmake ..                                                \
  -DREPO_PATH='/etc/sysrepo'                            \
  -DCMAKE_INSTALL_PREFIX='/opt/sysrepo'
make
sudo make install
popd
git clone https://github.com/sysrepo/sysrepo-cpp.git
pushd sysrepo-cpp
git checkout 02634174ffc60568301c3d9b9b7cf710cff6a586
mkdir -p ./build
pushd ./build
export CMAKE_PREFIX_PATH='/opt/libyang:/opt/libyang-cpp:/opt/sysrepo'
cmake ..                                                \
  -DBUILD_TESTING=OFF                                   \
  -DCMAKE_INSTALL_PREFIX='/opt/sysrepo-cpp'
make
sudo make install
popd

zlib

The compression library zlib is required by netopeer2.
Note that this could probably be installed via apt-get, but following these instructions makes sure that you get the 1.2.11 version:

wget http://www.zlib.net/zlib-1.2.11.tar.xz && \
  tar -xf zlib-1.2.11.tar.xz && \
  rm zlib-1.2.11.tar.xz && \
  pushd zlib-1.2.11 && mkdir build && cd build && \
  cmake .. && \
  make && \
  sudo make install && \
  popd

libssh

You will need to install a recent version of libssh.
Unfortunately, many repositories run significantly behind, so this installs the latest (as of the publication of this KB article):

wget https://git.libssh.org/projects/libssh.git/snapshot/libssh-0.8.6.tar.gz && \
  tar -xf libssh-0.8.6.tar.gz && \
  rm libssh-0.8.6.tar.gz && \
 pushd libssh-0.8.6 && mkdir build && cd build && \
  cmake .. && \
  make && \
  sudo make install && \
  popd

libnetconf2

libnetconf2 is a NETCONF library in C intended for building NETCONF clients and servers.
The following instructions install libnetconf2 from GitHub. Unfortunately, we need a specific commit at this time:

git clone https://github.com/CESNET/libnetconf2.git && \
  pushd libnetconf2 && \
  git checkout 526f9f8d09b415a7df1cba4b5dcfc4705ad6f29b && \
  mkdir build && cd build && \
  cmake .. && \
  make && \
  sudo make install && \
  popd

netopeer2

netopeer2 is a second-generation set of tools which implement network configuration tools based on the NETCONF protocol.

The netopeer daemon will be started during installation, so ldconfig must be run to ensure that the previously installed libraries are available.

ldconfig
wget https://github.com/CESNET/Netopeer2/archive/v0.7-r1.tar.gz && \
  tar -xf v0.7-r1.tar.gz && \
  rm v0.7-r1.tar.gz && \
  pushd Netopeer2-0.7-r1 && \
  cd keystored && mkdir build && cd build && \
  cmake .. && \
  make && \
  sudo make install && \
  cd ../../server && mkdir build && cd build && \
  cmake .. && \
  make && \
  sudo make install && \
  cd ../../cli/ && mkdir build && cd build && \
  cmake .. && \
  make && \
  sudo make install && \
  popd

CONFIGURATION

To ensure that all libraries that have been installed are now available, execute:

sudo ldconfig

Testing

The simplest check to see if netopeer2-server is installed correctly is to run it with the -h (help) option:

$ netopeer2-server -h
Usage: netopeer2-server [-dhV] [-v level] [-c category]
 -d                  debug mode (do not daemonize and print
                     verbose messages to stderr instead of syslog)
 -h                  display help
 -V                  show program version
 -v level            verbose output level:
                         0 - errors
                         1 - errors and warnings
                         2 - errors, warnings and verbose messages
 -c category[,category]*  verbose debug level, print only these debug message categories
 categories: DICT, YANG, YIN, XPATH, DIFF, MSG, EDIT_CONFIG, SSH, SYSREPO

Similarly, confirm that netopeer2-cli is installed and functional:

$ netopeer2-cli
get_netconf_dir: Configuration directory "/home/demouser/.netopeer2-cli" did not exist, created.
load_config: No saved history.
load_config: No saved configuration.
> ^D

You should confirm that sysrepo is installed and runnable:

$ sysrepoctl -l
Sysrepo schema directory: /etc/sysrepo/yang/
Sysrepo data directory:   /etc/sysrepo/data/
(Do not alter the contents of these directories manually)

Module Name                | Revision   | Conformance | Data Owner          | Permissions | Submodules                    | Enabled Features
-----------------------------------------------------------------------------------------------------------------------------------------------
ietf-netconf-notifications | 2012-02-06 | Installed   | root:root           | 666         |                               |
ietf-netconf               | 2011-06-01 | Installed   | root:root           | 666         |                               | writable-running candidate rollback-on-error validate startup xpath
ietf-netconf-acm           | 2018-02-14 | Imported    |                     |             |                               |
nc-notifications           | 2008-07-14 | Installed   | root:root           | 666         |                               |
[...]

Configuring Netopeer2

To authenticate to the netopeer2 daemon, you will need a set of SSH credentials (public/private keypair). It is highly recommended that you create a separate set of credentials from those that you use elsewhere:

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/demouser/.ssh/id_rsa): /home/demouser/.ssh/demouser_net
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/demouser/.ssh/demouser_net.
Your public key has been saved in /home/demouser/.ssh/demouser_net.pub.
The key fingerprint is:
SHA256:g2bNYVLYKRE7[...]NUP8hEbot0 demouser@ubuntu
The key's randomart image is:
+---[RSA 2048]----+
|     .+=..       |
|   .o=Eoo        |
|  o.=+B.o        |
| . + E.B .       |
|  . o.B.S        |
|o.o o+o. .       |
|** + o           |
|BoB   .          |
|o*.o..           |
+----[SHA256]-----+
$ cat ~demouser/.ssh/demouser_net.pub
ssh-rsa AAAAB3NzaC1yc2EAAA[...]IU5VpoyTkx/lPZ63YZQIYs91YzoN/FtHQ7oZsXrnv3WToO2V demouser@ubuntu

Update load_auth_pubkey.xml

The file as, found in the source tarball, should look exactly like this:

$ cat Netopeer2-0.7-r1/server/configuration/load_auth_pubkey.xml
<system xmlns="urn:ietf:params:xml:ns:yang:ietf-system">
  <authentication>
    <user>
      <name>[system-username]</name>
      <authorized-key>
        <name>[arbitrary-key-name]</name>
        <algorithm>[key-algorithm]</algorithm>
        <key-data>[key-data]</key-data>
      </authorized-key>
    </user>
  </authentication>
</system>

It has to be updated to match the previously generated key:

cp Netopeer2-0.7-r1/server/configuration/load_auth_pubkey.xml .

Then edit it to include the ssh key as created above (replace the AAA ... O2V in the following text with the public portion of the ssh key that was created above. Note that you will be changing:

  1. user name
  2. authorized-key name
  3. authorized-key algorithm
  4. authorized-key key-data
<system xmlns="urn:ietf:params:xml:ns:yang:ietf-system">
  <authentication>
    <user>
      <name>demouser</name>
      <authorized-key>
        <name>demouser_net</name>
        <algorithm>ssh-rsa</algorithm>
        <key-data>AAAAB3NzaC1yc2EAAAADAQABA[...]Ys91YzoN/FtHQ7oZsXrnv3WToO2V</key-data>
      </authorized-key>
    </user>
  </authentication>
</system>

The edited load_auth_pubkey.xml must now be uploaded into the sysrepo datastore:

sudo sysrepocfg --import=load_auth_pubkey.xml ietf-system --datastore=startup

Configure netopeer2-cli

At this point there should not be any keys imported:

$ netopeer2-cli
> auth keys
The keys used for SSH authentication:
(none)
>

To import generated keys, execute the following:

> auth keys add /home/demouser/.ssh/demouser_net.pub /home/demouser/.ssh/demouser_net
> auth keys
The keys used for SSH authentication:
#0: /home/demouser/.ssh/demouser_rsa.pub (private /home/demouser/.ssh/demouser_rsa)
>

To check the preferences of authentication:

> auth pref
The SSH authentication method preferences:
	'publickey':   1
	'password':    2
	'interactive': 3
>

It is possible to change these using auth pref interactive N where N is a priority number (a lower number has higher precedence).

Start netopeer processes:

$ sudo netopeer2-server

You may want to start netopeer2-server in debug mode:

$ sudo netopeer2-server -d -v3

At this point, you should be able to connect to the netopeer2-server:

$ netopeer2-cli
> connect
Interactive SSH Authentication
Type your password:
Password:
>

and also check the running configuration:

> get-config --source running
DATA
<netconf-server xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-server">
  <listen>
    <endpoint>
      <name>all-interfaces</name>
      <ssh>
        <address>0.0.0.0</address>
        <port>830</port>
        <host-keys>
          <host-key>
            <name>imported SSH key</name>
            <public-key>ssh_host_rsa_key</public-key>
          </host-key>
        </host-keys>
      </ssh>
    </endpoint>
  </listen>
</netconf-server>
<system xmlns="urn:ietf:params:xml:ns:yang:ietf-system">
  <authentication>
    <user>
      <name>demouser</name>
      <authorized-key>
        <name>demouser_net</name>
        <algorithm>ssh-rsa</algorithm>
        <key-data>AAAAB3NzaC1yc2EAAAADAQABA[...]Ys91YzoN/FtHQ7oZsXrnv3WToO2V</key-data>
      </authorized-key>
    </user>
  </authentication>
</system>

KEA INSTALLATION and CONFIGURATION

Download and install Kea 2.6.1

Note that this installs Kea into the directory kea-bin in the demouser's home directory. It does not install software into system paths:

wget https://ftp.isc.org/isc/kea/2.6.1/kea-2.6.1.tar.gz && \
  tar -xf kea-2.6.1.tar.gz && \
  rm kea-2.6.1.tar.gz && \
  pushd kea-2.6.1 && \
  autoreconf -if && \
  ./configure --prefix=/home/demouser/kea-bin \
    --with-libyang=/opt/libyang --with-libyang-cpp=/opt/libyang-cpp \
    --with-sysrepo=/opt/sysrepo --with-sysrepo-cpp=/opt/sysrepo-cpp
  make && \
  sudo make install && \
  popd

Confirm that the file kea-2.6.1/config.report contains:

NETCONF:
  yes

  libyang:
    LIBYANG_CPPFLAGS:
    LIBYANG_INCLUDEDIR:    -I/opt/libyang/include
    LIBYANG_LIBS:          -L/opt/libyang/lib -lyang -Wl,-R/opt/libyang/lib -lyang
    LIBYANG_PREFIX:        /opt/libyang
    LIBYANG_VERSION:       2.1.4

  libyang-cpp:
    LIBYANGCPP_CPPFLAGS:
    LIBYANGCPP_INCLUDEDIR: -I/opt/libyang-cpp/include -I/opt/libyang/include
    LIBYANGCPP_LIBS:       -L/opt/libyang-cpp/lib -lyang-cpp -Wl,-R/opt/libyang-cpp/lib -lyang-cpp
    LIBYANGCPP_PREFIX:     /opt/libyang-cpp
    LIBYANGCPP_VERSION:    1.1.0

  sysrepo:
    SYSREPO_CPPFLAGS:
    SYSREPO_INCLUDEDIR:    -I/opt/sysrepo/include -I/opt/libyang/include
    SYSREPO_LIBS:          -L/opt/sysrepo/lib -lsysrepo -Wl,-R/opt/sysrepo/lib -lsysrepo
    SYSREPO_PREFIX:        /opt/sysrepo
    SYSREPO_VERSION:       2.2.12

    SR_REPO_PATH:          /etc/sysrepo
    SR_PLUGINS_PATH:       /opt/sysrepo/lib/sysrepo/plugins
    SRPD_PLUGINS_PATH:     /opt/sysrepo/lib/sysrepo-plugind/plugins

  sysrepo-cpp:
    SYSREPOCPP_CPPFLAGS:
    SYSREPOCPP_INCLUDEDIR: -I/opt/sysrepo-cpp/include -I/opt/sysrepo/include -I/opt/libyang-cpp/include -I/opt/libyang/include
    SYSREPOCPP_LIBS:       -L/opt/sysrepo-cpp/lib -lsysrepo-cpp -Wl,-R/opt/sysrepo-cpp/lib -lsysrepo-cpp
    SYSREPOCPP_PREFIX :    /opt/sysrepo-cpp
    SYSREPOCPP_VERSION:    1.1.0

Now you need to install all the Kea YANG modules:

/home/demouser/kea-bin/share/kea/yang/modules/utils/reinstall.sh

That should work, but if problems are encountered, the modules can also be installed manually:

pushd /home/demouser/kea-bin/share/kea/yang/modules/
for i in \
  keatest-module \
  ietf-interfaces \
  ietf-dhcpv6-common \
  ietf-dhcpv6-client \
  ietf-dhcpv6-relay \
  ietf-dhcpv6-server \
  ietf-yang-types \
  ietf-dhcpv6-options \
  ietf-dhcpv6-types \
  ietf-inet-types \
  kea-types \
  kea-dhcp-types \
  kea-dhcp-ddns \
  kea-ctrl-agent \
  kea-dhcp4-server \
  kea-dhcp6-server \
; do
  sudo /opt/sysrepoctl -i "${i}"
done
popd

At this point, you will need to prepare three config files:

  1. kea-startup.xml for Kea, which will be uploaded to sysrepo:
$ cat kea-startup.xml
<config xmlns="urn:ietf:params:xml:ns:yang:kea-dhcp6-server">
  <control-socket>
    <socket-name>/home/demouser/.control_socket</socket-name>
    <socket-type>unix</socket-type>
  </control-socket>
</config>

Upload it to the sysrepo startup datastore using the command:

sudo sysrepocfg --datastore=startup --import=kea-startup.xml
  1. kea.conf file for kea-dhcp6. The most important configuration options at this point are logging and socket.
$ cat kea.conf
{
  "Dhcp6": {
    "interfaces-config": {
      "interfaces": [
        "enp0s8"
      ]
    },
    "subnet6": [],
    "lease-database": {
      "type": "memfile",
      "lfc-interval": 0
    },
    "control-socket": {
      "socket-type": "unix",
      "socket-name": "/home/demouser/.control_socket"
    }
  },
  "Logging": {
    "loggers": [
      {
        "name": "kea-dhcp6",
        "output-options": [
          {
            "output": "stdout"
          }
        ],
        "debuglevel": 99,
        "severity": "DEBUG"
      }
    ]
  }
}

and
3) keanetconf.conf for the Kea netconf module (be sure to use the same socket as above):

$ cat keanetconf.conf
{
  "Netconf": {
    "managed-servers": {
      "dhcp6": {
        "model": "kea-dhcp6-server",
        "comment": "DHCP6 server",
        "boot-update": true,
        "subscribe-changes": true,
        "validate-changes": true,
        "control-socket": {
          "socket-name": "/home/demouser/.control_socket",
          "socket-type": "unix"
        }
      }
    }
  },
  "Logging": {
    "loggers": [
      {
        "name": "kea-netconf",
        "output-options": [
          {
            "output": "stdout"
          }
        ],
        "severity": "DEBUG",
        "debuglevel": 99
      }
    ]
  }
}

Testing:

Start kea-dhcp6:

$ sudo ~demouser/kea-bin/sbin/kea-dhcp6 -c ~demouser/KeaNetconf/kea.conf

Start kea-netconf:

$ sudo ~demouser/kea-bin/sbin/kea-netconf -c ~demouser/KeaNetconf/keanetconf.conf

At this point kea should be automatically reconfigured with configuration stored in kea-startup.xml which was uploaded to the startup datastore.

You must now create a config that you want to upload. Remember to use the same socket location or you will lose the connection with Kea.

You will need to change the interface from enp0s8 to match your system
$ cat kea.xml
<config xmlns="urn:ietf:params:xml:ns:yang:kea-dhcp6-server">
  <subnet6>
    <id>1</id>
    <pool>
      <start-address>2001:db8::1:0</start-address>
      <end-address>2001:db8::1:1</end-address>
    </pool>
    <subnet>2001:db8::/64</subnet>
  </subnet6>
  <interfaces-config>
    <interfaces>enp0s8</interfaces>
  </interfaces-config>
  <control-socket>
    <socket-name>/home/demouser/.control_socket</socket-name>
    <socket-type>unix</socket-type>
  </control-socket>
</config>

Connect to netopeer2-server:

$ netopeer2-cli
> connect
Interactive SSH Authentication
Type your password:
Password:
>

Send pre-prepared config to running datastore:

> edit-config --target running --config=kea.xml

If you see:

> edit-config --target running --config=kea.xml
OK

kea-netconf should detect the change and only verify the config:

019-01-17 15:47:09.918 INFO  [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGE_EVENT Received YANG configuration change VERIFY event
2019-01-17 15:47:09.918 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: created: /kea-dhcp6-server:config/subnet6[id='1'] (list instance)
2019-01-17 15:47:09.918 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: created: /kea-dhcp6-server:config/subnet6[id='1']/id = 1
2019-01-17 15:47:09.918 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: created: /kea-dhcp6-server:config/subnet6[id='1']/pool[start-address='2001:db8::1:0'][end-address='2001:db8::1:1'] (list instance)
2019-01-17 15:47:09.918 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: created: /kea-dhcp6-server:config/subnet6[id='1']/pool[start-address='2001:db8::1:0'][end-address='2001:db8::1:1']/start-address = 2001:db8::1:0
2019-01-17 15:47:09.918 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: created: /kea-dhcp6-server:config/subnet6[id='1']/pool[start-address='2001:db8::1:0'][end-address='2001:db8::1:1']/end-address = 2001:db8::1:1
2019-01-17 15:47:09.918 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: created: /kea-dhcp6-server:config/subnet6[id='1']/subnet = 2001:db8::/64
2019-01-17 15:47:09.918 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: moved: /kea-dhcp6-server:config/subnet6[id='1'] first
2019-01-17 15:47:09.918 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: created: /kea-dhcp6-server:config/interfaces-config (container)
2019-01-17 15:47:09.918 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: created: /kea-dhcp6-server:config/interfaces-config/interfaces = enp0s8
2019-01-17 15:47:09.919 INFO  [kea-netconf.netconf/6911] NETCONF_VALIDATE_CONFIG_STARTED started validating configuration for dhcp6 server
2019-01-17 15:47:09.929 DEBUG [kea-netconf.netconf/6911] NETCONF_VALIDATE_CONFIG validating configuration with dhcp6 server: {
  "Dhcp6": {
    "control-socket": {
      "socket-name": "/home/demouser/.control_socket",
      "socket-type": "unix"
    },
    "interfaces-config": {
      "interfaces": [ "enp0s8" ]
    },
    "subnet6": [
      {
        "id": 1,
        "pools": [
          {
            "pool": "2001:db8::1:0 - 2001:db8::1:1"
          }
        ],
        "subnet": "2001:db8::/64"
      }
    ]
  }
}
2019-01-17 15:47:09.930 INFO  [kea-netconf.netconf/6911] NETCONF_VALIDATE_CONFIG_COMPLETED completed validating configuration for dhcp6 server

When you are ready to apply changes, use:

> edit-config --target running --defop=replace --config=kea.xml
OK
> commit
OK

At this point, kea-netconf should have logged:

2019-01-17 15:47:09.939 INFO  [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGE_EVENT Received YANG configuration change APPLY event
2019-01-17 15:47:09.940 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: created: /kea-dhcp6-server:config/subnet6[id='1'] (list instance)
2019-01-17 15:47:09.940 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: created: /kea-dhcp6-server:config/subnet6[id='1']/id = 1
2019-01-17 15:47:09.940 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: created: /kea-dhcp6-server:config/subnet6[id='1']/pool[start-address='2001:db8::1:0'][end-address='2001:db8::1:1'] (list instance)
2019-01-17 15:47:09.940 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: created: /kea-dhcp6-server:config/subnet6[id='1']/pool[start-address='2001:db8::1:0'][end-address='2001:db8::1:1']/start-address = 2001:db8::1:0
2019-01-17 15:47:09.940 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: created: /kea-dhcp6-server:config/subnet6[id='1']/pool[start-address='2001:db8::1:0'][end-address='2001:db8::1:1']/end-address = 2001:db8::1:1
2019-01-17 15:47:09.941 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: created: /kea-dhcp6-server:config/subnet6[id='1']/subnet = 2001:db8::/64
2019-01-17 15:47:09.941 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: moved: /kea-dhcp6-server:config/subnet6[id='1'] first
2019-01-17 15:47:09.941 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: created: /kea-dhcp6-server:config/interfaces-config (container)
2019-01-17 15:47:09.941 DEBUG [kea-netconf.netconf/6911] NETCONF_CONFIG_CHANGED_DETAIL YANG configuration changed: created: /kea-dhcp6-server:config/interfaces-config/interfaces = enp0s8
2019-01-17 15:47:09.944 INFO  [kea-netconf.netconf/6911] NETCONF_UPDATE_CONFIG_STARTED started updating configuration for dhcp6 server
2019-01-17 15:47:09.956 DEBUG [kea-netconf.netconf/6911] NETCONF_UPDATE_CONFIG updating configuration with dhcp6 server: {
  "Dhcp6": {
    "control-socket": {
      "socket-name": "/home/demouser/.control_socket",
      "socket-type": "unix"
    },
    "interfaces-config": {
      "interfaces": [ "enp0s8" ]
    },
    "subnet6": [
      {
        "id": 1,
        "pools": [
          {
            "pool": "2001:db8::1:0 - 2001:db8::1:1"
          }
        ],
        "subnet": "2001:db8::/64"
      }
    ]
  }
}
2019-01-17 15:47:09.958 INFO  [kea-netconf.netconf/6911] NETCONF_UPDATE_CONFIG_COMPLETED completed updating configuration for dhcp6 server

kea-dhcp6 will log:

2019-01-17 15:47:09.956 INFO  [kea-dhcp6.commands/6909] COMMAND_RECEIVED Received command 'config-set'
2019-01-17 15:47:09.956 INFO  [kea-dhcp6.hosts/6909] HOSTS_BACKENDS_REGISTERED the following host backend types are available:
2019-01-17 15:47:09.956 INFO  [kea-dhcp6.dhcpsrv/6909] DHCPSRV_CFGMGR_ADD_IFACE listening on interface enp0s8
2019-01-17 15:47:09.956 INFO  [kea-dhcp6.dhcpsrv/6909] DHCPSRV_CFGMGR_NEW_SUBNET6 a new subnet has been added to configuration: 2001:db8::/64 with params t1=900, t2=1800, preferred-lifetime=3600, valid-lifetime=7200, rapid-commit is disabled
2019-01-17 15:47:09.956 INFO  [kea-dhcp6.dhcp6/6909] DHCP6_CONFIG_COMPLETE DHCPv6 server has completed configuration: added IPv6 subnets: 1; DDNS: disabled
2019-01-17 15:47:09.956 INFO  [kea-dhcp6.dhcpsrv/6909] DHCPSRV_MEMFILE_DB opening memory file lease database: type=memfile universe=6

At this point, you can claim success! Everything is working as it should!

Errors:

If you see messages like:

> edit-config --target running --config=kea.xml
ERROR
	type:     application
	tag:      operation-failed
	severity: error
	message:  Validation of the changes failed

that means that kea.xml is invalid.

If you see:

> edit-config --target running --config=kea.xml
ERROR
	type:     application
	tag:      operation-failed
	severity: error
	path:     /kea-dhcp6-server:config/subnet6[id='1']
	message:  The node is not enabled in the running datastore

That means that kea-netconf is not running!

Additional sample commands:

Get current model of kea-dhcp6-server (that includes revision date):

get-schema --model kea-dhcp6-server

Replace the current running datastore:

edit-config --target running --defop=replace --config=kea.xml

Merge the current running datastore with kea.xml (can produce conflicts, this is default action):

edit-config --target running --defop=replace --config=kea.xml