Many validation functions have changed error parameter from cbuf to xml tree.
This commit is contained in:
parent
dfa3970ab2
commit
fc78824110
22 changed files with 527 additions and 384 deletions
|
|
@ -69,6 +69,9 @@
|
||||||
|
|
||||||
### API changes on existing features (you may need to change your code)
|
### API changes on existing features (you may need to change your code)
|
||||||
|
|
||||||
|
* Many validation functions have changed error parameter from cbuf to xml tree.
|
||||||
|
* XML trees are more flexible for utility tools
|
||||||
|
* If you use these(mostly internal), you need to change the error function: `generic_validate, from_validate_common, xml_yang_validate_all_top, xml_yang_validate_all, xml_yang_validate_add, xml_yang_validate_rpc, xml_yang_validate_list_key_only`
|
||||||
* Replaced `CLIXON_DATADIR` with two configurable options defining where Clixon installs Yang files.
|
* Replaced `CLIXON_DATADIR` with two configurable options defining where Clixon installs Yang files.
|
||||||
* use `--with-yang-installdir=DIR` to install Clixon yang files in DIR
|
* use `--with-yang-installdir=DIR` to install Clixon yang files in DIR
|
||||||
* use `--with-std-yang-installdir=DIR` to install standard yang files that Clixon may use in DIR
|
* use `--with-std-yang-installdir=DIR` to install standard yang files that Clixon may use in DIR
|
||||||
|
|
|
||||||
|
|
@ -411,6 +411,7 @@ from_client_edit_config(clicon_handle h,
|
||||||
cbuf *cbx = NULL; /* Assist cbuf */
|
cbuf *cbx = NULL; /* Assist cbuf */
|
||||||
int ret;
|
int ret;
|
||||||
char *username;
|
char *username;
|
||||||
|
cxobj *xret = NULL;
|
||||||
|
|
||||||
username = clicon_username_get(h);
|
username = clicon_username_get(h);
|
||||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||||
|
|
@ -470,10 +471,13 @@ from_client_edit_config(clicon_handle h,
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
/* xmldb_put (difflist handling) requires list keys */
|
/* xmldb_put (difflist handling) requires list keys */
|
||||||
if ((ret = xml_yang_validate_list_key_only(h, xc, cbret)) < 0)
|
if ((ret = xml_yang_validate_list_key_only(h, xc, &xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0){
|
||||||
|
if (clicon_xml2cbuf(cbret, xret, 0, 0) < 0)
|
||||||
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
}
|
||||||
/* Cant do this earlier since we dont have a yang spec to
|
/* Cant do this earlier since we dont have a yang spec to
|
||||||
* the upper part of the tree, until we get the "config" tree.
|
* the upper part of the tree, until we get the "config" tree.
|
||||||
*/
|
*/
|
||||||
|
|
@ -493,6 +497,8 @@ from_client_edit_config(clicon_handle h,
|
||||||
ok:
|
ok:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
if (xret)
|
||||||
|
xml_free(xret);
|
||||||
if (cbx)
|
if (cbx)
|
||||||
cbuf_free(cbx);
|
cbuf_free(cbx);
|
||||||
clicon_debug(1, "%s done cbret:%s", __FUNCTION__, cbuf_get(cbret));
|
clicon_debug(1, "%s done cbret:%s", __FUNCTION__, cbuf_get(cbret));
|
||||||
|
|
@ -1121,6 +1127,7 @@ from_client_msg(clicon_handle h,
|
||||||
yang_stmt *ye;
|
yang_stmt *ye;
|
||||||
yang_stmt *ymod;
|
yang_stmt *ymod;
|
||||||
cxobj *xnacm = NULL;
|
cxobj *xnacm = NULL;
|
||||||
|
cxobj *xret = NULL;
|
||||||
|
|
||||||
clicon_debug(1, "%s", __FUNCTION__);
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
yspec = clicon_dbspec_yang(h);
|
yspec = clicon_dbspec_yang(h);
|
||||||
|
|
@ -1147,10 +1154,13 @@ from_client_msg(clicon_handle h,
|
||||||
* maybe not necessary since it should be */
|
* maybe not necessary since it should be */
|
||||||
if (xml_spec_populate_rpc(h, x, yspec) < 0)
|
if (xml_spec_populate_rpc(h, x, yspec) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((ret = xml_yang_validate_rpc(h, x, cbret)) < 0)
|
if ((ret = xml_yang_validate_rpc(h, x, &xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0){
|
||||||
|
if (clicon_xml2cbuf(cbret, xret, 0, 0) < 0)
|
||||||
|
goto done;
|
||||||
goto reply;
|
goto reply;
|
||||||
|
}
|
||||||
xe = NULL;
|
xe = NULL;
|
||||||
username = xml_find_value(x, "username");
|
username = xml_find_value(x, "username");
|
||||||
/* May be used by callbacks, etc */
|
/* May be used by callbacks, etc */
|
||||||
|
|
@ -1222,6 +1232,8 @@ from_client_msg(clicon_handle h,
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
clicon_debug(1, "%s retval:%d", __FUNCTION__, retval);
|
clicon_debug(1, "%s retval:%d", __FUNCTION__, retval);
|
||||||
|
if (xret)
|
||||||
|
xml_free(xret);
|
||||||
if (xt)
|
if (xt)
|
||||||
xml_free(xt);
|
xml_free(xt);
|
||||||
if (cbret)
|
if (cbret)
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@
|
||||||
* are if code comes via XML/NETCONF.
|
* are if code comes via XML/NETCONF.
|
||||||
* @param[in] yspec Yang spec
|
* @param[in] yspec Yang spec
|
||||||
* @param[in] td Transaction data
|
* @param[in] td Transaction data
|
||||||
* @param[out] cbret Cligen buffer containing netconf error (if retval == 0)
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
* @retval 0 Validation failed (with cbret set)
|
* @retval 0 Validation failed (with cbret set)
|
||||||
* @retval 1 Validation OK
|
* @retval 1 Validation OK
|
||||||
|
|
@ -90,7 +90,7 @@ static int
|
||||||
generic_validate(clicon_handle h,
|
generic_validate(clicon_handle h,
|
||||||
yang_stmt *yspec,
|
yang_stmt *yspec,
|
||||||
transaction_data_t *td,
|
transaction_data_t *td,
|
||||||
cbuf *cbret)
|
cxobj **xret)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cxobj *x1;
|
cxobj *x1;
|
||||||
|
|
@ -100,7 +100,7 @@ generic_validate(clicon_handle h,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* All entries */
|
/* All entries */
|
||||||
if ((ret = xml_yang_validate_all_top(h, td->td_target, cbret)) < 0)
|
if ((ret = xml_yang_validate_all_top(h, td->td_target, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -109,7 +109,7 @@ generic_validate(clicon_handle h,
|
||||||
x1 = td->td_scvec[i]; /* source changed */
|
x1 = td->td_scvec[i]; /* source changed */
|
||||||
x2 = td->td_tcvec[i]; /* target changed */
|
x2 = td->td_tcvec[i]; /* target changed */
|
||||||
/* Should this be recursive? */
|
/* Should this be recursive? */
|
||||||
if ((ret = xml_yang_validate_add(h, x2, cbret)) < 0)
|
if ((ret = xml_yang_validate_add(h, x2, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -119,7 +119,7 @@ generic_validate(clicon_handle h,
|
||||||
x1 = td->td_dvec[i];
|
x1 = td->td_dvec[i];
|
||||||
ys = xml_spec(x1);
|
ys = xml_spec(x1);
|
||||||
if (ys && yang_mandatory(ys) && yang_config(ys)==0){
|
if (ys && yang_mandatory(ys) && yang_config(ys)==0){
|
||||||
if (netconf_missing_element(cbret, "protocol", xml_name(x1), "Missing mandatory variable") < 0)
|
if (netconf_missing_element_xml(xret, "protocol", xml_name(x1), "Missing mandatory variable") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -127,7 +127,7 @@ generic_validate(clicon_handle h,
|
||||||
/* added entries */
|
/* added entries */
|
||||||
for (i=0; i<td->td_alen; i++){
|
for (i=0; i<td->td_alen; i++){
|
||||||
x2 = td->td_avec[i];
|
x2 = td->td_avec[i];
|
||||||
if ((ret = xml_yang_validate_add(h, x2, cbret)) < 0)
|
if ((ret = xml_yang_validate_add(h, x2, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -175,6 +175,7 @@ startup_common(clicon_handle h,
|
||||||
modstate_diff_t *msd = NULL;
|
modstate_diff_t *msd = NULL;
|
||||||
cxobj *xt = NULL;
|
cxobj *xt = NULL;
|
||||||
cxobj *x;
|
cxobj *x;
|
||||||
|
cxobj *xret = NULL;
|
||||||
|
|
||||||
/* If CLICON_XMLDB_MODSTATE is enabled, then get the db XML with
|
/* If CLICON_XMLDB_MODSTATE is enabled, then get the db XML with
|
||||||
* potentially non-matching module-state in msd
|
* potentially non-matching module-state in msd
|
||||||
|
|
@ -225,11 +226,13 @@ startup_common(clicon_handle h,
|
||||||
/* 5. Make generic validation on all new or changed data.
|
/* 5. Make generic validation on all new or changed data.
|
||||||
Note this is only call that uses 3-values */
|
Note this is only call that uses 3-values */
|
||||||
clicon_debug(1, "Validating startup %s", db);
|
clicon_debug(1, "Validating startup %s", db);
|
||||||
if ((ret = generic_validate(h, yspec, td, cbret)) < 0)
|
if ((ret = generic_validate(h, yspec, td, &xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0){
|
||||||
|
if (clicon_xml2cbuf(cbret, xret, 0, 0) < 0)
|
||||||
|
goto done;
|
||||||
goto fail; /* STARTUP_INVALID */
|
goto fail; /* STARTUP_INVALID */
|
||||||
|
}
|
||||||
/* 6. Call plugin transaction validate callbacks */
|
/* 6. Call plugin transaction validate callbacks */
|
||||||
if (plugin_transaction_validate(h, td) < 0)
|
if (plugin_transaction_validate(h, td) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -240,6 +243,8 @@ startup_common(clicon_handle h,
|
||||||
ok:
|
ok:
|
||||||
retval = 1;
|
retval = 1;
|
||||||
done:
|
done:
|
||||||
|
if (xret)
|
||||||
|
xml_free(xret);
|
||||||
if (xt)
|
if (xt)
|
||||||
xml_free(xt);
|
xml_free(xt);
|
||||||
if (msd)
|
if (msd)
|
||||||
|
|
@ -374,6 +379,7 @@ startup_commit(clicon_handle h,
|
||||||
* and call application callback validations.
|
* and call application callback validations.
|
||||||
* @param[in] h Clicon handle
|
* @param[in] h Clicon handle
|
||||||
* @param[in] candidate The candidate database. The wanted backend state
|
* @param[in] candidate The candidate database. The wanted backend state
|
||||||
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
* @retval -1 Error - or validation failed (but cbret not set)
|
* @retval -1 Error - or validation failed (but cbret not set)
|
||||||
* @retval 0 Validation failed (with cbret set)
|
* @retval 0 Validation failed (with cbret set)
|
||||||
* @retval 1 Validation OK
|
* @retval 1 Validation OK
|
||||||
|
|
@ -385,7 +391,7 @@ static int
|
||||||
from_validate_common(clicon_handle h,
|
from_validate_common(clicon_handle h,
|
||||||
char *candidate,
|
char *candidate,
|
||||||
transaction_data_t *td,
|
transaction_data_t *td,
|
||||||
cbuf *cbret)
|
cxobj **xret)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
yang_stmt *yspec;
|
yang_stmt *yspec;
|
||||||
|
|
@ -409,7 +415,7 @@ from_validate_common(clicon_handle h,
|
||||||
* But xml_diff requires some basic validation, at least check that yang-specs
|
* But xml_diff requires some basic validation, at least check that yang-specs
|
||||||
* have been assigned
|
* have been assigned
|
||||||
*/
|
*/
|
||||||
if ((ret = xml_yang_validate_all_top(h, td->td_target, cbret)) < 0)
|
if ((ret = xml_yang_validate_all_top(h, td->td_target, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -462,7 +468,7 @@ from_validate_common(clicon_handle h,
|
||||||
|
|
||||||
/* 5. Make generic validation on all new or changed data.
|
/* 5. Make generic validation on all new or changed data.
|
||||||
Note this is only call that uses 3-values */
|
Note this is only call that uses 3-values */
|
||||||
if ((ret = generic_validate(h, yspec, td, cbret)) < 0)
|
if ((ret = generic_validate(h, yspec, td, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -503,6 +509,7 @@ candidate_commit(clicon_handle h,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
transaction_data_t *td = NULL;
|
transaction_data_t *td = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
cxobj *xret = NULL;
|
||||||
|
|
||||||
/* 1. Start transaction */
|
/* 1. Start transaction */
|
||||||
if ((td = transaction_new()) == NULL)
|
if ((td = transaction_new()) == NULL)
|
||||||
|
|
@ -511,10 +518,13 @@ candidate_commit(clicon_handle h,
|
||||||
/* Common steps (with validate). Load candidate and running and compute diffs
|
/* Common steps (with validate). Load candidate and running and compute diffs
|
||||||
* Note this is only call that uses 3-values
|
* Note this is only call that uses 3-values
|
||||||
*/
|
*/
|
||||||
if ((ret = from_validate_common(h, candidate, td, cbret)) < 0)
|
if ((ret = from_validate_common(h, candidate, td, &xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0){
|
||||||
|
if (clicon_xml2cbuf(cbret, xret, 0, 0) < 0)
|
||||||
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* 7. Call plugin transaction commit callbacks */
|
/* 7. Call plugin transaction commit callbacks */
|
||||||
if (plugin_transaction_commit(h, td) < 0)
|
if (plugin_transaction_commit(h, td) < 0)
|
||||||
|
|
@ -563,7 +573,9 @@ candidate_commit(clicon_handle h,
|
||||||
xmldb_get0_free(h, &td->td_src);
|
xmldb_get0_free(h, &td->td_src);
|
||||||
transaction_free(td);
|
transaction_free(td);
|
||||||
}
|
}
|
||||||
return retval;
|
if (xret)
|
||||||
|
xml_free(xret);
|
||||||
|
return retval;
|
||||||
fail:
|
fail:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -725,6 +737,7 @@ from_client_validate(clicon_handle h,
|
||||||
transaction_data_t *td = NULL;
|
transaction_data_t *td = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
char *db;
|
char *db;
|
||||||
|
cxobj *xret = NULL;
|
||||||
|
|
||||||
if ((db = netconf_db_find(xe, "source")) == NULL){
|
if ((db = netconf_db_find(xe, "source")) == NULL){
|
||||||
if (netconf_missing_element(cbret, "protocol", "source", NULL) < 0)
|
if (netconf_missing_element(cbret, "protocol", "source", NULL) < 0)
|
||||||
|
|
@ -737,9 +750,15 @@ from_client_validate(clicon_handle h,
|
||||||
if ((td = transaction_new()) == NULL)
|
if ((td = transaction_new()) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
/* Common steps (with commit) */
|
/* Common steps (with commit) */
|
||||||
if ((ret = from_validate_common(h, db, td, cbret)) < 1){
|
if ((ret = from_validate_common(h, db, td, &xret)) < 1){
|
||||||
|
/* A little complex due to several sources of validation fails or errors.
|
||||||
|
* (1) xerr is set -> translate to cbret; (2) cbret set use that; otherwise
|
||||||
|
* use clicon_err. */
|
||||||
|
if (xret && clicon_xml2cbuf(cbret, xret, 0, 0) < 0)
|
||||||
|
goto done;
|
||||||
plugin_transaction_abort(h, td);
|
plugin_transaction_abort(h, td);
|
||||||
if (netconf_operation_failed(cbret, "application", clicon_err_reason)< 0)
|
if (!cbuf_len(cbret) &&
|
||||||
|
netconf_operation_failed(cbret, "application", clicon_err_reason)< 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
|
|
@ -773,6 +792,8 @@ from_client_validate(clicon_handle h,
|
||||||
xmldb_get0_free(h, &td->td_src);
|
xmldb_get0_free(h, &td->td_src);
|
||||||
transaction_free(td);
|
transaction_free(td);
|
||||||
}
|
}
|
||||||
|
if (xret)
|
||||||
|
xml_free(xret);
|
||||||
return retval;
|
return retval;
|
||||||
} /* from_client_validate */
|
} /* from_client_validate */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ static int ignore_packet_errors = 1;
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
netconf_input_packet(clicon_handle h,
|
netconf_input_packet(clicon_handle h,
|
||||||
cbuf *cb)
|
cbuf *cb)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
@ -125,9 +125,10 @@ netconf_input_packet(clicon_handle h,
|
||||||
isrpc++;
|
isrpc++;
|
||||||
if (xml_spec_populate_rpc(h, xrpc, yspec) < 0)
|
if (xml_spec_populate_rpc(h, xrpc, yspec) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((ret = xml_yang_validate_rpc(h, xrpc, cbret)) < 0)
|
if ((ret = xml_yang_validate_rpc(h, xrpc, &xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
|
clicon_xml2cbuf(cbret, xret, 0, 0);
|
||||||
netconf_output_encap(1, cbret, "rpc-error");
|
netconf_output_encap(1, cbret, "rpc-error");
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
|
|
@ -155,7 +156,7 @@ netconf_input_packet(clicon_handle h,
|
||||||
netconf_output_encap(1, cbret, "rpc-error");
|
netconf_output_encap(1, cbret, "rpc-error");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((xc = xml_child_i(xret,0))!=NULL){
|
if ((xc = xml_child_i(xret, 0))!=NULL){
|
||||||
xa=NULL;
|
xa=NULL;
|
||||||
/* Copy message-id attribute from incoming to reply.
|
/* Copy message-id attribute from incoming to reply.
|
||||||
* RFC 6241:
|
* RFC 6241:
|
||||||
|
|
|
||||||
|
|
@ -547,6 +547,7 @@ netconf_application_rpc(clicon_handle h,
|
||||||
yang_stmt *yinput;
|
yang_stmt *yinput;
|
||||||
yang_stmt *youtput;
|
yang_stmt *youtput;
|
||||||
cxobj *xoutput;
|
cxobj *xoutput;
|
||||||
|
cxobj *xerr = NULL;
|
||||||
cbuf *cb = NULL;
|
cbuf *cb = NULL;
|
||||||
cbuf *cbret = NULL;
|
cbuf *cbret = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
@ -587,15 +588,13 @@ netconf_application_rpc(clicon_handle h,
|
||||||
xml_spec_set(xn, yinput); /* needed for xml_spec_populate */
|
xml_spec_set(xn, yinput); /* needed for xml_spec_populate */
|
||||||
if (xml_apply(xn, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
if (xml_apply(xn, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((ret = xml_yang_validate_all_top(h, xn, cbret)) < 0)
|
if ((ret = xml_yang_validate_all_top(h, xn, &xerr)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){
|
if (ret > 0 && (ret = xml_yang_validate_add(h, xn, &xerr)) < 0)
|
||||||
netconf_output_encap(1, cbret, "rpc-error");
|
|
||||||
goto ok;
|
|
||||||
}
|
|
||||||
if ((ret = xml_yang_validate_add(h, xn, cbret)) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
|
if (clicon_xml2cbuf(cbret, xerr, 0, 0) < 0)
|
||||||
|
goto done;
|
||||||
netconf_output_encap(1, cbret, "rpc-error");
|
netconf_output_encap(1, cbret, "rpc-error");
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
|
|
@ -622,15 +621,13 @@ netconf_application_rpc(clicon_handle h,
|
||||||
if (xml_apply(xoutput, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
if (xml_apply(xoutput, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if ((ret = xml_yang_validate_all_top(h, xoutput, cbret)) < 0)
|
if ((ret = xml_yang_validate_all_top(h, xoutput, &xerr)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){
|
if (ret > 0 && (ret = xml_yang_validate_add(h, xoutput, &xerr)) < 0)
|
||||||
clicon_log(LOG_WARNING, "Errors in output netconf %s", cbuf_get(cbret));
|
|
||||||
goto ok;
|
|
||||||
}
|
|
||||||
if ((ret = xml_yang_validate_add(h, xoutput, cbret)) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
|
if (clicon_xml2cbuf(cbret, xerr, 0, 0) < 0)
|
||||||
|
goto done;
|
||||||
clicon_log(LOG_WARNING, "Errors in output netconf %s", cbuf_get(cbret));
|
clicon_log(LOG_WARNING, "Errors in output netconf %s", cbuf_get(cbret));
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
|
|
@ -641,6 +638,8 @@ netconf_application_rpc(clicon_handle h,
|
||||||
ok:
|
ok:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
if (xerr)
|
||||||
|
xml_free(xerr);
|
||||||
if (cb)
|
if (cb)
|
||||||
cbuf_free(cb);
|
cbuf_free(cb);
|
||||||
if (cbret)
|
if (cbret)
|
||||||
|
|
|
||||||
|
|
@ -1476,14 +1476,9 @@ api_operations_post_output(clicon_handle h,
|
||||||
cxobj *xa; /* xml attribute (xmlns) */
|
cxobj *xa; /* xml attribute (xmlns) */
|
||||||
cxobj *x;
|
cxobj *x;
|
||||||
cxobj *xok;
|
cxobj *xok;
|
||||||
cbuf *cbret = NULL;
|
|
||||||
int isempty;
|
int isempty;
|
||||||
|
|
||||||
// clicon_debug(1, "%s", __FUNCTION__);
|
// clicon_debug(1, "%s", __FUNCTION__);
|
||||||
if ((cbret = cbuf_new()) == NULL){
|
|
||||||
clicon_err(OE_UNIX, 0, "cbuf_new");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
/* Validate that exactly only <rpc-reply> tag */
|
/* Validate that exactly only <rpc-reply> tag */
|
||||||
if ((xoutput = xml_child_i_type(xret, 0, CX_ELMNT)) == NULL ||
|
if ((xoutput = xml_child_i_type(xret, 0, CX_ELMNT)) == NULL ||
|
||||||
strcmp(xml_name(xoutput),"rpc-reply") != 0 ||
|
strcmp(xml_name(xoutput),"rpc-reply") != 0 ||
|
||||||
|
|
@ -1521,14 +1516,12 @@ api_operations_post_output(clicon_handle h,
|
||||||
#if 0
|
#if 0
|
||||||
if (xml_apply(xoutput, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
if (xml_apply(xoutput, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((ret = xml_yang_validate_all(xoutput, cbret)) < 0)
|
if ((ret = xml_yang_validate_all(xoutput, &xerr)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 1 &&
|
if (ret == 1 &&
|
||||||
(ret = xml_yang_validate_add(h, xoutput, cbret)) < 0)
|
(ret = xml_yang_validate_add(h, xoutput, &xerr)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){ /* validation failed */
|
if (ret == 0){ /* validation failed */
|
||||||
if (xml_parse_string(cbuf_get(cbret), yspec, &xerr) < 0)
|
|
||||||
goto done;
|
|
||||||
if ((xe = xpath_first(xerr, "rpc-reply/rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-reply/rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -1573,8 +1566,6 @@ api_operations_post_output(clicon_handle h,
|
||||||
retval = 1;
|
retval = 1;
|
||||||
done:
|
done:
|
||||||
clicon_debug(1, "%s retval: %d", __FUNCTION__, retval);
|
clicon_debug(1, "%s retval: %d", __FUNCTION__, retval);
|
||||||
if (cbret)
|
|
||||||
cbuf_free(cbret);
|
|
||||||
if (xerr)
|
if (xerr)
|
||||||
xml_free(xerr);
|
xml_free(xerr);
|
||||||
return retval;
|
return retval;
|
||||||
|
|
@ -1760,14 +1751,12 @@ api_operations_post(clicon_handle h,
|
||||||
/* 6. Validate incoming RPC and fill in defaults */
|
/* 6. Validate incoming RPC and fill in defaults */
|
||||||
if (xml_spec_populate_rpc(h, xtop, yspec) < 0) /* */
|
if (xml_spec_populate_rpc(h, xtop, yspec) < 0) /* */
|
||||||
goto done;
|
goto done;
|
||||||
if ((ret = xml_yang_validate_rpc(h, xtop, cbret)) < 0)
|
if ((ret = xml_yang_validate_rpc(h, xtop, &xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
if (xml_parse_string(cbuf_get(cbret), NULL, &xret) < 0)
|
if ((xe = xpath_first(xret, "rpc-error")) == NULL){
|
||||||
goto done;
|
|
||||||
if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) == NULL){
|
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto ok;
|
||||||
}
|
}
|
||||||
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
if (api_return_err(h, r, xe, pretty, use_xml) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@
|
||||||
***** END LICENSE BLOCK *****
|
***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
* Netconf library functions. See RFC6241
|
* Netconf library functions. See RFC6241
|
||||||
*
|
* Functions to generate a netconf error message come in two forms: xml-tree and
|
||||||
|
* cbuf. XML tree is preferred.
|
||||||
*/
|
*/
|
||||||
#ifndef _CLIXON_NETCONF_LIB_H
|
#ifndef _CLIXON_NETCONF_LIB_H
|
||||||
#define _CLIXON_NETCONF_LIB_H
|
#define _CLIXON_NETCONF_LIB_H
|
||||||
|
|
@ -60,16 +61,18 @@ int netconf_lock_denied(cbuf *cb, char *info, char *message);
|
||||||
int netconf_resource_denied(cbuf *cb, char *type, char *message);
|
int netconf_resource_denied(cbuf *cb, char *type, char *message);
|
||||||
int netconf_rollback_failed(cbuf *cb, char *type, char *message);
|
int netconf_rollback_failed(cbuf *cb, char *type, char *message);
|
||||||
int netconf_data_exists(cbuf *cb, char *message);
|
int netconf_data_exists(cbuf *cb, char *message);
|
||||||
int netconf_data_missing(cbuf *cb, char *message);
|
int netconf_data_missing(cbuf *cb, char *missing_choice, char *message);
|
||||||
|
int netconf_data_missing_xml(cxobj **xret, char *missing_choice, char *message);
|
||||||
int netconf_operation_not_supported(cbuf *cb, char *type, char *message);
|
int netconf_operation_not_supported(cbuf *cb, char *type, char *message);
|
||||||
int netconf_operation_failed(cbuf *cb, char *type, char *message);
|
int netconf_operation_failed(cbuf *cb, char *type, char *message);
|
||||||
int netconf_operation_failed_xml(cxobj **xret, char *type, char *message);
|
int netconf_operation_failed_xml(cxobj **xret, char *type, char *message);
|
||||||
int netconf_malformed_message(cbuf *cb, char *message);
|
int netconf_malformed_message(cbuf *cb, char *message);
|
||||||
int netconf_malformed_message_xml(cxobj **xret, char *message);
|
int netconf_malformed_message_xml(cxobj **xret, char *message);
|
||||||
int netconf_data_not_unique(cbuf *cb, cxobj *x, cvec *cvk);
|
int netconf_data_not_unique_xml(cxobj **xret, cxobj *x, cvec *cvk);
|
||||||
int netconf_minmax_elements(cbuf *cb, cxobj *x, int max);
|
int netconf_minmax_elements_xml(cxobj **xret, cxobj *x, int max);
|
||||||
int netconf_trymerge(cxobj *x, yang_stmt *yspec, cxobj **xret);
|
int netconf_trymerge(cxobj *x, yang_stmt *yspec, cxobj **xret);
|
||||||
int netconf_module_load(clicon_handle h);
|
int netconf_module_load(clicon_handle h);
|
||||||
char *netconf_db_find(cxobj *xn, char *name);
|
char *netconf_db_find(cxobj *xn, char *name);
|
||||||
|
int netconf_err2cb(cxobj *xerr, cbuf **cberr);
|
||||||
|
|
||||||
#endif /* _CLIXON_NETCONF_LIB_H */
|
#endif /* _CLIXON_NETCONF_LIB_H */
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,11 @@ int xml2txt(FILE *f, cxobj *x, int level);
|
||||||
int xml2cli(FILE *f, cxobj *x, char *prepend, enum genmodel_type gt);
|
int xml2cli(FILE *f, cxobj *x, char *prepend, enum genmodel_type gt);
|
||||||
int xml_yang_root(cxobj *x, cxobj **xr);
|
int xml_yang_root(cxobj *x, cxobj **xr);
|
||||||
int xmlns_assign(cxobj *x);
|
int xmlns_assign(cxobj *x);
|
||||||
int xml_yang_validate_rpc(clicon_handle h, cxobj *xrpc, cbuf *cbret);
|
int xml_yang_validate_rpc(clicon_handle h, cxobj *xrpc, cxobj **xret);
|
||||||
int xml_yang_validate_list_key_only(clicon_handle h, cxobj *xt, cbuf *cbret);
|
int xml_yang_validate_list_key_only(clicon_handle h, cxobj *xt, cxobj **xret);
|
||||||
int xml_yang_validate_add(clicon_handle h, cxobj *xt, cbuf *cbret);
|
int xml_yang_validate_add(clicon_handle h, cxobj *xt, cxobj **xret);
|
||||||
int xml_yang_validate_all(clicon_handle h, cxobj *xt, cbuf *cbret);
|
int xml_yang_validate_all(clicon_handle h, cxobj *xt, cxobj **xret);
|
||||||
int xml_yang_validate_all_top(clicon_handle h, cxobj *xt, cbuf *cbret);
|
int xml_yang_validate_all_top(clicon_handle h, cxobj *xt, cxobj **xret);
|
||||||
int xml2cvec(cxobj *xt, yang_stmt *ys, cvec **cvv0);
|
int xml2cvec(cxobj *xt, yang_stmt *ys, cvec **cvv0);
|
||||||
int cvec2xml_1(cvec *cvv, char *toptag, cxobj *xp, cxobj **xt0);
|
int cvec2xml_1(cvec *cvv, char *toptag, cxobj *xp, cxobj **xt0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ text_modify(clicon_handle h,
|
||||||
break;
|
break;
|
||||||
case OP_DELETE:
|
case OP_DELETE:
|
||||||
if (x0==NULL){
|
if (x0==NULL){
|
||||||
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
|
if (netconf_data_missing(cbret, NULL, "Data does not exist; cannot delete resource") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -376,7 +376,7 @@ text_modify(clicon_handle h,
|
||||||
break;
|
break;
|
||||||
case OP_DELETE:
|
case OP_DELETE:
|
||||||
if (x0==NULL){
|
if (x0==NULL){
|
||||||
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
|
if (netconf_data_missing(cbret, NULL, "Data does not exist; cannot delete resource") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -488,7 +488,7 @@ text_modify_top(clicon_handle h,
|
||||||
I.e., curl -u andy:bar -sS -X DELETE http://localhost/restconf/data
|
I.e., curl -u andy:bar -sS -X DELETE http://localhost/restconf/data
|
||||||
*/
|
*/
|
||||||
case OP_DELETE:
|
case OP_DELETE:
|
||||||
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
|
if (netconf_data_missing(cbret, NULL, "Data does not exist; cannot delete resource") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@
|
||||||
***** END LICENSE BLOCK *****
|
***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
* Netconf library functions. See RFC6241
|
* Netconf library functions. See RFC6241
|
||||||
|
* Functions to generate a netconf error message come in two forms: xml-tree and
|
||||||
|
* cbuf. XML tree is preferred.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
|
@ -63,6 +65,8 @@
|
||||||
#include "clixon_options.h"
|
#include "clixon_options.h"
|
||||||
#include "clixon_data.h"
|
#include "clixon_data.h"
|
||||||
#include "clixon_xml_map.h"
|
#include "clixon_xml_map.h"
|
||||||
|
#include "clixon_xpath_ctx.h"
|
||||||
|
#include "clixon_xpath.h"
|
||||||
#include "clixon_netconf_lib.h"
|
#include "clixon_netconf_lib.h"
|
||||||
|
|
||||||
/*! Create Netconf in-use error XML tree according to RFC 6241 Appendix A
|
/*! Create Netconf in-use error XML tree according to RFC 6241 Appendix A
|
||||||
|
|
@ -752,36 +756,79 @@ netconf_data_exists(cbuf *cb,
|
||||||
* does not exist. For example, a "delete" operation was attempted on
|
* does not exist. For example, a "delete" operation was attempted on
|
||||||
* data that does not exist.
|
* data that does not exist.
|
||||||
* @param[out] cb CLIgen buf. Error XML is written in this buffer
|
* @param[out] cb CLIgen buf. Error XML is written in this buffer
|
||||||
|
* @param[in] missing_choice If set, see RFC7950: 15.6 violates mandatiry choice
|
||||||
* @param[in] message Error message
|
* @param[in] message Error message
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
netconf_data_missing(cbuf *cb,
|
netconf_data_missing(cbuf *cb,
|
||||||
|
char *missing_choice,
|
||||||
char *message)
|
char *message)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
char *encstr = NULL;
|
cxobj *xret = NULL;
|
||||||
|
|
||||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
if (netconf_data_missing_xml(&xret, missing_choice, message) < 0)
|
||||||
"<error-type>application</error-type>"
|
goto done;
|
||||||
"<error-tag>data-missing</error-tag>"
|
if (clicon_xml2cbuf(cb, xret, 0, 0) < 0)
|
||||||
"<error-severity>error</error-severity>") <0)
|
goto done;
|
||||||
goto err;
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (xret)
|
||||||
|
xml_free(xret);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Create Netconf data-missing error XML tree according to RFC 6241 App A
|
||||||
|
*
|
||||||
|
* Request could not be completed because the relevant data model content
|
||||||
|
* does not exist. For example, a "delete" operation was attempted on
|
||||||
|
* data that does not exist.
|
||||||
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
|
* @param[in] missing_choice If set, see RFC7950: 15.6 violates mandatiry choice
|
||||||
|
* @param[in] message Error message
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
netconf_data_missing_xml(cxobj **xret,
|
||||||
|
char *missing_choice,
|
||||||
|
char *message)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
char *encstr = NULL;
|
||||||
|
cxobj *xerr;
|
||||||
|
|
||||||
|
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>application</error-type>"
|
||||||
|
"<error-tag>data-missing</error-tag>") < 0)
|
||||||
|
goto done;
|
||||||
|
if (missing_choice) /* NYI: RFC7950: 15.6 <error-path> */
|
||||||
|
if (xml_parse_va(&xerr, NULL,
|
||||||
|
"<error-app-tag>missing-choice</error-app-tag>"
|
||||||
|
"<error-info><missing-choice>%s</missing-choice></error-info>",
|
||||||
|
missing_choice) < 0)
|
||||||
|
goto done;
|
||||||
|
if (xml_parse_va(&xerr, NULL,
|
||||||
|
"<error-severity>error</error-severity>") < 0)
|
||||||
|
goto done;
|
||||||
if (message){
|
if (message){
|
||||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
if (xml_parse_va(&xerr, NULL,
|
||||||
goto err;
|
"<error-message>%s</error-message>", encstr) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
|
||||||
goto err;
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (encstr)
|
if (encstr)
|
||||||
free(encstr);
|
free(encstr);
|
||||||
return retval;
|
return retval;
|
||||||
err:
|
|
||||||
clicon_err(OE_XML, errno, "cprintf");
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Create Netconf operation-not-supported error XML according to RFC 6241 App A
|
/*! Create Netconf operation-not-supported error XML according to RFC 6241 App A
|
||||||
|
|
@ -970,79 +1017,97 @@ netconf_malformed_message_xml(cxobj **xret,
|
||||||
*
|
*
|
||||||
* A NETCONF operation would result in configuration data where a
|
* A NETCONF operation would result in configuration data where a
|
||||||
* "unique" constraint is invalidated.
|
* "unique" constraint is invalidated.
|
||||||
* @param[out] cb CLIgen buf. Error XML is written in this buffer
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
* @param[in] x List element containing duplicate
|
* @param[in] x List element containing duplicate
|
||||||
* @param[in] cvk List of comonents in x that are non-unique
|
* @param[in] cvk List of comonents in x that are non-unique
|
||||||
* @see RFC7950 Sec 15.1
|
* @see RFC7950 Sec 15.1
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
netconf_data_not_unique(cbuf *cb,
|
netconf_data_not_unique_xml(cxobj **xret,
|
||||||
cxobj *x,
|
cxobj *x,
|
||||||
cvec *cvk)
|
cvec *cvk)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cg_var *cvi = NULL;
|
cg_var *cvi = NULL;
|
||||||
cxobj *xi;
|
cxobj *xi;
|
||||||
|
cxobj *xerr;
|
||||||
|
cxobj *xinfo;
|
||||||
|
cbuf *cb = NULL;
|
||||||
|
|
||||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
if (*xret == NULL){
|
||||||
"<error-type>protocol</error-type>"
|
if ((*xret = xml_new("rpc-reply", NULL, NULL)) == NULL)
|
||||||
"<error-tag>operation-failed</error-tag>"
|
goto done;
|
||||||
"<error-app-tag>data-not-unique</error-app-tag>"
|
}
|
||||||
"<error-severity>error</error-severity>"
|
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||||
"<error-info>") < 0)
|
goto done;
|
||||||
goto err;
|
if ((xerr = xml_new("rpc-error", *xret, NULL)) == NULL)
|
||||||
while ((cvi = cvec_each(cvk, cvi)) != NULL){
|
goto done;
|
||||||
if ((xi = xml_find(x, cv_string_get(cvi))) == NULL)
|
if (xml_parse_va(&xerr, NULL, "<error-type>protocol</error-type>"
|
||||||
continue; /* ignore, shouldnt happen */
|
"<error-tag>operation-failed</error-tag>"
|
||||||
cprintf(cb, "<non-unique>");
|
"<error-app-tag>data-not-unique</error-app-tag>"
|
||||||
clicon_xml2cbuf(cb, xi, 0, 0);
|
"<error-severity>error</error-severity>") < 0)
|
||||||
cprintf(cb, "</non-unique>");
|
goto done;
|
||||||
|
if (cvec_len(cvk)){
|
||||||
|
if ((xinfo = xml_new("error-info", xerr, NULL)) == NULL)
|
||||||
|
goto done;
|
||||||
|
if ((cb = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
while ((cvi = cvec_each(cvk, cvi)) != NULL){
|
||||||
|
if ((xi = xml_find(x, cv_string_get(cvi))) == NULL)
|
||||||
|
continue; /* ignore, shouldnt happen */
|
||||||
|
clicon_xml2cbuf(cb, xi, 0, 0);
|
||||||
|
if (xml_parse_va(&xinfo, NULL, "<non-unique>%s</non-unique>", cbuf_get(cb)) < 0)
|
||||||
|
goto done;
|
||||||
|
cbuf_reset(cb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (cprintf(cb, "</error-info></rpc-error></rpc-reply>") <0)
|
|
||||||
goto err;
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
if (cb)
|
||||||
|
cbuf_free(cb);
|
||||||
return retval;
|
return retval;
|
||||||
err:
|
|
||||||
clicon_err(OE_XML, errno, "cprintf");
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Create Netconf too-many/few-elements err msg according to RFC 7950 15.2/15.3
|
/*! Create Netconf too-many/few-elements err msg according to RFC 7950 15.2/15.3
|
||||||
*
|
*
|
||||||
* A NETCONF operation would result in configuration data where a
|
* A NETCONF operation would result in configuration data where a
|
||||||
list or a leaf-list would have too many entries, the following error
|
list or a leaf-list would have too many entries, the following error
|
||||||
* @param[out] cb CLIgen buf. Error XML is written in this buffer
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
* @param[in] x List element containing duplicate
|
* @param[in] x List element containing duplicate
|
||||||
* @param[in] max If set, return too-many, otherwise too-few
|
* @param[in] max If set, return too-many, otherwise too-few
|
||||||
* @see RFC7950 Sec 15.1
|
* @see RFC7950 Sec 15.1
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
netconf_minmax_elements(cbuf *cb,
|
netconf_minmax_elements_xml(cxobj **xret,
|
||||||
cxobj *x,
|
cxobj *x,
|
||||||
int max)
|
int max)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
cxobj *xerr;
|
||||||
|
|
||||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
if (*xret == NULL){
|
||||||
"<error-type>protocol</error-type>"
|
if ((*xret = xml_new("rpc-reply", NULL, NULL)) == NULL)
|
||||||
"<error-tag>operation-failed</error-tag>"
|
goto done;
|
||||||
"<error-app-tag>too-%s-elements</error-app-tag>"
|
}
|
||||||
"<error-severity>error</error-severity>"
|
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||||
"<error-path>%s</error-path>"
|
goto done;
|
||||||
"</rpc-error></rpc-reply>",
|
if ((xerr = xml_new("rpc-error", *xret, NULL)) == NULL)
|
||||||
max?"many":"few",
|
goto done;
|
||||||
xml_name(x)) < 0) /* XXX should be xml2xpath */
|
if (xml_parse_va(&xerr, NULL, "<error-type>protocol</error-type>"
|
||||||
goto err;
|
"<error-tag>operation-failed</error-tag>"
|
||||||
|
"<error-app-tag>too-%s-elements</error-app-tag>"
|
||||||
|
"<error-severity>error</error-severity>"
|
||||||
|
"<error-path>%s</error-path>",
|
||||||
|
max?"many":"few",
|
||||||
|
xml_name(x)) < 0) /* XXX should be xml2xpath */
|
||||||
|
goto done;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
err:
|
|
||||||
clicon_err(OE_XML, errno, "cprintf");
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Help function: merge - check yang - if error make netconf errmsg
|
/*! Help function: merge - check yang - if error make netconf errmsg
|
||||||
* @param[in] x XML tree
|
* @param[in] x XML tree
|
||||||
* @param[in] yspec Yang spec
|
* @param[in] yspec Yang spec
|
||||||
|
|
@ -1156,3 +1221,41 @@ netconf_db_find(cxobj *xn,
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Generate netconf error msg to cbuf to use in string printout or logs
|
||||||
|
* @param[in] xerr Netconf error message on the level: <rpc-reply><rpc-error>
|
||||||
|
* @param[out] cberr Translation from netconf err to cbuf. Free with cbuf_free.
|
||||||
|
* @retval 0 OK, with cberr set
|
||||||
|
* @retval -1 Error
|
||||||
|
* @code
|
||||||
|
* cbuf *cb = NULL;
|
||||||
|
* if (netconf_err2cb(xerr, &cb) < 0)
|
||||||
|
* err;
|
||||||
|
* printf("%s", cbuf_get(cb));
|
||||||
|
* @endcode
|
||||||
|
* @see clicon_rpc_generate_error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
netconf_err2cb(cxobj *xerr,
|
||||||
|
cbuf **cberr)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
cbuf *cb = NULL;
|
||||||
|
cxobj *x;
|
||||||
|
|
||||||
|
if ((cb = cbuf_new()) ==NULL){
|
||||||
|
clicon_err(OE_XML, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ((x=xpath_first(xerr, "error-type"))!=NULL)
|
||||||
|
cprintf(cb, "%s ", xml_body(x));
|
||||||
|
if ((x=xpath_first(xerr, "error-tag"))!=NULL)
|
||||||
|
cprintf(cb, "%s ", xml_body(x));
|
||||||
|
if ((x=xpath_first(xerr, "error-message"))!=NULL)
|
||||||
|
cprintf(cb, "%s ", xml_body(x));
|
||||||
|
if ((x=xpath_first(xerr, "error-info"))!=NULL)
|
||||||
|
clicon_xml2cbuf(cb, xml_child_i(x,0), 0, 0);
|
||||||
|
*cberr = cb;
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@
|
||||||
#include "clixon_data.h"
|
#include "clixon_data.h"
|
||||||
#include "clixon_xpath_ctx.h"
|
#include "clixon_xpath_ctx.h"
|
||||||
#include "clixon_xpath.h"
|
#include "clixon_xpath.h"
|
||||||
|
#include "clixon_netconf_lib.h"
|
||||||
#include "clixon_xml_map.h"
|
#include "clixon_xml_map.h"
|
||||||
|
|
||||||
/* Mapping between Clicon startup modes string <--> constants,
|
/* Mapping between Clicon startup modes string <--> constants,
|
||||||
|
|
@ -145,6 +146,7 @@ parse_configfile(clicon_handle h,
|
||||||
char *body;
|
char *body;
|
||||||
clicon_hash_t *copt = clicon_options(h);
|
clicon_hash_t *copt = clicon_options(h);
|
||||||
cbuf *cbret = NULL;
|
cbuf *cbret = NULL;
|
||||||
|
cxobj *xret = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (filename == NULL || !strlen(filename)){
|
if (filename == NULL || !strlen(filename)){
|
||||||
|
|
@ -194,13 +196,11 @@ parse_configfile(clicon_handle h,
|
||||||
}
|
}
|
||||||
if (xml_apply0(xc, CX_ELMNT, xml_default, h) < 0)
|
if (xml_apply0(xc, CX_ELMNT, xml_default, h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((cbret = cbuf_new()) == NULL){
|
if ((ret = xml_yang_validate_add(h, xc, &xret)) < 0)
|
||||||
clicon_err(OE_XML, errno, "cbuf_new");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if ((ret = xml_yang_validate_add(h, xc, cbret)) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
|
if (netconf_err2cb(xret, &cbret) < 0)
|
||||||
|
goto done;
|
||||||
clicon_err(OE_CFG, 0, "Config file validation: %s", cbuf_get(cbret));
|
clicon_err(OE_CFG, 0, "Config file validation: %s", cbuf_get(cbret));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -234,6 +234,8 @@ parse_configfile(clicon_handle h,
|
||||||
done:
|
done:
|
||||||
if (cbret)
|
if (cbret)
|
||||||
cbuf_free(cbret);
|
cbuf_free(cbret);
|
||||||
|
if (xret)
|
||||||
|
xml_free(xret);
|
||||||
if (xt)
|
if (xt)
|
||||||
xml_free(xt);
|
xml_free(xt);
|
||||||
if (f)
|
if (f)
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@
|
||||||
#include "clixon_proto.h"
|
#include "clixon_proto.h"
|
||||||
#include "clixon_err.h"
|
#include "clixon_err.h"
|
||||||
#include "clixon_err_string.h"
|
#include "clixon_err_string.h"
|
||||||
|
#include "clixon_netconf_lib.h"
|
||||||
#include "clixon_proto_client.h"
|
#include "clixon_proto_client.h"
|
||||||
|
|
||||||
/*! Send internal netconf rpc from client to backend
|
/*! Send internal netconf rpc from client to backend
|
||||||
|
|
@ -224,29 +225,22 @@ clicon_rpc_netconf_xml(clicon_handle h,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Generate and log clicon error function call from Netconf error message
|
/*! Generate and log clicon error function call from Netconf error message
|
||||||
|
* @param[in] prefix Print this string (if given) before: "<prefix>: <error>"
|
||||||
* @param[in] xerr Netconf error message on the level: <rpc-reply><rpc-error>
|
* @param[in] xerr Netconf error message on the level: <rpc-reply><rpc-error>
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clicon_rpc_generate_error(char *format,
|
clicon_rpc_generate_error(char *prefix,
|
||||||
cxobj *xerr)
|
cxobj *xerr)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cbuf *cb = NULL;
|
cbuf *cb = NULL;
|
||||||
cxobj *x;
|
|
||||||
|
|
||||||
if ((cb = cbuf_new()) ==NULL){
|
if (netconf_err2cb(xerr, &cb) < 0)
|
||||||
clicon_err(OE_XML, errno, "cbuf_new");
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
if (prefix)
|
||||||
if ((x=xpath_first(xerr, "error-type"))!=NULL)
|
clicon_log(LOG_ERR, "%s: %s", prefix, cbuf_get(cb));
|
||||||
cprintf(cb, "%s ", xml_body(x));
|
else
|
||||||
if ((x=xpath_first(xerr, "error-tag"))!=NULL)
|
clicon_log(LOG_ERR, "%s", cbuf_get(cb));
|
||||||
cprintf(cb, "%s ", xml_body(x));
|
|
||||||
if ((x=xpath_first(xerr, "error-message"))!=NULL)
|
|
||||||
cprintf(cb, "%s ", xml_body(x));
|
|
||||||
if ((x=xpath_first(xerr, "error-info"))!=NULL)
|
|
||||||
clicon_xml2cbuf(cb, xml_child_i(x,0), 0, 0);
|
|
||||||
clicon_log(LOG_ERR, "%s: %s", format, cbuf_get(cb));
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (cb)
|
if (cb)
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@
|
||||||
#include "clixon_options.h"
|
#include "clixon_options.h"
|
||||||
#include "clixon_data.h"
|
#include "clixon_data.h"
|
||||||
#include "clixon_yang_module.h"
|
#include "clixon_yang_module.h"
|
||||||
|
#include "clixon_netconf_lib.h"
|
||||||
#include "clixon_xml_map.h"
|
#include "clixon_xml_map.h"
|
||||||
#include "clixon_xml_changelog.h"
|
#include "clixon_xml_changelog.h"
|
||||||
#include "clixon_xpath_ctx.h"
|
#include "clixon_xpath_ctx.h"
|
||||||
|
|
@ -424,8 +425,9 @@ clixon_xml_changelog_init(clicon_handle h)
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
cxobj *xt = NULL;
|
cxobj *xt = NULL;
|
||||||
yang_stmt *yspec;
|
yang_stmt *yspec;
|
||||||
cbuf *cbret = NULL;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
cxobj *xret = NULL;
|
||||||
|
cbuf *cbret = NULL;
|
||||||
|
|
||||||
yspec = clicon_dbspec_yang(h);
|
yspec = clicon_dbspec_yang(h);
|
||||||
if ((filename = clicon_option_str(h, "CLICON_XML_CHANGELOG_FILE")) != NULL){
|
if ((filename = clicon_option_str(h, "CLICON_XML_CHANGELOG_FILE")) != NULL){
|
||||||
|
|
@ -437,15 +439,13 @@ clixon_xml_changelog_init(clicon_handle h)
|
||||||
goto done;
|
goto done;
|
||||||
if (xml_rootchild(xt, 0, &xt) < 0)
|
if (xml_rootchild(xt, 0, &xt) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((cbret = cbuf_new()) == NULL){
|
if ((ret = xml_yang_validate_all(h, xt, &xret)) < 0)
|
||||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
if (ret==1 && (ret = xml_yang_validate_add(h, xt, &xret)) < 0)
|
||||||
if ((ret = xml_yang_validate_all(h, xt, cbret)) < 0)
|
|
||||||
goto done;
|
|
||||||
if (ret==1 && (ret = xml_yang_validate_add(h, xt, cbret)) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){ /* validation failed */
|
if (ret == 0){ /* validation failed */
|
||||||
|
if (netconf_err2cb(xret, &cbret) < 0)
|
||||||
|
goto done;
|
||||||
clicon_err(OE_YANG, 0, "validation failed: %s", cbuf_get(cbret));
|
clicon_err(OE_YANG, 0, "validation failed: %s", cbuf_get(cbret));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -455,12 +455,14 @@ clixon_xml_changelog_init(clicon_handle h)
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
if (cbret)
|
||||||
|
cbuf_free(cbret);
|
||||||
|
if (xret)
|
||||||
|
xml_free(xret);
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
close(fd);
|
close(fd);
|
||||||
if (xt)
|
if (xt)
|
||||||
xml_free(xt);
|
xml_free(xt);
|
||||||
if (cbret)
|
|
||||||
cbuf_free(cbret);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ xml2cli(FILE *f,
|
||||||
/*! Validate xml node of type leafref, ensure the value is one of that path's reference
|
/*! Validate xml node of type leafref, ensure the value is one of that path's reference
|
||||||
* @param[in] xt XML leaf node of type leafref
|
* @param[in] xt XML leaf node of type leafref
|
||||||
* @param[in] ytype Yang type statement belonging to the XML node
|
* @param[in] ytype Yang type statement belonging to the XML node
|
||||||
* @param[out] cbret Error buffer
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
* @retval 1 Validation OK
|
* @retval 1 Validation OK
|
||||||
* @retval 0 Validation failed
|
* @retval 0 Validation failed
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
|
|
@ -256,7 +256,7 @@ xml2cli(FILE *f,
|
||||||
static int
|
static int
|
||||||
validate_leafref(cxobj *xt,
|
validate_leafref(cxobj *xt,
|
||||||
yang_stmt *ytype,
|
yang_stmt *ytype,
|
||||||
cbuf *cbret)
|
cxobj **xret)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
yang_stmt *ypath;
|
yang_stmt *ypath;
|
||||||
|
|
@ -270,7 +270,7 @@ validate_leafref(cxobj *xt,
|
||||||
if ((leafrefbody = xml_body(xt)) == NULL)
|
if ((leafrefbody = xml_body(xt)) == NULL)
|
||||||
goto ok;
|
goto ok;
|
||||||
if ((ypath = yang_find(ytype, Y_PATH, NULL)) == NULL){
|
if ((ypath = yang_find(ytype, Y_PATH, NULL)) == NULL){
|
||||||
if (netconf_missing_element(cbret, "application", yang_argument_get(ytype), "Leafref requires path statement") < 0)
|
if (netconf_missing_element_xml(xret, "application", yang_argument_get(ytype), "Leafref requires path statement") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -284,12 +284,12 @@ validate_leafref(cxobj *xt,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i==xlen){
|
if (i==xlen){
|
||||||
if (netconf_bad_element(cbret, "application", leafrefbody, "Leafref validation failed: No such leaf") < 0)
|
if (netconf_bad_element_xml(xret, "application", leafrefbody, "Leafref validation failed: No such leaf") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
ok:
|
ok:
|
||||||
retval = 0;
|
retval = 1;
|
||||||
done:
|
done:
|
||||||
if (xvec)
|
if (xvec)
|
||||||
free(xvec);
|
free(xvec);
|
||||||
|
|
@ -312,7 +312,7 @@ validate_leafref(cxobj *xt,
|
||||||
* @param[in] xt XML leaf node of type identityref
|
* @param[in] xt XML leaf node of type identityref
|
||||||
* @param[in] ys Yang spec of leaf
|
* @param[in] ys Yang spec of leaf
|
||||||
* @param[in] ytype Yang type field of type identityref
|
* @param[in] ytype Yang type field of type identityref
|
||||||
* @param[out] cbret Error buffer
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
* @retval 1 Validation OK
|
* @retval 1 Validation OK
|
||||||
* @retval 0 Validation failed
|
* @retval 0 Validation failed
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
|
|
@ -324,7 +324,8 @@ static int
|
||||||
validate_identityref(cxobj *xt,
|
validate_identityref(cxobj *xt,
|
||||||
yang_stmt *ys,
|
yang_stmt *ys,
|
||||||
yang_stmt *ytype,
|
yang_stmt *ytype,
|
||||||
cbuf *cbret)
|
cxobj **xret)
|
||||||
|
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
char *node;
|
char *node;
|
||||||
|
|
@ -350,13 +351,13 @@ validate_identityref(cxobj *xt,
|
||||||
}
|
}
|
||||||
/* This is the type's base reference */
|
/* This is the type's base reference */
|
||||||
if ((ybaseref = yang_find(ytype, Y_BASE, NULL)) == NULL){
|
if ((ybaseref = yang_find(ytype, Y_BASE, NULL)) == NULL){
|
||||||
if (netconf_missing_element(cbret, "application", yang_argument_get(ytype), "Identityref validation failed, no base") < 0)
|
if (netconf_missing_element_xml(xret, "application", yang_argument_get(ytype), "Identityref validation failed, no base") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
/* This is the actual base identity */
|
/* This is the actual base identity */
|
||||||
if ((ybaseid = yang_find_identity(ybaseref, yang_argument_get(ybaseref))) == NULL){
|
if ((ybaseid = yang_find_identity(ybaseref, yang_argument_get(ybaseref))) == NULL){
|
||||||
if (netconf_missing_element(cbret, "application", yang_argument_get(ybaseref), "Identityref validation failed, no base identity") < 0)
|
if (netconf_missing_element_xml(xret, "application", yang_argument_get(ybaseref), "Identityref validation failed, no base identity") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -367,7 +368,7 @@ validate_identityref(cxobj *xt,
|
||||||
cbuf_reset(cb);
|
cbuf_reset(cb);
|
||||||
cprintf(cb, "Identityref validation failed, %s not derived from %s",
|
cprintf(cb, "Identityref validation failed, %s not derived from %s",
|
||||||
node, yang_argument_get(ybaseid));
|
node, yang_argument_get(ybaseid));
|
||||||
if (netconf_operation_failed(cbret, "application", cbuf_get(cb)) < 0)
|
if (netconf_operation_failed_xml(xret, "application", cbuf_get(cb)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -413,10 +414,12 @@ xml_yang_root(cxobj *x,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Validate an RPC node
|
/*! Validate an RPC node
|
||||||
* @param[in] xt XML node to be validated
|
* @param[in] h Clicon handle
|
||||||
* @retval 1 Validation OK
|
* @param[in] xrpc XML node to be validated
|
||||||
* @retval 0 Validation failed
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
* @retval -1 Error
|
* @retval 1 Validation OK
|
||||||
|
* @retval 0 Validation failed
|
||||||
|
* @retval -1 Error
|
||||||
* rfc7950
|
* rfc7950
|
||||||
* 7.14.2
|
* 7.14.2
|
||||||
* If a leaf in the input tree has a "mandatory" statement with the
|
* If a leaf in the input tree has a "mandatory" statement with the
|
||||||
|
|
@ -454,8 +457,8 @@ xml_yang_root(cxobj *x,
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xml_yang_validate_rpc(clicon_handle h,
|
xml_yang_validate_rpc(clicon_handle h,
|
||||||
cxobj *xrpc,
|
cxobj *xrpc,
|
||||||
cbuf *cbret)
|
cxobj **xret)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
yang_stmt *yn=NULL; /* rpc name */
|
yang_stmt *yn=NULL; /* rpc name */
|
||||||
|
|
@ -469,15 +472,15 @@ xml_yang_validate_rpc(clicon_handle h,
|
||||||
/* xn is name of rpc, ie <rcp><xn/></rpc> */
|
/* xn is name of rpc, ie <rcp><xn/></rpc> */
|
||||||
while ((xn = xml_child_each(xrpc, xn, CX_ELMNT)) != NULL) {
|
while ((xn = xml_child_each(xrpc, xn, CX_ELMNT)) != NULL) {
|
||||||
if ((yn = xml_spec(xn)) == NULL){
|
if ((yn = xml_spec(xn)) == NULL){
|
||||||
if (netconf_unknown_element(cbret, "application", xml_name(xn), NULL) < 0)
|
if (netconf_unknown_element_xml(xret, "application", xml_name(xn), NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if ((retval = xml_yang_validate_all(h, xn, cbret)) < 1)
|
if ((retval = xml_yang_validate_all(h, xn, xret)) < 1)
|
||||||
goto done; /* error or validation fail */
|
goto done; /* error or validation fail */
|
||||||
if ((retval = xml_yang_validate_add(h, xn, cbret)) < 1)
|
if ((retval = xml_yang_validate_add(h, xn, xret)) < 1)
|
||||||
goto done; /* error or validation fail */
|
goto done; /* error or validation fail */
|
||||||
if (xml_apply0(xn, CX_ELMNT, xml_default, NULL) < 0)
|
if (xml_apply0(xn, CX_ELMNT, xml_default, h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
// ok: /* pass validation */
|
// ok: /* pass validation */
|
||||||
|
|
@ -492,7 +495,7 @@ xml_yang_validate_rpc(clicon_handle h,
|
||||||
/*! Check if an xml node is a part of a choice and have >1 siblings
|
/*! Check if an xml node is a part of a choice and have >1 siblings
|
||||||
* @param[in] xt XML node to be validated
|
* @param[in] xt XML node to be validated
|
||||||
* @param[in] yt xt:s yang statement
|
* @param[in] yt xt:s yang statement
|
||||||
* @param[out] cbret Error buffer (set w netconf error if retval == 0)
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
* @retval 1 Validation OK
|
* @retval 1 Validation OK
|
||||||
* @retval 0 Validation failed (cbret set)
|
* @retval 0 Validation failed (cbret set)
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
|
|
@ -501,7 +504,7 @@ xml_yang_validate_rpc(clicon_handle h,
|
||||||
static int
|
static int
|
||||||
check_choice(cxobj *xt,
|
check_choice(cxobj *xt,
|
||||||
yang_stmt *yt,
|
yang_stmt *yt,
|
||||||
cbuf *cbret)
|
cxobj **xret)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
yang_stmt *y;
|
yang_stmt *y;
|
||||||
|
|
@ -552,7 +555,7 @@ check_choice(cxobj *xt,
|
||||||
continue; /* not choice */
|
continue; /* not choice */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (netconf_bad_element(cbret, "application", xml_name(x), "Element in choice statement already exists") < 0)
|
if (netconf_bad_element_xml(xret, "application", xml_name(x), "Element in choice statement already exists") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
@ -569,7 +572,7 @@ check_choice(cxobj *xt,
|
||||||
/*! Check if an xml node lacks mandatory children
|
/*! Check if an xml node lacks mandatory children
|
||||||
* @param[in] xt XML node to be validated
|
* @param[in] xt XML node to be validated
|
||||||
* @param[in] yt xt:s yang statement
|
* @param[in] yt xt:s yang statement
|
||||||
* @param[out] cbret Error buffer (set w netconf error if retval == 0)
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
* @retval 1 Validation OK
|
* @retval 1 Validation OK
|
||||||
* @retval 0 Validation failed (cbret set)
|
* @retval 0 Validation failed (cbret set)
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
|
|
@ -577,7 +580,8 @@ check_choice(cxobj *xt,
|
||||||
static int
|
static int
|
||||||
check_mandatory(cxobj *xt,
|
check_mandatory(cxobj *xt,
|
||||||
yang_stmt *yt,
|
yang_stmt *yt,
|
||||||
cbuf *cbret)
|
cxobj **xret)
|
||||||
|
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -600,7 +604,7 @@ check_mandatory(cxobj *xt,
|
||||||
while ((cvi = cvec_each(cvk, cvi)) != NULL) {
|
while ((cvi = cvec_each(cvk, cvi)) != NULL) {
|
||||||
keyname = cv_string_get(cvi);
|
keyname = cv_string_get(cvi);
|
||||||
if (xml_find_type(xt, NULL, keyname, CX_ELMNT) == NULL){
|
if (xml_find_type(xt, NULL, keyname, CX_ELMNT) == NULL){
|
||||||
if (netconf_missing_element(cbret, "application", keyname, "Mandatory key") < 0)
|
if (netconf_missing_element_xml(xret, "application", keyname, "Mandatory key") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -623,7 +627,7 @@ check_mandatory(cxobj *xt,
|
||||||
break; /* got it */
|
break; /* got it */
|
||||||
}
|
}
|
||||||
if (x == NULL){
|
if (x == NULL){
|
||||||
if (netconf_missing_element(cbret, "application", yc->ys_argument, "Mandatory variable") < 0)
|
if (netconf_missing_element_xml(xret, "application", yc->ys_argument, "Mandatory variable") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -640,17 +644,7 @@ check_mandatory(cxobj *xt,
|
||||||
if (x == NULL){
|
if (x == NULL){
|
||||||
/* @see RFC7950: 15.6 Error Message for Data That Violates
|
/* @see RFC7950: 15.6 Error Message for Data That Violates
|
||||||
* a Mandatory "choice" Statement */
|
* a Mandatory "choice" Statement */
|
||||||
if (cprintf(cbret, "<rpc-reply><rpc-error>"
|
if (netconf_data_missing_xml(xret, yc->ys_argument, NULL) < 0)
|
||||||
"<error-type>application</error-type>"
|
|
||||||
"<error-tag>data-missing</error-tag>"
|
|
||||||
"<error-app-tag>missing-choice</error-app-tag>"
|
|
||||||
#ifdef NYI
|
|
||||||
// "<error-path></error-path>"
|
|
||||||
#endif
|
|
||||||
"<error-info><missing-choice>%s</missing-choice></error-info>"
|
|
||||||
"<error-severity>error</error-severity>"
|
|
||||||
"</rpc-error></rpc-reply>",
|
|
||||||
yc->ys_argument) <0)
|
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -667,10 +661,14 @@ check_mandatory(cxobj *xt,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
check_list_key(cxobj *xt,
|
check_list_key(cxobj *xt,
|
||||||
yang_stmt *yt,
|
yang_stmt *yt,
|
||||||
cbuf *cbret)
|
cxobj **xret)
|
||||||
|
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -690,7 +688,7 @@ check_list_key(cxobj *xt,
|
||||||
while ((cvi = cvec_each(cvk, cvi)) != NULL) {
|
while ((cvi = cvec_each(cvk, cvi)) != NULL) {
|
||||||
keyname = cv_string_get(cvi);
|
keyname = cv_string_get(cvi);
|
||||||
if (xml_find_type(xt, NULL, keyname, CX_ELMNT) == NULL){
|
if (xml_find_type(xt, NULL, keyname, CX_ELMNT) == NULL){
|
||||||
if (netconf_missing_element(cbret, "application", keyname, "Mandatory key") < 0)
|
if (netconf_missing_element_xml(xret, "application", keyname, "Mandatory key") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -739,7 +737,7 @@ check_insert_duplicate(char **vec,
|
||||||
* @param[in] xt The parent of x
|
* @param[in] xt The parent of x
|
||||||
* @param[in] y Its yang spec (Y_LIST)
|
* @param[in] y Its yang spec (Y_LIST)
|
||||||
* @param[in] yu A yang unique spec (Y_UNIQUE)
|
* @param[in] yu A yang unique spec (Y_UNIQUE)
|
||||||
* @param[out] cbret Error buffer (set w netconf error if retval == 0)
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
* @retval 1 Validation OK
|
* @retval 1 Validation OK
|
||||||
* @retval 0 Validation failed (cbret set)
|
* @retval 0 Validation failed (cbret set)
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
|
|
@ -750,7 +748,8 @@ check_unique_list(cxobj *x,
|
||||||
cxobj *xt,
|
cxobj *xt,
|
||||||
yang_stmt *y,
|
yang_stmt *y,
|
||||||
yang_stmt *yu,
|
yang_stmt *yu,
|
||||||
cbuf *cbret)
|
cxobj **xret)
|
||||||
|
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cvec *cvk; /* unique vector */
|
cvec *cvk; /* unique vector */
|
||||||
|
|
@ -784,7 +783,7 @@ check_unique_list(cxobj *x,
|
||||||
if (cvi==NULL){
|
if (cvi==NULL){
|
||||||
/* Last element (i) is newly inserted, see if it is already there */
|
/* Last element (i) is newly inserted, see if it is already there */
|
||||||
if (check_insert_duplicate(vec, i, vlen) < 0){
|
if (check_insert_duplicate(vec, i, vlen) < 0){
|
||||||
if (netconf_data_not_unique(cbret, x, cvk) < 0)
|
if (netconf_data_not_unique_xml(xret, x, cvk) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -807,7 +806,7 @@ check_unique_list(cxobj *x,
|
||||||
* @param[in] x One x (the last) of a specific lis
|
* @param[in] x One x (the last) of a specific lis
|
||||||
* @param[in] y Yang spec of x
|
* @param[in] y Yang spec of x
|
||||||
* @param[in] nr Number of elements (like x) in thlist
|
* @param[in] nr Number of elements (like x) in thlist
|
||||||
* @param[out] cbret Error buffer (set w netconf error if retval == 0)
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
* @retval 1 Validation OK
|
* @retval 1 Validation OK
|
||||||
* @retval 0 Validation failed (cbret set)
|
* @retval 0 Validation failed (cbret set)
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
|
|
@ -817,7 +816,7 @@ static int
|
||||||
check_min_max(cxobj *x,
|
check_min_max(cxobj *x,
|
||||||
yang_stmt *y,
|
yang_stmt *y,
|
||||||
int nr,
|
int nr,
|
||||||
cbuf *cbret)
|
cxobj **xret)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
yang_stmt *ymin; /* yang min */
|
yang_stmt *ymin; /* yang min */
|
||||||
|
|
@ -827,7 +826,7 @@ check_min_max(cxobj *x,
|
||||||
if ((ymin = yang_find(y, Y_MIN_ELEMENTS, NULL)) != NULL){
|
if ((ymin = yang_find(y, Y_MIN_ELEMENTS, NULL)) != NULL){
|
||||||
cv = yang_cv_get(ymin);
|
cv = yang_cv_get(ymin);
|
||||||
if (nr < cv_uint32_get(cv)){
|
if (nr < cv_uint32_get(cv)){
|
||||||
if (netconf_minmax_elements(cbret, x, 0) < 0)
|
if (netconf_minmax_elements_xml(xret, x, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -836,7 +835,7 @@ check_min_max(cxobj *x,
|
||||||
cv = yang_cv_get(ymax);
|
cv = yang_cv_get(ymax);
|
||||||
if (cv_uint32_get(cv) > 0 && /* 0 means unbounded */
|
if (cv_uint32_get(cv) > 0 && /* 0 means unbounded */
|
||||||
nr > cv_uint32_get(cv)){
|
nr > cv_uint32_get(cv)){
|
||||||
if (netconf_minmax_elements(cbret, x, 1) < 0)
|
if (netconf_minmax_elements_xml(xret, x, 1) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -851,9 +850,9 @@ check_min_max(cxobj *x,
|
||||||
|
|
||||||
/*! Detect unique constraint for duplicates from parent node and minmax
|
/*! Detect unique constraint for duplicates from parent node and minmax
|
||||||
* @param[in] xt XML parent (may have lists w unique constraints as child)
|
* @param[in] xt XML parent (may have lists w unique constraints as child)
|
||||||
* @param[out] cbret Error buffer (set w netconf error if retval == 0)
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
* @retval 1 Validation OK
|
* @retval 1 Validation OK
|
||||||
* @retval 0 Validation failed (cbret set)
|
* @retval 0 Validation failed (xret set)
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
* Assume xt:s children are sorted and yang populated.
|
* Assume xt:s children are sorted and yang populated.
|
||||||
* The function does two different things of the children of an XML node:
|
* The function does two different things of the children of an XML node:
|
||||||
|
|
@ -889,8 +888,8 @@ check_min_max(cxobj *x,
|
||||||
* are not allowed.
|
* are not allowed.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
check_list_unique_minmax(cxobj *xt,
|
check_list_unique_minmax(cxobj *xt,
|
||||||
cbuf *cbret)
|
cxobj **xret)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cxobj *x = NULL;
|
cxobj *x = NULL;
|
||||||
|
|
@ -932,7 +931,7 @@ check_list_unique_minmax(cxobj *xt,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Check if the list length violates min/max */
|
/* Check if the list length violates min/max */
|
||||||
if ((ret = check_min_max(xp, yp, nr, cbret)) < 0)
|
if ((ret = check_min_max(xp, yp, nr, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -953,7 +952,7 @@ check_list_unique_minmax(cxobj *xt,
|
||||||
do {
|
do {
|
||||||
if (yang_keyword_get(ye) == Y_LIST || yang_keyword_get(ye) == Y_LEAF_LIST){
|
if (yang_keyword_get(ye) == Y_LIST || yang_keyword_get(ye) == Y_LEAF_LIST){
|
||||||
/* Check if the list length violates min/max */
|
/* Check if the list length violates min/max */
|
||||||
if ((ret = check_min_max(xt, ye, 0, cbret)) < 0)
|
if ((ret = check_min_max(xt, ye, 0, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -973,7 +972,7 @@ check_list_unique_minmax(cxobj *xt,
|
||||||
* its first element x, its yang spec y, its parent xt, and
|
* its first element x, its yang spec y, its parent xt, and
|
||||||
* a unique yang spec yu,
|
* a unique yang spec yu,
|
||||||
*/
|
*/
|
||||||
if ((ret = check_unique_list(x, xt, y, yu, cbret)) < 0)
|
if ((ret = check_unique_list(x, xt, y, yu, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -984,7 +983,7 @@ check_list_unique_minmax(cxobj *xt,
|
||||||
*/
|
*/
|
||||||
if (yp){
|
if (yp){
|
||||||
/* Check if the list length violates min/max */
|
/* Check if the list length violates min/max */
|
||||||
if ((ret = check_min_max(xp, yp, nr, cbret)) < 0)
|
if ((ret = check_min_max(xp, yp, nr, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -996,7 +995,7 @@ check_list_unique_minmax(cxobj *xt,
|
||||||
do {
|
do {
|
||||||
if (yang_keyword_get(ye) == Y_LIST || yang_keyword_get(ye) == Y_LEAF_LIST){
|
if (yang_keyword_get(ye) == Y_LIST || yang_keyword_get(ye) == Y_LEAF_LIST){
|
||||||
/* Check if the list length violates min/max */
|
/* Check if the list length violates min/max */
|
||||||
if ((ret = check_min_max(xt, ye, 0, cbret)) < 0)
|
if ((ret = check_min_max(xt, ye, 0, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -1014,14 +1013,14 @@ check_list_unique_minmax(cxobj *xt,
|
||||||
* 1. Check if mandatory leafs present as subs.
|
* 1. Check if mandatory leafs present as subs.
|
||||||
* 2. Check leaf values, eg int ranges and string regexps.
|
* 2. Check leaf values, eg int ranges and string regexps.
|
||||||
* @param[in] xt XML node to be validated
|
* @param[in] xt XML node to be validated
|
||||||
* @param[out] cbret Error buffer (set w netconf error if retval == 0)
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
* @retval 1 Validation OK
|
* @retval 1 Validation OK
|
||||||
* @retval 0 Validation failed (cbret set)
|
* @retval 0 Validation failed (cbret set)
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
* @code
|
* @code
|
||||||
* cxobj *x;
|
* cxobj *x;
|
||||||
* cbuf *cbret = cbuf_new();
|
* cbuf *xret = NULL;
|
||||||
* if ((ret = xml_yang_validate_add(h, x, cbret)) < 0)
|
* if ((ret = xml_yang_validate_add(h, x, &xret)) < 0)
|
||||||
* err;
|
* err;
|
||||||
* if (ret == 0)
|
* if (ret == 0)
|
||||||
* fail;
|
* fail;
|
||||||
|
|
@ -1032,8 +1031,8 @@ check_list_unique_minmax(cxobj *xt,
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xml_yang_validate_add(clicon_handle h,
|
xml_yang_validate_add(clicon_handle h,
|
||||||
cxobj *xt,
|
cxobj *xt,
|
||||||
cbuf *cbret)
|
cxobj **xret)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cg_var *cv = NULL;
|
cg_var *cv = NULL;
|
||||||
|
|
@ -1047,11 +1046,11 @@ xml_yang_validate_add(clicon_handle h,
|
||||||
/* if not given by argument (overide) use default link
|
/* if not given by argument (overide) use default link
|
||||||
and !Node has a config sub-statement and it is false */
|
and !Node has a config sub-statement and it is false */
|
||||||
if ((yt = xml_spec(xt)) != NULL && yang_config(yt) != 0){
|
if ((yt = xml_spec(xt)) != NULL && yang_config(yt) != 0){
|
||||||
if ((ret = check_choice(xt, yt, cbret)) < 0)
|
if ((ret = check_choice(xt, yt, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
if ((ret = check_mandatory(xt, yt, cbret)) < 0)
|
if ((ret = check_mandatory(xt, yt, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -1073,21 +1072,21 @@ xml_yang_validate_add(clicon_handle h,
|
||||||
* are considered as "" */
|
* are considered as "" */
|
||||||
cvtype = cv_type_get(cv);
|
cvtype = cv_type_get(cv);
|
||||||
if (cv_isint(cvtype) || cvtype == CGV_BOOL || cvtype == CGV_DEC64){
|
if (cv_isint(cvtype) || cvtype == CGV_BOOL || cvtype == CGV_DEC64){
|
||||||
if (netconf_bad_element(cbret, "application", yt->ys_argument, "Invalid NULL value") < 0)
|
if (netconf_bad_element_xml(xret, "application", yt->ys_argument, "Invalid NULL value") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (cv_parse1(body, cv, &reason) != 1){
|
if (cv_parse1(body, cv, &reason) != 1){
|
||||||
if (netconf_bad_element(cbret, "application", yt->ys_argument, reason) < 0)
|
if (netconf_bad_element_xml(xret, "application", yt->ys_argument, reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ys_cv_validate(h, cv, yt, &reason)) != 1){
|
if ((ys_cv_validate(h, cv, yt, &reason)) != 1){
|
||||||
if (netconf_bad_element(cbret, "application", yt->ys_argument, reason) < 0)
|
if (netconf_bad_element_xml(xret, "application", yt->ys_argument, reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -1098,7 +1097,7 @@ xml_yang_validate_add(clicon_handle h,
|
||||||
}
|
}
|
||||||
x = NULL;
|
x = NULL;
|
||||||
while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL) {
|
while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL) {
|
||||||
if ((ret = xml_yang_validate_add(h, x, cbret)) < 0)
|
if ((ret = xml_yang_validate_add(h, x, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -1116,11 +1115,12 @@ xml_yang_validate_add(clicon_handle h,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Some checks done only at edit_config, eg keys in lists
|
/*! Some checks done only at edit_config, eg keys in lists
|
||||||
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xml_yang_validate_list_key_only(clicon_handle h,
|
xml_yang_validate_list_key_only(clicon_handle h,
|
||||||
cxobj *xt,
|
cxobj *xt,
|
||||||
cbuf *cbret)
|
cxobj **xret)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
yang_stmt *yt; /* yang spec of xt going in */
|
yang_stmt *yt; /* yang spec of xt going in */
|
||||||
|
|
@ -1130,14 +1130,14 @@ xml_yang_validate_list_key_only(clicon_handle h,
|
||||||
/* if not given by argument (overide) use default link
|
/* if not given by argument (overide) use default link
|
||||||
and !Node has a config sub-statement and it is false */
|
and !Node has a config sub-statement and it is false */
|
||||||
if ((yt = xml_spec(xt)) != NULL && yang_config(yt) != 0){
|
if ((yt = xml_spec(xt)) != NULL && yang_config(yt) != 0){
|
||||||
if ((ret = check_list_key(xt, yt, cbret)) < 0)
|
if ((ret = check_list_key(xt, yt, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
x = NULL;
|
x = NULL;
|
||||||
while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL) {
|
while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL) {
|
||||||
if ((ret = xml_yang_validate_list_key_only(h, x, cbret)) < 0)
|
if ((ret = xml_yang_validate_list_key_only(h, x, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -1154,17 +1154,18 @@ xml_yang_validate_list_key_only(clicon_handle h,
|
||||||
/*! Validate a single XML node with yang specification for all (not only added) entries
|
/*! Validate a single XML node with yang specification for all (not only added) entries
|
||||||
* 1. Check leafrefs. Eg you delete a leaf and a leafref references it.
|
* 1. Check leafrefs. Eg you delete a leaf and a leafref references it.
|
||||||
* @param[in] xt XML node to be validated
|
* @param[in] xt XML node to be validated
|
||||||
* @param[out] cbret Error buffer (set w netconf error if retval == 0)
|
* @param[out] xret Error XML tree (if retval=0). Free with xml_free after use
|
||||||
* @retval 1 Validation OK
|
* @retval 1 Validation OK
|
||||||
* @retval 0 Validation failed (cbret set)
|
* @retval 0 Validation failed (cbret set)
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
* @code
|
* @code
|
||||||
* cxobj *x;
|
* cxobj *x;
|
||||||
* cbuf *cbret = cbuf_new();
|
* cbuf *xret = NULL;
|
||||||
* if ((ret = xml_yang_validate_all(x, cbret)) < 0)
|
* if ((ret = xml_yang_validate_all(h, x, &xret)) < 0)
|
||||||
* err;
|
* err;
|
||||||
* if (ret == 0)
|
* if (ret == 0)
|
||||||
* fail;
|
* fail;
|
||||||
|
* xml_free(xret);
|
||||||
* @endcode
|
* @endcode
|
||||||
* @see xml_yang_validate_add
|
* @see xml_yang_validate_add
|
||||||
* @see xml_yang_validate_rpc
|
* @see xml_yang_validate_rpc
|
||||||
|
|
@ -1172,8 +1173,8 @@ xml_yang_validate_list_key_only(clicon_handle h,
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xml_yang_validate_all(clicon_handle h,
|
xml_yang_validate_all(clicon_handle h,
|
||||||
cxobj *xt,
|
cxobj *xt,
|
||||||
cbuf *cbret)
|
cxobj **xret)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
yang_stmt *ys; /* yang node */
|
yang_stmt *ys; /* yang node */
|
||||||
|
|
@ -1188,7 +1189,7 @@ xml_yang_validate_all(clicon_handle h,
|
||||||
and !Node has a config sub-statement and it is false */
|
and !Node has a config sub-statement and it is false */
|
||||||
ys=xml_spec(xt);
|
ys=xml_spec(xt);
|
||||||
if (ys==NULL){
|
if (ys==NULL){
|
||||||
if (netconf_unknown_element(cbret, "application", xml_name(xt), NULL) < 0)
|
if (netconf_unknown_element_xml(xret, "application", xml_name(xt), NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -1207,12 +1208,16 @@ xml_yang_validate_all(clicon_handle h,
|
||||||
*/
|
*/
|
||||||
if ((yc = yang_find(ys, Y_TYPE, NULL)) != NULL){
|
if ((yc = yang_find(ys, Y_TYPE, NULL)) != NULL){
|
||||||
if (strcmp(yc->ys_argument, "leafref") == 0){
|
if (strcmp(yc->ys_argument, "leafref") == 0){
|
||||||
if (validate_leafref(xt, yc, cbret) < 0)
|
if ((ret = validate_leafref(xt, yc, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
if (ret == 0)
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
else if (strcmp(yc->ys_argument, "identityref") == 0){
|
else if (strcmp(yc->ys_argument, "identityref") == 0){
|
||||||
if (validate_identityref(xt, ys, yc, cbret) < 0)
|
if ((ret = validate_identityref(xt, ys, yc, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
if (ret == 0)
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -1230,7 +1235,7 @@ xml_yang_validate_all(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
if (!nr){
|
if (!nr){
|
||||||
ye = yang_find(yc, Y_ERROR_MESSAGE, NULL);
|
ye = yang_find(yc, Y_ERROR_MESSAGE, NULL);
|
||||||
if (netconf_operation_failed(cbret, "application",
|
if (netconf_operation_failed_xml(xret, "application",
|
||||||
ye?ye->ys_argument:"must xpath validation failed") < 0)
|
ye?ye->ys_argument:"must xpath validation failed") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -1242,7 +1247,7 @@ xml_yang_validate_all(clicon_handle h,
|
||||||
if ((nr = xpath_vec_bool(xt, "%s", xpath)) < 0)
|
if ((nr = xpath_vec_bool(xt, "%s", xpath)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (!nr){
|
if (!nr){
|
||||||
if (netconf_operation_failed(cbret, "application",
|
if (netconf_operation_failed_xml(xret, "application",
|
||||||
"when xpath validation failed") < 0)
|
"when xpath validation failed") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -1251,7 +1256,7 @@ xml_yang_validate_all(clicon_handle h,
|
||||||
}
|
}
|
||||||
x = NULL;
|
x = NULL;
|
||||||
while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL) {
|
while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL) {
|
||||||
if ((ret = xml_yang_validate_all(h, x, cbret)) < 0)
|
if ((ret = xml_yang_validate_all(h, x, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -1259,7 +1264,7 @@ xml_yang_validate_all(clicon_handle h,
|
||||||
/* Check unique and min-max after choice test for example*/
|
/* Check unique and min-max after choice test for example*/
|
||||||
if (yang_config(ys) != 0){
|
if (yang_config(ys) != 0){
|
||||||
/* Checks if next level contains any unique list constraints */
|
/* Checks if next level contains any unique list constraints */
|
||||||
if ((ret = check_list_unique_minmax(xt, cbret)) < 0)
|
if ((ret = check_list_unique_minmax(xt, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -1274,24 +1279,25 @@ xml_yang_validate_all(clicon_handle h,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Translate a single xml node to a cligen variable vector. Note not recursive
|
/*! Translate a single xml node to a cligen variable vector. Note not recursive
|
||||||
|
* @param[out] xret Error XML tree (if ret == 0). Free with xml_free after use
|
||||||
* @retval 1 Validation OK
|
* @retval 1 Validation OK
|
||||||
* @retval 0 Validation failed (cbret set)
|
* @retval 0 Validation failed (xret set)
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xml_yang_validate_all_top(clicon_handle h,
|
xml_yang_validate_all_top(clicon_handle h,
|
||||||
cxobj *xt,
|
cxobj *xt,
|
||||||
cbuf *cbret)
|
cxobj **xret)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
cxobj *x;
|
cxobj *x;
|
||||||
|
|
||||||
x = NULL;
|
x = NULL;
|
||||||
while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL) {
|
while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL) {
|
||||||
if ((ret = xml_yang_validate_all(h, x, cbret)) < 1)
|
if ((ret = xml_yang_validate_all(h, x, xret)) < 1)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if ((ret = check_list_unique_minmax(xt, cbret)) < 1)
|
if ((ret = check_list_unique_minmax(xt, xret)) < 1)
|
||||||
return ret;
|
return ret;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ testnr=0
|
||||||
for test in $pattern; do
|
for test in $pattern; do
|
||||||
if [ $testnr != 0 ]; then echo; fi
|
if [ $testnr != 0 ]; then echo; fi
|
||||||
testfile=$test
|
testfile=$test
|
||||||
ret=$(./$test) # . ./$test
|
. ./$test
|
||||||
errcode=$?
|
errcode=$?
|
||||||
if [ $errcode -ne 0 ]; then
|
if [ $errcode -ne 0 ]; then
|
||||||
err=1
|
err=1
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ cat <<EOF > $cfg
|
||||||
<CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
||||||
|
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
|
||||||
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
||||||
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
|
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
|
||||||
<CLICON_BACKEND_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP>
|
<CLICON_BACKEND_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP>
|
||||||
|
|
@ -108,80 +109,82 @@ cat <<EOF > $fyang
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
new "test params: -f $cfg -y $fyang"
|
new "test params: -f $cfg"
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "kill old backend"
|
new "kill old backend"
|
||||||
sudo clixon_backend -zf $cfg
|
sudo clixon_backend -zf $cfg
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
err
|
err
|
||||||
fi
|
fi
|
||||||
new "start backend -s init -f $cfg -y $fyang"
|
new "start backend -s init -f $cfg"
|
||||||
start_backend -s init -f $cfg -y $fyang
|
start_backend -s init -f $cfg
|
||||||
|
|
||||||
new "waiting"
|
new "waiting"
|
||||||
sleep $RCWAIT
|
sleep $RCWAIT
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new "Set crypto to aes"
|
new "Set crypto to aes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><edit-config><target><candidate/></target><config><crypto xmlns="urn:example:my-crypto">aes</crypto></config></edit-config></rpc>]]>]]>' '^<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><ok/></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><edit-config><target><candidate/></target><config><crypto xmlns="urn:example:my-crypto">aes</crypto></config></edit-config></rpc>]]>]]>' '^<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><ok/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "netconf validate "
|
new "netconf validate "
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Set crypto to mc:aes"
|
new "Set crypto to mc:aes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><crypto xmlns="urn:example:my-crypto">mc:aes</crypto></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><crypto xmlns="urn:example:my-crypto">mc:aes</crypto></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate"
|
new "netconf validate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Set crypto to des:des3"
|
new "Set crypto to des:des3"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><crypto xmlns="urn:example:my-crypto">des:des3</crypto></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><crypto xmlns="urn:example:my-crypto">des:des3</crypto></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate"
|
new "netconf validate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Set crypto to mc:foo"
|
new "Set crypto to mc:foo"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><crypto xmlns="urn:example:my-crypto">mc:foo</crypto></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><crypto xmlns="urn:example:my-crypto">mc:foo</crypto></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate"
|
new "netconf validate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Set crypto to des:des3 using xmlns"
|
new "Set crypto to des:des3 using xmlns"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><crypto xmlns="urn:example:my-crypto" xmlns:des="urn:example:des">des:des3</crypto></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><crypto xmlns="urn:example:my-crypto" xmlns:des="urn:example:des">des:des3</crypto></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate"
|
new "netconf validate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
if false; then
|
||||||
# XXX this is not supported
|
# XXX this is not supported
|
||||||
#new "Set crypto to x:des3 using xmlns"
|
new "Set crypto to x:des3 using xmlns"
|
||||||
#expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><crypto xmlns="urn:example:my-crypto" xmlns:x="urn:example:des">x:des3</crypto></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><crypto xmlns="urn:example:my-crypto" xmlns:x="urn:example:des">x:des3</crypto></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate"
|
new "netconf validate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
fi # not supported
|
||||||
|
|
||||||
new "Set crypto to foo:bar"
|
new "Set crypto to foo:bar"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><crypto xmlns="urn:example:my-crypto">foo:bar</crypto></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><crypto xmlns="urn:example:my-crypto">foo:bar</crypto></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate"
|
new "netconf validate (expect fail)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 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, foo:bar not derived from crypto-alg</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>operation-failed</error-tag><error-severity>error</error-severity><error-message>Identityref validation failed, foo:bar not derived from crypto-alg</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "cli set crypto to mc:aes"
|
new "cli set crypto to mc:aes"
|
||||||
expectfn "$clixon_cli -1 -f $cfg -y $fyang -l o set crypto mc:aes" 0 "^$"
|
expectfn "$clixon_cli -1 -f $cfg -l o set crypto mc:aes" 0 "^$"
|
||||||
|
|
||||||
new "cli validate"
|
new "cli validate"
|
||||||
expectfn "$clixon_cli -1 -f $cfg -y $fyang -l o validate" 0 "^$"
|
expectfn "$clixon_cli -1 -f $cfg -l o validate" 0 "^$"
|
||||||
|
|
||||||
new "cli set crypto to aes"
|
new "cli set crypto to aes"
|
||||||
expectfn "$clixon_cli -1 -f $cfg -y $fyang -l o set crypto aes" 0 "^$"
|
expectfn "$clixon_cli -1 -f $cfg -l o set crypto aes" 0 "^$"
|
||||||
|
|
||||||
new "cli validate"
|
new "cli validate"
|
||||||
expectfn "$clixon_cli -1 -f $cfg -y $fyang -l o validate" 0 "^$"
|
expectfn "$clixon_cli -1 -f $cfg -l o validate" 0 "^$"
|
||||||
|
|
||||||
new "cli set crypto to des:des3"
|
new "cli set crypto to des:des3"
|
||||||
expectfn "$clixon_cli -1 -f $cfg -y $fyang -l o set crypto des:des3" 0 "^$"
|
expectfn "$clixon_cli -1 -f $cfg -l o set crypto des:des3" 0 "^$"
|
||||||
|
|
||||||
new "cli validate"
|
new "cli validate"
|
||||||
expectfn "$clixon_cli -1 -f $cfg -y $fyang -l o validate" 0 "^$"
|
expectfn "$clixon_cli -1 -f $cfg -l o validate" 0 "^$"
|
||||||
|
|
||||||
if [ $BE -eq 0 ]; then
|
if [ $BE -eq 0 ]; then
|
||||||
exit # BE
|
exit # BE
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ cat <<EOF > $cfg
|
||||||
<CLICON_CONFIGFILE>/tmp/conf_yang.xml</CLICON_CONFIGFILE>
|
<CLICON_CONFIGFILE>/tmp/conf_yang.xml</CLICON_CONFIGFILE>
|
||||||
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
||||||
|
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
|
||||||
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
||||||
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
||||||
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
||||||
|
|
@ -149,16 +150,16 @@ cat <<EOF > $dbdir/running_db
|
||||||
</config>
|
</config>
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
new "test params: -s running -f $cfg -y $fyang -- -s"
|
new "test params: -s running -f $cfg -- -s"
|
||||||
|
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "kill old backend"
|
new "kill old backend"
|
||||||
sudo clixon_backend -zf $cfg -y $fyang
|
sudo clixon_backend -zf $cfg
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
err
|
err
|
||||||
fi
|
fi
|
||||||
new "start backend"
|
new "start backend"
|
||||||
start_backend -s running -f $cfg -y $fyang -- -s
|
start_backend -s running -f $cfg -- -s
|
||||||
|
|
||||||
new "waiting"
|
new "waiting"
|
||||||
sleep $RCWAIT
|
sleep $RCWAIT
|
||||||
|
|
@ -169,75 +170,75 @@ new "state data (should be unordered: 42,41,43)"
|
||||||
cat <<EOF > $tmp
|
cat <<EOF > $tmp
|
||||||
<rpc><get><filter type="xpath" select="state"/></get></rpc>]]>]]>
|
<rpc><get><filter type="xpath" select="state"/></get></rpc>]]>]]>
|
||||||
EOF
|
EOF
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "$(cat $tmp)" '<rpc-reply><data><state xmlns="urn:example:clixon"><op>42</op><op>41</op><op>43</op></state></data></rpc-reply>]]>]]>'
|
expecteof "$clixon_netconf -qf $cfg" 0 "$(cat $tmp)" '<rpc-reply><data><state xmlns="urn:example:clixon"><op>42</op><op>41</op><op>43</op></state></data></rpc-reply>]]>]]>'
|
||||||
|
|
||||||
# Check as file
|
# Check as file
|
||||||
new "verify running from start, should be: c,l,y0,y1,y2,y3; y1 and y3 sorted."
|
new "verify running from start, should be: c,l,y0,y1,y2,y3; y1 and y3 sorted."
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>' '^<rpc-reply><data><c xmlns="urn:example:order"><d>hej</d></c><l xmlns="urn:example:order">hopp</l><y0 xmlns="urn:example:order">d</y0><y0 xmlns="urn:example:order">b</y0><y0 xmlns="urn:example:order">c</y0><y0 xmlns="urn:example:order">a</y0><y1 xmlns="urn:example:order">a</y1><y1 xmlns="urn:example:order">b</y1><y1 xmlns="urn:example:order">c</y1><y1 xmlns="urn:example:order">d</y1><y2 xmlns="urn:example:order"><k>d</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>a</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>c</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>b</k><a>bar</a></y2><y3 xmlns="urn:example:order"><k>a</k><a>bar</a></y3><y3 xmlns="urn:example:order"><k>b</k><a>bar</a></y3><y3 xmlns="urn:example:order"><k>c</k><a>bar</a></y3><y3 xmlns="urn:example:order"><k>d</k><a>bar</a></y3></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>' '^<rpc-reply><data><c xmlns="urn:example:order"><d>hej</d></c><l xmlns="urn:example:order">hopp</l><y0 xmlns="urn:example:order">d</y0><y0 xmlns="urn:example:order">b</y0><y0 xmlns="urn:example:order">c</y0><y0 xmlns="urn:example:order">a</y0><y1 xmlns="urn:example:order">a</y1><y1 xmlns="urn:example:order">b</y1><y1 xmlns="urn:example:order">c</y1><y1 xmlns="urn:example:order">d</y1><y2 xmlns="urn:example:order"><k>d</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>a</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>c</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>b</k><a>bar</a></y2><y3 xmlns="urn:example:order"><k>a</k><a>bar</a></y3><y3 xmlns="urn:example:order"><k>b</k><a>bar</a></y3><y3 xmlns="urn:example:order"><k>c</k><a>bar</a></y3><y3 xmlns="urn:example:order"><k>d</k><a>bar</a></y3></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "get each ordered-by user leaf-list"
|
new "get each ordered-by user leaf-list"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y2[k='a']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y2 xmlns="urn:example:order"><k>a</k><a>bar</a></y2></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y2[k='a']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y2 xmlns="urn:example:order"><k>a</k><a>bar</a></y2></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "get each ordered-by user leaf-list"
|
new "get each ordered-by user leaf-list"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y3[k='a']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y3 xmlns="urn:example:order"><k>a</k><a>bar</a></y3></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y3[k='a']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y3 xmlns="urn:example:order"><k>a</k><a>bar</a></y3></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "get each ordered-by user leaf-list"
|
new "get each ordered-by user leaf-list"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y2[k='b']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y2 xmlns="urn:example:order"><k>b</k><a>bar</a></y2></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y2[k='b']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y2 xmlns="urn:example:order"><k>b</k><a>bar</a></y2></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "get each ordered-by user leaf-list"
|
new "get each ordered-by user leaf-list"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y3[k='b']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y3 xmlns="urn:example:order"><k>b</k><a>bar</a></y3></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y3[k='b']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y3 xmlns="urn:example:order"><k>b</k><a>bar</a></y3></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "delete candidate"
|
new "delete candidate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><default-operation>none</default-operation><config operation="delete"/></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><default-operation>none</default-operation><config operation="delete"/></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
# LEAF_LISTS
|
# LEAF_LISTS
|
||||||
|
|
||||||
new "add two entries (c,b) to leaf-list user order"
|
new "add two entries (c,b) to leaf-list user order"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:order">c</y0><y0 xmlns="urn:example:order">b</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:order">c</y0><y0 xmlns="urn:example:order">b</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "add one entry (a) to leaf-list user order"
|
new "add one entry (a) to leaf-list user order"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:order">a</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:order">a</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit"
|
new "netconf commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "add one entry (0) to leaf-list user order after commit"
|
new "add one entry (0) to leaf-list user order after commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:order">0</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:order">0</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit"
|
new "netconf commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "verify leaf-list user order in running (as entered: c,b,a,0)"
|
new "verify leaf-list user order in running (as entered: c,b,a,0)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><running/></source><filter type="xpath" select="/y0"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><y0 xmlns="urn:example:order">c</y0><y0 xmlns="urn:example:order">b</y0><y0 xmlns="urn:example:order">a</y0><y0 xmlns="urn:example:order">0</y0></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><running/></source><filter type="xpath" select="/y0"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><y0 xmlns="urn:example:order">c</y0><y0 xmlns="urn:example:order">b</y0><y0 xmlns="urn:example:order">a</y0><y0 xmlns="urn:example:order">0</y0></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
# LISTS
|
# LISTS
|
||||||
|
|
||||||
new "add two entries to list user order"
|
new "add two entries to list user order"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y2 xmlns="urn:example:order"><k>c</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>b</k><a>foo</a></y2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><y2 xmlns="urn:example:order"><k>c</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>b</k><a>foo</a></y2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "add one entry to list user order"
|
new "add one entry to list user order"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y2 xmlns="urn:example:order"><k>a</k><a>fie</a></y2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><y2 xmlns="urn:example:order"><k>a</k><a>fie</a></y2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "verify list user order (as entered)"
|
new "verify list user order (as entered)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/y2"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><y2 xmlns="urn:example:order"><k>c</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>b</k><a>foo</a></y2><y2 xmlns="urn:example:order"><k>a</k><a>fie</a></y2></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/y2"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><y2 xmlns="urn:example:order"><k>c</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>b</k><a>foo</a></y2><y2 xmlns="urn:example:order"><k>a</k><a>fie</a></y2></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "Overwrite existing ordered-by user y2->c"
|
new "Overwrite existing ordered-by user y2->c"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y2 xmlns="urn:example:order">
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><y2 xmlns="urn:example:order">
|
||||||
<k>c</k><a>newc</a>
|
<k>c</k><a>newc</a>
|
||||||
</y2></config></edit-config></rpc>]]>]]>'
|
</y2></config></edit-config></rpc>]]>]]>'
|
||||||
|
|
||||||
new "Overwrite existing ordered-by user y2->b"
|
new "Overwrite existing ordered-by user y2->b"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y2 xmlns="urn:example:order">
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><y2 xmlns="urn:example:order">
|
||||||
<k>b</k><a>newb</a>
|
<k>b</k><a>newb</a>
|
||||||
</y2></config></edit-config></rpc>]]>]]>'
|
</y2></config></edit-config></rpc>]]>]]>'
|
||||||
|
|
||||||
new "Overwrite existing ordered-by user y2->a"
|
new "Overwrite existing ordered-by user y2->a"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y2 xmlns="urn:example:order">
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><y2 xmlns="urn:example:order">
|
||||||
<k>a</k><a>newa</a>
|
<k>a</k><a>newa</a>
|
||||||
</y2></config></edit-config></rpc>]]>]]>'
|
</y2></config></edit-config></rpc>]]>]]>'
|
||||||
|
|
||||||
new "Tests for no duplicates."
|
new "Tests for no duplicates."
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/y2"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><y2 xmlns="urn:example:order"><k>c</k><a>newc</a></y2><y2 xmlns="urn:example:order"><k>b</k><a>newb</a></y2><y2 xmlns="urn:example:order"><k>a</k><a>newa</a></y2></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/y2"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><y2 xmlns="urn:example:order"><k>c</k><a>newc</a></y2><y2 xmlns="urn:example:order"><k>b</k><a>newb</a></y2><y2 xmlns="urn:example:order"><k>a</k><a>newa</a></y2></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
#-- order by type rather than strings.
|
#-- order by type rather than strings.
|
||||||
# there are three leaf-lists:strings, ints, and decimal64, and two lists:
|
# there are three leaf-lists:strings, ints, and decimal64, and two lists:
|
||||||
|
|
@ -246,44 +247,44 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><cand
|
||||||
# The check is to write the entries as: 10,2,1, and then expect them to
|
# The check is to write the entries as: 10,2,1, and then expect them to
|
||||||
# get back as 1,2,10 (if typed).
|
# get back as 1,2,10 (if typed).
|
||||||
new "put strings (10,2,1)"
|
new "put strings (10,2,1)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><types xmlns="urn:example:order">
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><types xmlns="urn:example:order">
|
||||||
<strings>10</strings><strings>2</strings><strings>1</strings>
|
<strings>10</strings><strings>2</strings><strings>1</strings>
|
||||||
</types></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
</types></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "check string order (1,10,2)"
|
new "check string order (1,10,2)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/types/strings"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><types xmlns="urn:example:order"><strings>1</strings><strings>10</strings><strings>2</strings></types></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/types/strings"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><types xmlns="urn:example:order"><strings>1</strings><strings>10</strings><strings>2</strings></types></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "put leaf-list int (10,2,1)"
|
new "put leaf-list int (10,2,1)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><types xmlns="urn:example:order">
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><types xmlns="urn:example:order">
|
||||||
<ints>10</ints><ints>2</ints><ints>1</ints>
|
<ints>10</ints><ints>2</ints><ints>1</ints>
|
||||||
</types></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
</types></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "check leaf-list int order (1,2,10)"
|
new "check leaf-list int order (1,2,10)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/types/ints"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><types xmlns="urn:example:order"><ints>1</ints><ints>2</ints><ints>10</ints></types></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/types/ints"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><types xmlns="urn:example:order"><ints>1</ints><ints>2</ints><ints>10</ints></types></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "put list int (10,2,1)"
|
new "put list int (10,2,1)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><types xmlns="urn:example:order">
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><types xmlns="urn:example:order">
|
||||||
<listints><a>10</a></listints><listints><a>2</a></listints><listints><a>1</a></listints>
|
<listints><a>10</a></listints><listints><a>2</a></listints><listints><a>1</a></listints>
|
||||||
</types></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
</types></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "check list int order (1,2,10)"
|
new "check list int order (1,2,10)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/types/listints"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><types xmlns="urn:example:order"><listints><a>1</a></listints><listints><a>2</a></listints><listints><a>10</a></listints></types></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/types/listints"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><types xmlns="urn:example:order"><listints><a>1</a></listints><listints><a>2</a></listints><listints><a>10</a></listints></types></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "put leaf-list decimal64 (10,2,1)"
|
new "put leaf-list decimal64 (10,2,1)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><types xmlns="urn:example:order">
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><types xmlns="urn:example:order">
|
||||||
<decs>10.0</decs><decs>2.0</decs><decs>1.0</decs>
|
<decs>10.0</decs><decs>2.0</decs><decs>1.0</decs>
|
||||||
</types></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
</types></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "check leaf-list decimal64 order (1,2,10)"
|
new "check leaf-list decimal64 order (1,2,10)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/types/decs"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><types xmlns="urn:example:order"><decs>1.0</decs><decs>2.0</decs><decs>10.0</decs></types></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/types/decs"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><types xmlns="urn:example:order"><decs>1.0</decs><decs>2.0</decs><decs>10.0</decs></types></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "put list decimal64 (10,2,1)"
|
new "put list decimal64 (10,2,1)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><types xmlns="urn:example:order">
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><types xmlns="urn:example:order">
|
||||||
<listdecs><a>10.0</a></listdecs><listdecs><a>2.0</a></listdecs><listdecs><a>1.0</a></listdecs>
|
<listdecs><a>10.0</a></listdecs><listdecs><a>2.0</a></listdecs><listdecs><a>1.0</a></listdecs>
|
||||||
</types></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
</types></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "check list decimal64 order (1,2,10)"
|
new "check list decimal64 order (1,2,10)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/types/listdecs"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><types xmlns="urn:example:order"><listdecs><a>1.0</a></listdecs><listdecs><a>2.0</a></listdecs><listdecs><a>10.0</a></listdecs></types></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/types/listdecs"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><types xmlns="urn:example:order"><listdecs><a>1.0</a></listdecs><listdecs><a>2.0</a></listdecs><listdecs><a>10.0</a></listdecs></types></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
if [ $BE -eq 0 ]; then
|
if [ $BE -eq 0 ]; then
|
||||||
exit # BE
|
exit # BE
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ cat <<EOF > $cfg
|
||||||
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
||||||
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_DIR>$IETFRFC</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_RESTCONF_PRETTY>false</CLICON_RESTCONF_PRETTY>
|
||||||
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
|
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
|
||||||
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
|
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
|
||||||
|
|
@ -101,7 +102,7 @@ cat <<EOF > $fyang
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
new "test params: -f $cfg -y $fyang"
|
new "test params: -f $cfg"
|
||||||
|
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "kill old backend"
|
new "kill old backend"
|
||||||
|
|
@ -109,15 +110,15 @@ if [ $BE -ne 0 ]; then
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
err
|
err
|
||||||
fi
|
fi
|
||||||
new "start backend -s init -f $cfg -y $fyang"
|
new "start backend -s init -f $cfg"
|
||||||
start_backend -s init -f $cfg -y $fyang
|
start_backend -s init -f $cfg
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new "kill old restconf daemon"
|
new "kill old restconf daemon"
|
||||||
sudo pkill -u www-data -f "/www-data/clixon_restconf"
|
sudo pkill -u www-data -f "/www-data/clixon_restconf"
|
||||||
|
|
||||||
new "start restconf daemon"
|
new "start restconf daemon"
|
||||||
start_restconf -f $cfg -y $fyang
|
start_restconf -f $cfg
|
||||||
|
|
||||||
new "waiting"
|
new "waiting"
|
||||||
wait_backend
|
wait_backend
|
||||||
|
|
@ -128,35 +129,35 @@ wait_restconf
|
||||||
new "1. Netconf RFC5277 stream testing"
|
new "1. Netconf RFC5277 stream testing"
|
||||||
# 1.1 Stream discovery
|
# 1.1 Stream discovery
|
||||||
new "netconf event stream discovery RFC5277 Sec 3.2.5"
|
new "netconf event stream discovery RFC5277 Sec 3.2.5"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get><filter type="xpath" select="netconf/streams" xmlns="urn:ietf:params:xml:ns:netmod:notification"/></get></rpc>]]>]]>' '<rpc-reply><data><netconf xmlns="urn:ietf:params:xml:ns:netmod:notification"><streams><stream><name>EXAMPLE</name><description>Example event stream</description><replay-support>true</replay-support></stream></streams></netconf></data></rpc-reply>]]>]]>'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get><filter type="xpath" select="netconf/streams" xmlns="urn:ietf:params:xml:ns:netmod:notification"/></get></rpc>]]>]]>' '<rpc-reply><data><netconf xmlns="urn:ietf:params:xml:ns:netmod:notification"><streams><stream><name>EXAMPLE</name><description>Example event stream</description><replay-support>true</replay-support></stream></streams></netconf></data></rpc-reply>]]>]]>'
|
||||||
|
|
||||||
new "netconf event stream discovery RFC8040 Sec 6.2"
|
new "netconf event stream discovery RFC8040 Sec 6.2"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get><filter type="xpath" select="restconf-state/streams"/></get></rpc>]]>]]>' '<rpc-reply><data><restconf-state xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring"><streams><stream><name>EXAMPLE</name><description>Example event stream</description><replay-support>true</replay-support><access><encoding>xml</encoding><location>https://localhost/streams/EXAMPLE</location></access></stream></streams></restconf-state></data></rpc-reply>]]>]]>'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get><filter type="xpath" select="restconf-state/streams"/></get></rpc>]]>]]>' '<rpc-reply><data><restconf-state xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring"><streams><stream><name>EXAMPLE</name><description>Example event stream</description><replay-support>true</replay-support><access><encoding>xml</encoding><location>https://localhost/streams/EXAMPLE</location></access></stream></streams></restconf-state></data></rpc-reply>]]>]]>'
|
||||||
|
|
||||||
#
|
#
|
||||||
# 1.2 Netconf stream subscription
|
# 1.2 Netconf stream subscription
|
||||||
new "netconf EXAMPLE subscription"
|
new "netconf EXAMPLE subscription"
|
||||||
expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream></create-subscription></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' $NCWAIT
|
expectwait "$clixon_netconf -qf $cfg" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream></create-subscription></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' $NCWAIT
|
||||||
|
|
||||||
new "netconf subscription with empty startTime"
|
new "netconf subscription with empty startTime"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream><startTime/></create-subscription></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>startTime</bad-element></error-info><error-severity>error</error-severity><error-message>regexp match fail:'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream><startTime/></create-subscription></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>startTime</bad-element></error-info><error-severity>error</error-severity><error-message>regexp match fail:'
|
||||||
|
|
||||||
new "netconf EXAMPLE subscription with simple filter"
|
new "netconf EXAMPLE subscription with simple filter"
|
||||||
expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream><filter type="xpath" select="event"/></create-subscription></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' $NCWAIT
|
expectwait "$clixon_netconf -qf $cfg" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream><filter type="xpath" select="event"/></create-subscription></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' $NCWAIT
|
||||||
|
|
||||||
new "netconf EXAMPLE subscription with filter classifier"
|
new "netconf EXAMPLE subscription with filter classifier"
|
||||||
expectwait "$clixon_netconf -qf $cfg -y $fyang" "<rpc><create-subscription xmlns=\"urn:ietf:params:xml:ns:netmod:notification\"><stream>EXAMPLE</stream><filter type=\"xpath\" select=\"event[event-class='fault']\"/></create-subscription></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' $NCWAIT
|
expectwait "$clixon_netconf -qf $cfg" "<rpc><create-subscription xmlns=\"urn:ietf:params:xml:ns:netmod:notification\"><stream>EXAMPLE</stream><filter type=\"xpath\" select=\"event[event-class='fault']\"/></create-subscription></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' $NCWAIT
|
||||||
|
|
||||||
new "netconf NONEXIST subscription"
|
new "netconf NONEXIST subscription"
|
||||||
expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>NONEXIST</stream></create-subscription></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>invalid-value</error-tag><error-severity>error</error-severity><error-message>No such stream</error-message></rpc-error></rpc-reply>]]>]]>$' $NCWAIT
|
expectwait "$clixon_netconf -qf $cfg" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>NONEXIST</stream></create-subscription></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>invalid-value</error-tag><error-severity>error</error-severity><error-message>No such stream</error-message></rpc-error></rpc-reply>]]>]]>$' $NCWAIT
|
||||||
|
|
||||||
new "netconf EXAMPLE subscription with wrong date"
|
new "netconf EXAMPLE subscription with wrong date"
|
||||||
expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream><startTime>kallekaka</startTime></create-subscription></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>startTime</bad-element></error-info><error-severity>error</error-severity><error-message>regexp match fail:' 0
|
expectwait "$clixon_netconf -qf $cfg" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream><startTime>kallekaka</startTime></create-subscription></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>startTime</bad-element></error-info><error-severity>error</error-severity><error-message>regexp match fail:' 0
|
||||||
|
|
||||||
#new "netconf EXAMPLE subscription with replay"
|
#new "netconf EXAMPLE subscription with replay"
|
||||||
#NOW=$(date +"%Y-%m-%dT%H:%M:%S")
|
#NOW=$(date +"%Y-%m-%dT%H:%M:%S")
|
||||||
#sleep 10
|
#sleep 10
|
||||||
#expectwait "$clixon_netconf -qf $cfg -y $fyang" "<rpc><create-subscription xmlns=\"urn:ietf:params:xml:ns:netmod:notification\"><stream>EXAMPLE</stream><startTime>$NOW</startTime></create-subscription></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' 10
|
#expectwait "$clixon_netconf -qf $cfg" "<rpc><create-subscription xmlns=\"urn:ietf:params:xml:ns:netmod:notification\"><stream>EXAMPLE</stream><startTime>$NOW</startTime></create-subscription></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' 10
|
||||||
sleep 2
|
sleep 2
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ cat <<EOF > $cfg
|
||||||
<CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
||||||
|
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
|
||||||
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
||||||
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
||||||
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
||||||
|
|
@ -76,7 +77,7 @@ module example{
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
new "test params: -f $cfg -y $fyang"
|
new "test params: -f $cfg"
|
||||||
|
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "kill old backend"
|
new "kill old backend"
|
||||||
|
|
@ -84,21 +85,21 @@ if [ $BE -ne 0 ]; then
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
err
|
err
|
||||||
fi
|
fi
|
||||||
new "start backend -s init -f $cfg -y $fyang"
|
new "start backend -s init -f $cfg"
|
||||||
start_backend -s init -f $cfg -y $fyang
|
start_backend -s init -f $cfg
|
||||||
|
|
||||||
new "waiting"
|
new "waiting"
|
||||||
sleep $RCWAIT
|
sleep $RCWAIT
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new "cli set transitive string"
|
new "cli set transitive string"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c talle x" 0 "^$"
|
expectfn "$clixon_cli -1f $cfg -l o set c talle x" 0 "^$"
|
||||||
|
|
||||||
new "cli set transitive union"
|
new "cli set transitive union"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set c ulle 33" 0 "^$"
|
expectfn "$clixon_cli -1f $cfg -l o set c ulle 33" 0 "^$"
|
||||||
|
|
||||||
new "cli set transitive union error"
|
new "cli set transitive union error"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang 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": Unknown command$'
|
||||||
|
|
||||||
if [ $BE -eq 0 ]; then
|
if [ $BE -eq 0 ]; then
|
||||||
exit # BE
|
exit # BE
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ cat <<EOF > $cfg
|
||||||
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
||||||
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
||||||
|
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
|
||||||
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
||||||
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
||||||
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
||||||
|
|
@ -89,56 +90,56 @@ module $APPNAME{
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
new "test params: -f $cfg -y $fyang"
|
new "test params: -f $cfg"
|
||||||
|
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "kill old backend"
|
new "kill old backend"
|
||||||
sudo clixon_backend -zf $cfg -y $fyang
|
sudo clixon_backend -zf $cfg
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
err
|
err
|
||||||
fi
|
fi
|
||||||
new "start backend -s init -f $cfg -y $fyang"
|
new "start backend -s init -f $cfg"
|
||||||
start_backend -s init -f $cfg -y $fyang
|
start_backend -s init -f $cfg
|
||||||
|
|
||||||
new "waiting"
|
new "waiting"
|
||||||
sleep $RCWAIT
|
sleep $RCWAIT
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new "when: add static route"
|
new "when: add static route"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><whenex xmlns="urn:example:clixon"><type>static</type><name>r1</name><static-routes/></whenex></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><whenex xmlns="urn:example:clixon"><type>static</type><name>r1</name><static-routes/></whenex></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "when: validate ok"
|
new "when: validate ok"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "when: add direct route"
|
new "when: add direct route"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><whenex xmlns="urn:example:clixon"><type>direct</type><name>r2</name><static-routes/></whenex></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><whenex xmlns="urn:example:clixon"><type>direct</type><name>r2</name><static-routes/></whenex></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "when get config"
|
new "when get config"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" '^<rpc-reply><data><whenex xmlns="urn:example:clixon"><type>direct</type><name>r2</name><static-routes/></whenex><whenex xmlns="urn:example:clixon"><type>static</type><name>r1</name><static-routes/></whenex></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" '^<rpc-reply><data><whenex xmlns="urn:example:clixon"><type>direct</type><name>r2</name><static-routes/></whenex><whenex xmlns="urn:example:clixon"><type>static</type><name>r1</name><static-routes/></whenex></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "when: validate fail"
|
new "when: validate fail"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 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>when xpath validation failed</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>operation-failed</error-tag><error-severity>error</error-severity><error-message>when xpath validation failed</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "when: discard-changes"
|
new "when: discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "must: add interface"
|
new "must: add interface"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><interface xmlns="urn:example:clixon"><ifType>ethernet</ifType><ifMTU>1500</ifMTU></interface></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><interface xmlns="urn:example:clixon"><ifType>ethernet</ifType><ifMTU>1500</ifMTU></interface></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "must: validate ok"
|
new "must: validate ok"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "must: add atm interface"
|
new "must: add atm interface"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><interface xmlns="urn:example:clixon"><ifType>atm</ifType><ifMTU>32</ifMTU></interface></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><interface xmlns="urn:example:clixon"><ifType>atm</ifType><ifMTU>32</ifMTU></interface></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "must: atm validate fail"
|
new "must: atm validate fail"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 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>An ATM MTU must be 64 .. 17966</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>operation-failed</error-tag><error-severity>error</error-severity><error-message>An ATM MTU must be 64 .. 17966</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "must: add eth interface"
|
new "must: add eth interface"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><interface xmlns="urn:example:clixon"><ifType>ethernet</ifType><ifMTU>989</ifMTU></interface></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><interface xmlns="urn:example:clixon"><ifType>ethernet</ifType><ifMTU>989</ifMTU></interface></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "must: eth validate fail"
|
new "must: eth validate fail"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 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>An Ethernet MTU must be 1500</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>operation-failed</error-tag><error-severity>error</error-severity><error-message>An Ethernet MTU must be 1500</error-message></rpc-error></rpc-reply>]]>]]>"
|
||||||
|
|
||||||
if [ $BE -eq 0 ]; then
|
if [ $BE -eq 0 ]; then
|
||||||
exit # BE
|
exit # BE
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ cat <<EOF > $cfg
|
||||||
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>$dir</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
||||||
|
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
|
||||||
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
||||||
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
||||||
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
||||||
|
|
@ -141,35 +142,35 @@ module $APPNAME{
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
new "test params: -f $cfg -y $fyang"
|
new "test params: -f $cfg"
|
||||||
|
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "kill old backend"
|
new "kill old backend"
|
||||||
sudo clixon_backend -zf $cfg -y $fyang
|
sudo clixon_backend -zf $cfg
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
err
|
err
|
||||||
fi
|
fi
|
||||||
new "start backend -s init -f $cfg -y $fyang"
|
new "start backend -s init -f $cfg"
|
||||||
start_backend -s init -f $cfg -y $fyang
|
start_backend -s init -f $cfg
|
||||||
|
|
||||||
new "waiting"
|
new "waiting"
|
||||||
wait_backend
|
wait_backend
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new "cli defined extension"
|
new "cli defined extension"
|
||||||
expectfn "$clixon_cli -1f $cfg -y $fyang show version" 0 "3."
|
expectfn "$clixon_cli -1f $cfg show version" 0 "3."
|
||||||
|
|
||||||
new "empty values in leaf-list"
|
new "empty values in leaf-list"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><f><e>a</e></f></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><f><e>a</e></f></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "empty values in leaf-list2"
|
new "empty values in leaf-list2"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><f><e/></f></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><f><e/></f></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get config"
|
new "netconf get config"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" '^<rpc-reply><data><x xmlns="urn:example:clixon"><f><e/><e>a</e></f></x></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" '^<rpc-reply><data><x xmlns="urn:example:clixon"><f><e/><e>a</e></f></x></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "netconf discard-changes"
|
new "netconf discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
|
||||||
#new "cli not defined extension"
|
#new "cli not defined extension"
|
||||||
|
|
@ -179,106 +180,106 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]
|
||||||
#expectfn "$clixon_cli -1f $cfg -y $fyangerr show version" 0 "Yang error: Extension ex:not-defined not found"
|
#expectfn "$clixon_cli -1f $cfg -y $fyangerr show version" 0 "Yang error: Extension ex:not-defined not found"
|
||||||
|
|
||||||
new "netconf schema resource, RFC 7895"
|
new "netconf schema resource, RFC 7895"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get><filter type="xpath" select="modules-state/module" xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library"/></get></rpc>]]>]]>' '<module><name>ietf-yang-types</name><revision>2013-07-15</revision><namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</namespace><conformance-type>implement</conformance-type></module>'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get><filter type="xpath" select="modules-state/module" xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library"/></get></rpc>]]>]]>' '<module><name>ietf-yang-types</name><revision>2013-07-15</revision><namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</namespace><conformance-type>implement</conformance-type></module>'
|
||||||
|
|
||||||
new "netconf edit config"
|
new "netconf edit config"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><y><a>1</a><b>2</b><c>5</c><val>one</val></y><d/></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><y><a>1</a><b>2</b><c>5</c><val>one</val></y><d/></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit"
|
new "netconf commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
# text empty type in running
|
# text empty type in running
|
||||||
new "netconf commit 2nd"
|
new "netconf commit 2nd"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get config xpath"
|
new "netconf get config xpath"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/x/y[a=1][b=2][c=5]\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><x xmlns="urn:example:clixon"><y><a>1</a><b>2</b><c>5</c><val>one</val></y></x></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/x/y[a=1][b=2][c=5]\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><x xmlns="urn:example:clixon"><y><a>1</a><b>2</b><c>5</c><val>one</val></y></x></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "netconf edit leaf-list"
|
new "netconf edit leaf-list"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><f><e>hej</e><e>hopp</e></f></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><f><e>hej</e><e>hopp</e></f></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get leaf-list"
|
new "netconf get leaf-list"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/x/f/e"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><x xmlns="urn:example:clixon"><f><e>hej</e><e>hopp</e></f></x></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/x/f/e"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><x xmlns="urn:example:clixon"><f><e>hej</e><e>hopp</e></f></x></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "netconf get leaf-list path"
|
new "netconf get leaf-list path"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/x/f[e='hej']\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><x xmlns=\"urn:example:clixon\"><f><e>hej</e><e>hopp</e></f></x></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/x/f[e='hej']\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><x xmlns=\"urn:example:clixon\"><f><e>hej</e><e>hopp</e></f></x></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get (should be some)"
|
new "netconf get (should be some)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get><filter type=\"xpath\" select=\"/\"/></get></rpc>]]>]]>" '^<rpc-reply><data><x xmlns="urn:example:clixon"><y><a>1</a><b>2</b><c>5</c><val>one</val></y><d/></x>'
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><get><filter type=\"xpath\" select=\"/\"/></get></rpc>]]>]]>" '^<rpc-reply><data><x xmlns="urn:example:clixon"><y><a>1</a><b>2</b><c>5</c><val>one</val></y><d/></x>'
|
||||||
|
|
||||||
new "cli set leaf-list"
|
new "cli set leaf-list"
|
||||||
expectfn "$clixon_cli -1f $cfg -y $fyang set x f e foo" 0 ""
|
expectfn "$clixon_cli -1f $cfg set x f e foo" 0 ""
|
||||||
|
|
||||||
new "cli show leaf-list"
|
new "cli show leaf-list"
|
||||||
expectfn "$clixon_cli -1f $cfg -y $fyang show xpath /x/f/e" 0 "<e>foo</e>"
|
expectfn "$clixon_cli -1f $cfg show xpath /x/f/e" 0 "<e>foo</e>"
|
||||||
|
|
||||||
new "netconf set state data (not allowed)"
|
new "netconf set state data (not allowed)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><state xmlns="urn:example:clixon"><op>42</op></state></config></edit-config></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>protocol</error-type><error-tag>invalid-value</error-tag><error-severity>error</error-severity><error-message>State data not allowed</error-message></rpc-error></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><state xmlns="urn:example:clixon"><op>42</op></state></config></edit-config></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>protocol</error-type><error-tag>invalid-value</error-tag><error-severity>error</error-severity><error-message>State data not allowed</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "netconf set presence and not present"
|
new "netconf set presence and not present"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><nopresence/><presence/></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><nopresence/><presence/></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get presence only"
|
new "netconf get presence only"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/x/presence"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><x xmlns="urn:example:clixon"><presence/></x></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/x/presence"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><x xmlns="urn:example:clixon"><presence/></x></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "netconf get presence only"
|
new "netconf get presence only"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/x/nopresence"/></get-config></rpc>]]>]]>' "^<rpc-reply><data/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/x/nopresence"/></get-config></rpc>]]>]]>' "^<rpc-reply><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf discard-changes"
|
new "netconf discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf anyxml"
|
new "netconf anyxml"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><any><foo><bar a="nisse"/></foo></any></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><any><foo><bar a="nisse"/></foo></any></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate anyxml"
|
new "netconf validate anyxml"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf delete candidate"
|
new "netconf delete candidate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><default-operation>none</default-operation><config operation="delete"/></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><default-operation>none</default-operation><config operation="delete"/></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
# Check 3-keys
|
# Check 3-keys
|
||||||
new "netconf add one 3-key entry"
|
new "netconf add one 3-key entry"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><y><a>1</a><b>1</b><c>1</c><val>one</val></y></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><y><a>1</a><b>1</b><c>1</c><val>one</val></y></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf check add one 3-key"
|
new "netconf check add one 3-key"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x xmlns="urn:example:clixon"><y><a>1</a><b>1</b><c>1</c><val>one</val></y></x></data></rpc-reply>]]>]]>'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x xmlns="urn:example:clixon"><y><a>1</a><b>1</b><c>1</c><val>one</val></y></x></data></rpc-reply>]]>]]>'
|
||||||
|
|
||||||
new "netconf add another (with same 1st key)"
|
new "netconf add another (with same 1st key)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf check add another"
|
new "netconf check add another"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x xmlns="urn:example:clixon"><y><a>1</a><b>1</b><c>1</c><val>one</val></y><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x xmlns="urn:example:clixon"><y><a>1</a><b>1</b><c>1</c><val>one</val></y><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>'
|
||||||
|
|
||||||
new "netconf replace first"
|
new "netconf replace first"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><y><a>1</a><b>1</b><c>1</c><val>replace</val></y></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><y><a>1</a><b>1</b><c>1</c><val>replace</val></y></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf check replace"
|
new "netconf check replace"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x xmlns="urn:example:clixon"><y><a>1</a><b>1</b><c>1</c><val>replace</val></y><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x xmlns="urn:example:clixon"><y><a>1</a><b>1</b><c>1</c><val>replace</val></y><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>'
|
||||||
|
|
||||||
new "netconf delete first"
|
new "netconf delete first"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><y operation="remove"><a>1</a><b>1</b><c>1</c></y></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><y operation="remove"><a>1</a><b>1</b><c>1</c></y></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf check delete"
|
new "netconf check delete"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x xmlns="urn:example:clixon"><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x xmlns="urn:example:clixon"><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>'
|
||||||
|
|
||||||
# clear db for next test
|
# clear db for next test
|
||||||
new "netconf delete candidate"
|
new "netconf delete candidate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><default-operation>none</default-operation><config operation="delete"/></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><default-operation>none</default-operation><config operation="delete"/></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit empty candidate"
|
new "netconf commit empty candidate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconfig config submodule"
|
new "netconfig config submodule"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><mylist xmlns="urn:example:clixon"><x>a</x><subm-container><subm-leaf>foo</subm-leaf></subm-container></mylist></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><mylist xmlns="urn:example:clixon"><x>a</x><subm-container><subm-leaf>foo</subm-leaf></subm-container></mylist></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf submodule get config"
|
new "netconf submodule get config"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply><data><mylist xmlns="urn:example:clixon"><x>a</x><subm-container><subm-leaf>foo</subm-leaf></subm-container></mylist></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply><data><mylist xmlns="urn:example:clixon"><x>a</x><subm-container><subm-leaf>foo</subm-leaf></subm-container></mylist></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "netconf submodule validate"
|
new "netconf submodule validate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf submodule discard-changes"
|
new "netconf submodule discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
if [ $BE -eq 0 ]; then
|
if [ $BE -eq 0 ]; then
|
||||||
exit # BE
|
exit # BE
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ main(int argc,
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int fd = 0; /* stdin */
|
int fd = 0; /* stdin */
|
||||||
cxobj *xcfg = NULL;
|
cxobj *xcfg = NULL;
|
||||||
cbuf *cberr;
|
cbuf *cbret = NULL;
|
||||||
|
|
||||||
/* In the startup, logs to stderr & debug flag set later */
|
/* In the startup, logs to stderr & debug flag set later */
|
||||||
clicon_log_init(__FILE__, LOG_INFO, CLICON_LOG_STDERR);
|
clicon_log_init(__FILE__, LOG_INFO, CLICON_LOG_STDERR);
|
||||||
|
|
@ -205,13 +205,13 @@ main(int argc,
|
||||||
if ((ret = json_parse_file(fd, yspec, &xt, &xerr)) < 0)
|
if ((ret = json_parse_file(fd, yspec, &xt, &xerr)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
xml_print(stderr, xerr);
|
clicon_rpc_generate_error("util_xml", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (xml_parse_file(fd, "</config>", NULL, &xt) < 0){
|
if (xml_parse_file(fd, "</config>", NULL, &xt) < 0){
|
||||||
fprintf(stderr, "xml parse error %s\n", clicon_err_reason);
|
fprintf(stderr, "xml parse error: %s\n", clicon_err_reason);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -227,10 +227,6 @@ main(int argc,
|
||||||
/* 3. Validate data (if yspec) */
|
/* 3. Validate data (if yspec) */
|
||||||
if (validate){
|
if (validate){
|
||||||
xc = xml_child_i(xt, 0);
|
xc = xml_child_i(xt, 0);
|
||||||
if ((cberr = cbuf_new()) == NULL){
|
|
||||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
/* Populate */
|
/* Populate */
|
||||||
if (xml_apply0(xc, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
if (xml_apply0(xc, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -242,12 +238,14 @@ main(int argc,
|
||||||
goto done;
|
goto done;
|
||||||
if (xml_apply0(xc, -1, xml_sort_verify, h) < 0)
|
if (xml_apply0(xc, -1, xml_sort_verify, h) < 0)
|
||||||
clicon_log(LOG_NOTICE, "%s: sort verify failed", __FUNCTION__);
|
clicon_log(LOG_NOTICE, "%s: sort verify failed", __FUNCTION__);
|
||||||
if ((ret = xml_yang_validate_all_top(h, xc, cberr)) < 0)
|
if ((ret = xml_yang_validate_all_top(h, xc, &xerr)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret > 0 && (ret = xml_yang_validate_add(h, xc, cberr)) < 0)
|
if (ret > 0 && (ret = xml_yang_validate_add(h, xc, &xerr)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
fprintf(stderr, "%s", cbuf_get(cberr));
|
if (netconf_err2cb(xerr, &cbret) < 0)
|
||||||
|
goto done;
|
||||||
|
fprintf(stderr, "xml validation error: %s\n", cbuf_get(cbret));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -264,6 +262,8 @@ main(int argc,
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
if (cbret)
|
||||||
|
cbuf_free(cbret);
|
||||||
if (xt)
|
if (xt)
|
||||||
xml_free(xt);
|
xml_free(xt);
|
||||||
if (cb)
|
if (cb)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue