* Bumped version to 4.3.0.PRE

* Added wildcard `*` as a mode to `CLICON_MODE` in clispec files
* [Add missing includes](https://github.com/clicon/clixon/pulls)
This commit is contained in:
Olof hagsand 2019-11-03 13:05:50 +01:00
parent b26eb5851f
commit 728fe9c6ac
29 changed files with 227 additions and 75 deletions

View file

@ -1,5 +1,14 @@
# Clixon Changelog # Clixon Changelog
## 4.3.0 (Expected: ~December 2019)
### Minor changes
* Added wildcard `*` as a mode to `CLICON_MODE` in clispec files
* If you set "CLICON_MODE="*";" in a clispec file it means that syntax will appear in all CLI spec modes.
### Corrected Bugs
* [Add missing includes](https://github.com/clicon/clixon/pulls)
## 4.2.0 (October 27 2019) ## 4.2.0 (October 27 2019)
### Summary ### Summary
@ -12,7 +21,7 @@ The main improvement in thus release concerns security in terms of priveleges an
* use `-U <user>` clixon_backend command-line option to drop to `user` * use `-U <user>` clixon_backend command-line option to drop to `user`
* Generic options are the following: * Generic options are the following:
* `CLICON_BACKEND_USER` sets the user to drop priveleges to * `CLICON_BACKEND_USER` sets the user to drop priveleges to
* CLICON_BACKEND_PRIVELEGES can have the following values: * `CLICON_BACKEND_PRIVELEGES` can have the following values:
* `none` Make no drop/change in privileges. This is currently the default. * `none` Make no drop/change in privileges. This is currently the default.
* `drop_perm` After initialization, drop privileges permanently * `drop_perm` After initialization, drop privileges permanently
* `drop_perm` After initialization, drop privileges temporarily (to a euid) * `drop_perm` After initialization, drop privileges temporarily (to a euid)

View file

@ -46,7 +46,6 @@
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <assert.h> #include <assert.h>
#include <fnmatch.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/time.h> #include <sys/time.h>
#include <regex.h> #include <regex.h>

View file

@ -200,14 +200,16 @@ cli_nomatch(clicon_handle h)
} }
int int
cli_prompt_set(clicon_handle h, char *prompt) cli_prompt_set(clicon_handle h,
char *prompt)
{ {
cligen_handle ch = cligen(h); cligen_handle ch = cligen(h);
return cligen_prompt_set(ch, prompt); return cligen_prompt_set(ch, prompt);
} }
int int
cli_logsyntax_set(clicon_handle h, int status) cli_logsyntax_set(clicon_handle h,
int status)
{ {
cligen_handle ch = cligen(h); cligen_handle ch = cligen(h);
return cligen_logsyntax_set(ch, status); return cligen_logsyntax_set(ch, status);

View file

@ -45,7 +45,6 @@
#include <stdarg.h> #include <stdarg.h>
#include <syslog.h> #include <syslog.h>
#include <errno.h> #include <errno.h>
#include <assert.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <dirent.h> #include <dirent.h>
#include <libgen.h> #include <libgen.h>
@ -209,15 +208,17 @@ clixon_str2fn(char *name,
return NULL; return NULL;
} }
/*! Append to syntax mode from file /*! Load a file containing syntax and append to specified modes, also load C plugin
* @param[in] h Clixon handle * @param[in] h Clixon handle
* @param[in] filename Name of file where syntax is specified (in syntax-group dir) * @param[in] filename Name of file where syntax is specified (in syntax-group dir)
* @param[in] dir Name of dir, or NULL * @param[in] dir Name of dir, or NULL
* @param[out] allpt Universal CLIgen parse tree: apply to all modes
*/ */
static int static int
cli_load_syntax(clicon_handle h, cli_load_syntax_file(clicon_handle h,
const char *filename, const char *filename,
const char *dir) const char *dir,
parse_tree *ptall)
{ {
void *handle = NULL; /* Handle to plugin .so module */ void *handle = NULL; /* Handle to plugin .so module */
char *mode = NULL; /* Name of syntax mode to append new syntax */ char *mode = NULL; /* Name of syntax mode to append new syntax */
@ -253,10 +254,18 @@ cli_load_syntax(clicon_handle h,
goto done; goto done;
} }
fclose(f); fclose(f);
/* Get CLICON specific global variables */ /* Get CLICON specific global variables:
* CLICON_MODE: which mode(s) this syntax applies to
* CLICON_PROMPT: Cli prompt in this mode
* CLICON_PLUGIN: Name of C API plugin
* Note: the base case is that it is:
* (1) a single mode or
* (2) "*" all modes or "m1:m2" - a list of modes
* but for (2), prompt and plgnam may have unclear semantics
*/
mode = cvec_find_str(cvv, "CLICON_MODE");
prompt = cvec_find_str(cvv, "CLICON_PROMPT"); prompt = cvec_find_str(cvv, "CLICON_PROMPT");
plgnam = cvec_find_str(cvv, "CLICON_PLUGIN"); plgnam = cvec_find_str(cvv, "CLICON_PLUGIN");
mode = cvec_find_str(cvv, "CLICON_MODE");
if (plgnam != NULL) { /* Find plugin for callback resolving */ if (plgnam != NULL) { /* Find plugin for callback resolving */
if ((cp = clixon_plugin_find(h, plgnam)) != NULL) if ((cp = clixon_plugin_find(h, plgnam)) != NULL)
@ -288,8 +297,19 @@ cli_load_syntax(clicon_handle h,
goto done; goto done;
} }
} }
/* Find all modes in CLICON_MODE string: where to append the pt syntax tree */
if ((vec = clicon_strsep(mode, ":", &nvec)) == NULL) if ((vec = clicon_strsep(mode, ":", &nvec)) == NULL)
goto done; goto done;
if (nvec == 1 && strcmp(vec[0], "*") == 0){
/* Special case: Add this to all modes. Add to special "universal" syntax
* and add to all syntaxes after all files have been loaded. At this point
* all modes may not be known (not yet loaded)
*/
if (cligen_parsetree_merge(ptall, NULL, pt) < 0)
return -1;
}
else {
for (i = 0; i < nvec; i++) { for (i = 0; i < nvec; i++) {
if (syntax_append(h, if (syntax_append(h,
cli_syntax(h), cli_syntax(h),
@ -300,6 +320,7 @@ cli_load_syntax(clicon_handle h,
if (prompt) if (prompt)
cli_set_prompt(h, vec[i], prompt); cli_set_prompt(h, vec[i], prompt);
} }
}
cligen_parsetree_free(pt, 1); cligen_parsetree_free(pt, 1);
retval = 0; retval = 0;
@ -329,6 +350,7 @@ cli_syntax_load(clicon_handle h)
cligen_susp_cb_t *fns = NULL; cligen_susp_cb_t *fns = NULL;
cligen_interrupt_cb_t *fni = NULL; cligen_interrupt_cb_t *fni = NULL;
clixon_plugin *cp; clixon_plugin *cp;
parse_tree ptall = {0,}; /* Universal CLIgen parse tree all modes */
/* Syntax already loaded. XXX should we re-load?? */ /* Syntax already loaded. XXX should we re-load?? */
if ((stx = cli_syntax(h)) != NULL) if ((stx = cli_syntax(h)) != NULL)
@ -347,30 +369,38 @@ cli_syntax_load(clicon_handle h)
cli_syntax_set(h, stx); cli_syntax_set(h, stx);
/* Load single specific clispec file */
if (clispec_file){ if (clispec_file){
if (cli_load_syntax(h, clispec_file, NULL) < 0) if (cli_load_syntax_file(h, clispec_file, NULL, &ptall) < 0)
goto done; goto done;
} }
/* Load all clispec .cli files in directory */
if (clispec_dir){ if (clispec_dir){
/* load syntaxfiles */ /* Get directory list of files */
if ((ndp = clicon_file_dirent(clispec_dir, &dp, "(.cli)$", S_IFREG)) < 0) if ((ndp = clicon_file_dirent(clispec_dir, &dp, "(.cli)$", S_IFREG)) < 0)
goto done; goto done;
/* Load the rest */ /* Load the syntax parse trees into cli_syntax stx structure */
for (i = 0; i < ndp; i++) { for (i = 0; i < ndp; i++) {
clicon_debug(1, "DEBUG: Loading syntax '%.*s'", clicon_debug(1, "DEBUG: Loading syntax '%.*s'",
(int)strlen(dp[i].d_name)-4, dp[i].d_name); (int)strlen(dp[i].d_name)-4, dp[i].d_name);
if (cli_load_syntax(h, dp[i].d_name, clispec_dir) < 0) if (cli_load_syntax_file(h, dp[i].d_name, clispec_dir, &ptall) < 0)
goto done; goto done;
} }
} }
/* Did we successfully load any syntax modes? */ /* Were any syntax modes successfully loaded? If not, leave */
if (stx->stx_nmodes <= 0) { if (stx->stx_nmodes <= 0) {
retval = 0; retval = 0;
goto done; goto done;
} }
/* Parse syntax tree for all modes */
/* Go thorugh all modes and :
* 1) Add the universal syntax
* 2) add syntax tree (of those modes - "activate" syntax from stx to CLIgen)
*/
m = stx->stx_modes; m = stx->stx_modes;
do { do {
if (cligen_parsetree_merge(&m->csm_pt, NULL, ptall) < 0)
return -1;
if (gen_parse_tree(h, m) != 0) if (gen_parse_tree(h, m) != 0)
goto done; goto done;
m = NEXTQ(cli_syntaxmode_t *, m); m = NEXTQ(cli_syntaxmode_t *, m);
@ -389,13 +419,13 @@ cli_syntax_load(clicon_handle h)
/* All good. We can now proudly return a new group */ /* All good. We can now proudly return a new group */
retval = 0; retval = 0;
done: done:
if (retval != 0) { if (retval != 0) {
clixon_plugin_exit(h); clixon_plugin_exit(h);
cli_syntax_unload(h); cli_syntax_unload(h);
cli_syntax_set(h, NULL); cli_syntax_set(h, NULL);
} }
cligen_parsetree_free(ptall, 1);
if (dp) if (dp)
free(dp); free(dp);
return retval; return retval;

4
configure vendored
View file

@ -2172,9 +2172,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
: ${INSTALLFLAGS="-s"} : ${INSTALLFLAGS="-s"}
CLIXON_VERSION_MAJOR="4" CLIXON_VERSION_MAJOR="4"
CLIXON_VERSION_MINOR="2" CLIXON_VERSION_MINOR="3"
CLIXON_VERSION_PATCH="0" CLIXON_VERSION_PATCH="0"
CLIXON_VERSION="\"${CLIXON_VERSION_MAJOR}.${CLIXON_VERSION_MINOR}.${CLIXON_VERSION_PATCH}\"" CLIXON_VERSION="\"${CLIXON_VERSION_MAJOR}.${CLIXON_VERSION_MINOR}.${CLIXON_VERSION_PATCH}.PRE\""
# Check CLIgen # Check CLIgen
if test "$prefix" = "NONE"; then if test "$prefix" = "NONE"; then

View file

@ -43,9 +43,9 @@ AC_INIT(lib/clixon/clixon.h.in)
: ${INSTALLFLAGS="-s"} : ${INSTALLFLAGS="-s"}
CLIXON_VERSION_MAJOR="4" CLIXON_VERSION_MAJOR="4"
CLIXON_VERSION_MINOR="2" CLIXON_VERSION_MINOR="3"
CLIXON_VERSION_PATCH="0" CLIXON_VERSION_PATCH="0"
CLIXON_VERSION="\"${CLIXON_VERSION_MAJOR}.${CLIXON_VERSION_MINOR}.${CLIXON_VERSION_PATCH}\"" CLIXON_VERSION="\"${CLIXON_VERSION_MAJOR}.${CLIXON_VERSION_MINOR}.${CLIXON_VERSION_PATCH}.PRE\""
# Check CLIgen # Check CLIgen
if test "$prefix" = "NONE"; then if test "$prefix" = "NONE"; then

View file

@ -122,6 +122,12 @@ After release:
``` ```
* Run autoconf * Run autoconf
Create release branch:
```
git checkout -b release-4.2 4.2.0
git push origin release-4.2
```
## Use of constants etc ## Use of constants etc
Use MAXPATHLEN (not PATH_MAX) Use MAXPATHLEN (not PATH_MAX)

View file

@ -43,7 +43,6 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/param.h> #include <sys/param.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <fnmatch.h> /* matching strings */
#include <signal.h> /* matching strings */ #include <signal.h> /* matching strings */
/* clicon */ /* clicon */

View file

@ -51,20 +51,14 @@
#include <sys/param.h> /* MAXPATHLEN */ #include <sys/param.h> /* MAXPATHLEN */
/* /*
* CLIXON version macros * CLIXON version macros, set in configure and resolved when expanding to
* clixon.h
*/ */
#undef CLIXON_VERSION_STRING #undef CLIXON_VERSION_STRING
#undef CLIXON_VERSION_MAJOR #undef CLIXON_VERSION_MAJOR
#undef CLIXON_VERSION_MINOR #undef CLIXON_VERSION_MINOR
#undef CLIXON_VERSION_PATCH #undef CLIXON_VERSION_PATCH
/*
* Use this constant to disable some prototypes that should not be visible outside the lib.
* This is an alternative to use separate internal include files.
*/
#define LIBCLIXON_API 1
#include <clixon/clixon_sig.h> #include <clixon/clixon_sig.h>
#include <clixon/clixon_uid.h> #include <clixon/clixon_uid.h>
#include <clixon/clixon_err.h> #include <clixon/clixon_err.h>

View file

@ -58,6 +58,10 @@ typedef struct map_str2int map_str2int;
/*! A malloc version that aligns on 4 bytes. To avoid warning from valgrind */ /*! A malloc version that aligns on 4 bytes. To avoid warning from valgrind */
#define align4(s) (((s)/4)*4 + 4) #define align4(s) (((s)/4)*4 + 4)
/* Required for the inline to compile */
#include <stdlib.h>
#include <string.h>
/*! A strdup version that aligns on 4 bytes. To avoid warning from valgrind */ /*! A strdup version that aligns on 4 bytes. To avoid warning from valgrind */
static inline char * strdup4(char *str) static inline char * strdup4(char *str)
{ {

View file

@ -42,7 +42,6 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <fnmatch.h>
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>

View file

@ -43,7 +43,6 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <fnmatch.h>
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>

View file

@ -47,7 +47,6 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <limits.h> #include <limits.h>
#include <fnmatch.h>
#include <stdint.h> #include <stdint.h>
#include <syslog.h> #include <syslog.h>
#include <assert.h> #include <assert.h>

View file

@ -44,7 +44,6 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <fnmatch.h>
#include <stdint.h> #include <stdint.h>
#include <assert.h> #include <assert.h>
#include <syslog.h> #include <syslog.h>

View file

@ -46,7 +46,6 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <fnmatch.h>
#include <stdint.h> #include <stdint.h>
#include <assert.h> #include <assert.h>

View file

@ -46,7 +46,6 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <fnmatch.h>
#include <stdint.h> #include <stdint.h>
#include <assert.h> #include <assert.h>

View file

@ -45,7 +45,6 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <fnmatch.h>
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>

View file

@ -50,7 +50,6 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <fnmatch.h>
#include <stdint.h> #include <stdint.h>
#include <assert.h> #include <assert.h>

View file

@ -44,7 +44,6 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <fnmatch.h>
#include <stdint.h> #include <stdint.h>
#include <assert.h> #include <assert.h>
#include <syslog.h> #include <syslog.h>

View file

@ -65,7 +65,6 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <fnmatch.h>
#include <stdint.h> #include <stdint.h>
#include <assert.h> #include <assert.h>
#include <syslog.h> #include <syslog.h>

View file

@ -40,7 +40,6 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <fnmatch.h>
#include <stdint.h> #include <stdint.h>
#include <assert.h> #include <assert.h>
#include <syslog.h> #include <syslog.h>

View file

@ -63,7 +63,6 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <fnmatch.h>
#include <stdint.h> #include <stdint.h>
#include <assert.h> #include <assert.h>
#include <syslog.h> #include <syslog.h>

View file

@ -105,7 +105,6 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <fnmatch.h>
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#include <sys/types.h> #include <sys/types.h>

125
test/test_cli_submodes.sh Executable file
View file

@ -0,0 +1,125 @@
#!/usr/bin/env bash
# CLIgen mode tests
# Have two modes: AAA and BBB
# Have the following clispec files with syntax for:
# 1) * 2) AAA, 3) BBB, 4) CCC, 5) AAA:BBB, 6) BBB:CCC
# Verify then that modes AAA and BBB have right syntax (also negative)
# AAA should have syntax from 1,2,5 (and not 3,4,6)
# BBB should have syntax from 1,3,5,6 (and not 2,4)
# Magic line must be first in script (see README.md)
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
APPNAME=example
# include err() and new() functions and creates $dir
cfg=$dir/conf_yang.xml
clidir=$dir/clidir
if [ ! -d $clidir ]; then
mkdir $clidir
fi
# Use yang in example
cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config">
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
<CLICON_YANG_MODULE_MAIN>clixon-example</CLICON_YANG_MODULE_MAIN>
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
<CLICON_CLISPEC_DIR>$clidir</CLICON_CLISPEC_DIR>
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
</clixon-config>
EOF
# clispec files 1..6 for submodes AAA and BBB as described in top comment
cat <<EOF > $clidir/cli1.cli
CLICON_MODE="*";
cmd1;
EOF
cat <<EOF > $clidir/cli2.cli
CLICON_MODE="AAA";
cmd2;
EOF
cat <<EOF > $clidir/cli3.cli
CLICON_MODE="BBB";
cmd3;
EOF
cat <<EOF > $clidir/cli4.cli
CLICON_MODE="CCC";
cmd4;
EOF
cat <<EOF > $clidir/cli5.cli
CLICON_MODE="AAA:BBB";
cmd5;
EOF
cat <<EOF > $clidir/cli6.cli
CLICON_MODE="BBB:CCC";
cmd6;
EOF
new "test params: -f $cfg"
if [ $BE -ne 0 ]; then
new "kill old backend"
sudo clixon_backend -z -f $cfg
if [ $? -ne 0 ]; then
err
fi
new "start backend -s init -f $cfg"
start_backend -s init -f $cfg
new "waiting"
wait_backend
fi
m=AAA
# Tests using mode AAA that should pass
for c in 1 2 5; do
new "cli mode $m 1 cmd$c OK"
expectfn "$clixon_cli -1 -m $m -f $cfg cmd$c" 0 "^$"
done
# Tests using mode AAA that should fail
for c in 3 4 6; do
new "cli mode $m 1 cmd$c Not OK"
expectfn "$clixon_cli -1 -m $m -f $cfg cmd$c" 255 "^$"
done
m=BBB
# Tests using mode BBB that should pass
for c in 1 3 5 6; do
new "cli mode $m 1 cmd$c OK"
expectfn "$clixon_cli -1 -m $m -f $cfg cmd$c" 0 "^$"
done
# Tests using mode BBB that should fail
for c in 2 4; do
new "cli mode $m 1 cmd$c Not OK"
expectfn "$clixon_cli -1 -m $m -f $cfg cmd$c" 255 "^$"
done
if [ $BE -eq 0 ]; then
exit # BE
fi
new "Kill backend"
# Check if premature kill
pid=$(pgrep -u root -f clixon_backend)
if [ -z "$pid" ]; then
err "backend already dead"
fi
# kill backend
stop_backend -f $cfg
rm -rf $dir

View file

@ -44,7 +44,6 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <fnmatch.h>
#include <stdint.h> #include <stdint.h>
#include <assert.h> #include <assert.h>
#include <syslog.h> #include <syslog.h>

View file

@ -47,7 +47,6 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <limits.h> #include <limits.h>
#include <fnmatch.h>
#include <stdint.h> #include <stdint.h>
#include <syslog.h> #include <syslog.h>
#include <assert.h> #include <assert.h>

View file

@ -46,7 +46,6 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <fnmatch.h>
#include <stdint.h> #include <stdint.h>
#include <assert.h> #include <assert.h>
#include <syslog.h> #include <syslog.h>

View file

@ -46,7 +46,6 @@ See https://www.w3.org/TR/xpath/
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <fnmatch.h>
#include <stdint.h> #include <stdint.h>
#include <assert.h> #include <assert.h>
#include <syslog.h> #include <syslog.h>

View file

@ -338,20 +338,21 @@ module clixon-config {
leaf CLICON_CLI_DIR { leaf CLICON_CLI_DIR {
type string; type string;
description description
"Location of cli frontend .so plugins. Load all .so "Directory containing frontend cli loadable plugins. Load all .so
plugins in this dir as CLI object plugins"; plugins in this directory as CLI object plugins";
} }
leaf CLICON_CLISPEC_DIR { leaf CLICON_CLISPEC_DIR {
type string; type string;
description description
"Location of frontend .cli cligen spec files. Load all .cli "Directory containing frontend cligen spec files. Load all .cli
files in this dir as CLI specification files"; files in this directory as CLI specification files.
See also CLICON_CLISPEC_FILE.";
} }
leaf CLICON_CLISPEC_FILE { leaf CLICON_CLISPEC_FILE {
type string; type string;
description "Specific frontend .cli cligen spec file as simple description
alternative to CLICON_CLISPEC_DIR. Also available as "Specific frontend cligen spec file as aletrnative or complement
-c in clixon_cli."; to CLICON_CLISPEC_DIR. Also available as -c in clixon_cli.";
} }
leaf CLICON_CLI_MODE { leaf CLICON_CLI_MODE {
type string; type string;