Could we extract a netconfc-module from the ct_netconfc-library?

Hi Community,
I am playing with writing a somewhat complete NETCONF-client library in Erlang.

I have found previous attempts for instance from the OpenFlow-era - and there are some libraries.

However, I have found that the ct_netconfc-modules are more complete.
The only “however” is: it can only be used in the context of common-tests.

I have started a private simple Proof-of-concept - based on the netconfc-modules.
The changes entail removing some references to ct_util, ct_server etc - but in general the library after tinkering with it for some hours is already very usable.

Any thoughts on this?

Maybe the library could actually be extracted, and by means of callback re-integrated in ct_common.
Making sure we do not have converging code-bases.

Kind regards,

Fabian

5 Likes

Hi Fabian,

I am also exploring Netconf clients.

I have evaluated the available Netconf clients - FlowForwarding/enetconf, ferigis/Netconf & ruanhao/simple-netconf-client. I see ct_netconfc has better support among all. ct_netconfc supports more RPC operations and Notifications.

You said “it can only be used in the context of common-tests”. May I know the reason for thinking so? In fact, ferigis/Netconf uses ct_netconfc for and for opening SSH session. Given this, I think we could develop Netconf client by using ct_netconfc. What’s your opinion?

1 Like

Hi Bhuvan,

What you propose is exactly what I have done. Create a new enetconfc-library heavily based on the ct_netconfc module.

As ruanhao mentions in one of his posts ( translated by google 使用 Erlang 实现 Netconf Client · Hao Ruan ) normally you would not use common-test code in a released application.

The code which is currently used is basically a “copy” of the ct_netconfc-module, with some minor cleanups and additions. For instance we added standard operations such as validate,commit,commit_confirmed and discard_changes.

Also the gen_conn-module is too common-test specific - with some of the logging infrastructure etc.

I will try to liberate the library on github.

2 Likes

Yes, I have checked this post. Why do you think that “normally you would not use common-test code in a released application”? I see common-test modules such as ct_netconfc, ct_snmp are very similar to Java libraries such JNC, SNMP4J which provide functions/interfaces required to communicate with Netconf, SNMP servers.

And, ruanhao wanted to use TCP rather than SSH provided by ct_netconfc. I think that is the reason for him to use gen_server/gen_tcp.

1 Like

Have you used send_rpc to support these RPCs? In fact, ct_netconfc has implemented various RPC operations as a wrapper around this function.

When do you release the library in github?

1 Like

Hi bhuvan - I do not have a date yet for the liberation.

In general however - about your question of using common-tests - yes you are right that you can use common-test for testing your software ( see Erlang -- Common Test Basics ) - however it is the same as any unit-test code / property-testing-code - that code is normally not running in production.

Another note: The library which we use connect via ssh as any normal netconf-server. (See RFC 6242: Using the NETCONF Protocol over Secure Shell (SSH)) - which is the way ct_netconfc does. We have not implemented any other means - such as the TCP implementation from Hao Ruan.

Kind regards,

Fabian

2 Likes

Hi Fabian,

Is it possible for you to share a sample of this code for a few operations say <hello>, <get_config>, <edit_config>? This helps me in understanding the internals of ct_netconfc & understand which part of ct_netconfc is reusable while developing a standalone Netconf client. Appreciate any help in this regard.

1 Like

Hi - below some small examples:

Setup:

ssh:start().
Port = {port,2022}.
Host = {ssh, {172,17,3,2}}.
User = {user,"admin"}.
Pass = {password, "admin"}.

{ok, Client} = enetconfc:open([
        Host,
        Port,
        User,
        Pass,
        {preferred_algorithms, [{public_key, ['ssh-rsa']}]}
    ]).

Capabilities test:

Res =  enetconfc:get_capabilities(Client).
Res = [
 "urn:ietf:params:netconf:base:1.0",
 "urn:ietf:params:netconf:base:1.1",
 "urn:ietf:params:netconf:capability:confirmed-commit:1.1",
 "urn:ietf:params:netconf:capability:confirmed-commit:1.0",
 "urn:ietf:params:netconf:capability:writable-running:1.0",
 "urn:ietf:params:netconf:capability:candidate:1.0",
 "urn:ietf:params:netconf:capability:rollback-on-error:1.0",
 "urn:ietf:params:netconf:capability:validate:1.0",
 "urn:ietf:params:netconf:capability:validate:1.1",
 "urn:ietf:params:netconf:capability:xpath:1.0",
 "urn:ietf:params:netconf:capability:notification:1.0",
 "urn:ietf:params:netconf:capability:partial-lock:1.0",
 ....
].

Get System from the running-configuration:

{ok, Running} = enetconfc:get_config(
    Client,
    running,
    {xpath, "/system"}
).

Etc … our client looks like this.

As mentioned before I have not had to chance to open-source it yet but will try to prioritize.

Kind regards,

Fabian

2 Likes

Hi Fabian,

Thanks for sharing the example code. I see it uses FlowForwarding/enetconf module.

From your earlier response, I thought you have removed commontest (ct_) specific code from ct_netconfc to arrive at a Netconf client.

I see ct_netconfc is updated periodically and it supports more Netconf operations. Whereas, FlowForwarding/enetconf was abandoned many years back and support a smaller number of Netconf operations compared to ct_netconfc. For example, FlowForwarding/enetconf does not support Netconf notifications.

1 Like