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
|
||||
|
||||
/* Check if list/leaf-list */
|
||||
if (yang_path_arg(yspec, xpath, &ylist) < 0)
|
||||
if (yang_path_arg(yspec, xpath?xpath:"/", &ylist) < 0)
|
||||
goto done;
|
||||
if (ylist == NULL){
|
||||
if ((cbmsg = cbuf_new()) == NULL){
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ typedef struct {
|
|||
*/
|
||||
typedef struct {
|
||||
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 */
|
||||
cxobj *pd_xstate; /* Returned xml state tree */
|
||||
} pagination_data_t;
|
||||
|
|
|
|||
|
|
@ -286,7 +286,6 @@ transaction_log(clicon_handle h,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*! Get pagination data: offset parameter
|
||||
*
|
||||
* @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
|
||||
* [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)
|
||||
goto done;
|
||||
if (sd->sd_code){
|
||||
|
|
|
|||
|
|
@ -526,6 +526,10 @@ xpath_parse(const char *xpath,
|
|||
clixon_xpath_yacc xpy = {0,};
|
||||
cbuf *cb = NULL;
|
||||
|
||||
if (xpath == NULL){
|
||||
clicon_err(OE_XML, EINVAL, "XPath is NULL");
|
||||
goto done;
|
||||
}
|
||||
xpy.xpy_parse_string = xpath;
|
||||
xpy.xpy_name = "xpath parser";
|
||||
xpy.xpy_linenum = 1;
|
||||
|
|
|
|||
|
|
@ -397,8 +397,14 @@ xp_yang_eval(xp_yang_ctx *xy,
|
|||
}
|
||||
}
|
||||
if (xy0 == NULL && xy1 == NULL && xy2 == NULL){
|
||||
clicon_err(OE_XML, EFAULT, "Internal error: no result produced");
|
||||
goto done;
|
||||
if (xptree->xs_type == XP_ABSPATH){
|
||||
if ((*xyr = xy_dup(xy)) == NULL)
|
||||
goto done;
|
||||
}
|
||||
else {
|
||||
clicon_err(OE_XML, EFAULT, "Internal error: no result produced");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (xy2){
|
||||
*xyr = xy2;
|
||||
|
|
@ -460,6 +466,10 @@ yang_path_arg(yang_stmt *ys,
|
|||
xp_yang_ctx *xyr = 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)
|
||||
goto done;
|
||||
if ((xy = xy_dup(NULL)) == NULL)
|
||||
|
|
|
|||
|
|
@ -1035,6 +1035,7 @@ yang_parse_filename(const char *filename,
|
|||
* @param[in] module Module name
|
||||
* @param[in] revision Revision (or NULL)
|
||||
* @param[in] yspec Yang statement
|
||||
* @param[in] origname Name of yang module triggering this parsing, for logging
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*
|
||||
|
|
@ -1044,7 +1045,8 @@ static yang_stmt *
|
|||
yang_parse_module(clicon_handle h,
|
||||
const char *module,
|
||||
const char *revision,
|
||||
yang_stmt *yspec)
|
||||
yang_stmt *yspec,
|
||||
char *origname)
|
||||
{
|
||||
cbuf *fbuf = NULL;
|
||||
char *filename;
|
||||
|
|
@ -1053,20 +1055,27 @@ yang_parse_module(clicon_handle h,
|
|||
yang_stmt *yrev; /* yang revision */
|
||||
uint32_t revf = 0; /* revision in filename */
|
||||
uint32_t revm = 0; /* revision in parsed new module (should be same as revf) */
|
||||
cbuf *cb = NULL;
|
||||
|
||||
if ((fbuf = cbuf_new()) == NULL){
|
||||
clicon_err(OE_YANG, errno, "cbuf_new");
|
||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
/* Match a yang file with or without revision in yang-dir list */
|
||||
if ((nr = yang_parse_find_match(h, module, revision, &revf, fbuf)) < 0)
|
||||
goto done;
|
||||
if (nr == 0){
|
||||
if ((cb = cbuf_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
cprintf(cb, "%s", module);
|
||||
if (revision)
|
||||
clicon_err(OE_YANG, ENOENT, "No yang files found matching \"%s@%s\" in the list of CLICON_YANG_DIRs",
|
||||
module, revision);
|
||||
cprintf(cb, "@%s", 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
|
||||
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;
|
||||
}
|
||||
filename = cbuf_get(fbuf);
|
||||
|
|
@ -1099,6 +1108,8 @@ yang_parse_module(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
done:
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
if (fbuf)
|
||||
cbuf_free(fbuf);
|
||||
return ymod; /* top-level (sub)module */
|
||||
|
|
@ -1149,7 +1160,7 @@ yang_parse_recurse(clicon_handle h,
|
|||
keyw==Y_IMPORT?Y_MODULE:Y_SUBMODULE,
|
||||
submodule) == NULL){
|
||||
/* 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;
|
||||
/* Sanity check: if submodule, its belongs-to statement shall point to the module */
|
||||
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)
|
||||
goto ok;
|
||||
/* 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;
|
||||
if (yang_parse_post(h, yspec, modmin) < 0)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -46,3 +46,4 @@ NADMIN=$(cat <<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>]]>]]>$"
|
||||
|
||||
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"}]}}'
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue