From 85408206988673f9285605584f51f27b8ca6043b Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Sun, 13 Dec 2020 22:19:25 +0100 Subject: [PATCH] * New clixon-lib@2020-12-08.yang revision * Added: autocli-op extension (see new features) * Added: rpc process-control for process/daemon management * Added enable flag and removed presence in clixon-restconf --- CHANGELOG.md | 17 +++-- apps/restconf/restconf_main_evhtp.c | 62 ++++++++++------- example/main/example_backend.c | 5 +- example/main/example_backend_nacm.c | 7 +- test/all.sh | 2 +- test/lib.sh | 4 +- test/sum.sh | 8 +-- test/test_restconf.sh | 2 + test/test_ssl_certs.sh | 1 + yang/clixon/clixon-lib@2020-12-08.yang | 53 ++++++++++++++ yang/clixon/clixon-restconf@2020-10-30.yang | 76 ++++----------------- 11 files changed, 135 insertions(+), 102 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8864ca1e..bd97e6dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Clixon Changelog -* [4.9.0](#490) Expected 15 December 2020 +* [4.9.0](#490) Expected 19 December 2020 * [4.8.0](#480) 18 October 2020 * [4.7.0](#470) 14 September 2020 * [4.6.0](#460) 14 August 2020 @@ -25,10 +25,15 @@ * [3.3.2](#332) Aug 27 2017 * [3.3.1](#331) June 7 2017 -## 4.9.0 Expected: 15 Dec 2020 +## 4.9.0 Expected: 19 Dec 2020 ### New features +* More YANG extension functionality, + * See [Augment auto-cli for hiding/modifying cli syntax #156](https://github.com/clicon/clixon/issues/156) and [hiding auto-generated CLI entries #153](https://github.com/clicon/clixon/issues/153) + * Extensions can be used in augmentations + * Extension `autocli-op` has been added to add "hidden" commands in the autocli + * Documentation: https://clixon-docs.readthedocs.io/en/latest/misc.html#extensions * Restconf configuration has a new configure model: `clixon-restconf.yang` enabling more flexible socket config * The new restconf config, including addresses, authentication type, is set either in clixon-config local config or in backend datastore (ie running) * This only applies to the evhtp restconf daemon, not fcgi/nginx, where the nginx config is used. @@ -41,6 +46,9 @@ Users may have to change how they access the system * Error-type changed from protocol to application for data-not-unique netconf/restconf errors +* New clixon-lib@2020-12-08.yang revision + * Added: autocli-op extension (see new features) + * Added: rpc process-control for process/daemon management * New clixon-config@2020-11-03.yang revision * Moved to clixon-restconf.yang and marked as obsolete: - CLICON_RESTCONF_IPV4_ADDR @@ -64,11 +72,6 @@ Developers may need to change their code ### Minor changes -* More YANG extension functionality, - * See [Augment auto-cli for hiding/modifying cli syntax #156](https://github.com/clicon/clixon/issues/156) and [hiding auto-generated CLI entries #153](https://github.com/clicon/clixon/issues/153) - * Extensions can be used in augmentations - * Extension `autocli-op` has been added to add "hidden" commands in the autocli - * Documentation: https://clixon-docs.readthedocs.io/en/latest/misc.html#extensions * Added new revision of main example yang: `clixon-example@2020-12-01.yang` * Support for building static lib: `LINKAGE=static configure` * Change comment character to be active anywhere to beginning of _word_ only. diff --git a/apps/restconf/restconf_main_evhtp.c b/apps/restconf/restconf_main_evhtp.c index d178955f..956e417e 100644 --- a/apps/restconf/restconf_main_evhtp.c +++ b/apps/restconf/restconf_main_evhtp.c @@ -934,6 +934,9 @@ cx_evhtp_socket(clicon_handle h, * @param[in] xconfig XML config * @param[in] nsc Namespace context * @param[in] eh Evhtp handle + * @retval -1 Error + * @retval 0 OK, but restconf disenabled, proceed with other if possible + * @retval 1 OK */ static int cx_evhtp_init(clicon_handle h, @@ -942,6 +945,8 @@ cx_evhtp_init(clicon_handle h, cx_evhtp_handle *eh) { int retval = -1; + char* enable; + int ssl_enable = 0; cxobj **vec = NULL; size_t veclen; char *server_cert_path = NULL; @@ -949,11 +954,14 @@ cx_evhtp_init(clicon_handle h, char *server_ca_cert_path = NULL; char *auth_type = NULL; int auth_type_client_certificate = 0; - //XXX char *client_cert_ca = NULL; cxobj *x; int i; - int ssl_enable = 0; + if ((x = xpath_first(xrestconf, nsc, "enable")) != NULL && + (enable = xml_body(x)) != NULL){ + if (strcmp(enable, "false") == 0) + goto disable; + } /* If at least one socket has ssl then enable global ssl_enable */ ssl_enable = xpath_first(xrestconf, nsc, "socket[ssl='true']") != NULL; /* get common fields */ @@ -1002,11 +1010,14 @@ cx_evhtp_init(clicon_handle h, auth_type_client_certificate) < 0) goto done; } - retval = 0; + retval = 1; done: if (vec) free(vec); return retval; + disable: + retval = 0; + goto done; } /*! Read restconf from config @@ -1026,22 +1037,24 @@ int restconf_config(clicon_handle h, cx_evhtp_handle *eh) { - int retval = -1; - char *dir; - yang_stmt *yspec = NULL; - char *str; - clixon_plugin *cp = NULL; - cvec *nsctx_global = NULL; /* Global namespace context */ - size_t cligen_buflen; - size_t cligen_bufthreshold; - cvec *nsc = NULL; - cxobj *xerr = NULL; - uint32_t id = 0; /* Session id, to poll backend up */ - struct passwd *pw; - cxobj *xconfig1 = NULL; - cxobj *xrestconf1 = NULL; - cxobj *xconfig2 = NULL; - cxobj *xrestconf2 = NULL; + int retval = -1; + char *dir; + yang_stmt *yspec = NULL; + char *str; + clixon_plugin *cp = NULL; + cvec *nsctx_global = NULL; /* Global namespace context */ + size_t cligen_buflen; + size_t cligen_bufthreshold; + cvec *nsc = NULL; + cxobj *xerr = NULL; + uint32_t id = 0; /* Session id, to poll backend up */ + struct passwd *pw; + cxobj *xconfig1 = NULL; + cxobj *xrestconf1 = NULL; + cxobj *xconfig2 = NULL; + cxobj *xrestconf2 = NULL; + int ret; + int backend = 1; /* query backend for config */ /* Set default namespace according to CLICON_NAMESPACE_NETCONF_DEFAULT */ xml_nsctx_namespace_netconf_default(h); @@ -1137,13 +1150,14 @@ restconf_config(clicon_handle h, /* First get local config */ xconfig1 = clicon_conf_xml(h); if ((xrestconf1 = xpath_first(xconfig1, NULL, "restconf")) != NULL){ - /* Initialize evhtp with local config */ - if (cx_evhtp_init(h, xrestconf1, NULL, eh) < 0) + /* Initialize evhtp with local config: ret 0 means disabled -> need to query remote */ + if ((ret = cx_evhtp_init(h, xrestconf1, NULL, eh)) < 0) goto done; + if (ret == 1) + backend = 0; } - else { - /* Query backend of config. - * Before evhtp, try again if not done */ + if (backend){ /* Query backend of config. */ + /* Before evhtp, try again if not done */ while (1){ if (clicon_hello_req(h, &id) < 0){ if (errno == ENOENT){ diff --git a/example/main/example_backend.c b/example/main/example_backend.c index c6a979f9..f1ca0b35 100644 --- a/example/main/example_backend.c +++ b/example/main/example_backend.c @@ -1122,7 +1122,10 @@ clixon_plugin_init(clicon_handle h) "example"/* Xml tag when callback is made */ ) < 0) goto done; - /* Called after the regular system copy_config callback */ + /* Called before the regular system copy_config callback + * If you want to have it called _after_ the system callback, place this call in + * the _start function. + */ if (rpc_callback_register(h, example_copy_extra, NULL, NETCONF_BASE_NAMESPACE, diff --git a/example/main/example_backend_nacm.c b/example/main/example_backend_nacm.c index 6bc0ac63..72f9e54e 100644 --- a/example/main/example_backend_nacm.c +++ b/example/main/example_backend_nacm.c @@ -37,7 +37,7 @@ * features: * - nacm * - transaction test - * -t enable transaction logging (cal syslog for every transaction) + * -t enable transaction logging (call syslog for every transaction) * -v Failing validate and commit if is present (synthetic error) */ #include @@ -58,6 +58,9 @@ /* These include signatures for plugin and transaction callbacks. */ #include +/* Command line options to be passed to getopt(3) */ +#define BACKEND_NACM_OPTS "tv:" + /*! Variable to control transaction logging (for debug) * If set, call syslog for every transaction callback * Start backend with -- -t @@ -233,7 +236,7 @@ clixon_plugin_init(clicon_handle h) goto done; opterr = 0; optind = 1; - while ((c = getopt(argc, argv, "tv:")) != -1) + while ((c = getopt(argc, argv, BACKEND_NACM_OPTS)) != -1) switch (c) { case 't': /* transaction log */ _transaction_log = 1; diff --git a/test/all.sh b/test/all.sh index 93a825b5..ee06a5e9 100755 --- a/test/all.sh +++ b/test/all.sh @@ -40,7 +40,7 @@ for test in $pattern; do fi done if [ $err -eq 0 ]; then - echo OK + echo "OK, ${testnr} tests" else echo -e "\e[31mError" echo -ne "\e[0m" diff --git a/test/lib.sh b/test/lib.sh index 875ec4b3..d746e220 100755 --- a/test/lib.sh +++ b/test/lib.sh @@ -198,9 +198,9 @@ fi # Can be placed in clixon-config # Note that https clause assumes there exists certs and keys in /etc/ssl,... if [ $RCPROTO = http ]; then - RESTCONFIG="passworddefault
0.0.0.0
80false
" + RESTCONFIG="truepassworddefault
0.0.0.0
80false
" else - RESTCONFIG="password/etc/ssl/certs/clixon-server-crt.pem/etc/ssl/private/clixon-server-key.pem/etc/ssl/certs/clixon-ca-crt.pemdefault
0.0.0.0
443true
" + RESTCONFIG="truepassword/etc/ssl/certs/clixon-server-crt.pem/etc/ssl/private/clixon-server-key.pem/etc/ssl/certs/clixon-ca-crt.pemdefault
0.0.0.0
443true
" fi # Some tests may set owner of testdir to something strange and quit, need diff --git a/test/sum.sh b/test/sum.sh index af988ad5..ddbc0770 100755 --- a/test/sum.sh +++ b/test/sum.sh @@ -25,21 +25,21 @@ if [ $# -gt 0 ]; then exit -1 fi -err=0 +let err=0 # error counter for testfile in $pattern; do # For lib.sh the variable must be called testfile echo "Running $testfile" ./$testfile > /dev/null 2>&1 errcode=$? if [ $errcode -ne 0 ]; then - err=1 + let err++ echo -e "\e[31mError in $testfile errcode=$errcode" echo -ne "\e[0m" fi done if [ $err -eq 0 ]; then - echo OK + echo "OK" else - echo -e "\e[31mError" + echo -e "\e[31m${err} Errors" echo -ne "\e[0m" exit -1 fi diff --git a/test/test_restconf.sh b/test/test_restconf.sh index fe2ebed4..38f6c228 100755 --- a/test/test_restconf.sh +++ b/test/test_restconf.sh @@ -64,6 +64,7 @@ if $IPv6; then # For backend config, create 4 sockets, all combinations IPv4/IPv6 + http/https RESTCONFIG=$(cat < + true password $srvcert $srvkey @@ -79,6 +80,7 @@ else # For backend config, create 4 sockets, all combinations IPv4/IPv6 + http/https RESTCONFIG=$(cat < + true password $srvcert $srvkey diff --git a/test/test_ssl_certs.sh b/test/test_ssl_certs.sh index 9ad0b7cb..c1dcfaa0 100755 --- a/test/test_ssl_certs.sh +++ b/test/test_ssl_certs.sh @@ -140,6 +140,7 @@ cat < $cfg true internal + true client-certificate $srvcert $srvkey diff --git a/yang/clixon/clixon-lib@2020-12-08.yang b/yang/clixon/clixon-lib@2020-12-08.yang index d2678bde..70e18fd5 100644 --- a/yang/clixon/clixon-lib@2020-12-08.yang +++ b/yang/clixon/clixon-lib@2020-12-08.yang @@ -44,6 +44,7 @@ module clixon-lib { 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 { @@ -63,6 +64,28 @@ module clixon-lib { 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 @@ -123,4 +146,34 @@ module clixon-lib { } } } + + rpc process-control { + description + "Control a specific process or daemon: start/stop, etc. + This is for direct managing of a porcess 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'."; + } + leaf namespace { + type string; + description + "Network namespace."; + } + } + output { + leaf status { + type boolean; + } + } + } } diff --git a/yang/clixon/clixon-restconf@2020-10-30.yang b/yang/clixon/clixon-restconf@2020-10-30.yang index bbea7738..05b17204 100644 --- a/yang/clixon/clixon-restconf@2020-10-30.yang +++ b/yang/clixon/clixon-restconf@2020-10-30.yang @@ -57,35 +57,27 @@ module clixon-restconf { description "PAM password auth"; } + enum none { + description + "No authentication, no security."; + } } description "Enumeration of HTTP authorization types."; } - 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"; - } grouping clixon-restconf{ description - "HTTP daemon configuration."; + "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-list auth-type { type http-auth-type; description @@ -135,42 +127,4 @@ module clixon-restconf { presence "Enables RESTCONF"; uses clixon-restconf; } - rpc restconf-control { - input { - leaf operation { - type service-operation; - mandatory true; - description - "One of the strings 'start', 'stop', 'restart', or 'status'."; - } - leaf namespace { - type string; - description - "Network namespace."; - } - } - output { - leaf stdout { - type string; - } - } - } - rpc restconf-coredump { - input { - leaf operation { - type boolean; - mandatory true; - } - leaf namespace { - type string; - description - "Network namespace."; - } - } - output { - leaf stdout { - type string; - } - } - } }