Corrected error message for list min/max-value to comply to RFC 7950: a proper path is now returned, peviously only the list symbol. it is also exposed in the CLI correctly.
* Example: `<error-path>/c/a1</error-path>`
This commit is contained in:
parent
a3e80080e2
commit
558abb1f9b
5 changed files with 49 additions and 28 deletions
|
|
@ -1173,19 +1173,23 @@ netconf_data_not_unique_xml(cxobj **xret,
|
|||
/*! Create Netconf too-many/few-elements err msg according to RFC 7950 15.2/15.3
|
||||
*
|
||||
* A NETCONF operation would result in configuration data where a
|
||||
list or a leaf-list would have too many entries, the following error
|
||||
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||
* @param[in] x List element containing duplicate
|
||||
* list or a leaf-list would have too many entries, the following error
|
||||
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||
* @param[in] xp XML parent node (for error)
|
||||
* @param[in] name Name of list (for error)
|
||||
* @param[in] max If set, return too-many, otherwise too-few
|
||||
* @see RFC7950 Sec 15.1
|
||||
*/
|
||||
int
|
||||
netconf_minmax_elements_xml(cxobj **xret,
|
||||
cxobj *x,
|
||||
cxobj *xp,
|
||||
char *name,
|
||||
int max)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *xerr;
|
||||
char *path = NULL;
|
||||
cbuf *cb = NULL;
|
||||
|
||||
if (*xret == NULL){
|
||||
if ((*xret = xml_new("rpc-reply", NULL, CX_ELMNT)) == NULL)
|
||||
|
|
@ -1195,16 +1199,31 @@ netconf_minmax_elements_xml(cxobj **xret,
|
|||
goto done;
|
||||
if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
if ((cb = cbuf_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
if (xml_parent(xp)){ /* Dont include root, eg <config> */
|
||||
if (xml2xpath(xp, &path) < 0)
|
||||
goto done;
|
||||
if (path)
|
||||
cprintf(cb, "%s", path);
|
||||
}
|
||||
cprintf(cb, "/%s", name);
|
||||
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-type>protocol</error-type>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-app-tag>too-%s-elements</error-app-tag>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-path>%s</error-path>",
|
||||
max?"many":"few",
|
||||
xml_name(x)) < 0) /* XXX should be xml2xpath */
|
||||
cbuf_get(cb)) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
if (path)
|
||||
free(path);
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -1381,6 +1400,8 @@ netconf_err2cb(cxobj *xerr,
|
|||
clicon_xml2cbuf(cberr, xml_child_i(x,0), 0, 0, -1);
|
||||
if ((x=xpath_first(xerr, NULL, "//error-app-tag"))!=NULL)
|
||||
cprintf(cberr, ": %s ", xml_body(x));
|
||||
if ((x=xpath_first(xerr, NULL, "//error-path"))!=NULL)
|
||||
cprintf(cberr, ": %s ", xml_body(x));
|
||||
retval = 0;
|
||||
return retval;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -694,17 +694,17 @@ check_unique_list(cxobj *x,
|
|||
}
|
||||
|
||||
/*! Given a list, check if any min/max-elemants constraints apply
|
||||
* @param[in] x One x (the last) of a specific lis
|
||||
* @param[in] y Yang spec of x
|
||||
* @param[in] nr Number of elements (like x) in thlist
|
||||
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||
* @param[in] xp Parent of the xml list there are too few/many
|
||||
* @param[in] y Yang spec of the failing list
|
||||
* @param[in] nr Number of elements (like x) in thlist
|
||||
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||
* @retval 1 Validation OK
|
||||
* @retval 0 Validation failed (cbret set)
|
||||
* @retval -1 Error
|
||||
* @see RFC7950 7.7.5
|
||||
*/
|
||||
static int
|
||||
check_min_max(cxobj *x,
|
||||
check_min_max(cxobj *xp,
|
||||
yang_stmt *y,
|
||||
int nr,
|
||||
cxobj **xret)
|
||||
|
|
@ -717,7 +717,7 @@ check_min_max(cxobj *x,
|
|||
if ((ymin = yang_find(y, Y_MIN_ELEMENTS, NULL)) != NULL){
|
||||
cv = yang_cv_get(ymin);
|
||||
if (nr < cv_uint32_get(cv)){
|
||||
if (netconf_minmax_elements_xml(xret, x, 0) < 0)
|
||||
if (netconf_minmax_elements_xml(xret, xp, yang_argument_get(y), 0) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -726,7 +726,7 @@ check_min_max(cxobj *x,
|
|||
cv = yang_cv_get(ymax);
|
||||
if (cv_uint32_get(cv) > 0 && /* 0 means unbounded */
|
||||
nr > cv_uint32_get(cv)){
|
||||
if (netconf_minmax_elements_xml(xret, x, 1) < 0)
|
||||
if (netconf_minmax_elements_xml(xret, xp, yang_argument_get(y), 1) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -787,10 +787,9 @@ check_list_unique_minmax(cxobj *xt,
|
|||
yang_stmt *y;
|
||||
yang_stmt *yt;
|
||||
yang_stmt *yprev = NULL; /* previous in list */
|
||||
yang_stmt *ye = NULL; /* yang each list to catch emtpy */
|
||||
yang_stmt *ych; /* y:s parent node (if choice that ye can compare to) */
|
||||
cxobj *xp = NULL; /* previous in list */
|
||||
yang_stmt *yu; /* yang unique */
|
||||
yang_stmt *ye = NULL; /* yang each list to catch emtpy */
|
||||
yang_stmt *ych; /* y:s parent node (if choice that ye can compare to) */
|
||||
yang_stmt *yu; /* yang unique */
|
||||
int ret;
|
||||
int nr=0; /* Nr of list elements for min/max check */
|
||||
enum rfc_6020 keyw;
|
||||
|
|
@ -818,7 +817,7 @@ check_list_unique_minmax(cxobj *xt,
|
|||
/* Only lists and leaf-lists are allowed to be many
|
||||
* This checks duplicate container and leafs
|
||||
*/
|
||||
if (netconf_minmax_elements_xml(xret, x, 1) < 0)
|
||||
if (netconf_minmax_elements_xml(xret, xt, xml_name(x), 1) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -832,14 +831,13 @@ check_list_unique_minmax(cxobj *xt,
|
|||
}
|
||||
else {
|
||||
/* Check if the list length violates min/max */
|
||||
if ((ret = check_min_max(xp, yprev, nr, xret)) < 0)
|
||||
if ((ret = check_min_max(xt, yprev, nr, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
yprev = y; /* Restart min/max count */
|
||||
xp = x; /* Need a reference to the XML as well */
|
||||
nr = 1;
|
||||
/* Gap analysis: Check if there is any empty list between y and yprev
|
||||
* Note, does not detect empty choice list (too complicated)
|
||||
|
|
@ -884,7 +882,7 @@ check_list_unique_minmax(cxobj *xt,
|
|||
*/
|
||||
if (yprev){
|
||||
/* Check if the list length violates min/max */
|
||||
if ((ret = check_min_max(xp, yprev, nr, xret)) < 0)
|
||||
if ((ret = check_min_max(xt, yprev, nr, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue