From e0bcca54059af38e905e0db4ea3f8f7a2c3c40a2 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Wed, 12 Jan 2022 21:58:41 +0100 Subject: [PATCH] * New `clixon-lib@2021-12-05.yang` revision * Extension `autocli-op` obsoleted and no longer supported * You need to change to use clixon-autocli `hide`and `hide-show` instead. * Translate as follows: * `cl:autocli-op hide` -> `autocli:hide` * `cl:autocli-op hide-database` -> `autocli:hide-show` * `cl:autocli-op hide-database-auto-completion` -> `autocli:hide; autocli:hide-show` --- CHANGELOG.md | 10 +- apps/cli/cli_auto.c | 27 +- apps/cli/cli_generate.c | 44 ++-- apps/cli/cli_plugin.c | 1 - apps/cli/cli_show.c | 11 +- example/main/clixon-example@2020-12-01.yang | 68 ++--- lib/clixon/clixon_options.h | 1 + lib/src/clixon_yang_internal.h | 2 +- test/config.sh.in | 3 +- test/test_cli_auto_extension.sh | 105 ++++---- test/test_restconf.sh | 2 +- yang/clixon/Makefile.in | 2 +- yang/clixon/clixon-autocli@2021-12-05.yang | 12 + yang/clixon/clixon-lib@2021-12-05.yang | 268 ++++++++++++++++++++ 14 files changed, 410 insertions(+), 146 deletions(-) create mode 100644 yang/clixon/clixon-lib@2021-12-05.yang diff --git a/CHANGELOG.md b/CHANGELOG.md index a69c967c..87252264 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,11 +54,19 @@ Planned: January, 2022 * `@datamodelstate` translated to `@basemodel, @remove:leafvar` * Note: while @datamodel etc are backward compatible, the autocli redesign is NOT backward compatible * see API changes - + * Moved hide extensions from `clixon-lib` to `clixon-autocli` + ### API changes on existing protocol/config features Users may have to change how they access the system +* New `clixon-lib@2021-12-05.yang` revision + * Extension `autocli-op` obsoleted and no longer supported + * You need to change to use clixon-autocli `hide`and `hide-show` instead. + * Translate as follows: + * `cl:autocli-op hide` -> `autocli:hide` + * `cl:autocli-op hide-database` -> `autocli:hide-show` + * `cl:autocli-op hide-database-auto-completion` -> `autocli:hide; autocli:hide-show` * New `clixon-config@2021-12-05.yang` revision * Imported (as a sub-spec): clixon-clispec.yang * Removed obsolete options: diff --git a/apps/cli/cli_auto.c b/apps/cli/cli_auto.c index 345918df..56a6c8a7 100644 --- a/apps/cli/cli_auto.c +++ b/apps/cli/cli_auto.c @@ -96,6 +96,9 @@ co2apipath(cg_obj *co) return cv_string_get(cv);; } +/* Append to cvv1 to cvv0 + * @note if cvv0 is non-null, the first element of cvv1 is skipped + */ static cvec* cvec_append(cvec *cvv0, cvec *cvv1) @@ -167,17 +170,14 @@ cli_xml2file(cxobj *xn, int haselement; char *val; char *encstr = NULL; /* xml encoded string */ - char *opext = NULL; + int exist = 0; if (xn == NULL) goto ok; - /* Look for autocli-op defined in clixon-lib.yang */ - if (yang_extension_value(xml_spec(xn), "autocli-op", CLIXON_LIB_NS, NULL, &opext) < 0) { + if (yang_extension_value(xml_spec(xn), "hide-show", CLIXON_AUTOCLI_NS, &exist, NULL) < 0) + goto done; + if (exist) goto ok; - } - if ((opext != NULL) && ((strcmp(opext, "hide-database") == 0) || (strcmp(opext, "hide-database-auto-completion") == 0))){ - goto ok; - } name = xml_name(xn); namespace = xml_prefix(xn); switch(xml_type(xn)){ @@ -268,19 +268,16 @@ cli_xml2txt(cxobj *xn, cxobj *xc = NULL; int children=0; int retval = -1; - char *opext = NULL; + int exist = 0; if (xn == NULL || fn == NULL){ clicon_err(OE_XML, EINVAL, "xn or fn is NULL"); goto done; } - /* Look for autocli-op defined in clixon-lib.yang */ - if (yang_extension_value(xml_spec(xn), "autocli-op", CLIXON_LIB_NS, NULL, &opext) < 0) { + if (yang_extension_value(xml_spec(xn), "hide-show", CLIXON_AUTOCLI_NS, &exist, NULL) < 0) + goto done; + if (exist) goto ok; - } - if ((opext != NULL) && ((strcmp(opext, "hide-database") == 0) || (strcmp(opext, "hide-database-auto-completion") == 0))){ - goto ok; - } xc = NULL; /* count children (elements and bodies, not attributes) */ while ((xc = xml_child_each(xn, xc, -1)) != NULL) if (xml_type(xc) == CX_ELMNT || xml_type(xc) == CX_BODY) @@ -353,7 +350,7 @@ cli_auto_edit(clicon_handle h, goto done; } /* Find the matching cligen object - * Note, is complictead: either an instantiated tree (co_treeref_orig) + * Note, is complicated: either an instantiated tree (co_treeref_orig) * or actual tree (co_ref) */ if ((co = cligen_co_match(cli_cligen(h))) != NULL){ diff --git a/apps/cli/cli_generate.c b/apps/cli/cli_generate.c index bcf682fd..fc065104 100644 --- a/apps/cli/cli_generate.c +++ b/apps/cli/cli_generate.c @@ -134,11 +134,12 @@ cli_expand_var_generate(clicon_handle h, cbuf *cb) { int retval = -1; - char *api_path_fmt = NULL, *opext = NULL; + char *api_path_fmt = NULL; + int exist = 0; - if (yang_extension_value(ys, "autocli-op", CLIXON_LIB_NS, NULL, &opext) < 0) + if (yang_extension_value(ys, "hide", CLIXON_AUTOCLI_NS, &exist, NULL) < 0) goto done; - if (opext && strcmp(opext, "hide-database") == 0) { + if (exist) { retval = 1; goto done; } @@ -760,9 +761,10 @@ yang2cli_leaf(clicon_handle h, int retval = -1; char *helptext = NULL; char *s; - char *opext = NULL; + int extralevel = 0; autocli_listkw_t listkw; + int exist = 0; /* description */ if ((yd = yang_find(ys, Y_DESCRIPTION, NULL)) != NULL){ @@ -774,9 +776,6 @@ yang2cli_leaf(clicon_handle h, *s = '\0'; } cprintf(cb, "%*s", level*3, ""); - /* Look for autocli-op defined in clixon-lib.yang */ - if (yang_extension_value(ys, "autocli-op", CLIXON_LIB_NS, NULL, &opext) < 0) - goto done; if (autocli_list_keyword(h, &listkw) < 0) goto done; if (listkw == AUTOCLI_LISTKW_ALL || @@ -784,14 +783,12 @@ yang2cli_leaf(clicon_handle h, cprintf(cb, "%s", yang_argument_get(ys)); yang2cli_helptext(cb, helptext); cprintf(cb, " "); - if (opext && strcmp(opext, "hide") == 0){ + if (yang_extension_value(ys, "hide", CLIXON_AUTOCLI_NS, &exist, NULL) < 0) + goto done; + if (exist){ cprintf(cb, ", hide{"); extralevel = 1; } - if (opext && strcmp(opext, "hide-database-auto-completion") == 0){ - cprintf(cb, ", hide-database-auto-completion{"); - extralevel = 1; - } if (yang2cli_var(h, ys, ys, helptext, cb) < 0) goto done; } @@ -832,9 +829,9 @@ yang2cli_container(clicon_handle h, char *s; int compress = 0; int hide_oc = 0; - char *opext = NULL; yang_stmt *ymod = NULL; - + int exist = 0; + if (ys_real_module(ys, &ymod) < 0) goto done; /* If non-presence container && HIDE mode && only child is @@ -856,16 +853,11 @@ yang2cli_container(clicon_handle h, } if (cli_callback_generate(h, ys, cb) < 0) goto done; - - /* Look for autocli-op defined in clixon-lib.yang */ - if (yang_extension_value(ys, "autocli-op", CLIXON_LIB_NS, NULL, &opext) < 0) + if (yang_extension_value(ys, "hide", CLIXON_AUTOCLI_NS, &exist, NULL) < 0) goto done; - if (opext != NULL && strcmp(opext, "hide") == 0){ + if (exist){ cprintf(cb, ",hide"); } - if (opext != NULL && strcmp(opext, "hide-database-auto-completion") == 0){ - cprintf(cb, ", hide-database-auto-completion"); - } cprintf(cb, ";{\n"); } @@ -904,7 +896,7 @@ yang2cli_list(clicon_handle h, char *helptext = NULL; char *s; int last_key = 0; - char *opext = NULL; + int exist = 0; cprintf(cb, "%*s%s", level*3, "", yang_argument_get(ys)); if ((yd = yang_find(ys, Y_DESCRIPTION, NULL)) != NULL){ @@ -916,15 +908,11 @@ yang2cli_list(clicon_handle h, *s = '\0'; yang2cli_helptext(cb, helptext); } - /* Look for autocli-op defined in clixon-lib.yang */ - if (yang_extension_value(ys, "autocli-op", CLIXON_LIB_NS, NULL, &opext) < 0) + if (yang_extension_value(ys, "hide", CLIXON_AUTOCLI_NS, &exist, NULL) < 0) goto done; - if (opext != NULL && strcmp(opext, "hide") == 0){ + if (exist){ cprintf(cb, ",hide"); } - if (opext != NULL && strcmp(opext, "hide-database-auto-completion") == 0){ - cprintf(cb, ",hide-database-auto-completion"); - } /* Loop over all key variables */ cvk = yang_cvec_get(ys); /* Use Y_LIST cache, see ys_populate_list() */ cvi = NULL; diff --git a/apps/cli/cli_plugin.c b/apps/cli/cli_plugin.c index 444df8f4..467021e4 100644 --- a/apps/cli/cli_plugin.c +++ b/apps/cli/cli_plugin.c @@ -608,7 +608,6 @@ clicon_parse(clicon_handle h, clicon_err_reset(); if ((ret = cligen_eval(ch, match_obj, cvv, callbacks)) < 0) cli_handler_err(stdout); - } else ret = 0; diff --git a/apps/cli/cli_show.c b/apps/cli/cli_show.c index 5f7af818..c8a8859d 100644 --- a/apps/cli/cli_show.c +++ b/apps/cli/cli_show.c @@ -1038,9 +1038,9 @@ xml2cli(clicon_handle h, yang_stmt *ys; int match; char *body; - char *opext = NULL; int compress = 0; autocli_listkw_t listkw; + int exist = 0; if (autocli_list_keyword(h, &listkw) < 0) goto done; @@ -1048,13 +1048,10 @@ xml2cli(clicon_handle h, goto ok; if ((ys = xml_spec(xn)) == NULL) goto ok; - /* Look for autocli-op defined in clixon-lib.yang */ - if (yang_extension_value(xml_spec(xn), "autocli-op", CLIXON_LIB_NS, NULL, &opext) < 0) { + if (yang_extension_value(ys, "hide-show", CLIXON_AUTOCLI_NS, &exist, NULL) < 0) + goto done; + if (exist) goto ok; - } - if ((opext != NULL) && ((strcmp(opext, "hide-database") == 0) || (strcmp(opext, "hide-database-auto-completion") == 0))){ - goto ok; - } /* If leaf/leaf-list or presence container, then print line */ if (yang_keyword_get(ys) == Y_LEAF || yang_keyword_get(ys) == Y_LEAF_LIST){ diff --git a/example/main/clixon-example@2020-12-01.yang b/example/main/clixon-example@2020-12-01.yang index 12befb36..f2baf3ae 100644 --- a/example/main/clixon-example@2020-12-01.yang +++ b/example/main/clixon-example@2020-12-01.yang @@ -10,14 +10,14 @@ module clixon-example { prefix ip; } import iana-if-type { - prefix ianaift; + prefix ianaift; } import ietf-datastores { - prefix ds; + prefix ds; + } + import clixon-autocli{ + prefix autocli; } - import clixon-lib{ - prefix cl; - } description "Clixon example used as a part of the Clixon test suite. It can be used as a basis for making new Clixon applications. @@ -57,7 +57,7 @@ module clixon-example { } leaf hidden{ type string; - cl:autocli-op hide; + autocli:hide; } leaf stat{ description "Inline state data for example application"; @@ -68,11 +68,11 @@ module clixon-example { } /* State data (not config) for the example application*/ container state { - config false; - description "state data for the example application (must be here for example get operation)"; - leaf-list op { + config false; + description "state data for the example application (must be here for example get operation)"; + leaf-list op { type string; - } + } } augment "/if:interfaces/if:interface" { container my-status { @@ -88,38 +88,38 @@ module clixon-example { } /* yang extension implemented by the example backend code. */ extension e4 { - description - "The first child of the ex:e4 (unknown) statement is inserted into + description + "The first child of the ex:e4 (unknown) statement is inserted into the module as a regular data statement. This means that 'uses bar;' in the ex:e4 statement below is a valid data node"; - argument arg; + argument arg; } grouping bar { - leaf bar{ - type string; - } + leaf bar{ + type string; + } } ex:e4 arg1{ - uses bar; + uses bar; } /* Example notification as used in RFC 5277 and RFC 8040 */ notification event { - description "Example notification event."; - leaf event-class { - type string; - description "Event class identifier."; - } - container reportingEntity { - description "Event specific information."; - leaf card { - type string; - description "Line card identifier."; - } - } - leaf severity { - type string; - description "Event severity description."; - } + description "Example notification event."; + leaf event-class { + type string; + description "Event class identifier."; + } + container reportingEntity { + description "Event specific information."; + leaf card { + type string; + description "Line card identifier."; + } + } + leaf severity { + type string; + description "Event severity description."; + } } rpc client-rpc { description "Example local client-side RPC that is processed by the @@ -166,7 +166,7 @@ module clixon-example { } leaf y { description - "If a leaf in the input tree has a 'mandatory' statement with the + "If a leaf in the input tree has a 'mandatory' statement with the value 'true', the leaf MUST be present in an RPC invocation."; type string; default "42"; diff --git a/lib/clixon/clixon_options.h b/lib/clixon/clixon_options.h index 2d733a9d..beae9398 100644 --- a/lib/clixon/clixon_options.h +++ b/lib/clixon/clixon_options.h @@ -52,6 +52,7 @@ */ #define CLIXON_CONF_NS "http://clicon.org/config" #define CLIXON_LIB_NS "http://clicon.org/lib" +#define CLIXON_AUTOCLI_NS "http://clicon.org/autocli" #define CLIXON_RESTCONF_NS "http://clicon.org/restconf" /* diff --git a/lib/src/clixon_yang_internal.h b/lib/src/clixon_yang_internal.h index 84b4f274..b5093d36 100644 --- a/lib/src/clixon_yang_internal.h +++ b/lib/src/clixon_yang_internal.h @@ -67,7 +67,7 @@ struct yang_stmt{ int ys_len; /* Number of children */ struct yang_stmt **ys_stmt; /* Vector of children statement pointers */ struct yang_stmt *ys_parent; /* Backpointer to parent: yang-stmt or yang-spec */ - enum rfc_6020 ys_keyword; /* See clicon_yang_parse.tab.h */ + enum rfc_6020 ys_keyword; /* */ char *ys_argument; /* String / argument depending on keyword */ uint16_t ys_flags; /* Flags according to YANG_FLAG_MARK and others */ diff --git a/test/config.sh.in b/test/config.sh.in index 0eb2ce48..6965e3b4 100755 --- a/test/config.sh.in +++ b/test/config.sh.in @@ -65,7 +65,8 @@ CLIXON_VERSION=@CLIXON_VERSION@ DATASTORE_TOP="config" # clixon yang revisions occuring in tests -CLIXON_LIB_REV="2021-11-11" +CLIXON_AUTOCLI_REV="2021-12-05" +CLIXON_LIB_REV="2021-12-05" CLIXON_CONFIG_REV="2021-11-11" CLIXON_RESTCONF_REV="2021-05-20" CLIXON_EXAMPLE_REV="2020-12-01" diff --git a/test/test_cli_auto_extension.sh b/test/test_cli_auto_extension.sh index 56797ede..665afd2e 100755 --- a/test/test_cli_auto_extension.sh +++ b/test/test_cli_auto_extension.sh @@ -1,7 +1,6 @@ #!/usr/bin/env bash -# Tests for using autocli extension defined in clixon-lib +# Tests for using autocli hide extension # This is both a test of yang extensions and autocli -# The extension is autocli-op and can take the value "hide" (maybe more) # Try both inline and augmented mode # @see https://clixon-docs.readthedocs.io/en/latest/misc.html#extensions # Magic line must be first in script (see README.md) @@ -74,12 +73,12 @@ cat < $fyang module example { namespace "urn:example:clixon"; prefix ex; - import clixon-lib{ - prefix cl; + import clixon-autocli{ + prefix autocli; } - grouping pg { - cl:autocli-op hide; /* This is the extension */ + autocli:hide; + autocli:hide-show; leaf value{ description "a value"; type string; @@ -111,12 +110,6 @@ cat < $fyang2 module example-augment { namespace "urn:example:augment"; prefix aug; - import example{ - prefix ex; - } - import clixon-lib{ - prefix cl; - } } EOF @@ -145,8 +138,7 @@ set table parameter x show config xml EOF new "set table parameter hidden" - expectpart "$(cat $fin | $clixon_cli -f $cfg 2>&1)" 0 "set table parameter x" "x
" - + expectpart "$(cat $fin | $clixon_cli -f $cfg 2>&1)" 0 "set table parameter x" "
" } function testvalue() @@ -163,9 +155,8 @@ function testvalue() set table parameter x value 42 show config xml EOF - new "set table parameter hidden leaf" - expectpart "$(cat $fin | $clixon_cli -f $cfg 2>&1)" 0 "x42
" - + new "set table parameter hidden leaf2" + expectpart "$(cat $fin | $clixon_cli -f $cfg 2>&1)" 0 "x
" } # INLINE MODE @@ -176,33 +167,34 @@ testparam # Second annotate /table/parameter/value cat < $fyang module example { - namespace "urn:example:clixon"; - prefix ex; - import clixon-lib{ - prefix cl; - } - container table{ - list parameter{ - key name; - leaf name{ - type string; - } - leaf value{ - cl:autocli-op hide; /* Here is the example */ - description "a value"; - type string; - } - list index{ - key i; - leaf i{ - type string; - } - leaf iv{ - type string; - } - } - } - } + namespace "urn:example:clixon"; + prefix ex; + import clixon-autocli{ + prefix autocli; + } + container table{ + list parameter{ + key name; + leaf name{ + type string; + } + leaf value{ + autocli:hide; + autocli:hide-show; + description "a value"; + type string; + } + list index{ + key i; + leaf i{ + type string; + } + leaf iv{ + type string; + } + } + } + } } EOF @@ -247,16 +239,16 @@ module example-augment { import example{ prefix ex; } - import clixon-lib{ - prefix cl; + import clixon-autocli{ + prefix autocli; } augment "/ex:table/ex:parameter" { - cl:autocli-op hide; + autocli:hide; + autocli:hide-show; } } EOF - new "Test hidden parameter in table/param augment" testparam @@ -269,11 +261,12 @@ module example-augment { import example{ prefix ex; } - import clixon-lib{ - prefix cl; + import clixon-autocli{ + prefix autocli; } augment "/ex:table/ex:parameter/ex:value" { - cl:autocli-op hide; + autocli:hide; + autocli:hide-show; } } EOF @@ -292,7 +285,6 @@ module example { import example-augment{ prefix aug; } - container table{ list parameter{ key name; @@ -310,11 +302,12 @@ cat < $fyang2 module example-augment { namespace "urn:example:augment"; prefix aug; - import clixon-lib{ - prefix cl; + import clixon-autocli{ + prefix autocli; } - grouping pg { - cl:autocli-op hide; /* This is the extension */ + grouping pg { + autocli:hide; + autocli:hide-show; leaf value{ description "a value"; type string; diff --git a/test/test_restconf.sh b/test/test_restconf.sh index fe6b1088..a6a44008 100755 --- a/test/test_restconf.sh +++ b/test/test_restconf.sh @@ -341,7 +341,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/$HVER 200" '{"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/$HVER 200" "{\"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}\",\"" + expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+json' $proto://$addr/restconf/data/ietf-yang-library:modules-state)" 0 "HTTP/$HVER 200" "{\"ietf-yang-library:modules-state\":{\"module-set-id\":\"0\",\"module\":\[{\"name\":\"clixon-autocli\",\"revision\":\"${CLIXON_AUTOCLI_REV}\",\"namespace\":\"http://clicon.org/autocli\",\"conformance-type\":\"implement\"},{\"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/$HVER 200" "Allow: OPTIONS,HEAD,GET,POST,PUT,PATCH,DELETE" diff --git a/yang/clixon/Makefile.in b/yang/clixon/Makefile.in index 571117d3..733f35a7 100644 --- a/yang/clixon/Makefile.in +++ b/yang/clixon/Makefile.in @@ -43,7 +43,7 @@ YANG_INSTALLDIR = @YANG_INSTALLDIR@ YANGSPECS = clixon-config@2021-07-11.yang # 5.3 YANGSPECS = clixon-config@2021-12-05.yang # 5.5 -YANGSPECS += clixon-lib@2021-11-11.yang # 5.4 +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 diff --git a/yang/clixon/clixon-autocli@2021-12-05.yang b/yang/clixon/clixon-autocli@2021-12-05.yang index 14b356cd..237733b9 100644 --- a/yang/clixon/clixon-autocli@2021-12-05.yang +++ b/yang/clixon/clixon-autocli@2021-12-05.yang @@ -45,6 +45,18 @@ module clixon-autocli{ description "Initial version"; } + extension hide { + description + "Modify the autocli by hiding the command associated with a YANG node and its + sub-commands. + The command is active but not shown by ? or TAB. In other words, it hides the + auto-completion of commands"; + } + extension hide-show { + description + "Modify the autocli by hiding the command associated with a YANG node and its + sub-commands in CLI show commands."; + } typedef autocli-op { description "Autocli rule-type operation, each rule use different fields as diff --git a/yang/clixon/clixon-lib@2021-12-05.yang b/yang/clixon/clixon-lib@2021-12-05.yang new file mode 100644 index 00000000..f3bc0057 --- /dev/null +++ b/yang/clixon/clixon-lib@2021-12-05.yang @@ -0,0 +1,268 @@ +module clixon-lib { + yang-version 1.1; + namespace "http://clicon.org/lib"; + prefix cl; + + import ietf-yang-types { + prefix yang; + } + organization + "Clicon / Clixon"; + + contact + "Olof Hagsand "; + + 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-12-05 { + description + "Obsoleted: extension autocli-op"; + } + revision 2021-11-11 { + description + "Changed: RPC stats extended with YANG stats"; + } + 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 (meaning, it hides the auto-completion of commands) + - hide-database This command hides the database + - hide-database-auto-completion This command hides the database and the auto completion (meaning, this command acts as both commands above) + Obsolete: use clixon-autocli:hide and clixon-autocli:hide-show instead"; + argument cliop; + status obsolete; + } + 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. + These are global counters incremented by new() and decreased by free() calls. + This number is higher than the sum of all datastore/module residing objects, since + objects may be used for other purposes than datastore/modules"; + leaf xmlnr{ + description + "Number of existing XML objects: number of residing xml/json objects + in the internal 'cxobj' representation."; + type uint64; + } + leaf yangnr{ + description + "Number of resident YANG objects. "; + type uint64; + } + } + list datastore{ + description "Per datastore statistics for cxobj"; + 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; + } + } + list module{ + description "Per YANG module statistics"; + key "name"; + leaf name{ + description "Name of YANG module."; + type string; + } + leaf nr{ + description + "Number of YANG objects. That is number of residing YANG objects"; + type uint64; + } + leaf size{ + description + "Size in bytes of internal YANG object representation."; + 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 active { + description + "True if process is running, false if not. + More specifically, there is a process-id and it exists (in Linux: kill(pid,0). + Note that this is actual state and status is administrative state, + which means that changing the administrative state, eg stopped->running + may not immediately switch active to true."; + type boolean; + } + leaf description { + type string; + description "Description of process. This is a static string"; + } + leaf command { + type string; + description "Start command with arguments"; + } + leaf status { + description + "Administrative status (except on external kill where it enters stopped + directly from running): + stopped: pid=0, No process running + running: pid set, Process started and believed to be running + exiting: pid set, Process is killed by parent but not waited for"; + type string; + } + leaf starttime { + description "Time of starting process UTC"; + type yang:date-and-time; + } + leaf pid { + description "Process-id of main running process (if active)"; + type uint32; + } + } + case other { + description + "Output from start/stop/restart rpc"; + leaf ok { + type empty; + } + } + } + } + } +}