Added configure option CLICON_STREAM_RETENTION is default number of seconds before dropping replay buffers

restconf
start-time and stop-time query parameters
stream_register->stream_add
This commit is contained in:
Olof hagsand 2018-10-28 22:13:33 +01:00
parent f23a21d5db
commit 208ccd82a8
11 changed files with 179 additions and 121 deletions

View file

@ -1,98 +1,81 @@
# Clixon Changelog
## 3.8.0 (Upcoming)
## 3.8.0 (Expected: Nov 4)
### Major New features
* YANG Features
* Yang 1.1 feature and if-feature according to RFC 7950 7.20.1 and 7.20.2.
* See https://github.com/clicon/clixon/issues/41
* Features are declared via CLICON_FEATURE in the configuration file. Examples showing enabling (1) a specific feature; (2) all features in a module; (3) all features in all modules:
```
* Features are declared via CLICON_FEATURE in the configuration file. Example below shows enabling (1) a specific feature; (2) all features in a module; (3) all features in all modules:
```
<CLICON_FEATURE>ietf-routing:router-id</CLICON_FEATURE>
<CLICON_FEATURE>ietf-routing:*</CLICON_FEATURE>
<CLICON_FEATURE>*:*</CLICON_FEATURE>
```
```
* logical combination of features not implemented, eg if-feature "not foo or bar and baz";
* ietf-netconf yang module added with candidate, validate, startup and xpath features enabled.
* YANG Module Library support
* According to RFC 7895 and implemented by ietf-yang-library.yang
* Changed Netconf hello to single capabilty urn:ietf:params:netconf:capability:yang-library:1.0 according to YANG 1.1 RFC7950 Sec 5.6.4.
* Set by option: CLICON_MODULE_LIBRARY_RFC7895 - enabled by default
* Option CLICON_MODULE_SET_ID is set and changed when modules change.
* Notification not supported
* YANG module library
* YANG modules according to RFC 7895 and implemented by ietf-yang-library.yang
* Enabled by configuration option CLICON_MODULE_LIBRARY_RFC7895 - enabled by default
* RFC 7895 defines a module-set-id. COnfigure option CLICON_MODULE_SET_ID is set and changed when modules change.
* Yang 1.1 notification support (RFC 7950: Sec 7.16)
* Restconf stream notification support - two variants.
* Both a "native" stream support and one using nginx/nchan pub/sub.
* See (apps/restconf/README.md) for details.
* New event streams implementation
* New event streams implementation with replay
* See clicon_stream.[ch] for details
* Added stream discovery according to RFC 5277 for netconf and RFC 8040 for restconf
* Enabled by CLICON_STREAM_DISCOVERY_RFC5277 and CLICON_STREAM_DISCOVERY_RFC8040.
* Enabled by CLICON_STREAM_DISCOVERY_RFC5277 and CLICON_STREAM_DISCOVERY_RFC8040
* Configure option CLICON_STREAM_RETENTION is default number of seconds before dropping replay buffers
8040.
* Restconf stream notification support according to RFC8040
* See (apps/restconf/README.md) for more details.
* start-time and stop-time query parameters
* Set access/subscribe base URL with: CLICON_STREAM_URL (default "https://localhost") and CLICON_STREAM_PATH (default "streams")
* Example: new stream "foo" will get access URL: https://localhost/streams/foo
* Optional pub/sub support enabled by ./configure --enable-publish
* Alternative variant using pub/sub support enabled by ./configure --enable-publish
* Set publish URL base with: CLICON_STREAM_PUB (default http://localhost/pub)
* Example: new stream "foo" will get pub URL: https://localhost/pub/foo
* Stream replay support
* Example: new stream "foo" will publish event streams on URL: https://localhost/pub/foo
* RFC8040 Restconf replay support: start-time and stop-time query parameter support
* This only applies to "native" restconf stream support, Nchan mode has different replay functionality
* RFC5277 Netconf replay support using <startTime> and
* RFC5277 Netconf replay supported
* Replay support is only in-memory and not persistent. External time-series DB could be added.
### API changes on existing features (you may need to change your code)
* clixon-config YAML file has new revision: 2018-10-21.
* Netconf hello capability updated to YANG 1.1 RFC7950 Sec 5.6.4
* Added urn:ietf:params:netconf:capability:yang-library:1.0
* Thanks @SCadilhac for helping out, see https://github.com/clicon/clixon/issues/39
* Major rewrite of event streams
* Major rewrite of event streams (as described above)
* If you used old event callbacks API, you need to switch to the streams API
* See clixon_stream.[ch]
* Old streams API which needs to be removed include:
* clicon_log_register_callback()
* subscription_add() --> stream_register()
* subscription_add() --> stream_add()
* backend_notify() and backend_notify_xml() - use stream_notify() instead
* Example uses "NETCONF" stream instead of "ROUTING"
* clixon_restconf and clixon_netconf now take -D <level> as command-line option instead of just -D
* clixon_restconf and clixon_netconf changed to take -D `<level>` as command-line option instead of just -D (without debig level)
* This aligns to clixon_cli and clixon_backend
* Application command option -S to clixon_netconf is obsolete. Use `clixon_netconf -l s` instead.
* Unified log handling for all clicon applications using -l e|o|s|f<file>.
* Unified log handling for all clicon applications using command-line option: `-l e|o|s|f<file>`.
* The options stand for e:stderr, o:stdout, s: syslog, f:file
* Added file logging (`-l f` or `-l f<file>`) for cases where neither syslog nor stderr is useful.
* Comply to RFC 8040 3.5.3.1 rule: api-identifier = [module-name ":"] identifier
* The "module-name" was a no-op before.
* This means that there was no difference between eg: GET /restconf/data/ietf-yang-library:modules-state and GET /restconf/data/XXXX:modules-state
* This means that there was no difference between eg: GET /restconf/data/ietf-yang-library:modules-state and GET /restconf/data/foobar:modules-state
* Generilized top-level yang parsing functions
* All yang modules are stored in the clicon_dbspec_yang() option.
* Except clixon-config module due to bug reported below
* Clarified semantics of main yang module:
* -y option to commands MUST specify filename
* CLICON_YANG_MODULE_MAIN MUST specify a module
* Command-line option -y MUST specify a filename
* Configure option CLICON_YANG_MODULE_MAIN MUST specify a module name
* yang_parse() changed to take either filename or module name and revision.
* Removed clicon_dbspec_name[_set]().
* Replace code for initializing the main yang module
* Replace yang_spec_main() with yang_spec_parse_module() as follows:
```
/* old code */
if ((yspec = yang_spec_main(ch)) == NULL)
goto done;
/* new code */
if ((yspec = yspec_new()) == NULL)
goto done;
clicon_dbspec_yang_set(h, yspec);
if (yang_spec_parse_module(h, clicon_yang_module_main(h),
clicon_yang_dir(h), clicon_yang_module_revision(h), yspec) < 0)
goto done;
```
* Removed clicon_dbspec_name() and clicon_dbspec_name_set().
* Replace calls to yang_spec_main() with yang_spec_parse_module(). See for
example backend_main() and others if you need details.
### Minor changes
* clixon-config YAML file has new revision: 2018-10-21.
* Allow new lines in CLI prompts
* uri_percent_encode() and xml_chardata_encode() changed to use stdarg parameters
* Added CLIXON_DEFAULT_CONFIG=/usr/local/etc/clixon.xml as option and in example (so you dont need to provide -f command-line option).
* Yang 1.1 action syntax added (but function is not supported)
* Added Configure option CLIXON_DEFAULT_CONFIG=/usr/local/etc/clixon.xml as option and in example (so you dont need to provide -f command-line option).
* New function: clicon_conf_xml() returns configuration tree
* Obsoleted COMPAT_CLIV and COMPAT_XSL that were optional in 3.7
* Added timeout option -t for clixon_netconf - quit after max time.
* Added -l option for clixon_backend for directing syslog to stderr or stdout if running in foreground
* Added command-line option `-t <timeout>` for clixon_netconf - quit after max time.
### Corrected Bugs
* Single quotes for XML attributes https://github.com/clicon/clixon/issues/51
@ -104,12 +87,12 @@
* Set dir /www-data with www-data as owner, see https://github.com/clicon/clixon/issues/37
### Known issues
* netconf rpc input is not sanity checked for wrong symbols (just ignored).
* Netconf RPC input is not sanity checked for wrong symbols (just ignored).
* Yang sub-command order and cardinality not checked.
* Top-level Yang symbol cannot be called "config" in any imported yang file.
* datastore uses "config" as reserved keyword for storing any XML whoich collides with code for detecting Yang sanity.
* Namespace name relabeling is not supported.
* Eg: if "des" is defined as prefix for an imported module, then a relabeling using xmlfns is not supported, such as:
* Eg: if "des" is defined as prefix for an imported module, then a relabeling using xmlns is not supported, such as:
```
<crypto xmlns:x="urn:example:des">x:des3</crypto>
```

View file

@ -1,8 +1,8 @@
# Clixon
Clixon is an automatic configuration manager where you generate
interactive CLI, NETCONF, RESTCONF and embedded databases with
transaction support from a YANG specification.
Clixon is a YANG-based configuration manager, with interactive CLI,
NETCONF and RESTCONF interfaces, an embedded database and transaction
support.
* [Background](#background)
* [Frequently asked questions](doc/FAQ.md)
@ -107,23 +107,21 @@ specification for handling XML configuration data. The YANG spec is
used to generate an interactive CLI, netconf and restconf clients. It
also manages an XML datastore.
Clixon mainly follows [YANG 1.0 RFC 6020](https://www.rfc-editor.org/rfc/rfc6020.txt) with some exceptions:
- conformance: deviation
- list features: min/max-elements, unique
- action statements
Clixon follows:
- [YANG 1.0 RFC 6020](https://www.rfc-editor.org/rfc/rfc6020.txt)
- [YANG 1.1 RFC 7950](https://www.rfc-editor.org/rfc/rfc7950.txt).
- [RFC 7895: YANG module library](http://www.rfc-base.org/txt/rfc-7895.txt)
The aim is also to cover new features in YANG 1.1 [YANG RFC 7950](https://www.rfc-editor.org/rfc/rfc7950.txt)
Clixon has its own XML library designed for performance.
However, the following YANG syntax modules are not implemented:
`deviation`, `min/max-elements`, `unique`, and `action`.
Netconf
=======
Clixon implements the following NETCONF proposals or standards:
- [NETCONF Configuration Protocol](http://www.rfc-base.org/txt/rfc-4741.txt)
- [Using the NETCONF Configuration Protocol over Secure Shell (SSH)](http://www.rfc-base.org/txt/rfc-4742.txt)
- [NETCONF Event Notifications](http://www.rfc-base.org/txt/rfc-5277.txt)
Some updates are being made to RFC 6241 and RFC 6242.
- [RFC 6241: NETCONF Configuration Protocol](http://www.rfc-base.org/txt/rfc-6241.txt)
- [RFC 6242: Using the NETCONF Configuration Protocol over Secure Shell (SSH)](http://www.rfc-base.org/txt/rfc-6242.txt)
- [RFC 5277: NETCONF Event Notifications](http://www.rfc-base.org/txt/rfc-5277.txt)
- [RFC 8341: Network Configuration Access Control Model](http://www.rfc-base.org/txt/rfc-8341.txt)
Clixon does not yet support the following netconf features:
@ -154,8 +152,6 @@ The Clixon datastore is a stand-alone XML based datastore. The idea is
to be able to use different datastores backends with the same
API.
Update: There used to be a key-value plugin based on qdbm but isnow obsoleted. Only a text datastore is implemented.
The datastore is primarily designed to be used by Clixon but can be used
separately.
@ -163,7 +159,6 @@ See [more detailed instructions](datastore/README.md).
Auth
====
Authentication is managed outside Clixon using SSH, SSL, Oauth2, etc.
For CLI, login is typically made via SSH. For netconf, SSH netconf

View file

@ -172,6 +172,7 @@ static int
restconf_stream(clicon_handle h,
FCGX_Request *r,
char *name,
cvec *qvec,
int pretty,
int use_xml,
int *sp)
@ -181,6 +182,9 @@ restconf_stream(clicon_handle h,
cxobj *xe;
cbuf *cb = NULL;
int s; /* socket */
int i;
cg_var *cv;
char *vname;
*sp = -1;
clicon_debug(1, "%s", __FUNCTION__);
@ -188,7 +192,23 @@ restconf_stream(clicon_handle h,
clicon_err(OE_XML, errno, "cbuf_new");
goto done;
}
cprintf(cb, "<rpc><create-subscription><stream>%s</stream></create-subscription></rpc>]]>]]>", name);
cprintf(cb, "<rpc><create-subscription><stream>%s</stream>", name);
/* Print all fields */
for (i=0; i<cvec_len(qvec); i++){
cv = cvec_i(qvec, i);
vname = cv_name_get(cv);
if (strcmp(vname, "start-time") == 0){
cprintf(cb, "<startTime>");
cv2cbuf(cv, cb);
cprintf(cb, "</startTime>");
}
else if (strcmp(vname, "stop-time") == 0){
cprintf(cb, "<stopTime>");
cv2cbuf(cv, cb);
cprintf(cb, "</stopTime>");
}
}
cprintf(cb, "</create-subscription></rpc>]]>]]>");
if (clicon_rpc_netconf(h, cbuf_get(cb), &xret, &s) < 0)
goto done;
if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) != NULL){
@ -267,7 +287,7 @@ api_stream(clicon_handle h,
int s=-1;
clicon_debug(1, "%s", __FUNCTION__);
path = FCGX_GetParam("REQUEST_URI", r->envp);
path = FCGX_GetParam("DOCUMENT_URI", r->envp);
query = FCGX_GetParam("QUERY_STRING", r->envp);
pretty = clicon_option_bool(h, "CLICON_RESTCONF_PRETTY");
test(r, 1);
@ -294,7 +314,6 @@ api_stream(clicon_handle h,
clicon_debug(1, "%s: method=%s", __FUNCTION__, method);
if (str2cvec(query, '&', '=', &qvec) < 0)
goto done;
if (str2cvec(path, '/', '=', &pcvec) < 0) /* rest url eg /album=ricky/foo */
goto done;
/* data */
@ -327,7 +346,7 @@ api_stream(clicon_handle h,
goto ok;
}
clicon_debug(1, "%s auth2:%d %s", __FUNCTION__, authenticated, clicon_username_get(h));
if (restconf_stream(h, r, method, pretty, use_xml, &s) < 0)
if (restconf_stream(h, r, method, qvec, pretty, use_xml, &s) < 0)
goto done;
if (s != -1){
/* Listen to backend socket */

View file

@ -2,17 +2,18 @@
## What is Clixon?
Clixon is a configuration management tool including a generated CLI ,
Yang parser, netconf and restconf interface and an embedded databases.
Clixon is a YANG-based configuration manager, with interactive CLI,
NETCONF and RESTCONF interfaces, an embedded database and transaction
support.
## Why should I use Clixon?
If you want an easy-to-use configuration frontend based on yang with an
If you want an easy-to-use configuration toolkit based on yang with an
open-source license. Typically for embedded devices requiring a
config interface such as routers and switches.
## What license is available?
CLIXON is dual license. Either Apache License, Version 2.0 or GNU
Clixon is dual license. Either Apache License, Version 2.0 or GNU
General Public License Version 2.
## Is Clixon extendible?
@ -41,6 +42,16 @@ The example:
sudo make install
```
## How do you run Clixon example commands?
- Start a backend server: `clixon_backend -Ff /usr/local/etc/example.xml`
- Start a cli session: `clixon_cli -f /usr/local/etc/example.xml`
- Start a netconf session: `clixon_netconf -f /usr/local/etc/example.xml`
- Start a restconf daemon: `sudo su -c "/www-data/clixon_restconf -f /usr/local/etc/example.xml " -s /bin/sh www-data`
- Send a restconf command: `curl -G http://127.0.0.1/restconf/data`
More info in the [example](../example) directory.
## Do I need to setup anything? (IMPORTANT)
The config demon requires a valid group to create a server UNIX domain socket.
@ -63,18 +74,11 @@ clicon:x:1001:<user>,www-data
## What about reference documentation?
Clixon uses Doxygen for reference documentation.
Build using 'make doc' and aim your browser at doc/html/index.html or
use the web resource: http://clicon.org/ref/index.html
## How do you run the example?
- Start a backend server: 'clixon_backend -Ff /usr/local/etc/example.xml'
- Start a cli session: clixon_cli -f /usr/local/etc/example.xml
- Start a netconf session: clixon_netconf -f /usr/local/etc/example.xml
Build using 'make doc' and aim your browser at doc/html/index.html.
## How is configuration data stored?
Configuration data is stored in an XML datastore. The default is a
text-based datastore. In the example the datastore are regular files found in
/usr/local/var/example/.
Configuration data is stored in an XML datastore. In the example the
datastore are regular files found in /usr/local/var/example/.
## What is validate and commit?
Clixon follows netconf in its validate and commit semantics.
@ -93,7 +97,7 @@ configuration file is /usr/local/etc/clixon.xml. The example
configuration file is installed at /usr/local/etc/example.xml. The
YANG specification for the configuration file is clixon-config.yang.
You can change where CLixon looks for the configuration FILE as follows:
You can change where Clixon looks for the configuration FILE as follows:
- Provide -f FILE option when starting a program (eg clixon_backend -f FILE)
- Provide --with-configfile=FILE when configuring
- Provide --with-sysconfig=<dir> when configuring, then FILE is <dir>/clixon.xml
@ -130,7 +134,9 @@ Look in the example documentation for more info.
As an alternative to cli configuration, you can use netconf. Easiest is to just pipe netconf commands to the clixon_netconf application.
Example:
```
echo "<rpc><get-config><source><candidate/></source><configuration/></get-config></rpc>]]>]]>" | clixon_netconf -f /usr/local/etc/example.xml
```
However, more useful is to run clixon_netconf as an SSH
subsystem. Register the subsystem in /etc/sshd_config:
@ -155,7 +161,6 @@ For example, using nginx, install, and edit config file: /etc/nginx/sites-availa
server {
...
location /restconf {
root /usr/share/nginx/html/restconf;
fastcgi_pass unix:/www-data/fastcgi_restconf.sock;
include fastcgi_params;
}
@ -166,8 +171,6 @@ Start nginx daemon
sudo /etc/init.d/nginx start
```
Read more in the restconf docs.
Example:
```
curl -G http://127.0.0.1/restconf/data/interfaces/interface/name=eth9/type
@ -177,14 +180,24 @@ Example:
}
]
```
Read more in the (restconf)[../apps/restconf] docs.
## How do I use notifications?
## Does Clixon support event streams?
Yes, Clixon supports event notification streams in the CLI, Netconf and Restconf API:s.
The example has a prebuilt notification stream called "EXAMPLE" that triggers every 5s.
You enable the notification via the CLI:
```
cli> notify
cli>
event-class fault;
reportingEntity {
card Ethernet0;
}
severity major;
...
```
or via NETCONF:
```

View file

@ -41,7 +41,7 @@ Send netconf command:
```
Start clixon restconf daemon
```
> sudo su -c "/www-data/clixon_restconf -f /usr/local/etc/example.xml " -s /bin/sh www-data
sudo su -c "/www-data/clixon_restconf -f /usr/local/etc/example.xml " -s /bin/sh www-data
```
Send restconf command
```
@ -81,7 +81,7 @@ Send restconf command
The example has an EXAMPLE stream notification triggering every 5s. To start a notification
stream in the session using netconf, create a subscription:
```
<rpc><create-subscription><stream>ROUTING</stream></create-subscription></rpc>]]>]]>
<rpc><create-subscription><stream>EXAMPLE</stream></create-subscription></rpc>]]>]]>
<rpc-reply><ok/></rpc-reply>]]>]]>
<notification><event>Routing notification</event></notification>]]>]]>
<notification><event>Routing notification</event></notification>]]>]]>

View file

@ -294,14 +294,18 @@ static clixon_plugin_api api = {
clixon_plugin_api *
clixon_plugin_init(clicon_handle h)
{
clicon_debug(1, "%s backend", __FUNCTION__);
struct timeval retention = {0,0};
clicon_debug(1, "%s backend", __FUNCTION__);
/* Example stream initialization:
* 1) Register EXAMPLE stream
* 2) setup timer for notifications, so something happens on stream
* 3) setup stream callbacks for notification to push channel
*/
if (stream_register(h, "EXAMPLE", "Example event stream", 1) < 0)
if (clicon_option_exists(h, "CLICON_STREAM_RETENTION"))
retention.tv_sec = clicon_option_int(h, "CLICON_STREAM_RETENTION");
if (stream_add(h, "EXAMPLE", "Example event stream", 1,
retention.tv_sec?&retention:NULL) < 0)
goto done;
/* assumes: CLIXON_PUBLISH_STREAMS, eg configure --enable-publish
*/

View file

@ -64,7 +64,7 @@ load("Load configuration from XML file") <filename:string>("Filename (local file
}
example("This is a comment") <var:int32>("Just a random number"), mycallback("myarg");
rpc("ex:fib-route rpc") <instance:string>("routing instance"), fib_route_rpc("myarg");
notify("Get notifications from backend"), cli_notify("NETCONF", "1", "text");
no("Negate") notify("Get notifications from backend"), cli_notify("NETCONF", "0", "xml");
notify("Get notifications from backend"), cli_notify("EXAMPLE", "1", "text");
no("Negate") notify("Get notifications from backend"), cli_notify("EXAMPLE", "0", "xml");
lock,cli_lock("candidate");
unlock,cli_unlock("candidate");

View file

@ -72,7 +72,9 @@ struct event_stream{
char *es_description;
struct stream_subscription *es_subscription;
int es_replay_enabled; /* set if replay is enables */
struct timeval es_retention; /* replay retention - how much to save */
struct stream_replay *es_replay;
};
typedef struct event_stream event_stream_t;
@ -80,7 +82,7 @@ typedef struct event_stream event_stream_t;
* Prototypes
*/
event_stream_t *stream_find(clicon_handle h, const char *name);
int stream_register(clicon_handle h, const char *name, const char *description, int replay_enabled);
int stream_add(clicon_handle h, const char *name, const char *description, int replay_enabled, struct timeval *retention);
int stream_delete_all(clicon_handle h);
int stream_get_xml(clicon_handle h, int access, cbuf *cb);
int stream_timer_setup(int fd, void *arg);

View file

@ -104,13 +104,18 @@ stream_find(clicon_handle h,
}
/*! Add notification event stream
*
* @param[in] h Clicon handle
* @param[in] name Name of stream
* @param[in] description Description of stream
* @param[in] replay_enabled Set if replay possible in stream
* @param[in] retention For replay buffer how much relative to save
*/
int
stream_register(clicon_handle h,
stream_add(clicon_handle h,
const char *name,
const char *description,
const int replay_enabled)
const int replay_enabled,
struct timeval *retention)
{
int retval = -1;
event_stream_t *es;
@ -131,6 +136,8 @@ stream_register(clicon_handle h,
goto done;
}
es->es_replay_enabled = replay_enabled;
if (retention)
es->es_retention = *retention;
clicon_stream_append(h, es);
ok:
retval = 0;
@ -159,9 +166,9 @@ stream_delete_all(clicon_handle h)
while ((ss = es->es_subscription) != NULL)
stream_ss_rm(es, ss);
while ((r = es->es_replay) != NULL){
DELQ(r, es->es_replay, struct stream_replay *);
if (r->r_xml)
xml_free(r->r_xml);
DELQ(r, es->es_replay, struct stream_replay *);
free(r);
}
free(es);
@ -224,20 +231,25 @@ stream_timer_setup(int fd,
struct timeval now;
struct timeval t;
struct timeval t1 = {STREAM_TIMER_TIMEOUT_S, 0};
struct timeval tret;
event_stream_t *es;
struct stream_subscription *ss;
struct stream_subscription *ss1;
struct stream_replay *r;
struct stream_replay *r1;
/* Go thru callbacks and see if any have timed out, if so remove them
* Could also be done by a separate timer.
*/
gettimeofday(&now, NULL);
/* for all event streams, remove subscription if past stop time */
/* For all event streams:
* 1) Go through subscriptions, if stop-time and its past, remove it
* XXX: but client may not be closed
* 2) Go throughreplay buffer and remove entries with passed retention time
*/
if ((es = clicon_stream(h)) != NULL){
do {
/* 1) Go through subscriptions, if stop-time and its past, remove it */
if ((ss = es->es_subscription) != NULL)
do {
if (timerisset(&ss->ss_stoptime) && timercmp(&ss->ss_stoptime, &now, <)){
@ -249,6 +261,23 @@ stream_timer_setup(int fd,
else
ss = NEXTQ(struct stream_subscription *, ss);
} while (ss && ss != es->es_subscription);
/* 2) Go throughreplay buffer and remove entries with passed retention time */
if (timerisset(&es->es_retention) &&
(r = es->es_replay) != NULL){
timersub(&now, &es->es_retention, &tret);
do {
if (timercmp(&r->r_tv, &tret, <)){
r1 = NEXTQ(struct stream_replay *, r);
DELQ(r, es->es_replay, struct stream_replay *);
if (r->r_xml)
xml_free(r->r_xml);
free(r);
r = r1;
}
else
r = NEXTQ(struct stream_replay *, r);
} while (r && r!=es->es_replay);
}
es = NEXTQ(struct event_stream *, es);
} while (es && es != clicon_stream(h));
}
@ -551,7 +580,6 @@ stream_replay_notify(clicon_handle h,
struct stream_subscription *ss)
{
int retval = -1;
struct stream_replay *r;
/* If <startTime> is not present, this is not a replay */

View file

@ -122,8 +122,14 @@ if false; then
# data: <notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>2018-10-21T19:22:16.387228</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event></notification>
new "restconf monitor event ok stream"
expectwait 'curl -s -X GET -H "Accept: text/event-stream" -H "Cache-Control: no-cache" -H "Connection: keep-alive" http://localhost/streams/EXAMPLE' 0 'foo' 2
expectwait 'curl -s -X GET -H "Accept: text/event-stream" -H "Cache-Control: no-cache" -H "Connection: keep-alive" http://localhost/streams/EXAMPLE' 0 'foo' 5
new "restconf monitor event starttime"
NOW=$(date +"%Y-%m-%dT%H%%3A%M%%3A%S")
sleep 10
expectwait "curl -s -X GET -H \"Accept: text/event-stream\" -H \"Cache-Control: no-cache\" -H \"Connection: keep-alive\" http://localhost/streams/EXAMPLE?start-time=$NOW" 0 'foo' 2
fi
# Restconf stream subscription RFC8040 Sec 6.3 - Nginx nchan solution
# Need manual testing
new "restconf monitor streams nchan NEEDS manual testing"

View file

@ -418,5 +418,13 @@ module clixon-config {
Note this may be a local/provate URL behind reverse-proxy.
If not given, do NOT enable stream publishing using NCHAN.";
}
leaf CLICON_STREAM_RETENTION {
type uint32;
default 0;
units s;
description "Retention for stream replay buffers in seconds, ie how much
data to store before dropping. 0 means no retention";
}
}
}