diff --git a/CHANGELOG.md b/CHANGELOG.md
index e9edfa55..c73fdc88 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,10 @@
* Example extended with inclusion of iana-if-type RFC 7224 interface identities
* Applications which have not strictly enforced the identities may now have problems with validation and may need to be modified.
### Minor changes:
+* Added a generated CLI show command that works on the generated parse tree with auto completion.
+ * A typical call is: show @datamodel:example, cli_show_auto("candidate", "json");
+ * The example contains a more elaborate example.
+ * Thanks ngashok for request, see https://github.com/clicon/clixon/issues/24
* Added xmlns validation
* for eg
* Added yang identityref runtime validation
diff --git a/apps/cli/cli_generate.c b/apps/cli/cli_generate.c
index d4a2aca9..24c52c2f 100644
--- a/apps/cli/cli_generate.c
+++ b/apps/cli/cli_generate.c
@@ -141,6 +141,7 @@ cli_expand_var_generate(clicon_handle h,
* @param[in] ys yang_stmt of the node at hand
* @param[in] cb0 The string where the result format string is inserted.
* @see cli_dbxml This is where the xmlkeyfmt string is used
+ * @see pt_callback_reference in CLIgen where the actual callback overwrites the template
*/
static int
cli_callback_generate(clicon_handle h,
diff --git a/apps/cli/cli_show.c b/apps/cli/cli_show.c
index 94a4c7c4..52821f7a 100644
--- a/apps/cli/cli_show.c
+++ b/apps/cli/cli_show.c
@@ -417,7 +417,7 @@ show_yang(clicon_handle h,
* @param[in] argv String vector: []
* Format of argv:
* "running"|"candidate"|"startup"
- * "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
+ * "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
* xpath expression, that may contain one %, eg "/sender[name=%s]"
* optional name of variable in cvv. If set, xpath must have a '%s'
* @code
@@ -600,6 +600,92 @@ int cli_show_version(clicon_handle h, cvec *vars, cvec *argv)
return 0;
}
+/*! Generic show configuration CLIGEN callback using generated CLI syntax
+ * Format of argv:
+ * Generated API PATH
+ * "running"|"candidate"|"startup"
+ * "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
+ */
+int
+cli_show_auto(clicon_handle h,
+ cvec *cvv,
+ cvec *argv)
+{
+ int retval = 1;
+ yang_spec *yspec;
+ char *api_path_fmt; /* xml key format */
+ // char *api_path = NULL; /* xml key */
+ char *db;
+ char *xpath;
+ char *formatstr;
+ enum format_enum format = FORMAT_XML;
+ cxobj *xt = NULL;
+ cxobj *xp;
+ cxobj *xerr;
+ enum genmodel_type gt;
+
+ if (cvec_len(argv) != 3){
+ clicon_err(OE_PLUGIN, 0, "%s: Usage: * . (*) generated.", __FUNCTION__);
+ goto done;
+ }
+ /* First argv argument: API_path format */
+ api_path_fmt = cv_string_get(cvec_i(argv, 0));
+ /* Second argv argument: Database */
+ db = cv_string_get(cvec_i(argv, 1));
+ /* Third format: output format */
+ formatstr = cv_string_get(cvec_i(argv, 2));
+ if ((format = format_str2int(formatstr)) < 0){
+ clicon_err(OE_PLUGIN, 0, "Not valid format: %s", formatstr);
+ goto done;
+ }
+ if ((yspec = clicon_dbspec_yang(h)) == NULL){
+ clicon_err(OE_FATAL, 0, "No DB_SPEC");
+ goto done;
+ }
+
+ // if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path) < 0)
+ // goto done;
+ if (api_path_fmt2xpath(api_path_fmt, cvv, &xpath) < 0)
+ goto done;
+ /* Get configuration from database */
+ if (clicon_rpc_get_config(h, db, xpath, &xt) < 0)
+ goto done;
+ if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
+ clicon_rpc_generate_error("Get configuration", xerr);
+ goto done;
+ }
+ if ((xp = xpath_first(xt, xpath)) != NULL)
+ /* Print configuration according to format */
+ switch (format){
+ case FORMAT_XML:
+ clicon_xml2file(stdout, xp, 0, 1);
+ break;
+ case FORMAT_JSON:
+ xml2json(stdout, xp, 1);
+ break;
+ case FORMAT_TEXT:
+ xml2txt(stdout, xp, 0); /* tree-formed text */
+ break;
+ case FORMAT_CLI:
+ if ((gt = clicon_cli_genmodel_type(h)) == GT_ERR)
+ goto done;
+ xml2cli(stdout, xp, NULL, gt); /* cli syntax */
+ break;
+ case FORMAT_NETCONF:
+ fprintf(stdout, "\n");
+ clicon_xml2file(stdout, xp, 2, 1);
+ fprintf(stdout, "]]>]]>\n");
+ break;
+ default: /* see cli_show_config() */
+ break;
+ }
+ retval = 0;
+ done:
+ if (xt)
+ xml_free(xt);
+ return retval;
+}
+
#ifdef COMPAT_CLIV
int show_yangv(clicon_handle h, cvec *vars, cvec *argv)
{
diff --git a/apps/cli/clixon_cli_api.h b/apps/cli/clixon_cli_api.h
index 713ea521..c31645ba 100644
--- a/apps/cli/clixon_cli_api.h
+++ b/apps/cli/clixon_cli_api.h
@@ -142,6 +142,8 @@ int show_conf_xpath(clicon_handle h, cvec *cvv, cvec *argv);
int cli_show_config(clicon_handle h, cvec *cvv, cvec *argv);
+int cli_show_auto(clicon_handle h, cvec *cvv, cvec *argv);
+
#ifdef COMPAT_CLIV
int cli_setv(clicon_handle h, cvec *vars, cvec *argv);
int cli_mergev(clicon_handle h, cvec *vars, cvec *argv);
diff --git a/example/example_cli.cli b/example/example_cli.cli
index 8853aed2..1040f834 100644
--- a/example/example_cli.cli
+++ b/example/example_cli.cli
@@ -42,13 +42,16 @@ show("Show a particular state of the system"){
xml("Show configuration as XML"), cli_show_config("candidate", "xml", "/");{
@datamodel:example, cli_show_auto("candidate", "text");
}
+ cli("Show configuration as CLI commands"), cli_show_config("candidate", "cli", "/");{
+ @datamodel:example, cli_show_auto("candidate", "cli");
+ }
netconf("Show configuration as netconf edit-config operation"), cli_show_config("candidate", "netconf", "/");{
@datamodel:example, cli_show_auto("candidate", "netconf");
}
text("Show configuration as text"), cli_show_config("candidate","text","/");{
@datamodel:example, cli_show_auto("candidate", "text");
}
- json("Show configuration as cli commands"), cli_show_config("candidate", "json", "/");{
+ json("Show configuration as JSON"), cli_show_config("candidate", "json", "/");{
@datamodel:example, cli_show_auto("candidate", "json");
}
}