* Changed clicon_rpc_get and clicon_rpc_get_config functions: added username and replaced namespace with namespace context

* Fixed several issues with multiple namespaces.
This commit is contained in:
Olof hagsand 2019-10-03 22:01:16 +02:00
parent 3efd5703d6
commit 6e41592aec
16 changed files with 224 additions and 370 deletions

View file

@ -695,13 +695,13 @@ compare_dbs(clicon_handle h,
astext = cv_int32_get(cvec_i(argv, 0));
else
astext = 0;
if (clicon_rpc_get_config(h, "running", "/", NULL, &xc1) < 0)
if (clicon_rpc_get_config(h, NULL, "running", "/", NULL, &xc1) < 0)
goto done;
if ((xerr = xpath_first(xc1, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto done;
}
if (clicon_rpc_get_config(h, "candidate", "/", NULL, &xc2) < 0)
if (clicon_rpc_get_config(h, NULL, "candidate", "/", NULL, &xc2) < 0)
goto done;
if ((xerr = xpath_first(xc2, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
@ -862,7 +862,7 @@ save_config_file(clicon_handle h,
goto done;
}
filename = cv_string_get(cv);
if (clicon_rpc_get_config(h, dbstr,"/", NULL, &xt) < 0)
if (clicon_rpc_get_config(h, NULL, dbstr,"/", NULL, &xt) < 0)
goto done;
if (xt == NULL){
clicon_err(OE_CFG, 0, "get config: empty tree"); /* Shouldnt happen */
@ -1203,8 +1203,10 @@ cli_copy_config(clicon_handle h,
goto done;
}
cprintf(cb, xpath, keyname, fromname);
if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL)
goto done;
/* Get from object configuration and store in x1 */
if (clicon_rpc_get_config(h, db, cbuf_get(cb), namespace, &x1) < 0)
if (clicon_rpc_get_config(h, NULL, db, cbuf_get(cb), nsc, &x1) < 0)
goto done;
if ((xerr = xpath_first(x1, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
@ -1224,8 +1226,7 @@ cli_copy_config(clicon_handle h,
goto done;
xml_name_set(x2, "config");
cprintf(cb, "/%s", keyname);
if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL)
goto done;
if ((x = xpath_first_nsc(x2, nsc, "%s", cbuf_get(cb))) == NULL){
clicon_err(OE_PLUGIN, 0, "Field %s not found in copy tree", keyname);
goto done;

View file

@ -117,7 +117,6 @@ expand_dbvar(void *h,
cxobj *xcur;
char *xpathcur;
char *reason = NULL;
char *namespace = NULL;
cvec *nsc = NULL;
if (argv == NULL || cvec_len(argv) != 2){
@ -150,11 +149,11 @@ expand_dbvar(void *h,
*/
if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path) < 0)
goto done;
if (api_path2xpath(api_path, yspec, &xpath, &namespace) < 0)
if (api_path2xpath(api_path, yspec, &xpath, &nsc) < 0)
goto done;
/* Get configuration */
if (clicon_rpc_get_config(h, dbstr, xpath, namespace, &xt) < 0) /* XXX */
if (clicon_rpc_get_config(h, NULL, dbstr, xpath, nsc, &xt) < 0) /* XXX */
goto done;
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
@ -175,8 +174,6 @@ expand_dbvar(void *h,
if (y==NULL)
goto ok;
if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL)
goto done;
/* Special case for leafref. Detect leafref via Yang-type,
* Get Yang path element, tentatively add the new syntax to the whole
@ -437,6 +434,7 @@ cli_show_config1(clicon_handle h,
enum genmodel_type gt;
yang_stmt *yspec;
char *namespace = NULL;
cvec *nsc = NULL;
if (cvec_len(argv) != 3 && cvec_len(argv) != 4){
clicon_err(OE_PLUGIN, 0, "Got %d arguments. Expected: <dbname>,<format>,<xpath>[,<attr>]", cvec_len(argv));
@ -461,10 +459,13 @@ cli_show_config1(clicon_handle h,
}
cprintf(cbxpath, "%s", xpath);
/* Fourth argument is namespace */
if (cvec_len(argv) == 4)
if (cvec_len(argv) == 4){
namespace = cv_string_get(cvec_i(argv, 3));
if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL)
goto done;
}
if (state == 0){ /* Get configuration-only from database */
if (clicon_rpc_get_config(h, db, cbuf_get(cbxpath), namespace, &xt) < 0)
if (clicon_rpc_get_config(h, NULL, db, cbuf_get(cbxpath), nsc, &xt) < 0)
goto done;
}
else { /* Get configuration and state from database */
@ -472,7 +473,7 @@ cli_show_config1(clicon_handle h,
clicon_err(OE_FATAL, 0, "Show state only for running database, not %s", db);
goto done;
}
if (clicon_rpc_get(h, cbuf_get(cbxpath), namespace, CONTENT_ALL, -1, &xt) < 0)
if (clicon_rpc_get(h, cbuf_get(cbxpath), nsc, CONTENT_ALL, -1, &xt) < 0)
goto done;
}
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
@ -519,6 +520,8 @@ cli_show_config1(clicon_handle h,
}
retval = 0;
done:
if (nsc)
xml_nsctx_free(nsc);
if (xt)
xml_free(xt);
if (val)
@ -617,15 +620,15 @@ show_conf_xpath(clicon_handle h,
/* Look for namespace in command (kludge: cv must be called "ns") */
cv = cvec_find(cvv, "ns");
namespace = cv_string_get(cv);
if (clicon_rpc_get_config(h, str, xpath, namespace, &xt) < 0)
if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL)
goto done;
if (clicon_rpc_get_config(h, NULL, str, xpath, nsc, &xt) < 0)
goto done;
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto done;
}
if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL)
goto done;
if (xpath_vec_nsc(xt, nsc, "%s", &xv, &xlen, xpath) < 0)
goto done;
for (i=0; i<xlen; i++)
@ -681,7 +684,6 @@ cli_show_auto1(clicon_handle h,
cxobj *xp;
cxobj *xerr;
enum genmodel_type gt;
char *namespace = NULL;
char *api_path = NULL;
if (cvec_len(argv) != 3){
@ -704,18 +706,16 @@ cli_show_auto1(clicon_handle h,
}
if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path) < 0)
goto done;
if (api_path2xpath(api_path, yspec, &xpath, &namespace) < 0)
if (api_path2xpath(api_path, yspec, &xpath, &nsc) < 0)
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] == '/')
xpath[strlen(xpath)-1] = '\0';
if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL)
goto done;
if (state == 0){ /* Get configuration-only from database */
if (clicon_rpc_get_config(h, db, xpath, namespace, &xt) < 0)
if (clicon_rpc_get_config(h, NULL, db, xpath, nsc, &xt) < 0)
goto done;
}
else{ /* Get configuration and state from database */
@ -723,7 +723,7 @@ cli_show_auto1(clicon_handle h,
clicon_err(OE_FATAL, 0, "Show state only for running database, not %s", db);
goto done;
}
if (clicon_rpc_get(h, xpath, namespace, CONTENT_ALL, -1, &xt) < 0)
if (clicon_rpc_get(h, xpath, nsc, CONTENT_ALL, -1, &xt) < 0)
goto done;
}

View file

@ -647,19 +647,15 @@ restconf_insert_attributes(cxobj *xdata,
char *attrname;
int ret;
char *xpath = NULL;
char *namespace = NULL;
cvec *nsc = NULL;
cbuf *cb = NULL;
char *p;
cg_var *cv = NULL;
y = xml_spec(xdata);
if ((instr = cvec_find_str(qvec, "insert")) != NULL){
/* First add xmlns:yang attribute */
if ((xa = xml_new("yang", xdata, NULL)) == NULL)
goto done;
if (xml_prefix_set(xa, "xmlns") < 0)
goto done;
xml_type_set(xa, CX_ATTR);
if (xml_value_set(xa, YANG_XML_NAMESPACE) < 0)
if (xmlns_set(xdata, "yang", YANG_XML_NAMESPACE) < 0)
goto done;
/* Then add insert attribute */
if ((xa = xml_new("insert", xdata, NULL)) == NULL)
@ -685,7 +681,7 @@ restconf_insert_attributes(cxobj *xdata,
if (xml_prefix_set(xa, "yang") < 0)
goto done;
xml_type_set(xa, CX_ATTR);
if ((ret = api_path2xpath(pstr, ys_spec(y), &xpath, &namespace)) < 0)
if ((ret = api_path2xpath(pstr, ys_spec(y), &xpath, &nsc)) < 0)
goto done;
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
@ -715,10 +711,20 @@ restconf_insert_attributes(cxobj *xdata,
if (xml_value_set(xa, cbuf_get(cb)) < 0)
goto done;
}
/* Add prefix/namespaces used in attributes */
cv = NULL;
while ((cv = cvec_each(nsc, cv)) != NULL)
if (xmlns_set(xdata, cv_name_get(cv), cv_string_get(cv)) < 0)
goto done;
if (nsc)
xml_sort(xdata, NULL); /* Ensure attr is first */
cprintf(cb, "/>");
retval = 0;
done:
if (xpath)
free(xpath);
if (nsc)
xml_nsctx_free(nsc);
if (cb)
cbuf_free(cb);
return retval;

View file

@ -262,8 +262,8 @@ api_data_write(clicon_handle h,
char *namespace = NULL;
char *dname;
int nullspec = 0;
char *xpath = NULL;
cbuf *cbpath = NULL;
cvec *nsc = NULL;
clicon_debug(1, "%s api_path:\"%s\"", __FUNCTION__, api_path0);
clicon_debug(1, "%s data:\"%s\"", __FUNCTION__, data);
@ -276,11 +276,11 @@ api_data_write(clicon_handle h,
api_path = index(api_path+1, '/');
/* Check if object exists in backend.
* Translate api-path to xpath */
namespace = NULL;
if ((cbpath = cbuf_new()) == NULL)
goto done;
cprintf(cbpath, "/");
if ((ret = api_path2xpath_cvv(pcvec, pi, yspec, cbpath, &namespace, &xerr)) < 0)
if ((ret = api_path2xpath_cvv(pcvec, pi, yspec, cbpath, &nsc, &xerr)) < 0)
goto done;
if (ret == 0){
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
@ -291,25 +291,9 @@ api_data_write(clicon_handle h,
goto done;
goto ok;
}
xpath = cbuf_get(cbpath);
/* Create text buffer for transfer to backend */
if ((cbx = cbuf_new()) == NULL)
goto done;
/* show done automaticaly by the system, therefore recovery user is used
* here */
cprintf(cbx, "<rpc username=\"%s\"", NACM_RECOVERY_USER);
if (namespace)
cprintf(cbx, " xmlns:nc=\"%s\">", NETCONF_BASE_NAMESPACE);
cprintf(cbx, "><get-config><source><candidate/></source>");
if (namespace)
cprintf(cbx, "<nc:filter nc:type=\"xpath\" nc:select=\"%s\" xmlns=\"%s\"/>",
xpath, namespace);
else /* If xpath != /, this will probably yield an error later */
cprintf(cbx, "<filter type=\"xpath\" select=\"%s\"/>", xpath);
cprintf(cbx, "</get-config></rpc>");
xret = NULL;
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0){
if (clicon_rpc_get_config(h, NACM_RECOVERY_USER,
"candidate", cbuf_get(cbpath), nsc, &xret) < 0){
if (netconf_operation_failed_xml(&xerr, "protocol", clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
@ -319,6 +303,7 @@ api_data_write(clicon_handle h,
if (api_return_err(h, r, xe, pretty, media_out, 0) < 0)
goto done;
goto ok;
}
#if 0
if (debug){
@ -329,8 +314,7 @@ api_data_write(clicon_handle h,
cbuf_free(ccc);
}
#endif
if ((xe = xpath_first(xret, "/rpc-reply/data")) == NULL ||
xml_child_nr(xe) == 0){ /* Object does not exist */
if (xml_child_nr(xret) == 0){ /* Object does not exist */
if (plain_patch){ /* If the target resource instance does not exist, the server MUST NOT create it. */
restconf_badrequest(r);
goto ok;
@ -342,13 +326,12 @@ api_data_write(clicon_handle h,
if (plain_patch)
op = OP_MERGE;
else
op = OP_REPLACE;
op = OP_REPLACE;
}
if (xret){
xml_free(xret);
xret = NULL;
}
/* Create config top-of-tree */
if ((xtop = xml_new("config", NULL, NULL)) == NULL)
goto done;
@ -573,7 +556,6 @@ api_data_write(clicon_handle h,
}
}
}
xml_purge(xbot);
if (xml_addsub(xparent, xdata) < 0)
goto done;
@ -597,7 +579,6 @@ api_data_write(clicon_handle h,
/* If restconf insert/point attributes are present, translate to netconf */
if (restconf_insert_attributes(xdata, qvec) < 0)
goto done;
/* If we already have that default namespace, remove it in child */
if ((xa = xml_find_type(xdata, NULL, "xmlns", CX_ATTR)) != NULL){
if (xml2ns(xparent, NULL, &namespace) < 0)
@ -610,7 +591,9 @@ api_data_write(clicon_handle h,
/* For internal XML protocol: add username attribute for access control
*/
username = clicon_username_get(h);
cbuf_reset(cbx);
/* Create text buffer for transfer to backend */
if ((cbx = cbuf_new()) == NULL)
goto done;
cprintf(cbx, "<rpc username=\"%s\" xmlns:%s=\"%s\">",
username?username:"",
NETCONF_BASE_PREFIX,
@ -685,6 +668,8 @@ api_data_write(clicon_handle h,
retval = 0;
done:
clicon_debug(1, "%s retval:%d", __FUNCTION__, retval);
if (nsc)
xml_nsctx_free(nsc);
if (cbpath)
cbuf_free(cbpath);
if (xret)

View file

@ -165,16 +165,11 @@ api_data_get2(clicon_handle h,
if ((cbpath = cbuf_new()) == NULL)
goto done;
cprintf(cbpath, "/");
/* Create a namespace context for ymod as the default namespace to use with
* xpath expressions */
if ((nsc = cvec_new(0)) == NULL){
clicon_err(OE_XML, errno, "cvec_new");
goto done;
}
/* We know "data" is element pi-1.
* Translate api-path to xpath: xpath (cbpath) and namespace context (nsc)
*/
if ((ret = api_path2xpath_cvv2(pcvec, pi, yspec, cbpath, nsc, &xerr)) < 0)
if ((ret = api_path2xpath_cvv(pcvec, pi, yspec, cbpath, &nsc, &xerr)) < 0)
goto done;
if (ret == 0){
clicon_err_reset();
@ -192,7 +187,7 @@ api_data_get2(clicon_handle h,
case CONTENT_CONFIG:
case CONTENT_NONCONFIG:
case CONTENT_ALL:
ret = clicon_rpc_get_nsc(h, xpath, nsc, content, depth, &xret);
ret = clicon_rpc_get(h, xpath, nsc, content, depth, &xret);
break;
default:
clicon_err(OE_XML, EINVAL, "Invalid content attribute %d", content);