YANG/NETCONF is a nice new technology that we'd like to adopt in Kea. The major benefits of YANG include:
- standardized model that can be used between different vendors (even if there are vendor specific extensions, the similarity between the core functionalities is beneficial in heterogenous environments) extended to fit Kea
- ability to use plethora of YANG/NETCONF tools
- it's a technology that is getting more and more popular these days. We should embrace.
A new library libkea-yang will be added (src/lib/yang). It will provide the following functionalities:
- generic way to handle YANG basic types (convert YANG primitives to JSON and vice versa)
- load any YANG model
- base classes for translators (able to convert YANG configuration to JSON format)
- generic way to connect to sysrepo
- retrieve configuration for chosen model (this will be needed during server startup)
- subscribe to configuration changes on a chosen model (this will be needed to pick up any changes that may appear during runtime)
- subscribe to configuration changes in a specified sub-tree of a chosen model (this will be needed for specialized translators to pick up changes, e.g. dedicated subnet translators).
We need a way to handle any YANG configuration in a generic way. We must not limit ourselves to only DHCPv4 or DHCPv6 servers, as it is likely that in the not so distant future also DDNS and possibly even CA could earn its own YANG models.
Translator has to provide the following services:
- name of the model it supports
- xpath for specific subtree in sysrepo notation
- a callback that will be called from sysrepo. It should retrieve the data.
- translate() mechanism that will convert YANG data to JSON structures understandable by Kea
For testing purposes it is desirable for a translator to also provide:
- conversion from JSON structures understandable by to back to YANG data. This is useful for testing that the toJSON(toYANG(X)) == X. However, this may not be true for certain elements in the model (namely, the DHCPv6 YANG model has concept of option-sets that are used in various places, e.g. subnets. Once converted to Kea, the options-sets are dereferenced and there is no way to generate the original option-sets).
We need translators for the following scopes (these are generic, so we can hope to turn it into a generic model one day and maybe donate it to IETF):
- Pool4, Pool6, PdPool
- Subnet4, Subnet6
- SharedNetwork4, SharedNetwork6
- Host (host reservation with all details)
- Server4 (covers global parameters)
- Server6 (covers global parameters)
Kea specific (it's unlikely to ever make it into generic model):
- DBAccess (processes configuration of lease and host backends)
- ControlSocket (processes configuration of a control socket)
- Hook (processes a single entry in hook-libraries)
Config Change Watcher
This mechanism will install specified translators and install their callbacks, then process their output (send JSON commands, possibly send back responses).
The framework running translators has to handle the following tasks:
- manage sysrepo connection (open, subscribe to session, ...)
- subscribe to specified YANG model
- install specified translators (i.e. retrieve the initial data, subscribe to changes)
- for each callback retrieve the JSON output generated
- depending on the configuration, do one of three:
- print out the JSON output on stdout
- send the JSON output over control channel to DHCP server directly (UNIX socket)
- send the JSON output over http(s) to CA
This daemon, when started, will connect to Sysrepo (a YANG model and configuration storage that provides remote NETCONF interface) and will conduct two tasks (each role can be enabled or disabled in configuration):
retrieve the initial configuration and send it to Kea using JSON commands. This will be used to conduct the initial configuration. This may be used when you are deploying a new Kea instance and want it to retrieve its configuration from NETCONF. This mechanism will be used in scenarios when NETCONF will be treated as the primary configuration storage and the source of truth.
monitor YANG configuration and detect changes. This mode may be used along with !#1 (closed) above if you want Kea to monitor YANG configuration and react when anything changes, such as new subnet being configured or existing subnet being deleted.
To provide maximu, flexibility Kea-netconf daemon will eventually get three modes of output generation:
stdout. Kea-netconf could be configured to print the JSON commands on its standard output. This may be useful if you want to redirect them to a text file, pass to another tool or pipe it to somewhere. The most flexible option and it's likely to be implemented first.
unix socket - Kea DHCPv4 and DHCPv6 support reception of JSON commands over UNIX socket. D2 (DHCP-DDNS) will get this capability in Kea1.5. It will be useful to support this mode next, so kea-netconf could be used together with a running DHCP server (and some time later possibly with D2 as well)
http connection - The supports proper HTTP interface using Control Agent (CA). Kea-netconf will eventually get the capability to send commands over http interface. The major benefit of this approach is that it would disassociate location of sysrepo and the DHCP servers, so they could potentially be run on different hosts. The downside of this approach is that CA has to be run. Some people may dislike running http interface, especially in more constrained environments as running https requires also running a full http server, such as apache or nginx.
Kea-netconf will be optional. If you don't want netconf, don't run it. Also, since it requires non-trivial dependencies (sysrepo is required, which requires several new libraries that were not needed by Kea so far). As such, it's compilation will be disabled by default. This approach will be similar to database backends.
Discarded ideas: plugin
There are two ways how a software can be integrated with sysrepo using one of two approaches: stand-alone daemon and a plugin. The first hackathon used a plugin, but we quickly discovered that using a plugin has serious issues, so the next two hackathons used daemon. This is also what we're going to do with production code in Kea.
- The sysrepo documentation says to use plugins only if you can't do the native (daemon) implementation.
- A plugin requires sysrepo process to be running. This significantly complicates failure recovery (we would depend on currently non-existent sysrepo start/stop scripts)
- Plugin installation is more complex and requires higher privileges. In a usual sysrepo installation root access is needed to install extra plugins. This would mean that tests would have to be run as root. There are ways to work around it, but suid scripts would complicate the already complex test environment.
- We need non-trivial configuration pertaining to the netconf interface itself (things like models to subscribe to, logging configuration, which translators to load, how to connect to Kea - socket of stdout, etc.). This means we need to have a netconf.json configuration, with parsers, configuration storage etc. This looks very much like a daemon already.
- The number of daemons we have in Kea is growing. I see no reason why treat netconf differently. It should give users the same look and feel as other Kea daemons.
For those reasons, we will go with a daemon approach, not a plugin. Any code developed for a plugin that is still considered useful needs to be ported to kea-netconf daemon.