New clixon-autocli@2024-08-01.yang revision: Added disable operation for module rules
This commit is contained in:
parent
b1a4656f72
commit
74e8934636
7 changed files with 44 additions and 298 deletions
|
|
@ -16,6 +16,8 @@ Expected: October 2024
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
|
* New `clixon-autocli@2024-08-01.yang` revision
|
||||||
|
- Added: disable operation for module rules
|
||||||
* Optimize YANG memory
|
* Optimize YANG memory
|
||||||
* Added union and extended struct for uncommon fields
|
* Added union and extended struct for uncommon fields
|
||||||
* Removed per-object YANG linenr info
|
* Removed per-object YANG linenr info
|
||||||
|
|
@ -23,7 +25,7 @@ Expected: October 2024
|
||||||
* New: [CLI simple alias](https://github.com/clicon/cligen/issues/112)
|
* New: [CLI simple alias](https://github.com/clicon/cligen/issues/112)
|
||||||
* See: https://clixon-docs.readthedocs.io/en/latest/cli.html#cli-aliases
|
* See: https://clixon-docs.readthedocs.io/en/latest/cli.html#cli-aliases
|
||||||
* List pagination: Added where, sort-by and direction parameter for configured data
|
* List pagination: Added where, sort-by and direction parameter for configured data
|
||||||
* New `clixon-lib@2024-04-01.yang` revision
|
* New `clixon-lib@2024-08-01.yang` revision
|
||||||
- Added: list-pagination-partial-state extension
|
- Added: list-pagination-partial-state extension
|
||||||
|
|
||||||
### API changes on existing protocol/config features
|
### API changes on existing protocol/config features
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,9 @@
|
||||||
/* Mapping from YANG autocli-op to C enum */
|
/* Mapping from YANG autocli-op to C enum */
|
||||||
static const map_str2int autocli_op_map[] = {
|
static const map_str2int autocli_op_map[] = {
|
||||||
{"enable", AUTOCLI_OP_ENABLE},
|
{"enable", AUTOCLI_OP_ENABLE},
|
||||||
|
{"disable", AUTOCLI_OP_DISABLE},
|
||||||
{"compress", AUTOCLI_OP_COMPRESS},
|
{"compress", AUTOCLI_OP_COMPRESS},
|
||||||
{NULL, -1}
|
{NULL, -1}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Mapping from YANG list-keyword-type to C enum */
|
/* Mapping from YANG list-keyword-type to C enum */
|
||||||
|
|
@ -68,7 +69,7 @@ static const map_str2int list_kw_map[] = {
|
||||||
{"kw-none", AUTOCLI_LISTKW_NONE},
|
{"kw-none", AUTOCLI_LISTKW_NONE},
|
||||||
{"kw-nokey", AUTOCLI_LISTKW_NOKEY},
|
{"kw-nokey", AUTOCLI_LISTKW_NOKEY},
|
||||||
{"kw-all", AUTOCLI_LISTKW_ALL},
|
{"kw-all", AUTOCLI_LISTKW_ALL},
|
||||||
{NULL, -1}
|
{NULL, -1}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -108,6 +109,7 @@ autocli_listkw_int2str(int listkw)
|
||||||
* @param[out] enablep Include this module in autocli
|
* @param[out] enablep Include this module in autocli
|
||||||
* @retval 0 OK, and enablep set
|
* @retval 0 OK, and enablep set
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
|
* Special rule: module-default=false and no operation=enable rules is disable
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
autocli_module(clixon_handle h,
|
autocli_module(clixon_handle h,
|
||||||
|
|
@ -120,6 +122,7 @@ autocli_module(clixon_handle h,
|
||||||
char *str;
|
char *str;
|
||||||
char *element;
|
char *element;
|
||||||
int enable = 0;
|
int enable = 0;
|
||||||
|
int op;
|
||||||
cxobj *xautocli;
|
cxobj *xautocli;
|
||||||
char *body;
|
char *body;
|
||||||
|
|
||||||
|
|
@ -136,18 +139,18 @@ autocli_module(clixon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
enable = strcmp(str, "true") == 0;
|
enable = strcmp(str, "true") == 0;
|
||||||
if (!enable){
|
if (enable && modname == NULL)
|
||||||
xrule = NULL;
|
goto ok;
|
||||||
while ((xrule = xml_child_each(xautocli, xrule, CX_ELMNT)) != NULL) {
|
xrule = NULL;
|
||||||
if (strcmp(xml_name(xrule), "rule") != 0)
|
while ((xrule = xml_child_each(xautocli, xrule, CX_ELMNT)) != NULL) {
|
||||||
continue;
|
if (strcmp(xml_name(xrule), "rule") != 0)
|
||||||
if ((str = xml_find_body(xrule, "operation")) == NULL)
|
continue;
|
||||||
continue;
|
if ((str = xml_find_body(xrule, "operation")) == NULL)
|
||||||
/* Peek in element of rule to skip non-compress operations */
|
continue;
|
||||||
if (autocli_str2op(str) != AUTOCLI_OP_ENABLE)
|
/* Skip other than enable/disable */
|
||||||
continue;
|
op = autocli_str2op(str);
|
||||||
/* At this point this rule is a compress rule
|
if (!enable && op == AUTOCLI_OP_ENABLE) {
|
||||||
* enable rules logic is:
|
/* Enable rules logic is:
|
||||||
* - If match, break, done
|
* - If match, break, done
|
||||||
*/
|
*/
|
||||||
xmod = NULL;
|
xmod = NULL;
|
||||||
|
|
@ -168,6 +171,23 @@ autocli_module(clixon_handle h,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (enable && op == AUTOCLI_OP_DISABLE) {
|
||||||
|
xmod = NULL;
|
||||||
|
while ((xmod = xml_child_each(xrule, xmod, CX_ELMNT)) != NULL) {
|
||||||
|
if ((element = xml_name(xmod)) == NULL)
|
||||||
|
continue;
|
||||||
|
if (strcmp(element, "module-name") == 0){
|
||||||
|
if ((body = xml_body(xmod)) == NULL)
|
||||||
|
continue; /* invalid rule? */
|
||||||
|
if (fnmatch(body, modname, 0) == 0)
|
||||||
|
break; /* match */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (xmod != NULL){ /* break: found match */
|
||||||
|
enable = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ok:
|
ok:
|
||||||
*enablep = enable;
|
*enablep = enable;
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
*/
|
*/
|
||||||
enum autocli_op{
|
enum autocli_op{
|
||||||
AUTOCLI_OP_ENABLE,
|
AUTOCLI_OP_ENABLE,
|
||||||
|
AUTOCLI_OP_DISABLE,
|
||||||
AUTOCLI_OP_COMPRESS,
|
AUTOCLI_OP_COMPRESS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,7 @@ install: $(YANGSPECS) $(CLISPECS) $(PLUGINS) $(APPNAME).xml restconf.xml autocli
|
||||||
[ -n "$$(getent group "$(CLICON_GROUP)")" ] || groupadd "$(CLICON_GROUP)"
|
[ -n "$$(getent group "$(CLICON_GROUP)")" ] || groupadd "$(CLICON_GROUP)"
|
||||||
[ -n "$$(getent passwd "$(CLICON_USER)")" ] || useradd -M -s /usr/sbin/nologin -g "$(CLICON_GROUP)" "$(CLICON_USER)"
|
[ -n "$$(getent passwd "$(CLICON_USER)")" ] || useradd -M -s /usr/sbin/nologin -g "$(CLICON_GROUP)" "$(CLICON_USER)"
|
||||||
install -d -m 0755 $(DESTDIR)$(sysconfdir)/clixon
|
install -d -m 0755 $(DESTDIR)$(sysconfdir)/clixon
|
||||||
|
install -d -m 0755 $(DESTDIR)$(sysconfdir)/clixon/$(APPNAME)
|
||||||
install -m 0644 $(APPNAME).xml $(DESTDIR)$(sysconfdir)/clixon
|
install -m 0644 $(APPNAME).xml $(DESTDIR)$(sysconfdir)/clixon
|
||||||
install -m 0644 autocli.xml $(DESTDIR)$(sysconfdir)/clixon/$(APPNAME)
|
install -m 0644 autocli.xml $(DESTDIR)$(sysconfdir)/clixon/$(APPNAME)
|
||||||
install -m 0644 restconf.xml $(DESTDIR)$(sysconfdir)/clixon/$(APPNAME)
|
install -m 0644 restconf.xml $(DESTDIR)$(sysconfdir)/clixon/$(APPNAME)
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
<clixon-config xmlns="http://clicon.org/config">
|
<clixon-config xmlns="http://clicon.org/config">
|
||||||
<autocli>
|
<autocli>
|
||||||
<module-default>false</module-default>
|
<module-default>true</module-default>
|
||||||
<list-keyword-default>kw-nokey</list-keyword-default>
|
<list-keyword-default>kw-nokey</list-keyword-default>
|
||||||
<treeref-state-default>false</treeref-state-default>
|
<treeref-state-default>false</treeref-state-default>
|
||||||
<edit-mode-default>list container</edit-mode-default>
|
<edit-mode-default>list container</edit-mode-default>
|
||||||
<completion-default>true</completion-default>
|
<completion-default>true</completion-default>
|
||||||
<rule>
|
<rule>
|
||||||
<name>include clixon-example</name>
|
<name>exclude nacm</name>
|
||||||
<module-name>clixon-example</module-name>
|
<module-name>ietf-netconf-acm</module-name>
|
||||||
<operation>enable</operation>
|
<operation>disable</operation>
|
||||||
</rule>
|
</rule>
|
||||||
</autocli>
|
</autocli>
|
||||||
</clixon-config>
|
</clixon-config>
|
||||||
|
|
|
||||||
|
|
@ -1096,7 +1096,7 @@ xpath_traverse_canonical(xpath_tree *xs,
|
||||||
* Then incoming:
|
* Then incoming:
|
||||||
* xpath0: /x/c:y
|
* xpath0: /x/c:y
|
||||||
* nsc0: NULL:"urn:example:a"; c:"urn:example:b"
|
* nsc0: NULL:"urn:example:a"; c:"urn:example:b"
|
||||||
* will be translated to:
|
* is translated to:
|
||||||
* xpath1: /a:x/b:y
|
* xpath1: /a:x/b:y
|
||||||
* nsc1: a:"urn:example:a"; b:"urn:example:b"
|
* nsc1: a:"urn:example:a"; b:"urn:example:b"
|
||||||
* @code
|
* @code
|
||||||
|
|
|
||||||
|
|
@ -1,278 +0,0 @@
|
||||||
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 2023-05-01 {
|
|
||||||
description
|
|
||||||
"Added extensions skip and alias
|
|
||||||
Added grouping-treeref
|
|
||||||
Released in Clixon 6.3";
|
|
||||||
}
|
|
||||||
revision 2022-02-11 {
|
|
||||||
description
|
|
||||||
"Released in Clixon 5.6";
|
|
||||||
}
|
|
||||||
revision 2021-12-05 {
|
|
||||||
description
|
|
||||||
"Initial version
|
|
||||||
Released in Clixon 5.5";
|
|
||||||
}
|
|
||||||
extension hide {
|
|
||||||
description
|
|
||||||
"Hide 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
|
|
||||||
"Hide the command associated with a YANG node and its
|
|
||||||
sub-commands in CLI show commands.";
|
|
||||||
}
|
|
||||||
extension skip {
|
|
||||||
description
|
|
||||||
"Skip the command associated with a YANG node and its sub-commands altogether.
|
|
||||||
The command is completely removed from the CLI, but still exists in NETCONF/
|
|
||||||
RESTCONF.";
|
|
||||||
}
|
|
||||||
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.";
|
|
||||||
}
|
|
||||||
extension alias {
|
|
||||||
description
|
|
||||||
"Replace the command name with a new value.
|
|
||||||
Instead of using the YANG argument name, use this instead";
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
leaf grouping-treeref {
|
|
||||||
description
|
|
||||||
"Controls the behaviour when generating CLISPEC of YANG 'uses' statements into the
|
|
||||||
corresponding 'grouping' definition: macro expansion.
|
|
||||||
For optimization of memory footprint.
|
|
||||||
If 'false', replace the uses definition with the grouping definition.
|
|
||||||
If 'true' use indirect tree reference '@treeref' to reference the grouping definition. This
|
|
||||||
saves memory for large YANGs.
|
|
||||||
|
|
||||||
See also AUTOCLI_GROUPING_TOPLEVEL_SKIP and AUTOCLI_GROUPING_AUGMENT_SKIP for
|
|
||||||
temporary disabled cornercases.
|
|
||||||
This option was introduced in Clixon 6.3";
|
|
||||||
type boolean;
|
|
||||||
default false;
|
|
||||||
}
|
|
||||||
/* 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