* Yang Configure options changed
* `CLICON_YANG_DIR` is changed from a single directory to a path of directories
* Note CLIXON_DATADIR (=/usr/local/share/clixon) need to be in the list
* CLICON_YANG_MAIN_FILE Provides a filename with a single module filename.
* CLICON_YANG_MAIN_DIR Provides a directory where all yang modules should be loaded.
* Change all @datamodel:tree to @datamodel in all CLI specification files
* If you generate CLI code from the model (CLIXON_CLI_GENMODEL).
* For backward compatibility, define CLICON_CLI_MODEL_TREENAME_PATCH in clixon_custom.h
* Removed return value ymodp from yang parse functions (eg yang_parse()).
* New config option: CLICON_CLI_MODEL_TREENAME defining name of generated syntax tree if CLIXON_CLI_GENMODEL is set.
This commit is contained in:
parent
d09a8c08aa
commit
ac1aa44fc4
21 changed files with 309 additions and 140 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
|
@ -12,15 +12,23 @@
|
|||
* Support of submodule, include and belongs-to.
|
||||
* Openconfig yang specs parsed: https://github.com/openconfig/public
|
||||
* Improved unknown handling
|
||||
* Configure option `CLICON_YANG_DIR` is changed from a single directory to a path of directories
|
||||
* Note CLIXON_DATADIR (=/usr/local/share/clixon) need to be in the list
|
||||
* Yang Configure options changed
|
||||
* `CLICON_YANG_DIR` is changed from a single directory to a path of directories
|
||||
* Note CLIXON_DATADIR (=/usr/local/share/clixon) need to be in the list
|
||||
* CLICON_YANG_MAIN_FILE Provides a filename with a single module filename.
|
||||
* CLICON_YANG_MAIN_DIR Provides a directory where all yang modules should be loaded.
|
||||
|
||||
### API changes on existing features (you may need to change your code)
|
||||
* Yang parser is stricter (see above) which may break parsing of existing yang specs.
|
||||
* Yang parser functions have changed signatures. Please check the source if you call these functions.
|
||||
* Add `<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>` to your configuration file, or corresponding CLICON_DATADIR directory for Clixon system yang files.
|
||||
* Change all @datamodel:tree to @datamodel in all CLI specification files
|
||||
* If you generate CLI code from the model (CLIXON_CLI_GENMODEL).
|
||||
* For backward compatibility, define CLICON_CLI_MODEL_TREENAME_PATCH in clixon_custom.h
|
||||
|
||||
### Minor changes
|
||||
* Removed return value ymodp from yang parse functions (eg yang_parse()).
|
||||
* New config option: CLICON_CLI_MODEL_TREENAME defining name of generated syntax tree if CLIXON_CLI_GENMODEL is set.
|
||||
* XML parser conformance to W3 spec
|
||||
* Names lexically correct (NCName)
|
||||
* Syntactically Correct handling of '<?' (processing instructions) and '<?xml' (XML declaration)
|
||||
|
|
|
|||
|
|
@ -230,7 +230,8 @@ The figure shows the SDK runtime of Clixon.
|
|||
|
||||
Reference
|
||||
=========
|
||||
A reference manual can be built using [Doxygen](http://www.doxygen.nl/index.html). You need to install doxygen and graphviz on your system.
|
||||
Clixon uses [Doxygen](http://www.doxygen.nl/index.html) for reference documentation.
|
||||
You need to install doxygen and graphviz on your system.
|
||||
Build it in the doc directory and point the browser to `.../clixon/doc/html/index.html` as follows:
|
||||
```
|
||||
> cd doc
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ nacm_load_external(clicon_handle h)
|
|||
}
|
||||
if ((yspec = yspec_new()) == NULL)
|
||||
goto done;
|
||||
if (yang_parse(h, NULL, "ietf-netconf-acm", NULL, yspec, NULL) < 0)
|
||||
if (yang_parse(h, NULL, "ietf-netconf-acm", NULL, yspec) < 0)
|
||||
goto done;
|
||||
fd = fileno(f);
|
||||
/* Read configfile */
|
||||
|
|
@ -527,7 +527,7 @@ main(int argc,
|
|||
int logdst = CLICON_LOG_SYSLOG|CLICON_LOG_STDERR;
|
||||
yang_spec *yspec = NULL;
|
||||
yang_spec *yspecfg = NULL; /* For config XXX clixon bug */
|
||||
char *yang_filename = NULL;
|
||||
char *str;
|
||||
|
||||
/* In the startup, logs to stderr & syslog and debug flag set later */
|
||||
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
||||
|
|
@ -652,8 +652,8 @@ main(int argc,
|
|||
case 'g': /* config socket group */
|
||||
clicon_option_str_set(h, "CLICON_SOCK_GROUP", optarg);
|
||||
break;
|
||||
case 'y' :{ /* Load yang spec file (override yang main module) */
|
||||
yang_filename = optarg;
|
||||
case 'y' :{ /* Load yang absolute filename */
|
||||
clicon_option_str_set(h, "CLICON_YANG_MAIN_FILE", optarg);
|
||||
break;
|
||||
}
|
||||
case 'x' :{ /* xmldb plugin */
|
||||
|
|
@ -750,17 +750,20 @@ main(int argc,
|
|||
if ((yspec = yspec_new()) == NULL)
|
||||
goto done;
|
||||
clicon_dbspec_yang_set(h, yspec);
|
||||
/* Load main application yang specification either module or specific file
|
||||
* If -y <file> is given, it overrides main module */
|
||||
if (yang_filename){
|
||||
if (yang_spec_parse_file(h, yang_filename, yspec, NULL) < 0)
|
||||
/* Load Yang modules
|
||||
* 1. Load a yang module as a specific absolute filename */
|
||||
if ((str = clicon_yang_main_file(h)) != NULL)
|
||||
if (yang_spec_parse_file(h, str, yspec) < 0)
|
||||
goto done;
|
||||
/* 2. Load a (single) main module */
|
||||
if ((str = clicon_yang_module_main(h)) != NULL)
|
||||
if (yang_spec_parse_module(h, str, clicon_yang_module_revision(h),
|
||||
yspec) < 0)
|
||||
goto done;
|
||||
/* 3. Load all modules in a directory */
|
||||
if ((str = clicon_yang_main_dir(h)) != NULL)
|
||||
if (yang_spec_load_dir(h, str, yspec) < 0)
|
||||
goto done;
|
||||
}
|
||||
else if (yang_spec_parse_module(h, clicon_yang_module_main(h),
|
||||
clicon_yang_module_revision(h),
|
||||
yspec, NULL) < 0)
|
||||
goto done;
|
||||
|
||||
/* Load yang module library, RFC7895 */
|
||||
if (yang_modules_init(h) < 0)
|
||||
goto done;
|
||||
|
|
@ -769,11 +772,11 @@ main(int argc,
|
|||
goto done;
|
||||
/* Load yang Restconf stream discovery */
|
||||
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC8040") &&
|
||||
yang_spec_parse_module(h, "ietf-restconf-monitoring", NULL, yspec, NULL)< 0)
|
||||
yang_spec_parse_module(h, "ietf-restconf-monitoring", NULL, yspec)< 0)
|
||||
goto done;
|
||||
/* Load yang Netconf stream discovery */
|
||||
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277") &&
|
||||
yang_spec_parse_module(h, "ietf-netconf-notification", NULL, yspec, NULL)< 0)
|
||||
yang_spec_parse_module(h, "ietf-netconf-notification", 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)
|
||||
|
|
|
|||
|
|
@ -250,15 +250,14 @@ main(int argc, char **argv)
|
|||
int logclisyntax = 0;
|
||||
int help = 0;
|
||||
char *treename = NULL;
|
||||
int len;
|
||||
// int len;
|
||||
int logdst = CLICON_LOG_STDERR;
|
||||
char *restarg = NULL; /* what remains after options */
|
||||
int dump_configfile_xml = 0;
|
||||
yang_spec *yspec;
|
||||
yang_spec *yspecfg = NULL; /* For config XXX clixon bug */
|
||||
struct passwd *pw;
|
||||
char *yang_filename = NULL;
|
||||
yang_stmt *ymod = NULL; /* Main module */
|
||||
char *str;
|
||||
|
||||
/* Defaults */
|
||||
once = 0;
|
||||
|
|
@ -390,8 +389,8 @@ main(int argc, char **argv)
|
|||
case 'L' : /* Debug print dynamic CLI syntax */
|
||||
logclisyntax++;
|
||||
break;
|
||||
case 'y' :{ /* Load yang spec file (override yang main module) */
|
||||
yang_filename = optarg;
|
||||
case 'y' :{ /* Load yang absolute filename */
|
||||
clicon_option_str_set(h, "CLICON_YANG_MAIN_FILE", optarg);
|
||||
break;
|
||||
}
|
||||
case 'c' :{ /* Overwrite clispec with absolute filename */
|
||||
|
|
@ -430,16 +429,24 @@ main(int argc, char **argv)
|
|||
goto done;
|
||||
clicon_dbspec_yang_set(h, yspec);
|
||||
|
||||
/* Load main application yang specification either module or specific file
|
||||
* If -y <file> is given, it overrides main module */
|
||||
if (yang_filename){
|
||||
if (yang_spec_parse_file(h, yang_filename, yspec, &ymod) < 0)
|
||||
/* Load Yang modules
|
||||
* 1. Load a yang module as a specific absolute filename */
|
||||
if ((str = clicon_yang_main_file(h)) != NULL){
|
||||
if (yang_spec_parse_file(h, str, yspec) < 0)
|
||||
goto done;
|
||||
}
|
||||
else if (yang_spec_parse_module(h, clicon_yang_module_main(h),
|
||||
clicon_yang_module_revision(h),
|
||||
yspec, &ymod) < 0)
|
||||
goto done;
|
||||
/* 2. Load a (single) main module */
|
||||
if ((str = clicon_yang_module_main(h)) != NULL){
|
||||
if (yang_spec_parse_module(h, str, clicon_yang_module_revision(h),
|
||||
yspec) < 0)
|
||||
goto done;
|
||||
}
|
||||
/* 3. Load all modules in a directory */
|
||||
if ((str = clicon_yang_main_dir(h)) != NULL){
|
||||
if (yang_spec_load_dir(h, str, yspec) < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Load yang module library, RFC7895 */
|
||||
if (yang_modules_init(h) < 0)
|
||||
goto done;
|
||||
|
|
@ -448,25 +455,22 @@ main(int argc, char **argv)
|
|||
|
||||
/* Create tree generated from dataspec. If no other trees exists, this is
|
||||
* the only one.
|
||||
* The following code creates the tree @datamodel
|
||||
* This tree is referenced from the main CLI spec (CLICON_CLISPEC_DIR)
|
||||
* using the "tree reference"
|
||||
* syntax, ie @datamodel
|
||||
* But note that yang2cli generates syntax for ALL modules, not just for
|
||||
* <module>.
|
||||
*/
|
||||
if (clicon_cli_genmodel(h)){
|
||||
parse_tree pt = {0,}; /* cli parse tree */
|
||||
char *name; /* main module name */
|
||||
char *treeref;
|
||||
|
||||
treeref = clicon_cli_model_treename(h);
|
||||
/* Create cli command tree from dbspec */
|
||||
if (yang2cli(h, yspec, &pt, clicon_cli_genmodel_type(h)) < 0)
|
||||
goto done;
|
||||
|
||||
/* name of main module */
|
||||
name = ymod->ys_argument;
|
||||
|
||||
len = strlen("datamodel:") + strlen(name) + 1;
|
||||
if ((treename = malloc(len)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "malloc");
|
||||
goto done;
|
||||
}
|
||||
snprintf(treename, len, "datamodel:%s", name);
|
||||
cligen_tree_add(cli_cligen(h), treename, pt);
|
||||
cligen_tree_add(cli_cligen(h), treeref, pt);
|
||||
|
||||
if (printgen)
|
||||
cligen_print(stdout, pt, 1);
|
||||
|
|
|
|||
|
|
@ -209,6 +209,30 @@ clixon_str2fn(char *name,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef CLICON_CLI_MODEL_TREENAME_PATCH
|
||||
/*! Patch all CLI spec calls to @datamodel:tree to @datamodel.
|
||||
* This is a backward compatible fix for 3.9 for CLIgen specification files
|
||||
* using model generation (CLIXON_CLI_GENMODEL).
|
||||
* All new references should use @datamodel (or CLICON_CLI_MODEL_TREENAME).
|
||||
* whereas older code used @datamodel:tree.
|
||||
*/
|
||||
static int
|
||||
mask_datamodel_fn(cg_obj *co,
|
||||
void *arg)
|
||||
{
|
||||
char *str = "datamodel:";
|
||||
int len = strlen(str);
|
||||
if (co->co_type == CO_REFERENCE){
|
||||
|
||||
if (strlen(co->co_command) > len &&
|
||||
strncmp(co->co_command, "datamodel:", len)==0){
|
||||
co->co_command[len-1] = '\0';
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* CLICON_CLI_MODEL_TREENAME_PATCH */
|
||||
|
||||
/*! Append to syntax mode from file
|
||||
* @param[in] h Clixon handle
|
||||
* @param[in] filename Name of file where syntax is specified (in syntax-group dir)
|
||||
|
|
@ -253,7 +277,10 @@ cli_load_syntax(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
#ifdef CLICON_CLI_MODEL_TREENAME_PATCH
|
||||
if (pt_apply(pt, mask_datamodel_fn, h) < 0)
|
||||
goto done;
|
||||
#endif
|
||||
/* Get CLICON specific global variables */
|
||||
prompt = cvec_find_str(cvv, "CLICON_PROMPT");
|
||||
plgnam = cvec_find_str(cvv, "CLICON_PLUGIN");
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@ main(int argc,
|
|||
struct timeval tv = {0,}; /* timeout */
|
||||
yang_spec *yspec = NULL;
|
||||
yang_spec *yspecfg = NULL; /* For config XXX clixon bug */
|
||||
char *yang_filename = NULL;
|
||||
char *str;
|
||||
|
||||
/* Create handle */
|
||||
if ((h = clicon_handle_init()) == NULL)
|
||||
|
|
@ -420,7 +420,7 @@ main(int argc,
|
|||
clicon_option_str_set(h, "CLICON_NETCONF_DIR", optarg);
|
||||
break;
|
||||
case 'y' :{ /* Load yang spec file (override yang main module) */
|
||||
yang_filename = optarg;
|
||||
clicon_option_str_set(h, "CLICON_YANG_MAIN_FILE", optarg);
|
||||
break;
|
||||
}
|
||||
case 'U': /* Clixon 'pseudo' user */
|
||||
|
|
@ -444,16 +444,23 @@ main(int argc,
|
|||
if ((yspec = yspec_new()) == NULL)
|
||||
goto done;
|
||||
clicon_dbspec_yang_set(h, yspec);
|
||||
/* Load main application yang specification either module or specific file
|
||||
* If -y <file> is given, it overrides main module */
|
||||
if (yang_filename){
|
||||
if (yang_spec_parse_file(h, yang_filename, yspec, NULL) < 0)
|
||||
/* Load Yang modules
|
||||
* 1. Load a yang module as a specific absolute filename */
|
||||
if ((str = clicon_yang_main_file(h)) != NULL){
|
||||
if (yang_spec_parse_file(h, str, yspec) < 0)
|
||||
goto done;
|
||||
}
|
||||
/* 2. Load a (single) main module */
|
||||
if ((str = clicon_yang_module_main(h)) != NULL){
|
||||
if (yang_spec_parse_module(h, str, clicon_yang_module_revision(h),
|
||||
yspec) < 0)
|
||||
goto done;
|
||||
}
|
||||
/* 3. Load all modules in a directory */
|
||||
if ((str = clicon_yang_main_dir(h)) != NULL){
|
||||
if (yang_spec_load_dir(h, str, yspec) < 0)
|
||||
goto done;
|
||||
}
|
||||
else if (yang_spec_parse_module(h, clicon_yang_module_main(h),
|
||||
clicon_yang_module_revision(h),
|
||||
yspec, NULL) < 0)
|
||||
goto done;
|
||||
|
||||
/* Load yang module library, RFC7895 */
|
||||
if (yang_modules_init(h) < 0)
|
||||
|
|
|
|||
|
|
@ -522,9 +522,9 @@ main(int argc,
|
|||
int logdst = CLICON_LOG_SYSLOG;
|
||||
yang_spec *yspec = NULL;
|
||||
yang_spec *yspecfg = NULL; /* For config XXX clixon bug */
|
||||
char *yang_filename = NULL;
|
||||
char *stream_path;
|
||||
int finish;
|
||||
char *str;
|
||||
|
||||
/* In the startup, logs to stderr & debug flag set later */
|
||||
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
||||
|
|
@ -601,7 +601,7 @@ main(int argc,
|
|||
clicon_option_str_set(h, "CLICON_RESTCONF_DIR", optarg);
|
||||
break;
|
||||
case 'y' : /* Load yang spec file (override yang main module) */
|
||||
yang_filename = optarg;
|
||||
clicon_option_str_set(h, "CLICON_YANG_MAIN_FILE", optarg);
|
||||
break;
|
||||
case 'a': /* internal backend socket address family */
|
||||
clicon_option_str_set(h, "CLICON_SOCK_FAMILY", optarg);
|
||||
|
|
@ -627,26 +627,34 @@ main(int argc,
|
|||
if ((yspec = yspec_new()) == NULL)
|
||||
goto done;
|
||||
clicon_dbspec_yang_set(h, yspec);
|
||||
/* Load main application yang specification either module or specific file
|
||||
* If -y <file> is given, it overrides main module */
|
||||
if (yang_filename){
|
||||
if (yang_spec_parse_file(h, yang_filename, yspec, NULL) < 0)
|
||||
|
||||
/* Load Yang modules
|
||||
* 1. Load a yang module as a specific absolute filename */
|
||||
if ((str = clicon_yang_main_file(h)) != NULL){
|
||||
if (yang_spec_parse_file(h, str, yspec) < 0)
|
||||
goto done;
|
||||
}
|
||||
/* 2. Load a (single) main module */
|
||||
if ((str = clicon_yang_module_main(h)) != NULL){
|
||||
if (yang_spec_parse_module(h, str, clicon_yang_module_revision(h),
|
||||
yspec) < 0)
|
||||
goto done;
|
||||
}
|
||||
/* 3. Load all modules in a directory */
|
||||
if ((str = clicon_yang_main_dir(h)) != NULL){
|
||||
if (yang_spec_load_dir(h, str, yspec) < 0)
|
||||
goto done;
|
||||
}
|
||||
else if (yang_spec_parse_module(h, clicon_yang_module_main(h),
|
||||
clicon_yang_module_revision(h),
|
||||
yspec, NULL) < 0)
|
||||
goto done;
|
||||
|
||||
/* Load yang module library, RFC7895 */
|
||||
if (yang_modules_init(h) < 0)
|
||||
goto done;
|
||||
/* Add system modules */
|
||||
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC8040") &&
|
||||
yang_spec_parse_module(h, "ietf-restconf-monitoring", NULL, yspec, NULL)< 0)
|
||||
yang_spec_parse_module(h, "ietf-restconf-monitoring", NULL, yspec)< 0)
|
||||
goto done;
|
||||
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277") &&
|
||||
yang_spec_parse_module(h, "ietf-netconf-notification", NULL, yspec, NULL)< 0)
|
||||
yang_spec_parse_module(h, "ietf-netconf-notification", NULL, yspec)< 0)
|
||||
goto done;
|
||||
/* Call start function in all plugins before we go interactive
|
||||
Pass all args after the standard options to plugin_start
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ main(int argc, char **argv)
|
|||
if ((yspec = yspec_new()) == NULL)
|
||||
goto done;
|
||||
/* Parse yang spec from given file */
|
||||
if (yang_parse(h, yangmodule, NULL, NULL, yspec, NULL) < 0)
|
||||
if (yang_parse(h, yangmodule, NULL, NULL, yspec) < 0)
|
||||
goto done;
|
||||
/* Set database directory option */
|
||||
if (xmldb_setopt(h, "dbdir", dbdir) < 0)
|
||||
|
|
|
|||
15
doc/FAQ.md
15
doc/FAQ.md
|
|
@ -73,8 +73,14 @@ clicon:x:1001:<user>,www-data
|
|||
```
|
||||
|
||||
## What about reference documentation?
|
||||
Clixon uses Doxygen for reference documentation.
|
||||
Build using 'make doc' and aim your browser at doc/html/index.html.
|
||||
Clixon uses [Doxygen](http://www.doxygen.nl/index.html) for reference documentation.
|
||||
You need to install doxygen and graphviz on your system.
|
||||
Build it in the doc directory and point the browser to `.../clixon/doc/html/index.html` as follows:
|
||||
```
|
||||
> cd doc
|
||||
> make doc
|
||||
> make graphs # detailed callgraphs
|
||||
```
|
||||
|
||||
## How is configuration data stored?
|
||||
Configuration data is stored in an XML datastore. In the example the
|
||||
|
|
@ -115,12 +121,15 @@ are included.
|
|||
|
||||
The following configuration file options control the loading of Yang files:
|
||||
- `CLICON_YANG_DIR` - A list of directories (yang dir path) where Clixon searches for module and submodules.
|
||||
- `CLICON_YANG_MAIN_DIR` - Load all yang modules in this directory.
|
||||
- `CLICON_YANG_MAIN_FILE` - Load a specific Yang module fiven by a file.
|
||||
- `CLICON_YANG_MODULE_MAIN` - Specifies a single module to load. The module is searched for in the yang dir path.
|
||||
- `CLICON_YANG_MODULE_REVISION` : Specifies a revision to the main module.
|
||||
|
||||
Note that the special `CLIXON_DATADIR`, by default `/usr/local/share/clixon` should be included in the yang dir path for Clixon system files to be found.
|
||||
|
||||
Application also has a command-line option `-y` to include a single Yang using absolute file path. This is mainly for debugging.
|
||||
You can combine the options, however, more specific options override
|
||||
less specific. For example, `CLICON_YANG_MAIN_FILE` overrides `CLICON_YANG_MODULE_MAIN`.
|
||||
|
||||
## How do I enable Yang features?
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ CLICON_PLUGIN="example_cli";
|
|||
translate value (<value:string translate:incstr()>),cli_set("/translate/value");
|
||||
|
||||
# Note, when switching to PT, change datamodel to only @datamodel
|
||||
set @datamodel:example, cli_set();
|
||||
merge @datamodel:example, cli_merge();
|
||||
create @datamodel:example, cli_create();
|
||||
delete("Delete a configuration item") @datamodel:example, cli_del();
|
||||
set @datamodel, cli_set();
|
||||
merge @datamodel, cli_merge();
|
||||
create @datamodel, cli_create();
|
||||
delete("Delete a configuration item") @datamodel, cli_del();
|
||||
|
||||
validate("Validate changes"), cli_validate();
|
||||
commit("Commit the changes"), cli_commit();
|
||||
|
|
@ -40,19 +40,19 @@ show("Show a particular state of the system"){
|
|||
}
|
||||
configuration("Show configuration"), cli_show_config("candidate", "text", "/");{
|
||||
xml("Show configuration as XML"), cli_show_config("candidate", "xml", "/");{
|
||||
@datamodel:example, cli_show_auto("candidate", "text");
|
||||
@datamodel, cli_show_auto("candidate", "text");
|
||||
}
|
||||
cli("Show configuration as CLI commands"), cli_show_config("candidate", "cli", "/");{
|
||||
@datamodel:example, cli_show_auto("candidate", "cli");
|
||||
@datamodel, cli_show_auto("candidate", "cli");
|
||||
}
|
||||
netconf("Show configuration as netconf edit-config operation"), cli_show_config("candidate", "netconf", "/");{
|
||||
@datamodel:example, cli_show_auto("candidate", "netconf");
|
||||
@datamodel, cli_show_auto("candidate", "netconf");
|
||||
}
|
||||
text("Show configuration as text"), cli_show_config("candidate","text","/");{
|
||||
@datamodel:example, cli_show_auto("candidate", "text");
|
||||
@datamodel, cli_show_auto("candidate", "text");
|
||||
}
|
||||
json("Show configuration as JSON"), cli_show_config("candidate", "json", "/");{
|
||||
@datamodel:example, cli_show_auto("candidate", "json");
|
||||
@datamodel, cli_show_auto("candidate", "json");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,3 +51,15 @@ int strverscmp (__const char *__s1, __const char *__s2);
|
|||
*/
|
||||
#define XMLNS_YANG_ONLY 1
|
||||
|
||||
/* Set for full XML namespace code in XML, NETCONF and YANG
|
||||
* Experimental
|
||||
*/
|
||||
#undef ENABLE_XMLNS
|
||||
|
||||
/* If set, patch all CLI spec calls to @datamodel:tree to @datamodel.
|
||||
* This is a backward compatible fix for 3.9 for CLIgen specification files
|
||||
* using model generation (CLIXON_CLI_GENMODEL).
|
||||
* All new references should use @datamodel (or CLICON_CLI_MODEL_TREENAME).
|
||||
* whereas older code used @datamodel:tree.
|
||||
*/
|
||||
#define CLICON_CLI_MODEL_TREENAME_PATCH
|
||||
|
|
|
|||
|
|
@ -105,6 +105,12 @@ int clicon_option_del(clicon_handle h, const char *name);
|
|||
static inline char *clicon_configfile(clicon_handle h){
|
||||
return clicon_option_str(h, "CLICON_CONFIGFILE");
|
||||
}
|
||||
static inline char *clicon_yang_main_file(clicon_handle h){
|
||||
return clicon_option_str(h, "CLICON_YANG_MAIN_FILE");
|
||||
}
|
||||
static inline char *clicon_yang_main_dir(clicon_handle h){
|
||||
return clicon_option_str(h, "CLICON_YANG_MAIN_DIR");
|
||||
}
|
||||
static inline char *clicon_yang_module_main(clicon_handle h){
|
||||
return clicon_option_str(h, "CLICON_YANG_MODULE_MAIN");
|
||||
}
|
||||
|
|
@ -129,6 +135,9 @@ static inline char *clicon_clispec_dir(clicon_handle h){
|
|||
static inline char *clicon_cli_mode(clicon_handle h){
|
||||
return clicon_option_str(h, "CLICON_CLI_MODE");
|
||||
}
|
||||
static inline char *clicon_cli_model_treename(clicon_handle h){
|
||||
return clicon_option_str(h, "CLICON_CLI_MODEL_TREENAME");
|
||||
}
|
||||
static inline char *clicon_sock(clicon_handle h){
|
||||
return clicon_option_str(h, "CLICON_SOCK");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ int yang_nodeid_split(char *nodeid, char **prefix, char **id);
|
|||
yang_stmt *ys_module(yang_stmt *ys);
|
||||
yang_spec *ys_spec(yang_stmt *ys);
|
||||
yang_stmt *yang_find_module_by_prefix(yang_stmt *ys, char *prefix);
|
||||
yang_stmt *yang_find(yang_node *yn, int keyword, char *argument);
|
||||
yang_stmt *yang_find(yang_node *yn, int keyword, const char *argument);
|
||||
int yang_match(yang_node *yn, int keyword, char *argument);
|
||||
yang_stmt *yang_find_datanode(yang_node *yn, char *argument);
|
||||
yang_stmt *yang_find_schemanode(yang_node *yn, char *argument);
|
||||
|
|
@ -269,7 +269,7 @@ 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 *filename,
|
||||
const char *module,
|
||||
const char *revision, yang_spec *ysp, yang_stmt **ymodp);
|
||||
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, yang_stmt *ys,
|
||||
|
|
@ -281,8 +281,9 @@ 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);
|
||||
int yang_spec_parse_module(clicon_handle h, char *module, char *revision, yang_spec *yspec, yang_stmt **ymodp);
|
||||
int yang_spec_parse_file(clicon_handle h, char *filename, yang_spec *yspec, yang_stmt **ymodp);
|
||||
int yang_spec_parse_module(clicon_handle h, char *module, char *revision, yang_spec *yspec);
|
||||
int yang_spec_parse_file(clicon_handle h, char *filename, yang_spec *yspec);
|
||||
int yang_spec_load_dir(clicon_handle h, char *dir, yang_spec *yspec);
|
||||
cvec *yang_arg2cvec(yang_stmt *ys, char *delimi);
|
||||
int yang_key_match(yang_node *yn, char *name);
|
||||
|
||||
|
|
|
|||
|
|
@ -988,9 +988,9 @@ netconf_module_load(clicon_handle h)
|
|||
|
||||
yspec = clicon_dbspec_yang(h);
|
||||
/* Load yang spec */
|
||||
if (yang_spec_parse_module(h, "ietf-netconf", NULL, yspec, NULL)< 0)
|
||||
if (yang_spec_parse_module(h, "ietf-netconf", NULL, yspec)< 0)
|
||||
goto done;
|
||||
if (yang_spec_parse_module(h, "ietf-netconf-notification", NULL, yspec, NULL)< 0)
|
||||
if (yang_spec_parse_module(h, "ietf-netconf-notification", NULL, yspec)< 0)
|
||||
goto done;
|
||||
if ((xc = clicon_conf_xml(h)) == NULL){
|
||||
clicon_err(OE_CFG, ENOENT, "Clicon configuration not loaded");
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ clicon_options_main(clicon_handle h,
|
|||
/* Set clixon_conf pointer to handle */
|
||||
clicon_conf_xml_set(h, xconfig);
|
||||
/* Parse clixon yang spec */
|
||||
if (yang_parse(h, NULL, "clixon-config", NULL, yspec, NULL) < 0)
|
||||
if (yang_parse(h, NULL, "clixon-config", NULL, yspec) < 0)
|
||||
goto done;
|
||||
clicon_conf_xml_set(h, NULL);
|
||||
if (xconfig)
|
||||
|
|
|
|||
|
|
@ -269,8 +269,7 @@ clixon_plugins_load(clicon_handle h,
|
|||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
/* Get plugin objects names from plugin directory */
|
||||
if((ndp = clicon_file_dirent(dir, &dp,
|
||||
regexp?regexp:"(.so)$", S_IFREG))<0)
|
||||
if((ndp = clicon_file_dirent(dir, &dp, regexp?regexp:"(.so)$", S_IFREG)) < 0)
|
||||
goto done;
|
||||
/* Load all plugins */
|
||||
for (i = 0; i < ndp; i++) {
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ xml_parse_attr(struct xml_parse_yacc_arg *ya,
|
|||
int retval = -1;
|
||||
cxobj *xa;
|
||||
|
||||
#ifdef notyet
|
||||
#ifdef ENABLE_XMLNS
|
||||
if (prefix && strcmp(prefix,"xmlns")==0)
|
||||
fprintf(stderr, "PrefixedAttName NCNAME:%s = %s\n", name, attval);
|
||||
if (prefix==NULL && strcmp(name,"xmlns")==0)
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#define __USE_GNU /* strverscmp */
|
||||
#define __USE_GNU /* strverscmp */
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <regex.h>
|
||||
|
|
@ -56,6 +56,7 @@
|
|||
#include <syslog.h>
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
/* cligen */
|
||||
|
|
@ -416,7 +417,7 @@ yn_each(yang_node *yn,
|
|||
yang_stmt *
|
||||
yang_find(yang_node *yn,
|
||||
int keyword,
|
||||
char *argument)
|
||||
const char *argument)
|
||||
{
|
||||
yang_stmt *ys = NULL;
|
||||
int i;
|
||||
|
|
@ -1939,7 +1940,6 @@ yang_parse_find_match(clicon_handle h,
|
|||
S_IFREG)) < 0)
|
||||
goto done;
|
||||
/* Entries are sorted, last entry should be most recent date
|
||||
* Found
|
||||
*/
|
||||
if (ndp != 0){
|
||||
cprintf(fbuf, "%s/%s", dir, dp[ndp-1].d_name);
|
||||
|
|
@ -2278,7 +2278,6 @@ yang_merge_submodules(clicon_handle h,
|
|||
* @param[in] module Name of main YANG module. Or absolute file name.
|
||||
* @param[in] revision Main module revision date string or NULL
|
||||
* @param[in,out] ysp Yang specification. Should have been created by caller using yspec_new
|
||||
* @param[out] ymodp Yang module of first, topmost Yang module, if given.
|
||||
* @retval 0 Everything OK
|
||||
* @retval -1 Error encountered
|
||||
* The database symbols are inserted in alphabetical order.
|
||||
|
|
@ -2298,72 +2297,89 @@ yang_parse(clicon_handle h,
|
|||
const char *filename,
|
||||
const char *module,
|
||||
const char *revision,
|
||||
yang_spec *ysp,
|
||||
yang_stmt **ymodp)
|
||||
yang_spec *yspec)
|
||||
{
|
||||
int retval = -1;
|
||||
yang_stmt *ymod = NULL; /* Top-level yang (sub)module */
|
||||
int i;
|
||||
int modnr; /* Existing number of modules */
|
||||
char *base = NULL;;
|
||||
|
||||
/* Apply steps 2.. on new modules, ie ones after modnr. */
|
||||
modnr = ysp->yp_len;
|
||||
modnr = yspec->yp_len;
|
||||
if (filename){
|
||||
if ((ymod = yang_parse_filename(filename, ysp)) == NULL)
|
||||
/* Find module, and do not load file if module already exists */
|
||||
if (basename(filename) == NULL){
|
||||
clicon_err(OE_YANG, errno, "No basename");
|
||||
goto done;
|
||||
}
|
||||
if ((base = strdup(basename(filename))) == NULL){
|
||||
clicon_err(OE_YANG, errno, "strdup");
|
||||
goto done;
|
||||
}
|
||||
if (index(base, '@') != NULL)
|
||||
*index(base, '@') = '\0';
|
||||
if (yang_find((yang_node*)yspec, Y_MODULE, base) != NULL)
|
||||
goto ok;
|
||||
if ((ymod = yang_parse_filename(filename, yspec)) == NULL)
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
if ((ymod = yang_parse_module(h, module, revision, ysp)) == NULL)
|
||||
else {
|
||||
/* Do not load module if it already exists */
|
||||
if (yang_find((yang_node*)yspec, Y_MODULE, module) != NULL)
|
||||
goto ok;
|
||||
if ((ymod = yang_parse_module(h, module, revision, yspec)) == NULL)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* 1: Parse from text to yang parse-tree. */
|
||||
/* Iterate through modules */
|
||||
if (yang_parse_recurse(h, ymod, ysp) < 0)
|
||||
if (yang_parse_recurse(h, ymod, yspec) < 0)
|
||||
goto done;
|
||||
|
||||
/* 2. Check cardinality maybe this should be done after grouping/augment */
|
||||
for (i=modnr; i<ysp->yp_len; i++) /* XXX */
|
||||
if (yang_cardinality(h, ysp->yp_stmt[i], ysp->yp_stmt[i]->ys_argument) < 0)
|
||||
for (i=modnr; i<yspec->yp_len; i++) /* XXX */
|
||||
if (yang_cardinality(h, yspec->yp_stmt[i], yspec->yp_stmt[i]->ys_argument) < 0)
|
||||
goto done;
|
||||
|
||||
/* 3: Merge sub-modules with modules - after this step, no submodules exist
|
||||
* In the merge, remove submodule headers
|
||||
*/
|
||||
for (i=modnr; i<ysp->yp_len; i++){
|
||||
if (ysp->yp_stmt[i]->ys_keyword != Y_SUBMODULE)
|
||||
for (i=modnr; i<yspec->yp_len; i++){
|
||||
if (yspec->yp_stmt[i]->ys_keyword != Y_SUBMODULE)
|
||||
continue;
|
||||
}
|
||||
i = 0;
|
||||
while (i<ysp->yp_len){
|
||||
while (i<yspec->yp_len){
|
||||
int j;
|
||||
if (ysp->yp_stmt[i]->ys_keyword != Y_SUBMODULE){
|
||||
if (yspec->yp_stmt[i]->ys_keyword != Y_SUBMODULE){
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (yang_merge_submodules(h, ysp, ysp->yp_stmt[i]) < 0)
|
||||
if (yang_merge_submodules(h, yspec, yspec->yp_stmt[i]) < 0)
|
||||
goto done;
|
||||
/* shift down one step */
|
||||
for (j=i; j<ysp->yp_len-1; j++)
|
||||
ysp->yp_stmt[j] = ysp->yp_stmt[j+1];
|
||||
ysp->yp_len--;
|
||||
for (j=i; j<yspec->yp_len-1; j++)
|
||||
yspec->yp_stmt[j] = yspec->yp_stmt[j+1];
|
||||
yspec->yp_len--;
|
||||
}
|
||||
|
||||
/* 4: Check features: check if enabled and remove disabled features */
|
||||
for (i=modnr; i<ysp->yp_len; i++) /* XXX */
|
||||
if (yang_features(h, ysp->yp_stmt[i]) < 0)
|
||||
for (i=modnr; i<yspec->yp_len; i++) /* XXX */
|
||||
if (yang_features(h, yspec->yp_stmt[i]) < 0)
|
||||
goto done;
|
||||
|
||||
/* 5: Go through parse tree and populate it with cv types */
|
||||
for (i=modnr; i<ysp->yp_len; i++)
|
||||
if (yang_apply((yang_node*)ysp->yp_stmt[i], -1, ys_populate, (void*)h) < 0)
|
||||
for (i=modnr; i<yspec->yp_len; i++)
|
||||
if (yang_apply((yang_node*)yspec->yp_stmt[i], -1, ys_populate, (void*)h) < 0)
|
||||
goto done;
|
||||
|
||||
/* 6: Resolve all types: populate type caches. Requires eg length/range cvecs
|
||||
* from ys_populate step.
|
||||
* Must be done using static binding.
|
||||
*/
|
||||
for (i=modnr; i<ysp->yp_len; i++)
|
||||
if (yang_apply((yang_node*)ysp->yp_stmt[i], Y_TYPE, ys_resolve_type, NULL) < 0)
|
||||
for (i=modnr; i<yspec->yp_len; i++)
|
||||
if (yang_apply((yang_node*)yspec->yp_stmt[i], Y_TYPE, ys_resolve_type, NULL) < 0)
|
||||
goto done;
|
||||
|
||||
/* Up to here resolving is made in the context they are defined, rather
|
||||
|
|
@ -2374,25 +2390,26 @@ yang_parse(clicon_handle h,
|
|||
*/
|
||||
|
||||
/* 7: Macro expansion of all grouping/uses pairs. Expansion needs marking */
|
||||
for (i=modnr; i<ysp->yp_len; i++){
|
||||
if (yang_expand((yang_node*)ysp->yp_stmt[i]) < 0)
|
||||
for (i=modnr; i<yspec->yp_len; i++){
|
||||
if (yang_expand((yang_node*)yspec->yp_stmt[i]) < 0)
|
||||
goto done;
|
||||
yang_apply((yang_node*)ysp->yp_stmt[i], -1, ys_flag_reset, (void*)YANG_FLAG_MARK);
|
||||
yang_apply((yang_node*)yspec->yp_stmt[i], -1, ys_flag_reset, (void*)YANG_FLAG_MARK);
|
||||
}
|
||||
|
||||
/* 8: Top-level augmentation of all modules XXX: only new modules? */
|
||||
if (yang_augment_spec(ysp) < 0)
|
||||
if (yang_augment_spec(yspec) < 0)
|
||||
goto done;
|
||||
|
||||
/* 9: sanity check of schemanode references, need more here */
|
||||
for (i=modnr; i<ysp->yp_len; i++)
|
||||
if (yang_apply((yang_node*)ysp->yp_stmt[i], -1, ys_schemanode_check, NULL) < 0)
|
||||
for (i=modnr; i<yspec->yp_len; i++)
|
||||
if (yang_apply((yang_node*)yspec->yp_stmt[i], -1, ys_schemanode_check, NULL) < 0)
|
||||
goto done;
|
||||
/* Return main module parsed in step 1 */
|
||||
if (ymodp)
|
||||
*ymodp = ymod;
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
done:
|
||||
if (base)
|
||||
free(base);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -2792,7 +2809,6 @@ yang_config(yang_stmt *ys)
|
|||
* @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
|
||||
* @param[out] ymodp Yang module of first, topmost Yang module, if given.
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @see yang_spec_parse_file
|
||||
|
|
@ -2801,8 +2817,7 @@ int
|
|||
yang_spec_parse_module(clicon_handle h,
|
||||
char *module,
|
||||
char *revision,
|
||||
yang_spec *yspec,
|
||||
yang_stmt **ymodp)
|
||||
yang_spec *yspec)
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
|
|
@ -2819,7 +2834,7 @@ yang_spec_parse_module(clicon_handle h,
|
|||
clicon_err(OE_YANG, EINVAL, "yang module illegal format");
|
||||
goto done;
|
||||
}
|
||||
if (yang_parse(h, NULL, module, revision, yspec, ymodp) < 0)
|
||||
if (yang_parse(h, NULL, module, revision, yspec) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
@ -2831,7 +2846,6 @@ yang_spec_parse_module(clicon_handle h,
|
|||
* @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
|
||||
* @param[out] ymodp Yang module of first, topmost Yang module, if given.
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @see yang_spec_parse_module for yang dir,module,revision instead of actual filename
|
||||
|
|
@ -2839,8 +2853,7 @@ yang_spec_parse_module(clicon_handle h,
|
|||
int
|
||||
yang_spec_parse_file(clicon_handle h,
|
||||
char *filename,
|
||||
yang_spec *yspec,
|
||||
yang_stmt **ymodp)
|
||||
yang_spec *yspec)
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
|
|
@ -2848,13 +2861,62 @@ yang_spec_parse_file(clicon_handle h,
|
|||
clicon_err(OE_YANG, EINVAL, "yang spec is NULL");
|
||||
goto done;
|
||||
}
|
||||
if (yang_parse(h, filename, NULL, NULL, yspec, ymodp) < 0)
|
||||
if (yang_parse(h, filename, NULL, NULL, yspec) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Load all yang modules in directory
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] dir Load all yang modules in this directory
|
||||
* @param[in,out] yspec Modules parse are added to this yangspec
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
yang_spec_load_dir(clicon_handle h,
|
||||
char *dir,
|
||||
yang_spec *yspec)
|
||||
{
|
||||
int retval = -1;
|
||||
int ndp;
|
||||
struct dirent *dp = NULL;
|
||||
int i;
|
||||
char filename[MAXPATHLEN];
|
||||
char *base;
|
||||
char *b;
|
||||
int j;
|
||||
int len;
|
||||
|
||||
/* Get plugin objects names from plugin directory */
|
||||
if((ndp = clicon_file_dirent(dir, &dp, "(.yang)$", S_IFREG)) < 0)
|
||||
goto done;
|
||||
/* Load all yang files */
|
||||
for (i = 0; i < ndp; i++) {
|
||||
base = dp[i].d_name;
|
||||
/* Entries are sorted, see if later entry exists (include @), if so skip
|
||||
* this one and take last.
|
||||
*/
|
||||
if ((b = index(base, '@')) != NULL)
|
||||
len = b-base;
|
||||
else
|
||||
len = strlen(base);
|
||||
for (j = (i+1); j < ndp; j++)
|
||||
if (strncmp(base, dp[j].d_name, len) == 0)
|
||||
break;
|
||||
if (j<ndp) /* exists later entry */
|
||||
continue;
|
||||
snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, dp[i].d_name);
|
||||
if (yang_parse(h, filename, NULL, NULL, yspec) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Given a yang node, translate the argument string to a cv vector
|
||||
*
|
||||
* @param[in] ys Yang statement
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ yang_modules_init(clicon_handle h)
|
|||
goto done;
|
||||
}
|
||||
/* Ensure revision exists is set */
|
||||
if (yang_spec_parse_module(h, "ietf-yang-library", NULL, yspec, NULL)< 0)
|
||||
if (yang_spec_parse_module(h, "ietf-yang-library", NULL, yspec)< 0)
|
||||
goto done;
|
||||
/* Find revision */
|
||||
if (yang_modules_revision(h) == NULL){
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ APPNAME=example
|
|||
. ./lib.sh
|
||||
|
||||
cfg=$dir/conf_yang.xml
|
||||
fyang=$dir/test.yang
|
||||
fyang=$dir/$APPNAME.yang
|
||||
fsubmod=$dir/example-types.yang
|
||||
fyangerr=$dir/err.yang
|
||||
|
||||
|
|
|
|||
|
|
@ -142,9 +142,19 @@ module clixon-config {
|
|||
they appear. Ensure that CLIXON_DATADIR(default
|
||||
/usr/local/share/clixon) is present in the path";
|
||||
}
|
||||
leaf CLICON_YANG_MAIN_FILE {
|
||||
type string;
|
||||
description
|
||||
"If specified load a yang module in a specific absolute filename";
|
||||
}
|
||||
leaf CLICON_YANG_MAIN_DIR {
|
||||
type string;
|
||||
description
|
||||
"If given, load all modules in this directory.
|
||||
See also CLICON_YANG_DIR which specifies a path of dirs";
|
||||
}
|
||||
leaf CLICON_YANG_MODULE_MAIN {
|
||||
type string;
|
||||
default "clicon";
|
||||
description
|
||||
"Option used to construct initial yang file:
|
||||
<module>[@<revision>]";
|
||||
|
|
@ -224,9 +234,18 @@ module clixon-config {
|
|||
type int32;
|
||||
default 1;
|
||||
description
|
||||
"Generate code for CLI completion of existing db symbols.
|
||||
Example: Add name=\"myspec\" in datamodel spec and reference
|
||||
as @myspec";
|
||||
"If set, generate CLI specification for CLI completion of
|
||||
loaded Yang modules. This CLI tree can be accessed in CLI
|
||||
spec files using the tree reference syntax (eg @datamodel).
|
||||
See also CLICON_CLI_MODEL_TREENAME.";
|
||||
}
|
||||
leaf CLICON_CLI_MODEL_TREENAME {
|
||||
type string;
|
||||
default "datamodel";
|
||||
description
|
||||
"If CLICON_CLI_GENMODEL is set, CLI specs can reference the
|
||||
model syntax using this reference.
|
||||
Example: set @datamodel, cli_set();";
|
||||
}
|
||||
leaf CLICON_CLI_GENMODEL_COMPLETION {
|
||||
type int32;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue