restconf RPC
This commit is contained in:
parent
d0660bf611
commit
fd91bb2933
17 changed files with 371 additions and 109 deletions
|
|
@ -974,7 +974,10 @@ clicon_xml2cbuf(cbuf *cb,
|
|||
}
|
||||
if (prettyprint && xml_body(x)==NULL)
|
||||
cprintf(cb, "%*s", level*XML_INDENT, "");
|
||||
cprintf(cb, "</%s>", name);
|
||||
cprintf(cb, "</");
|
||||
if (xml_namespace(x))
|
||||
cprintf(cb, "%s:", xml_namespace(x));
|
||||
cprintf(cb, "%s>", name);
|
||||
}
|
||||
if (prettyprint)
|
||||
cprintf(cb, "\n");
|
||||
|
|
|
|||
|
|
@ -644,7 +644,7 @@ xml_diff1(yang_stmt *ys,
|
|||
while ((x1 = xml_child_each(xt1, x1, CX_ELMNT)) != NULL){
|
||||
name = xml_name(x1);
|
||||
if (ys->ys_keyword == Y_SPEC)
|
||||
y = yang_find_topnode((yang_spec*)ys, name);
|
||||
y = yang_find_topnode((yang_spec*)ys, name, 0);
|
||||
else
|
||||
y = yang_find_datanode((yang_node*)ys, name);
|
||||
if (y == NULL){
|
||||
|
|
@ -754,7 +754,7 @@ xml_diff1(yang_stmt *ys,
|
|||
while ((x2 = xml_child_each(xt2, x2, CX_ELMNT)) != NULL){
|
||||
name = xml_name(x2);
|
||||
if (ys->ys_keyword == Y_SPEC)
|
||||
y = yang_find_topnode((yang_spec*)ys, name);
|
||||
y = yang_find_topnode((yang_spec*)ys, name, 0);
|
||||
else
|
||||
y = yang_find_datanode((yang_node*)ys, name);
|
||||
if (y == NULL){
|
||||
|
|
@ -1482,7 +1482,7 @@ xml_spec_populate(cxobj *x,
|
|||
(yp = xml_spec(xp)) != NULL)
|
||||
y = yang_find_datanode((yang_node*)yp, xml_name(x));
|
||||
else
|
||||
y = yang_find_topnode(yspec, name); /* still NULL for config */
|
||||
y = yang_find_topnode(yspec, name, 0); /* still NULL for config */
|
||||
#ifdef XXX_OBSOLETE /* Add validate elsewhere */
|
||||
if (y==NULL){
|
||||
clicon_err(OE_XML, EBADF, "yang spec not found for xml node '%s' xml parent name: '%s' yangspec:'%s']",
|
||||
|
|
@ -1544,7 +1544,7 @@ api_path2xpath_cvv(yang_spec *yspec,
|
|||
clicon_debug(1, "[%d] cvname:%s", i, name);
|
||||
clicon_debug(1, "cv2str%d", cv2str(cv, NULL, 0));
|
||||
if (i == offset){
|
||||
if ((y = yang_find_topnode(yspec, name)) == NULL){
|
||||
if ((y = yang_find_topnode(yspec, name, 0)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "No yang node found: %s", name);
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -1635,17 +1635,19 @@ api_path2xpath(yang_spec *yspec,
|
|||
* @param[in] nvec Length of vec
|
||||
* @param[in] x0 Xpath tree so far
|
||||
* @param[in] y0 Yang spec for x0
|
||||
* @param[in] schemanode If set use schema nodes otherwise data nodes.
|
||||
* @param[out] xpathp Resulting xml tree
|
||||
* @param[out] ypathp Yang spec matching xpathp
|
||||
* @see api_path2xml
|
||||
*/
|
||||
static int
|
||||
api_path2xml_vec(char **vec,
|
||||
int nvec,
|
||||
cxobj *x0,
|
||||
yang_node *y0,
|
||||
cxobj **xpathp,
|
||||
yang_node **ypathp)
|
||||
api_path2xml_vec(char **vec,
|
||||
int nvec,
|
||||
cxobj *x0,
|
||||
yang_node *y0,
|
||||
int schemanode,
|
||||
cxobj **xpathp,
|
||||
yang_node **ypathp)
|
||||
{
|
||||
int retval = -1;
|
||||
int j;
|
||||
|
|
@ -1663,6 +1665,7 @@ api_path2xml_vec(char **vec,
|
|||
int nvalvec;
|
||||
cxobj *x = NULL;
|
||||
yang_stmt *y = NULL;
|
||||
char *local;
|
||||
|
||||
if ((name = vec[0]) == NULL){
|
||||
if (xpathp)
|
||||
|
|
@ -1678,10 +1681,21 @@ api_path2xml_vec(char **vec,
|
|||
if (percent_decode(restval_enc, &restval) < 0)
|
||||
goto done;
|
||||
}
|
||||
if (y0->yn_keyword == Y_SPEC) /* top-node */
|
||||
y = yang_find_topnode((yang_spec*)y0, name);
|
||||
else
|
||||
y = yang_find_datanode((yang_node*)y0, name);
|
||||
/* Split into prefix and localname, ignore prefix for now */
|
||||
if ((local = index(name, ':')) != NULL){
|
||||
*local = '\0';
|
||||
local++;
|
||||
name = local;
|
||||
}
|
||||
if (y0->yn_keyword == Y_SPEC){ /* top-node */
|
||||
clicon_debug(1, "%s 1 %s", __FUNCTION__, name);
|
||||
y = yang_find_topnode((yang_spec*)y0, name, schemanode);
|
||||
}
|
||||
else {
|
||||
clicon_debug(1, "%s 2 %s", __FUNCTION__, name);
|
||||
y = schemanode?yang_find_schemanode((yang_node*)y0, name):
|
||||
yang_find_datanode((yang_node*)y0, name);
|
||||
}
|
||||
if (y == NULL){
|
||||
clicon_err(OE_YANG, errno, "No yang node found: %s", name);
|
||||
goto done;
|
||||
|
|
@ -1756,6 +1770,7 @@ api_path2xml_vec(char **vec,
|
|||
}
|
||||
if (api_path2xml_vec(vec+1, nvec-1,
|
||||
x, (yang_node*)y,
|
||||
schemanode,
|
||||
xpathp, ypathp) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
|
|
@ -1769,14 +1784,17 @@ api_path2xml_vec(char **vec,
|
|||
|
||||
/*! Create xml tree from api-path
|
||||
* @param[in] api_path API-path as defined in RFC 8040
|
||||
* @param[in] yspec Yang spec
|
||||
* @param[in] schemanode If set use schema nodes otherwise data nodes.
|
||||
* @param[out] xpathp Resulting xml tree
|
||||
* @param[out] ypathp Yang spec matching xpathp
|
||||
* @see api_path2xml_vec
|
||||
*/
|
||||
int
|
||||
api_path2xml(char *api_path,
|
||||
api_path2xml(char *api_path,
|
||||
yang_spec *yspec,
|
||||
cxobj *xpath,
|
||||
int schemanode,
|
||||
cxobj **xpathp,
|
||||
yang_node **ypathp)
|
||||
{
|
||||
|
|
@ -1800,7 +1818,7 @@ api_path2xml(char *api_path,
|
|||
}
|
||||
nvec--; /* NULL-terminated */
|
||||
if (api_path2xml_vec(vec+1, nvec,
|
||||
xpath, (yang_node*)yspec,
|
||||
xpath, (yang_node*)yspec, schemanode,
|
||||
xpathp, ypathp) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
|
|
@ -1984,7 +2002,7 @@ xml_merge(cxobj *x0,
|
|||
while ((x1c = xml_child_each(x1, x1c, CX_ELMNT)) != NULL) {
|
||||
x1cname = xml_name(x1c);
|
||||
/* Get yang spec of the child */
|
||||
if ((yc = yang_find_topnode(yspec, x1cname)) == NULL){
|
||||
if ((yc = yang_find_topnode(yspec, x1cname, 0)) == NULL){
|
||||
clicon_err(OE_YANG, ENOENT, "No yang spec");
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -2050,3 +2068,4 @@ yang_enum_int_value(cxobj *node,
|
|||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -453,18 +453,68 @@ yang_find_datanode(yang_node *yn,
|
|||
return ysmatch;
|
||||
}
|
||||
|
||||
/*! Find 'top-node', eg first data node in all (sub)modules in a yang spec
|
||||
/*! Find child schema node with matching argument (container, leaf, etc)
|
||||
* @note XXX unify code with yang_find_datanode?
|
||||
* @see yang_find_datanode
|
||||
*/
|
||||
yang_stmt *
|
||||
yang_find_schemanode(yang_node *yn,
|
||||
char *argument)
|
||||
{
|
||||
yang_stmt *ys = NULL;
|
||||
yang_stmt *yc = NULL;
|
||||
yang_stmt *ysmatch = NULL;
|
||||
int i, j;
|
||||
|
||||
for (i=0; i<yn->yn_len; i++){
|
||||
ys = yn->yn_stmt[i];
|
||||
if (ys->ys_keyword == Y_CHOICE){ /* Look for its children */
|
||||
for (j=0; j<ys->ys_len; j++){
|
||||
yc = ys->ys_stmt[j];
|
||||
if (yc->ys_keyword == Y_CASE) /* Look for its children */
|
||||
ysmatch = yang_find_schemanode((yang_node*)yc, argument);
|
||||
else
|
||||
if (yang_schemanode(yc)){
|
||||
if (argument == NULL)
|
||||
ysmatch = yc;
|
||||
else
|
||||
if (yc->ys_argument && strcmp(argument, yc->ys_argument) == 0)
|
||||
ysmatch = yc;
|
||||
}
|
||||
if (ysmatch)
|
||||
goto match;
|
||||
}
|
||||
} /* Y_CHOICE */
|
||||
else
|
||||
if (yang_schemanode(ys)){
|
||||
if (argument == NULL)
|
||||
ysmatch = ys;
|
||||
else
|
||||
if (ys->ys_argument && strcmp(argument, ys->ys_argument) == 0)
|
||||
ysmatch = ys;
|
||||
if (ysmatch)
|
||||
goto match;
|
||||
}
|
||||
}
|
||||
match:
|
||||
return ysmatch;
|
||||
}
|
||||
|
||||
|
||||
/*! Find first matching data node in all (sub)modules in a yang spec
|
||||
*
|
||||
* @param[in] ysp Yang specification
|
||||
* @param[in] name if NULL, match any(first) argument. XXX is that really a case?
|
||||
* @param[in] name if NULL, match any(first) argument. XXX is that really a case?
|
||||
* @param[in] schemanode If set look for schema nodes, otherwise only data nodes
|
||||
* A yang specification has modules as children which in turn can have
|
||||
* syntax-nodes as children. This function goes through all the modules to
|
||||
* look for syntax-nodes. Note that if a child to a module is a choice,
|
||||
* look for nodes. Note that if a child to a module is a choice,
|
||||
* the search is made recursively made to the choice's children.
|
||||
*/
|
||||
yang_stmt *
|
||||
yang_find_topnode(yang_spec *ysp,
|
||||
char *name)
|
||||
char *name,
|
||||
int schemanode)
|
||||
{
|
||||
yang_stmt *ys = NULL;
|
||||
yang_stmt *yc = NULL;
|
||||
|
|
@ -472,12 +522,43 @@ yang_find_topnode(yang_spec *ysp,
|
|||
|
||||
for (i=0; i<ysp->yp_len; i++){
|
||||
ys = ysp->yp_stmt[i];
|
||||
if ((yc = yang_find_datanode((yang_node*)ys, name)) != NULL)
|
||||
return yc;
|
||||
if (schemanode){
|
||||
if ((yc = yang_find_schemanode((yang_node*)ys, name)) != NULL)
|
||||
return yc;
|
||||
}
|
||||
else
|
||||
if ((yc = yang_find_datanode((yang_node*)ys, name)) != NULL)
|
||||
return yc;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*! Given a yang statement, find the prefix associated to this module
|
||||
* @param[in] ys Yang statement
|
||||
* @retval NULL Not found
|
||||
* @retval prefix Prefix as char* pointer into yang tree
|
||||
*/
|
||||
char *
|
||||
yang_find_myprefix(yang_stmt *ys)
|
||||
{
|
||||
yang_stmt *ymod; /* My module */
|
||||
yang_stmt *yprefix;
|
||||
char *prefix = NULL;
|
||||
|
||||
if ((ymod = ys_module(ys)) == NULL){
|
||||
clicon_err(OE_YANG, 0, "My yang module not found");
|
||||
goto done;
|
||||
}
|
||||
if ((yprefix = yang_find((yang_node*)ymod, Y_PREFIX, NULL)) == NULL){
|
||||
clicon_err(OE_YANG, 0, "No prefix in my module");
|
||||
goto done;
|
||||
}
|
||||
prefix = yprefix->ys_argument;
|
||||
done:
|
||||
return prefix;
|
||||
}
|
||||
|
||||
|
||||
/*! Reset flag in complete tree, arg contains flag */
|
||||
static int
|
||||
ys_flag_reset(yang_stmt *ys,
|
||||
|
|
@ -505,8 +586,13 @@ ys_module(yang_stmt *ys)
|
|||
{
|
||||
yang_node *yn;
|
||||
|
||||
#if 1
|
||||
if (ys==NULL || ys->ys_keyword==Y_SPEC)
|
||||
return NULL;
|
||||
#else
|
||||
if (ys==NULL || ys->ys_keyword==Y_SPEC)
|
||||
return ys;
|
||||
#endif
|
||||
while (ys != NULL && ys->ys_keyword != Y_MODULE && ys->ys_keyword != Y_SUBMODULE){
|
||||
yn = ys->ys_parent;
|
||||
/* Some extra stuff to ensure ys is a stmt */
|
||||
|
|
@ -572,6 +658,7 @@ ytype_prefix(yang_stmt *ys)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*! Given a yang statement and a prefix, return yang module to that prefix
|
||||
* Note, not the other module but the proxy import statement only
|
||||
* @param[in] ys A yang statement
|
||||
|
|
@ -588,22 +675,25 @@ yang_find_module_by_prefix(yang_stmt *ys,
|
|||
yang_stmt *my_ymod;
|
||||
yang_stmt *ymod = NULL;
|
||||
yang_spec *yspec;
|
||||
char *myprefix;
|
||||
|
||||
if ((yspec = ys_spec(ys)) == NULL){
|
||||
clicon_err(OE_YANG, 0, "My yang spec not found");
|
||||
goto done;
|
||||
}
|
||||
myprefix = yang_find_myprefix(ys);
|
||||
if ((my_ymod = ys_module(ys)) == NULL){
|
||||
clicon_err(OE_YANG, 0, "My yang module not found");
|
||||
goto done;
|
||||
}
|
||||
if ((yspec = ys_spec(my_ymod)) == NULL){
|
||||
clicon_err(OE_YANG, 0, "My yang spec not found");
|
||||
goto done;
|
||||
}
|
||||
#if 0
|
||||
if (my_ymod->ys_keyword != Y_MODULE &&
|
||||
my_ymod->ys_keyword != Y_SUBMODULE){
|
||||
clicon_err(OE_YANG, 0, "%s not module or sub-module", my_ymod->ys_argument);
|
||||
goto done;
|
||||
}
|
||||
if ((yprefix = yang_find((yang_node*)my_ymod, Y_PREFIX, NULL)) != NULL &&
|
||||
strcmp(yprefix->ys_argument, prefix) == 0){
|
||||
#endif
|
||||
if (strcmp(myprefix, prefix) == 0){
|
||||
ymod = my_ymod;
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -1730,6 +1820,7 @@ yang_abs_schema_nodeid(yang_spec *yspec,
|
|||
yang_stmt *ymod;
|
||||
char *id;
|
||||
char *prefix = NULL;
|
||||
|
||||
yang_stmt *yprefix;
|
||||
|
||||
/* check absolute schema_nodeid */
|
||||
|
|
@ -1765,9 +1856,16 @@ yang_abs_schema_nodeid(yang_spec *yspec,
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (ymod == NULL){
|
||||
clicon_err(OE_YANG, 0, "Module with prefix %s not found", prefix);
|
||||
goto done;
|
||||
if (ymod == NULL){ /* Try with topnode */
|
||||
yang_stmt *ys;
|
||||
if ((ys = yang_find_topnode(yspec, id, 1)) == NULL){
|
||||
clicon_err(OE_YANG, 0, "Module with id:%s:%s not found", prefix,id);
|
||||
goto done;
|
||||
}
|
||||
if ((ymod = ys_module(ys)) == NULL){
|
||||
clicon_err(OE_YANG, 0, "Module with id:%s:%s not found2", prefix,id);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (schema_nodeid_vec((yang_node*)ymod, vec+1, nvec-1, yres) < 0)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -107,6 +107,8 @@ yang_builtin(char *type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*! Set type cache for yang type
|
||||
*/
|
||||
int
|
||||
yang_type_cache_set(yang_type_cache **ycache0,
|
||||
yang_stmt *resolved,
|
||||
|
|
@ -142,7 +144,6 @@ yang_type_cache_set(yang_type_cache **ycache0,
|
|||
}
|
||||
ycache->yc_fraction = fraction;
|
||||
retval = 0;
|
||||
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -209,6 +210,7 @@ yang_type_cache_free(yang_type_cache *ycache)
|
|||
* @param[in] ys This is a type statement
|
||||
* @param[in] arg Not used
|
||||
* Typically only called once when loading te yang type system.
|
||||
* @note unions not cached
|
||||
*/
|
||||
int
|
||||
ys_resolve_type(yang_stmt *ys,
|
||||
|
|
@ -226,13 +228,16 @@ ys_resolve_type(yang_stmt *ys,
|
|||
if (yang_type_resolve((yang_stmt*)ys->ys_parent, ys, &resolved,
|
||||
&options, &mincv, &maxcv, &pattern, &fraction) < 0)
|
||||
goto done;
|
||||
/* skip unions since they may have different sets of options, mincv, etc */
|
||||
|
||||
if (resolved && strcmp(resolved->ys_argument, "union")==0)
|
||||
;
|
||||
;
|
||||
/* skip unions since they may have different sets of options, mincv, etc
|
||||
* You would have to resolve all sub-types also recursively
|
||||
*/
|
||||
else
|
||||
if (yang_type_cache_set(&ys->ys_typecache,
|
||||
resolved, options, mincv, maxcv, pattern, fraction) < 0)
|
||||
goto done;
|
||||
if (yang_type_cache_set(&ys->ys_typecache,
|
||||
resolved, options, mincv, maxcv, pattern, fraction) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue