1# Clixon Restconf 2 3 * [Evhtp](#evhtp) 4 * [Nginx](#nginx) 5 * [Streams](#streams) 6 * [Nchan Streams](#nchan) 7 * [Debugging](#debugging) 8 9There are two installation instructions: for libevhtp and nginx. 10 11## Evhtp 12 13Download, build and install libevhtp from source. Prereqs: libevent and cmake. 14``` 15 git clone https://github.com/criticalstack/libevhtp.git 16 cd libevhtp/build 17 cmake -DEVHTP_DISABLE_REGEX=ON -DEVHTP_DISABLE_EVTHR=ON .. 18 make 19 sudo make install 20``` 21 22Configure clixon with evhtp: 23``` 24 ./configure --with-restconf=evhtp 25``` 26 27Ensure www-data is member of the CLICON_SOCK_GROUP (default clicon). If not, add it: 28``` 29 sudo usermod -a -G clicon www-data 30``` 31 32## Nginx 33 34Installation instruction for Nginx. Other reverse proxies should work but are not verified. 35 36Ensure www-data is member of the CLICON_SOCK_GROUP (default clicon). If not, add it: 37``` 38 sudo usermod -a -G clicon www-data 39``` 40 41This implementation uses FastCGI, see http://www.mit.edu/~yandros/doc/specs/fcgi-spec.html. 42 43Download and start nginx. For example on ubuntu: 44``` 45 sudo apt install ngnix 46``` 47on FreeBSD: 48``` 49 sudo pkg install ngnix 50``` 51 52Edit the nginx config file. (On Ubuntu: `/etc/nginx/sites-available/default`, on FreeBSD: `/usr/local/etc/nginx/sites-available/default`) 53``` 54 server { 55 ... 56 location / { 57 fastcgi_pass unix:/www-data/fastcgi_restconf.sock; 58 include fastcgi_params; 59 } 60 } 61``` 62 63Start nginx daemon 64``` 65 sudo /etc/init.d nginx start 66``` 67Alternatively, start it via systemd: 68``` 69 sudo systemctl start nginx.service 70``` 71Or on FreeBSD: 72``` 73 sudo service nginx start 74``` 75 76## Run 77 78Start clixon backend daemon (if not already started) 79``` 80 sudo clixon_backend -s init -f /usr/local/etc/example.xml 81``` 82 83Start clixon restconf daemon 84``` 85 sudo -u www-data -s /www-data/clixon_restconf -f /usr/local/etc/example.xml 86``` 87On FreeBSD: 88``` 89 sudo -u www -s /www/clixon_restconf -f /usr/local/etc/example.xml 90``` 91 92Make restconf calls with curl (or other http client). Example of writing a new interface specification: 93``` 94 curl -sX PUT http://localhost/restconf/data/ietf-interfaces:interfaces -H 'Content-Type: application/yang-data+json' -d '{"ietf-interfaces:interfaces":{"interface":{"name":"eth1","type":"clixon-example:eth","enabled":true}}}' 95``` 96 97Get the data 98``` 99 curl -X GET http://127.0.0.1/restconf/data/ietf-interfaces:interfaces 100 { 101 "ietf-interfaces:interfaces": { 102 "interface": [ 103 { 104 "name": "eth1", 105 "type": "clixon-example:eth", 106 "enabled": true 107 } 108 ] 109 } 110 } 111 112``` 113Get the type of a specific interface: 114``` 115 curl -X GET http://127.0.0.1/restconf/data/ietf-interfacesinterfaces/interface=eth1/type 116 { 117 "ietf-interfaces:type": "clixon-example:eth" 118 } 119``` 120 121## Streams 122 123Clixon have two experimental restconf event stream implementations following 124RFC8040 Section 6 using SSE. One native and one using Nginx 125nchan. The Nchan alternaitve is described in the 126next section. 127 128The [example](../../example/main/README.md) creates an EXAMPLE stream. 129 130Set the Clixon configuration options: 131``` 132<CLICON_STREAM_PATH>streams</CLICON_STREAM_PATH> 133<CLICON_STREAM_URL>https://example.com</CLICON_STREAM_URL> 134<CLICON_STREAM_RETENTION>3600</CLICON_STREAM_RETENTION> 135``` 136In this example, the stream EXAMPLE would be accessed with `https://example.com/streams/EXAMPLE`. 137 138The retention is configured as 1 hour, i.e., the stream replay function will only save timeseries one hour. 139 140Clixon defines an internal in-memory (not persistent) replay function 141controlled by the configure option above. 142 143You may access a restconf streams using curl. 144 145Add the following to extend the nginx configuration file with the following statements (for example): 146``` 147 location /streams { 148 fastcgi_pass unix:/www-data/fastcgi_restconf.sock; 149 include fastcgi_params; 150 proxy_http_version 1.1; 151 proxy_set_header Connection ""; 152 } 153``` 154 155An example of a stream access is as follows: 156``` 157> curl -H "Accept: text/event-stream" -s -X GET http://localhost/streams/EXAMPLE 158data: <notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>2018-11-04T14:47:11.373124</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event></notification> 159 160data: <notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>2018-11-04T14:47:16.375265</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event></notification> 161``` 162 163You can also specify start and stop time. Start-time enables replay of existing samples, while stop-time is used both for replay, but also for stopping a stream at some future time. 164``` 165 curl -H "Accept: text/event-stream" -s -X GET http://localhost/streams/EXAMPLE?start-time=2014-10-25T10:02:00&stop-time=2014-10-25T12:31:00 166``` 167 168See (stream tests)[../test/test_streams.sh] for more examples. 169 170## Nchan 171 172As an alternative streams implementation, Nginx/Nchan can be used. 173Nginx uses pub/sub channels and can be configured in a variety of 174ways. The following uses a simple variant with one generic subscription 175channel (streams) and one publication channel (pub). 176 177The advantage with Nchan is the large eco-system around Nginx and Nchan. 178 179Native mode and Nchan mode can co-exist, but the publish URL of Nchan should be different from the streams URL of the native streams. 180 181Nchan mode does not use Clixon retention, since it uses its own replay mechanism. 182 183Download and install nchan, see (https://nchan.io/#install). 184 185Add the following to extend the Nginx configuration file with the following statements (example): 186``` 187 location ~ /sub/(\w+)$ { 188 nchan_subscriber; 189 nchan_channel_id $1; #first capture of the location match 190 } 191 location ~ /pub/(\w+)$ { 192 nchan_publisher; 193 nchan_channel_id $1; #first capture of the location match 194 } 195``` 196 197Configure clixon with `--enable-publish` which enables curl code for 198publishing streams to nchan. 199 200You also need to configure CLICON_STREAM_PUB to enable pushing notifications to Nginx/Nchan. Example: 201``` 202<CLICON_STREAM_PUB>http://localhost/pub</CLICON_STREAM_PUB> 203``` 204Clicon will then publish events from stream EXAMPLE to `http://localhost/pub/EXAMPLE 205 206Access the event stream EXAMPLE using curl: 207``` 208 curl -H "Accept: text/event-stream" -s -X GET http://localhost/streams/EXAMPLE 209: hi 210 211id: 1541344320:0 212data: <notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>2018-11-04T15:12:00.435769</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event></notification> 213 214id: 1541344325:0 215data: <notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>2018-11-04T15:12:05.446425</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event></notification> 216 217``` 218Note that the SSE stream output is different than for native streams, and that `Last-Event-Id` is used for replay: 219``` 220curl -H "Accept: text/event-stream" -H "Last-Event-ID: 1539961709:0" -s -X GET http://localhost/streams/EXAMPLE 221``` 222 223See (https://nchan.io/#eventsource) on more info on how to access an SSE sub endpoint. 224 225## Debugging 226 227Start the restconf fastcgi program with debug flag: 228``` 229sudo su -c "/www-data/clixon_restconf -D 1 -f /usr/local/etc/example.xml" -s /bin/sh www-data 230``` 231Look at syslog: 232``` 233tail -f /var/log/syslog | grep clixon_restconf 234``` 235 236Send command: 237``` 238curl -G http://127.0.0.1/restconf/data/* 239``` 240 241You can also run restconf in a debugger. 242``` 243sudo gdb /www-data/clixon_restconf 244(gdb) run -D 1 -f /usr/local/etc/example.xml 245``` 246but you need to ensure /www-data/fastcgi_restconf.sock has the following access (may need to be done after restconf has started) 247``` 248rwxr-xr-x 1 www-data www-data 0 sep 22 11:46 /www-data/fastcgi_restconf.sock 249``` 250 251You can set debug level of the backend via restconf: 252``` 253 curl -is -X POST -H "Content-Type: application/yang-data+json" -d '{"clixon-lib:input":{"level":1}}' http://localhost/restconf/operations/clixon-lib:debug 254``` 255