* Added yang population of data in clicon_rpc_get[_config]
This commit is contained in:
parent
2de8497972
commit
bab3b5ad56
6 changed files with 114 additions and 62 deletions
|
|
@ -433,7 +433,6 @@ cli_show_config1(clicon_handle h,
|
|||
cvec *argv)
|
||||
{
|
||||
int retval = -1;
|
||||
int ret;
|
||||
char *db;
|
||||
char *formatstr;
|
||||
char *xpath;
|
||||
|
|
@ -496,13 +495,6 @@ cli_show_config1(clicon_handle h,
|
|||
clicon_rpc_generate_error(xerr, "Get configuration", NULL);
|
||||
goto done;
|
||||
}
|
||||
/* Some formats (eg cli) require yang */
|
||||
if ((ret = xml_spec_populate(xt, yspec, &xerr)) < 0)
|
||||
goto done;
|
||||
if (ret == 0){
|
||||
clicon_rpc_generate_error(xerr, "Get configuration", NULL);
|
||||
goto done;
|
||||
}
|
||||
/* Print configuration according to format */
|
||||
switch (format){
|
||||
case FORMAT_XML:
|
||||
|
|
@ -688,7 +680,6 @@ cli_show_auto1(clicon_handle h,
|
|||
cvec *argv)
|
||||
{
|
||||
int retval = 1;
|
||||
int ret;
|
||||
yang_stmt *yspec;
|
||||
char *api_path_fmt; /* xml key format */
|
||||
// char *api_path = NULL; /* xml key */
|
||||
|
|
@ -743,18 +734,10 @@ cli_show_auto1(clicon_handle h,
|
|||
if (clicon_rpc_get(h, xpath, nsc, CONTENT_ALL, -1, &xt) < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error(xerr, "Get configuration", NULL);
|
||||
goto done;
|
||||
}
|
||||
/* Some formats (eg cli) require yang */
|
||||
if ((ret = xml_spec_populate(xt, yspec, &xerr)) < 0)
|
||||
goto done;
|
||||
if (ret == 0){
|
||||
clicon_rpc_generate_error(xerr, "Get configuration", NULL);
|
||||
goto done;
|
||||
}
|
||||
if ((xp = xpath_first(xt, nsc, "%s", xpath)) != NULL)
|
||||
/* Print configuration according to format */
|
||||
switch (format){
|
||||
|
|
|
|||
|
|
@ -204,8 +204,6 @@ api_data_get2(clicon_handle h,
|
|||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if (xml_spec_populate(xret, yspec, NULL) < 0)
|
||||
goto done;
|
||||
/* We get return via netconf which is complete tree from root
|
||||
* We need to cut that tree to only the object.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -343,7 +343,7 @@ clicon_rpc_generate_error(cxobj *xerr,
|
|||
* @endcode
|
||||
* @see clicon_rpc_get
|
||||
* @see clicon_rpc_generate_error
|
||||
* @note the netconf return message us yang populated, but returned data is not
|
||||
* @note the netconf return message is yang populated, as well as the return data
|
||||
*/
|
||||
int
|
||||
clicon_rpc_get_config(clicon_handle h,
|
||||
|
|
@ -357,10 +357,13 @@ clicon_rpc_get_config(clicon_handle h,
|
|||
struct clicon_msg *msg = NULL;
|
||||
cbuf *cb = NULL;
|
||||
cxobj *xret = NULL;
|
||||
cxobj *xerr = NULL;
|
||||
cxobj *xd;
|
||||
cg_var *cv = NULL;
|
||||
char *prefix;
|
||||
uint32_t session_id;
|
||||
int ret;
|
||||
yang_stmt *yspec;
|
||||
|
||||
if (session_id_check(h, &session_id) < 0)
|
||||
goto done;
|
||||
|
|
@ -394,9 +397,21 @@ clicon_rpc_get_config(clicon_handle h,
|
|||
/* Send xml error back: first check error, then ok */
|
||||
if ((xd = xpath_first(xret, NULL, "/rpc-reply/rpc-error")) != NULL)
|
||||
xd = xml_parent(xd); /* point to rpc-reply */
|
||||
else if ((xd = xpath_first(xret, NULL, "/rpc-reply/data")) == NULL)
|
||||
else if ((xd = xpath_first(xret, NULL, "/rpc-reply/data")) == NULL){
|
||||
if ((xd = xml_new("data", NULL, NULL)) == NULL)
|
||||
goto done;
|
||||
}
|
||||
else{
|
||||
yspec = clicon_dbspec_yang(h);
|
||||
if ((ret = xml_spec_populate(xd, yspec, &xerr)) < 0)
|
||||
goto done;
|
||||
if (ret == 0){
|
||||
if ((xd = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
||||
clicon_err(OE_XML, ENOENT, "Expected rpc-error tag but none found(internal)");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (xt){
|
||||
if (xml_rm(xd) < 0)
|
||||
goto done;
|
||||
|
|
@ -406,6 +421,8 @@ clicon_rpc_get_config(clicon_handle h,
|
|||
done:
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
if (xerr)
|
||||
xml_free(xerr);
|
||||
if (xret)
|
||||
xml_free(xret);
|
||||
if (msg)
|
||||
|
|
@ -674,7 +691,7 @@ clicon_rpc_unlock(clicon_handle h,
|
|||
* @endcode
|
||||
* @see clicon_rpc_get_config which is almost the same as with content=config, but you can also select dbname
|
||||
* @see clicon_rpc_generate_error
|
||||
* @note the netconf return message us yang populated, but returned data is not
|
||||
* @note the netconf return message is yang populated, as well as the return data
|
||||
*/
|
||||
int
|
||||
clicon_rpc_get(clicon_handle h,
|
||||
|
|
@ -688,11 +705,14 @@ clicon_rpc_get(clicon_handle h,
|
|||
struct clicon_msg *msg = NULL;
|
||||
cbuf *cb = NULL;
|
||||
cxobj *xret = NULL;
|
||||
cxobj *xerr = NULL;
|
||||
cxobj *xd;
|
||||
char *username;
|
||||
cg_var *cv = NULL;
|
||||
char *prefix;
|
||||
uint32_t session_id;
|
||||
int ret;
|
||||
yang_stmt *yspec;
|
||||
|
||||
if (session_id_check(h, &session_id) < 0)
|
||||
goto done;
|
||||
|
|
@ -733,9 +753,21 @@ clicon_rpc_get(clicon_handle h,
|
|||
/* Send xml error back: first check error, then ok */
|
||||
if ((xd = xpath_first(xret, NULL, "/rpc-reply/rpc-error")) != NULL)
|
||||
xd = xml_parent(xd); /* point to rpc-reply */
|
||||
else if ((xd = xpath_first(xret, NULL, "/rpc-reply/data")) == NULL)
|
||||
else if ((xd = xpath_first(xret, NULL, "/rpc-reply/data")) == NULL){
|
||||
if ((xd = xml_new("data", NULL, NULL)) == NULL)
|
||||
goto done;
|
||||
}
|
||||
else{
|
||||
yspec = clicon_dbspec_yang(h);
|
||||
if ((ret = xml_spec_populate(xd, yspec, &xerr)) < 0)
|
||||
goto done;
|
||||
if (ret == 0){
|
||||
if ((xd = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
||||
clicon_err(OE_XML, ENOENT, "Expected rpc-error tag but none found(internal)");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (xt){
|
||||
if (xml_rm(xd) < 0)
|
||||
goto done;
|
||||
|
|
@ -745,6 +777,8 @@ clicon_rpc_get(clicon_handle h,
|
|||
done:
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
if (xerr)
|
||||
xml_free(xerr);
|
||||
if (xret)
|
||||
xml_free(xret);
|
||||
if (msg)
|
||||
|
|
|
|||
|
|
@ -1313,7 +1313,11 @@ populate_self_top(cxobj *xt,
|
|||
* err;
|
||||
* @endcode
|
||||
* @note For subs to anyxml nodes will not have spec set
|
||||
* There are several functions in the API family
|
||||
* @see xml_spec_populate_rpc for incoming rpc
|
||||
* @see xml_spec_populate_parent Not top-level and parent is properly yang populated
|
||||
* @see xml_spec_populate0 If the calling xml object should also be populated
|
||||
* @see xml_spec_populate0_parent
|
||||
*/
|
||||
int
|
||||
xml_spec_populate(cxobj *xt,
|
||||
|
|
@ -1357,9 +1361,15 @@ xml_spec_populate_parent(cxobj *xt,
|
|||
if (ret == 0)
|
||||
failed++;
|
||||
}
|
||||
retval = (failed==0) ? 1 : 0;
|
||||
if (failed)
|
||||
goto fail;
|
||||
retval = 1;
|
||||
done:
|
||||
return retval;
|
||||
fail:
|
||||
retval = 0;
|
||||
goto done;
|
||||
|
||||
}
|
||||
|
||||
/*! Find yang spec association of tree of XML nodes
|
||||
|
|
@ -1378,7 +1388,8 @@ xml_spec_populate0(cxobj *xt,
|
|||
|
||||
if ((ret = populate_self_top(xt, yspec, xerr)) < 0)
|
||||
goto done;
|
||||
if (ret == 1){
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
xc = NULL; /* Apply on children */
|
||||
while ((xc = xml_child_each(xt, xc, CX_ELMNT)) != NULL) {
|
||||
if ((ret = xml_spec_populate0_parent(xc, xerr)) < 0)
|
||||
|
|
@ -1386,10 +1397,14 @@ xml_spec_populate0(cxobj *xt,
|
|||
if (ret == 0)
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
retval = (failed==0) ? 1 : 0;
|
||||
if (failed)
|
||||
goto fail;
|
||||
retval = 1;
|
||||
done:
|
||||
return retval;
|
||||
fail:
|
||||
retval = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*! Find yang spec association of tree of XML nodes
|
||||
|
|
@ -1408,8 +1423,7 @@ xml_spec_populate0_parent(cxobj *xt,
|
|||
if ((ret = populate_self_parent(xt, xerr)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
failed++;
|
||||
else if (ret != 1){ /* 1 means anyxml parent */
|
||||
goto fail;
|
||||
xc = NULL; /* Apply on children */
|
||||
while ((xc = xml_child_each(xt, xc, CX_ELMNT)) != NULL) {
|
||||
if ((ret = xml_spec_populate0_parent(xc, xerr)) < 0)
|
||||
|
|
@ -1417,10 +1431,14 @@ xml_spec_populate0_parent(cxobj *xt,
|
|||
if (ret == 0)
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
retval = (failed==0) ? 1 : 0;
|
||||
if (failed)
|
||||
goto fail;
|
||||
retval = 1;
|
||||
done:
|
||||
return retval;
|
||||
fail:
|
||||
retval = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*! Given an XML node, build an xpath to root, internal function
|
||||
|
|
|
|||
|
|
@ -167,14 +167,16 @@ fi
|
|||
new "waiting"
|
||||
wait_backend
|
||||
|
||||
new "kill old restconf daemon"
|
||||
sudo pkill -u $wwwuser -f clixon_restconf
|
||||
if [ $RC -ne 0 ]; then
|
||||
new "kill old restconf daemon"
|
||||
sudo pkill -u $wwwuser -f clixon_restconf
|
||||
|
||||
new "start restconf daemon"
|
||||
start_restconf -f $cfg
|
||||
new "start restconf daemon"
|
||||
start_restconf -f $cfg
|
||||
|
||||
new "waiting"
|
||||
wait_restconf
|
||||
new "waiting"
|
||||
wait_restconf
|
||||
fi
|
||||
|
||||
# mandatory-leaf See RFC7950 Sec 7.17
|
||||
new "netconf set interface with augmented type and mandatory leaf"
|
||||
|
|
@ -240,7 +242,6 @@ EOF
|
|||
new "restconf POST augment multi-namespace path e2 (middle path)"
|
||||
expectpart "$(curl -s -X POST -H 'Content-Type: application/yang-data+xml' http://localhost/restconf/data/ietf-interfaces:interfaces/interface=e2 -d "$XML" )" 0 ''
|
||||
|
||||
|
||||
new "restconf GET augment multi-namespace top"
|
||||
expectpart "$(curl -si -X GET http://localhost/restconf/data/ietf-interfaces:interfaces)" 0 'HTTP/1.1 200 OK' '{"ietf-interfaces:interfaces":{"interface":\[{"name":"e1","type":"example-augment:some-new-iftype","example-augment:ospf":{"reference-bandwidth":23},"example-augment:mandatory-leaf":"true","example-augment:port":80,"example-augment:lport":8080},{"name":"e2","type":"fddi","example-augment:ospf":{"reference-bandwidth":23},"example-augment:mandatory-leaf":"true","example-augment:other":"ietf-interfaces:fddi","example-augment:port":80,"example-augment:lport":8080},{"name":"e3","type":"fddi","example-augment:mandatory-leaf":"true","example-augment:me":"you","example-augment:port":80,"example-augment:lport":8080}\]}}'
|
||||
|
||||
|
|
@ -253,8 +254,10 @@ expectpart "$(curl -si -X GET http://localhost/restconf/data/ietf-interfaces:int
|
|||
new "restconf GET augment multi-namespace cross level 2"
|
||||
expectpart "$(curl -si -X GET http://localhost/restconf/data/ietf-interfaces:interfaces/interface=e1/example-augment:ospf/reference-bandwidth)" 0 'HTTP/1.1 200 OK' '{"example-augment:reference-bandwidth":23}'
|
||||
|
||||
new "Kill restconf daemon"
|
||||
stop_restconf
|
||||
if [ $RC -ne 0 ]; then
|
||||
new "Kill restconf daemon"
|
||||
stop_restconf
|
||||
fi
|
||||
|
||||
if [ $BE -eq 0 ]; then
|
||||
exit # BE
|
||||
|
|
|
|||
|
|
@ -80,21 +80,36 @@ fi
|
|||
new "waiting"
|
||||
wait_backend
|
||||
|
||||
new "kill old restconf daemon"
|
||||
sudo pkill -u $wwwuser -f clixon_restconf
|
||||
if [ $RC -ne 0 ]; then
|
||||
new "kill old restconf daemon"
|
||||
sudo pkill -u $wwwuser -f clixon_restconf
|
||||
|
||||
new "start restconf daemon"
|
||||
start_restconf -f $cfg
|
||||
new "start restconf daemon"
|
||||
start_restconf -f $cfg
|
||||
|
||||
new "waiting"
|
||||
wait_restconf
|
||||
new "waiting"
|
||||
wait_restconf
|
||||
fi
|
||||
|
||||
new "restconf PUT add whole list entry"
|
||||
expecteq "$(curl -s -X PUT -H "Content-Type: application/yang-data+json" http://localhost/restconf/data/list:c/a=x,y -d '{"list:a":{"b":"x","c":"y","nonkey":"0"}}')" 0 ''
|
||||
|
||||
# GETs to ensure you get list [] in JSON
|
||||
new "restconf GET whole list entry"
|
||||
expecteq "$(curl -s -X GET -H "Accept: application/yang-data+json" http://localhost/restconf/data/list:c/)" 0 '{"list:c":{"a":[{"b":"x","c":"y","nonkey":"0"}]}}
|
||||
'
|
||||
|
||||
new "restconf GET list entry"
|
||||
expecteq "$(curl -s -X GET -H "Accept: application/yang-data+json" http://localhost/restconf/data/list:c/a=x,y)" 0 '{"list:a":[{"b":"x","c":"y","nonkey":"0"}]}
|
||||
'
|
||||
|
||||
new "restconf PUT add whole list entry XML"
|
||||
expecteq "$(curl -s -X PUT -H 'Content-Type: application/yang-data+xml' -H 'Accept: application/yang-data+xml' -d '<a xmlns="urn:example:clixon"><b>xx</b><c>xy</c><nonkey>0</nonkey></a>' http://localhost/restconf/data/list:c/a=xx,xy)" 0 ''
|
||||
|
||||
new "restconf GET list entry two XXX shouldnt be allowed"
|
||||
expecteq "$(curl -s -X GET -H "Accept: application/yang-data+json" http://localhost/restconf/data/list:c/a/b)" 0 '{"list:b":["x","xx"]}
|
||||
'
|
||||
|
||||
new "restconf PUT change whole list entry (same keys)"
|
||||
expecteq "$(curl -s -X PUT -H "Content-Type: application/yang-data+json" http://localhost/restconf/data/list:c/a=x,y -d '{"list:a":{"b":"x","c":"y","nonkey":"z"}}')" 0 ''
|
||||
|
||||
|
|
@ -149,9 +164,10 @@ expecteq "$(curl -s -X PUT -H "Content-Type: application/yang-data+json" http://
|
|||
new "restconf PUT change list+leaf-list entry (expect fail)"
|
||||
expectpart "$(curl -s -X PUT -H "Content-Type: application/yang-data+json" http://localhost/restconf/data/list:c/a=x,y/f=u -d '{"list:f":"w"}')" 0 '{"ietf-restconf:errors":{"error":{"error-type":"protocol","error-tag":"operation-failed","error-severity":"error","error-message":"api-path keys do not match data keys"}}}'
|
||||
|
||||
|
||||
new "Kill restconf daemon"
|
||||
stop_restconf
|
||||
if [ $RC -ne 0 ]; then
|
||||
new "Kill restconf daemon"
|
||||
stop_restconf
|
||||
fi
|
||||
|
||||
if [ $BE -eq 0 ]; then
|
||||
exit # BE
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue