* Generilized top-level yang parsing functions

* Clarified semantics of main yang module:
    * -y option to commands MUST specify filename
    * CLICON_YANG_MODULE_MAIN MUST specify a module
    * yang_parse() changed to take either filename or module name and revision.
  * Removed clicon_dbspec_name[_set]().
    * Use yang_main_module_name() instead.
  * Replaced yang_spec_main with yang_spec_parse_module
  * Added yang_spec_parse_file
This commit is contained in:
Olof hagsand 2018-10-07 11:04:33 +02:00
parent 782f75a7b9
commit acb8748470
21 changed files with 369 additions and 340 deletions

View file

@ -3,14 +3,18 @@
## 3.8.0 (Upcoming)
### Major New features
### API changes on existing features (you may need to change your code)
* YANG Module Library support
* According to RFC 7895 and implemented by ietf-yang-library.yang
* Supported: module, name, revision, namespace
* Not supported: notification, deviation, module-set-id, etc.
* Enabled by default, disable by resetting CLICON_MODULE_LIBRARY_RFC7895
* Yang 1.1 notification support (RFC 7950: Sec 7.16)
* Major rewrite of event streams
* See clicon_stream.[ch] for details
* Added stream discovery according to RFC 5277 for netconf and RFC 8040 for restconf
* Enabled by CLICON_STREAM_DISCOVERY_RFC5277 and CLICON_STREAM_DISCOVERY_RFC8040.
### API changes on existing features (you may need to change your code)
* Major rewrite of event streams
* If you used old event callbacks API, you need to switch to the streams API
* See clixon_stream.[ch]
@ -18,23 +22,30 @@
* clicon_log_register_callback()
* subscription_add() --> stream_register()
* backend_notify() and backend_notify_xml() - use stream_notify() instead
* Added stream discovery according to RFC 5277 for netconf and RFC 8040 for restconf
* Enabled by CLICON_STREAM_DISCOVERY_RFC5277 and CLICON_STREAM_DISCOVERY_RFC8040.
* Example uses "NETCONF" stream instead of "ROUTING"
* clixon_restconf and clixon_netconf now take -D <level> as command-line option instead of just -D
* This aligns to clixon_cli and clixon_backend
* Application command option -S to clixon_netconf is obsolete. Use `clixon_netconf -l s` instead.
### Minor changes
* Added timeout option -t for clixon_netconf - quit after max time.
* Comply to RFC 8040 3.5.3.1 rule: api-identifier = [module-name ":"] identifier
* The "module-name" was a no-op before.
* This means that there was no difference between eg: GET /restconf/data/ietf-yang-library:modules-state and GET /restconf/data/XXXX:modules-state
* Unified log handling for all clicon applications using -l e|o|s|f<file>.
* The options stand for e:stderr, o:stdout, s: syslog, f:file
* Added file logging (`-l f` or `-l f<file>`) for cases where neither syslog nor stderr is useful.
* Comply to RFC 8040 3.5.3.1 rule: api-identifier = [module-name ":"] identifier
* The "module-name" was a no-op before.
* This means that there was no difference between eg: GET /restconf/data/ietf-yang-library:modules-state and GET /restconf/data/XXXX:modules-state
* Generilized top-level yang parsing functions
* Clarified semantics of main yang module:
* -y option to commands MUST specify filename
* CLICON_YANG_MODULE_MAIN MUST specify a module
* yang_parse() changed to take either filename or module name and revision.
* Removed clicon_dbspec_name[_set]().
* Use yang_main_module_name() instead.
* Replaced yang_spec_main with yang_spec_parse_module
* Added yang_spec_parse_file
### Minor changes
* Obsoleted COMPAT_CLIV and COMPAT_XSL that were optional in 3.7
* Added timeout option -t for clixon_netconf - quit after max time.
* Added -l option for clixon_backend for directing syslog to stderr or stdout if running in foreground
### Corrected Bugs

View file

@ -129,24 +129,24 @@ usage(clicon_handle h,
fprintf(stderr, "usage:%s\n"
"where options are\n"
" -h\t\tHelp\n"
" -D <level>\tDebug level\n"
" -f <file>\tCLICON config file\n"
" -l <s|e|o|f<file>> \tLog on (s)yslog, std(e)rr or std(o)ut (stderr is default) Only valid if -F, if background syslog is on syslog.\n"
" -d <dir>\tSpecify backend plugin directory (default: %s)\n"
" -b <dir>\tSpecify XMLDB database directory\n"
" -F\t\tRun in foreground, do not run as daemon\n"
" -z\t\tKill other config daemon and exit\n"
" -a UNIX|IPv4|IPv6\tInternal backend socket family\n"
" -u <path|addr>\tInternal socket domain path or IP addr (see -a)(default: %s)\n"
" -P <file>\tPid filename (default: %s)\n"
" -1\t\tRun once and then quit (dont wait for events)\n"
" -s <mode>\tSpecify backend startup mode: none|startup|running|init (replaces -IRCr\n"
" -c <file>\tLoad extra xml configuration, but don't commit.\n"
" -g <group>\tClient membership required to this group (default: %s)\n"
"\t-h\t\tHelp\n"
"\t-D <level>\tDebug level\n"
"\t-f <file>\tCLICON config file\n"
"\t-l (s|e|o|f<file>) Log on (s)yslog, std(e)rr or std(o)ut (stderr is default) Only valid if -F, if background syslog is on syslog.\n"
"\t-d <dir>\tSpecify backend plugin directory (default: %s)\n"
"\t-b <dir>\tSpecify XMLDB database directory\n"
"\t-F\t\tRun in foreground, do not run as daemon\n"
"\t-z\t\tKill other config daemon and exit\n"
"\t-a UNIX|IPv4|IPv6 Internal backend socket family\n"
"\t-u <path|addr>\tInternal socket domain path or IP addr (see -a)(default: %s)\n"
"\t-P <file>\tPid filename (default: %s)\n"
"\t-1\t\tRun once and then quit (dont wait for events)\n"
"\t-s <mode>\tSpecify backend startup mode: none|startup|running|init)\n"
"\t-c <file>\tLoad extra xml configuration, but don't commit.\n"
"\t-g <group>\tClient membership required to this group (default: %s)\n"
" -y <file>\tOverride yang spec file (dont include .yang suffix)\n"
" -x <plugin>\tXMLDB plugin\n",
"\t-y <file>\tLoad yang spec file (override yang main module)\n"
"\t-x <plugin>\tXMLDB plugin\n",
argv0,
plgdir ? plgdir : "none",
confsock ? confsock : "none",
@ -258,7 +258,7 @@ nacm_load_external(clicon_handle h)
}
if ((yspec = yspec_new()) == NULL)
goto done;
if (yang_parse(h, CLIXON_DATADIR, "ietf-netconf-acm", NULL, yspec) < 0)
if (yang_parse(h, NULL, "ietf-netconf-acm", CLIXON_DATADIR, NULL, yspec) < 0)
goto done;
fd = fileno(f);
/* Read configfile */
@ -519,6 +519,8 @@ main(int argc,
char *xml_format;
char *nacm_mode;
int logdst = CLICON_LOG_SYSLOG|CLICON_LOG_STDERR;
yang_spec *yspec = NULL;
char *yang_filename = NULL;
/* In the startup, logs to stderr & syslog and debug flag set later */
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
@ -638,8 +640,8 @@ main(int argc,
case 'g': /* config socket group */
clicon_option_str_set(h, "CLICON_SOCK_GROUP", optarg);
break;
case 'y' :{ /* Override yang module or absolute filename */
clicon_option_str_set(h, "CLICON_YANG_MODULE_MAIN", optarg);
case 'y' :{ /* Load yang spec file (override yang main module) */
yang_filename = optarg;
break;
}
case 'x' :{ /* xmldb plugin */
@ -727,18 +729,31 @@ main(int argc,
/* Connect to plugin to get a handle */
if (xmldb_connect(h) < 0)
goto done;
/* Read and parse application yang specification */
if (yang_spec_main(h) == NULL)
if ((yspec = yspec_new()) == NULL)
goto done;
clicon_dbspec_yang_set(h, yspec);
/* Read and parse application yang specification: either a module and search
* in dir, or a specific file
*/
if (yang_filename){
if (yang_spec_parse_file(h, yang_filename, clicon_yang_dir(h), yspec) < 0)
goto done;
}
else if (yang_spec_parse_module(h, clicon_yang_module_main(h),
clicon_yang_dir(h),
clicon_yang_module_revision(h),
yspec) < 0)
goto done;
/* Add system modules */
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC8040") &&
yang_spec_append(h, CLIXON_DATADIR, "ietf-restconf-monitoring", NULL)< 0)
yang_spec_parse_module(h, "ietf-restconf-monitoring", CLIXON_DATADIR, NULL, yspec)< 0)
goto done;
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277") &&
yang_spec_append(h, CLIXON_DATADIR, "ietf-netconf-notification", NULL)< 0)
yang_spec_parse_module(h, "ietf-netconf-notification", CLIXON_DATADIR, NULL, yspec)< 0)
goto done;
if (clicon_option_bool(h, "CLICON_MODULE_LIBRARY_RFC7895") &&
yang_spec_append(h, CLIXON_DATADIR, "ietf-yang-library", NULL)< 0)
yang_spec_parse_module(h, "ietf-yang-library", CLIXON_DATADIR, NULL, yspec)< 0)
goto done;
/* Set options: database dir and yangspec (could be hidden in connect?)*/
if (xmldb_setopt(h, "dbdir", clicon_xmldb_dir(h)) < 0)

View file

@ -251,6 +251,7 @@ main(int argc, char **argv)
int dump_configfile_xml = 0;
yang_spec *yspec;
struct passwd *pw;
char *yang_filename = NULL;
/* Defaults */
once = 0;
@ -379,8 +380,8 @@ main(int argc, char **argv)
case 'L' : /* Debug print dynamic CLI syntax */
logclisyntax++;
break;
case 'y' :{ /* Overwrite yang module or absolute filename */
clicon_option_str_set(h, "CLICON_YANG_MODULE_MAIN", optarg);
case 'y' :{ /* Load yang spec file (override yang main module) */
yang_filename = optarg;
break;
}
case 'c' :{ /* Overwrite clispec with absolute filename */
@ -414,8 +415,19 @@ main(int argc, char **argv)
*/
cv_exclude_keys(clicon_cli_varonly(h));
/* Parse db specification as cli*/
if ((yspec = yang_spec_main(h)) == NULL)
if ((yspec = yspec_new()) == NULL)
goto done;
clicon_dbspec_yang_set(h, yspec);
/* Parse db specification as cli.
* If -y <file> is given, it overrides main module */
if (yang_filename){
if (yang_spec_parse_file(h, yang_filename, clicon_yang_dir(h), yspec) < 0)
goto done;
}
else if (yang_spec_parse_module(h, clicon_yang_module_main(h),
clicon_yang_dir(h),
clicon_yang_module_revision(h),
yspec) < 0)
goto done;
if (printspec)
yang_print(stdout, (yang_node*)yspec);
@ -425,17 +437,20 @@ main(int argc, char **argv)
*/
if (clicon_cli_genmodel(h)){
parse_tree pt = {0,}; /* cli parse tree */
char *name; /* main module name */
/* Create cli command tree from dbspec */
if (yang2cli(h, yspec, &pt, clicon_cli_genmodel_type(h)) < 0)
goto done;
len = strlen("datamodel:") + strlen(clicon_dbspec_name(h)) + 1;
name = yang_main_module_name(yspec);
len = strlen("datamodel:") + strlen(name) + 1;
if ((treename = malloc(len)) == NULL){
clicon_err(OE_UNIX, errno, "malloc");
goto done;
}
snprintf(treename, len, "datamodel:%s", clicon_dbspec_name(h));
snprintf(treename, len, "datamodel:%s", name);
cligen_tree_add(cli_cligen(h), treename, pt);
if (printgen)

View file

@ -276,8 +276,6 @@ netconf_terminate(clicon_handle h)
clicon_rpc_close_session(h);
if ((yspec = clicon_dbspec_yang(h)) != NULL)
yspec_free(yspec);
if ((yspec = clicon_netconf_yang(h)) != NULL)
yspec_free(yspec);
event_exit();
clicon_handle_exit(h);
clicon_log_exit();
@ -306,12 +304,12 @@ usage(clicon_handle h,
"\t-D <level>\tDebug level\n"
"\t-q\t\tQuiet: dont send hello prompt\n"
"\t-f <file>\tConfiguration file (mandatory)\n"
"\t-l <e|o|s|f<file>> \tLog on std(e)rr, std(o)ut, (s)yslog, (f)ile (syslog is default)\n"
"\t-l (e|o|s|f<file>) \tLog on std(e)rr, std(o)ut, (s)yslog, (f)ile (syslog is default)\n"
"\t-a UNIX|IPv4|IPv6\tInternal backend socket family\n"
"\t-u <path|addr>\tInternal socket domain path or IP addr (see -a)\n"
"\t-d <dir>\tSpecify netconf plugin directory dir (default: %s)\n"
"\t-y <file>\tOverride yang spec file (dont include .yang suffix)\n"
"\t-y <file>\tLoad yang spec file (override yang main module)\n"
"\t-U <user>\tOver-ride unix user with a pseudo user for NACM.\n"
"\t-t <sec>\tTimeout in seconds. Quit after this time.\n",
argv0,
@ -333,6 +331,8 @@ main(int argc,
int logdst = CLICON_LOG_STDERR;
struct passwd *pw;
struct timeval tv = {0,}; /* timeout */
yang_spec *yspec = NULL;
char *yang_filename = NULL;
/* Create handle */
if ((h = clicon_handle_init()) == NULL)
@ -407,8 +407,8 @@ main(int argc,
usage(h, argv[0]);
clicon_option_str_set(h, "CLICON_NETCONF_DIR", optarg);
break;
case 'y' :{ /* Overwrite yang module or absolute filename */
clicon_option_str_set(h, "CLICON_YANG_MODULE_MAIN", optarg);
case 'y' :{ /* Load yang spec file (override yang main module) */
yang_filename = optarg;
break;
}
case 'U': /* Clixon 'pseudo' user */
@ -428,12 +428,22 @@ main(int argc,
argc -= optind;
argv += optind;
if ((yspec = yspec_new()) == NULL)
goto done;
clicon_dbspec_yang_set(h, yspec);
/* Parse yang database spec file */
if (yang_spec_main(h) == NULL)
if (yang_filename){
if (yang_spec_parse_file(h, yang_filename, clicon_yang_dir(h), yspec) < 0)
goto done;
}
else if (yang_spec_parse_module(h, clicon_yang_module_main(h),
clicon_yang_dir(h),
clicon_yang_module_revision(h),
yspec) < 0)
goto done;
/* Parse netconf yang spec file */
if (yang_spec_netconf(h) == NULL)
/* Add netconf yang spec, used by netconf client and as internal protocol */
if (yang_spec_parse_module(h, "ietf-yang-library", CLIXON_DATADIR, NULL, yspec)< 0)
goto done;
/* Initialize plugins group */

View file

@ -955,15 +955,9 @@ netconf_rpc_dispatch(clicon_handle h,
{
int retval = -1;
cxobj *xe;
yang_spec *yspec = NULL;
char *username;
cxobj *xa;
/* Check incoming RPC against system / netconf RPC:s */
if ((yspec = clicon_netconf_yang(h)) == NULL){
clicon_err(OE_YANG, ENOENT, "No netconf yang spec");
goto done;
}
/* Tag username on all incoming requests in case they are forwarded as internal messages
* This may be unecesary since not all are forwarded.
* It may even be wrong if something else is done with the incoming message?

View file

@ -494,7 +494,7 @@ usage(clicon_handle h,
"\t-f <file>\tConfiguration file (mandatory)\n"
"\t-l <s|f<file>> \tLog on (s)yslog, (f)ile (syslog is default)\n"
"\t-d <dir>\tSpecify restconf plugin directory dir (default: %s)\n"
"\t-y <file>\tOverride yang spec file (dont include .yang suffix)\n"
"\t-y <file>\tLoad yang spec file (override yang main module)\n"
"\t-a UNIX|IPv4|IPv6\tInternal backend socket family\n"
"\t-u <path|addr>\tInternal socket domain path or IP addr (see -a)\n",
argv0,
@ -522,6 +522,8 @@ main(int argc,
char *dir;
char *tmp;
int logdst = CLICON_LOG_SYSLOG;
yang_spec *yspec = NULL;
char *yang_filename = NULL;
/* In the startup, logs to stderr & debug flag set later */
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
@ -589,8 +591,8 @@ main(int argc,
usage(h, argv[0]);
clicon_option_str_set(h, "CLICON_RESTCONF_DIR", optarg);
break;
case 'y' : /* yang module */
yangspec = optarg;
case 'y' : /* Load yang spec file (override yang main module) */
yang_filename = optarg;
break;
case 'a': /* internal backend socket address family */
clicon_option_str_set(h, "CLICON_SOCK_FAMILY", optarg);
@ -616,18 +618,28 @@ main(int argc,
if (clixon_plugins_load(h, CLIXON_PLUGIN_INIT, dir, NULL) < 0)
return -1;
/* Parse yang database spec file */
if (yang_spec_main(h) == NULL)
/* Parse main yang spec */
if ((yspec = yspec_new()) == NULL)
goto done;
clicon_dbspec_yang_set(h, yspec);
if (yang_filename){
if (yang_spec_parse_file(h, yang_filename, clicon_yang_dir(h), yspec) < 0)
goto done;
}
else if (yang_spec_parse_module(h, clicon_yang_module_main(h),
clicon_yang_dir(h),
clicon_yang_module_revision(h),
yspec) < 0)
goto done;
/* Add system modules */
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC8040") &&
yang_spec_append(h, CLIXON_DATADIR, "ietf-restconf-monitoring", NULL)< 0)
yang_spec_parse_module(h, "ietf-restconf-monitoring", CLIXON_DATADIR, NULL, yspec)< 0)
goto done;
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277") &&
yang_spec_append(h, CLIXON_DATADIR, "ietf-netconf-notification", NULL)< 0)
yang_spec_parse_module(h, "ietf-netconf-notification", CLIXON_DATADIR, NULL, yspec)< 0)
goto done;
if (clicon_option_bool(h, "CLICON_MODULE_LIBRARY_RFC7895") &&
yang_spec_append(h, CLIXON_DATADIR, "ietf-yang-library", NULL)< 0)
yang_spec_parse_module(h, "ietf-yang-library", CLIXON_DATADIR, NULL, yspec)< 0)
goto done;
if (stream_register(h, "NETCONF", "default NETCONF event stream") < 0)

View file

@ -206,7 +206,7 @@ main(int argc, char **argv)
if ((yspec = yspec_new()) == NULL)
goto done;
/* Parse yang spec from given file */
if (yang_parse(h, yangdir, yangmodule, NULL, yspec) < 0)
if (yang_parse(h, NULL, yangmodule, yangdir, NULL, yspec) < 0)
goto done;
/* Set database directory option */
if (xmldb_setopt(h, "dbdir", dbdir) < 0)

View file

@ -1387,7 +1387,7 @@ main(int argc,
db_init(db);
if ((yspec = yspec_new()) == NULL)
goto done
if (yang_parse(h, yangdir, yangmod, NULL, yspec) < 0)
if (yang_parse(h, NULL, yangmod, yangdir, NULL, yspec) < 0)
goto done;
if (strcmp(cmd, "get")==0){
if (argc < 5)

View file

@ -44,6 +44,7 @@
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/syslog.h>
/* clicon */
#include <cligen/cligen.h>
@ -119,7 +120,7 @@ clixon_plugin_init(clicon_handle h)
clicon_debug(1, "%s backend nacm", __FUNCTION__);
nacm_mode = clicon_option_str(h, "CLICON_NACM_MODE");
if (nacm_mode==NULL || strcmp(nacm_mode, "disabled") == 0){
clicon_debug(1, "%s CLICON_NACM_MODE not enabled: example nacm module disabled", __FUNCTION__);
clicon_log(LOG_WARNING, "%s CLICON_NACM_MODE not enabled: example nacm module disabled", __FUNCTION__);
return NULL;
}
return &api;

View file

@ -164,12 +164,6 @@ int clicon_quiet_mode_set(clicon_handle h, int val);
yang_spec * clicon_dbspec_yang(clicon_handle h);
int clicon_dbspec_yang_set(clicon_handle h, struct yang_spec *ys);
char *clicon_dbspec_name(clicon_handle h);
int clicon_dbspec_name_set(clicon_handle h, char *name);
yang_spec *clicon_netconf_yang(clicon_handle h);
int clicon_netconf_yang_set(clicon_handle h, struct yang_spec *ys);
plghndl_t clicon_xmldb_plugin_get(clicon_handle h);
int clicon_xmldb_plugin_set(clicon_handle h, plghndl_t handle);

View file

@ -244,6 +244,7 @@ yang_stmt *ys_dup(yang_stmt *old);
int yn_insert(yang_node *yn_parent, yang_stmt *ys_child);
yang_stmt *yn_each(yang_node *yn, yang_stmt *ys);
char *yang_key2str(int keyword);
char *yang_main_module_name(yang_spec *ysp);
char *yarg_prefix(yang_stmt *ys);
char *yarg_id(yang_stmt *ys);
int yang_nodeid_split(char *nodeid, char **prefix, char **id);
@ -260,8 +261,9 @@ int yang_print(FILE *f, yang_node *yn);
int yang_print_cbuf(cbuf *cb, yang_node *yn, int marginal);
int ys_populate(yang_stmt *ys, void *arg);
yang_stmt *yang_parse_file(int fd, const char *name, yang_spec *ysp);
int yang_parse(clicon_handle h, const char *yang_dir,
const char *module, const char *revision, yang_spec *ysp);
int yang_parse(clicon_handle h, const char *filename,
const char *module, const char *dir,
const char *revision, yang_spec *ysp);
int yang_apply(yang_node *yn, enum rfc_6020 key, yang_applyfn_t fn,
void *arg);
int yang_abs_schema_nodeid(yang_spec *yspec, char *schema_nodeid,
@ -272,9 +274,8 @@ cg_var *ys_parse(yang_stmt *ys, enum cv_type cvtype);
int ys_parse_sub(yang_stmt *ys, char *extra);
int yang_mandatory(yang_stmt *ys);
int yang_config(yang_stmt *ys);
yang_spec *yang_spec_netconf(clicon_handle h);
yang_spec *yang_spec_main(clicon_handle h);
int yang_spec_append(clicon_handle h, char *yang_dir, char *yang_module, char *yang_revision);
int yang_spec_parse_module(clicon_handle h, char *module, char *dir, char *revision, yang_spec *yspec);
int yang_spec_parse_file(clicon_handle h, char *filename, char *dir, yang_spec *yspec);
cvec *yang_arg2cvec(yang_stmt *ys, char *delimi);
int yang_key_match(yang_node *yn, char *name);

View file

@ -216,7 +216,7 @@ clicon_options_main(clicon_handle h)
if (xml){ /* Read clixon yang file */
if ((yspec = yspec_new()) == NULL)
goto done;
if (yang_parse(h, CLIXON_DATADIR, "clixon-config", NULL, yspec) < 0)
if (yang_parse(h, NULL, "clixon-config", CLIXON_DATADIR, NULL, yspec) < 0)
goto done;
/* Read configfile */
if (clicon_option_readfile_xml(copt, configfile, yspec) < 0)
@ -571,58 +571,6 @@ clicon_dbspec_yang_set(clicon_handle h,
return 0;
}
/*! Get YANG NETCONF specification
* Must use hash functions directly since they are not strings.
*/
yang_spec *
clicon_netconf_yang(clicon_handle h)
{
clicon_hash_t *cdat = clicon_data(h);
size_t len;
void *p;
if ((p = hash_value(cdat, "netconf_yang", &len)) != NULL)
return *(yang_spec **)p;
return NULL;
}
/*! Set yang netconf specification
* ys must be a malloced pointer
*/
int
clicon_netconf_yang_set(clicon_handle h,
struct yang_spec *ys)
{
clicon_hash_t *cdat = clicon_data(h);
/* It is the pointer to ys that should be copied by hash,
so we send a ptr to the ptr to indicate what to copy.
*/
if (hash_add(cdat, "netconf_yang", &ys, sizeof(ys)) == NULL)
return -1;
return 0;
}
/*! Get dbspec name as read from spec. Can be used in CLI '@' syntax.
* XXX: this we muśt change,...
*/
char *
clicon_dbspec_name(clicon_handle h)
{
if (!clicon_option_exists(h, "dbspec_name"))
return NULL;
return clicon_option_str(h, "dbspec_name");
}
/*! Set dbspec name as read from spec. Can be used in CLI '@' syntax.
*/
int
clicon_dbspec_name_set(clicon_handle h, char *name)
{
return clicon_option_str_set(h, "dbspec_name", name);
}
/*! Get xmldb datastore plugin handle, as used by dlopen/dlsym/dlclose */
plghndl_t
clicon_xmldb_plugin_get(clicon_handle h)

View file

@ -344,6 +344,8 @@ ys_dup(yang_stmt *old)
/*! Insert yang statement as child of a parent yang_statement, last in list
*
* @param[in] yn_parent Add child to this parent
* @param[in] ys_child Add this child
* Also add parent to child as up-pointer
*/
int
@ -607,7 +609,6 @@ yang_find_schemanode(yang_node *yn,
return ysmatch;
}
/*! Find first matching data node in all (sub)modules in a yang spec
*
* @param[in] ysp Yang specification
@ -756,7 +757,22 @@ yang_key2str(int keyword)
return (char*)clicon_int2str(ykmap, keyword);
}
/*! Find top module or sub-module. Note that ultimate top is yang spec
/*! Name of main module of a specification. That is, name of first module
* @param[in] ysp Yang specification
* @retval name Name of first yang module
*/
char *
yang_main_module_name(yang_spec *ysp)
{
yang_stmt *ym;
if ((ym = yang_find((yang_node*)ysp, Y_MODULE, 0)) != NULL)
return ym->ys_argument;
return NULL;
}
/*! Find top module or sub-module given a statement. Ultimate top is yang spec
* The routine recursively finds ancestors.
* @param[in] ys Any yang statement in a yang tree
* @retval ymod The top module or sub-module
* @see ys_spec
@ -1612,7 +1628,8 @@ yang_expand(yang_node *yn)
* Calling order:
* yang_parse # Parse top-level yang module. Expand and populate yang tree
* yang_parse_recurse # Parse one yang module, go through its (sub)modules, parse them and then recursively parse them
* yang_parse_file # Read yang file into a string
* yang_parse_filename # Read yang file into a string
* yang_parse_file # Read yang open file descriptor into a string
* yang_parse_str # Set up yacc parser and call it given a string
* clixon_yang_parseparse # Actual yang parsing using yacc
*/
@ -1712,49 +1729,6 @@ yang_parse_file(int fd,
return ymod; /* top-level (sub)module */
}
/*! Open a file, read into a string and invoke yang parsing
*
* Similar to clicon_yang_str(), just read a file first
* (cloned from cligen)
* @param[in] h CLICON handle
* @param[in] filename Name of file
* @param[in] ysp Yang specification. Should ave been created by caller using yspec_new
* @retval ymod Top-level yang (sub)module
* @retval NULL Error encountered
* The database symbols are inserted in alphabetical order.
* Calling order:
* yang_parse # Parse top-level yang module. Expand and populate yang tree
* yang_parse_recurse # Parse one yang module, go through its (sub)modules, parse them and then recursively parse them
* yang_parse_file # Read yang file into a string
* yang_parse_str # Set up yacc parser and call it given a string
* clixon_yang_parseparse # Actual yang parsing using yacc
*/
static yang_stmt *
yang_parse_filename(const char *filename,
yang_spec *ysp)
{
yang_stmt *ymod = NULL;
int fd = -1;
struct stat st;
clicon_log(LOG_DEBUG, "Parsing yang file: %s", filename);
if (stat(filename, &st) < 0){
clicon_err(OE_YANG, errno, "%s not found", filename);
goto done;
}
if ((fd = open(filename, O_RDONLY)) < 0){
clicon_err(OE_YANG, errno, "open(%s)", filename);
goto done;
}
if ((ymod = yang_parse_file(fd, filename, ysp)) < 0)
goto done;
done:
if (fd != -1)
close(fd);
return ymod; /* top-level (sub)module */
}
/*! No specific revision give. Match a yang file given dir and module
* @param[in] h CLICON handle
* @param[in] yang_dir Directory where all YANG module files reside
@ -1805,6 +1779,82 @@ yang_parse_find_match(const char *yang_dir,
return retval;
}
/*! Open a file, read into a string and invoke yang parsing
*
* Similar to clicon_yang_str(), just read a file first
* (cloned from cligen)
* @param[in] h CLICON handle
* @param[in] filename Name of file
* @param[in] ysp Yang specification. Should ave been created by caller using yspec_new
* @retval ymod Top-level yang (sub)module
* @retval NULL Error encountered
* The database symbols are inserted in alphabetical order.
* Calling order:
* yang_parse # Parse top-level yang module. Expand and populate yang tree
* yang_parse_recurse # Parse one yang module, go through its (sub)modules, parse them and then recursively parse them
* yang_parse_filename # Read yang file into a string
* yang_parse_file # Read yang open file descriptor into a string
* yang_parse_str # Set up yacc parser and call it given a string
* clixon_yang_parseparse # Actual yang parsing using yacc
*/
static yang_stmt *
yang_parse_filename(const char *filename,
yang_spec *ysp)
{
yang_stmt *ymod = NULL;
int fd = -1;
struct stat st;
clicon_log(LOG_DEBUG, "Parsing yang file: %s", filename);
if (stat(filename, &st) < 0){
clicon_err(OE_YANG, errno, "%s not found", filename);
goto done;
}
if ((fd = open(filename, O_RDONLY)) < 0){
clicon_err(OE_YANG, errno, "open(%s)", filename);
goto done;
}
if ((ymod = yang_parse_file(fd, filename, ysp)) < 0)
goto done;
done:
if (fd != -1)
close(fd);
return ymod; /* top-level (sub)module */
}
static yang_stmt *
yang_parse_module(const char *module,
const char *dir,
const char *revision,
yang_spec *ysp)
{
cbuf *fbuf = NULL;
int nr;
yang_stmt *ymod = NULL;
if ((fbuf = cbuf_new()) == NULL){
clicon_err(OE_YANG, errno, "cbuf_new");
goto done;
}
if (revision)
cprintf(fbuf, "%s/%s@%s.yang", dir, module, revision);
else{
/* No specific revision, Match a yang file */
if ((nr = yang_parse_find_match(dir, module, fbuf)) < 0)
goto done;
if (nr == 0){
clicon_err(OE_YANG, errno, "No matching %s yang files found in %s (expected module name or absolute filename)", module, dir);
goto done;
}
}
if ((ymod = yang_parse_filename(cbuf_get(fbuf), ysp)) == NULL)
goto done;
done:
return ymod; /* top-level (sub)module */
}
/*! Parse one yang module then go through (sub)modules and parse them recursively
*
* @param[in] h CLICON handle
@ -1818,68 +1868,44 @@ yang_parse_find_match(const char *yang_dir,
* Calling order:
* yang_parse # Parse top-level yang module. Expand and populate yang tree
* yang_parse_recurse # Parse one yang module, go through its (sub)modules, parse them and then recursively parse them
* yang_parse_file # Read yang file into a string
* yang_parse_filename # Read yang file into a string
* yang_parse_file # Read yang open file descriptor into a string
* yang_parse_str # Set up yacc parser and call it given a string
* clixon_yang_parseparse # Actual yang parsing using yacc
*/
static yang_stmt *
yang_parse_recurse(const char *yang_dir,
const char *module,
const char *revision,
static int
yang_parse_recurse(yang_stmt *ymod,
const char *dir,
yang_spec *ysp)
{
int retval = -1;
yang_stmt *yi = NULL; /* import */
yang_stmt *ymod = NULL;
yang_stmt *yrev;
char *modname;
char *submodule;
char *subrevision;
cbuf *fbuf = NULL;
int nr;
if (module[0] == '/'){
if ((ymod = yang_parse_filename(module, ysp)) == NULL)
goto done;
}
else {
if ((fbuf = cbuf_new()) == NULL){
clicon_err(OE_YANG, errno, "cbuf_new");
goto done;
}
if (revision)
cprintf(fbuf, "%s/%s@%s.yang", yang_dir, module, revision);
else{
/* No specific revision, Match a yang file */
if ((nr = yang_parse_find_match(yang_dir, module, fbuf)) < 0)
goto done;
if (nr == 0){
clicon_err(OE_YANG, errno, "No matching %s yang files found in %s (expected module name or absolute filename)", module, yang_dir);
goto done;
}
}
if ((ymod = yang_parse_filename(cbuf_get(fbuf), ysp)) == NULL)
goto done;
}
yang_stmt *subymod;
/* go through all import statements of ysp (or its module) */
while ((yi = yn_each((yang_node*)ymod, yi)) != NULL){
if (yi->ys_keyword != Y_IMPORT)
continue;
modname = yi->ys_argument;
submodule = yi->ys_argument;
if ((yrev = yang_find((yang_node*)yi, Y_REVISION_DATE, NULL)) != NULL)
subrevision = yrev->ys_argument;
else
subrevision = NULL;
if (yang_find((yang_node*)ysp, Y_MODULE, modname) == NULL)
if (yang_find((yang_node*)ysp, Y_MODULE, submodule) == NULL)
/* recursive call */
if (yang_parse_recurse(yang_dir, modname, subrevision, ysp) == NULL){
if ((subymod = yang_parse_module(submodule, dir, subrevision, ysp)) == NULL)
goto done;
if (yang_parse_recurse(subymod, dir, ysp) < 0){
ymod = NULL;
goto done;
}
}
retval = 0;
done:
if (fbuf)
cbuf_free(fbuf);
return ymod; /* top-level (sub)module */
return retval; /* top-level (sub)module */
}
int
@ -1929,7 +1955,8 @@ ys_schemanode_check(yang_stmt *ys,
*
* @param[in] h CLICON handle
* @param[in] yang_dir Directory where all YANG module files reside (except mainfile)
* @param[in] mainmod Name of main YANG module. Or absolute file name.
* @param[in] filename File name containing Yang specification. Overrides module
* @param[in] module Name of main YANG module. Or absolute file name.
* @param[in] revision Main module revision date string or NULL
* @param[out] ysp Yang specification. Should have been created by caller using yspec_new
* @retval 0 Everything OK
@ -1941,34 +1968,49 @@ ys_schemanode_check(yang_stmt *ys,
* yang_parse # Parse top-level yang module. Expand and populate yang tree
* yang_parse_recurse # Parse one yang module, go through its (sub)modules,
* parse them and then recursively parse them
* yang_parse_file # Read yang file into a string
* yang_parse_filename # Read yang file into a string
* yang_parse_file # Read yang open file descriptor into a string
* yang_parse_str # Set up yacc parser and call it given a string
* clixon_yang_parseparse # Actual yang parsing using yacc
*/
int
yang_parse(clicon_handle h,
const char *yang_dir,
const char *mainmodule,
const char *filename,
const char *module,
const char *dir,
const char *revision,
yang_spec *ysp)
{
int retval = -1;
yang_stmt *ymod; /* Top-level yang (sub)module */
yang_stmt *ymod = NULL; /* Top-level yang (sub)module */
int i;
int modnr; /* Existing number of modules */
/* Step 1: parse from text to yang parse-tree. */
if ((ymod = yang_parse_recurse(yang_dir, mainmodule, revision, ysp)) == NULL)
modnr = ysp->yp_len;
if (filename){
if ((ymod = yang_parse_filename(filename, ysp)) == NULL)
goto done;
}
else
if ((ymod = yang_parse_module(module, dir, revision, ysp)) == NULL)
goto done;
/* From here on, apply actions on new modules, ie ones after modnr. */
/* Step 1: parse from text to yang parse-tree. */
/* Iterate through modules */
if (yang_parse_recurse(ymod, dir, ysp) < 0)
goto done;
/* Add top module name as dbspec-name */
clicon_dbspec_name_set(h, ymod->ys_argument);
/* Step 2: Go through parse tree and populate it with cv types */
if (yang_apply((yang_node*)ysp, -1, ys_populate, NULL) < 0)
for (i=modnr; i<ysp->yp_len; i++)
if (yang_apply((yang_node*)ysp->yp_stmt[i], -1, ys_populate, NULL) < 0)
goto done;
/* Step 3: Resolve all types: populate type caches. Requires eg length/range cvecs
* from ys_populate step
*/
yang_apply((yang_node*)ysp, Y_TYPE, ys_resolve_type, NULL);
for (i=modnr; i<ysp->yp_len; i++)
yang_apply((yang_node*)ysp->yp_stmt[i], Y_TYPE, ys_resolve_type, NULL);
/* Up to here resolving is made in the context they are defined, rather than the
context they are used. Like static scoping. After this we expand all
@ -1976,16 +2018,19 @@ yang_parse(clicon_handle h,
*/
/* Step 4: Macro expansion of all grouping/uses pairs. Expansion needs marking */
if (yang_expand((yang_node*)ysp) < 0)
for (i=modnr; i<ysp->yp_len; i++){
if (yang_expand((yang_node*)ysp->yp_stmt[i]) < 0)
goto done;
yang_apply((yang_node*)ymod, -1, ys_flag_reset, (void*)YANG_FLAG_MARK);
yang_apply((yang_node*)ysp->yp_stmt[i], -1, ys_flag_reset, (void*)YANG_FLAG_MARK);
}
/* Step 4: Top-level augmentation of all modules */
/* Step 4: Top-level augmentation of all modules XXX: only new modules? */
if (yang_augment_spec(ysp) < 0)
goto done;
/* sanity check of schemanode references, need more here */
if (yang_apply((yang_node*)ysp, -1, ys_schemanode_check, NULL) < 0)
for (i=modnr; i<ysp->yp_len; i++)
if (yang_apply((yang_node*)ysp->yp_stmt[i], -1, ys_schemanode_check, NULL) < 0)
goto done;
retval = 0;
@ -2405,94 +2450,84 @@ yang_config(yang_stmt *ys)
return 1;
}
/*! Parse netconf yang spec, used by netconf client and as internal protocol
* @note not used yet - unfinnisshed code
*/
yang_spec *
yang_spec_netconf(clicon_handle h)
{
yang_spec *yspec = NULL;
if ((yspec = yspec_new()) == NULL)
goto done;
if (yang_parse(h, CLIXON_DATADIR, "ietf-netconf", NULL, yspec) < 0){
yspec_free(yspec); yspec = NULL;
goto done;
}
clicon_netconf_yang_set(h, yspec);
done:
return yspec;
}
/*! Parse yang specification and its dependencies recursively and return
/*! Parse yang specification and its dependencies recursively given module
* @param[in] h clicon handle
*/
yang_spec*
yang_spec_main(clicon_handle h)
{
yang_spec *yspec = NULL;
char *yang_module;
char *yang_revision;
char *yang_dir;
if ((yang_dir = clicon_yang_dir(h)) == NULL){
clicon_err(OE_FATAL, 0, "CLICON_YANG_DIR option not set");
goto done;
}
/* Yang module is either specific absolute filename, or main module */
if ((yang_module = clicon_yang_module_main(h)) == NULL){
clicon_err(OE_FATAL, 0, "CLICON_YANG_MODULE_MAIN option not set");
goto done;
}
yang_revision = clicon_yang_module_revision(h);
if ((yspec = yspec_new()) == NULL)
goto done;
if (yang_parse(h, yang_dir, yang_module, yang_revision, yspec) < 0){
yspec_free(yspec); yspec = NULL;
goto done;
}
clicon_dbspec_yang_set(h, yspec);
done:
return yspec;
}
/*! Parse yang specification, its dependencies, and append to default yang spec
* yang_spec_main should have been called first.
* @param[in] h clicon handle
* @param[in] yang_dir Directory, either system-wide or application-specific
* @param[in] yang_module Name of module
* @param[in] yang_revision Revision, or NULL
* @see yang_spec_main
* @param[in] module Module name, or absolute filename (including dir)
* @param[in] dir Directory where to look for modules and sub-modules
* @param[in] revision Revision, or NULL
* @param[in,out] yspec Modules parse are added to this yangspec
* @retval 0 OK
* @retval -1 Error
* @see yang_spec_parse_file
*/
int
yang_spec_append(clicon_handle h,
char *yang_dir,
char *yang_module,
char *yang_revision)
yang_spec_parse_module(clicon_handle h,
char *module,
char *dir,
char *revision,
yang_spec *yspec)
{
int retval = -1;
yang_spec *yspec = NULL;
yang_spec *yspec0;
yang_stmt *ym = NULL; /* module */
if ((yspec0 = clicon_dbspec_yang(h)) == NULL){
clicon_err(OE_YANG, ENOENT, "yang spec not found");
if (yspec == NULL){
clicon_err(OE_YANG, EINVAL, "yang spec is NULL");
goto done;
}
if ((yspec = yspec_new()) == NULL)
goto done;
if (yang_parse(h, yang_dir, yang_module, yang_revision, yspec) < 0){
yspec_free(yspec); yspec = NULL;
if (module == NULL){
clicon_err(OE_YANG, EINVAL, "yang module not set");
goto done;
}
while ((ym = yn_each((yang_node*)yspec, ym)) != NULL)
if (yn_insert((yang_node*)yspec0, ym) < 0)
/* Sanity check - use yang_spec_parse_file instead */
if (strlen(module) && module[0] == '/'){
clicon_err(OE_YANG, EINVAL, "yang module illegal format");
goto done;
yspec->yp_len = 0;
}
if (dir == NULL){
clicon_err(OE_YANG, EINVAL, "yang dir not set");
goto done;
}
if (yang_parse(h, NULL, module, dir, revision, yspec) < 0){
yspec_free(yspec);
yspec = NULL;
goto done;
}
retval = 0;
done:
if (yspec)
return retval;
}
/*! Parse yang specification and its dependencies recursively given filename
* @param[in] h clicon handle
* @param[in] filename Actual filename (including dir and revision)
* @param[in] dir Directory for sub-modules
* @param[in,out] yspec Modules parse are added to this yangspec
* @retval 0 OK
* @retval -1 Error
* @see yang_spec_parse_module for yang dir,module,revision instead of actual filename
*/
int
yang_spec_parse_file(clicon_handle h,
char *filename,
char *dir,
yang_spec *yspec)
{
int retval = -1;
if (yspec == NULL){
clicon_err(OE_YANG, EINVAL, "yang spec is NULL");
goto done;
}
if (dir == NULL){
clicon_err(OE_YANG, EINVAL, "yang dir not set");
goto done;
}
if (yang_parse(h, filename, NULL, dir, NULL, yspec) < 0){
yspec_free(yspec);
yspec = NULL;
goto done;
}
retval = 0;
done:
return retval;
}

View file

@ -15,7 +15,6 @@ cat <<EOF > $cfg
<config>
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
<CLICON_YANG_MODULE_MAIN>$fyang</CLICON_YANG_MODULE_MAIN>
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
<CLICON_RESTCONF_DIR>/usr/local/lib/$APPNAME/restconf</CLICON_RESTCONF_DIR>
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>

View file

@ -18,7 +18,6 @@ cat <<EOF > $cfg
<config>
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_YANG_DIR>/usr/local/share/example/yang</CLICON_YANG_DIR>
<CLICON_YANG_MODULE_MAIN>$fyang</CLICON_YANG_MODULE_MAIN>
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
<CLICON_BACKEND_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP>

View file

@ -13,7 +13,6 @@ cat <<EOF > $cfg
<config>
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
<CLICON_YANG_MODULE_MAIN>$fyang</CLICON_YANG_MODULE_MAIN>
<CLICON_RESTCONF_PRETTY>false</CLICON_RESTCONF_PRETTY>
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
@ -88,7 +87,7 @@ new "kill old restconf daemon"
sudo pkill -u www-data clixon_restconf
new "start restconf daemon"
sudo start-stop-daemon -S -q -o -b -x /www-data/clixon_restconf -d /www-data -c www-data -- -f $cfg -D 1
sudo start-stop-daemon -S -q -o -b -x /www-data/clixon_restconf -d /www-data -c www-data -- -f $cfg -y $fyang # -D 1
sleep 1
@ -110,7 +109,7 @@ expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription><stre
new "netconf NETCONF subscription with simple filter"
expectwait "$clixon_netconf -qf $cfg -y $fyang" "<rpc><create-subscription><stream>NETCONF</stream><filter type=\"xpath\" select=\"event\"/></create-subscription></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' 5
new "netconf NETCONF subscription with filter classfier"
new "netconf NETCONF subscription with filter classifier"
expectwait "$clixon_netconf -qf $cfg -y $fyang" "<rpc><create-subscription><stream>NETCONF</stream><filter type=\"xpath\" select=\"event[event-class='fault']\"/></create-subscription></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' 5
#new "restconf monitor event stream RFC8040 Sec 6.3"

View file

@ -11,7 +11,6 @@ cat <<EOF > $cfg
<config>
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
<CLICON_YANG_MODULE_MAIN>$fyang</CLICON_YANG_MODULE_MAIN>
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
<CLICON_BACKEND_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP>
@ -163,22 +162,22 @@ new "netconf validate"
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-tag>operation-failed</error-tag><error-type>application</error-type><error-severity>error</error-severity><error-message>Identityref validation failed, foo:bar not derived from crypto-alg</error-message></rpc-error></rpc-reply>]]>]]>$"
new "cli set crypto to mc:aes"
expectfn "$clixon_cli -1 -f $cfg -l o set crypto mc:aes" 0 "^$"
expectfn "$clixon_cli -1 -f $cfg -y $fyang -l o set crypto mc:aes" 0 "^$"
new "cli validate"
expectfn "$clixon_cli -1 -f $cfg -l o validate" 0 "^$"
expectfn "$clixon_cli -1 -f $cfg -y $fyang -l o validate" 0 "^$"
new "cli set crypto to aes"
expectfn "$clixon_cli -1 -f $cfg -l o set crypto aes" 0 "^$"
expectfn "$clixon_cli -1 -f $cfg -y $fyang -l o set crypto aes" 0 "^$"
new "cli validate"
expectfn "$clixon_cli -1 -f $cfg -l o validate" 0 "^$"
expectfn "$clixon_cli -1 -f $cfg -y $fyang -l o validate" 0 "^$"
new "cli set crypto to des:des3"
expectfn "$clixon_cli -1 -f $cfg -l o set crypto des:des3" 0 "^$"
expectfn "$clixon_cli -1 -f $cfg -y $fyang -l o set crypto des:des3" 0 "^$"
new "cli validate"
expectfn "$clixon_cli -1 -f $cfg -l o validate" 0 "^$"
expectfn "$clixon_cli -1 -f $cfg -y $fyang -l o validate" 0 "^$"
new "Kill backend"
# Check if still alive

View file

@ -12,7 +12,6 @@ cat <<EOF > $cfg
<config>
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_YANG_DIR>/usr/local/share/$APPNAME/yang</CLICON_YANG_DIR>
<CLICON_YANG_MODULE_MAIN>$fyang</CLICON_YANG_MODULE_MAIN>
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
<CLICON_BACKEND_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP>

View file

@ -7,12 +7,11 @@ APPNAME=example
cfg=$dir/conf.xml
fyang=$dir/restconf.yang
# <CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN>
cat <<EOF > $cfg
<config>
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_YANG_DIR>/usr/local/share/$APPNAME/yang</CLICON_YANG_DIR>
<CLICON_YANG_MODULE_MAIN>$fyang</CLICON_YANG_MODULE_MAIN>
<CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN>
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
<CLICON_BACKEND_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP>

View file

@ -12,7 +12,6 @@ cat <<EOF > $cfg
<config>
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_YANG_DIR>/usr/local/var</CLICON_YANG_DIR>
<CLICON_YANG_MODULE_MAIN>$fyang</CLICON_YANG_MODULE_MAIN>
<CLICON_RESTCONF_PRETTY>false</CLICON_RESTCONF_PRETTY>
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
<CLICON_BACKEND_PIDFILE>$dir/restconf.pidfile</CLICON_BACKEND_PIDFILE>
@ -60,7 +59,7 @@ new "kill old restconf daemon"
sudo pkill -u www-data clixon_restconf
new "start restconf daemon"
sudo start-stop-daemon -S -q -o -b -x /www-data/clixon_restconf -d /www-data -c www-data -- -f $cfg # -D 1
sudo start-stop-daemon -S -q -o -b -x /www-data/clixon_restconf -d /www-data -c www-data -- -f $cfg -y $fyang # -D 1
sleep 1

View file

@ -351,9 +351,9 @@ module clixon-config {
}
leaf CLICON_MODULE_LIBRARY_RFC7895 {
type boolean;
default false;
default true;
description "Enable RFC 7895 YANG Module library support as state
data. Ifenabled, module info will appear when doing
data. If enabled, module info will appear when doing
netconf get or restconf GET";
}
leaf CLICON_STREAM_DISCOVERY_RFC5277 {