Merge branch 'master' of https://github.com/clicon/clixon.
Added new API function `xpath_parse()` to split parsing and xml evaluation.
This commit is contained in:
commit
1f8c759f3d
64 changed files with 2282 additions and 1350 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -49,6 +49,7 @@ build-root/*.rpm
|
|||
build-root/rpmbuild
|
||||
|
||||
util/clixon_util_datastore
|
||||
util/clixon_util_insert
|
||||
util/clixon_util_json
|
||||
util/clixon_util_stream
|
||||
util/clixon_util_xml
|
||||
|
|
|
|||
15
CHANGELOG.md
15
CHANGELOG.md
|
|
@ -86,7 +86,15 @@
|
|||
* rpc get and get-config api function has an added namespace argument:
|
||||
* `clicon_rpc_get_config(clicon_handle h, char *db, char *xpath, char *namespace, cxobj **xt);`
|
||||
* `int clicon_rpc_get(clicon_handle h, char *xpath, char *namespace, cxobj **xt);`
|
||||
|
||||
* Error messages for invalid number ranges and string lengths have been uniformed and changed.
|
||||
* Error messages for invalid ranges are now on the form:
|
||||
```
|
||||
Number 23 out of range: 1 - 10
|
||||
String length 23 out of range: 1 - 10
|
||||
```
|
||||
* On validation callbacks, XML_FLAG_ADD is added to all nodes at startup validation, not just the top-level. This is the same behaviour as for steady-state validation.
|
||||
* All hash_ functions have been prefixed with `clicon_` to avoid name collision with other packages (frr)
|
||||
* All calls to the following functions must be changed: `hash_init`, `hash_free`, `hash_lookup`, `hash_value`, `hash_add`, `hash_del`, `hash_dump`, and `hash_keys`.
|
||||
* RESTCONF strict namespace validation of data in POST and PUT.
|
||||
* Accepted:
|
||||
```
|
||||
|
|
@ -209,7 +217,9 @@
|
|||
|
||||
### Minor changes
|
||||
|
||||
* Added new API function `xpath_parse()` to split parsing and xml evaluation.
|
||||
* Rewrote `api_path2xpath` to handle namespaces.
|
||||
* `api_path2xml_vec` strict mode check added if list key length mismatch
|
||||
* `startup_extraxml` triggers unnecessary validation
|
||||
* Renamed startup_db_reset -> xmldb_db_reset (its a general function)
|
||||
* In startup_extraxml(), check if reset callbacks or extraxml file actually makes and changes to the tmp db.
|
||||
|
|
@ -260,6 +270,9 @@
|
|||
|
||||
### Corrected Bugs
|
||||
|
||||
* Return 404 Not found error if restconf GET does not return requested instance
|
||||
* Fixed [Wrong yang-generated cli code for typeref identityref combination #88](https://github.com/clicon/clixon/issues/88)
|
||||
* Fixed [identityref validation fails when using typedef #87](https://github.com/clicon/clixon/issues/87)
|
||||
* Fixed a problem with some netconf error messages caused restconf daemon to exit due to no XML encoding
|
||||
* Check cligen tab mode, dont start if CLICON_CLI_TAB_MODE is undefined
|
||||
* Startup transactions did not mark added tree with XML_FLAG_ADD as it should.
|
||||
|
|
|
|||
|
|
@ -214,7 +214,8 @@ startup_common(clicon_handle h,
|
|||
xt = NULL;
|
||||
x = NULL;
|
||||
while ((x = xml_child_each(td->td_target, x, CX_ELMNT)) != NULL){
|
||||
xml_flag_set(x, XML_FLAG_ADD);
|
||||
xml_flag_set(x, XML_FLAG_ADD); /* Also down */
|
||||
xml_apply(x, CX_ELMNT, (xml_applyfn_t*)xml_flag_set, (void*)XML_FLAG_ADD);
|
||||
if (cxvec_append(x, &td->td_avec, &td->td_alen) < 0)
|
||||
goto done;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ cli_notification_register(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
snprintf(logname, len, "log_socket_%s", stream);
|
||||
if ((p = hash_value(cdat, logname, &len)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, logname, &len)) != NULL)
|
||||
s_exist = *(int*)p;
|
||||
|
||||
if (status){ /* start */
|
||||
|
|
@ -119,14 +119,14 @@ cli_notification_register(clicon_handle h,
|
|||
goto done;
|
||||
if (cligen_regfd(s, fn, arg) < 0)
|
||||
goto done;
|
||||
if (hash_add(cdat, logname, &s, sizeof(s)) == NULL)
|
||||
if (clicon_hash_add(cdat, logname, &s, sizeof(s)) == NULL)
|
||||
goto done;
|
||||
}
|
||||
else{ /* stop */
|
||||
if (s_exist != -1){
|
||||
cligen_unregfd(s_exist);
|
||||
}
|
||||
hash_del(cdat, logname);
|
||||
clicon_hash_del(cdat, logname);
|
||||
#if 0 /* cant turn off */
|
||||
if (clicon_rpc_create_subscription(h, status, stream, format, filter, NULL) < 0)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -163,7 +163,6 @@ cli_callback_generate(clicon_handle h,
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*! Generate identityref statements for CLI variables
|
||||
* @param[in] ys Yang statement
|
||||
* @param[in] ytype Yang union type being resolved
|
||||
|
|
@ -186,13 +185,13 @@ yang2cli_var_identityref(yang_stmt *ys,
|
|||
char *id;
|
||||
int i;
|
||||
|
||||
/* Add a wildchar string first -let validate take it for default prefix */
|
||||
cprintf(cb, ">");
|
||||
if (helptext)
|
||||
cprintf(cb, "(\"%s\")", helptext);
|
||||
if ((ybaseref = yang_find(ytype, Y_BASE, NULL)) != NULL &&
|
||||
(ybaseid = yang_find_identity(ys, yang_argument_get(ybaseref))) != NULL){
|
||||
if (cvec_len(yang_cvec_get(ybaseid)) > 0){
|
||||
/* Add a wildchar string first -let validate take it for default prefix */
|
||||
cprintf(cb, ">");
|
||||
if (helptext)
|
||||
cprintf(cb, "(\"%s\")", helptext);
|
||||
cprintf(cb, "|<%s:%s choice:", yang_argument_get(ys), cvtypestr);
|
||||
i = 0;
|
||||
while ((cv = cvec_each(yang_cvec_get(ybaseid), cv)) != NULL){
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ int test(FCGX_Request *r, int dbg);
|
|||
cbuf *readdata(FCGX_Request *r);
|
||||
int get_user_cookie(char *cookiestr, char *attribute, char **val);
|
||||
int api_return_err(clicon_handle h, FCGX_Request *r, cxobj *xerr,
|
||||
int pretty, int use_xml);
|
||||
int pretty, int use_xml, int code);
|
||||
|
||||
|
||||
#endif /* _CLIXON_RESTCONF_H_ */
|
||||
|
|
|
|||
|
|
@ -394,13 +394,16 @@ get_user_cookie(char *cookiestr,
|
|||
* @param[in] xerr XML error message from backend
|
||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||
* @param[in] use_xml Set to 0 for JSON and 1 for XML
|
||||
* @param[in] code If 0 use rfc8040 sec 7 netconf2restconf error-tag mapping
|
||||
* otherwise use this code
|
||||
*/
|
||||
int
|
||||
api_return_err(clicon_handle h,
|
||||
FCGX_Request *r,
|
||||
cxobj *xerr,
|
||||
int pretty,
|
||||
int use_xml)
|
||||
int use_xml,
|
||||
int code0)
|
||||
{
|
||||
int retval = -1;
|
||||
cbuf *cb = NULL;
|
||||
|
|
@ -417,8 +420,12 @@ api_return_err(clicon_handle h,
|
|||
goto ok;
|
||||
}
|
||||
tagstr = xml_body(xtag);
|
||||
if ((code = restconf_err2code(tagstr)) < 0)
|
||||
code = 500; /* internal server error */
|
||||
if (code0 != 0)
|
||||
code = code0;
|
||||
else{
|
||||
if ((code = restconf_err2code(tagstr)) < 0)
|
||||
code = 500; /* internal server error */
|
||||
}
|
||||
if ((reason_phrase = restconf_code2reason(code)) == NULL)
|
||||
reason_phrase="";
|
||||
if (xml_name_set(xerr, "error") < 0)
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ int test(FCGX_Request *r, int dbg);
|
|||
cbuf *readdata(FCGX_Request *r);
|
||||
int get_user_cookie(char *cookiestr, char *attribute, char **val);
|
||||
int api_return_err(clicon_handle h, FCGX_Request *r, cxobj *xerr,
|
||||
int pretty, int use_xml);
|
||||
int pretty, int use_xml, int code);
|
||||
int restconf_terminate(clicon_handle h);
|
||||
|
||||
#endif /* _RESTCONF_LIB_H_ */
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@ api_restconf(clicon_handle h,
|
|||
if (netconf_access_denied_xml(&xret, "protocol", "The requested URL was unauthorized") < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if (api_return_err(h, r, xerr, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xerr, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ api_data_get2(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -233,7 +233,7 @@ api_data_get2(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -252,7 +252,7 @@ api_data_get2(clicon_handle h,
|
|||
#endif
|
||||
/* Check if error return */
|
||||
if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -283,7 +283,20 @@ api_data_get2(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
/* Check if not exists */
|
||||
if (xlen == 0){
|
||||
/* 4.3: If a retrieval request for a data resource represents an
|
||||
instance that does not exist, then an error response containing
|
||||
a "404 Not Found" status-line MUST be returned by the server.
|
||||
The error-tag value "invalid-value" is used in this case. */
|
||||
if (netconf_invalid_value_xml(&xe, "application", "Instance does not exist") < 0)
|
||||
goto done;
|
||||
/* override invalid-value default 400 with 404 */
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 404) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -495,7 +508,7 @@ api_data_post(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -509,7 +522,7 @@ api_data_post(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -522,7 +535,7 @@ api_data_post(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -531,7 +544,7 @@ api_data_post(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -546,7 +559,7 @@ api_data_post(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -568,14 +581,15 @@ api_data_post(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (debug){
|
||||
cbuf *ccc=cbuf_new();
|
||||
if (clicon_xml2cbuf(ccc, xe, 0, 0) < 0)
|
||||
goto done;
|
||||
clicon_debug(1, "%s XE:%s", __FUNCTION__, cbuf_get(ccc));
|
||||
}
|
||||
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
#if 0
|
||||
if (debug){
|
||||
cbuf *ccc=cbuf_new();
|
||||
if (clicon_xml2cbuf(ccc, xe, 0, 0) < 0)
|
||||
goto done;
|
||||
clicon_debug(1, "%s XE:%s", __FUNCTION__, cbuf_get(ccc));
|
||||
}
|
||||
#endif
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -607,7 +621,7 @@ api_data_post(clicon_handle h,
|
|||
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0)
|
||||
goto done;
|
||||
if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -629,7 +643,7 @@ api_data_post(clicon_handle h,
|
|||
/* log errors from discard, but ignore */
|
||||
if ((xpath_first(xretdis, NULL, "//rpc-error")) != NULL)
|
||||
clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__);
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0) /* Use original xe */
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) /* Use original xe */
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -843,7 +857,7 @@ api_data_put(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -858,7 +872,7 @@ api_data_put(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -871,7 +885,7 @@ api_data_put(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -880,7 +894,7 @@ api_data_put(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -895,7 +909,7 @@ api_data_put(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -915,7 +929,7 @@ api_data_put(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -955,7 +969,7 @@ api_data_put(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -980,7 +994,7 @@ api_data_put(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -1004,7 +1018,7 @@ api_data_put(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -1039,9 +1053,8 @@ api_data_put(clicon_handle h,
|
|||
clicon_debug(1, "%s xml: %s api_path:%s",__FUNCTION__, cbuf_get(cbx), api_path);
|
||||
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0)
|
||||
goto done;
|
||||
|
||||
if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -1062,7 +1075,7 @@ api_data_put(clicon_handle h,
|
|||
/* log errors from discard, but ignore */
|
||||
if ((xpath_first(xretdis, NULL, "//rpc-error")) != NULL)
|
||||
clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__);
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -1195,7 +1208,7 @@ api_data_delete(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -1219,7 +1232,7 @@ api_data_delete(clicon_handle h,
|
|||
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0)
|
||||
goto done;
|
||||
if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -1241,7 +1254,7 @@ api_data_delete(clicon_handle h,
|
|||
/* log errors from discard, but ignore */
|
||||
if ((xpath_first(xretdis, NULL, "//rpc-error")) != NULL)
|
||||
clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__);
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -1433,7 +1446,7 @@ api_operations_post_input(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -1446,7 +1459,7 @@ api_operations_post_input(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -1455,7 +1468,7 @@ api_operations_post_input(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -1488,7 +1501,7 @@ api_operations_post_input(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -1562,7 +1575,7 @@ api_operations_post_output(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -1599,7 +1612,7 @@ api_operations_post_output(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -1732,7 +1745,7 @@ api_operations_post(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -1751,7 +1764,7 @@ api_operations_post(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -1762,7 +1775,7 @@ api_operations_post(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -1791,7 +1804,7 @@ api_operations_post(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto done;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -1831,7 +1844,7 @@ api_operations_post(clicon_handle h,
|
|||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||
goto ok;
|
||||
}
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -1860,7 +1873,7 @@ api_operations_post(clicon_handle h,
|
|||
goto done;
|
||||
/* Local error: return it and quit */
|
||||
if ((xe = xpath_first(xret, NULL, "rpc-reply/rpc-error")) != NULL){
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -1869,7 +1882,7 @@ api_operations_post(clicon_handle h,
|
|||
if (clicon_rpc_netconf_xml(h, xtop, &xret, NULL) < 0)
|
||||
goto done;
|
||||
if ((xe = xpath_first(xret, NULL, "rpc-reply/rpc-error")) != NULL){
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ restconf_stream(clicon_handle h,
|
|||
if (clicon_rpc_netconf(h, cbuf_get(cb), &xret, &s) < 0)
|
||||
goto done;
|
||||
if ((xe = xpath_first(xret, NULL, "rpc-reply/rpc-error")) != NULL){
|
||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -417,7 +417,7 @@ api_stream(clicon_handle h,
|
|||
if (netconf_access_denied_xml(&xret, "protocol", "The requested URL was unauthorized") < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if (api_return_err(h, r, xerr, pretty, use_xml) < 0)
|
||||
if (api_return_err(h, r, xerr, pretty, use_xml, 0) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,51 @@ Docker is used to build Alpine Linux
|
|||
### Build docker image
|
||||
|
||||
## FreeBSD
|
||||
### Package install
|
||||
|
||||
FreeBSD has ports for both cligen and clixon available.
|
||||
You can install them as binary packages, or you can build
|
||||
them in a ports source tree locally.
|
||||
|
||||
If you install using binary packages or build from the
|
||||
ports collection, the installation locations comply
|
||||
with FreeBSD standards and you have some assurance
|
||||
that the installed package is correct and functional.
|
||||
|
||||
The nginx setup for RESTCONF is altered - the system user
|
||||
www is used, and the restconf daemon is placed in
|
||||
/usr/local/sbin.
|
||||
|
||||
### Binary package install
|
||||
|
||||
To install the pre-built binary package, use the FreeBSD
|
||||
pkg command.
|
||||
|
||||
```
|
||||
% pkg install clixon
|
||||
```
|
||||
|
||||
This will install clixon and all the dependencies needed.
|
||||
|
||||
### Build from source
|
||||
|
||||
If you prefer you can also build clixon from the
|
||||
[FreeBSD ports collection](https://www.freebsd.org/doc/handbook/ports-using.html)
|
||||
|
||||
Once you have the Ports Collection installed, you build
|
||||
clixon like this:
|
||||
|
||||
```
|
||||
% cd /usr/ports/devel/clixon
|
||||
% make && make install
|
||||
```
|
||||
|
||||
One issue with using the Ports Collection is that it may
|
||||
not install the latest version from GitHub. The port is
|
||||
generally updated soon after an official release, but there
|
||||
is still a lag between it and the master branch. The maintainer
|
||||
for the port tries to assure that the master branch will
|
||||
compile always, but no FreeBSD specific functional testing
|
||||
is done.
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -44,14 +44,14 @@ struct clicon_hash {
|
|||
};
|
||||
typedef struct clicon_hash *clicon_hash_t;
|
||||
|
||||
clicon_hash_t *hash_init (void);
|
||||
void hash_free (clicon_hash_t *);
|
||||
clicon_hash_t hash_lookup (clicon_hash_t *head, const char *key);
|
||||
void *hash_value (clicon_hash_t *head, const char *key, size_t *vlen);
|
||||
clicon_hash_t hash_add (clicon_hash_t *head, const char *key, void *val, size_t vlen);
|
||||
int hash_del (clicon_hash_t *head, const char *key);
|
||||
int hash_dump(clicon_hash_t *head, FILE *f);
|
||||
int hash_keys(clicon_hash_t *hash, char ***vector, size_t *nkeys);
|
||||
clicon_hash_t *clicon_hash_init (void);
|
||||
void clicon_hash_free (clicon_hash_t *);
|
||||
clicon_hash_t clicon_hash_lookup (clicon_hash_t *head, const char *key);
|
||||
void *clicon_hash_value (clicon_hash_t *head, const char *key, size_t *vlen);
|
||||
clicon_hash_t clicon_hash_add (clicon_hash_t *head, const char *key, void *val, size_t vlen);
|
||||
int clicon_hash_del (clicon_hash_t *head, const char *key);
|
||||
int clicon_hash_dump(clicon_hash_t *head, FILE *f);
|
||||
int clicon_hash_keys(clicon_hash_t *hash, char ***vector, size_t *nkeys);
|
||||
|
||||
/*
|
||||
* Macros to iterate over hash contents.
|
||||
|
|
@ -59,24 +59,23 @@ int hash_keys(clicon_hash_t *hash, char ***vector, size_t *nkeys);
|
|||
*
|
||||
* Example:
|
||||
* char *k;
|
||||
* clicon_hash_t *h = hash_init();
|
||||
* clicon_hash_t *h = clicon_hash_init();
|
||||
*
|
||||
* hash_add(h, "colour", "red", 6);
|
||||
* hash_add(h, "name", "rudolf" 7);
|
||||
* hash_add(h, "species", "reindeer" 9);
|
||||
* clicon_hash_add(h, "colour", "red", 6);
|
||||
* clicon_hash_add(h, "name", "rudolf" 7);
|
||||
* clicon_hash_add(h, "species", "reindeer" 9);
|
||||
*
|
||||
* hash_each(h, k) {
|
||||
* printf ("%s = %s\n", k, (char *)hash_value(h, k, NULL));
|
||||
* clicon_hash_each(h, k) {
|
||||
* printf ("%s = %s\n", k, (char *)clicon_hash_value(h, k, NULL));
|
||||
* } hash_each_end();
|
||||
*/
|
||||
#define hash_each(__hash__, __key__) \
|
||||
#define clicon_hash_each(__hash__, __key__) \
|
||||
{ \
|
||||
int __i__; \
|
||||
size_t __n__; \
|
||||
char **__k__ = hash_keys((__hash__),&__n__); \
|
||||
if (__k__) { \
|
||||
for(__i__ = 0; __i__ < __n__ && ((__key__) = __k__[__i__]); __i__++)
|
||||
#define hash_each_end(__hash__) if (__k__) free(__k__); } }
|
||||
|
||||
#define clicon_hash_each_end(__hash__) if (__k__) free(__k__); } }
|
||||
|
||||
#endif /* _CLIXON_HASH_H_ */
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
*/
|
||||
int netconf_in_use(cbuf *cb, char *type, char *message);
|
||||
int netconf_invalid_value(cbuf *cb, char *type, char *message);
|
||||
int netconf_invalid_value_xml(cxobj **xret, char *type, char *message);
|
||||
int netconf_too_big(cbuf *cb, char *type, char *message);
|
||||
int netconf_missing_attribute(cbuf *cb, char *type, char *info, char *message);
|
||||
int netconf_bad_attribute(cbuf *cb, char *type, char *info, char *message);
|
||||
|
|
|
|||
|
|
@ -75,31 +75,61 @@ enum axis_type{
|
|||
A_ROOT /* XXX Not in https://www.w3.org/TR/xpath-10 */
|
||||
};
|
||||
|
||||
/*
|
||||
* Variables
|
||||
*/
|
||||
extern const map_str2int xpopmap[];
|
||||
/* used as non-terminal type in yacc rules */
|
||||
enum xp_type{
|
||||
XP_EXP,
|
||||
XP_AND,
|
||||
XP_RELEX,
|
||||
XP_ADD,
|
||||
XP_UNION,
|
||||
XP_PATHEXPR,
|
||||
XP_LOCPATH,
|
||||
XP_ABSPATH,
|
||||
XP_RELLOCPATH,
|
||||
XP_STEP,
|
||||
XP_NODE, /* s0 is namespace prefix, s1 is name */
|
||||
XP_NODE_FN,
|
||||
XP_PRED,
|
||||
XP_PRI0,
|
||||
XP_PRIME_NR,
|
||||
XP_PRIME_STR,
|
||||
XP_PRIME_FN,
|
||||
};
|
||||
|
||||
extern int xpatherrordiff;
|
||||
/*! XPATH Parsing generates a tree of nodes that is later traversed
|
||||
*/
|
||||
struct xpath_tree{
|
||||
enum xp_type xs_type;
|
||||
int xs_int;
|
||||
double xs_double;
|
||||
char *xs_s0;
|
||||
char *xs_s1;
|
||||
struct xpath_tree *xs_c0; /* child 0 */
|
||||
struct xpath_tree *xs_c1; /* child 1 */
|
||||
};
|
||||
typedef struct xpath_tree xpath_tree;
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
char* xpath_tree_int2str(int nodetype);
|
||||
int xpath_tree_print(cbuf *cb, xpath_tree *xs);
|
||||
int xpath_tree_free(xpath_tree *xs);
|
||||
int xpath_parse(cvec *nsc, char *xpath, xpath_tree **xptree);
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||
cxobj *xpath_first(cxobj *xcur, cvec *nsc, char *format, ...) __attribute__ ((format (printf, 3, 4)));
|
||||
int xpath_vec(cxobj *xcur, cvec *nsc, char *format, cxobj ***vec, size_t *veclen, ...) __attribute__ ((format (printf, 3, 6)));
|
||||
int xpath_vec_flag(cxobj *xcur, cvec *nsc, char *format, uint16_t flags,
|
||||
cxobj ***vec, size_t *veclen, ...) __attribute__ ((format (printf, 3, 7)));
|
||||
cxobj *xpath_first(cxobj *xcur, cvec *nsc, char *format, ...) __attribute__ ((format (printf, 3, 4)));
|
||||
int xpath_vec_bool(cxobj *xcur, cvec *nsc, char *format, ...) __attribute__ ((format (printf, 3, 4)));
|
||||
|
||||
#else
|
||||
cxobj *xpath_first(cxobj *xcur, cvec *nsc, char *format, ...);
|
||||
int xpath_vec(cxobj *xcur, cvec *nsc, char *format, cxobj ***vec, size_t *veclen, ...);
|
||||
int xpath_vec_flag(cxobj *xcur, cvec *nsc, char *format, uint16_t flags,
|
||||
cxobj ***vec, size_t *veclen, ...);
|
||||
cxobj *xpath_first(cxobj *xcur, cvec *nsc, char *format, ...);
|
||||
int xpath_vec_bool(cxobj *xcur, cvec *nsc, char *format, ...);
|
||||
#endif
|
||||
|
||||
int xpath_vec_ctx(cxobj *xcur, cvec *nsc, char *xpath, xp_ctx **xrp);
|
||||
|
||||
#endif /* _CLIXON_XPATH_H */
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ SRC = clixon_sig.c clixon_log.c clixon_err.c clixon_event.c \
|
|||
clixon_yang_cardinality.c clixon_xml_changelog.c clixon_xml_nsctx.c \
|
||||
clixon_hash.c clixon_options.c clixon_data.c clixon_plugin.c \
|
||||
clixon_proto.c clixon_proto_client.c \
|
||||
clixon_xpath.c clixon_xpath_ctx.c clixon_sha1.c \
|
||||
clixon_xpath.c clixon_xpath_ctx.c clixon_xpath_eval.c clixon_sha1.c \
|
||||
clixon_datastore.c clixon_datastore_write.c clixon_datastore_read.c \
|
||||
clixon_datastore_tree.c \
|
||||
clixon_netconf_lib.c clixon_stream.c clixon_nacm.c
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ clicon_dbspec_yang(clicon_handle h)
|
|||
size_t len;
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, "dbspec_yang", &len)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, "dbspec_yang", &len)) != NULL)
|
||||
return *(yang_stmt **)p;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -100,7 +100,7 @@ clicon_dbspec_yang_set(clicon_handle h,
|
|||
/* It is the pointer to ys that should be copied by hash,
|
||||
so we send a ptr to the ptr to indicate what to copy.
|
||||
*/
|
||||
if (hash_add(cdat, "dbspec_yang", &ys, sizeof(ys)) == NULL)
|
||||
if (clicon_hash_add(cdat, "dbspec_yang", &ys, sizeof(ys)) == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -118,7 +118,7 @@ clicon_nacm_ext(clicon_handle h)
|
|||
size_t len;
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, "nacm_xml", &len)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, "nacm_xml", &len)) != NULL)
|
||||
return *(cxobj **)p;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ clicon_nacm_ext_set(clicon_handle h,
|
|||
/* It is the pointer to xn that should be copied by hash,
|
||||
so we send a ptr to the ptr to indicate what to copy.
|
||||
*/
|
||||
if (hash_add(cdat, "nacm_xml", &xn, sizeof(xn)) == NULL)
|
||||
if (clicon_hash_add(cdat, "nacm_xml", &xn, sizeof(xn)) == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -158,7 +158,7 @@ clicon_config_yang(clicon_handle h)
|
|||
size_t len;
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, "control_yang", &len)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, "control_yang", &len)) != NULL)
|
||||
return *(yang_stmt **)p;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -175,7 +175,7 @@ clicon_config_yang_set(clicon_handle h,
|
|||
/* It is the pointer to ys that should be copied by hash,
|
||||
so we send a ptr to the ptr to indicate what to copy.
|
||||
*/
|
||||
if (hash_add(cdat, "control_yang", &ys, sizeof(ys)) == NULL)
|
||||
if (clicon_hash_add(cdat, "control_yang", &ys, sizeof(ys)) == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -192,7 +192,7 @@ clicon_conf_xml(clicon_handle h)
|
|||
size_t len;
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, "clixon_conf", &len)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, "clixon_conf", &len)) != NULL)
|
||||
return *(cxobj **)p;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -209,7 +209,7 @@ clicon_conf_xml_set(clicon_handle h,
|
|||
/* It is the pointer to x that should be copied by hash,
|
||||
* so we send a ptr to the ptr to indicate what to copy.
|
||||
*/
|
||||
if (hash_add(cdat, "clixon_conf", &x, sizeof(x)) == NULL)
|
||||
if (clicon_hash_add(cdat, "clixon_conf", &x, sizeof(x)) == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -223,7 +223,7 @@ clicon_username_get(clicon_handle h)
|
|||
{
|
||||
clicon_hash_t *cdat = clicon_data(h);
|
||||
|
||||
return (char*)hash_value(cdat, "username", NULL);
|
||||
return (char*)clicon_hash_value(cdat, "username", NULL);
|
||||
}
|
||||
|
||||
/*! Set authorized user name
|
||||
|
|
@ -238,8 +238,8 @@ clicon_username_set(clicon_handle h,
|
|||
clicon_hash_t *cdat = clicon_data(h);
|
||||
|
||||
if (username == NULL)
|
||||
return hash_del(cdat, "username");
|
||||
return hash_add(cdat, "username", username, strlen(username)+1)==NULL?-1:0;
|
||||
return clicon_hash_del(cdat, "username");
|
||||
return clicon_hash_add(cdat, "username", username, strlen(username)+1)==NULL?-1:0;
|
||||
}
|
||||
|
||||
/*! Get backend daemon startup status
|
||||
|
|
@ -252,7 +252,7 @@ clicon_startup_status_get(clicon_handle h)
|
|||
clicon_hash_t *cdat = clicon_data(h);
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, "startup_status", NULL)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, "startup_status", NULL)) != NULL)
|
||||
return *(enum startup_status *)p;
|
||||
return STARTUP_ERR;
|
||||
}
|
||||
|
|
@ -268,7 +268,7 @@ clicon_startup_status_set(clicon_handle h,
|
|||
enum startup_status status)
|
||||
{
|
||||
clicon_hash_t *cdat = clicon_data(h);
|
||||
if (hash_add(cdat, "startup_status", &status, sizeof(status))==NULL)
|
||||
if (clicon_hash_add(cdat, "startup_status", &status, sizeof(status))==NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -284,7 +284,7 @@ clicon_socket_get(clicon_handle h)
|
|||
clicon_hash_t *cdat = clicon_data(h);
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, "socket", NULL)) == NULL)
|
||||
if ((p = clicon_hash_value(cdat, "socket", NULL)) == NULL)
|
||||
return -1;
|
||||
return *(int*)p;
|
||||
}
|
||||
|
|
@ -302,8 +302,8 @@ clicon_socket_set(clicon_handle h,
|
|||
clicon_hash_t *cdat = clicon_data(h);
|
||||
|
||||
if (s == -1)
|
||||
return hash_del(cdat, "socket");
|
||||
return hash_add(cdat, "socket", &s, sizeof(int))==NULL?-1:0;
|
||||
return clicon_hash_del(cdat, "socket");
|
||||
return clicon_hash_add(cdat, "socket", &s, sizeof(int))==NULL?-1:0;
|
||||
}
|
||||
|
||||
/*! Get module state cache
|
||||
|
|
@ -319,7 +319,7 @@ clicon_modst_cache_get(clicon_handle h,
|
|||
clicon_hash_t *cdat = clicon_data(h);
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, brief?"modst_brief":"modst_full", NULL)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, brief?"modst_brief":"modst_full", NULL)) != NULL)
|
||||
return *(cxobj **)p;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -346,7 +346,7 @@ clicon_modst_cache_set(clicon_handle h,
|
|||
assert(strcmp(xml_name(xms),"modules-state")==0);
|
||||
if ((x = xml_dup(xms)) == NULL)
|
||||
return -1;
|
||||
if (hash_add(cdat, brief?"modst_brief":"modst_full", &x, sizeof(x))==NULL)
|
||||
if (clicon_hash_add(cdat, brief?"modst_brief":"modst_full", &x, sizeof(x))==NULL)
|
||||
return -1;
|
||||
ok:
|
||||
return 0;
|
||||
|
|
@ -363,7 +363,7 @@ clicon_xml_changelog_get(clicon_handle h)
|
|||
clicon_hash_t *cdat = clicon_data(h);
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, "xml-changelog", NULL)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, "xml-changelog", NULL)) != NULL)
|
||||
return *(cxobj **)p;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -381,7 +381,7 @@ clicon_xml_changelog_set(clicon_handle h,
|
|||
{
|
||||
clicon_hash_t *cdat = clicon_data(h);
|
||||
|
||||
if (hash_add(cdat, "xml-changelog", &xchlog, sizeof(xchlog))==NULL)
|
||||
if (clicon_hash_add(cdat, "xml-changelog", &xchlog, sizeof(xchlog))==NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -403,12 +403,12 @@ clicon_argv_get(clicon_handle h,
|
|||
void *p;
|
||||
|
||||
if (argc){
|
||||
if ((p = hash_value(cdat, "argc", NULL)) == NULL)
|
||||
if ((p = clicon_hash_value(cdat, "argc", NULL)) == NULL)
|
||||
return -1;
|
||||
*argc = *(int*)p;
|
||||
}
|
||||
if (argv){
|
||||
if ((p = hash_value(cdat, "argv", NULL)) == NULL)
|
||||
if ((p = clicon_hash_value(cdat, "argv", NULL)) == NULL)
|
||||
return -1;
|
||||
*argv = (char**)p;
|
||||
}
|
||||
|
|
@ -444,10 +444,10 @@ clicon_argv_set(clicon_handle h,
|
|||
memcpy(argvv+1, argv, argc*sizeof(char*));
|
||||
argvv[0] = prgm;
|
||||
/* Note the value is the argv vector (which is copied) */
|
||||
if (hash_add(cdat, "argv", argvv, len*sizeof(char*))==NULL)
|
||||
if (clicon_hash_add(cdat, "argv", argvv, len*sizeof(char*))==NULL)
|
||||
goto done;
|
||||
argc += 1;
|
||||
if (hash_add(cdat, "argc", &argc, sizeof(argc))==NULL)
|
||||
if (clicon_hash_add(cdat, "argc", &argc, sizeof(argc))==NULL)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
@ -470,7 +470,7 @@ clicon_db_elmnt_get(clicon_handle h,
|
|||
clicon_hash_t *cdat = clicon_db_elmnt(h);
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, db, NULL)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, db, NULL)) != NULL)
|
||||
return (db_elmnt *)p;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -491,7 +491,7 @@ clicon_db_elmnt_set(clicon_handle h,
|
|||
{
|
||||
clicon_hash_t *cdat = clicon_db_elmnt(h);
|
||||
|
||||
if (hash_add(cdat, db, de, sizeof(*de))==NULL)
|
||||
if (clicon_hash_add(cdat, db, de, sizeof(*de))==NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,10 +161,10 @@ xmldb_disconnect(clicon_handle h)
|
|||
int i;
|
||||
db_elmnt *de;
|
||||
|
||||
if (hash_keys(clicon_db_elmnt(h), &keys, &klen) < 0)
|
||||
if (clicon_hash_keys(clicon_db_elmnt(h), &keys, &klen) < 0)
|
||||
goto done;
|
||||
for(i = 0; i < klen; i++)
|
||||
if ((de = hash_value(clicon_db_elmnt(h), keys[i], NULL)) != NULL){
|
||||
if ((de = clicon_hash_value(clicon_db_elmnt(h), keys[i], NULL)) != NULL){
|
||||
if (de->de_xml){
|
||||
xml_free(de->de_xml);
|
||||
de->de_xml = NULL;
|
||||
|
|
@ -311,7 +311,7 @@ xmldb_unlock_all(clicon_handle h,
|
|||
int i;
|
||||
db_elmnt *de;
|
||||
|
||||
if (hash_keys(clicon_db_elmnt(h), &keys, &klen) < 0)
|
||||
if (clicon_hash_keys(clicon_db_elmnt(h), &keys, &klen) < 0)
|
||||
goto done;
|
||||
for (i = 0; i < klen; i++)
|
||||
if ((de = clicon_db_elmnt_get(h, keys[i])) != NULL &&
|
||||
|
|
|
|||
|
|
@ -596,10 +596,6 @@ xmldb_get_zerocopy(clicon_handle h,
|
|||
db_elmnt *de = NULL;
|
||||
db_elmnt de0 = {0,};
|
||||
|
||||
if (!clicon_option_bool(h, "CLICON_XMLDB_CACHE")){
|
||||
clicon_err(OE_CFG, 0, "CLICON_XMLDB_CACHE must be set");
|
||||
goto done;
|
||||
}
|
||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||
clicon_err(OE_YANG, ENOENT, "No yang spec");
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -111,15 +111,15 @@ clicon_handle_init0(int size)
|
|||
}
|
||||
memset(ch, 0, size);
|
||||
ch->ch_magic = CLICON_MAGIC;
|
||||
if ((ch->ch_copt = hash_init()) == NULL){
|
||||
if ((ch->ch_copt = clicon_hash_init()) == NULL){
|
||||
clicon_handle_exit((clicon_handle)ch);
|
||||
goto done;
|
||||
}
|
||||
if ((ch->ch_data = hash_init()) == NULL){
|
||||
if ((ch->ch_data = clicon_hash_init()) == NULL){
|
||||
clicon_handle_exit((clicon_handle)ch);
|
||||
goto done;
|
||||
}
|
||||
if ((ch->ch_db_elmnt = hash_init()) == NULL){
|
||||
if ((ch->ch_db_elmnt = clicon_hash_init()) == NULL){
|
||||
clicon_handle_exit((clicon_handle)ch);
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -154,12 +154,12 @@ clicon_handle_exit(clicon_handle h)
|
|||
clicon_hash_t *ha;
|
||||
|
||||
if ((ha = clicon_options(h)) != NULL)
|
||||
hash_free(ha);
|
||||
clicon_hash_free(ha);
|
||||
if ((ha = clicon_data(h)) != NULL)
|
||||
hash_free(ha);
|
||||
clicon_hash_free(ha);
|
||||
|
||||
if ((ha = clicon_db_elmnt(h)) != NULL)
|
||||
hash_free(ha);
|
||||
clicon_hash_free(ha);
|
||||
stream_delete_all(h, 1);
|
||||
free(ch);
|
||||
retval = 0;
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ hash_bucket(const char *str)
|
|||
* @see hash_free For freeing the hash-table
|
||||
*/
|
||||
clicon_hash_t *
|
||||
hash_init(void)
|
||||
clicon_hash_init(void)
|
||||
{
|
||||
clicon_hash_t *hash;
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ hash_init(void)
|
|||
* @retval void
|
||||
*/
|
||||
void
|
||||
hash_free(clicon_hash_t *hash)
|
||||
clicon_hash_free(clicon_hash_t *hash)
|
||||
{
|
||||
int i;
|
||||
clicon_hash_t tmp;
|
||||
|
|
@ -157,8 +157,8 @@ hash_free(clicon_hash_t *hash)
|
|||
* @retval NULL Not found
|
||||
*/
|
||||
clicon_hash_t
|
||||
hash_lookup(clicon_hash_t *hash,
|
||||
const char *key)
|
||||
clicon_hash_lookup(clicon_hash_t *hash,
|
||||
const char *key)
|
||||
{
|
||||
uint32_t bkt;
|
||||
clicon_hash_t h;
|
||||
|
|
@ -183,13 +183,13 @@ hash_lookup(clicon_hash_t *hash,
|
|||
* @retval NULL Key not found or value NULL
|
||||
*/
|
||||
void *
|
||||
hash_value(clicon_hash_t *hash,
|
||||
const char *key,
|
||||
size_t *vlen)
|
||||
clicon_hash_value(clicon_hash_t *hash,
|
||||
const char *key,
|
||||
size_t *vlen)
|
||||
{
|
||||
clicon_hash_t h;
|
||||
|
||||
h = hash_lookup(hash, key);
|
||||
h = clicon_hash_lookup(hash, key);
|
||||
if (h == NULL)
|
||||
return NULL; /* OK, key not found */
|
||||
|
||||
|
|
@ -209,10 +209,10 @@ hash_value(clicon_hash_t *hash,
|
|||
* @note special case val is NULL and vlen==0
|
||||
*/
|
||||
clicon_hash_t
|
||||
hash_add(clicon_hash_t *hash,
|
||||
const char *key,
|
||||
void *val,
|
||||
size_t vlen)
|
||||
clicon_hash_add(clicon_hash_t *hash,
|
||||
const char *key,
|
||||
void *val,
|
||||
size_t vlen)
|
||||
{
|
||||
void *newval = NULL;
|
||||
clicon_hash_t h;
|
||||
|
|
@ -225,7 +225,7 @@ hash_add(clicon_hash_t *hash,
|
|||
goto catch;
|
||||
}
|
||||
/* If variable exist, don't allocate a new. just replace value */
|
||||
h = hash_lookup(hash, key);
|
||||
h = clicon_hash_lookup(hash, key);
|
||||
if (h == NULL) {
|
||||
if ((new = (clicon_hash_t)malloc(sizeof(*new))) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "malloc: %s", strerror(errno));
|
||||
|
|
@ -283,12 +283,12 @@ catch:
|
|||
* @retval -1 Key not found
|
||||
*/
|
||||
int
|
||||
hash_del(clicon_hash_t *hash,
|
||||
const char *key)
|
||||
clicon_hash_del(clicon_hash_t *hash,
|
||||
const char *key)
|
||||
{
|
||||
clicon_hash_t h;
|
||||
|
||||
h = hash_lookup(hash, key);
|
||||
h = clicon_hash_lookup(hash, key);
|
||||
if (h == NULL)
|
||||
return -1;
|
||||
|
||||
|
|
@ -311,9 +311,9 @@ hash_del(clicon_hash_t *hash,
|
|||
* @note: vector needs to be deallocated with free
|
||||
*/
|
||||
int
|
||||
hash_keys(clicon_hash_t *hash,
|
||||
char ***vector,
|
||||
size_t *nkeys)
|
||||
clicon_hash_keys(clicon_hash_t *hash,
|
||||
char ***vector,
|
||||
size_t *nkeys)
|
||||
{
|
||||
int retval = -1;
|
||||
int bkt;
|
||||
|
|
@ -357,8 +357,8 @@ catch:
|
|||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
hash_dump(clicon_hash_t *hash,
|
||||
FILE *f)
|
||||
clicon_hash_dump(clicon_hash_t *hash,
|
||||
FILE *f)
|
||||
{
|
||||
int retval = -1;
|
||||
int i;
|
||||
|
|
@ -369,10 +369,10 @@ hash_dump(clicon_hash_t *hash,
|
|||
|
||||
if (hash == NULL)
|
||||
goto ok;
|
||||
if (hash_keys(hash, &keys, &klen) < 0)
|
||||
if (clicon_hash_keys(hash, &keys, &klen) < 0)
|
||||
goto done;
|
||||
for(i = 0; i < klen; i++) {
|
||||
val = hash_value(hash, keys[i], &vlen);
|
||||
val = clicon_hash_value(hash, keys[i], &vlen);
|
||||
printf("%s =\t 0x%p , length %zu\n", keys[i], val, vlen);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,48 @@ netconf_in_use(cbuf *cb,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/*! Create Netconf invalid-value error XML tree according to RFC 6241 Appendix A
|
||||
*
|
||||
* The request specifies an unacceptable value for one or more parameters.
|
||||
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||
* @param[in] type Error type: "application" or "protocol"
|
||||
* @param[in] message Error message (will be XML encoded)
|
||||
*/
|
||||
int
|
||||
netconf_invalid_value_xml(cxobj **xret,
|
||||
char *type,
|
||||
char *message)
|
||||
{
|
||||
int retval =-1;
|
||||
cxobj *xerr;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (*xret == NULL){
|
||||
if ((*xret = xml_new("rpc-reply", NULL, NULL)) == NULL)
|
||||
goto done;
|
||||
}
|
||||
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||
goto done;
|
||||
if ((xerr = xml_new("rpc-error", *xret, NULL)) == NULL)
|
||||
goto done;
|
||||
if (xml_parse_va(&xerr, NULL, "<error-type>%s</error-type>"
|
||||
"<error-tag>invalid-value</error-tag>"
|
||||
"<error-severity>error</error-severity>", type) < 0)
|
||||
goto done;
|
||||
if (message){
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (xml_parse_va(&xerr, NULL, "<error-message>%s</error-message>",
|
||||
encstr) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Create Netconf invalid-value error XML tree according to RFC 6241 Appendix A
|
||||
*
|
||||
* The request specifies an unacceptable value for one or more parameters.
|
||||
|
|
@ -120,6 +162,20 @@ netconf_invalid_value(cbuf *cb,
|
|||
char *type,
|
||||
char *message)
|
||||
{
|
||||
#if 1
|
||||
int retval = -1;
|
||||
cxobj *xret = NULL;
|
||||
|
||||
if (netconf_invalid_value_xml(&xret, type, message) < 0)
|
||||
goto done;
|
||||
if (clicon_xml2cbuf(cb, xret, 0, 0) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
if (xret)
|
||||
xml_free(xret);
|
||||
return retval;
|
||||
#else
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
|
|
@ -145,6 +201,7 @@ netconf_invalid_value(cbuf *cb,
|
|||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
goto done;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*! Create Netconf too-big error XML tree according to RFC 6241 Appendix A
|
||||
|
|
|
|||
|
|
@ -112,10 +112,10 @@ clicon_option_dump(clicon_handle h,
|
|||
size_t vlen;
|
||||
cxobj *x = NULL;
|
||||
|
||||
if (hash_keys(hash, &keys, &klen) < 0)
|
||||
if (clicon_hash_keys(hash, &keys, &klen) < 0)
|
||||
goto done;
|
||||
for(i = 0; i < klen; i++) {
|
||||
val = hash_value(hash, keys[i], &vlen);
|
||||
val = clicon_hash_value(hash, keys[i], &vlen);
|
||||
if (vlen){
|
||||
if (((char*)val)[vlen-1]=='\0') /* assume string */
|
||||
clicon_debug(dbglevel, "%s =\t \"%s\"", keys[i], (char*)val);
|
||||
|
|
@ -234,7 +234,7 @@ parse_configfile(clicon_handle h,
|
|||
/* Used as an arg to this fn */
|
||||
if (strcmp(name,"CLICON_CONFIGFILE")==0)
|
||||
continue;
|
||||
if (hash_add(copt,
|
||||
if (clicon_hash_add(copt,
|
||||
name,
|
||||
body,
|
||||
strlen(body)+1) == NULL)
|
||||
|
|
@ -284,7 +284,7 @@ clicon_option_add(clicon_handle h,
|
|||
name, value, name) < 0)
|
||||
goto done;
|
||||
}
|
||||
if (hash_add(copt,
|
||||
if (clicon_hash_add(copt,
|
||||
name,
|
||||
value,
|
||||
strlen(value)+1) == NULL)
|
||||
|
|
@ -319,10 +319,10 @@ clicon_options_main(clicon_handle h,
|
|||
/*
|
||||
* Set configure file if not set by command-line above
|
||||
*/
|
||||
if (!hash_lookup(copt, "CLICON_CONFIGFILE")){
|
||||
if (!clicon_hash_lookup(copt, "CLICON_CONFIGFILE")){
|
||||
clicon_option_str_set(h, "CLICON_CONFIGFILE", CLIXON_DEFAULT_CONFIG);
|
||||
}
|
||||
configfile = hash_value(copt, "CLICON_CONFIGFILE", NULL);
|
||||
configfile = clicon_hash_value(copt, "CLICON_CONFIGFILE", NULL);
|
||||
clicon_debug(1, "CLICON_CONFIGFILE=%s", configfile);
|
||||
/* File must end with .xml */
|
||||
if ((suffix = rindex(configfile, '.')) != NULL){
|
||||
|
|
@ -385,7 +385,7 @@ clicon_option_exists(clicon_handle h,
|
|||
{
|
||||
clicon_hash_t *copt = clicon_options(h);
|
||||
|
||||
return (hash_lookup(copt, (char*)name) != NULL);
|
||||
return (clicon_hash_lookup(copt, (char*)name) != NULL);
|
||||
}
|
||||
|
||||
/*! Get a single string option string via handle
|
||||
|
|
@ -404,9 +404,9 @@ clicon_option_str(clicon_handle h,
|
|||
{
|
||||
clicon_hash_t *copt = clicon_options(h);
|
||||
|
||||
if (hash_lookup(copt, (char*)name) == NULL)
|
||||
if (clicon_hash_lookup(copt, (char*)name) == NULL)
|
||||
return NULL;
|
||||
return hash_value(copt, (char*)name, NULL);
|
||||
return clicon_hash_value(copt, (char*)name, NULL);
|
||||
}
|
||||
|
||||
/*! Set a single string option via handle
|
||||
|
|
@ -423,7 +423,7 @@ clicon_option_str_set(clicon_handle h,
|
|||
{
|
||||
clicon_hash_t *copt = clicon_options(h);
|
||||
|
||||
return hash_add(copt, (char*)name, val, strlen(val)+1)==NULL?-1:0;
|
||||
return clicon_hash_add(copt, (char*)name, val, strlen(val)+1)==NULL?-1:0;
|
||||
}
|
||||
|
||||
/*! Get options as integer but stored as string
|
||||
|
|
@ -518,7 +518,7 @@ clicon_option_del(clicon_handle h,
|
|||
{
|
||||
clicon_hash_t *copt = clicon_options(h);
|
||||
|
||||
return hash_del(copt, (char*)name);
|
||||
return clicon_hash_del(copt, (char*)name);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -343,11 +343,12 @@ validate_identityref(cxobj *xt,
|
|||
|
||||
{
|
||||
int retval = -1;
|
||||
char *node;
|
||||
char *node = NULL;
|
||||
yang_stmt *ybaseref; /* This is the type's base reference */
|
||||
yang_stmt *ybaseid;
|
||||
char *prefix = NULL;
|
||||
cbuf *cb = NULL;
|
||||
cbuf *cb2 = NULL;
|
||||
|
||||
/* Get idref value. Then see if this value is derived from ytype.
|
||||
* Always add default prefix because derived identifiers are stored with
|
||||
|
|
@ -380,10 +381,13 @@ validate_identityref(cxobj *xt,
|
|||
* The derived node list is a cvec computed XXX
|
||||
*/
|
||||
if (cvec_find(yang_cvec_get(ybaseid), node) == NULL){
|
||||
cbuf_reset(cb);
|
||||
cprintf(cb, "Identityref validation failed, %s not derived from %s",
|
||||
if ((cb2 = cbuf_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
cprintf(cb2, "Identityref validation failed, %s not derived from %s",
|
||||
node, yang_argument_get(ybaseid));
|
||||
if (netconf_operation_failed_xml(xret, "application", cbuf_get(cb)) < 0)
|
||||
if (netconf_operation_failed_xml(xret, "application", cbuf_get(cb2)) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -391,6 +395,8 @@ validate_identityref(cxobj *xt,
|
|||
done:
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
if (cb2)
|
||||
cbuf_free(cb2);
|
||||
return retval;
|
||||
fail:
|
||||
retval = 0;
|
||||
|
|
@ -1221,19 +1227,20 @@ xml_yang_validate_all(clicon_handle h,
|
|||
/* Special case if leaf is leafref, then first check against
|
||||
current xml tree
|
||||
*/
|
||||
if ((yc = yang_find(ys, Y_TYPE, NULL)) != NULL){
|
||||
if (strcmp(yc->ys_argument, "leafref") == 0){
|
||||
if ((ret = validate_leafref(xt, yc, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
}
|
||||
else if (strcmp(yc->ys_argument, "identityref") == 0){
|
||||
if ((ret = validate_identityref(xt, ys, yc, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
/* Get base type yc */
|
||||
if (yang_type_get(ys, NULL, &yc, NULL, NULL, NULL, NULL, NULL) < 0)
|
||||
goto done;
|
||||
if (strcmp(yang_argument_get(yc), "leafref") == 0){
|
||||
if ((ret = validate_leafref(xt, yc, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
}
|
||||
else if (strcmp(yang_argument_get(yc), "identityref") == 0){
|
||||
if ((ret = validate_identityref(xt, ys, yc, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -2557,7 +2564,7 @@ api_path2xml_vec(char **vec,
|
|||
else{
|
||||
if ((valvec = clicon_strsep(restval, ",", &nvalvec)) == NULL)
|
||||
goto done;
|
||||
if (nvalvec != cvec_len(cvk)){
|
||||
if ((nvalvec != cvec_len(cvk)) && strict){
|
||||
clicon_err(OE_XML, EINVAL, "List key %s length mismatch", name);
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -59,8 +59,9 @@
|
|||
#include "clixon_handle.h"
|
||||
#include "clixon_yang.h"
|
||||
#include "clixon_xml.h"
|
||||
#include "clixon_xpath_parse.h"
|
||||
#include "clixon_xpath_ctx.h"
|
||||
#include "clixon_xpath.h"
|
||||
#include "clixon_xpath_parse.h"
|
||||
|
||||
/*
|
||||
* Variables
|
||||
|
|
|
|||
1062
lib/src/clixon_xpath_eval.c
Normal file
1062
lib/src/clixon_xpath_eval.c
Normal file
File diff suppressed because it is too large
Load diff
49
lib/src/clixon_xpath_eval.h
Normal file
49
lib/src/clixon_xpath_eval.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
*
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren
|
||||
|
||||
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 *****
|
||||
|
||||
* Clixon XML XPATH 1.0 according to https://www.w3.org/TR/xpath-10
|
||||
*/
|
||||
#ifndef _CLIXON_XPATH_EVAL_H
|
||||
#define _CLIXON_XPATH_EVAL_H
|
||||
|
||||
/*
|
||||
* Variables
|
||||
*/
|
||||
extern const map_str2int xpopmap[];
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
int xp_eval(xp_ctx *xc, xpath_tree *xs, cvec *nsc, xp_ctx **xrp);
|
||||
|
||||
#endif /* _CLIXON_XPATH_EVAL_H */
|
||||
|
|
@ -39,40 +39,6 @@
|
|||
/*
|
||||
* Types
|
||||
*/
|
||||
/* used as non-terminal type in yacc rules */
|
||||
enum xp_type{
|
||||
XP_EXP,
|
||||
XP_AND,
|
||||
XP_RELEX,
|
||||
XP_ADD,
|
||||
XP_UNION,
|
||||
XP_PATHEXPR,
|
||||
XP_LOCPATH,
|
||||
XP_ABSPATH,
|
||||
XP_RELLOCPATH,
|
||||
XP_STEP,
|
||||
XP_NODE, /* s0 is namespace prefix, s1 is name */
|
||||
XP_NODE_FN,
|
||||
XP_PRED,
|
||||
XP_PRI0,
|
||||
XP_PRIME_NR,
|
||||
XP_PRIME_STR,
|
||||
XP_PRIME_FN,
|
||||
};
|
||||
|
||||
/*! XPATH Parsing generates a tree of nodes that is later traversed
|
||||
*/
|
||||
struct xpath_tree{
|
||||
enum xp_type xs_type;
|
||||
int xs_int;
|
||||
double xs_double;
|
||||
char *xs_s0;
|
||||
char *xs_s1;
|
||||
struct xpath_tree *xs_c0; /* child 0 */
|
||||
struct xpath_tree *xs_c1; /* child 1 */
|
||||
};
|
||||
typedef struct xpath_tree xpath_tree;
|
||||
|
||||
struct clicon_xpath_yacc_arg{ /* XXX: mostly unrelevant */
|
||||
const char *xy_name; /* Name of syntax (for error string) */
|
||||
int xy_linenum; /* Number of \n in parsed buffer */
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
#include "clixon_xpath_ctx.h"
|
||||
#include "clixon_xpath.h"
|
||||
#include "clixon_xpath_parse.h"
|
||||
#include "clixon_xpath_eval.h"
|
||||
|
||||
/* Redefine main lex function so that you can send arguments to it: _yy is added to arg list */
|
||||
#define YY_DECL int clixon_xpath_parselex(void *_yy)
|
||||
|
|
|
|||
|
|
@ -588,6 +588,105 @@ cv_validate_pattern(clicon_handle h,
|
|||
(rmax && (i) > cv_##type##_get(rmax)))
|
||||
|
||||
|
||||
/*! Error messsage for int violating ranges
|
||||
* @note contains kludge - duplicate loop
|
||||
*/
|
||||
static int
|
||||
outofrange(cg_var *cv0,
|
||||
cvec *cvv,
|
||||
char **reason)
|
||||
{
|
||||
int retval = -1;
|
||||
cbuf *cb = NULL;
|
||||
cg_var *cv1;
|
||||
cg_var *cv2;
|
||||
int i;
|
||||
|
||||
if ((cb = cbuf_new()) == NULL)
|
||||
goto done;
|
||||
cprintf(cb, "Number ");
|
||||
cv2cbuf(cv0, cb);
|
||||
cprintf(cb, " out of range: ");
|
||||
/* Kludge: need to repeat the same loop as in the main function in
|
||||
cv_validate1 */
|
||||
i = 0;
|
||||
while (i<cvec_len(cvv)){
|
||||
cv1 = cvec_i(cvv, i++); /* Increment to check for max pair */
|
||||
if (strcmp(cv_name_get(cv1),"range_min") != 0){
|
||||
clicon_err(OE_YANG, EINVAL, "Internal error, expected range_min");
|
||||
goto done;
|
||||
}
|
||||
if (i<cvec_len(cvv) &&
|
||||
(cv2 = cvec_i(cvv, i)) != NULL &&
|
||||
strcmp(cv_name_get(cv2),"range_max") == 0){
|
||||
i++;
|
||||
}
|
||||
else
|
||||
cv2 = cv1;
|
||||
if (i>2)
|
||||
cprintf(cb, ", ");
|
||||
cv2cbuf(cv1, cb);
|
||||
cprintf(cb, " - ");
|
||||
cv2cbuf(cv2, cb);
|
||||
}
|
||||
if (reason && (*reason = strdup(cbuf_get(cb))) == NULL)
|
||||
goto done;
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Error messsage for string violating string limits
|
||||
* @note contains kludge - duplicate loop
|
||||
*/
|
||||
static int
|
||||
outoflength(uint64_t u64,
|
||||
cvec *cvv,
|
||||
char **reason)
|
||||
{
|
||||
int retval = -1;
|
||||
cbuf *cb = NULL;
|
||||
cg_var *cv1;
|
||||
cg_var *cv2;
|
||||
int i;
|
||||
|
||||
if ((cb = cbuf_new()) == NULL)
|
||||
goto done;
|
||||
cprintf(cb, "String length %" PRIu64 " out of range: ", u64);
|
||||
|
||||
/* Kludge: need to repeat the same loop as in the main function in
|
||||
cv_validate1 */
|
||||
i = 0;
|
||||
while (i<cvec_len(cvv)){
|
||||
cv1 = cvec_i(cvv, i++); /* Increment to check for max pair */
|
||||
if (strcmp(cv_name_get(cv1),"range_min") != 0){
|
||||
clicon_err(OE_YANG, EINVAL, "Internal error, expected range_min");
|
||||
goto done;
|
||||
}
|
||||
if (i<cvec_len(cvv) &&
|
||||
(cv2 = cvec_i(cvv, i)) != NULL &&
|
||||
strcmp(cv_name_get(cv2),"range_max") == 0){
|
||||
i++;
|
||||
}
|
||||
else
|
||||
cv2 = cv1;
|
||||
if (i>2)
|
||||
cprintf(cb, ", ");
|
||||
cv2cbuf(cv1, cb);
|
||||
cprintf(cb, " - ");
|
||||
cv2cbuf(cv2, cb);
|
||||
}
|
||||
if (reason && (*reason = strdup(cbuf_get(cb))) == NULL)
|
||||
goto done;
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Validate CLIgen variable
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] cv A cligen variable to validate. This is a correctly parsed cv.
|
||||
|
|
@ -600,6 +699,7 @@ cv_validate_pattern(clicon_handle h,
|
|||
* @retval 0 Validation not OK, malloced reason is returned. Free reason with free()
|
||||
* @retval 1 Validation OK
|
||||
* @note reason if given must be freed by caller
|
||||
* @see cv_validate Corresponding type check in cligen
|
||||
*/
|
||||
static int
|
||||
cv_validate1(clicon_handle h,
|
||||
|
|
@ -705,14 +805,13 @@ cv_validate1(clicon_handle h,
|
|||
/* Check fails */
|
||||
if (i==cvec_len(cvv)){ /* And it is last */
|
||||
if (reason){
|
||||
if (reti)
|
||||
*reason = cligen_reason("Number out of range: %"
|
||||
PRId64, ii);
|
||||
else if (retu)
|
||||
*reason = cligen_reason("Number out of range: %"
|
||||
PRIu64, uu);
|
||||
if (reti || retu){
|
||||
if (outofrange(cv, cvv, reason) < 0)
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
*reason = cligen_reason("string length out of range: %" PRIu64, uu);
|
||||
if (outoflength(uu, cvv, reason) < 0)
|
||||
goto done;
|
||||
}
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -1317,13 +1416,14 @@ yang_type_resolve(yang_stmt *yorig,
|
|||
*
|
||||
* @code
|
||||
* yang_stmt *yrestype;
|
||||
* char *origtype = NULL;
|
||||
* int options;
|
||||
* cvec *cvv = NULL;
|
||||
* cvec *patterns = cvec_new(0);
|
||||
* cvec *regexps = cvec_new(0);
|
||||
* uint8_t fraction;
|
||||
*
|
||||
* if (yang_type_get(ys, &type, &yrestype, &options, &cvv,
|
||||
* if (yang_type_get(ys, &origtype, &yrestype, &options, &cvv,
|
||||
* patterns, regexps, &fraction) < 0)
|
||||
* goto err;
|
||||
* if (yrestype == NULL) # unresolved
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
: ${pattern:=test_*.sh}
|
||||
|
||||
if [ $# -gt 0 ]; then
|
||||
echo "usage: $0 # detailed logs and stopon first error"
|
||||
echo "usage: $0 # detailed logs and stop on first error. Use pattern=\"\" $0 to"
|
||||
echo " Use pattern=<pattern> $0 to narrow down test cases"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
|
|
|
|||
17
test/mem.sh
17
test/mem.sh
|
|
@ -86,7 +86,20 @@ done
|
|||
testnr=0
|
||||
for c in $cmds; do
|
||||
if [ $testnr != 0 ]; then echo; fi
|
||||
echo "Mem test for $c"
|
||||
echo "================="
|
||||
echo "Mem test $c begin"
|
||||
length=$(echo "Mem test $c begin" | wc -c)
|
||||
let i=1
|
||||
while [ $i -lt $length ]; do
|
||||
echo -n "="
|
||||
let i++
|
||||
done
|
||||
echo
|
||||
memonce $c
|
||||
echo "Mem test $c done"
|
||||
let i=1
|
||||
while [ $i -lt $length ]; do
|
||||
echo -n "="
|
||||
let i++
|
||||
done
|
||||
echo
|
||||
done
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
# mandatory-leaf See RFC7950 Sec 7.17
|
||||
|
|
|
|||
|
|
@ -124,7 +124,9 @@ new "start restconf daemon"
|
|||
start_restconf -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
wait_restconf
|
||||
|
||||
|
||||
# First vanilla (protocol) case
|
||||
new "netconf validate empty"
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
new "cli read and add entry to existing history"
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
new "cli enabled feature"
|
||||
|
|
|
|||
|
|
@ -106,7 +106,37 @@ cat <<EOF > $fyang
|
|||
container aes-parameters {
|
||||
when "../crypto = 'mc:aes'";
|
||||
}
|
||||
}
|
||||
identity acl-base;
|
||||
typedef acl-type {
|
||||
description "problem detected in ietf-access-control-list.yang";
|
||||
type identityref {
|
||||
base acl-base;
|
||||
}
|
||||
}
|
||||
identity ipv4-acl-type {
|
||||
base mc:acl-base;
|
||||
}
|
||||
identity ipv6-acl-type {
|
||||
base mc:acl-base;
|
||||
}
|
||||
container acls {
|
||||
list acl {
|
||||
key name;
|
||||
leaf name {
|
||||
type string;
|
||||
}
|
||||
leaf type {
|
||||
type acl-type;
|
||||
}
|
||||
}
|
||||
}
|
||||
identity empty; /* some errors with an empty identity set */
|
||||
leaf e {
|
||||
type identityref {
|
||||
base mc:empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
new "test params: -f $cfg"
|
||||
|
|
@ -120,7 +150,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
new "Set crypto to aes"
|
||||
|
|
@ -186,6 +216,43 @@ expectfn "$clixon_cli -1 -f $cfg -l o set crypto des:des3" 0 "^$"
|
|||
new "cli validate"
|
||||
expectfn "$clixon_cli -1 -f $cfg -l o validate" 0 "^$"
|
||||
|
||||
new "Netconf set acl-type"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><acls xmlns="urn:example:my-crypto"><acl><name>x</name><type>mc:ipv4-acl-type</type></acl></acls></config></edit-config></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||
|
||||
new "netconf validate "
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "Netconf set undefined acl-type"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><acls xmlns="urn:example:my-crypto"><acl><name>x</name><type>undefined</type></acl></acls></config></edit-config></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||
|
||||
new "netconf validate fail"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>operation-failed</error-tag><error-severity>error</error-severity><error-message>Identityref validation failed, mc:undefined not derived from acl-base</error-message></rpc-error></rpc-reply>]]>]]>'
|
||||
|
||||
new "netconf discard-changes"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "CLI set acl-type"
|
||||
expectfn "$clixon_cli -1 -f $cfg -l o set acls acl x type mc:ipv4-acl-type" 0 "^$"
|
||||
|
||||
new "cli validate"
|
||||
expectfn "$clixon_cli -1 -f $cfg -l o validate" 0 "^$"
|
||||
|
||||
new "CLI set wrong acl-type"
|
||||
expectfn "$clixon_cli -1 -f $cfg -l o set acls acl x type undefined" 0 "^$"
|
||||
|
||||
new "cli validate"
|
||||
expectfn "$clixon_cli -1 -f $cfg -l o validate" 255 "Identityref validation failed"
|
||||
|
||||
# test empty identityref list
|
||||
new "cli set empty"
|
||||
expectfn "$clixon_cli -1 -f $cfg -l o set e undefined" 0 "^$"
|
||||
|
||||
new "cli validate"
|
||||
expectfn "$clixon_cli -1 -f $cfg -l o validate" 255 "Identityref validation failed"
|
||||
|
||||
new "netconf discard-changes"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
if [ $BE -eq 0 ]; then
|
||||
exit # BE
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ cat <<EOF > $cfg
|
|||
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
|
||||
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
|
||||
<CLICON_XMLDB_DIR>$dir</CLICON_XMLDB_DIR>
|
||||
<CLICON_XMLDB_CACHE>true</CLICON_XMLDB_CACHE>
|
||||
</clixon-config>
|
||||
EOF
|
||||
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
new "leafref base config"
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
new "minmax: minimal"
|
||||
|
|
|
|||
|
|
@ -124,16 +124,15 @@ fi
|
|||
new "kill old restconf daemon"
|
||||
sudo pkill -u www-data -f "/www-data/clixon_restconf"
|
||||
|
||||
sleep 1
|
||||
new "start restconf daemon (-a is enable basic authentication)"
|
||||
start_restconf -f $cfg -- -a
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
wait_restconf
|
||||
|
||||
new "auth get"
|
||||
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" 0 'null
|
||||
'
|
||||
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" 0 '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-type": "application","error-tag": "invalid-value","error-severity": "error","error-message": "Instance does not exist"}}}}
'
|
||||
|
||||
# explicitly disable nacm (regression on netgate bug)
|
||||
new "disable nacm"
|
||||
|
|
|
|||
|
|
@ -101,14 +101,12 @@ EOF
|
|||
new "kill old restconf daemon"
|
||||
sudo pkill -u www-data -f "/www-data/clixon_restconf"
|
||||
|
||||
sleep 1
|
||||
new "start restconf daemon (-a is enable basic authentication)"
|
||||
start_restconf -f $cfg -- -a
|
||||
|
||||
new "waiting"
|
||||
wait_backend
|
||||
wait_restconf
|
||||
|
||||
|
||||
#----------- First get
|
||||
case "$ret1" in
|
||||
|
|
@ -117,8 +115,7 @@ EOF
|
|||
;;
|
||||
1) ret='{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "access-denied","error-severity": "error","error-message": "default deny"}}}
'
|
||||
;;
|
||||
2) ret='null
|
||||
'
|
||||
2) ret='{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-type": "application","error-tag": "invalid-value","error-severity": "error","error-message": "Instance does not exist"}}}}
'
|
||||
;;
|
||||
esac
|
||||
|
||||
|
|
@ -142,8 +139,7 @@ EOF
|
|||
;;
|
||||
1) ret='{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "access-denied","error-severity": "error","error-message": "default deny"}}}
'
|
||||
;;
|
||||
2) ret='null
|
||||
'
|
||||
2) ret='{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-type": "application","error-tag": "invalid-value","error-severity": "error","error-message": "Instance does not exist"}}}}
'
|
||||
;;
|
||||
3) ret='{"nacm-example:x": 42}
|
||||
'
|
||||
|
|
|
|||
|
|
@ -139,12 +139,12 @@ fi
|
|||
new "kill old restconf daemon"
|
||||
sudo pkill -u www-data -f "/www-data/clixon_restconf"
|
||||
|
||||
sleep 1
|
||||
new "start restconf daemon (-a is enable basic authentication)"
|
||||
start_restconf -f $cfg -- -a
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
wait_restconf
|
||||
|
||||
new "auth set authentication config"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><edit-config><target><candidate/></target><config>$RULES</config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
@ -200,8 +200,7 @@ expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/clixon-e
|
|||
'
|
||||
|
||||
new "limit read other module fail"
|
||||
expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" 0 'null
|
||||
'
|
||||
expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" 0 '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-type": "application","error-tag": "invalid-value","error-severity": "error","error-message": "Instance does not exist"}}}}
'
|
||||
|
||||
new "limit read state OK"
|
||||
expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/clixon-example:state)" 0 '{"clixon-example:state": {"op": ["42","41","43"]}}
|
||||
|
|
|
|||
|
|
@ -148,12 +148,12 @@ fi
|
|||
new "kill old restconf daemon"
|
||||
sudo pkill -u www-data -f "/www-data/clixon_restconf"
|
||||
|
||||
sleep 1
|
||||
new "start restconf daemon (-a is enable basic authentication)"
|
||||
start_restconf -f $cfg -- -a
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
wait_restconf
|
||||
|
||||
# Set nacm from scratch
|
||||
nacm(){
|
||||
|
|
|
|||
|
|
@ -148,12 +148,12 @@ fi
|
|||
new "kill old restconf daemon"
|
||||
sudo pkill -u www-data -f "/www-data/clixon_restconf"
|
||||
|
||||
sleep 1
|
||||
new "start restconf daemon (-a is enable basic authentication)"
|
||||
start_restconf -f $cfg -- -a
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
wait_restconf
|
||||
|
||||
new "auth set authentication config"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><edit-config><target><candidate/></target><config>$RULES</config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
@ -191,9 +191,8 @@ expecteq "$(curl -u guest:bar -sS -X DELETE http://localhost/restconf/data)" 0 '
|
|||
new "deny-delete-config: limited fail (restconf) ok"
|
||||
expecteq "$(curl -u wilma:bar -sS -X DELETE http://localhost/restconf/data)" 0 ''
|
||||
|
||||
new "admin get nacm (should be null)"
|
||||
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" 0 'null
|
||||
'
|
||||
new "admin get nacm (should fail)"
|
||||
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" 0 '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-type": "application","error-tag": "invalid-value","error-severity": "error","error-message": "Instance does not exist"}}}}
'
|
||||
|
||||
new "deny-delete-config: admin ok (restconf)"
|
||||
expecteq "$(curl -u andy:bar -sS -X DELETE http://localhost/restconf/data)" 0 ''
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s running -f $cfg -- -s
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
# STATE (should not be ordered)
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ new "restconf DELETE"
|
|||
expectfn 'curl -s -X DELETE http://localhost/restconf/data/example:cont1' 0 ""
|
||||
|
||||
new "restconf GET null datastore"
|
||||
expectfn "curl -s -X GET http://localhost/restconf/data/example:cont1" 0 'null'
|
||||
expectfn "curl -s -X GET http://localhost/restconf/data/example:cont1" 0 '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-type": "application","error-tag": "invalid-value","error-severity": "error","error-message": "Instance does not exist"}}}}'
|
||||
|
||||
new "restconf POST initial tree"
|
||||
expectfn 'curl -s -X POST -d {"example:cont1":{"interface":{"name":"local0","type":"regular"}}} http://localhost/restconf/data' 0 ""
|
||||
|
|
@ -149,7 +149,7 @@ new "restconf DELETE whole datastore"
|
|||
expectfn 'curl -s -X DELETE http://localhost/restconf/data' 0 ""
|
||||
|
||||
new "restconf GET null datastore"
|
||||
expectfn "curl -s -X GET http://localhost/restconf/data/example:cont1" 0 'null'
|
||||
expectfn "curl -s -X GET http://localhost/restconf/data/example:cont1" 0 '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-type": "application","error-tag": "invalid-value","error-severity": "error","error-message": "Instance does not exist"}}}}'
|
||||
|
||||
new "restconf PUT initial datastore"
|
||||
expectfn 'curl -s -X PUT -d {"data":{"example:cont1":{"interface":{"name":"local0","type":"regular"}}}} http://localhost/restconf/data' 0 ""
|
||||
|
|
|
|||
120
test/test_restconf_err.sh
Executable file
120
test/test_restconf_err.sh
Executable file
|
|
@ -0,0 +1,120 @@
|
|||
#!/bin/bash
|
||||
# Restconf error-code functionality
|
||||
# See RFC8040
|
||||
# Testcases:
|
||||
# Sec 4.3 (GET): If a retrieval request for a data resource represents an
|
||||
# instance that does not exist, then an error response containing a "404 Not
|
||||
# Found" status-line MUST be returned by the server. The error-tag
|
||||
# value "invalid-value" is used in this case.
|
||||
|
||||
# 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.xml
|
||||
fyang=$dir/restconf.yang
|
||||
fxml=$dir/initial.xml
|
||||
|
||||
# <CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN>
|
||||
cat <<EOF > $cfg
|
||||
<clixon-config xmlns="http://clicon.org/config">
|
||||
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
||||
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
|
||||
<CLICON_RESTCONF_PRETTY>false</CLICON_RESTCONF_PRETTY>
|
||||
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
|
||||
<CLICON_BACKEND_PIDFILE>$dir/restconf.pidfile</CLICON_BACKEND_PIDFILE>
|
||||
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
|
||||
</clixon-config>
|
||||
EOF
|
||||
|
||||
cat <<EOF > $fyang
|
||||
module example{
|
||||
yang-version 1.1;
|
||||
namespace "urn:example:clixon";
|
||||
prefix ex;
|
||||
list a {
|
||||
key k;
|
||||
leaf k {
|
||||
type int32;
|
||||
}
|
||||
leaf description{
|
||||
type string;
|
||||
}
|
||||
leaf b{
|
||||
type string;
|
||||
}
|
||||
container c{
|
||||
presence "for test";
|
||||
}
|
||||
list d{
|
||||
key k;
|
||||
leaf k {
|
||||
type string;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Initial tree
|
||||
XML=$(cat <<EOF
|
||||
<a xmlns="urn:example:clixon"><k>0</k><description>No leaf b, No container c, No leaf d</description></a>
|
||||
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
|
||||
sudo pkill clixon_backend # to be sure
|
||||
new "start backend -s init -f $cfg"
|
||||
start_backend -s init -f $cfg
|
||||
fi
|
||||
|
||||
new "kill old restconf daemon"
|
||||
sudo pkill -u www-data -f "/www-data/clixon_restconf"
|
||||
|
||||
new "start restconf daemon"
|
||||
start_restconf -f $cfg
|
||||
|
||||
new "waiting"
|
||||
wait_backend
|
||||
wait_restconf
|
||||
|
||||
new "restconf POST initial tree"
|
||||
expecteq "$(curl -s -X POST -H 'Content-Type: application/yang-data+xml' -d "$XML" http://localhost/restconf/data)" 0 ''
|
||||
|
||||
new "restconf GET initial datastore"
|
||||
expecteq "$(curl -s -X GET -H 'Accept: application/yang-data+xml' http://localhost/restconf/data/example:a)" 0 "$XML
|
||||
"
|
||||
|
||||
new "restconf GET non-existent container header"
|
||||
expectfn "curl -s -I -X GET http://localhost/restconf/data/example:a/c" 0 "HTTP/1.1 404 Not Found"
|
||||
|
||||
new "restconf GET non-existent container body"
|
||||
expectfn "curl -s -X GET http://localhost/restconf/data/example:a/c" 0 '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-type": "application","error-tag": "invalid-value","error-severity": "error","error-message": "Instance does not exist"}}}}'
|
||||
|
||||
new "Kill restconf daemon"
|
||||
stop_restconf
|
||||
|
||||
if [ $BE -eq 0 ]; then
|
||||
exit # BE
|
||||
fi
|
||||
|
||||
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
|
||||
|
||||
rm -rf $dir
|
||||
|
|
@ -68,7 +68,8 @@ testrun(){
|
|||
start_restconf -f $cfg -y $fyang $option
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
wait_restconf
|
||||
|
||||
new "restconf put 42"
|
||||
expecteq "$(curl -s -X PUT http://localhost/restconf/data/example:x/y=42 -d '{"example:y":{"a":"42","b":"42"}}')" 0 ""
|
||||
|
|
|
|||
|
|
@ -50,7 +50,9 @@ new "start restconf daemon"
|
|||
start_restconf -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
wait_restconf
|
||||
|
||||
|
||||
new "rpc tests"
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ testrun(){
|
|||
start_backend -s $mode -f $cfg -c $dir/extra_db
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
else
|
||||
new "Restart backend as eg follows: -Ff $cfg -s $mode -c $dir/extra_db # $BETIMEOUT s"
|
||||
sleep $BETIMEOUT
|
||||
|
|
|
|||
|
|
@ -121,8 +121,9 @@ if [ $BE -ne 0 ]; then
|
|||
fi
|
||||
new "start backend -s init -f $cfg -l f$flog -- -t /x/y[a=$errnr]"
|
||||
start_backend -s init -f $cfg -l f$flog -- -t /x/y[a=$errnr] # -t means transaction logging
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
let nr=0
|
||||
|
|
@ -177,7 +178,7 @@ new "3. Validate system-error config (9999 not in range)"
|
|||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><edit-config><target><candidate/></target><config><x xmlns='urn:example:clixon'><y><a>$nr</a><b>9999</b></y></x></config></edit-config></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||
|
||||
new "Validate system-error validate (should fail)"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>b</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: 9999</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>b</bad-element></error-info><error-severity>error</error-severity><error-message>Number 9999 out of range: 0 - 100</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||
|
||||
new "Validate system-error discard-changes"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
|
|||
|
|
@ -192,6 +192,10 @@ module example{
|
|||
pattern '[a-zA-Z_][a-zA-Z0-9_\-.]*';
|
||||
}
|
||||
}
|
||||
leaf bool {
|
||||
description "For testing different truth values in CLI";
|
||||
type boolean;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
|
|
@ -231,14 +235,14 @@ EOF
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
new "cli set transitive string. type is alpha followed by number and is defined in three levels of modules"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set c talle x99" 0 '^$'
|
||||
|
||||
new "cli set transitive string error. Wrong type"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set c talle 9xx" 255 '^CLI syntax error: "set c talle 9xx": Unknown command$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set c talle 9xx" 255 '^CLI syntax error: "set c talle 9xx": regexp match fail: 9xx does not match \[a-z\]\[0-9\]\*$'
|
||||
|
||||
new "netconf discard-changes"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
@ -266,10 +270,10 @@ EOF
|
|||
expectfn "$clixon_cli -1f $cfg -l o -l o validate" 0 '^$'
|
||||
|
||||
new "cli set transitive union error. should fail"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set c ulle kalle" 255 '^CLI syntax error: "set c ulle kalle": Unknown command$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set c ulle kalle" 255 "^CLI syntax error: \"set c ulle kalle\": 'kalle' is not a number$"
|
||||
|
||||
new "cli set transitive union error int"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set c ulle 55" 255 '^CLI syntax error: "set c ulle 55": Unknown command$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set c ulle 55" 255 '^CLI syntax error: "set c ulle 55": Number 55 out of range: 4 - 44$'
|
||||
|
||||
new "netconf set transitive union error int"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><c xmlns="urn:example:clixon"><ulle>55</ulle></c></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>"
|
||||
|
|
@ -354,13 +358,13 @@ EOF
|
|||
#expectfn "$clixon_cli -1f $cfg -l o set num1 \-100" 0 '^$'
|
||||
|
||||
new "cli range test num1 2 error"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num1 2" 255 '^CLI syntax error: "set num1 2": Unknown command$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num1 2" 255 '^CLI syntax error: "set num1 2": Number 2 out of range: 1 - 1$'
|
||||
|
||||
new "netconf range set num1 -1"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><num1 xmlns="urn:example:clixon">-1</num1></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf validate num1 -1 wrong"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num1</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: -1</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num1</bad-element></error-info><error-severity>error</error-severity><error-message>Number -1 out of range: 1 - 1</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||
|
||||
new "netconf discard-changes"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
@ -368,19 +372,19 @@ EOF
|
|||
#-------- num2 range and blanks
|
||||
|
||||
new "cli range test num2 3 error"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num2 3" 255 '^CLI syntax error: "set num2 3": Number out of range: 3$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num2 3" 255 '^CLI syntax error: "set num2 3": Number 3 out of range: 4 - 4000$'
|
||||
|
||||
new "cli range test num2 1000 ok"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num2 1000" 0 '^$'
|
||||
|
||||
new "cli range test num2 5000 error"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num2 5000" 255 '^CLI syntax error: "set num2 5000": Unknown command$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num2 5000" 255 '^CLI syntax error: "set num2 5000": Number 5000 out of range: 4 - 4000$'
|
||||
|
||||
new "netconf range set num2 3 fail"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">3</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf validate num2 3 fail"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num2</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: 3</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num2</bad-element></error-info><error-severity>error</error-severity><error-message>Number 3 out of range: 4 - 4000</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||
|
||||
new "netconf range set num2 1000 ok"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">1000</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
@ -392,7 +396,7 @@ EOF
|
|||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">5000</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf validate num2 5000 fail"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num2</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: 5000</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num2</bad-element></error-info><error-severity>error</error-severity><error-message>Number 5000 out of range: 4 - 4000</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||
|
||||
new "netconf discard-changes"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
@ -403,7 +407,7 @@ EOF
|
|||
expectfn "$clixon_cli -1f $cfg -l o set num3 42" 0 '^$'
|
||||
|
||||
new "cli range test num3 260 fail"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num3 260" 255 '^CLI syntax error: "set num3 260": Unknown command$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num3 260" 255 '^CLI syntax error: "set num3 260": Number 260 out of range: 0 - 255$'
|
||||
|
||||
new "cli range test num3 -1 fail"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num3 -1" 255 "CLI syntax error:"
|
||||
|
|
@ -412,7 +416,7 @@ EOF
|
|||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><num3 xmlns="urn:example:clixon">260</num3></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf validate num3 260 fail"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num3</bad-element></error-info><error-severity>error</error-severity><error-message>260 is out of range(type is uint8)</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num3</bad-element></error-info><error-severity>error</error-severity><error-message>Number 260 out of range: 0 - 255</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||
|
||||
new "netconf discard-changes"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
@ -420,19 +424,19 @@ EOF
|
|||
#-------- num4 multiple ranges 1..2 | 42..50
|
||||
|
||||
new "cli range test num4 multiple 0 fail"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num4 0" 255 '^CLI syntax error: "set num4 0": Number out of range: 0$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num4 0" 255 '^CLI syntax error: "set num4 0": Number 0 out of range: 1 - 2, 42 - 50$'
|
||||
|
||||
new "cli range test num4 multiple 2 ok"
|
||||
expectfn "$clixon_cli -1f $cfg -l e set num4 2" 0 '^$'
|
||||
|
||||
new "cli range test num4 multiple 20 fail"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num4 20" 255 '^CLI syntax error: "set num4 20": Unknown command$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num4 20" 255 '^CLI syntax error: "set num4 20": Number 20 out of range: 1 - 2, 42 - 50$'
|
||||
|
||||
new "cli range test num4 multiple 42 ok"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num4 42" 0 '^$'
|
||||
|
||||
new "cli range test num4 multiple 99 fail"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num4 99" 255 '^CLI syntax error: "set num4 99": Unknown command$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set num4 99" 255 '^CLI syntax error: "set num4 99": Number 99 out of range: 1 - 2, 42 - 50$'
|
||||
|
||||
new "netconf range set num4 multiple 2"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
@ -467,7 +471,7 @@ EOF
|
|||
expectfn "$clixon_cli -1f $cfg -l o set dec 15.0" 0 '^$'
|
||||
|
||||
new "cli range dec64 multiple 30.0 fail"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set dec 30.0" 255 '^CLI syntax error: "set dec 30.0": Unknown command$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set dec 30.0" 255 '^CLI syntax error: "set dec 30.0": Number 30.000 out of range: -3.500 - -2.500, 0.000 - 0.000, 10.000 - 20.000$'
|
||||
|
||||
new "dec64 discard-changes"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
@ -477,7 +481,7 @@ EOF
|
|||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-3.59</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf range dec64 -3.59 validate fail"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number -3.590 out of range'
|
||||
|
||||
new "netconf range dec64 -3.5"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-3.500</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
@ -489,13 +493,13 @@ EOF
|
|||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-2</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf range dec64 -2 validate fail"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number -2.000 out of range'
|
||||
|
||||
new "netconf range dec64 -0.001"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">-0.001</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf range dec64 -0.001 validate fail"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number -0.001 out of range'
|
||||
|
||||
new "netconf range dec64 0.0"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">0.0</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
@ -507,18 +511,18 @@ EOF
|
|||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><dec xmlns="urn:example:clixon">+0.001</dec></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf range dec64 +0.001 validate fail"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range'
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>dec</bad-element></error-info><error-severity>error</error-severity><error-message>Number 0.001 out of range'
|
||||
|
||||
#----------------string ranges---------------------
|
||||
#-------- len1 single range (2)
|
||||
new "cli length test len1 1 fail"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set len1 x" 255 '^CLI syntax error: "set len1 x": String length not within limits: 1$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set len1 x" 255 '^CLI syntax error: "set len1 x": String length 1 out of range: 2 - 2$'
|
||||
|
||||
new "cli length test len1 2 OK"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set len1 xy" 0 '^$'
|
||||
|
||||
new "cli length test len1 3 error"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set len1 hej" 255 '^CLI syntax error: "set len1 hej": Unknown command$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set len1 hej" 255 '^CLI syntax error: "set len1 hej": String length 3 out of range: 2 - 2$'
|
||||
|
||||
new "netconf discard-changes"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
@ -527,12 +531,12 @@ EOF
|
|||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><len1 xmlns="urn:example:clixon">x</len1></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf validate len1 1 wrong"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>len1</bad-element></error-info><error-severity>error</error-severity><error-message>string length out of range: 1</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>len1</bad-element></error-info><error-severity>error</error-severity><error-message>String length 1 out of range: 2 - 2</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||
|
||||
#-------- len2 range and blanks
|
||||
|
||||
new "cli length test len2 3 error"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set len2 ab" 255 '^CLI syntax error: "set len2 ab": String length not within limits: 2$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set len2 ab" 255 '^CLI syntax error: "set len2 ab": String length 2 out of range: 4 - 4000$'
|
||||
|
||||
new "cli length test len2 42 ok"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set len2 hejhophdsakjhkjsadhkjsahdkjsad" 0 '^$'
|
||||
|
|
@ -547,32 +551,32 @@ EOF
|
|||
|
||||
#-------- len4 multiple ranges 2..3 | 20-29
|
||||
new "cli length test len4 1 error"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set len4 a" 255 '^CLI syntax error: "set len4 a": String length not within limits: 1$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set len4 a" 255 '^CLI syntax error: "set len4 a": String length 1 out of range: 2 - 3, 20 - 29$'
|
||||
|
||||
new "cli length test len4 2 ok"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set len4 ab" 0 '^$'
|
||||
|
||||
new "cli length test len4 10 error"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghij" 255 '^CLI syntax error: "set len4 abcdefghij": Unknown command$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghij" 255 '^CLI syntax error: "set len4 abcdefghij": String length 10 out of range: 2 - 3, 20 - 29$'
|
||||
|
||||
new "cli length test len4 20 ok"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghijabcdefghija" 0 '^$'
|
||||
|
||||
new "cli length test len4 30 error"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghijabcdefghijabcdefghij" 255 '^CLI syntax error: "set len4 abcdefghijabcdefghijabcdefghij": Unknown command$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghijabcdefghijabcdefghij" 255 '^CLI syntax error: "set len4 abcdefghijabcdefghijabcdefghij": String length 30 out of range: 2 - 3, 20 - 29$'
|
||||
|
||||
# XSD schema -> POSIX ECE translation
|
||||
new "cli yang pattern \d ok"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set digit4 0123" 0 '^$'
|
||||
|
||||
new "cli yang pattern \d error"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set digit4 01b2" 255 '^CLI syntax error: "set digit4 01b2": Unknown command$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set digit4 01b2" 255 '^CLI syntax error: "set digit4 01b2": regexp match fail: 01b2 does not match'
|
||||
|
||||
new "cli yang pattern \w ok"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set word4 abc9" 0 '^$'
|
||||
|
||||
new "cli yang pattern \w error"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set word4 ab%3" 255 '^CLI syntax error: "set word4 ab%3": Unknown command$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set word4 ab%3" 255 '^CLI syntax error: "set word4 ab%3": regexp match fail: ab%3 does not match'
|
||||
|
||||
new "netconf pattern \w"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><word4 xmlns="urn:example:clixon">aXG9</word4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
@ -589,7 +593,6 @@ EOF
|
|||
new "netconf discard-changes"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
|
||||
#------ minus
|
||||
|
||||
new "type with minus"
|
||||
|
|
@ -601,6 +604,27 @@ EOF
|
|||
#new "cli type with minus"
|
||||
#expectfn "$clixon_cli -1f $cfg -l o set name my-name" 0 '^$'
|
||||
|
||||
#------ cli truth-values: true/on/enable false/off/disable
|
||||
|
||||
new "cli truth: true"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set bool true" 0 '^$'
|
||||
new "cli truth: false"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set bool false" 0 '^$'
|
||||
new "cli truth: on"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set bool on" 0 '^$'
|
||||
new "cli verify on translates to true"
|
||||
expectfn "$clixon_cli -1f $cfg -l o show conf" 0 'bool true;'
|
||||
new "cli truth: off"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set bool off" 0 '^$'
|
||||
new "cli verify off translates to false"
|
||||
expectfn "$clixon_cli -1f $cfg -l o show conf" 0 'bool false;'
|
||||
new "cli truth: enable"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set bool enable" 0 '^$'
|
||||
new "cli truth: disable"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set bool disable" 0 '^$'
|
||||
new "cli truth: wrong"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set bool wrong" 255 "'wrong' is not a boolean value"
|
||||
|
||||
if [ $BE -ne 0 ]; then
|
||||
new "Kill backend"
|
||||
# Check if premature kill
|
||||
|
|
@ -619,7 +643,7 @@ testrun nocache
|
|||
# Run with db cache
|
||||
testrun cache
|
||||
|
||||
# Run with
|
||||
testrun cache-zerocopy
|
||||
# Run with zero-copy XXX does not work
|
||||
#testrun cache-zerocopy
|
||||
|
||||
rm -rf $dir
|
||||
|
|
|
|||
317
test/test_type_range.sh
Executable file
317
test/test_type_range.sh
Executable file
|
|
@ -0,0 +1,317 @@
|
|||
#!/bin/bash
|
||||
# Range type tests.
|
||||
# Mainly error messages and multiple ranges
|
||||
# Tests all int types including decimal64 and string length ranges
|
||||
# See also test_type.sh
|
||||
|
||||
# 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
|
||||
|
||||
# Which format to use as datastore format internally
|
||||
: ${format:=xml}
|
||||
|
||||
cfg=$dir/conf_yang.xml
|
||||
fyang=$dir/type.yang
|
||||
dclispec=$dir/clispec/
|
||||
|
||||
# XXX: add more types, now only uint8 and int8
|
||||
cat <<EOF > $fyang
|
||||
module example{
|
||||
yang-version 1.1;
|
||||
namespace "urn:example:clixon";
|
||||
prefix ex;
|
||||
typedef tint8{
|
||||
type int8{
|
||||
range "1..10 | 14..20";
|
||||
}
|
||||
}
|
||||
typedef tint16{
|
||||
type int16{
|
||||
range "1..10 | 14..20";
|
||||
}
|
||||
}
|
||||
typedef tint32{
|
||||
type int32{
|
||||
range "1..10 | 14..20";
|
||||
}
|
||||
}
|
||||
typedef tint64{
|
||||
type int64{
|
||||
range "1..10 | 14..20";
|
||||
}
|
||||
}
|
||||
typedef tuint8{
|
||||
type uint8{
|
||||
range "1..10 | 14..20";
|
||||
}
|
||||
}
|
||||
typedef tuint16{
|
||||
type uint16{
|
||||
range "1..10 | 14..20";
|
||||
}
|
||||
}
|
||||
typedef tuint32{
|
||||
type uint32{
|
||||
range "1..10 | 14..20";
|
||||
}
|
||||
}
|
||||
typedef tuint64{
|
||||
type uint64{
|
||||
range "1..10 | 14..20";
|
||||
}
|
||||
}
|
||||
typedef tdecimal64{
|
||||
type decimal64{
|
||||
fraction-digits 3;
|
||||
range "1..10 | 14..20";
|
||||
}
|
||||
}
|
||||
typedef tstring{
|
||||
type string{
|
||||
length "1..10 | 14..20";
|
||||
}
|
||||
}
|
||||
/* here follows constrained ints */
|
||||
leaf lint8 {
|
||||
type tint8;
|
||||
}
|
||||
leaf lint16 {
|
||||
type tint16;
|
||||
}
|
||||
leaf lint32 {
|
||||
type tint32;
|
||||
}
|
||||
leaf lint64 {
|
||||
type tint64;
|
||||
}
|
||||
leaf luint8 {
|
||||
type tuint8;
|
||||
}
|
||||
leaf luint16 {
|
||||
type tuint16;
|
||||
}
|
||||
leaf luint32 {
|
||||
type tuint32;
|
||||
}
|
||||
leaf luint64 {
|
||||
type tuint64;
|
||||
}
|
||||
leaf ldecimal64 {
|
||||
type tdecimal64;
|
||||
}
|
||||
leaf lstring {
|
||||
type tstring;
|
||||
}
|
||||
/* here follows unlimited ints */
|
||||
leaf rint8 {
|
||||
type int8;
|
||||
}
|
||||
leaf rint16 {
|
||||
type int16;
|
||||
}
|
||||
leaf rint32 {
|
||||
type int32;
|
||||
}
|
||||
leaf rint64 {
|
||||
type int64;
|
||||
}
|
||||
leaf ruint8 {
|
||||
type uint8;
|
||||
}
|
||||
leaf ruint16 {
|
||||
type uint16;
|
||||
}
|
||||
leaf ruint32 {
|
||||
type uint32;
|
||||
}
|
||||
leaf ruint64 {
|
||||
type uint64;
|
||||
}
|
||||
leaf rdecimal64 {
|
||||
type decimal64{
|
||||
fraction-digits 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
mkdir $dclispec
|
||||
|
||||
# clispec for both generated cli and a hardcoded range check
|
||||
cat <<EOF > $dclispec/clispec.cli
|
||||
CLICON_MODE="example";
|
||||
CLICON_PROMPT="%U@%H> ";
|
||||
CLICON_PLUGIN="example_cli";
|
||||
|
||||
# Manually added (not generated)
|
||||
manual hint8 <id:int8 range[1:10] range[14:20]>;
|
||||
manual hint16 <id:int16 range[1:10] range[14:20]>;
|
||||
manual hint32 <id:int32 range[1:10] range[14:20]>;
|
||||
manual hint64 <id:int64 range[1:10] range[14:20]>;
|
||||
|
||||
manual huint8 <id:uint8 range[1:10] range[14:20]>;
|
||||
manual huint16 <id:uint16 range[1:10] range[14:20]>;
|
||||
manual huint32 <id:uint32 range[1:10] range[14:20]>;
|
||||
manual huint64 <id:uint64 range[1:10] range[14:20]>;
|
||||
|
||||
manual hdecimal64 <id:decimal64 range[1:10] range[14:20]>;
|
||||
|
||||
manual hstring <id:string length[1:10] length[14:20]>;
|
||||
|
||||
# Generated cli
|
||||
set @datamodel, cli_set();
|
||||
merge @datamodel, cli_merge();
|
||||
create @datamodel, cli_create();
|
||||
show, cli_show_config("candidate", "text", "/");
|
||||
quit("Quit"), cli_quit();
|
||||
EOF
|
||||
|
||||
cat <<EOF > $cfg
|
||||
<clixon-config xmlns="http://clicon.org/config">
|
||||
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
||||
<CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
|
||||
<CLICON_CLISPEC_DIR>$dclispec</CLICON_CLISPEC_DIR>
|
||||
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
||||
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
||||
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
|
||||
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
|
||||
<CLICON_CLI_GENMODEL_COMPLETION>1</CLICON_CLI_GENMODEL_COMPLETION>
|
||||
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
|
||||
<CLICON_XMLDB_FORMAT>$format</CLICON_XMLDB_FORMAT>
|
||||
</clixon-config>
|
||||
EOF
|
||||
|
||||
# Type range tests.
|
||||
# Parameters: 1: type (eg uint8)
|
||||
# 2: val OK
|
||||
# 3: eval Invalid value
|
||||
# 4: post (eg .000 - special for decimal64, others should have "")
|
||||
testrange(){
|
||||
t=$1
|
||||
val=$2
|
||||
eval=$3
|
||||
post=$4
|
||||
|
||||
if [ $t = "string" ]; then # special case for string type error msg
|
||||
len=$(echo -n "$eval" | wc -c)
|
||||
errmsg="String length $len out of range: 1$post - 10$post, 14$post - 20$post"
|
||||
else
|
||||
errmsg="Number $eval$post out of range: 1$post - 10$post, 14$post - 20$post"
|
||||
fi
|
||||
|
||||
new "generated cli set $t leaf invalid"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set l$t $eval" 255 "$errmsg";
|
||||
|
||||
new "generated cli set $t leaf OK"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set l$t $val" 0 '^$'
|
||||
|
||||
# XXX Error in cligen order: Unknown command vs Number out of range
|
||||
# olof@vandal> set luint8 0
|
||||
# CLI syntax error: "set luint8 0": Number 0 is out of range: 14 - 20
|
||||
# olof@vandal> set luint8 1
|
||||
# olof@vandal> set luint8 0
|
||||
# CLI syntax error: "set luint8 0": Unknown command
|
||||
# (SAME AS FIRST ^)
|
||||
new "generated cli set $t leaf invalid"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set l$t $eval" 255 "$errmsg"
|
||||
|
||||
new "manual cli set $t leaf OK"
|
||||
expectfn "$clixon_cli -1f $cfg -l o man h$t $val" 0 '^$'
|
||||
|
||||
new "manual cli set $t leaf invalid"
|
||||
echo "$clixon_cli -1f $cfg -l o set h$t $eval"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set l$t $eval" 255 "$errmsg"
|
||||
|
||||
new "discard"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "Netconf set invalid $t leaf"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><edit-config><target><candidate/></target><config><l$t xmlns=\"urn:example:clixon\">$eval</l$t></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf get config"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><l$t xmlns=\"urn:example:clixon\">$eval</l$t></data></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf validate invalid range"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>l$t</bad-element></error-info><error-severity>error</error-severity><error-message>$errmsg</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||
|
||||
new "discard"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
}
|
||||
|
||||
# Type unlimited value range test. Only test invalid number out of range of type
|
||||
# Parameters: 1: type (eg uint8)
|
||||
# 2: val
|
||||
# 3: post (eg .000 - special for decimal64, others should have "")
|
||||
testunlimit(){
|
||||
t=$1
|
||||
val=$2
|
||||
rmin=$3
|
||||
rmax=$4
|
||||
post=$5
|
||||
|
||||
errmsg="Number $val$post out of range: $rmin$post - $rmax$post"
|
||||
|
||||
new "Netconf set invalid $t leaf"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><edit-config><target><candidate/></target><config><r$t xmlns=\"urn:example:clixon\">$val</r$t></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf validate invalid range"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>r$t</bad-element></error-info><error-severity>error</error-severity><error-message>$errmsg</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||
|
||||
new "discard"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
new "waiting"
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
new "test params: -f $cfg"
|
||||
|
||||
# Test all int types
|
||||
testunlimit int8 300 -128 127 ""
|
||||
testunlimit int16 73000 -32768 32767 ""
|
||||
testunlimit int32 4900000000 -2147483648 2147483647 ""
|
||||
testunlimit int64 49739274983274983274983274 -9223372036854775808 9223372036854775807 ""
|
||||
testunlimit uint8 300 0 255 ""
|
||||
testunlimit uint16 73000 0 65535 ""
|
||||
testunlimit uint32 4900000000 0 4294967295 ""
|
||||
testunlimit uint64 49739274983274983274983274 0 18446744073709551615 ""
|
||||
#testunlimit decimal64 49739274983274983274983274 -9223372036854775808 9223372036854775807 ".000"
|
||||
|
||||
# Test all int types
|
||||
for t in int8 int16 int32 int64 uint8 uint16 uint32 uint64; do
|
||||
testrange $t 1 0 ""
|
||||
done
|
||||
|
||||
# decimal64 requires 3 decimals as postfix
|
||||
testrange decimal64 1 0 ".000"
|
||||
|
||||
# test string with lengthlimit
|
||||
testrange string "012" "01234567890" ""
|
||||
|
||||
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
|
||||
|
|
@ -89,7 +89,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
new "cli set transitive string"
|
||||
|
|
@ -99,7 +99,7 @@ new "cli set transitive union"
|
|||
expectfn "$clixon_cli -1f $cfg -l o set c ulle 33" 0 "^$"
|
||||
|
||||
new "cli set transitive union error"
|
||||
expectfn "$clixon_cli -1f $cfg -l o set c ulle kalle" 255 '^CLI syntax error: "set c ulle kalle": Unknown command$'
|
||||
expectfn "$clixon_cli -1f $cfg -l o set c ulle kalle" 255 "^CLI syntax error: \"set c ulle kalle\": 'kalle' is not a number$"
|
||||
|
||||
if [ $BE -eq 0 ]; then
|
||||
exit # BE
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
# RFC test two-field caes
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ runtest(){
|
|||
start_backend -s $mode -f $cfg -o "CLICON_XMLDB_MODSTATE=$modstate"
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
else
|
||||
new "Restart backend as eg follows: -Ff $cfg -s $mode -o \"CLICON_XMLDB_MODSTATE=$modstate\" ($BETIMEOUT s)"
|
||||
sleep $BETIMEOUT
|
||||
|
|
|
|||
|
|
@ -254,8 +254,6 @@ if [ $BE -ne 0 ]; then
|
|||
new "start backend -s $mode -f $cfg"
|
||||
start_backend -s $mode -f $cfg
|
||||
fi
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
|
||||
new "kill old restconf daemon"
|
||||
sudo pkill -u www-data clixon_restconf
|
||||
|
|
@ -264,7 +262,8 @@ new "start restconf daemon"
|
|||
start_restconf -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
wait_restconf
|
||||
|
||||
new "Check running db content"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>' "^<rpc-reply><data>$XML</data></rpc-reply>]]>]]>$"
|
||||
|
|
|
|||
|
|
@ -265,8 +265,6 @@ testrun(){
|
|||
new "start backend -s startup -f $cfg -- -u"
|
||||
start_backend -s startup -f $cfg -- -u
|
||||
fi
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
|
||||
new "kill old restconf daemon"
|
||||
sudo pkill -u www-data clixon_restconf
|
||||
|
|
@ -275,7 +273,8 @@ testrun(){
|
|||
start_restconf -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
wait_restconf
|
||||
|
||||
new "Check running db content"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>' "^<rpc-reply><data>$runxml</data></rpc-reply>]]>]]>$"
|
||||
|
|
|
|||
|
|
@ -112,8 +112,6 @@ if [ $BE -ne 0 ]; then
|
|||
new "start backend -s $mode -f $cfg"
|
||||
start_backend -s $mode -f $cfg
|
||||
fi
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
|
||||
new "kill old restconf daemon"
|
||||
sudo pkill -u www-data clixon_restconf
|
||||
|
|
@ -122,7 +120,8 @@ new "start restconf daemon"
|
|||
start_restconf -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
wait_restconf
|
||||
|
||||
new "Check running db content is failsafe"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>' "^<rpc-reply><data>$SAMEXML</data></rpc-reply>]]>]]>$"
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
new "when: add static route"
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
new "1. Set newex"
|
||||
|
|
@ -134,7 +134,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
new "Set oldex"
|
||||
|
|
@ -178,7 +178,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
new "Set newex"
|
||||
|
|
@ -222,7 +222,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
new "Set oldex"
|
||||
|
|
@ -266,7 +266,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
new "Set newex"
|
||||
|
|
@ -312,7 +312,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
new "Set oldex"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><oldex xmlns="urn:example:clixon">str</oldex></config></edit-config></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||
|
|
@ -357,7 +357,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
new "Set oldex"
|
||||
|
|
@ -403,7 +403,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
fi
|
||||
|
||||
new "Set oldex"
|
||||
|
|
|
|||
|
|
@ -83,7 +83,8 @@ new "start restconf daemon"
|
|||
start_restconf -f $cfg
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
wait_backend
|
||||
wait_restconf
|
||||
|
||||
new "netconf set x in example1"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon1">42</x></config></edit-config></rpc>]]>]]>' '^<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><ok/></rpc-reply>]]>]]>$'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue