diff --git a/CHANGELOG.md b/CHANGELOG.md index c7320e2c..90e53777 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,7 +35,7 @@ Expected: September, 2021 ### New features -* List pageing for Netconf and Restconf +* List paging for Netconf and Restconf * Experimental, work-in-progress * Enable with LIST_PAGINATION compile-time option * According to: @@ -773,7 +773,7 @@ Developers may need to change their code * The register function has removed `from` and `rev` parameters: `upgrade_callback_register(h, cb, namespace, arg)` * The callback function has a new `op` parameter with possible values: `XML_FLAG_ADD`, `XML_FLAG_CHANGE` or `XML_FLAG_CHANGE`: `clicon_upgrade_cb(h, xn, ns, op, from, to, arg, cbret)` -* Added new cli show functions to work with cligen_output for cligen pageing to work. To achieve this, replace function calls as follows: +* Added new cli show functions to work with cligen_output for cligen paging to work. To achieve this, replace function calls as follows: * `xml2txt(...)` --> `xml2txt_cb(..., cligen_output)` * `xml2cli(...)` --> `xml2cli_cb(..., cligen_output)` * `clicon_xml2file(...)` --> `clicon_xml2file_cb(..., cligen_output)` diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index f9882c76..eed8b767 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -150,6 +150,8 @@ release_all_dbs(clicon_handle h, } retval = 0; done: + if (keys) + free(keys); return retval; } diff --git a/apps/backend/backend_get.c b/apps/backend/backend_get.c index 78346f61..30639cf2 100644 --- a/apps/backend/backend_get.c +++ b/apps/backend/backend_get.c @@ -73,9 +73,6 @@ #include "backend_handle.h" #include "backend_get.h" -/* List pagination remaining attribute using meta */ -#undef REMAINING - /*! * Maybe should be in the restconf client instead of backend? * @param[in] h Clicon handle @@ -276,6 +273,122 @@ get_client_statedata(clicon_handle h, goto done; } +/*! Help function to filter out anything that is outside of xpath + * + * Code complex to filter out anything that is outside of xpath + * Actually this is a safety catch, should really be done in plugins + * and modules_state functions. + * But it is problematic, because defaults, at least of config data, is in place + * and we need to re-add it. + * Note original xpath + * + * @param[in] h Clicon handle + * @param[in] yspec Yang spec + * @param[in] xret Result XML tree + * @param[in] xpath XPath point to object to get + * @param[in] nsc Namespace context of xpath + * @param[out] x1p Pointer to first matching object if any + * @retval 0 OK + * @retval -1 Error + */ +static int +filter_xpath_again(clicon_handle h, + yang_stmt *yspec, + cxobj *xret, + char *xpath, + cvec *nsc, + cxobj **x1p) +{ + int retval = -1; + cxobj **xvec = NULL; + size_t xlen; + int i; + + if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) + goto done; + /* If vectors are specified then mark the nodes found and + * then filter out everything else, + * otherwise return complete tree. + */ + if (xvec != NULL){ + for (i=0; i..., ", NETCONF_BASE_NAMESPACE); /* OK */ + if (xret==NULL) + cprintf(cbret, ""); + else{ + if (xml_name_set(xret, NETCONF_OUTPUT_DATA) < 0) + goto done; + /* Top level is data, so add 1 to depth if significant */ + if (clicon_xml2cbuf(cbret, xret, 0, 0, depth>0?depth+1:depth) < 0) + goto done; + } + cprintf(cbret, ""); + retval = 0; + done: + if (xvec) + free(xvec); + return retval; +} + #ifdef LIST_PAGINATION /*! Help function for parsing restconf query parameter and setting netconf attribute @@ -318,8 +431,8 @@ element2value(clicon_handle h, * @param[in] xe Request: * @param[in] content Get config/state/both * @param[in] db Database name - * @param[in] xpath - * @param[in] nsc + * @param[in] xpath XPath point to object to get + * @param[in] nsc Namespace context of xpath * @param[out] cbret Return xml tree, eg ..., ", NETCONF_BASE_NAMESPACE); /* OK */ - if (xret==NULL) - cprintf(cbret, ""); - else{ - if (xml_name_set(xret, NETCONF_OUTPUT_DATA) < 0) - goto done; - /* Top level is data, so add 1 to depth if significant */ - if (clicon_xml2cbuf(cbret, xret, 0, 0, depth>0?depth+1:depth) < 0) - goto done; - } - cprintf(cbret, ""); +#endif /* LIST_PAGINATION_REMAINING */ + if (get_nacm_and_reply(h, xret, xpath, nsc, username, depth, cbret) < 0) + goto done; ok: retval = 0; done: @@ -600,10 +659,6 @@ get_list_pagination(clicon_handle h, cbuf_free(cbpath); if (xerr) xml_free(xerr); - if (xvec) - free(xvec); - if (xvecnacm) - free(xvecnacm); if (xret) xml_free(xret); return retval; @@ -636,18 +691,12 @@ get_common(clicon_handle h, cxobj *xfilter; char *xpath = NULL; cxobj *xret = NULL; - cxobj **xvec = NULL; - size_t xlen; - cxobj **xvecnacm = NULL; - size_t xlennacm; - cxobj *xnacm = NULL; char *username; cvec *nsc0 = NULL; /* Create a netconf namespace context from filter */ cvec *nsc = NULL; char *attr; int32_t depth = -1; /* Nr of levels to print, -1 is all, 0 is none */ yang_stmt *yspec; - int i; cxobj *xerr = NULL; int ret; char *reason = NULL; @@ -817,57 +866,10 @@ get_common(clicon_handle h, if (xml_apply(xret, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, (void*)XML_FLAG_MARK) < 0) goto done; } - /* Code complex to filter out anything that is outside of xpath - * Actually this is a safety catch, should really be done in plugins - * and modules_state functions. - * But it is problematic, because defaults, at least of config data, is in place - * and we need to re-add it. - * Note original xpath - */ - if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) + if (filter_xpath_again(h, yspec, xret, xpath, nsc, NULL) < 0) goto done; - - /* If vectors are specified then mark the nodes found and - * then filter out everything else, - * otherwise return complete tree. - */ - if (xvec != NULL){ - for (i=0; i", NETCONF_BASE_NAMESPACE); /* OK */ - if (xret==NULL) - cprintf(cbret, ""); - else{ - if (xml_name_set(xret, NETCONF_OUTPUT_DATA) < 0) - goto done; - /* Top level is data, so add 1 to depth if significant */ - if (clicon_xml2cbuf(cbret, xret, 0, 0, depth>0?depth+1:depth) < 0) - goto done; - } - cprintf(cbret, ""); ok: retval = 0; done: @@ -886,12 +888,6 @@ get_common(clicon_handle h, xml_free(xerr); if (xpath) free(xpath); - if (xvec) - free(xvec); - if (xvecnacm) - free(xvecnacm); - if (xret) - xml_free(xret); return retval; } diff --git a/example/main/example_backend.c b/example/main/example_backend.c index 2d515262..57ca70ce 100644 --- a/example/main/example_backend.c +++ b/example/main/example_backend.c @@ -1092,7 +1092,7 @@ example_daemon(clicon_handle h) yang_stmt *yspec; /* Read state file (or should this be in init/start?) */ - if (_state && _state_file && _state_file_cached){ + if (_state && _state_file && _state_file_cached && 0){ yspec = clicon_dbspec_yang(h); if ((fp = fopen(_state_file, "r")) == NULL){ clicon_err(OE_UNIX, errno, "open(%s)", _state_file); diff --git a/include/clixon_custom.h b/include/clixon_custom.h index 3f7f6aa9..628478af 100644 --- a/include/clixon_custom.h +++ b/include/clixon_custom.h @@ -124,3 +124,8 @@ * draft-wwlh-netconf-list-pagination-rc-01 */ #define LIST_PAGINATION + +/*! Enable "remaining" attribute (sub-feature of list pagination) + * As defined in draft-wwlh-netconf-list-pagination-00 using Yang metadata value [RFC7952] + */ +#undef LIST_PAGINATION_REMAINING diff --git a/test/example_social.sh b/test/example_social.sh index 779c18c3..7daea9ab 100755 --- a/test/example_social.sh +++ b/test/example_social.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Example-social from draft-netconf-list-pagination-00.txt appendix A.1 # Assumes variable fexample is set to name of yang file -# Note inverted pattern is commented +# Note audit-logs/audit-log/outcome is changed from mandatory to default cat < $fexample module example-social { @@ -281,7 +281,7 @@ cat < $fexample } leaf outcome { type boolean; - mandatory true; + default true; /* Note changed from mandatory in original */ description "Indicate if request was permitted."; } diff --git a/test/test_paging_state.sh b/test/test_paging_state.sh index 4b51387e..f145bd7e 100755 --- a/test/test_paging_state.sh +++ b/test/test_paging_state.sh @@ -7,8 +7,8 @@ # Magic line must be first in script (see README.md) s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi -#echo "...skipped: Must run interactvely" -#if [ "$s" = $0 ]; then exit 0; else return 0; fi +echo "...skipped: Must run interactvely" +if [ "$s" = $0 ]; then exit 0; else return 0; fi APPNAME=example @@ -16,6 +16,9 @@ cfg=$dir/conf.xml fexample=$dir/example-social.yang fstate=$dir/mystate.xml +# For 1M test,m use an external file since the generation takes considerable time +#fstate=~/tmp/mystate.xml + # Common example-module spec (fexample must be set) . ./example_social.sh @@ -59,14 +62,10 @@ new "generate state with $perfnr list entries" echo "" >> $fstate for (( i=0; i<$perfnr; i++ )); do echo " " >> $fstate - mon=$(( ( RANDOM % 10 ) )) - day=$(( ( RANDOM % 10 ) )) - hour=$(( ( RANDOM % 10 ) )) - echo " 2020-0$mon-0$dayT0$hour:48:11Z" >> $fstate + echo " 2021-09-05T018:48:11Z" >> $fstate echo " bob$i" >> $fstate echo " 192.168.1.32" >> $fstate echo " POST" >> $fstate - echo " true" >> $fstate echo " " >> $fstate done echo -n "" >> $fstate # No CR @@ -90,6 +89,7 @@ wait_backend # XXX How to run without using a terminal? new "cli show" +echo "$clixon_cli -1 -f $cfg -l o show pagination xpath /es:audit-logs/es:audit-log cli" $clixon_cli -1 -f $cfg -l o show pagination xpath /es:audit-logs/es:audit-log cli if [ $BE -ne 0 ]; then diff --git a/yang/clixon/clixon-config@2021-07-11.yang b/yang/clixon/clixon-config@2021-07-11.yang index 3de7cd7b..4a11af17 100644 --- a/yang/clixon/clixon-config@2021-07-11.yang +++ b/yang/clixon/clixon-config@2021-07-11.yang @@ -692,7 +692,7 @@ module clixon-config { type int32; default 24; description - "Set to number of CLI terminal rows for pageing/scrolling. 0 means unlimited. + "Set to number of CLI terminal rows for paging/scrolling. 0 means unlimited. The number is set statically UNLESS: - there is no terminal, such as file input, in which case nr lines is 0 - there is a terminal sufficiently powerful to read the number of lines from diff --git a/yang/clixon/clixon-netconf-list-pagination@2021-08-27.yang b/yang/clixon/clixon-netconf-list-pagination@2021-08-27.yang index 0acb3add..089b2165 100644 --- a/yang/clixon/clixon-netconf-list-pagination@2021-08-27.yang +++ b/yang/clixon/clixon-netconf-list-pagination@2021-08-27.yang @@ -80,7 +80,7 @@ module clixon-netconf-list-pagination { represent any value greater than or equal to 2^32-1 elements."; } - grouping pageing-parameters { + grouping paging-parameters { leaf list-pagination { type boolean; default false; @@ -173,10 +173,10 @@ module clixon-netconf-list-pagination { } } augment /nc:get-config/nc:input { - uses pageing-parameters; + uses paging-parameters; } // extending the get operation augment /nc:get/nc:input { - uses pageing-parameters; + uses paging-parameters; } }