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:
parent
42d5b6fba2
commit
743076b171
23 changed files with 256 additions and 56 deletions
|
|
@ -413,7 +413,6 @@ element2value(clicon_handle h,
|
|||
* @param[in] x XML node
|
||||
* @param[in] flag Flag to be used
|
||||
* @retval 0 OK
|
||||
|
||||
*/
|
||||
static int
|
||||
xml_flag_default_value(cxobj *x,
|
||||
|
|
@ -464,7 +463,7 @@ xml_add_default_tag(cxobj *x,
|
|||
goto done;
|
||||
if (xml_value_set(xattr, "true") < 0)
|
||||
goto done;
|
||||
if (xml_prefix_set(xattr, "wd") < 0)
|
||||
if (xml_prefix_set(xattr, IETF_NETCONF_WITH_DEFAULTS_ATTR_PREFIX) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
|
|
@ -478,7 +477,6 @@ xml_add_default_tag(cxobj *x,
|
|||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
|
||||
static int
|
||||
with_defaults(cxobj *xe,
|
||||
cxobj *xret)
|
||||
|
|
@ -506,7 +504,7 @@ with_defaults(cxobj *xe,
|
|||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if (strcmp(mode, "trim") == 0) {
|
||||
else if (strcmp(mode, "trim") == 0) {
|
||||
/* Remove default nodes from XML */
|
||||
if (xml_tree_prune_flags(xret, XML_FLAG_DEFAULT, XML_FLAG_DEFAULT) < 0)
|
||||
goto done;
|
||||
|
|
@ -521,8 +519,8 @@ with_defaults(cxobj *xe,
|
|||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if (strcmp(mode, "report-all-tagged") == 0) {
|
||||
if (xmlns_set(xret, "wd", "urn:ietf:params:xml:ns:netconf:default:1.0") < 0)
|
||||
else if (strcmp(mode, "report-all-tagged") == 0) {
|
||||
if (xmlns_set(xret, IETF_NETCONF_WITH_DEFAULTS_ATTR_PREFIX, IETF_NETCONF_WITH_DEFAULTS_ATTR_NAMESPACE) < 0)
|
||||
goto done;
|
||||
/* Mark nodes having default schema values */
|
||||
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 ok;
|
||||
}
|
||||
if (strcmp(mode, "report-all") == 0) {
|
||||
else if (strcmp(mode, "report-all") == 0) {
|
||||
/* Accept mode, do nothing */
|
||||
goto ok;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -347,8 +347,14 @@ cli_auto_top(clicon_handle h,
|
|||
* <format> "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
|
||||
* <pretty> 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
|
||||
* @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
|
||||
cli_auto_show(clicon_handle h,
|
||||
|
|
@ -376,9 +382,11 @@ cli_auto_show(clicon_handle h,
|
|||
char *prefix = NULL;
|
||||
int state;
|
||||
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){
|
||||
clicon_err(OE_PLUGIN, EINVAL, "Usage: <treename> <database> <format> <pretty> <state> [<prefix>].");
|
||||
if (cvec_len(argv) < 5 || cvec_len(argv) > 7){
|
||||
clicon_err(OE_PLUGIN, EINVAL, "Usage: <treename> <database> <format> <pretty> <state> [<default> <cli-prefix>].");
|
||||
goto done;
|
||||
}
|
||||
/* First argv argument: treename */
|
||||
|
|
@ -407,10 +415,27 @@ cli_auto_show(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
state = cv_bool_get(boolcv);
|
||||
|
||||
/* Sixth: prefix */
|
||||
if (cvec_len(argv) == 6) {
|
||||
prefix = cv_string_get(cvec_i(argv, 5));
|
||||
/* Sixth: default */
|
||||
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;
|
||||
}
|
||||
/* Seventh: cli prefix */
|
||||
if (cvec_len(argv) > 6) {
|
||||
prefix = cv_string_get(cvec_i(argv, 6));
|
||||
}
|
||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||
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)
|
||||
goto done;
|
||||
skiproot = (xpath != NULL) && (strcmp(xpath,"/") != 0);
|
||||
if (state == 0){ /* Get configuration-only from database */
|
||||
if (clicon_rpc_get_config(h, NULL, db, xpath, nsc, &xt) < 0)
|
||||
goto done;
|
||||
}
|
||||
else { /* Get configuration and state from database */
|
||||
if (strcmp(db, "running") != 0){
|
||||
if (state && 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)
|
||||
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 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;
|
||||
}
|
||||
/* 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)
|
||||
goto done;
|
||||
|
||||
|
|
|
|||
|
|
@ -772,13 +772,13 @@ compare_dbs(clicon_handle h,
|
|||
format = FORMAT_TEXT;
|
||||
else
|
||||
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;
|
||||
if ((xerr = xpath_first(xc1, NULL, "/rpc-error")) != NULL){
|
||||
clixon_netconf_error(xerr, "Get configuration", NULL);
|
||||
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;
|
||||
if ((xerr = xpath_first(xc2, NULL, "/rpc-error")) != NULL){
|
||||
clixon_netconf_error(xerr, "Get configuration", NULL);
|
||||
|
|
@ -1028,7 +1028,7 @@ save_config_file(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
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;
|
||||
if (xt == NULL){
|
||||
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)
|
||||
goto done;
|
||||
/* 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;
|
||||
if ((xerr = xpath_first(x1, NULL, "/rpc-error")) != NULL){
|
||||
clixon_netconf_error(xerr, "Get configuration", NULL);
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ expand_dbvar(void *h,
|
|||
goto done;
|
||||
}
|
||||
/* 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;
|
||||
if ((xe = xpath_first(xt, NULL, "/rpc-error")) != 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));
|
||||
}
|
||||
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;
|
||||
}
|
||||
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)
|
||||
goto done;
|
||||
#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;
|
||||
#endif
|
||||
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
|
||||
|
|
@ -741,7 +741,7 @@ cli_show_auto1(clicon_handle h,
|
|||
xpath[strlen(xpath)-1] = '\0';
|
||||
|
||||
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;
|
||||
}
|
||||
else{ /* Get configuration and state from database */
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ restconf_main_config(clicon_handle h,
|
|||
clicon_err(OE_UNIX, errno, "getpwuid");
|
||||
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;
|
||||
if ((xerr = xpath_first(xconfig, NULL, "/rpc-error")) != NULL){
|
||||
clixon_netconf_error(xerr, "Get backend restconf config", NULL);
|
||||
|
|
|
|||
|
|
@ -670,7 +670,7 @@ restconf_clixon_backend(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
/* 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;
|
||||
if ((xerr = xpath_first(xconfig, NULL, "/rpc-error")) != NULL){
|
||||
clixon_netconf_error(xerr, "Get backend restconf config", NULL);
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ mycallback(clicon_handle h, cvec *cvv, cvec *argv)
|
|||
/* Show eth0 interfaces config using XPATH */
|
||||
if (clicon_rpc_get_config(h, NULL, "running",
|
||||
"/interfaces/interface[name='eth0']",
|
||||
nsc,
|
||||
nsc, NULL,
|
||||
&xret) < 0)
|
||||
goto done;
|
||||
if (clixon_xml2file(stdout, xret, 0, 1, cligen_output, 0, 1) < 0)
|
||||
|
|
|
|||
|
|
@ -85,14 +85,33 @@ show("Show a particular state of the system"){
|
|||
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);{
|
||||
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 ");
|
||||
xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", true, false);{
|
||||
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);
|
||||
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);
|
||||
|
||||
}
|
||||
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(); {
|
||||
clixon-example("Show clixon-example yang spec"), show_yang("clixon-example");
|
||||
|
|
|
|||
|
|
@ -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_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_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,
|
||||
char *xml);
|
||||
int clicon_rpc_copy_config(clicon_handle h, char *db1, char *db2);
|
||||
|
|
|
|||
|
|
@ -65,6 +65,16 @@
|
|||
*/
|
||||
#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
|
||||
* ietf-netconf.yang defines it as output:
|
||||
* output { anyxml data;
|
||||
|
|
|
|||
|
|
@ -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 xml_rpc_isaction(cxobj *xn);
|
||||
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_ */
|
||||
|
|
|
|||
|
|
@ -458,6 +458,7 @@ clicon_rpc_netconf_xml(clicon_handle h,
|
|||
* @param[in] db Name of database
|
||||
* @param[in] xpath XPath (or "")
|
||||
* @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.
|
||||
* Either <config> or <rpc-error>.
|
||||
* @retval 0 OK
|
||||
|
|
@ -468,7 +469,7 @@ clicon_rpc_netconf_xml(clicon_handle h,
|
|||
*
|
||||
* if ((nsc = xml_nsctx_init(NULL, "urn:example:hello")) == NULL)
|
||||
* 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;
|
||||
* if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
|
||||
* clixon_netconf_error(xerr, "msg", "/hello/world");
|
||||
|
|
@ -489,6 +490,7 @@ clicon_rpc_get_config(clicon_handle h,
|
|||
char *db,
|
||||
char *xpath,
|
||||
cvec *nsc,
|
||||
char *defaults,
|
||||
cxobj **xt)
|
||||
{
|
||||
int retval = -1;
|
||||
|
|
@ -523,6 +525,10 @@ clicon_rpc_get_config(clicon_handle h,
|
|||
goto done;
|
||||
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>");
|
||||
if ((msg = clicon_msg_encode(session_id, "%s", cbuf_get(cb))) == NULL)
|
||||
goto done;
|
||||
|
|
@ -910,7 +916,9 @@ clicon_rpc_get(clicon_handle h,
|
|||
cprintf(cb, "/>");
|
||||
}
|
||||
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>");
|
||||
if ((msg = clicon_msg_encode(session_id,
|
||||
"%s", cbuf_get(cb))) == NULL)
|
||||
|
|
|
|||
|
|
@ -1367,7 +1367,7 @@ xml_wrap(cxobj *xc,
|
|||
* @param[in] xc xml child node (to be removed and freed)
|
||||
* @retval 0 OK
|
||||
* @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
|
||||
* @see xml_free Free, dont remove from parent
|
||||
* @see xml_child_rm Remove if child order is known (does not free)
|
||||
|
|
@ -1500,6 +1500,7 @@ xml_rm_children(cxobj *xp,
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*! 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
|
||||
* and return it, remove the parent and all other children. (unwrap)
|
||||
|
|
|
|||
|
|
@ -2218,3 +2218,52 @@ xml_find_action(cxobj *xn,
|
|||
done:
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ quit("Quit"), cli_quit();
|
|||
show("Show a particular state of the system"){
|
||||
configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, 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);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ quit("Quit"), cli_quit();
|
|||
show("Show a particular state of the system"){
|
||||
configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, 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);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ discard("Discard edits (rollback 0)"), discard_changes();
|
|||
|
||||
show("Show a particular state of the system"){
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,9 +134,9 @@ show("Show a particular state of the system"){
|
|||
text("Show comparison in text"), compare_dbs((int32)1);
|
||||
}
|
||||
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 ");
|
||||
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 ");
|
||||
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);
|
||||
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"){
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ delete("Delete a configuration item") {
|
|||
show("Show a particular state of the system"){
|
||||
|
||||
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();
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ show("Show a particular state of the system"){
|
|||
text("Show comparison in text"), compare_dbs((int32)1);
|
||||
}
|
||||
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 ");
|
||||
text("Show configuration as TEXT"), cli_auto_show("datamodel", "candidate", "text", true, false, "set ");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ cat <<EOF > $cfg
|
|||
<CLICON_FEATURE>ietf-netconf:startup</CLICON_FEATURE>
|
||||
<CLICON_YANG_DIR>${YANG_INSTALLDIR}</CLICON_YANG_DIR>
|
||||
<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_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP>
|
||||
<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"){
|
||||
configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", 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);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
# Test of the IETF rfc6243: With-defaults Capability for NETCONF
|
||||
#
|
||||
# Test cases below follows the RFC.
|
||||
|
|
@ -14,6 +13,7 @@ APPNAME=example
|
|||
cfg=$dir/conf_yang.xml
|
||||
fyang=$dir/example-default.yang
|
||||
fstate=$dir/state.xml
|
||||
clispec=$dir/spec.cli
|
||||
RESTCONFIG=$(restconf_config none false)
|
||||
|
||||
cat <<EOF > $cfg
|
||||
|
|
@ -23,7 +23,7 @@ cat <<EOF > $cfg
|
|||
<CLICON_MODULE_SET_ID>42</CLICON_MODULE_SET_ID>
|
||||
<CLICON_YANG_DIR>${YANG_INSTALLDIR}</CLICON_YANG_DIR>
|
||||
<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_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP>
|
||||
<CLICON_NETCONF_DIR>/usr/local/lib/$APPNAME/netconf</CLICON_NETCONF_DIR>
|
||||
|
|
@ -116,6 +116,41 @@ module example {
|
|||
}
|
||||
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
|
||||
|
||||
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" \
|
||||
'<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
|
||||
new "Kill restconf daemon"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue