Change internal protocol from clicon_proto.h to netconf.

This commit is contained in:
Olof hagsand 2017-03-25 11:10:50 +01:00
parent 2e09f54d12
commit 2fcefda831
66 changed files with 3012 additions and 5141 deletions

View file

@ -14,7 +14,6 @@ clixon_netconf -f /usr/local/etc/routing.conf
1. Setting data example using netconf
-------------------------------------
<rpc><edit-config><target><candidate/></target><config>
<interfaces>
<interface>
@ -45,7 +44,38 @@ clixon_netconf -f /usr/local/etc/routing.conf
<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>
3. Run as docker container
3. Creating notification
------------------------
The example has an example notification triggering every 10s. To start a notification
stream in the session, create a subscription:
<rpc><create-subscription><stream>ROUTING</stream></create-subscription></rpc>]]>]]>
<rpc-reply><ok/></rpc-reply>]]>]]>
<notification><event>Routing notification</event></notification>]]>]]>
<notification><event>Routing notification</event></notification>]]>]]>
...
This can also be triggered via the CLI:
cli> notify
cli> Routing notification
Routing notification
...
4. Downcall
-----------
Clixon has an extension mechanism which can be used to make extended internal
netconf messages to the backend configuration engine. You may need this to
make some special operation that is not covered by standard
netconf functions. The example has a simple "echo" downcall
mechanism that simply echoes what is sent down and is included for
reference. A more realistic downcall would perform some action, such as
reading some status.
Example:
cli> downcall "This is a string"
This is a string
cli>p
5. Run as docker container
--------------------------
cd docker
# look in README

View file

@ -698,4 +698,4 @@
}
}
}
}
}

View file

@ -19,18 +19,11 @@ CLICON_CLI_GENMODEL_COMPLETION 1
# CLICON_CLI_GENMODEL_TYPE VARS
CLICON_CLI_GENMODEL_TYPE VARS
# Set if xmldb runs in a separate process (clixon_xmldb).
# Also set addr and port below
CLICON_XMLDB_RPC 0
# xmldb inet address (if CLICON_XMLDB_RPC)
CLICON_XMLDB_ADDR 127.0.0.1
# xmldb tcp port (if CLICON_XMLDB_RPC)
CLICON_XMLDB_PORT 7878
# Set if you want to use old obsolete cligen callback variable syntax
# Migration: Set to 0 and change all user-defined cli callbacks in your cli spec files
# E.g cmd, callback("single arg"); -> cmd, callback("two" "args");
# And change predefined callbacks, eg cli_commit -> cli_commitv in all cli files
CLICON_CLIGEN_CALLBACK_SINGLE_ARG 0
# Enabled uses "startup" configuration on boot
CLICON_USE_STARTUP_CONFIG 0

View file

@ -42,7 +42,7 @@
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
/* clicon */
#include <cligen/cligen.h>
@ -53,6 +53,9 @@
/* These include signatures for plugin and transaction callbacks. */
#include <clixon/clixon_backend.h>
/* forward */
static int notification_timer_setup(clicon_handle h);
/*! This is called on validate (and commit). Check validity of candidate
*/
int
@ -83,7 +86,47 @@ transaction_commit(clicon_handle h,
return 0;
}
/*! Routing example notifcation timer handler. Here is where the periodic action is
*/
static int
notification_timer(int fd,
void *arg)
{
int retval = -1;
clicon_handle h = (clicon_handle)arg;
if (backend_notify(h, "ROUTING", 0, "Routing notification") < 0)
goto done;
if (notification_timer_setup(h) < 0)
goto done;
retval = 0;
done:
return retval;
}
/*! Set up routing notifcation timer
*/
static int
notification_timer_setup(clicon_handle h)
{
struct timeval t, t1;
gettimeofday(&t, NULL);
t1.tv_sec = 10; t1.tv_usec = 0;
timeradd(&t, &t1, &t);
return event_reg_timeout(t, notification_timer, h, "notification timer");
}
static int
routing_downcall(clicon_handle h,
cxobj *xe, /* Request: <rpc><xn></rpc> */
struct client_entry *ce, /* Client session */
cbuf *cbret, /* Reply eg <rpc-reply>... */
void *arg) /* Argument given at register */
{
cprintf(cbret, "<rpc-reply><ok>%s</ok></rpc-reply>", xml_body(xe));
return 0;
}
/*
* Plugin initialization
*/
@ -92,8 +135,15 @@ plugin_init(clicon_handle h)
{
int retval = -1;
if (notification_timer_setup(h) < 0)
goto done;
if (backend_netconf_register_callback(h, routing_downcall,
NULL,
"myrouting"/* Xml tag when callback is made */
) < 0)
goto done;
retval = 0;
// done:
done:
return retval;
}

View file

@ -71,7 +71,7 @@ int
mycallback(clicon_handle h, cvec *cvv, cvec *argv)
{
int retval = -1;
cxobj *xt = NULL;
cxobj *xret = NULL;
cg_var *myvar;
/* Access cligen callback variables */
@ -80,14 +80,51 @@ mycallback(clicon_handle h, cvec *cvv, cvec *argv)
cli_output(stderr, "arg = %s\n", cv_string_get(cvec_i(argv,0))); /* get string value */
/* Show eth0 interfaces config using XPATH */
if (xmldb_get(h, "candidate",
"/interfaces/interface[name=eth0]",
&xt, NULL, NULL) < 0)
if (clicon_rpc_get_config(h, "running","/interfaces/interface[name=eth0]",
&xret) < 0)
goto done;
xml_print(stdout, xt);
xml_print(stdout, xret);
retval = 0;
done:
if (xt)
xml_free(xt);
if (xret)
xml_free(xret);
return retval;
}
/*! get argument and send as string to backend as RPC (which returns the string)
*/
int
downcall(clicon_handle h,
cvec *vars,
cvec *argv)
{
int retval = -1;
struct clicon_msg *msg = NULL;
char *str="";
cg_var *cv;
cxobj *xret=NULL;
cxobj *xerr;
cxobj *xdata;
if (cvec_len(vars)==2){
if ((cv = cvec_i(vars, 1)) != NULL)
str = cv_string_get(cv);
}
if ((msg = clicon_msg_netconf_encode("<rpc><myrouting>%s</myrouting></rpc>", str)) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
goto done;
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
clicon_rpc_generate_error(xerr);
goto done;
}
if ((xdata = xpath_first(xret, "//ok")) != NULL)
cli_output(stdout, "%s\n", xml_body(xdata));
retval = 0;
done:
if (xret)
xml_free(xret);
if (msg)
free(msg);
return retval;
}

View file

@ -17,13 +17,14 @@ delete("Delete a configuration item") all("Delete whole candidate configuration
startup("Store running as startup config"), db_copy("running","startup");
no("Negate or remove") debug("Debugging parts of the system"), cli_debug_cliv((int32)0);
debug("Debugging parts of the system"), cli_debug_cliv((int32)1);{
level("Set debug level: 1..n") <level:int32>("Set debug level (0..n)"), cli_debug_cliv();
level("Set debug level: 1..n") <level:int32>("Set debug level (0..n)"), cli_debug_backendv();
}
discard("Discard edits (rollback 0)"), discard_changesv();
compare("Compare running and candidate"), compare_dbsv((int32)1);
show("Show a particular state of the system"){
xpath("Show configuration") <xpath:string>("XPATH expression"), show_confv_xpath("candidate","/");
xpath("Show configuration") <xpath:string>("XPATH expression"), show_confv_xpath("candidate");
compare("Compare candidate and running databases"), compare_dbsv((int32)0);{
xml("Show comparison in xml"), compare_dbsv((int32)0);
text("Show comparison in text"), compare_dbsv((int32)1);
@ -43,3 +44,8 @@ load("Load configuration from XML file") <filename:string>("Filename (local file
merge("Merge file with existent candidate"), load_config_filev("filename","merge");
}
example("This is a comment") <var:int32>("Just a random number"), mycallback("myarg");
downcall("This is a downcall") <str:rest>, downcall();
notify("Get notifications from backend"), cli_notifyv("ROUTING","1","txt");
no("Negate") notify("Get notifications from backend"), cli_notifyv("ROUTING","0","xml");
lock,cli_lock("candidate");
unlock,cli_unlock("candidate");