* 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
|
|
@ -79,7 +79,7 @@ all: $(PLUGINS)
|
|||
|
||||
CLISPECS = $(APPNAME)_cli.cli
|
||||
|
||||
YANGSPECS = clixon-example@2019-01-13.yang
|
||||
YANGSPECS = clixon-example@2019-07-23.yang
|
||||
|
||||
# Backend plugin
|
||||
BE_SRC = $(APPNAME)_backend.c
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
* [Streams](#streams)
|
||||
* [RPC Operations](#rpc-operations)
|
||||
* [State data](#state-data)
|
||||
* [Extensions](#extension)
|
||||
* [Authentication and NACM](#authentication-and-nacm)
|
||||
* [Systemd](#systemd)
|
||||
* [Docker](#docker)
|
||||
|
|
@ -270,6 +271,33 @@ The example contains some stubs for authorization according to [RFC8341(NACM)](h
|
|||
* A basic auth HTTP callback, see: example_restconf_credentials() containing three example users: andy, wilma, and guest, according to the examples in Appendix A in [RFC8341](https://tools.ietf.org/html/rfc8341).
|
||||
* A NACM backend plugin reporting the mandatory NACM state variables.
|
||||
|
||||
## Extensions
|
||||
|
||||
Clixon supports Yang extensions, but you need to write plugin code.
|
||||
The example backend implements an "example:e4" Yang extension, as follows:
|
||||
```
|
||||
extension e4 {
|
||||
description
|
||||
"The first child of the ex:e4 (unknown) statement is replaced with its first
|
||||
child. This means that 'uses bar;' in the ex:e4 statement below is a valid
|
||||
data node";
|
||||
argument arg;
|
||||
}
|
||||
ex:e4 arg1{
|
||||
uses bar;
|
||||
}
|
||||
```
|
||||
|
||||
The backend plugin code registers an extension callback in the init struct:
|
||||
```
|
||||
.ca_extension=example_extension, /* yang extensions */
|
||||
```
|
||||
|
||||
The callback then receives a callback on all "unknown" Yang statements
|
||||
during yang parsing. If the extension matches "example:e4", it applies
|
||||
the extension. In the example, it replaces the "ex:e4" statements with
|
||||
its first child, making it a proper yang statement.
|
||||
|
||||
## Systemd
|
||||
|
||||
Example systemd files for backend and restconf daemons are found under the systemd directory. Install them under /etc/systemd/system for example.
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@ module clixon-example {
|
|||
yang-version 1.1;
|
||||
namespace "urn:example:clixon";
|
||||
prefix ex;
|
||||
revision 2019-07-23 {
|
||||
description "Extension e4. Released in Clixon 4.1.0";
|
||||
}
|
||||
revision 2019-01-13 {
|
||||
description
|
||||
"Released in Clixon 3.9";
|
||||
description "Released in Clixon 3.9";
|
||||
}
|
||||
import ietf-interfaces {
|
||||
prefix if;
|
||||
|
|
@ -40,6 +42,23 @@ module clixon-example {
|
|||
type string;
|
||||
}
|
||||
}
|
||||
/* yang extension implemented by the example backend code. */
|
||||
extension e4 {
|
||||
description
|
||||
"The first child of the ex:e4 (unknown) statement is replaced with its first
|
||||
child. This means that 'uses bar;' in the ex:e4 statement below is a valid
|
||||
data node";
|
||||
argument arg;
|
||||
}
|
||||
grouping bar {
|
||||
leaf bar{
|
||||
type string;
|
||||
}
|
||||
}
|
||||
ex:e4 arg1{
|
||||
uses bar;
|
||||
}
|
||||
|
||||
/* Example notification as used in RFC 5277 and RFC 8040 */
|
||||
notification event {
|
||||
description "Example notification event.";
|
||||
|
|
@ -351,6 +351,42 @@ example_statedata(clicon_handle h,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Callback for yang extensions example:e4
|
||||
*
|
||||
* @param[in] h Clixon handle
|
||||
* @param[in] yext Yang node of extension
|
||||
* @param[in] ys Yang node of (unknown) statement belonging to extension
|
||||
* @retval 0 OK, all callbacks executed OK
|
||||
* @retval -1 Error in one callback
|
||||
*/
|
||||
int
|
||||
example_extension(clicon_handle h,
|
||||
yang_stmt *yext,
|
||||
yang_stmt *ys)
|
||||
{
|
||||
int retval = -1;
|
||||
char *extname;
|
||||
char *modname;
|
||||
yang_stmt *ymod;
|
||||
yang_stmt *yc;
|
||||
|
||||
ymod = ys_module(yext);
|
||||
modname = yang_argument_get(ymod);
|
||||
extname = yang_argument_get(yext);
|
||||
if (strcmp(modname, "example") != 0 || strcmp(extname, "e4") != 0)
|
||||
goto ok;
|
||||
clicon_debug(1, "%s Enabled extension:%s:%s", __FUNCTION__, modname, extname);
|
||||
if ((yc = ys_prune(ys, 0)) == NULL)
|
||||
goto done;
|
||||
if (yn_insert(yang_parent_get(ys), yc) < 0)
|
||||
goto done;
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*! Testcase upgrade function moving interfaces-state to interfaces
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] xn XML tree to be updated
|
||||
|
|
@ -616,6 +652,7 @@ static clixon_plugin_api api = {
|
|||
clixon_plugin_init, /* init - must be called clixon_plugin_init */
|
||||
example_start, /* start */
|
||||
example_exit, /* exit */
|
||||
.ca_extension=example_extension, /* yang extensions */
|
||||
.ca_reset=example_reset, /* reset */
|
||||
.ca_statedata=example_statedata, /* statedata */
|
||||
.ca_trans_begin=main_begin, /* trans begin */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue