* Changed: RPC process-control output to choice dependent on operation
This commit is contained in:
Olof hagsand 2021-03-12 12:10:25 +01:00
parent 7762b10cbb
commit 7e9a207ab2
11 changed files with 260 additions and 24 deletions

View file

@ -38,6 +38,8 @@ Expected: April
* Each peer MUST send at least the base NETCONF capability, "urn:ietf:params:netconf:base:1.1" (or 1.0 for RFC 4741)
* The netconf client will terminate (close the socket) if the client does not comply
* You can set `CLICON_NETCONF_HELLO_OPTIONAL` to true to use the old behavior of essentially ignoring hellos.
* New clixon-lib@2020-03-08.yang revision
* Changed: RPC process-control output to choice dependent on operation
* New clixon-config@2020-03-08.yang revision
* Added: `CLICON_NETCONF_HELLO_OPTIONAL`

View file

@ -1596,8 +1596,14 @@ from_client_process_control(clicon_handle h,
/* Make the actual process operation (with wrap function enabled) */
if (clixon_process_operation(h, name, op, 1, &pid) < 0)
goto done;
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><pid xmlns=\"%s\">%u</pid></rpc-reply>",
NETCONF_BASE_NAMESPACE, CLIXON_LIB_NS, pid);
if (op == PROC_OP_STATUS)
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><status xmlns=\"%s\">%s</status><pid xmlns=\"%s\">%u</pid></rpc-reply>",
NETCONF_BASE_NAMESPACE,
CLIXON_LIB_NS, pid?"true":"false",
CLIXON_LIB_NS, pid);
else
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok xmlns=\"%s\"/></rpc-reply>",
NETCONF_BASE_NAMESPACE, CLIXON_LIB_NS);
retval = 0;
done:
return retval;

View file

@ -68,10 +68,19 @@ How to debug
CFLAGS="-g -Wall" INSTALLFLAGS="" ./configure
```
### Set backend debug flag using curl
### Set backend debug using curl
Set backend debug using rpc
curl -Ssik -X POST -H "Content-Type: application/yang-data+json" http://localhost/restconf/operations/clixon-lib:debug -d '{"clixon-lib:input":{"level":1}}'
### Set restconf debug using curl
Only if using clixon-restconf.yang
curl -Ssik -X PUT -H "Content-Type: application/yang-data+json" http://localhost/restconf/data/clixon-rstconf:restconf/debug -d '{"clixon-restconf:debug":{"level":1}}'
Get restconf daemon status
curl -Ssik -X POST -H "Content-Type: application/yang-data+json" http://localhost/restconf/operations/clixon-lib:process-control -d '{"clixon-lib:input":{"name":"restconf","operation":"status"}}'
### Make your own simplified yang and configuration file.
```

View file

@ -494,10 +494,14 @@ proc_op_run(pid_t pid0,
* @param[in] name Name of process
* @param[in] op start, stop, restart, status
* @param[in] wrapit If set, call potential callback, if false, dont call it
* @param[out] status true if process is running / false if not running on entry
* @param[out] pid >0 process# and is running / 0: not running
* @retval -1 Error
* @retval 0 OK
* @see upgrade_callback_reg_fn which registers the callbacks
* @note operations are not made directly but postponed by a scheduling the actions.
* This is not really necessary for all operations (like start) but made for all
* for reducing complexity of code.
* @see clixon_process_sched where operations are actually executed
*/
int
clixon_process_operation(clicon_handle h,
@ -516,6 +520,13 @@ clixon_process_operation(clicon_handle h,
pe = _proc_entry_list;
do {
if (strcmp(pe->pe_name, name) == 0){
if (op == PROC_OP_STATUS){
if (pe->pe_clone)
continue; /* this may be a dying duplicate */
if (pid)
*pid = pe->pe_pid;
}
else {
/* Call wrapper function that eg changes op based on config */
if (wrapit && pe->pe_callback != NULL)
if (pe->pe_callback(h, pe, &op) < 0)
@ -527,8 +538,8 @@ clixon_process_operation(clicon_handle h,
clicon_debug(1, "%s scheduling %s pid:%d", __FUNCTION__, name, pe->pe_pid);
sched++;
}
if (pid)
*pid = pe->pe_pid;
}
break; /* hit break here */
}
pe = NEXTQ(process_entry_t *, pe);
@ -587,6 +598,7 @@ clixon_process_start_all(clicon_handle h)
* (2) edit changes or rpc restart especially of restconf where you may saw of your arm and terminate
* return socket.
* A special complexity is restarting processes, where the old is killed, but state must be kept until it is reaped
* @see clixon_process_waitpid where killed/restarted processes are "reaped"
*/
static int
clixon_process_sched(int fd,

View file

@ -66,3 +66,8 @@ CLIXON_VERSION=@CLIXON_VERSION@
# see also DATASTORE_TOP_SYMBOL
DATASTORE_TOP="config"
# clixon yang revisions occuring in tests
CLIXON_LIB_REV="2021-03-08"
CLIXON_CONFIG_REV="2021-03-08"
CLIXON_EXAMPLE_REV="2020-12-01"

View file

@ -25,7 +25,8 @@ cfg=$dir/conf.xml
# clixon-example and clixon-restconf is used in the test, need local copy
# This is a kludge: look in src otherwise assume it is installed in /usr/local/share
# Note that revisions may change and may need to be updated
y=clixon-example@2020-12-01.yang
y="clixon-example@${CLIXON_EXAMPLE_REV}.yang"
if [ -d ${TOP_SRCDIR}/example/main/$y ]; then
cp ${TOP_SRCDIR}/example/main/$y $dir/
else
@ -193,7 +194,7 @@ function testrun()
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+json' $proto://$addr/restconf/data/ietf-yang-library:modules-state/module=ietf-interfaces,2018-02-20)" 0 'HTTP/1.1 200 OK' '{"ietf-yang-library:module":\[{"name":"ietf-interfaces","revision":"2018-02-20","namespace":"urn:ietf:params:xml:ns:yang:ietf-interfaces","conformance-type":"implement"}\]}'
new "restconf schema resource, mod-state top-level"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+json' $proto://$addr/restconf/data/ietf-yang-library:modules-state)" 0 'HTTP/1.1 200 OK' '{"ietf-yang-library:modules-state":{"module-set-id":"0","module":\[{"name":"clixon-example","revision":"2020-12-01","namespace":"urn:example:clixon","conformance-type":"implement"},{"name":"clixon-lib","revision":"2020-12-30","'
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+json' $proto://$addr/restconf/data/ietf-yang-library:modules-state)" 0 'HTTP/1.1 200 OK' "{\"ietf-yang-library:modules-state\":{\"module-set-id\":\"0\",\"module\":\[{\"name\":\"clixon-example\",\"revision\":\"${CLIXON_EXAMPLE_REV}\",\"namespace\":\"urn:example:clixon\",\"conformance-type\":\"implement\"},{\"name\":\"clixon-lib\",\"revision\":\"${CLIXON_LIB_REV}\",\""
new "restconf options. RFC 8040 4.1"
expectpart "$(curl $CURLOPTS -X OPTIONS $proto://$addr/restconf/data)" 0 "HTTP/1.1 200 OK" "Allow: OPTIONS,HEAD,GET,POST,PUT,PATCH,DELETE"

View file

@ -104,7 +104,7 @@ expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+xml' $RCPR
# This just catches the header and the jukebox module, the RFC has foo and bar which
# seems wrong to recreate
new "B.1.2. Retrieve the Server Module Information"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+json' $RCPROTO://localhost/restconf/data/ietf-yang-library:modules-state)" 0 "HTTP/1.1 200 OK" 'Cache-Control: no-cache' "Content-Type: application/yang-data+json" '{"ietf-yang-library:modules-state":{"module-set-id":"0","module":\[{"name":"clixon-lib","revision":"2020-12-30","namespace":"http://clicon.org/lib","conformance-type":"implement"}' '{"name":"example-events","revision":"","namespace":"urn:example:events","conformance-type":"implement"}' '{"name":"example-jukebox","revision":"2016-08-15","namespace":"http://example.com/ns/example-jukebox","conformance-type":"implement"}' '{"name":"example-system","revision":"","namespace":"http://example.com/ns/example-system","conformance-type":"implement"}'
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+json' $RCPROTO://localhost/restconf/data/ietf-yang-library:modules-state)" 0 "HTTP/1.1 200 OK" 'Cache-Control: no-cache' "Content-Type: application/yang-data+json" "{\"ietf-yang-library:modules-state\":{\"module-set-id\":\"0\",\"module\":\[{\"name\":\"clixon-lib\",\"revision\":\"${CLIXON_LIB_REV}\",\"namespace\":\"http://clicon.org/lib\",\"conformance-type\":\"implement\"}" '{"name":"example-events","revision":"","namespace":"urn:example:events","conformance-type":"implement"}' '{"name":"example-jukebox","revision":"2016-08-15","namespace":"http://example.com/ns/example-jukebox","conformance-type":"implement"}' '{"name":"example-system","revision":"","namespace":"http://example.com/ns/example-system","conformance-type":"implement"}'
new "B.1.3. Retrieve the Server Capability Information"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+xml' $RCPROTO://localhost/restconf/data/ietf-restconf-monitoring:restconf-state/capabilities)" 0 "HTTP/1.1 200 OK" "Content-Type: application/yang-data+xml" 'Cache-Control: no-cache' '<capabilities xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring"><capability>urn:ietf:params:restconf:capability:defaults:1.0?basic-mode=explicit</capability><capability>urn:ietf:params:restconf:capability:depth</capability>

View file

@ -141,8 +141,8 @@ if [ $BE -ne 0 ]; then
fi
# For debug
#>&2 echo "curl $CURLOPTS -X POST -H \"Content-Type: application/yang-data+json\" $RCPROTO://localhost/restconf/operations/clixon-lib:process-control -d '{\"clixon-lib:input\":{\"name\":\"restconf\",\"operation\":\"status\"}}'"
>&2 echo "curl $CURLOPTS -X POST -H \"Content-Type: application/yang-data+json\" $RCPROTO://localhost/restconf/operations/clixon-lib:process-control -d '{\"clixon-lib:input\":{\"name\":\"restconf\",\"operation\":\"status\"}}'"
exit
# Get pid of running process and check return xml
new "1. Get rpc status"
pid0=$(testrpc status 1) # Save pid0

View file

@ -301,7 +301,7 @@ cat <<EOF > $dir/startup_db
</${DATASTORE_TOP}>
EOF
MODSTATE1='<modules-state xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library"><module-set-id>0</module-set-id><module><name>clixon-lib</name><revision>2020-12-30</revision><namespace>http://clicon.org/lib</namespace></module>'
MODSTATE1="<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\"><module-set-id>0</module-set-id><module><name>clixon-lib</name><revision>${CLIXON_LIB_REV}</revision><namespace>http://clicon.org/lib</namespace></module>"
MODSTATE2='<module><name>interfaces</name><revision>2018-02-20</revision><namespace>urn:example:interfaces</namespace></module>'

View file

@ -42,7 +42,7 @@ datarootdir = @datarootdir@
YANG_INSTALLDIR = @YANG_INSTALLDIR@
YANGSPECS = clixon-config@2021-03-08.yang
YANGSPECS += clixon-lib@2020-12-30.yang
YANGSPECS += clixon-lib@2021-03-08.yang
YANGSPECS += clixon-rfc5277@2008-07-01.yang
YANGSPECS += clixon-xml-changelog@2019-03-21.yang
YANGSPECS += clixon-restconf@2020-12-30.yang

View file

@ -0,0 +1,201 @@
module clixon-lib {
yang-version 1.1;
namespace "http://clicon.org/lib";
prefix cl;
organization
"Clicon / Clixon";
contact
"Olof Hagsand <olof@hagsand.se>";
description
"Clixon Netconf extensions for communication between clients and backend.
***** BEGIN LICENSE BLOCK *****
Copyright (C) 2009-2019 Olof Hagsand
Copyright (C) 2020-2021 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 2021-03-08 {
description
"Changed: RPC process-control output to choice dependent on operation";
}
revision 2020-12-30 {
description
"Changed: RPC process-control output parameter status to pid";
}
revision 2020-12-08 {
description
"Added: autocli-op extension.
rpc process-control for process/daemon management
Released in clixon 4.9";
}
revision 2020-04-23 {
description
"Added: stats RPC for clixon XML and memory statistics.
Added: restart-plugin RPC for restarting individual plugins without restarting backend.";
}
revision 2019-08-13 {
description
"No changes (reverted change)";
}
revision 2019-06-05 {
description
"ping rpc added for liveness";
}
revision 2019-01-02 {
description
"Released in Clixon 3.9";
}
typedef service-operation {
type enumeration {
enum start {
description
"Start if not already running";
}
enum stop {
description
"Stop if running";
}
enum restart {
description
"Stop if running, then start";
}
enum status {
description
"Check status";
}
}
description
"Common operations that can be performed on a service";
}
extension autocli-op {
description
"Takes an argument an operation defing how to modify the clispec at
this point in the YANG tree for the automated generated CLI.
Note that this extension is only used in clixon_cli.
Operations is expected to be extended, but the following operations are defined:
- hide This command is active but not shown by ? or TAB";
argument cliop;
}
rpc debug {
description "Set debug level of backend.";
input {
leaf level {
type uint32;
}
}
}
rpc ping {
description "Check aliveness of backend daemon.";
}
rpc stats {
description "Clixon XML statistics.";
output {
container global{
description "Clixon global statistics";
leaf xmlnr{
description "Number of XML objects: number of residing xml/json objects
in the internal 'cxobj' representation.";
type uint64;
}
}
list datastore{
description "Datastore statistics";
key "name";
leaf name{
description "name of datastore (eg running).";
type string;
}
leaf nr{
description "Number of XML objects. That is number of residing xml/json objects
in the internal 'cxobj' representation.";
type uint64;
}
leaf size{
description "Size in bytes of internal datastore cache of datastore tree.";
type uint64;
}
}
}
}
rpc restart-plugin {
description "Restart specific backend plugins.";
input {
leaf-list plugin {
description "Name of plugin to restart";
type string;
}
}
}
rpc process-control {
description
"Control a specific process or daemon: start/stop, etc.
This is for direct managing of a process by the backend.
Alternatively one can manage a daemon via systemd, containerd, kubernetes, etc.";
input {
leaf name {
description "Name of process";
type string;
mandatory true;
}
leaf operation {
type service-operation;
mandatory true;
description
"One of the strings 'start', 'stop', 'restart', or 'status'.";
}
}
output {
choice result {
case status {
description
"Output from status rpc";
leaf status {
description "True if process is running, false if not";
type boolean;
}
leaf pid {
description "Process-id of running process or 0 if not running
Value is only valid for operation status";
type uint32;
}
}
case other {
description
"Output from start/stop/restart rpc";
leaf ok {
type empty;
}
}
}
}
}
}