notconf is a NETCONF device simulator based on Netopeer2 and sysrepo running in a container. A simulator in this case is a NETCONF server that exposes the standard NETCONF management interface of the simulated device without actually performing and (network) functions.
The intended use is to provide a light-weight device for testing network automation systems that produce configuration or otherwise interface with the device over NETCONF. The simulated device consumes few resources in contrast with creating a complete virtual machine (router).
If you are familiar with Cisco NSO, notconf is a drop-in replacement for netsim. The advantages of notconf over netsim are:
- notconf is open source and based on open source software
- building a custom image with custom (vendor) YANG modules is easy and faster than with netsim (no YANG compilation required)
For running the container from a pre-built image the only prerequisite is Docker
or some other container runtime like Podman. Building the base and custom images
further requires make, git and xmlstarlet and optionally netconf-console2 for
NETCONF operations testing. netconf-console2 is also installed in the
notconf:debug image for convenience. For an definitive list check the GitHub
action workflow for the build-notconf-base
.
The base container image notconf:latest
contains the Netopeer2 installation with
all of its runtime dependencies. The set of YANG modules included in the NETCONF
server is the bare minimum to make Netopeer2 work. This is enough for any
NETCONF client to establish a NETCONF session, but not much else. You will most
likely want to include your own or vendor YANG modules to simulate a network
device. In the following example we will use the test.yang
YANG module
included in this repository in the test
directory. The vanilla notconf image
will load all YANG modules found in the /yang-modules
directory inside the
container. Therefore the quickest way to use custom modules is to bind mount a
host directory to the /yang-modules
directory in the container.
Yang modules could also contain optional features that, by default, are disabled.
At startup the container will look for the file /yang-modules/enable-features.csv
to determine if some features should be enabled. Each row of the file should start
with a module name followed by comma and the name of a feature to enable,
one pair per line.
# start the container and bind mount the `test` directory to `/yang-modules`
❯ docker run -d --rm --name notconf-test -v $(pwd)/test/yang-modules:/yang-modules notconf
# verify the NETCONF server supports the test YANG module
# with netconf-console2 installed on your local machine:
❯ netconf-console2 --host $(docker inspect notconf-test --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}') --port 830 --get /modules-state
# or run netconf-console2 from the notconf:debug image:
❯ docker run -i --network container:notconf-test ghcr.io/notconf/notconf/notconf:debug netconf-console2 --port 830 --get /modules-state
...
<module>
<name>test</name>
<revision/>
<schema>file:///etc/sysrepo/yang/test.yang</schema>
<namespace>urn:notconf:test</namespace>
<conformance-type>implement</conformance-type>
</module>
</modules-state>
</data>
You may notice that startup times for the notconf container vary depending on the number and complexity of loaded YANG modules. The majority of the time in the startup script is spent installing the YANG modules with sysrepoctl. This can be optimized though by building a custom notconf image where the modules are instead installed at image build time.
In the next example we will build a notconf image that includes the test.yang
module. The Dockerfile.yang
file is a multi-stage file that first installs the
modules in found in the path configured with the COMPOSE_PATH
build argument,
then copies the results to a clean image.
# build the custom notconf-test image
❯ docker build -f Dockerfile.yang -t notconf-test --build-arg COMPOSE_PATH=test/yang-modules .
Sending build context to Docker daemon
Step 1/9 : ARG IMAGE_PATH
Step 2/9 : ARG IMAGE_TAG=latest
Step 3/9 : FROM ${IMAGE_PATH}notconf:${IMAGE_TAG} AS notconf-install
---> 62b1b5b48905
Step 4/9 : ARG COMPOSE_PATH
---> Running in 9cf6b8d26422
Removing intermediate container 9cf6b8d26422
...
Successfully built 5abbdafc0f9a
Successfully tagged notconf-test:latest
# start the container with the composed image and verify the test.yang module is present
❯ docker run -d --rm --name notconf-test -v $(pwd)/test:/yang-modules notconf
❯ docker run -i --rm --network container:notconf-test ghcr.io/notconf/notconf/notconf:debug netconf-console2 --port 830 --get -x '/modules-state/module[name="test"]'
<?xml version='1.0' encoding='UTF-8'?>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<modules-state xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library">
<module>
<name>test</name>
<revision/>
<schema>file:///etc/sysrepo/yang/test.yang</schema>
<namespace>urn:notconf:test</namespace>
<conformance-type>implement</conformance-type>
</module>
</modules-state>
</data>
Note: Dockerfile.yang
has two additional optional build arguments:
IMAGE_PATH
: prefix to the base notconf container image, likeghcr.io/notconf/notconf/notconf
, defaults to empty stringIMAGE_TAG
: suffix to the base notconf container image, defaults tolatest
YANG modules for several network devices from different vendors can be found in the public YangModels/yang repository. The majority of the modules are valid YANG 1.1 modules, but there are some tweaks that need to be made in order for sysrepo to accept them. This repository contains "fixup" Makefiles for the platforms:
- nokia/sros
- juniper/junos
- cisco/xr
In addition to the obvious NETCONF interface for modifying the running configuration, notconf also allows users to modify startup configuration and operational (config false) data.
Any XML files placed in the /yang-modules/startup
directory in the container
will be automatically imported into the startup datastore when the notconf
container starts. When all files are imported the startup datastore is copied to
running. The XML files must conform to YANG models loaded and must not
contain operational data.
Any XML files placed in the /yang-modules/operational
directory in the
container will be automatically imported into the operational datastore when the
notconf container starts, or when any change is detected to this directory. The
XML files must conform to YANG models loaded and must not contain configuration
data.
To update operational data in a running notconf container just update one of the
files! When a change is detected all XMLs are sorted by filename and then loaded
in order. The time to load operational data depends on the set of installed YANG
modules and the amount of operational data provided in XMLs. If you want to
ensure your test scripts do not proceed with test before all operational data is
ready, you can execute the /wait-operational-sync.sh
script in the container.
The script will block until the process is complete.
# start the container and bind mount the `test` directory to `/yang-modules`
❯ docker run -d --rm --name notconf-test -v $(pwd)/test/yang-modules:/yang-modules notconf
# verify operational data in test/yang-modules/operational/test-oper.xml is present
❯ docker run -i --network container:notconf-test ghcr.io/notconf/notconf/notconf:debug netconf-console2 --port 830 --get -x /bob
<?xml version='1.0' encoding='UTF-8'?>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<bob xmlns="urn:notconf:test">
<startup>Robert!</startup>
<state>
<great>success</great>
</state>
</bob>
</data>
# now you can modify the files in test/yang-modules/operational and observe the changes
#
# for test scripts, if you want to make sure operational data update is done, use the wait-operational-sync.sh script
❯ docker exec notconf-test /wait-operational-sync.sh
Triggering operational data sync
Operational data sync done!
- Automatically build composed images for more platforms (+ versions)
All the heavy lifting of providing a NETCONF server is done by Netopeer2 and
sysrepo, so this repository does not contain much code. The base notconf image
includes the dependencies compiled with the "Release" option. If you need to
troubleshoot some behavior of the NETCONF server it may be beneficial to use the
binaries compiled with the "Debug" options. The notconf:debug
image is
automatically built and tagged in the build process.