The Clixon API has been extended with namespaces, or namespace contexts in the following cases:

* CLIspec functions have added namespace parameter:
    * `cli_show_config <db> <format> <xpath>` --> `cli_show_config <db> <format> <xpath> <namespace>`
    * `cli_copy_config <db> <xpath> ...` --> `cli_copy_config <db> <xpath> <namespace> ...`
  * Xpath API
    * `xpath_first(x, format, ...)` --> `xpath_first(x, nsc, format, ...)`
    * `xpath_vec(x, format, vec, veclen, ...)` --> `xpath_vec(x, nsc, format, vec, veclen, ...)`
    * `xpath_vec_flag(x, format, flags, vec, veclen, ...)` --> `xpath_vec_flag(x, format, flags, vec, veclen, ...)`
    * `xpath_vec_bool(x, format, ...)` --> `xpath_vec_bool(x, nsc, format, ...)`
    * `xpath_vec_ctx(x, xpath, xp)` --> `xpath_vec_ctx(x, nsc, xpath, xp)`
  * xmldb_get0 has an added `nsc` parameter:
    * `xmldb_get0(h, db, xpath, copy, xret, msd)` --> `xmldb_get0(h, db, nsc, xpath, copy, xret, msd)`
  * The plugin statedata callback (ca_statedata) has been extended with an nsc parameter:
    * `int example_statedata(clicon_handle h, cvec *nsc, char *xpath, cxobj *xstate);`
  * rpc get and get-config api function has an added namespace argument:
    * `clicon_rpc_get_config(clicon_handle h, char *db, char *xpath, char *namespace, cxobj **xt);`
    * `int clicon_rpc_get(clicon_handle h, char *xpath, char *namespace, cxobj **xt);`
This commit is contained in:
Olof hagsand 2019-07-08 10:36:37 +02:00
parent 73d8e97a01
commit 67b8685bab
78 changed files with 1507 additions and 538 deletions

View file

@ -217,6 +217,7 @@ client_get_streams(clicon_handle h,
/*! Get system state-data, including streams and plugins
* @param[in] h Clicon handle
* @param[in] xpath Xpath selection, not used but may be to filter early
* @param[in] nsc XML Namespace context for xpath
* @param[in,out] xret Existing XML tree, merge x into this
* @retval -1 Error (fatal)
* @retval 0 Statedata callback failed (clicon_err called)
@ -225,6 +226,7 @@ client_get_streams(clicon_handle h,
static int
client_statedata(clicon_handle h,
char *xpath,
cvec *nsc,
cxobj **xret)
{
int retval = -1;
@ -251,12 +253,12 @@ client_statedata(clicon_handle h,
goto fail;
}
if (clicon_option_bool(h, "CLICON_MODULE_LIBRARY_RFC7895")){
if ((ret = yang_modules_state_get(h, yspec, xpath, 0, xret)) < 0)
if ((ret = yang_modules_state_get(h, yspec, xpath, nsc, 0, xret)) < 0)
goto done;
if (ret == 0)
goto fail;
}
if ((ret = clixon_plugin_statedata(h, yspec, xpath, xret)) < 0)
if ((ret = clixon_plugin_statedata(h, yspec, nsc, xpath, xret)) < 0)
goto done;
if (ret == 0)
goto fail;
@ -264,7 +266,7 @@ client_statedata(clicon_handle h,
* Actually this is a safety catch, should realy be done in plugins
* and modules_state functions.
*/
if (xpath_vec(*xret, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
if (xpath_vec(*xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
goto done;
/* If vectors are specified then mark the nodes found and
* then filter out everything else,
@ -320,6 +322,7 @@ from_client_get_config(clicon_handle h,
size_t xlen;
int ret;
char *username;
cvec *nsc = NULL; /* Create a netconf namespace context from filter */
username = clicon_username_get(h);
if ((db = netconf_db_find(xe, "source")) == NULL){
@ -336,13 +339,22 @@ from_client_get_config(clicon_handle h,
goto done;
goto ok;
}
if ((xfilter = xml_find(xe, "filter")) != NULL)
if ((xfilter = xml_find(xe, "filter")) != NULL){
if ((xpath = xml_find_value(xfilter, "select"))==NULL)
xpath="/";
/* Create namespace context for xpath from <filter>
* The set of namespace declarations are those in scope on the
* <filter> element.
*/
else
if (xml_nsctx_node(xfilter, &nsc) < 0)
goto done;
}
/* Note xret can be pruned by nacm below (and change name),
* so zero-copy cant be used
* Also, must use external namespace context here due to <filter stmt
*/
if (xmldb_get(h, db, xpath, &xret) < 0){
if (xmldb_get0(h, db, nsc, xpath, 1, &xret, NULL) < 0) {
if (netconf_operation_failed(cbret, "application", "read registry")< 0)
goto done;
goto ok;
@ -351,7 +363,7 @@ from_client_get_config(clicon_handle h,
if ((ret = nacm_access_pre(h, username, NACM_DATA, &xnacm)) < 0)
goto done;
if (ret == 0){ /* Do NACM validation */
if (xpath_vec(xret, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
goto done;
/* NACM datanode/module read validation */
if (nacm_datanode_read(xret, xvec, xlen, username, xnacm) < 0)
@ -374,6 +386,8 @@ from_client_get_config(clicon_handle h,
xml_free(xnacm);
if (xvec)
free(xvec);
if (nsc)
xml_nsctx_free(nsc);
if (cbx)
cbuf_free(cbx);
if (xret)
@ -441,14 +455,14 @@ from_client_edit_config(clicon_handle h,
goto done;
goto ok;
}
if ((x = xpath_first(xn, "default-operation")) != NULL){
if ((x = xpath_first(xn, NULL, "default-operation")) != NULL){
if (xml_operation(xml_body(x), &operation) < 0){
if (netconf_invalid_value(cbret, "protocol", "Wrong operation")< 0)
goto done;
goto ok;
}
}
if ((xc = xpath_first(xn, "config")) == NULL){
if ((xc = xpath_first(xn, NULL, "config")) == NULL){
if (netconf_missing_element(cbret, "protocol", "config", NULL) < 0)
goto done;
goto ok;
@ -806,24 +820,34 @@ from_client_get(clicon_handle h,
cxobj **xvec = NULL;
size_t xlen;
cxobj *xnacm = NULL;
char *username;
char *username;
cvec *nsc = NULL; /* Create a netconf namespace context from filter */
username = clicon_username_get(h);
if ((xfilter = xml_find(xe, "filter")) != NULL)
if ((xfilter = xml_find(xe, "filter")) != NULL){
if ((xpath = xml_find_value(xfilter, "select"))==NULL)
xpath="/";
/* Create namespace context for xpath from <filter>
* The set of namespace declarations are those in scope on the
* <filter> element.
*/
else
if (xml_nsctx_node(xfilter, &nsc) < 0)
goto done;
}
/* Get config
* Note xret can be pruned by nacm below and change name and
* metrged with state data, so zero-copy cant be used
* Also, must use external namespace context here due to <filter stmt
*/
if (xmldb_get(h, "running", xpath, &xret) < 0){
if (xmldb_get0(h, "running", nsc, xpath, 1, &xret, NULL) < 0) {
if (netconf_operation_failed(cbret, "application", "read registry")< 0)
goto done;
goto ok;
}
/* Get state data from plugins as defined by plugin_statedata(), if any */
clicon_err_reset();
if ((ret = client_statedata(h, xpath, &xret)) < 0)
if ((ret = client_statedata(h, xpath, nsc, &xret)) < 0)
goto done;
if (ret == 0){ /* Error from callback (error in xret) */
if (clicon_xml2cbuf(cbret, xret, 0, 0) < 0)
@ -834,7 +858,7 @@ from_client_get(clicon_handle h,
if ((ret = nacm_access_pre(h, username, NACM_DATA, &xnacm)) < 0)
goto done;
if (ret == 0){ /* Do NACM validation */
if (xpath_vec(xret, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
goto done;
/* NACM datanode/module read validation */
if (nacm_datanode_read(xret, xvec, xlen, username, xnacm) < 0)
@ -858,6 +882,8 @@ from_client_get(clicon_handle h,
xml_free(xnacm);
if (xvec)
free(xvec);
if (nsc)
xml_nsctx_free(nsc);
if (xret)
xml_free(xret);
return retval;
@ -986,10 +1012,13 @@ from_client_create_subscription(clicon_handle h,
char *selector = NULL;
struct timeval start;
struct timeval stop;
cvec *nsc = NULL;
if ((x = xpath_first(xe, "//stream")) != NULL)
if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:netmod:notification")) == NULL)
goto done;
if ((x = xpath_first(xe, nsc, "//stream")) != NULL)
stream = xml_find_value(x, "body");
if ((x = xpath_first(xe, "//stopTime")) != NULL){
if ((x = xpath_first(xe, nsc, "//stopTime")) != NULL){
if ((stoptime = xml_find_value(x, "body")) != NULL &&
str2time(stoptime, &stop) < 0){
if (netconf_bad_element(cbret, "application", "stopTime", "Expected timestamp") < 0)
@ -997,7 +1026,7 @@ from_client_create_subscription(clicon_handle h,
goto ok;
}
}
if ((x = xpath_first(xe, "//startTime")) != NULL){
if ((x = xpath_first(xe, nsc, "//startTime")) != NULL){
if ((starttime = xml_find_value(x, "body")) != NULL &&
str2time(starttime, &start) < 0){
if (netconf_bad_element(cbret, "application", "startTime", "Expected timestamp") < 0)
@ -1005,7 +1034,7 @@ from_client_create_subscription(clicon_handle h,
goto ok;
}
}
if ((xfilter = xpath_first(xe, "//filter")) != NULL){
if ((xfilter = xpath_first(xe, nsc, "//filter")) != NULL){
if ((ftype = xml_find_value(xfilter, "type")) != NULL){
/* Only accept xpath as filter type */
if (strcmp(ftype, "xpath") != 0){
@ -1041,6 +1070,8 @@ from_client_create_subscription(clicon_handle h,
ok:
retval = 0;
done:
if (nsc)
xml_nsctx_free(nsc);
return retval;
}
@ -1144,7 +1175,7 @@ from_client_msg(clicon_handle h,
goto reply;
}
if ((x = xpath_first(xt, "/rpc")) == NULL){
if ((x = xpath_first(xt, NULL, "/rpc")) == NULL){
if (netconf_malformed_message(cbret, "rpc keyword expected")< 0)
goto done;
goto reply;

View file

@ -184,7 +184,7 @@ startup_common(clicon_handle h,
if ((msd = modstate_diff_new()) == NULL)
goto done;
clicon_debug(1, "Reading startup config from %s", db);
if (xmldb_get0(h, db, "/", 0, &xt, msd) < 0)
if (xmldb_get0(h, db, NULL, "/", 0, &xt, msd) < 0)
goto done;
/* Clear flags xpath for get */
xml_apply0(xt, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset,
@ -404,7 +404,7 @@ from_validate_common(clicon_handle h,
goto done;
}
/* This is the state we are going to */
if (xmldb_get0(h, candidate, "/", 0, &td->td_target, NULL) < 0)
if (xmldb_get0(h, candidate, NULL, "/", 0, &td->td_target, NULL) < 0)
goto done;
/* Clear flags xpath for get */
@ -422,7 +422,7 @@ from_validate_common(clicon_handle h,
/* 2. Parse xml trees
* This is the state we are going from */
if (xmldb_get0(h, "running", "/", 0, &td->td_src, NULL) < 0)
if (xmldb_get0(h, "running", NULL, "/", 0, &td->td_src, NULL) < 0)
goto done;
/* Clear flags xpath for get */
xml_apply0(td->td_src, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset,

View file

@ -122,6 +122,7 @@ clixon_plugin_reset(clicon_handle h,
int
clixon_plugin_statedata(clicon_handle h,
yang_stmt *yspec,
cvec *nsc,
char *xpath,
cxobj **xret)
{
@ -136,7 +137,7 @@ clixon_plugin_statedata(clicon_handle h,
continue;
if ((x = xml_new("config", NULL, NULL)) == NULL)
goto done;
if (fn(h, xpath, x) < 0)
if (fn(h, nsc, xpath, x) < 0)
goto fail; /* Dont quit here on user callbacks */
if (xml_apply(x, CX_ELMNT, xml_spec_populate, yspec) < 0)
goto done;

View file

@ -71,7 +71,8 @@ int backend_plugin_initiate(clicon_handle h);
int clixon_plugin_reset(clicon_handle h, char *db);
int clixon_plugin_statedata(clicon_handle h, yang_stmt *yspec, char *xpath, cxobj **xtop);
int clixon_plugin_statedata(clicon_handle h, yang_stmt *yspec, cvec *nsc,
char *xpath, cxobj **xtop);
transaction_data_t * transaction_new(void);
int transaction_free(transaction_data_t *);

View file

@ -86,7 +86,7 @@ db_merge(clicon_handle h,
cxobj *xt = NULL;
/* Get data as xml from db1 */
if (xmldb_get0(h, (char*)db1, NULL, 0, &xt, NULL) < 0)
if (xmldb_get0(h, (char*)db1, NULL, NULL, 0, &xt, NULL) < 0)
goto done;
/* Merge xml into db2. Without commit */
retval = xmldb_put(h, (char*)db2, OP_MERGE, xt, clicon_username_get(h), cbret);
@ -339,7 +339,7 @@ startup_module_state(clicon_handle h,
goto ok;
/* Set up cache
* Now, access brief module cache with clicon_modst_cache_get(h, 1) */
if ((ret = yang_modules_state_get(h, yspec, NULL, 1, &x)) < 0)
if ((ret = yang_modules_state_get(h, yspec, NULL, NULL, 1, &x)) < 0)
goto done;
if (ret == 0)
goto fail;

View file

@ -680,15 +680,15 @@ compare_dbs(clicon_handle h,
astext = cv_int32_get(cvec_i(argv, 0));
else
astext = 0;
if (clicon_rpc_get_config(h, "running", "/", &xc1) < 0)
if (clicon_rpc_get_config(h, "running", "/", NULL, &xc1) < 0)
goto done;
if ((xerr = xpath_first(xc1, "/rpc-error")) != NULL){
if ((xerr = xpath_first(xc1, NULL, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto done;
}
if (clicon_rpc_get_config(h, "candidate", "/", &xc2) < 0)
if (clicon_rpc_get_config(h, "candidate", "/", NULL, &xc2) < 0)
goto done;
if ((xerr = xpath_first(xc2, "/rpc-error")) != NULL){
if ((xerr = xpath_first(xc2, NULL, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto done;
}
@ -847,13 +847,13 @@ save_config_file(clicon_handle h,
goto done;
}
filename = cv_string_get(cv);
if (clicon_rpc_get_config(h, dbstr,"/", &xt) < 0)
if (clicon_rpc_get_config(h, dbstr,"/", NULL, &xt) < 0)
goto done;
if (xt == NULL){
clicon_err(OE_CFG, 0, "get config: empty tree"); /* Shouldnt happen */
goto done;
}
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto done;
}
@ -961,7 +961,7 @@ cli_notification_cb(int s,
}
if (clicon_msg_decode(reply, NULL, &xt) < 0) /* XXX pass yang_spec */
goto done;
if ((xe = xpath_first(xt, "//event")) != NULL){
if ((xe = xpath_first(xt, NULL, "//event")) != NULL){
x = NULL;
while ((x = xml_child_each(xe, x, -1)) != NULL) {
switch (format){
@ -1110,14 +1110,15 @@ cli_unlock(clicon_handle h,
* @param[in] cvv Vector of variables from CLIgen command-line
* @param[in] argv Vector: <db>, <xpath>, <field>, <fromvar>, <tovar>
* Explanation of argv fields:
* db: Database name, eg candidate|tmp|startup
* xpath: XPATH expression with exactly two %s pointing to field and from name
* field: Name of list key, eg name
* fromvar:Name of variable containing name of object to copy from (given by xpath)
* tovar: Name of variable containing name of object to copy to.
* db: Database name, eg candidate|tmp|startup
* xpath: XPATH expression with exactly two %s pointing to field and from name
* namespace: XPATH default namespace
* field: Name of list key, eg name
* fromvar: Name of variable containing name of object to copy from (given by xpath)
* tovar: Name of variable containing name of object to copy to.
* @code
* cli spec:
* copy snd <n1:string> to <n2:string>, cli_copy_config("candidate", "/sender[%s='%s']", "from", "n1", "n2");
* copy snd <n1:string> to <n2:string>, cli_copy_config("candidate", "/sender[%s='%s']", "urn:example:clixon", "from", "n1", "n2");
* cli command:
* copy snd from to to
* @endcode
@ -1133,6 +1134,7 @@ cli_copy_config(clicon_handle h,
cxobj *x2 = NULL;
cxobj *x;
char *xpath;
char *namespace;
int i;
int j;
cbuf *cb = NULL;
@ -1144,21 +1146,24 @@ cli_copy_config(clicon_handle h,
cg_var *tocv;
char *toname;
cxobj *xerr;
cvec *nsc = NULL;
if (cvec_len(argv) != 5){
clicon_err(OE_PLUGIN, 0, "Requires four elements: <db> <xpath> <keyname> <from> <to>");
if (cvec_len(argv) != 6){
clicon_err(OE_PLUGIN, 0, "Requires 6 elements: <db> <xpath> <namespace> <keyname> <from> <to>");
goto done;
}
/* First argv argument: Database */
db = cv_string_get(cvec_i(argv, 0));
/* Second argv argument: xpath */
xpath = cv_string_get(cvec_i(argv, 1));
/* Third argv argument: namespace */
namespace = cv_string_get(cvec_i(argv, 2));
/* Third argv argument: name of keyname */
keyname = cv_string_get(cvec_i(argv, 2));
keyname = cv_string_get(cvec_i(argv, 3));
/* Fourth argv argument: from variable */
fromvar = cv_string_get(cvec_i(argv, 3));
fromvar = cv_string_get(cvec_i(argv, 4));
/* Fifth argv argument: to variable */
tovar = cv_string_get(cvec_i(argv, 4));
tovar = cv_string_get(cvec_i(argv, 5));
/* Get from variable -> cv -> from name */
if ((fromcv = cvec_find(cvv, fromvar)) == NULL){
@ -1184,9 +1189,9 @@ cli_copy_config(clicon_handle h,
}
cprintf(cb, xpath, keyname, fromname);
/* Get from object configuration and store in x1 */
if (clicon_rpc_get_config(h, db, cbuf_get(cb), &x1) < 0)
if (clicon_rpc_get_config(h, db, cbuf_get(cb), namespace, &x1) < 0)
goto done;
if ((xerr = xpath_first(x1, "/rpc-error")) != NULL){
if ((xerr = xpath_first(x1, NULL, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto done;
}
@ -1204,7 +1209,9 @@ cli_copy_config(clicon_handle h,
goto done;
xml_name_set(x2, "config");
cprintf(cb, "/%s", keyname);
if ((x = xpath_first(x2, "%s", cbuf_get(cb))) == NULL){
if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL)
goto done;
if ((x = xpath_first(x2, nsc, "%s", cbuf_get(cb))) == NULL){
clicon_err(OE_PLUGIN, 0, "Field %s not found in copy tree", keyname);
goto done;
}
@ -1218,6 +1225,8 @@ cli_copy_config(clicon_handle h,
goto done;
retval = 0;
done:
if (nsc)
xml_nsctx_free(nsc);
if (cb)
cbuf_free(cb);
if (x1 != NULL)

View file

@ -178,7 +178,7 @@ yang2cli_var_identityref(yang_stmt *ys,
char *helptext,
cbuf *cb)
{
int retval = -1;
int retval = -1;
yang_stmt *ybaseref;
yang_stmt *ybaseid;
cg_var *cv = NULL;

View file

@ -119,6 +119,8 @@ expand_dbvar(void *h,
cxobj *xcur;
char *xpathcur;
char *reason = NULL;
char *namespace = NULL;
cvec *nsc = NULL;
if (argv == NULL || cvec_len(argv) != 2){
clicon_err(OE_PLUGIN, 0, "requires arguments: <db> <xmlkeyfmt>");
@ -148,14 +150,14 @@ expand_dbvar(void *h,
--> ^/interface/eth0/address/.*$
--> /interface/[name="eth0"]/address
*/
if (api_path_fmt2xpath(api_path_fmt, cvv, &xpath) < 0)
goto done;
if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path) < 0)
goto done;
if (api_path2xpath(api_path, yspec, &xpath, &namespace) < 0)
goto done;
/* Get configuration */
if (clicon_rpc_get_config(h, dbstr, xpath, &xt) < 0)
if (clicon_rpc_get_config(h, dbstr, xpath, namespace, &xt) < 0) /* XXX */
goto done;
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto ok;
}
@ -172,6 +174,9 @@ expand_dbvar(void *h,
goto done;
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
* tree and apply the path to that.
@ -193,12 +198,12 @@ expand_dbvar(void *h,
fprintf(stderr, "%s\n", reason);
goto done;
}
if ((xcur = xpath_first(xt, "%s", xpath)) == NULL){
if ((xcur = xpath_first(xt, nsc, "%s", xpath)) == NULL){
clicon_err(OE_DB, 0, "xpath %s should return merged content", xpath);
goto done;
}
}
if (xpath_vec(xcur, "%s", &xvec, &xlen, xpathcur) < 0)
if (xpath_vec(xcur, nsc, "%s", &xvec, &xlen, xpathcur) < 0)
goto done;
bodystr0 = NULL; /* Assume sorted XML where duplicates are adjacent */
for (i = 0; i < xlen; i++) {
@ -217,6 +222,8 @@ expand_dbvar(void *h,
ok:
retval = 0;
done:
if (nsc)
xml_nsctx_free(nsc);
if (reason)
free(reason);
if (api_path)
@ -231,6 +238,7 @@ expand_dbvar(void *h,
free(xpath);
return retval;
}
int
expandv_dbvar(void *h,
char *name,
@ -241,6 +249,7 @@ expandv_dbvar(void *h,
{
return expand_dbvar(h, name, cvv, argv, commands, helptexts);
}
/*! List files in a directory
*/
int
@ -390,10 +399,10 @@ show_yang(clicon_handle h,
* Format of argv:
* <dbname> "running"|"candidate"|"startup" # note only running state=1
* <format> "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
* <xpath> xpath expression, that may contain one %, eg "/sender[name="%s"]"
* <varname> optional name of variable in cvv. If set, xpath must have a '%s'
* <xpath> xpath expression, that may contain one %, eg "/sender[name='foo']"
* <namespace> If xpath set, the namespace the symbols in xpath belong to (optional)
* @code
* show config id <n:string>, cli_show_config("running","xml","iface[name="%s"]","n");
* show config id <n:string>, cli_show_config("running","xml","iface[name='foo']","urn:example:example");
* @endcode
* @note if state parameter is set, then db must be running
*/
@ -409,16 +418,13 @@ cli_show_config1(clicon_handle h,
char *xpath;
enum format_enum format;
cbuf *cbxpath = NULL;
char *attr = NULL;
int i;
int j;
cg_var *cvattr;
char *val = NULL;
cxobj *xt = NULL;
cxobj *xc;
cxobj *xerr;
enum genmodel_type gt;
yang_stmt *yspec;
char *namespace = 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));
@ -441,33 +447,12 @@ cli_show_config1(clicon_handle h,
clicon_err(OE_PLUGIN, errno, "cbuf_new");
goto done;
}
/* Fourth argument is stdarg to xpath format string */
if (cvec_len(argv) == 4){
attr = cv_string_get(cvec_i(argv, 3));
j = 0;
for (i=0; i<strlen(xpath); i++)
if (xpath[i] == '%')
j++;
if (j != 1){
clicon_err(OE_PLUGIN, 0, "xpath '%s' does not have a single '%%'",
xpath);
goto done;
}
if ((cvattr = cvec_find(cvv, attr)) == NULL){
clicon_err(OE_PLUGIN, 0, "attr '%s' not found in cligen var list", attr);
goto done;
}
if ((val = cv2str_dup(cvattr)) == NULL){
clicon_err(OE_PLUGIN, errno, "cv2str_dup");
goto done;
}
cprintf(cbxpath, xpath, val);
}
else
cprintf(cbxpath, "%s", xpath);
cprintf(cbxpath, "%s", xpath);
/* Fourth argument is namespace */
if (cvec_len(argv) == 4)
namespace = cv_string_get(cvec_i(argv, 3));
if (state == 0){ /* Get configuration-only from database */
if (clicon_rpc_get_config(h, db, cbuf_get(cbxpath), &xt) < 0)
if (clicon_rpc_get_config(h, db, cbuf_get(cbxpath), namespace, &xt) < 0)
goto done;
}
else { /* Get configuration and state from database */
@ -475,10 +460,10 @@ 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), &xt) < 0)
if (clicon_rpc_get(h, cbuf_get(cbxpath), namespace, &xt) < 0)
goto done;
}
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto done;
}
@ -540,9 +525,9 @@ done:
* <dbname> "running"|"candidate"|"startup"
* <format> "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
* <xpath> xpath expression, that may contain one %, eg "/sender[name="%s"]"
* <varname> optional name of variable in cvv. If set, xpath must have a '%s'
* <namespace> If xpath set, the namespace the symbols in xpath belong to (optional)
* @code
* show config id <n:string>, cli_show_config("running","xml","iface[name="%s"]","n");
* show config id <n:string>, cli_show_config("running","xml","iface[name='foo']","urn:example:example");
* @endcode
* @see cli_show_config_state For config and state data (not only config)
*/
@ -565,7 +550,7 @@ cli_show_config(clicon_handle h,
* <xpath> xpath expression, that may contain one %, eg "/sender[name="%s"]"
* <varname> optional name of variable in cvv. If set, xpath must have a '%s'
* @code
* show config id <n:string>, cli_show_config_state("running","xml","iface[name="%s"]","n");
* show state id <n:string>, cli_show_config_state("running","xml","iface[name='foo']","urn:example:example");
* @endcode
* @see cli_show_config For config-only, no state
*/
@ -580,9 +565,9 @@ cli_show_config_state(clicon_handle h,
/*! Show configuration as text given an xpath
* Utility function used by cligen spec file
* @param[in] h CLICON handle
* @param[in] cvv Vector of variables from CLIgen command-line
* @param[in] arg A string: <dbname> <xpath>
* @note Hardcoded that a variable in cvv is named "xpath"
* @param[in] cvv Vector of variables from CLIgen command-line must contain xpath and ns variables
* @param[in] argv A string: <dbname>
* @note Hardcoded that variable xpath and ns cvv must exist. (kludge)
*/
int
show_conf_xpath(clicon_handle h,
@ -598,6 +583,8 @@ show_conf_xpath(clicon_handle h,
cxobj **xv = NULL;
size_t xlen;
int i;
char *namespace = NULL;
cvec *nsc = NULL;
if (cvec_len(argv) != 1){
clicon_err(OE_PLUGIN, 0, "Requires one element to be <dbname>");
@ -611,21 +598,31 @@ show_conf_xpath(clicon_handle h,
clicon_err(OE_PLUGIN, 0, "No such db name: %s", str);
goto done;
}
/* Look for xpath in command (kludge: cv must be called "xpath") */
cv = cvec_find(cvv, "xpath");
xpath = cv_string_get(cv);
if (clicon_rpc_get_config(h, str, xpath, &xt) < 0)
/* 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)
goto done;
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto done;
}
if (xpath_vec(xt, "%s", &xv, &xlen, xpath) < 0)
if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL)
goto done;
if (xpath_vec(xt, nsc, "%s", &xv, &xlen, xpath) < 0)
goto done;
for (i=0; i<xlen; i++)
xml_print(stdout, xv[i]);
retval = 0;
done:
if (nsc)
xml_nsctx_free(nsc);
if (xv)
free(xv);
if (xt)
@ -641,7 +638,7 @@ int cli_show_version(clicon_handle h,
return 0;
}
/*! Generic show configuration CLIGEN callback using generated CLI syntax
/*! Generic show configuration CLIgen callback using generated CLI syntax
* @param[in] h CLICON handle
* @param[in] state If set, show both config and state, otherwise only config
* @param[in] cvv Vector of variables from CLIgen command-line
@ -651,6 +648,7 @@ int cli_show_version(clicon_handle h,
* <dbname> "running"|"candidate"|"startup"
* <format> "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
* @note if state parameter is set, then db must be running
* @note that first argument is generated by code.
*/
static int
cli_show_auto1(clicon_handle h,
@ -664,12 +662,15 @@ cli_show_auto1(clicon_handle h,
// char *api_path = NULL; /* xml key */
char *db;
char *xpath = NULL;
cvec *nsc = NULL;
char *formatstr;
enum format_enum format = FORMAT_XML;
cxobj *xt = NULL;
cxobj *xp;
cxobj *xerr;
enum genmodel_type gt;
char *namespace = NULL;
char *api_path = NULL;
if (cvec_len(argv) != 3){
clicon_err(OE_PLUGIN, 0, "Usage: <api-path-fmt>* <database> <format>. (*) generated.");
@ -689,19 +690,20 @@ cli_show_auto1(clicon_handle h,
clicon_err(OE_FATAL, 0, "No DB_SPEC");
goto done;
}
// if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path) < 0)
// goto done;
if (api_path_fmt2xpath(api_path_fmt, cvv, &xpath) < 0)
if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path) < 0)
goto done;
if (api_path2xpath(api_path, yspec, &xpath, &namespace) < 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, &xt) < 0)
if (clicon_rpc_get_config(h, db, xpath, namespace, &xt) < 0)
goto done;
}
else{ /* Get configuration and state from database */
@ -709,15 +711,15 @@ 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, &xt) < 0)
if (clicon_rpc_get(h, xpath, namespace, &xt) < 0)
goto done;
}
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto done;
}
if ((xp = xpath_first(xt, "%s", xpath)) != NULL)
if ((xp = xpath_first(xt, nsc, "%s", xpath)) != NULL)
/* Print configuration according to format */
switch (format){
case FORMAT_XML:
@ -744,6 +746,10 @@ cli_show_auto1(clicon_handle h,
}
retval = 0;
done:
if (nsc)
xml_nsctx_free(nsc);
if (api_path)
free(api_path);
if (xpath)
free(xpath);
if (xt)

View file

@ -100,7 +100,7 @@ netconf_hello_dispatch(cxobj *xn)
cxobj *xp;
int retval = -1;
if ((xp = xpath_first(xn, "//hello")) != NULL)
if ((xp = xpath_first(xn, NULL, "//hello")) != NULL)
retval = netconf_hello(xp);
return retval;
}

View file

@ -164,14 +164,14 @@ netconf_get_target(cxobj *xn,
cxobj *x;
char *target = NULL;
if ((x = xpath_first(xn, "%s", path)) != NULL){
if (xpath_first(x, "candidate") != NULL)
if ((x = xpath_first(xn, NULL, "%s", path)) != NULL){
if (xpath_first(x, NULL, "candidate") != NULL)
target = "candidate";
else
if (xpath_first(x, "running") != NULL)
if (xpath_first(x, NULL, "running") != NULL)
target = "running";
else
if (xpath_first(x, "startup") != NULL)
if (xpath_first(x, NULL, "startup") != NULL)
target = "startup";
}
return target;

View file

@ -121,7 +121,7 @@ netconf_input_packet(clicon_handle h,
goto done;
}
free(str0);
if ((xrpc=xpath_first(xreq, "//rpc")) != NULL){
if ((xrpc=xpath_first(xreq, NULL, "//rpc")) != NULL){
isrpc++;
if (xml_spec_populate_rpc(h, xrpc, yspec) < 0)
goto done;
@ -134,7 +134,7 @@ netconf_input_packet(clicon_handle h,
}
}
else
if (xpath_first(xreq, "//hello") != NULL)
if (xpath_first(xreq, NULL, "//hello") != NULL)
;
else{
clicon_log(LOG_WARNING, "Invalid netconf msg: neither rpc or hello: dropped");

View file

@ -140,7 +140,7 @@ netconf_get_config(clicon_handle h,
cxobj *xconf;
/* ie <filter>...</filter> */
if ((xfilter = xpath_first(xn, "filter")) != NULL)
if ((xfilter = xpath_first(xn, NULL, "filter")) != NULL)
ftype = xml_find_value(xfilter, "type");
if (ftype == NULL || strcmp(ftype, "xpath")==0){
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
@ -154,8 +154,8 @@ netconf_get_config(clicon_handle h,
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
goto done;
if (xfilter &&
(xfilterconf = xpath_first(xfilter, "//configuration"))!= NULL &&
(xconf = xpath_first(*xret, "/rpc-reply/data")) != NULL){
(xfilterconf = xpath_first(xfilter, NULL, "//configuration"))!= NULL &&
(xconf = xpath_first(*xret, NULL, "/rpc-reply/data")) != NULL){
/* xml_filter removes parts of xml tree not matching */
if ((strcmp(xml_name(xfilterconf), xml_name(xconf))!=0) ||
xml_filter(xfilterconf, xconf) < 0){
@ -208,7 +208,7 @@ get_edit_opts(cxobj *xn,
cxobj *x;
char *optstr;
if ((x = xpath_first(xn, "test-option")) != NULL){
if ((x = xpath_first(xn, NULL, "test-option")) != NULL){
if ((optstr = xml_body(x)) != NULL){
if (strcmp(optstr, "test-then-set") == 0)
*testopt = TEST_THEN_SET;
@ -220,7 +220,7 @@ get_edit_opts(cxobj *xn,
goto parerr;
}
}
if ((x = xpath_first(xn, "error-option")) != NULL){
if ((x = xpath_first(xn, NULL, "error-option")) != NULL){
if ((optstr = xml_body(x)) != NULL){
if (strcmp(optstr, "stop-on-error") == 0)
*erropt = STOP_ON_ERROR;
@ -352,7 +352,7 @@ netconf_get(clicon_handle h,
cxobj *xconf;
/* ie <filter>...</filter> */
if ((xfilter = xpath_first(xn, "filter")) != NULL)
if ((xfilter = xpath_first(xn, NULL, "filter")) != NULL)
ftype = xml_find_value(xfilter, "type");
if (ftype == NULL || strcmp(ftype, "xpath")==0){
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
@ -366,8 +366,8 @@ netconf_get(clicon_handle h,
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
goto done;
if (xfilter &&
(xfilterconf = xpath_first(xfilter, "//configuration"))!= NULL &&
(xconf = xpath_first(*xret, "/rpc-reply/data")) != NULL){
(xfilterconf = xpath_first(xfilter, NULL, "//configuration"))!= NULL &&
(xconf = xpath_first(*xret, NULL, "/rpc-reply/data")) != NULL){
/* xml_filter removes parts of xml tree not matching */
if ((strcmp(xml_name(xfilterconf), xml_name(xconf))!=0) ||
xml_filter(xfilterconf, xconf) < 0){
@ -428,6 +428,7 @@ netconf_notification_cb(int s,
cxobj *xt = NULL; /* top xml */
clicon_handle h = (clicon_handle)arg;
yang_stmt *yspec = NULL;
cvec *nsc = NULL;
clicon_debug(1, "%s", __FUNCTION__);
/* get msg (this is the reason this function is called) */
@ -444,7 +445,10 @@ netconf_notification_cb(int s,
yspec = clicon_dbspec_yang(h);
if (clicon_msg_decode(reply, yspec, &xt) < 0)
goto done;
if ((xn = xpath_first(xt, "notification")) == NULL)
if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:netconf:notification:1.0")) == NULL)
goto done;
if ((xn = xpath_first(xt, nsc, "notification")) == NULL)
goto ok;
/* create netconf message */
if ((cb = cbuf_new()) == NULL){
@ -460,9 +464,11 @@ netconf_notification_cb(int s,
}
fflush(stdout);
cbuf_free(cb);
ok:
ok:
retval = 0;
done:
done:
if (nsc)
xml_nsctx_free(nsc);
if (xt != NULL)
xml_free(xt);
if (reply)
@ -494,7 +500,7 @@ netconf_create_subscription(clicon_handle h,
int s;
char *ftype;
if ((xfilter = xpath_first(xn, "//filter")) != NULL){
if ((xfilter = xpath_first(xn, NULL, "//filter")) != NULL){
if ((ftype = xml_find_value(xfilter, "type")) != NULL){
if (strcmp(ftype, "xpath") != 0){
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
@ -510,7 +516,7 @@ netconf_create_subscription(clicon_handle h,
}
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, &s) < 0)
goto done;
if (xpath_first(*xret, "rpc-reply/rpc-error") != NULL)
if (xpath_first(*xret, NULL, "rpc-reply/rpc-error") != NULL)
goto ok;
if (event_reg_fd(s,
netconf_notification_cb,
@ -616,7 +622,7 @@ netconf_application_rpc(clicon_handle h,
*/
if (0)
if ((youtput = yang_find(yrpc, Y_OUTPUT, NULL)) != NULL){
xoutput=xpath_first(*xret, "/");
xoutput=xpath_first(*xret, NULL, "/");
xml_spec_set(xoutput, youtput); /* needed for xml_spec_populate */
if (xml_apply(xoutput, CX_ELMNT, xml_spec_populate, yspec) < 0)
goto done;

View file

@ -412,7 +412,7 @@ api_return_err(clicon_handle h,
clicon_debug(1, "%s", __FUNCTION__);
if ((cb = cbuf_new()) == NULL)
goto done;
if ((xtag = xpath_first(xerr, "//error-tag")) == NULL){
if ((xtag = xpath_first(xerr, NULL, "//error-tag")) == NULL){
notfound(r);
goto ok;
}

View file

@ -396,7 +396,7 @@ api_restconf(clicon_handle h,
else{
if (netconf_access_denied_xml(&xret, "protocol", "The requested URL was unauthorized") < 0)
goto done;
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
if (api_return_err(h, r, xerr, pretty, use_xml) < 0)
goto done;
goto ok;

View file

@ -186,7 +186,7 @@ api_data_get2(clicon_handle h,
{
int retval = -1;
cbuf *cbpath = NULL;
char *path;
char *xpath = NULL;
cbuf *cbx = NULL;
yang_stmt *yspec;
cxobj *xret = NULL;
@ -197,6 +197,8 @@ api_data_get2(clicon_handle h,
int i;
cxobj *x;
int ret;
char *namespace = NULL;
cvec *nsc = NULL;
clicon_debug(1, "%s", __FUNCTION__);
yspec = clicon_dbspec_yang(h);
@ -204,13 +206,13 @@ api_data_get2(clicon_handle h,
goto done;
cprintf(cbpath, "/");
/* We know "data" is element pi-1 */
if ((ret = api_path2xpath(yspec, pcvec, pi, cbpath)) < 0)
if ((ret = api_path2xpath_cvv(pcvec, pi, yspec, cbpath, &namespace)) < 0)
goto done;
if (ret == 0){
if (netconf_operation_failed_xml(&xerr, "protocol", clicon_err_reason) < 0)
goto done;
clicon_err_reset();
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -218,12 +220,16 @@ api_data_get2(clicon_handle h,
goto done;
goto ok;
}
path = cbuf_get(cbpath);
clicon_debug(1, "%s path:%s", __FUNCTION__, path);
if (clicon_rpc_get(h, path, &xret) < 0){
xpath = cbuf_get(cbpath);
clicon_debug(1, "%s path:%s", __FUNCTION__, xpath);
/* Create a namespace context for ymod as the default namespace to use with
* xpath expressions */
if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL)
goto done;
if (clicon_rpc_get(h, xpath, namespace, &xret) < 0){
if (netconf_operation_failed_xml(&xerr, "protocol", clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -245,7 +251,7 @@ api_data_get2(clicon_handle h,
}
#endif
/* Check if error return */
if ((xe = xpath_first(xret, "//rpc-error")) != NULL){
if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
goto done;
goto ok;
@ -259,7 +265,7 @@ api_data_get2(clicon_handle h,
FCGX_FPrintF(r->out, "\r\n");
goto ok;
}
if (path==NULL || strcmp(path,"/")==0){ /* Special case: data root */
if (xpath==NULL || strcmp(xpath,"/")==0){ /* Special case: data root */
if (use_xml){
if (clicon_xml2cbuf(cbx, xret, 0, pretty) < 0) /* Dont print top object? */
goto done;
@ -270,10 +276,10 @@ api_data_get2(clicon_handle h,
}
}
else{
if (xpath_vec(xret, "%s", &xvec, &xlen, path) < 0){
if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath) < 0){
if (netconf_operation_failed_xml(&xerr, "application", clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -283,14 +289,14 @@ api_data_get2(clicon_handle h,
}
if (use_xml){
for (i=0; i<xlen; i++){
char *prefix, *namespace;
char *prefix, *namespace2; /* Same as namespace? */
x = xvec[i];
/* Some complexities in grafting namespace in existing trees to new */
prefix = xml_prefix(x);
if (xml_find_type_value(x, prefix, "xmlns", CX_ATTR) == NULL){
if (xml2ns(x, prefix, &namespace) < 0)
if (xml2ns(x, prefix, &namespace2) < 0)
goto done;
if (namespace && xmlns_set(x, prefix, namespace) < 0)
if (namespace2 && xmlns_set(x, prefix, namespace2) < 0)
goto done;
}
if (clicon_xml2cbuf(cbx, x, 0, pretty) < 0) /* Dont print top object? */
@ -315,6 +321,8 @@ api_data_get2(clicon_handle h,
retval = 0;
done:
clicon_debug(1, "%s retval:%d", __FUNCTION__, retval);
if (nsc)
xml_nsctx_free(nsc);
if (cbx)
cbuf_free(cbx);
if (cbpath)
@ -483,7 +491,7 @@ api_data_post(clicon_handle h,
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
clicon_err_reset();
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -497,7 +505,7 @@ api_data_post(clicon_handle h,
if (xml_parse_string(data, NULL, &xdata0) < 0){
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -510,7 +518,7 @@ api_data_post(clicon_handle h,
if ((ret = json_parse_str(data, yspec, &xdata0, &xerr)) < 0){
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -519,7 +527,7 @@ api_data_post(clicon_handle h,
goto ok;
}
if (ret == 0){
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -534,7 +542,7 @@ api_data_post(clicon_handle h,
if (xml_child_nr(xdata0) != 1){
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -556,7 +564,7 @@ api_data_post(clicon_handle h,
if (ymoddata != ymodapi){
if (netconf_malformed_message_xml(&xerr, "Data is not prefixed with matching namespace") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -598,7 +606,7 @@ api_data_post(clicon_handle h,
clicon_debug(1, "%s xml: %s api_path:%s",__FUNCTION__, cbuf_get(cbx), api_path);
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0)
goto done;
if ((xe = xpath_first(xret, "//rpc-error")) != NULL){
if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
goto done;
goto ok;
@ -612,14 +620,14 @@ api_data_post(clicon_handle h,
cprintf(cbx, "<commit/></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
goto done;
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
cbuf_reset(cbx);
cprintf(cbx, "<rpc username=\"%s\">", username?username:"");
cprintf(cbx, "<discard-changes/></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretdis, NULL) < 0)
goto done;
/* log errors from discard, but ignore */
if ((xpath_first(xretdis, "//rpc-error")) != NULL)
if ((xpath_first(xretdis, NULL, "//rpc-error")) != NULL)
clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__);
if (api_return_err(h, r, xe, pretty, use_xml) < 0) /* Use original xe */
goto done;
@ -642,7 +650,7 @@ api_data_post(clicon_handle h,
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
goto done;
/* If copy-config failed, log and ignore (already committed) */
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__);
}
@ -831,7 +839,7 @@ api_data_put(clicon_handle h,
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
clicon_err_reset();
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -846,7 +854,7 @@ api_data_put(clicon_handle h,
if (xml_parse_string(data, yspec, &xdata0) < 0){
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -859,7 +867,7 @@ api_data_put(clicon_handle h,
if ((ret = json_parse_str(data, yspec, &xdata0, &xerr)) < 0){
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -868,7 +876,7 @@ api_data_put(clicon_handle h,
goto ok;
}
if (ret == 0){
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -883,7 +891,7 @@ api_data_put(clicon_handle h,
if (xml_child_nr(xdata0) != 1){
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -903,7 +911,7 @@ api_data_put(clicon_handle h,
if (ymoddata != ymodapi){
if (netconf_malformed_message_xml(&xerr, "Data is not prefixed with matching namespace") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -943,7 +951,7 @@ api_data_put(clicon_handle h,
if (strcmp(dname, xml_name(xbot))){
if (netconf_operation_failed_xml(&xerr, "protocol", "Not same symbol in api-path as data") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -968,7 +976,7 @@ api_data_put(clicon_handle h,
if (match_list_keys(ybot, xdata, xbot) < 0){
if (netconf_operation_failed_xml(&xerr, "protocol", "api-path keys do not match data keys") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -992,7 +1000,7 @@ api_data_put(clicon_handle h,
if (parbod == NULL || strcmp(parbod, xml_body(xdata))){
if (netconf_operation_failed_xml(&xerr, "protocol", "api-path keys do not match data keys") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -1032,7 +1040,7 @@ api_data_put(clicon_handle h,
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0)
goto done;
if ((xe = xpath_first(xret, "//rpc-error")) != NULL){
if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
goto done;
goto ok;
@ -1045,14 +1053,14 @@ api_data_put(clicon_handle h,
cprintf(cbx, "<commit/></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
goto done;
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
cbuf_reset(cbx);
cprintf(cbx, "<rpc username=\"%s\">", username?username:"");
cprintf(cbx, "<discard-changes/></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretdis, NULL) < 0)
goto done;
/* log errors from discard, but ignore */
if ((xpath_first(xretdis, "//rpc-error")) != NULL)
if ((xpath_first(xretdis, NULL, "//rpc-error")) != NULL)
clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__);
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
goto done;
@ -1075,7 +1083,7 @@ api_data_put(clicon_handle h,
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
goto done;
/* If copy-config failed, log and ignore (already committed) */
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__);
}
@ -1183,7 +1191,7 @@ api_data_delete(clicon_handle h,
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
clicon_err_reset();
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -1210,7 +1218,7 @@ api_data_delete(clicon_handle h,
cprintf(cbx, "</edit-config></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0)
goto done;
if ((xe = xpath_first(xret, "//rpc-error")) != NULL){
if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
goto done;
goto ok;
@ -1224,14 +1232,14 @@ api_data_delete(clicon_handle h,
cprintf(cbx, "<commit/></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
goto done;
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
cbuf_reset(cbx);
cprintf(cbx, "<rpc username=\"%s\">", NACM_RECOVERY_USER);
cprintf(cbx, "<discard-changes/></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretdis, NULL) < 0)
goto done;
/* log errors from discard, but ignore */
if ((xpath_first(xretdis, "//rpc-error")) != NULL)
if ((xpath_first(xretdis, NULL, "//rpc-error")) != NULL)
clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__);
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
goto done;
@ -1254,7 +1262,7 @@ api_data_delete(clicon_handle h,
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
goto done;
/* If copy-config failed, log and ignore (already committed) */
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__);
}
@ -1421,7 +1429,7 @@ api_operations_post_input(clicon_handle h,
if (xml_parse_string(data, yspec, &xdata) < 0){
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -1434,7 +1442,7 @@ api_operations_post_input(clicon_handle h,
if ((ret = json_parse_str(data, yspec, &xdata, &xerr)) < 0){
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -1443,7 +1451,7 @@ api_operations_post_input(clicon_handle h,
goto fail;
}
if (ret == 0){
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -1476,7 +1484,7 @@ api_operations_post_input(clicon_handle h,
else
if (netconf_malformed_message_xml(&xerr, "restconf RPC has malformed input statement (multiple or not called input)") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -1550,7 +1558,7 @@ api_operations_post_output(clicon_handle h,
xml_child_nr_type(xret, CX_ELMNT) != 1){
if (netconf_malformed_message_xml(&xerr, "restconf RPC does not have single input") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -1587,7 +1595,7 @@ api_operations_post_output(clicon_handle h,
(ret = xml_yang_validate_add(h, xoutput, &xerr)) < 0)
goto done;
if (ret == 0){ /* validation failed */
if ((xe = xpath_first(xerr, "rpc-reply/rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-reply/rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -1720,7 +1728,7 @@ api_operations_post(clicon_handle h,
if (oppath == NULL || strcmp(oppath,"/")==0){
if (netconf_operation_failed_xml(&xerr, "protocol", "Operation name expected") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -1739,7 +1747,7 @@ api_operations_post(clicon_handle h,
if ((ys = yang_find(yspec, Y_MODULE, prefix)) == NULL){
if (netconf_operation_failed_xml(&xerr, "protocol", "yang module not found") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -1750,7 +1758,7 @@ api_operations_post(clicon_handle h,
if ((yrpc = yang_find(ys, Y_RPC, id)) == NULL){
if (netconf_missing_element_xml(&xerr, "application", id, "RPC not defined") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -1779,7 +1787,7 @@ api_operations_post(clicon_handle h,
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
clicon_err_reset();
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -1819,7 +1827,7 @@ api_operations_post(clicon_handle h,
if ((ret = xml_yang_validate_rpc(h, xtop, &xret)) < 0)
goto done;
if (ret == 0){
if ((xe = xpath_first(xret, "rpc-error")) == NULL){
if ((xe = xpath_first(xret, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto ok;
}
@ -1851,7 +1859,7 @@ api_operations_post(clicon_handle h,
if (xml_parse_string(cbuf_get(cbret), NULL, &xret) < 0)
goto done;
/* Local error: return it and quit */
if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) != NULL){
if ((xe = xpath_first(xret, NULL, "rpc-reply/rpc-error")) != NULL){
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
goto done;
goto ok;
@ -1860,7 +1868,7 @@ api_operations_post(clicon_handle h,
else { /* Send to backend */
if (clicon_rpc_netconf_xml(h, xtop, &xret, NULL) < 0)
goto done;
if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) != NULL){
if ((xe = xpath_first(xret, NULL, "rpc-reply/rpc-error")) != NULL){
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
goto done;
goto ok;

View file

@ -187,11 +187,11 @@ restconf_stream_cb(int s,
clicon_err(OE_PLUGIN, errno, "cbuf_new");
goto done;
}
if ((xn = xpath_first(xtop, "notification")) == NULL)
if ((xn = xpath_first(xtop, NULL, "notification")) == NULL)
goto ok;
#ifdef notused
xt = xpath_first(xn, "eventTime");
if ((xe = xpath_first(xn, "event")) == NULL) /* event can depend on yang? */
xt = xpath_first(xn, NULL, "eventTime");
if ((xe = xpath_first(xn, NULL, "event")) == NULL) /* event can depend on yang? */
goto ok;
if (xt)
@ -268,7 +268,7 @@ restconf_stream(clicon_handle h,
cprintf(cb, "</create-subscription></rpc>]]>]]>");
if (clicon_rpc_netconf(h, cbuf_get(cb), &xret, &s) < 0)
goto done;
if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) != NULL){
if ((xe = xpath_first(xret, NULL, "rpc-reply/rpc-error")) != NULL){
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
goto done;
goto ok;
@ -416,7 +416,7 @@ api_stream(clicon_handle h,
else{
if (netconf_access_denied_xml(&xret, "protocol", "The requested URL was unauthorized") < 0)
goto done;
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
if (api_return_err(h, r, xerr, pretty, use_xml) < 0)
goto done;
goto ok;