Added error handling in yang_path_arg triggered by no filter in get paginated
Fixed cornercase of restconf error return when no body Fixed cornercase when exactly / given as xpath Better error message when YANG not found: added which YANG file imports it
This commit is contained in:
parent
a4b4dc97ce
commit
2dcc14a0db
9 changed files with 39 additions and 14 deletions
|
|
@ -467,7 +467,7 @@ get_list_pagination(clicon_handle h,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Check if list/leaf-list */
|
/* Check if list/leaf-list */
|
||||||
if (yang_path_arg(yspec, xpath, &ylist) < 0)
|
if (yang_path_arg(yspec, xpath?xpath:"/", &ylist) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ylist == NULL){
|
if (ylist == NULL){
|
||||||
if ((cbmsg = cbuf_new()) == NULL){
|
if ((cbmsg = cbuf_new()) == NULL){
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t pd_offset; /* Start of pagination interval */
|
uint32_t pd_offset; /* Start of pagination interval */
|
||||||
uint32_t pd_limit; /* Number of elemenents (limit) */
|
uint32_t pd_limit; /* Number of elements (limit) */
|
||||||
int pd_locked; /* Running datastore is locked by this caller */
|
int pd_locked; /* Running datastore is locked by this caller */
|
||||||
cxobj *pd_xstate; /* Returned xml state tree */
|
cxobj *pd_xstate; /* Returned xml state tree */
|
||||||
} pagination_data_t;
|
} pagination_data_t;
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,6 @@ transaction_log(clicon_handle h,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Get pagination data: offset parameter
|
/*! Get pagination data: offset parameter
|
||||||
*
|
*
|
||||||
* @param[in] pd Pagination userdata
|
* @param[in] pd Pagination userdata
|
||||||
|
|
|
||||||
|
|
@ -487,7 +487,7 @@ http2_exec(restconf_conn *rc,
|
||||||
* (Successful) response to a CONNECT request (Section 4.3.6 of
|
* (Successful) response to a CONNECT request (Section 4.3.6 of
|
||||||
* [RFC7231]).
|
* [RFC7231]).
|
||||||
*/
|
*/
|
||||||
if (sd->sd_code != 204 && sd->sd_code > 199)
|
if (sd->sd_code != 204 && sd->sd_code > 199 && sd->sd_body_len)
|
||||||
if (restconf_reply_header(sd, "Content-Length", "%zu", sd->sd_body_len) < 0)
|
if (restconf_reply_header(sd, "Content-Length", "%zu", sd->sd_body_len) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (sd->sd_code){
|
if (sd->sd_code){
|
||||||
|
|
|
||||||
|
|
@ -526,6 +526,10 @@ xpath_parse(const char *xpath,
|
||||||
clixon_xpath_yacc xpy = {0,};
|
clixon_xpath_yacc xpy = {0,};
|
||||||
cbuf *cb = NULL;
|
cbuf *cb = NULL;
|
||||||
|
|
||||||
|
if (xpath == NULL){
|
||||||
|
clicon_err(OE_XML, EINVAL, "XPath is NULL");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
xpy.xpy_parse_string = xpath;
|
xpy.xpy_parse_string = xpath;
|
||||||
xpy.xpy_name = "xpath parser";
|
xpy.xpy_name = "xpath parser";
|
||||||
xpy.xpy_linenum = 1;
|
xpy.xpy_linenum = 1;
|
||||||
|
|
|
||||||
|
|
@ -397,8 +397,14 @@ xp_yang_eval(xp_yang_ctx *xy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (xy0 == NULL && xy1 == NULL && xy2 == NULL){
|
if (xy0 == NULL && xy1 == NULL && xy2 == NULL){
|
||||||
clicon_err(OE_XML, EFAULT, "Internal error: no result produced");
|
if (xptree->xs_type == XP_ABSPATH){
|
||||||
goto done;
|
if ((*xyr = xy_dup(xy)) == NULL)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clicon_err(OE_XML, EFAULT, "Internal error: no result produced");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (xy2){
|
if (xy2){
|
||||||
*xyr = xy2;
|
*xyr = xy2;
|
||||||
|
|
@ -460,6 +466,10 @@ yang_path_arg(yang_stmt *ys,
|
||||||
xp_yang_ctx *xyr = NULL;
|
xp_yang_ctx *xyr = NULL;
|
||||||
xp_yang_ctx *xy = NULL;
|
xp_yang_ctx *xy = NULL;
|
||||||
|
|
||||||
|
if (path_arg == NULL){
|
||||||
|
clicon_err(OE_XML, EINVAL, "path-arg is NULL");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (xpath_parse(path_arg, &xptree) < 0)
|
if (xpath_parse(path_arg, &xptree) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xy = xy_dup(NULL)) == NULL)
|
if ((xy = xy_dup(NULL)) == NULL)
|
||||||
|
|
|
||||||
|
|
@ -1035,6 +1035,7 @@ yang_parse_filename(const char *filename,
|
||||||
* @param[in] module Module name
|
* @param[in] module Module name
|
||||||
* @param[in] revision Revision (or NULL)
|
* @param[in] revision Revision (or NULL)
|
||||||
* @param[in] yspec Yang statement
|
* @param[in] yspec Yang statement
|
||||||
|
* @param[in] origname Name of yang module triggering this parsing, for logging
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
*
|
*
|
||||||
|
|
@ -1044,7 +1045,8 @@ static yang_stmt *
|
||||||
yang_parse_module(clicon_handle h,
|
yang_parse_module(clicon_handle h,
|
||||||
const char *module,
|
const char *module,
|
||||||
const char *revision,
|
const char *revision,
|
||||||
yang_stmt *yspec)
|
yang_stmt *yspec,
|
||||||
|
char *origname)
|
||||||
{
|
{
|
||||||
cbuf *fbuf = NULL;
|
cbuf *fbuf = NULL;
|
||||||
char *filename;
|
char *filename;
|
||||||
|
|
@ -1053,20 +1055,27 @@ yang_parse_module(clicon_handle h,
|
||||||
yang_stmt *yrev; /* yang revision */
|
yang_stmt *yrev; /* yang revision */
|
||||||
uint32_t revf = 0; /* revision in filename */
|
uint32_t revf = 0; /* revision in filename */
|
||||||
uint32_t revm = 0; /* revision in parsed new module (should be same as revf) */
|
uint32_t revm = 0; /* revision in parsed new module (should be same as revf) */
|
||||||
|
cbuf *cb = NULL;
|
||||||
|
|
||||||
if ((fbuf = cbuf_new()) == NULL){
|
if ((fbuf = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_YANG, errno, "cbuf_new");
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* Match a yang file with or without revision in yang-dir list */
|
/* Match a yang file with or without revision in yang-dir list */
|
||||||
if ((nr = yang_parse_find_match(h, module, revision, &revf, fbuf)) < 0)
|
if ((nr = yang_parse_find_match(h, module, revision, &revf, fbuf)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (nr == 0){
|
if (nr == 0){
|
||||||
|
if ((cb = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cprintf(cb, "%s", module);
|
||||||
if (revision)
|
if (revision)
|
||||||
clicon_err(OE_YANG, ENOENT, "No yang files found matching \"%s@%s\" in the list of CLICON_YANG_DIRs",
|
cprintf(cb, "@%s", revision);
|
||||||
module, revision);
|
if (origname)
|
||||||
|
clicon_err(OE_YANG, ENOENT, "No yang files found matching \"%s\" in the list of CLICON_YANG_DIRs when loading %s.yang", cbuf_get(cb), origname);
|
||||||
else
|
else
|
||||||
clicon_err(OE_YANG, ENOENT, "No yang files found matching \"%s\" in the list of CLICON_YANG_DIRs", module);
|
clicon_err(OE_YANG, ENOENT, "No yang files found matching \"%s\" in the list of CLICON_YANG_DIRs", cbuf_get(cb));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
filename = cbuf_get(fbuf);
|
filename = cbuf_get(fbuf);
|
||||||
|
|
@ -1099,6 +1108,8 @@ yang_parse_module(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
|
if (cb)
|
||||||
|
cbuf_free(cb);
|
||||||
if (fbuf)
|
if (fbuf)
|
||||||
cbuf_free(fbuf);
|
cbuf_free(fbuf);
|
||||||
return ymod; /* top-level (sub)module */
|
return ymod; /* top-level (sub)module */
|
||||||
|
|
@ -1149,7 +1160,7 @@ yang_parse_recurse(clicon_handle h,
|
||||||
keyw==Y_IMPORT?Y_MODULE:Y_SUBMODULE,
|
keyw==Y_IMPORT?Y_MODULE:Y_SUBMODULE,
|
||||||
submodule) == NULL){
|
submodule) == NULL){
|
||||||
/* recursive call */
|
/* recursive call */
|
||||||
if ((subymod = yang_parse_module(h, submodule, subrevision, ysp)) == NULL)
|
if ((subymod = yang_parse_module(h, submodule, subrevision, ysp, yang_argument_get(ymod))) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
/* Sanity check: if submodule, its belongs-to statement shall point to the module */
|
/* Sanity check: if submodule, its belongs-to statement shall point to the module */
|
||||||
if (keyw == Y_INCLUDE){
|
if (keyw == Y_INCLUDE){
|
||||||
|
|
@ -1581,7 +1592,7 @@ yang_spec_parse_module(clicon_handle h,
|
||||||
if (yang_find_module_by_name_revision(yspec, name, revision) != NULL)
|
if (yang_find_module_by_name_revision(yspec, name, revision) != NULL)
|
||||||
goto ok;
|
goto ok;
|
||||||
/* Find a yang module and parse it and all its submodules */
|
/* Find a yang module and parse it and all its submodules */
|
||||||
if (yang_parse_module(h, name, revision, yspec) == NULL)
|
if (yang_parse_module(h, name, revision, yspec, NULL) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (yang_parse_post(h, yspec, modmin) < 0)
|
if (yang_parse_post(h, yspec, modmin) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -46,3 +46,4 @@ NADMIN=$(cat <<EOF
|
||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
|
DEFAULTNACM='<nacm xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-acm"><enable-nacm>true</enable-nacm><read-default>permit</read-default><write-default>deny</write-default><exec-default>permit</exec-default><enable-external-groups>true</enable-external-groups></nacm>'
|
||||||
|
|
|
||||||
|
|
@ -315,7 +315,7 @@ new "netconf commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get config"
|
new "netconf get config"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source></get-config></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><data>$XML</data></rpc-reply>]]>]]>"
|
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source><filter type='subtree'><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"/></filter></get-config></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><data>$XML</data></rpc-reply>]]>]]>"
|
||||||
|
|
||||||
JSON='{"ietf-interfaces:interfaces":{"example-augment:ports":[{"id":22,"str":"foo"},{"id":44,"str":"bar"}]}}'
|
JSON='{"ietf-interfaces:interfaces":{"example-augment:ports":[{"id":22,"str":"foo"},{"id":44,"str":"bar"}]}}'
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue