Limited http-data static server

* Renamed from www-data to http-data
* New `clixon-restconf@2022-03-21.yang` revision
  * Added option:
    * `enable-http-data`
  * Added feature: `http-data`
* Added new str2str mapper
* Test: new test_http_data.sh, added CI github action testing
This commit is contained in:
Olof hagsand 2022-04-21 15:37:58 +02:00
parent 76213057b6
commit 2a8cedf0c3
13 changed files with 551 additions and 76 deletions

View file

@ -2,9 +2,9 @@ name: Clixon CI
on:
push:
branches: [ master ]
branches: [ master, http-data ]
pull_request:
branches: [ master ]
branches: [ master, http-data ]
jobs:
build:

View file

@ -39,14 +39,16 @@ Expected: May 2022
### New features
* Extended the Restconf implementation with a limited www-data
* Extended the Restconf implementation with a limited http-data static service
* Added two new config options to clixon-config.yang:
* `CLICON_WWW_DATA_PATH`
* `CLICON_WWW_DATA_ROOT`
* The limited implemtation is as follows:
* path: Local files within `CLICON_WWW_DATA_ROOT`
* operation GET, HEAD, or OPTIONS
* query parameters not supported
* `CLICON_HTTP_DATA_PATH`
* `CLICON_HTTP_DATA_ROOT`
* Added feature http-data to restconf-config.yang and the following option:
* `enable-http-data`
* The limited implementation is as follows:
* path: Local static files within `CLICON_WWW_DATA_ROOT`
* operation GET, HEAD, or OPTIONS
* query parameters not supported
5. indata should be NULL (no write operations)
6. Limited media: text/html, JavaScript, image, and css
7. Authentication as restconf
@ -68,10 +70,12 @@ Users may have to change how they access the system
* New `clixon-config@2022-03-21.yang` revision
* Added option:
* `CLICON_NETCONF_BASE_CAPABILITY`
* `CLICON_WWW_DATA_PATH`
* `CLICON_WWW_DATA_ROOT`
* Added feature: `www-data`
* `CLICON_HTTP_DATA_PATH`
* `CLICON_HTTP_DATA_ROOT`
* New `clixon-restconf@2022-03-21.yang` revision
* Added option:
* `enable-http-data`
* Added feature: `http-data`
* Netconf data-not-unique info changed to return schema nodes instead of XML for RFC7950 compliance
* CLI reconnects to backend if backend restarts with a warning
* Note that edits to the candidate database or locks will be lost

View file

@ -98,7 +98,7 @@ APPSRC += restconf_methods_post.c
APPSRC += restconf_methods_get.c
APPSRC += restconf_methods_patch.c
APPSRC += restconf_root.c
APPSRC += clixon_www_data.c
APPSRC += clixon_http_data.c
APPSRC += restconf_main_$(with_restconf).c
ifeq ($(with_restconf),native)
APPSRC += restconf_http1.c

View file

@ -32,7 +32,7 @@
***** END LICENSE BLOCK *****
*
* Limited www data handler embedded in restconf code
* Limited static http data service embedded in restconf code
*/
@ -66,7 +66,23 @@
#include "restconf_handle.h"
#include "restconf_api.h"
#include "restconf_err.h"
#include "clixon_www_data.h"
#include "clixon_http_data.h"
/* File extension <-> HTTP Content media mapping
* File extensions (on the left) MIME types (to the right)
* @see https://www.iana.org/assignments/media-types/media-types.xhtml
*/
static const map_str2str mime_map[] = {
{"html", "text/html"},
{"css", "text/css"},
{"eot", "application/vnd.ms-fontobject"},
{"woff", "application/font-woff"},
{"js", "application/javascript"},
{"svg", "image/svg+xml"},
{"ico", "image/x-icon"},
{"woff2", "application/font-woff2"}, /* font/woff2? */
{ NULL, NULL} /* if not found: application/octet-stream */
};
/*! Check if uri path denotes a data path
*
@ -79,20 +95,20 @@ api_path_is_data(clicon_handle h,
char **data)
{
char *path;
char *www_data_path;
char *http_data_path;
if ((path = restconf_uripath(h)) == NULL)
return 0;
if ((www_data_path = clicon_option_str(h, "CLICON_WWW_DATA_PATH")) == NULL)
if ((http_data_path = clicon_option_str(h, "CLICON_HTTP_DATA_PATH")) == NULL)
return 0;
if (strlen(path) < 1 + strlen(www_data_path)) /* "/" + www_data_path */
if (strlen(path) < strlen(http_data_path))
return 0;
if (path[0] != '/')
return 0;
if (strncmp(path+1, www_data_path, strlen(www_data_path)) != 0)
if (strncmp(path, http_data_path, strlen(http_data_path)) != 0)
return 0;
if (data)
*data = path + 1 + strlen(www_data_path);
*data = path + strlen(http_data_path);
return 1;
}
@ -103,7 +119,7 @@ api_path_is_data(clicon_handle h,
* @see api_return_err
*/
static int
api_www_data_err(clicon_handle h,
api_http_data_err(clicon_handle h,
void *req,
int code)
{
@ -144,10 +160,11 @@ api_www_data_err(clicon_handle h,
* @param[in] pathname With stripped prefix (eg /data), ultimately a filename
* @note: primitive file handling, just check if file exists and read it all
* XXX 1: Buffer copying once too many, see #if 0 below
* XXX 2: Generic file system below CLICON_WWW_DATA_ROOT, no checks for links or ..
* XXX 2: Generic file system below CLICON_HTTP_DATA_ROOT, no checks for links or ..
* Need pathname santitization: no .. or ~, just a directory structure.
*/
static int
api_www_data_file(clicon_handle h,
api_http_data_file(clicon_handle h,
void *req,
char *pathname,
int head)
@ -161,28 +178,37 @@ api_www_data_file(clicon_handle h,
long fsize;
size_t sz;
char *www_data_root = NULL;
char *suffix;
char *media;
if ((cbfile = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
if ((www_data_root = clicon_option_str(h, "CLICON_WWW_DATA_ROOT")) == NULL){
clicon_err(OE_RESTCONF, ENOENT, "CLICON_WWW_DATA_ROOT missing");
if ((www_data_root = clicon_option_str(h, "CLICON_HTTP_DATA_ROOT")) == NULL){
clicon_err(OE_RESTCONF, ENOENT, "CLICON_HTTP_DATA_ROOT missing");
goto done;
}
/* Need pathname santitization: no .. or ~, just a directory structure.
*/
if ((suffix = rindex(pathname, '.')) == NULL){
media = "application/octet-stream";
}
else {
suffix++;
if ((media = clicon_str2str(mime_map, suffix)) == NULL)
media = "application/octet-stream";
}
cprintf(cbfile, "%s", www_data_root);
if (pathname)
cprintf(cbfile, "/%s", pathname);
filename = cbuf_get(cbfile);
if (stat(filename, &fstat) < 0){
if (api_www_data_err(h, req, 404) < 0) /* not found */
if (api_http_data_err(h, req, 404) < 0) /* not found */
goto done;
goto ok;
}
if ((f = fopen(filename, "rb")) == NULL){
if (api_www_data_err(h, req, 403) < 0) /* Forbidden or 500? */
if (api_http_data_err(h, req, 403) < 0) /* Forbidden or 500? */
goto done;
goto ok;
}
@ -218,7 +244,7 @@ api_www_data_file(clicon_handle h,
}
}
#endif
if (restconf_reply_header(req, "Content-Type", "%s", "text/html") < 0)
if (restconf_reply_header(req, "Content-Type", "%s", media) < 0)
goto done;
if (restconf_reply_send(req, 200, cbdata, head) < 0)
goto done;
@ -235,11 +261,11 @@ api_www_data_file(clicon_handle h,
return retval;
}
/*! Gete data request
/*! Get data request
*
* This implementation is constrained as follows:
* 1. Enable as part of restconf and set feature www-data and CLICON_WWW_DATA_PATH
* 2. path: Local files within CLICON_WWW_DATA_ROOT
* 1. Enable as part of restconf and set feature www-data and CLICON_HTTP_DATA_PATH
* 2. path: Local files within CLICON_HTTP_DATA_ROOT
* 3. operations: GET, HEAD, OPTIONS
* 4. query parameters not supported
* 5. indata should be NULL (no write operations)
@ -252,9 +278,9 @@ api_www_data_file(clicon_handle h,
* Need to enable clixon-restconf.yang www-data feature
*/
int
api_www_data(clicon_handle h,
void *req,
cvec *qvec)
api_http_data(clicon_handle h,
void *req,
cvec *qvec)
{
int retval = -1;
char *request_method = NULL;
@ -273,7 +299,7 @@ api_www_data(clicon_handle h,
/* 1. path: with stripped prefix, ultimately: dir/filename
*/
if (!api_path_is_data(h, &pathname)){
if (api_www_data_err(h, req, 404) < 0) /* not found */
if (api_http_data_err(h, req, 404) < 0) /* not found */
goto done;
goto ok;
}
@ -288,13 +314,13 @@ api_www_data(clicon_handle h,
options = 1;
}
else {
if (api_www_data_err(h, req, 405) < 0) /* method not allowed */
if (api_http_data_err(h, req, 405) < 0) /* method not allowed */
goto done;
goto ok;
}
/* 3. query parameters not accepted */
if (qvec != NULL){
if (api_www_data_err(h, req, 400) < 0) /* bad request */
if (api_http_data_err(h, req, 400) < 0) /* bad request */
goto done;
goto ok;
}
@ -304,7 +330,7 @@ api_www_data(clicon_handle h,
goto done;
}
if (cbuf_len(indata)){
if (api_www_data_err(h, req, 400) < 0) /* bad request */
if (api_http_data_err(h, req, 400) < 0) /* bad request */
goto done;
goto ok;
}
@ -332,7 +358,7 @@ api_www_data(clicon_handle h,
if (restconf_reply_send(req, 200, NULL, 0) < 0)
goto done;
}
else if (api_www_data_file(h, req, pathname, head) < 0)
else if (api_http_data_file(h, req, pathname, head) < 0)
goto done;
ok:
retval = 0;

View file

@ -32,16 +32,16 @@
***** END LICENSE BLOCK *****
*
* Limited www data handler embedded in restconf code
* Limited static http data service embedded in restconf code
*/
#ifndef _CLIXON_WWW_DATA_H_
#define _CLIXON_WWW_DATA_H_
#ifndef _CLIXON_HTTP_DATA_H_
#define _CLIXON_HTTP_DATA_H_
/*
* Prototypes
*/
int api_path_is_data(clicon_handle h, char **data);
int api_www_data(clicon_handle h, void *req, cvec *qvec);
int api_http_data(clicon_handle h, void *req, cvec *qvec);
#endif /* _CLIXON_WWW_DATA_H_ */
#endif /* _CLIXON_HTTP_DATA_H_ */

View file

@ -66,7 +66,7 @@
#include "restconf_err.h"
#include "clixon_http1_parse.h"
#include "restconf_http1.h"
#include "clixon_www_data.h"
#include "clixon_http_data.h"
/* Size of xml read buffer */
#define BUFLEN 1024
@ -428,7 +428,7 @@ restconf_http1_path_root(clicon_handle h,
goto done;
}
else if (api_path_is_data(h, NULL)){
if (api_www_data(h, sd, sd->sd_qvec) < 0)
if (api_http_data(h, sd, sd->sd_qvec) < 0)
goto done;
}
else if (api_root_restconf(h, sd, sd->sd_qvec) < 0) /* error handling */

View file

@ -87,7 +87,7 @@
#include "restconf_native.h" /* Restconf-openssl mode specific headers*/
#ifdef HAVE_LIBNGHTTP2 /* Ends at end-of-file */
#include "restconf_nghttp2.h" /* Restconf-openssl mode specific headers*/
#include "clixon_www_data.h"
#include "clixon_http_data.h"
#define ARRLEN(x) (sizeof(x) / sizeof(x[0]))
@ -326,7 +326,7 @@ restconf_nghttp2_path(restconf_stream_data *sd)
goto done;
}
else if (api_path_is_data(h, NULL)){
if (api_www_data(h, sd, sd->sd_qvec) < 0)
if (api_http_data(h, sd, sd->sd_qvec) < 0)
goto done;
}
else if (api_root_restconf(h, sd, sd->sd_qvec) < 0) /* error handling */

View file

@ -100,7 +100,8 @@ int uri_percent_decode(char *enc, char **str);
const char *clicon_int2str(const map_str2int *mstab, int i);
int clicon_str2int(const map_str2int *mstab, char *str);
int clicon_str2int_search(const map_str2int *mstab, char *str, int upper);
int nodeid_split(char *nodeid, char **prefix, char **id);
char *clicon_str2str(const map_str2str *mstab, char *str);
int nodeid_split(char *nodeid, char **prefix, char **id);
char *clixon_trim(char *str);
char *clixon_trim2(char *str, char *trims);
int clicon_strcmp(char *s1, char *s2);

View file

@ -787,6 +787,24 @@ clicon_str2int_search(const map_str2int *mstab,
return -1; /* not found */
}
/*! Map from string to string using str2str map
* @param[in] mstab String, string map
* @param[in] str Input string
* @retval str Output string
* @retval NULL Error, not found
*/
char*
clicon_str2str(const map_str2str *mstab,
char *str)
{
const struct map_str2str *ms;
for (ms = &mstab[0]; ms->ms_s0; ms++)
if (strcmp(ms->ms_s0, str) == 0)
return ms->ms_s1;
return NULL;
}
/*! Split colon-separated node identifier into prefix and name
* @param[in] node-id
* @param[out] prefix If non-NULL, return malloced string, or NULL.

158
test/test_http_data.sh Executable file
View file

@ -0,0 +1,158 @@
#!/usr/bin/env bash
# Simple web data
# Magic line must be first in script (see README.md)
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
APPNAME=example
cfg=$dir/conf.xml
wdir=$dir/www
rm -rf $wdir
mkdir $wdir
# Does not work with fcgi
if [ "${WITH_RESTCONF}" = "fcgi" ]; then
echo "...skipped: Must run with --with-restconf=native"
if [ "$s" = $0 ]; then exit 0; else return 0; fi
fi
RESTCONFIG=$(restconf_config none false)
# Clixon config
cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config">
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_FEATURE>clixon-restconf:allow-auth-none</CLICON_FEATURE> <!-- Use auth-type=none -->
<CLICON_FEATURE>clixon-restconf:http-data</CLICON_FEATURE>
<CLICON_YANG_DIR>${YANG_INSTALLDIR}</CLICON_YANG_DIR>
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
<CLICON_YANG_MAIN_DIR>$dir</CLICON_YANG_MAIN_DIR>
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
<CLICON_BACKEND_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP>
<CLICON_RESTCONF_DIR>/usr/local/lib/$APPNAME/restconf</CLICON_RESTCONF_DIR>
<CLICON_HTTP_DATA_PATH>/data</CLICON_HTTP_DATA_PATH>
<CLICON_HTTP_DATA_ROOT>$wdir</CLICON_HTTP_DATA_ROOT>
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
<CLICON_RESTCONF_HTTP2_PLAIN>true</CLICON_RESTCONF_HTTP2_PLAIN>
$RESTCONFIG
</clixon-config>
EOF
# Host setup:
# <CLICON_HTTP_DATA_PATH>/</CLICON_HTTP_DATA_PATH>
# <CLICON_HTTP_DATA_ROOT>/var/www/html</CLICON_HTTP_DATA_ROOT>
# Data file
cat <<EOF > $wdir/index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to Clixon!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to Clixon!</h1>
<p>If you see this page, the clixon web server is successfully installed and
working. Further configuration is required.</p>
</body>
</html>
EOF
cat <<EOF > $wdir/example.css
img {
display: inline;
border:
0 none;
}
body {
font-family: verdana, arial, helvetica, sans-serif;
text-align: left;
position: relative;
}
table {
border-collapse: collapse;
text-align: left;
}
div, span {
text-align:left;
}
h1,h2,h3,h4,h5,h6 {
color: white;
}
EOF
new "test params: -f $cfg"
if [ $BE -ne 0 ]; then
new "kill old backend"
sudo clixon_backend -zf $cfg
if [ $? -ne 0 ]; then
err
fi
sudo pkill -f clixon_backend # to be sure
new "start backend -s init -f $cfg"
start_backend -s init -f $cfg
fi
new "wait backend"
wait_backend
if [ $RC -ne 0 ]; then
new "kill old restconf daemon"
stop_restconf_pre
new "start restconf daemon"
start_restconf -f $cfg
fi
new "wait restconf"
wait_restconf
new "WWW get html"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: text/html' $RCPROTO://localhost/data/index.html)" 0 "HTTP/$HVER 200" "Content-Type: text/html" "<title>Welcome to Clixon!</title>"
new "WWW get css"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: text/html' $RCPROTO://localhost/data/example.css)" 0 "HTTP/$HVER 200" "Content-Type: text/css" "display: inline;" --not-- "Content-Type: text/html"
new "WWW head"
expectpart "$(curl $CURLOPTS --head -H 'Accept: text/html' $RCPROTO://localhost/data/index.html)" 0 "HTTP/$HVER 200" "Content-Type: text/html" --not-- "<title>Welcome to Clixon!</title>"
new "WWW options"
expectpart "$(curl $CURLOPTS -X OPTIONS $RCPROTO://localhost/data/index.html)" 0 "HTTP/$HVER 200" "allow: OPTIONS,HEAD,GET"
new "WWW get http not found"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: text/html' $RCPROTO://localhost/data/notfound.html)" 0 "HTTP/$HVER 404" "Content-Type: text/html" "<title>404 Not Found</title>"
new "WWW post not allowed"
expectpart "$(curl $CURLOPTS -X POST -H 'Accept: text/html' -H "Content-Type: application/yang-data+json" -d '{"ietf-interfaces:interfaces":{"interface":{"name":"eth/0/0","type":"clixon-example:eth","enabled":true}}}' $RCPROTO://localhost/data/notfound.html)" 0 "HTTP/$HVER 405" "Content-Type: text/html" "<title>405 Method Not Allowed</title>"
if [ $BE -ne 0 ]; then
new "Kill backend"
# Check if premature kill
pid=$(pgrep -u root -f clixon_backend)
if [ -z "$pid" ]; then
err "backend already dead"
fi
# kill backend
stop_backend -f $cfg
fi
rm -rf $dir
new "endtest"
endtest

View file

@ -46,7 +46,7 @@ YANGSPECS = clixon-config@2022-03-21.yang # 5.7
YANGSPECS += clixon-lib@2021-12-05.yang # 5.5
YANGSPECS += clixon-rfc5277@2008-07-01.yang
YANGSPECS += clixon-xml-changelog@2019-03-21.yang
YANGSPECS += clixon-restconf@2021-05-20.yang # 5.2
YANGSPECS += clixon-restconf@2022-03-21.yang # 5.7
YANGSPECS += clixon-autocli@2022-02-11.yang # 5.6
all:

View file

@ -50,10 +50,8 @@ module clixon-config {
description
"Added option:
CLICON_NETCONF_BASE_CAPABILITY
CLICON_WWW_DATA_PATH
CLICON_WWW_DATA_ROOT
Added feature:
www-data
CLICON_HTTP_DATA_PATH
CLICON_HTTP_DATA_ROOT
Released in Clixon 5.7";
}
revision 2022-02-11 {
@ -216,20 +214,6 @@ module clixon-config {
description
"Released in Clixon 3.8";
}
feature www-data {
description
"This feature allows for a very limited www-data function as
addition to RESTCONF.
it is limited to:
1. path: Local files within WWW_DATA_ROOT
2. operation GET or HEAD
3. query parameters not supported
4. indata should be NULL (no write operations)
5. Limited media: text/html, JavaScript, image, and css
6. Authentication as restconf
7. HTTP/1+2, TLS as restconf";
}
extension search_index {
description "This list argument acts as a search index using optimized binary search.
";
@ -619,14 +603,14 @@ module clixon-config {
Note this also disables plain http/2 in prior-knowledge, that is, in http/2-only mode.
HTTP/2 in https(TLS) is unaffected";
}
leaf CLICON_WWW_DATA_PATH {
if-feature "www-data";
leaf CLICON_HTTP_DATA_PATH {
if-feature "clrc:http-data";
type string;
description
"If set, enable www data on this sub-path";
"If set, enable www data on this sub-path, must start with / (example: /data)";
}
leaf CLICON_WWW_DATA_ROOT {
if-feature "www-data";
leaf CLICON_HTTP_DATA_ROOT {
if-feature "clrc:http-data";
type string;
default "/var/www";
description

View file

@ -0,0 +1,284 @@
module clixon-restconf {
yang-version 1.1;
namespace "http://clicon.org/restconf";
prefix "clrc";
import ietf-inet-types {
prefix inet;
}
organization
"Clixon";
contact
"Olof Hagsand <olof@hagsand.se>";
description
"This YANG module provides a data-model for the Clixon RESTCONF daemon.
There is also clixon-config also including some restconf options.
The separation is not always logical but there are some reasons for the split:
1. Some data (ie 'socket') is structurally complex and cannot be expressed as a
simple option
2. clixon-restconf is defined as a macro/grouping and can be included in
other YANGs. In particular, it can be used inside a datastore, which
is not possible for clixon-config.
3. Related to (2), options that should not be settable in a datastore should be
in clixon-config
***** BEGIN LICENSE BLOCK *****
Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate)
This file is part of CLIXON
Licensed under the Apache License, Version 2.0 (the \"License\");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an \"AS IS\" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Alternatively, the contents of this file may be used under the terms of
the GNU General Public License Version 3 or later (the \"GPL\"),
in which case the provisions of the GPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of the GPL, and not to allow others to
use your version of this file under the terms of Apache License version 2,
indicate your decision by deleting the provisions above and replace them with
the notice and other provisions required by the GPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the Apache License version 2 or the GPL.
***** END LICENSE BLOCK *****";
revision 2022-03-21 {
description
"Added feature:
http-data - Limited static http server
Released in Clixon 5.7";
}
revision 2021-05-20 {
description
"Added log-destination for restconf
Released in Clixon 5.2";
}
revision 2021-03-15 {
description
"make authentication-type none a feature
Added flag to enable core dumps
Released in Clixon 5.1";
}
revision 2020-12-30 {
description
"Added: debug field
Added 'none' as default value for auth-type
Changed http-auth-type enum from 'password' to 'user'";
}
revision 2020-10-30 {
description
"Initial release";
}
feature fcgi {
description
"This feature indicates that the restconf server supports the fast-cgi reverse
proxy solution.
That is, a reverse proxy is the HTTP front-end and the restconf daemon listens
to a fcgi socket.
The alternative is the internal native HTTP solution.";
}
feature allow-auth-none {
description
"This feature allows the use of authentication-type none.";
}
feature http-data {
description
"This feature allows for a very limited static http-data function as
addition to RESTCONF.
It is limited to:
1. path: Local static files within WWW_DATA_ROOT
2. operation GET, HEAD, OPTIONS
3. query parameters not supported
4. indata should be NULL (no write operations)
5. Limited media: text/html, JavaScript, image, and css
6. Authentication as restconf
7. HTTP/1+2, TLS as restconf";
}
typedef http-auth-type {
type enumeration {
enum none {
if-feature "allow-auth-none";
description
"Incoming message are set to authenticated by default. No ca-auth callback is called,
Authenticated user is set to special user 'none'.
Typically assumes NACM is not enabled.";
}
enum client-certificate {
description
"TLS client certificate validation is made on each incoming message. If it passes
the authenticated user is extracted from the SSL_CN parameter
The ca-auth callback can be used to revise this behavior.";
}
enum user {
description
"User-defined authentication as defined by the ca-auth callback.
One example is some form of password authentication, such as basic auth.";
}
}
description
"Enumeration of HTTP authorization types.";
}
typedef log-destination {
type enumeration {
enum syslog {
description
"Log to syslog with:
ident: clixon_restconf and PID
facility: LOG_USER";
}
enum file {
description
"Log to generated file at /var/log/clixon_restconf.log";
}
}
}
grouping clixon-restconf{
description
"HTTP RESTCONF configuration.";
leaf enable {
type boolean;
default "false";
description
"Enables RESTCONF functionality.
Note that starting/stopping of a restconf daemon is different from it being
enabled or not.
For example, if the restconf daemon is under systemd management, the restconf
daemon will only start if enable=true.";
}
leaf enable-http-data {
type boolean;
default "false";
if-feature "http-data";
description
"Enables Limited static http-data functionality.
enable must be true for this option to be meaningful.";
}
leaf auth-type {
type http-auth-type;
description
"The authentication type.
Note client-certificate applies only if ssl-enable is true and socket has ssl";
default user;
}
leaf debug {
description
"Set debug level of restconf daemon.
0 is no debug, 1 is debugging, more is detailed debug.
Debug logs will be directed to log-destination with LOG_DEBUG level (for syslog)";
type uint32;
default 0;
}
leaf log-destination {
description
"Log destination.
If debug is not set, only notice, error and warning will be logged";
type log-destination;
default syslog;
}
leaf enable-core-dump {
description
"enable core dumps.
this is a no-op on systems that don't support it.";
type boolean;
default false;
}
leaf pretty {
type boolean;
default true;
description
"Restconf return value pretty print.
Restconf clients may add HTTP header:
Accept: application/yang-data+json, or
Accept: application/yang-data+xml
to get return value in XML or JSON.
RFC 8040 examples print XML and JSON in pretty-printed form.
Setting this value to false makes restconf return not pretty-printed
which may be desirable for performance or tests
This replaces the CLICON_RESTCONF_PRETTY option in clixon-config.yang";
}
/* From this point only specific options
* First fcgi-specific options
*/
leaf fcgi-socket {
if-feature fcgi; /* Set by default by fcgi clixon_restconf daemon */
type string;
default "/www-data/fastcgi_restconf.sock";
description
"Path to FastCGI unix socket. Should be specified in webserver
Eg in nginx: fastcgi_pass unix:/www-data/clicon_restconf.sock
Only if with-restconf=fcgi, NOT native
This replaces CLICON_RESTCONF_PATH option in clixon-config.yang";
}
/* Second, local native options */
leaf server-cert-path {
type string;
description
"Path to server certificate file.
Note only applies if socket has ssl enabled";
}
leaf server-key-path {
type string;
description
"Path to server key file
Note only applies if socket has ssl enabled";
}
leaf server-ca-cert-path {
type string;
description
"Path to server CA cert file
Note only applies if socket has ssl enabled";
}
list socket {
description
"List of server sockets that the restconf daemon listens to.
Not fcgi";
key "namespace address port";
leaf namespace {
type string;
description
"Network namespace.
On platforms where namespaces are not suppported, 'default'
Default value can be changed by RESTCONF_NETNS_DEFAULT";
}
leaf address {
type inet:ip-address;
description "IP address to bind to";
}
leaf port {
type inet:port-number;
description "TCP port to bind to";
}
leaf ssl {
type boolean;
default true;
description "Enable for HTTPS otherwise HTTP protocol";
}
}
}
container restconf {
description
"This presence is strictly not necessary since the enable flag
in clixon-restconf is the flag bearing the actual semantics.
However, removing the presence leads to default config in all
clixon installations, even those which do not use backend-started restconf.
One could see this as mostly cosmetically annoying.
Alternative would be to make the inclusion of this yang conditional.";
presence "Enables RESTCONF";
uses clixon-restconf;
}
}