* Auto-CLI enhancements

* A generated clispec including state (default @datanodestate) also generated along with the config clispec tree (default @datanode)
  * New mode `GT_HIDE` set by option `CLICON_CLI_GENMODEL_TYPE` to collapse non-presence containers that only contain a single list
  * Added a prfix for cli_show_config/cli_show_auto so that it can produce parseable output
  * Thanks dcornejo@netgate.com for trying it out and suggestions
This commit is contained in:
Olof hagsand 2020-06-13 12:05:26 +02:00
parent e2d9c046af
commit e898dda016
16 changed files with 319 additions and 86 deletions

View file

@ -1305,8 +1305,9 @@ netconf_module_load(clicon_handle h)
/* Load yang spec */
if (yang_spec_parse_module(h, "ietf-netconf", NULL, yspec)< 0)
goto done;
if (yang_spec_parse_module(h, "clixon-rfc5277", NULL, yspec)< 0)
goto done;
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277"))
if (yang_spec_parse_module(h, "clixon-rfc5277", NULL, yspec)< 0)
goto done;
/* YANG module revision change management */
if (clicon_option_bool(h, "CLICON_XML_CHANGELOG"))
if (yang_spec_parse_module(h, "clixon-xml-changelog", NULL, yspec)< 0)

View file

@ -85,6 +85,7 @@ static const map_str2int cli_genmodel_map[] = {
{"NONE", GT_NONE},
{"VARS", GT_VARS},
{"ALL", GT_ALL},
{"HIDE", GT_HIDE},
{NULL, -1}
};

View file

@ -206,7 +206,7 @@ xml2cli(FILE *f,
if (yang_keyword_get(ys) == Y_LEAF || yang_keyword_get(ys) == Y_LEAF_LIST){
if (prepend0)
fprintf(f, "%s", prepend0);
if (gt == GT_ALL || gt == GT_VARS)
if (gt == GT_ALL || gt == GT_VARS || gt == GT_HIDE)
fprintf(f, "%s ", xml_name(x));
if ((body = xml_body(x)) != NULL){
if (index(body, ' '))
@ -224,7 +224,12 @@ xml2cli(FILE *f,
}
if (prepend0)
cprintf(cbpre, "%s", prepend0);
cprintf(cbpre, "%s ", xml_name(x));
/* If non-presence container && HIDE mode && only child is
* a list, then skip container keyword
* See also yang2cli_container */
if (yang_container_cli_hide(ys, gt) == 0)
cprintf(cbpre, "%s ", xml_name(x));
if (yang_keyword_get(ys) == Y_LIST){
/* If list then first loop through keys */

View file

@ -2537,6 +2537,54 @@ yang_arg2cvec(yang_stmt *ys,
return cvv;
}
/*! Check if yang is subject to generated cli GT_HIDE boolean
* The yang should be:
* 1) a non-presence container
* 2) parent of a (single) list XXX: or could multiple lists work?
* 3) no other data node children
* @retval 0 No, does not satisfy the GT_HIDE condition
* @retval 1 Yes, satisfies the GT_HIDE condition
* @see clixon-config.yang HIDE enumeration type
*/
int
yang_container_cli_hide(yang_stmt *ys,
enum genmodel_type gt)
{
yang_stmt *yc = NULL;
int i;
enum rfc_6020 keyw;
keyw = yang_keyword_get(ys);
/* HIDE mode */
if (gt != GT_HIDE)
return 0;
/* A container */
if (yang_keyword_get(ys) != Y_CONTAINER)
return 0;
/* Non-presence */
if (yang_find(ys, Y_PRESENCE, NULL) != NULL)
return 0;
/* Ensure a single list child and no other data nodes */
i = 0; /* Number of list nodes */
while ((yc = yn_each(ys, yc)) != NULL) {
keyw = yang_keyword_get(yc);
/* case/choice could hide anything so disqualify those */
if (keyw == Y_CASE || keyw == Y_CHOICE)
break;
if (!yang_datanode(yc)) /* Allowed, check next */
continue;
if (keyw != Y_LIST) /* Another datanode than list */
break;
if (i++>0) /* More than one list (or could this work?) */
break;
}
if (yc != NULL) /* break from loop */
return 0;
if (i != 1) /* List found */
return 0;
return 1; /* Passed all tests: yes you can hide this keyword */
}
/*! Check if yang node yn has key-stmt as child which matches name
*
* The function looks at the LIST argument string (not actual children)