YANG Action (RFC 7950 Section 7.15)

See [Support for "action" statement](https://github.com/clicon/clixon/issues/101)
This commit is contained in:
Olof hagsand 2022-06-03 11:14:58 +02:00
parent 87c65c3541
commit bdb516fec9
16 changed files with 583 additions and 104 deletions

View file

@ -35,6 +35,7 @@
* The example have the following optional arguments that you can pass as
* argc/argv after -- in clixon_backend:
* -a <..> Register callback for this yang action
* -r enable the reset function
* -s enable the state function
* -S <file> read state data from file, otherwise construct it programmatically (requires -s)
@ -66,7 +67,14 @@
#include <clixon/clixon_backend.h>
/* Command line options to be passed to getopt(3) */
#define BACKEND_EXAMPLE_OPTS "rsS:x:iuUt:v:"
#define BACKEND_EXAMPLE_OPTS "a:rsS:x:iuUt:v:"
/*! Yang action
* Start backend with -- -a <instance-id>
* where instance-id points to an action node in some YANG
* Hard-coded to action "reset" from RFC7950 7.15
*/
static char *_action_instanceid = NULL;
/*! Variable to control if reset code is run.
* The reset code inserts "extra XML" which assumes ietf-interfaces is
@ -357,6 +365,28 @@ example_copy_extra(clicon_handle h, /* Clicon handle */
return retval;
}
/*! Action callback, example from RFC7950 7.15
* Note callback is hardcoded C, while registration is controlled by -- -a option
*/
static int
example_action_reset(clicon_handle h, /* Clicon handle */
cxobj *xe, /* Request: <rpc><xn></rpc> */
cbuf *cbret, /* Reply eg <rpc-reply>... */
void *arg, /* client_entry */
void *regarg) /* Argument given at register */
{
int retval = -1;
char *reset_at;
if ((reset_at = xml_find_body(xe, "reset-at")) != NULL)
/* Just copy input to output */
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><reset-finished-at xmlns=\"urn:example:server-farm\">%s</reset-finished-at></rpc-reply>",
NETCONF_BASE_NAMESPACE, reset_at);
retval = 0;
// done:
return retval;
}
/*! Called to get state data from plugin by programmatically adding state
*
* @param[in] h Clicon handle
@ -1155,7 +1185,29 @@ example_reset(clicon_handle h,
int
example_start(clicon_handle h)
{
return 0;
int retval = -1;
yang_stmt *yspec;
yang_stmt *ya = NULL;
/* Register action callback, example from RFC7950 7.15
* Can not be made in _init since YANG is not loaded
* Note that callback is hardcoded here since it is C, but YANG and name of action
* is not. It is enough to point via an schema-node id to the correct action,
* such as "/sfarm:server/sfarm:reset"
*/
if (_action_instanceid){
if ((yspec = clicon_dbspec_yang(h)) == NULL){
clicon_err(OE_FATAL, 0, "No DB_SPEC");
goto done;
}
if (yang_abs_schema_nodeid(yspec, _action_instanceid, &ya) == 0){
if (ya && action_callback_register(h, ya, example_action_reset, NULL) < 0)
goto done;
}
}
retval = 0;
done:
return retval;
}
/*! Plugin daemon.
@ -1254,6 +1306,9 @@ clixon_plugin_init(clicon_handle h)
optind = 1;
while ((c = getopt(argc, argv, BACKEND_EXAMPLE_OPTS)) != -1)
switch (c) {
case 'a':
_action_instanceid = optarg;
break;
case 'r':
_reset = 1;
break;
@ -1346,6 +1401,7 @@ clixon_plugin_init(clicon_handle h)
"copy-config"
) < 0)
goto done;
/* Upgrade callback: if you start the backend with -- -u you will get the
* test interface example. Otherwise the auto-upgrade feature is enabled.
*/