From c94e9dad67536584c8f3ae4cad5229a60ee7057b Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Tue, 22 Nov 2022 13:56:20 +0100 Subject: [PATCH] Feature Request: Support RFC 6022 (NETCONF Monitoring) * Added capabilities and schema state, and get-schema rpc * New `clixon-config@2022-11-01.yang` revision * Added option: * `CLICON_NETCONF_MONITORING` * `CLICON_NETCONF_MONITORING_LOCATION` --- CHANGELOG.md | 14 +- apps/backend/backend_client.c | 113 +- apps/backend/backend_get.c | 6 + apps/netconf/netconf_rpc.c | 2 +- lib/clixon/clixon.h.in | 1 + lib/clixon/clixon_netconf_lib.h | 26 +- lib/clixon/clixon_netconf_monitoring.h | 46 + lib/clixon/clixon_stream.h | 16 - lib/src/Makefile.in | 2 +- lib/src/clixon_netconf_lib.c | 121 ++- lib/src/clixon_netconf_monitoring.c | 179 ++++ lib/src/clixon_stream.c | 5 +- test/test_augment_state.sh | 1 + test/test_leafref_state.sh | 1 + test/test_netconf_monitoring.sh | 105 ++ test/test_netconf_monitoring_location.sh | 114 ++ test/test_netconf_monitoring_multiple.sh | 109 ++ test/test_yang_anydata.sh | 1 + yang/clixon/Makefile.in | 2 +- yang/clixon/clixon-config@2022-11-01.yang | 1188 +++++++++++++++++++++ 20 files changed, 1988 insertions(+), 64 deletions(-) create mode 100644 lib/clixon/clixon_netconf_monitoring.h create mode 100644 lib/src/clixon_netconf_monitoring.c create mode 100755 test/test_netconf_monitoring.sh create mode 100755 test/test_netconf_monitoring_location.sh create mode 100755 test/test_netconf_monitoring_multiple.sh create mode 100644 yang/clixon/clixon-config@2022-11-01.yang diff --git a/CHANGELOG.md b/CHANGELOG.md index 402e541e..d959c705 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Clixon Changelog -* [6.0.0](#600) Expected: End of 2022 +* [6.0.0](#600) Expected: Nov 2022 * [5.9.0](#590) 24 September 2022 * [5.8.0](#580) 28 July 2022 * [5.7.0](#570) 17 May 2022 @@ -38,10 +38,16 @@ * [3.3.1](#331) June 7 2017 ## 6.0.0 -Expected: End of 2022 +Expected: Nov 2022 ### New features +* Netconf monitoring + * First part: Capabilities and schema state and get-schema + * Remains: Datastore, sessions and statistics state + * Standards + * RFC 6022 "YANG Module for NETCONF Monitoring" + * See [Feature Request: Support RFC 6022 (NETCONF Monitoring)](https://github.com/clicon/clixon/issues/370) * Confirmed-commit capability * Standards * RFC 4741 "NETCONF Configuration Protocol": Section 8.4 @@ -57,6 +63,10 @@ Expected: End of 2022 Users may have to change how they access the system +* New `clixon-config@2022-11-01.yang` revision + * Added option: + * `CLICON_NETCONF_MONITORING` + * `CLICON_NETCONF_MONITORING_LOCATION` * Added `PRETTYPRINT_INDENT` compile-time option controlling indentation level for XML,JSON and TEXT * Default value is `3` * NETCONF: Removed `message-id` from hello protocol following RFC 6241 diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index 6c78e968..aa85374e 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -722,7 +722,7 @@ from_client_lock(clicon_handle h, yang_stmt *yspec; if ((yspec = clicon_dbspec_yang(h)) == NULL){ - clicon_err(OE_YANG, ENOENT, "No yang spec9"); + clicon_err(OE_YANG, ENOENT, "No yang spec"); goto done; } if ((db = netconf_db_find(xe, "target")) == NULL){ @@ -1046,6 +1046,109 @@ from_client_create_subscription(clicon_handle h, return retval; } +/*! Retrieve a schema from the NETCONF server. + * + * @param[in] h Clicon handle + * @param[in] xe Request: + * @param[out] cbret Return xml tree, eg ..., is 'operation-failed', and is + * 'data-not-unique'. + */ + if (netconf_data_not_unique(cbret, NULL, NULL)< 0) + goto done; + goto ok; + } + else + ymatch = ymod; + } + if (ymatch == NULL){ + if (netconf_invalid_value(cbret, "protocol", "No such schema") < 0) + goto done; + goto ok; + } + if (format && strcmp(format, "yang") != 0){ + if (netconf_invalid_value(cbret, "protocol", "Format not supported") < 0) + goto done; + goto ok; + } + cprintf(cbret, "", + NETCONF_BASE_NAMESPACE, NETCONF_MONITORING_NAMESPACE); + if ((cbyang = cbuf_new()) == NULL){ + clicon_err(OE_UNIX, errno, "cbuf_new"); + goto done; + } + yang_print_cbuf(cbyang, ymatch, 0, 0); + xml_chardata_cbuf_append(cbret, cbuf_get(cbyang)); + cprintf(cbret, ""); + ok: + retval = 0; + done: + if (cbyang) + cbuf_free(cbyang); + if (nsc) + xml_nsctx_free(nsc); + return retval; +} + /*! Set debug level. * @param[in] h Clicon handle * @param[in] xe Request: @@ -1388,6 +1491,10 @@ from_client_msg(clicon_handle h, goto reply; } ce->ce_id = id; + /* As a side-effect, this expands xt with default values according to "report-all" + * This may not be correct, the RFC does not mention expanding default values for + * input RPC + */ if ((ret = xml_yang_validate_rpc(h, x, 1, &xret)) < 0) goto done; if (ret == 0){ @@ -1604,6 +1711,10 @@ backend_rpc_init(clicon_handle h) if (rpc_callback_register(h, from_client_create_subscription, NULL, EVENT_RFC5277_NAMESPACE, "create-subscription") < 0) goto done; + /* RFC 6022 */ + if (rpc_callback_register(h, from_client_get_schema, NULL, + NETCONF_MONITORING_NAMESPACE, "get-schema") < 0) + goto done; /* Clixon RPC */ if (rpc_callback_register(h, from_client_debug, NULL, CLIXON_LIB_NS, "debug") < 0) diff --git a/apps/backend/backend_get.c b/apps/backend/backend_get.c index 4f6476a3..51f6fd3b 100644 --- a/apps/backend/backend_get.c +++ b/apps/backend/backend_get.c @@ -251,6 +251,12 @@ get_client_statedata(clicon_handle h, if (ret == 0) goto fail; } + if (clicon_option_bool(h, "CLICON_NETCONF_MONITORING")){ + if ((ret = netconf_monitoring_state_get(h, yspec, xpath, nsc, 0, xret)) < 0) + goto done; + if (ret == 0) + goto fail; + } /* Use plugin state callbacks */ if ((ret = clixon_plugin_statedata_all(h, yspec, nsc, xpath, xret)) < 0) goto done; diff --git a/apps/netconf/netconf_rpc.c b/apps/netconf/netconf_rpc.c index 2e32b31c..5e5a721c 100644 --- a/apps/netconf/netconf_rpc.c +++ b/apps/netconf/netconf_rpc.c @@ -470,7 +470,7 @@ netconf_notification_cb(int s, clicon_err(OE_NETCONF, EFAULT, "Notification malformed"); goto done; } - if ((nsc = xml_nsctx_init(NULL, NOTIFICATION_RFC5277_NAMESPACE)) == NULL) + if ((nsc = xml_nsctx_init(NULL, NETCONF_NOTIFICATION_NAMESPACE)) == NULL) goto done; if ((xn = xpath_first(xt, nsc, "notification")) == NULL) goto ok; diff --git a/lib/clixon/clixon.h.in b/lib/clixon/clixon.h.in index eb5966bb..eeb6e307 100644 --- a/lib/clixon/clixon.h.in +++ b/lib/clixon/clixon.h.in @@ -84,6 +84,7 @@ extern "C" { #include #include #include +#include #include #include #include diff --git a/lib/clixon/clixon_netconf_lib.h b/lib/clixon/clixon_netconf_lib.h index 0b1f571e..1e6d3cba 100644 --- a/lib/clixon/clixon_netconf_lib.h +++ b/lib/clixon/clixon_netconf_lib.h @@ -68,7 +68,29 @@ * operations, content, and the element. */ #define YANG_XML_NAMESPACE "urn:ietf:params:xml:ns:yang:1" - + +/* RFC 6022 YANG Module for NETCONF Monitoring + */ +#define NETCONF_MONITORING_NAMESPACE "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring" + +/* Default STREAM namespace (see rfc5277 3.1) + * From RFC8040: + * The structure of the event data is based on the + * element definition in Section 4 of [RFC5277]. It MUST conform to the + * schema for the element in Section 4 of [RFC5277], + * using the XML namespace as defined in the XSD as follows: + * urn:ietf:params:xml:ns:netconf:notification:1.0 + * It is used everywhere in yangmodels, but not in openconfig + */ +#define NETCONF_NOTIFICATION_NAMESPACE "urn:ietf:params:xml:ns:netconf:notification:1.0" +#define NETCONF_NOTIFICATION_CAPABILITY "urn:ietf:params:netconf:capability:notification:1.0" + +/* + * Then there is also this namespace that is only used in RFC5277 seems to be for "netconf" + * events. The usage seems wrong here,... + */ +#define EVENT_RFC5277_NAMESPACE "urn:ietf:params:xml:ns:netmod:notification" + /* * Types */ @@ -152,6 +174,7 @@ int netconf_operation_failed(cbuf *cb, char *type, char *message); int netconf_operation_failed_xml(cxobj **xret, char *type, char *message); int netconf_malformed_message(cbuf *cb, char *message); int netconf_malformed_message_xml(cxobj **xret, char *message); +int netconf_data_not_unique(cbuf *cb, cxobj *x, cvec *cvk); int netconf_data_not_unique_xml(cxobj **xret, cxobj *x, cvec *cvk); int netconf_minmax_elements_xml(cxobj **xret, cxobj *xp, char *name, int max); int netconf_trymerge(cxobj *x, yang_stmt *yspec, cxobj **xret); @@ -161,6 +184,7 @@ char *netconf_db_find(cxobj *xn, char *name); int netconf_err2cb(cxobj *xerr, cbuf *cberr); const netconf_content netconf_content_str2int(char *str); const char *netconf_content_int2str(netconf_content nr); +int netconf_capabilites(clicon_handle h, cbuf *cb); int netconf_hello_server(clicon_handle h, cbuf *cb, uint32_t session_id); int netconf_hello_req(clicon_handle h, cbuf *cb); int clixon_netconf_error_fn(const char *fn, const int line, cxobj *xerr, const char *fmt, const char *arg); diff --git a/lib/clixon/clixon_netconf_monitoring.h b/lib/clixon/clixon_netconf_monitoring.h new file mode 100644 index 00000000..0e6cdd13 --- /dev/null +++ b/lib/clixon/clixon_netconf_monitoring.h @@ -0,0 +1,46 @@ +/* + * + ***** BEGIN LICENSE BLOCK ***** + + Copyright (C) 2009-2019 Olof Hagsand + Copyright (C) 2020-2022 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 ***** + + * RFC 6022 YANG Module for NETCONF Monitoring + */ + +#ifndef _CLIXON_NETCONF_MONITORING_H_ +#define _CLIXON_NETCONF_MONITORING_H_ + +/* + * Prototypes + */ +int netconf_monitoring_state_get(clicon_handle h, yang_stmt *yspec, char *xpath, cvec *nsc, int brief, cxobj **xret); + +#endif /* _CLIXON_NETCONF_MONITORING_H_ */ diff --git a/lib/clixon/clixon_stream.h b/lib/clixon/clixon_stream.h index 796664b6..4334fceb 100644 --- a/lib/clixon/clixon_stream.h +++ b/lib/clixon/clixon_stream.h @@ -41,22 +41,6 @@ /* * Constants */ -/* Default STREAM namespace (see rfc5277 3.1) - * From RFC8040: - * The structure of the event data is based on the - * element definition in Section 4 of [RFC5277]. It MUST conform to the - * schema for the element in Section 4 of [RFC5277], - * using the XML namespace as defined in the XSD as follows: - * urn:ietf:params:xml:ns:netconf:notification:1.0 - * It is used everywhere in yangmodels, but not in openconfig - */ -#define NOTIFICATION_RFC5277_NAMESPACE "urn:ietf:params:xml:ns:netconf:notification:1.0" - -/* - * Then there is also this namespace that is only used in RFC5277 seems to be for "netconf" - * events. The usage seems wrong here,... - */ -#define EVENT_RFC5277_NAMESPACE "urn:ietf:params:xml:ns:netmod:notification" /* * Types diff --git a/lib/src/Makefile.in b/lib/src/Makefile.in index 0a847475..9959028f 100644 --- a/lib/src/Makefile.in +++ b/lib/src/Makefile.in @@ -82,7 +82,7 @@ SRC = clixon_sig.c clixon_uid.c clixon_log.c clixon_err.c clixon_event.c \ clixon_string.c clixon_regex.c clixon_handle.c clixon_file.c \ clixon_xml.c clixon_xml_io.c clixon_xml_sort.c clixon_xml_map.c clixon_xml_vec.c \ clixon_xml_bind.c clixon_json.c clixon_proc.c \ - clixon_yang.c clixon_yang_type.c clixon_yang_module.c \ + clixon_yang.c clixon_yang_type.c clixon_yang_module.c clixon_netconf_monitoring.c \ clixon_yang_parse_lib.c clixon_yang_sub_parse.c \ clixon_yang_cardinality.c clixon_xml_changelog.c clixon_xml_nsctx.c \ clixon_path.c clixon_validate.c clixon_validate_minmax.c \ diff --git a/lib/src/clixon_netconf_lib.c b/lib/src/clixon_netconf_lib.c index 3e094ed9..369e56b9 100644 --- a/lib/src/clixon_netconf_lib.c +++ b/lib/src/clixon_netconf_lib.c @@ -1245,7 +1245,7 @@ netconf_operation_failed_xml(cxobj **xret, return retval; } -/*! Create Netconf malformed-message error XML tree according to RFC 6241 App A +/*! Create Netconf malformed-message error cbuf according to RFC 6241 App A * * A message could not be handled because it failed to be parsed correctly. * For example, the message is not well-formed XML or it uses an @@ -1259,7 +1259,7 @@ int netconf_malformed_message(cbuf *cb, char *message) { - int retval = -1; + int retval = -1; cxobj *xret = NULL; if (netconf_malformed_message_xml(&xret, message) < 0) @@ -1332,6 +1332,35 @@ netconf_malformed_message_xml(cxobj **xret, return retval; } +/*! Create Netconf data-not-unique error message according to RFC 7950 15.1 + * + * A NETCONF operation would result in configuration data where a + * "unique" constraint is invalidated. + * @param[out] xret Error XML tree. Free with xml_free after use + * @param[in] x List element containing duplicate + * @param[in] cvk List of components in x that are non-unique + * @see RFC7950 Sec 15.1 + * @see netconf_data_not_unique_xml Same but returns XML tree + */ +int +netconf_data_not_unique(cbuf *cb, + cxobj *x, + cvec *cvk) +{ + int retval = -1; + cxobj *xret = NULL; + + if (netconf_data_not_unique_xml(&xret, x, cvk) < 0) + goto done; + if (clixon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) + goto done; + retval = 0; + done: + if (xret) + xml_free(xret); + return retval; +} + /*! Create Netconf data-not-unique error message according to RFC 7950 15.1 * * A NETCONF operation would result in configuration data where a @@ -1714,22 +1743,8 @@ netconf_content_int2str(netconf_content nr) return clicon_int2str(netconf_content_map, nr); } -/*! Create Netconf server hello. Single cap and defer individual to querying modules - - * @param[in] h Clicon handle - * @param[in] cb Msg buffer - * @param[in] session_id Id of client session - * Lots of dependencies here. regarding the hello protocol. - * RFC6241 NETCONF Protocol says: (8.1) - * MUST send a element containing a list of that peer's capabilities - * MUST send at least the base NETCONF capability, urn:ietf:params:netconf:base:1.1 - * MAY include capabilities for previous NETCONF versions - * A server MUST include a - * A client MUST NOT include a - * A server receiving MUST terminate the NETCONF session. - * A client not receiving MUST terminate w/o sending - * the example shows urn:ietf:params:netconf:capability:startup:1.0 - +/*! List capabilities + * * RFC5277 NETCONF Event Notifications * urn:ietf:params:netconf:capability:notification:1.0 is advertised during the capability exchange * @@ -1750,29 +1765,18 @@ netconf_content_int2str(netconf_content nr) * urn:ietf:params:netconf:capability:startup:1.0 (8.7) * urn:ietf:params:netconf:capability:xpath:1.0 (8.9) * urn:ietf:params:netconf:capability:notification:1.0 (RFC5277) - * - * @note the hello message is created bythe netconf application, not the - * backend, and backend may implement more modules - please consider if using - * library routines for detecting capabilities here. In contrast, yang module - * list (RFC7895) is processed by the backend. - * @note If you add new, remember to encode bodies if needed, see xml_chardata_encode() - * @note - * @see yang_modules_state_get - * @see netconf_module_load */ int -netconf_hello_server(clicon_handle h, - cbuf *cb, - uint32_t session_id) +netconf_capabilites(clicon_handle h, + cbuf *cb) { - int retval = -1; - char *module_set_id; - char *ietf_yang_library_revision; - char *encstr = NULL; + int retval = -1; + char *encstr = NULL; + char *ietf_yang_library_revision; yang_stmt *yspec = clicon_dbspec_yang(h); + char *module_set_id; module_set_id = clicon_option_str(h, "CLICON_MODULE_SET_ID"); - cprintf(cb, "", NETCONF_BASE_NAMESPACE); cprintf(cb, ""); if (clicon_option_int(h, "CLICON_NETCONF_BASE_CAPABILITY") > 0){ /* Each peer MUST send at least the base NETCONF capability, "urn:ietf:params:netconf:base:1.1" @@ -1810,20 +1814,59 @@ netconf_hello_server(clicon_handle h, xml_chardata_cbuf_append(cb, "urn:ietf:params:netconf:capability:with-defaults:1.0?basic-mode=explicit&also-supported=report-all,trim,report-all-tagged"); cprintf(cb, ""); /* RFC5277 Notification Capability */ - cprintf(cb, "urn:ietf:params:netconf:capability:notification:1.0"); + cprintf(cb, "%s", NETCONF_NOTIFICATION_CAPABILITY); + /* It is somewhat arbitrary why some features/capabilities are hardocded and why some are not * rfc 6241 Sec 8.4 confirmed-commit capabilities */ if (if_feature(yspec, "ietf-netconf", "confirmed-commit")) cprintf(cb, "urn:ietf:params:netconf:capability:confirmed-commit:1.1"); - cprintf(cb, ""); + retval = 0; + done: + if (encstr) + free(encstr); + return retval; +} + +/*! Create Netconf server hello. Single cap and defer individual to querying modules + * @param[in] h Clicon handle + * @param[in] cb Msg buffer + * @param[in] session_id Id of client session + * Lots of dependencies here. regarding the hello protocol. + * RFC6241 NETCONF Protocol says: (8.1) + * MUST send a element containing a list of that peer's capabilities + * MUST send at least the base NETCONF capability, urn:ietf:params:netconf:base:1.1 + * MAY include capabilities for previous NETCONF versions + * A server MUST include a + * A client MUST NOT include a + * A server receiving MUST terminate the NETCONF session. + * A client not receiving MUST terminate w/o sending + * the example shows urn:ietf:params:netconf:capability:startup:1.0 + * + * @note the hello message is created bythe netconf application, not the + * backend, and backend may implement more modules - please consider if using + * library routines for detecting capabilities here. In contrast, yang module + * list (RFC7895) is processed by the backend. + * @note If you add new, remember to encode bodies if needed, see xml_chardata_encode() + * @note + * @see yang_modules_state_get + * @see netconf_module_load + */ +int +netconf_hello_server(clicon_handle h, + cbuf *cb, + uint32_t session_id) +{ + int retval = -1; + + cprintf(cb, "", NETCONF_BASE_NAMESPACE); + if (netconf_capabilites(h, cb) < 0) + goto done; if (session_id) cprintf(cb, "%lu", (long unsigned int)session_id); cprintf(cb, ""); retval = 0; done: - if (encstr) - free(encstr); return retval; } diff --git a/lib/src/clixon_netconf_monitoring.c b/lib/src/clixon_netconf_monitoring.c new file mode 100644 index 00000000..b556d3ee --- /dev/null +++ b/lib/src/clixon_netconf_monitoring.c @@ -0,0 +1,179 @@ +/* + * + ***** BEGIN LICENSE BLOCK ***** + + Copyright (C) 2009-2019 Olof Hagsand + Copyright (C) 2020-2022 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 ***** + + * RFC 6022 YANG Module for NETCONF Monitoring + */ + +#ifdef HAVE_CONFIG_H +#include "clixon_config.h" /* generated by config & autoconf */ +#endif + +#include +#include +#include +#include +#include +#include + +/* cligen */ +#include + +/* clicon */ +#include "clixon_log.h" +#include "clixon_queue.h" +#include "clixon_hash.h" +#include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" +#include "clixon_xml_io.h" +#include "clixon_netconf_lib.h" +#include "clixon_options.h" +#include "clixon_err.h" +#include "clixon_netconf_monitoring.h" + +/*! + * @param[in] h Clicon handle + * @param[in] yspec Yang spec + * @param[in,out] cb CLIgen buffer + * @retval -1 Error (fatal) + * @retval 0 OK + */ +static int +yang_modules(clicon_handle h, + yang_stmt *yspec, + cbuf *cb) +{ + int retval = -1; + yang_stmt *ym = NULL; + yang_stmt *y1; + char *identifier; + char *revision; + char *dir; + + cprintf(cb, ""); + while ((ym = yn_each(yspec, ym)) != NULL) { + cprintf(cb, ""); + identifier = yang_argument_get(ym); + cprintf(cb, "%s", identifier); + cprintf(cb, ""); + revision = NULL; + if ((y1 = yang_find(ym, Y_REVISION, NULL)) != NULL){ + revision = yang_argument_get(y1); + cprintf(cb, "%s", revision); + } + cprintf(cb, ""); + cprintf(cb, "yang"); + if ((y1 = yang_find(ym, Y_NAMESPACE, NULL)) != NULL){ + cprintf(cb, "%s", yang_argument_get(y1)); + } + /* A local implementation may have other locations, how to configure? */ + cprintf(cb, "NETCONF"); + if ((dir = clicon_option_str(h,"CLICON_NETCONF_MONITORING_LOCATION")) != NULL){ + if (revision) + cprintf(cb, "%s/%s@%s.yang", dir, identifier, revision); + else + cprintf(cb, "%s/%s.yang", dir, identifier); + } + cprintf(cb, ""); + } + cprintf(cb, ""); + retval = 0; + //done: + return retval; +} + +/*! Get modules state according to RFC 7895 + * @param[in] h Clicon handle + * @param[in] yspec Yang spec + * @param[in] xpath XML Xpath + * @param[in] nsc XML Namespace context for xpath + * @param[in] brief Just name, revision and uri (no cache) + * @param[in,out] xret Existing XML tree, merge x into this + * @retval -1 Error (fatal) + * @retval 0 Statedata callback failed + * @retval 1 OK + * 2.1 + * netconf-state + * /capabilities + * /datastores + * /schemas + * /sessions + * /statistics + */ +int +netconf_monitoring_state_get(clicon_handle h, + yang_stmt *yspec, + char *xpath, + cvec *nsc, + int brief, + cxobj **xret) +{ + int retval = -1; + cbuf *cb = NULL; + + if ((cb = cbuf_new()) ==NULL){ + clicon_err(OE_XML, errno, "cbuf_new"); + goto done; + } + /* capabilities 2.1.1 */ + cprintf(cb, "", NETCONF_MONITORING_NAMESPACE); + if (netconf_capabilites(h, cb) < 0) + goto done; + + /* datastores 2.1.2 */ + // XXX + + /* schemas 2.1.3 */ + if (yang_modules(h, yspec, cb) < 0) + goto done; + + /* sessions 2.1.4 */ + // XXX + + /* statistics 2.1.5 */ + // XXX + + cprintf(cb, ""); + if (clixon_xml_parse_string(cbuf_get(cb), YB_MODULE, yspec, xret, NULL) < 0) + goto done; + retval = 1; + done: + clicon_debug(1, "%s %d", __FUNCTION__, retval); + if (cb) + cbuf_free(cb); + return retval; + // fail: + // retval = 0; + // goto done; +} diff --git a/lib/src/clixon_stream.c b/lib/src/clixon_stream.c index b141757c..fbff0211 100644 --- a/lib/src/clixon_stream.c +++ b/lib/src/clixon_stream.c @@ -80,6 +80,7 @@ #include "clixon_yang.h" #include "clixon_xml.h" #include "clixon_xml_io.h" +#include "clixon_netconf_lib.h" #include "clixon_options.h" #include "clixon_data.h" #include "clixon_xpath_ctx.h" @@ -585,7 +586,7 @@ stream_notify(clicon_handle h, } /* From RFC5277 */ cprintf(cb, "%s%s", - NOTIFICATION_RFC5277_NAMESPACE, timestr, str); + NETCONF_NOTIFICATION_NAMESPACE, timestr, str); if (clixon_xml_parse_string(cbuf_get(cb), YB_MODULE, yspec, &xev, NULL) < 0) goto done; if (xml_rootchild(xev, 0, &xev) < 0) @@ -649,7 +650,7 @@ stream_notify_xml(clicon_handle h, goto done; } cprintf(cb, "%sNULL", - NOTIFICATION_RFC5277_NAMESPACE, + NETCONF_NOTIFICATION_NAMESPACE, timestr); /* XXX str is always NULL */ if (clixon_xml_parse_string(cbuf_get(cb), YB_NONE, yspec, &xev, NULL) < 0) goto done; diff --git a/test/test_augment_state.sh b/test/test_augment_state.sh index db982650..0dc65175 100755 --- a/test/test_augment_state.sh +++ b/test/test_augment_state.sh @@ -28,6 +28,7 @@ cat < $cfg /usr/local/var/$APPNAME false false + false EOF diff --git a/test/test_leafref_state.sh b/test/test_leafref_state.sh index 5c5f8c12..b35597bd 100755 --- a/test/test_leafref_state.sh +++ b/test/test_leafref_state.sh @@ -41,6 +41,7 @@ cat < $cfg /usr/local/var/$APPNAME true false + false EOF diff --git a/test/test_netconf_monitoring.sh b/test/test_netconf_monitoring.sh new file mode 100755 index 00000000..297f92ae --- /dev/null +++ b/test/test_netconf_monitoring.sh @@ -0,0 +1,105 @@ +#!/usr/bin/env bash +# Test for RFC6022 YANG Module for NETCONF Monitoring +# See eg Examples: +# 4.1. Retrieving Schema List via Operation +# 4.2. Retrieving Schema Instances + +# 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_yang.xml +fyang=$dir/clixon-example@2022-01-01.yang + +cat < $cfg + + $cfg + ${YANG_INSTALLDIR} + $fyang + false + /usr/local/lib/$APPNAME/clispec + /usr/local/lib/$APPNAME/cli + $APPNAME + /usr/local/var/$APPNAME/$APPNAME.sock + /usr/local/lib/$APPNAME/backend + /usr/local/var/$APPNAME/$APPNAME.pidfile + $dir + true + +EOF + +cat < $fyang +module clixon-example{ + yang-version 1.1; + namespace "urn:example:clixon"; + prefix ex; + revision 2022-01-01; +} +EOF + +new "test params: -f $cfg" + +if [ $BE -ne 0 ]; then + new "kill old backend" + sudo clixon_backend -zf $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 "Retrieving all state via operation" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "urn:ietf:params:netconf:base:1.0urn:ietf:params:netconf:base:1.1.*.*" "" + +# 4.1. Retrieving Schema List via Operation +new "Retrieving Schema List via Operation" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "clixon-example2022-01-01yangurn:example:clixonNETCONF.*" + +# 4.2. Retrieving Schema Instances +# From 2b. bar, version 2008-06-1 in YANG format, via get-schema +new "Retrieving clixon-example schema instance using id, version, format" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2022-01-01yang" "module clixon-example {yang-version 1.1;namespace urn:example:clixon;prefix ex;revision 2022-01-01;}" + +new "Retrieving clixon-example schema instance using id, version only" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2022-01-01" "module clixon-example {yang-version 1.1;namespace urn:example:clixon;prefix ex;revision 2022-01-01;}" + +new "Retrieving clixon-example schema instance using id only" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example" "module clixon-example {yang-version 1.1;namespace urn:example:clixon;prefix ex;revision 2022-01-01;}" + +new "Retrieving ietf-inet-types schema" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "ietf-inet-types" "module ietf-inet-types {namespace urn:ietf:params:xml:ns:yang:ietf- +inet-types;prefix inet" + +# Negative tests +new "get-schema: no id" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "applicationmissing-elementidentifiererrorMandatory variable of get-schema in module ietf-netconf-monitoring" + +new "get-schema: non-existing schema" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "not-found" "protocolinvalid-valueerrorNo such schema" + +new "get-schema: non-existing format" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2022-01-01xsd" "protocolinvalid-valueerrorFormat not supported" + +new "get-schema: non-existing date" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2013-01-01yang" "protocolinvalid-valueerrorNo such schema" + +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 + +rm -rf $dir + +new "endtest" +endtest diff --git a/test/test_netconf_monitoring_location.sh b/test/test_netconf_monitoring_location.sh new file mode 100755 index 00000000..604b3526 --- /dev/null +++ b/test/test_netconf_monitoring_location.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env bash +# Test for RFC6022 YANG Module for NETCONF Monitoring +# Tests the location scheme by using the clixon http-data feature + +# 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_yang.xml +fyang=$dir/clixon-example@2022-01-01.yang + +# Proper test setup +datapath=/data +wdir=$dir/www + +RESTCONFIG=$(restconf_config none false $RCPROTO $enable) + +cat < $cfg + + $cfg + clixon-restconf:allow-auth-none + clixon-restconf:http-data + ${YANG_INSTALLDIR} + $fyang + false + /usr/local/lib/$APPNAME/clispec + /usr/local/lib/$APPNAME/cli + $APPNAME + /usr/local/var/$APPNAME/$APPNAME.sock + /usr/local/lib/$APPNAME/backend + /usr/local/var/$APPNAME/$APPNAME.pidfile + $dir + $datapath + $wdir + true + $RCPROTO://localhost/www + $RESTCONFIG + +EOF + +cat < $dir/clixon-example@2022-01-01.yang +module clixon-example{ + yang-version 1.1; + namespace "urn:example:clixon"; + prefix ex; + revision 2022-01-01; +} +EOF + +# Same via HTTP +cat < $dir/www/data/clixon-example@2022-01-01.yang +module clixon-example{ + yang-version 1.1; + namespace "urn:example:clixon"; + prefix ex; + revision 2022-01-01; +} +EOF + +new "test params: -f $cfg" + +if [ $BE -ne 0 ]; then + new "kill old backend" + sudo clixon_backend -zf $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 + +if [ $RC -ne 0 ]; then + new "kill old restconf daemon" + stop_restconf_pre + + new "start restconf daemon" + start_restconf -f $cfg +fi + +new "wait restconf" +wait_restconf $RCPROTO + +new "Retrieving Schema List via Operation" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "clixon-example2022-01-01yangurn:example:clixonNETCONF$RCPROTO://localhost/www/clixon-example@2022-01-01.yang.*" + +# 4.2. Retrieving Schema Instances +# From 2b. bar, version 2008-06-1 in YANG format, via get-schema +new "Get clixon-example schema via http location" +expectpart "$(curl $CURLOPTS -X GET -H 'Accept: text/html' $RCPROTO://localhost/www/clixon-example@2022-01-01.yang)" 0 "HTTP/$HVER 404" + +if [ $RC -ne 0 ]; then + new "Kill restconf daemon" + stop_restconf +fi + +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 + +rm -rf $dir + +new "endtest" +endtest diff --git a/test/test_netconf_monitoring_multiple.sh b/test/test_netconf_monitoring_multiple.sh new file mode 100755 index 00000000..79c7c7a2 --- /dev/null +++ b/test/test_netconf_monitoring_multiple.sh @@ -0,0 +1,109 @@ +#!/usr/bin/env bash +# Test for RFC6022 YANG Module for NETCONF Monitoring for multiple schemas +# Clixon supports multiple schemas only in the case of specific upgrade scenarios +# The following is made to check multipel schemas: +# 1. Two revisions of clixon-example.yang in MAIN_DIR +# 2. MODSTATE and CHECKOLD is true and STARTUP enabled + +# 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_yang.xml + +cat < $cfg + + $cfg + ietf-netconf:startup + ${YANG_INSTALLDIR} + $dir + false + /usr/local/lib/$APPNAME/clispec + /usr/local/lib/$APPNAME/cli + $APPNAME + /usr/local/var/$APPNAME/$APPNAME.sock + /usr/local/lib/$APPNAME/backend + /usr/local/var/$APPNAME/$APPNAME.pidfile + $dir + true + true + true + +EOF + +# Double yang specs to get two revisions +cat < $dir/clixon-example@2000-01-01.yang +module clixon-example{ + yang-version 1.1; + namespace "urn:example:clixon"; + prefix ex; + revision 2000-01-01; +} +EOF + +cat < $dir/clixon-example@2022-01-01.yang +module clixon-example{ + yang-version 1.1; + namespace "urn:example:clixon"; + prefix ex; + revision 2022-01-01; +} +EOF + +# Just to get multi +cat < $dir/startup_db +<${DATASTORE_TOP}> + + + default + 42 + + clixon-example + 2000-01-01 + urn:example:clixon + + + + +EOF + +new "test params: -f $cfg" + +if [ $BE -ne 0 ]; then + new "kill old backend" + sudo clixon_backend -zf $cfg + if [ $? -ne 0 ]; then + err + fi + new "start backend -s startup -f $cfg" + start_backend -s startup -f $cfg +fi + +new "wait backend" +wait_backend + +new "get-schema: multiple schemas, fail" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example" "applicationoperation-faileddata-not-uniqueerror" + +new "get-schema: multiple schemas 2000-01-01" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2000-01-01" "module clixon-example {yang-version 1.1;namespace urn:example:clixon;prefix ex;revision 2000-01-01;}" + +new "get-schema: multiple schemas 2022-01-01" +expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2022-01-01" "module clixon-example {yang-version 1.1;namespace urn:example:clixon;prefix ex;revision 2022-01-01;}" + +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 + +rm -rf $dir + +new "endtest" +endtest diff --git a/test/test_yang_anydata.sh b/test/test_yang_anydata.sh index 53ecbdae..be3b5fa9 100755 --- a/test/test_yang_anydata.sh +++ b/test/test_yang_anydata.sh @@ -146,6 +146,7 @@ function testrun() false $unknown false + false $F $RESTCONFIG diff --git a/yang/clixon/Makefile.in b/yang/clixon/Makefile.in index a39d498d..980a3298 100644 --- a/yang/clixon/Makefile.in +++ b/yang/clixon/Makefile.in @@ -42,7 +42,7 @@ datarootdir = @datarootdir@ YANG_INSTALLDIR = @YANG_INSTALLDIR@ # Note: mirror these to test/config.sh.in -YANGSPECS = clixon-config@2022-03-21.yang # 5.7 +YANGSPECS = clixon-config@2022-11-01.yang # 6.0 YANGSPECS += clixon-lib@2021-12-05.yang # 5.5 YANGSPECS += clixon-rfc5277@2008-07-01.yang YANGSPECS += clixon-xml-changelog@2019-03-21.yang diff --git a/yang/clixon/clixon-config@2022-11-01.yang b/yang/clixon/clixon-config@2022-11-01.yang new file mode 100644 index 00000000..63cb5528 --- /dev/null +++ b/yang/clixon/clixon-config@2022-11-01.yang @@ -0,0 +1,1188 @@ +module clixon-config { + yang-version 1.1; + namespace "http://clicon.org/config"; + prefix cc; + + import clixon-restconf { + prefix clrc; + } + import clixon-autocli { + prefix autocli; + } + organization + "Clicon / Clixon"; + + contact + "Olof Hagsand "; + + description + "Clixon configuration file + ***** BEGIN LICENSE BLOCK ***** + Copyright (C) 2009-2019 Olof Hagsand + Copyright (C) 2020-2022 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 2022-11-01 { + description + "Added option: + CLICON_NETCONF_MONITORING + CLICON_NETCONF_MONITORING_LOCATION + Released in Clixon 6.1"; + } + revision 2022-03-21 { + description + "Added option: + CLICON_RESTCONF_API_ROOT + CLICON_NETCONF_BASE_CAPABILITY + CLICON_HTTP_DATA_PATH + CLICON_HTTP_DATA_ROOT + CLICON_CLI_EXPAND_LEAFREF + Released in Clixon 5.7"; + } + revision 2022-02-11 { + description + "Added option: + CLICON_LOG_STRING_LIMIT + CLICON_YANG_LIBRARY + Changed default value: + CLICON_MODULE_LIBRARY_RFC7895 to false + Removed (previosly marked) obsolete options: + CLICON_RESTCONF_PATH + CLICON_RESTCONF_PRETTY + CLICON_CLI_GENMODEL + CLICON_CLI_GENMODEL_TYPE + CLICON_CLI_GENMODEL_COMPLETION + CLICON_CLI_AUTOCLI_EXCLUDE + CLICON_CLI_MODEL_TREENAME + Released in Clixon 5.6"; + } + revision 2021-12-05 { + description + "Imported + clixon-autocli.yang + Removed (previosly marked) obsolete options: + CLICON_YANG_LIST_CHECK + Marked as obsolete: + CLICON_CLI_GENMODEL (use autocli/enable-autocli instead) + CLICON_CLI_GENMODEL_TYPE (use autocli/list-keyword-default and compress rules instead) + CLICON_CLI_GENMODEL_COMPLETION (use autocli/completion-default instead) + CLICON_CLI_AUTOCLI_EXCLUDE (use autocli/module-default, rule/enable logic instead) + CLICON_CLI_MODEL_TREENAME (use constant AUTOCLI_TREENAME instead) + Released in Clixon 5.5"; + } + revision 2021-11-11 { + description + "Added option: + CLICON_PLUGIN_CALLBACK_CHECK + CLICON_YANG_AUGMENT_ACCEPT_BROKEN + Modified options: + CLICON_CLI_GENMODEL_TYPE: added OC_COMPRESS enum + CLICON_YANG_DIR: recursive search + Released in Clixon 5.4"; + } + revision 2021-07-11 { + description + "Added option: + CLICON_RESTCONF_HTTP2_PLAIN + Removed default value: + CLICON_RESTCONF_INSTALLDIR + Marked as obsolete: + CLICON_YANG_LIST_CHECK + Released in Clixon 5.3"; + } + revision 2021-05-20 { + description + "Added option: + CLICON_RESTCONF_USER + CLICON_RESTCONF_PRIVILEGES + CLICON_RESTCONF_INSTALLDIR + CLICON_RESTCONF_STARTUP_DONTUPDATE + CLICON_NETCONF_MESSAGE_ID_OPTIONAL + Released in Clixon 5.2"; + } + revision 2021-03-08 { + description + "Added option: + CLICON_NETCONF_HELLO_OPTIONAL + CLICON_CLI_AUTOCLI_EXCLUDE + CLICON_XMLDB_UPGRADE_CHECKOLD + Released in Clixon 5.1"; + } + revision 2020-12-30 { + description + "Added option: + CLICON_ANONYMOUS_USER + Removed obsolete options: + CLICON_RESTCONF_IPV4_ADDR + CLICON_RESTCONF_IPV6_ADDR + CLICON_RESTCONF_HTTP_PORT + CLICON_RESTCONF_HTTPS_PORT + CLICON_SSL_SERVER_CERT + CLICON_SSL_SERVER_KEY + CLICON_SSL_CA_CERT + CLICON_TRANSACTION_MOD + Marked as obsolete and moved to clixon-restconf.yang: + CLICON_RESTCONF_PATH + CLICON_RESTCONF_PRETTY"; + } + revision 2020-11-03 { + description + "Added CLICON_BACKEND_RESTCONF_PROCESS + Copied to clixon-restconf.yang and marked as obsolete: + CLICON_RESTCONF_IPV4_ADDR + CLICON_RESTCONF_IPV6_ADDR + CLICON_RESTCONF_HTTP_PORT + CLICON_RESTCONF_HTTPS_PORT + CLICON_SSL_SERVER_CERT + CLICON_SSL_SERVER_KEY + CLICON_SSL_CA_CERT + Removed obsolete option CLICON_TRANSACTION_MOD"; + } + revision 2020-10-01 { + description + "Added: CLICON_CONFIGDIR."; + } + revision 2020-08-17 { + description + "Added: CLICON_RESTCONF_IPV4_ADDR, CLICON_RESTCONF_IPV6_ADDR, + CLICON_RESTCONF_HTTP_PORT, CLICON_RESTCONF_HTTPS_PORT + CLICON_NAMESPACE_NETCONF_DEFAULT, + CLICON_CLI_HELPSTRING_TRUNCATE, CLICON_CLI_HELPSTRING_LINES"; + } + revision 2020-06-17 { + description + "Added: CLICON_CLI_LINES_DEFAULT + Added enum HIDE to CLICON_CLI_GENMODEL + Added CLICON_SSL_SERVER_CERT, CLICON_SSL_SERVER_KEY, CLICON_SSL_CA_CERT + Added CLICON_NACM_DISABLED_ON_EMPTY + Removed default valude of CLICON_NACM_RECOVERY_USER"; + } + revision 2020-04-23 { + description + "Added: CLICON_YANG_UNKNOWN_ANYDATA to treat unknown XML (wrt YANG) as anydata. + Deleted: xml-stats non-config data (replaced by rpc stats in clixon-lib.yang)"; + } + revision 2020-02-22 { + description + "Added: search index extension, + Added: clixon-stats state for clixon XML and memory statistics. + Added: CLICON_CLI_BUF_START and CLICON_CLI_BUF_THRESHOLD for quadratic and linear + growth of CLIgen buffers (cbuf:s) + Added: CLICON_VALIDATE_STATE_XML for controling validation of user state XML + Added: CLICON_CLICON_YANG_LIST_CHECK to skip list key checks"; + } + revision 2019-09-11 { + description + "Added: CLICON_BACKEND_USER: drop of privileges to user, + CLICON_BACKEND_PRIVILEGES: how to drop privileges + CLICON_NACM_CREDENTIALS: If and how to check backend sock privileges with NACM + CLICON_NACM_RECOVERY_USER: Name of NACM recovery user."; + } + revision 2019-06-05 { + description + "Added: CLICON_YANG_REGEXP, CLICON_CLI_TAB_MODE, + CLICON_CLI_HIST_FILE, CLICON_CLI_HIST_SIZE, + CLICON_XML_CHANGELOG, CLICON_XML_CHANGELOG_FILE; + Renamed CLICON_XMLDB_CACHE to CLICON_DATASTORE_CACHE (changed type) + Deleted: CLICON_XMLDB_PLUGIN, CLICON_USE_STARTUP_CONFIG"; + } + revision 2019-03-05{ + description + "Changed URN. Changed top-level symbol to clixon-config. + Released in Clixon 3.10"; + } + revision 2019-02-06 { + description + "Released in Clixon 3.9"; + } + revision 2018-10-21 { + description + "Released in Clixon 3.8"; + } + extension search_index { + description "This list argument acts as a search index using optimized binary search. + "; + } + typedef startup_mode{ + description + "Which method to boot/start clicon backend. + The methods differ in how they reach a running state + Which source database to commit from, if any."; + type enumeration{ + enum none{ + description + "Do not touch running state + Typically after crash when running state and db are synched"; + } + enum init{ + description + "Initialize running state. + Start with a completely clean running state"; + } + enum running{ + description + "Commit running db configuration into running state + After reboot if a persistent running db exists"; + } + enum startup{ + description + "Commit startup configuration into running state + After reboot when no persistent running db exists"; + } + enum running-startup{ + description + "First try running db, if it is empty try startup db."; + } + } + } + typedef datastore_format{ + description + "Datastore format."; + type enumeration{ + enum xml{ + description + "Save and load xmldb as XML + More specifically, such a file looks like: ... provided + DATASTORE_TOP_SYMBOL is 'config'"; + } + enum json{ + description "Save and load xmldb as JSON"; + } + } + } + typedef datastore_cache{ + description + "XML configuration, ie running/candididate/ datastore cache behaviour."; + type enumeration{ + enum nocache{ + description "No cache always work directly with file"; + } + enum cache{ + description "Use in-memory cache. + Make copies when accessing internally."; + } + enum cache-zerocopy{ + description "Use in-memory cache and dont copy. + Fastest but opens up for callbacks changing cache."; + } + } + } + typedef nacm_mode{ + description + "Mode of RFC8341 Network Configuration Access Control Model. + It is unclear from the RFC whether NACM rules are internal + in a configuration (ie embedded in regular config) or external/OOB + in s separate, specific NACM-config"; + type enumeration{ + enum disabled{ + description "NACM is disabled"; + } + enum internal{ + description "NACM is enabled and available in the regular config"; + } + enum external{ + description "NACM is enabled and available in a separate config"; + } + } + } + typedef regexp_mode{ + description + "The regular expression engine Clixon uses in its validation of + Yang patterns, and in the CLI. + Yang RFC 7950 stipulates XSD XML Schema regexps + according to W3 CXML Schema Part 2: Datatypes Second Edition, + see http://www.w3.org/TR/2004/REC-xmlschema-2-20041028#regexs"; + type enumeration{ + enum posix { + description + "Translate XSD XML Schema regexp:s to Posix regexp. This is + not a complete translation, but can be considered good-enough + for Yang use-cases as defined by openconfig and yang-models + for example."; + } + enum libxml2 { + description + "Use libxml2 XSD XML Schema regexp engine. This is a complete + XSD regexp engine.. + Requires libxml2 to be available at configure time + (HAVE_LIBXML2 should be set)"; + } + } + } + typedef priv_mode{ + description + "Privilege mode, used for dropping (or not) privileges to a non-provileged + user after initialization"; + type enumeration{ + enum none { + description + "Make no drop/change in privileges."; + } + enum drop_perm { + description + "After initialization, drop privileges permanently to a uid"; + } + enum drop_temp { + description + "After initialization, drop privileges temporarily to a euid"; + } + } + } + typedef nacm_cred_mode{ + description + "How NACM user should be matched with unix socket peer credentials. + This means nacm user must match socket peer user accessing the + backend socket. For IP sockets only mode none makes sense."; + type enumeration{ + enum none { + description + "Dont match NACM user to any user credentials. Any user can pose + as any other user. Set this for IP sockets, or dont use NACM."; + } + enum exact { + description + "Exact match between NACM user and unix socket peer user."; + } + enum except { + description + "Exact match between NACM user and unix socket peer user, except + for root and www user (restconf)."; + } + } + } + typedef socket_address_family { + description "Address family for internal socket"; + type enumeration{ + enum UNIX { + description "Unix domain socket"; + } + enum IPv4 { + description "IPv4"; + } + enum IPv6 { + description "IPv6"; + } + } + } + container clixon-config { + container restconf { + uses clrc:clixon-restconf; + } + container autocli { + uses autocli:clixon-autocli; + } + leaf-list CLICON_FEATURE { + description + "Supported features as used by YANG feature/if-feature + value is: :, where and + are either names, or the special character '*'. + *:* means enable all features + :* means enable all features in the specified module + *: means enable the specific feature in all modules"; + type string; + } + leaf-list CLICON_YANG_DIR { + ordered-by user; + type string; + description + "Yang directory path for finding module and submodule files. + A list of these options should be in the configuration. + When loading a Yang module, Clixon searches this list in the order + they appear. + Note since Clixon 5.4 such a directory is searched recursively, not just the + directory itself. + Ensure that YANG_INSTALLDIR (default + /usr/local/share/clixon) is present in the path"; + } + leaf CLICON_CONFIGFILE{ + type string; + description + "Location of the main configuration-file. + Default is CLIXON_DEFAULT_CONFIG=/usr/local/etc/clicon.xml set in configure. + Note that due to bootstrapping, this value is not actually read from file + and therefore a default value would be meaningless."; + } + leaf CLICON_CONFIGDIR{ + type string; + description + "Location of directory of extra configuration files. + If not given, only main configfile is read. + If given, and if the directory exists, all files in this directory will be loaded + AFTER the main config file (CLICON_CONFIGFILE) in the following way: + - leaf values are overwritten + - leaf-list values are appended + The files in this directory will be loaded alphabetically. + If the dir is given but does not exist will result in an error. + You can override file setting with -E command-line option. + Note that due to bootstraping this value is only meaningful in the main config file"; + } + leaf CLICON_YANG_MAIN_FILE { + type string; + description + "If specified load a yang module in a specific absolute filename. + This corresponds to the -y command-line option in most CLixon + programs."; + } + leaf CLICON_YANG_MAIN_DIR { + type string; + description + "If given, load all modules in this directory (all .yang files) + See also CLICON_YANG_DIR which specifies a path of dirs"; + } + leaf CLICON_YANG_MODULE_MAIN { + type string; + description + "Option used to construct initial yang file: + [@]"; + } + leaf CLICON_YANG_MODULE_REVISION { + type string; + description + "Option used to construct initial yang file: + [@]. + Used together with CLICON_YANG_MODULE_MAIN"; + } + leaf CLICON_YANG_REGEXP { + type regexp_mode; + default posix; + description + "The regular expression engine Clixon uses in its validation of + Yang patterns, and in the CLI. + There is a 'good-enough' posix translation mode and a complete + libxml2 mode"; + } + leaf CLICON_YANG_UNKNOWN_ANYDATA{ + type boolean; + default false; + description + "Treat unknown XML/JSON nodes as anydata when loading from startup db. + This does not apply to namespaces, which means a top-level node: xxx:yyy + is accepted only if yyy is unknown, not xxx. + Note that this option has several caveats which needs to be fixed. Please + use with care. + The primary issue is that the unknown->anydata handling is not restricted to + only loading from startup but may occur in other circumstances as well. This + means that sanity checks of erroneous XML/JSON may not be properly signalled. + Note this is similar to what happens to YANG nodes that are disabled by a false + if-feature statement."; + } + leaf CLICON_BACKEND_DIR { + type string; + description + "Location of backend .so plugins. Load all .so + plugins in this dir as backend plugins"; + } + leaf CLICON_BACKEND_REGEXP { + type string; + description + "Regexp of matching backend plugins in CLICON_BACKEND_DIR"; + default "(.so)$"; + } + leaf CLICON_NETCONF_DIR{ + type string; + description "Location of netconf (frontend) .so plugins"; + } + leaf CLICON_NETCONF_HELLO_OPTIONAL { + type boolean; + default false; + description + "This option relates to RFC 6241 Sec 8.1 Capabilies Exchange where it says: + When the NETCONF session is opened, each peer (both client and server) MUST + send a element... + If true, an RPC can be processed directly with no preceeding hello message. + This is legacy clixon but invalid according to the RFC. + If false, NETCONF hello messages are mandatory before any RPC can be processed. + That is, if clixon receives an rpc with no previous hello message, an error + is returned, which conforms to the RFC. + Note this applies only to external NETCONF, not the internal (IPC) netconf"; + } + leaf CLICON_NETCONF_MESSAGE_ID_OPTIONAL { + type boolean; + default false; + description + "This option relates to RFC 6241 Sec 4.1 Element + The element has a mandatory attribute 'message-id', which is a + string chosen by the sender of the RPC. + If true, an RPC can be sent without a message-id. + This applies to both external NETCONF and internal (IPC) netconf"; + } + leaf CLICON_NETCONF_BASE_CAPABILITY { + type int32; + default 1; + description + "This option relates to RFC6241 Sec 8.1 capabilities exchange. + This number is the highest netconf base capability announced during + the hello protocol. + Specifically, If the option number is 0, only 'urn:ietf:params:netconf:base:1.0' + is announced, if it is 1, both 'urn:ietf:params:netconf:base:1.0' and + 'urn:ietf:params:netconf:base:1.1' are announced. + Base capability '1' includes switching over to chunked framing as defined in + RFC6242 for example. + This only applies to the external NETCONF"; + } + leaf CLICON_RESTCONF_API_ROOT { + type string; + default "/restconf"; + description + "The RESTCONF API root path + See RFC 8040 Sec 1.16 and 3.1"; + } + leaf CLICON_RESTCONF_DIR { + type string; + description + "Location of restconf (frontend) .so plugins. Load all .so + plugins in this dir as restconf code plugins + Note: This cannot be moved to clixon-restconf.yang because it is needed + early in the bootstrapping phase, before clixon-restconf.yang config may + be loaded."; + } + leaf CLICON_RESTCONF_INSTALLDIR { + type string; + description + "If set, path to dir of clixon-restconf daemon binary as used by backend if + started internally (run-time). + If this path is not set, clixon_restconf will be looked for according to + configured installdir: $(sbindir) (install-time) + Since programs can be moved around at install/cross-compile time the installed + dir may be difficult to know at install time, which is the reason why + CLICON_RESTCONF_INSTALLDIR exists, in order to override the Makefile + installdir. + Note on the installdir, DESTDIR is not included since according to man pages: + by specifying DESTDIR should not change the operation of the software in + any way, so its value should not be included in any file contents. "; + } + leaf CLICON_RESTCONF_STARTUP_DONTUPDATE { + type boolean; + default false; + description + "According to RFC 8040 Sec 1.4: + If the NETCONF server supports :startup, the RESTCONF server MUST automatically + update the [...] startup configuration [...] as a consequence of a RESTCONF + edit operation. + Setting this option disables this behaviour, ie the startup configuration is NOT + automatically updated. + If this option is false, the startup is autoamtically updated following the RFC"; + } + leaf CLICON_RESTCONF_USER { + type string; + description + "Run clixon_daemon as this user + When drop privileges is used, the daemon will drop privileges to this user. + In pre-5.2 code this was configured as compile-time constant WWWUSER with + default value www-data + See also CLICON_PRIVILEGES setting"; + default www-data; + } + leaf CLICON_RESTCONF_PRIVILEGES { + type priv_mode; + default drop_perm; + description + "Restconf privileges mode. + If drop_perm or drop_temp then drop privileges to CLICON_RESTCONF_USER. + If the platform does not support getresuid and accompanying functions, the mode + must be set to 'none'. + "; + } + leaf CLICON_RESTCONF_HTTP2_PLAIN { + type boolean; + default false; + description + "Applies to plain (non-tls) http/2 ie when clixon is configured with --enable-nghttp2 + If false, disable direct and upgrade for plain(non-tls) HTTP/2. + If true, allow direct and upgrade for plain(non-tls) HTTP/2. + It may especially useful to disable in http/1 + http/2 mode to avoid the complex + upgrade/switch from http/1 to http/2. + Note this also disables plain http/2 in prior-knowledge, that is, in http/2-only mode. + HTTP/2 in https(TLS) is unaffected"; + } + leaf CLICON_HTTP_DATA_PATH { + if-feature "clrc:http-data"; + default "/"; + type string; + description + "URI match for http-data serving files specified by CLICON_HTTP_DATA_ROOT. + Must start with / (example: /) + Restconf paths at /restconf is always done before data (or streams) + The PATH is appended to CLICON_HTTP_DATA_ROOT to find a file. + Example, if PATH is /data and ROOT is /www, and a GET /index.html, the + corresponding file is '/www/data/index.html' + Both feature clixon-restconf:http-data and restconf/enable-http-data + must be enabled for this match to occur."; + } + leaf CLICON_HTTP_DATA_ROOT{ + if-feature "clrc:http-data"; + type string; + default "/var/www"; + description + "Location in file system where http-data files are looked for. + Soft links, '..', '~' etc are not followed. + See also CLICON_HTTP_DATA_PATH + Both feature clixon-restconf:http-data and restconf/enable-http-data + must be enabled for this match to occur."; + } + leaf CLICON_CLI_DIR { + type string; + description + "Directory containing frontend cli loadable plugins. Load all .so + plugins in this directory as CLI object plugins"; + } + leaf CLICON_CLISPEC_DIR { + type string; + description + "Directory containing frontend cligen spec files. Load all .cli + files in this directory as CLI specification files. + See also CLICON_CLISPEC_FILE."; + } + leaf CLICON_CLISPEC_FILE { + type string; + description + "Specific frontend cligen spec file as alternative or complement + to CLICON_CLISPEC_DIR. Also available as -c in clixon_cli."; + } + leaf CLICON_CLI_MODE { + type string; + default "base"; + description + "Startup CLI mode. This should match a CLICON_MODE variable set in + one of the clispec files"; + } + leaf CLICON_CLI_VARONLY { + type int32; + default 1; + description + "Dont include keys in cvec in cli vars callbacks, + ie a & k in 'a k ' ignored + (consider boolean)"; + } + leaf CLICON_CLI_LINESCROLLING { + type int32; + default 1; + description + "Set to 0 if you want CLI to wrap to next line. + Set to 1 if you want CLI to scroll sideways when approaching + right margin"; + } + leaf CLICON_CLI_LINES_DEFAULT { + type int32; + default 24; + description + "Set to number of CLI terminal rows for 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 + ioctl calls. + In other words, this setting is used ONLY on raw terminals such as serial + consoles."; + } + leaf CLICON_CLI_TAB_MODE { + type int8; + default 0; + description + "Set CLI tab mode. This is a bitfield of three bits: + bit 1: 0: shows short info of available commands + 1: has same output as , ie line per command + bit 2: 0: On , select a command over a if both exist + 1: Commands and vars have same preference. + bit 3: 0: On , never complete more than one level per + 1: Complete all levels at once if possible. + "; + } + leaf CLICON_CLI_UTF8 { + type int8; + default 0; + description + "Set to 1 to enable CLIgen UTF-8 experimental mode. + Note that this feature is EXPERIMENTAL and may not properly handle + scrolling, control characters, etc + (consider boolean)"; + } + leaf CLICON_CLI_HIST_FILE { + type string; + default "~/.clixon_cli_history"; + description + "Name of CLI history file. If not given, history is not saved. + The number of lines is saved is given by CLICON_CLI_HIST_SIZE."; + } + leaf CLICON_CLI_HIST_SIZE { + type int32; + default 300; + description + "Number of lines to save in CLI history. + Also, if CLICON_CLI_HIST_FILE is set, also the size in lines + of the saved history."; + } + leaf CLICON_CLI_BUF_START { + type uint32; + default 256; + description + "CLIgen buffer (cbuf) initial size. + When the buffer needs to grow, the allocation grows quadratic up to a threshold + after which linear growth continues. + See CLICON_CLI_BUF_THRESHOLD"; + } + leaf CLICON_CLI_BUF_THRESHOLD { + type uint32; + default 65536; + description + "CLIgen buffer (cbuf) threshold size. + When the buffer exceeds the threshold, the allocation grows by adding the threshold + value to the buffer length. + If 0, the growth continues with quadratic growth. + See CLICON_CLI_BUF_THRESHOLD"; + } + leaf CLICON_CLI_HELPSTRING_TRUNCATE { + type boolean; + default false; + description + "CLIgen help string on query (?): Truncate help string on right margin mode + This only applies if you have long help strings, such as when generating them from a + spec such as the autocli"; + } + leaf CLICON_CLI_HELPSTRING_LINES { + type int32; + default 0; + description + "CLIgen help string on query (?) limit of number of lines to show, 0 means unlimited. + This only applies if you have multi-line help strings, such as when generating + from a spec, such as in the autocli."; + } + leaf CLICON_CLI_EXPAND_LEAFREF { + type boolean; + default false; + description + "If true, then CLI expansion of leafrefs (in expand_dbvar) are done using the + source values, not the references. + This applies to the autocli but also in a handcrafted CLI if expand_dbvar is used. + Example, assume ifref with leafref pointing to source if values: + abc + b + If true, expansion will suggest a, b, c (source if values) + If false, expansion will suggest b (destination ifref values) + While setting this value makes sense for adding new values, it makes less sense for + deleting."; + } + leaf CLICON_SOCK_FAMILY { + type socket_address_family; + default UNIX; + description + "Address family for communicating with clixon_backend with one of: + Note IPv6 not implemented. + Note that UNIX socket makes credential check as follows: + (1) client needs rw access to the socket + (2) NACM credentials can be checked according to CLICON_NACM_CREDENTIALS + Warning: Only UNIX (not IPv4) sockets have credential mechanism. + "; + } + leaf CLICON_SOCK { + type string; + mandatory true; + description + "String description of Clixon Internal (IPC) socket that connects a clixon + client to the clixon backend. This string is dependent on family. + If CLICON_SOCK_FAMILY is: + - UNIX: The value is a Unix socket path + - IPv4: IPv4 address string + - IPv6: IPv6 address string (NYI)"; + } + leaf CLICON_SOCK_PORT { + type int32; + default 4535; + description + "Inet socket port for communicating with clixon_backend + (only IPv4|IPv6)"; + } + leaf CLICON_SOCK_GROUP { + type string; + default "clicon"; + description + "Group membership to access clixon_backend unix socket and gid for + deamon"; + } + leaf CLICON_BACKEND_USER { + type string; + description + "User name for backend (both foreground and daemonized). + If you set this value the backend if started as root will lower + the privileges after initialization. + The ownership of files created by the backend will also be set to this + user (eg datastores). + It also sets the backend unix socket owner to this user, but its group + is set by CLICON_SOCK_GROUP. + See also CLICON_BACKEND_PRIVILEGES setting"; + } + leaf CLICON_BACKEND_PRIVILEGES { + type priv_mode; + default none; + description + "Backend privileges mode. + If CLICON_BACKEND_USER user is set, mode can be set to drop_perm or + drop_temp."; + } + leaf CLICON_BACKEND_PIDFILE { + type string; + mandatory true; + description "Process-id file of backend daemon"; + } + leaf CLICON_BACKEND_RESTCONF_PROCESS { + type boolean; + default false; + description + "If set, enable process-control of restconf daemon, ie start/stop restconf + daemon internally from backend daemon. + Also, if set, restconf daemon queries backend for its config + if not set, restconf daemon reads its config from main config file + It uses clixon-restconf.yang for config and clixon-lib.yang for RPC + Process control of restconf daemon is as follows: + - on RPC start, if enable is true, start the service, if false, error or ignore it + - on RPC stop, stop the service + - on backend start make the state as configured + - on enable change, make the state as configured + Disable if you start the restconf daemon by other means."; + } + leaf CLICON_AUTOCOMMIT { + type int32; + default 0; + description + "Set if all configuration changes are committed automatically + on every edit change. Explicit commit commands unnecessary + If confirm-commit, follow RESTCONF semantics: commit ephemeral but fail on + persistent confirming commit. + (consider boolean)"; + } + leaf CLICON_XMLDB_DIR { + type string; + mandatory true; + description + "Directory where \"running\", \"candidate\" and \"startup\" are placed."; + } + leaf CLICON_DATASTORE_CACHE { + type datastore_cache; + default cache; + description + "Clixon datastore cache behaviour. There are three values: no cache, + cache with copy, or cache without copy. + Note: 'cache' is default value and supported with regressions etc. + Others are experimental (in Clixon 5.5)"; + } + leaf CLICON_XMLDB_FORMAT { + type datastore_format; + default xml; + description "XMLDB datastore format."; + } + leaf CLICON_XMLDB_PRETTY { + type boolean; + default true; + description + "XMLDB datastore pretty print. + If set, insert spaces and line-feeds making the XML/JSON human + readable. If not set, make the XML/JSON more compact."; + } + leaf CLICON_XMLDB_MODSTATE { + type boolean; + default false; + description + "If set, tag datastores with RFC 8525 YANG Module Library + info. When loaded at startup, a check is made if the system + yang modules match. + See also CLICON_MODULE_LIBRARY_RFC7895"; + } + leaf CLICON_XMLDB_UPGRADE_CHECKOLD { + type boolean; + default true; + description + "Controls behavior of check of startup in upgrade scenarios. + If set, yang bind and check datastore syntax against the old Yang. + The old yang must be accessible via YANG_DIR. + Will fail startup if old yang not found or if old config does not match. + If not set, no yang check of old config is made until it is upgraded to new yang."; + } + leaf CLICON_XML_CHANGELOG { + type boolean; + default false; + description "If true enable automatic upgrade using yang clixon + changelog."; + } + leaf CLICON_XML_CHANGELOG_FILE { + type string; + description "Name of file with module revision changelog. + If CLICON_XML_CHANGELOG is true, Clixon + reads the module changelog from this file."; + } + leaf CLICON_VALIDATE_STATE_XML { + type boolean; + default false; + description + "Validate user state callback content. + Users may register state callbacks using ca_statedata callback + When set, the XML returned from the callback is validated after merging with + the running db. If it fails, an internal error is returned to the originating + user. + If the option is not set, the XML returned by the user is not validated. + Note that enabling currently causes a large performance overhead for large + lists, therefore it is recommended to enable it during development and debugging + but disable it in production, until this has been resolved."; + } + leaf CLICON_PLUGIN_CALLBACK_CHECK { + type int32; + default 0; + description + "Debug option. + If >0, make a check of resources before and after each plugin callback code + to check if the plugin violated resources. + This is primarily intended for development and debugging but may also be enabled + in a running system. + If 1, errors will be logged to syslog as WARNINGs. + If 2, the program will abort using assert() on first error + The checks are currently made by plugin_context_check() and include: + - termios settings + - signal vectors + The checks will be made for all callbacks as defined in struct clixon_plugin_api + as well as the CLIgen callbacks. + See https://clixon-docs.readthedocs.io/en/latest/backend.html#plugin-callback-guidelines"; + } + leaf CLICON_YANG_AUGMENT_ACCEPT_BROKEN { + type boolean; + default false; + description + "Debug option. If enabled, accept broken augments on the form: + augment { ... } + where is an XPath which MUST be an existing node but for many + yangmodels do not. + There are several cases why this may be the case: + - syntax errors, + - features that need to be enabled + - wrong XPaths, etc + This option should be enabled only for passing some testcases it should + normally never be enabled in system YANGs that are used in a system."; + } + leaf CLICON_NAMESPACE_NETCONF_DEFAULT { + type boolean; + default false; + description + "Undefine if you want to ensure strict namespace assignment on all netconf + and XML statements according to the standard RFC 6241. + If defined, top-level rpc calls need not have namespaces (eg using xmlns=) + since the default NETCONF namespace will be assumed. (This is not standard). + See rfc6241 3.1: urn:ietf:params:xml:ns:netconf:base:1.0."; + + } + leaf CLICON_STARTUP_MODE { + type startup_mode; + description "Which method to boot/start clicon backend"; + } + leaf CLICON_ANONYMOUS_USER { + type string; + default "anonymous"; + description + "Name of anonymous user. + The current only case where such a user is used is in RESTCONF authentication when + auth-type=none and no known user is known."; + } + leaf CLICON_NACM_MODE { + type nacm_mode; + default disabled; + description + "RFC8341 network access configuration control model (NACM) mode: disabled, + in regular (internal) config or separate external file given by CLICON_NACM_FILE"; + } + leaf CLICON_NACM_FILE { + type string; + description + "RFC8341 NACM external configuration file (if CLIXON_NACM_MODE is external)"; + } + leaf CLICON_NACM_CREDENTIALS { + type nacm_cred_mode; + default except; + description + "Verify nacm user credentials with unix socket peer cred. + This means nacm user must match unix user accessing the backend + socket."; + } + leaf CLICON_NACM_RECOVERY_USER { + type string; + description + "RFC8341 defines a 'recovery session' as outside its scope. Clixon + defines this user as having special admin rights to exempt from + all access control enforcements. + Note setting of CLICON_NACM_CREDENTIALS is important, if set to + exact for example, this user must exist and be used, otherwise + another user (such as root or www) can pose as the recovery user."; + } + leaf CLICON_NACM_DISABLED_ON_EMPTY { + type boolean; + default false; + description + "RFC 8341 and ietf-netconf-acm@2018-02-14.yang defines enable-nacm as true by + default. Since also write-default is deny by default it leads to that empty + configs can not be edited. + This means that a startup config must always have a NACM configuration or + that the NACM recovery session is used to edit an empty config. + If this option is set, Clixon disables NACM if a datastore does NOT contain a + NACM config on load."; + } + leaf CLICON_YANG_LIBRARY { + type boolean; + default true; + description + "Enable YANG library support as state data according to RFC8525. + If enabled, module info will appear when doing netconf get or + restconf GET. + The module state data is on the form: + ... + If CLICON_MODULE_LIBRARY_RFC7895 is set (as well), the module state uses RFC7895 + instead where the modile state is on the form: + ... + See also CLICON_XMLDB_MODSTATE where the module state info is used to tag datastores + with module information."; + } + leaf CLICON_MODULE_LIBRARY_RFC7895 { + type boolean; + default false; + description + "Enable RFC 7895 YANG Module library support as state data, instead of RFC8525. + Note CLICON_YANG_LIBRARY must be enabled for this to have effect. + See also CLICON_YANG_LIBRARY and CLICON_MODULE_SET_ID"; + status obsolete; + } + + leaf CLICON_MODULE_SET_ID { + type string; + default "0"; + description + "Only if CLICON_YANG_LIBRARY enabled. + Contains a server-specific identifier representing the current set of modules + and submodules. The server MUST change the value of this leaf if the + information represented by the 'module' list instances has changed. + The /yang-library/content-id state-data leaf is set with this value + If CLICON_MODULE_LIBRARY_RFC7895 is enabled, it sets the modules-state/module-set-id + instead"; + } + leaf CLICON_NETCONF_MONITORING { + type boolean; + default true; + description + "Enable Netconf monitoring support as state data according to RFC6022. + If enabled, netconf monitoring info will appear when doing netconf get or + restconf GET."; + } + leaf CLICON_NETCONF_MONITORING_LOCATION { + type string; + description + "Extra Netconf monitoring location directory where schemas can be retrieved + apart from NETCONF. + Only if CLICON_NETCONF_MONITORING"; + } + leaf CLICON_STREAM_DISCOVERY_RFC5277 { + type boolean; + default false; + description + "Enable event stream discovery as described in RFC 5277 + sections 3.2. If enabled, available streams will appear + when doing netconf get or restconf GET"; + } + leaf CLICON_STREAM_DISCOVERY_RFC8040 { + type boolean; + default false; + description + "Enable monitoring information for the RESTCONF protocol from RFC 8040 as specified + in module ietf-restconf-monitoring.yang + Note that the name of this option is misleading, the monitoring module defines state + for both capabilities and streams, not only streams which the name indicates. + Also, consider changinf default to true."; + } + leaf CLICON_STREAM_PATH { + type string; + default "streams"; + description + "Stream path appended to CLICON_STREAM_URL to form + stream subscription URL. + See CLICON_RESTCONF_API_ROOT and CLICON_HTTP_DATA_ROOT + Should be changed to include '/' "; + } + leaf CLICON_STREAM_URL { + type string; + default "https://localhost"; + description "Prepend this to CLICON_STREAM_PATH to form URL. + See RFC 8040 Sec 9.3 location leaf: + 'Contains a URL that represents the entry point for + establishing notification delivery via server-sent events.' + Prepend this constant to name of stream. + Example: https://localhost/streams/NETCONF. Note this is the + external URL, not local behind a reverse-proxy. + Note that -s command-line option to clixon_restconf + should correspond to last path of url (eg 'streams')"; + } + leaf CLICON_STREAM_PUB { + type string; + description "For stream publish using eg nchan, the base address + to publish to. Example value: http://localhost/pub + Example: stream NETCONF would then be pushed to + http://localhost/pub/NETCONF. + Note this may be a local/provate URL behind reverse-proxy. + If not given, do NOT enable stream publishing using NCHAN."; + } + leaf CLICON_STREAM_RETENTION { + type uint32; + default 3600; + units s; + description "Retention for stream replay buffers in seconds, ie how much + data to store before dropping. 0 means no retention"; + + } + leaf CLICON_LOG_STRING_LIMIT { + type uint32; + default 0; + description + "Length limitation of debug and log strings. + Especially useful for dynamic debug strings, such as packet dumps. + 0 means no limit"; + + } + leaf-list CLICON_SNMP_MIB { + description + "Names of MIBs that are used by clixon_snmp. + For each MIB M, a YANG file M.yang is expected to be found. + If not found, an error is genereated. + The YANG file M.yang is typically generated from the source MIB but can also + be handcrafted. An example of such a script is scripts/mib_to_yang.sh. + A list of these options should be in the configuration."; + type string; + } + leaf CLICON_SNMP_AGENT_SOCK { + type string; + default "unix:/tmp/clixon_snmp.sock"; + description + "String description of AgentX socket that clixon_snmp listens to. + For example, for net-snmpd, the socket is created by using the following: + --agentXSocket=unix: + This string currently only supports UNIX socket path. + Note also that the user should consider setting permissions appropriately + XXX: This should be in later yang revision and documented as added when + merged with master"; + } + } +}