With-defaults CLI support

Extended cli_auto_show() with with-defaults argument, also changing its signature
Example: Added with-defaults argument to clispec
C-API: Added with-defaults argument to clicon_rpc_get_config
Replaced with-defaults prefix/namespace with constants
This commit is contained in:
Olof hagsand 2022-09-09 12:30:57 +02:00
parent 42d5b6fba2
commit 743076b171
23 changed files with 256 additions and 56 deletions

View file

@ -413,7 +413,6 @@ element2value(clicon_handle h,
* @param[in] x XML node * @param[in] x XML node
* @param[in] flag Flag to be used * @param[in] flag Flag to be used
* @retval 0 OK * @retval 0 OK
*/ */
static int static int
xml_flag_default_value(cxobj *x, xml_flag_default_value(cxobj *x,
@ -464,11 +463,11 @@ xml_add_default_tag(cxobj *x,
goto done; goto done;
if (xml_value_set(xattr, "true") < 0) if (xml_value_set(xattr, "true") < 0)
goto done; goto done;
if (xml_prefix_set(xattr, "wd") < 0) if (xml_prefix_set(xattr, IETF_NETCONF_WITH_DEFAULTS_ATTR_PREFIX) < 0)
goto done; goto done;
} }
retval = 0; retval = 0;
done: done:
return retval; return retval;
} }
@ -478,7 +477,6 @@ xml_add_default_tag(cxobj *x,
* @retval 0 OK * @retval 0 OK
* @retval -1 Error * @retval -1 Error
*/ */
static int static int
with_defaults(cxobj *xe, with_defaults(cxobj *xe,
cxobj *xret) cxobj *xret)
@ -506,7 +504,7 @@ with_defaults(cxobj *xe,
goto done; goto done;
goto ok; goto ok;
} }
if (strcmp(mode, "trim") == 0) { else if (strcmp(mode, "trim") == 0) {
/* Remove default nodes from XML */ /* Remove default nodes from XML */
if (xml_tree_prune_flags(xret, XML_FLAG_DEFAULT, XML_FLAG_DEFAULT) < 0) if (xml_tree_prune_flags(xret, XML_FLAG_DEFAULT, XML_FLAG_DEFAULT) < 0)
goto done; goto done;
@ -521,8 +519,8 @@ with_defaults(cxobj *xe,
goto done; goto done;
goto ok; goto ok;
} }
if (strcmp(mode, "report-all-tagged") == 0) { else if (strcmp(mode, "report-all-tagged") == 0) {
if (xmlns_set(xret, "wd", "urn:ietf:params:xml:ns:netconf:default:1.0") < 0) if (xmlns_set(xret, IETF_NETCONF_WITH_DEFAULTS_ATTR_PREFIX, IETF_NETCONF_WITH_DEFAULTS_ATTR_NAMESPACE) < 0)
goto done; goto done;
/* Mark nodes having default schema values */ /* Mark nodes having default schema values */
if (xml_apply(xret, CX_ELMNT, (xml_applyfn_t*) xml_flag_default_value, (void*) XML_FLAG_MARK) < 0) if (xml_apply(xret, CX_ELMNT, (xml_applyfn_t*) xml_flag_default_value, (void*) XML_FLAG_MARK) < 0)
@ -532,7 +530,7 @@ with_defaults(cxobj *xe,
goto done; goto done;
goto ok; goto ok;
} }
if (strcmp(mode, "report-all") == 0) { else if (strcmp(mode, "report-all") == 0) {
/* Accept mode, do nothing */ /* Accept mode, do nothing */
goto ok; goto ok;
} }

View file

@ -347,8 +347,14 @@ cli_auto_top(clicon_handle h,
* <format> "text"|"xml"|"json"|"cli"|"netconf" (see format_enum) * <format> "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
* <pretty> true|false: pretty-print or not * <pretty> true|false: pretty-print or not
* <state> true|false: pretty-print or not * <state> true|false: pretty-print or not
* <prefix> to print before cli syntax output * <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
* @see cli_show_auto * @see cli_show_auto
* @note default mods accorsing to RFC6243 + two extra modes based on report-all-tagged:
* report-all-tagged-default Strip "default" attribute (=report-all xxx)
* report-all-tagged-strip Strip "default" attribute and all nodes tagged with it (=trim)
* XXX Merge with cli_show_auto
*/ */
int int
cli_auto_show(clicon_handle h, cli_auto_show(clicon_handle h,
@ -376,9 +382,11 @@ cli_auto_show(clicon_handle h,
char *prefix = NULL; char *prefix = NULL;
int state; int state;
cg_var *boolcv = NULL; cg_var *boolcv = NULL;
char *defaultstr = NULL; /* with extended tagged modes */
char *withdefaultstr = NULL; /* RFC 6243 modes */
if (cvec_len(argv) != 5 && cvec_len(argv) != 6){ if (cvec_len(argv) < 5 || cvec_len(argv) > 7){
clicon_err(OE_PLUGIN, EINVAL, "Usage: <treename> <database> <format> <pretty> <state> [<prefix>]."); clicon_err(OE_PLUGIN, EINVAL, "Usage: <treename> <database> <format> <pretty> <state> [<default> <cli-prefix>].");
goto done; goto done;
} }
/* First argv argument: treename */ /* First argv argument: treename */
@ -407,10 +415,27 @@ cli_auto_show(clicon_handle h,
goto done; goto done;
} }
state = cv_bool_get(boolcv); state = cv_bool_get(boolcv);
/* Sixth: default */
/* Sixth: prefix */ if (cvec_len(argv) > 5) {
if (cvec_len(argv) == 6) { defaultstr = cv_string_get(cvec_i(argv, 5));
prefix = 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;
}
/* Seventh: cli prefix */
if (cvec_len(argv) > 6) {
prefix = cv_string_get(cvec_i(argv, 6));
} }
if ((yspec = clicon_dbspec_yang(h)) == NULL){ if ((yspec = clicon_dbspec_yang(h)) == NULL){
clicon_err(OE_FATAL, 0, "No DB_SPEC"); clicon_err(OE_FATAL, 0, "No DB_SPEC");
@ -428,22 +453,31 @@ cli_auto_show(clicon_handle h,
if (api_path2xpath(api_path, yspec, &xpath, &nsc, NULL) < 0) if (api_path2xpath(api_path, yspec, &xpath, &nsc, NULL) < 0)
goto done; goto done;
skiproot = (xpath != NULL) && (strcmp(xpath,"/") != 0); skiproot = (xpath != NULL) && (strcmp(xpath,"/") != 0);
if (state == 0){ /* Get configuration-only from database */ if (state && strcmp(db, "running") != 0){
if (clicon_rpc_get_config(h, NULL, db, xpath, nsc, &xt) < 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; goto done;
} }
else { /* Get configuration and state from database */ else { /* Get configuration and state from running */
if (strcmp(db, "running") != 0){ if (clicon_rpc_get(h, xpath, nsc, CONTENT_ALL, -1, withdefaultstr, &xt) < 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)
goto done; goto done;
} }
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){ if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
clixon_netconf_error(xerr, "Get configuration", NULL); clixon_netconf_error(xerr, "Get configuration", NULL);
goto done; goto done;
} }
/* Special tagged modes: strip wd:default=true attribute and (optionally) nodes associated with it */
if (defaultstr &&
(strcmp(defaultstr, "report-all-tagged-strip") == 0 ||
strcmp(defaultstr, "report-all-tagged-default") == 0)){
if (purge_tagged_nodes(xt, IETF_NETCONF_WITH_DEFAULTS_ATTR_NAMESPACE, "default", "true",
strcmp(defaultstr, "report-all-tagged-strip")
) < 0)
goto done;
}
if (xpath_vec(xt, nsc, "%s", &vec, &veclen, xpath) < 0) if (xpath_vec(xt, nsc, "%s", &vec, &veclen, xpath) < 0)
goto done; goto done;

View file

@ -772,13 +772,13 @@ compare_dbs(clicon_handle h,
format = FORMAT_TEXT; format = FORMAT_TEXT;
else else
format = FORMAT_XML; format = FORMAT_XML;
if (clicon_rpc_get_config(h, NULL, "running", "/", NULL, &xc1) < 0) if (clicon_rpc_get_config(h, NULL, "running", "/", NULL, NULL, &xc1) < 0)
goto done; goto done;
if ((xerr = xpath_first(xc1, NULL, "/rpc-error")) != NULL){ if ((xerr = xpath_first(xc1, NULL, "/rpc-error")) != NULL){
clixon_netconf_error(xerr, "Get configuration", NULL); clixon_netconf_error(xerr, "Get configuration", NULL);
goto done; goto done;
} }
if (clicon_rpc_get_config(h, NULL, "candidate", "/", NULL, &xc2) < 0) if (clicon_rpc_get_config(h, NULL, "candidate", "/", NULL, NULL, &xc2) < 0)
goto done; goto done;
if ((xerr = xpath_first(xc2, NULL, "/rpc-error")) != NULL){ if ((xerr = xpath_first(xc2, NULL, "/rpc-error")) != NULL){
clixon_netconf_error(xerr, "Get configuration", NULL); clixon_netconf_error(xerr, "Get configuration", NULL);
@ -1028,7 +1028,7 @@ save_config_file(clicon_handle h,
goto done; goto done;
} }
filename = cv_string_get(cv); filename = cv_string_get(cv);
if (clicon_rpc_get_config(h, NULL, dbstr,"/", NULL, &xt) < 0) if (clicon_rpc_get_config(h, NULL, dbstr,"/", NULL, NULL, &xt) < 0)
goto done; goto done;
if (xt == NULL){ if (xt == NULL){
clicon_err(OE_CFG, 0, "get config: empty tree"); /* Shouldnt happen */ clicon_err(OE_CFG, 0, "get config: empty tree"); /* Shouldnt happen */
@ -1396,7 +1396,7 @@ cli_copy_config(clicon_handle h,
if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL) if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL)
goto done; goto done;
/* Get from object configuration and store in x1 */ /* Get from object configuration and store in x1 */
if (clicon_rpc_get_config(h, NULL, db, cbuf_get(cb), nsc, &x1) < 0) if (clicon_rpc_get_config(h, NULL, db, cbuf_get(cb), nsc, NULL, &x1) < 0)
goto done; goto done;
if ((xerr = xpath_first(x1, NULL, "/rpc-error")) != NULL){ if ((xerr = xpath_first(x1, NULL, "/rpc-error")) != NULL){
clixon_netconf_error(xerr, "Get configuration", NULL); clixon_netconf_error(xerr, "Get configuration", NULL);

View file

@ -315,7 +315,7 @@ expand_dbvar(void *h,
goto done; goto done;
} }
/* Get configuration based on cbxpath */ /* Get configuration based on cbxpath */
if (clicon_rpc_get_config(h, NULL, dbstr, cbuf_get(cbxpath), nsc, &xt) < 0) if (clicon_rpc_get_config(h, NULL, dbstr, cbuf_get(cbxpath), nsc, NULL, &xt) < 0)
goto done; goto done;
if ((xe = xpath_first(xt, NULL, "/rpc-error")) != NULL){ if ((xe = xpath_first(xt, NULL, "/rpc-error")) != NULL){
clixon_netconf_error(xe, "Get configuration", NULL); clixon_netconf_error(xe, "Get configuration", NULL);
@ -476,7 +476,7 @@ cli_show_config1(clicon_handle h,
prefix = cv_string_get(cvec_i(argv, 4)); prefix = cv_string_get(cvec_i(argv, 4));
} }
if (state == 0){ /* Get configuration-only from database */ if (state == 0){ /* Get configuration-only from database */
if (clicon_rpc_get_config(h, NULL, db, cbuf_get(cbxpath), nsc, &xt) < 0) if (clicon_rpc_get_config(h, NULL, db, cbuf_get(cbxpath), nsc, NULL, &xt) < 0)
goto done; goto done;
} }
else { /* Get configuration and state from database */ else { /* Get configuration and state from database */
@ -637,7 +637,7 @@ show_conf_xpath(clicon_handle h,
if (clicon_rpc_get(h, xpath, nsc, CONTENT_ALL, -1, &xt) < 0) if (clicon_rpc_get(h, xpath, nsc, CONTENT_ALL, -1, &xt) < 0)
goto done; goto done;
#else #else
if (clicon_rpc_get_config(h, NULL, dbname, xpath, nsc, &xt) < 0) if (clicon_rpc_get_config(h, NULL, dbname, xpath, nsc, NULL, &xt) < 0)
goto done; goto done;
#endif #endif
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){ if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
@ -741,7 +741,7 @@ cli_show_auto1(clicon_handle h,
xpath[strlen(xpath)-1] = '\0'; xpath[strlen(xpath)-1] = '\0';
if (state == 0){ /* Get configuration-only from database */ if (state == 0){ /* Get configuration-only from database */
if (clicon_rpc_get_config(h, NULL, db, xpath, nsc, &xt) < 0) if (clicon_rpc_get_config(h, NULL, db, xpath, nsc, NULL, &xt) < 0)
goto done; goto done;
} }
else{ /* Get configuration and state from database */ else{ /* Get configuration and state from database */

View file

@ -181,7 +181,7 @@ restconf_main_config(clicon_handle h,
clicon_err(OE_UNIX, errno, "getpwuid"); clicon_err(OE_UNIX, errno, "getpwuid");
goto done; goto done;
} }
if (clicon_rpc_get_config(h, pw->pw_name, "running", "/restconf", nsc, &xconfig) < 0) if (clicon_rpc_get_config(h, pw->pw_name, "running", "/restconf", nsc, NULL, &xconfig) < 0)
goto done; goto done;
if ((xerr = xpath_first(xconfig, NULL, "/rpc-error")) != NULL){ if ((xerr = xpath_first(xconfig, NULL, "/rpc-error")) != NULL){
clixon_netconf_error(xerr, "Get backend restconf config", NULL); clixon_netconf_error(xerr, "Get backend restconf config", NULL);

View file

@ -670,7 +670,7 @@ restconf_clixon_backend(clicon_handle h,
goto done; goto done;
} }
/* XXX xconfig leaked */ /* XXX xconfig leaked */
if (clicon_rpc_get_config(h, pw->pw_name, "running", "/restconf", nsc, &xconfig) < 0) if (clicon_rpc_get_config(h, pw->pw_name, "running", "/restconf", nsc, NULL, &xconfig) < 0)
goto done; goto done;
if ((xerr = xpath_first(xconfig, NULL, "/rpc-error")) != NULL){ if ((xerr = xpath_first(xconfig, NULL, "/rpc-error")) != NULL){
clixon_netconf_error(xerr, "Get backend restconf config", NULL); clixon_netconf_error(xerr, "Get backend restconf config", NULL);

View file

@ -71,7 +71,7 @@ mycallback(clicon_handle h, cvec *cvv, cvec *argv)
/* Show eth0 interfaces config using XPATH */ /* Show eth0 interfaces config using XPATH */
if (clicon_rpc_get_config(h, NULL, "running", if (clicon_rpc_get_config(h, NULL, "running",
"/interfaces/interface[name='eth0']", "/interfaces/interface[name='eth0']",
nsc, nsc, NULL,
&xret) < 0) &xret) < 0)
goto done; goto done;
if (clixon_xml2file(stdout, xret, 0, 1, cligen_output, 0, 1) < 0) if (clixon_xml2file(stdout, xret, 0, 1, cligen_output, 0, 1) < 0)

View file

@ -83,16 +83,35 @@ show("Show a particular state of the system"){
cli, cli_pagination("use xpath var", "es", "http://example.com/ns/example-social", "cli", "10"); cli, cli_pagination("use xpath var", "es", "http://example.com/ns/example-social", "cli", "10");
text, cli_pagination("use xpath var", "es", "http://example.com/ns/example-social", "text", "10"); text, cli_pagination("use xpath var", "es", "http://example.com/ns/example-social", "text", "10");
json, cli_pagination("use xpath var", "es", "http://example.com/ns/example-social", "json", "10"); json, cli_pagination("use xpath var", "es", "http://example.com/ns/example-social", "json", "10");
} }
configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{ configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{
xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", true, false); xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", true, false);{
cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", true, false, "set "); default("With-default mode"){
report-all, cli_auto_show("datamodel", "candidate", "xml", true, false, "report-all");
trim, cli_auto_show("datamodel", "candidate", "xml", true, false, "trim");
explicit, cli_auto_show("datamodel", "candidate", "xml", true, false, "explicit");
report-all-tagged, cli_auto_show("datamodel", "candidate", "xml", true, false, "report-all-tagged");
report-all-tagged-default, cli_auto_show("datamodel", "candidate", "xml", true, false, "report-all-tagged-default");
report-all-tagged-strip, cli_auto_show("datamodel", "candidate", "xml", true, false, "report-all-tagged-strip");
}
}
cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", true, false, "explicit", "set ");
netconf("Show configuration as netconf edit-config operation"), cli_auto_show("datamodel", "candidate", "netconf", true, false); netconf("Show configuration as netconf edit-config operation"), cli_auto_show("datamodel", "candidate", "netconf", true, false);
text("Show configuration as text"), cli_auto_show("datamodel", "candidate", "text", true, false); text("Show configuration as text"), cli_auto_show("datamodel", "candidate", "text", true, false);
json("Show configuration as JSON"), cli_auto_show("datamodel", "candidate", "json", true, false); json("Show configuration as JSON"), cli_auto_show("datamodel", "candidate", "json", true, false);
} }
state("Show configuration and state"), cli_auto_show("datamodel", "running", "text", true, true); { state("Show configuration and state"), cli_auto_show("datamodel", "running", "text", true, true); {
xml("Show configuration and state as XML"), cli_auto_show("datamodel", "running", "xml", true, true); xml("Show configuration and state as XML"), cli_auto_show("datamodel", "running", "xml", true, true);{
default("With-default mode"){
report-all, cli_auto_show("datamodel", "running", "xml", true, true, "report-all");
trim, cli_auto_show("datamodel", "running", "xml", true, true, "trim");
explicit, cli_auto_show("datamodel", "running", "xml", true, true, "explicit");
report-all-tagged, cli_auto_show("datamodel", "running", "xml", true, true, "report-all-tagged");
report-all-tagged-default, cli_auto_show("datamodel", "running", "xml", true, true, "report-all-tagged-default");
report-all-tagged-strip, cli_auto_show("datamodel", "running", "xml", true, true, "report-all-tagged-strip");
}
}
} }
yang("Show yang specs"), show_yang(); { yang("Show yang specs"), show_yang(); {
clixon-example("Show clixon-example yang spec"), show_yang("clixon-example"); clixon-example("Show clixon-example yang spec"), show_yang("clixon-example");

View file

@ -47,7 +47,7 @@ int clicon_rpc_msg(clicon_handle h, struct clicon_msg *msg, cxobj **xret0);
int clicon_rpc_msg_persistent(clicon_handle h, struct clicon_msg *msg, cxobj **xret0, int *sock0); int clicon_rpc_msg_persistent(clicon_handle h, struct clicon_msg *msg, cxobj **xret0, int *sock0);
int clicon_rpc_netconf(clicon_handle h, char *xmlst, cxobj **xret, int *sp); int clicon_rpc_netconf(clicon_handle h, char *xmlst, cxobj **xret, int *sp);
int clicon_rpc_netconf_xml(clicon_handle h, cxobj *xml, cxobj **xret, int *sp); int clicon_rpc_netconf_xml(clicon_handle h, cxobj *xml, cxobj **xret, int *sp);
int clicon_rpc_get_config(clicon_handle h, char *username, char *db, char *xpath, cvec *nsc, cxobj **xret); int clicon_rpc_get_config(clicon_handle h, char *username, char *db, char *xpath, cvec *nsc, char *defaults, cxobj **xret);
int clicon_rpc_edit_config(clicon_handle h, char *db, enum operation_type op, int clicon_rpc_edit_config(clicon_handle h, char *db, enum operation_type op,
char *xml); char *xml);
int clicon_rpc_copy_config(clicon_handle h, char *db1, char *db2); int clicon_rpc_copy_config(clicon_handle h, char *db1, char *db2);

View file

@ -65,6 +65,16 @@
*/ */
#define IETF_PAGINATON_NC_NAMESPACE "urn:ietf:params:xml:ns:yang:ietf-list-pagination-nc" #define IETF_PAGINATON_NC_NAMESPACE "urn:ietf:params:xml:ns:yang:ietf-list-pagination-nc"
/* RFC 6243 With-defaults Capability for NETCONF
* ietf-netconf-with-defaults
* First in use in get requests
*/
#define IETF_NETCONF_WITH_DEFAULTS_YANG_NAMESPACE "urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults"
/* Second in use in by replies for tagged attributes */
#define IETF_NETCONF_WITH_DEFAULTS_ATTR_NAMESPACE "urn:ietf:params:xml:ns:netconf:default:1.0"
#define IETF_NETCONF_WITH_DEFAULTS_ATTR_PREFIX "wd"
/* Output symbol for netconf get/get-config /* Output symbol for netconf get/get-config
* ietf-netconf.yang defines it as output: * ietf-netconf.yang defines it as output:
* output { anyxml data; * output { anyxml data;

View file

@ -77,5 +77,6 @@ int xml_copy_marked(cxobj *x0, cxobj *x1);
int yang_check_when_xpath(cxobj *xn, cxobj *xp, yang_stmt *yn, int *hit, int *nrp, char **xpathp); int yang_check_when_xpath(cxobj *xn, cxobj *xp, yang_stmt *yn, int *hit, int *nrp, char **xpathp);
int xml_rpc_isaction(cxobj *xn); int xml_rpc_isaction(cxobj *xn);
int xml_find_action(cxobj *xn, int top, cxobj **xap); int xml_find_action(cxobj *xn, int top, cxobj **xap);
int purge_tagged_nodes(cxobj *xn, char *ns, char *name, char *value, int keepnode);
#endif /* _CLIXON_XML_MAP_H_ */ #endif /* _CLIXON_XML_MAP_H_ */

View file

@ -921,7 +921,7 @@ nacm_datanode_read_recurse(clicon_handle h,
if (xml_flag(x, XML_FLAG_DEL)){ if (xml_flag(x, XML_FLAG_DEL)){
if (xml_purge(x) < 0) if (xml_purge(x) < 0)
goto done; goto done;
x = xprev; x = xprev;
} }
} }
} }

View file

@ -457,7 +457,8 @@ clicon_rpc_netconf_xml(clicon_handle h,
* @param[in] username If NULL, use default * @param[in] username If NULL, use default
* @param[in] db Name of database * @param[in] db Name of database
* @param[in] xpath XPath (or "") * @param[in] xpath XPath (or "")
* @param[in] nsc Namespace context for filter * @param[in] nsc Namespace context for filter
* @param[in] defaults Value of the with-defaults mode, rfc6243, or NULL
* @param[out] xt XML tree. Free with xml_free. * @param[out] xt XML tree. Free with xml_free.
* Either <config> or <rpc-error>. * Either <config> or <rpc-error>.
* @retval 0 OK * @retval 0 OK
@ -468,7 +469,7 @@ clicon_rpc_netconf_xml(clicon_handle h,
* *
* if ((nsc = xml_nsctx_init(NULL, "urn:example:hello")) == NULL) * if ((nsc = xml_nsctx_init(NULL, "urn:example:hello")) == NULL)
* err; * err;
* if (clicon_rpc_get_config(h, NULL, "running", "/hello/world", nsc, &xt) < 0) * if (clicon_rpc_get_config(h, NULL, "running", "/hello/world", nsc, "explicit", &xt) < 0)
* err; * err;
* if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){ * if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
* clixon_netconf_error(xerr, "msg", "/hello/world"); * clixon_netconf_error(xerr, "msg", "/hello/world");
@ -489,6 +490,7 @@ clicon_rpc_get_config(clicon_handle h,
char *db, char *db,
char *xpath, char *xpath,
cvec *nsc, cvec *nsc,
char *defaults,
cxobj **xt) cxobj **xt)
{ {
int retval = -1; int retval = -1;
@ -523,6 +525,10 @@ clicon_rpc_get_config(clicon_handle h,
goto done; goto done;
cprintf(cb, "/>"); cprintf(cb, "/>");
} }
if (defaults != NULL)
cprintf(cb, "<with-defaults xmlns=\"%s\">%s</with-defaults>",
IETF_NETCONF_WITH_DEFAULTS_YANG_NAMESPACE,
defaults);
cprintf(cb, "</get-config></rpc>"); cprintf(cb, "</get-config></rpc>");
if ((msg = clicon_msg_encode(session_id, "%s", cbuf_get(cb))) == NULL) if ((msg = clicon_msg_encode(session_id, "%s", cbuf_get(cb))) == NULL)
goto done; goto done;
@ -910,7 +916,9 @@ clicon_rpc_get(clicon_handle h,
cprintf(cb, "/>"); cprintf(cb, "/>");
} }
if (defaults != NULL) if (defaults != NULL)
cprintf(cb, "<with-defaults xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\">%s</with-defaults>", defaults); cprintf(cb, "<with-defaults xmlns=\"%s\">%s</with-defaults>",
IETF_NETCONF_WITH_DEFAULTS_YANG_NAMESPACE,
defaults);
cprintf(cb, "</get></rpc>"); cprintf(cb, "</get></rpc>");
if ((msg = clicon_msg_encode(session_id, if ((msg = clicon_msg_encode(session_id,
"%s", cbuf_get(cb))) == NULL) "%s", cbuf_get(cb))) == NULL)

View file

@ -1367,7 +1367,7 @@ xml_wrap(cxobj *xc,
* @param[in] xc xml child node (to be removed and freed) * @param[in] xc xml child node (to be removed and freed)
* @retval 0 OK * @retval 0 OK
* @retval -1 * @retval -1
* @note you cannot remove xchild in the loop (unless yoy keep track of xprev) * @note you cannot remove xchild in the loop (unless you keep track of xprev)
* @note Linear complexity - use xml_child_rm if possible * @note Linear complexity - use xml_child_rm if possible
* @see xml_free Free, dont remove from parent * @see xml_free Free, dont remove from parent
* @see xml_child_rm Remove if child order is known (does not free) * @see xml_child_rm Remove if child order is known (does not free)
@ -1500,6 +1500,7 @@ xml_rm_children(cxobj *xp,
return retval; return retval;
} }
/*! Remove top XML object and all children except a single child /*! Remove top XML object and all children except a single child
* Given a root xml node, and the i:th child, remove the child from its parent * Given a root xml node, and the i:th child, remove the child from its parent
* and return it, remove the parent and all other children. (unwrap) * and return it, remove the parent and all other children. (unwrap)

View file

@ -2218,3 +2218,52 @@ xml_find_action(cxobj *xn,
done: done:
return retval; return retval;
} }
/*! Utility function: recursive traverse an XML tree and remove nodes based on attribute value
* Conditionally remove attribute and node
* @param[in] xn XML node
* @param[in] ns Namespace of attribute
* @param[in] name Attribute name
* @param[in] value Attribute value
* @param[in] keepnode 0: remove node associated with attribute; 1: keep node but remove attr
*/
int
purge_tagged_nodes(cxobj *xn,
char *ns,
char *name,
char *value,
int keepnode)
{
int retval = -1;
cxobj *x;
cxobj *xa;
cxobj *xprev;
char *prefix;
char *v;
int ret;
x = NULL;
xprev = NULL;
while ((x = xml_child_each(xn, x, CX_ELMNT)) != NULL) {
if ((ret = xml2prefix(x, ns, &prefix)) < 0)
goto done;
if (ret == 0)
continue;
if ((xa = xml_find_type(x, prefix, "default", CX_ATTR)) != NULL){
if (!keepnode &&
(v = xml_value(xa)) != NULL &&
strcmp(v, value) == 0){
xml_purge(x);
x = xprev;
continue;
}
xml_purge(xa); /* remove attribute regardless */
}
if (purge_tagged_nodes(x, ns, name, value, keepnode) < 0)
goto done;
xprev = x;
}
retval = 0;
done:
return retval;
}

View file

@ -82,7 +82,7 @@ quit("Quit"), cli_quit();
show("Show a particular state of the system"){ show("Show a particular state of the system"){
configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{ configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{
xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", false, false); xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", false, false);
cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", false, false, "set "); cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", false, false, "report-all", "set ");
netconf("Show configuration as netconf edit-config operation"), cli_auto_show("datamodel", "candidate", "netconf", false, false); netconf("Show configuration as netconf edit-config operation"), cli_auto_show("datamodel", "candidate", "netconf", false, false);
text("Show configuration as text"), cli_auto_show("datamodel", "candidate", "text", false, false); text("Show configuration as text"), cli_auto_show("datamodel", "candidate", "text", false, false);
json("Show configuration as JSON"), cli_auto_show("datamodel", "candidate", "json", false, false); json("Show configuration as JSON"), cli_auto_show("datamodel", "candidate", "json", false, false);

View file

@ -81,7 +81,7 @@ quit("Quit"), cli_quit();
show("Show a particular state of the system"){ show("Show a particular state of the system"){
configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{ configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{
xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", false, false); xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", false, false);
cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", false, false, "set "); cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", false, false, "report-all", "set ");
netconf("Show configuration as netconf edit-config operation"), cli_auto_show("datamodel", "candidate", "netconf", false, false); netconf("Show configuration as netconf edit-config operation"), cli_auto_show("datamodel", "candidate", "netconf", false, false);
text("Show configuration as text"), cli_auto_show("datamodel", "candidate", "text", false, false); text("Show configuration as text"), cli_auto_show("datamodel", "candidate", "text", false, false);
json("Show configuration as JSON"), cli_auto_show("datamodel", "candidate", "json", false, false); json("Show configuration as JSON"), cli_auto_show("datamodel", "candidate", "json", false, false);

View file

@ -201,7 +201,7 @@ discard("Discard edits (rollback 0)"), discard_changes();
show("Show a particular state of the system"){ show("Show a particular state of the system"){
configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{ configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{
cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", true, false, "set "); cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", true, false, "report-all", "set ");
xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", true, false, NULL); xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", true, false, NULL);
} }
} }

View file

@ -134,9 +134,9 @@ show("Show a particular state of the system"){
text("Show comparison in text"), compare_dbs((int32)1); text("Show comparison in text"), compare_dbs((int32)1);
} }
configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{ configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{
cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", true, false, "set "); cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", true, false, "report-all", "set ");
xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", true, false, "set "); xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", true, false);
text("Show configuration as TEXT"), cli_auto_show("datamodel", "candidate", "text", true, false, "set "); text("Show configuration as TEXT"), cli_auto_show("datamodel", "candidate", "text", true, false);
} }
} }
save("Save candidate configuration to XML file") <filename:string>("Filename (local filename)"), save_config_file("candidate","filename", "xml"){ save("Save candidate configuration to XML file") <filename:string>("Filename (local filename)"), save_config_file("candidate","filename", "xml"){

View file

@ -167,7 +167,7 @@ delete("Delete a configuration item") {
show("Show a particular state of the system"){ show("Show a particular state of the system"){
configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{ configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{
cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", true, false, "set "); cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", true, false, "report-all", "set ");
} }
} }
validate("Validate changes"), cli_validate(); validate("Validate changes"), cli_validate();

View file

@ -108,7 +108,7 @@ show("Show a particular state of the system"){
text("Show comparison in text"), compare_dbs((int32)1); text("Show comparison in text"), compare_dbs((int32)1);
} }
configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{ configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{
cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", true, false, "set "); cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", true, false, "report-all", "set ");
xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", true, false, "set "); xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", true, false, "set ");
text("Show configuration as TEXT"), cli_auto_show("datamodel", "candidate", "text", true, false, "set "); text("Show configuration as TEXT"), cli_auto_show("datamodel", "candidate", "text", true, false, "set ");
} }

View file

@ -58,7 +58,6 @@ cat <<EOF > $cfg
<CLICON_FEATURE>ietf-netconf:startup</CLICON_FEATURE> <CLICON_FEATURE>ietf-netconf:startup</CLICON_FEATURE>
<CLICON_YANG_DIR>${YANG_INSTALLDIR}</CLICON_YANG_DIR> <CLICON_YANG_DIR>${YANG_INSTALLDIR}</CLICON_YANG_DIR>
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE> <CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR> <CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
<CLICON_BACKEND_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP> <CLICON_BACKEND_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP>
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR> <CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
@ -216,7 +215,7 @@ quit("Quit"), cli_quit();
show("Show a particular state of the system"){ show("Show a particular state of the system"){
configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{ configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{
xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", true, false); xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", true, false);
cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", false, false, "set "); cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", false, false, "report-all", "set ");
netconf("Show configuration as netconf edit-config operation"), cli_auto_show("datamodel", "candidate", "netconf", false, false); netconf("Show configuration as netconf edit-config operation"), cli_auto_show("datamodel", "candidate", "netconf", false, false);
text("Show configuration as text"), cli_auto_show("datamodel", "candidate", "text", false, false); text("Show configuration as text"), cli_auto_show("datamodel", "candidate", "text", false, false);
json("Show configuration as JSON"), cli_auto_show("datamodel", "candidate", "json", false, false); json("Show configuration as JSON"), cli_auto_show("datamodel", "candidate", "json", false, false);

View file

@ -1,6 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Test of the IETF rfc6243: With-defaults Capability for NETCONF # Test of the IETF rfc6243: With-defaults Capability for NETCONF
# #
# Test cases below follows the RFC. # Test cases below follows the RFC.
@ -14,6 +13,7 @@ APPNAME=example
cfg=$dir/conf_yang.xml cfg=$dir/conf_yang.xml
fyang=$dir/example-default.yang fyang=$dir/example-default.yang
fstate=$dir/state.xml fstate=$dir/state.xml
clispec=$dir/spec.cli
RESTCONFIG=$(restconf_config none false) RESTCONFIG=$(restconf_config none false)
cat <<EOF > $cfg cat <<EOF > $cfg
@ -23,7 +23,7 @@ cat <<EOF > $cfg
<CLICON_MODULE_SET_ID>42</CLICON_MODULE_SET_ID> <CLICON_MODULE_SET_ID>42</CLICON_MODULE_SET_ID>
<CLICON_YANG_DIR>${YANG_INSTALLDIR}</CLICON_YANG_DIR> <CLICON_YANG_DIR>${YANG_INSTALLDIR}</CLICON_YANG_DIR>
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE> <CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR> <CLICON_CLISPEC_DIR>$dir</CLICON_CLISPEC_DIR>
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR> <CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
<CLICON_BACKEND_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP> <CLICON_BACKEND_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP>
<CLICON_NETCONF_DIR>/usr/local/lib/$APPNAME/netconf</CLICON_NETCONF_DIR> <CLICON_NETCONF_DIR>/usr/local/lib/$APPNAME/netconf</CLICON_NETCONF_DIR>
@ -116,6 +116,41 @@ module example {
} }
EOF EOF
# CLIspec for cli tests
cat <<EOF > $clispec
CLICON_MODE="example";
CLICON_PROMPT="%U@%H %W> ";
CLICON_PLUGIN="example_cli";
set @datamodel, cli_auto_set();
validate("Validate changes"), cli_validate();
commit("Commit the changes"), cli_commit();
quit("Quit"), cli_quit();
discard("Discard edits (rollback 0)"), discard_changes();
show("Show a particular state of the system"){
configuration("Show configuration")
xml("Show configuration and state as XML")
default("With-default mode"){
report-all, cli_auto_show("datamodel", "candidate", "xml", false, false, "report-all");
trim, cli_auto_show("datamodel", "candidate", "xml", false, false, "trim");
explicit, cli_auto_show("datamodel", "candidate", "xml", false, false, "explicit");
report-all-tagged, cli_auto_show("datamodel", "candidate", "xml", false, false, "report-all-tagged");
report-all-tagged-default, cli_auto_show("datamodel", "candidate", "xml", false, false, "report-all-tagged-default");
report-all-tagged-strip, cli_auto_show("datamodel", "candidate", "xml", false, false, "report-all-tagged-strip");
}
state("Show configuration and state")
xml("Show configuration and state as XML")
default("With-default mode"){
report-all, cli_auto_show("datamodel", "running", "xml", false, true, "report-all");
trim, cli_auto_show("datamodel", "running", "xml", false, true, "trim");
explicit, cli_auto_show("datamodel", "running", "xml", false, true, "explicit");
report-all-tagged, cli_auto_show("datamodel", "running", "xml", false, true, "report-all-tagged");
report-all-tagged-default, cli_auto_show("datamodel", "running", "xml", false, true, "report-all-tagged-default");
report-all-tagged-strip, cli_auto_show("datamodel", "running", "xml", false, true, "report-all-tagged-strip");
}
}
EOF
# A.2. Example Data Set # A.2. Example Data Set
EXAMPLENS="xmlns=\"http://example.com/ns/interfaces\"" EXAMPLENS="xmlns=\"http://example.com/ns/interfaces\""
@ -527,6 +562,52 @@ expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+xml' $RCPR
"Cache-Control: no-cache" \ "Cache-Control: no-cache" \
'<interface xmlns="http://example.com/ns/interfaces" xmlns:wd="urn:ietf:params:xml:ns:netconf:default:1.0"><name>eth1</name><mtu wd:default="true">1500</mtu><status wd:default="true">ok</status></interface>' '<interface xmlns="http://example.com/ns/interfaces" xmlns:wd="urn:ietf:params:xml:ns:netconf:default:1.0"><name>eth1</name><mtu wd:default="true">1500</mtu><status wd:default="true">ok</status></interface>'
# CLI tests
mode=explicit
new "cli with-default config $mode"
expectpart "$($clixon_cli -1 -f $cfg show config xml default $mode)" 0 "^<interfaces xmlns=\"http://example.com/ns/interfaces\"><interface><name>eth0</name><mtu>8192</mtu></interface><interface><name>eth1</name></interface><interface><name>eth2</name><mtu>9000</mtu></interface><interface><name>eth3</name><mtu>1500</mtu></interface></interfaces>$"
new "cli with-default state $mode"
expectpart "$($clixon_cli -1 -f $cfg show state xml default $mode)" 0 "^<interfaces xmlns=\"http://example.com/ns/interfaces\"><interface><name>eth0</name><mtu>8192</mtu><status>ok</status></interface><interface><name>eth1</name><status>ok</status></interface><interface><name>eth2</name><mtu>9000</mtu><status>not feeling so good</status></interface><interface><name>eth3</name><mtu>1500</mtu><status>waking up</status></interface></interfaces>$"
mode=report-all
new "cli with-default config $mode"
expectpart "$($clixon_cli -1 -f $cfg show config xml default $mode)" 0 "^<interfaces xmlns=\"http://example.com/ns/interfaces\"><interface><name>eth0</name><mtu>8192</mtu></interface><interface><name>eth1</name><mtu>1500</mtu></interface><interface><name>eth2</name><mtu>9000</mtu></interface><interface><name>eth3</name><mtu>1500</mtu></interface></interfaces>$"
new "cli with-default state $mode"
expectpart "$($clixon_cli -1 -f $cfg show state xml default $mode)" 0 "^<interfaces xmlns=\"http://example.com/ns/interfaces\"><interface><name>eth0</name><mtu>8192</mtu><status>ok</status></interface><interface><name>eth1</name><mtu>1500</mtu><status>ok</status></interface><interface><name>eth2</name><mtu>9000</mtu><status>not feeling so good</status></interface><interface><name>eth3</name><mtu>1500</mtu><status>waking up</status></interface></interfaces>$"
mode=report-all-tagged
new "cli with-default config $mode"
expectpart "$($clixon_cli -1 -f $cfg show config xml default $mode)" 0 "^<interfaces xmlns=\"http://example.com/ns/interfaces\"><interface><name>eth0</name><mtu>8192</mtu></interface><interface><name>eth1</name><mtu wd:default=\"true\">1500</mtu></interface><interface><name>eth2</name><mtu>9000</mtu></interface><interface><name>eth3</name><mtu wd:default=\"true\">1500</mtu></interface></interfaces>$"
new "cli with-default state $mode"
expectpart "$($clixon_cli -1 -f $cfg show state xml default $mode)" 0 "^<interfaces xmlns=\"http://example.com/ns/interfaces\"><interface><name>eth0</name><mtu>8192</mtu><status wd:default=\"true\">ok</status></interface><interface><name>eth1</name><mtu wd:default=\"true\">1500</mtu><status wd:default=\"true\">ok</status></interface><interface><name>eth2</name><mtu>9000</mtu><status>not feeling so good</status></interface><interface><name>eth3</name><mtu wd:default=\"true\">1500</mtu><status>waking up</status></interface></interfaces>$"
mode=trim
new "cli with-default config $mode"
expectpart "$($clixon_cli -1 -f $cfg show config xml default $mode)" 0 "^<interfaces xmlns=\"http://example.com/ns/interfaces\"><interface><name>eth0</name><mtu>8192</mtu></interface><interface><name>eth1</name></interface><interface><name>eth2</name><mtu>9000</mtu></interface><interface><name>eth3</name></interface></interfaces>$"
new "cli with-default state $mode"
expectpart "$($clixon_cli -1 -f $cfg show state xml default $mode)" 0 "^<interfaces xmlns=\"http://example.com/ns/interfaces\"><interface><name>eth0</name><mtu>8192</mtu></interface><interface><name>eth1</name></interface><interface><name>eth2</name><mtu>9000</mtu><status>not feeling so good</status></interface><interface><name>eth3</name><status>waking up</status></interface></interfaces>$"
mode=report-all-tagged-default
new "cli with-default config $mode"
expectpart "$($clixon_cli -1 -f $cfg show config xml default $mode)" 0 "^<interfaces xmlns=\"http://example.com/ns/interfaces\"><interface><name>eth0</name><mtu>8192</mtu></interface><interface><name>eth1</name><mtu>1500</mtu></interface><interface><name>eth2</name><mtu>9000</mtu></interface><interface><name>eth3</name><mtu>1500</mtu></interface></interfaces>$"
new "cli with-default state $mode"
expectpart "$($clixon_cli -1 -f $cfg show state xml default $mode)" 0 "^<interfaces xmlns=\"http://example.com/ns/interfaces\"><interface><name>eth0</name><mtu>8192</mtu><status>ok</status></interface><interface><name>eth1</name><mtu>1500</mtu><status>ok</status></interface><interface><name>eth2</name><mtu>9000</mtu><status>not feeling so good</status></interface><interface><name>eth3</name><mtu>1500</mtu><status>waking up</status></interface></interfaces>$"
mode=report-all-tagged-strip
new "cli with-default config $mode"
expectpart "$($clixon_cli -1 -f $cfg show config xml default $mode)" 0 "^<interfaces xmlns=\"http://example.com/ns/interfaces\"><interface><name>eth0</name><mtu>8192</mtu></interface><interface><name>eth1</name></interface><interface><name>eth2</name><mtu>9000</mtu></interface><interface><name>eth3</name></interface></interfaces>$"
new "cli with-default state $mode"
expectpart "$($clixon_cli -1 -f $cfg show state xml default $mode)" 0 "^<interfaces xmlns=\"http://example.com/ns/interfaces\"><interface><name>eth0</name><mtu>8192</mtu></interface><interface><name>eth1</name></interface><interface><name>eth2</name><mtu>9000</mtu><status>not feeling so good</status></interface><interface><name>eth3</name><status>waking up</status></interface></interfaces>$"
mode=negative-test
new "cli with-default config $mode"
expectpart "$($clixon_cli -1 -f $cfg -l o show config xml default $mode)" 255 "Unknown command"
if [ $RC -ne 0 ]; then if [ $RC -ne 0 ]; then
new "Kill restconf daemon" new "Kill restconf daemon"