* [Strict auto completion for CLI argument expansion #163](https://github.com/clicon/clixon/issues/163)
* Fixed a bug with the extension API: different unknown statements were treated as same
This commit is contained in:
parent
cf2de375f7
commit
0a593cd513
8 changed files with 437 additions and 15 deletions
|
|
@ -62,6 +62,7 @@ Users may have to change how they access the system
|
||||||
|
|
||||||
### Minor features
|
### Minor features
|
||||||
|
|
||||||
|
* [Strict auto completion for CLI argument expansion #163](https://github.com/clicon/clixon/issues/163)
|
||||||
* [Convert int64, uint64 and decimal64 to string in xml to json #310](https://github.com/clicon/clixon/pull/310)
|
* [Convert int64, uint64 and decimal64 to string in xml to json #310](https://github.com/clicon/clixon/pull/310)
|
||||||
* Backend ignore of SIGPIPE. This occurs if client quits unexpectedly over the UNIX socket.
|
* Backend ignore of SIGPIPE. This occurs if client quits unexpectedly over the UNIX socket.
|
||||||
* This is a timing issue but occurs more frequently in large RESTCONF messgaes.
|
* This is a timing issue but occurs more frequently in large RESTCONF messgaes.
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,7 @@ cli_expand_var_generate(clicon_handle h,
|
||||||
char *cvtypestr,
|
char *cvtypestr,
|
||||||
int options,
|
int options,
|
||||||
uint8_t fraction_digits,
|
uint8_t fraction_digits,
|
||||||
|
int pre,
|
||||||
cbuf *cb)
|
cbuf *cb)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
@ -142,7 +143,9 @@ cli_expand_var_generate(clicon_handle h,
|
||||||
}
|
}
|
||||||
if (yang2api_path_fmt(ys, 1, &api_path_fmt) < 0)
|
if (yang2api_path_fmt(ys, 1, &api_path_fmt) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb, "|<%s:%s", yang_argument_get(ys), cvtypestr);
|
if (pre)
|
||||||
|
cprintf(cb, "|");
|
||||||
|
cprintf(cb, "<%s:%s", yang_argument_get(ys), cvtypestr);
|
||||||
if (options & YANG_OPTIONS_FRACTION_DIGITS)
|
if (options & YANG_OPTIONS_FRACTION_DIGITS)
|
||||||
cprintf(cb, " fraction-digits:%u", fraction_digits);
|
cprintf(cb, " fraction-digits:%u", fraction_digits);
|
||||||
cprintf(cb, " %s(\"candidate\",\"%s\")>",
|
cprintf(cb, " %s(\"candidate\",\"%s\")>",
|
||||||
|
|
@ -600,6 +603,8 @@ yang2cli_var_leafref(clicon_handle h,
|
||||||
int completionp;
|
int completionp;
|
||||||
char *cvtypestr;
|
char *cvtypestr;
|
||||||
int ret;
|
int ret;
|
||||||
|
int flag;
|
||||||
|
int regular_value = 1; /* if strict-expand==0 then regular-value is false */
|
||||||
|
|
||||||
/* Give up: use yreferred
|
/* Give up: use yreferred
|
||||||
* XXX: inline of else clause below
|
* XXX: inline of else clause below
|
||||||
|
|
@ -613,21 +618,25 @@ yang2cli_var_leafref(clicon_handle h,
|
||||||
strcmp(type, "identityref") != 0 &&
|
strcmp(type, "identityref") != 0 &&
|
||||||
strcmp(type, "bits") != 0;
|
strcmp(type, "bits") != 0;
|
||||||
}
|
}
|
||||||
|
if (yang_extension_value(ys, "strict-expand", CLIXON_AUTOCLI_NS, &flag, NULL) < 0)
|
||||||
if (completionp)
|
|
||||||
cprintf(cb, "(");
|
|
||||||
if (yang2cli_var_sub(h, ys, yrestype, helptext, cvtype,
|
|
||||||
options, cvv, patterns, fraction_digits, cb) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
|
regular_value = !flag;
|
||||||
|
if (completionp && regular_value)
|
||||||
|
cprintf(cb, "(");
|
||||||
|
if (regular_value)
|
||||||
|
if (yang2cli_var_sub(h, ys, yrestype, helptext, cvtype,
|
||||||
|
options, cvv, patterns, fraction_digits, cb) < 0)
|
||||||
|
goto done;
|
||||||
if (completionp){
|
if (completionp){
|
||||||
if ((ret = cli_expand_var_generate(h, ys, cvtypestr,
|
if ((ret = cli_expand_var_generate(h, ys, cvtypestr,
|
||||||
options, fraction_digits,
|
options, fraction_digits, regular_value,
|
||||||
cb)) < 0)
|
cb)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
yang2cli_helptext(cb, helptext);
|
yang2cli_helptext(cb, helptext);
|
||||||
cprintf(cb, ")");
|
|
||||||
}
|
}
|
||||||
|
if (completionp && regular_value)
|
||||||
|
cprintf(cb, ")");
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
|
|
@ -694,7 +703,7 @@ yang2cli_var(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
if (completionp){
|
if (completionp){
|
||||||
if ((result = cli_expand_var_generate(h, ys, cvtypestr,
|
if ((result = cli_expand_var_generate(h, ys, cvtypestr,
|
||||||
options, fraction_digits,cb)) < 0)
|
options, fraction_digits, 1, cb)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
yang2cli_helptext(cb, helptext);
|
yang2cli_helptext(cb, helptext);
|
||||||
|
|
@ -738,7 +747,6 @@ yang2cli_var(clicon_handle h,
|
||||||
cvv, patterns, fraction_digits, cb) < 0)
|
cvv, patterns, fraction_digits, cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
ok:
|
ok:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -922,7 +930,6 @@ yang2cli_container(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Generate CLI code for Yang list statement
|
/*! Generate CLI code for Yang list statement
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] ys Yang statement
|
* @param[in] ys Yang statement
|
||||||
|
|
|
||||||
|
|
@ -3770,6 +3770,8 @@ yang_extension_value(yang_stmt *ys,
|
||||||
cbuf *cb = NULL;
|
cbuf *cb = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (exist)
|
||||||
|
*exist = 0;
|
||||||
if ((cb = cbuf_new()) == NULL){
|
if ((cb = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -68,10 +68,10 @@ CLIXON_VERSION=@CLIXON_VERSION@
|
||||||
# see also DATASTORE_TOP_SYMBOL
|
# see also DATASTORE_TOP_SYMBOL
|
||||||
DATASTORE_TOP="config"
|
DATASTORE_TOP="config"
|
||||||
|
|
||||||
# clixon yang revisions occuring in tests
|
# clixon yang revisions occuring in tests (see eg yang/clixon/Makefile.in)
|
||||||
CLIXON_AUTOCLI_REV="2021-12-05"
|
CLIXON_AUTOCLI_REV="2022-02-11"
|
||||||
CLIXON_LIB_REV="2021-12-05"
|
CLIXON_LIB_REV="2021-12-05"
|
||||||
CLIXON_CONFIG_REV="2021-11-11"
|
CLIXON_CONFIG_REV="2022-02-11"
|
||||||
CLIXON_RESTCONF_REV="2021-05-20"
|
CLIXON_RESTCONF_REV="2021-05-20"
|
||||||
CLIXON_EXAMPLE_REV="2020-12-01"
|
CLIXON_EXAMPLE_REV="2020-12-01"
|
||||||
|
|
||||||
|
|
|
||||||
160
test/test_autocli_strict_expand.sh
Executable file
160
test/test_autocli_strict_expand.sh
Executable file
|
|
@ -0,0 +1,160 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# autocli extension strict expansion
|
||||||
|
# See https://github.com/clicon/clixon/issues/163
|
||||||
|
# test is: add a couple of expansion alternatives, ensure cli cannot select any oother option
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
cfg=$dir/conf_yang.xml
|
||||||
|
fyang=$dir/example.yang
|
||||||
|
clidir=$dir/cli
|
||||||
|
if [ -d $clidir ]; then
|
||||||
|
rm -rf $clidir/*
|
||||||
|
else
|
||||||
|
mkdir $clidir
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use yang in example
|
||||||
|
|
||||||
|
# Generate autocli for these modules
|
||||||
|
AUTOCLI=$(autocli_config ${APPNAME}\* kw-nokey false)
|
||||||
|
|
||||||
|
cat <<EOF > $cfg
|
||||||
|
<clixon-config xmlns="http://clicon.org/config">
|
||||||
|
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
||||||
|
<CLICON_FEATURE>ietf-netconf:startup</CLICON_FEATURE>
|
||||||
|
<CLICON_YANG_DIR>${YANG_INSTALLDIR}</CLICON_YANG_DIR>
|
||||||
|
<CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
|
||||||
|
<CLICON_YANG_MAIN_DIR>$dir</CLICON_YANG_MAIN_DIR>
|
||||||
|
<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_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
||||||
|
<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>$dir</CLICON_XMLDB_DIR>
|
||||||
|
<CLICON_MODULE_LIBRARY_RFC7895>false</CLICON_MODULE_LIBRARY_RFC7895>
|
||||||
|
${AUTOCLI}
|
||||||
|
</clixon-config>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat <<EOF > $clidir/ex.cli
|
||||||
|
CLICON_MODE="example";
|
||||||
|
CLICON_PROMPT="%U@%H %W> ";
|
||||||
|
|
||||||
|
# Autocli syntax tree operations
|
||||||
|
edit @datamodel, cli_auto_edit("datamodel");
|
||||||
|
up, cli_auto_up("datamodel");
|
||||||
|
top, cli_auto_top("datamodel");
|
||||||
|
set @datamodel, cli_auto_set();
|
||||||
|
merge @datamodel, cli_auto_merge();
|
||||||
|
create @datamodel, cli_auto_create();
|
||||||
|
delete("Delete a configuration item") {
|
||||||
|
@datamodel, cli_auto_del();
|
||||||
|
all("Delete whole candidate configuration"), delete_all("candidate");
|
||||||
|
}
|
||||||
|
show("Show a particular state of the system")
|
||||||
|
configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "xml", false, false);
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Yang specs must be here first for backend. But then the specs are changed but just for CLI
|
||||||
|
# Annotate original Yang spec example directly
|
||||||
|
# First annotate /table/parameter
|
||||||
|
# Had a problem with unknown in grouping -> test uses uses/grouping
|
||||||
|
cat <<EOF > $fyang
|
||||||
|
module example {
|
||||||
|
namespace "urn:example:clixon";
|
||||||
|
prefix ex;
|
||||||
|
import clixon-autocli{
|
||||||
|
prefix autocli;
|
||||||
|
}
|
||||||
|
container table{
|
||||||
|
list parameter{
|
||||||
|
key name;
|
||||||
|
leaf name{
|
||||||
|
autocli:strict-expand;
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
leaf value{
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
leaf value2{
|
||||||
|
autocli:strict-expand;
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
leaf-list value3{
|
||||||
|
autocli:strict-expand;
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
|
||||||
|
new "wait backend"
|
||||||
|
wait_backend
|
||||||
|
|
||||||
|
# The list
|
||||||
|
new "Add three list options"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><edit-config><default-operation>merge</default-operation><target><candidate/></target><config><table xmlns=\"urn:example:clixon\"><parameter><name>opta</name><value>42</value></parameter><parameter><name>optb</name><value>43</value></parameter><parameter><name>optc</name><value>44</value></parameter></table></config></edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
new "netconf commit"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
new "show config"
|
||||||
|
expectpart "$($clixon_cli -1 -f $cfg show conf)" 0 "<table xmlns=\"urn:example:clixon\"><parameter><name>opta</name><value>42</value></parameter><parameter><name>optb</name><value>43</value></parameter><parameter><name>optc</name><value>44</value></parameter></table>"
|
||||||
|
|
||||||
|
new "Check query"
|
||||||
|
expectpart "$(echo "set table parameter ?" | $clixon_cli -f $cfg 2>&1)" 0 opta optb optc --not-- '<name>'
|
||||||
|
|
||||||
|
new "Check completion"
|
||||||
|
expectpart "$(echo "set table parameter " | $clixon_cli -f $cfg 2>&1)" 0 opta optb optc --not-- '<name>'
|
||||||
|
|
||||||
|
# Leafs
|
||||||
|
new "Add leafs"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><edit-config><default-operation>merge</default-operation><target><candidate/></target><config><table xmlns=\"urn:example:clixon\"><parameter><name>opta</name><value>42</value><value2>43</value2><value3>44</value3></parameter></table></config></edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
new "netconf commit"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
new "show config leafs"
|
||||||
|
expectpart "$($clixon_cli -1 -f $cfg show conf)" 0 "<table xmlns=\"urn:example:clixon\"><parameter><name>opta</name><value>42</value><value2>43</value2><value3>44</value3></parameter><parameter><name>optb</name><value>43</value></parameter><parameter><name>optc</name><value>44</value></parameter></table>"
|
||||||
|
|
||||||
|
new "Check query value"
|
||||||
|
expectpart "$(echo "set table parameter opta value ?" | $clixon_cli -f $cfg 2>&1)" 0 42 '<value>'
|
||||||
|
|
||||||
|
new "Check query value2"
|
||||||
|
expectpart "$(echo "set table parameter opta value2 ?" | $clixon_cli -f $cfg 2>&1)" 0 43 --not-- '<value>'
|
||||||
|
|
||||||
|
new "Check query value3"
|
||||||
|
expectpart "$(echo "set table parameter opta value3 ?" | $clixon_cli -f $cfg 2>&1)" 0 44 --not-- '<value>'
|
||||||
|
|
||||||
|
if [ $BE -ne 0 ]; then
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf $dir
|
||||||
|
|
||||||
|
new "endtest"
|
||||||
|
endtest
|
||||||
|
|
@ -17,6 +17,9 @@ fyang=$dir/type.yang
|
||||||
fyang2=$dir/example2.yang
|
fyang2=$dir/example2.yang
|
||||||
fyang3=$dir/example3.yang
|
fyang3=$dir/example3.yang
|
||||||
|
|
||||||
|
# Generate autocli for these modules
|
||||||
|
AUTOCLI=$(autocli_config ${APPNAME}\* kw-nokey false)
|
||||||
|
|
||||||
# transitive type, exists in fyang3, referenced from fyang2, but not declared in fyang
|
# transitive type, exists in fyang3, referenced from fyang2, but not declared in fyang
|
||||||
cat <<EOF > $fyang3
|
cat <<EOF > $fyang3
|
||||||
module example3{
|
module example3{
|
||||||
|
|
@ -228,6 +231,7 @@ function testrun(){
|
||||||
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
|
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
|
||||||
<CLICON_DATASTORE_CACHE>$dbcache</CLICON_DATASTORE_CACHE>
|
<CLICON_DATASTORE_CACHE>$dbcache</CLICON_DATASTORE_CACHE>
|
||||||
<CLICON_XMLDB_FORMAT>$format</CLICON_XMLDB_FORMAT>
|
<CLICON_XMLDB_FORMAT>$format</CLICON_XMLDB_FORMAT>
|
||||||
|
${AUTOCLI}
|
||||||
</clixon-config>
|
</clixon-config>
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,13 @@ datarootdir = @datarootdir@
|
||||||
# Also mandatory standard YANGs (see ../mandatory)
|
# Also mandatory standard YANGs (see ../mandatory)
|
||||||
YANG_INSTALLDIR = @YANG_INSTALLDIR@
|
YANG_INSTALLDIR = @YANG_INSTALLDIR@
|
||||||
|
|
||||||
|
# Note: mirror these to test/config.sh.in
|
||||||
YANGSPECS = clixon-config@2022-02-11.yang # 5.6
|
YANGSPECS = clixon-config@2022-02-11.yang # 5.6
|
||||||
YANGSPECS += clixon-lib@2021-12-05.yang # 5.5
|
YANGSPECS += clixon-lib@2021-12-05.yang # 5.5
|
||||||
YANGSPECS += clixon-rfc5277@2008-07-01.yang
|
YANGSPECS += clixon-rfc5277@2008-07-01.yang
|
||||||
YANGSPECS += clixon-xml-changelog@2019-03-21.yang
|
YANGSPECS += clixon-xml-changelog@2019-03-21.yang
|
||||||
YANGSPECS += clixon-restconf@2021-05-20.yang # 5.2
|
YANGSPECS += clixon-restconf@2021-05-20.yang # 5.2
|
||||||
YANGSPECS += clixon-autocli@2021-12-05.yang # 5.5
|
YANGSPECS += clixon-autocli@2022-02-11.yang # 5.6
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
|
||||||
|
|
|
||||||
247
yang/clixon/clixon-autocli@2022-02-11.yang
Normal file
247
yang/clixon/clixon-autocli@2022-02-11.yang
Normal file
|
|
@ -0,0 +1,247 @@
|
||||||
|
module clixon-autocli{
|
||||||
|
yang-version 1.1;
|
||||||
|
namespace "http://clicon.org/autocli";
|
||||||
|
prefix autocli;
|
||||||
|
|
||||||
|
organization
|
||||||
|
"Clicon / Clixon";
|
||||||
|
|
||||||
|
contact
|
||||||
|
"Olof Hagsand <olof@hagsand.se>";
|
||||||
|
|
||||||
|
description
|
||||||
|
"Clixon CLIgen specification declarations, including autocli.
|
||||||
|
Design inspired by ietf-netconf-acm.yang
|
||||||
|
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
Copyright (C) 2020-2021 Olof Hagsand and Rubicon Communications, LLC(Netgate)
|
||||||
|
|
||||||
|
This file is part of CLIXON
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the \"License\");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an \"AS IS\" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
Alternatively, the contents of this file may be used under the terms of
|
||||||
|
the GNU General Public License Version 3 or later (the \"GPL\"),
|
||||||
|
in which case the provisions of the GPL are applicable instead
|
||||||
|
of those above. If you wish to allow use of your version of this file only
|
||||||
|
under the terms of the GPL, and not to allow others to
|
||||||
|
use your version of this file under the terms of Apache License version 2,
|
||||||
|
indicate your decision by deleting the provisions above and replace them with
|
||||||
|
the notice and other provisions required by the GPL. If you do not delete
|
||||||
|
the provisions above, a recipient may use your version of this file under
|
||||||
|
the terms of any one of the Apache License version 2 or the GPL.
|
||||||
|
|
||||||
|
***** END LICENSE BLOCK *****";
|
||||||
|
|
||||||
|
revision 2022-02-11 {
|
||||||
|
description
|
||||||
|
"Initial version
|
||||||
|
Released in Clixon 5.6";
|
||||||
|
}
|
||||||
|
revision 2021-12-05 {
|
||||||
|
description
|
||||||
|
"Initial version
|
||||||
|
Released in Clixon 5.5";
|
||||||
|
}
|
||||||
|
extension hide {
|
||||||
|
description
|
||||||
|
"Modify the autocli by hiding the command associated with a YANG node and its
|
||||||
|
sub-commands.
|
||||||
|
The command is active but not shown by ? or TAB. In other words, it hides the
|
||||||
|
auto-completion of commands";
|
||||||
|
}
|
||||||
|
extension hide-show {
|
||||||
|
description
|
||||||
|
"Modify the autocli by hiding the command associated with a YANG node and its
|
||||||
|
sub-commands in CLI show commands.";
|
||||||
|
}
|
||||||
|
extension strict-expand {
|
||||||
|
description
|
||||||
|
"Modify the autocli by only showing exactly the expanded values of a variable.
|
||||||
|
It should not be possible to add a new value that is not in the expanded list.";
|
||||||
|
}
|
||||||
|
typedef autocli-op {
|
||||||
|
description
|
||||||
|
"Autocli rule-type operation, each rule use different fields as
|
||||||
|
described in the individual enums below.";
|
||||||
|
type enumeration {
|
||||||
|
enum enable {
|
||||||
|
description
|
||||||
|
"Include a complete subtree to rendering of autocli.
|
||||||
|
Example:
|
||||||
|
<module-default>false</module-default>
|
||||||
|
<rule>
|
||||||
|
<name>wifi</name>
|
||||||
|
<operation>enable</operation>
|
||||||
|
<module-name>openconfig-wifi</module-name>
|
||||||
|
</rule>
|
||||||
|
Only on module-level and if module-default is false,
|
||||||
|
Rule fields used: module-name";
|
||||||
|
}
|
||||||
|
enum compress {
|
||||||
|
description
|
||||||
|
"Skip a keyword from a command.
|
||||||
|
Keep the command, only make it shorter by omitting a part.
|
||||||
|
Example: compress containers if single list child
|
||||||
|
<rule>
|
||||||
|
<name>container compress</name>
|
||||||
|
<operation>compress</operation>
|
||||||
|
<yang-keyword>container</yang-keyword>
|
||||||
|
<yang-keyword-child>list</yang-keyword-child>
|
||||||
|
</rule>
|
||||||
|
Rule fields used:
|
||||||
|
module-name, yang-keyword, schema-nodeid, yang-keyword-child, extension";
|
||||||
|
}
|
||||||
|
enum edit-mode {
|
||||||
|
description
|
||||||
|
"Autocli CLI edit modes for YANG symbols.
|
||||||
|
For example,
|
||||||
|
edit interface eth0<CR>
|
||||||
|
enters a new mode with local context.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
typedef list-keyword-type {
|
||||||
|
description
|
||||||
|
"Autocli CLI keyword behaviour in YANG lists.
|
||||||
|
With 'keyword' is meant CLIgen 'constants' rather than 'variables'.
|
||||||
|
Assume a YANG LIST: list a{ key x; leaf x; leaf y;} and how to generate
|
||||||
|
the autocli";
|
||||||
|
type enumeration {
|
||||||
|
enum kw-none{
|
||||||
|
description "No extra keywords, only variables: a <x> <y>";
|
||||||
|
}
|
||||||
|
enum kw-nokey{
|
||||||
|
description "Keywords on non-key variables: a <x> y <y>";
|
||||||
|
}
|
||||||
|
enum kw-all{
|
||||||
|
description "Keywords on all variables: a x <x> y <y>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
typedef yang-keywords {
|
||||||
|
type bits {
|
||||||
|
bit list;
|
||||||
|
bit listall{ /* NYI */
|
||||||
|
description
|
||||||
|
"Variant of list encompassing all list entries, not just an instance";
|
||||||
|
}
|
||||||
|
bit container;
|
||||||
|
bit leaf; /* Also leaf-list (NYI) */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
grouping clixon-autocli{
|
||||||
|
/* options */
|
||||||
|
leaf module-default {
|
||||||
|
description
|
||||||
|
"Include YANG modules for generation of autocli.
|
||||||
|
If true, all modules with a top-level datanode are generated, ie
|
||||||
|
they get a top-level entry in the @basemodel tree.
|
||||||
|
If false, you need to explicitly enable modules for autocli generation
|
||||||
|
using 'enable' rules";
|
||||||
|
type boolean;
|
||||||
|
default true;
|
||||||
|
}
|
||||||
|
leaf list-keyword-default {
|
||||||
|
description
|
||||||
|
"Autocli CLI keyword behaviour in YANG lists.";
|
||||||
|
type list-keyword-type;
|
||||||
|
default kw-nokey;
|
||||||
|
}
|
||||||
|
leaf treeref-state-default {
|
||||||
|
description
|
||||||
|
"If 'true', generate CLI from YANG state/non-config statements as well, not only config data.
|
||||||
|
Many specs have very large state parts, for example openconfig has ca 10 times
|
||||||
|
larger state than config parts, see for example openconfig-isis.yang.";
|
||||||
|
type boolean;
|
||||||
|
default false;
|
||||||
|
}
|
||||||
|
leaf edit-mode-default {
|
||||||
|
description
|
||||||
|
"Open automatic edit-modes for some YANG keywords and do not allow others.
|
||||||
|
A CLI edit mode opens a carriage-return option and changes the context to be
|
||||||
|
in that local context.
|
||||||
|
For example:
|
||||||
|
cli> interfaces interface e0<cr>
|
||||||
|
eth0>
|
||||||
|
Default is to generate edit-modes for all containers and lists.";
|
||||||
|
type yang-keywords;
|
||||||
|
default "list container";
|
||||||
|
}
|
||||||
|
leaf completion-default {
|
||||||
|
description
|
||||||
|
"Generate code for CLI completion of existing db symbols.
|
||||||
|
That is, check existing configure database for completion options.
|
||||||
|
This is normally always enabled.";
|
||||||
|
type boolean;
|
||||||
|
default true;
|
||||||
|
}
|
||||||
|
/* rules */
|
||||||
|
list rule {
|
||||||
|
description
|
||||||
|
"Represents a modification rule of a clixon clispec.";
|
||||||
|
key name;
|
||||||
|
leaf name {
|
||||||
|
description
|
||||||
|
"Arbitrary name assigned for the rule, must be unique";
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
leaf description {
|
||||||
|
description
|
||||||
|
"Rule description";
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
leaf operation {
|
||||||
|
description "Rule operation";
|
||||||
|
type autocli-op;
|
||||||
|
}
|
||||||
|
leaf module-name {
|
||||||
|
description
|
||||||
|
"Name of the module associated with this rule.
|
||||||
|
Wildchars '*' and '?' can be used (glob pattern).
|
||||||
|
Revision and yang suffix are omitted
|
||||||
|
Example: 'openconfig-*'";
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
leaf yang-keyword {
|
||||||
|
description
|
||||||
|
"If present identifes a YANG keyword which the rule applies to
|
||||||
|
Example: 'container'
|
||||||
|
";
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
leaf schema-nodeid {
|
||||||
|
description
|
||||||
|
"path in the form of /<id>/<id> or just a single <id> identifying a YANG
|
||||||
|
schema-node identifier as defined in RFC 7950 Sec 6.5
|
||||||
|
Example: 'config', '/interfaces/interface'";
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
leaf yang-keyword-child {
|
||||||
|
description
|
||||||
|
"The YANG statement has a single child, and the yang type of the child is the
|
||||||
|
value of this option
|
||||||
|
A (maybe too) specific property to cover openconfig compressions
|
||||||
|
as defined here:
|
||||||
|
https://github.com/openconfig/ygot/blob/master/docs/design.md#openconfig-path-compression";
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
leaf extension {
|
||||||
|
/* Consider making this a container with name/module/value instead */
|
||||||
|
description
|
||||||
|
"The extension is set either in the node itself, or in this module
|
||||||
|
Extension prefix must be set
|
||||||
|
Example: oc-ext:openconfig-version";
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue