- Better restconf debug: when restconf debug flag set in datastore, ensure the process is started with -D set

- Fixed native http support for base container
- Changed test certs and restconf scripts to functions
This commit is contained in:
Olof hagsand 2021-04-08 22:40:41 +02:00
parent 244060fddc
commit 15d01c58d8
49 changed files with 539 additions and 103 deletions

View file

@ -61,6 +61,44 @@
#define RESTCONF_PROCESS "restconf" #define RESTCONF_PROCESS "restconf"
/*! Set current debug flag when starting process using -D <dbg>
*
* process argv list including -D is set on start. But the debug flags may change and this is a way
* to set it dynamically, ie at the time the process is started, not when the backend is started.
* @param[in] h Clixon backend
* @param[in] dbg Debug string , eg "0" or "1"
*/
static int
restconf_pseudo_set_debug(clicon_handle h,
char *dbg)
{
int retval = -1;
char **argv;
int argc;
int i;
if (dbg == NULL)
goto ok;
if (clixon_process_argv_get(h, RESTCONF_PROCESS, &argv, &argc) < 0)
goto done;
for (i=0; i<argc; i++){
if (argv[i] == NULL)
break;
if (strcmp(argv[i], "-D") == 0 && argc > i+1 && argv[i+1]){
free(argv[i+1]);
if ((argv[i+1] = strdup(dbg)) == NULL){
clicon_err(OE_UNIX, errno, "strdup");
goto done;
}
break;
}
}
ok:
retval = 0;
done:
return retval;
}
/*! Process rpc callback function /*! Process rpc callback function
* - if RPC op is start, if enable is true, start the service, if false, error or ignore it * - if RPC op is start, if enable is true, start the service, if false, error or ignore it
* - if RPC op is stop, stop the service * - if RPC op is stop, stop the service
@ -73,6 +111,7 @@ restconf_rpc_wrapper(clicon_handle h,
{ {
int retval = -1; int retval = -1;
cxobj *xt = NULL; cxobj *xt = NULL;
cxobj *xb;
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(1, "%s", __FUNCTION__);
switch (*operation){ switch (*operation){
@ -88,6 +127,17 @@ restconf_rpc_wrapper(clicon_handle h,
xpath_first(xt, NULL, "/restconf[enable='false']") != NULL) { xpath_first(xt, NULL, "/restconf[enable='false']") != NULL) {
*operation = PROC_OP_NONE; *operation = PROC_OP_NONE;
} }
else{
/* Get debug flag of restconf config, set the restconf start -D daemon flag according
* to it. The restconf daemon cannoit read its debug flag from config initially,
* but in this way it is set directly in its input args.
* Its a trick.
*/
if ((xb = xpath_first(xt, NULL, "/restconf/debug")) != NULL){
if (restconf_pseudo_set_debug(h, xml_body(xb)) < 0)
goto done;
}
}
break; break;
default: default:
break; break;
@ -103,6 +153,8 @@ restconf_rpc_wrapper(clicon_handle h,
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @note Could also look in clixon-restconf and start process if enable is true, but that needs to * @note Could also look in clixon-restconf and start process if enable is true, but that needs to
* be in start callback using a pseudo plugin. * be in start callback using a pseudo plugin.
* - Debug flag inheritance only works if backend is started with debug. If debug is set later
* this is ignored.
*/ */
static int static int
restconf_pseudo_process_control(clicon_handle h) restconf_pseudo_process_control(clicon_handle h)
@ -112,11 +164,8 @@ restconf_pseudo_process_control(clicon_handle h)
int i; int i;
int nr; int nr;
cbuf *cb = NULL; cbuf *cb = NULL;
cbuf *cbdbg = NULL;
nr = 4; nr = 6;
if (clicon_debug_get() != 0)
nr += 2;
if ((argv = calloc(nr, sizeof(char *))) == NULL){ if ((argv = calloc(nr, sizeof(char *))) == NULL){
clicon_err(OE_UNIX, errno, "calloc"); clicon_err(OE_UNIX, errno, "calloc");
goto done; goto done;
@ -133,15 +182,8 @@ restconf_pseudo_process_control(clicon_handle h)
/* Add debug if backend has debug. /* Add debug if backend has debug.
* There is also a debug flag in clixon-restconf.yang but it kicks in after it starts * There is also a debug flag in clixon-restconf.yang but it kicks in after it starts
*/ */
if (clicon_debug_get() != 0){ argv[i++] = "-D";
argv[i++] = "-D"; argv[i++] = "0";
if ((cbdbg = cbuf_new()) == NULL){ /* Cant use cb since it would overwrite it */
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
cprintf(cbdbg, "%d", clicon_debug_get());
argv[i++] = cbuf_get(cbdbg);
}
argv[i++] = NULL; argv[i++] = NULL;
assert(i==nr); assert(i==nr);
if (clixon_process_register(h, RESTCONF_PROCESS, if (clixon_process_register(h, RESTCONF_PROCESS,
@ -156,8 +198,6 @@ restconf_pseudo_process_control(clicon_handle h)
done: done:
if (cb) if (cb)
cbuf_free(cb); cbuf_free(cb);
if (cbdbg)
cbuf_free(cbdbg);
return retval; return retval;
} }
@ -200,14 +240,26 @@ restconf_pseudo_process_commit(clicon_handle h,
cxobj *xtarget; cxobj *xtarget;
cxobj *cx; cxobj *cx;
int enabled = 0; int enabled = 0;
cxobj *xb;
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(1, "%s", __FUNCTION__);
xtarget = transaction_target(td); xtarget = transaction_target(td);
if (xpath_first(xtarget, NULL, "/restconf[enable='true']") != NULL) if (xpath_first(xtarget, NULL, "/restconf[enable='true']") != NULL)
enabled++; enabled++;
/* Get debug flag of restconf config, set the restconf start -D daemon flag according
* to it. The restconf daemon cannoit read its debug flag from config initially,
* but in this way it is set directly in its input args.
* Its a trick.
*/
if ((xb = xpath_first(xtarget, NULL, "/restconf/debug")) != NULL){
if (restconf_pseudo_set_debug(h, xml_body(xb)) < 0)
goto done;
}
/* Toggle start/stop if enable flag changed */ /* Toggle start/stop if enable flag changed */
if ((cx = xpath_first(xtarget, NULL, "/restconf/enable")) != NULL && if ((cx = xpath_first(xtarget, NULL, "/restconf/enable")) != NULL &&
xml_flag(cx, XML_FLAG_CHANGE|XML_FLAG_ADD)){ xml_flag(cx, XML_FLAG_CHANGE|XML_FLAG_ADD)){
if (clixon_process_operation(h, RESTCONF_PROCESS, if (clixon_process_operation(h, RESTCONF_PROCESS,
enabled?PROC_OP_START:PROC_OP_STOP, 0) < 0) enabled?PROC_OP_START:PROC_OP_STOP, 0) < 0)
goto done; goto done;

View file

@ -181,8 +181,8 @@
/* See see listen(5) */ /* See see listen(5) */
#define SOCKET_LISTEN_BACKLOG 8 #define SOCKET_LISTEN_BACKLOG 8
/* Cert verify depth */ /* Cert verify depth: dont know what to set here? */
#define VERIFY_DEPTH 1 #define VERIFY_DEPTH 5
/* Forward */ /* Forward */
static int restconf_connection(int s, void* arg); static int restconf_connection(int s, void* arg);

View file

@ -47,14 +47,13 @@ RUN apk add --update libevent cmake libevent-dev
# clone libevhtp # clone libevhtp
WORKDIR /clixon WORKDIR /clixon
RUN git clone https://github.com/clicon/libevhtp.git RUN git clone https://github.com/clicon/clixon-libevhtp.git
WORKDIR /clixon/libevhtp/build WORKDIR /clixon/clixon-libevhtp
RUN cmake -DEVHTP_DISABLE_REGEX=ON -DEVHTP_DISABLE_EVTHR=ON .. RUN ./configure
RUN make
RUN make install
# NOTE: Patch include queue.h to use the queue.h included in the evhtp release instead RUN make
RUN (cd /usr/local/include/evhtp/; sed -i -e 's/<sys\/queue.h>/<evhtp\/sys\/queue.h>/' evhtp.h) RUN mkdir /usr/local/include
RUN make install
RUN mkdir /clixon/build RUN mkdir /clixon/build
WORKDIR /clixon WORKDIR /clixon
@ -77,7 +76,7 @@ COPY clixon .
RUN adduser -D -H www-data RUN adduser -D -H www-data
# Configure, build and install clixon # Configure, build and install clixon
RUN ./configure --prefix=/clixon/build --with-cligen=/clixon/build --with-wwwuser=www-data --enable-optyangs --with-restconf=evhtp RUN ./configure --prefix=/clixon/build --with-cligen=/clixon/build --with-wwwuser=www-data --enable-optyangs --with-restconf=native
RUN make RUN make
RUN make install RUN make install

View file

@ -4,7 +4,7 @@ This directory contains code for building and pushing the clixon base docker
container. By default it is pushed to docker hub clixon/clixon, but you can change container. By default it is pushed to docker hub clixon/clixon, but you can change
the IMAGE in Makefile.in and push it to another name. the IMAGE in Makefile.in and push it to another name.
This clixon base container uses libevhtp, native http. This clixon base container uses native http.
The clixon docker base image can be used to build clixon The clixon docker base image can be used to build clixon
applications. It has the whole code for a clixon release which it applications. It has the whole code for a clixon release which it

View file

@ -100,7 +100,7 @@ RUN install *.sh /clixon/build/bin/test
# Copy startscript # Copy startscript
WORKDIR /clixon WORKDIR /clixon
COPY startsystem_evhtp.sh startsystem.sh COPY startsystem_native.sh startsystem.sh
RUN install startsystem.sh /clixon/build/bin/ RUN install startsystem.sh /clixon/build/bin/
# #

View file

@ -62,6 +62,7 @@ int clixon_proc_socket(char **argv, pid_t *pid, int *sock);
int clixon_proc_socket_close(pid_t pid, int sock); int clixon_proc_socket_close(pid_t pid, int sock);
int clixon_proc_background(char **argv, const char *netns, pid_t *pid); int clixon_proc_background(char **argv, const char *netns, pid_t *pid);
proc_operation clixon_process_op_str2int(char *opstr); proc_operation clixon_process_op_str2int(char *opstr);
int clixon_process_argv_get(clicon_handle h, const char *name, char ***argv, int *argc);
int clixon_process_register(clicon_handle h, const char *name, const char *descr, const char *netns, proc_cb_t *callback, char **argv, int argc); int clixon_process_register(clicon_handle h, const char *name, const char *descr, const char *netns, proc_cb_t *callback, char **argv, int argc);
int clixon_process_delete_all(clicon_handle h); int clixon_process_delete_all(clicon_handle h);
int clixon_process_operation(clicon_handle h, const char *name, proc_operation op, const int wrapit); int clixon_process_operation(clicon_handle h, const char *name, proc_operation op, const int wrapit);

View file

@ -34,6 +34,20 @@
***** END LICENSE BLOCK ***** ***** END LICENSE BLOCK *****
* Processes daemons * Processes daemons
* States of processes:
A description of process states.
It starts in a STOPPED state. On operation "start" or "restart" it gets a pid and goes into RUNNING:
STOPPED --(re)start--> RUNNING
In RUNNING several things can happen:
- It is killed externally: the process then gets a SIGCHLD which triggers a wait and it goes into STOPPED:
RUNNING --sigchld/wait--> STOPPED
It is stopped due to an rpc or by config commit removing the config. In that case the parent
process kills the process and enters into EXITING waiting for a SIGCHLD that triggers a wait:
RUNNING --stop--> EXITING --sigchld/wait--> STOPPED
It is restarted due to an rpc or config change (eg a server is added, a key modified, etc). Then
a new process is started which enters RUNNING, while the old process (the dying clone) enters EXITING:
STOPPED --restart--> RUNNING(newpid)
RUNNING --stop--> EXITING --sigchld/wait--> REMOVED (oldpid/clone)
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -313,7 +327,40 @@ clixon_process_op_str2int(char *opstr)
return clicon_str2int(proc_operation_map, opstr); return clicon_str2int(proc_operation_map, opstr);
} }
/*! Make a copy of process-entry struct */ /*! Access function process list argv list
*
* @param[in] h Clixon handle
* @param[in] name Name of process
* @param[out] argv Malloced argv list (Null terminated)
* @param[out] argc Length of argv
*
* @note Can be used to change in the argv list elements directly with care: Dont change list
* itself, but its elements can be freed and re-alloced.
*/
int
clixon_process_argv_get(clicon_handle h,
const char *name,
char ***argv,
int *argc)
{
process_entry_t *pe;
pe = _proc_entry_list;
do {
if (strcmp(pe->pe_name, name) == 0){
*argv = pe->pe_argv;
*argc = pe->pe_argc;
}
pe = NEXTQ(process_entry_t *, pe);
} while (pe != _proc_entry_list);
return 0;
}
/*! Make a copy of process-entry struct
*
* @param[in] pe0 Original process-entry
* @param[in] pnew New copy of pe0
*/
static int static int
clixon_process_register_dup(process_entry_t *pe0, clixon_process_register_dup(process_entry_t *pe0,
process_entry_t **pnew) process_entry_t **pnew)
@ -604,10 +651,13 @@ clixon_process_status(clicon_handle h,
cprintf(cbret, "%s", pe->pe_argv[i]); cprintf(cbret, "%s", pe->pe_argv[i]);
} }
cprintf(cbret, "</command>"); cprintf(cbret, "</command>");
cprintf(cbret, "<status xmlns=\"%s\">%u</status>", CLIXON_LIB_NS, pe->pe_status); if (run && timerisset(&pe->pe_starttime)){
if (run && time2str(pe->pe_starttime, timestr, sizeof(timestr)) < 0) if (time2str(pe->pe_starttime, timestr, sizeof(timestr)) < 0){
goto done; clicon_err(OE_UNIX, errno, "time2str");
cprintf(cbret, "<starttime xmlns=\"%s\">%s</starttime>", CLIXON_LIB_NS, timestr); goto done;
}
cprintf(cbret, "<starttime xmlns=\"%s\">%s</starttime>", CLIXON_LIB_NS, timestr);
}
cprintf(cbret, "</rpc-reply>"); cprintf(cbret, "</rpc-reply>");
break; /* hit break here */ break; /* hit break here */
} }
@ -706,16 +756,26 @@ clixon_process_sched(int fd,
} }
if (op == PROC_OP_STOP) if (op == PROC_OP_STOP)
break; break;
if (clixon_proc_background(pe->pe_argv, pe->pe_netns, &newpid) < 0) if (!run){
goto done; if (clixon_proc_background(pe->pe_argv, pe->pe_netns, &pe->pe_pid) < 0)
gettimeofday(&pe->pe_starttime, NULL); goto done;
clicon_debug(1, "%s restart pid:%d -> %d", __FUNCTION__, pe->pe_pid, newpid); gettimeofday(&pe->pe_starttime, NULL);
/* Create a new pe */ clicon_debug(1, "%s started pid:%d", __FUNCTION__, pe->pe_pid);
if (clixon_process_register_dup(pe, &pe1) < 0) }
goto done; else {
pe->pe_clone = 1; /* Delete when reaped */ /* This is the case where there is an existing process running.
pe1->pe_op = PROC_OP_NONE; /* Dont restart again */ * it was killed above but still runs and needs to be reaped */
pe1->pe_pid = newpid; if (clixon_proc_background(pe->pe_argv, pe->pe_netns, &newpid) < 0)
goto done;
gettimeofday(&pe->pe_starttime, NULL);
clicon_debug(1, "%s restart pid:%d -> %d", __FUNCTION__, pe->pe_pid, newpid);
/* Create a new pe */
if (clixon_process_register_dup(pe, &pe1) < 0)
goto done;
pe->pe_clone = 1; /* Delete when reaped */
pe1->pe_op = PROC_OP_NONE; /* Dont restart again */
pe1->pe_pid = newpid;
}
break; break;
case PROC_OP_START: case PROC_OP_START:
if (run) /* Already runs */ if (run) /* Already runs */

View file

@ -331,6 +331,7 @@ clicon_msg_send(int s,
struct clicon_msg *msg) struct clicon_msg *msg)
{ {
int retval = -1; int retval = -1;
int e;
clicon_debug(2, "%s: send msg len=%d", clicon_debug(2, "%s: send msg len=%d",
__FUNCTION__, ntohl(msg->op_len)); __FUNCTION__, ntohl(msg->op_len));
@ -338,9 +339,10 @@ clicon_msg_send(int s,
msg_dump(msg); msg_dump(msg);
if (atomicio((ssize_t (*)(int, void *, size_t))write, if (atomicio((ssize_t (*)(int, void *, size_t))write,
s, msg, ntohl(msg->op_len)) < 0){ s, msg, ntohl(msg->op_len)) < 0){
clicon_err(OE_CFG, errno, "atomicio"); e = errno;
clicon_err(OE_CFG, e, "atomicio");
clicon_log(LOG_WARNING, "%s: write: %s len:%u msg:%s", __FUNCTION__, clicon_log(LOG_WARNING, "%s: write: %s len:%u msg:%s", __FUNCTION__,
strerror(errno), ntohs(msg->op_len), msg->op_body); strerror(e), ntohs(msg->op_len), msg->op_body);
goto done; goto done;
} }
retval = 0; retval = 0;

View file

@ -72,3 +72,8 @@ CLIXON_CONFIG_REV="2021-03-08"
CLIXON_RESTCONF_REV="2020-12-30" CLIXON_RESTCONF_REV="2020-12-30"
CLIXON_EXAMPLE_REV="2020-12-01" CLIXON_EXAMPLE_REV="2020-12-01"
# Length of TSL RSA key
# Problem with small key such as 1024 not allowed in centos8 for example (why is this)
# Problem with long keys are they take time to generate, eg on ARM
CERTKEYLEN=2048

View file

@ -202,9 +202,9 @@ function restconf_config()
PRETTY=$2 PRETTY=$2
if [ $RCPROTO = http ]; then if [ $RCPROTO = http ]; then
RESTCONFIG="<restconf><enable>true</enable><auth-type>$AUTH</auth-type><pretty>$PRETTY</pretty><debug>$DBG</debug><socket><namespace>default</namespace><address>0.0.0.0</address><port>80</port><ssl>false</ssl></socket></restconf>" echo "<restconf><enable>true</enable><auth-type>$AUTH</auth-type><pretty>$PRETTY</pretty><debug>$DBG</debug><socket><namespace>default</namespace><address>0.0.0.0</address><port>80</port><ssl>false</ssl></socket></restconf>"
else else
RESTCONFIG="<restconf><enable>true</enable><auth-type>$AUTH</auth-type><pretty>$PRETTY</pretty><server-cert-path>/etc/ssl/certs/clixon-server-crt.pem</server-cert-path><server-key-path>/etc/ssl/private/clixon-server-key.pem</server-key-path><server-ca-cert-path>/etc/ssl/certs/clixon-ca-crt.pem</server-ca-cert-path><debug>$DBG</debug><socket><namespace>default</namespace><address>0.0.0.0</address><port>443</port><ssl>true</ssl></socket></restconf>" echo "<restconf><enable>true</enable><auth-type>$AUTH</auth-type><pretty>$PRETTY</pretty><server-cert-path>/etc/ssl/certs/clixon-server-crt.pem</server-cert-path><server-key-path>/etc/ssl/private/clixon-server-key.pem</server-key-path><server-ca-cert-path>/etc/ssl/certs/clixon-ca-crt.pem</server-ca-cert-path><debug>$DBG</debug><socket><namespace>default</namespace><address>0.0.0.0</address><port>443</port><ssl>true</ssl></socket></restconf>"
fi fi
} }
@ -707,23 +707,19 @@ function expectmatch(){
fi fi
} }
# Create server certs # Create CA certs
# Output variables set as filenames on entry, set as cert/keys on exit: # Output variables set as filenames on entry, set as cert/keys on exit:
# Vars: # Vars:
# 1: cakey filename # 1: cakey filename
# 2: cacert filename # 2: cacert filename
# 3: srvkey filename function cacerts()
# 4: srvcert filename
function servercerts()
{ {
if [ $# -ne 4 ]; then if [ $# -ne 2 ]; then
echo "servercerts function: Expected: cakey cacert srvkey srvcert" echo "cacerts function: Expected: cakey cacert"
exit 1 exit 1
fi fi
cakey=$1 cakey=$1
cacert=$2 cacert=$2
srvkey=$3
srvcert=$4
tmpdir=$dir/tmpcertdir tmpdir=$dir/tmpcertdir
@ -765,7 +761,32 @@ challengePassword = test
EOF EOF
# Generate CA cert # Generate CA cert
openssl req -x509 -days 1 -config $tmpdir/ca.cnf -keyout $cakey -out $cacert openssl req -x509 -days 1 -config $tmpdir/ca.cnf -keyout $cakey -out $cacert || err "Generate CA cert"
rm -rf $tmpdir
}
# Create server certs
# Output variables set as filenames on entry, set as cert/keys on exit:
# Vars:
# 1: cakey filename (input)
# 2: cacert filename (input)
# 3: srvkey filename (output)
# 4: srvcert filename (output)
function servercerts()
{
if [ $# -ne 4 ]; then
echo "servercerts function: Expected: cakey cacert srvkey srvcert"
exit 1
fi
cakey=$1
cacert=$2
srvkey=$3
srvcert=$4
tmpdir=$dir/tmpcertdir
test -d $tmpdir || mkdir $tmpdir
cat<<EOF > $tmpdir/srv.cnf cat<<EOF > $tmpdir/srv.cnf
[req] [req]
@ -783,13 +804,13 @@ subjectAltName = DNS:clicon.org
EOF EOF
# Generate server key # Generate server key
openssl genrsa -out $srvkey ${CERTKEYLEN} openssl genrsa -out $srvkey ${CERTKEYLEN} || err "Generate server key"
# Generate CSR (signing request) # Generate CSR (signing request)
openssl req -new -config $tmpdir/srv.cnf -key $srvkey -out $tmpdir/srv_csr.pem openssl req -new -config $tmpdir/srv.cnf -key $srvkey -out $tmpdir/srv_csr.pem || err "Generate signing request"
# Sign server cert by CA # Sign server cert by CA
openssl x509 -req -extfile $tmpdir/srv.cnf -days 1 -passin "pass:password" -in $tmpdir/srv_csr.pem -CA $cacert -CAkey $cakey -CAcreateserial -out $srvcert openssl x509 -req -extfile $tmpdir/srv.cnf -days 1 -passin "pass:password" -in $tmpdir/srv_csr.pem -CA $cacert -CAkey $cakey -CAcreateserial -out $srvcert || err "Sign server cert"
rm -rf $tmpdir rm -rf $tmpdir
} }

View file

@ -22,7 +22,7 @@ fyang=$dir/scaling.yang
fconfig=$dir/large.xml fconfig=$dir/large.xml
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
cat <<EOF > $fyang cat <<EOF > $fyang
module scaling{ module scaling{

View file

@ -29,7 +29,4 @@ IPv6=true
# start # start
NGINXCHECK=true NGINXCHECK=true
# Lenght of TSL RSA key
# Problem with small key such as 1024 not allowed in centos8 for example (why is this)
# Problem with long keys are they take time to generate, eg on ARM
CERTKEYLEN=2048

View file

@ -25,7 +25,7 @@ if [ ! -d $pdir ]; then
fi fi
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -24,7 +24,7 @@ fyang=$dir/main.yang
fyang2=$dir/ietf-interfaces@2019-03-04.yang fyang2=$dir/ietf-interfaces@2019-03-04.yang
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -15,7 +15,7 @@ cfg=$dir/choice.xml
fyang=$dir/type.yang fyang=$dir/type.yang
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -22,7 +22,7 @@ if [ ! -d $pdir ]; then
fi fi
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -30,7 +30,7 @@ cfg=$dir/conf_yang.xml
# Use yang in example # Use yang in example
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none true RESTCONFIG=$(restconf_config none true)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -11,7 +11,7 @@ cfg=$dir/conf_yang.xml
fyang=$dir/example-my-crypto.yang fyang=$dir/example-my-crypto.yang
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -18,7 +18,7 @@ cfg=$dir/conf_yang.xml
fyang=$dir/nacm-example.yang fyang=$dir/nacm-example.yang
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config user false RESTCONFIG=$(restconf_config user false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -46,7 +46,7 @@ fyang=$dir/nacm-example.yang
fyang2=$dir/itf.yang fyang2=$dir/itf.yang
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config user false RESTCONFIG=$(restconf_config user false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -18,7 +18,7 @@ cfg=$dir/conf_yang.xml
fyang=$dir/nacm-example.yang fyang=$dir/nacm-example.yang
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config user false RESTCONFIG=$(restconf_config user false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -26,7 +26,7 @@ fyang=$dir/nacm-example.yang
fyang2=$dir/nacm-example2.yang fyang2=$dir/nacm-example2.yang
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config user false RESTCONFIG=$(restconf_config user false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -18,7 +18,7 @@ cfg=$dir/conf_yang.xml
fyang=$dir/nacm-example.yang fyang=$dir/nacm-example.yang
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config user false RESTCONFIG=$(restconf_config user false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -14,7 +14,7 @@ fyang=$dir/nacm-example.yang
: ${format:=xml} : ${format:=xml}
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config user false RESTCONFIG=$(restconf_config user false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -16,7 +16,7 @@ fyang=$dir/nacm-example.yang
nacmfile=$dir/nacmfile nacmfile=$dir/nacmfile
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config user false RESTCONFIG=$(restconf_config user false)
# Note filter out example_backend_nacm.so in CLICON_BACKEND_REGEXP below # Note filter out example_backend_nacm.so in CLICON_BACKEND_REGEXP below
cat <<EOF > $cfg cat <<EOF > $cfg

View file

@ -19,7 +19,7 @@ cfg=$dir/conf_yang.xml
fyang=$dir/nacm-example.yang fyang=$dir/nacm-example.yang
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config user false RESTCONFIG=$(restconf_config user false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -32,7 +32,7 @@ cfg=$dir/conf_yang.xml
fyang=$dir/nacm-example.yang fyang=$dir/nacm-example.yang
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config user false RESTCONFIG=$(restconf_config user false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -35,7 +35,7 @@ cfg=$dir/conf_yang.xml
fyang=$dir/nacm-example.yang fyang=$dir/nacm-example.yang
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config user false RESTCONFIG=$(restconf_config user false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -21,7 +21,7 @@ fyang=$dir/nacm-example.yang
# cred:none, exact, except # cred:none, exact, except
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config user false RESTCONFIG=$(restconf_config user false)
cat <<EOF > $fyang cat <<EOF > $fyang
module nacm-example{ module nacm-example{

View file

@ -53,7 +53,7 @@ module scaling{
EOF EOF
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -30,7 +30,7 @@ fconfig=$dir/large.xml
fstate=$dir/state.xml fstate=$dir/state.xml
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -30,7 +30,7 @@ fconfig=$dir/large.xml
fstate=$dir/state.xml fstate=$dir/state.xml
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -49,10 +49,11 @@ if [ "${WITH_RESTCONF}" = "native" ]; then
cacert=$certdir/ca_cert.pem cacert=$certdir/ca_cert.pem
test -d $certdir || mkdir $certdir test -d $certdir || mkdir $certdir
# Create server certs and CA # Create server certs and CA
cacerts $cakey $cacert
servercerts $cakey $cacert $srvkey $srvcert servercerts $cakey $cacert $srvkey $srvcert
else else
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
fi fi
# This is a fixed 'state' implemented in routing_backend. It is assumed to be always there # This is a fixed 'state' implemented in routing_backend. It is assumed to be always there

View file

@ -13,7 +13,7 @@ cfg=$dir/conf.xml
fyang=$dir/restconf.yang fyang=$dir/restconf.yang
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
# <CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN> # <CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN>
cat <<EOF > $cfg cat <<EOF > $cfg

View file

@ -193,7 +193,7 @@ function testrun()
# echo "expectmsg:$expectmsg" # echo "expectmsg:$expectmsg"
# Change restconf configuration before start restconf daemon # Change restconf configuration before start restconf daemon
restconf_config $auth false RESTCONFIG=$(restconf_config $auth false)
# Start with common config, then append fcgi/native specific config # Start with common config, then append fcgi/native specific config
cat <<EOF > $cfg cat <<EOF > $cfg

View file

@ -31,7 +31,7 @@ fxml=$dir/initial.xml
fstate=$dir/state.xml fstate=$dir/state.xml
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
# <CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN> # <CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN>
cat <<EOF > $cfg cat <<EOF > $cfg

View file

@ -24,7 +24,7 @@ cat <<EOF > $dir/example-system.yang
EOF EOF
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
# <CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN> # <CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN>
cat <<EOF > $cfg cat <<EOF > $cfg

View file

@ -11,7 +11,7 @@ cfg=$dir/conf.xml
fyang=$dir/list.yang fyang=$dir/list.yang
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
# <CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN> # <CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN>
cat <<EOF > $cfg cat <<EOF > $cfg

View file

@ -44,6 +44,7 @@ cacert=$certdir/ca_cert.pem
test -d $certdir || mkdir $certdir test -d $certdir || mkdir $certdir
# Create server certs and CA # Create server certs and CA
cacerts $cakey $cacert
servercerts $cakey $cacert $srvkey $srvcert servercerts $cakey $cacert $srvkey $srvcert
# XXX Note default port need to be 80 for wait_restconf to work # XXX Note default port need to be 80 for wait_restconf to work

View file

@ -43,7 +43,7 @@ fyang=$dir/stream.yang
xml=$dir/xml.xml xml=$dir/xml.xml
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
# <CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN> # <CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN>
cat <<EOF > $cfg cat <<EOF > $cfg

View file

@ -13,7 +13,7 @@ startupdb=$dir/startup_db
fjukebox=$dir/example-jukebox.yang fjukebox=$dir/example-jukebox.yang
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config user false RESTCONFIG=$(restconf_config user false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -20,7 +20,7 @@ cfg=$dir/conf.xml
startupdb=$dir/startup_db startupdb=$dir/startup_db
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

262
test/test_restconf_rpc2.sh Executable file
View file

@ -0,0 +1,262 @@
#!/usr/bin/env bash
# Send restconf rpc:s when starting from backend
# Two specific usecases that have been problematic are tested here
# In comparison test_restconf_rpc.sh:
# - uses externally started restconf, here started by backend
# - generic tests, here specific
# The first usecases is:
# 1. Start a minimal restconf
# 2. Kill it externally (or it exits)
# 3. Start a server
# 4. Query status (Error message is returned)
# The second usecase is
# 1. Start server with bad address
# 2. Zombie process appears
# 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
startupdb=$dir/startup_db
# Restconf debug
RESTCONFDBG=0
cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config">
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_FEATURE>ietf-netconf:startup</CLICON_FEATURE>
<CLICON_FEATURE>clixon-restconf:allow-auth-none</CLICON_FEATURE> <!-- Use auth-type=none -->
<CLICON_YANG_DIR>/usr/local/share/clixon</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_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>$dir</CLICON_XMLDB_DIR>
<CLICON_MODULE_LIBRARY_RFC7895>true</CLICON_MODULE_LIBRARY_RFC7895>
<!-- start restconf from backend -->
<CLICON_BACKEND_RESTCONF_PROCESS>true</CLICON_BACKEND_RESTCONF_PROCESS>
</clixon-config>
EOF
cat <<EOF > $dir/example.yang
module example {
namespace "urn:example:clixon";
prefix ex;
revision 2021-03-05;
leaf val{
type string;
}
}
EOF
function testrpc()
{
operation=$1
expectret=$2
sleep $DEMSLEEP
new "send rpc $operation"
ret=$($clixon_netconf -qf $cfg<<EOF
$DEFAULTHELLO
<rpc $DEFAULTNS>
<process-control xmlns="http://clicon.org/lib">
<name>restconf</name>
<operation>$operation</operation>
</process-control>
</rpc>]]>]]>
EOF
)
>&2 echo "ret:$ret" # debug
expect1="<pid xmlns=\"http://clicon.org/lib\">[0-9]*</pid>"
match=$(echo "$ret" | grep --null -Go "$expect1")
# >&2 echo "match:$match" # debug
if [ -z "$match" ]; then
pid=0
else
pid=$(echo "$match" | awk -F'[<>]' '{print $3}')
fi
>&2 echo "pid:$pid" # debug
if [ -z "$pid" ]; then
err "Running process" "$ret"
fi
new "check restconf retvalue"
if [ $operation = "status" ]; then
if [ $expectret -eq 0 ]; then
if [ $pid -ne 0 ]; then
err "No process" "$pid"
fi
else
if [ $pid -eq 0 ]; then
err "Running process"
fi
fi
echo "$pid" # cant use return that only uses 0-255
fi
sleep $DEMSLEEP
}
new "kill old restconf"
stop_restconf_pre
new "test params: -f $cfg"
if [ $BE -ne 0 ]; then
new "kill old backend"
sudo clixon_backend -z -f $cfg
if [ $? -ne 0 ]; then
err
fi
new "start backend -s init -f $cfg"
start_backend -s init -f $cfg
fi
new "wait backend"
wait_backend
RESTCONFIG1=$(cat <<EOF
<restconf xmlns="http://clicon.org/restconf">
<enable>true</enable>
<debug>$RESTCONFDBG</debug>
</restconf>
EOF
)
LIBNS='xmlns="http://clicon.org/lib"'
new "get status 1"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><process-control xmlns=\"http://clicon.org/lib\"><name>restconf</name><operation>status</operation></process-control></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><active $LIBNS>false</active><description $LIBNS>Clixon RESTCONF process</description><command $LIBNS>/www-data/clixon_restconf -f $cfg -D $RESTCONFDBG</command></rpc-reply>]]>]]>$"
new "enable minimal restconf, no server"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><edit-config><target><candidate/></target><config>$RESTCONFIG1</config></edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
new "netconf commit"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
# Get pid2
pid2=$(testrpc status 1)
echo "pid:$pid2"
new "get status 2"
ret=$($clixon_netconf -qf $cfg<<EOF
$DEFAULTHELLO
<rpc $DEFAULTNS>
<process-control xmlns="http://clicon.org/lib">
<name>restconf</name>
<operation>status</operation>
</process-control>
</rpc>]]>]]>
EOF
)
expect="^<rpc-reply $DEFAULTNS><active $LIBNS>true</active><description $LIBNS>Clixon RESTCONF process</description><pid $LIBNS>$pid2</pid><command $LIBNS>/www-data/clixon_restconf -f $cfg -D $RESTCONFDBG</command><starttime $LIBNS>20[0-9][0-9]\-[0-9][0-9]\-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\.[0-9]*Z</starttime>"
match=$(echo "$ret" | grep --null -Go "$expect")
if [ -z "$match" ]; then
err "$expect" "$ret"
fi
# Kill it
sudo kill $pid2
sleep $DEMSLEEP
# Ensure no pid
pid2=$(testrpc status 0)
RESTCONFIG2=$(cat <<EOF
<restconf xmlns="http://clicon.org/restconf">
<socket><namespace>default</namespace><address>0.0.0.0</address><port>80</port><ssl>false</ssl></socket>
</restconf>
EOF
)
new "create a server"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><edit-config><target><candidate/></target><config>$RESTCONFIG2</config></edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
new "netconf commit"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
# 3. get status
new "get status 3"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><process-control xmlns=\"http://clicon.org/lib\"><name>restconf</name><operation>status</operation></process-control></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><active $LIBNS>true</active><description $LIBNS>Clixon RESTCONF process</description><pid $LIBNS>"
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
sleep $DEMSLEEP # Lots of processes need to die before next test
new "kill old restconf"
stop_restconf_pre
new "test params: -f $cfg"
if [ $BE -ne 0 ]; then
new "kill old backend"
sudo clixon_backend -z -f $cfg
if [ $? -ne 0 ]; then
err
fi
new "start backend -s init -f $cfg"
start_backend -s init -f $cfg
fi
new "wait backend"
wait_backend
new "get status 1"
testrpc status 0
RESTCONFIG1=$(cat <<EOF
<restconf xmlns="http://clicon.org/restconf">
<enable>true</enable>
<debug>$RESTCONFDBG</debug>
<auth-type>none</auth-type>
<server-cert-path>$srvcert</server-cert-path>
<server-key-path>$srvkey</server-key-path>
<server-ca-cert-path>$cakey</server-ca-cert-path>
<pretty>false</pretty>
<socket><namespace>default</namespace><address>221.0.0.1</address><port>80</port><ssl>false</ssl></socket>
</restconf>
EOF
)
new "Create server with invalid address"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><edit-config><target><candidate/></target><config>$RESTCONFIG1</config></edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
new "netconf commit"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
sleep $DEMSLEEP
new "Check zombies"
ret=$(ps aux|grep defunc | grep -v grep)
if [ -n "$ret" ]; then
err "No zombie process" "$ret"
fi
new "endtest"
endtest
# Set by restconf_config
unset RESTCONFIG1
unset RESTCONFIG2
unset RESTCONFDBG
rm -rf $dir

View file

@ -25,15 +25,19 @@ cfg=$dir/conf.xml
# Local for test here # Local for test here
certdir=$dir/certs certdir=$dir/certs
cakey=$certdir/ca_key.pem
cacert=$certdir/ca_cert.pem
srvkey=$certdir/srv_key.pem srvkey=$certdir/srv_key.pem
srvcert=$certdir/srv_cert.pem srvcert=$certdir/srv_cert.pem
cakey=$certdir/ca_key.pem # needed?
cacert=$certdir/ca_cert.pem # These is another CA (invalid) for creating invalid client certs
xcakey=$certdir/xca_key.pem
xcacert=$certdir/xca_cert.pem
users="andy guest" # generate certs for some users in nacm.sh users="andy guest" # generate certs for some users in nacm.sh
xusers="limited" # Set invalid cert x1users="limited" # Set invalid cert
x2users="invalid" # Wrong CA
# Whether to generate new keys or not (only if $dir is not removed) # Whether to generate new keys or not (only if $dir is not removed)
# Here dont generate keys if restconf started stand-alone (RC=0) # Here dont generate keys if restconf started stand-alone (RC=0)
@ -93,10 +97,14 @@ EOF
if $genkeys; then if $genkeys; then
# Create server certs # Create server certs
cacerts $cakey $cacert
servercerts $cakey $cacert $srvkey $srvcert servercerts $cakey $cacert $srvkey $srvcert
# Other (invalid)
cacerts $xcakey $xcacert
# create client certs # create client certs
for name in $users $xusers; do for name in $users $x1users; do
cat<<EOF > $dir/$name.cnf cat<<EOF > $dir/$name.cnf
[req] [req]
prompt = no prompt = no
@ -119,9 +127,33 @@ EOF
done # client key done # client key
# invalid (days = 0) # invalid (days = 0)
for name in $xusers; do for name in $x1users; do
openssl x509 -req -extfile $dir/$name.cnf -days 0 -passin "pass:password" -in $certdir/$name.csr -CA $cacert -CAkey $cakey -CAcreateserial -out $certdir/$name.crt openssl x509 -req -extfile $dir/$name.cnf -days 0 -passin "pass:password" -in $certdir/$name.csr -CA $cacert -CAkey $cakey -CAcreateserial -out $certdir/$name.crt
done # invalid done # invalid
# create client certs from invalid CA
for name in $x2users; do
cat<<EOF > $dir/$name.cnf
[req]
prompt = no
distinguished_name = dn
[dn]
CN = $name # This can be verified using SSL_set1_host
emailAddress = $name@foo.bar
O = Clixon
L = Stockholm
C = SE
EOF
# Create client key
openssl genrsa -out "$certdir/$name.key" 2048
# Generate CSR (signing request)
openssl req -new -config $dir/$name.cnf -key $certdir/$name.key -out $certdir/$name.csr
# Sign by CA
openssl x509 -req -extfile $dir/$name.cnf -days 1 -passin "pass:password" -in $certdir/$name.csr -CA $xcacert -CAkey $xcakey -CAcreateserial -out $certdir/$name.crt
done # client key
fi # genkeys fi # genkeys
# Write local config # Write local config
@ -222,6 +254,9 @@ EOF
new "limited invalid cert" new "limited invalid cert"
expectpart "$(curl $CURLOPTS --key $certdir/limited.key --cert $certdir/limited.crt -X GET $RCPROTO://localhost/restconf/data/example:x 2>&1)" "35 55 56" # 55 "certificate expired" expectpart "$(curl $CURLOPTS --key $certdir/limited.key --cert $certdir/limited.crt -X GET $RCPROTO://localhost/restconf/data/example:x 2>&1)" "35 55 56" # 55 "certificate expired"
new "invalid cert from wrong CA"
expectpart "$(curl $CURLOPTS --key $certdir/invalid.key --cert $certdir/limited.crt -X GET $RCPROTO://localhost/restconf/data/example:x 2>&1)" 58 "unable to set private key file" # 58 unable to set private key file
# Just ensure all is OK # Just ensure all is OK
new "admin get x 42" new "admin get x 42"
expectpart "$(curl $CURLOPTS --key $certdir/andy.key --cert $certdir/andy.crt -X GET $RCPROTO://localhost/restconf/data/example:x)" 0 "HTTP/1.1 200 OK" '{"example:x":42}' expectpart "$(curl $CURLOPTS --key $certdir/andy.key --cert $certdir/andy.crt -X GET $RCPROTO://localhost/restconf/data/example:x)" 0 "HTTP/1.1 200 OK" '{"example:x":42}'

View file

@ -35,7 +35,7 @@ EOF
# Use yang in example # Use yang in example
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none true RESTCONFIG=$(restconf_config none true)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -14,7 +14,7 @@ APPNAME=example
cfg=$dir/conf.xml cfg=$dir/conf.xml
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
# Use yang in example # Use yang in example
cat <<EOF > $cfg cat <<EOF > $cfg

View file

@ -28,7 +28,7 @@ fextra1=$dir/extra1.yang # Referenced from sub1
fextra2=$dir/extra2.yang # Referenced from sub2 fextra2=$dir/extra2.yang # Referenced from sub2
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">

View file

@ -22,7 +22,7 @@ funknown=$dir/yang/unknown.yang
fstate=$dir/state.xml fstate=$dir/state.xml
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
cat <<EOF > $fanydata cat <<EOF > $fanydata
module any{ module any{

View file

@ -14,7 +14,7 @@ fyang1=$dir/example1.yang
fyang2=$dir/example2.yang fyang2=$dir/example2.yang
# Define default restconfig config: RESTCONFIG # Define default restconfig config: RESTCONFIG
restconf_config none false RESTCONFIG=$(restconf_config none false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">