Background
Recently, I have a task on building an application with interaction on NETCONF. IMO, I have no idea what is NETCONF before this task. But, I finally complete, partially, the task. This blog summarises what I have learnt on NETCONF, and bait some reading from you guys :D
The diagram illustrates 2 critical components in the application: CoreServer, and TargetHost. To summarise the application literally, I need to build a CoreServer such that users can monitor the device’s network status with NETCONF in RESTful manner.
In this blog post, I will focus on the TargetHost, the NETCONF part, only. Hopefully, I will write another blog on the CoreServer.
What is a NETCONF actually?
As the blog’s title, this is a quick try. I did not spent much time on studying what NETCONF actually is. Below is just my understanding on some quick research. Forgive me for being wrong since this part is not the critical part on my application. Most of the useful links have been captured at the last section. I recommend you to go thorough them if you really want to figure out NETCONF inside out.
AFAIK, NETCONF is yet another network management protocol which is similar to SNMP. It aims on configuring, and getting configurations from supported devices in a cross platform manner.
Back in to my application, since it is a protocol, I will need a server that understand NETCONF, and do the jobs accordingly. Secondly, I will need a client that sending commands in NETCONF manner in order to instruct the server to do things I want.
Why NETCONF with docker?
According to the Google search, NETCONF should be a common, and old protocol. It means that the quickest way for having an effective NETCONF server is having a commercial router. Since I don’t have that luxury for having 1 of them, I need to build 1 for myself. The problem is I don’t have any spare devices on my hand. So, I try to run that server in a docker container.
Following is the docker image I used
- https://hub.docker.com/r/yuma123/netconfd
Configuring the netconfd in the docker image
My netconfd should be able to manipulate with network interfaces. So, I config, expressed in docker-compose.yml, as following
This yml is edited from the application I have worked. I don’t go thorough it line by line. But, 2 parts are important: Environment, and portsversion: 3 service: TargetClient: networks: - hands-on-interview extra_hosts: - "host.docker.internal:host-gateway" image: yuma123/netconfd:2.12 environment: NETCONF_USER: "handsonadmin" NETCONF_PASSWORD: "handsonpassword" NETCONF_PORT: "830" NETCONF_LOG_LEVEL: "info" NETCONF_MODULES: "ietf-interfaces" ports: - "127.0.0.1:56734:830" networks: hands-on-interview:
Environments are the expected way for configuring the daemon while the port configurations allowing us to debug the daemon with another command line toolyangcli
as discussed later on.List interfaces with
After theyangcli
netconfd
docker container is up, we can listing network interfaces withyangcli
. I tried both way: interactive, and one-off command.
The tricky part is using--net=host
docker feature. And, that’s why we need to setup the port mapping for the netcond docker container. Otherwise, we cannot connect to that server easily.Interactive way
```Run the yangcli under host network
docker run -it —rm —net=host yuma123/yangcli:2.12
yangcli>
Connect to the docker container in the localhost
yangcli> connect ncport=56734 server=127.0.0.1 user=handsonadmin password=handsonpassword
Test with show vars
yangcli> show vars
Show interfaces-state
yangcli> sget /interfaces-state
## One-off bash command
docker run -it —rm —net=host yuma123/yangcli:2.12 \
—ncport=56734 \
—server=127.0.0.1 \
—user=handsonadmin \
—password=handsonpassword \
—run-command=”sget /interfaces-state” \
—batch-mode \
—timeout=5 \
—display-mode=xml \
—log-level=info
* Expected results are listed below
```html
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<data>
<interfaces-state xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface>
<name>lo</name>
<oper-status>unknown</oper-status>
<statistics>
<in-octets>0</in-octets>
<in-unicast-pkts>0</in-unicast-pkts>
<in-errors>0</in-errors>
<in-discards>0</in-discards>
<in-multicast-pkts>0</in-multicast-pkts>
<out-octets>0</out-octets>
<out-unicast-pkts>0</out-unicast-pkts>
<out-errors>0</out-errors>
<out-discards>0</out-discards>
</statistics>
</interface>
<interface>
<name>tunl0</name>
<oper-status>down</oper-status>
<statistics>
<in-octets>0</in-octets>
<in-unicast-pkts>0</in-unicast-pkts>
<in-errors>0</in-errors>
<in-discards>0</in-discards>
<in-multicast-pkts>0</in-multicast-pkts>
<out-octets>0</out-octets>
<out-unicast-pkts>0</out-unicast-pkts>
<out-errors>0</out-errors>
<out-discards>0</out-discards>
</statistics>
</interface>
<interface>
<name>ip6tnl0</name>
<oper-status>down</oper-status>
<statistics>
<in-octets>0</in-octets>
<in-unicast-pkts>0</in-unicast-pkts>
<in-errors>0</in-errors>
<in-discards>0</in-discards>
<in-multicast-pkts>0</in-multicast-pkts>
<out-octets>0</out-octets>
<out-unicast-pkts>0</out-unicast-pkts>
<out-errors>0</out-errors>
<out-discards>0</out-discards>
</statistics>
</interface>
<interface>
<name>eth0</name>
<oper-status>up</oper-status>
<statistics>
<in-octets>111371</in-octets>
<in-unicast-pkts>738</in-unicast-pkts>
<in-errors>0</in-errors>
<in-discards>0</in-discards>
<in-multicast-pkts>0</in-multicast-pkts>
<out-octets>481471</out-octets>
<out-unicast-pkts>664</out-unicast-pkts>
<out-errors>0</out-errors>
<out-discards>0</out-discards>
</statistics>
</interface>
</interfaces-state>
</data>
</rpc-reply>
Conclusions
After making use of the docker image from netconfd
, and yangcli
, we now have a server running NETCONF effectively. The rest of my job is utilising ncclient
, a python library, to talk with the server instead of using yangcli
since that cli does not provide programmer friendly output.
Thanks for reading up to here. See you in the next blog. Before we end, I have captured the useful links during this study.
沒有留言:
張貼留言