From 74e8934636853e036ff2d761241171c282d97ee4 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Sun, 18 Aug 2024 12:39:13 +0200 Subject: [PATCH] New `clixon-autocli@2024-08-01.yang` revision: Added disable operation for module rules --- CHANGELOG.md | 4 +- apps/cli/cli_autocli.c | 48 ++-- apps/cli/cli_autocli.h | 1 + example/main/Makefile.in | 1 + example/main/autocli.xml | 8 +- lib/src/clixon_xpath.c | 2 +- yang/clixon/clixon-autocli@2023-05-01.yang | 278 --------------------- 7 files changed, 44 insertions(+), 298 deletions(-) delete mode 100644 yang/clixon/clixon-autocli@2023-05-01.yang diff --git a/CHANGELOG.md b/CHANGELOG.md index d11dc535..057e7e9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ Expected: October 2024 ### Features +* New `clixon-autocli@2024-08-01.yang` revision + - Added: disable operation for module rules * Optimize YANG memory * Added union and extended struct for uncommon fields * Removed per-object YANG linenr info @@ -23,7 +25,7 @@ Expected: October 2024 * New: [CLI simple alias](https://github.com/clicon/cligen/issues/112) * See: https://clixon-docs.readthedocs.io/en/latest/cli.html#cli-aliases * 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 ### API changes on existing protocol/config features diff --git a/apps/cli/cli_autocli.c b/apps/cli/cli_autocli.c index 8252c514..7a7e479f 100644 --- a/apps/cli/cli_autocli.c +++ b/apps/cli/cli_autocli.c @@ -59,8 +59,9 @@ /* Mapping from YANG autocli-op to C enum */ static const map_str2int autocli_op_map[] = { {"enable", AUTOCLI_OP_ENABLE}, + {"disable", AUTOCLI_OP_DISABLE}, {"compress", AUTOCLI_OP_COMPRESS}, - {NULL, -1} + {NULL, -1} }; /* 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-nokey", AUTOCLI_LISTKW_NOKEY}, {"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 * @retval 0 OK, and enablep set * @retval -1 Error + * Special rule: module-default=false and no operation=enable rules is disable */ int autocli_module(clixon_handle h, @@ -120,6 +122,7 @@ autocli_module(clixon_handle h, char *str; char *element; int enable = 0; + int op; cxobj *xautocli; char *body; @@ -136,18 +139,18 @@ autocli_module(clixon_handle h, goto done; } enable = strcmp(str, "true") == 0; - if (!enable){ - xrule = NULL; - while ((xrule = xml_child_each(xautocli, xrule, CX_ELMNT)) != NULL) { - if (strcmp(xml_name(xrule), "rule") != 0) - continue; - if ((str = xml_find_body(xrule, "operation")) == NULL) - continue; - /* Peek in element of rule to skip non-compress operations */ - if (autocli_str2op(str) != AUTOCLI_OP_ENABLE) - continue; - /* At this point this rule is a compress rule - * enable rules logic is: + if (enable && modname == NULL) + goto ok; + xrule = NULL; + while ((xrule = xml_child_each(xautocli, xrule, CX_ELMNT)) != NULL) { + if (strcmp(xml_name(xrule), "rule") != 0) + continue; + if ((str = xml_find_body(xrule, "operation")) == NULL) + continue; + /* Skip other than enable/disable */ + op = autocli_str2op(str); + if (!enable && op == AUTOCLI_OP_ENABLE) { + /* Enable rules logic is: * - If match, break, done */ xmod = NULL; @@ -168,6 +171,23 @@ autocli_module(clixon_handle h, 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: *enablep = enable; diff --git a/apps/cli/cli_autocli.h b/apps/cli/cli_autocli.h index ac687f97..64949daf 100644 --- a/apps/cli/cli_autocli.h +++ b/apps/cli/cli_autocli.h @@ -44,6 +44,7 @@ */ enum autocli_op{ AUTOCLI_OP_ENABLE, + AUTOCLI_OP_DISABLE, AUTOCLI_OP_COMPRESS, }; diff --git a/example/main/Makefile.in b/example/main/Makefile.in index 844e4da0..8510382d 100644 --- a/example/main/Makefile.in +++ b/example/main/Makefile.in @@ -179,6 +179,7 @@ install: $(YANGSPECS) $(CLISPECS) $(PLUGINS) $(APPNAME).xml restconf.xml autocli [ -n "$$(getent group "$(CLICON_GROUP)")" ] || groupadd "$(CLICON_GROUP)" [ -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/$(APPNAME) install -m 0644 $(APPNAME).xml $(DESTDIR)$(sysconfdir)/clixon install -m 0644 autocli.xml $(DESTDIR)$(sysconfdir)/clixon/$(APPNAME) install -m 0644 restconf.xml $(DESTDIR)$(sysconfdir)/clixon/$(APPNAME) diff --git a/example/main/autocli.xml b/example/main/autocli.xml index 6d92bd0a..78ebc5fe 100644 --- a/example/main/autocli.xml +++ b/example/main/autocli.xml @@ -1,14 +1,14 @@ - false + true kw-nokey false list container true - include clixon-example - clixon-example - enable + exclude nacm + ietf-netconf-acm + disable diff --git a/lib/src/clixon_xpath.c b/lib/src/clixon_xpath.c index b47f8eb3..841fc73a 100644 --- a/lib/src/clixon_xpath.c +++ b/lib/src/clixon_xpath.c @@ -1096,7 +1096,7 @@ xpath_traverse_canonical(xpath_tree *xs, * Then incoming: * xpath0: /x/c:y * nsc0: NULL:"urn:example:a"; c:"urn:example:b" - * will be translated to: + * is translated to: * xpath1: /a:x/b:y * nsc1: a:"urn:example:a"; b:"urn:example:b" * @code diff --git a/yang/clixon/clixon-autocli@2023-05-01.yang b/yang/clixon/clixon-autocli@2023-05-01.yang deleted file mode 100644 index 9c05806c..00000000 --- a/yang/clixon/clixon-autocli@2023-05-01.yang +++ /dev/null @@ -1,278 +0,0 @@ -module clixon-autocli{ - yang-version 1.1; - namespace "http://clicon.org/autocli"; - prefix autocli; - - organization - "Clicon / Clixon"; - - contact - "Olof Hagsand "; - - 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: - false - - wifi - enable - openconfig-wifi - - 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 - - container compress - compress - container - list - - 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 - 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 "; - } - enum kw-nokey{ - description "Keywords on non-key variables: a y "; - } - enum kw-all{ - description "Keywords on all variables: a x 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 - 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 // or just a single 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; - } - } - } -}