Added restconf/operations get, see RFC8040 Sec 3.3.2:
This commit is contained in:
Olof hagsand 2018-03-04 21:24:38 +01:00
parent 6a22524d38
commit 990700b68d
16 changed files with 355 additions and 93 deletions

View file

@ -304,10 +304,12 @@ xml2json1_cbuf(cbuf *cb,
break;
}
case NO_ARRAY:
if (!flat)
cprintf(cb, "%*s\"%s\": ",
pretty?(level*JSON_INDENT):0, "",
xml_name(x));
if (!flat){
cprintf(cb, "%*s\"", pretty?(level*JSON_INDENT):0, "");
if (xml_namespace(x))
cprintf(cb, "%s:", xml_namespace(x));
cprintf(cb, "%s\": ", xml_name(x));
}
switch (childt){
case NULL_CHILD:
cprintf(cb, "null");
@ -323,9 +325,10 @@ xml2json1_cbuf(cbuf *cb,
break;
case FIRST_ARRAY:
case SINGLE_ARRAY:
cprintf(cb, "%*s\"%s\": ",
pretty?(level*JSON_INDENT):0, "",
xml_name(x));
cprintf(cb, "%*s\"", pretty?(level*JSON_INDENT):0, "");
if (xml_namespace(x))
cprintf(cb, "%s:", xml_namespace(x));
cprintf(cb, "%s\": ", xml_name(x));
level++;
cprintf(cb, "[%s%*s",
pretty?"\n":"",

View file

@ -587,7 +587,7 @@ yang_next(yang_node *y,
yang_stmt *ys;
if (y->yn_keyword == Y_SPEC)
ys = yang_find_topnode((yang_spec*)y, name, 0);
ys = yang_find_topnode((yang_spec*)y, name, YC_DATANODE);
else
ys = yang_find_datanode(y, name);
if (ys == NULL)
@ -1313,7 +1313,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, 0); /* still NULL for config */
y = yang_find_topnode(yspec, name, YC_DATANODE); /* still NULL for config */
#endif
if (y)
xml_spec_set(x, y);
@ -1367,7 +1367,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, 0)) == NULL){
if ((y = yang_find_topnode(yspec, name, YC_DATANODE)) == NULL){
clicon_err(OE_UNIX, errno, "No yang node found: %s", name);
goto done;
}
@ -1448,7 +1448,7 @@ 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[in] nodeclass Set to schema nodes, data nodes, etc
* @param[out] xpathp Resulting xml tree
* @param[out] ypathp Yang spec matching xpathp
* @see api_path2xml
@ -1458,7 +1458,7 @@ api_path2xml_vec(char **vec,
int nvec,
cxobj *x0,
yang_node *y0,
int schemanode,
yang_class nodeclass,
cxobj **xpathp,
yang_node **ypathp)
{
@ -1500,10 +1500,10 @@ api_path2xml_vec(char **vec,
name = local;
}
if (y0->yn_keyword == Y_SPEC){ /* top-node */
y = yang_find_topnode((yang_spec*)y0, name, schemanode);
y = yang_find_topnode((yang_spec*)y0, name, nodeclass);
}
else {
y = schemanode?yang_find_schemanode((yang_node*)y0, name):
y = (nodeclass==YC_SCHEMANODE)?yang_find_schemanode((yang_node*)y0, name):
yang_find_datanode((yang_node*)y0, name);
}
if (y == NULL){
@ -1572,7 +1572,7 @@ api_path2xml_vec(char **vec,
}
if (api_path2xml_vec(vec+1, nvec-1,
x, (yang_node*)y,
schemanode,
nodeclass,
xpathp, ypathp) < 0)
goto done;
retval = 0;
@ -1588,7 +1588,7 @@ api_path2xml_vec(char **vec,
* @param[in] api_path API-path as defined in RFC 8040
* @param[in] yspec Yang spec
* @param[in,out] xtop Incoming XML tree
* @param[in] schemanode If set use schema nodes otherwise data nodes.
* @param[in] nodeclass Set to schema nodes, data nodes, etc
* @param[out] xbotp Resulting xml tree (end of xpath)
* @param[out] ybotp Yang spec matching xbotp
* @example
@ -1605,7 +1605,7 @@ int
api_path2xml(char *api_path,
yang_spec *yspec,
cxobj *xtop,
int schemanode,
yang_class nodeclass,
cxobj **xbotp,
yang_node **ybotp)
{
@ -1628,7 +1628,7 @@ api_path2xml(char *api_path,
}
nvec--; /* NULL-terminated */
if (api_path2xml_vec(vec+1, nvec,
xtop, (yang_node*)yspec, schemanode,
xtop, (yang_node*)yspec, nodeclass,
xbotp, ybotp) < 0)
goto done;
retval = 0;
@ -1736,7 +1736,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, 0)) == NULL){
if ((yc = yang_find_topnode(yspec, x1cname, YC_DATANODE)) == NULL){
clicon_err(OE_YANG, ENOENT, "No yang spec");
goto done;
}

View file

@ -93,7 +93,7 @@ xml_child_spec(char *name,
if (xp && (yparent = xml_spec(xp)) != NULL)
y = yang_find_datanode((yang_node*)yparent, name);
else if (yspec)
y = yang_find_topnode(yspec, name, 0); /* still NULL for config */
y = yang_find_topnode(yspec, name, YC_DATANODE); /* still NULL for config */
else
y = NULL;
*yresult = y;

View file

@ -402,6 +402,94 @@ yang_find(yang_node *yn,
}
return match ? ys : NULL;
}
#ifdef NOTYET
/*! Prototype more generic than yang_find_datanode and yang_find_schemanode
*/
yang_stmt *
yang_find_class(yang_node *yn,
char *argument,
yang_class class)
{
yang_stmt *ys = NULL;
yang_stmt *yc = NULL;
yang_stmt *ysmatch = NULL;
int i, j;
int ok;
for (i=0; i<yn->yn_len; i++){
ys = yn->yn_stmt[i];
switch(class){
case YC_NONE:
ok = 1;
break;
case YC_DATANODE:
ok = yang_datanode(ys);
break;
case YC_DATADEFINITION:
ok = yang_datadefinition(ys);
break;
case YC_SCHEMANODE:
ok = yang_schemanode(ys);
break;
}
if (!ok)
continue;
switch(class){
case YC_NONE:
if (argument == NULL)
ysmatch = ys;
else
if (ys->ys_argument && strcmp(argument, ys->ys_argument) == 0)
ysmatch = ys;
if (ysmatch)
goto match;
break;
case YC_DATANODE:
case YC_DATADEFINITION:
if (argument == NULL)
ysmatch = ys;
else
if (ys->ys_argument && strcmp(argument, ys->ys_argument) == 0)
ysmatch = ys;
if (ysmatch)
goto match;
break;
case YC_SCHEMANODE:
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_class((yang_node*)yc, argument, class);
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 (argument == NULL)
ysmatch = ys;
else
if (ys->ys_argument && strcmp(argument, ys->ys_argument) == 0)
ysmatch = ys;
if (ysmatch)
goto match;
}
break;
} /* switch */
} /* for */
match:
return ysmatch;
}
#endif /* NOTYET */
/*! Find child data node with matching argument (container, leaf, etc)
*
@ -455,6 +543,8 @@ yang_find_datanode(yang_node *yn,
}
/*! Find child schema node with matching argument (container, leaf, etc)
* @param[in] yn Yang node, current context node.
* @param[in] argument if NULL, match any(first) argument.
* @note XXX unify code with yang_find_datanode?
* @see yang_find_datanode
*/
@ -505,7 +595,7 @@ yang_find_schemanode(yang_node *yn,
/*! 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] argument 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
@ -514,8 +604,8 @@ yang_find_schemanode(yang_node *yn,
*/
yang_stmt *
yang_find_topnode(yang_spec *ysp,
char *name,
int schemanode)
char *argument,
yang_class class)
{
yang_stmt *ys = NULL;
yang_stmt *yc = NULL;
@ -523,13 +613,22 @@ yang_find_topnode(yang_spec *ysp,
for (i=0; i<ysp->yp_len; i++){
ys = ysp->yp_stmt[i];
if (schemanode){
if ((yc = yang_find_schemanode((yang_node*)ys, name)) != NULL)
switch (class){
case YC_NONE:
if ((yc = yang_find((yang_node*)ys, 0, argument)) != NULL)
return yc;
break;
case YC_DATANODE:
if ((yc = yang_find_datanode((yang_node*)ys, argument)) != NULL)
return yc;
break;
case YC_SCHEMANODE:
if ((yc = yang_find_schemanode((yang_node*)ys, argument)) != NULL)
return yc;
break;
case YC_DATADEFINITION:
break; /* nyi */
}
else
if ((yc = yang_find_datanode((yang_node*)ys, name)) != NULL)
return yc;
}
return NULL;
}
@ -1929,7 +2028,7 @@ yang_abs_schema_nodeid(yang_spec *yspec,
}
if (ymod == NULL){ /* Try with topnode */
yang_stmt *ys;
if ((ys = yang_find_topnode(yspec, id, 1)) == NULL){
if ((ys = yang_find_topnode(yspec, id, YC_SCHEMANODE)) == NULL){
clicon_err(OE_YANG, 0, "Module with id:%s:%s not found", prefix,id);
goto done;
}