Fixed: [All values in list don't appear when writing "show <list>" in cli](https://github.com/clicon/clixon/issues/359)

CLISPEC change:
* Changed signature of `cli_show_auto()`,
* remove: `cli_show_auto_state()`
This commit is contained in:
Olof hagsand 2022-09-14 15:31:45 +02:00
parent 76c1566d00
commit 9a224ea4a0
9 changed files with 408 additions and 65 deletions

View file

@ -346,7 +346,7 @@ cli_auto_top(clicon_handle h,
* <dbname> "running"|"candidate"|"startup"
* <format> "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
* <pretty> true|false: pretty-print or not
* <state> true|false: include state in output
* <state> true|false: also print state
* <default> Retrieval default mode: report-all, trim, explicit, report-all-tagged,
* report-all-tagged-default, report-all-tagged-strip
* <prefix> CLI prefix: to print before cli syntax output
@ -507,13 +507,13 @@ cli_auto_show(clicon_handle h,
goto done;
break;
case FORMAT_NETCONF:
fprintf(stdout, "<rpc xmlns=\"%s\" %s><edit-config><target><candidate/></target><config>",
cligen_output(stdout, "<rpc xmlns=\"%s\" %s><edit-config><target><candidate/></target><config>",
NETCONF_BASE_NAMESPACE, NETCONF_MESSAGE_ID_ATTR);
if (pretty)
fprintf(stdout, "\n");
cligen_output(stdout, "\n");
if (clixon_xml2file(stdout, xp, 2, pretty, cligen_output, skiproot, 1) < 0)
goto done;
fprintf(stdout, "</config></edit-config></rpc>]]>]]>\n");
cligen_output(stdout, "</config></edit-config></rpc>]]>]]>\n");
break;
} /* switch */
}

View file

@ -673,19 +673,23 @@ int cli_show_version(clicon_handle h,
*
* This callback can be used only in context of an autocli generated syntax tree, such as:
* show @datamodel, cli_show_auto();
*
* @param[in] h CLICON handle
* @param[in] state If set, show both config and state, otherwise only config
* @param[in] cvv Vector of variables from CLIgen command-line
* @param[in] argv String vector: <dbname> <format> <xpath> [<varname>]
* Format of argv:
* <api_path_fmt> Generated API PATH
* <dbname> "running"|"candidate"|"startup"
* <format> "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
* <prefix> to print before cli syntax output
* <dbname> "running"|"candidate"|"startup"
* <format> "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
* <pretty> true|false: pretty-print or not (Optional)
* <state> true|false: also print state
* <default> Retrieval default mode: report-all, trim, explicit, report-all-tagged,
* report-all-tagged-default, report-all-tagged-strip (Optional)
* <prefix> To print before cli syntax outptu
* @note if state parameter is set, then db must be running
* @note that first argument is generated by code.
* @see cli_show_config1
* XXX Merge with cli_auto_show
*/
static int
cli_show_auto1(clicon_handle h,
@ -707,9 +711,18 @@ cli_show_auto1(clicon_handle h,
char *api_path = NULL;
char *prefix = NULL;
int cvvi = 0;
cg_var *boolcv = NULL;
char *defaultstr = NULL; /* with extended tagged modes */
char *withdefaultstr = NULL; /* RFC 6243 modes */
int pretty = 1;
cxobj **vec = NULL;
size_t veclen;
int i;
yang_stmt *yp;
enum rfc_6020 ys_keyword;
if (cvec_len(argv) < 3 || cvec_len(argv) > 4){
clicon_err(OE_PLUGIN, EINVAL, "Usage: <api-path-fmt>* <database> <format> <prefix>. (*) generated.");
if (cvec_len(argv) < 3 || cvec_len(argv) > 7){
clicon_err(OE_PLUGIN, EINVAL, "Usage: <api-path-fmt>* <database> <format> [<pretty> <state> <default> <prefix>]. Number of args:%d", cvec_len(argv));
goto done;
}
/* First argv argument: API_path format */
@ -718,14 +731,50 @@ cli_show_auto1(clicon_handle h,
db = cv_string_get(cvec_i(argv, 1));
/* Third format: output format */
formatstr = cv_string_get(cvec_i(argv, 2));
if (cvec_len(argv) > 3){
/* Fourth format: prefix to print before cli syntax */
prefix = cv_string_get(cvec_i(argv, 3));
}
if ((int)(format = format_str2int(formatstr)) < 0){
clicon_err(OE_PLUGIN, 0, "Not valid format: %s", formatstr);
goto done;
}
if (cvec_len(argv) > 3){
/* Fourth: pretty-print */
if ((boolcv = cv_new(CGV_BOOL)) == NULL){
clicon_err(OE_UNIX, errno, "cv_new");
goto done;
}
if (cv_parse(cv_string_get(cvec_i(argv, 3)), boolcv) < 0){
clicon_err(OE_UNIX, errno, "Parse boolean %s", cv_string_get(cvec_i(argv, 3)));
goto done;
}
pretty = cv_bool_get(boolcv);
}
if (cvec_len(argv) > 4){
if (cv_parse(cv_string_get(cvec_i(argv, 4)), boolcv) < 0){
clicon_err(OE_UNIX, errno, "Parse boolean %s", cv_string_get(cvec_i(argv, 4)));
goto done;
}
state = cv_bool_get(boolcv);
}
if (cvec_len(argv) > 5){
defaultstr = cv_string_get(cvec_i(argv, 5));
/* From extended to RFC6243 withdefault modes */
if (strcmp(defaultstr, "report-all-tagged-strip") == 0)
withdefaultstr = "report-all-tagged";
else if (strcmp(defaultstr, "report-all-tagged-default") == 0)
withdefaultstr = "report-all-tagged";
else if (strcmp(defaultstr, "report-all") != 0 &&
strcmp(defaultstr, "trim") != 0 &&
strcmp(defaultstr, "explicit") != 0 &&
strcmp(defaultstr, "report-all-tagged") != 0){
clicon_err(OE_YANG, EINVAL, "Unexpected with-default option: %s", defaultstr);
goto done;
}
else
withdefaultstr = defaultstr;
}
if (cvec_len(argv) > 6){
/* Fourth format: prefix to print before cli syntax */
prefix = cv_string_get(cvec_i(argv, 6));
}
if ((yspec = clicon_dbspec_yang(h)) == NULL){
clicon_err(OE_FATAL, 0, "No DB_SPEC");
goto done;
@ -734,61 +783,104 @@ cli_show_auto1(clicon_handle h,
goto done;
if (api_path2xpath(api_path, yspec, &xpath, &nsc, NULL) < 0)
goto done;
if (xpath == NULL){
clicon_err(OE_FATAL, 0, "Invalid api-path-fmt: %s", api_path_fmt);
goto done;
}
/* XXX Kludge to overcome a trailing / in show, that I cannot add to
* yang2api_path_fmt_1 where it should belong.
*/
if (xpath[strlen(xpath)-1] == '/')
if (xpath && xpath[strlen(xpath)-1] == '/')
xpath[strlen(xpath)-1] = '\0';
if (state == 0){ /* Get configuration-only from database */
if (clicon_rpc_get_config(h, NULL, db, xpath, nsc, NULL, &xt) < 0)
if (state && strcmp(db, "running") != 0){
clicon_err(OE_FATAL, 0, "Show state only for running database, not %s", db);
goto done;
}
if (state == 0){ /* Get configuration-only from a database */
if (clicon_rpc_get_config(h, NULL, db, xpath, nsc, withdefaultstr, &xt) < 0)
goto done;
}
else{ /* Get configuration and state from database */
if (strcmp(db, "running") != 0){
clicon_err(OE_FATAL, 0, "Show state only for running database, not %s", db);
goto done;
}
if (clicon_rpc_get(h, xpath, nsc, CONTENT_ALL, -1, NULL, &xt) < 0)
else { /* Get configuration and state from running */
if (clicon_rpc_get(h, xpath, nsc, CONTENT_ALL, -1, withdefaultstr, &xt) < 0)
goto done;
}
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
clixon_netconf_error(xerr, "Get configuration", NULL);
goto done;
}
if ((xp = xpath_first(xt, nsc, "%s", xpath)) != NULL){
/* Print configuration according to format */
switch (format){
case FORMAT_CLI:
if (clixon_cli2file(h, stdout, xp, prefix, cligen_output, 0) < 0) /* cli syntax */
goto done;
break;
case FORMAT_NETCONF:
fprintf(stdout, "<rpc><edit-config><target><candidate/></target><config>\n");
if (clixon_xml2file(stdout, xp, 2, 1, fprintf, 0, 1) < 0)
goto done;
fprintf(stdout, "</config></edit-config></rpc>]]>]]>\n");
break;
case FORMAT_JSON:
if (clixon_json2file(stdout, xp, 1, cligen_output, 0, 1) < 0)
goto done;
break;
case FORMAT_TEXT:
if (clixon_txt2file(stdout, xp, 0, cligen_output, 0, 1) < 0)
goto done;
break;
case FORMAT_XML:
if (clixon_xml2file(stdout, xp, 0, 1, fprintf, 0, 1) < 0)
goto done;
break;
if (xpath_vec(xt, nsc, "%s", &vec, &veclen, xpath) < 0)
goto done;
if (veclen){
xp = vec[0]; /* First peek to see if it is special case yang list */
if ((yp = xml_spec(xp)) != NULL)
ys_keyword = yang_keyword_get(xml_spec(xp));
else
ys_keyword = 0;
/* Special case LIST */
if ((ys_keyword == Y_LIST || ys_keyword == Y_LEAF_LIST) && format == FORMAT_JSON){
switch (format){
case FORMAT_JSON:
if (xml2json_vec(stdout, vec, veclen, pretty) < 0) // XXX cligen_output
goto done;
break;
default:
break;
}
}
else /* Default */
for (i=0; i<veclen; i++){
xp = vec[i];
if ((yp = xml_spec(xp)) != NULL)
ys_keyword = yang_keyword_get(xml_spec(xp));
else
ys_keyword = 0;
/* Print configuration according to format */
switch (format){
case FORMAT_XML:
if (clixon_xml2file(stdout, xp, 0, pretty, cligen_output, 0, 1) < 0)
goto done;
if (!pretty && i == veclen-1)
cligen_output(stdout, "\n");
break;
case FORMAT_JSON:
if (clixon_json2file(stdout, xp, pretty, cligen_output, 0, 1) < 0)
goto done;
break;
case FORMAT_TEXT: /* XXX does not handle multiple leaf-list */
if (clixon_txt2file(stdout, xp, 0, cligen_output, 0, 1) < 0)
goto done;
break;
case FORMAT_CLI:
if (clixon_cli2file(h, stdout, xp, prefix, cligen_output, 0) < 0) /* cli syntax */
goto done;
break;
case FORMAT_NETCONF:
if (i==0){
cligen_output(stdout, "<rpc xmlns=\"%s\" %s><edit-config><target><candidate/></target><config>",
NETCONF_BASE_NAMESPACE, NETCONF_MESSAGE_ID_ATTR);
if (pretty)
cligen_output(stdout, "\n");
}
if (clixon_xml2file(stdout, xp, 2, pretty, cligen_output, 0, 1) < 0)
goto done;
if (i == veclen-1)
cligen_output(stdout, "</config></edit-config></rpc>]]>]]>\n");
break;
}
}
}
retval = 0;
done:
if (boolcv)
cv_free(boolcv);
if (nsc)
xml_nsctx_free(nsc);
if (api_path)
free(api_path);
if (vec)
free(vec);
if (xpath)
free(xpath);
if (xt)
@ -799,9 +891,13 @@ cli_show_auto1(clicon_handle h,
/*! Generic show configuration CLIgen callback using generated CLI syntax
* Format of argv:
* <api_path_fmt> Generated API PATH
* <dbname> "running"|"candidate"|"startup"
* <format> "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
* <prefix> to print before cli syntax outptu
* <dbname> "running"|"candidate"|"startup"
* <format> "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
* <pretty> true|false: pretty-print or not (Optional)
* <state> true|false: also print state
* <default> Retrieval default mode: report-all, trim, explicit, report-all-tagged,
* report-all-tagged-default, report-all-tagged-strip (Optional)
* <prefix> To print before cli syntax outptu
* @see cli_show_auto_state For config and state
* @note SHOULD be used: ... @datamodel, cli_show_auto(<dbname>,...) to get correct #args
* @see cli_auto_show
@ -820,6 +916,9 @@ cli_show_auto(clicon_handle h,
* <api_path_fmt> Generated API PATH
* <dbname> "running"
* <format> "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
* <pretty> true|false: pretty-print or not (Optional)
* <default> Retrieval default mode: report-all, trim, explicit, report-all-tagged,
* report-all-tagged-default, report-all-tagged-strip (Optional)
* <prefix> to print before cli syntax output
* @see cli_show_auto For config only
* @see cli_show_config_state Not auto-generated