* 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
This commit is contained in:
Olof hagsand 2018-06-05 16:45:43 +02:00
parent 0ad6703663
commit c5991c9844
5 changed files with 98 additions and 2 deletions

View file

@ -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 <a xmlns:x="uri"><x:b/></a>
* Added yang identityref runtime validation

View file

@ -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,

View file

@ -417,7 +417,7 @@ show_yang(clicon_handle h,
* @param[in] argv String vector: <dbname> <format> <xpath> [<varname>]
* Format of argv:
* <dbname> "running"|"candidate"|"startup"
* <dbname> "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
* <format> "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
* <xpath> xpath expression, that may contain one %, eg "/sender[name=%s]"
* <varname> 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:
* <api_path_fmt> Generated API PATH
* <dbname> "running"|"candidate"|"startup"
* <format> "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: <api-path-fmt>* <database> <format>. (*) 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, "<rpc><edit-config><target><candidate/></target><config>\n");
clicon_xml2file(stdout, xp, 2, 1);
fprintf(stdout, "</config></edit-config></rpc>]]>]]>\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)
{

View file

@ -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);

View file

@ -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");
}
}