* Pushed tag to 4.0.1.PRE
* Restconf RFC 8040 increased feature compliance
* Cache-Control: no-cache added in HTTP responses (RFC Section 5.5)
* Restconf monitoring capabilities (RFC Section 9.1)
* Added support for Yang extensions
* New plugin callback: ca_extension
* Main backend example includes example code on how to implement a Yang extension in a plugin.
* JSON changes
* Non-pretty-print output removed all extra spaces.
* Example: `{"nacm-example:x": 42}` --> {"nacm-example:x":42}`
* Empty JSON container changed from `null` to `{}`.
* Empty list and leafs remain as `null`
* Removed unnecessary configure dependencies
* libnsl, libcrypt, libm, if_vlan,...
* pseudo-plugin added, to enable callbacks also for main programs. Useful for extensions
* Yang Unique statements with multiple schema identifiers did not work on some platforms due to memory error.
This commit is contained in:
parent
fe46a0e093
commit
e7b60619da
60 changed files with 1619 additions and 568 deletions
|
|
@ -149,6 +149,37 @@ backend_client_rm(clicon_handle h,
|
|||
return backend_client_delete(h, ce); /* actually purge it */
|
||||
}
|
||||
|
||||
/*!
|
||||
* Maybe should be in the restconf client instead of backend?
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] yspec Yang spec
|
||||
* @param[in] xpath Xpath selection, not used but may be to filter early
|
||||
* @param[out] xrs XML restconf-state node
|
||||
* @see netconf_create_hello
|
||||
* @see rfc8040 Sections 9.1
|
||||
*/
|
||||
static int
|
||||
client_get_capabilities(clicon_handle h,
|
||||
yang_stmt *yspec,
|
||||
char *xpath,
|
||||
cxobj **xret)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *xrstate = NULL; /* xml restconf-state node */
|
||||
cxobj *xcap = NULL; /* xml capabilities node */
|
||||
|
||||
if ((xrstate = xpath_first(*xret, "restconf-state")) == NULL){
|
||||
clicon_err(OE_YANG, ENOENT, "restconf-state not found in config node");
|
||||
goto done;
|
||||
}
|
||||
if ((xcap = xml_new("capabilities", xrstate, yspec)) == NULL)
|
||||
goto done;
|
||||
if (xml_parse_va(&xcap, yspec, "<capability>urn:ietf:params:restconf:capability:defaults:1.0?basic-mode=explicit</capability>") < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Get streams state according to RFC 8040 or RFC5277 common function
|
||||
* @param[in] h Clicon handle
|
||||
|
|
@ -165,23 +196,18 @@ static int
|
|||
client_get_streams(clicon_handle h,
|
||||
yang_stmt *yspec,
|
||||
char *xpath,
|
||||
char *module,
|
||||
yang_stmt *ymod,
|
||||
char *top,
|
||||
cxobj **xret)
|
||||
{
|
||||
int retval = -1;
|
||||
yang_stmt *ystream = NULL; /* yang stream module */
|
||||
yang_stmt *yns = NULL; /* yang namespace */
|
||||
cxobj *x = NULL;
|
||||
cbuf *cb = NULL;
|
||||
int ret;
|
||||
|
||||
if ((ystream = yang_find(yspec, Y_MODULE, module)) == NULL){
|
||||
clicon_err(OE_YANG, 0, "%s yang module not found", module);
|
||||
goto done;
|
||||
}
|
||||
if ((yns = yang_find(ystream, Y_NAMESPACE, NULL)) == NULL){
|
||||
clicon_err(OE_YANG, 0, "%s yang namespace not found", module);
|
||||
if ((yns = yang_find(ymod, Y_NAMESPACE, NULL)) == NULL){
|
||||
clicon_err(OE_YANG, 0, "%s yang namespace not found", yang_argument_get(ymod));
|
||||
goto done;
|
||||
}
|
||||
if ((cb = cbuf_new()) == NULL){
|
||||
|
|
@ -189,6 +215,9 @@ client_get_streams(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
cprintf(cb,"<%s xmlns=\"%s\">", top, yang_argument_get(yns));
|
||||
/* Second argument is a hack to have the same function for the
|
||||
* RFC5277 and 8040 stream cases
|
||||
*/
|
||||
if (stream_get_xml(h, strcmp(top,"restconf-state")==0, cb) < 0)
|
||||
goto done;
|
||||
cprintf(cb,"</%s>", top);
|
||||
|
|
@ -234,23 +263,47 @@ client_statedata(clicon_handle h,
|
|||
size_t xlen;
|
||||
int i;
|
||||
yang_stmt *yspec;
|
||||
yang_stmt *ymod;
|
||||
int ret;
|
||||
char *namespace;
|
||||
|
||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||
clicon_err(OE_YANG, ENOENT, "No yang spec");
|
||||
goto done;
|
||||
}
|
||||
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277")){
|
||||
if ((ret = client_get_streams(h, yspec, xpath, "clixon-rfc5277", "netconf", xret)) < 0)
|
||||
if ((ymod = yang_find_module_by_name(yspec, "clixon-rfc5277")) == NULL){
|
||||
clicon_err(OE_YANG, ENOENT, "yang module clixon-rfc5277 not found");
|
||||
goto done;
|
||||
}
|
||||
if ((namespace = yang_find_mynamespace(ymod)) == NULL){
|
||||
clicon_err(OE_YANG, ENOENT, "clixon-rfc5277 namespace not found");
|
||||
goto done;
|
||||
}
|
||||
if (xml_parse_va(xret, yspec, "<netconf xmlns=\"%s\"/>", namespace) < 0)
|
||||
goto done;
|
||||
if ((ret = client_get_streams(h, yspec, xpath, ymod, "netconf", xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
}
|
||||
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC8040")){
|
||||
if ((ret = client_get_streams(h, yspec, xpath, "ietf-restconf-monitoring", "restconf-state", xret)) < 0)
|
||||
if ((ymod = yang_find_module_by_name(yspec, "ietf-restconf-monitoring")) == NULL){
|
||||
clicon_err(OE_YANG, ENOENT, "yang module ietf-restconf-monitoring not found");
|
||||
goto done;
|
||||
}
|
||||
if ((namespace = yang_find_mynamespace(ymod)) == NULL){
|
||||
clicon_err(OE_YANG, ENOENT, "ietf-restconf-monitoring namespace not found");
|
||||
goto done;
|
||||
}
|
||||
if (xml_parse_va(xret, yspec, "<restconf-state xmlns=\"%s\"/>", namespace) < 0)
|
||||
goto done;
|
||||
if ((ret = client_get_streams(h, yspec, xpath, ymod, "restconf-state", xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
if ((ret = client_get_capabilities(h, yspec, xpath, xret)) < 0)
|
||||
goto done;
|
||||
}
|
||||
if (clicon_option_bool(h, "CLICON_MODULE_LIBRARY_RFC7895")){
|
||||
if ((ret = yang_modules_state_get(h, yspec, xpath, nsc, 0, xret)) < 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue